context_unittest.cc 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390
  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/domain_reliability/context.h"
  5. #include <stddef.h>
  6. #include <map>
  7. #include <memory>
  8. #include <string>
  9. #include <utility>
  10. #include "base/bind.h"
  11. #include "base/json/json_reader.h"
  12. #include "base/strings/string_piece.h"
  13. #include "base/strings/stringprintf.h"
  14. #include "base/test/metrics/histogram_tester.h"
  15. #include "base/time/time.h"
  16. #include "components/domain_reliability/beacon.h"
  17. #include "components/domain_reliability/dispatcher.h"
  18. #include "components/domain_reliability/scheduler.h"
  19. #include "components/domain_reliability/test_util.h"
  20. #include "components/domain_reliability/uploader.h"
  21. #include "net/base/net_errors.h"
  22. #include "net/url_request/url_request_test_util.h"
  23. #include "testing/gtest/include/gtest/gtest.h"
  24. namespace domain_reliability {
  25. namespace {
  26. using base::Value;
  27. typedef std::vector<const DomainReliabilityBeacon*> BeaconVector;
  28. const char kBeaconOutcomeHistogram[] = "Net.DomainReliability.BeaconOutcome";
  29. std::unique_ptr<DomainReliabilityBeacon> MakeCustomizedBeacon(
  30. MockableTime* time,
  31. std::string status,
  32. std::string quic_error,
  33. bool quic_port_migration_detected) {
  34. std::unique_ptr<DomainReliabilityBeacon> beacon(
  35. new DomainReliabilityBeacon());
  36. beacon->url = GURL("https://localhost/");
  37. beacon->status = status;
  38. beacon->quic_error = quic_error;
  39. beacon->chrome_error = net::ERR_CONNECTION_RESET;
  40. beacon->server_ip = "127.0.0.1";
  41. beacon->was_proxied = false;
  42. beacon->protocol = "HTTP";
  43. beacon->details.quic_broken = true;
  44. beacon->details.quic_port_migration_detected = quic_port_migration_detected;
  45. beacon->http_response_code = -1;
  46. beacon->elapsed = base::Milliseconds(250);
  47. beacon->start_time = time->NowTicks() - beacon->elapsed;
  48. beacon->upload_depth = 0;
  49. beacon->sample_rate = 1.0;
  50. beacon->network_isolation_key = net::NetworkIsolationKey();
  51. return beacon;
  52. }
  53. std::unique_ptr<DomainReliabilityBeacon> MakeBeacon(MockableTime* time) {
  54. return MakeCustomizedBeacon(time, "tcp.connection_reset" /* status */,
  55. "" /* quic_error */,
  56. false /* quic_port_migration_detected */);
  57. }
  58. std::unique_ptr<DomainReliabilityBeacon> MakeBeaconWithNetworkIsolationKey(
  59. MockableTime* time,
  60. const std::string& status,
  61. const net::NetworkIsolationKey& network_isolation_key) {
  62. std::unique_ptr<DomainReliabilityBeacon> beacon =
  63. MakeCustomizedBeacon(time, status, "" /* quic_error */,
  64. false /* quic_port_migration_detected */);
  65. beacon->network_isolation_key = network_isolation_key;
  66. return beacon;
  67. }
  68. // Create a status string from in integer. For eviction tests. Include string
  69. // values before and after the string representation of the integer, to make
  70. // sure only exact matches are found when searching a JSON string.
  71. std::string StatusFromInt(int i) {
  72. return base::StringPrintf("status%i.test", i);
  73. }
  74. template <typename ValueTypeFindResult,
  75. typename ValueType,
  76. ValueTypeFindResult (Value::*FindValueType)(base::StringPiece) const>
  77. struct HasValue {
  78. bool operator()(const Value& dict,
  79. const std::string& key,
  80. ValueType expected_value) {
  81. ValueTypeFindResult actual_value = (dict.*FindValueType)(key);
  82. if (actual_value)
  83. EXPECT_EQ(expected_value, *actual_value);
  84. return actual_value && (expected_value == *actual_value);
  85. }
  86. };
  87. HasValue<absl::optional<bool>, bool, &Value::FindBoolPath> HasBooleanValue;
  88. HasValue<absl::optional<double>, double, &Value::FindDoublePath> HasDoubleValue;
  89. HasValue<absl::optional<int>, int, &Value::FindIntPath> HasIntegerValue;
  90. HasValue<const std::string*, std::string, &Value::FindStringPath>
  91. HasStringValue;
  92. bool GetEntryFromReport(const Value* report,
  93. size_t index,
  94. const Value** entry_out) {
  95. if (!report || !report->is_dict())
  96. return false;
  97. const Value* entries = report->FindListKey("entries");
  98. if (!entries || index >= entries->GetListDeprecated().size())
  99. return false;
  100. const Value& entry = entries->GetListDeprecated()[index];
  101. if (!entry.is_dict())
  102. return false;
  103. *entry_out = &entry;
  104. return true;
  105. }
  106. class DomainReliabilityContextTest : public testing::Test {
  107. protected:
  108. DomainReliabilityContextTest()
  109. : last_network_change_time_(time_.NowTicks()),
  110. dispatcher_(&time_),
  111. params_(MakeTestSchedulerParams()),
  112. uploader_(
  113. base::BindRepeating(&DomainReliabilityContextTest::OnUploadRequest,
  114. base::Unretained(this))),
  115. upload_reporter_string_("test-reporter"),
  116. upload_allowed_callback_(base::BindRepeating(
  117. &DomainReliabilityContextTest::UploadAllowedCallback,
  118. base::Unretained(this))),
  119. upload_pending_(false) {
  120. // Make sure that the last network change does not overlap requests
  121. // made in test cases, which start 250ms in the past (see |MakeBeacon|).
  122. last_network_change_time_ = time_.NowTicks();
  123. time_.Advance(base::Seconds(1));
  124. }
  125. void InitContext(std::unique_ptr<const DomainReliabilityConfig> config) {
  126. context_ = std::make_unique<DomainReliabilityContext>(
  127. &time_, params_, upload_reporter_string_, &last_network_change_time_,
  128. upload_allowed_callback_, &dispatcher_, &uploader_, std::move(config));
  129. }
  130. void ShutDownContext() { context_.reset(); }
  131. base::TimeDelta min_delay() const { return params_.minimum_upload_delay; }
  132. base::TimeDelta max_delay() const { return params_.maximum_upload_delay; }
  133. base::TimeDelta retry_interval() const {
  134. return params_.upload_retry_interval;
  135. }
  136. base::TimeDelta zero_delta() const { return base::Microseconds(0); }
  137. bool upload_allowed_callback_pending() const {
  138. return !upload_allowed_result_callback_.is_null();
  139. }
  140. bool upload_pending() const { return upload_pending_; }
  141. const std::string& upload_report() const {
  142. EXPECT_TRUE(upload_pending_);
  143. return upload_report_;
  144. }
  145. int upload_max_depth() const {
  146. EXPECT_TRUE(upload_pending_);
  147. return upload_max_depth_;
  148. }
  149. const GURL& upload_url() const {
  150. EXPECT_TRUE(upload_pending_);
  151. return upload_url_;
  152. }
  153. const net::NetworkIsolationKey& upload_network_isolation_key() const {
  154. EXPECT_TRUE(upload_pending_);
  155. return upload_network_isolation_key_;
  156. }
  157. void CallUploadCallback(DomainReliabilityUploader::UploadResult result) {
  158. ASSERT_TRUE(upload_pending_);
  159. std::move(upload_callback_).Run(result);
  160. upload_pending_ = false;
  161. ++num_uploads_completed_;
  162. EXPECT_EQ(num_uploads_completed_, num_uploads_);
  163. }
  164. bool CheckNoBeacons() {
  165. BeaconVector beacons;
  166. context_->GetQueuedBeaconsForTesting(&beacons);
  167. return beacons.empty();
  168. }
  169. const url::Origin& upload_allowed_origin() { return upload_allowed_origin_; }
  170. void CallUploadAllowedResultCallback(bool allowed) {
  171. DCHECK(!upload_allowed_result_callback_.is_null());
  172. std::move(upload_allowed_result_callback_).Run(allowed);
  173. }
  174. MockTime time_;
  175. base::TimeTicks last_network_change_time_;
  176. DomainReliabilityDispatcher dispatcher_;
  177. DomainReliabilityScheduler::Params params_;
  178. MockUploader uploader_;
  179. std::string upload_reporter_string_;
  180. DomainReliabilityContext::UploadAllowedCallback upload_allowed_callback_;
  181. std::unique_ptr<DomainReliabilityContext> context_;
  182. private:
  183. void OnUploadRequest(const std::string& report_json,
  184. int max_upload_depth,
  185. const GURL& upload_url,
  186. const net::NetworkIsolationKey& network_isolation_key,
  187. DomainReliabilityUploader::UploadCallback callback) {
  188. EXPECT_EQ(num_uploads_completed_, num_uploads_);
  189. ASSERT_FALSE(upload_pending_);
  190. upload_report_ = report_json;
  191. upload_max_depth_ = max_upload_depth;
  192. upload_url_ = upload_url;
  193. upload_network_isolation_key_ = network_isolation_key;
  194. upload_callback_ = std::move(callback);
  195. upload_pending_ = true;
  196. ++num_uploads_;
  197. }
  198. void UploadAllowedCallback(const url::Origin& origin,
  199. base::OnceCallback<void(bool)> callback) {
  200. upload_allowed_origin_ = origin;
  201. upload_allowed_result_callback_ = std::move(callback);
  202. }
  203. int num_uploads_ = 0;
  204. int num_uploads_completed_ = 0;
  205. bool upload_pending_;
  206. std::string upload_report_;
  207. int upload_max_depth_;
  208. GURL upload_url_;
  209. net::NetworkIsolationKey upload_network_isolation_key_;
  210. DomainReliabilityUploader::UploadCallback upload_callback_;
  211. url::Origin upload_allowed_origin_;
  212. base::OnceCallback<void(bool)> upload_allowed_result_callback_;
  213. };
  214. TEST_F(DomainReliabilityContextTest, Create) {
  215. InitContext(MakeTestConfig());
  216. EXPECT_TRUE(CheckNoBeacons());
  217. }
  218. TEST_F(DomainReliabilityContextTest, QueueBeacon) {
  219. base::HistogramTester histograms;
  220. InitContext(MakeTestConfig());
  221. context_->OnBeacon(MakeBeacon(&time_));
  222. BeaconVector beacons;
  223. context_->GetQueuedBeaconsForTesting(&beacons);
  224. EXPECT_EQ(1u, beacons.size());
  225. ShutDownContext();
  226. histograms.ExpectBucketCount(
  227. kBeaconOutcomeHistogram,
  228. DomainReliabilityBeacon::Outcome::kContextShutDown, 1);
  229. histograms.ExpectTotalCount(kBeaconOutcomeHistogram, 1);
  230. }
  231. TEST_F(DomainReliabilityContextTest, MaxNestedBeaconSchedules) {
  232. InitContext(MakeTestConfig());
  233. GURL url("http://example/always_report");
  234. std::unique_ptr<DomainReliabilityBeacon> beacon = MakeBeacon(&time_);
  235. beacon->upload_depth = DomainReliabilityContext::kMaxUploadDepthToSchedule;
  236. context_->OnBeacon(std::move(beacon));
  237. BeaconVector beacons;
  238. context_->GetQueuedBeaconsForTesting(&beacons);
  239. EXPECT_EQ(1u, beacons.size());
  240. time_.Advance(max_delay());
  241. EXPECT_TRUE(upload_allowed_callback_pending());
  242. }
  243. TEST_F(DomainReliabilityContextTest, OverlyNestedBeaconDoesNotSchedule) {
  244. InitContext(MakeTestConfig());
  245. GURL url("http://example/always_report");
  246. std::unique_ptr<DomainReliabilityBeacon> beacon = MakeBeacon(&time_);
  247. beacon->upload_depth =
  248. DomainReliabilityContext::kMaxUploadDepthToSchedule + 1;
  249. context_->OnBeacon(std::move(beacon));
  250. BeaconVector beacons;
  251. context_->GetQueuedBeaconsForTesting(&beacons);
  252. EXPECT_EQ(1u, beacons.size());
  253. time_.Advance(max_delay());
  254. EXPECT_FALSE(upload_allowed_callback_pending());
  255. }
  256. TEST_F(DomainReliabilityContextTest,
  257. MaxNestedBeaconAfterOverlyNestedBeaconSchedules) {
  258. base::HistogramTester histograms;
  259. InitContext(MakeTestConfig());
  260. // Add a beacon for a report that's too nested to schedule a beacon.
  261. std::unique_ptr<DomainReliabilityBeacon> beacon = MakeBeacon(&time_);
  262. beacon->upload_depth =
  263. DomainReliabilityContext::kMaxUploadDepthToSchedule + 1;
  264. context_->OnBeacon(std::move(beacon));
  265. BeaconVector beacons;
  266. context_->GetQueuedBeaconsForTesting(&beacons);
  267. EXPECT_EQ(1u, beacons.size());
  268. time_.Advance(max_delay());
  269. EXPECT_FALSE(upload_allowed_callback_pending());
  270. // Add a beacon for a report that should schedule a beacon, and make sure it
  271. // doesn't schedule until the deadline.
  272. beacon = MakeBeacon(&time_);
  273. beacon->upload_depth = DomainReliabilityContext::kMaxUploadDepthToSchedule;
  274. context_->OnBeacon(std::move(beacon));
  275. context_->GetQueuedBeaconsForTesting(&beacons);
  276. EXPECT_EQ(2u, beacons.size());
  277. time_.Advance(max_delay());
  278. EXPECT_TRUE(upload_allowed_callback_pending());
  279. CallUploadAllowedResultCallback(true);
  280. EXPECT_TRUE(upload_pending());
  281. // Check that both beacons were uploaded.
  282. DomainReliabilityUploader::UploadResult result;
  283. result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  284. CallUploadCallback(result);
  285. histograms.ExpectBucketCount(kBeaconOutcomeHistogram,
  286. DomainReliabilityBeacon::Outcome::kUploaded, 2);
  287. histograms.ExpectTotalCount(kBeaconOutcomeHistogram, 2);
  288. EXPECT_TRUE(CheckNoBeacons());
  289. ShutDownContext();
  290. histograms.ExpectTotalCount(kBeaconOutcomeHistogram, 2);
  291. }
  292. TEST_F(DomainReliabilityContextTest, ReportUpload) {
  293. base::HistogramTester histograms;
  294. InitContext(MakeTestConfig());
  295. context_->OnBeacon(
  296. MakeCustomizedBeacon(&time_, "tcp.connection_reset", "", true));
  297. BeaconVector beacons;
  298. context_->GetQueuedBeaconsForTesting(&beacons);
  299. EXPECT_EQ(1u, beacons.size());
  300. time_.Advance(max_delay());
  301. EXPECT_TRUE(upload_allowed_callback_pending());
  302. CallUploadAllowedResultCallback(true);
  303. EXPECT_TRUE(upload_pending());
  304. EXPECT_EQ(0, upload_max_depth());
  305. EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
  306. std::unique_ptr<Value> value =
  307. base::JSONReader::ReadDeprecated(upload_report());
  308. const Value* entry;
  309. ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry));
  310. EXPECT_TRUE(HasStringValue(*entry, "failure_data.custom_error",
  311. "net::ERR_CONNECTION_RESET"));
  312. EXPECT_TRUE(HasBooleanValue(*entry, "network_changed", false));
  313. EXPECT_TRUE(HasStringValue(*entry, "protocol", "HTTP"));
  314. EXPECT_TRUE(HasBooleanValue(*entry, "quic_broken", true));
  315. EXPECT_TRUE(HasBooleanValue(*entry, "quic_port_migration_detected", true));
  316. // N.B.: Assumes max_delay is 5 minutes.
  317. EXPECT_TRUE(HasIntegerValue(*entry, "request_age_ms", 300250));
  318. EXPECT_TRUE(HasIntegerValue(*entry, "request_elapsed_ms", 250));
  319. EXPECT_TRUE(HasDoubleValue(*entry, "sample_rate", 1.0));
  320. EXPECT_TRUE(HasStringValue(*entry, "server_ip", "127.0.0.1"));
  321. EXPECT_TRUE(HasStringValue(*entry, "status", "tcp.connection_reset"));
  322. EXPECT_TRUE(HasStringValue(*entry, "url", "https://localhost/"));
  323. EXPECT_TRUE(HasBooleanValue(*entry, "was_proxied", false));
  324. DomainReliabilityUploader::UploadResult result;
  325. result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  326. CallUploadCallback(result);
  327. histograms.ExpectBucketCount(kBeaconOutcomeHistogram,
  328. DomainReliabilityBeacon::Outcome::kUploaded, 1);
  329. histograms.ExpectTotalCount(kBeaconOutcomeHistogram, 1);
  330. EXPECT_TRUE(CheckNoBeacons());
  331. ShutDownContext();
  332. histograms.ExpectTotalCount(kBeaconOutcomeHistogram, 1);
  333. }
  334. TEST_F(DomainReliabilityContextTest, ReportUploadFails) {
  335. InitContext(MakeTestConfig());
  336. context_->OnBeacon(
  337. MakeCustomizedBeacon(&time_, "tcp.connection_reset", "", true));
  338. BeaconVector beacons;
  339. context_->GetQueuedBeaconsForTesting(&beacons);
  340. EXPECT_EQ(1u, beacons.size());
  341. time_.Advance(max_delay());
  342. EXPECT_TRUE(upload_allowed_callback_pending());
  343. CallUploadAllowedResultCallback(true);
  344. EXPECT_TRUE(upload_pending());
  345. EXPECT_EQ(0, upload_max_depth());
  346. EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
  347. // The upload fails.
  348. DomainReliabilityUploader::UploadResult result;
  349. result.status = DomainReliabilityUploader::UploadResult::FAILURE;
  350. CallUploadCallback(result);
  351. // The beacon should still be pending.
  352. beacons.clear();
  353. context_->GetQueuedBeaconsForTesting(&beacons);
  354. EXPECT_EQ(1u, beacons.size());
  355. // Another upload should be queued.
  356. time_.Advance(max_delay());
  357. EXPECT_TRUE(upload_allowed_callback_pending());
  358. }
  359. // Make sure that requests with only one NetworkIsolationKey are uploaded at a
  360. // time, in FIFO order.
  361. TEST_F(DomainReliabilityContextTest, ReportUploadNetworkIsolationKey) {
  362. const net::NetworkIsolationKey kNetworkIsolationKey1 =
  363. net::NetworkIsolationKey::CreateTransient();
  364. const net::NetworkIsolationKey kNetworkIsolationKey2 =
  365. net::NetworkIsolationKey::CreateTransient();
  366. const net::NetworkIsolationKey kNetworkIsolationKey3 =
  367. net::NetworkIsolationKey::CreateTransient();
  368. InitContext(MakeTestConfig());
  369. // Three beacons with kNetworkIsolationKey1, two with kNetworkIsolationKey2,
  370. // and one with kNetworkIsolationKey3. Have beacons with the same key both
  371. // adjacent to each other, and separated by beacons with other keys. Give
  372. // each a unique status, so it's easy to check which beacons are included in
  373. // each report.
  374. const char kStatusNik11[] = "nik1.status1";
  375. const char kStatusNik12[] = "nik1.status2";
  376. const char kStatusNik13[] = "nik1.status3";
  377. const char kStatusNik21[] = "nik2.status1";
  378. const char kStatusNik22[] = "nik2.status2";
  379. const char kStatusNik31[] = "nik3.status1";
  380. context_->OnBeacon(MakeBeaconWithNetworkIsolationKey(&time_, kStatusNik11,
  381. kNetworkIsolationKey1));
  382. context_->OnBeacon(MakeBeaconWithNetworkIsolationKey(&time_, kStatusNik12,
  383. kNetworkIsolationKey1));
  384. context_->OnBeacon(MakeBeaconWithNetworkIsolationKey(&time_, kStatusNik21,
  385. kNetworkIsolationKey2));
  386. context_->OnBeacon(MakeBeaconWithNetworkIsolationKey(&time_, kStatusNik31,
  387. kNetworkIsolationKey3));
  388. context_->OnBeacon(MakeBeaconWithNetworkIsolationKey(&time_, kStatusNik13,
  389. kNetworkIsolationKey1));
  390. context_->OnBeacon(MakeBeaconWithNetworkIsolationKey(&time_, kStatusNik22,
  391. kNetworkIsolationKey2));
  392. // All the beacons should be queued, in FIFO order.
  393. BeaconVector beacons;
  394. context_->GetQueuedBeaconsForTesting(&beacons);
  395. ASSERT_EQ(6u, beacons.size());
  396. EXPECT_EQ(kNetworkIsolationKey1, beacons[0]->network_isolation_key);
  397. EXPECT_EQ(kStatusNik11, beacons[0]->status);
  398. EXPECT_EQ(kNetworkIsolationKey1, beacons[1]->network_isolation_key);
  399. EXPECT_EQ(kStatusNik12, beacons[1]->status);
  400. EXPECT_EQ(kNetworkIsolationKey2, beacons[2]->network_isolation_key);
  401. EXPECT_EQ(kStatusNik21, beacons[2]->status);
  402. EXPECT_EQ(kNetworkIsolationKey3, beacons[3]->network_isolation_key);
  403. EXPECT_EQ(kStatusNik31, beacons[3]->status);
  404. EXPECT_EQ(kNetworkIsolationKey1, beacons[4]->network_isolation_key);
  405. EXPECT_EQ(kStatusNik13, beacons[4]->status);
  406. EXPECT_EQ(kNetworkIsolationKey2, beacons[5]->network_isolation_key);
  407. EXPECT_EQ(kStatusNik22, beacons[5]->status);
  408. // Wait for the report to start being uploaded.
  409. time_.Advance(max_delay());
  410. EXPECT_TRUE(upload_allowed_callback_pending());
  411. CallUploadAllowedResultCallback(true);
  412. EXPECT_TRUE(upload_pending());
  413. EXPECT_EQ(0, upload_max_depth());
  414. EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
  415. EXPECT_EQ(kNetworkIsolationKey1, upload_network_isolation_key());
  416. // Check that only the strings associated with the first NIK are present in
  417. // the report.
  418. EXPECT_NE(upload_report().find(kStatusNik11), std::string::npos);
  419. EXPECT_NE(upload_report().find(kStatusNik12), std::string::npos);
  420. EXPECT_NE(upload_report().find(kStatusNik13), std::string::npos);
  421. EXPECT_EQ(upload_report().find(kStatusNik21), std::string::npos);
  422. EXPECT_EQ(upload_report().find(kStatusNik22), std::string::npos);
  423. EXPECT_EQ(upload_report().find(kStatusNik31), std::string::npos);
  424. // Complete upload.
  425. DomainReliabilityUploader::UploadResult successful_result;
  426. successful_result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  427. CallUploadCallback(successful_result);
  428. // There should still be 3 beacons queued, in the same order as before.
  429. context_->GetQueuedBeaconsForTesting(&beacons);
  430. ASSERT_EQ(3u, beacons.size());
  431. EXPECT_EQ(kNetworkIsolationKey2, beacons[0]->network_isolation_key);
  432. EXPECT_EQ(kStatusNik21, beacons[0]->status);
  433. EXPECT_EQ(kNetworkIsolationKey3, beacons[1]->network_isolation_key);
  434. EXPECT_EQ(kStatusNik31, beacons[1]->status);
  435. EXPECT_EQ(kNetworkIsolationKey2, beacons[2]->network_isolation_key);
  436. EXPECT_EQ(kStatusNik22, beacons[2]->status);
  437. // The next upload should automatically trigger.
  438. time_.Advance(max_delay());
  439. EXPECT_TRUE(upload_allowed_callback_pending());
  440. CallUploadAllowedResultCallback(true);
  441. EXPECT_TRUE(upload_pending());
  442. EXPECT_EQ(0, upload_max_depth());
  443. EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
  444. EXPECT_EQ(kNetworkIsolationKey2, upload_network_isolation_key());
  445. // Check that only the strings associated with the second NIK are present in
  446. // the report.
  447. EXPECT_EQ(upload_report().find(kStatusNik11), std::string::npos);
  448. EXPECT_EQ(upload_report().find(kStatusNik12), std::string::npos);
  449. EXPECT_EQ(upload_report().find(kStatusNik13), std::string::npos);
  450. EXPECT_NE(upload_report().find(kStatusNik21), std::string::npos);
  451. EXPECT_NE(upload_report().find(kStatusNik22), std::string::npos);
  452. EXPECT_EQ(upload_report().find(kStatusNik31), std::string::npos);
  453. // Complete upload.
  454. CallUploadCallback(successful_result);
  455. // There should still be 1 beacon queued.
  456. context_->GetQueuedBeaconsForTesting(&beacons);
  457. ASSERT_EQ(1u, beacons.size());
  458. EXPECT_EQ(kNetworkIsolationKey3, beacons[0]->network_isolation_key);
  459. EXPECT_EQ(kStatusNik31, beacons[0]->status);
  460. // The next upload should automatically trigger.
  461. time_.Advance(max_delay());
  462. EXPECT_TRUE(upload_allowed_callback_pending());
  463. CallUploadAllowedResultCallback(true);
  464. EXPECT_TRUE(upload_pending());
  465. EXPECT_EQ(0, upload_max_depth());
  466. EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
  467. EXPECT_EQ(kNetworkIsolationKey3, upload_network_isolation_key());
  468. // Check that only the strings associated with the third NIK are present in
  469. // the report.
  470. EXPECT_EQ(upload_report().find(kStatusNik11), std::string::npos);
  471. EXPECT_EQ(upload_report().find(kStatusNik12), std::string::npos);
  472. EXPECT_EQ(upload_report().find(kStatusNik13), std::string::npos);
  473. EXPECT_EQ(upload_report().find(kStatusNik21), std::string::npos);
  474. EXPECT_EQ(upload_report().find(kStatusNik22), std::string::npos);
  475. EXPECT_NE(upload_report().find(kStatusNik31), std::string::npos);
  476. // Complete upload.
  477. CallUploadCallback(successful_result);
  478. EXPECT_TRUE(CheckNoBeacons());
  479. }
  480. // Make sure that kMaxUploadDepthToSchedule is respected when requests have
  481. // different NetworkIsolationKeys.
  482. TEST_F(DomainReliabilityContextTest, ReportUploadDepthNetworkIsolationKey) {
  483. const net::NetworkIsolationKey kNetworkIsolationKey1 =
  484. net::NetworkIsolationKey::CreateTransient();
  485. const net::NetworkIsolationKey kNetworkIsolationKey2 =
  486. net::NetworkIsolationKey::CreateTransient();
  487. InitContext(MakeTestConfig());
  488. const char kStatusNik1ExceedsMaxDepth[] = "nik1.exceeds_max_depth";
  489. const char kStatusNik2ExceedsMaxDepth[] = "nik2.exceeds_max_depth";
  490. const char kStatusNik2MaxDepth[] = "nik2.max_depth";
  491. // Add a beacon with kNetworkIsolationKey1 and a depth that exceeds the max
  492. // depth to trigger an upload. No upload should be queued.
  493. std::unique_ptr<DomainReliabilityBeacon> beacon =
  494. MakeBeaconWithNetworkIsolationKey(&time_, kStatusNik1ExceedsMaxDepth,
  495. kNetworkIsolationKey1);
  496. beacon->upload_depth =
  497. DomainReliabilityContext::kMaxUploadDepthToSchedule + 1;
  498. context_->OnBeacon(std::move(beacon));
  499. time_.Advance(max_delay());
  500. EXPECT_FALSE(upload_allowed_callback_pending());
  501. // Add a beacon with kNetworkIsolationKey2 and a depth that exceeds the max
  502. // depth to trigger an upload. No upload should be queued.
  503. beacon = MakeBeaconWithNetworkIsolationKey(&time_, kStatusNik2ExceedsMaxDepth,
  504. kNetworkIsolationKey2);
  505. beacon->upload_depth =
  506. DomainReliabilityContext::kMaxUploadDepthToSchedule + 1;
  507. context_->OnBeacon(std::move(beacon));
  508. time_.Advance(max_delay());
  509. EXPECT_FALSE(upload_allowed_callback_pending());
  510. // Add a beacon with kNetworkIsolationKey2 and a depth that equals the max
  511. // depth to trigger an upload. An upload should be queued.
  512. beacon = MakeBeaconWithNetworkIsolationKey(&time_, kStatusNik2MaxDepth,
  513. kNetworkIsolationKey2);
  514. beacon->upload_depth = DomainReliabilityContext::kMaxUploadDepthToSchedule;
  515. context_->OnBeacon(std::move(beacon));
  516. time_.Advance(max_delay());
  517. EXPECT_TRUE(upload_allowed_callback_pending());
  518. // All the beacons should still be queued.
  519. BeaconVector beacons;
  520. context_->GetQueuedBeaconsForTesting(&beacons);
  521. ASSERT_EQ(3u, beacons.size());
  522. EXPECT_EQ(kNetworkIsolationKey1, beacons[0]->network_isolation_key);
  523. EXPECT_EQ(kStatusNik1ExceedsMaxDepth, beacons[0]->status);
  524. EXPECT_EQ(DomainReliabilityContext::kMaxUploadDepthToSchedule + 1,
  525. beacons[0]->upload_depth);
  526. EXPECT_EQ(kNetworkIsolationKey2, beacons[1]->network_isolation_key);
  527. EXPECT_EQ(kStatusNik2ExceedsMaxDepth, beacons[1]->status);
  528. EXPECT_EQ(DomainReliabilityContext::kMaxUploadDepthToSchedule + 1,
  529. beacons[1]->upload_depth);
  530. EXPECT_EQ(kNetworkIsolationKey2, beacons[2]->network_isolation_key);
  531. EXPECT_EQ(kStatusNik2MaxDepth, beacons[2]->status);
  532. EXPECT_EQ(DomainReliabilityContext::kMaxUploadDepthToSchedule,
  533. beacons[2]->upload_depth);
  534. // Start the upload.
  535. CallUploadAllowedResultCallback(true);
  536. EXPECT_TRUE(upload_pending());
  537. EXPECT_EQ(DomainReliabilityContext::kMaxUploadDepthToSchedule + 1,
  538. upload_max_depth());
  539. EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
  540. EXPECT_EQ(kNetworkIsolationKey2, upload_network_isolation_key());
  541. // Check that only the strings associated with the second NIK are present in
  542. // the report.
  543. EXPECT_EQ(upload_report().find(kStatusNik1ExceedsMaxDepth),
  544. std::string::npos);
  545. EXPECT_NE(upload_report().find(kStatusNik2ExceedsMaxDepth),
  546. std::string::npos);
  547. EXPECT_NE(upload_report().find(kStatusNik2MaxDepth), std::string::npos);
  548. // Complete upload.
  549. DomainReliabilityUploader::UploadResult successful_result;
  550. successful_result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  551. CallUploadCallback(successful_result);
  552. // There should still be 1 beacon queued.
  553. context_->GetQueuedBeaconsForTesting(&beacons);
  554. ASSERT_EQ(1u, beacons.size());
  555. EXPECT_EQ(kNetworkIsolationKey1, beacons[0]->network_isolation_key);
  556. EXPECT_EQ(kStatusNik1ExceedsMaxDepth, beacons[0]->status);
  557. EXPECT_EQ(DomainReliabilityContext::kMaxUploadDepthToSchedule + 1,
  558. beacons[0]->upload_depth);
  559. // No upload should be queued, since the depth is too high.
  560. time_.Advance(max_delay());
  561. EXPECT_FALSE(upload_allowed_callback_pending());
  562. }
  563. TEST_F(DomainReliabilityContextTest, UploadForbidden) {
  564. InitContext(MakeTestConfig());
  565. context_->OnBeacon(
  566. MakeCustomizedBeacon(&time_, "tcp.connection_reset", "", true));
  567. BeaconVector beacons;
  568. context_->GetQueuedBeaconsForTesting(&beacons);
  569. EXPECT_EQ(1u, beacons.size());
  570. time_.Advance(max_delay());
  571. EXPECT_TRUE(upload_allowed_callback_pending());
  572. CallUploadAllowedResultCallback(false);
  573. EXPECT_FALSE(upload_pending());
  574. }
  575. TEST_F(DomainReliabilityContextTest, NetworkChanged) {
  576. InitContext(MakeTestConfig());
  577. context_->OnBeacon(MakeBeacon(&time_));
  578. BeaconVector beacons;
  579. context_->GetQueuedBeaconsForTesting(&beacons);
  580. EXPECT_EQ(1u, beacons.size());
  581. // Simulate a network change after the request but before the upload.
  582. last_network_change_time_ = time_.NowTicks();
  583. time_.Advance(max_delay());
  584. EXPECT_TRUE(upload_allowed_callback_pending());
  585. CallUploadAllowedResultCallback(true);
  586. EXPECT_TRUE(upload_pending());
  587. EXPECT_EQ(0, upload_max_depth());
  588. EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
  589. std::unique_ptr<Value> value =
  590. base::JSONReader::ReadDeprecated(upload_report());
  591. const Value* entry;
  592. ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry));
  593. EXPECT_TRUE(HasBooleanValue(*entry, "network_changed", true));
  594. DomainReliabilityUploader::UploadResult result;
  595. result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  596. CallUploadCallback(result);
  597. EXPECT_TRUE(CheckNoBeacons());
  598. }
  599. // Always expecting granular QUIC errors if status is quic.protocol error.
  600. TEST_F(DomainReliabilityContextTest,
  601. ReportUploadWithQuicProtocolErrorAndQuicError) {
  602. InitContext(MakeTestConfig());
  603. context_->OnBeacon(MakeCustomizedBeacon(&time_, "quic.protocol",
  604. "quic.invalid.stream_data", true));
  605. BeaconVector beacons;
  606. context_->GetQueuedBeaconsForTesting(&beacons);
  607. EXPECT_EQ(1u, beacons.size());
  608. time_.Advance(max_delay());
  609. EXPECT_TRUE(upload_allowed_callback_pending());
  610. CallUploadAllowedResultCallback(true);
  611. EXPECT_TRUE(upload_pending());
  612. EXPECT_EQ(0, upload_max_depth());
  613. EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
  614. std::unique_ptr<Value> value =
  615. base::JSONReader::ReadDeprecated(upload_report());
  616. const Value* entry;
  617. ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry));
  618. EXPECT_TRUE(HasBooleanValue(*entry, "quic_broken", true));
  619. EXPECT_TRUE(HasBooleanValue(*entry, "quic_port_migration_detected", true));
  620. EXPECT_TRUE(HasStringValue(*entry, "status", "quic.protocol"));
  621. EXPECT_TRUE(HasStringValue(*entry, "quic_error", "quic.invalid.stream_data"));
  622. DomainReliabilityUploader::UploadResult result;
  623. result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  624. CallUploadCallback(result);
  625. EXPECT_TRUE(CheckNoBeacons());
  626. }
  627. // If status is not quic.protocol, expect no granular QUIC error to be reported.
  628. TEST_F(DomainReliabilityContextTest,
  629. ReportUploadWithNonQuicProtocolErrorAndNoQuicError) {
  630. InitContext(MakeTestConfig());
  631. context_->OnBeacon(MakeBeacon(&time_));
  632. BeaconVector beacons;
  633. context_->GetQueuedBeaconsForTesting(&beacons);
  634. EXPECT_EQ(1u, beacons.size());
  635. time_.Advance(max_delay());
  636. EXPECT_TRUE(upload_allowed_callback_pending());
  637. CallUploadAllowedResultCallback(true);
  638. EXPECT_TRUE(upload_pending());
  639. EXPECT_EQ(0, upload_max_depth());
  640. EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
  641. std::unique_ptr<Value> value =
  642. base::JSONReader::ReadDeprecated(upload_report());
  643. const Value* entry;
  644. ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry));
  645. EXPECT_TRUE(HasStringValue(*entry, "status", "tcp.connection_reset"));
  646. EXPECT_FALSE(HasStringValue(*entry, "quic_error", ""));
  647. DomainReliabilityUploader::UploadResult result;
  648. result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  649. CallUploadCallback(result);
  650. EXPECT_TRUE(CheckNoBeacons());
  651. }
  652. // Edge cases that a non-QUIC protocol error with granular QUIC error reported,
  653. // probably indicating state machine in http_network_transaction is working
  654. // in a different way.
  655. TEST_F(DomainReliabilityContextTest,
  656. ReportUploadWithNonQuicProtocolErrorAndQuicError) {
  657. InitContext(MakeTestConfig());
  658. context_->OnBeacon(MakeCustomizedBeacon(&time_, "tcp.connection_reset",
  659. "quic.invalid.stream_data", false));
  660. BeaconVector beacons;
  661. context_->GetQueuedBeaconsForTesting(&beacons);
  662. EXPECT_EQ(1u, beacons.size());
  663. time_.Advance(max_delay());
  664. EXPECT_TRUE(upload_allowed_callback_pending());
  665. CallUploadAllowedResultCallback(true);
  666. EXPECT_TRUE(upload_pending());
  667. EXPECT_EQ(0, upload_max_depth());
  668. EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
  669. std::unique_ptr<Value> value =
  670. base::JSONReader::ReadDeprecated(upload_report());
  671. const Value* entry;
  672. ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry));
  673. EXPECT_TRUE(HasBooleanValue(*entry, "quic_broken", true));
  674. EXPECT_TRUE(HasStringValue(*entry, "status", "tcp.connection_reset"));
  675. EXPECT_TRUE(HasStringValue(*entry, "quic_error", "quic.invalid.stream_data"));
  676. DomainReliabilityUploader::UploadResult result;
  677. result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  678. CallUploadCallback(result);
  679. EXPECT_TRUE(CheckNoBeacons());
  680. }
  681. TEST_F(DomainReliabilityContextTest, ZeroSampleRate) {
  682. std::unique_ptr<DomainReliabilityConfig> config(MakeTestConfig());
  683. config->failure_sample_rate = 0.0;
  684. InitContext(std::move(config));
  685. BeaconVector beacons;
  686. for (int i = 0; i < 100; i++) {
  687. context_->OnBeacon(MakeBeacon(&time_));
  688. EXPECT_TRUE(CheckNoBeacons());
  689. }
  690. }
  691. TEST_F(DomainReliabilityContextTest, FractionalSampleRate) {
  692. std::unique_ptr<DomainReliabilityConfig> config(MakeTestConfig());
  693. config->failure_sample_rate = 0.5;
  694. InitContext(std::move(config));
  695. BeaconVector beacons;
  696. do {
  697. context_->OnBeacon(MakeBeacon(&time_));
  698. context_->GetQueuedBeaconsForTesting(&beacons);
  699. } while (beacons.empty());
  700. EXPECT_EQ(1u, beacons.size());
  701. time_.Advance(max_delay());
  702. EXPECT_TRUE(upload_allowed_callback_pending());
  703. CallUploadAllowedResultCallback(true);
  704. EXPECT_TRUE(upload_pending());
  705. EXPECT_EQ(0, upload_max_depth());
  706. EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
  707. std::unique_ptr<Value> value =
  708. base::JSONReader::ReadDeprecated(upload_report());
  709. const Value* entry;
  710. ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry));
  711. EXPECT_TRUE(HasDoubleValue(*entry, "sample_rate", 0.5));
  712. DomainReliabilityUploader::UploadResult result;
  713. result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  714. CallUploadCallback(result);
  715. EXPECT_TRUE(CheckNoBeacons());
  716. }
  717. TEST_F(DomainReliabilityContextTest, FailureSampleOnly) {
  718. std::unique_ptr<DomainReliabilityConfig> config(MakeTestConfig());
  719. config->success_sample_rate = 0.0;
  720. config->failure_sample_rate = 1.0;
  721. InitContext(std::move(config));
  722. BeaconVector beacons;
  723. context_->OnBeacon(MakeBeacon(&time_));
  724. context_->GetQueuedBeaconsForTesting(&beacons);
  725. EXPECT_EQ(1u, beacons.size());
  726. std::unique_ptr<DomainReliabilityBeacon> beacon(MakeBeacon(&time_));
  727. beacon->status = "ok";
  728. beacon->chrome_error = net::OK;
  729. context_->OnBeacon(std::move(beacon));
  730. context_->GetQueuedBeaconsForTesting(&beacons);
  731. EXPECT_EQ(1u, beacons.size());
  732. }
  733. TEST_F(DomainReliabilityContextTest, SuccessSampleOnly) {
  734. std::unique_ptr<DomainReliabilityConfig> config(MakeTestConfig());
  735. config->success_sample_rate = 1.0;
  736. config->failure_sample_rate = 0.0;
  737. InitContext(std::move(config));
  738. BeaconVector beacons;
  739. context_->OnBeacon(MakeBeacon(&time_));
  740. context_->GetQueuedBeaconsForTesting(&beacons);
  741. EXPECT_EQ(0u, beacons.size());
  742. std::unique_ptr<DomainReliabilityBeacon> beacon(MakeBeacon(&time_));
  743. beacon->status = "ok";
  744. beacon->chrome_error = net::OK;
  745. context_->OnBeacon(std::move(beacon));
  746. context_->GetQueuedBeaconsForTesting(&beacons);
  747. EXPECT_EQ(1u, beacons.size());
  748. }
  749. TEST_F(DomainReliabilityContextTest, SampleAllBeacons) {
  750. std::unique_ptr<DomainReliabilityConfig> config(MakeTestConfig());
  751. config->success_sample_rate = 1.0;
  752. config->failure_sample_rate = 1.0;
  753. InitContext(std::move(config));
  754. BeaconVector beacons;
  755. context_->OnBeacon(MakeBeacon(&time_));
  756. context_->GetQueuedBeaconsForTesting(&beacons);
  757. EXPECT_EQ(1u, beacons.size());
  758. std::unique_ptr<DomainReliabilityBeacon> beacon(MakeBeacon(&time_));
  759. beacon->status = "ok";
  760. beacon->chrome_error = net::OK;
  761. context_->OnBeacon(std::move(beacon));
  762. context_->GetQueuedBeaconsForTesting(&beacons);
  763. EXPECT_EQ(2u, beacons.size());
  764. }
  765. TEST_F(DomainReliabilityContextTest, SampleNoBeacons) {
  766. std::unique_ptr<DomainReliabilityConfig> config(MakeTestConfig());
  767. config->success_sample_rate = 0.0;
  768. config->failure_sample_rate = 0.0;
  769. InitContext(std::move(config));
  770. BeaconVector beacons;
  771. context_->OnBeacon(MakeBeacon(&time_));
  772. context_->GetQueuedBeaconsForTesting(&beacons);
  773. EXPECT_EQ(0u, beacons.size());
  774. std::unique_ptr<DomainReliabilityBeacon> beacon(MakeBeacon(&time_));
  775. beacon->status = "ok";
  776. beacon->chrome_error = net::OK;
  777. context_->OnBeacon(std::move(beacon));
  778. context_->GetQueuedBeaconsForTesting(&beacons);
  779. EXPECT_EQ(0u, beacons.size());
  780. }
  781. TEST_F(DomainReliabilityContextTest, ExpiredBeaconDoesNotUpload) {
  782. base::HistogramTester histograms;
  783. InitContext(MakeTestConfig());
  784. std::unique_ptr<DomainReliabilityBeacon> beacon = MakeBeacon(&time_);
  785. time_.Advance(base::Hours(2));
  786. context_->OnBeacon(std::move(beacon));
  787. time_.Advance(max_delay());
  788. EXPECT_FALSE(upload_allowed_callback_pending());
  789. BeaconVector beacons;
  790. context_->GetQueuedBeaconsForTesting(&beacons);
  791. EXPECT_TRUE(beacons.empty());
  792. histograms.ExpectBucketCount(kBeaconOutcomeHistogram,
  793. DomainReliabilityBeacon::Outcome::kExpired, 1);
  794. histograms.ExpectTotalCount(kBeaconOutcomeHistogram, 1);
  795. ShutDownContext();
  796. histograms.ExpectTotalCount(kBeaconOutcomeHistogram, 1);
  797. }
  798. TEST_F(DomainReliabilityContextTest, EvictOldestBeacon) {
  799. base::HistogramTester histograms;
  800. InitContext(MakeTestConfig());
  801. std::unique_ptr<DomainReliabilityBeacon> oldest_beacon = MakeBeacon(&time_);
  802. const DomainReliabilityBeacon* oldest_beacon_ptr = oldest_beacon.get();
  803. time_.Advance(base::Seconds(1));
  804. context_->OnBeacon(std::move(oldest_beacon));
  805. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  806. std::unique_ptr<DomainReliabilityBeacon> beacon = MakeBeacon(&time_);
  807. time_.Advance(base::Seconds(1));
  808. context_->OnBeacon(std::move(beacon));
  809. }
  810. BeaconVector beacons;
  811. context_->GetQueuedBeaconsForTesting(&beacons);
  812. EXPECT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  813. for (const DomainReliabilityBeacon* beacon : beacons) {
  814. EXPECT_NE(oldest_beacon_ptr, beacon);
  815. }
  816. histograms.ExpectBucketCount(kBeaconOutcomeHistogram,
  817. DomainReliabilityBeacon::Outcome::kEvicted, 1);
  818. histograms.ExpectTotalCount(kBeaconOutcomeHistogram, 1);
  819. ShutDownContext();
  820. histograms.ExpectBucketCount(
  821. kBeaconOutcomeHistogram,
  822. DomainReliabilityBeacon::Outcome::kContextShutDown,
  823. DomainReliabilityContext::kMaxQueuedBeacons);
  824. histograms.ExpectTotalCount(kBeaconOutcomeHistogram,
  825. 1 + DomainReliabilityContext::kMaxQueuedBeacons);
  826. }
  827. // Test eviction when there's no active upload.
  828. TEST_F(DomainReliabilityContextTest, Eviction) {
  829. InitContext(MakeTestConfig());
  830. // Add |DomainReliabilityContext::kMaxQueuedBeacons| beacons.
  831. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  832. context_->OnBeacon(
  833. MakeCustomizedBeacon(&time_, StatusFromInt(i), "" /* quic_error */,
  834. false /* quic_port_migration_detected */));
  835. }
  836. // No beacons should have been evicted.
  837. BeaconVector beacons;
  838. context_->GetQueuedBeaconsForTesting(&beacons);
  839. ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  840. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  841. EXPECT_EQ(beacons[i]->status, StatusFromInt(i));
  842. }
  843. // Add one more beacon.
  844. context_->OnBeacon(MakeCustomizedBeacon(
  845. &time_, StatusFromInt(DomainReliabilityContext::kMaxQueuedBeacons),
  846. "" /* quic_error */, false /* quic_port_migration_detected */));
  847. // The first beacon should have been evicted.
  848. context_->GetQueuedBeaconsForTesting(&beacons);
  849. ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  850. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  851. EXPECT_EQ(beacons[i]->status, StatusFromInt(i + 1));
  852. }
  853. // Wait for the report to start being uploaded.
  854. time_.Advance(max_delay());
  855. EXPECT_TRUE(upload_allowed_callback_pending());
  856. CallUploadAllowedResultCallback(true);
  857. EXPECT_TRUE(upload_pending());
  858. // All beacons but the first should be in the report.
  859. EXPECT_EQ(upload_report().find(StatusFromInt(0)), std::string::npos);
  860. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  861. EXPECT_NE(upload_report().find(StatusFromInt(i + 1)), std::string::npos);
  862. }
  863. DomainReliabilityUploader::UploadResult result;
  864. result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  865. CallUploadCallback(result);
  866. EXPECT_TRUE(CheckNoBeacons());
  867. }
  868. // Test eviction when there's an upload that eventually succeeds.
  869. TEST_F(DomainReliabilityContextTest, EvictionDuringSuccessfulUpload) {
  870. InitContext(MakeTestConfig());
  871. // Add |DomainReliabilityContext::kMaxQueuedBeacons| beacons.
  872. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  873. context_->OnBeacon(
  874. MakeCustomizedBeacon(&time_, StatusFromInt(i), "" /* quic_error */,
  875. false /* quic_port_migration_detected */));
  876. }
  877. // No beacons should have been evicted.
  878. BeaconVector beacons;
  879. context_->GetQueuedBeaconsForTesting(&beacons);
  880. ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  881. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  882. EXPECT_EQ(beacons[i]->status, StatusFromInt(i));
  883. }
  884. // Wait for the report to start being uploaded.
  885. time_.Advance(max_delay());
  886. EXPECT_TRUE(upload_allowed_callback_pending());
  887. CallUploadAllowedResultCallback(true);
  888. EXPECT_TRUE(upload_pending());
  889. // All beacons should be in the report.
  890. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  891. EXPECT_NE(upload_report().find(StatusFromInt(i)), std::string::npos);
  892. }
  893. // Add one more beacon.
  894. context_->OnBeacon(MakeCustomizedBeacon(
  895. &time_, StatusFromInt(DomainReliabilityContext::kMaxQueuedBeacons),
  896. "" /* quic_error */, false /* quic_port_migration_detected */));
  897. // The first beacon should have been evicted.
  898. context_->GetQueuedBeaconsForTesting(&beacons);
  899. ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  900. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  901. EXPECT_EQ(beacons[i]->status, StatusFromInt(i + 1));
  902. }
  903. // The upload completes.
  904. DomainReliabilityUploader::UploadResult successful_result;
  905. successful_result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  906. CallUploadCallback(successful_result);
  907. // The last beacon should still be queued.
  908. context_->GetQueuedBeaconsForTesting(&beacons);
  909. ASSERT_EQ(1u, beacons.size());
  910. EXPECT_EQ(beacons[0]->status,
  911. StatusFromInt(DomainReliabilityContext::kMaxQueuedBeacons));
  912. // Another upload should have still been queued, for the new report. Wait for
  913. // it to start uploading.
  914. time_.Advance(max_delay());
  915. EXPECT_TRUE(upload_allowed_callback_pending());
  916. CallUploadAllowedResultCallback(true);
  917. EXPECT_TRUE(upload_pending());
  918. // Only the last beacon should be in the report.
  919. EXPECT_NE(upload_report().find(
  920. StatusFromInt(DomainReliabilityContext::kMaxQueuedBeacons)),
  921. std::string::npos);
  922. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  923. EXPECT_EQ(upload_report().find(StatusFromInt(i)), std::string::npos);
  924. }
  925. // The upload completes.
  926. CallUploadCallback(successful_result);
  927. EXPECT_TRUE(CheckNoBeacons());
  928. }
  929. // Test eviction when there's an upload that eventually fails.
  930. TEST_F(DomainReliabilityContextTest, EvictionDuringUnsuccessfulUpload) {
  931. InitContext(MakeTestConfig());
  932. // Add |DomainReliabilityContext::kMaxQueuedBeacons| beacons.
  933. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  934. context_->OnBeacon(
  935. MakeCustomizedBeacon(&time_, StatusFromInt(i), "" /* quic_error */,
  936. false /* quic_port_migration_detected */));
  937. }
  938. // No beacons should have been evicted.
  939. BeaconVector beacons;
  940. context_->GetQueuedBeaconsForTesting(&beacons);
  941. ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  942. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  943. EXPECT_EQ(beacons[i]->status, StatusFromInt(i));
  944. }
  945. // Wait for the report to start being uploaded.
  946. time_.Advance(max_delay());
  947. EXPECT_TRUE(upload_allowed_callback_pending());
  948. CallUploadAllowedResultCallback(true);
  949. EXPECT_TRUE(upload_pending());
  950. // All beacons should be in the report.
  951. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  952. EXPECT_NE(upload_report().find(StatusFromInt(i)), std::string::npos);
  953. }
  954. // Add one more beacon.
  955. context_->OnBeacon(MakeCustomizedBeacon(
  956. &time_, StatusFromInt(DomainReliabilityContext::kMaxQueuedBeacons),
  957. "" /* quic_error */, false /* quic_port_migration_detected */));
  958. // The first beacon should have been evicted.
  959. context_->GetQueuedBeaconsForTesting(&beacons);
  960. ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  961. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  962. EXPECT_EQ(beacons[i]->status, StatusFromInt(i + 1));
  963. }
  964. // The upload fails.
  965. DomainReliabilityUploader::UploadResult result;
  966. result.status = DomainReliabilityUploader::UploadResult::FAILURE;
  967. CallUploadCallback(result);
  968. // All beacons but the first should still be queued.
  969. context_->GetQueuedBeaconsForTesting(&beacons);
  970. ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  971. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  972. EXPECT_EQ(beacons[i]->status, StatusFromInt(i + 1));
  973. }
  974. // Wait for the report to start being uploaded.
  975. time_.Advance(max_delay());
  976. EXPECT_TRUE(upload_allowed_callback_pending());
  977. CallUploadAllowedResultCallback(true);
  978. EXPECT_TRUE(upload_pending());
  979. // All beacons but the first should be in the report.
  980. EXPECT_EQ(upload_report().find(StatusFromInt(0)), std::string::npos);
  981. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  982. EXPECT_NE(upload_report().find(StatusFromInt(i + 1)), std::string::npos);
  983. }
  984. // The upload completes successfully.
  985. result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  986. CallUploadCallback(result);
  987. EXPECT_TRUE(CheckNoBeacons());
  988. }
  989. // Test eviction of all initially pending reports when there's an upload that
  990. // eventually succeeds.
  991. TEST_F(DomainReliabilityContextTest, EvictAllDuringSuccessfulUpload) {
  992. InitContext(MakeTestConfig());
  993. // Add |DomainReliabilityContext::kMaxQueuedBeacons| beacons.
  994. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  995. context_->OnBeacon(
  996. MakeCustomizedBeacon(&time_, StatusFromInt(i), "" /* quic_error */,
  997. false /* quic_port_migration_detected */));
  998. }
  999. // No beacons should have been evicted.
  1000. BeaconVector beacons;
  1001. context_->GetQueuedBeaconsForTesting(&beacons);
  1002. ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  1003. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  1004. EXPECT_EQ(beacons[i]->status, StatusFromInt(i));
  1005. }
  1006. // Wait for the report to start being uploaded.
  1007. time_.Advance(max_delay());
  1008. EXPECT_TRUE(upload_allowed_callback_pending());
  1009. CallUploadAllowedResultCallback(true);
  1010. EXPECT_TRUE(upload_pending());
  1011. // All beacons should be in the report.
  1012. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  1013. EXPECT_NE(upload_report().find(StatusFromInt(i)), std::string::npos);
  1014. }
  1015. // Evict all beacons, twice. It's important to add a beacon after all beacons
  1016. // from the original report have already been deleted, to make sure that
  1017. // eviction works correctly once |uploading_beacons_size_| reaches 0.
  1018. for (size_t i = 0; i < 2 * DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  1019. context_->OnBeacon(MakeCustomizedBeacon(
  1020. &time_, StatusFromInt(i + DomainReliabilityContext::kMaxQueuedBeacons),
  1021. "" /* quic_error */, false /* quic_port_migration_detected */));
  1022. }
  1023. // All the original beacons should have been evicted, as should the first
  1024. // |DomainReliabilityContext::kMaxQueuedBeacons| beacons from the above loop.
  1025. context_->GetQueuedBeaconsForTesting(&beacons);
  1026. ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  1027. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  1028. EXPECT_EQ(
  1029. beacons[i]->status,
  1030. StatusFromInt(i + 2 * DomainReliabilityContext::kMaxQueuedBeacons));
  1031. }
  1032. // The upload succeeds, but no beacons should be removed, since all the
  1033. // original beacons have already been evicted.
  1034. DomainReliabilityUploader::UploadResult successful_result;
  1035. successful_result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  1036. CallUploadCallback(successful_result);
  1037. // The same beacons as before should be queued.
  1038. context_->GetQueuedBeaconsForTesting(&beacons);
  1039. ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  1040. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  1041. EXPECT_EQ(
  1042. beacons[i]->status,
  1043. StatusFromInt(i + 2 * DomainReliabilityContext::kMaxQueuedBeacons));
  1044. }
  1045. // Wait for the report to start being uploaded.
  1046. time_.Advance(max_delay());
  1047. EXPECT_TRUE(upload_allowed_callback_pending());
  1048. CallUploadAllowedResultCallback(true);
  1049. EXPECT_TRUE(upload_pending());
  1050. // Check the expected beacons are in the report.
  1051. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons * 3; ++i) {
  1052. if (i < DomainReliabilityContext::kMaxQueuedBeacons * 2) {
  1053. EXPECT_EQ(upload_report().find(StatusFromInt(i)), std::string::npos);
  1054. } else {
  1055. EXPECT_NE(upload_report().find(StatusFromInt(i)), std::string::npos);
  1056. }
  1057. }
  1058. // The upload completes successfully.
  1059. CallUploadCallback(successful_result);
  1060. EXPECT_TRUE(CheckNoBeacons());
  1061. }
  1062. // Make sure that evictions account for when there are different
  1063. // NetworkIsolationKeys in use.
  1064. TEST_F(DomainReliabilityContextTest,
  1065. EvictionDuringSuccessfulUploadNetworkIsolationKey) {
  1066. ASSERT_EQ(0u, DomainReliabilityContext::kMaxQueuedBeacons % 2)
  1067. << "DomainReliabilityContext::kMaxQueuedBeacons must be even.";
  1068. InitContext(MakeTestConfig());
  1069. net::NetworkIsolationKey network_isolation_keys[] = {
  1070. net::NetworkIsolationKey::CreateTransient(),
  1071. net::NetworkIsolationKey::CreateTransient(),
  1072. };
  1073. // Add |DomainReliabilityContext::kMaxQueuedBeacons| beacons, using a
  1074. // different NetworkIsolationKey for every other beacon.
  1075. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  1076. context_->OnBeacon(MakeBeaconWithNetworkIsolationKey(
  1077. &time_, StatusFromInt(i), network_isolation_keys[i % 2]));
  1078. }
  1079. // No beacons should have been evicted.
  1080. BeaconVector beacons;
  1081. context_->GetQueuedBeaconsForTesting(&beacons);
  1082. ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  1083. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  1084. EXPECT_EQ(beacons[i]->status, StatusFromInt(i));
  1085. EXPECT_EQ(beacons[i]->network_isolation_key, network_isolation_keys[i % 2]);
  1086. }
  1087. // Wait for the report to start being uploaded.
  1088. time_.Advance(max_delay());
  1089. EXPECT_TRUE(upload_allowed_callback_pending());
  1090. CallUploadAllowedResultCallback(true);
  1091. EXPECT_TRUE(upload_pending());
  1092. EXPECT_EQ(network_isolation_keys[0], upload_network_isolation_key());
  1093. // All even-numbered beacons should be in the report.
  1094. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  1095. if (i % 2 == 0) {
  1096. EXPECT_NE(upload_report().find(StatusFromInt(i)), std::string::npos);
  1097. } else {
  1098. EXPECT_EQ(upload_report().find(StatusFromInt(i)), std::string::npos);
  1099. }
  1100. }
  1101. // Add two more beacons, using the same pattern as before
  1102. for (size_t i = 0; i < 2; ++i) {
  1103. context_->OnBeacon(MakeBeaconWithNetworkIsolationKey(
  1104. &time_, StatusFromInt(i + DomainReliabilityContext::kMaxQueuedBeacons),
  1105. network_isolation_keys[i % 2]));
  1106. }
  1107. // Only the first two beacons should have been evicted.
  1108. context_->GetQueuedBeaconsForTesting(&beacons);
  1109. ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  1110. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  1111. EXPECT_EQ(beacons[i]->status, StatusFromInt(i + 2));
  1112. EXPECT_EQ(beacons[i]->network_isolation_key, network_isolation_keys[i % 2]);
  1113. }
  1114. // The upload succeeds. Every beacon using the first NetworkIsolationKey,
  1115. // except the second to last, should have been evicted.
  1116. DomainReliabilityUploader::UploadResult successful_result;
  1117. successful_result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  1118. CallUploadCallback(successful_result);
  1119. // Check remaining beacons.
  1120. context_->GetQueuedBeaconsForTesting(&beacons);
  1121. ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons / 2 + 1,
  1122. beacons.size());
  1123. int beacon_index = 0;
  1124. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
  1125. if (i % 2 == 0 && i < DomainReliabilityContext::kMaxQueuedBeacons - 2)
  1126. continue;
  1127. EXPECT_EQ(beacons[beacon_index]->status, StatusFromInt(i + 2));
  1128. EXPECT_EQ(beacons[beacon_index]->network_isolation_key,
  1129. network_isolation_keys[i % 2]);
  1130. beacon_index++;
  1131. }
  1132. // Another report should be queued. Wait for it to start being uploaded.
  1133. time_.Advance(max_delay());
  1134. EXPECT_TRUE(upload_allowed_callback_pending());
  1135. CallUploadAllowedResultCallback(true);
  1136. EXPECT_TRUE(upload_pending());
  1137. EXPECT_EQ(network_isolation_keys[1], upload_network_isolation_key());
  1138. // Check the expected beacons are in the report.
  1139. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons + 2; ++i) {
  1140. if (i % 2 == 0 || i < 2) {
  1141. EXPECT_EQ(upload_report().find(StatusFromInt(i)), std::string::npos);
  1142. } else {
  1143. EXPECT_NE(upload_report().find(StatusFromInt(i)), std::string::npos);
  1144. }
  1145. }
  1146. // The upload completes successfully.
  1147. CallUploadCallback(successful_result);
  1148. // Check remaining beacons. There should only be one left.
  1149. context_->GetQueuedBeaconsForTesting(&beacons);
  1150. ASSERT_EQ(1u, beacons.size());
  1151. EXPECT_EQ(beacons[0]->status,
  1152. StatusFromInt(DomainReliabilityContext::kMaxQueuedBeacons));
  1153. EXPECT_EQ(beacons[0]->network_isolation_key, network_isolation_keys[0]);
  1154. // Another report should be queued. Wait for it to start being uploaded.
  1155. time_.Advance(max_delay());
  1156. EXPECT_TRUE(upload_allowed_callback_pending());
  1157. CallUploadAllowedResultCallback(true);
  1158. EXPECT_TRUE(upload_pending());
  1159. EXPECT_EQ(network_isolation_keys[0], upload_network_isolation_key());
  1160. // Check the expected beacons are in the report.
  1161. for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons + 2; ++i) {
  1162. if (i == DomainReliabilityContext::kMaxQueuedBeacons) {
  1163. EXPECT_NE(upload_report().find(StatusFromInt(i)), std::string::npos);
  1164. } else {
  1165. EXPECT_EQ(upload_report().find(StatusFromInt(i)), std::string::npos);
  1166. }
  1167. }
  1168. // The upload completes successfully.
  1169. CallUploadCallback(successful_result);
  1170. EXPECT_TRUE(CheckNoBeacons());
  1171. }
  1172. // TODO(juliatuttle): Add beacon_unittest.cc to test serialization.
  1173. } // namespace
  1174. } // namespace domain_reliability