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..d79f3b93da79053fdf2a4a53e84249fac527282e 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/message_loop/message_loop.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,44 @@ 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() { |
Ryan Sleevi
2016/04/29 22:54:16
This naming isn't consistent with Chromium. Was th
mab
2016/04/29 23:30:09
... which I guess means this is unnecessary? :-/
|
+ if (test_server_->Started()) { |
+ ASSERT_TRUE(test_server_->ShutdownAndWaitUntilComplete()); |
+ } |
+ io_thread_.Stop(); |
+ } |
+ |
+ void WaitForFetch() { |
+ while (tracker_->time_fetcher_) { |
+ base::MessageLoop::current()->RunUntilIdle(); |
+ } |
+ } |
+ |
// Replaces |tracker_| with a new object, while preserving the |
// testing clocks. |
void Reset() { |
@@ -49,7 +77,58 @@ 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); |
+ } |
+ |
+ 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("foo"); |
+ 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> ErrorResponseHandler( |
+ 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); |
+ } |
+ |
+ // Helper for verifying signatures over time server responses. Sets the |
+ // client's internal nonce, which is normally randomly generated, to a |
+ // predictable value. |
+ void OverrideNonce(uint32_t nonce) { |
+ tracker_->query_signer_->request_query_cup2key_ = |
+ base::StringPrintf("%d:%u", 1 /* key version */, nonce); |
} |
// Updates the notifier's time with the specified parameters. |
@@ -69,6 +148,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 +157,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 +213,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 +267,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 +277,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 +287,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 +319,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 +330,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 +340,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 +353,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 +367,91 @@ 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_->SetTimeServerURL(test_server_->GetURL("/")); |
+ tracker_->QueryTimeService(); |
+ OverrideNonce(123123123); |
+ WaitForFetch(); |
+ |
+ 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_TRUE(tracker_->query_timer_.IsRunning()); |
+ EXPECT_EQ(base::TimeDelta::FromMinutes(60), |
+ tracker_->query_timer_.GetCurrentDelay()); |
+} |
+ |
+TEST_F(NetworkTimeTrackerTest, NoNetworkQueryWhileSynced) { |
+ base::Time in_network_time = clock_->Now(); |
+ UpdateNetworkTime(in_network_time, resolution_, latency_, |
+ tick_clock_->NowTicks()); |
+ tracker_->QueryTimeService(); |
+ EXPECT_EQ(nullptr, tracker_->time_fetcher_); // No query should be started. |
+} |
+ |
+TEST_F(NetworkTimeTrackerTest, UpdateFromNetworkBadSignature) { |
+ test_server_->RegisterRequestHandler( |
+ base::Bind(&NetworkTimeTrackerTest::BadSignatureResponseHandler)); |
+ EXPECT_TRUE(test_server_->Start()); |
+ tracker_->SetTimeServerURL(test_server_->GetURL("/")); |
+ tracker_->QueryTimeService(); |
+ OverrideNonce(123123123); |
+ WaitForFetch(); |
+ |
+ base::Time out_network_time; |
+ EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, nullptr)); |
+ EXPECT_TRUE(tracker_->query_timer_.IsRunning()); |
+} |
+ |
+TEST_F(NetworkTimeTrackerTest, UpdateFromNetworkServerError) { |
+ test_server_->RegisterRequestHandler( |
+ base::Bind(&NetworkTimeTrackerTest::ErrorResponseHandler)); |
+ EXPECT_TRUE(test_server_->Start()); |
+ tracker_->SetTimeServerURL(test_server_->GetURL("/")); |
+ tracker_->QueryTimeService(); |
+ WaitForFetch(); |
+ |
+ base::Time out_network_time; |
+ EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, nullptr)); |
+ // Should see backoff in the error case. |
+ EXPECT_TRUE(tracker_->query_timer_.IsRunning()); |
+ EXPECT_EQ(base::TimeDelta::FromMinutes(120), |
+ tracker_->query_timer_.GetCurrentDelay()); |
+} |
+ |
+TEST_F(NetworkTimeTrackerTest, UpdateFromNetworkLargeResponse) { |
+ test_server_->RegisterRequestHandler( |
+ base::Bind(&NetworkTimeTrackerTest::GoodTimeResponseHandler)); |
+ EXPECT_TRUE(test_server_->Start()); |
+ tracker_->SetTimeServerURL(test_server_->GetURL("/")); |
+ |
+ base::Time out_network_time; |
+ |
+ tracker_->SetMaxResponseSize(3); |
+ tracker_->QueryTimeService(); |
+ OverrideNonce(123123123); |
+ WaitForFetch(); |
+ EXPECT_FALSE(tracker_->GetNetworkTime(&out_network_time, nullptr)); |
+ |
+ tracker_->SetMaxResponseSize(1024); |
+ tracker_->QueryTimeService(); |
+ OverrideNonce(123123123); |
+ WaitForFetch(); |
+ EXPECT_TRUE(tracker_->GetNetworkTime(&out_network_time, nullptr)); |
} |
} // namespace network_time |