• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
TestTickClock(base::TimeTicks * ticks_now)32   explicit TestTickClock(base::TimeTicks* ticks_now) : ticks_now_(ticks_now) {}
~TestTickClock()33   virtual ~TestTickClock() {}
34 
NowTicks()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:
~NetworkTimeTrackerTest()47   virtual ~NetworkTimeTrackerTest() {}
48 
SetUp()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 
Now() const58   base::Time Now() const {
59     return now_ + (ticks_now_ - base::TimeTicks());
60   }
61 
TicksNow() const62   base::TimeTicks TicksNow() const {
63     return ticks_now_;
64   }
65 
AddToTicksNow(int64 ms)66   void AddToTicksNow(int64 ms) {
67     ticks_now_ += base::TimeDelta::FromMilliseconds(ms);
68   }
69 
70   // Updates the notifier's time with the specified parameters.
UpdateNetworkTime(const base::Time & network_time,const base::TimeDelta & resolution,const base::TimeDelta & latency,const base::TimeTicks & post_time)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).
ValidateExpectedTime() const83   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 
network_time_tracker()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.
TEST_F(NetworkTimeTrackerTest,Uninitialized)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.
TEST_F(NetworkTimeTrackerTest,NetworkTimeUpdates)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