diff --git a/.github/workflows/test-results-linux.yml b/.github/workflows/test-results-linux.yml index 41ce59577..23a6b7a23 100644 --- a/.github/workflows/test-results-linux.yml +++ b/.github/workflows/test-results-linux.yml @@ -38,3 +38,4 @@ jobs: name: ${{matrix.config.name}} path: "**/My Projects/Torque3D/game/test_detail.xml" reporter: java-junit + output-to: 'checks' diff --git a/.github/workflows/test-results-mac.yml b/.github/workflows/test-results-mac.yml index 6e50b530c..867582e53 100644 --- a/.github/workflows/test-results-mac.yml +++ b/.github/workflows/test-results-mac.yml @@ -38,3 +38,4 @@ jobs: name: ${{matrix.config.name}} path: "**/My Projects/Torque3D/game/test_detail.xml" reporter: java-junit + output-to: 'checks' diff --git a/.github/workflows/test-results-windows.yml b/.github/workflows/test-results-windows.yml index 1e0052340..3bd32a0c9 100644 --- a/.github/workflows/test-results-windows.yml +++ b/.github/workflows/test-results-windows.yml @@ -38,3 +38,4 @@ jobs: name: ${{matrix.config.name}} path: "**/My Projects/Torque3D/game/test_detail.xml" reporter: java-junit + output-to: 'checks' diff --git a/Engine/source/platformPOSIX/POSIXFileio.cpp b/Engine/source/platformPOSIX/POSIXFileio.cpp index c9bfdd49c..6ba46adec 100644 --- a/Engine/source/platformPOSIX/POSIXFileio.cpp +++ b/Engine/source/platformPOSIX/POSIXFileio.cpp @@ -990,19 +990,42 @@ StringTableEntry Platform::getExecutablePath() //----------------------------------------------------------------------------- bool Platform::isFile(const char *pFilePath) { - if (!pFilePath || !*pFilePath) - return false; + if (!pFilePath || !*pFilePath) + return false; + + char pathName[MaxPath]; + + // if it starts with cwd, we need to strip that off so that we can look for + // the file in the pref dir + char cwd[MaxPath]; + getcwd(cwd, MaxPath); + + if (dStrstr(pFilePath, cwd) == pFilePath) + pFilePath = pFilePath + dStrlen(cwd) + 1; + + // if its relative, first look in the pref dir + if (pFilePath[0] != '/' && pFilePath[0] != '\\') + { + MungePath(pathName, MaxPath, pFilePath, GetPrefDir()); + } + else + { + // here if the path is absolute or not in the pref dir + MungePath(pathName, MaxPath, pFilePath, cwd); + } + // Get file info struct stat fStat; - if (stat(pFilePath, &fStat) < 0) - { - // Since file does not exist on disk see if it exists in a zip file loaded - return Torque::FS::IsFile(pFilePath); - } + if (stat(pathName, &fStat) == 0) + return true; + + if ((fStat.st_mode & S_IFMT) == S_IFREG) + return true; + + // Since stat failed see if it exists in a zip file loaded + if (Torque::FS::IsFile(pathName)) + return true; - // if the file is a "regular file" then true - if ( (fStat.st_mode & S_IFMT) == S_IFREG) - return true; // must be some other file (directory, device, etc.) return false; } @@ -1341,4 +1364,4 @@ void setExePathName(const char* exePathName) sBinName = binName; } } -#endif \ No newline at end of file +#endif diff --git a/Engine/source/platformSDL/threads/thread.cpp b/Engine/source/platformSDL/threads/thread.cpp index bef141c8a..ec3dbbd2f 100644 --- a/Engine/source/platformSDL/threads/thread.cpp +++ b/Engine/source/platformSDL/threads/thread.cpp @@ -23,6 +23,7 @@ #include "platform/threads/thread.h" #include "platform/threads/semaphore.h" #include "platform/threads/mutex.h" +#include "platform/platformIntrinsics.h" #include #include #include @@ -30,13 +31,23 @@ class PlatformThreadData { public: - ThreadRunFunction mRunFunc = NULL; - void* mRunArg = NULL; - Thread* mThread = NULL; - Semaphore mGateway; // default count is 1 - SDL_threadID mThreadID = 0; - SDL_Thread* mSdlThread = NULL; - bool mDead = true; + ThreadRunFunction mRunFunc; + void* mRunArg; + Thread* mThread; + Semaphore mGateway; + SDL_threadID mThreadID; + SDL_Thread* mSdlThread; + U32 mDead; + + PlatformThreadData() + { + mRunFunc = NULL; + mRunArg = 0; + mThread = 0; + mThreadID = 0; + mSdlThread = NULL; + mDead = false; + } }; ThreadManager::MainThreadId ThreadManager::smMainThreadId; @@ -50,22 +61,19 @@ ThreadManager::MainThreadId ThreadManager::smMainThreadId; static int ThreadRunHandler(void * arg) { PlatformThreadData *mData = reinterpret_cast(arg); - Thread *thread = mData->mThread; - mData->mThreadID = SDL_ThreadID(); - ThreadManager::addThread(thread); - thread->run(mData->mRunArg); - ThreadManager::removeThread(thread); + ThreadManager::addThread(mData->mThread); + mData->mThread->run(mData->mRunArg); + ThreadManager::removeThread(mData->mThread); - bool autoDelete = thread->autoDelete; + bool autoDelete = mData->mThread->autoDelete; - mData->mThreadID = 0; - mData->mDead = true; + dCompareAndSwap(mData->mDead, false, true); mData->mGateway.release(); if( autoDelete ) - delete thread; + delete mData->mThread; return 0; } diff --git a/Engine/source/testing/unitTesting.cpp b/Engine/source/testing/unitTesting.cpp index f14647785..b69edb138 100644 --- a/Engine/source/testing/unitTesting.cpp +++ b/Engine/source/testing/unitTesting.cpp @@ -26,6 +26,7 @@ #include "console/codeBlock.h" #include "console/engineAPI.h" #include "console/consoleInternal.h" +#include "gfx/gfxInit.h" #if defined(TORQUE_OS_WIN) #define _CRTDBG_MAP_ALLOC @@ -145,42 +146,38 @@ private: const char* mFunctionName; }; -// uncomment to debug tests and use the test explorer. -//#define TEST_EXPLORER -#if !defined(TEST_EXPLORER) int main(int argc, char** argv) { - StandardMainLoop::init(); - StandardMainLoop::handleCommandLine(argc, (const char**)argv); - StandardMainLoop::shutdown(); - return StandardMainLoop::getReturnStatus(); -} -#else -int main(int argc, char** argv) -{ - StandardMainLoop::init(); + testing::GTEST_FLAG(output) = "xml:test_detail.xml"; + testing::GTEST_FLAG(stack_trace_depth) = 10; + printf("Running main() from %s\n", __FILE__); - // setup simular to runTests - Con::evaluate("GFXInit::createNullDevice();"); - Con::evaluate("if (!isObject(GuiDefaultProfile)) new GuiControlProfile(GuiDefaultProfile){}; if (!isObject(GuiTooltipProfile)) new GuiControlProfile(GuiTooltipProfile){};"); + // Initialize Google Test. testing::InitGoogleTest(&argc, argv); - // Fetch the unit test instance. - testing::UnitTest& unitTest = *testing::UnitTest::GetInstance(); - // Fetch the unit test event listeners. - testing::TestEventListeners& listeners = unitTest.listeners(); + // torques handle command. + StandardMainLoop::init(); + // setup torque for testing. + GFXInit::enumerateAdapters(); + GFXAdapter* a = GFXInit::chooseAdapter(NullDevice, ""); + GFXDevice* newDevice = GFX; + if (newDevice == NULL) + newDevice = GFXInit::createDevice(a); + newDevice->setAllowRender(false); - listeners.Append(new MemoryLeakDetector()); + // required for tests that add gui elements. + Con::evaluate("if (!isObject(GuiDefaultProfile)) new GuiControlProfile(GuiDefaultProfile){}; if (!isObject(GuiTooltipProfile)) new GuiControlProfile(GuiTooltipProfile){};"); - // Add the Torque unit test listener. - listeners.Append(new TorqueUnitTestListener(true)); + // this call is to add the tests that exist in runTests.tscript + // note these tests will not appear in the test explorer. + if(argc > 1) + StandardMainLoop::handleCommandLine(argc, (const char**)argv); + // run tests. int res = RUN_ALL_TESTS(); - StandardMainLoop::shutdown(); - return res; + return 0; } -#endif DefineEngineFunction(addUnitTest, void, (const char* function), , "Add a TorqueScript function as a GTest unit test.\n" @@ -227,58 +224,3 @@ DefineEngineFunction(expectTrue, void, (bool test, const char* message), (""), { EXPECT_TRUE(test) << scriptFileMessage(message).c_str(); } - -DefineEngineFunction(runAllUnitTests, int, (const char* testSpecs, const char* reportFormat), (""), - "Runs engine unit tests. Some tests are marked as 'stress' tests which do not " - "necessarily check correctness, just performance or possible nondeterministic " - "glitches. There may also be interactive or networking tests which may be " - "excluded by using the testSpecs argument.\n" - "This function should only be called once per executable run, because of " - "googletest's design.\n\n" - - "@param testSpecs A space-sepatated list of filters for test cases. " - "See https://code.google.com/p/googletest/wiki/AdvancedGuide#Running_a_Subset_of_the_Tests " - "and http://stackoverflow.com/a/14021997/945863 " - "for a description of the flag format.") -{ - Vector args; - args.push_back(NULL); // Program name is unused by googletest. - String specsArg; - if (dStrlen(testSpecs) > 0) - { - specsArg = testSpecs; - specsArg.replace(' ', ':'); - specsArg.insert(0, "--gtest_filter="); - args.push_back(const_cast(specsArg.c_str())); - } - - String reportFormatArg; - if (dStrlen(reportFormat) > 0) - { - reportFormatArg = String::ToString("--gtest_output=%s", reportFormat); - args.push_back(const_cast(reportFormatArg.c_str())); - } - S32 argc = args.size(); - - // Initialize Google Test. - testing::InitGoogleTest(&argc, args.address()); - - // Fetch the unit test instance. - testing::UnitTest& unitTest = *testing::UnitTest::GetInstance(); - - // Fetch the unit test event listeners. - testing::TestEventListeners& listeners = unitTest.listeners(); - - // Release the default listener. - delete listeners.Release(listeners.default_result_printer()); - - // Add the Torque unit test listener. - listeners.Append(new TorqueUnitTestListener(false)); - - // Perform googletest run. - Con::printf("\nUnit Tests Starting...\n"); - const S32 result = RUN_ALL_TESTS(); - Con::printf("... Unit Tests Ended.\n"); - - return result; -} diff --git a/Templates/BaseGame/game/runTests.tscript b/Templates/BaseGame/game/runTests.tscript index 25b53dd99..f22a98f77 100644 --- a/Templates/BaseGame/game/runTests.tscript +++ b/Templates/BaseGame/game/runTests.tscript @@ -1,13 +1,6 @@ -// Placeholder initialisation that the tests expect -GFXInit::createNullDevice(); +// put script tests here -if(!isObject(GuiDefaultProfile)) - new GuiControlProfile (GuiDefaultProfile) {}; -if(!isObject(GuiTooltipProfile)) - new GuiControlProfile (GuiTooltipProfile) {}; - -setLogMode(2); -$Con::LogBufferEnabled = false; -$Testing::CheckMemoryLeaks = false; -runAllUnitTests("-*.Stress*", "xml"); -quit(); +function MyTest() { + expectTrue(2+2 == 4, "basic math should work"); +} +addUnitTest(MyTest); \ No newline at end of file