Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / network_time / network_time_tracker_unittest.cc
blobe30cc790117cabea8c077a4e01db5100712b1a59
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"
7 #include <math.h>
9 #include "base/bind.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"
17 namespace {
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 {
32 public:
33 explicit TestTickClock(base::TimeTicks* ticks_now) : ticks_now_(ticks_now) {}
34 virtual ~TestTickClock() {}
36 virtual base::TimeTicks NowTicks() OVERRIDE {
37 return *ticks_now_;
40 private:
41 base::TimeTicks* ticks_now_;
44 } // namespace
46 class NetworkTimeTrackerTest : public testing::Test {
47 public:
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 {
67 return ticks_now_;
70 void AddToTicksNow(int64 ms) {
71 ticks_now_ += base::TimeDelta::FromMilliseconds(ms);
74 void StartTracker() {
75 network_time_tracker_.reset(new NetworkTimeTracker());
76 network_time_notifier_->AddObserver(
77 network_time_tracker_->BuildObserverCallback());
78 message_loop_.RunUntilIdle();
81 void StopTracker() {
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(
92 FROM_HERE,
93 base::Bind(&net::NetworkTimeNotifier::UpdateNetworkTime,
94 base::Unretained(network_time_notifier_.get()),
95 network_time,
96 resolution,
97 latency,
98 post_time));
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(),
110 &network_time,
111 &uncertainty))
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();
126 private:
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()
133 // for details.
134 base::Time 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
141 // the tracker.
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;
152 StartTracker();
153 EXPECT_FALSE(network_time_tracker()->GetNetworkTime(base::TimeTicks(),
154 &network_time,
155 &uncertainty));
158 // Verify that the the tracker receives and properly handles updates to the
159 // network time.
160 TEST_F(NetworkTimeTrackerTest, NetworkTimeUpdates) {
161 StartTracker();
162 UpdateNetworkTime(
163 Now(),
164 base::TimeDelta::FromMilliseconds(kResolution1),
165 base::TimeDelta::FromMilliseconds(kLatency1),
166 TicksNow());
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.
174 UpdateNetworkTime(
175 Now(),
176 base::TimeDelta::FromMilliseconds(kResolution2),
177 base::TimeDelta::FromMilliseconds(kLatency2),
178 TicksNow());
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
186 // disparity.
187 base::Time old_now = Now();
188 base::TimeTicks old_ticks = TicksNow();
189 AddToTicksNow(kPseudoSleepTime2);
190 UpdateNetworkTime(
191 old_now,
192 base::TimeDelta::FromMilliseconds(kResolution2),
193 base::TimeDelta::FromMilliseconds(kLatency2),
194 old_ticks);
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) {
201 UpdateNetworkTime(
202 Now(),
203 base::TimeDelta::FromMilliseconds(kResolution1),
204 base::TimeDelta::FromMilliseconds(kLatency1),
205 TicksNow());
206 StartTracker();
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) {
213 StartTracker();
214 StopTracker();
215 UpdateNetworkTime(
216 Now(),
217 base::TimeDelta::FromMilliseconds(kResolution1),
218 base::TimeDelta::FromMilliseconds(kLatency1),
219 TicksNow());