From 10fda05e32bc25cd76eaa8fb13d2511959fb8385 Mon Sep 17 00:00:00 2001 From: Souryo Date: Tue, 29 Dec 2015 16:27:37 -0500 Subject: [PATCH] Tests: Added command line utility to run all tests on multiple threads at once (No GUI) to speed up test runs --- NES.sln | 13 ++ TestHelper/TestHelper.cpp | 161 ++++++++++++++++++++++++ TestHelper/TestHelper.vcxproj | 169 ++++++++++++++++++++++++++ TestHelper/TestHelper.vcxproj.filters | 14 +++ 4 files changed, 357 insertions(+) create mode 100644 TestHelper/TestHelper.cpp create mode 100644 TestHelper/TestHelper.vcxproj create mode 100644 TestHelper/TestHelper.vcxproj.filters diff --git a/NES.sln b/NES.sln index 93f7b0f5..9dc9f7d9 100644 --- a/NES.sln +++ b/NES.sln @@ -32,6 +32,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PGOHelper", "PGOHelper\PGOH EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BlipBuffer", "BlipBuffer\BlipBuffer.vcxproj", "{CF35D78C-F710-41D2-968F-C46ACCFF6F07}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestHelper", "TestHelper\TestHelper.vcxproj", "{2A607369-8B5D-494A-9E40-C5DC8D821AA3}" + ProjectSection(ProjectDependencies) = postProject + {37749BB2-FA78-4EC9-8990-5628FC0BBA19} = {37749BB2-FA78-4EC9-8990-5628FC0BBA19} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -95,6 +100,14 @@ Global {CF35D78C-F710-41D2-968F-C46ACCFF6F07}.Release|x64.ActiveCfg = Release|x64 {CF35D78C-F710-41D2-968F-C46ACCFF6F07}.Release|x86.ActiveCfg = Release|Win32 {CF35D78C-F710-41D2-968F-C46ACCFF6F07}.Release|x86.Build.0 = Release|Win32 + {2A607369-8B5D-494A-9E40-C5DC8D821AA3}.Debug|x64.ActiveCfg = Debug|x64 + {2A607369-8B5D-494A-9E40-C5DC8D821AA3}.Debug|x64.Build.0 = Debug|x64 + {2A607369-8B5D-494A-9E40-C5DC8D821AA3}.Debug|x86.ActiveCfg = Debug|Win32 + {2A607369-8B5D-494A-9E40-C5DC8D821AA3}.Debug|x86.Build.0 = Debug|Win32 + {2A607369-8B5D-494A-9E40-C5DC8D821AA3}.Release|x64.ActiveCfg = Release|x64 + {2A607369-8B5D-494A-9E40-C5DC8D821AA3}.Release|x64.Build.0 = Release|x64 + {2A607369-8B5D-494A-9E40-C5DC8D821AA3}.Release|x86.ActiveCfg = Release|Win32 + {2A607369-8B5D-494A-9E40-C5DC8D821AA3}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/TestHelper/TestHelper.cpp b/TestHelper/TestHelper.cpp new file mode 100644 index 00000000..ec52b371 --- /dev/null +++ b/TestHelper/TestHelper.cpp @@ -0,0 +1,161 @@ +#if _WIN64 || __x86_64__ || __ppc64__ + #define ENVIRONMENT64 +#else + #define ENVIRONMENT32 +#endif + +#ifdef ENVIRONMENT32 + #ifdef _DEBUG + #define MESEN_LIBRARY_PATH "../bin/x86/Debug/" + #else + #define MESEN_LIBRARY_PATH "../bin/x86/Release/" + #endif +#else + #ifdef _DEBUG + #define MESEN_LIBRARY_PATH "../bin/x64/Debug/" + #else + #define MESEN_LIBRARY_PATH "../bin/x64/Release/" + #endif +#endif + +#pragma comment(lib, MESEN_LIBRARY_PATH"Utilities.lib") + +#include +#include +#include +#include +#include +#include +#include +#include "../Utilities/FolderUtilities.h" +#include "../Utilities/SimpleLock.h" +#include "../Utilities/Timer.h" +#include "../Core/MessageManager.h" + +typedef void (__stdcall *NotificationListenerCallback)(ConsoleNotificationType); + +class InteropNotificationListener : public INotificationListener +{ + NotificationListenerCallback _callback; +public: + InteropNotificationListener(NotificationListenerCallback callback) + { + _callback = callback; + } + + void ProcessNotification(ConsoleNotificationType type, void* parameter) + { + _callback((ConsoleNotificationType)type); + } +}; + +extern "C" { + void __stdcall InitializeEmu(char* homeFolder, void*, void*); + int __stdcall RomTestRun(char* filename); + void __stdcall LoadROM(char* filename); + void __stdcall Run(); + void __stdcall Stop(); + INotificationListener* __stdcall RegisterNotificationCallback(NotificationListenerCallback callback); +} + +std::thread *runThread = nullptr; +std::atomic testIndex; +vector testFilenames; +vector failedTests; +SimpleLock lock; +Timer timer; + +void OnNotificationReceived(ConsoleNotificationType type) +{ + if(type == ConsoleNotificationType::GameLoaded) { + runThread = new std::thread(Run); + } +} + +void RunEmu() +{ + Run(); +} + +void RunTest() +{ + while(true) { + lock.Acquire(); + int index = testIndex++; + lock.Release(); + + if(index < testFilenames.size()) { + string filepath = testFilenames[index]; + string filename = FolderUtilities::GetFilename(filepath, false); + string command = "TestHelper.exe /testrom \"" + filepath + "\""; + + lock.Acquire(); + std::cout << std::to_string(index) << ") " << filename << std::endl; + lock.Release(); + + if(std::system(command.c_str()) != 1) { + //Test failed + lock.Acquire(); + failedTests.push_back(filename); + std::cout << " **** " << std::to_string(index) << ") " << filename << " failed" << std::endl; + lock.Release(); + } + } else { + break; + } + } +} + +int main(int argc, char* argv[]) +{ + using namespace std; + if(argc <= 2) { + string testFolder; + if(argc == 1) { + wchar_t path[MAX_PATH]; + SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path); + testFolder = utf8::utf8::encode(path) + "\\Mesen\\Tests"; + } else { + testFolder = argv[1]; + } + + vector testThreads; + testFilenames = FolderUtilities::GetFilesInFolder(testFolder, "*.mtp", true); + testIndex = 0; + + timer.Reset(); + + for(int i = 0; i < 4; i++) { + std::thread *testThread = new std::thread(RunTest); + testThreads.push_back(testThread); + } + + for(int i = 0; i < 4; i++) { + testThreads[i]->join(); + delete testThreads[i]; + } + + std::cout << std::endl << std::endl; + std::cout << "------------" << std::endl; + std::cout << "Failed tests" << std::endl; + std::cout << "------------" << std::endl; + for(string failedTest : failedTests) { + std::cout << failedTest << std::endl; + } + std::cout << std::endl << std::endl << "Elapsed time: " << (timer.GetElapsedMS() / 1000) << " seconds"; + + std::getchar(); + } else if(argc == 3) { + char* testFilename = argv[2]; + RegisterNotificationCallback((NotificationListenerCallback)OnNotificationReceived); + InitializeEmu("C:\\Windows\\Temp\\Mesen", nullptr, nullptr); + int result = RomTestRun(testFilename); + if(runThread != nullptr) { + runThread->join(); + delete runThread; + } + return result; + } + return 0; +} + diff --git a/TestHelper/TestHelper.vcxproj b/TestHelper/TestHelper.vcxproj new file mode 100644 index 00000000..c9667d99 --- /dev/null +++ b/TestHelper/TestHelper.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {2A607369-8B5D-494A-9E40-C5DC8D821AA3} + Win32Proj + TestHelper + + + + Application + true + v120 + Unicode + + + Application + true + v120 + Unicode + + + Application + false + v120 + true + Unicode + + + Application + false + v120 + true + Unicode + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\ + obj\$(Platform)\$(Configuration)\ + + + obj\$(Platform)\$(Configuration)\ + true + $(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\ + + + false + $(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\ + obj\$(Platform)\$(Configuration)\ + + + obj\$(Platform)\$(Configuration)\ + false + $(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + + + Console + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + {37749bb2-fa78-4ec9-8990-5628fc0bba19} + false + true + false + true + true + + + + + + \ No newline at end of file diff --git a/TestHelper/TestHelper.vcxproj.filters b/TestHelper/TestHelper.vcxproj.filters new file mode 100644 index 00000000..d79f51e5 --- /dev/null +++ b/TestHelper/TestHelper.vcxproj.filters @@ -0,0 +1,14 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file