1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
7 #pragma allow_unsafe_buffers
8 #endif
9
10 #include "net/reporting/reporting_delivery_agent.h"
11
12 #include <optional>
13 #include <vector>
14
15 #include "base/json/json_reader.h"
16 #include "base/memory/raw_ptr.h"
17 #include "base/test/metrics/histogram_tester.h"
18 #include "base/test/scoped_feature_list.h"
19 #include "base/test/simple_test_tick_clock.h"
20 #include "base/test/values_test_util.h"
21 #include "base/time/time.h"
22 #include "base/timer/mock_timer.h"
23 #include "base/unguessable_token.h"
24 #include "base/values.h"
25 #include "net/base/backoff_entry.h"
26 #include "net/base/features.h"
27 #include "net/base/isolation_info.h"
28 #include "net/base/network_anonymization_key.h"
29 #include "net/base/schemeful_site.h"
30 #include "net/reporting/reporting_cache.h"
31 #include "net/reporting/reporting_report.h"
32 #include "net/reporting/reporting_test_util.h"
33 #include "net/reporting/reporting_uploader.h"
34 #include "testing/gtest/include/gtest/gtest.h"
35 #include "url/gurl.h"
36 #include "url/origin.h"
37
38 namespace net {
39 namespace {
40
41 constexpr char kReportingUploadHeaderTypeHistogram[] =
42 "Net.Reporting.UploadHeaderType";
43
44 } // namespace
45
46 class ReportingDeliveryAgentTest : public ReportingTestBase {
47 protected:
ReportingDeliveryAgentTest()48 ReportingDeliveryAgentTest() {
49 // This is a private API of the reporting service, so no need to test the
50 // case kPartitionConnectionsByNetworkIsolationKey is disabled - the
51 // feature is only applied at the entry points of the service.
52 feature_list_.InitAndEnableFeature(
53 features::kPartitionConnectionsByNetworkIsolationKey);
54
55 ReportingPolicy policy;
56 policy.endpoint_backoff_policy.num_errors_to_ignore = 0;
57 policy.endpoint_backoff_policy.initial_delay_ms = 60000;
58 policy.endpoint_backoff_policy.multiply_factor = 2.0;
59 policy.endpoint_backoff_policy.jitter_factor = 0.0;
60 policy.endpoint_backoff_policy.maximum_backoff_ms = -1;
61 policy.endpoint_backoff_policy.entry_lifetime_ms = 0;
62 policy.endpoint_backoff_policy.always_use_initial_delay = false;
63 UsePolicy(policy);
64 }
65
AddReport(const std::optional<base::UnguessableToken> & reporting_source,const NetworkAnonymizationKey & network_anonymization_key,const GURL & url,const std::string & group)66 void AddReport(const std::optional<base::UnguessableToken>& reporting_source,
67 const NetworkAnonymizationKey& network_anonymization_key,
68 const GURL& url,
69 const std::string& group) {
70 base::Value::Dict report_body;
71 report_body.Set("key", "value");
72 cache()->AddReport(reporting_source, network_anonymization_key, url,
73 kUserAgent_, group, kType_, std::move(report_body),
74 /*depth=*/0, /*queued=*/tick_clock()->NowTicks(),
75 /*attempts=*/0, ReportingTargetType::kDeveloper);
76 }
77
AddEnterpriseReport(const GURL & url,const std::string & group)78 void AddEnterpriseReport(const GURL& url, const std::string& group) {
79 base::Value::Dict report_body;
80 report_body.Set("key", "value");
81 cache()->AddReport(/*reporting_source=*/std::nullopt,
82 net::NetworkAnonymizationKey(), url, kUserAgent_, group,
83 kType_, std::move(report_body), /*depth=*/0,
84 /*queued=*/tick_clock()->NowTicks(), /*attempts=*/0,
85 ReportingTargetType::kEnterprise);
86 }
87
88 // The first report added to the cache is uploaded immediately, and a timer is
89 // started for all subsequent reports (which may then be batched). To test
90 // behavior involving batching multiple reports, we need to add, upload, and
91 // immediately resolve a dummy report to prime the delivery timer.
UploadFirstReportAndStartTimer()92 void UploadFirstReportAndStartTimer() {
93 ReportingEndpointGroupKey dummy_group(
94 NetworkAnonymizationKey(),
95 url::Origin::Create(GURL("https://dummy.test")), "dummy",
96 ReportingTargetType::kDeveloper);
97 ASSERT_TRUE(SetEndpointInCache(
98 dummy_group, GURL("https://dummy.test/upload"), kExpires_));
99 AddReport(std::nullopt, dummy_group.network_anonymization_key,
100 dummy_group.origin.value().GetURL(), dummy_group.group_name);
101
102 ASSERT_EQ(1u, pending_uploads().size());
103 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
104 EXPECT_EQ(0u, pending_uploads().size());
105 EXPECT_TRUE(delivery_timer()->IsRunning());
106 }
107
108 // Prime delivery timer with a document report with a endpoint group that
109 // has matching reporting_source.
UploadFirstDocumentReportAndStartTimer()110 void UploadFirstDocumentReportAndStartTimer() {
111 ReportingEndpointGroupKey dummy_group(
112 kNak_, kDocumentReportingSource_,
113 url::Origin::Create(GURL("https://dummy.test")), "dummy",
114 ReportingTargetType::kDeveloper);
115 SetV1EndpointInCache(dummy_group, kDocumentReportingSource_,
116 kIsolationInfo_, GURL("https://dummy.test/upload"));
117 AddReport(kDocumentReportingSource_, dummy_group.network_anonymization_key,
118 dummy_group.origin.value().GetURL(), dummy_group.group_name);
119
120 ASSERT_EQ(1u, pending_uploads().size());
121 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
122 EXPECT_EQ(0u, pending_uploads().size());
123 EXPECT_TRUE(delivery_timer()->IsRunning());
124 }
125
SendReportsForSource(base::UnguessableToken reporting_source)126 void SendReportsForSource(base::UnguessableToken reporting_source) {
127 delivery_agent()->SendReportsForSource(reporting_source);
128 }
129
SendReports()130 void SendReports() { delivery_agent()->SendReportsForTesting(); }
131
132 base::test::ScopedFeatureList feature_list_;
133
134 const GURL kUrl_ = GURL("https://origin/path");
135 const GURL kOtherUrl_ = GURL("https://other-origin/path");
136 const GURL kSubdomainUrl_ = GURL("https://sub.origin/path");
137 const url::Origin kOrigin_ = url::Origin::Create(GURL("https://origin/"));
138 const url::Origin kOtherOrigin_ =
139 url::Origin::Create(GURL("https://other-origin/"));
140 const std::optional<base::UnguessableToken> kEmptyReportingSource_ =
141 std::nullopt;
142 const base::UnguessableToken kDocumentReportingSource_ =
143 base::UnguessableToken::Create();
144 const NetworkAnonymizationKey kNak_ =
145 NetworkAnonymizationKey::CreateSameSite(SchemefulSite(kOrigin_));
146 const NetworkAnonymizationKey kOtherNak_ =
147 NetworkAnonymizationKey::CreateSameSite(SchemefulSite(kOtherOrigin_));
148 const IsolationInfo kIsolationInfo_ =
149 IsolationInfo::Create(IsolationInfo::RequestType::kOther,
150 kOrigin_,
151 kOrigin_,
152 SiteForCookies::FromOrigin(kOrigin_));
153 const IsolationInfo kOtherIsolationInfo_ =
154 IsolationInfo::Create(IsolationInfo::RequestType::kOther,
155 kOtherOrigin_,
156 kOtherOrigin_,
157 SiteForCookies::FromOrigin(kOtherOrigin_));
158 const GURL kEndpoint_ = GURL("https://endpoint/");
159 const std::string kUserAgent_ = "Mozilla/1.0";
160 const std::string kGroup_ = "group";
161 const std::string kType_ = "type";
162 const base::Time kExpires_ = base::Time::Now() + base::Days(7);
163 const ReportingEndpointGroupKey kGroupKey_ =
164 ReportingEndpointGroupKey(kNak_,
165 kOrigin_,
166 kGroup_,
167 ReportingTargetType::kDeveloper);
168 const ReportingEndpointGroupKey kDocumentGroupKey_ =
169 ReportingEndpointGroupKey(kGroupKey_, kDocumentReportingSource_);
170 };
171
TEST_F(ReportingDeliveryAgentTest,SuccessfulImmediateUpload)172 TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateUpload) {
173 base::HistogramTester histograms;
174 ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
175 AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_);
176
177 // Upload is automatically started when cache is modified.
178
179 ASSERT_EQ(1u, pending_uploads().size());
180 EXPECT_EQ(kEndpoint_, pending_uploads()[0]->url());
181 {
182 auto value = pending_uploads()[0]->GetValue();
183
184 ASSERT_TRUE(value->is_list());
185 ASSERT_EQ(1u, value->GetList().size());
186
187 const base::Value& report = value->GetList()[0];
188 ASSERT_TRUE(report.is_dict());
189 const base::Value::Dict& report_dict = report.GetDict();
190 EXPECT_EQ(5u, report_dict.size());
191
192 ExpectDictIntegerValue(0, report_dict, "age");
193 ExpectDictStringValue(kType_, report_dict, "type");
194 ExpectDictStringValue(kUrl_.spec(), report_dict, "url");
195 ExpectDictStringValue(kUserAgent_, report_dict, "user_agent");
196 const base::Value::Dict* body = report_dict.FindDict("body");
197 EXPECT_EQ("value", *body->FindString("key"));
198 }
199 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
200
201 // Successful upload should remove delivered reports.
202 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
203 cache()->GetReports(&reports);
204 EXPECT_TRUE(reports.empty());
205 histograms.ExpectBucketCount(
206 kReportingUploadHeaderTypeHistogram,
207 ReportingDeliveryAgent::ReportingUploadHeaderType::kReportTo, 1);
208 histograms.ExpectBucketCount(
209 kReportingUploadHeaderTypeHistogram,
210 ReportingDeliveryAgent::ReportingUploadHeaderType::kReportingEndpoints,
211 0);
212
213 {
214 ReportingEndpoint::Statistics stats =
215 GetEndpointStatistics(kGroupKey_, kEndpoint_);
216 EXPECT_EQ(1, stats.attempted_uploads);
217 EXPECT_EQ(1, stats.successful_uploads);
218 EXPECT_EQ(1, stats.attempted_reports);
219 EXPECT_EQ(1, stats.successful_reports);
220 }
221
222 // TODO(dcreager): Check that BackoffEntry was informed of success.
223 }
224
TEST_F(ReportingDeliveryAgentTest,ReportToHeaderCountedCorrectly)225 TEST_F(ReportingDeliveryAgentTest, ReportToHeaderCountedCorrectly) {
226 base::HistogramTester histograms;
227
228 // Set an endpoint with no reporting source (as if configured with the
229 // Report-To header).
230 ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
231
232 // Add and upload a report with an associated source.
233 AddReport(kDocumentReportingSource_, kNak_, kUrl_, kGroup_);
234 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
235
236 // Successful upload should count this as a Report-To delivery, even though
237 // the report itself had a reporting source.
238 histograms.ExpectBucketCount(
239 kReportingUploadHeaderTypeHistogram,
240 ReportingDeliveryAgent::ReportingUploadHeaderType::kReportTo, 1);
241 histograms.ExpectBucketCount(
242 kReportingUploadHeaderTypeHistogram,
243 ReportingDeliveryAgent::ReportingUploadHeaderType::kReportingEndpoints,
244 0);
245 }
246
TEST_F(ReportingDeliveryAgentTest,SuccessfulImmediateUploadDocumentReport)247 TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateUploadDocumentReport) {
248 base::HistogramTester histograms;
249
250 SetV1EndpointInCache(kDocumentGroupKey_, kDocumentReportingSource_,
251 kIsolationInfo_, kEndpoint_);
252 AddReport(kDocumentReportingSource_, kNak_, kUrl_, kGroup_);
253
254 // Upload is automatically started when cache is modified.
255
256 ASSERT_EQ(1u, pending_uploads().size());
257 EXPECT_EQ(kEndpoint_, pending_uploads()[0]->url());
258 {
259 const auto value = pending_uploads()[0]->GetValue();
260
261 ASSERT_TRUE(value->is_list());
262 ASSERT_EQ(1u, value->GetList().size());
263
264 const base::Value& report = value->GetList()[0];
265 ASSERT_TRUE(report.is_dict());
266 const base::Value::Dict& report_dict = report.GetDict();
267
268 ExpectDictIntegerValue(0, report_dict, "age");
269 ExpectDictStringValue(kType_, report_dict, "type");
270 ExpectDictStringValue(kUrl_.spec(), report_dict, "url");
271 ExpectDictStringValue(kUserAgent_, report_dict, "user_agent");
272 const base::Value::Dict* body = report_dict.FindDict("body");
273 EXPECT_EQ("value", *body->FindString("key"));
274 }
275 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
276
277 // Successful upload should remove delivered reports.
278 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
279 cache()->GetReports(&reports);
280 EXPECT_TRUE(reports.empty());
281 histograms.ExpectBucketCount(
282 kReportingUploadHeaderTypeHistogram,
283 ReportingDeliveryAgent::ReportingUploadHeaderType::kReportingEndpoints,
284 1);
285 histograms.ExpectBucketCount(
286 kReportingUploadHeaderTypeHistogram,
287 ReportingDeliveryAgent::ReportingUploadHeaderType::kReportTo, 0);
288
289 {
290 ReportingEndpoint::Statistics stats =
291 GetEndpointStatistics(kDocumentGroupKey_, kEndpoint_);
292 EXPECT_EQ(1, stats.attempted_uploads);
293 EXPECT_EQ(1, stats.successful_uploads);
294 EXPECT_EQ(1, stats.attempted_reports);
295 EXPECT_EQ(1, stats.successful_reports);
296 }
297 }
298
TEST_F(ReportingDeliveryAgentTest,UploadHeaderTypeEnumCountPerReport)299 TEST_F(ReportingDeliveryAgentTest, UploadHeaderTypeEnumCountPerReport) {
300 UploadFirstDocumentReportAndStartTimer();
301 base::HistogramTester histograms;
302
303 SetV1EndpointInCache(kDocumentGroupKey_, kDocumentReportingSource_,
304 kIsolationInfo_, kEndpoint_);
305 AddReport(kDocumentReportingSource_, kNak_, kUrl_, kGroup_);
306 AddReport(kDocumentReportingSource_, kNak_, kUrl_, kGroup_);
307
308 // There should be one upload per (NAK, origin, reporting source).
309 EXPECT_TRUE(delivery_timer()->IsRunning());
310 delivery_timer()->Fire();
311
312 ASSERT_EQ(1u, pending_uploads().size());
313 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
314
315 // Successful upload should remove delivered reports.
316 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
317 cache()->GetReports(&reports);
318 EXPECT_TRUE(reports.empty());
319 histograms.ExpectBucketCount(
320 kReportingUploadHeaderTypeHistogram,
321 ReportingDeliveryAgent::ReportingUploadHeaderType::kReportingEndpoints,
322 2);
323 histograms.ExpectBucketCount(
324 kReportingUploadHeaderTypeHistogram,
325 ReportingDeliveryAgent::ReportingUploadHeaderType::kReportTo, 0);
326 }
327
TEST_F(ReportingDeliveryAgentTest,SuccessfulImmediateSubdomainUpload)328 TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateSubdomainUpload) {
329 ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_,
330 OriginSubdomains::INCLUDE));
331 AddReport(kEmptyReportingSource_, kNak_, kSubdomainUrl_, kGroup_);
332
333 // Upload is automatically started when cache is modified.
334
335 ASSERT_EQ(1u, pending_uploads().size());
336 EXPECT_EQ(kEndpoint_, pending_uploads()[0]->url());
337 {
338 auto value = pending_uploads()[0]->GetValue();
339
340 ASSERT_TRUE(value->is_list());
341 ASSERT_EQ(1u, value->GetList().size());
342
343 const base::Value& report = value->GetList()[0];
344 ASSERT_TRUE(report.is_dict());
345 const base::Value::Dict& report_dict = report.GetDict();
346 EXPECT_EQ(5u, report_dict.size());
347
348 ExpectDictIntegerValue(0, report_dict, "age");
349 ExpectDictStringValue(kType_, report_dict, "type");
350 ExpectDictStringValue(kSubdomainUrl_.spec(), report_dict, "url");
351 ExpectDictStringValue(kUserAgent_, report_dict, "user_agent");
352 const base::Value::Dict* body = report_dict.FindDict("body");
353 EXPECT_EQ("value", *body->FindString("key"));
354 }
355 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
356
357 // Successful upload should remove delivered reports.
358 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
359 cache()->GetReports(&reports);
360 EXPECT_TRUE(reports.empty());
361
362 {
363 ReportingEndpoint::Statistics stats =
364 GetEndpointStatistics(kGroupKey_, kEndpoint_);
365 EXPECT_EQ(1, stats.attempted_uploads);
366 EXPECT_EQ(1, stats.successful_uploads);
367 EXPECT_EQ(1, stats.attempted_reports);
368 EXPECT_EQ(1, stats.successful_reports);
369 }
370
371 // TODO(dcreager): Check that BackoffEntry was informed of success.
372 }
373
TEST_F(ReportingDeliveryAgentTest,SuccessfulImmediateSubdomainUploadWithOverwrittenEndpoint)374 TEST_F(ReportingDeliveryAgentTest,
375 SuccessfulImmediateSubdomainUploadWithOverwrittenEndpoint) {
376 ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_,
377 OriginSubdomains::INCLUDE));
378 AddReport(kEmptyReportingSource_, kNak_, kSubdomainUrl_, kGroup_);
379
380 // Upload is automatically started when cache is modified.
381
382 ASSERT_EQ(1u, pending_uploads().size());
383 // Change the endpoint group to exclude subdomains.
384 ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_,
385 OriginSubdomains::EXCLUDE));
386 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
387
388 {
389 ReportingEndpoint::Statistics stats =
390 GetEndpointStatistics(kGroupKey_, kEndpoint_);
391 EXPECT_EQ(1, stats.attempted_uploads);
392 EXPECT_EQ(1, stats.successful_uploads);
393 EXPECT_EQ(1, stats.attempted_reports);
394 EXPECT_EQ(1, stats.successful_reports);
395 }
396
397 // Successful upload should remove delivered reports.
398 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
399 cache()->GetReports(&reports);
400 EXPECT_TRUE(reports.empty());
401 }
402
TEST_F(ReportingDeliveryAgentTest,SuccessfulDelayedUpload)403 TEST_F(ReportingDeliveryAgentTest, SuccessfulDelayedUpload) {
404 // Trigger and complete an upload to start the delivery timer.
405 ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
406 AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_);
407 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
408
409 // Add another report to upload after a delay.
410 AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_);
411
412 EXPECT_TRUE(delivery_timer()->IsRunning());
413 delivery_timer()->Fire();
414
415 ASSERT_EQ(1u, pending_uploads().size());
416 EXPECT_EQ(kEndpoint_, pending_uploads()[0]->url());
417 {
418 auto value = pending_uploads()[0]->GetValue();
419
420 ASSERT_TRUE(value->is_list());
421 ASSERT_EQ(1u, value->GetList().size());
422
423 const base::Value& report = value->GetList()[0];
424 ASSERT_TRUE(report.is_dict());
425 const base::Value::Dict& report_dict = report.GetDict();
426 EXPECT_EQ(5u, report_dict.size());
427
428 ExpectDictIntegerValue(0, report_dict, "age");
429 ExpectDictStringValue(kType_, report_dict, "type");
430 ExpectDictStringValue(kUrl_.spec(), report_dict, "url");
431 ExpectDictStringValue(kUserAgent_, report_dict, "user_agent");
432 const base::Value::Dict* body = report_dict.FindDict("body");
433 EXPECT_EQ("value", *body->FindString("key"));
434 }
435 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
436
437 {
438 ReportingEndpoint::Statistics stats =
439 GetEndpointStatistics(kGroupKey_, kEndpoint_);
440 EXPECT_EQ(2, stats.attempted_uploads);
441 EXPECT_EQ(2, stats.successful_uploads);
442 EXPECT_EQ(2, stats.attempted_reports);
443 EXPECT_EQ(2, stats.successful_reports);
444 }
445
446 // Successful upload should remove delivered reports.
447 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
448 cache()->GetReports(&reports);
449 EXPECT_TRUE(reports.empty());
450
451 // TODO(juliatuttle): Check that BackoffEntry was informed of success.
452 }
453
TEST_F(ReportingDeliveryAgentTest,FailedUpload)454 TEST_F(ReportingDeliveryAgentTest, FailedUpload) {
455 ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
456 AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_);
457
458 EXPECT_TRUE(delivery_timer()->IsRunning());
459 delivery_timer()->Fire();
460
461 ASSERT_EQ(1u, pending_uploads().size());
462 pending_uploads()[0]->Complete(ReportingUploader::Outcome::FAILURE);
463
464 {
465 ReportingEndpoint::Statistics stats =
466 GetEndpointStatistics(kGroupKey_, kEndpoint_);
467 EXPECT_EQ(1, stats.attempted_uploads);
468 EXPECT_EQ(0, stats.successful_uploads);
469 EXPECT_EQ(1, stats.attempted_reports);
470 EXPECT_EQ(0, stats.successful_reports);
471 }
472
473 // Failed upload should increment reports' attempts.
474 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
475 cache()->GetReports(&reports);
476 ASSERT_EQ(1u, reports.size());
477 EXPECT_EQ(1, reports[0]->attempts);
478
479 // Since endpoint is now failing, an upload won't be started despite a pending
480 // report.
481 ASSERT_TRUE(pending_uploads().empty());
482 EXPECT_TRUE(delivery_timer()->IsRunning());
483 delivery_timer()->Fire();
484 EXPECT_TRUE(pending_uploads().empty());
485
486 {
487 ReportingEndpoint::Statistics stats =
488 GetEndpointStatistics(kGroupKey_, kEndpoint_);
489 EXPECT_EQ(1, stats.attempted_uploads);
490 EXPECT_EQ(0, stats.successful_uploads);
491 EXPECT_EQ(1, stats.attempted_reports);
492 EXPECT_EQ(0, stats.successful_reports);
493 }
494 }
495
TEST_F(ReportingDeliveryAgentTest,DisallowedUpload)496 TEST_F(ReportingDeliveryAgentTest, DisallowedUpload) {
497 // This mimics the check that is controlled by the BACKGROUND_SYNC permission
498 // in a real browser profile.
499 context()->test_delegate()->set_disallow_report_uploads(true);
500
501 static const int kAgeMillis = 12345;
502
503 ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
504 AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_);
505
506 tick_clock()->Advance(base::Milliseconds(kAgeMillis));
507
508 EXPECT_TRUE(delivery_timer()->IsRunning());
509 delivery_timer()->Fire();
510
511 // We should not try to upload the report, since we weren't given permission
512 // for this origin.
513 EXPECT_TRUE(pending_uploads().empty());
514
515 {
516 ReportingEndpoint::Statistics stats =
517 GetEndpointStatistics(kGroupKey_, kEndpoint_);
518 EXPECT_EQ(0, stats.attempted_uploads);
519 EXPECT_EQ(0, stats.successful_uploads);
520 EXPECT_EQ(0, stats.attempted_reports);
521 EXPECT_EQ(0, stats.successful_reports);
522 }
523
524 // Disallowed reports should NOT have been removed from the cache.
525 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
526 cache()->GetReports(&reports);
527 EXPECT_EQ(1u, reports.size());
528 }
529
TEST_F(ReportingDeliveryAgentTest,RemoveEndpointUpload)530 TEST_F(ReportingDeliveryAgentTest, RemoveEndpointUpload) {
531 static const ReportingEndpointGroupKey kOtherGroupKey(
532 kNak_, kOtherOrigin_, kGroup_, ReportingTargetType::kDeveloper);
533
534 ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
535 ASSERT_TRUE(SetEndpointInCache(kOtherGroupKey, kEndpoint_, kExpires_));
536
537 AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_);
538
539 EXPECT_TRUE(delivery_timer()->IsRunning());
540 delivery_timer()->Fire();
541
542 ASSERT_EQ(1u, pending_uploads().size());
543 pending_uploads()[0]->Complete(ReportingUploader::Outcome::REMOVE_ENDPOINT);
544
545 // "Remove endpoint" upload should remove endpoint from *all* origins and
546 // increment reports' attempts.
547 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
548 cache()->GetReports(&reports);
549 ASSERT_EQ(1u, reports.size());
550 EXPECT_EQ(1, reports[0]->attempts);
551
552 EXPECT_FALSE(FindEndpointInCache(kGroupKey_, kEndpoint_));
553 EXPECT_FALSE(FindEndpointInCache(kOtherGroupKey, kEndpoint_));
554
555 // Since endpoint is now failing, an upload won't be started despite a pending
556 // report.
557 EXPECT_TRUE(delivery_timer()->IsRunning());
558 delivery_timer()->Fire();
559 EXPECT_TRUE(pending_uploads().empty());
560 }
561
TEST_F(ReportingDeliveryAgentTest,ConcurrentRemove)562 TEST_F(ReportingDeliveryAgentTest, ConcurrentRemove) {
563 ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
564 AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_);
565
566 EXPECT_TRUE(delivery_timer()->IsRunning());
567 delivery_timer()->Fire();
568 ASSERT_EQ(1u, pending_uploads().size());
569
570 // Remove the report while the upload is running.
571 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
572 cache()->GetReports(&reports);
573 EXPECT_EQ(1u, reports.size());
574
575 const ReportingReport* report = reports[0];
576 EXPECT_FALSE(cache()->IsReportDoomedForTesting(report));
577
578 // Report should appear removed, even though the cache has doomed it.
579 cache()->RemoveReports(reports);
580 cache()->GetReports(&reports);
581 EXPECT_TRUE(reports.empty());
582 EXPECT_TRUE(cache()->IsReportDoomedForTesting(report));
583
584 // Completing upload shouldn't crash, and report should still be gone.
585 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
586 cache()->GetReports(&reports);
587 EXPECT_TRUE(reports.empty());
588 }
589
TEST_F(ReportingDeliveryAgentTest,ConcurrentRemoveDuringPermissionsCheck)590 TEST_F(ReportingDeliveryAgentTest, ConcurrentRemoveDuringPermissionsCheck) {
591 // Pause the permissions check, so that we can try to remove some reports
592 // while we're in the middle of verifying that we can upload them. (This is
593 // similar to the previous test, but removes the reports during a different
594 // part of the upload process.)
595 context()->test_delegate()->set_pause_permissions_check(true);
596
597 ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
598 AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_);
599
600 ASSERT_TRUE(context()->test_delegate()->PermissionsCheckPaused());
601
602 // Remove the report while the upload is running.
603 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
604 cache()->GetReports(&reports);
605 EXPECT_EQ(1u, reports.size());
606
607 const ReportingReport* report = reports[0];
608 EXPECT_FALSE(cache()->IsReportDoomedForTesting(report));
609
610 // Report should appear removed, even though the cache has doomed it.
611 cache()->RemoveReports(reports);
612 cache()->GetReports(&reports);
613 EXPECT_TRUE(reports.empty());
614 EXPECT_TRUE(cache()->IsReportDoomedForTesting(report));
615
616 // Completing upload shouldn't crash, and report should still be gone.
617 context()->test_delegate()->ResumePermissionsCheck();
618 ASSERT_EQ(1u, pending_uploads().size());
619 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
620 cache()->GetReports(&reports);
621 EXPECT_TRUE(reports.empty());
622 }
623
624 // Reports uploaded together must share a NAK and origin.
625 // Test that the agent will not combine reports destined for the same endpoint
626 // if the reports are from different origins or NAKs, but does combine all
627 // reports for the same (NAK, origin).
TEST_F(ReportingDeliveryAgentTest,OnlyBatchSameNakAndOrigin)628 TEST_F(ReportingDeliveryAgentTest, OnlyBatchSameNakAndOrigin) {
629 const ReportingEndpointGroupKey kGroupKeys[] = {
630 ReportingEndpointGroupKey(kNak_, kOrigin_, kGroup_,
631 ReportingTargetType::kDeveloper),
632 ReportingEndpointGroupKey(kNak_, kOtherOrigin_, kGroup_,
633 ReportingTargetType::kDeveloper),
634 ReportingEndpointGroupKey(kOtherNak_, kOrigin_, kGroup_,
635 ReportingTargetType::kDeveloper),
636 ReportingEndpointGroupKey(kOtherNak_, kOtherOrigin_, kGroup_,
637 ReportingTargetType::kDeveloper),
638 };
639 for (const ReportingEndpointGroupKey& group_key : kGroupKeys) {
640 ASSERT_TRUE(SetEndpointInCache(group_key, kEndpoint_, kExpires_));
641 }
642
643 // Trigger and complete an upload to start the delivery timer.
644 UploadFirstReportAndStartTimer();
645
646 // Now that the delivery timer is running, these reports won't be immediately
647 // uploaded.
648 AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_);
649 AddReport(kEmptyReportingSource_, kNak_, kOtherUrl_, kGroup_);
650 AddReport(kEmptyReportingSource_, kNak_, kOtherUrl_, kGroup_);
651 AddReport(kEmptyReportingSource_, kOtherNak_, kUrl_, kGroup_);
652 AddReport(kEmptyReportingSource_, kOtherNak_, kUrl_, kGroup_);
653 AddReport(kEmptyReportingSource_, kOtherNak_, kUrl_, kGroup_);
654 AddReport(kEmptyReportingSource_, kOtherNak_, kOtherUrl_, kGroup_);
655 AddReport(kEmptyReportingSource_, kOtherNak_, kOtherUrl_, kGroup_);
656 AddReport(kEmptyReportingSource_, kOtherNak_, kOtherUrl_, kGroup_);
657 AddReport(kEmptyReportingSource_, kOtherNak_, kOtherUrl_, kGroup_);
658 EXPECT_EQ(0u, pending_uploads().size());
659
660 // There should be one upload per (NAK, origin).
661 EXPECT_TRUE(delivery_timer()->IsRunning());
662 delivery_timer()->Fire();
663 ASSERT_EQ(4u, pending_uploads().size());
664
665 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
666 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
667 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
668 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
669 EXPECT_EQ(0u, pending_uploads().size());
670
671 for (int i = 0; i < 4; ++i) {
672 ReportingEndpoint::Statistics stats =
673 GetEndpointStatistics(kGroupKeys[i], kEndpoint_);
674 EXPECT_EQ(1, stats.attempted_uploads);
675 EXPECT_EQ(1, stats.successful_uploads);
676 EXPECT_EQ(i + 1, stats.attempted_reports);
677 EXPECT_EQ(i + 1, stats.successful_reports);
678 }
679 }
680
681 // Test that the agent won't start a second upload for a (NAK, origin, group)
682 // while one is pending, even if a different endpoint is available, but will
683 // once the original delivery is complete and the (NAK, origin, group) is no
684 // longer pending.
TEST_F(ReportingDeliveryAgentTest,SerializeUploadsToGroup)685 TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToGroup) {
686 static const GURL kDifferentEndpoint("https://endpoint2/");
687
688 ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
689 ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kDifferentEndpoint, kExpires_));
690
691 // Trigger and complete an upload to start the delivery timer.
692 UploadFirstReportAndStartTimer();
693
694 // First upload causes this group key to become pending.
695 AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_);
696 EXPECT_EQ(0u, pending_uploads().size());
697 EXPECT_TRUE(delivery_timer()->IsRunning());
698 delivery_timer()->Fire();
699 EXPECT_EQ(1u, pending_uploads().size());
700
701 // Second upload isn't started because the group is pending.
702 AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_);
703 EXPECT_TRUE(delivery_timer()->IsRunning());
704 delivery_timer()->Fire();
705 ASSERT_EQ(1u, pending_uploads().size());
706
707 // Resolve the first upload.
708 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
709 EXPECT_EQ(0u, pending_uploads().size());
710
711 // Now the other upload can happen.
712 EXPECT_TRUE(delivery_timer()->IsRunning());
713 delivery_timer()->Fire();
714 ASSERT_EQ(1u, pending_uploads().size());
715 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
716 EXPECT_EQ(0u, pending_uploads().size());
717
718 // A total of 2 reports were uploaded.
719 {
720 ReportingEndpoint::Statistics stats =
721 GetEndpointStatistics(kGroupKey_, kEndpoint_);
722 ReportingEndpoint::Statistics different_stats =
723 GetEndpointStatistics(kGroupKey_, kDifferentEndpoint);
724 EXPECT_EQ(2, stats.attempted_uploads + different_stats.attempted_uploads);
725 EXPECT_EQ(2, stats.successful_uploads + different_stats.successful_uploads);
726 EXPECT_EQ(2, stats.attempted_reports + different_stats.attempted_reports);
727 EXPECT_EQ(2, stats.successful_reports + different_stats.successful_reports);
728 }
729 }
730
731 // Tests that the agent will start parallel uploads to different groups within
732 // the same (NAK, origin) to endpoints with different URLs.
TEST_F(ReportingDeliveryAgentTest,ParallelizeUploadsAcrossGroups)733 TEST_F(ReportingDeliveryAgentTest, ParallelizeUploadsAcrossGroups) {
734 static const GURL kDifferentEndpoint("https://endpoint2/");
735 static const std::string kDifferentGroup("group2");
736 const ReportingEndpointGroupKey kDifferentGroupKey(
737 kNak_, kOrigin_, kDifferentGroup, ReportingTargetType::kDeveloper);
738
739 ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
740 ASSERT_TRUE(
741 SetEndpointInCache(kDifferentGroupKey, kDifferentEndpoint, kExpires_));
742
743 // Trigger and complete an upload to start the delivery timer.
744 UploadFirstReportAndStartTimer();
745
746 AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_);
747 AddReport(kEmptyReportingSource_, kNak_, kUrl_, kDifferentGroup);
748
749 EXPECT_TRUE(delivery_timer()->IsRunning());
750 delivery_timer()->Fire();
751 ASSERT_EQ(2u, pending_uploads().size());
752
753 pending_uploads()[1]->Complete(ReportingUploader::Outcome::SUCCESS);
754 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
755 EXPECT_EQ(0u, pending_uploads().size());
756
757 {
758 ReportingEndpoint::Statistics stats =
759 GetEndpointStatistics(kGroupKey_, kEndpoint_);
760 EXPECT_EQ(1, stats.attempted_uploads);
761 EXPECT_EQ(1, stats.successful_uploads);
762 EXPECT_EQ(1, stats.attempted_reports);
763 EXPECT_EQ(1, stats.successful_reports);
764 }
765 {
766 ReportingEndpoint::Statistics stats =
767 GetEndpointStatistics(kDifferentGroupKey, kDifferentEndpoint);
768 EXPECT_EQ(1, stats.attempted_uploads);
769 EXPECT_EQ(1, stats.successful_uploads);
770 EXPECT_EQ(1, stats.attempted_reports);
771 EXPECT_EQ(1, stats.successful_reports);
772 }
773 }
774
775 // Tests that the agent will include reports for different groups for the same
776 // (NAK, origin) in the same upload if they are destined for the same endpoint
777 // URL.
TEST_F(ReportingDeliveryAgentTest,BatchReportsAcrossGroups)778 TEST_F(ReportingDeliveryAgentTest, BatchReportsAcrossGroups) {
779 static const std::string kDifferentGroup("group2");
780 const ReportingEndpointGroupKey kDifferentGroupKey(
781 kNak_, kOrigin_, kDifferentGroup, ReportingTargetType::kDeveloper);
782
783 ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
784 ASSERT_TRUE(SetEndpointInCache(kDifferentGroupKey, kEndpoint_, kExpires_));
785
786 UploadFirstReportAndStartTimer();
787
788 AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_);
789 AddReport(kEmptyReportingSource_, kNak_, kUrl_, kDifferentGroup);
790
791 EXPECT_TRUE(delivery_timer()->IsRunning());
792 delivery_timer()->Fire();
793 ASSERT_EQ(1u, pending_uploads().size());
794 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
795 EXPECT_EQ(0u, pending_uploads().size());
796
797 {
798 ReportingEndpoint::Statistics stats =
799 GetEndpointStatistics(kGroupKey_, kEndpoint_);
800 EXPECT_EQ(1, stats.attempted_uploads);
801 EXPECT_EQ(1, stats.successful_uploads);
802 EXPECT_EQ(1, stats.attempted_reports);
803 EXPECT_EQ(1, stats.successful_reports);
804 }
805 {
806 ReportingEndpoint::Statistics stats =
807 GetEndpointStatistics(kDifferentGroupKey, kEndpoint_);
808 EXPECT_EQ(1, stats.attempted_uploads);
809 EXPECT_EQ(1, stats.successful_uploads);
810 EXPECT_EQ(1, stats.attempted_reports);
811 EXPECT_EQ(1, stats.successful_reports);
812 }
813 }
814
815 // Tests that the agent can send all outstanding reports for a single source
816 // when necessary. This test queues two reports for the same reporting source,
817 // for different endpoints, another for a different source at the same URL, and
818 // another for a different source on a different origin.
TEST_F(ReportingDeliveryAgentTest,SendDeveloperReportsForSource)819 TEST_F(ReportingDeliveryAgentTest, SendDeveloperReportsForSource) {
820 static const std::string kGroup2("group2");
821
822 // Two other reporting sources; kReportingSource2 will enqueue reports for the
823 // same URL as kReportingSource_, while kReportingSource3 will be a separate
824 // origin.
825 const base::UnguessableToken kReportingSource1 =
826 base::UnguessableToken::Create();
827 const base::UnguessableToken kReportingSource2 =
828 base::UnguessableToken::Create();
829 const base::UnguessableToken kReportingSource3 =
830 base::UnguessableToken::Create();
831
832 const IsolationInfo kIsolationInfo1 =
833 IsolationInfo::Create(IsolationInfo::RequestType::kOther, kOrigin_,
834 kOrigin_, SiteForCookies::FromOrigin(kOrigin_));
835 const IsolationInfo kIsolationInfo2 =
836 IsolationInfo::Create(IsolationInfo::RequestType::kOther, kOrigin_,
837 kOrigin_, SiteForCookies::FromOrigin(kOrigin_));
838 const IsolationInfo kIsolationInfo3 = IsolationInfo::Create(
839 IsolationInfo::RequestType::kOther, kOtherOrigin_, kOtherOrigin_,
840 SiteForCookies::FromOrigin(kOtherOrigin_));
841
842 // Set up identical endpoint configuration for kReportingSource1 and
843 // kReportingSource2. kReportingSource3 is independent.
844 const ReportingEndpointGroupKey kGroup1Key1(kNak_, kReportingSource1,
845 kOrigin_, kGroup_,
846 ReportingTargetType::kDeveloper);
847 const ReportingEndpointGroupKey kGroup2Key1(kNak_, kReportingSource1,
848 kOrigin_, kGroup2,
849 ReportingTargetType::kDeveloper);
850 const ReportingEndpointGroupKey kGroup1Key2(kNak_, kReportingSource2,
851 kOrigin_, kGroup_,
852 ReportingTargetType::kDeveloper);
853 const ReportingEndpointGroupKey kGroup2Key2(kNak_, kReportingSource2,
854 kOrigin_, kGroup2,
855 ReportingTargetType::kDeveloper);
856 const ReportingEndpointGroupKey kOtherGroupKey(
857 kOtherNak_, kReportingSource3, kOtherOrigin_, kGroup_,
858 ReportingTargetType::kDeveloper);
859
860 SetV1EndpointInCache(kGroup1Key1, kReportingSource1, kIsolationInfo1, kUrl_);
861 SetV1EndpointInCache(kGroup2Key1, kReportingSource1, kIsolationInfo1, kUrl_);
862 SetV1EndpointInCache(kGroup1Key2, kReportingSource2, kIsolationInfo2, kUrl_);
863 SetV1EndpointInCache(kGroup2Key2, kReportingSource2, kIsolationInfo2, kUrl_);
864 SetV1EndpointInCache(kOtherGroupKey, kReportingSource3, kIsolationInfo3,
865 kOtherUrl_);
866
867 UploadFirstReportAndStartTimer();
868
869 AddReport(kReportingSource1, kNak_, kUrl_, kGroup_);
870 AddReport(kReportingSource1, kNak_, kUrl_, kGroup2);
871 AddReport(kReportingSource2, kNak_, kUrl_, kGroup_);
872 AddReport(kReportingSource3, kOtherNak_, kUrl_, kGroup_);
873
874 // There should be four queued reports at this point.
875 EXPECT_EQ(4u, cache()->GetReportCountWithStatusForTesting(
876 ReportingReport::Status::QUEUED));
877 EXPECT_EQ(0u, pending_uploads().size());
878 SendReportsForSource(kReportingSource1);
879 // Sending all reports for the source should only queue two, despite the fact
880 // that there are other reports queued for the same origin and endpoint.
881 EXPECT_EQ(2u, cache()->GetReportCountWithStatusForTesting(
882 ReportingReport::Status::QUEUED));
883 EXPECT_EQ(2u, cache()->GetReportCountWithStatusForTesting(
884 ReportingReport::Status::PENDING));
885 // All pending reports for the same source should be batched into a single
886 // upload.
887 ASSERT_EQ(1u, pending_uploads().size());
888 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
889 EXPECT_EQ(0u, pending_uploads().size());
890 }
891
TEST_F(ReportingDeliveryAgentTest,SendEnterpriseReports)892 TEST_F(ReportingDeliveryAgentTest, SendEnterpriseReports) {
893 const ReportingEndpointGroupKey kEnterpriseGroupKey(
894 NetworkAnonymizationKey(), /*reporting_source=*/std::nullopt,
895 /*origin=*/std::nullopt, kGroup_, ReportingTargetType::kEnterprise);
896
897 SetEnterpriseEndpointInCache(kEnterpriseGroupKey, kUrl_);
898
899 AddEnterpriseReport(kUrl_, kGroup_);
900
901 // Upload is automatically started when cache is modified.
902 ASSERT_EQ(1u, pending_uploads().size());
903 EXPECT_EQ(kUrl_, pending_uploads()[0]->url());
904 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
905 EXPECT_EQ(0u, pending_uploads().size());
906
907 // Successful upload should remove delivered reports.
908 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
909 cache()->GetReports(&reports);
910 EXPECT_TRUE(reports.empty());
911 }
912
TEST_F(ReportingDeliveryAgentTest,SendEnterpriseReportsBatched)913 TEST_F(ReportingDeliveryAgentTest, SendEnterpriseReportsBatched) {
914 const ReportingEndpointGroupKey kEnterpriseGroupKey(
915 NetworkAnonymizationKey(), /*reporting_source=*/std::nullopt,
916 /*origin=*/std::nullopt, kGroup_, ReportingTargetType::kEnterprise);
917
918 SetEnterpriseEndpointInCache(kEnterpriseGroupKey, kUrl_);
919
920 // Call so the reports will be batched together.
921 UploadFirstReportAndStartTimer();
922
923 AddEnterpriseReport(kUrl_, kGroup_);
924 AddEnterpriseReport(kUrl_, kGroup_);
925
926 // There should be two queued reports at this point.
927 EXPECT_EQ(2u, cache()->GetReportCountWithStatusForTesting(
928 ReportingReport::Status::QUEUED));
929 EXPECT_EQ(0u, pending_uploads().size());
930
931 SendReports();
932
933 EXPECT_EQ(2u, cache()->GetReportCountWithStatusForTesting(
934 ReportingReport::Status::PENDING));
935
936 // All pending reports should be batched into a single upload.
937 ASSERT_EQ(1u, pending_uploads().size());
938 EXPECT_EQ(kUrl_, pending_uploads()[0]->url());
939 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
940 EXPECT_EQ(0u, pending_uploads().size());
941
942 // Successful upload should remove delivered reports.
943 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
944 cache()->GetReports(&reports);
945 EXPECT_TRUE(reports.empty());
946 }
947
TEST_F(ReportingDeliveryAgentTest,SendDeveloperAndEnterpriseReports)948 TEST_F(ReportingDeliveryAgentTest, SendDeveloperAndEnterpriseReports) {
949 const ReportingEndpointGroupKey kDeveloperGroupKey(
950 kNak_, kDocumentReportingSource_, kOrigin_, kGroup_,
951 ReportingTargetType::kDeveloper);
952 const ReportingEndpointGroupKey kEnterpriseGroupKey(
953 NetworkAnonymizationKey(),
954 /*reporting_source=*/std::nullopt, /*origin=*/std::nullopt, kGroup_,
955 ReportingTargetType::kEnterprise);
956
957 SetV1EndpointInCache(kDeveloperGroupKey, kDocumentReportingSource_,
958 kIsolationInfo_, kUrl_);
959 SetEnterpriseEndpointInCache(kEnterpriseGroupKey, kUrl_);
960
961 AddReport(kDocumentReportingSource_, kNak_, kUrl_, kGroup_);
962 AddEnterpriseReport(kUrl_, kGroup_);
963
964 SendReports();
965
966 // Web developer and enterprise pending reports should be in separate uploads.
967 ASSERT_EQ(2u, pending_uploads().size());
968 EXPECT_EQ(kUrl_, pending_uploads()[0]->url());
969 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
970 ASSERT_EQ(1u, pending_uploads().size());
971 EXPECT_EQ(kUrl_, pending_uploads()[0]->url());
972 pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
973 EXPECT_EQ(0u, pending_uploads().size());
974
975 // Successful upload should remove delivered reports.
976 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
977 cache()->GetReports(&reports);
978 EXPECT_TRUE(reports.empty());
979 }
980
981 // Tests that the agent can send all outstanding V1 reports for multiple sources
982 // and that these are not batched together.
TEST_F(ReportingDeliveryAgentTest,SendReportsForMultipleSources)983 TEST_F(ReportingDeliveryAgentTest, SendReportsForMultipleSources) {
984 static const std::string kGroup2("group2");
985
986 // Two other reporting sources; kReportingSource2 will enqueue reports for the
987 // same URL as kReportingSource_, while kReportingSource3 will be a separate
988 // origin.
989 const base::UnguessableToken kReportingSource1 =
990 base::UnguessableToken::Create();
991 const base::UnguessableToken kReportingSource2 =
992 base::UnguessableToken::Create();
993 const base::UnguessableToken kReportingSource3 =
994 base::UnguessableToken::Create();
995
996 const IsolationInfo kIsolationInfo1 =
997 IsolationInfo::Create(IsolationInfo::RequestType::kOther, kOrigin_,
998 kOrigin_, SiteForCookies::FromOrigin(kOrigin_));
999 const IsolationInfo kIsolationInfo2 =
1000 IsolationInfo::Create(IsolationInfo::RequestType::kOther, kOrigin_,
1001 kOrigin_, SiteForCookies::FromOrigin(kOrigin_));
1002 const IsolationInfo kIsolationInfo3 = IsolationInfo::Create(
1003 IsolationInfo::RequestType::kOther, kOtherOrigin_, kOtherOrigin_,
1004 SiteForCookies::FromOrigin(kOtherOrigin_));
1005
1006 // Set up identical endpoint configuration for kReportingSource1 and
1007 // kReportingSource2. kReportingSource3 is independent.
1008 const ReportingEndpointGroupKey kGroup1Key1(kNak_, kReportingSource1,
1009 kOrigin_, kGroup_,
1010 ReportingTargetType::kDeveloper);
1011 const ReportingEndpointGroupKey kGroup2Key1(kNak_, kReportingSource1,
1012 kOrigin_, kGroup2,
1013 ReportingTargetType::kDeveloper);
1014 const ReportingEndpointGroupKey kGroup1Key2(kNak_, kReportingSource2,
1015 kOrigin_, kGroup_,
1016 ReportingTargetType::kDeveloper);
1017 const ReportingEndpointGroupKey kGroup2Key2(kNak_, kReportingSource2,
1018 kOrigin_, kGroup2,
1019 ReportingTargetType::kDeveloper);
1020 const ReportingEndpointGroupKey kOtherGroupKey(
1021 kOtherNak_, kReportingSource3, kOtherOrigin_, kGroup_,
1022 ReportingTargetType::kDeveloper);
1023
1024 SetV1EndpointInCache(kGroup1Key1, kReportingSource1, kIsolationInfo1, kUrl_);
1025 SetV1EndpointInCache(kGroup2Key1, kReportingSource1, kIsolationInfo1, kUrl_);
1026 SetV1EndpointInCache(kGroup1Key2, kReportingSource2, kIsolationInfo2, kUrl_);
1027 SetV1EndpointInCache(kGroup2Key2, kReportingSource2, kIsolationInfo2, kUrl_);
1028 SetV1EndpointInCache(kOtherGroupKey, kReportingSource3, kIsolationInfo3,
1029 kOtherUrl_);
1030
1031 UploadFirstReportAndStartTimer();
1032
1033 AddReport(kReportingSource1, kNak_, kUrl_, kGroup_);
1034 AddReport(kReportingSource1, kNak_, kUrl_, kGroup2);
1035 AddReport(kReportingSource2, kNak_, kUrl_, kGroup_);
1036 AddReport(kReportingSource3, kOtherNak_, kUrl_, kGroup_);
1037
1038 // There should be four queued reports at this point.
1039 EXPECT_EQ(4u, cache()->GetReportCountWithStatusForTesting(
1040 ReportingReport::Status::QUEUED));
1041 EXPECT_EQ(0u, pending_uploads().size());
1042
1043 // Send reports for both ReportingSource 1 and 2 at the same time. These
1044 // should be sent to the same endpoint, but should still not be batched
1045 // together.
1046 SendReportsForSource(kReportingSource1);
1047 SendReportsForSource(kReportingSource2);
1048
1049 // We expect to see three pending reports, and one still queued. The pending
1050 // reports should be divided into two uploads.
1051 EXPECT_EQ(1u, cache()->GetReportCountWithStatusForTesting(
1052 ReportingReport::Status::QUEUED));
1053 EXPECT_EQ(3u, cache()->GetReportCountWithStatusForTesting(
1054 ReportingReport::Status::PENDING));
1055 ASSERT_EQ(2u, pending_uploads().size());
1056 }
1057
1058 } // namespace net
1059