1 // Copyright 2014 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. 4 5 #include "components/network_time/network_time_tracker.h" 6 7 #include <math.h> 8 9 #include "base/compiler_specific.h" 10 #include "base/prefs/testing_pref_service.h" 11 #include "base/time/tick_clock.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 namespace network_time { 15 16 namespace { 17 18 // These are all in milliseconds. 19 const int64 kLatency1 = 50; 20 const int64 kLatency2 = 500; 21 22 // Can not be smaller than 15, it's the NowFromSystemTime() resolution. 23 const int64 kResolution1 = 17; 24 const int64 kResolution2 = 177; 25 26 const int64 kPseudoSleepTime1 = 500000001; 27 const int64 kPseudoSleepTime2 = 1888; 28 29 // A custom tick clock that will return an arbitrary time. 30 class TestTickClock : public base::TickClock { 31 public: 32 explicit TestTickClock(base::TimeTicks* ticks_now) : ticks_now_(ticks_now) {} 33 virtual ~TestTickClock() {} 34 35 virtual base::TimeTicks NowTicks() OVERRIDE { 36 return *ticks_now_; 37 } 38 39 private: 40 base::TimeTicks* ticks_now_; 41 }; 42 43 } // namespace 44 45 class NetworkTimeTrackerTest : public testing::Test { 46 public: 47 virtual ~NetworkTimeTrackerTest() {} 48 49 virtual void SetUp() OVERRIDE { 50 NetworkTimeTracker::RegisterPrefs(pref_service_.registry()); 51 52 now_ = base::Time::NowFromSystemTime(); 53 network_time_tracker_.reset(new NetworkTimeTracker( 54 scoped_ptr<base::TickClock>(new TestTickClock(&ticks_now_)), 55 &pref_service_)); 56 } 57 58 base::Time Now() const { 59 return now_ + (ticks_now_ - base::TimeTicks()); 60 } 61 62 base::TimeTicks TicksNow() const { 63 return ticks_now_; 64 } 65 66 void AddToTicksNow(int64 ms) { 67 ticks_now_ += base::TimeDelta::FromMilliseconds(ms); 68 } 69 70 // Updates the notifier's time with the specified parameters. 71 void UpdateNetworkTime(const base::Time& network_time, 72 const base::TimeDelta& resolution, 73 const base::TimeDelta& latency, 74 const base::TimeTicks& post_time) { 75 network_time_tracker_->UpdateNetworkTime( 76 network_time, resolution, latency, post_time); 77 } 78 79 // Ensures the network time tracker has a network time and that the 80 // disparity between the network time version of |ticks_now_| and the actual 81 // |ticks_now_| value is within the uncertainty (should always be true 82 // because the network time notifier uses |ticks_now_| for the tick clock). 83 testing::AssertionResult ValidateExpectedTime() const { 84 base::Time network_time; 85 base::TimeDelta uncertainty; 86 if (!network_time_tracker_->GetNetworkTime(TicksNow(), 87 &network_time, 88 &uncertainty)) 89 return testing::AssertionFailure() << "Failed to get network time."; 90 if (fabs(static_cast<double>(Now().ToInternalValue() - 91 network_time.ToInternalValue())) > 92 static_cast<double>(uncertainty.ToInternalValue())) { 93 return testing::AssertionFailure() 94 << "Expected network time not within uncertainty."; 95 } 96 return testing::AssertionSuccess(); 97 } 98 99 NetworkTimeTracker* network_time_tracker() { 100 return network_time_tracker_.get(); 101 } 102 103 private: 104 // Used in building the current time that TestTickClock reports. See Now() 105 // for details. 106 base::Time now_; 107 base::TimeTicks ticks_now_; 108 109 TestingPrefServiceSimple pref_service_; 110 111 // The network time tracker being tested. 112 scoped_ptr<NetworkTimeTracker> network_time_tracker_; 113 }; 114 115 // Should not return a value before UpdateNetworkTime gets called. 116 TEST_F(NetworkTimeTrackerTest, Uninitialized) { 117 base::Time network_time; 118 base::TimeDelta uncertainty; 119 EXPECT_FALSE(network_time_tracker()->GetNetworkTime(base::TimeTicks(), 120 &network_time, 121 &uncertainty)); 122 } 123 124 // Verify that the the tracker receives and properly handles updates to the 125 // network time. 126 TEST_F(NetworkTimeTrackerTest, NetworkTimeUpdates) { 127 UpdateNetworkTime( 128 Now(), 129 base::TimeDelta::FromMilliseconds(kResolution1), 130 base::TimeDelta::FromMilliseconds(kLatency1), 131 TicksNow()); 132 EXPECT_TRUE(ValidateExpectedTime()); 133 134 // Fake a wait for kPseudoSleepTime1 to make sure we keep tracking. 135 AddToTicksNow(kPseudoSleepTime1); 136 EXPECT_TRUE(ValidateExpectedTime()); 137 138 // Update the time with a new now value and kLatency2. 139 UpdateNetworkTime( 140 Now(), 141 base::TimeDelta::FromMilliseconds(kResolution2), 142 base::TimeDelta::FromMilliseconds(kLatency2), 143 TicksNow()); 144 145 // Fake a wait for kPseudoSleepTime2 to make sure we keep tracking still. 146 AddToTicksNow(kPseudoSleepTime2); 147 EXPECT_TRUE(ValidateExpectedTime()); 148 149 // Fake a long delay between update task post time and the network notifier 150 // updating its network time. The uncertainty should account for the 151 // disparity. 152 base::Time old_now = Now(); 153 base::TimeTicks old_ticks = TicksNow(); 154 AddToTicksNow(kPseudoSleepTime2); 155 UpdateNetworkTime( 156 old_now, 157 base::TimeDelta::FromMilliseconds(kResolution2), 158 base::TimeDelta::FromMilliseconds(kLatency2), 159 old_ticks); 160 EXPECT_TRUE(ValidateExpectedTime()); 161 } 162 163 } // namespace network_time 164