Home | History | Annotate | Download | only in network_time
      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