瀏覽代碼

Merge pull request #1068 from marauder2k9-torque/UnitTestingTestExplorer

Fix failing unit tests
Brian Roberts 2 年之前
父節點
當前提交
27cc4912b4

+ 1 - 0
.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'

+ 1 - 0
.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'

+ 1 - 0
.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'

+ 34 - 11
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
+#endif

+ 24 - 16
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 <stdlib.h>
 #include <SDL.h>
 #include <SDL_thread.h>
@@ -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<PlatformThreadData*>(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;
 }

+ 23 - 81
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();
-
-   listeners.Append(new MemoryLeakDetector());
+   // 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);
+
+   // 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<char*> 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<char*>(specsArg.c_str()));
-   }
-
-   String reportFormatArg;
-   if (dStrlen(reportFormat) > 0)
-   {
-      reportFormatArg = String::ToString("--gtest_output=%s", reportFormat);
-      args.push_back(const_cast<char*>(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;
-}

+ 5 - 12
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);