reporting_delivery_agent_unittest.cc 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  1. // Copyright 2017 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 "net/reporting/reporting_delivery_agent.h"
  5. #include <vector>
  6. #include "base/json/json_reader.h"
  7. #include "base/test/metrics/histogram_tester.h"
  8. #include "base/test/scoped_feature_list.h"
  9. #include "base/test/simple_test_tick_clock.h"
  10. #include "base/test/values_test_util.h"
  11. #include "base/time/time.h"
  12. #include "base/timer/mock_timer.h"
  13. #include "base/unguessable_token.h"
  14. #include "base/values.h"
  15. #include "net/base/backoff_entry.h"
  16. #include "net/base/features.h"
  17. #include "net/base/isolation_info.h"
  18. #include "net/base/network_isolation_key.h"
  19. #include "net/base/schemeful_site.h"
  20. #include "net/reporting/reporting_cache.h"
  21. #include "net/reporting/reporting_report.h"
  22. #include "net/reporting/reporting_test_util.h"
  23. #include "net/reporting/reporting_uploader.h"
  24. #include "testing/gtest/include/gtest/gtest.h"
  25. #include "third_party/abseil-cpp/absl/types/optional.h"
  26. #include "url/gurl.h"
  27. #include "url/origin.h"
  28. namespace net {
  29. namespace {
  30. constexpr char kReportingUploadHeaderTypeHistogram[] =
  31. "Net.Reporting.UploadHeaderType";
  32. class ReportingDeliveryAgentTest : public ReportingTestBase {
  33. protected:
  34. ReportingDeliveryAgentTest() {
  35. // This is a private API of the reporting service, so no need to test the
  36. // case kPartitionNelAndReportingByNetworkIsolationKey is disabled - the
  37. // feature is only applied at the entry points of the service.
  38. feature_list_.InitAndEnableFeature(
  39. features::kPartitionNelAndReportingByNetworkIsolationKey);
  40. ReportingPolicy policy;
  41. policy.endpoint_backoff_policy.num_errors_to_ignore = 0;
  42. policy.endpoint_backoff_policy.initial_delay_ms = 60000;
  43. policy.endpoint_backoff_policy.multiply_factor = 2.0;
  44. policy.endpoint_backoff_policy.jitter_factor = 0.0;
  45. policy.endpoint_backoff_policy.maximum_backoff_ms = -1;
  46. policy.endpoint_backoff_policy.entry_lifetime_ms = 0;
  47. policy.endpoint_backoff_policy.always_use_initial_delay = false;
  48. UsePolicy(policy);
  49. }
  50. void AddReport(const absl::optional<base::UnguessableToken>& reporting_source,
  51. const NetworkIsolationKey& network_isolation_key,
  52. const GURL& url,
  53. const std::string& group) {
  54. base::Value::Dict report_body;
  55. report_body.Set("key", "value");
  56. cache()->AddReport(reporting_source, network_isolation_key, url,
  57. kUserAgent_, group, kType_, std::move(report_body),
  58. 0 /* depth */, tick_clock()->NowTicks() /* queued */,
  59. 0 /* attempts */);
  60. }
  61. // The first report added to the cache is uploaded immediately, and a timer is
  62. // started for all subsequent reports (which may then be batched). To test
  63. // behavior involving batching multiple reports, we need to add, upload, and
  64. // immediately resolve a dummy report to prime the delivery timer.
  65. void UploadFirstReportAndStartTimer() {
  66. ReportingEndpointGroupKey dummy_group(
  67. NetworkIsolationKey(), url::Origin::Create(GURL("https://dummy.test")),
  68. "dummy");
  69. ASSERT_TRUE(SetEndpointInCache(
  70. dummy_group, GURL("https://dummy.test/upload"), kExpires_));
  71. AddReport(absl::nullopt, dummy_group.network_isolation_key,
  72. dummy_group.origin.GetURL(), dummy_group.group_name);
  73. ASSERT_EQ(1u, pending_uploads().size());
  74. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  75. EXPECT_EQ(0u, pending_uploads().size());
  76. EXPECT_TRUE(delivery_timer()->IsRunning());
  77. }
  78. // Prime delivery timer with a document report with a endpoint group that
  79. // has matching reporting_source.
  80. void UploadFirstDocumentReportAndStartTimer() {
  81. ReportingEndpointGroupKey dummy_group(
  82. kNik_, kDocumentReportingSource_,
  83. url::Origin::Create(GURL("https://dummy.test")), "dummy");
  84. SetV1EndpointInCache(dummy_group, kDocumentReportingSource_,
  85. kIsolationInfo_, GURL("https://dummy.test/upload"));
  86. AddReport(kDocumentReportingSource_, dummy_group.network_isolation_key,
  87. dummy_group.origin.GetURL(), dummy_group.group_name);
  88. ASSERT_EQ(1u, pending_uploads().size());
  89. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  90. EXPECT_EQ(0u, pending_uploads().size());
  91. EXPECT_TRUE(delivery_timer()->IsRunning());
  92. }
  93. void SendReportsForSource(base::UnguessableToken reporting_source) {
  94. delivery_agent()->SendReportsForSource(reporting_source);
  95. }
  96. base::test::ScopedFeatureList feature_list_;
  97. const GURL kUrl_ = GURL("https://origin/path");
  98. const GURL kOtherUrl_ = GURL("https://other-origin/path");
  99. const GURL kSubdomainUrl_ = GURL("https://sub.origin/path");
  100. const url::Origin kOrigin_ = url::Origin::Create(GURL("https://origin/"));
  101. const url::Origin kOtherOrigin_ =
  102. url::Origin::Create(GURL("https://other-origin/"));
  103. const absl::optional<base::UnguessableToken> kEmptyReportingSource_ =
  104. absl::nullopt;
  105. const base::UnguessableToken kDocumentReportingSource_ =
  106. base::UnguessableToken::Create();
  107. const NetworkIsolationKey kNik_ =
  108. NetworkIsolationKey(SchemefulSite(kOrigin_), SchemefulSite(kOrigin_));
  109. const NetworkIsolationKey kOtherNik_ =
  110. NetworkIsolationKey(SchemefulSite(kOtherOrigin_),
  111. SchemefulSite(kOtherOrigin_));
  112. const IsolationInfo kIsolationInfo_ =
  113. IsolationInfo::Create(IsolationInfo::RequestType::kOther,
  114. kOrigin_,
  115. kOrigin_,
  116. SiteForCookies::FromOrigin(kOrigin_));
  117. const IsolationInfo kOtherIsolationInfo_ =
  118. IsolationInfo::Create(IsolationInfo::RequestType::kOther,
  119. kOtherOrigin_,
  120. kOtherOrigin_,
  121. SiteForCookies::FromOrigin(kOtherOrigin_));
  122. const GURL kEndpoint_ = GURL("https://endpoint/");
  123. const std::string kUserAgent_ = "Mozilla/1.0";
  124. const std::string kGroup_ = "group";
  125. const std::string kType_ = "type";
  126. const base::Time kExpires_ = base::Time::Now() + base::Days(7);
  127. const ReportingEndpointGroupKey kGroupKey_ =
  128. ReportingEndpointGroupKey(kNik_, kOrigin_, kGroup_);
  129. const ReportingEndpointGroupKey kDocumentGroupKey_ =
  130. ReportingEndpointGroupKey(kGroupKey_, kDocumentReportingSource_);
  131. };
  132. TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateUpload) {
  133. base::HistogramTester histograms;
  134. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
  135. AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_);
  136. // Upload is automatically started when cache is modified.
  137. ASSERT_EQ(1u, pending_uploads().size());
  138. EXPECT_EQ(kEndpoint_, pending_uploads()[0]->url());
  139. {
  140. auto value = pending_uploads()[0]->GetValue();
  141. ASSERT_TRUE(value->is_list());
  142. ASSERT_EQ(1u, value->GetList().size());
  143. const base::Value& report = value->GetList()[0];
  144. ASSERT_TRUE(report.is_dict());
  145. const base::Value::Dict& report_dict = report.GetDict();
  146. EXPECT_EQ(5u, report_dict.size());
  147. ExpectDictIntegerValue(0, report_dict, "age");
  148. ExpectDictStringValue(kType_, report_dict, "type");
  149. ExpectDictStringValue(kUrl_.spec(), report_dict, "url");
  150. ExpectDictStringValue(kUserAgent_, report_dict, "user_agent");
  151. const base::Value::Dict* body = report_dict.FindDict("body");
  152. EXPECT_EQ("value", *body->FindString("key"));
  153. }
  154. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  155. // Successful upload should remove delivered reports.
  156. std::vector<const ReportingReport*> reports;
  157. cache()->GetReports(&reports);
  158. EXPECT_TRUE(reports.empty());
  159. histograms.ExpectBucketCount(
  160. kReportingUploadHeaderTypeHistogram,
  161. ReportingDeliveryAgent::ReportingUploadHeaderType::kReportTo, 1);
  162. histograms.ExpectBucketCount(
  163. kReportingUploadHeaderTypeHistogram,
  164. ReportingDeliveryAgent::ReportingUploadHeaderType::kReportingEndpoints,
  165. 0);
  166. {
  167. ReportingEndpoint::Statistics stats =
  168. GetEndpointStatistics(kGroupKey_, kEndpoint_);
  169. EXPECT_EQ(1, stats.attempted_uploads);
  170. EXPECT_EQ(1, stats.successful_uploads);
  171. EXPECT_EQ(1, stats.attempted_reports);
  172. EXPECT_EQ(1, stats.successful_reports);
  173. }
  174. // TODO(dcreager): Check that BackoffEntry was informed of success.
  175. }
  176. TEST_F(ReportingDeliveryAgentTest, ReportToHeaderCountedCorrectly) {
  177. base::HistogramTester histograms;
  178. // Set an endpoint with no reporting source (as if configured with the
  179. // Report-To header).
  180. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
  181. // Add and upload a report with an associated source.
  182. AddReport(kDocumentReportingSource_, kNik_, kUrl_, kGroup_);
  183. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  184. // Successful upload should count this as a Report-To delivery, even though
  185. // the report itself had a reporting source.
  186. histograms.ExpectBucketCount(
  187. kReportingUploadHeaderTypeHistogram,
  188. ReportingDeliveryAgent::ReportingUploadHeaderType::kReportTo, 1);
  189. histograms.ExpectBucketCount(
  190. kReportingUploadHeaderTypeHistogram,
  191. ReportingDeliveryAgent::ReportingUploadHeaderType::kReportingEndpoints,
  192. 0);
  193. }
  194. TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateUploadDocumentReport) {
  195. base::HistogramTester histograms;
  196. SetV1EndpointInCache(kDocumentGroupKey_, kDocumentReportingSource_,
  197. kIsolationInfo_, kEndpoint_);
  198. AddReport(kDocumentReportingSource_, kNik_, kUrl_, kGroup_);
  199. // Upload is automatically started when cache is modified.
  200. ASSERT_EQ(1u, pending_uploads().size());
  201. EXPECT_EQ(kEndpoint_, pending_uploads()[0]->url());
  202. {
  203. const auto value = pending_uploads()[0]->GetValue();
  204. ASSERT_TRUE(value->is_list());
  205. ASSERT_EQ(1u, value->GetList().size());
  206. const base::Value& report = value->GetList()[0];
  207. ASSERT_TRUE(report.is_dict());
  208. const base::Value::Dict& report_dict = report.GetDict();
  209. ExpectDictIntegerValue(0, report_dict, "age");
  210. ExpectDictStringValue(kType_, report_dict, "type");
  211. ExpectDictStringValue(kUrl_.spec(), report_dict, "url");
  212. ExpectDictStringValue(kUserAgent_, report_dict, "user_agent");
  213. const base::Value::Dict* body = report_dict.FindDict("body");
  214. EXPECT_EQ("value", *body->FindString("key"));
  215. }
  216. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  217. // Successful upload should remove delivered reports.
  218. std::vector<const ReportingReport*> reports;
  219. cache()->GetReports(&reports);
  220. EXPECT_TRUE(reports.empty());
  221. histograms.ExpectBucketCount(
  222. kReportingUploadHeaderTypeHistogram,
  223. ReportingDeliveryAgent::ReportingUploadHeaderType::kReportingEndpoints,
  224. 1);
  225. histograms.ExpectBucketCount(
  226. kReportingUploadHeaderTypeHistogram,
  227. ReportingDeliveryAgent::ReportingUploadHeaderType::kReportTo, 0);
  228. {
  229. ReportingEndpoint::Statistics stats =
  230. GetEndpointStatistics(kDocumentGroupKey_, kEndpoint_);
  231. EXPECT_EQ(1, stats.attempted_uploads);
  232. EXPECT_EQ(1, stats.successful_uploads);
  233. EXPECT_EQ(1, stats.attempted_reports);
  234. EXPECT_EQ(1, stats.successful_reports);
  235. }
  236. }
  237. TEST_F(ReportingDeliveryAgentTest, UploadHeaderTypeEnumCountPerReport) {
  238. UploadFirstDocumentReportAndStartTimer();
  239. base::HistogramTester histograms;
  240. SetV1EndpointInCache(kDocumentGroupKey_, kDocumentReportingSource_,
  241. kIsolationInfo_, kEndpoint_);
  242. AddReport(kDocumentReportingSource_, kNik_, kUrl_, kGroup_);
  243. AddReport(kDocumentReportingSource_, kNik_, kUrl_, kGroup_);
  244. // There should be one upload per (NIK, origin, reporting source).
  245. EXPECT_TRUE(delivery_timer()->IsRunning());
  246. delivery_timer()->Fire();
  247. ASSERT_EQ(1u, pending_uploads().size());
  248. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  249. // Successful upload should remove delivered reports.
  250. std::vector<const ReportingReport*> reports;
  251. cache()->GetReports(&reports);
  252. EXPECT_TRUE(reports.empty());
  253. histograms.ExpectBucketCount(
  254. kReportingUploadHeaderTypeHistogram,
  255. ReportingDeliveryAgent::ReportingUploadHeaderType::kReportingEndpoints,
  256. 2);
  257. histograms.ExpectBucketCount(
  258. kReportingUploadHeaderTypeHistogram,
  259. ReportingDeliveryAgent::ReportingUploadHeaderType::kReportTo, 0);
  260. }
  261. TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateSubdomainUpload) {
  262. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_,
  263. OriginSubdomains::INCLUDE));
  264. AddReport(kEmptyReportingSource_, kNik_, kSubdomainUrl_, kGroup_);
  265. // Upload is automatically started when cache is modified.
  266. ASSERT_EQ(1u, pending_uploads().size());
  267. EXPECT_EQ(kEndpoint_, pending_uploads()[0]->url());
  268. {
  269. auto value = pending_uploads()[0]->GetValue();
  270. ASSERT_TRUE(value->is_list());
  271. ASSERT_EQ(1u, value->GetList().size());
  272. const base::Value& report = value->GetList()[0];
  273. ASSERT_TRUE(report.is_dict());
  274. const base::Value::Dict& report_dict = report.GetDict();
  275. EXPECT_EQ(5u, report_dict.size());
  276. ExpectDictIntegerValue(0, report_dict, "age");
  277. ExpectDictStringValue(kType_, report_dict, "type");
  278. ExpectDictStringValue(kSubdomainUrl_.spec(), report_dict, "url");
  279. ExpectDictStringValue(kUserAgent_, report_dict, "user_agent");
  280. const base::Value::Dict* body = report_dict.FindDict("body");
  281. EXPECT_EQ("value", *body->FindString("key"));
  282. }
  283. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  284. // Successful upload should remove delivered reports.
  285. std::vector<const ReportingReport*> reports;
  286. cache()->GetReports(&reports);
  287. EXPECT_TRUE(reports.empty());
  288. {
  289. ReportingEndpoint::Statistics stats =
  290. GetEndpointStatistics(kGroupKey_, kEndpoint_);
  291. EXPECT_EQ(1, stats.attempted_uploads);
  292. EXPECT_EQ(1, stats.successful_uploads);
  293. EXPECT_EQ(1, stats.attempted_reports);
  294. EXPECT_EQ(1, stats.successful_reports);
  295. }
  296. // TODO(dcreager): Check that BackoffEntry was informed of success.
  297. }
  298. TEST_F(ReportingDeliveryAgentTest,
  299. SuccessfulImmediateSubdomainUploadWithOverwrittenEndpoint) {
  300. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_,
  301. OriginSubdomains::INCLUDE));
  302. AddReport(kEmptyReportingSource_, kNik_, kSubdomainUrl_, kGroup_);
  303. // Upload is automatically started when cache is modified.
  304. ASSERT_EQ(1u, pending_uploads().size());
  305. // Change the endpoint group to exclude subdomains.
  306. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_,
  307. OriginSubdomains::EXCLUDE));
  308. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  309. {
  310. ReportingEndpoint::Statistics stats =
  311. GetEndpointStatistics(kGroupKey_, kEndpoint_);
  312. EXPECT_EQ(1, stats.attempted_uploads);
  313. EXPECT_EQ(1, stats.successful_uploads);
  314. EXPECT_EQ(1, stats.attempted_reports);
  315. EXPECT_EQ(1, stats.successful_reports);
  316. }
  317. // Successful upload should remove delivered reports.
  318. std::vector<const ReportingReport*> reports;
  319. cache()->GetReports(&reports);
  320. EXPECT_TRUE(reports.empty());
  321. }
  322. TEST_F(ReportingDeliveryAgentTest, SuccessfulDelayedUpload) {
  323. // Trigger and complete an upload to start the delivery timer.
  324. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
  325. AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_);
  326. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  327. // Add another report to upload after a delay.
  328. AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_);
  329. EXPECT_TRUE(delivery_timer()->IsRunning());
  330. delivery_timer()->Fire();
  331. ASSERT_EQ(1u, pending_uploads().size());
  332. EXPECT_EQ(kEndpoint_, pending_uploads()[0]->url());
  333. {
  334. auto value = pending_uploads()[0]->GetValue();
  335. ASSERT_TRUE(value->is_list());
  336. ASSERT_EQ(1u, value->GetList().size());
  337. const base::Value& report = value->GetList()[0];
  338. ASSERT_TRUE(report.is_dict());
  339. const base::Value::Dict& report_dict = report.GetDict();
  340. EXPECT_EQ(5u, report_dict.size());
  341. ExpectDictIntegerValue(0, report_dict, "age");
  342. ExpectDictStringValue(kType_, report_dict, "type");
  343. ExpectDictStringValue(kUrl_.spec(), report_dict, "url");
  344. ExpectDictStringValue(kUserAgent_, report_dict, "user_agent");
  345. const base::Value::Dict* body = report_dict.FindDict("body");
  346. EXPECT_EQ("value", *body->FindString("key"));
  347. }
  348. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  349. {
  350. ReportingEndpoint::Statistics stats =
  351. GetEndpointStatistics(kGroupKey_, kEndpoint_);
  352. EXPECT_EQ(2, stats.attempted_uploads);
  353. EXPECT_EQ(2, stats.successful_uploads);
  354. EXPECT_EQ(2, stats.attempted_reports);
  355. EXPECT_EQ(2, stats.successful_reports);
  356. }
  357. // Successful upload should remove delivered reports.
  358. std::vector<const ReportingReport*> reports;
  359. cache()->GetReports(&reports);
  360. EXPECT_TRUE(reports.empty());
  361. // TODO(juliatuttle): Check that BackoffEntry was informed of success.
  362. }
  363. TEST_F(ReportingDeliveryAgentTest, FailedUpload) {
  364. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
  365. AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_);
  366. EXPECT_TRUE(delivery_timer()->IsRunning());
  367. delivery_timer()->Fire();
  368. ASSERT_EQ(1u, pending_uploads().size());
  369. pending_uploads()[0]->Complete(ReportingUploader::Outcome::FAILURE);
  370. {
  371. ReportingEndpoint::Statistics stats =
  372. GetEndpointStatistics(kGroupKey_, kEndpoint_);
  373. EXPECT_EQ(1, stats.attempted_uploads);
  374. EXPECT_EQ(0, stats.successful_uploads);
  375. EXPECT_EQ(1, stats.attempted_reports);
  376. EXPECT_EQ(0, stats.successful_reports);
  377. }
  378. // Failed upload should increment reports' attempts.
  379. std::vector<const ReportingReport*> reports;
  380. cache()->GetReports(&reports);
  381. ASSERT_EQ(1u, reports.size());
  382. EXPECT_EQ(1, reports[0]->attempts);
  383. // Since endpoint is now failing, an upload won't be started despite a pending
  384. // report.
  385. ASSERT_TRUE(pending_uploads().empty());
  386. EXPECT_TRUE(delivery_timer()->IsRunning());
  387. delivery_timer()->Fire();
  388. EXPECT_TRUE(pending_uploads().empty());
  389. {
  390. ReportingEndpoint::Statistics stats =
  391. GetEndpointStatistics(kGroupKey_, kEndpoint_);
  392. EXPECT_EQ(1, stats.attempted_uploads);
  393. EXPECT_EQ(0, stats.successful_uploads);
  394. EXPECT_EQ(1, stats.attempted_reports);
  395. EXPECT_EQ(0, stats.successful_reports);
  396. }
  397. }
  398. TEST_F(ReportingDeliveryAgentTest, DisallowedUpload) {
  399. // This mimics the check that is controlled by the BACKGROUND_SYNC permission
  400. // in a real browser profile.
  401. context()->test_delegate()->set_disallow_report_uploads(true);
  402. static const int kAgeMillis = 12345;
  403. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
  404. AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_);
  405. tick_clock()->Advance(base::Milliseconds(kAgeMillis));
  406. EXPECT_TRUE(delivery_timer()->IsRunning());
  407. delivery_timer()->Fire();
  408. // We should not try to upload the report, since we weren't given permission
  409. // for this origin.
  410. EXPECT_TRUE(pending_uploads().empty());
  411. {
  412. ReportingEndpoint::Statistics stats =
  413. GetEndpointStatistics(kGroupKey_, kEndpoint_);
  414. EXPECT_EQ(0, stats.attempted_uploads);
  415. EXPECT_EQ(0, stats.successful_uploads);
  416. EXPECT_EQ(0, stats.attempted_reports);
  417. EXPECT_EQ(0, stats.successful_reports);
  418. }
  419. // Disallowed reports should NOT have been removed from the cache.
  420. std::vector<const ReportingReport*> reports;
  421. cache()->GetReports(&reports);
  422. EXPECT_EQ(1u, reports.size());
  423. }
  424. TEST_F(ReportingDeliveryAgentTest, RemoveEndpointUpload) {
  425. static const ReportingEndpointGroupKey kOtherGroupKey(kNik_, kOtherOrigin_,
  426. kGroup_);
  427. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
  428. ASSERT_TRUE(SetEndpointInCache(kOtherGroupKey, kEndpoint_, kExpires_));
  429. AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_);
  430. EXPECT_TRUE(delivery_timer()->IsRunning());
  431. delivery_timer()->Fire();
  432. ASSERT_EQ(1u, pending_uploads().size());
  433. pending_uploads()[0]->Complete(ReportingUploader::Outcome::REMOVE_ENDPOINT);
  434. // "Remove endpoint" upload should remove endpoint from *all* origins and
  435. // increment reports' attempts.
  436. std::vector<const ReportingReport*> reports;
  437. cache()->GetReports(&reports);
  438. ASSERT_EQ(1u, reports.size());
  439. EXPECT_EQ(1, reports[0]->attempts);
  440. EXPECT_FALSE(FindEndpointInCache(kGroupKey_, kEndpoint_));
  441. EXPECT_FALSE(FindEndpointInCache(kOtherGroupKey, kEndpoint_));
  442. // Since endpoint is now failing, an upload won't be started despite a pending
  443. // report.
  444. EXPECT_TRUE(delivery_timer()->IsRunning());
  445. delivery_timer()->Fire();
  446. EXPECT_TRUE(pending_uploads().empty());
  447. }
  448. TEST_F(ReportingDeliveryAgentTest, ConcurrentRemove) {
  449. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
  450. AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_);
  451. EXPECT_TRUE(delivery_timer()->IsRunning());
  452. delivery_timer()->Fire();
  453. ASSERT_EQ(1u, pending_uploads().size());
  454. // Remove the report while the upload is running.
  455. std::vector<const ReportingReport*> reports;
  456. cache()->GetReports(&reports);
  457. EXPECT_EQ(1u, reports.size());
  458. const ReportingReport* report = reports[0];
  459. EXPECT_FALSE(cache()->IsReportDoomedForTesting(report));
  460. // Report should appear removed, even though the cache has doomed it.
  461. cache()->RemoveReports(reports);
  462. cache()->GetReports(&reports);
  463. EXPECT_TRUE(reports.empty());
  464. EXPECT_TRUE(cache()->IsReportDoomedForTesting(report));
  465. // Completing upload shouldn't crash, and report should still be gone.
  466. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  467. cache()->GetReports(&reports);
  468. EXPECT_TRUE(reports.empty());
  469. }
  470. // Flaky on ChromeOS: https://crbug.com/1348434
  471. #if defined(CHROMEOS)
  472. #define MAYBE_ConcurrentRemoveDuringPermissionsCheck \
  473. DISABLED_ConcurrentRemoveDuringPermissionsCheck
  474. #else
  475. #define MAYBE_ConcurrentRemoveDuringPermissionsCheck \
  476. ConcurrentRemoveDuringPermissionsCheck
  477. #endif
  478. TEST_F(ReportingDeliveryAgentTest,
  479. MAYBE_ConcurrentRemoveDuringPermissionsCheck) {
  480. // Pause the permissions check, so that we can try to remove some reports
  481. // while we're in the middle of verifying that we can upload them. (This is
  482. // similar to the previous test, but removes the reports during a different
  483. // part of the upload process.)
  484. context()->test_delegate()->set_pause_permissions_check(true);
  485. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
  486. AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_);
  487. ASSERT_TRUE(context()->test_delegate()->PermissionsCheckPaused());
  488. // Remove the report while the upload is running.
  489. std::vector<const ReportingReport*> reports;
  490. cache()->GetReports(&reports);
  491. EXPECT_EQ(1u, reports.size());
  492. const ReportingReport* report = reports[0];
  493. EXPECT_FALSE(cache()->IsReportDoomedForTesting(report));
  494. // Report should appear removed, even though the cache has doomed it.
  495. cache()->RemoveReports(reports);
  496. cache()->GetReports(&reports);
  497. EXPECT_TRUE(reports.empty());
  498. EXPECT_TRUE(cache()->IsReportDoomedForTesting(report));
  499. // Completing upload shouldn't crash, and report should still be gone.
  500. context()->test_delegate()->ResumePermissionsCheck();
  501. ASSERT_EQ(1u, pending_uploads().size());
  502. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  503. cache()->GetReports(&reports);
  504. EXPECT_TRUE(reports.empty());
  505. }
  506. // Reports uploaded together must share a NIK and origin.
  507. // Test that the agent will not combine reports destined for the same endpoint
  508. // if the reports are from different origins or NIKs, but does combine all
  509. // reports for the same (NIK, origin).
  510. TEST_F(ReportingDeliveryAgentTest, OnlyBatchSameNikAndOrigin) {
  511. const ReportingEndpointGroupKey kGroupKeys[] = {
  512. ReportingEndpointGroupKey(kNik_, kOrigin_, kGroup_),
  513. ReportingEndpointGroupKey(kNik_, kOtherOrigin_, kGroup_),
  514. ReportingEndpointGroupKey(kOtherNik_, kOrigin_, kGroup_),
  515. ReportingEndpointGroupKey(kOtherNik_, kOtherOrigin_, kGroup_),
  516. };
  517. for (const ReportingEndpointGroupKey& group_key : kGroupKeys) {
  518. ASSERT_TRUE(SetEndpointInCache(group_key, kEndpoint_, kExpires_));
  519. }
  520. // Trigger and complete an upload to start the delivery timer.
  521. UploadFirstReportAndStartTimer();
  522. // Now that the delivery timer is running, these reports won't be immediately
  523. // uploaded.
  524. AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_);
  525. AddReport(kEmptyReportingSource_, kNik_, kOtherUrl_, kGroup_);
  526. AddReport(kEmptyReportingSource_, kNik_, kOtherUrl_, kGroup_);
  527. AddReport(kEmptyReportingSource_, kOtherNik_, kUrl_, kGroup_);
  528. AddReport(kEmptyReportingSource_, kOtherNik_, kUrl_, kGroup_);
  529. AddReport(kEmptyReportingSource_, kOtherNik_, kUrl_, kGroup_);
  530. AddReport(kEmptyReportingSource_, kOtherNik_, kOtherUrl_, kGroup_);
  531. AddReport(kEmptyReportingSource_, kOtherNik_, kOtherUrl_, kGroup_);
  532. AddReport(kEmptyReportingSource_, kOtherNik_, kOtherUrl_, kGroup_);
  533. AddReport(kEmptyReportingSource_, kOtherNik_, kOtherUrl_, kGroup_);
  534. EXPECT_EQ(0u, pending_uploads().size());
  535. // There should be one upload per (NIK, origin).
  536. EXPECT_TRUE(delivery_timer()->IsRunning());
  537. delivery_timer()->Fire();
  538. ASSERT_EQ(4u, pending_uploads().size());
  539. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  540. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  541. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  542. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  543. EXPECT_EQ(0u, pending_uploads().size());
  544. for (int i = 0; i < 4; ++i) {
  545. ReportingEndpoint::Statistics stats =
  546. GetEndpointStatistics(kGroupKeys[i], kEndpoint_);
  547. EXPECT_EQ(1, stats.attempted_uploads);
  548. EXPECT_EQ(1, stats.successful_uploads);
  549. EXPECT_EQ(i + 1, stats.attempted_reports);
  550. EXPECT_EQ(i + 1, stats.successful_reports);
  551. }
  552. }
  553. // Test that the agent won't start a second upload for a (NIK, origin, group)
  554. // while one is pending, even if a different endpoint is available, but will
  555. // once the original delivery is complete and the (NIK, origin, group) is no
  556. // longer pending.
  557. TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToGroup) {
  558. static const GURL kDifferentEndpoint("https://endpoint2/");
  559. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
  560. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kDifferentEndpoint, kExpires_));
  561. // Trigger and complete an upload to start the delivery timer.
  562. UploadFirstReportAndStartTimer();
  563. // First upload causes this group key to become pending.
  564. AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_);
  565. EXPECT_EQ(0u, pending_uploads().size());
  566. EXPECT_TRUE(delivery_timer()->IsRunning());
  567. delivery_timer()->Fire();
  568. EXPECT_EQ(1u, pending_uploads().size());
  569. // Second upload isn't started because the group is pending.
  570. AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_);
  571. EXPECT_TRUE(delivery_timer()->IsRunning());
  572. delivery_timer()->Fire();
  573. ASSERT_EQ(1u, pending_uploads().size());
  574. // Resolve the first upload.
  575. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  576. EXPECT_EQ(0u, pending_uploads().size());
  577. // Now the other upload can happen.
  578. EXPECT_TRUE(delivery_timer()->IsRunning());
  579. delivery_timer()->Fire();
  580. ASSERT_EQ(1u, pending_uploads().size());
  581. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  582. EXPECT_EQ(0u, pending_uploads().size());
  583. // A total of 2 reports were uploaded.
  584. {
  585. ReportingEndpoint::Statistics stats =
  586. GetEndpointStatistics(kGroupKey_, kEndpoint_);
  587. ReportingEndpoint::Statistics different_stats =
  588. GetEndpointStatistics(kGroupKey_, kDifferentEndpoint);
  589. EXPECT_EQ(2, stats.attempted_uploads + different_stats.attempted_uploads);
  590. EXPECT_EQ(2, stats.successful_uploads + different_stats.successful_uploads);
  591. EXPECT_EQ(2, stats.attempted_reports + different_stats.attempted_reports);
  592. EXPECT_EQ(2, stats.successful_reports + different_stats.successful_reports);
  593. }
  594. }
  595. // Tests that the agent will start parallel uploads to different groups within
  596. // the same (NIK, origin) to endpoints with different URLs.
  597. TEST_F(ReportingDeliveryAgentTest, ParallelizeUploadsAcrossGroups) {
  598. static const GURL kDifferentEndpoint("https://endpoint2/");
  599. static const std::string kDifferentGroup("group2");
  600. const ReportingEndpointGroupKey kDifferentGroupKey(kNik_, kOrigin_,
  601. kDifferentGroup);
  602. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
  603. ASSERT_TRUE(
  604. SetEndpointInCache(kDifferentGroupKey, kDifferentEndpoint, kExpires_));
  605. // Trigger and complete an upload to start the delivery timer.
  606. UploadFirstReportAndStartTimer();
  607. AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_);
  608. AddReport(kEmptyReportingSource_, kNik_, kUrl_, kDifferentGroup);
  609. EXPECT_TRUE(delivery_timer()->IsRunning());
  610. delivery_timer()->Fire();
  611. ASSERT_EQ(2u, pending_uploads().size());
  612. pending_uploads()[1]->Complete(ReportingUploader::Outcome::SUCCESS);
  613. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  614. EXPECT_EQ(0u, pending_uploads().size());
  615. {
  616. ReportingEndpoint::Statistics stats =
  617. GetEndpointStatistics(kGroupKey_, kEndpoint_);
  618. EXPECT_EQ(1, stats.attempted_uploads);
  619. EXPECT_EQ(1, stats.successful_uploads);
  620. EXPECT_EQ(1, stats.attempted_reports);
  621. EXPECT_EQ(1, stats.successful_reports);
  622. }
  623. {
  624. ReportingEndpoint::Statistics stats =
  625. GetEndpointStatistics(kDifferentGroupKey, kDifferentEndpoint);
  626. EXPECT_EQ(1, stats.attempted_uploads);
  627. EXPECT_EQ(1, stats.successful_uploads);
  628. EXPECT_EQ(1, stats.attempted_reports);
  629. EXPECT_EQ(1, stats.successful_reports);
  630. }
  631. }
  632. // Tests that the agent will include reports for different groups for the same
  633. // (NIK, origin) in the same upload if they are destined for the same endpoint
  634. // URL.
  635. TEST_F(ReportingDeliveryAgentTest, BatchReportsAcrossGroups) {
  636. static const std::string kDifferentGroup("group2");
  637. const ReportingEndpointGroupKey kDifferentGroupKey(kNik_, kOrigin_,
  638. kDifferentGroup);
  639. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
  640. ASSERT_TRUE(SetEndpointInCache(kDifferentGroupKey, kEndpoint_, kExpires_));
  641. UploadFirstReportAndStartTimer();
  642. AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_);
  643. AddReport(kEmptyReportingSource_, kNik_, kUrl_, kDifferentGroup);
  644. EXPECT_TRUE(delivery_timer()->IsRunning());
  645. delivery_timer()->Fire();
  646. ASSERT_EQ(1u, pending_uploads().size());
  647. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  648. EXPECT_EQ(0u, pending_uploads().size());
  649. {
  650. ReportingEndpoint::Statistics stats =
  651. GetEndpointStatistics(kGroupKey_, kEndpoint_);
  652. EXPECT_EQ(1, stats.attempted_uploads);
  653. EXPECT_EQ(1, stats.successful_uploads);
  654. EXPECT_EQ(1, stats.attempted_reports);
  655. EXPECT_EQ(1, stats.successful_reports);
  656. }
  657. {
  658. ReportingEndpoint::Statistics stats =
  659. GetEndpointStatistics(kDifferentGroupKey, kEndpoint_);
  660. EXPECT_EQ(1, stats.attempted_uploads);
  661. EXPECT_EQ(1, stats.successful_uploads);
  662. EXPECT_EQ(1, stats.attempted_reports);
  663. EXPECT_EQ(1, stats.successful_reports);
  664. }
  665. }
  666. // Tests that the agent can send all outstanding reports for a single source
  667. // when necessary. This test queues two reports for the same reporting source,
  668. // for different endpoints, another for a different source at the same URL, and
  669. // another for a different source on a different origin.
  670. TEST_F(ReportingDeliveryAgentTest, SendReportsForSource) {
  671. static const std::string kGroup2("group2");
  672. // Two other reporting sources; kReportingSource2 will enqueue reports for the
  673. // same URL as kReportingSource_, while kReportingSource3 will be a separate
  674. // origin.
  675. const base::UnguessableToken kReportingSource1 =
  676. base::UnguessableToken::Create();
  677. const base::UnguessableToken kReportingSource2 =
  678. base::UnguessableToken::Create();
  679. const base::UnguessableToken kReportingSource3 =
  680. base::UnguessableToken::Create();
  681. const IsolationInfo kIsolationInfo1 =
  682. IsolationInfo::Create(IsolationInfo::RequestType::kOther, kOrigin_,
  683. kOrigin_, SiteForCookies::FromOrigin(kOrigin_));
  684. const IsolationInfo kIsolationInfo2 =
  685. IsolationInfo::Create(IsolationInfo::RequestType::kOther, kOrigin_,
  686. kOrigin_, SiteForCookies::FromOrigin(kOrigin_));
  687. const IsolationInfo kIsolationInfo3 = IsolationInfo::Create(
  688. IsolationInfo::RequestType::kOther, kOtherOrigin_, kOtherOrigin_,
  689. SiteForCookies::FromOrigin(kOtherOrigin_));
  690. // Set up identical endpoint configuration for kReportingSource1 and
  691. // kReportingSource2. kReportingSource3 is independent.
  692. const ReportingEndpointGroupKey kGroup1Key1(kNik_, kReportingSource1,
  693. kOrigin_, kGroup_);
  694. const ReportingEndpointGroupKey kGroup2Key1(kNik_, kReportingSource1,
  695. kOrigin_, kGroup2);
  696. const ReportingEndpointGroupKey kGroup1Key2(kNik_, kReportingSource2,
  697. kOrigin_, kGroup_);
  698. const ReportingEndpointGroupKey kGroup2Key2(kNik_, kReportingSource2,
  699. kOrigin_, kGroup2);
  700. const ReportingEndpointGroupKey kOtherGroupKey(kOtherNik_, kReportingSource3,
  701. kOtherOrigin_, kGroup_);
  702. SetV1EndpointInCache(kGroup1Key1, kReportingSource1, kIsolationInfo1, kUrl_);
  703. SetV1EndpointInCache(kGroup2Key1, kReportingSource1, kIsolationInfo1, kUrl_);
  704. SetV1EndpointInCache(kGroup1Key2, kReportingSource2, kIsolationInfo2, kUrl_);
  705. SetV1EndpointInCache(kGroup2Key2, kReportingSource2, kIsolationInfo2, kUrl_);
  706. SetV1EndpointInCache(kOtherGroupKey, kReportingSource3, kIsolationInfo3,
  707. kOtherUrl_);
  708. UploadFirstReportAndStartTimer();
  709. AddReport(kReportingSource1, kNik_, kUrl_, kGroup_);
  710. AddReport(kReportingSource1, kNik_, kUrl_, kGroup2);
  711. AddReport(kReportingSource2, kNik_, kUrl_, kGroup_);
  712. AddReport(kReportingSource3, kOtherNik_, kUrl_, kGroup_);
  713. // There should be four queued reports at this point.
  714. EXPECT_EQ(4u, cache()->GetReportCountWithStatusForTesting(
  715. ReportingReport::Status::QUEUED));
  716. EXPECT_EQ(0u, pending_uploads().size());
  717. SendReportsForSource(kReportingSource1);
  718. // Sending all reports for the source should only queue two, despite the fact
  719. // that there are other reports queued for the same origin and endpoint.
  720. EXPECT_EQ(2u, cache()->GetReportCountWithStatusForTesting(
  721. ReportingReport::Status::QUEUED));
  722. EXPECT_EQ(2u, cache()->GetReportCountWithStatusForTesting(
  723. ReportingReport::Status::PENDING));
  724. // All pending reports for the same source should be batched into a single
  725. // upload.
  726. ASSERT_EQ(1u, pending_uploads().size());
  727. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
  728. EXPECT_EQ(0u, pending_uploads().size());
  729. }
  730. // Tests that the agent can send all outstanding V1 reports for multiple sources
  731. // and that these are not batched together.
  732. TEST_F(ReportingDeliveryAgentTest, SendReportsForMultipleSources) {
  733. static const std::string kGroup2("group2");
  734. // Two other reporting sources; kReportingSource2 will enqueue reports for the
  735. // same URL as kReportingSource_, while kReportingSource3 will be a separate
  736. // origin.
  737. const base::UnguessableToken kReportingSource1 =
  738. base::UnguessableToken::Create();
  739. const base::UnguessableToken kReportingSource2 =
  740. base::UnguessableToken::Create();
  741. const base::UnguessableToken kReportingSource3 =
  742. base::UnguessableToken::Create();
  743. const IsolationInfo kIsolationInfo1 =
  744. IsolationInfo::Create(IsolationInfo::RequestType::kOther, kOrigin_,
  745. kOrigin_, SiteForCookies::FromOrigin(kOrigin_));
  746. const IsolationInfo kIsolationInfo2 =
  747. IsolationInfo::Create(IsolationInfo::RequestType::kOther, kOrigin_,
  748. kOrigin_, SiteForCookies::FromOrigin(kOrigin_));
  749. const IsolationInfo kIsolationInfo3 = IsolationInfo::Create(
  750. IsolationInfo::RequestType::kOther, kOtherOrigin_, kOtherOrigin_,
  751. SiteForCookies::FromOrigin(kOtherOrigin_));
  752. // Set up identical endpoint configuration for kReportingSource1 and
  753. // kReportingSource2. kReportingSource3 is independent.
  754. const ReportingEndpointGroupKey kGroup1Key1(kNik_, kReportingSource1,
  755. kOrigin_, kGroup_);
  756. const ReportingEndpointGroupKey kGroup2Key1(kNik_, kReportingSource1,
  757. kOrigin_, kGroup2);
  758. const ReportingEndpointGroupKey kGroup1Key2(kNik_, kReportingSource2,
  759. kOrigin_, kGroup_);
  760. const ReportingEndpointGroupKey kGroup2Key2(kNik_, kReportingSource2,
  761. kOrigin_, kGroup2);
  762. const ReportingEndpointGroupKey kOtherGroupKey(kOtherNik_, kReportingSource3,
  763. kOtherOrigin_, kGroup_);
  764. SetV1EndpointInCache(kGroup1Key1, kReportingSource1, kIsolationInfo1, kUrl_);
  765. SetV1EndpointInCache(kGroup2Key1, kReportingSource1, kIsolationInfo1, kUrl_);
  766. SetV1EndpointInCache(kGroup1Key2, kReportingSource2, kIsolationInfo2, kUrl_);
  767. SetV1EndpointInCache(kGroup2Key2, kReportingSource2, kIsolationInfo2, kUrl_);
  768. SetV1EndpointInCache(kOtherGroupKey, kReportingSource3, kIsolationInfo3,
  769. kOtherUrl_);
  770. UploadFirstReportAndStartTimer();
  771. AddReport(kReportingSource1, kNik_, kUrl_, kGroup_);
  772. AddReport(kReportingSource1, kNik_, kUrl_, kGroup2);
  773. AddReport(kReportingSource2, kNik_, kUrl_, kGroup_);
  774. AddReport(kReportingSource3, kOtherNik_, kUrl_, kGroup_);
  775. // There should be four queued reports at this point.
  776. EXPECT_EQ(4u, cache()->GetReportCountWithStatusForTesting(
  777. ReportingReport::Status::QUEUED));
  778. EXPECT_EQ(0u, pending_uploads().size());
  779. // Send reports for both ReportingSource 1 and 2 at the same time. These
  780. // should be sent to the same endpoint, but should still not be batched
  781. // together.
  782. SendReportsForSource(kReportingSource1);
  783. SendReportsForSource(kReportingSource2);
  784. // We expect to see three pending reports, and one still queued. The pending
  785. // reports should be divided into two uploads.
  786. EXPECT_EQ(1u, cache()->GetReportCountWithStatusForTesting(
  787. ReportingReport::Status::QUEUED));
  788. EXPECT_EQ(3u, cache()->GetReportCountWithStatusForTesting(
  789. ReportingReport::Status::PENDING));
  790. ASSERT_EQ(2u, pending_uploads().size());
  791. }
  792. } // namespace
  793. } // namespace net