OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/network_time/network_time_tracker.h" | 5 #include "chrome/browser/network_time/network_time_tracker.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 | 8 |
9 #include "base/bind.h" | |
10 #include "base/bind_helpers.h" | |
11 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
12 #include "base/message_loop/message_loop.h" | 10 #include "base/time/tick_clock.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" | 11 #include "testing/gtest/include/gtest/gtest.h" |
16 | 12 |
17 namespace { | 13 namespace { |
18 | 14 |
19 // These are all in milliseconds. | 15 // These are all in milliseconds. |
20 const int64 kLatency1 = 50; | 16 const int64 kLatency1 = 50; |
21 const int64 kLatency2 = 500; | 17 const int64 kLatency2 = 500; |
22 | 18 |
23 // Can not be smaller than 15, it's the NowFromSystemTime() resolution. | 19 // Can not be smaller than 15, it's the NowFromSystemTime() resolution. |
24 const int64 kResolution1 = 17; | 20 const int64 kResolution1 = 17; |
(...skipping 14 matching lines...) Expand all Loading... |
39 | 35 |
40 private: | 36 private: |
41 base::TimeTicks* ticks_now_; | 37 base::TimeTicks* ticks_now_; |
42 }; | 38 }; |
43 | 39 |
44 } // namespace | 40 } // namespace |
45 | 41 |
46 class NetworkTimeTrackerTest : public testing::Test { | 42 class NetworkTimeTrackerTest : public testing::Test { |
47 public: | 43 public: |
48 NetworkTimeTrackerTest() | 44 NetworkTimeTrackerTest() |
49 : ui_thread(content::BrowserThread::UI, &message_loop_), | 45 : now_(base::Time::NowFromSystemTime()), |
50 io_thread(content::BrowserThread::IO, &message_loop_), | 46 network_time_tracker_(new NetworkTimeTracker( |
51 now_(base::Time::NowFromSystemTime()), | 47 scoped_ptr<base::TickClock>(new TestTickClock(&ticks_now_)))) {} |
52 tick_clock_(new TestTickClock(&ticks_now_)), | |
53 network_time_notifier_( | |
54 new net::NetworkTimeNotifier( | |
55 tick_clock_.PassAs<base::TickClock>())) {} | |
56 virtual ~NetworkTimeTrackerTest() {} | 48 virtual ~NetworkTimeTrackerTest() {} |
57 | 49 |
58 virtual void TearDown() OVERRIDE { | |
59 message_loop_.RunUntilIdle(); | |
60 } | |
61 | |
62 base::Time Now() const { | 50 base::Time Now() const { |
63 return now_ + (ticks_now_ - base::TimeTicks()); | 51 return now_ + (ticks_now_ - base::TimeTicks()); |
64 } | 52 } |
65 | 53 |
66 base::TimeTicks TicksNow() const { | 54 base::TimeTicks TicksNow() const { |
67 return ticks_now_; | 55 return ticks_now_; |
68 } | 56 } |
69 | 57 |
70 void AddToTicksNow(int64 ms) { | 58 void AddToTicksNow(int64 ms) { |
71 ticks_now_ += base::TimeDelta::FromMilliseconds(ms); | 59 ticks_now_ += base::TimeDelta::FromMilliseconds(ms); |
72 } | 60 } |
73 | 61 |
74 void StartTracker() { | 62 // Updates the notifier's time with the specified parameters. |
75 network_time_tracker_.reset(new NetworkTimeTracker()); | |
76 network_time_notifier_->AddObserver( | |
77 network_time_tracker_->BuildObserverCallback()); | |
78 message_loop_.RunUntilIdle(); | |
79 } | |
80 | |
81 void StopTracker() { | |
82 network_time_tracker_.reset(); | |
83 } | |
84 | |
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, | 63 void UpdateNetworkTime(const base::Time& network_time, |
88 const base::TimeDelta& resolution, | 64 const base::TimeDelta& resolution, |
89 const base::TimeDelta& latency, | 65 const base::TimeDelta& latency, |
90 const base::TimeTicks& post_time) { | 66 const base::TimeTicks& post_time) { |
91 message_loop_.PostTask( | 67 network_time_tracker_->UpdateNetworkTime( |
92 FROM_HERE, | 68 network_time, resolution, latency, post_time); |
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(); | |
100 } | 69 } |
101 | 70 |
102 // Ensures the network time tracker has a network time and that the | 71 // 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 | 72 // disparity between the network time version of |ticks_now_| and the actual |
104 // |ticks_now_| value is within the uncertainty (should always be true | 73 // |ticks_now_| value is within the uncertainty (should always be true |
105 // because the network time notifier uses |ticks_now_| for the tick clock). | 74 // because the network time notifier uses |ticks_now_| for the tick clock). |
106 testing::AssertionResult ValidateExpectedTime() const { | 75 testing::AssertionResult ValidateExpectedTime() const { |
107 base::Time network_time; | 76 base::Time network_time; |
108 base::TimeDelta uncertainty; | 77 base::TimeDelta uncertainty; |
109 if (!network_time_tracker_->GetNetworkTime(TicksNow(), | 78 if (!network_time_tracker_->GetNetworkTime(TicksNow(), |
110 &network_time, | 79 &network_time, |
111 &uncertainty)) | 80 &uncertainty)) |
112 return testing::AssertionFailure() << "Failed to get network time."; | 81 return testing::AssertionFailure() << "Failed to get network time."; |
113 if (fabs(static_cast<double>(Now().ToInternalValue() - | 82 if (fabs(static_cast<double>(Now().ToInternalValue() - |
114 network_time.ToInternalValue())) > | 83 network_time.ToInternalValue())) > |
115 static_cast<double>(uncertainty.ToInternalValue())) { | 84 static_cast<double>(uncertainty.ToInternalValue())) { |
116 return testing::AssertionFailure() | 85 return testing::AssertionFailure() |
117 << "Expected network time not within uncertainty."; | 86 << "Expected network time not within uncertainty."; |
118 } | 87 } |
119 return testing::AssertionSuccess(); | 88 return testing::AssertionSuccess(); |
120 } | 89 } |
121 | 90 |
122 NetworkTimeTracker* network_time_tracker() { | 91 NetworkTimeTracker* network_time_tracker() { |
123 return network_time_tracker_.get(); | 92 return network_time_tracker_.get(); |
124 } | 93 } |
125 | 94 |
126 private: | 95 private: |
127 // Message loop and threads for the tracker's internal logic. | 96 // Used in building the current time that TestTickClock reports. See Now() |
128 base::MessageLoop message_loop_; | |
129 content::TestBrowserThread ui_thread; | |
130 content::TestBrowserThread io_thread; | |
131 | |
132 // Used in building the current time that |tick_clock_| reports. See Now() | |
133 // for details. | 97 // for details. |
134 base::Time now_; | 98 base::Time now_; |
135 base::TimeTicks ticks_now_; | 99 base::TimeTicks ticks_now_; |
136 | 100 |
137 // A custom clock that allows arbitrary time delays. | |
138 scoped_ptr<TestTickClock> tick_clock_; | |
139 | |
140 // The network time notifier that receives time updates and posts them to | |
141 // the tracker. | |
142 scoped_ptr<net::NetworkTimeNotifier> network_time_notifier_; | |
143 | |
144 // The network time tracker being tested. | 101 // The network time tracker being tested. |
145 scoped_ptr<NetworkTimeTracker> network_time_tracker_; | 102 scoped_ptr<NetworkTimeTracker> network_time_tracker_; |
146 }; | 103 }; |
147 | 104 |
148 // Should not return a value before UpdateNetworkTime gets called. | 105 // Should not return a value before UpdateNetworkTime gets called. |
149 TEST_F(NetworkTimeTrackerTest, Uninitialized) { | 106 TEST_F(NetworkTimeTrackerTest, Uninitialized) { |
150 base::Time network_time; | 107 base::Time network_time; |
151 base::TimeDelta uncertainty; | 108 base::TimeDelta uncertainty; |
152 StartTracker(); | |
153 EXPECT_FALSE(network_time_tracker()->GetNetworkTime(base::TimeTicks(), | 109 EXPECT_FALSE(network_time_tracker()->GetNetworkTime(base::TimeTicks(), |
154 &network_time, | 110 &network_time, |
155 &uncertainty)); | 111 &uncertainty)); |
156 } | 112 } |
157 | 113 |
158 // Verify that the the tracker receives and properly handles updates to the | 114 // Verify that the the tracker receives and properly handles updates to the |
159 // network time. | 115 // network time. |
160 TEST_F(NetworkTimeTrackerTest, NetworkTimeUpdates) { | 116 TEST_F(NetworkTimeTrackerTest, NetworkTimeUpdates) { |
161 StartTracker(); | |
162 UpdateNetworkTime( | 117 UpdateNetworkTime( |
163 Now(), | 118 Now(), |
164 base::TimeDelta::FromMilliseconds(kResolution1), | 119 base::TimeDelta::FromMilliseconds(kResolution1), |
165 base::TimeDelta::FromMilliseconds(kLatency1), | 120 base::TimeDelta::FromMilliseconds(kLatency1), |
166 TicksNow()); | 121 TicksNow()); |
167 EXPECT_TRUE(ValidateExpectedTime()); | 122 EXPECT_TRUE(ValidateExpectedTime()); |
168 | 123 |
169 // Fake a wait for kPseudoSleepTime1 to make sure we keep tracking. | 124 // Fake a wait for kPseudoSleepTime1 to make sure we keep tracking. |
170 AddToTicksNow(kPseudoSleepTime1); | 125 AddToTicksNow(kPseudoSleepTime1); |
171 EXPECT_TRUE(ValidateExpectedTime()); | 126 EXPECT_TRUE(ValidateExpectedTime()); |
(...skipping 15 matching lines...) Expand all Loading... |
187 base::Time old_now = Now(); | 142 base::Time old_now = Now(); |
188 base::TimeTicks old_ticks = TicksNow(); | 143 base::TimeTicks old_ticks = TicksNow(); |
189 AddToTicksNow(kPseudoSleepTime2); | 144 AddToTicksNow(kPseudoSleepTime2); |
190 UpdateNetworkTime( | 145 UpdateNetworkTime( |
191 old_now, | 146 old_now, |
192 base::TimeDelta::FromMilliseconds(kResolution2), | 147 base::TimeDelta::FromMilliseconds(kResolution2), |
193 base::TimeDelta::FromMilliseconds(kLatency2), | 148 base::TimeDelta::FromMilliseconds(kLatency2), |
194 old_ticks); | 149 old_ticks); |
195 EXPECT_TRUE(ValidateExpectedTime()); | 150 EXPECT_TRUE(ValidateExpectedTime()); |
196 } | 151 } |
197 | |
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()); | |
208 } | |
209 | |
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()); | |
220 } | |
OLD | NEW |