blob: c0328526703ceade325afb4978611ce8b6cef36e [file] [log] [blame]
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -07001// Copyright 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "platform/api/time.h"
6
Jordan Baylesc9201dd2020-06-02 15:51:31 -07007#include <chrono>
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -07008#include <thread>
9
Jordan Bayles2d01f172019-06-07 11:11:50 -070010#include "gtest/gtest.h"
Jordan Baylesc9201dd2020-06-02 15:51:31 -070011#include "util/chrono_helpers.h"
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -070012
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -070013namespace openscreen {
Yuri Wiitalaf162a612019-11-22 22:46:04 -080014namespace {
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -070015
Yuri Wiitalaf162a612019-11-22 22:46:04 -080016// Tests that the clock always seems to tick forward. If this test is broken, or
17// is flaky, the time source is probably not monotonic.
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -070018TEST(TimeTest, PlatformClockIsMonotonic) {
19 constexpr auto kSleepPeriod = milliseconds(2);
20 for (int i = 0; i < 50; ++i) {
21 const auto start = Clock::now();
22 std::this_thread::sleep_for(kSleepPeriod);
23 const auto stop = Clock::now();
24 EXPECT_GE(stop - start, kSleepPeriod / 2);
25 }
26}
27
Yuri Wiitalaf162a612019-11-22 22:46:04 -080028// Tests that the clock ticks at least 10000 times per second, a requirement
29// specified in the API header comments.
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -070030TEST(TimeTest, PlatformClockHasSufficientResolution) {
Yuri Wiitalaf162a612019-11-22 22:46:04 -080031 constexpr std::chrono::duration<int, Clock::kRequiredResolution>
32 kMaxAllowedDurationBetweenTicks(1);
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -070033 constexpr int kMaxRetries = 100;
34
35 // Loop until a small-enough clock change is observed. The platform is given
36 // multiple chances because unpredictable events, like thread context
37 // switches, could suspend the current thread for a "long" time, masking what
38 // the clock is actually capable of.
39 Clock::duration delta = microseconds(0);
40 for (int i = 0; i < kMaxRetries; ++i) {
41 const auto start = Clock::now();
42 // Loop until the clock changes.
43 do {
44 delta = Clock::now() - start;
45 ASSERT_LE(microseconds(0), delta);
46 } while (delta == microseconds(0));
47
Yuri Wiitalaf162a612019-11-22 22:46:04 -080048 if (delta <= kMaxAllowedDurationBetweenTicks) {
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -070049 break;
50 }
51 }
52
Yuri Wiitalaf162a612019-11-22 22:46:04 -080053 EXPECT_LE(delta, kMaxAllowedDurationBetweenTicks);
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -070054}
55
Yuri Wiitalaf162a612019-11-22 22:46:04 -080056} // namespace
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -070057} // namespace openscreen