Commit 9a219a14 by Jamie Madill Committed by Commit Bot

Test Runner: Handle skipped gtests.

GTEST_SKIP() allows us to skip tests using the GoogleTest APIs. This CL updates our test runner code to handle these skips. Bug: angleproject:5951 Change-Id: Idef5802c7c81bd92226f5a93281a1cea0f1b24ee Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2892272Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 1d1c4518
...@@ -51,6 +51,7 @@ constexpr char kIsolatedOutDir[] = "--isolated-outdir="; ...@@ -51,6 +51,7 @@ constexpr char kIsolatedOutDir[] = "--isolated-outdir=";
constexpr char kStartedTestString[] = "[ RUN ] "; constexpr char kStartedTestString[] = "[ RUN ] ";
constexpr char kPassedTestString[] = "[ OK ] "; constexpr char kPassedTestString[] = "[ OK ] ";
constexpr char kFailedTestString[] = "[ FAILED ] "; constexpr char kFailedTestString[] = "[ FAILED ] ";
constexpr char kSkippedTestString[] = "[ SKIPPED ] ";
constexpr char kArtifactsFakeTestName[] = "TestArtifactsFakeTest"; constexpr char kArtifactsFakeTestName[] = "TestArtifactsFakeTest";
...@@ -162,6 +163,7 @@ const char *ResultTypeToString(TestResultType type) ...@@ -162,6 +163,7 @@ const char *ResultTypeToString(TestResultType type)
return "FAIL"; return "FAIL";
case TestResultType::Pass: case TestResultType::Pass:
return "PASS"; return "PASS";
case TestResultType::Skip:
case TestResultType::NoResult: case TestResultType::NoResult:
return "SKIP"; return "SKIP";
case TestResultType::Timeout: case TestResultType::Timeout:
...@@ -180,12 +182,17 @@ TestResultType GetResultTypeFromString(const std::string &str) ...@@ -180,12 +182,17 @@ TestResultType GetResultTypeFromString(const std::string &str)
if (str == "PASS") if (str == "PASS")
return TestResultType::Pass; return TestResultType::Pass;
if (str == "SKIP") if (str == "SKIP")
return TestResultType::NoResult; return TestResultType::Skip;
if (str == "TIMEOUT") if (str == "TIMEOUT")
return TestResultType::Timeout; return TestResultType::Timeout;
return TestResultType::Unknown; return TestResultType::Unknown;
} }
bool IsFailedResult(TestResultType resultType)
{
return resultType != TestResultType::Pass && resultType != TestResultType::Skip;
}
js::Value ResultTypeToJSString(TestResultType type, js::Document::AllocatorType *allocator) js::Value ResultTypeToJSString(TestResultType type, js::Document::AllocatorType *allocator)
{ {
js::Value jsName; js::Value jsName;
...@@ -312,7 +319,7 @@ void WriteResultsFile(bool interrupted, ...@@ -312,7 +319,7 @@ void WriteResultsFile(bool interrupted,
jsResult.AddMember("actual", actualResult, allocator); jsResult.AddMember("actual", actualResult, allocator);
jsResult.AddMember("expected", expectedResult, allocator); jsResult.AddMember("expected", expectedResult, allocator);
if (result.type != TestResultType::Pass) if (IsFailedResult(result.type))
{ {
jsResult.AddMember("is_unexpected", true, allocator); jsResult.AddMember("is_unexpected", true, allocator);
} }
...@@ -397,7 +404,7 @@ void UpdateCurrentTestResult(const testing::TestResult &resultIn, TestResults *r ...@@ -397,7 +404,7 @@ void UpdateCurrentTestResult(const testing::TestResult &resultIn, TestResults *r
// Note: Crashes and Timeouts are detected by the crash handler and a watchdog thread. // Note: Crashes and Timeouts are detected by the crash handler and a watchdog thread.
if (resultIn.Skipped()) if (resultIn.Skipped())
{ {
resultOut.type = TestResultType::NoResult; resultOut.type = TestResultType::Skip;
} }
else if (resultIn.Failed()) else if (resultIn.Failed())
{ {
...@@ -689,7 +696,7 @@ bool GetSingleTestResultFromJSON(const js::Value &name, ...@@ -689,7 +696,7 @@ bool GetSingleTestResultFromJSON(const js::Value &name,
printf("Failed to parse result type.\n"); printf("Failed to parse result type.\n");
return false; return false;
} }
if (resultType != TestResultType::Pass) if (IsFailedResult(resultType))
{ {
flakyFailures++; flakyFailures++;
} }
...@@ -798,8 +805,7 @@ bool MergeTestResults(TestResults *input, TestResults *output, int flakyRetries) ...@@ -798,8 +805,7 @@ bool MergeTestResults(TestResults *input, TestResults *output, int flakyRetries)
// Mark the tests that haven't exhausted their retries as 'SKIP'. This makes ANGLE // Mark the tests that haven't exhausted their retries as 'SKIP'. This makes ANGLE
// attempt the test again. // attempt the test again.
uint32_t runCount = outputResult.flakyFailures + 1; uint32_t runCount = outputResult.flakyFailures + 1;
if (inputResult.type != TestResultType::Pass && if (IsFailedResult(inputResult.type) && runCount < static_cast<uint32_t>(flakyRetries))
runCount < static_cast<uint32_t>(flakyRetries))
{ {
printf("Retrying flaky test: %s.%s.\n", id.testSuiteName.c_str(), printf("Retrying flaky test: %s.%s.\n", id.testSuiteName.c_str(),
id.testName.c_str()); id.testName.c_str());
...@@ -1470,9 +1476,10 @@ bool TestSuite::finishProcess(ProcessInfo *processInfo) ...@@ -1470,9 +1476,10 @@ bool TestSuite::finishProcess(ProcessInfo *processInfo)
std::string line; std::string line;
while (std::getline(linesStream, line)) while (std::getline(linesStream, line))
{ {
size_t startPos = line.find(kStartedTestString); size_t startPos = line.find(kStartedTestString);
size_t failPos = line.find(kFailedTestString); size_t failPos = line.find(kFailedTestString);
size_t passPos = line.find(kPassedTestString); size_t passPos = line.find(kPassedTestString);
size_t skippedPos = line.find(kSkippedTestString);
if (startPos != std::string::npos) if (startPos != std::string::npos)
{ {
...@@ -1490,6 +1497,11 @@ bool TestSuite::finishProcess(ProcessInfo *processInfo) ...@@ -1490,6 +1497,11 @@ bool TestSuite::finishProcess(ProcessInfo *processInfo)
std::string testName = line.substr(strlen(kPassedTestString)); std::string testName = line.substr(strlen(kPassedTestString));
ParseTestIdentifierAndSetResult(testName, TestResultType::Pass, &batchResults); ParseTestIdentifierAndSetResult(testName, TestResultType::Pass, &batchResults);
} }
else if (skippedPos != std::string::npos)
{
std::string testName = line.substr(strlen(kSkippedTestString));
ParseTestIdentifierAndSetResult(testName, TestResultType::Skip, &batchResults);
}
} }
} }
...@@ -1508,7 +1520,7 @@ bool TestSuite::finishProcess(ProcessInfo *processInfo) ...@@ -1508,7 +1520,7 @@ bool TestSuite::finishProcess(ProcessInfo *processInfo)
for (const auto &resultIter : batchResults.results) for (const auto &resultIter : batchResults.results)
{ {
const TestResult &result = resultIter.second; const TestResult &result = resultIter.second;
if (result.type != TestResultType::NoResult && result.type != TestResultType::Pass) if (result.type != TestResultType::NoResult && IsFailedResult(result.type))
{ {
printf("To reproduce the batch, use filter:\n%s\n", printf("To reproduce the batch, use filter:\n%s\n",
processInfo->filterString.c_str()); processInfo->filterString.c_str());
...@@ -1543,6 +1555,10 @@ bool TestSuite::finishProcess(ProcessInfo *processInfo) ...@@ -1543,6 +1555,10 @@ bool TestSuite::finishProcess(ProcessInfo *processInfo)
{ {
printf(" (%0.1lf ms)\n", result.elapsedTimeSeconds * 1000.0); printf(" (%0.1lf ms)\n", result.elapsedTimeSeconds * 1000.0);
} }
else if (result.type == TestResultType::Skip)
{
printf(" (skipped)\n");
}
else if (result.type == TestResultType::Timeout) else if (result.type == TestResultType::Timeout)
{ {
printf(" (TIMEOUT in %0.1lf s)\n", result.elapsedTimeSeconds); printf(" (TIMEOUT in %0.1lf s)\n", result.elapsedTimeSeconds);
...@@ -1721,13 +1737,18 @@ int TestSuite::run() ...@@ -1721,13 +1737,18 @@ int TestSuite::run()
int TestSuite::printFailuresAndReturnCount() const int TestSuite::printFailuresAndReturnCount() const
{ {
std::vector<std::string> failures; std::vector<std::string> failures;
uint32_t skipCount = 0;
for (const auto &resultIter : mTestResults.results) for (const auto &resultIter : mTestResults.results)
{ {
const TestIdentifier &id = resultIter.first; const TestIdentifier &id = resultIter.first;
const TestResult &result = resultIter.second; const TestResult &result = resultIter.second;
if (result.type != TestResultType::Pass) if (result.type == TestResultType::Skip)
{
skipCount++;
}
else if (result.type != TestResultType::Pass)
{ {
const FileLine &fileLine = mTestFileLines.find(id)->second; const FileLine &fileLine = mTestFileLines.find(id)->second;
...@@ -1746,6 +1767,10 @@ int TestSuite::printFailuresAndReturnCount() const ...@@ -1746,6 +1767,10 @@ int TestSuite::printFailuresAndReturnCount() const
{ {
printf(" %s\n", failure.c_str()); printf(" %s\n", failure.c_str());
} }
if (skipCount > 0)
{
printf("%u tests skipped.\n", skipCount);
}
return static_cast<int>(failures.size()); return static_cast<int>(failures.size());
} }
...@@ -1845,6 +1870,8 @@ const char *TestResultTypeToString(TestResultType type) ...@@ -1845,6 +1870,8 @@ const char *TestResultTypeToString(TestResultType type)
return "NoResult"; return "NoResult";
case TestResultType::Pass: case TestResultType::Pass:
return "Pass"; return "Pass";
case TestResultType::Skip:
return "Skip";
case TestResultType::Timeout: case TestResultType::Timeout:
return "Timeout"; return "Timeout";
case TestResultType::Unknown: case TestResultType::Unknown:
......
...@@ -60,6 +60,7 @@ enum class TestResultType ...@@ -60,6 +60,7 @@ enum class TestResultType
Fail, Fail,
NoResult, NoResult,
Pass, Pass,
Skip,
Timeout, Timeout,
Unknown, Unknown,
}; };
......
...@@ -115,6 +115,7 @@ TEST_F(TestSuiteTest, RunMockTests) ...@@ -115,6 +115,7 @@ TEST_F(TestSuiteTest, RunMockTests)
std::map<TestIdentifier, TestResult> expectedResults = { std::map<TestIdentifier, TestResult> expectedResults = {
{{"MockTestSuiteTest", "DISABLED_Pass"}, {TestResultType::Pass, 0.0}}, {{"MockTestSuiteTest", "DISABLED_Pass"}, {TestResultType::Pass, 0.0}},
{{"MockTestSuiteTest", "DISABLED_Fail"}, {TestResultType::Fail, 0.0}}, {{"MockTestSuiteTest", "DISABLED_Fail"}, {TestResultType::Fail, 0.0}},
{{"MockTestSuiteTest", "DISABLED_Skip"}, {TestResultType::Skip, 0.0}},
{{"MockTestSuiteTest", "DISABLED_Timeout"}, {TestResultType::Timeout, 0.0}}, {{"MockTestSuiteTest", "DISABLED_Timeout"}, {TestResultType::Timeout, 0.0}},
}; };
...@@ -176,6 +177,12 @@ TEST(MockTestSuiteTest, DISABLED_Timeout) ...@@ -176,6 +177,12 @@ TEST(MockTestSuiteTest, DISABLED_Timeout)
angle::Sleep(20000); angle::Sleep(20000);
} }
// Trigger a test skip.
TEST(MockTestSuiteTest, DISABLED_Skip)
{
GTEST_SKIP() << "Test skipped.";
}
// Trigger a flaky test failure. // Trigger a flaky test failure.
TEST(MockFlakyTestSuiteTest, DISABLED_Flaky) TEST(MockFlakyTestSuiteTest, DISABLED_Flaky)
{ {
......
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