network_time_tracker_unittest.cc 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/network_time/network_time_tracker.h"
  5. #include <memory>
  6. #include <string>
  7. #include <utility>
  8. #include "base/bind.h"
  9. #include "base/callback_forward.h"
  10. #include "base/compiler_specific.h"
  11. #include "base/memory/raw_ptr.h"
  12. #include "base/run_loop.h"
  13. #include "base/test/metrics/histogram_tester.h"
  14. #include "base/test/simple_test_clock.h"
  15. #include "base/test/simple_test_tick_clock.h"
  16. #include "base/test/task_environment.h"
  17. #include "base/time/time.h"
  18. #include "build/build_config.h"
  19. #include "components/client_update_protocol/ecdsa.h"
  20. #include "components/network_time/network_time_pref_names.h"
  21. #include "components/network_time/network_time_test_utils.h"
  22. #include "components/prefs/testing_pref_service.h"
  23. #include "net/http/http_response_headers.h"
  24. #include "net/test/embedded_test_server/embedded_test_server.h"
  25. #include "net/test/embedded_test_server/http_response.h"
  26. #include "services/network/public/cpp/resource_request.h"
  27. #include "services/network/public/cpp/url_loader_completion_status.h"
  28. #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
  29. #include "services/network/public/mojom/url_response_head.mojom.h"
  30. #include "services/network/test/test_shared_url_loader_factory.h"
  31. #include "services/network/test/test_url_loader_factory.h"
  32. #include "services/network/test/test_utils.h"
  33. #include "testing/gtest/include/gtest/gtest.h"
  34. namespace network_time {
  35. namespace {
  36. const uint32_t kOneDayInSeconds = 86400;
  37. const char kFetchFailedHistogram[] = "NetworkTimeTracker.UpdateTimeFetchFailed";
  38. const char kFetchValidHistogram[] = "NetworkTimeTracker.UpdateTimeFetchValid";
  39. const char kClockDivergencePositiveHistogram[] =
  40. "NetworkTimeTracker.ClockDivergence.Positive";
  41. const char kClockDivergenceNegativeHistogram[] =
  42. "NetworkTimeTracker.ClockDivergence.Negative";
  43. const char kWallClockBackwardsHistogram[] =
  44. "NetworkTimeTracker.WallClockRanBackwards";
  45. const char kTimeBetweenFetchesHistogram[] =
  46. "NetworkTimeTracker.TimeBetweenFetches";
  47. // Latencies simulated by the fake network responses for the network times. This
  48. // array should have the same length as `kGoodTimeResponseBody`.
  49. const base::TimeDelta kGoodTimeResponseLatency[] = {
  50. base::Milliseconds(500), base::Milliseconds(520), base::Milliseconds(450),
  51. base::Milliseconds(550), base::Milliseconds(480),
  52. };
  53. struct MockedResponse {
  54. network::mojom::URLResponseHeadPtr head;
  55. std::string body;
  56. network::URLLoaderCompletionStatus status;
  57. };
  58. } // namespace
  59. class NetworkTimeTrackerTest : public ::testing::Test {
  60. public:
  61. ~NetworkTimeTrackerTest() override {}
  62. NetworkTimeTrackerTest()
  63. : task_environment_(
  64. base::test::SingleThreadTaskEnvironment::MainThreadType::IO),
  65. field_trial_test_(new FieldTrialTest()),
  66. clock_(new base::SimpleTestClock),
  67. tick_clock_(new base::SimpleTestTickClock) {
  68. NetworkTimeTracker::RegisterPrefs(pref_service_.registry());
  69. field_trial_test_->SetFeatureParams(
  70. true, 0.0 /* query probability */,
  71. NetworkTimeTracker::FETCHES_IN_BACKGROUND_AND_ON_DEMAND,
  72. NetworkTimeTracker::ClockDriftSamples::NO_SAMPLES);
  73. url_loader_factory_.SetInterceptor(base::BindRepeating(
  74. &NetworkTimeTrackerTest::Intercept, weak_ptr_factory_.GetWeakPtr()));
  75. tracker_ = std::make_unique<NetworkTimeTracker>(
  76. std::unique_ptr<base::Clock>(clock_),
  77. std::unique_ptr<const base::TickClock>(tick_clock_), &pref_service_,
  78. base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
  79. &url_loader_factory_));
  80. // Do this to be sure that |is_null| returns false.
  81. clock_->Advance(base::Days(111));
  82. tick_clock_->Advance(base::Days(222));
  83. // Can not be smaller than 15, it's the NowFromSystemTime() resolution.
  84. resolution_ = base::Milliseconds(17);
  85. latency_ = base::Milliseconds(50);
  86. adjustment_ = 7 * base::Milliseconds(kTicksResolutionMs);
  87. }
  88. // Sets `response_handler` as handler for all requests made through
  89. // `url_loader_factory_`.
  90. void SetResponseHandler(
  91. base::RepeatingCallback<MockedResponse()> response_handler) {
  92. response_handler_ = std::move(response_handler);
  93. }
  94. // Replaces |tracker_| with a new object, while preserving the
  95. // testing clocks.
  96. void Reset() {
  97. base::SimpleTestClock* new_clock = new base::SimpleTestClock();
  98. new_clock->SetNow(clock_->Now());
  99. base::SimpleTestTickClock* new_tick_clock = new base::SimpleTestTickClock();
  100. new_tick_clock->SetNowTicks(tick_clock_->NowTicks());
  101. clock_ = new_clock;
  102. tick_clock_ = new_tick_clock;
  103. tracker_ = std::make_unique<NetworkTimeTracker>(
  104. std::unique_ptr<base::Clock>(clock_),
  105. std::unique_ptr<const base::TickClock>(tick_clock_), &pref_service_,
  106. base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
  107. &url_loader_factory_));
  108. }
  109. // Good signature over invalid data, though made with a non-production key.
  110. static MockedResponse BadDataResponseHandler() {
  111. network::mojom::URLResponseHeadPtr head =
  112. network::CreateURLResponseHead(net::HTTP_OK);
  113. std::string body =
  114. ")]}'\n"
  115. "{\"current_time_millis\":NaN,\"server_nonce\":9.420921002039447E182}";
  116. head->headers->AddHeader(
  117. "x-cup-server-proof",
  118. "3046022100a07aa437b24f1f6bb7ff6f6d1e004dd4bcb717c93e21d6bae5ef8d6d984c"
  119. "86a7022100e423419ff49fae37b421ef6cdeab348b45c63b236ab365f36f4cd3b4d4d6"
  120. "d852:"
  121. "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85"
  122. "5");
  123. return MockedResponse{std::move(head), std::move(body)};
  124. }
  125. static MockedResponse GoodTimeResponseHandler() {
  126. network::mojom::URLResponseHeadPtr head =
  127. network::CreateURLResponseHead(net::HTTP_OK);
  128. head->headers->AddHeader("x-cup-server-proof",
  129. kGoodTimeResponseServerProofHeader[0]);
  130. return MockedResponse{std::move(head), kGoodTimeResponseBody[0]};
  131. }
  132. static MockedResponse BadSignatureResponseHandler() {
  133. network::mojom::URLResponseHeadPtr head =
  134. network::CreateURLResponseHead(net::HTTP_OK);
  135. std::string body =
  136. ")]}'\n"
  137. "{\"current_time_millis\":1461621971825,\"server_nonce\":-6."
  138. "006853099049523E85}";
  139. head->headers->AddHeader("x-cup-server-proof", "dead:beef");
  140. return MockedResponse{std::move(head), std::move(body)};
  141. }
  142. static MockedResponse ServerErrorResponseHandler() {
  143. network::mojom::URLResponseHeadPtr head =
  144. network::CreateURLResponseHead(net::HTTP_INTERNAL_SERVER_ERROR);
  145. return MockedResponse{std::move(head), ""};
  146. }
  147. static MockedResponse NetworkErrorResponseHandler() {
  148. network::mojom::URLResponseHeadPtr head =
  149. network::mojom::URLResponseHead::New();
  150. return MockedResponse{
  151. std::move(head), "",
  152. network::URLLoaderCompletionStatus(net::ERR_EMPTY_RESPONSE)};
  153. }
  154. // Updates the notifier's time with the specified parameters.
  155. void UpdateNetworkTime(const base::Time& network_time,
  156. const base::TimeDelta& resolution,
  157. const base::TimeDelta& latency,
  158. const base::TimeTicks& post_time) {
  159. tracker_->UpdateNetworkTime(
  160. network_time, resolution, latency, post_time);
  161. }
  162. // Advances both the system clock and the tick clock. This should be used for
  163. // the normal passage of time, i.e. when neither clock is doing anything odd.
  164. void AdvanceBoth(const base::TimeDelta& delta) {
  165. tick_clock_->Advance(delta);
  166. clock_->Advance(delta);
  167. }
  168. protected:
  169. base::test::SingleThreadTaskEnvironment task_environment_;
  170. std::unique_ptr<FieldTrialTest> field_trial_test_;
  171. base::TimeDelta resolution_;
  172. base::TimeDelta latency_;
  173. base::TimeDelta adjustment_;
  174. raw_ptr<base::SimpleTestClock> clock_;
  175. raw_ptr<base::SimpleTestTickClock> tick_clock_;
  176. TestingPrefServiceSimple pref_service_;
  177. std::unique_ptr<NetworkTimeTracker> tracker_;
  178. network::TestURLLoaderFactory url_loader_factory_;
  179. base::RepeatingCallback<MockedResponse()> response_handler_;
  180. private:
  181. void Intercept(const network::ResourceRequest& request) {
  182. CHECK(response_handler_);
  183. MockedResponse response = response_handler_.Run();
  184. // status.decoded_body_length = response.body.size();
  185. url_loader_factory_.AddResponse(request.url, std::move(response.head),
  186. std::move(response.body),
  187. std::move(response.status));
  188. }
  189. base::WeakPtrFactory<NetworkTimeTrackerTest> weak_ptr_factory_{this};
  190. };
  191. TEST_F(NetworkTimeTrackerTest, Uninitialized) {
  192. base::Time network_time;
  193. base::TimeDelta uncertainty;
  194. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_NO_SYNC_ATTEMPT,
  195. tracker_->GetNetworkTime(&network_time, &uncertainty));
  196. }
  197. TEST_F(NetworkTimeTrackerTest, LongPostingDelay) {
  198. // The request arrives at the server, which records the time. Advance the
  199. // clock to simulate the latency of sending the reply, which we'll say for
  200. // convenience is half the total latency.
  201. base::Time in_network_time = clock_->Now();
  202. AdvanceBoth(latency_ / 2);
  203. // Record the tick counter at the time the reply is received. At this point,
  204. // we would post UpdateNetworkTime to be run on the browser thread.
  205. base::TimeTicks posting_time = tick_clock_->NowTicks();
  206. // Simulate that it look a long time (1888us) for the browser thread to get
  207. // around to executing the update.
  208. AdvanceBoth(base::Microseconds(1888));
  209. UpdateNetworkTime(in_network_time, resolution_, latency_, posting_time);
  210. base::Time out_network_time;
  211. base::TimeDelta uncertainty;
  212. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  213. tracker_->GetNetworkTime(&out_network_time, &uncertainty));
  214. EXPECT_EQ(resolution_ + latency_ + adjustment_, uncertainty);
  215. EXPECT_EQ(clock_->Now(), out_network_time);
  216. }
  217. TEST_F(NetworkTimeTrackerTest, LopsidedLatency) {
  218. // Simulate that the server received the request instantaneously, and that all
  219. // of the latency was in sending the reply. (This contradicts the assumption
  220. // in the code.)
  221. base::Time in_network_time = clock_->Now();
  222. AdvanceBoth(latency_);
  223. UpdateNetworkTime(in_network_time, resolution_, latency_,
  224. tick_clock_->NowTicks());
  225. // But, the answer is still within the uncertainty bounds!
  226. base::Time out_network_time;
  227. base::TimeDelta uncertainty;
  228. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  229. tracker_->GetNetworkTime(&out_network_time, &uncertainty));
  230. EXPECT_LT(out_network_time - uncertainty / 2, clock_->Now());
  231. EXPECT_GT(out_network_time + uncertainty / 2, clock_->Now());
  232. }
  233. TEST_F(NetworkTimeTrackerTest, ClockIsWack) {
  234. // Now let's assume the system clock is completely wrong.
  235. base::Time in_network_time = clock_->Now() - base::Days(90);
  236. UpdateNetworkTime(in_network_time - latency_ / 2, resolution_, latency_,
  237. tick_clock_->NowTicks());
  238. base::Time out_network_time;
  239. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  240. tracker_->GetNetworkTime(&out_network_time, nullptr));
  241. EXPECT_EQ(in_network_time, out_network_time);
  242. }
  243. TEST_F(NetworkTimeTrackerTest, ClocksDivergeSlightly) {
  244. // The two clocks are allowed to diverge a little bit.
  245. base::HistogramTester histograms;
  246. histograms.ExpectTotalCount(kClockDivergencePositiveHistogram, 0);
  247. histograms.ExpectTotalCount(kClockDivergenceNegativeHistogram, 0);
  248. histograms.ExpectTotalCount(kWallClockBackwardsHistogram, 0);
  249. base::Time in_network_time = clock_->Now();
  250. UpdateNetworkTime(in_network_time - latency_ / 2, resolution_, latency_,
  251. tick_clock_->NowTicks());
  252. base::TimeDelta small = base::Seconds(30);
  253. tick_clock_->Advance(small);
  254. base::Time out_network_time;
  255. base::TimeDelta out_uncertainty;
  256. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  257. tracker_->GetNetworkTime(&out_network_time, &out_uncertainty));
  258. EXPECT_EQ(in_network_time + small, out_network_time);
  259. // The clock divergence should show up in the uncertainty.
  260. EXPECT_EQ(resolution_ + latency_ + adjustment_ + small, out_uncertainty);
  261. histograms.ExpectTotalCount(kClockDivergencePositiveHistogram, 0);
  262. histograms.ExpectTotalCount(kClockDivergenceNegativeHistogram, 0);
  263. histograms.ExpectTotalCount(kWallClockBackwardsHistogram, 0);
  264. }
  265. TEST_F(NetworkTimeTrackerTest, NetworkTimeUpdates) {
  266. // Verify that the the tracker receives and properly handles updates to the
  267. // network time.
  268. base::Time out_network_time;
  269. base::TimeDelta uncertainty;
  270. UpdateNetworkTime(clock_->Now() - latency_ / 2, resolution_, latency_,
  271. tick_clock_->NowTicks());
  272. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  273. tracker_->GetNetworkTime(&out_network_time, &uncertainty));
  274. EXPECT_EQ(clock_->Now(), out_network_time);
  275. EXPECT_EQ(resolution_ + latency_ + adjustment_, uncertainty);
  276. // Fake a wait to make sure we keep tracking.
  277. AdvanceBoth(base::Seconds(1));
  278. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  279. tracker_->GetNetworkTime(&out_network_time, &uncertainty));
  280. EXPECT_EQ(clock_->Now(), out_network_time);
  281. EXPECT_EQ(resolution_ + latency_ + adjustment_, uncertainty);
  282. // And one more time.
  283. UpdateNetworkTime(clock_->Now() - latency_ / 2, resolution_, latency_,
  284. tick_clock_->NowTicks());
  285. AdvanceBoth(base::Seconds(1));
  286. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  287. tracker_->GetNetworkTime(&out_network_time, &uncertainty));
  288. EXPECT_EQ(clock_->Now(), out_network_time);
  289. EXPECT_EQ(resolution_ + latency_ + adjustment_, uncertainty);
  290. }
  291. TEST_F(NetworkTimeTrackerTest, SpringForward) {
  292. base::HistogramTester histograms;
  293. histograms.ExpectTotalCount(kClockDivergencePositiveHistogram, 0);
  294. histograms.ExpectTotalCount(kClockDivergenceNegativeHistogram, 0);
  295. histograms.ExpectTotalCount(kWallClockBackwardsHistogram, 0);
  296. // Simulate the wall clock advancing faster than the tick clock.
  297. UpdateNetworkTime(clock_->Now(), resolution_, latency_,
  298. tick_clock_->NowTicks());
  299. tick_clock_->Advance(base::Seconds(1));
  300. clock_->Advance(base::Days(1));
  301. base::Time out_network_time;
  302. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_SYNC_LOST,
  303. tracker_->GetNetworkTime(&out_network_time, nullptr));
  304. histograms.ExpectTotalCount(kClockDivergencePositiveHistogram, 0);
  305. histograms.ExpectTotalCount(kClockDivergenceNegativeHistogram, 1);
  306. histograms.ExpectTotalCount(kWallClockBackwardsHistogram, 0);
  307. // The recorded clock divergence should be 1 second - 1 day in seconds.
  308. histograms.ExpectBucketCount(
  309. kClockDivergenceNegativeHistogram,
  310. base::Seconds(kOneDayInSeconds - 1).InMilliseconds(), 1);
  311. }
  312. TEST_F(NetworkTimeTrackerTest, TickClockSpringsForward) {
  313. base::HistogramTester histograms;
  314. histograms.ExpectTotalCount(kClockDivergencePositiveHistogram, 0);
  315. histograms.ExpectTotalCount(kClockDivergenceNegativeHistogram, 0);
  316. histograms.ExpectTotalCount(kWallClockBackwardsHistogram, 0);
  317. // Simulate the tick clock advancing faster than the wall clock.
  318. UpdateNetworkTime(clock_->Now(), resolution_, latency_,
  319. tick_clock_->NowTicks());
  320. tick_clock_->Advance(base::Days(1));
  321. clock_->Advance(base::Seconds(1));
  322. base::Time out_network_time;
  323. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_SYNC_LOST,
  324. tracker_->GetNetworkTime(&out_network_time, nullptr));
  325. histograms.ExpectTotalCount(kClockDivergencePositiveHistogram, 1);
  326. histograms.ExpectTotalCount(kClockDivergenceNegativeHistogram, 0);
  327. histograms.ExpectTotalCount(kWallClockBackwardsHistogram, 0);
  328. // The recorded clock divergence should be 1 day - 1 second.
  329. histograms.ExpectBucketCount(
  330. kClockDivergencePositiveHistogram,
  331. base::Seconds(kOneDayInSeconds - 1).InMilliseconds(), 1);
  332. }
  333. TEST_F(NetworkTimeTrackerTest, FallBack) {
  334. base::HistogramTester histograms;
  335. histograms.ExpectTotalCount(kClockDivergencePositiveHistogram, 0);
  336. histograms.ExpectTotalCount(kClockDivergenceNegativeHistogram, 0);
  337. histograms.ExpectTotalCount(kWallClockBackwardsHistogram, 0);
  338. // Simulate the wall clock running backward.
  339. UpdateNetworkTime(clock_->Now(), resolution_, latency_,
  340. tick_clock_->NowTicks());
  341. tick_clock_->Advance(base::Seconds(1));
  342. clock_->Advance(base::Days(-1));
  343. base::Time out_network_time;
  344. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_SYNC_LOST,
  345. tracker_->GetNetworkTime(&out_network_time, nullptr));
  346. histograms.ExpectTotalCount(kClockDivergencePositiveHistogram, 0);
  347. histograms.ExpectTotalCount(kClockDivergenceNegativeHistogram, 0);
  348. histograms.ExpectTotalCount(kWallClockBackwardsHistogram, 1);
  349. histograms.ExpectBucketCount(
  350. kWallClockBackwardsHistogram,
  351. base::Seconds(kOneDayInSeconds - 1).InMilliseconds(), 1);
  352. }
  353. TEST_F(NetworkTimeTrackerTest, SuspendAndResume) {
  354. // Simulate the wall clock advancing while the tick clock stands still, as
  355. // would happen in a suspend+resume cycle.
  356. UpdateNetworkTime(clock_->Now(), resolution_, latency_,
  357. tick_clock_->NowTicks());
  358. clock_->Advance(base::Hours(1));
  359. base::Time out_network_time;
  360. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_SYNC_LOST,
  361. tracker_->GetNetworkTime(&out_network_time, nullptr));
  362. }
  363. TEST_F(NetworkTimeTrackerTest, Serialize) {
  364. // Test that we can serialize and deserialize state and get consistent
  365. // results.
  366. base::Time in_network_time = clock_->Now() - base::Days(90);
  367. UpdateNetworkTime(in_network_time - latency_ / 2, resolution_, latency_,
  368. tick_clock_->NowTicks());
  369. base::Time out_network_time;
  370. base::TimeDelta out_uncertainty;
  371. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  372. tracker_->GetNetworkTime(&out_network_time, &out_uncertainty));
  373. EXPECT_EQ(in_network_time, out_network_time);
  374. EXPECT_EQ(resolution_ + latency_ + adjustment_, out_uncertainty);
  375. // 6 days is just under the threshold for discarding data.
  376. base::TimeDelta delta = base::Days(6);
  377. AdvanceBoth(delta);
  378. Reset();
  379. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  380. tracker_->GetNetworkTime(&out_network_time, &out_uncertainty));
  381. EXPECT_EQ(in_network_time + delta, out_network_time);
  382. EXPECT_EQ(resolution_ + latency_ + adjustment_, out_uncertainty);
  383. }
  384. TEST_F(NetworkTimeTrackerTest, DeserializeOldFormat) {
  385. // Test that deserializing old data (which do not record the uncertainty and
  386. // tick clock) causes the serialized data to be ignored.
  387. base::Time in_network_time = clock_->Now() - base::Days(90);
  388. UpdateNetworkTime(in_network_time - latency_ / 2, resolution_, latency_,
  389. tick_clock_->NowTicks());
  390. base::Time out_network_time;
  391. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  392. tracker_->GetNetworkTime(&out_network_time, nullptr));
  393. absl::optional<double> local, network;
  394. const base::Value::Dict& saved_prefs =
  395. pref_service_.GetValueDict(prefs::kNetworkTimeMapping);
  396. local = saved_prefs.FindDouble("local");
  397. network = saved_prefs.FindDouble("network");
  398. ASSERT_TRUE(local);
  399. ASSERT_TRUE(network);
  400. base::Value::Dict prefs;
  401. prefs.Set("local", *local);
  402. prefs.Set("network", *network);
  403. pref_service_.Set(prefs::kNetworkTimeMapping, base::Value(std::move(prefs)));
  404. Reset();
  405. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_NO_SYNC_ATTEMPT,
  406. tracker_->GetNetworkTime(&out_network_time, nullptr));
  407. }
  408. TEST_F(NetworkTimeTrackerTest, SerializeWithLongDelay) {
  409. // Test that if the serialized data are more than a week old, they are
  410. // discarded.
  411. base::Time in_network_time = clock_->Now() - base::Days(90);
  412. UpdateNetworkTime(in_network_time - latency_ / 2, resolution_, latency_,
  413. tick_clock_->NowTicks());
  414. base::Time out_network_time;
  415. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  416. tracker_->GetNetworkTime(&out_network_time, nullptr));
  417. AdvanceBoth(base::Days(8));
  418. Reset();
  419. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_NO_SYNC_ATTEMPT,
  420. tracker_->GetNetworkTime(&out_network_time, nullptr));
  421. }
  422. TEST_F(NetworkTimeTrackerTest, SerializeWithTickClockAdvance) {
  423. // Test that serialized data are discarded if the wall clock and tick clock
  424. // have not advanced consistently since data were serialized.
  425. base::Time in_network_time = clock_->Now() - base::Days(90);
  426. UpdateNetworkTime(in_network_time - latency_ / 2, resolution_, latency_,
  427. tick_clock_->NowTicks());
  428. base::Time out_network_time;
  429. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  430. tracker_->GetNetworkTime(&out_network_time, nullptr));
  431. tick_clock_->Advance(base::Days(1));
  432. Reset();
  433. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_SYNC_LOST,
  434. tracker_->GetNetworkTime(&out_network_time, nullptr));
  435. }
  436. TEST_F(NetworkTimeTrackerTest, SerializeWithWallClockAdvance) {
  437. // Test that serialized data are discarded if the wall clock and tick clock
  438. // have not advanced consistently since data were serialized.
  439. base::Time in_network_time = clock_->Now() - base::Days(90);
  440. UpdateNetworkTime(in_network_time - latency_ / 2, resolution_, latency_,
  441. tick_clock_->NowTicks());
  442. base::Time out_network_time;
  443. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  444. tracker_->GetNetworkTime(&out_network_time, nullptr));
  445. clock_->Advance(base::Days(1));
  446. Reset();
  447. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_SYNC_LOST,
  448. tracker_->GetNetworkTime(&out_network_time, nullptr));
  449. }
  450. TEST_F(NetworkTimeTrackerTest, UpdateFromNetwork) {
  451. base::HistogramTester histograms;
  452. histograms.ExpectTotalCount(kFetchFailedHistogram, 0);
  453. histograms.ExpectTotalCount(kFetchValidHistogram, 0);
  454. base::Time out_network_time;
  455. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_NO_SYNC_ATTEMPT,
  456. tracker_->GetNetworkTime(&out_network_time, nullptr));
  457. // First query should happen soon.
  458. EXPECT_EQ(base::Minutes(0), tracker_->GetTimerDelayForTesting());
  459. SetResponseHandler(base::BindRepeating(&GoodTimeResponseHandler));
  460. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
  461. tracker_->WaitForFetchForTesting(123123123);
  462. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  463. tracker_->GetNetworkTime(&out_network_time, nullptr));
  464. // Enabling load timing for the resource requests seems to increase accuracy
  465. // beyond milliseconds. Accuracy of GoodTimeResponseHandler is
  466. // milliseconds, any difference below 1 ms can therefore be ignored.
  467. EXPECT_LT(base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[0]) -
  468. out_network_time,
  469. base::Milliseconds(1));
  470. // Should see no backoff in the success case.
  471. EXPECT_EQ(base::Minutes(60), tracker_->GetTimerDelayForTesting());
  472. histograms.ExpectTotalCount(kFetchFailedHistogram, 0);
  473. histograms.ExpectTotalCount(kFetchValidHistogram, 1);
  474. histograms.ExpectBucketCount(kFetchValidHistogram, true, 1);
  475. }
  476. TEST_F(NetworkTimeTrackerTest, StartTimeFetch) {
  477. SetResponseHandler(base::BindRepeating(&GoodTimeResponseHandler));
  478. base::Time out_network_time;
  479. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_NO_SYNC_ATTEMPT,
  480. tracker_->GetNetworkTime(&out_network_time, nullptr));
  481. base::RunLoop run_loop;
  482. EXPECT_TRUE(tracker_->StartTimeFetch(run_loop.QuitClosure()));
  483. tracker_->WaitForFetchForTesting(123123123);
  484. run_loop.Run();
  485. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  486. tracker_->GetNetworkTime(&out_network_time, nullptr));
  487. // Enabling load timing for the resource requests seems to increase accuracy
  488. // beyond milliseconds. Accuracy of GoodTimeResponseHandler is milliseconds,
  489. // any difference below 1 ms can therefore be ignored.
  490. EXPECT_LT(base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[0]) -
  491. out_network_time,
  492. base::Milliseconds(1));
  493. // Should see no backoff in the success case.
  494. EXPECT_EQ(base::Minutes(60), tracker_->GetTimerDelayForTesting());
  495. }
  496. // Tests that when StartTimeFetch() is called with a query already in
  497. // progress, it calls the callback when that query completes.
  498. TEST_F(NetworkTimeTrackerTest, StartTimeFetchWithQueryInProgress) {
  499. SetResponseHandler(base::BindRepeating(&GoodTimeResponseHandler));
  500. base::Time out_network_time;
  501. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_NO_SYNC_ATTEMPT,
  502. tracker_->GetNetworkTime(&out_network_time, nullptr));
  503. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
  504. base::RunLoop run_loop;
  505. EXPECT_TRUE(tracker_->StartTimeFetch(run_loop.QuitClosure()));
  506. tracker_->WaitForFetchForTesting(123123123);
  507. run_loop.Run();
  508. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  509. tracker_->GetNetworkTime(&out_network_time, nullptr));
  510. // Enabling load timing for the resource requests seems to increase accuracy
  511. // beyond milliseconds. Accuracy of GoodTimeResponseHandler is milliseconds,
  512. // any difference below 1 ms can therefore be ignored.
  513. EXPECT_LT(base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[0]) -
  514. out_network_time,
  515. base::Milliseconds(1));
  516. // Should see no backoff in the success case.
  517. EXPECT_EQ(base::Minutes(60), tracker_->GetTimerDelayForTesting());
  518. }
  519. // Tests that StartTimeFetch() returns false if called while network
  520. // time is available.
  521. TEST_F(NetworkTimeTrackerTest, StartTimeFetchWhileSynced) {
  522. SetResponseHandler(base::BindRepeating(&GoodTimeResponseHandler));
  523. base::Time in_network_time = clock_->Now();
  524. UpdateNetworkTime(in_network_time, resolution_, latency_,
  525. tick_clock_->NowTicks());
  526. // No query should be started so long as NetworkTimeTracker is synced.
  527. base::RunLoop run_loop;
  528. EXPECT_FALSE(tracker_->StartTimeFetch(run_loop.QuitClosure()));
  529. }
  530. // Tests that StartTimeFetch() returns false if the field trial
  531. // is not configured to allow on-demand time fetches.
  532. TEST_F(NetworkTimeTrackerTest, StartTimeFetchWithoutVariationsParam) {
  533. field_trial_test_->SetFeatureParams(
  534. true, 0.0, NetworkTimeTracker::FETCHES_IN_BACKGROUND_ONLY,
  535. NetworkTimeTracker::ClockDriftSamples::NO_SAMPLES);
  536. SetResponseHandler(base::BindRepeating(&GoodTimeResponseHandler));
  537. base::Time out_network_time;
  538. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_NO_SYNC_ATTEMPT,
  539. tracker_->GetNetworkTime(&out_network_time, nullptr));
  540. base::RunLoop run_loop;
  541. EXPECT_FALSE(tracker_->StartTimeFetch(run_loop.QuitClosure()));
  542. }
  543. TEST_F(NetworkTimeTrackerTest, NoNetworkQueryWhileSynced) {
  544. SetResponseHandler(base::BindRepeating(&GoodTimeResponseHandler));
  545. field_trial_test_->SetFeatureParams(
  546. true, 0.0, NetworkTimeTracker::FETCHES_IN_BACKGROUND_AND_ON_DEMAND,
  547. NetworkTimeTracker::ClockDriftSamples::NO_SAMPLES);
  548. base::Time in_network_time = clock_->Now();
  549. UpdateNetworkTime(in_network_time, resolution_, latency_,
  550. tick_clock_->NowTicks());
  551. // No query should be started so long as NetworkTimeTracker is synced, but the
  552. // next check should happen soon.
  553. EXPECT_FALSE(tracker_->QueryTimeServiceForTesting());
  554. EXPECT_EQ(base::Minutes(6), tracker_->GetTimerDelayForTesting());
  555. field_trial_test_->SetFeatureParams(
  556. true, 1.0, NetworkTimeTracker::FETCHES_IN_BACKGROUND_AND_ON_DEMAND,
  557. NetworkTimeTracker::ClockDriftSamples::NO_SAMPLES);
  558. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
  559. tracker_->WaitForFetchForTesting(123123123);
  560. EXPECT_EQ(base::Minutes(60), tracker_->GetTimerDelayForTesting());
  561. }
  562. TEST_F(NetworkTimeTrackerTest, NoNetworkQueryWhileFeatureDisabled) {
  563. // Disable network time queries and check that a query is not sent.
  564. field_trial_test_->SetFeatureParams(
  565. false, 0.0, NetworkTimeTracker::FETCHES_IN_BACKGROUND_AND_ON_DEMAND,
  566. NetworkTimeTracker::ClockDriftSamples::NO_SAMPLES);
  567. EXPECT_FALSE(tracker_->QueryTimeServiceForTesting());
  568. // The timer is not started when the feature is disabled.
  569. EXPECT_EQ(base::Minutes(0), tracker_->GetTimerDelayForTesting());
  570. // Enable time queries and check that a query is sent.
  571. field_trial_test_->SetFeatureParams(
  572. true, 0.0, NetworkTimeTracker::FETCHES_IN_BACKGROUND_AND_ON_DEMAND,
  573. NetworkTimeTracker::ClockDriftSamples::NO_SAMPLES);
  574. SetResponseHandler(base::BindRepeating(&GoodTimeResponseHandler));
  575. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
  576. tracker_->WaitForFetchForTesting(123123123);
  577. }
  578. TEST_F(NetworkTimeTrackerTest, UpdateFromNetworkBadSignature) {
  579. base::HistogramTester histograms;
  580. histograms.ExpectTotalCount(kFetchFailedHistogram, 0);
  581. histograms.ExpectTotalCount(kFetchValidHistogram, 0);
  582. SetResponseHandler(base::BindRepeating(&BadSignatureResponseHandler));
  583. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
  584. tracker_->WaitForFetchForTesting(123123123);
  585. base::Time out_network_time;
  586. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_NO_SUCCESSFUL_SYNC,
  587. tracker_->GetNetworkTime(&out_network_time, nullptr));
  588. EXPECT_EQ(base::Minutes(120), tracker_->GetTimerDelayForTesting());
  589. histograms.ExpectTotalCount(kFetchFailedHistogram, 0);
  590. histograms.ExpectTotalCount(kFetchValidHistogram, 1);
  591. histograms.ExpectBucketCount(kFetchValidHistogram, false, 1);
  592. }
  593. static const uint8_t kDevKeyPubBytes[] = {
  594. 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
  595. 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
  596. 0x42, 0x00, 0x04, 0xe0, 0x6b, 0x0d, 0x76, 0x75, 0xa3, 0x99, 0x7d, 0x7c,
  597. 0x1b, 0xd6, 0x3c, 0x73, 0xbb, 0x4b, 0xfe, 0x0a, 0xe7, 0x2f, 0x61, 0x3d,
  598. 0x77, 0x0a, 0xaa, 0x14, 0xd8, 0x5a, 0xbf, 0x14, 0x60, 0xec, 0xf6, 0x32,
  599. 0x77, 0xb5, 0xa7, 0xe6, 0x35, 0xa5, 0x61, 0xaf, 0xdc, 0xdf, 0x91, 0xce,
  600. 0x45, 0x34, 0x5f, 0x36, 0x85, 0x2f, 0xb9, 0x53, 0x00, 0x5d, 0x86, 0xe7,
  601. 0x04, 0x16, 0xe2, 0x3d, 0x21, 0x76, 0x2b};
  602. TEST_F(NetworkTimeTrackerTest, UpdateFromNetworkBadData) {
  603. base::HistogramTester histograms;
  604. histograms.ExpectTotalCount(kFetchFailedHistogram, 0);
  605. histograms.ExpectTotalCount(kFetchValidHistogram, 0);
  606. SetResponseHandler(
  607. base::BindRepeating(&NetworkTimeTrackerTest::BadDataResponseHandler));
  608. base::StringPiece key = {reinterpret_cast<const char*>(kDevKeyPubBytes),
  609. sizeof(kDevKeyPubBytes)};
  610. tracker_->SetPublicKeyForTesting(key);
  611. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
  612. tracker_->WaitForFetchForTesting(123123123);
  613. base::Time out_network_time;
  614. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_NO_SUCCESSFUL_SYNC,
  615. tracker_->GetNetworkTime(&out_network_time, nullptr));
  616. EXPECT_EQ(base::Minutes(120), tracker_->GetTimerDelayForTesting());
  617. histograms.ExpectTotalCount(kFetchFailedHistogram, 0);
  618. histograms.ExpectTotalCount(kFetchValidHistogram, 1);
  619. histograms.ExpectBucketCount(kFetchValidHistogram, false, 1);
  620. }
  621. TEST_F(NetworkTimeTrackerTest, UpdateFromNetworkServerError) {
  622. base::HistogramTester histograms;
  623. histograms.ExpectTotalCount(kFetchFailedHistogram, 0);
  624. histograms.ExpectTotalCount(kFetchValidHistogram, 0);
  625. SetResponseHandler(
  626. base::BindRepeating(&NetworkTimeTrackerTest::ServerErrorResponseHandler));
  627. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
  628. tracker_->WaitForFetchForTesting(123123123);
  629. base::Time out_network_time;
  630. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_NO_SUCCESSFUL_SYNC,
  631. tracker_->GetNetworkTime(&out_network_time, nullptr));
  632. // Should see backoff in the error case.
  633. EXPECT_EQ(base::Minutes(120), tracker_->GetTimerDelayForTesting());
  634. histograms.ExpectTotalCount(kFetchFailedHistogram, 1);
  635. // There was no network error, so the histogram is recorded as
  636. // net::OK, indicating that the connection succeeded but there was a
  637. // non-200 HTTP status code.
  638. histograms.ExpectBucketCount(kFetchFailedHistogram, net::OK, 1);
  639. histograms.ExpectTotalCount(kFetchValidHistogram, 0);
  640. }
  641. #if BUILDFLAG(IS_IOS)
  642. // http://crbug.com/658619
  643. #define MAYBE_UpdateFromNetworkNetworkError \
  644. DISABLED_UpdateFromNetworkNetworkError
  645. #else
  646. #define MAYBE_UpdateFromNetworkNetworkError UpdateFromNetworkNetworkError
  647. #endif
  648. TEST_F(NetworkTimeTrackerTest, MAYBE_UpdateFromNetworkNetworkError) {
  649. base::HistogramTester histograms;
  650. histograms.ExpectTotalCount(kFetchFailedHistogram, 0);
  651. histograms.ExpectTotalCount(kFetchValidHistogram, 0);
  652. SetResponseHandler(base::BindRepeating(
  653. &NetworkTimeTrackerTest::NetworkErrorResponseHandler));
  654. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
  655. tracker_->WaitForFetchForTesting(123123123);
  656. base::Time out_network_time;
  657. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_NO_SUCCESSFUL_SYNC,
  658. tracker_->GetNetworkTime(&out_network_time, nullptr));
  659. // Should see backoff in the error case.
  660. EXPECT_EQ(base::Minutes(120), tracker_->GetTimerDelayForTesting());
  661. histograms.ExpectTotalCount(kFetchFailedHistogram, 1);
  662. histograms.ExpectBucketCount(kFetchFailedHistogram, -net::ERR_EMPTY_RESPONSE,
  663. 1);
  664. histograms.ExpectTotalCount(kFetchValidHistogram, 0);
  665. }
  666. TEST_F(NetworkTimeTrackerTest, UpdateFromNetworkLargeResponse) {
  667. base::HistogramTester histograms;
  668. histograms.ExpectTotalCount(kFetchFailedHistogram, 0);
  669. histograms.ExpectTotalCount(kFetchValidHistogram, 0);
  670. SetResponseHandler(base::BindRepeating(&GoodTimeResponseHandler));
  671. base::Time out_network_time;
  672. tracker_->SetMaxResponseSizeForTesting(3);
  673. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
  674. tracker_->WaitForFetchForTesting(123123123);
  675. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_NO_SUCCESSFUL_SYNC,
  676. tracker_->GetNetworkTime(&out_network_time, nullptr));
  677. histograms.ExpectTotalCount(kFetchFailedHistogram, 1);
  678. histograms.ExpectTotalCount(kFetchValidHistogram, 0);
  679. tracker_->SetMaxResponseSizeForTesting(1024);
  680. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
  681. tracker_->WaitForFetchForTesting(123123123);
  682. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  683. tracker_->GetNetworkTime(&out_network_time, nullptr));
  684. histograms.ExpectTotalCount(kFetchFailedHistogram, 1);
  685. histograms.ExpectTotalCount(kFetchValidHistogram, 1);
  686. histograms.ExpectBucketCount(kFetchValidHistogram, true, 1);
  687. }
  688. TEST_F(NetworkTimeTrackerTest, UpdateFromNetworkFirstSyncPending) {
  689. base::HistogramTester histograms;
  690. histograms.ExpectTotalCount(kFetchFailedHistogram, 0);
  691. histograms.ExpectTotalCount(kFetchValidHistogram, 0);
  692. SetResponseHandler(
  693. base::BindRepeating(&NetworkTimeTrackerTest::BadDataResponseHandler));
  694. base::StringPiece key = {reinterpret_cast<const char*>(kDevKeyPubBytes),
  695. sizeof(kDevKeyPubBytes)};
  696. tracker_->SetPublicKeyForTesting(key);
  697. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
  698. // Do not wait for the fetch to complete; ask for the network time
  699. // immediately while the request is still pending.
  700. base::Time out_network_time;
  701. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_FIRST_SYNC_PENDING,
  702. tracker_->GetNetworkTime(&out_network_time, nullptr));
  703. histograms.ExpectTotalCount(kFetchFailedHistogram, 0);
  704. histograms.ExpectTotalCount(kFetchValidHistogram, 0);
  705. tracker_->WaitForFetchForTesting(123123123);
  706. }
  707. TEST_F(NetworkTimeTrackerTest, UpdateFromNetworkSubseqeuntSyncPending) {
  708. base::HistogramTester histograms;
  709. histograms.ExpectTotalCount(kFetchFailedHistogram, 0);
  710. histograms.ExpectTotalCount(kFetchValidHistogram, 0);
  711. SetResponseHandler(
  712. base::BindRepeating(&NetworkTimeTrackerTest::BadDataResponseHandler));
  713. base::StringPiece key = {reinterpret_cast<const char*>(kDevKeyPubBytes),
  714. sizeof(kDevKeyPubBytes)};
  715. tracker_->SetPublicKeyForTesting(key);
  716. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
  717. tracker_->WaitForFetchForTesting(123123123);
  718. base::Time out_network_time;
  719. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_NO_SUCCESSFUL_SYNC,
  720. tracker_->GetNetworkTime(&out_network_time, nullptr));
  721. // After one sync attempt failed, kick off another one, and ask for
  722. // the network time while it is still pending.
  723. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
  724. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_SUBSEQUENT_SYNC_PENDING,
  725. tracker_->GetNetworkTime(&out_network_time, nullptr));
  726. histograms.ExpectTotalCount(kFetchFailedHistogram, 0);
  727. histograms.ExpectTotalCount(kFetchValidHistogram, 1);
  728. histograms.ExpectBucketCount(kFetchValidHistogram, false, 1);
  729. tracker_->WaitForFetchForTesting(123123123);
  730. }
  731. namespace {
  732. // NetworkTimeTrackerTest.TimeBetweenFetchesHistogram needs to make several time
  733. // queries that return different times.
  734. // MultipleGoodTimeResponseHandler::ResponseHandler is like
  735. // GoodTimeResponseHandler, but returning different times on each of three
  736. // requests that happen in sequence.
  737. //
  738. // See comments inline for how to update the times that are returned.
  739. class MultipleGoodTimeResponseHandler {
  740. public:
  741. MultipleGoodTimeResponseHandler() {}
  742. MultipleGoodTimeResponseHandler(const MultipleGoodTimeResponseHandler&) =
  743. delete;
  744. MultipleGoodTimeResponseHandler& operator=(
  745. const MultipleGoodTimeResponseHandler&) = delete;
  746. ~MultipleGoodTimeResponseHandler() {}
  747. MockedResponse ResponseHandler();
  748. // Returns the time that is returned in the (i-1)'th response handled by
  749. // ResponseHandler(), or null base::Time() if too many responses have been
  750. // handled.
  751. base::Time GetTimeAtIndex(unsigned int i);
  752. private:
  753. // The index into |kGoodTimeResponseHandlerJsTime|, |kGoodTimeResponseBody|,
  754. // and |kGoodTimeResponseServerProofHeaders| that will be used in the
  755. // response in the next ResponseHandler() call.
  756. unsigned int next_time_index_ = 0;
  757. };
  758. MockedResponse MultipleGoodTimeResponseHandler::ResponseHandler() {
  759. if (next_time_index_ >= std::size(kGoodTimeResponseBody)) {
  760. return MockedResponse{network::CreateURLResponseHead(net::HTTP_BAD_REQUEST),
  761. ""};
  762. }
  763. network::mojom::URLResponseHeadPtr head =
  764. network::CreateURLResponseHead(net::HTTP_OK);
  765. head->headers->AddHeader(
  766. "x-cup-server-proof",
  767. kGoodTimeResponseServerProofHeader[next_time_index_]);
  768. // Simulate response latency.
  769. head->load_timing.send_end = base::TimeTicks::Now();
  770. head->load_timing.receive_headers_start =
  771. head->load_timing.send_end + kGoodTimeResponseLatency[next_time_index_];
  772. MockedResponse response{std::move(head),
  773. kGoodTimeResponseBody[next_time_index_]};
  774. next_time_index_++;
  775. return response;
  776. }
  777. base::Time MultipleGoodTimeResponseHandler::GetTimeAtIndex(unsigned int i) {
  778. if (i >= std::size(kGoodTimeResponseHandlerJsTime))
  779. return base::Time();
  780. return base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[i]);
  781. }
  782. } // namespace
  783. TEST_F(NetworkTimeTrackerTest, TimeBetweenFetchesHistogram) {
  784. MultipleGoodTimeResponseHandler response_handler;
  785. base::HistogramTester histograms;
  786. histograms.ExpectTotalCount(kTimeBetweenFetchesHistogram, 0);
  787. SetResponseHandler(
  788. base::BindRepeating(&MultipleGoodTimeResponseHandler::ResponseHandler,
  789. base::Unretained(&response_handler)));
  790. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
  791. tracker_->WaitForFetchForTesting(123123123);
  792. base::Time out_network_time;
  793. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  794. tracker_->GetNetworkTime(&out_network_time, nullptr));
  795. // After the first query, there should be no histogram value because
  796. // there was no delta to record.
  797. histograms.ExpectTotalCount(kTimeBetweenFetchesHistogram, 0);
  798. // Trigger a second query, which should cause the delta from the first
  799. // query to be recorded.
  800. clock_->Advance(base::Hours(1));
  801. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting());
  802. tracker_->WaitForFetchForTesting(123123123);
  803. EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
  804. tracker_->GetNetworkTime(&out_network_time, nullptr));
  805. histograms.ExpectTotalCount(kTimeBetweenFetchesHistogram, 1);
  806. histograms.ExpectBucketCount(
  807. kTimeBetweenFetchesHistogram,
  808. (response_handler.GetTimeAtIndex(1) - response_handler.GetTimeAtIndex(0))
  809. .InMilliseconds(),
  810. 1);
  811. }
  812. TEST_F(NetworkTimeTrackerTest, ClockSkewHistograms) {
  813. field_trial_test_->SetFeatureParams(
  814. true, 1.0 /* query probability */,
  815. NetworkTimeTracker::FETCHES_IN_BACKGROUND_AND_ON_DEMAND,
  816. NetworkTimeTracker::ClockDriftSamples::NO_SAMPLES);
  817. MultipleGoodTimeResponseHandler response_handler;
  818. base::HistogramTester histograms_first;
  819. base::TimeDelta mean_latency = base::Seconds(0);
  820. SetResponseHandler(
  821. base::BindRepeating(&MultipleGoodTimeResponseHandler::ResponseHandler,
  822. base::Unretained(&response_handler)));
  823. clock_->SetNow(
  824. base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[0] + 3500));
  825. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/false));
  826. tracker_->WaitForFetchForTesting(123123123);
  827. base::TimeDelta latency1 = kGoodTimeResponseLatency[0];
  828. mean_latency += latency1;
  829. std::unique_ptr<base::HistogramSamples> samples_positive(
  830. histograms_first.GetHistogramSamplesSinceCreation(
  831. "PrivacyBudget.ClockSkew.Magnitude.Positive"));
  832. EXPECT_EQ(1, samples_positive->GetCount(
  833. (base::Seconds(3.5) - latency1 / 2).InMilliseconds()));
  834. EXPECT_EQ(1, samples_positive->TotalCount());
  835. std::unique_ptr<base::HistogramSamples> samples_negative(
  836. histograms_first.GetHistogramSamplesSinceCreation(
  837. "PrivacyBudget.ClockSkew.Magnitude.Negative"));
  838. EXPECT_EQ(0, samples_negative->TotalCount());
  839. std::unique_ptr<base::HistogramSamples> samples_latency(
  840. histograms_first.GetHistogramSamplesSinceCreation(
  841. "PrivacyBudget.ClockSkew.FetchLatency"));
  842. EXPECT_EQ(1, samples_latency->TotalCount());
  843. EXPECT_EQ(1, samples_latency->GetCount(latency1.InMilliseconds()));
  844. std::unique_ptr<base::HistogramSamples> samples_latency_jitter(
  845. histograms_first.GetHistogramSamplesSinceCreation(
  846. "PrivacyBudget.ClockSkew.FetchLatencyJitter"));
  847. EXPECT_EQ(0, samples_latency_jitter->TotalCount());
  848. base::HistogramTester histograms_second;
  849. clock_->SetNow(
  850. base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[1] + 3500));
  851. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/false));
  852. tracker_->WaitForFetchForTesting(123123123);
  853. base::TimeDelta latency2 = kGoodTimeResponseLatency[1];
  854. mean_latency += latency2;
  855. samples_positive = histograms_second.GetHistogramSamplesSinceCreation(
  856. "PrivacyBudget.ClockSkew.Magnitude.Positive");
  857. EXPECT_EQ(1, samples_positive->GetCount(
  858. (base::Seconds(3.5) - latency2 / 2).InMilliseconds()));
  859. EXPECT_EQ(1, samples_positive->TotalCount());
  860. samples_negative = histograms_second.GetHistogramSamplesSinceCreation(
  861. "PrivacyBudget.ClockSkew.Magnitude.Negative");
  862. EXPECT_EQ(0, samples_negative->TotalCount());
  863. samples_latency = histograms_second.GetHistogramSamplesSinceCreation(
  864. "PrivacyBudget.ClockSkew.FetchLatency");
  865. EXPECT_EQ(1, samples_latency->TotalCount());
  866. EXPECT_EQ(1, samples_latency->GetCount(latency2.InMilliseconds()));
  867. samples_latency_jitter = histograms_second.GetHistogramSamplesSinceCreation(
  868. "PrivacyBudget.ClockSkew.FetchLatencyJitter");
  869. EXPECT_EQ(0, samples_latency_jitter->TotalCount());
  870. base::HistogramTester histograms_third;
  871. clock_->SetNow(
  872. base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[2] - 2500));
  873. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/false));
  874. tracker_->WaitForFetchForTesting(123123123);
  875. base::TimeDelta latency3 = kGoodTimeResponseLatency[2];
  876. mean_latency += latency3;
  877. samples_positive = histograms_third.GetHistogramSamplesSinceCreation(
  878. "PrivacyBudget.ClockSkew.Magnitude.Positive");
  879. EXPECT_EQ(0, samples_positive->TotalCount());
  880. samples_negative = histograms_third.GetHistogramSamplesSinceCreation(
  881. "PrivacyBudget.ClockSkew.Magnitude.Negative");
  882. EXPECT_EQ(1, samples_negative->TotalCount());
  883. EXPECT_EQ(1, samples_negative->GetCount(
  884. (base::Seconds(2.5) + latency3 / 2).InMilliseconds()));
  885. samples_latency = histograms_third.GetHistogramSamplesSinceCreation(
  886. "PrivacyBudget.ClockSkew.FetchLatency");
  887. EXPECT_EQ(1, samples_latency->TotalCount());
  888. EXPECT_EQ(1, samples_latency->GetCount(latency3.InMilliseconds()));
  889. // After three fetches, the FetchLatencyJitter should be reported.
  890. samples_latency_jitter = histograms_third.GetHistogramSamplesSinceCreation(
  891. "PrivacyBudget.ClockSkew.FetchLatencyJitter");
  892. EXPECT_EQ(1, samples_latency_jitter->TotalCount());
  893. mean_latency /= 3.0;
  894. int64_t stddev = (mean_latency - latency1).InMicroseconds() *
  895. (mean_latency - latency1).InMicroseconds() +
  896. (mean_latency - latency2).InMicroseconds() *
  897. (mean_latency - latency2).InMicroseconds() +
  898. (mean_latency - latency3).InMicroseconds() *
  899. (mean_latency - latency3).InMicroseconds();
  900. stddev = std::lround(std::sqrt(base::strict_cast<double>(stddev)));
  901. EXPECT_EQ(1, samples_latency_jitter->GetCount(
  902. base::Microseconds(stddev).InMilliseconds()));
  903. }
  904. TEST_F(NetworkTimeTrackerTest, ClockSkewHistogramsEmptyForOnDemandChecks) {
  905. field_trial_test_->SetFeatureParams(
  906. true, 1.0 /* query probability */,
  907. NetworkTimeTracker::FETCHES_IN_BACKGROUND_AND_ON_DEMAND,
  908. NetworkTimeTracker::ClockDriftSamples::NO_SAMPLES);
  909. MultipleGoodTimeResponseHandler response_handler;
  910. base::HistogramTester histograms;
  911. SetResponseHandler(
  912. base::BindRepeating(&MultipleGoodTimeResponseHandler::ResponseHandler,
  913. base::Unretained(&response_handler)));
  914. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/true));
  915. tracker_->WaitForFetchForTesting(123123123);
  916. histograms.ExpectTotalCount("PrivacyBudget.ClockSkew.Magnitude.Positive", 0);
  917. histograms.ExpectTotalCount("PrivacyBudget.ClockSkew.Magnitude.Negative", 0);
  918. histograms.ExpectTotalCount("PrivacyBudget.ClockSkew.FetchLatency", 0);
  919. histograms.ExpectTotalCount("PrivacyBudget.ClockSkew.FetchLatencyJitter", 0);
  920. }
  921. TEST_F(NetworkTimeTrackerTest, ClockDriftHistogramsEmptyForOnDemandChecks) {
  922. MultipleGoodTimeResponseHandler response_handler;
  923. base::HistogramTester histograms;
  924. field_trial_test_->SetFeatureParams(
  925. true, 1.0 /* query probability */,
  926. NetworkTimeTracker::FETCHES_IN_BACKGROUND_AND_ON_DEMAND,
  927. NetworkTimeTracker::ClockDriftSamples::TWO_SAMPLES);
  928. SetResponseHandler(
  929. base::BindRepeating(&MultipleGoodTimeResponseHandler::ResponseHandler,
  930. base::Unretained(&response_handler)));
  931. clock_->SetNow(base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[0]));
  932. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/true));
  933. tracker_->WaitForFetchForTesting(123123123);
  934. clock_->SetNow(base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[1]));
  935. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/true));
  936. tracker_->WaitForFetchForTesting(123123123);
  937. clock_->SetNow(base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[2]));
  938. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/true));
  939. tracker_->WaitForFetchForTesting(123123123);
  940. clock_->SetNow(base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[3]));
  941. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/true));
  942. tracker_->WaitForFetchForTesting(123123123);
  943. histograms.ExpectTotalCount("PrivacyBudget.ClockDrift.Magnitude.Positive", 0);
  944. histograms.ExpectTotalCount("PrivacyBudget.ClockDrift.Magnitude.Negative", 0);
  945. histograms.ExpectTotalCount("PrivacyBudget.ClockDrift.FetchLatencyVariance",
  946. 0);
  947. }
  948. TEST_F(NetworkTimeTrackerTest, ClockDriftHistogramsPositive) {
  949. MultipleGoodTimeResponseHandler response_handler;
  950. base::HistogramTester histograms;
  951. field_trial_test_->SetFeatureParams(
  952. true, 1.0 /* query probability */,
  953. NetworkTimeTracker::FETCHES_IN_BACKGROUND_AND_ON_DEMAND,
  954. NetworkTimeTracker::ClockDriftSamples::TWO_SAMPLES);
  955. SetResponseHandler(
  956. base::BindRepeating(&MultipleGoodTimeResponseHandler::ResponseHandler,
  957. base::Unretained(&response_handler)));
  958. // This part will trigger a skew measurement fetch first, followed by a drift
  959. // measurement using two samples.
  960. clock_->SetNow(base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[0]));
  961. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/false));
  962. tracker_->WaitForFetchForTesting(123123123);
  963. // The next measurements are used for computing drift.
  964. clock_->SetNow(base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[1]));
  965. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/false));
  966. tracker_->WaitForFetchForTesting(123123123);
  967. base::TimeDelta latency1 = kGoodTimeResponseLatency[1];
  968. // We add an on demand time query in the middle to check it does not interfere
  969. // with our samples.
  970. clock_->SetNow(base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[2]));
  971. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/true));
  972. tracker_->WaitForFetchForTesting(123123123);
  973. clock_->SetNow(base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[3]));
  974. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/false));
  975. tracker_->WaitForFetchForTesting(123123123);
  976. clock_->SetNow(
  977. base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[4] + 150));
  978. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/false));
  979. tracker_->WaitForFetchForTesting(123123123);
  980. base::TimeDelta latency3 = kGoodTimeResponseLatency[4];
  981. double expected_positive_drift =
  982. (base::Milliseconds(150) - latency3 / 2 + latency1 / 2).InMicroseconds() /
  983. 2.0;
  984. ASSERT_GT(expected_positive_drift, 0);
  985. histograms.ExpectTotalCount("PrivacyBudget.ClockDrift.Magnitude.Positive", 1);
  986. histograms.ExpectUniqueSample("PrivacyBudget.ClockDrift.Magnitude.Positive",
  987. expected_positive_drift, 1);
  988. histograms.ExpectTotalCount("PrivacyBudget.ClockDrift.Magnitude.Negative", 0);
  989. histograms.ExpectTotalCount("PrivacyBudget.ClockDrift.FetchLatencyVariance",
  990. 1);
  991. base::TimeDelta mean = (latency1 + latency3) / 2.0;
  992. double variance =
  993. (latency1 - mean).InMilliseconds() * (latency1 - mean).InMilliseconds() +
  994. (latency3 - mean).InMilliseconds() * (latency3 - mean).InMilliseconds();
  995. histograms.ExpectUniqueSample("PrivacyBudget.ClockDrift.FetchLatencyVariance",
  996. variance, 1);
  997. }
  998. TEST_F(NetworkTimeTrackerTest, ClockDriftHistogramsNegative) {
  999. MultipleGoodTimeResponseHandler response_handler;
  1000. base::HistogramTester histograms;
  1001. field_trial_test_->SetFeatureParams(
  1002. true, 1.0 /* query probability */,
  1003. NetworkTimeTracker::FETCHES_IN_BACKGROUND_AND_ON_DEMAND,
  1004. NetworkTimeTracker::ClockDriftSamples::TWO_SAMPLES);
  1005. SetResponseHandler(
  1006. base::BindRepeating(&MultipleGoodTimeResponseHandler::ResponseHandler,
  1007. base::Unretained(&response_handler)));
  1008. // This part will trigger a skew measurement fetch first, followed by a drift
  1009. // measurement using two samples.
  1010. clock_->SetNow(base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[0]));
  1011. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/false));
  1012. tracker_->WaitForFetchForTesting(123123123);
  1013. // These are the two measurements used for computing drift.
  1014. clock_->SetNow(base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[1]));
  1015. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/false));
  1016. tracker_->WaitForFetchForTesting(123123123);
  1017. base::TimeDelta latency1 = kGoodTimeResponseLatency[1];
  1018. clock_->SetNow(base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[2]));
  1019. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/false));
  1020. tracker_->WaitForFetchForTesting(123123123);
  1021. clock_->SetNow(base::Time::FromJsTime(kGoodTimeResponseHandlerJsTime[3] - 1));
  1022. EXPECT_TRUE(tracker_->QueryTimeServiceForTesting(/*on_demand=*/false));
  1023. tracker_->WaitForFetchForTesting(123123123);
  1024. base::TimeDelta latency3 = kGoodTimeResponseLatency[3];
  1025. double expected_negative_drift =
  1026. (base::Milliseconds(1) - latency1 / 2 + latency3 / 2).InMicroseconds() /
  1027. 2.0;
  1028. ASSERT_GT(expected_negative_drift, 0);
  1029. histograms.ExpectTotalCount("PrivacyBudget.ClockDrift.Magnitude.Positive", 0);
  1030. histograms.ExpectTotalCount("PrivacyBudget.ClockDrift.Magnitude.Negative", 1);
  1031. histograms.ExpectUniqueSample("PrivacyBudget.ClockDrift.Magnitude.Negative",
  1032. expected_negative_drift, 1);
  1033. base::TimeDelta mean = (latency1 + latency3) / 2.0;
  1034. double variance =
  1035. (latency1 - mean).InMilliseconds() * (latency1 - mean).InMilliseconds() +
  1036. (latency3 - mean).InMilliseconds() * (latency3 - mean).InMilliseconds();
  1037. histograms.ExpectTotalCount("PrivacyBudget.ClockDrift.FetchLatencyVariance",
  1038. 1);
  1039. histograms.ExpectUniqueSample("PrivacyBudget.ClockDrift.FetchLatencyVariance",
  1040. variance, 1);
  1041. }
  1042. } // namespace network_time