1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
// 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) {}
~TestTickClock() override {}
base::TimeTicks NowTicks() override { return *ticks_now_; }
private:
base::TimeTicks* ticks_now_;
};
} // namespace
class NetworkTimeTrackerTest : public testing::Test {
public:
~NetworkTimeTrackerTest() override {}
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
|