Chromium Code Reviews| 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..3a7886038b5d8d314304f01ea4836a07ae776f15 100644 |
| --- a/components/network_time/network_time_tracker_unittest.cc |
| +++ b/components/network_time/network_time_tracker_unittest.cc |
| @@ -5,12 +5,20 @@ |
| #include "components/network_time/network_time_tracker.h" |
| #include <memory> |
| +#include <utility> |
| #include "base/compiler_specific.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 +27,33 @@ 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); |
| } |
| + void TearDown() override { io_thread_.Stop(); } |
| + |
| // Replaces |tracker_| with a new object, while preserving the |
| // testing clocks. |
| void Reset() { |
| @@ -49,7 +65,78 @@ class NetworkTimeTrackerTest : public testing::Test { |
| 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, though made with a non-production key. |
|
mmenke
2016/05/06 15:00:37
"Good signature over invalid" seems a bit hard to
mab
2016/05/06 18:12:37
Done.
|
| + 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 +156,8 @@ class NetworkTimeTrackerTest : public testing::Test { |
| } |
| protected: |
| + base::Thread io_thread_; |
| + base::MessageLoop message_loop_; |
| base::TimeDelta resolution_; |
| base::TimeDelta latency_; |
| base::TimeDelta adjustment_; |
| @@ -76,6 +165,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 +221,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 +275,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 +285,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 +295,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 +327,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 +338,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 +348,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 +361,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 +375,127 @@ 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, 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 |