Googletest export

Use monotonic time to measure test duration

System time may be updated while a test is running. When this occurs a
duration measured using system time may appear to move backwards, or
jump far forwards.
This change updates the duration measurement to use monotonic time
instead. Timestamps for the test start still use system time.

PiperOrigin-RevId: 361700881
This commit is contained in:
Abseil Team 2021-03-08 18:00:25 -08:00 committed by Dino Radaković
parent bb4f87e6c6
commit 763eaa4305

View File

@ -1031,7 +1031,25 @@ std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
); // NOLINT
}
// Returns the current time in milliseconds.
// A helper class for measuring elapsed times.
class Timer {
public:
Timer() : start_(std::chrono::steady_clock::now()) {}
// Return time elapsed in milliseconds since the timer was created.
TimeInMillis Elapsed() {
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - start_)
.count();
}
private:
std::chrono::time_point<std::chrono::steady_clock> start_;
};
// Returns a timestamp as milliseconds since the epoch. Note this time may jump
// around subject to adjustments by the system, to measure elapsed time use
// Timer instead.
TimeInMillis GetTimeInMillis() {
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now() -
@ -2824,7 +2842,8 @@ void TestInfo::Run() {
// Notifies the unit test event listeners that a test is about to start.
repeater->OnTestStart(*this);
const TimeInMillis start = internal::GetTimeInMillis();
result_.set_start_timestamp(internal::GetTimeInMillis());
internal::Timer timer;
impl->os_stack_trace_getter()->UponLeavingGTest();
@ -2849,8 +2868,7 @@ void TestInfo::Run() {
test, &Test::DeleteSelf_, "the test fixture's destructor");
}
result_.set_start_timestamp(start);
result_.set_elapsed_time(internal::GetTimeInMillis() - start);
result_.set_elapsed_time(timer.Elapsed());
// Notifies the unit test event listener that a test has just finished.
repeater->OnTestEnd(*this);
@ -2992,6 +3010,7 @@ void TestSuite::Run() {
this, &TestSuite::RunSetUpTestSuite, "SetUpTestSuite()");
start_timestamp_ = internal::GetTimeInMillis();
internal::Timer timer;
for (int i = 0; i < total_test_count(); i++) {
GetMutableTestInfo(i)->Run();
if (GTEST_FLAG(fail_fast) && GetMutableTestInfo(i)->result()->Failed()) {
@ -3001,7 +3020,7 @@ void TestSuite::Run() {
break;
}
}
elapsed_time_ = internal::GetTimeInMillis() - start_timestamp_;
elapsed_time_ = timer.Elapsed();
impl->os_stack_trace_getter()->UponLeavingGTest();
internal::HandleExceptionsInMethodIfSupported(
@ -5685,7 +5704,7 @@ bool UnitTestImpl::RunAllTests() {
// assertions executed before RUN_ALL_TESTS().
ClearNonAdHocTestResult();
const TimeInMillis start = GetTimeInMillis();
Timer timer;
// Shuffles test suites and tests if requested.
if (has_tests_to_run && GTEST_FLAG(shuffle)) {
@ -5751,7 +5770,7 @@ bool UnitTestImpl::RunAllTests() {
repeater->OnEnvironmentsTearDownEnd(*parent_);
}
elapsed_time_ = GetTimeInMillis() - start;
elapsed_time_ = timer.Elapsed();
// Tells the unit test event listener that the tests have just finished.
repeater->OnTestIterationEnd(*parent_, i);