Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 1fd3e5d

Browse files
null77Commit Bot
authored andcommitted
Test Runner: Fix race in watchdog timeouts.
This fixes a TSAN warning that popped up with the standalone test runner. The watchdog timer actually was never started so timeouts were not working as intended. It also switches the timeout mode to call _Exit which skips all the atexit handlers and avoids some races on teardown. This change also speeds up the TestSuiteTest. Also a small fix to GetTempDir that was including an extra path separator on Windows. Bug: angleproject:3162 Bug: angleproject:5117 Change-Id: I0e7880a08b61bbb6e30c65665d5c0acec2d78db2 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2442381 Reviewed-by: Yuly Novikov <[email protected]> Commit-Queue: Jamie Madill <[email protected]>
1 parent 01641c7 commit 1fd3e5d

File tree

3 files changed

+26
-15
lines changed

3 files changed

+26
-15
lines changed

src/tests/test_utils/runner/TestSuite.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
#include "common/system_utils.h"
1515
#include "util/Timer.h"
1616

17+
#include <stdlib.h>
1718
#include <time.h>
19+
1820
#include <fstream>
1921
#include <unordered_map>
2022

@@ -944,7 +946,7 @@ TestSuite::TestSuite(int *argc, char **argv)
944946
mResultsFile = resultFileName.str();
945947
}
946948

947-
if (!mResultsFile.empty() || !mHistogramJsonFile.empty())
949+
if (!mBotMode)
948950
{
949951
testing::TestEventListeners &listeners = testing::UnitTest::GetInstance()->listeners();
950952
listeners.Append(new TestEventListener(mResultsFile, mHistogramJsonFile,
@@ -987,6 +989,7 @@ bool TestSuite::parseSingleArg(const char *argument)
987989

988990
void TestSuite::onCrashOrTimeout(TestResultType crashOrTimeout)
989991
{
992+
std::lock_guard<std::mutex> guard(mTestResults.currentTestMutex);
990993
if (mTestResults.currentTest.valid())
991994
{
992995
TestResult &result = mTestResults.results[mTestResults.currentTest];
@@ -1191,12 +1194,7 @@ int TestSuite::run()
11911194
mTestResults.allDone = true;
11921195
}
11931196

1194-
for (int tries = 0; tries < 10; ++tries)
1195-
{
1196-
if (!mWatchdogThread.joinable())
1197-
break;
1198-
angle::Sleep(100);
1199-
}
1197+
mWatchdogThread.join();
12001198
return retVal;
12011199
}
12021200

@@ -1333,16 +1331,17 @@ void TestSuite::startWatchdog()
13331331
if (mTestResults.currentTestTimer.getElapsedTime() >
13341332
static_cast<double>(mTestTimeout))
13351333
{
1336-
onCrashOrTimeout(TestResultType::Timeout);
1337-
exit(2);
1334+
break;
13381335
}
13391336

13401337
if (mTestResults.allDone)
13411338
return;
13421339
}
13431340

1344-
angle::Sleep(1000);
1341+
angle::Sleep(500);
13451342
} while (true);
1343+
onCrashOrTimeout(TestResultType::Timeout);
1344+
::_Exit(1);
13461345
};
13471346
mWatchdogThread = std::thread(watchdogMain);
13481347
}

src/tests/test_utils/runner/TestSuite_unittest.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ TEST_F(TestSuiteTest, RunMockTests)
4848
executablePath += std::string("/") + kTestHelperExecutable + GetExecutableExtension();
4949

5050
constexpr uint32_t kMaxTempDirLen = 100;
51-
char tempFileName[kMaxTempDirLen * 2];
52-
ASSERT_TRUE(GetTempDir(tempFileName, kMaxTempDirLen));
51+
char tempDirName[kMaxTempDirLen * 2];
52+
ASSERT_TRUE(GetTempDir(tempDirName, kMaxTempDirLen));
5353

5454
std::stringstream tempFNameStream;
55-
tempFNameStream << tempFileName << "/test_temp_" << rand() << ".json";
55+
tempFNameStream << tempDirName << GetPathSeparator() << "test_temp_" << rand() << ".json";
5656
mTempFileName = tempFNameStream.str();
5757

5858
std::string resultsFileName = "--results-file=" + mTempFileName;
@@ -62,7 +62,7 @@ TEST_F(TestSuiteTest, RunMockTests)
6262
"--gtest_filter=MockTestSuiteTest.DISABLED_*",
6363
"--gtest_also_run_disabled_tests",
6464
"--bot-mode",
65-
"--test-timeout=10",
65+
"--test-timeout=2",
6666
resultsFileName.c_str()};
6767

6868
ProcessHandle process(args, true, true);
@@ -71,6 +71,9 @@ TEST_F(TestSuiteTest, RunMockTests)
7171
EXPECT_TRUE(process->finished());
7272
EXPECT_EQ(process->getStderr(), "");
7373

74+
// Uncomment this for debugging.
75+
// printf("stdout:\n%s\n", process->getStdout().c_str());
76+
7477
TestResults actual;
7578
ASSERT_TRUE(GetTestResultsFromFile(mTempFileName.c_str(), &actual));
7679
EXPECT_TRUE(DeleteFile(mTempFileName.c_str()));
@@ -101,7 +104,7 @@ TEST(MockTestSuiteTest, DISABLED_Fail)
101104
// Trigger a test timeout.
102105
TEST(MockTestSuiteTest, DISABLED_Timeout)
103106
{
104-
angle::Sleep(30000);
107+
angle::Sleep(5000);
105108
}
106109

107110
// Trigger a test crash.

util/windows/test_utils_win.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,15 @@ Process *LaunchProcess(const std::vector<const char *> &args,
403403
bool GetTempDir(char *tempDirOut, uint32_t maxDirNameLen)
404404
{
405405
DWORD pathLen = ::GetTempPathA(maxDirNameLen, tempDirOut);
406+
// Strip last path character if present.
407+
if (pathLen > 0)
408+
{
409+
size_t lastChar = strlen(tempDirOut) - 1;
410+
if (tempDirOut[lastChar] == '\\')
411+
{
412+
tempDirOut[lastChar] = 0;
413+
}
414+
}
406415
return (pathLen < MAX_PATH && pathLen > 0);
407416
}
408417

0 commit comments

Comments
 (0)