diff --git a/headless/Compare.cpp b/headless/Compare.cpp index 2d1a9ae886..fcce78c8ea 100644 --- a/headless/Compare.cpp +++ b/headless/Compare.cpp @@ -152,9 +152,19 @@ protected: std::ifstream &in_; }; +std::string ExpectedFromFilename(const std::string &bootFilename) +{ + return bootFilename.substr(0, bootFilename.length() - 4) + ".expected"; +} + +std::string ExpectedScreenshotFromFilename(const std::string &bootFilename) +{ + return bootFilename.substr(0, bootFilename.length() - 4) + ".expected.bmp"; +} + bool CompareOutput(const std::string &bootFilename, const std::string &output) { - std::string expect_filename = bootFilename.substr(0, bootFilename.length() - 4) + ".expected"; + std::string expect_filename = ExpectedFromFilename(bootFilename); std::ifstream in; in.open(expect_filename.c_str(), std::ios::in); if (!in.fail()) diff --git a/headless/Compare.h b/headless/Compare.h index 2152e13b70..6efd3bd285 100644 --- a/headless/Compare.h +++ b/headless/Compare.h @@ -23,5 +23,8 @@ extern bool teamCityMode; extern std::string teamCityName; void TeamCityPrint(const char *fmt, ...); +std::string ExpectedFromFilename(const std::string &bootFilename); +std::string ExpectedScreenshotFromFilename(const std::string &bootFilename); + bool CompareOutput(const std::string &bootFilename, const std::string &output); double CompareScreenshot(const u8 *pixels, int w, int h, int stride, const std::string screenshotFilename, std::string &error); \ No newline at end of file diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 50f13f2860..d4b8acf3a1 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -127,6 +127,76 @@ static std::string ChopEnd(std::string s, std::string end) return s; } +bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, bool autoCompare, double timeout) +{ + if (teamCityMode) { + // Kinda ugly, trying to guesstimate the test name from filename... + teamCityName = ChopEnd(ChopFront(ChopFront(coreParameter.fileToStart, "tests/"), "pspautotests/tests/"), ".prx"); + } + + std::string output; + if (autoCompare) + coreParameter.collectEmuLog = &output; + + std::string error_string; + if (!PSP_Init(coreParameter, &error_string)) { + fprintf(stderr, "Failed to start %s. Error: %s\n", coreParameter.fileToStart.c_str(), error_string.c_str()); + printf("TESTERROR\n"); + TeamCityPrint("##teamcity[testIgnored name='%s' message='PRX/ELF missing']\n", teamCityName.c_str()); + return 1; + } + + TeamCityPrint("##teamcity[testStarted name='%s' captureStandardOutput='true']\n", teamCityName.c_str()); + + host->BootDone(); + + if (autoCompare) + headlessHost->SetComparisonScreenshot(ExpectedScreenshotFromFilename(coreParameter.fileToStart)); + + time_update(); + bool passed = true; + double deadline = time_now() + timeout; + + coreState = CORE_RUNNING; + while (coreState == CORE_RUNNING) + { + int blockTicks = usToCycles(1000000 / 10); + PSP_RunLoopFor(blockTicks); + + // If we were rendering, this might be a nice time to do something about it. + if (coreState == CORE_NEXTFRAME) { + coreState = CORE_RUNNING; + headlessHost->SwapBuffers(); + } + time_update(); + if (time_now_d() > deadline) { + // Don't compare, print the output at least up to this point, and bail. + printf("%s", output.c_str()); + passed = false; + + host->SendDebugOutput("TIMEOUT\n"); + TeamCityPrint("##teamcity[testFailed name='%s' message='Test timeout']\n", teamCityName.c_str()); + Core_Stop(); + } + } + + host->ShutdownGL(); + PSP_Shutdown(); + + headlessHost->FlushDebugOutput(); + + delete host; + host = NULL; + headlessHost = NULL; + + if (autoCompare && passed) + passed = CompareOutput(coreParameter.fileToStart, output); + + TeamCityPrint("##teamcity[testFinished name='%s']\n", teamCityName.c_str()); + + return passed; +} + int main(int argc, const char* argv[]) { bool fullLog = false; @@ -229,8 +299,6 @@ int main(int argc, const char* argv[]) logman->AddListener(type, printfLogger); } - std::string output; - CoreParameter coreParameter; coreParameter.cpuCore = useJit ? CPU_JIT : CPU_INTERPRETER; coreParameter.gpuCore = glWorking ? gpuCore : GPU_NULL; @@ -240,8 +308,6 @@ int main(int argc, const char* argv[]) coreParameter.startPaused = false; coreParameter.enableDebugging = false; coreParameter.printfEmuLog = !autoCompare; - if (autoCompare) - coreParameter.collectEmuLog = &output; coreParameter.headLess = true; coreParameter.renderWidth = 480; coreParameter.renderHeight = 272; @@ -283,65 +349,10 @@ int main(int argc, const char* argv[]) g_Config.flashDirectory = g_Config.memCardDirectory+"/flash/"; #endif - if (teamCityMode) { - // Kinda ugly, trying to guesstimate the test name from filename... - teamCityName = ChopEnd(ChopFront(ChopFront(bootFilename, "tests/"), "pspautotests/tests/"), ".prx"); - } - - if (!PSP_Init(coreParameter, &error_string)) { - fprintf(stderr, "Failed to start %s. Error: %s\n", coreParameter.fileToStart.c_str(), error_string.c_str()); - printf("TESTERROR\n"); - TeamCityPrint("##teamcity[testIgnored name='%s' message='PRX/ELF missing']\n", teamCityName.c_str()); - return 1; - } - - TeamCityPrint("##teamcity[testStarted name='%s' captureStandardOutput='true']\n", teamCityName.c_str()); - - host->BootDone(); - if (screenshotFilename != 0) headlessHost->SetComparisonScreenshot(screenshotFilename); - time_update(); - bool doCompare = true; - double deadline = time_now() + timeout; - - coreState = CORE_RUNNING; - while (coreState == CORE_RUNNING) - { - int blockTicks = usToCycles(1000000 / 10); - PSP_RunLoopFor(blockTicks); - - // If we were rendering, this might be a nice time to do something about it. - if (coreState == CORE_NEXTFRAME) { - coreState = CORE_RUNNING; - headlessHost->SwapBuffers(); - } - time_update(); - if (time_now_d() > deadline) { - // Don't compare, print the output at least up to this point, and bail. - printf("%s", output.c_str()); - doCompare = false; - - host->SendDebugOutput("TIMEOUT\n"); - TeamCityPrint("##teamcity[testFailed name='%s' message='Test timeout']\n", teamCityName.c_str()); - Core_Stop(); - } - } - - host->ShutdownGL(); - PSP_Shutdown(); - - headlessHost->FlushDebugOutput(); - - delete host; - host = NULL; - headlessHost = NULL; - - if (autoCompare && doCompare) - CompareOutput(bootFilename, output); - - TeamCityPrint("##teamcity[testFinished name='%s']\n", teamCityName.c_str()); + RunAutoTest(headlessHost, coreParameter, autoCompare, timeout); return 0; }