Commit f0d9471c by Jamie Madill Committed by Commit Bot

Test Runner: More misc improvements.

- reduces default batch size from 1000 -> 256 - reduces default max processes to a max of 16 - stripes tests when in bot mode - prints less spam when waiting for child processes The striping and smaller batch size can help with slow tests. The max process limit seemed to prevent errors on Linux. Bug: angleproject:3162 Change-Id: Ibed89ca35db54c62ec8ed63b32bc5aed916faec9 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2447037 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent e44c94d9
...@@ -50,7 +50,9 @@ constexpr int kDefaultBatchTimeout = 240; ...@@ -50,7 +50,9 @@ constexpr int kDefaultBatchTimeout = 240;
#else #else
constexpr int kDefaultBatchTimeout = 600; constexpr int kDefaultBatchTimeout = 600;
#endif #endif
constexpr int kDefaultBatchSize = 1000; constexpr int kDefaultBatchSize = 256;
constexpr double kIdleMessageTimeout = 10.0;
constexpr int kDefaultMaxProcesses = 16;
const char *ParseFlagValue(const char *flag, const char *argument) const char *ParseFlagValue(const char *flag, const char *argument)
{ {
...@@ -76,13 +78,13 @@ bool ParseIntArg(const char *flag, const char *argument, int *valueOut) ...@@ -76,13 +78,13 @@ bool ParseIntArg(const char *flag, const char *argument, int *valueOut)
if (*end != '\0') if (*end != '\0')
{ {
printf("Error parsing integer flag value.\n"); printf("Error parsing integer flag value.\n");
exit(1); exit(EXIT_FAILURE);
} }
if (longValue == LONG_MAX || longValue == LONG_MIN || static_cast<int>(longValue) != longValue) if (longValue == LONG_MAX || longValue == LONG_MIN || static_cast<int>(longValue) != longValue)
{ {
printf("Overflow when parsing integer flag value.\n"); printf("Overflow when parsing integer flag value.\n");
exit(1); exit(EXIT_FAILURE);
} }
*valueOut = static_cast<int>(longValue); *valueOut = static_cast<int>(longValue);
...@@ -682,20 +684,21 @@ TestQueue BatchTests(const std::vector<TestIdentifier> &tests, int batchSize) ...@@ -682,20 +684,21 @@ TestQueue BatchTests(const std::vector<TestIdentifier> &tests, int batchSize)
for (const auto &configAndIds : testsSortedByConfig) for (const auto &configAndIds : testsSortedByConfig)
{ {
const std::vector<TestIdentifier> &configTests = configAndIds.second; const std::vector<TestIdentifier> &configTests = configAndIds.second;
std::vector<TestIdentifier> batchTests;
for (const TestIdentifier &id : configTests) // Count the number of batches needed for this config.
int batchesForConfig = static_cast<int>(configTests.size() + batchSize - 1) / batchSize;
// Create batches with striping to split up slow tests.
for (int batchIndex = 0; batchIndex < batchesForConfig; ++batchIndex)
{ {
if (batchTests.size() >= static_cast<size_t>(batchSize)) std::vector<TestIdentifier> batchTests;
for (size_t testIndex = batchIndex; testIndex < configTests.size();
testIndex += batchesForConfig)
{ {
testQueue.emplace(std::move(batchTests)); batchTests.push_back(configTests[testIndex]);
ASSERT(batchTests.empty());
} }
batchTests.push_back(id);
}
if (!batchTests.empty())
{
testQueue.emplace(std::move(batchTests)); testQueue.emplace(std::move(batchTests));
ASSERT(batchTests.empty());
} }
} }
...@@ -765,7 +768,7 @@ TestSuite::TestSuite(int *argc, char **argv) ...@@ -765,7 +768,7 @@ TestSuite::TestSuite(int *argc, char **argv)
mBatchSize(kDefaultBatchSize), mBatchSize(kDefaultBatchSize),
mCurrentResultCount(0), mCurrentResultCount(0),
mTotalResultCount(0), mTotalResultCount(0),
mMaxProcesses(NumberOfProcessors()), mMaxProcesses(std::min(NumberOfProcessors(), kDefaultMaxProcesses)),
mTestTimeout(kDefaultTestTimeout), mTestTimeout(kDefaultTestTimeout),
mBatchTimeout(kDefaultBatchTimeout) mBatchTimeout(kDefaultBatchTimeout)
{ {
...@@ -783,7 +786,7 @@ TestSuite::TestSuite(int *argc, char **argv) ...@@ -783,7 +786,7 @@ TestSuite::TestSuite(int *argc, char **argv)
if (*argc <= 0) if (*argc <= 0)
{ {
printf("Missing test arguments.\n"); printf("Missing test arguments.\n");
exit(1); exit(EXIT_FAILURE);
} }
mTestExecutableName = argv[0]; mTestExecutableName = argv[0];
...@@ -817,7 +820,7 @@ TestSuite::TestSuite(int *argc, char **argv) ...@@ -817,7 +820,7 @@ TestSuite::TestSuite(int *argc, char **argv)
if ((mShardIndex == -1) != (mShardCount == -1)) if ((mShardIndex == -1) != (mShardCount == -1))
{ {
printf("Shard index and shard count must be specified together.\n"); printf("Shard index and shard count must be specified together.\n");
exit(1); exit(EXIT_FAILURE);
} }
if (!mFilterFile.empty()) if (!mFilterFile.empty())
...@@ -825,28 +828,28 @@ TestSuite::TestSuite(int *argc, char **argv) ...@@ -825,28 +828,28 @@ TestSuite::TestSuite(int *argc, char **argv)
if (filterArgIndex.valid()) if (filterArgIndex.valid())
{ {
printf("Cannot use gtest_filter in conjunction with a filter file.\n"); printf("Cannot use gtest_filter in conjunction with a filter file.\n");
exit(1); exit(EXIT_FAILURE);
} }
uint32_t fileSize = 0; uint32_t fileSize = 0;
if (!GetFileSize(mFilterFile.c_str(), &fileSize)) if (!GetFileSize(mFilterFile.c_str(), &fileSize))
{ {
printf("Error getting filter file size: %s\n", mFilterFile.c_str()); printf("Error getting filter file size: %s\n", mFilterFile.c_str());
exit(1); exit(EXIT_FAILURE);
} }
std::vector<char> fileContents(fileSize + 1, 0); std::vector<char> fileContents(fileSize + 1, 0);
if (!ReadEntireFileToString(mFilterFile.c_str(), fileContents.data(), fileSize)) if (!ReadEntireFileToString(mFilterFile.c_str(), fileContents.data(), fileSize))
{ {
printf("Error loading filter file: %s\n", mFilterFile.c_str()); printf("Error loading filter file: %s\n", mFilterFile.c_str());
exit(1); exit(EXIT_FAILURE);
} }
mFilterString.assign(fileContents.data()); mFilterString.assign(fileContents.data());
if (mFilterString.substr(0, strlen("--gtest_filter=")) != std::string("--gtest_filter=")) if (mFilterString.substr(0, strlen("--gtest_filter=")) != std::string("--gtest_filter="))
{ {
printf("Filter file must start with \"--gtest_filter=\".\n"); printf("Filter file must start with \"--gtest_filter=\".\n");
exit(1); exit(EXIT_FAILURE);
} }
// Note that we only add a filter string if we previously deleted a shader filter file // Note that we only add a filter string if we previously deleted a shader filter file
...@@ -866,14 +869,14 @@ TestSuite::TestSuite(int *argc, char **argv) ...@@ -866,14 +869,14 @@ TestSuite::TestSuite(int *argc, char **argv)
if (mShardCount == 0) if (mShardCount == 0)
{ {
printf("Shard count must be > 0.\n"); printf("Shard count must be > 0.\n");
exit(1); exit(EXIT_FAILURE);
} }
else if (mShardCount > 0) else if (mShardCount > 0)
{ {
if (mShardIndex >= mShardCount) if (mShardIndex >= mShardCount)
{ {
printf("Shard index must be less than shard count.\n"); printf("Shard index must be less than shard count.\n");
exit(1); exit(EXIT_FAILURE);
} }
if (!angle::GetEnvironmentVar("GTEST_SHARD_INDEX").empty() || if (!angle::GetEnvironmentVar("GTEST_SHARD_INDEX").empty() ||
...@@ -882,7 +885,7 @@ TestSuite::TestSuite(int *argc, char **argv) ...@@ -882,7 +885,7 @@ TestSuite::TestSuite(int *argc, char **argv)
printf( printf(
"Error: --shard-index and --shard-count are incompatible with GTEST_SHARD_INDEX " "Error: --shard-index and --shard-count are incompatible with GTEST_SHARD_INDEX "
"and GTEST_TOTAL_SHARDS.\n"); "and GTEST_TOTAL_SHARDS.\n");
exit(1); exit(EXIT_FAILURE);
} }
testSet = testSet =
...@@ -925,7 +928,7 @@ TestSuite::TestSuite(int *argc, char **argv) ...@@ -925,7 +928,7 @@ TestSuite::TestSuite(int *argc, char **argv)
mTestQueue.pop(); mTestQueue.pop();
} }
exit(0); exit(EXIT_SUCCESS);
} }
} }
...@@ -1201,8 +1204,6 @@ int TestSuite::run() ...@@ -1201,8 +1204,6 @@ int TestSuite::run()
Timer totalRunTime; Timer totalRunTime;
totalRunTime.start(); totalRunTime.start();
constexpr double kIdleMessageTimeout = 5.0;
Timer messageTimer; Timer messageTimer;
messageTimer.start(); messageTimer.start();
...@@ -1225,6 +1226,7 @@ int TestSuite::run() ...@@ -1225,6 +1226,7 @@ int TestSuite::run()
} }
// Check for process completion. // Check for process completion.
uint32_t totalTestCount = 0;
for (auto processIter = mCurrentProcesses.begin(); processIter != mCurrentProcesses.end();) for (auto processIter = mCurrentProcesses.begin(); processIter != mCurrentProcesses.end();)
{ {
ProcessInfo &processInfo = *processIter; ProcessInfo &processInfo = *processIter;
...@@ -1257,22 +1259,17 @@ int TestSuite::run() ...@@ -1257,22 +1259,17 @@ int TestSuite::run()
} }
else else
{ {
totalTestCount += static_cast<uint32_t>(processInfo.testsInBatch.size());
processIter++; processIter++;
} }
} }
if (!progress && messageTimer.getElapsedTime() > kIdleMessageTimeout) if (!progress && messageTimer.getElapsedTime() > kIdleMessageTimeout)
{ {
for (const ProcessInfo &processInfo : mCurrentProcesses) const ProcessInfo &processInfo = mCurrentProcesses[0];
{ double processTime = processInfo.process->getElapsedTimeSeconds();
double processTime = processInfo.process->getElapsedTimeSeconds(); printf("Running %d tests in %d processes, longest for %d seconds.\n", totalTestCount,
if (processTime > kIdleMessageTimeout) static_cast<int>(mCurrentProcesses.size()), static_cast<int>(processTime));
{
printf("Running for %d seconds: %s\n", static_cast<int>(processTime),
processInfo.commandLine.c_str());
}
}
messageTimer.start(); messageTimer.start();
} }
...@@ -1341,7 +1338,7 @@ void TestSuite::startWatchdog() ...@@ -1341,7 +1338,7 @@ void TestSuite::startWatchdog()
angle::Sleep(500); angle::Sleep(500);
} while (true); } while (true);
onCrashOrTimeout(TestResultType::Timeout); onCrashOrTimeout(TestResultType::Timeout);
::_Exit(1); ::_Exit(EXIT_FAILURE);
}; };
mWatchdogThread = std::thread(watchdogMain); mWatchdogThread = std::thread(watchdogMain);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment