Commit 573d7f34 by Jamie Madill Committed by Commit Bot

Test Runner: Pick single/multi-process mode automatically.

This enables multi-process when running with more than one test config. This saves developers from remembering to add the arg. It can also simplify our test configurations by allowing us to omit the default arguments. On Android by default we stay with single process. It also changes the --bot-mode flag into --single-process and --multi-process which override the default behaviour. Bug: angleproject:5585 Change-Id: I3dd885a8a8e6604c224693c546ff5d15224e016e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2664246Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent ffb36559
...@@ -121,6 +121,17 @@ bool ParseFlag(const char *expected, const char *actual, bool *flagOut) ...@@ -121,6 +121,17 @@ bool ParseFlag(const char *expected, const char *actual, bool *flagOut)
return false; return false;
} }
template <typename SetterFuncT>
bool ParseFlagCustom(const char *expected, const char *actual, SetterFuncT setterFunc)
{
if (strcmp(expected, actual) == 0)
{
setterFunc();
return true;
}
return false;
}
bool ParseStringArg(const char *flag, const char *argument, std::string *valueOut) bool ParseStringArg(const char *flag, const char *argument, std::string *valueOut)
{ {
const char *value = ParseFlagValue(flag, argument); const char *value = ParseFlagValue(flag, argument);
...@@ -967,6 +978,44 @@ void GTestListTests(const std::map<TestIdentifier, TestResult> &resultsMap) ...@@ -967,6 +978,44 @@ void GTestListTests(const std::map<TestIdentifier, TestResult> &resultsMap)
} }
} }
} }
ANGLE_MAYBE_UNUSED std::set<std::string> GetUniqueTestConfigs(
const std::vector<TestIdentifier> &testIdentifiers)
{
std::set<std::string> uniqueConfigNames;
for (const TestIdentifier &id : testIdentifiers)
{
std::string config = GetConfigNameFromTestIdentifier(id);
uniqueConfigNames.insert(config);
}
return uniqueConfigNames;
}
TestSuiteRunMode DetermineTestSuiteRunMode(const std::vector<TestIdentifier> &testSet, int batchId)
{
#if defined(ANGLE_PLATFORM_ANDROID)
// TODO: Run single config per process on Android. http://anglebug.com/5600
return TestSuiteRunMode::SingleProcess;
#else
// Run single-process if in a child batch.
if (batchId != -1)
{
return TestSuiteRunMode::SingleProcess;
}
// If more than one config, enable multi-process by default.
// Also use multi-process if we only have the single default config.
std::set<std::string> testConfigs = GetUniqueTestConfigs(testSet);
if ((testConfigs.size() == 1) && (*testConfigs.begin() != "default"))
{
return TestSuiteRunMode::SingleProcess;
}
else
{
return TestSuiteRunMode::MultiProcess;
}
#endif // defined(ANGLE_PLATFORM_ANDROID)
}
} // namespace } // namespace
// static // static
...@@ -1030,7 +1079,7 @@ ProcessInfo::ProcessInfo(ProcessInfo &&other) ...@@ -1030,7 +1079,7 @@ ProcessInfo::ProcessInfo(ProcessInfo &&other)
TestSuite::TestSuite(int *argc, char **argv) TestSuite::TestSuite(int *argc, char **argv)
: mShardCount(-1), : mShardCount(-1),
mShardIndex(-1), mShardIndex(-1),
mBotMode(false), mRunMode(TestSuiteRunMode::Unspecified),
mDebugTestGroups(false), mDebugTestGroups(false),
mGTestListTests(false), mGTestListTests(false),
mListTests(false), mListTests(false),
...@@ -1173,6 +1222,12 @@ TestSuite::TestSuite(int *argc, char **argv) ...@@ -1173,6 +1222,12 @@ TestSuite::TestSuite(int *argc, char **argv)
std::vector<TestIdentifier> testSet = GetFilteredTests(&mTestFileLines, alsoRunDisabledTests); std::vector<TestIdentifier> testSet = GetFilteredTests(&mTestFileLines, alsoRunDisabledTests);
if (mRunMode == TestSuiteRunMode::Unspecified)
{
mRunMode = DetermineTestSuiteRunMode(testSet, mBatchId);
ASSERT(mRunMode != TestSuiteRunMode::Unspecified);
}
if (mShardCount == 0) if (mShardCount == 0)
{ {
printf("Shard count must be > 0.\n"); printf("Shard count must be > 0.\n");
...@@ -1192,7 +1247,7 @@ TestSuite::TestSuite(int *argc, char **argv) ...@@ -1192,7 +1247,7 @@ TestSuite::TestSuite(int *argc, char **argv)
testSet = GetShardTests(testSet, mShardIndex, mShardCount, &mTestFileLines, testSet = GetShardTests(testSet, mShardIndex, mShardCount, &mTestFileLines,
alsoRunDisabledTests); alsoRunDisabledTests);
if (!mBotMode) if (mRunMode == TestSuiteRunMode::SingleProcess)
{ {
mFilterString = GetTestFilter(testSet); mFilterString = GetTestFilter(testSet);
...@@ -1224,7 +1279,7 @@ TestSuite::TestSuite(int *argc, char **argv) ...@@ -1224,7 +1279,7 @@ TestSuite::TestSuite(int *argc, char **argv)
mTestResults.testArtifactsFakeTestName = fakeTestName.str(); mTestResults.testArtifactsFakeTestName = fakeTestName.str();
} }
if (mBotMode) if (mRunMode == TestSuiteRunMode::MultiProcess)
{ {
// Split up test batches. // Split up test batches.
mTestQueue = BatchTests(testSet, mBatchSize); mTestQueue = BatchTests(testSet, mBatchSize);
...@@ -1249,7 +1304,8 @@ TestSuite::TestSuite(int *argc, char **argv) ...@@ -1249,7 +1304,8 @@ TestSuite::TestSuite(int *argc, char **argv)
mTotalResultCount = testSet.size(); mTotalResultCount = testSet.size();
if ((mBotMode || !mResultsDirectory.empty()) && mResultsFile.empty()) if ((mRunMode == TestSuiteRunMode::MultiProcess || !mResultsDirectory.empty()) &&
mResultsFile.empty())
{ {
// Create a default output file in bot mode. // Create a default output file in bot mode.
mResultsFile = "output.json"; mResultsFile = "output.json";
...@@ -1262,7 +1318,7 @@ TestSuite::TestSuite(int *argc, char **argv) ...@@ -1262,7 +1318,7 @@ TestSuite::TestSuite(int *argc, char **argv)
mResultsFile = resultFileName.str(); mResultsFile = resultFileName.str();
} }
if (!mBotMode) if (mRunMode == TestSuiteRunMode::SingleProcess)
{ {
testing::TestEventListeners &listeners = testing::UnitTest::GetInstance()->listeners(); testing::TestEventListeners &listeners = testing::UnitTest::GetInstance()->listeners();
listeners.Append(new TestEventListener( listeners.Append(new TestEventListener(
...@@ -1304,7 +1360,10 @@ bool TestSuite::parseSingleArg(const char *argument) ...@@ -1304,7 +1360,10 @@ bool TestSuite::parseSingleArg(const char *argument)
ParseStringArg(kHistogramJsonFileArg, argument, &mHistogramJsonFile) || ParseStringArg(kHistogramJsonFileArg, argument, &mHistogramJsonFile) ||
ParseStringArg("--isolated-script-test-perf-output=", argument, &mHistogramJsonFile) || ParseStringArg("--isolated-script-test-perf-output=", argument, &mHistogramJsonFile) ||
ParseStringArg(kIsolatedOutDir, argument, &mTestArtifactDirectory) || ParseStringArg(kIsolatedOutDir, argument, &mTestArtifactDirectory) ||
ParseFlag("--bot-mode", argument, &mBotMode) || ParseFlagCustom("--single-process", argument,
[this]() { this->mRunMode = TestSuiteRunMode::SingleProcess; }) ||
ParseFlagCustom("--multi-process", argument,
[this]() { this->mRunMode = TestSuiteRunMode::MultiProcess; }) ||
ParseFlag("--debug-test-groups", argument, &mDebugTestGroups) || ParseFlag("--debug-test-groups", argument, &mDebugTestGroups) ||
ParseFlag(kGTestListTests, argument, &mGTestListTests) || ParseFlag(kGTestListTests, argument, &mGTestListTests) ||
ParseFlag(kListTests, argument, &mListTests) || ParseFlag(kListTests, argument, &mListTests) ||
...@@ -1605,7 +1664,7 @@ int TestSuite::run() ...@@ -1605,7 +1664,7 @@ int TestSuite::run()
} }
// Run tests serially. // Run tests serially.
if (!mBotMode) if (mRunMode == TestSuiteRunMode::SingleProcess)
{ {
// Only start the watchdog if the debugger is not attached and we're a child process. // Only start the watchdog if the debugger is not attached and we're a child process.
if (!angle::IsDebuggerAttached() && mBatchId != -1) if (!angle::IsDebuggerAttached() && mBatchId != -1)
......
...@@ -119,6 +119,13 @@ struct ProcessInfo : angle::NonCopyable ...@@ -119,6 +119,13 @@ struct ProcessInfo : angle::NonCopyable
std::string filterString; std::string filterString;
}; };
enum class TestSuiteRunMode
{
Unspecified,
SingleProcess,
MultiProcess,
};
using TestQueue = std::queue<std::vector<TestIdentifier>>; using TestQueue = std::queue<std::vector<TestIdentifier>>;
class TestSuite class TestSuite
...@@ -164,7 +171,7 @@ class TestSuite ...@@ -164,7 +171,7 @@ class TestSuite
int mShardIndex; int mShardIndex;
angle::CrashCallback mCrashCallback; angle::CrashCallback mCrashCallback;
TestResults mTestResults; TestResults mTestResults;
bool mBotMode; TestSuiteRunMode mRunMode;
bool mDebugTestGroups; bool mDebugTestGroups;
bool mGTestListTests; bool mGTestListTests;
bool mListTests; bool mListTests;
......
...@@ -63,9 +63,9 @@ class TestSuiteTest : public testing::Test ...@@ -63,9 +63,9 @@ class TestSuiteTest : public testing::Test
std::string resultsFileName = "--results-file=" + mTempFileName; std::string resultsFileName = "--results-file=" + mTempFileName;
std::vector<const char *> args = { std::vector<const char *> args = {executablePath.c_str(), kRunTestSuite,
executablePath.c_str(), kRunTestSuite, "--gtest_also_run_disabled_tests", "--gtest_also_run_disabled_tests", "--test-timeout=5",
"--bot-mode", "--test-timeout=5", resultsFileName.c_str()}; resultsFileName.c_str()};
for (const std::string &arg : extraArgs) for (const std::string &arg : extraArgs)
{ {
......
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