// Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "platform/api/time.h" #include #include #include "gtest/gtest.h" #include "util/chrono_helpers.h" namespace openscreen { namespace { // Tests that the clock always seems to tick forward. If this test is broken, or // is flaky, the time source is probably not monotonic. TEST(TimeTest, PlatformClockIsMonotonic) { constexpr auto kSleepPeriod = milliseconds(2); for (int i = 0; i < 50; ++i) { const auto start = Clock::now(); std::this_thread::sleep_for(kSleepPeriod); const auto stop = Clock::now(); EXPECT_GE(stop - start, kSleepPeriod / 2); } } // Tests that the clock ticks at least 10000 times per second, a requirement // specified in the API header comments. TEST(TimeTest, PlatformClockHasSufficientResolution) { constexpr std::chrono::duration kMaxAllowedDurationBetweenTicks(1); constexpr int kMaxRetries = 100; // Loop until a small-enough clock change is observed. The platform is given // multiple chances because unpredictable events, like thread context // switches, could suspend the current thread for a "long" time, masking what // the clock is actually capable of. Clock::duration delta = microseconds(0); for (int i = 0; i < kMaxRetries; ++i) { const auto start = Clock::now(); // Loop until the clock changes. do { delta = Clock::now() - start; ASSERT_LE(microseconds(0), delta); } while (delta == microseconds(0)); if (delta <= kMaxAllowedDurationBetweenTicks) { break; } } EXPECT_LE(delta, kMaxAllowedDurationBetweenTicks); } } // namespace } // namespace openscreen