1 // Copyright 2013 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 "chrome/browser/network_time/network_time_tracker.h"
10 #include "base/bind_helpers.h"
11 #include "base/compiler_specific.h"
12 #include "base/message_loop/message_loop.h"
13 #include "content/public/test/test_browser_thread.h"
14 #include "net/base/network_time_notifier.h"
15 #include "testing/gtest/include/gtest/gtest.h"
19 // These are all in milliseconds.
20 const int64 kLatency1
= 50;
21 const int64 kLatency2
= 500;
23 // Can not be smaller than 15, it's the NowFromSystemTime() resolution.
24 const int64 kResolution1
= 17;
25 const int64 kResolution2
= 177;
27 const int64 kPseudoSleepTime1
= 500000001;
28 const int64 kPseudoSleepTime2
= 1888;
30 // A custom tick clock that will return an arbitrary time.
31 class TestTickClock
: public base::TickClock
{
33 explicit TestTickClock(base::TimeTicks
* ticks_now
) : ticks_now_(ticks_now
) {}
34 virtual ~TestTickClock() {}
36 virtual base::TimeTicks
NowTicks() OVERRIDE
{
41 base::TimeTicks
* ticks_now_
;
46 class NetworkTimeTrackerTest
: public testing::Test
{
48 NetworkTimeTrackerTest()
49 : ui_thread(content::BrowserThread::UI
, &message_loop_
),
50 io_thread(content::BrowserThread::IO
, &message_loop_
),
51 now_(base::Time::NowFromSystemTime()),
52 tick_clock_(new TestTickClock(&ticks_now_
)),
53 network_time_notifier_(
54 new net::NetworkTimeNotifier(
55 tick_clock_
.PassAs
<base::TickClock
>())) {}
56 virtual ~NetworkTimeTrackerTest() {}
58 virtual void TearDown() OVERRIDE
{
59 message_loop_
.RunUntilIdle();
62 base::Time
Now() const {
63 return now_
+ (ticks_now_
- base::TimeTicks());
66 base::TimeTicks
TicksNow() const {
70 void AddToTicksNow(int64 ms
) {
71 ticks_now_
+= base::TimeDelta::FromMilliseconds(ms
);
75 network_time_tracker_
.reset(new NetworkTimeTracker());
76 network_time_notifier_
->AddObserver(
77 network_time_tracker_
->BuildObserverCallback());
78 message_loop_
.RunUntilIdle();
82 network_time_tracker_
.reset();
85 // Updates the notifier's time with the specified parameters and waits until
86 // the observers have been updated.
87 void UpdateNetworkTime(const base::Time
& network_time
,
88 const base::TimeDelta
& resolution
,
89 const base::TimeDelta
& latency
,
90 const base::TimeTicks
& post_time
) {
91 message_loop_
.PostTask(
93 base::Bind(&net::NetworkTimeNotifier::UpdateNetworkTime
,
94 base::Unretained(network_time_notifier_
.get()),
99 message_loop_
.RunUntilIdle();
102 // Ensures the network time tracker has a network time and that the
103 // disparity between the network time version of |ticks_now_| and the actual
104 // |ticks_now_| value is within the uncertainty (should always be true
105 // because the network time notifier uses |ticks_now_| for the tick clock).
106 testing::AssertionResult
ValidateExpectedTime() const {
107 base::Time network_time
;
108 base::TimeDelta uncertainty
;
109 if (!network_time_tracker_
->GetNetworkTime(TicksNow(),
112 return testing::AssertionFailure() << "Failed to get network time.";
113 if (fabs(static_cast<double>(Now().ToInternalValue() -
114 network_time
.ToInternalValue())) >
115 static_cast<double>(uncertainty
.ToInternalValue())) {
116 return testing::AssertionFailure()
117 << "Expected network time not within uncertainty.";
119 return testing::AssertionSuccess();
122 NetworkTimeTracker
* network_time_tracker() {
123 return network_time_tracker_
.get();
127 // Message loop and threads for the tracker's internal logic.
128 base::MessageLoop message_loop_
;
129 content::TestBrowserThread ui_thread
;
130 content::TestBrowserThread io_thread
;
132 // Used in building the current time that |tick_clock_| reports. See Now()
135 base::TimeTicks ticks_now_
;
137 // A custom clock that allows arbitrary time delays.
138 scoped_ptr
<TestTickClock
> tick_clock_
;
140 // The network time notifier that receives time updates and posts them to
142 scoped_ptr
<net::NetworkTimeNotifier
> network_time_notifier_
;
144 // The network time tracker being tested.
145 scoped_ptr
<NetworkTimeTracker
> network_time_tracker_
;
148 // Should not return a value before UpdateNetworkTime gets called.
149 TEST_F(NetworkTimeTrackerTest
, Uninitialized
) {
150 base::Time network_time
;
151 base::TimeDelta uncertainty
;
153 EXPECT_FALSE(network_time_tracker()->GetNetworkTime(base::TimeTicks(),
158 // Verify that the the tracker receives and properly handles updates to the
160 TEST_F(NetworkTimeTrackerTest
, NetworkTimeUpdates
) {
164 base::TimeDelta::FromMilliseconds(kResolution1
),
165 base::TimeDelta::FromMilliseconds(kLatency1
),
167 EXPECT_TRUE(ValidateExpectedTime());
169 // Fake a wait for kPseudoSleepTime1 to make sure we keep tracking.
170 AddToTicksNow(kPseudoSleepTime1
);
171 EXPECT_TRUE(ValidateExpectedTime());
173 // Update the time with a new now value and kLatency2.
176 base::TimeDelta::FromMilliseconds(kResolution2
),
177 base::TimeDelta::FromMilliseconds(kLatency2
),
180 // Fake a wait for kPseudoSleepTime2 to make sure we keep tracking still.
181 AddToTicksNow(kPseudoSleepTime2
);
182 EXPECT_TRUE(ValidateExpectedTime());
184 // Fake a long delay between update task post time and the network notifier
185 // updating its network time. The uncertainty should account for the
187 base::Time old_now
= Now();
188 base::TimeTicks old_ticks
= TicksNow();
189 AddToTicksNow(kPseudoSleepTime2
);
192 base::TimeDelta::FromMilliseconds(kResolution2
),
193 base::TimeDelta::FromMilliseconds(kLatency2
),
195 EXPECT_TRUE(ValidateExpectedTime());
198 // Starting the tracker after the network time has been set with the notifier
199 // should update the tracker's time as well.
200 TEST_F(NetworkTimeTrackerTest
, UpdateThenStartTracker
) {
203 base::TimeDelta::FromMilliseconds(kResolution1
),
204 base::TimeDelta::FromMilliseconds(kLatency1
),
207 EXPECT_TRUE(ValidateExpectedTime());
210 // Time updates after the tracker has been destroyed should not attempt to
211 // dereference the destroyed tracker.
212 TEST_F(NetworkTimeTrackerTest
, UpdateAfterTrackerDestroyed
) {
217 base::TimeDelta::FromMilliseconds(kResolution1
),
218 base::TimeDelta::FromMilliseconds(kLatency1
),