| Index: components/network_time/network_time_tracker_unittest.cc
|
| diff --git a/components/network_time/network_time_tracker_unittest.cc b/components/network_time/network_time_tracker_unittest.cc
|
| index b42196cf0183b723eee4eacfd22071c2ca25ff5a..6b7d75da86e549e1d813cc861938764096e8d5b3 100644
|
| --- a/components/network_time/network_time_tracker_unittest.cc
|
| +++ b/components/network_time/network_time_tracker_unittest.cc
|
| @@ -5,12 +5,21 @@
|
| #include "components/network_time/network_time_tracker.h"
|
|
|
| #include <memory>
|
| +#include <utility>
|
|
|
| #include "base/compiler_specific.h"
|
| +#include "base/feature_list.h"
|
| +#include "base/strings/stringprintf.h"
|
| #include "base/test/simple_test_clock.h"
|
| #include "base/test/simple_test_tick_clock.h"
|
| +#include "components/client_update_protocol/ecdsa.h"
|
| #include "components/network_time/network_time_pref_names.h"
|
| #include "components/prefs/testing_pref_service.h"
|
| +#include "net/http/http_response_headers.h"
|
| +#include "net/test/embedded_test_server/embedded_test_server.h"
|
| +#include "net/test/embedded_test_server/http_response.h"
|
| +#include "net/url_request/url_fetcher.h"
|
| +#include "net/url_request/url_request_test_util.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| namespace network_time {
|
| @@ -19,25 +28,35 @@ class NetworkTimeTrackerTest : public testing::Test {
|
| public:
|
| ~NetworkTimeTrackerTest() override {}
|
|
|
| - void SetUp() override {
|
| + NetworkTimeTrackerTest()
|
| + : io_thread_("IO thread"),
|
| + clock_(new base::SimpleTestClock),
|
| + tick_clock_(new base::SimpleTestTickClock),
|
| + test_server_(new net::EmbeddedTestServer) {
|
| + base::Thread::Options thread_options;
|
| + thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
|
| + EXPECT_TRUE(io_thread_.StartWithOptions(thread_options));
|
| NetworkTimeTracker::RegisterPrefs(pref_service_.registry());
|
|
|
| - clock_ = new base::SimpleTestClock();
|
| - tick_clock_ = new base::SimpleTestTickClock();
|
| + tracker_.reset(new NetworkTimeTracker(
|
| + std::unique_ptr<base::Clock>(clock_),
|
| + std::unique_ptr<base::TickClock>(tick_clock_), &pref_service_,
|
| + new net::TestURLRequestContextGetter(io_thread_.task_runner())));
|
| +
|
| // Do this to be sure that |is_null| returns false.
|
| clock_->Advance(base::TimeDelta::FromDays(111));
|
| tick_clock_->Advance(base::TimeDelta::FromDays(222));
|
|
|
| - tracker_.reset(new NetworkTimeTracker(
|
| - std::unique_ptr<base::Clock>(clock_),
|
| - std::unique_ptr<base::TickClock>(tick_clock_), &pref_service_));
|
| -
|
| // Can not be smaller than 15, it's the NowFromSystemTime() resolution.
|
| resolution_ = base::TimeDelta::FromMilliseconds(17);
|
| latency_ = base::TimeDelta::FromMilliseconds(50);
|
| adjustment_ = 7 * base::TimeDelta::FromMilliseconds(kTicksResolutionMs);
|
| +
|
| + SetNetworkQueriesWithFinch(true);
|
| }
|
|
|
| + void TearDown() override { io_thread_.Stop(); }
|
| +
|
| // Replaces |tracker_| with a new object, while preserving the
|
| // testing clocks.
|
| void Reset() {
|
| @@ -46,10 +65,81 @@ class NetworkTimeTrackerTest : public testing::Test {
|
| base::SimpleTestTickClock* new_tick_clock = new base::SimpleTestTickClock();
|
| new_tick_clock->SetNowTicks(tick_clock_->NowTicks());
|
| clock_ = new_clock;
|
| - tick_clock_= new_tick_clock;
|
| + tick_clock_ = new_tick_clock;
|
| tracker_.reset(new NetworkTimeTracker(
|
| std::unique_ptr<base::Clock>(clock_),
|
| - std::unique_ptr<base::TickClock>(tick_clock_), &pref_service_));
|
| + std::unique_ptr<base::TickClock>(tick_clock_), &pref_service_,
|
| + new net::TestURLRequestContextGetter(io_thread_.task_runner())));
|
| + }
|
| +
|
| + // Returns a valid time response. Update as follows:
|
| + //
|
| + // curl http://clients2.google.com/time/1/current?cup2key=1:123123123
|
| + //
|
| + // where 1 is the key version and 123123123 is the nonce. Copy the nonce, the
|
| + // response, and the x-cup-server-proof header into the test.
|
| + static std::unique_ptr<net::test_server::HttpResponse>
|
| + GoodTimeResponseHandler(const net::test_server::HttpRequest& request) {
|
| + net::test_server::BasicHttpResponse* response =
|
| + new net::test_server::BasicHttpResponse();
|
| + response->set_code(net::HTTP_OK);
|
| + response->set_content(
|
| + ")]}'\n"
|
| + "{\"current_time_millis\":1461621971825,\"server_nonce\":-6."
|
| + "006853099049523E85}");
|
| + response->AddCustomHeader(
|
| + "x-cup-server-proof",
|
| + "304402202e0f24db1ea69f1bbe81da4108f381fcf7a2781c53cf7663cb47083cb5fe8e"
|
| + "fd"
|
| + "022009d2b67c0deceaaf849f7c529be96701ed5f15d5efcaf401a94e0801accc9832:"
|
| + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
|
| + return std::unique_ptr<net::test_server::HttpResponse>(response);
|
| + }
|
| +
|
| + // Good signature over invalid data, though made with a non-production key.
|
| + static std::unique_ptr<net::test_server::HttpResponse> BadDataResponseHandler(
|
| + const net::test_server::HttpRequest& request) {
|
| + net::test_server::BasicHttpResponse* response =
|
| + new net::test_server::BasicHttpResponse();
|
| + response->set_code(net::HTTP_OK);
|
| + response->set_content(
|
| + ")]}'\n"
|
| + "{\"current_time_millis\":NaN,\"server_nonce\":9.420921002039447E182}");
|
| + response->AddCustomHeader(
|
| + "x-cup-server-proof",
|
| + "3046022100a07aa437b24f1f6bb7ff6f6d1e004dd4bcb717c93e21d6bae5ef8d6d984c"
|
| + "86a7022100e423419ff49fae37b421ef6cdeab348b45c63b236ab365f36f4cd3b4d4d6"
|
| + "d852:"
|
| + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85"
|
| + "5");
|
| + return std::unique_ptr<net::test_server::HttpResponse>(response);
|
| + }
|
| +
|
| + static std::unique_ptr<net::test_server::HttpResponse>
|
| + BadSignatureResponseHandler(const net::test_server::HttpRequest& request) {
|
| + net::test_server::BasicHttpResponse* response =
|
| + new net::test_server::BasicHttpResponse();
|
| + response->set_code(net::HTTP_OK);
|
| + response->set_content(
|
| + ")]}'\n"
|
| + "{\"current_time_millis\":1461621971825,\"server_nonce\":-6."
|
| + "006853099049523E85}");
|
| + response->AddCustomHeader("x-cup-server-proof", "dead:beef");
|
| + return std::unique_ptr<net::test_server::HttpResponse>(response);
|
| + }
|
| +
|
| + static std::unique_ptr<net::test_server::HttpResponse>
|
| + ServerErrorResponseHandler(const net::test_server::HttpRequest& request) {
|
| + net::test_server::BasicHttpResponse* response =
|
| + new net::test_server::BasicHttpResponse();
|
| + response->set_code(net::HTTP_INTERNAL_SERVER_ERROR);
|
| + return std::unique_ptr<net::test_server::HttpResponse>(response);
|
| + }
|
| +
|
| + static std::unique_ptr<net::test_server::HttpResponse>
|
| + NetworkErrorResponseHandler(const net::test_server::HttpRequest& request) {
|
| + return std::unique_ptr<net::test_server::HttpResponse>(
|
| + new net::test_server::RawHttpResponse("", ""));
|
| }
|
|
|
| // Updates the notifier's time with the specified parameters.
|
| @@ -69,6 +159,17 @@ class NetworkTimeTrackerTest : public testing::Test {
|
| }
|
|
|
| protected:
|
| + void SetNetworkQueriesWithFinch(bool enable) {
|
| + base::FeatureList::ClearInstanceForTesting();
|
| + std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
|
| + if (enable) {
|
| + feature_list->InitializeFromCommandLine("NetworkTimeServiceQuerying", "");
|
| + }
|
| + base::FeatureList::SetInstance(std::move(feature_list));
|
| + }
|
| +
|
| + base::Thread io_thread_;
|
| + base::MessageLoop message_loop_;
|
| base::TimeDelta resolution_;
|
| base::TimeDelta latency_;
|
| base::TimeDelta adjustment_;
|
| @@ -76,6 +177,7 @@ class NetworkTimeTrackerTest : public testing::Test {
|
| base::SimpleTestTickClock* tick_clock_;
|
| TestingPrefServiceSimple pref_service_;
|
| std::unique_ptr<NetworkTimeTracker> tracker_;
|
| + std::unique_ptr<net::EmbeddedTestServer> test_server_;
|
| };
|
|
|
| TEST_F(NetworkTimeTrackerTest, Uninitialized) {
|
| @@ -131,7 +233,7 @@ TEST_F(NetworkTimeTrackerTest, ClockIsWack) {
|
| tick_clock_->NowTicks());
|
|
|
| base::Time out_network_time;
|
| - EXPECT_TRUE(tracker_->GetNetworkTime(&out_network_time, NULL));
|
| + EXPECT_TRUE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| EXPECT_EQ(in_network_time, out_network_time);
|
| }
|
|
|
| @@ -185,7 +287,7 @@ TEST_F(NetworkTimeTrackerTest, SpringForward) {
|
| tick_clock_->Advance(base::TimeDelta::FromSeconds(1));
|
| clock_->Advance(base::TimeDelta::FromDays(1));
|
| base::Time out_network_time;
|
| - EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, NULL));
|
| + EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| }
|
|
|
| TEST_F(NetworkTimeTrackerTest, FallBack) {
|
| @@ -195,7 +297,7 @@ TEST_F(NetworkTimeTrackerTest, FallBack) {
|
| tick_clock_->Advance(base::TimeDelta::FromSeconds(1));
|
| clock_->Advance(base::TimeDelta::FromDays(-1));
|
| base::Time out_network_time;
|
| - EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, NULL));
|
| + EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| }
|
|
|
| TEST_F(NetworkTimeTrackerTest, SuspendAndResume) {
|
| @@ -205,7 +307,7 @@ TEST_F(NetworkTimeTrackerTest, SuspendAndResume) {
|
| tick_clock_->NowTicks());
|
| clock_->Advance(base::TimeDelta::FromHours(1));
|
| base::Time out_network_time;
|
| - EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, NULL));
|
| + EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| }
|
|
|
| TEST_F(NetworkTimeTrackerTest, Serialize) {
|
| @@ -237,7 +339,7 @@ TEST_F(NetworkTimeTrackerTest, DeserializeOldFormat) {
|
| tick_clock_->NowTicks());
|
|
|
| base::Time out_network_time;
|
| - EXPECT_TRUE(tracker_->GetNetworkTime(&out_network_time, NULL));
|
| + EXPECT_TRUE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| double local, network;
|
| const base::DictionaryValue* saved_prefs =
|
| pref_service_.GetDictionary(prefs::kNetworkTimeMapping);
|
| @@ -248,7 +350,7 @@ TEST_F(NetworkTimeTrackerTest, DeserializeOldFormat) {
|
| prefs.SetDouble("network", network);
|
| pref_service_.Set(prefs::kNetworkTimeMapping, prefs);
|
| Reset();
|
| - EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, NULL));
|
| + EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| }
|
|
|
| TEST_F(NetworkTimeTrackerTest, SerializeWithLongDelay) {
|
| @@ -258,10 +360,10 @@ TEST_F(NetworkTimeTrackerTest, SerializeWithLongDelay) {
|
| UpdateNetworkTime(in_network_time - latency_ / 2, resolution_, latency_,
|
| tick_clock_->NowTicks());
|
| base::Time out_network_time;
|
| - EXPECT_TRUE(tracker_->GetNetworkTime(&out_network_time, NULL));
|
| + EXPECT_TRUE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| AdvanceBoth(base::TimeDelta::FromDays(8));
|
| Reset();
|
| - EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, NULL));
|
| + EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| }
|
|
|
| TEST_F(NetworkTimeTrackerTest, SerializeWithTickClockAdvance) {
|
| @@ -271,10 +373,10 @@ TEST_F(NetworkTimeTrackerTest, SerializeWithTickClockAdvance) {
|
| UpdateNetworkTime(in_network_time - latency_ / 2, resolution_, latency_,
|
| tick_clock_->NowTicks());
|
| base::Time out_network_time;
|
| - EXPECT_TRUE(tracker_->GetNetworkTime(&out_network_time, NULL));
|
| + EXPECT_TRUE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| tick_clock_->Advance(base::TimeDelta::FromDays(1));
|
| Reset();
|
| - EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, NULL));
|
| + EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| }
|
|
|
| TEST_F(NetworkTimeTrackerTest, SerializeWithWallClockAdvance) {
|
| @@ -285,10 +387,138 @@ TEST_F(NetworkTimeTrackerTest, SerializeWithWallClockAdvance) {
|
| tick_clock_->NowTicks());
|
|
|
| base::Time out_network_time;
|
| - EXPECT_TRUE(tracker_->GetNetworkTime(&out_network_time, NULL));
|
| + EXPECT_TRUE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| clock_->Advance(base::TimeDelta::FromDays(1));
|
| Reset();
|
| - EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, NULL));
|
| + EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| +}
|
| +
|
| +TEST_F(NetworkTimeTrackerTest, UpdateFromNetwork) {
|
| + base::Time out_network_time;
|
| + EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| +
|
| + test_server_->RegisterRequestHandler(
|
| + base::Bind(&NetworkTimeTrackerTest::GoodTimeResponseHandler));
|
| + EXPECT_TRUE(test_server_->Start());
|
| + tracker_->SetTimeServerURLForTesting(test_server_->GetURL("/"));
|
| + EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
|
| + tracker_->WaitForFetchForTesting(123123123);
|
| +
|
| + EXPECT_TRUE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| + EXPECT_EQ(base::Time::UnixEpoch() +
|
| + base::TimeDelta::FromMilliseconds(1461621971825),
|
| + out_network_time);
|
| + // Should see no backoff in the success case.
|
| + EXPECT_EQ(base::TimeDelta::FromMinutes(60),
|
| + tracker_->GetTimerDelayForTesting());
|
| +}
|
| +
|
| +TEST_F(NetworkTimeTrackerTest, NoNetworkQueryWhileSynced) {
|
| + base::Time in_network_time = clock_->Now();
|
| + UpdateNetworkTime(in_network_time, resolution_, latency_,
|
| + tick_clock_->NowTicks());
|
| + EXPECT_FALSE(
|
| + tracker_->QueryTimeServiceForTesting()); // No query should be started.
|
| +}
|
| +
|
| +TEST_F(NetworkTimeTrackerTest, NoNetworkQueryWhileFeatureDisabled) {
|
| + // Disable network time queries and check that a query is not sent.
|
| + SetNetworkQueriesWithFinch(false);
|
| + EXPECT_FALSE(tracker_->QueryTimeServiceForTesting());
|
| +
|
| + // Enable time queries and check that a query is sent.
|
| + SetNetworkQueriesWithFinch(true);
|
| + EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
|
| + tracker_->WaitForFetchForTesting(123123123);
|
| +}
|
| +
|
| +TEST_F(NetworkTimeTrackerTest, UpdateFromNetworkBadSignature) {
|
| + test_server_->RegisterRequestHandler(
|
| + base::Bind(&NetworkTimeTrackerTest::BadSignatureResponseHandler));
|
| + EXPECT_TRUE(test_server_->Start());
|
| + tracker_->SetTimeServerURLForTesting(test_server_->GetURL("/"));
|
| + EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
|
| + tracker_->WaitForFetchForTesting(123123123);
|
| +
|
| + base::Time out_network_time;
|
| + EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| + EXPECT_EQ(base::TimeDelta::FromMinutes(120),
|
| + tracker_->GetTimerDelayForTesting());
|
| +}
|
| +
|
| +static const uint8_t kDevKeyPubBytes[] = {
|
| + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
|
| + 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
|
| + 0x42, 0x00, 0x04, 0xe0, 0x6b, 0x0d, 0x76, 0x75, 0xa3, 0x99, 0x7d, 0x7c,
|
| + 0x1b, 0xd6, 0x3c, 0x73, 0xbb, 0x4b, 0xfe, 0x0a, 0xe7, 0x2f, 0x61, 0x3d,
|
| + 0x77, 0x0a, 0xaa, 0x14, 0xd8, 0x5a, 0xbf, 0x14, 0x60, 0xec, 0xf6, 0x32,
|
| + 0x77, 0xb5, 0xa7, 0xe6, 0x35, 0xa5, 0x61, 0xaf, 0xdc, 0xdf, 0x91, 0xce,
|
| + 0x45, 0x34, 0x5f, 0x36, 0x85, 0x2f, 0xb9, 0x53, 0x00, 0x5d, 0x86, 0xe7,
|
| + 0x04, 0x16, 0xe2, 0x3d, 0x21, 0x76, 0x2b};
|
| +
|
| +TEST_F(NetworkTimeTrackerTest, UpdateFromNetworkBadData) {
|
| + test_server_->RegisterRequestHandler(
|
| + base::Bind(&NetworkTimeTrackerTest::BadDataResponseHandler));
|
| + EXPECT_TRUE(test_server_->Start());
|
| + base::StringPiece key = {reinterpret_cast<const char*>(kDevKeyPubBytes),
|
| + sizeof(kDevKeyPubBytes)};
|
| + tracker_->SetPublicKeyForTesting(key);
|
| + tracker_->SetTimeServerURLForTesting(test_server_->GetURL("/"));
|
| + EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
|
| + tracker_->WaitForFetchForTesting(123123123);
|
| + base::Time out_network_time;
|
| + EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| + EXPECT_EQ(base::TimeDelta::FromMinutes(120),
|
| + tracker_->GetTimerDelayForTesting());
|
| +}
|
| +
|
| +TEST_F(NetworkTimeTrackerTest, UpdateFromNetworkServerError) {
|
| + test_server_->RegisterRequestHandler(
|
| + base::Bind(&NetworkTimeTrackerTest::ServerErrorResponseHandler));
|
| + EXPECT_TRUE(test_server_->Start());
|
| + tracker_->SetTimeServerURLForTesting(test_server_->GetURL("/"));
|
| + EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
|
| + tracker_->WaitForFetchForTesting(123123123);
|
| +
|
| + base::Time out_network_time;
|
| + EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| + // Should see backoff in the error case.
|
| + EXPECT_EQ(base::TimeDelta::FromMinutes(120),
|
| + tracker_->GetTimerDelayForTesting());
|
| +}
|
| +
|
| +TEST_F(NetworkTimeTrackerTest, UpdateFromNetworNetworkError) {
|
| + test_server_->RegisterRequestHandler(
|
| + base::Bind(&NetworkTimeTrackerTest::NetworkErrorResponseHandler));
|
| + EXPECT_TRUE(test_server_->Start());
|
| + tracker_->SetTimeServerURLForTesting(test_server_->GetURL("/"));
|
| + EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
|
| + tracker_->WaitForFetchForTesting(123123123);
|
| +
|
| + base::Time out_network_time;
|
| + EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| + // Should see backoff in the error case.
|
| + EXPECT_EQ(base::TimeDelta::FromMinutes(120),
|
| + tracker_->GetTimerDelayForTesting());
|
| +}
|
| +
|
| +TEST_F(NetworkTimeTrackerTest, UpdateFromNetworkLargeResponse) {
|
| + test_server_->RegisterRequestHandler(
|
| + base::Bind(&NetworkTimeTrackerTest::GoodTimeResponseHandler));
|
| + EXPECT_TRUE(test_server_->Start());
|
| + tracker_->SetTimeServerURLForTesting(test_server_->GetURL("/"));
|
| +
|
| + base::Time out_network_time;
|
| +
|
| + tracker_->SetMaxResponseSizeForTesting(3);
|
| + EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
|
| + tracker_->WaitForFetchForTesting(123123123);
|
| + EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| +
|
| + tracker_->SetMaxResponseSizeForTesting(1024);
|
| + EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
|
| + tracker_->WaitForFetchForTesting(123123123);
|
| + EXPECT_TRUE(tracker_->GetNetworkTime(&out_network_time, nullptr));
|
| }
|
|
|
| } // namespace network_time
|
|
|