Play-/tools/McServTest/Main.cpp

137 lines
4.3 KiB
C++
Raw Permalink Normal View History

2022-09-13 08:22:25 -04:00
#include <cstdio>
#include <cassert>
#include <cstring>
2023-06-09 12:51:41 -04:00
#include "Ps2Const.h"
2018-12-20 12:37:47 -05:00
#include "iop/IopBios.h"
2014-11-15 23:22:29 -05:00
#include "iop/Iop_McServ.h"
#include "iop/Iop_PathUtils.h"
2018-12-20 12:37:47 -05:00
#include "iop/Iop_SubSystem.h"
2014-11-15 23:22:29 -05:00
#include "AppConfig.h"
#include "PathUtils.h"
#include "StdStreamUtils.h"
#include "GameTestSheet.h"
#define MCSERV_CMD(a) (Iop::CMcServ::a | Iop::CMcServ::CMD_FLAG_DIRECT)
2019-10-21 12:42:29 -04:00
#define CHECK(condition) \
if(!(condition)) \
{ \
throw std::exception(); \
}
2014-11-15 23:22:29 -05:00
void PrepareTestEnvironment(const CGameTestSheet::EnvironmentActionArray& environment)
{
//TODO: There's a bug if there's a slash at the end of the path for the memory card
auto mcPathPreference = Iop::CMcServ::GetMcPathPreference(0);
auto memoryCardPath = fs::path("./memorycard");
fs::remove_all(memoryCardPath);
2014-11-15 23:22:29 -05:00
2017-12-31 13:45:51 -05:00
CAppConfig::GetInstance().RegisterPreferencePath(mcPathPreference, "");
CAppConfig::GetInstance().SetPreferencePath(mcPathPreference, memoryCardPath);
2018-04-30 21:01:23 +01:00
2014-11-15 23:22:29 -05:00
for(const auto& environmentAction : environment)
{
2022-02-07 12:05:50 -05:00
auto actionName = Iop::CMcServ::EncodeMcName(environmentAction.name);
2014-11-15 23:22:29 -05:00
if(environmentAction.type == CGameTestSheet::ENVIRONMENT_ACTION_CREATE_DIRECTORY)
{
2022-02-07 12:05:50 -05:00
auto folderToCreate = Iop::PathUtils::MakeHostPath(memoryCardPath, actionName.c_str());
2014-11-15 23:22:29 -05:00
Framework::PathUtils::EnsurePathExists(folderToCreate);
}
else if(environmentAction.type == CGameTestSheet::ENVIRONMENT_ACTION_CREATE_FILE)
{
2022-02-07 12:05:50 -05:00
auto fileToCreate = Iop::PathUtils::MakeHostPath(memoryCardPath, actionName.c_str());
2014-11-15 23:22:29 -05:00
auto inputStream = Framework::CreateOutputStdStream(fileToCreate.native());
inputStream.Seek(environmentAction.size - 1, Framework::STREAM_SEEK_SET);
inputStream.Write8(0x00);
}
}
}
void ExecuteTest(const CGameTestSheet::TEST& test)
{
2018-12-20 12:37:47 -05:00
Iop::CSubSystem subSystem(true);
subSystem.Reset();
auto bios = static_cast<CIopBios*>(subSystem.m_bios.get());
2023-06-09 12:51:41 -04:00
bios->Reset(PS2::IOP_BASE_RAM_SIZE, std::shared_ptr<Iop::CSifMan>());
2018-12-20 12:37:47 -05:00
auto mcServ = bios->GetMcServ();
2014-11-15 23:22:29 -05:00
2014-11-16 03:10:23 -05:00
if(!test.currentDirectory.empty())
{
uint32 result = 0;
2014-11-15 23:22:29 -05:00
2014-11-16 03:10:23 -05:00
Iop::CMcServ::CMD cmd;
memset(&cmd, 0, sizeof(cmd));
assert(test.currentDirectory.size() <= sizeof(cmd.name));
strncpy(cmd.name, test.currentDirectory.c_str(), sizeof(cmd.name));
2014-11-15 23:22:29 -05:00
mcServ->Invoke(MCSERV_CMD(CMD_ID_CHDIR), reinterpret_cast<uint32*>(&cmd), sizeof(cmd), &result, sizeof(uint32), nullptr);
2019-10-21 20:52:10 -04:00
CHECK(result == 0);
2014-11-16 03:10:23 -05:00
}
2014-11-15 23:22:29 -05:00
{
2014-11-16 03:10:23 -05:00
uint32 result = 0;
Iop::CMcServ::CMD cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.maxEntries = test.maxEntries;
assert(test.query.length() <= sizeof(cmd.name));
strncpy(cmd.name, test.query.c_str(), sizeof(cmd.name));
std::vector<Iop::CMcServ::ENTRY> entries;
if(cmd.maxEntries > 0)
{
entries.resize(cmd.maxEntries);
}
mcServ->Invoke(MCSERV_CMD(CMD_ID_GETDIR), reinterpret_cast<uint32*>(&cmd), sizeof(cmd), &result, sizeof(uint32), reinterpret_cast<uint8*>(entries.data()));
2014-11-16 03:10:23 -05:00
CHECK(result == test.result);
//Check that we can find all reference entries in the result
//Items don't need to be in the same order, but need to appear only once
for(const auto& refEntry : test.entries)
2014-11-15 23:22:29 -05:00
{
auto entryCount = std::count_if(entries.begin(), entries.end(),
2019-10-21 12:42:29 -04:00
[&refEntry](const auto& entry) {
return strcmp(reinterpret_cast<const char*>(entry.name), refEntry.c_str()) == 0;
});
CHECK(entryCount == 1);
2014-11-15 23:22:29 -05:00
}
}
}
int main(int argc, const char** argv)
{
auto testsPath = fs::path("./tests/");
2014-11-15 23:22:29 -05:00
fs::directory_iterator endDirectoryIterator;
for(fs::directory_iterator directoryIterator(testsPath);
2018-04-30 21:01:23 +01:00
directoryIterator != endDirectoryIterator; directoryIterator++)
2014-11-15 23:22:29 -05:00
{
2014-11-16 03:10:23 -05:00
auto testPath = directoryIterator->path();
2015-08-24 21:38:09 -04:00
auto stream = Framework::CreateInputStdStream(testPath.native());
CGameTestSheet testSheet(stream);
2014-11-16 03:10:23 -05:00
for(const auto& test : testSheet.GetTests())
{
auto environment = testSheet.GetEnvironment(test.environmentId);
PrepareTestEnvironment(environment);
ExecuteTest(test);
}
2014-11-15 23:22:29 -05:00
}
return 0;
}
2025-03-11 12:48:26 -04:00
fs::path CAppConfig::GetBasePath() const
{
static const char* BASE_DATA_PATH = "McServTest Data Files";
static const auto basePath =
[]() {
auto result = Framework::PathUtils::GetPersonalDataPath() / BASE_DATA_PATH;
Framework::PathUtils::EnsurePathExists(result);
return result;
}();
return basePath;
}