| 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 |