1 // Copyright 2018 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 #ifndef PLATFORM_TEST_FAKE_CLOCK_H_
6 #define PLATFORM_TEST_FAKE_CLOCK_H_
7 
8 #include <atomic>
9 #include <thread>
10 #include <vector>
11 
12 #include "platform/api/time.h"
13 
14 namespace openscreen {
15 
16 class FakeTaskRunner;
17 
18 class FakeClock {
19  public:
20   explicit FakeClock(Clock::time_point start_time);
21   ~FakeClock();
22 
23   // Moves the clock forward, simulating execution by running tasks in all
24   // FakeTaskRunners. The clock advances in one or more jumps, to ensure delayed
25   // tasks see the correct "now time" when they are executed.
26   void Advance(Clock::duration delta);
27 
28   static Clock::time_point now() noexcept;
29 
30  protected:
31   friend class FakeTaskRunner;
32 
33   void SubscribeToTimeChanges(FakeTaskRunner* task_runner);
34   void UnsubscribeFromTimeChanges(FakeTaskRunner* task_runner);
35 
36  private:
37   // Used for ensuring this FakeClock's lifecycle and mutations occur on the
38   // same thread.
39   const std::thread::id control_thread_id_;
40 
41   std::vector<FakeTaskRunner*> task_runners_;
42 
43   // This variable is atomic because some tests (e.g., TaskRunnerImplTest) will
44   // call now() on a different thread.
45   static std::atomic<Clock::time_point> now_;
46 };
47 
48 }  // namespace openscreen
49 
50 #endif  // PLATFORM_TEST_FAKE_CLOCK_H_
51