diff options
Diffstat (limited to 'components/network_time/network_time_tracker_unittest.cc')
-rw-r--r-- | components/network_time/network_time_tracker_unittest.cc | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/components/network_time/network_time_tracker_unittest.cc b/components/network_time/network_time_tracker_unittest.cc new file mode 100644 index 0000000..3febae8 --- /dev/null +++ b/components/network_time/network_time_tracker_unittest.cc @@ -0,0 +1,163 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/network_time/network_time_tracker.h" + +#include <math.h> + +#include "base/compiler_specific.h" +#include "base/prefs/testing_pref_service.h" +#include "base/time/tick_clock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace network_time { + +namespace { + +// These are all in milliseconds. +const int64 kLatency1 = 50; +const int64 kLatency2 = 500; + +// Can not be smaller than 15, it's the NowFromSystemTime() resolution. +const int64 kResolution1 = 17; +const int64 kResolution2 = 177; + +const int64 kPseudoSleepTime1 = 500000001; +const int64 kPseudoSleepTime2 = 1888; + +// A custom tick clock that will return an arbitrary time. +class TestTickClock : public base::TickClock { + public: + explicit TestTickClock(base::TimeTicks* ticks_now) : ticks_now_(ticks_now) {} + virtual ~TestTickClock() {} + + virtual base::TimeTicks NowTicks() OVERRIDE { + return *ticks_now_; + } + + private: + base::TimeTicks* ticks_now_; +}; + +} // namespace + +class NetworkTimeTrackerTest : public testing::Test { + public: + virtual ~NetworkTimeTrackerTest() {} + + virtual void SetUp() OVERRIDE { + NetworkTimeTracker::RegisterPrefs(pref_service_.registry()); + + now_ = base::Time::NowFromSystemTime(); + network_time_tracker_.reset(new NetworkTimeTracker( + scoped_ptr<base::TickClock>(new TestTickClock(&ticks_now_)), + &pref_service_)); + } + + base::Time Now() const { + return now_ + (ticks_now_ - base::TimeTicks()); + } + + base::TimeTicks TicksNow() const { + return ticks_now_; + } + + void AddToTicksNow(int64 ms) { + ticks_now_ += base::TimeDelta::FromMilliseconds(ms); + } + + // Updates the notifier's time with the specified parameters. + void UpdateNetworkTime(const base::Time& network_time, + const base::TimeDelta& resolution, + const base::TimeDelta& latency, + const base::TimeTicks& post_time) { + network_time_tracker_->UpdateNetworkTime( + network_time, resolution, latency, post_time); + } + + // Ensures the network time tracker has a network time and that the + // disparity between the network time version of |ticks_now_| and the actual + // |ticks_now_| value is within the uncertainty (should always be true + // because the network time notifier uses |ticks_now_| for the tick clock). + testing::AssertionResult ValidateExpectedTime() const { + base::Time network_time; + base::TimeDelta uncertainty; + if (!network_time_tracker_->GetNetworkTime(TicksNow(), + &network_time, + &uncertainty)) + return testing::AssertionFailure() << "Failed to get network time."; + if (fabs(static_cast<double>(Now().ToInternalValue() - + network_time.ToInternalValue())) > + static_cast<double>(uncertainty.ToInternalValue())) { + return testing::AssertionFailure() + << "Expected network time not within uncertainty."; + } + return testing::AssertionSuccess(); + } + + NetworkTimeTracker* network_time_tracker() { + return network_time_tracker_.get(); + } + + private: + // Used in building the current time that TestTickClock reports. See Now() + // for details. + base::Time now_; + base::TimeTicks ticks_now_; + + TestingPrefServiceSimple pref_service_; + + // The network time tracker being tested. + scoped_ptr<NetworkTimeTracker> network_time_tracker_; +}; + +// Should not return a value before UpdateNetworkTime gets called. +TEST_F(NetworkTimeTrackerTest, Uninitialized) { + base::Time network_time; + base::TimeDelta uncertainty; + EXPECT_FALSE(network_time_tracker()->GetNetworkTime(base::TimeTicks(), + &network_time, + &uncertainty)); +} + +// Verify that the the tracker receives and properly handles updates to the +// network time. +TEST_F(NetworkTimeTrackerTest, NetworkTimeUpdates) { + UpdateNetworkTime( + Now(), + base::TimeDelta::FromMilliseconds(kResolution1), + base::TimeDelta::FromMilliseconds(kLatency1), + TicksNow()); + EXPECT_TRUE(ValidateExpectedTime()); + + // Fake a wait for kPseudoSleepTime1 to make sure we keep tracking. + AddToTicksNow(kPseudoSleepTime1); + EXPECT_TRUE(ValidateExpectedTime()); + + // Update the time with a new now value and kLatency2. + UpdateNetworkTime( + Now(), + base::TimeDelta::FromMilliseconds(kResolution2), + base::TimeDelta::FromMilliseconds(kLatency2), + TicksNow()); + + // Fake a wait for kPseudoSleepTime2 to make sure we keep tracking still. + AddToTicksNow(kPseudoSleepTime2); + EXPECT_TRUE(ValidateExpectedTime()); + + // Fake a long delay between update task post time and the network notifier + // updating its network time. The uncertainty should account for the + // disparity. + base::Time old_now = Now(); + base::TimeTicks old_ticks = TicksNow(); + AddToTicksNow(kPseudoSleepTime2); + UpdateNetworkTime( + old_now, + base::TimeDelta::FromMilliseconds(kResolution2), + base::TimeDelta::FromMilliseconds(kLatency2), + old_ticks); + EXPECT_TRUE(ValidateExpectedTime()); +} + +} // namespace network_time |