1 // Copyright 2015 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.
5 #include "chromecast/base/system_time_change_notifier.h"
8 #include "base/location.h"
9 #include "base/macros.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "base/sequenced_task_runner.h"
13 #include "base/time/time.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace chromecast
{
20 class SequencedTaskRunnerNoDelay
: public base::SequencedTaskRunner
{
22 SequencedTaskRunnerNoDelay() {}
24 // base::SequencedTaskRunner implementation:
25 bool PostDelayedTask(const tracked_objects::Location
& from_here
,
26 const base::Closure
& task
,
27 base::TimeDelta delay
) override
{
28 base::MessageLoop::current()->PostTask(from_here
, task
);
32 bool PostNonNestableDelayedTask(const tracked_objects::Location
& from_here
,
33 const base::Closure
& task
,
34 base::TimeDelta delay
) override
{
38 bool RunsTasksOnCurrentThread() const override
{ return true; }
41 ~SequencedTaskRunnerNoDelay() override
{}
43 DISALLOW_COPY_AND_ASSIGN(SequencedTaskRunnerNoDelay
);
46 class TimeChangeObserver
: public SystemTimeChangeNotifier::Observer
{
48 TimeChangeObserver() : num_time_changed_(0) {}
49 ~TimeChangeObserver() override
{}
51 // SystemTimeChangeNotifier::Observer implementation:
52 void OnSystemTimeChanged() override
{ ++num_time_changed_
; }
54 int num_time_changed() const { return num_time_changed_
; }
57 int num_time_changed_
;
59 DISALLOW_COPY_AND_ASSIGN(TimeChangeObserver
);
64 class SystemTimeChangeNotifierTest
: public testing::Test
{
66 void SetUp() override
{
67 message_loop_
.reset(new base::MessageLoop
);
69 notifier_
.reset(new SystemTimeChangeNotifierPeriodicMonitor(
70 new SequencedTaskRunnerNoDelay()));
72 observer_
.reset(new TimeChangeObserver
);
73 notifier_
->AddObserver(observer_
.get());
74 notifier_
->Initialize();
77 void TearDown() override
{
78 notifier_
->Finalize();
81 // Runs pending tasks. It doesn't run tasks schedule after this call.
82 void RunPendingTasks() {
83 base::RunLoop run_loop
;
84 base::MessageLoop::current()->PostTask(FROM_HERE
, run_loop
.QuitClosure());
88 scoped_ptr
<base::MessageLoop
> message_loop_
;
89 scoped_ptr
<SystemTimeChangeNotifierPeriodicMonitor
> notifier_
;
90 scoped_ptr
<TimeChangeObserver
> observer_
;
93 TEST_F(SystemTimeChangeNotifierTest
, NotChanged
) {
94 EXPECT_EQ(0, observer_
->num_time_changed());
98 EXPECT_EQ(0, observer_
->num_time_changed());
101 TEST_F(SystemTimeChangeNotifierTest
, TimeChangedForwardLessThan10Seconds
) {
102 base::Time now
= base::Time::Now();
103 EXPECT_EQ(0, observer_
->num_time_changed());
105 // Time change NOT detected.
106 notifier_
->set_fake_now_for_testing(now
+ base::TimeDelta::FromSeconds(4));
108 EXPECT_EQ(0, observer_
->num_time_changed());
110 EXPECT_EQ(0, observer_
->num_time_changed());
113 TEST_F(SystemTimeChangeNotifierTest
, TimeChangedBackwardLessThan10Seconds
) {
114 base::Time now
= base::Time::Now();
115 EXPECT_EQ(0, observer_
->num_time_changed());
117 // Time change NOT detected.
118 notifier_
->set_fake_now_for_testing(now
- base::TimeDelta::FromSeconds(4));
120 EXPECT_EQ(0, observer_
->num_time_changed());
122 EXPECT_EQ(0, observer_
->num_time_changed());
125 TEST_F(SystemTimeChangeNotifierTest
, TimeChangedForwardMoreThan10Seconds
) {
126 base::Time now
= base::Time::Now();
127 EXPECT_EQ(0, observer_
->num_time_changed());
129 notifier_
->set_fake_now_for_testing(now
+ base::TimeDelta::FromSeconds(40));
131 // Still 0 since observe callback is running in next run loop.
132 EXPECT_EQ(0, observer_
->num_time_changed());
134 // Time change detected.
135 EXPECT_EQ(1, observer_
->num_time_changed());
138 TEST_F(SystemTimeChangeNotifierTest
, TimeChangedBackwardMoreThan10Seconds
) {
139 base::Time now
= base::Time::Now();
140 EXPECT_EQ(0, observer_
->num_time_changed());
142 notifier_
->set_fake_now_for_testing(now
- base::TimeDelta::FromSeconds(40));
144 // Still 0 since observe callback is running in next run loop.
145 EXPECT_EQ(0, observer_
->num_time_changed());
147 // Time change detected.
148 EXPECT_EQ(1, observer_
->num_time_changed());
151 TEST_F(SystemTimeChangeNotifierTest
, CannotDetectTimeDriftForward
) {
152 base::Time now
= base::Time::Now();
153 EXPECT_EQ(0, observer_
->num_time_changed());
155 // Time change NOT detected. Expected = now + 1, actual = now + 4.
156 notifier_
->set_fake_now_for_testing(now
+ base::TimeDelta::FromSeconds(4));
158 EXPECT_EQ(0, observer_
->num_time_changed());
160 // Time change NOT detected. Expected = now + 4 + 1, actual = now + 8.
161 notifier_
->set_fake_now_for_testing(now
+ base::TimeDelta::FromSeconds(8));
163 EXPECT_EQ(0, observer_
->num_time_changed());
165 // Time change NOT detected. Expected = now + 8 + 1, actual = now + 12.
166 notifier_
->set_fake_now_for_testing(now
+ base::TimeDelta::FromSeconds(12));
168 EXPECT_EQ(0, observer_
->num_time_changed());
170 // Time change detected. Expected = now + 12 + 1, actual = now + 16.
171 notifier_
->set_fake_now_for_testing(now
+ base::TimeDelta::FromSeconds(16));
173 EXPECT_EQ(0, observer_
->num_time_changed());
175 // Time change detected. Expected = now + 16 + 1, actual = now + 20.
176 notifier_
->set_fake_now_for_testing(now
+ base::TimeDelta::FromSeconds(20));
178 EXPECT_EQ(0, observer_
->num_time_changed());
181 TEST_F(SystemTimeChangeNotifierTest
, CannotDetectTTimeDriftBackward
) {
182 base::Time now
= base::Time::Now();
183 EXPECT_EQ(0, observer_
->num_time_changed());
185 // Time change NOT detected. Expected = now + 1, actual = now - 4.
186 notifier_
->set_fake_now_for_testing(now
- base::TimeDelta::FromSeconds(4));
188 EXPECT_EQ(0, observer_
->num_time_changed());
190 // Time change NOT detected. Expected = now - 4 + 1, actual = now - 8.
191 notifier_
->set_fake_now_for_testing(now
- base::TimeDelta::FromSeconds(8));
193 EXPECT_EQ(0, observer_
->num_time_changed());
195 // Time change detected. Expected = now - 8 + 1, actual = now - 12.
196 notifier_
->set_fake_now_for_testing(now
- base::TimeDelta::FromSeconds(12));
198 EXPECT_EQ(0, observer_
->num_time_changed());
200 // Time change detected. Expected = now - 12 + 1, actual = now - 16.
201 notifier_
->set_fake_now_for_testing(now
- base::TimeDelta::FromSeconds(16));
203 EXPECT_EQ(0, observer_
->num_time_changed());
205 // Time change detected. Expected = now - 20 + 1, actual = now - 20.
206 notifier_
->set_fake_now_for_testing(now
- base::TimeDelta::FromSeconds(20));
208 EXPECT_EQ(0, observer_
->num_time_changed());
211 } // namespace chromecast