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 #include "net/reporting/reporting_cache.h"
6
7 #include <string>
8 #include <utility>
9
10 #include "base/containers/contains.h"
11 #include "base/functional/bind.h"
12 #include "base/memory/raw_ptr.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/test/scoped_feature_list.h"
16 #include "base/test/simple_test_tick_clock.h"
17 #include "base/test/values_test_util.h"
18 #include "base/time/time.h"
19 #include "base/values.h"
20 #include "net/base/features.h"
21 #include "net/base/network_anonymization_key.h"
22 #include "net/base/schemeful_site.h"
23 #include "net/reporting/mock_persistent_reporting_store.h"
24 #include "net/reporting/reporting_cache_impl.h"
25 #include "net/reporting/reporting_cache_observer.h"
26 #include "net/reporting/reporting_endpoint.h"
27 #include "net/reporting/reporting_report.h"
28 #include "net/reporting/reporting_test_util.h"
29 #include "testing/gmock/include/gmock/gmock.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "url/gurl.h"
32 #include "url/origin.h"
33
34 namespace net {
35 namespace {
36
37 using CommandType = MockPersistentReportingStore::Command::Type;
38
39 class TestReportingCacheObserver : public ReportingCacheObserver {
40 public:
41 TestReportingCacheObserver() = default;
42
OnReportsUpdated()43 void OnReportsUpdated() override { ++cached_reports_update_count_; }
OnClientsUpdated()44 void OnClientsUpdated() override { ++cached_clients_update_count_; }
45
cached_reports_update_count() const46 int cached_reports_update_count() const {
47 return cached_reports_update_count_;
48 }
cached_clients_update_count() const49 int cached_clients_update_count() const {
50 return cached_clients_update_count_;
51 }
52
53 private:
54 int cached_reports_update_count_ = 0;
55 int cached_clients_update_count_ = 0;
56 };
57
58 // The tests are parametrized on a boolean value which represents whether or not
59 // to use a MockPersistentReportingStore.
60 class ReportingCacheTest : public ReportingTestBase,
61 public ::testing::WithParamInterface<bool> {
62 protected:
ReportingCacheTest()63 ReportingCacheTest() {
64 // This is a private API of the reporting service, so no need to test the
65 // case kPartitionNelAndReportingByNetworkIsolationKey is disabled - the
66 // feature is only applied at the entry points of the service.
67 feature_list_.InitAndEnableFeature(
68 features::kPartitionNelAndReportingByNetworkIsolationKey);
69
70 ReportingPolicy policy;
71 policy.max_report_count = 5;
72 policy.max_endpoints_per_origin = 3;
73 policy.max_endpoint_count = 5;
74 policy.max_group_staleness = base::Days(3);
75 UsePolicy(policy);
76
77 if (GetParam())
78 store_ = std::make_unique<MockPersistentReportingStore>();
79
80 UseStore(store_.get());
81
82 context()->AddCacheObserver(&observer_);
83 }
84
~ReportingCacheTest()85 ~ReportingCacheTest() override { context()->RemoveCacheObserver(&observer_); }
86
LoadReportingClients()87 void LoadReportingClients() {
88 // All ReportingCache methods assume that the store has been initialized.
89 if (store()) {
90 store()->LoadReportingClients(
91 base::BindOnce(&ReportingCache::AddClientsLoadedFromStore,
92 base::Unretained(cache())));
93 store()->FinishLoading(true);
94 }
95 }
96
observer()97 TestReportingCacheObserver* observer() { return &observer_; }
98
report_count()99 size_t report_count() {
100 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
101 cache()->GetReports(&reports);
102 return reports.size();
103 }
104
store()105 MockPersistentReportingStore* store() { return store_.get(); }
106
107 // Adds a new report to the cache, and returns it.
AddAndReturnReport(const NetworkAnonymizationKey & network_anonymization_key,const GURL & url,const std::string & user_agent,const std::string & group,const std::string & type,base::Value::Dict body,int depth,base::TimeTicks queued,int attempts)108 const ReportingReport* AddAndReturnReport(
109 const NetworkAnonymizationKey& network_anonymization_key,
110 const GURL& url,
111 const std::string& user_agent,
112 const std::string& group,
113 const std::string& type,
114 base::Value::Dict body,
115 int depth,
116 base::TimeTicks queued,
117 int attempts) {
118 const base::Value::Dict body_clone(body.Clone());
119
120 // The public API will only give us the (unordered) full list of reports in
121 // the cache. So we need to grab the list before we add, and the list after
122 // we add, and return the one element that's different. This is only used
123 // in test cases, so I've optimized for readability over execution speed.
124 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> before;
125 cache()->GetReports(&before);
126 cache()->AddReport(std::nullopt, network_anonymization_key, url, user_agent,
127 group, type, std::move(body), depth, queued, attempts);
128 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> after;
129 cache()->GetReports(&after);
130
131 for (const ReportingReport* report : after) {
132 // If report isn't in before, we've found the new instance.
133 if (!base::Contains(before, report)) {
134 EXPECT_EQ(network_anonymization_key, report->network_anonymization_key);
135 EXPECT_EQ(url, report->url);
136 EXPECT_EQ(user_agent, report->user_agent);
137 EXPECT_EQ(group, report->group);
138 EXPECT_EQ(type, report->type);
139 EXPECT_EQ(body_clone, report->body);
140 EXPECT_EQ(depth, report->depth);
141 EXPECT_EQ(queued, report->queued);
142 EXPECT_EQ(attempts, report->attempts);
143 return report;
144 }
145 }
146
147 // This can actually happen! If the newly created report isn't in the after
148 // vector, that means that we had to evict a report, and the new report was
149 // the only one eligible for eviction!
150 return nullptr;
151 }
152
153 // Creates a new endpoint group by way of adding two endpoints.
CreateGroupAndEndpoints(const ReportingEndpointGroupKey & group)154 void CreateGroupAndEndpoints(const ReportingEndpointGroupKey& group) {
155 EXPECT_FALSE(EndpointGroupExistsInCache(group, OriginSubdomains::DEFAULT));
156 ASSERT_TRUE(SetEndpointInCache(group, kEndpoint1_, kExpires1_));
157 ASSERT_TRUE(SetEndpointInCache(group, kEndpoint2_, kExpires1_));
158 }
159
160 // If |exist| is true, expect that the given group exists and has two
161 // endpoints, and its client exists. If |exist| is false, expect that the
162 // group and its endpoints don't exist (does not check the client in that
163 // case).
ExpectExistence(const ReportingEndpointGroupKey & group,bool exist)164 void ExpectExistence(const ReportingEndpointGroupKey& group, bool exist) {
165 ReportingEndpoint endpoint1 = FindEndpointInCache(group, kEndpoint1_);
166 ReportingEndpoint endpoint2 = FindEndpointInCache(group, kEndpoint2_);
167 EXPECT_EQ(exist, endpoint1.is_valid());
168 EXPECT_EQ(exist, endpoint2.is_valid());
169 if (exist) {
170 EXPECT_EQ(endpoint1.group_key, group);
171 EXPECT_EQ(endpoint2.group_key, group);
172 EXPECT_TRUE(cache()->ClientExistsForTesting(
173 group.network_anonymization_key, group.origin));
174 }
175 EXPECT_EQ(exist,
176 EndpointGroupExistsInCache(group, OriginSubdomains::DEFAULT));
177 }
178
179 base::test::ScopedFeatureList feature_list_;
180
181 const GURL kUrl1_ = GURL("https://origin1/path");
182 const GURL kUrl2_ = GURL("https://origin2/path");
183 const url::Origin kOrigin1_ = url::Origin::Create(GURL("https://origin1/"));
184 const url::Origin kOrigin2_ = url::Origin::Create(GURL("https://origin2/"));
185 const std::optional<base::UnguessableToken> kReportingSource_ =
186 base::UnguessableToken::Create();
187 const NetworkAnonymizationKey kNak_;
188 const NetworkAnonymizationKey kOtherNak_ =
189 NetworkAnonymizationKey::CreateCrossSite(SchemefulSite(kOrigin1_));
190 const IsolationInfo kIsolationInfo1_ =
191 IsolationInfo::Create(IsolationInfo::RequestType::kOther,
192 kOrigin1_,
193 kOrigin1_,
194 SiteForCookies::FromOrigin(kOrigin1_));
195 const IsolationInfo kIsolationInfo2_ =
196 IsolationInfo::Create(IsolationInfo::RequestType::kOther,
197 kOrigin2_,
198 kOrigin2_,
199 SiteForCookies::FromOrigin(kOrigin2_));
200 const GURL kEndpoint1_ = GURL("https://endpoint1/");
201 const GURL kEndpoint2_ = GURL("https://endpoint2/");
202 const GURL kEndpoint3_ = GURL("https://endpoint3/");
203 const GURL kEndpoint4_ = GURL("https://endpoint4/");
204 const std::string kUserAgent_ = "Mozilla/1.0";
205 const std::string kGroup1_ = "group1";
206 const std::string kGroup2_ = "group2";
207 const std::string kType_ = "default";
208 const base::TimeTicks kNowTicks_ = tick_clock()->NowTicks();
209 const base::Time kNow_ = clock()->Now();
210 const base::Time kExpires1_ = kNow_ + base::Days(7);
211 const base::Time kExpires2_ = kExpires1_ + base::Days(7);
212 // There are 2^3 = 8 of these to test the different combinations of matching
213 // vs mismatching NAK, origin, and group.
214 const ReportingEndpointGroupKey kGroupKey11_ =
215 ReportingEndpointGroupKey(kNak_, kOrigin1_, kGroup1_);
216 const ReportingEndpointGroupKey kGroupKey21_ =
217 ReportingEndpointGroupKey(kNak_, kOrigin2_, kGroup1_);
218 const ReportingEndpointGroupKey kGroupKey12_ =
219 ReportingEndpointGroupKey(kNak_, kOrigin1_, kGroup2_);
220 const ReportingEndpointGroupKey kGroupKey22_ =
221 ReportingEndpointGroupKey(kNak_, kOrigin2_, kGroup2_);
222 const ReportingEndpointGroupKey kOtherGroupKey11_ =
223 ReportingEndpointGroupKey(kOtherNak_, kOrigin1_, kGroup1_);
224 const ReportingEndpointGroupKey kOtherGroupKey21_ =
225 ReportingEndpointGroupKey(kOtherNak_, kOrigin2_, kGroup1_);
226 const ReportingEndpointGroupKey kOtherGroupKey12_ =
227 ReportingEndpointGroupKey(kOtherNak_, kOrigin1_, kGroup2_);
228 const ReportingEndpointGroupKey kOtherGroupKey22_ =
229 ReportingEndpointGroupKey(kOtherNak_, kOrigin2_, kGroup2_);
230
231 TestReportingCacheObserver observer_;
232 std::unique_ptr<MockPersistentReportingStore> store_;
233 };
234
235 // Note: These tests exercise both sides of the cache (reports and clients),
236 // aside from header parsing (i.e. OnParsedHeader(), AddOrUpdate*(),
237 // Remove*OtherThan() methods) which are exercised in the unittests for the
238 // header parser.
239
TEST_P(ReportingCacheTest,Reports)240 TEST_P(ReportingCacheTest, Reports) {
241 LoadReportingClients();
242
243 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
244 cache()->GetReports(&reports);
245 EXPECT_TRUE(reports.empty());
246
247 cache()->AddReport(kReportingSource_, kNak_, kUrl1_, kUserAgent_, kGroup1_,
248 kType_, base::Value::Dict(), 0, kNowTicks_, 0);
249 EXPECT_EQ(1, observer()->cached_reports_update_count());
250
251 cache()->GetReports(&reports);
252 ASSERT_EQ(1u, reports.size());
253 const ReportingReport* report = reports[0];
254 ASSERT_TRUE(report);
255 EXPECT_EQ(kNak_, report->network_anonymization_key);
256 EXPECT_EQ(kUrl1_, report->url);
257 EXPECT_EQ(kUserAgent_, report->user_agent);
258 EXPECT_EQ(kGroup1_, report->group);
259 EXPECT_EQ(kType_, report->type);
260 // TODO(juliatuttle): Check body?
261 EXPECT_EQ(kNowTicks_, report->queued);
262 EXPECT_EQ(0, report->attempts);
263 EXPECT_FALSE(cache()->IsReportPendingForTesting(report));
264 EXPECT_FALSE(cache()->IsReportDoomedForTesting(report));
265
266 cache()->IncrementReportsAttempts(reports);
267 EXPECT_EQ(2, observer()->cached_reports_update_count());
268
269 cache()->GetReports(&reports);
270 ASSERT_EQ(1u, reports.size());
271 report = reports[0];
272 ASSERT_TRUE(report);
273 EXPECT_EQ(1, report->attempts);
274
275 cache()->RemoveReports(reports);
276 EXPECT_EQ(3, observer()->cached_reports_update_count());
277
278 cache()->GetReports(&reports);
279 EXPECT_TRUE(reports.empty());
280 }
281
TEST_P(ReportingCacheTest,RemoveAllReports)282 TEST_P(ReportingCacheTest, RemoveAllReports) {
283 LoadReportingClients();
284
285 cache()->AddReport(kReportingSource_, kNak_, kUrl1_, kUserAgent_, kGroup1_,
286 kType_, base::Value::Dict(), 0, kNowTicks_, 0);
287 cache()->AddReport(kReportingSource_, kNak_, kUrl1_, kUserAgent_, kGroup1_,
288 kType_, base::Value::Dict(), 0, kNowTicks_, 0);
289 EXPECT_EQ(2, observer()->cached_reports_update_count());
290
291 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
292 cache()->GetReports(&reports);
293 EXPECT_EQ(2u, reports.size());
294
295 cache()->RemoveAllReports();
296 EXPECT_EQ(3, observer()->cached_reports_update_count());
297
298 cache()->GetReports(&reports);
299 EXPECT_TRUE(reports.empty());
300 }
301
TEST_P(ReportingCacheTest,RemovePendingReports)302 TEST_P(ReportingCacheTest, RemovePendingReports) {
303 LoadReportingClients();
304
305 cache()->AddReport(kReportingSource_, kNak_, kUrl1_, kUserAgent_, kGroup1_,
306 kType_, base::Value::Dict(), 0, kNowTicks_, 0);
307 EXPECT_EQ(1, observer()->cached_reports_update_count());
308
309 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
310 cache()->GetReports(&reports);
311 ASSERT_EQ(1u, reports.size());
312 EXPECT_FALSE(cache()->IsReportPendingForTesting(reports[0]));
313 EXPECT_FALSE(cache()->IsReportDoomedForTesting(reports[0]));
314
315 EXPECT_EQ(reports, cache()->GetReportsToDeliver());
316 EXPECT_TRUE(cache()->IsReportPendingForTesting(reports[0]));
317 EXPECT_FALSE(cache()->IsReportDoomedForTesting(reports[0]));
318
319 // After getting reports to deliver, everything in the cache should be
320 // pending, so another call to GetReportsToDeliver should return nothing.
321 EXPECT_EQ(0u, cache()->GetReportsToDeliver().size());
322
323 cache()->RemoveReports(reports);
324 EXPECT_TRUE(cache()->IsReportPendingForTesting(reports[0]));
325 EXPECT_TRUE(cache()->IsReportDoomedForTesting(reports[0]));
326 EXPECT_EQ(2, observer()->cached_reports_update_count());
327
328 // After removing report, future calls to GetReports should not return it.
329 std::vector<raw_ptr<const ReportingReport, VectorExperimental>>
330 visible_reports;
331 cache()->GetReports(&visible_reports);
332 EXPECT_TRUE(visible_reports.empty());
333 EXPECT_EQ(1u, cache()->GetFullReportCountForTesting());
334
335 // After clearing pending flag, report should be deleted.
336 cache()->ClearReportsPending(reports);
337 EXPECT_EQ(0u, cache()->GetFullReportCountForTesting());
338 }
339
TEST_P(ReportingCacheTest,RemoveAllPendingReports)340 TEST_P(ReportingCacheTest, RemoveAllPendingReports) {
341 LoadReportingClients();
342
343 cache()->AddReport(kReportingSource_, kNak_, kUrl1_, kUserAgent_, kGroup1_,
344 kType_, base::Value::Dict(), 0, kNowTicks_, 0);
345 EXPECT_EQ(1, observer()->cached_reports_update_count());
346
347 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
348 cache()->GetReports(&reports);
349 ASSERT_EQ(1u, reports.size());
350 EXPECT_FALSE(cache()->IsReportPendingForTesting(reports[0]));
351 EXPECT_FALSE(cache()->IsReportDoomedForTesting(reports[0]));
352
353 EXPECT_EQ(reports, cache()->GetReportsToDeliver());
354 EXPECT_TRUE(cache()->IsReportPendingForTesting(reports[0]));
355 EXPECT_FALSE(cache()->IsReportDoomedForTesting(reports[0]));
356
357 // After getting reports to deliver, everything in the cache should be
358 // pending, so another call to GetReportsToDeliver should return nothing.
359 EXPECT_EQ(0u, cache()->GetReportsToDeliver().size());
360
361 cache()->RemoveAllReports();
362 EXPECT_TRUE(cache()->IsReportPendingForTesting(reports[0]));
363 EXPECT_TRUE(cache()->IsReportDoomedForTesting(reports[0]));
364 EXPECT_EQ(2, observer()->cached_reports_update_count());
365
366 // After removing report, future calls to GetReports should not return it.
367 std::vector<raw_ptr<const ReportingReport, VectorExperimental>>
368 visible_reports;
369 cache()->GetReports(&visible_reports);
370 EXPECT_TRUE(visible_reports.empty());
371 EXPECT_EQ(1u, cache()->GetFullReportCountForTesting());
372
373 // After clearing pending flag, report should be deleted.
374 cache()->ClearReportsPending(reports);
375 EXPECT_EQ(0u, cache()->GetFullReportCountForTesting());
376 }
377
TEST_P(ReportingCacheTest,GetReportsAsValue)378 TEST_P(ReportingCacheTest, GetReportsAsValue) {
379 LoadReportingClients();
380
381 // We need a reproducible expiry timestamp for this test case.
382 const base::TimeTicks now = base::TimeTicks();
383 const ReportingReport* report1 =
384 AddAndReturnReport(kNak_, kUrl1_, kUserAgent_, kGroup1_, kType_,
385 base::Value::Dict(), 0, now + base::Seconds(200), 0);
386 const ReportingReport* report2 =
387 AddAndReturnReport(kOtherNak_, kUrl1_, kUserAgent_, kGroup2_, kType_,
388 base::Value::Dict(), 0, now + base::Seconds(100), 1);
389 // Mark report1 and report2 as pending.
390 EXPECT_THAT(cache()->GetReportsToDeliver(),
391 ::testing::UnorderedElementsAre(report1, report2));
392 // Mark report2 as doomed.
393 cache()->RemoveReports({report2});
394
395 base::Value actual = cache()->GetReportsAsValue();
396 base::Value expected = base::test::ParseJson(base::StringPrintf(
397 R"json(
398 [
399 {
400 "url": "https://origin1/path",
401 "group": "group2",
402 "network_anonymization_key": "%s",
403 "type": "default",
404 "status": "doomed",
405 "body": {},
406 "attempts": 1,
407 "depth": 0,
408 "queued": "100000",
409 },
410 {
411 "url": "https://origin1/path",
412 "group": "group1",
413 "network_anonymization_key": "%s",
414 "type": "default",
415 "status": "pending",
416 "body": {},
417 "attempts": 0,
418 "depth": 0,
419 "queued": "200000",
420 },
421 ]
422 )json",
423 kOtherNak_.ToDebugString().c_str(), kNak_.ToDebugString().c_str()));
424 EXPECT_EQ(expected, actual);
425
426 // Add two new reports that will show up as "queued".
427 const ReportingReport* report3 =
428 AddAndReturnReport(kNak_, kUrl2_, kUserAgent_, kGroup1_, kType_,
429 base::Value::Dict(), 2, now + base::Seconds(200), 0);
430 const ReportingReport* report4 =
431 AddAndReturnReport(kOtherNak_, kUrl1_, kUserAgent_, kGroup1_, kType_,
432 base::Value::Dict(), 0, now + base::Seconds(300), 0);
433 actual = cache()->GetReportsAsValue();
434 expected = base::test::ParseJson(base::StringPrintf(
435 R"json(
436 [
437 {
438 "url": "https://origin1/path",
439 "group": "group2",
440 "network_anonymization_key": "%s",
441 "type": "default",
442 "status": "doomed",
443 "body": {},
444 "attempts": 1,
445 "depth": 0,
446 "queued": "100000",
447 },
448 {
449 "url": "https://origin1/path",
450 "group": "group1",
451 "network_anonymization_key": "%s",
452 "type": "default",
453 "status": "pending",
454 "body": {},
455 "attempts": 0,
456 "depth": 0,
457 "queued": "200000",
458 },
459 {
460 "url": "https://origin2/path",
461 "group": "group1",
462 "network_anonymization_key": "%s",
463 "type": "default",
464 "status": "queued",
465 "body": {},
466 "attempts": 0,
467 "depth": 2,
468 "queued": "200000",
469 },
470 {
471 "url": "https://origin1/path",
472 "group": "group1",
473 "network_anonymization_key": "%s",
474 "type": "default",
475 "status": "queued",
476 "body": {},
477 "attempts": 0,
478 "depth": 0,
479 "queued": "300000",
480 },
481 ]
482 )json",
483 kOtherNak_.ToDebugString().c_str(), kNak_.ToDebugString().c_str(),
484 kNak_.ToDebugString().c_str(), kOtherNak_.ToDebugString().c_str()));
485 EXPECT_EQ(expected, actual);
486
487 // GetReportsToDeliver only returns the non-pending reports.
488 EXPECT_THAT(cache()->GetReportsToDeliver(),
489 ::testing::UnorderedElementsAre(report3, report4));
490 }
491
TEST_P(ReportingCacheTest,GetReportsToDeliverForSource)492 TEST_P(ReportingCacheTest, GetReportsToDeliverForSource) {
493 LoadReportingClients();
494
495 auto source1 = base::UnguessableToken::Create();
496 auto source2 = base::UnguessableToken::Create();
497
498 // Queue a V1 report for each of these sources, and a V0 report (with a null
499 // source) for the same URL.
500 cache()->AddReport(source1, kNak_, kUrl1_, kUserAgent_, kGroup1_, kType_,
501 base::Value::Dict(), 0, kNowTicks_, 0);
502 cache()->AddReport(source2, kNak_, kUrl1_, kUserAgent_, kGroup1_, kType_,
503 base::Value::Dict(), 0, kNowTicks_, 0);
504 cache()->AddReport(std::nullopt, kNak_, kUrl1_, kUserAgent_, kGroup1_, kType_,
505 base::Value::Dict(), 0, kNowTicks_, 0);
506 EXPECT_EQ(3, observer()->cached_reports_update_count());
507
508 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
509 cache()->GetReports(&reports);
510 ASSERT_EQ(3u, reports.size());
511
512 const auto report1 =
513 base::ranges::find(reports, source1, &ReportingReport::reporting_source);
514 DCHECK(report1 != reports.end());
515 const auto report2 =
516 base::ranges::find(reports, source2, &ReportingReport::reporting_source);
517 DCHECK(report2 != reports.end());
518 const auto report3 = base::ranges::find(reports, std::nullopt,
519 &ReportingReport::reporting_source);
520 DCHECK(report3 != reports.end());
521
522 // Get the reports for Source 1 and check the status of all reports.
523 EXPECT_EQ((std::vector<raw_ptr<const ReportingReport, VectorExperimental>>{
524 *report1}),
525 cache()->GetReportsToDeliverForSource(source1));
526 EXPECT_TRUE(cache()->IsReportPendingForTesting(*report1));
527 EXPECT_FALSE(cache()->IsReportDoomedForTesting(*report1));
528 EXPECT_FALSE(cache()->IsReportPendingForTesting(*report2));
529 EXPECT_FALSE(cache()->IsReportDoomedForTesting(*report2));
530 EXPECT_FALSE(cache()->IsReportPendingForTesting(*report3));
531 EXPECT_FALSE(cache()->IsReportDoomedForTesting(*report3));
532
533 // There should be one pending and two cached reports at this point.
534 EXPECT_EQ(1u, cache()->GetReportCountWithStatusForTesting(
535 ReportingReport::Status::PENDING));
536 EXPECT_EQ(2u, cache()->GetReportCountWithStatusForTesting(
537 ReportingReport::Status::QUEUED));
538
539 // Calling the method again should not retrieve any more reports, and should
540 // not change the status of any other reports in the cache.
541 EXPECT_EQ(0u, cache()->GetReportsToDeliverForSource(source1).size());
542 EXPECT_EQ(1u, cache()->GetReportCountWithStatusForTesting(
543 ReportingReport::Status::PENDING));
544 EXPECT_EQ(2u, cache()->GetReportCountWithStatusForTesting(
545 ReportingReport::Status::QUEUED));
546
547 // Get the reports for Source 2 and check the status again.
548 EXPECT_EQ((std::vector<raw_ptr<const ReportingReport, VectorExperimental>>{
549 *report2}),
550 cache()->GetReportsToDeliverForSource(source2));
551 EXPECT_TRUE(cache()->IsReportPendingForTesting(*report1));
552 EXPECT_FALSE(cache()->IsReportDoomedForTesting(*report1));
553 EXPECT_TRUE(cache()->IsReportPendingForTesting(*report2));
554 EXPECT_FALSE(cache()->IsReportDoomedForTesting(*report2));
555 EXPECT_FALSE(cache()->IsReportPendingForTesting(*report3));
556 EXPECT_FALSE(cache()->IsReportDoomedForTesting(*report3));
557
558 EXPECT_EQ(2u, cache()->GetReportCountWithStatusForTesting(
559 ReportingReport::Status::PENDING));
560 EXPECT_EQ(1u, cache()->GetReportCountWithStatusForTesting(
561 ReportingReport::Status::QUEUED));
562 }
563
564 TEST_P(ReportingCacheTest, Endpoints) {
565 LoadReportingClients();
566
567 EXPECT_EQ(0u, cache()->GetEndpointCount());
568 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, kEndpoint1_, kExpires1_));
569 EXPECT_EQ(1u, cache()->GetEndpointCount());
570
571 const ReportingEndpoint endpoint1 =
572 FindEndpointInCache(kGroupKey11_, kEndpoint1_);
573 ASSERT_TRUE(endpoint1);
574 EXPECT_EQ(kOrigin1_, endpoint1.group_key.origin);
575 EXPECT_EQ(kEndpoint1_, endpoint1.info.url);
576 EXPECT_EQ(kGroup1_, endpoint1.group_key.group_name);
577
578 EXPECT_TRUE(EndpointGroupExistsInCache(
579 kGroupKey11_, OriginSubdomains::DEFAULT, kExpires1_));
580
581 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin1_));
582
583 // Insert another endpoint in the same group.
584 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, kEndpoint2_, kExpires1_));
585 EXPECT_EQ(2u, cache()->GetEndpointCount());
586
587 const ReportingEndpoint endpoint2 =
588 FindEndpointInCache(kGroupKey11_, kEndpoint2_);
589 ASSERT_TRUE(endpoint2);
590 EXPECT_EQ(kOrigin1_, endpoint2.group_key.origin);
591 EXPECT_EQ(kEndpoint2_, endpoint2.info.url);
592 EXPECT_EQ(kGroup1_, endpoint2.group_key.group_name);
593
594 EXPECT_TRUE(EndpointGroupExistsInCache(
595 kGroupKey11_, OriginSubdomains::DEFAULT, kExpires1_));
596 EXPECT_EQ(1u, cache()->GetEndpointGroupCountForTesting());
597
598 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin1_));
599 std::set<url::Origin> origins_in_cache = cache()->GetAllOrigins();
600 EXPECT_EQ(1u, origins_in_cache.size());
601
602 // Insert another endpoint for a different origin with same group name.
603 ASSERT_TRUE(SetEndpointInCache(kGroupKey21_, kEndpoint2_, kExpires1_));
604 EXPECT_EQ(3u, cache()->GetEndpointCount());
605
606 const ReportingEndpoint endpoint3 =
607 FindEndpointInCache(kGroupKey21_, kEndpoint2_);
608 ASSERT_TRUE(endpoint3);
609 EXPECT_EQ(kOrigin2_, endpoint3.group_key.origin);
610 EXPECT_EQ(kEndpoint2_, endpoint3.info.url);
611 EXPECT_EQ(kGroup1_, endpoint3.group_key.group_name);
612
613 EXPECT_TRUE(EndpointGroupExistsInCache(
614 kGroupKey21_, OriginSubdomains::DEFAULT, kExpires1_));
615 EXPECT_EQ(2u, cache()->GetEndpointGroupCountForTesting());
616
617 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin2_));
618 origins_in_cache = cache()->GetAllOrigins();
619 EXPECT_EQ(2u, origins_in_cache.size());
620 }
621
622 TEST_P(ReportingCacheTest, ClientsKeyedByEndpointGroupKey) {
623 // Raise the endpoint limits for this test.
624 // (This needs to first remove the cache observer because this destroys the
625 // old ReportingContext, which must not have any observers upon destruction.)
626 context()->RemoveCacheObserver(&observer_);
627 ReportingPolicy policy;
628 policy.max_endpoints_per_origin = 5; // This test should use 4.
629 policy.max_endpoint_count = 20; // This test should use 16.
630 UsePolicy(policy);
631 context()->AddCacheObserver(&observer_);
632
633 LoadReportingClients();
634
635 const ReportingEndpointGroupKey kGroupKeys[] = {
636 kGroupKey11_, kGroupKey12_, kGroupKey21_,
637 kGroupKey22_, kOtherGroupKey11_, kOtherGroupKey12_,
638 kOtherGroupKey21_, kOtherGroupKey22_,
639 };
640
641 size_t endpoint_group_count = 0u;
642 size_t endpoint_count = 0u;
643
644 // Check that the group keys are all considered distinct, and nothing is
645 // overwritten.
646 for (const auto& group : kGroupKeys) {
647 CreateGroupAndEndpoints(group);
648 ExpectExistence(group, true);
649 ++endpoint_group_count;
650 EXPECT_EQ(endpoint_group_count, cache()->GetEndpointGroupCountForTesting());
651 endpoint_count += 2u;
652 EXPECT_EQ(endpoint_count, cache()->GetEndpointCount());
653 }
654
655 // Check that everything is there at the end.
656 for (const auto& group : kGroupKeys) {
657 ExpectExistence(group, true);
658 }
659
660 size_t client_count = 4u;
661 EXPECT_EQ(client_count, cache()->GetClientCountForTesting());
662
663 // Test that Clients with different NAKs are considered different, and test
664 // RemoveEndpointGroup() and RemoveClient().
665 const std::pair<NetworkAnonymizationKey, url::Origin> kNakOriginPairs[] = {
666 {kNak_, kOrigin1_},
667 {kNak_, kOrigin2_},
668 {kOtherNak_, kOrigin1_},
669 {kOtherNak_, kOrigin2_},
670 };
671
672 // SetEndpointInCache doesn't update store counts, which is why we start from
673 // zero and they go negative.
674 // TODO(crbug.com/895821): Populate the cache via the store so we don't
675 // need negative counts.
676 MockPersistentReportingStore::CommandList expected_commands;
677 int stored_group_count = 0;
678 int stored_endpoint_count = 0;
679 int store_remove_group_count = 0;
680 int store_remove_endpoint_count = 0;
681
682 for (const auto& pair : kNakOriginPairs) {
683 EXPECT_TRUE(cache()->ClientExistsForTesting(pair.first, pair.second));
684 ReportingEndpointGroupKey group1(pair.first, pair.second, kGroup1_);
685 ReportingEndpointGroupKey group2(pair.first, pair.second, kGroup2_);
686 ExpectExistence(group1, true);
687 ExpectExistence(group2, true);
688
689 cache()->RemoveEndpointGroup(group1);
690 ExpectExistence(group1, false);
691 ExpectExistence(group2, true);
692 EXPECT_TRUE(cache()->ClientExistsForTesting(pair.first, pair.second));
693
694 cache()->RemoveClient(pair.first, pair.second);
695 ExpectExistence(group1, false);
696 ExpectExistence(group2, false);
697 EXPECT_FALSE(cache()->ClientExistsForTesting(pair.first, pair.second));
698
699 --client_count;
700 EXPECT_EQ(client_count, cache()->GetClientCountForTesting());
701 endpoint_group_count -= 2u;
702 stored_group_count -= 2;
703 EXPECT_EQ(endpoint_group_count, cache()->GetEndpointGroupCountForTesting());
704 endpoint_count -= 4u;
705 stored_endpoint_count -= 4;
706 EXPECT_EQ(endpoint_count, cache()->GetEndpointCount());
707
708 if (store()) {
709 store()->Flush();
710 EXPECT_EQ(stored_endpoint_count, store()->StoredEndpointsCount());
711 EXPECT_EQ(stored_group_count, store()->StoredEndpointGroupsCount());
712 store_remove_group_count += 2u;
713 expected_commands.emplace_back(
714 CommandType::DELETE_REPORTING_ENDPOINT_GROUP, group1);
715 expected_commands.emplace_back(
716 CommandType::DELETE_REPORTING_ENDPOINT_GROUP, group2);
717 store_remove_endpoint_count += 4u;
718 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
719 group1, kEndpoint1_);
720 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
721 group1, kEndpoint2_);
722 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
723 group2, kEndpoint1_);
724 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
725 group2, kEndpoint2_);
726 EXPECT_EQ(
727 store_remove_group_count,
728 store()->CountCommands(CommandType::DELETE_REPORTING_ENDPOINT_GROUP));
729 EXPECT_EQ(store_remove_endpoint_count,
730 store()->CountCommands(CommandType::DELETE_REPORTING_ENDPOINT));
731 EXPECT_THAT(store()->GetAllCommands(),
732 testing::IsSupersetOf(expected_commands));
733 }
734 }
735 }
736
737 TEST_P(ReportingCacheTest, RemoveClientsForOrigin) {
738 LoadReportingClients();
739
740 // Origin 1
741 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, kEndpoint1_, kExpires1_));
742 ASSERT_TRUE(SetEndpointInCache(kOtherGroupKey11_, kEndpoint1_, kExpires1_));
743 ASSERT_TRUE(SetEndpointInCache(kOtherGroupKey12_, kEndpoint1_, kExpires1_));
744 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin1_));
745 // Origin 2
746 ASSERT_TRUE(SetEndpointInCache(kGroupKey21_, kEndpoint1_, kExpires1_));
747 ASSERT_TRUE(SetEndpointInCache(kOtherGroupKey22_, kEndpoint2_, kExpires1_));
748 ASSERT_TRUE(ClientExistsInCacheForOrigin(kOrigin2_));
749
750 EXPECT_EQ(5u, cache()->GetEndpointCount());
751
752 cache()->RemoveClientsForOrigin(kOrigin1_);
753
754 EXPECT_EQ(2u, cache()->GetEndpointCount());
755 EXPECT_FALSE(ClientExistsInCacheForOrigin(kOrigin1_));
756 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin2_));
757
758 if (store()) {
759 store()->Flush();
760 // SetEndpointInCache doesn't update store counts, which is why they go
761 // negative here.
762 // TODO(crbug.com/895821): Populate the cache via the store so we don't need
763 // negative counts.
764 EXPECT_EQ(-3, store()->StoredEndpointsCount());
765 EXPECT_EQ(-3, store()->StoredEndpointGroupsCount());
766 MockPersistentReportingStore::CommandList expected_commands;
767 EXPECT_EQ(3,
768 store()->CountCommands(CommandType::DELETE_REPORTING_ENDPOINT));
769 EXPECT_EQ(3, store()->CountCommands(
770 CommandType::DELETE_REPORTING_ENDPOINT_GROUP));
771 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT_GROUP,
772 kGroupKey11_);
773 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT_GROUP,
774 kOtherGroupKey11_);
775 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT_GROUP,
776 kOtherGroupKey12_);
777 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
778 kGroupKey11_, kEndpoint1_);
779 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
780 kOtherGroupKey11_, kEndpoint1_);
781 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
782 kOtherGroupKey12_, kEndpoint1_);
783 EXPECT_THAT(store()->GetAllCommands(),
784 testing::IsSupersetOf(expected_commands));
785 }
786 }
787
788 TEST_P(ReportingCacheTest, RemoveAllClients) {
789 LoadReportingClients();
790
791 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, kEndpoint1_, kExpires1_));
792 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, kEndpoint2_, kExpires1_));
793 ASSERT_TRUE(SetEndpointInCache(kGroupKey21_, kEndpoint1_, kExpires1_));
794 ASSERT_TRUE(SetEndpointInCache(kGroupKey22_, kEndpoint2_, kExpires1_));
795 EXPECT_EQ(4u, cache()->GetEndpointCount());
796 ASSERT_TRUE(ClientExistsInCacheForOrigin(kOrigin1_));
797 ASSERT_TRUE(ClientExistsInCacheForOrigin(kOrigin2_));
798
799 cache()->RemoveAllClients();
800
801 EXPECT_EQ(0u, cache()->GetEndpointCount());
802 EXPECT_FALSE(ClientExistsInCacheForOrigin(kOrigin1_));
803 EXPECT_FALSE(ClientExistsInCacheForOrigin(kOrigin2_));
804
805 if (store()) {
806 store()->Flush();
807 // SetEndpointInCache doesn't update store counts, which is why they go
808 // negative here.
809 // TODO(crbug.com/895821): Populate the cache via the store so we don't need
810 // negative counts.
811 EXPECT_EQ(-4, store()->StoredEndpointsCount());
812 EXPECT_EQ(-3, store()->StoredEndpointGroupsCount());
813 MockPersistentReportingStore::CommandList expected_commands;
814 EXPECT_EQ(4,
815 store()->CountCommands(CommandType::DELETE_REPORTING_ENDPOINT));
816 EXPECT_EQ(3, store()->CountCommands(
817 CommandType::DELETE_REPORTING_ENDPOINT_GROUP));
818 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
819 kGroupKey11_, kEndpoint1_);
820 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
821 kGroupKey11_, kEndpoint2_);
822 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
823 kGroupKey21_, kEndpoint1_);
824 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
825 kGroupKey22_, kEndpoint2_);
826 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT_GROUP,
827 kGroupKey11_);
828 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT_GROUP,
829 kGroupKey21_);
830 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT_GROUP,
831 kGroupKey22_);
832 EXPECT_THAT(store()->GetAllCommands(),
833 testing::IsSupersetOf(expected_commands));
834 }
835 }
836
837 TEST_P(ReportingCacheTest, RemoveEndpointGroup) {
838 LoadReportingClients();
839
840 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, kEndpoint1_, kExpires1_));
841 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, kEndpoint2_, kExpires1_));
842 ASSERT_TRUE(SetEndpointInCache(kGroupKey21_, kEndpoint1_, kExpires1_));
843 ASSERT_TRUE(SetEndpointInCache(kGroupKey22_, kEndpoint2_, kExpires1_));
844 EXPECT_EQ(4u, cache()->GetEndpointCount());
845 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin1_));
846 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin2_));
847 EXPECT_TRUE(EndpointGroupExistsInCache(
848 kGroupKey11_, OriginSubdomains::DEFAULT, kExpires1_));
849 EXPECT_TRUE(EndpointGroupExistsInCache(
850 kGroupKey21_, OriginSubdomains::DEFAULT, kExpires1_));
851 EXPECT_TRUE(EndpointGroupExistsInCache(
852 kGroupKey22_, OriginSubdomains::DEFAULT, kExpires1_));
853
854 cache()->RemoveEndpointGroup(kGroupKey21_);
855 EXPECT_TRUE(EndpointGroupExistsInCache(
856 kGroupKey11_, OriginSubdomains::DEFAULT, kExpires1_));
857 EXPECT_FALSE(EndpointGroupExistsInCache(
858 kGroupKey21_, OriginSubdomains::DEFAULT, kExpires1_));
859 EXPECT_TRUE(EndpointGroupExistsInCache(
860 kGroupKey22_, OriginSubdomains::DEFAULT, kExpires1_));
861
862 cache()->RemoveEndpointGroup(kGroupKey22_);
863 EXPECT_FALSE(EndpointGroupExistsInCache(
864 kGroupKey22_, OriginSubdomains::DEFAULT, kExpires1_));
865 // Removal of the last group for an origin also removes the client.
866 EXPECT_FALSE(ClientExistsInCacheForOrigin(kOrigin2_));
867 // Other origins are not affected.
868 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin1_));
869 EXPECT_TRUE(EndpointGroupExistsInCache(
870 kGroupKey11_, OriginSubdomains::DEFAULT, kExpires1_));
871
872 if (store()) {
873 store()->Flush();
874 // SetEndpointInCache doesn't update store counts, which is why they go
875 // negative here.
876 // TODO(crbug.com/895821): Populate the cache via the store so we don't need
877 // negative counts.
878 EXPECT_EQ(-2, store()->StoredEndpointsCount());
879 EXPECT_EQ(-2, store()->StoredEndpointGroupsCount());
880 EXPECT_EQ(2,
881 store()->CountCommands(CommandType::DELETE_REPORTING_ENDPOINT));
882 EXPECT_EQ(2, store()->CountCommands(
883 CommandType::DELETE_REPORTING_ENDPOINT_GROUP));
884 MockPersistentReportingStore::CommandList expected_commands;
885 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
886 kGroupKey21_, kEndpoint1_);
887 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
888 kGroupKey22_, kEndpoint2_);
889 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT_GROUP,
890 kGroupKey21_);
891 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT_GROUP,
892 kGroupKey22_);
893 EXPECT_THAT(store()->GetAllCommands(),
894 testing::IsSupersetOf(expected_commands));
895 }
896 }
897
898 TEST_P(ReportingCacheTest, RemoveEndpointsForUrl) {
899 LoadReportingClients();
900
901 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, kEndpoint1_, kExpires1_));
902 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, kEndpoint2_, kExpires1_));
903 ASSERT_TRUE(SetEndpointInCache(kGroupKey21_, kEndpoint1_, kExpires1_));
904 ASSERT_TRUE(SetEndpointInCache(kGroupKey22_, kEndpoint2_, kExpires1_));
905 EXPECT_EQ(4u, cache()->GetEndpointCount());
906 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin1_));
907 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin2_));
908 EXPECT_TRUE(EndpointGroupExistsInCache(
909 kGroupKey11_, OriginSubdomains::DEFAULT, kExpires1_));
910 EXPECT_TRUE(EndpointGroupExistsInCache(
911 kGroupKey21_, OriginSubdomains::DEFAULT, kExpires1_));
912 EXPECT_TRUE(EndpointGroupExistsInCache(
913 kGroupKey22_, OriginSubdomains::DEFAULT, kExpires1_));
914
915 cache()->RemoveEndpointsForUrl(kEndpoint1_);
916 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin1_));
917 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin2_));
918 EXPECT_TRUE(EndpointGroupExistsInCache(
919 kGroupKey11_, OriginSubdomains::DEFAULT, kExpires1_));
920 EXPECT_FALSE(EndpointGroupExistsInCache(
921 kGroupKey21_, OriginSubdomains::DEFAULT, kExpires1_));
922 EXPECT_TRUE(EndpointGroupExistsInCache(
923 kGroupKey22_, OriginSubdomains::DEFAULT, kExpires1_));
924
925 EXPECT_EQ(2u, cache()->GetEndpointCount());
926 EXPECT_FALSE(FindEndpointInCache(kGroupKey11_, kEndpoint1_));
927 EXPECT_TRUE(FindEndpointInCache(kGroupKey11_, kEndpoint2_));
928 EXPECT_FALSE(FindEndpointInCache(kGroupKey21_, kEndpoint1_));
929 EXPECT_TRUE(FindEndpointInCache(kGroupKey22_, kEndpoint2_));
930
931 if (store()) {
932 store()->Flush();
933 // SetEndpointInCache doesn't update store counts, which is why they go
934 // negative here.
935 // TODO(crbug.com/895821): Populate the cache via the store so we don't need
936 // negative counts.
937 EXPECT_EQ(-2, store()->StoredEndpointsCount());
938 EXPECT_EQ(-1, store()->StoredEndpointGroupsCount());
939 EXPECT_EQ(2,
940 store()->CountCommands(CommandType::DELETE_REPORTING_ENDPOINT));
941 EXPECT_EQ(1, store()->CountCommands(
942 CommandType::DELETE_REPORTING_ENDPOINT_GROUP));
943 MockPersistentReportingStore::CommandList expected_commands;
944 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
945 kGroupKey11_, kEndpoint1_);
946 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
947 kGroupKey21_, kEndpoint1_);
948 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT_GROUP,
949 kGroupKey21_);
950 EXPECT_THAT(store()->GetAllCommands(),
951 testing::IsSupersetOf(expected_commands));
952 }
953 }
954
955 TEST_P(ReportingCacheTest, RemoveSourceAndEndpoints) {
956 const base::UnguessableToken reporting_source_2 =
957 base::UnguessableToken::Create();
958 LoadReportingClients();
959
960 NetworkAnonymizationKey network_anonymization_key_1 =
961 kIsolationInfo1_.network_anonymization_key();
962 NetworkAnonymizationKey network_anonymization_key_2 =
963 kIsolationInfo2_.network_anonymization_key();
964
965 cache()->SetV1EndpointForTesting(
966 ReportingEndpointGroupKey(network_anonymization_key_1, *kReportingSource_,
967 kOrigin1_, kGroup1_),
968 *kReportingSource_, kIsolationInfo1_, kUrl1_);
969 cache()->SetV1EndpointForTesting(
970 ReportingEndpointGroupKey(network_anonymization_key_1, *kReportingSource_,
971 kOrigin1_, kGroup2_),
972 *kReportingSource_, kIsolationInfo1_, kUrl2_);
973 cache()->SetV1EndpointForTesting(
974 ReportingEndpointGroupKey(network_anonymization_key_2, reporting_source_2,
975 kOrigin2_, kGroup1_),
976 reporting_source_2, kIsolationInfo2_, kUrl2_);
977
978 EXPECT_EQ(2u, cache()->GetReportingSourceCountForTesting());
979 EXPECT_TRUE(cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup1_));
980 EXPECT_TRUE(cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup2_));
981 EXPECT_TRUE(cache()->GetV1EndpointForTesting(reporting_source_2, kGroup1_));
982 EXPECT_FALSE(cache()->GetExpiredSources().contains(*kReportingSource_));
983 EXPECT_FALSE(cache()->GetExpiredSources().contains(reporting_source_2));
984
985 cache()->SetExpiredSource(*kReportingSource_);
986
987 EXPECT_EQ(2u, cache()->GetReportingSourceCountForTesting());
988 EXPECT_TRUE(cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup1_));
989 EXPECT_TRUE(cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup2_));
990 EXPECT_TRUE(cache()->GetV1EndpointForTesting(reporting_source_2, kGroup1_));
991 EXPECT_TRUE(cache()->GetExpiredSources().contains(*kReportingSource_));
992 EXPECT_FALSE(cache()->GetExpiredSources().contains(reporting_source_2));
993
994 cache()->RemoveSourceAndEndpoints(*kReportingSource_);
995
996 EXPECT_EQ(1u, cache()->GetReportingSourceCountForTesting());
997 EXPECT_FALSE(cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup1_));
998 EXPECT_FALSE(cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup2_));
999 EXPECT_TRUE(cache()->GetV1EndpointForTesting(reporting_source_2, kGroup1_));
1000 EXPECT_FALSE(cache()->GetExpiredSources().contains(*kReportingSource_));
1001 EXPECT_FALSE(cache()->GetExpiredSources().contains(reporting_source_2));
1002 }
1003
1004 TEST_P(ReportingCacheTest, GetClientsAsValue) {
1005 LoadReportingClients();
1006
1007 // These times are bogus but we need a reproducible expiry timestamp for this
1008 // test case.
1009 const base::TimeTicks expires_ticks = base::TimeTicks() + base::Days(7);
1010 const base::Time expires =
1011 base::Time::UnixEpoch() + (expires_ticks - base::TimeTicks::UnixEpoch());
1012 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, kEndpoint1_, expires,
1013 OriginSubdomains::EXCLUDE));
1014 ASSERT_TRUE(SetEndpointInCache(kOtherGroupKey21_, kEndpoint2_, expires,
1015 OriginSubdomains::INCLUDE));
1016
1017 cache()->IncrementEndpointDeliveries(kGroupKey11_, kEndpoint1_,
1018 /* reports */ 2, /* succeeded */ true);
1019 cache()->IncrementEndpointDeliveries(kOtherGroupKey21_, kEndpoint2_,
1020 /* reports */ 1, /* succeeded */ false);
1021
1022 base::Value actual = cache()->GetClientsAsValue();
1023 base::Value expected = base::test::ParseJson(base::StringPrintf(
1024 R"json(
1025 [
1026 {
1027 "network_anonymization_key": "%s",
1028 "origin": "https://origin1",
1029 "groups": [
1030 {
1031 "name": "group1",
1032 "expires": "604800000",
1033 "includeSubdomains": false,
1034 "endpoints": [
1035 {"url": "https://endpoint1/", "priority": 1, "weight": 1,
1036 "successful": {"uploads": 1, "reports": 2},
1037 "failed": {"uploads": 0, "reports": 0}},
1038 ],
1039 },
1040 ],
1041 },
1042 {
1043 "network_anonymization_key": "%s",
1044 "origin": "https://origin2",
1045 "groups": [
1046 {
1047 "name": "group1",
1048 "expires": "604800000",
1049 "includeSubdomains": true,
1050 "endpoints": [
1051 {"url": "https://endpoint2/", "priority": 1, "weight": 1,
1052 "successful": {"uploads": 0, "reports": 0},
1053 "failed": {"uploads": 1, "reports": 1}},
1054 ],
1055 },
1056 ],
1057 },
1058 ]
1059 )json",
1060 kNak_.ToDebugString().c_str(), kOtherNak_.ToDebugString().c_str()));
1061
1062 // Compare disregarding order.
1063 base::Value::List& expected_list = expected.GetList();
1064 base::Value::List& actual_list = actual.GetList();
1065 std::sort(expected_list.begin(), expected_list.end());
1066 std::sort(actual_list.begin(), actual_list.end());
1067 EXPECT_EQ(expected, actual);
1068 }
1069
TEST_P(ReportingCacheTest,GetCandidateEndpointsForDelivery)1070 TEST_P(ReportingCacheTest, GetCandidateEndpointsForDelivery) {
1071 LoadReportingClients();
1072
1073 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, kEndpoint1_, kExpires1_));
1074 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, kEndpoint2_, kExpires1_));
1075 ASSERT_TRUE(SetEndpointInCache(kGroupKey21_, kEndpoint1_, kExpires1_));
1076 ASSERT_TRUE(SetEndpointInCache(kGroupKey22_, kEndpoint2_, kExpires1_));
1077 std::vector<ReportingEndpoint> candidate_endpoints =
1078 cache()->GetCandidateEndpointsForDelivery(kGroupKey11_);
1079 ASSERT_EQ(2u, candidate_endpoints.size());
1080 EXPECT_EQ(kGroupKey11_, candidate_endpoints[0].group_key);
1081 EXPECT_EQ(kGroupKey11_, candidate_endpoints[1].group_key);
1082
1083 candidate_endpoints = cache()->GetCandidateEndpointsForDelivery(kGroupKey21_);
1084 ASSERT_EQ(1u, candidate_endpoints.size());
1085 EXPECT_EQ(kGroupKey21_, candidate_endpoints[0].group_key);
1086 }
1087
1088 TEST_P(ReportingCacheTest, GetCandidateEndpointsFromDocumentForDelivery) {
1089 const base::UnguessableToken reporting_source_1 =
1090 base::UnguessableToken::Create();
1091 const base::UnguessableToken reporting_source_2 =
1092 base::UnguessableToken::Create();
1093
1094 NetworkAnonymizationKey network_anonymization_key =
1095 kIsolationInfo1_.network_anonymization_key();
1096 const ReportingEndpointGroupKey document_group_key_1 =
1097 ReportingEndpointGroupKey(network_anonymization_key, reporting_source_1,
1098 kOrigin1_, kGroup1_);
1099 const ReportingEndpointGroupKey document_group_key_2 =
1100 ReportingEndpointGroupKey(network_anonymization_key, reporting_source_1,
1101 kOrigin1_, kGroup2_);
1102 const ReportingEndpointGroupKey document_group_key_3 =
1103 ReportingEndpointGroupKey(network_anonymization_key, reporting_source_2,
1104 kOrigin1_, kGroup1_);
1105
1106 SetV1EndpointInCache(document_group_key_1, reporting_source_1,
1107 kIsolationInfo1_, kEndpoint1_);
1108 SetV1EndpointInCache(document_group_key_2, reporting_source_1,
1109 kIsolationInfo1_, kEndpoint2_);
1110 SetV1EndpointInCache(document_group_key_3, reporting_source_2,
1111 kIsolationInfo1_, kEndpoint1_);
1112 const ReportingEndpointGroupKey kReportGroupKey = ReportingEndpointGroupKey(
1113 network_anonymization_key, reporting_source_1, kOrigin1_, kGroup1_);
1114 std::vector<ReportingEndpoint> candidate_endpoints =
1115 cache()->GetCandidateEndpointsForDelivery(kReportGroupKey);
1116 ASSERT_EQ(1u, candidate_endpoints.size());
1117 EXPECT_EQ(document_group_key_1, candidate_endpoints[0].group_key);
1118 }
1119
1120 // V1 reporting endpoints must not be returned in response to a request for
1121 // endpoints for network reports (with no reporting source).
1122 TEST_P(ReportingCacheTest, GetCandidateEndpointsFromDocumentForNetworkReports) {
1123 const base::UnguessableToken reporting_source =
1124 base::UnguessableToken::Create();
1125
1126 NetworkAnonymizationKey network_anonymization_key =
1127 kIsolationInfo1_.network_anonymization_key();
1128
1129 const ReportingEndpointGroupKey kDocumentGroupKey = ReportingEndpointGroupKey(
1130 network_anonymization_key, reporting_source, kOrigin1_, kGroup1_);
1131
1132 SetV1EndpointInCache(kDocumentGroupKey, reporting_source, kIsolationInfo1_,
1133 kEndpoint1_);
1134 const ReportingEndpointGroupKey kNetworkReportGroupKey =
1135 ReportingEndpointGroupKey(network_anonymization_key, std::nullopt,
1136 kOrigin1_, kGroup1_);
1137 std::vector<ReportingEndpoint> candidate_endpoints =
1138 cache()->GetCandidateEndpointsForDelivery(kNetworkReportGroupKey);
1139 ASSERT_EQ(0u, candidate_endpoints.size());
1140 }
1141
1142 // V1 reporting endpoints must not be returned in response to a request for
1143 // endpoints for a different source.
1144 TEST_P(ReportingCacheTest, GetCandidateEndpointsFromDifferentDocument) {
1145 const base::UnguessableToken reporting_source =
1146 base::UnguessableToken::Create();
1147
1148 NetworkAnonymizationKey network_anonymization_key =
1149 kIsolationInfo1_.network_anonymization_key();
1150
1151 const ReportingEndpointGroupKey kDocumentGroupKey = ReportingEndpointGroupKey(
1152 network_anonymization_key, reporting_source, kOrigin1_, kGroup1_);
1153
1154 SetV1EndpointInCache(kDocumentGroupKey, reporting_source, kIsolationInfo1_,
1155 kEndpoint1_);
1156 const ReportingEndpointGroupKey kOtherGroupKey = ReportingEndpointGroupKey(
1157 network_anonymization_key, base::UnguessableToken::Create(), kOrigin1_,
1158 kGroup1_);
1159 std::vector<ReportingEndpoint> candidate_endpoints =
1160 cache()->GetCandidateEndpointsForDelivery(kOtherGroupKey);
1161 ASSERT_EQ(0u, candidate_endpoints.size());
1162 }
1163
1164 // When both V0 and V1 endpoints are present, V1 endpoints must only be
1165 // returned when the reporting source matches. Only when no reporting source is
1166 // given, or if there is no V1 endpoint with a matching source and name defined
1167 // should a V0 endpoint be used.
1168 TEST_P(ReportingCacheTest, GetMixedCandidateEndpointsForDelivery) {
1169 LoadReportingClients();
1170
1171 // This test relies on proper NAKs being used, so set those up, and endpoint
1172 // group keys to go with them.
1173 NetworkAnonymizationKey network_anonymization_key1 =
1174 kIsolationInfo1_.network_anonymization_key();
1175 NetworkAnonymizationKey network_anonymization_key2 =
1176 kIsolationInfo2_.network_anonymization_key();
1177 ReportingEndpointGroupKey group_key_11 = ReportingEndpointGroupKey(
1178 network_anonymization_key1, kOrigin1_, kGroup1_);
1179 ReportingEndpointGroupKey group_key_12 = ReportingEndpointGroupKey(
1180 network_anonymization_key1, kOrigin1_, kGroup2_);
1181 ReportingEndpointGroupKey group_key_21 = ReportingEndpointGroupKey(
1182 network_anonymization_key2, kOrigin2_, kGroup1_);
1183
1184 // Set up V0 endpoint groups for this origin.
1185 ASSERT_TRUE(SetEndpointInCache(group_key_11, kEndpoint1_, kExpires1_));
1186 ASSERT_TRUE(SetEndpointInCache(group_key_11, kEndpoint2_, kExpires1_));
1187 ASSERT_TRUE(SetEndpointInCache(group_key_12, kEndpoint2_, kExpires1_));
1188 ASSERT_TRUE(SetEndpointInCache(group_key_21, kEndpoint1_, kExpires1_));
1189
1190 // Set up a V1 endpoint for a document at the same origin.
1191 NetworkAnonymizationKey network_anonymization_key =
1192 kIsolationInfo1_.network_anonymization_key();
1193 const base::UnguessableToken reporting_source =
1194 base::UnguessableToken::Create();
1195 const ReportingEndpointGroupKey document_group_key =
1196 ReportingEndpointGroupKey(network_anonymization_key1, reporting_source,
1197 kOrigin1_, kGroup1_);
1198 SetV1EndpointInCache(document_group_key, reporting_source, kIsolationInfo1_,
1199 kEndpoint1_);
1200
1201 // This group key will match both the V1 endpoint, and two V0 endpoints. Only
1202 // the V1 endpoint should be returned.
1203 std::vector<ReportingEndpoint> candidate_endpoints =
1204 cache()->GetCandidateEndpointsForDelivery(ReportingEndpointGroupKey(
1205 network_anonymization_key1, reporting_source, kOrigin1_, kGroup1_));
1206 ASSERT_EQ(1u, candidate_endpoints.size());
1207 EXPECT_EQ(document_group_key, candidate_endpoints[0].group_key);
1208
1209 // This group key has no reporting source, so only V0 endpoints can be
1210 // returned.
1211 candidate_endpoints =
1212 cache()->GetCandidateEndpointsForDelivery(ReportingEndpointGroupKey(
1213 network_anonymization_key1, std::nullopt, kOrigin1_, kGroup1_));
1214 ASSERT_EQ(2u, candidate_endpoints.size());
1215 EXPECT_EQ(group_key_11, candidate_endpoints[0].group_key);
1216 EXPECT_EQ(group_key_11, candidate_endpoints[1].group_key);
1217
1218 // This group key has a reporting source, but no matching V1 endpoints have
1219 // been configured, so we should fall back to the V0 endpoints.
1220 candidate_endpoints =
1221 cache()->GetCandidateEndpointsForDelivery(ReportingEndpointGroupKey(
1222 network_anonymization_key1, reporting_source, kOrigin1_, kGroup2_));
1223 ASSERT_EQ(1u, candidate_endpoints.size());
1224 EXPECT_EQ(group_key_12, candidate_endpoints[0].group_key);
1225 }
1226
1227 TEST_P(ReportingCacheTest, GetCandidateEndpointsDifferentNak) {
1228 LoadReportingClients();
1229
1230 // Test that NAKs are respected by using 2 groups with the same origin and
1231 // group name but different NAKs.
1232 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, kEndpoint1_, kExpires1_));
1233 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, kEndpoint2_, kExpires1_));
1234 ASSERT_TRUE(SetEndpointInCache(kOtherGroupKey11_, kEndpoint1_, kExpires1_));
1235 ASSERT_TRUE(SetEndpointInCache(kOtherGroupKey11_, kEndpoint2_, kExpires1_));
1236
1237 std::vector<ReportingEndpoint> candidate_endpoints =
1238 cache()->GetCandidateEndpointsForDelivery(kGroupKey11_);
1239 ASSERT_EQ(2u, candidate_endpoints.size());
1240 EXPECT_EQ(kGroupKey11_, candidate_endpoints[0].group_key);
1241 EXPECT_EQ(kGroupKey11_, candidate_endpoints[1].group_key);
1242
1243 candidate_endpoints =
1244 cache()->GetCandidateEndpointsForDelivery(kOtherGroupKey11_);
1245 ASSERT_EQ(2u, candidate_endpoints.size());
1246 EXPECT_EQ(kOtherGroupKey11_, candidate_endpoints[0].group_key);
1247 EXPECT_EQ(kOtherGroupKey11_, candidate_endpoints[1].group_key);
1248 }
1249
1250 TEST_P(ReportingCacheTest, GetCandidateEndpointsExcludesExpired) {
1251 LoadReportingClients();
1252
1253 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, kEndpoint1_, kExpires1_));
1254 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, kEndpoint2_, kExpires1_));
1255 ASSERT_TRUE(SetEndpointInCache(kGroupKey21_, kEndpoint1_, kExpires1_));
1256 ASSERT_TRUE(SetEndpointInCache(kGroupKey22_, kEndpoint2_, kExpires2_));
1257 // Make kExpires1_ expired but not kExpires2_.
1258 clock()->Advance(base::Days(8));
1259 ASSERT_GT(clock()->Now(), kExpires1_);
1260 ASSERT_LT(clock()->Now(), kExpires2_);
1261
1262 std::vector<ReportingEndpoint> candidate_endpoints =
1263 cache()->GetCandidateEndpointsForDelivery(kGroupKey11_);
1264 ASSERT_EQ(0u, candidate_endpoints.size());
1265
1266 candidate_endpoints = cache()->GetCandidateEndpointsForDelivery(kGroupKey21_);
1267 ASSERT_EQ(0u, candidate_endpoints.size());
1268
1269 candidate_endpoints = cache()->GetCandidateEndpointsForDelivery(kGroupKey22_);
1270 ASSERT_EQ(1u, candidate_endpoints.size());
1271 EXPECT_EQ(kEndpoint2_, candidate_endpoints[0].info.url);
1272 }
1273
1274 TEST_P(ReportingCacheTest, ExcludeSubdomainsDifferentPort) {
1275 LoadReportingClients();
1276
1277 const url::Origin kOrigin = url::Origin::Create(GURL("https://example/"));
1278 const url::Origin kDifferentPortOrigin =
1279 url::Origin::Create(GURL("https://example:444/"));
1280
1281 ASSERT_TRUE(SetEndpointInCache(
1282 ReportingEndpointGroupKey(kNak_, kDifferentPortOrigin, kGroup1_),
1283 kEndpoint1_, kExpires1_, OriginSubdomains::EXCLUDE));
1284
1285 std::vector<ReportingEndpoint> candidate_endpoints =
1286 cache()->GetCandidateEndpointsForDelivery(
1287 ReportingEndpointGroupKey(kNak_, kOrigin, kGroup1_));
1288 ASSERT_EQ(0u, candidate_endpoints.size());
1289 }
1290
TEST_P(ReportingCacheTest,ExcludeSubdomainsSuperdomain)1291 TEST_P(ReportingCacheTest, ExcludeSubdomainsSuperdomain) {
1292 LoadReportingClients();
1293
1294 const url::Origin kOrigin = url::Origin::Create(GURL("https://foo.example/"));
1295 const url::Origin kSuperOrigin =
1296 url::Origin::Create(GURL("https://example/"));
1297
1298 ASSERT_TRUE(SetEndpointInCache(
1299 ReportingEndpointGroupKey(kNak_, kSuperOrigin, kGroup1_), kEndpoint1_,
1300 kExpires1_, OriginSubdomains::EXCLUDE));
1301
1302 std::vector<ReportingEndpoint> candidate_endpoints =
1303 cache()->GetCandidateEndpointsForDelivery(
1304 ReportingEndpointGroupKey(kNak_, kOrigin, kGroup1_));
1305 ASSERT_EQ(0u, candidate_endpoints.size());
1306 }
1307
TEST_P(ReportingCacheTest,IncludeSubdomainsDifferentPort)1308 TEST_P(ReportingCacheTest, IncludeSubdomainsDifferentPort) {
1309 LoadReportingClients();
1310
1311 const url::Origin kOrigin = url::Origin::Create(GURL("https://example/"));
1312 const url::Origin kDifferentPortOrigin =
1313 url::Origin::Create(GURL("https://example:444/"));
1314
1315 ASSERT_TRUE(SetEndpointInCache(
1316 ReportingEndpointGroupKey(kNak_, kDifferentPortOrigin, kGroup1_),
1317 kEndpoint1_, kExpires1_, OriginSubdomains::INCLUDE));
1318
1319 std::vector<ReportingEndpoint> candidate_endpoints =
1320 cache()->GetCandidateEndpointsForDelivery(
1321 ReportingEndpointGroupKey(kNak_, kOrigin, kGroup1_));
1322 ASSERT_EQ(1u, candidate_endpoints.size());
1323 EXPECT_EQ(kDifferentPortOrigin, candidate_endpoints[0].group_key.origin);
1324 }
1325
TEST_P(ReportingCacheTest,IncludeSubdomainsSuperdomain)1326 TEST_P(ReportingCacheTest, IncludeSubdomainsSuperdomain) {
1327 LoadReportingClients();
1328
1329 const url::Origin kOrigin = url::Origin::Create(GURL("https://foo.example/"));
1330 const url::Origin kSuperOrigin =
1331 url::Origin::Create(GURL("https://example/"));
1332
1333 ASSERT_TRUE(SetEndpointInCache(
1334 ReportingEndpointGroupKey(kNak_, kSuperOrigin, kGroup1_), kEndpoint1_,
1335 kExpires1_, OriginSubdomains::INCLUDE));
1336
1337 std::vector<ReportingEndpoint> candidate_endpoints =
1338 cache()->GetCandidateEndpointsForDelivery(
1339 ReportingEndpointGroupKey(kNak_, kOrigin, kGroup1_));
1340 ASSERT_EQ(1u, candidate_endpoints.size());
1341 EXPECT_EQ(kSuperOrigin, candidate_endpoints[0].group_key.origin);
1342 }
1343
TEST_P(ReportingCacheTest,IncludeSubdomainsPreferOriginToDifferentPort)1344 TEST_P(ReportingCacheTest, IncludeSubdomainsPreferOriginToDifferentPort) {
1345 LoadReportingClients();
1346
1347 const url::Origin kOrigin = url::Origin::Create(GURL("https://foo.example/"));
1348 const url::Origin kDifferentPortOrigin =
1349 url::Origin::Create(GURL("https://example:444/"));
1350
1351 ASSERT_TRUE(
1352 SetEndpointInCache(ReportingEndpointGroupKey(kNak_, kOrigin, kGroup1_),
1353 kEndpoint1_, kExpires1_, OriginSubdomains::INCLUDE));
1354 ASSERT_TRUE(SetEndpointInCache(
1355 ReportingEndpointGroupKey(kNak_, kDifferentPortOrigin, kGroup1_),
1356 kEndpoint1_, kExpires1_, OriginSubdomains::INCLUDE));
1357
1358 std::vector<ReportingEndpoint> candidate_endpoints =
1359 cache()->GetCandidateEndpointsForDelivery(
1360 ReportingEndpointGroupKey(kNak_, kOrigin, kGroup1_));
1361 ASSERT_EQ(1u, candidate_endpoints.size());
1362 EXPECT_EQ(kOrigin, candidate_endpoints[0].group_key.origin);
1363 }
1364
TEST_P(ReportingCacheTest,IncludeSubdomainsPreferOriginToSuperdomain)1365 TEST_P(ReportingCacheTest, IncludeSubdomainsPreferOriginToSuperdomain) {
1366 LoadReportingClients();
1367
1368 const url::Origin kOrigin = url::Origin::Create(GURL("https://foo.example/"));
1369 const url::Origin kSuperOrigin =
1370 url::Origin::Create(GURL("https://example/"));
1371
1372 ASSERT_TRUE(
1373 SetEndpointInCache(ReportingEndpointGroupKey(kNak_, kOrigin, kGroup1_),
1374 kEndpoint1_, kExpires1_, OriginSubdomains::INCLUDE));
1375 ASSERT_TRUE(SetEndpointInCache(
1376 ReportingEndpointGroupKey(kNak_, kSuperOrigin, kGroup1_), kEndpoint1_,
1377 kExpires1_, OriginSubdomains::INCLUDE));
1378
1379 std::vector<ReportingEndpoint> candidate_endpoints =
1380 cache()->GetCandidateEndpointsForDelivery(
1381 ReportingEndpointGroupKey(kNak_, kOrigin, kGroup1_));
1382 ASSERT_EQ(1u, candidate_endpoints.size());
1383 EXPECT_EQ(kOrigin, candidate_endpoints[0].group_key.origin);
1384 }
1385
TEST_P(ReportingCacheTest,IncludeSubdomainsPreferMoreSpecificSuperdomain)1386 TEST_P(ReportingCacheTest, IncludeSubdomainsPreferMoreSpecificSuperdomain) {
1387 LoadReportingClients();
1388
1389 const url::Origin kOrigin =
1390 url::Origin::Create(GURL("https://foo.bar.example/"));
1391 const url::Origin kSuperOrigin =
1392 url::Origin::Create(GURL("https://bar.example/"));
1393 const url::Origin kSuperSuperOrigin =
1394 url::Origin::Create(GURL("https://example/"));
1395
1396 ASSERT_TRUE(SetEndpointInCache(
1397 ReportingEndpointGroupKey(kNak_, kSuperOrigin, kGroup1_), kEndpoint1_,
1398 kExpires1_, OriginSubdomains::INCLUDE));
1399 ASSERT_TRUE(SetEndpointInCache(
1400 ReportingEndpointGroupKey(kNak_, kSuperSuperOrigin, kGroup1_),
1401 kEndpoint1_, kExpires1_, OriginSubdomains::INCLUDE));
1402
1403 std::vector<ReportingEndpoint> candidate_endpoints =
1404 cache()->GetCandidateEndpointsForDelivery(
1405 ReportingEndpointGroupKey(kNak_, kOrigin, kGroup1_));
1406 ASSERT_EQ(1u, candidate_endpoints.size());
1407 EXPECT_EQ(kSuperOrigin, candidate_endpoints[0].group_key.origin);
1408 }
1409
TEST_P(ReportingCacheTest,IncludeSubdomainsPreserveNak)1410 TEST_P(ReportingCacheTest, IncludeSubdomainsPreserveNak) {
1411 LoadReportingClients();
1412
1413 const url::Origin kOrigin = url::Origin::Create(GURL("https://foo.example/"));
1414 const url::Origin kSuperOrigin =
1415 url::Origin::Create(GURL("https://example/"));
1416
1417 ASSERT_TRUE(SetEndpointInCache(
1418 ReportingEndpointGroupKey(kNak_, kSuperOrigin, kGroup1_), kEndpoint1_,
1419 kExpires1_, OriginSubdomains::INCLUDE));
1420 ASSERT_TRUE(SetEndpointInCache(
1421 ReportingEndpointGroupKey(kOtherNak_, kSuperOrigin, kGroup1_),
1422 kEndpoint1_, kExpires1_, OriginSubdomains::INCLUDE));
1423
1424 std::vector<ReportingEndpoint> candidate_endpoints =
1425 cache()->GetCandidateEndpointsForDelivery(
1426 ReportingEndpointGroupKey(kOtherNak_, kOrigin, kGroup1_));
1427 ASSERT_EQ(1u, candidate_endpoints.size());
1428 EXPECT_EQ(kOtherNak_,
1429 candidate_endpoints[0].group_key.network_anonymization_key);
1430 }
1431
TEST_P(ReportingCacheTest,EvictOldestReport)1432 TEST_P(ReportingCacheTest, EvictOldestReport) {
1433 LoadReportingClients();
1434
1435 size_t max_report_count = policy().max_report_count;
1436
1437 ASSERT_LT(0u, max_report_count);
1438 ASSERT_GT(std::numeric_limits<size_t>::max(), max_report_count);
1439
1440 base::TimeTicks earliest_queued = tick_clock()->NowTicks();
1441
1442 // Enqueue the maximum number of reports, spaced apart in time.
1443 for (size_t i = 0; i < max_report_count; ++i) {
1444 cache()->AddReport(kReportingSource_, kNak_, kUrl1_, kUserAgent_, kGroup1_,
1445 kType_, base::Value::Dict(), 0, tick_clock()->NowTicks(),
1446 0);
1447 tick_clock()->Advance(base::Minutes(1));
1448 }
1449 EXPECT_EQ(max_report_count, report_count());
1450
1451 // Add one more report to force the cache to evict one.
1452 cache()->AddReport(kReportingSource_, kNak_, kUrl1_, kUserAgent_, kGroup1_,
1453 kType_, base::Value::Dict(), 0, tick_clock()->NowTicks(),
1454 0);
1455
1456 // Make sure the cache evicted a report to make room for the new one, and make
1457 // sure the report evicted was the earliest-queued one.
1458 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
1459 cache()->GetReports(&reports);
1460 EXPECT_EQ(max_report_count, reports.size());
1461 for (const ReportingReport* report : reports)
1462 EXPECT_NE(earliest_queued, report->queued);
1463 }
1464
TEST_P(ReportingCacheTest,DontEvictPendingReports)1465 TEST_P(ReportingCacheTest, DontEvictPendingReports) {
1466 LoadReportingClients();
1467
1468 size_t max_report_count = policy().max_report_count;
1469
1470 ASSERT_LT(0u, max_report_count);
1471 ASSERT_GT(std::numeric_limits<size_t>::max(), max_report_count);
1472
1473 // Enqueue the maximum number of reports, spaced apart in time.
1474 std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
1475 for (size_t i = 0; i < max_report_count; ++i) {
1476 reports.push_back(AddAndReturnReport(kNak_, kUrl1_, kUserAgent_, kGroup1_,
1477 kType_, base::Value::Dict(), 0,
1478 tick_clock()->NowTicks(), 0));
1479 tick_clock()->Advance(base::Minutes(1));
1480 }
1481 EXPECT_EQ(max_report_count, report_count());
1482
1483 // Mark all of the queued reports pending.
1484 EXPECT_THAT(cache()->GetReportsToDeliver(),
1485 ::testing::UnorderedElementsAreArray(reports));
1486
1487 // Add one more report to force the cache to evict one. Since the cache has
1488 // only pending reports, it will be forced to evict the *new* report!
1489 cache()->AddReport(kReportingSource_, kNak_, kUrl1_, kUserAgent_, kGroup1_,
1490 kType_, base::Value::Dict(), 0, kNowTicks_, 0);
1491
1492 // Make sure the cache evicted a report, and make sure the report evicted was
1493 // the new, non-pending one.
1494 std::vector<raw_ptr<const ReportingReport, VectorExperimental>>
1495 reports_after_eviction;
1496 cache()->GetReports(&reports_after_eviction);
1497 EXPECT_EQ(max_report_count, reports_after_eviction.size());
1498 for (const ReportingReport* report : reports_after_eviction) {
1499 EXPECT_TRUE(cache()->IsReportPendingForTesting(report));
1500 }
1501
1502 EXPECT_THAT(reports_after_eviction,
1503 ::testing::UnorderedElementsAreArray(reports));
1504 }
1505
TEST_P(ReportingCacheTest,EvictEndpointsOverPerOriginLimit)1506 TEST_P(ReportingCacheTest, EvictEndpointsOverPerOriginLimit) {
1507 LoadReportingClients();
1508
1509 for (size_t i = 0; i < policy().max_endpoints_per_origin; ++i) {
1510 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, MakeURL(i), kExpires1_));
1511 EXPECT_EQ(i + 1, cache()->GetEndpointCount());
1512 }
1513 EXPECT_EQ(policy().max_endpoints_per_origin, cache()->GetEndpointCount());
1514 // Insert one more endpoint; eviction should be triggered.
1515 SetEndpointInCache(kGroupKey11_, kEndpoint1_, kExpires1_);
1516 EXPECT_EQ(policy().max_endpoints_per_origin, cache()->GetEndpointCount());
1517 }
1518
TEST_P(ReportingCacheTest,EvictExpiredGroups)1519 TEST_P(ReportingCacheTest, EvictExpiredGroups) {
1520 LoadReportingClients();
1521
1522 for (size_t i = 0; i < policy().max_endpoints_per_origin; ++i) {
1523 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, MakeURL(i), kExpires1_));
1524 EXPECT_EQ(i + 1, cache()->GetEndpointCount());
1525 }
1526 EXPECT_EQ(policy().max_endpoints_per_origin, cache()->GetEndpointCount());
1527
1528 // Make the group expired (but not stale).
1529 clock()->SetNow(kExpires1_ - base::Minutes(1));
1530 cache()->GetCandidateEndpointsForDelivery(kGroupKey11_);
1531 clock()->SetNow(kExpires1_ + base::Minutes(1));
1532
1533 // Insert one more endpoint in a different group (not expired); eviction
1534 // should be triggered and the expired group should be deleted.
1535 SetEndpointInCache(kGroupKey12_, kEndpoint1_, kExpires2_);
1536 EXPECT_GE(policy().max_endpoints_per_origin, cache()->GetEndpointCount());
1537 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin1_));
1538 EXPECT_FALSE(
1539 EndpointGroupExistsInCache(kGroupKey11_, OriginSubdomains::DEFAULT));
1540 EXPECT_TRUE(
1541 EndpointGroupExistsInCache(kGroupKey12_, OriginSubdomains::DEFAULT));
1542 }
1543
TEST_P(ReportingCacheTest,EvictStaleGroups)1544 TEST_P(ReportingCacheTest, EvictStaleGroups) {
1545 LoadReportingClients();
1546
1547 for (size_t i = 0; i < policy().max_endpoints_per_origin; ++i) {
1548 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, MakeURL(i), kExpires1_));
1549 EXPECT_EQ(i + 1, cache()->GetEndpointCount());
1550 }
1551 EXPECT_EQ(policy().max_endpoints_per_origin, cache()->GetEndpointCount());
1552
1553 // Make the group stale (but not expired).
1554 clock()->Advance(2 * policy().max_group_staleness);
1555 ASSERT_LT(clock()->Now(), kExpires1_);
1556
1557 // Insert one more endpoint in a different group; eviction should be
1558 // triggered and the stale group should be deleted.
1559 SetEndpointInCache(kGroupKey12_, kEndpoint1_, kExpires1_);
1560 EXPECT_GE(policy().max_endpoints_per_origin, cache()->GetEndpointCount());
1561 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin1_));
1562 EXPECT_FALSE(
1563 EndpointGroupExistsInCache(kGroupKey11_, OriginSubdomains::DEFAULT));
1564 EXPECT_TRUE(
1565 EndpointGroupExistsInCache(kGroupKey12_, OriginSubdomains::DEFAULT));
1566 }
1567
TEST_P(ReportingCacheTest,EvictFromStalestGroup)1568 TEST_P(ReportingCacheTest, EvictFromStalestGroup) {
1569 LoadReportingClients();
1570
1571 for (size_t i = 0; i < policy().max_endpoints_per_origin; ++i) {
1572 ReportingEndpointGroupKey group_key(kNak_, kOrigin1_,
1573 base::NumberToString(i));
1574 ASSERT_TRUE(SetEndpointInCache(group_key, MakeURL(i), kExpires1_));
1575 EXPECT_EQ(i + 1, cache()->GetEndpointCount());
1576 EXPECT_TRUE(
1577 EndpointGroupExistsInCache(group_key, OriginSubdomains::DEFAULT));
1578 // Mark group used.
1579 cache()->GetCandidateEndpointsForDelivery(group_key);
1580 clock()->Advance(base::Minutes(1));
1581 }
1582 EXPECT_EQ(policy().max_endpoints_per_origin, cache()->GetEndpointCount());
1583
1584 // Insert one more endpoint in a different group; eviction should be
1585 // triggered and (only) the stalest group should be evicted from (and in this
1586 // case deleted).
1587 SetEndpointInCache(kGroupKey12_, kEndpoint1_, kExpires1_);
1588 EXPECT_GE(policy().max_endpoints_per_origin, cache()->GetEndpointCount());
1589 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin1_));
1590 EXPECT_FALSE(EndpointGroupExistsInCache(
1591 ReportingEndpointGroupKey(kNak_, kOrigin1_, "0"),
1592 OriginSubdomains::DEFAULT));
1593 EXPECT_TRUE(
1594 EndpointGroupExistsInCache(kGroupKey12_, OriginSubdomains::DEFAULT));
1595 for (size_t i = 1; i < policy().max_endpoints_per_origin; ++i) {
1596 ReportingEndpointGroupKey group_key(kNak_, kOrigin1_,
1597 base::NumberToString(i));
1598 EXPECT_TRUE(
1599 EndpointGroupExistsInCache(group_key, OriginSubdomains::DEFAULT));
1600 }
1601 }
1602
TEST_P(ReportingCacheTest,EvictFromLargestGroup)1603 TEST_P(ReportingCacheTest, EvictFromLargestGroup) {
1604 LoadReportingClients();
1605
1606 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, MakeURL(0), kExpires1_));
1607 // This group should be evicted from because it has 2 endpoints.
1608 ASSERT_TRUE(SetEndpointInCache(kGroupKey12_, MakeURL(1), kExpires1_));
1609 ASSERT_TRUE(SetEndpointInCache(kGroupKey12_, MakeURL(2), kExpires1_));
1610
1611 // max_endpoints_per_origin is set to 3.
1612 ASSERT_EQ(policy().max_endpoints_per_origin, cache()->GetEndpointCount());
1613
1614 // Insert one more endpoint in a different group; eviction should be
1615 // triggered.
1616 SetEndpointInCache(ReportingEndpointGroupKey(kNak_, kOrigin1_, "default"),
1617 kEndpoint1_, kExpires1_);
1618 EXPECT_EQ(policy().max_endpoints_per_origin, cache()->GetEndpointCount());
1619
1620 EXPECT_TRUE(
1621 EndpointGroupExistsInCache(kGroupKey11_, OriginSubdomains::DEFAULT));
1622 EXPECT_TRUE(
1623 EndpointGroupExistsInCache(kGroupKey12_, OriginSubdomains::DEFAULT));
1624 // Count the number of endpoints remaining in kGroupKey12_.
1625 std::vector<ReportingEndpoint> endpoints_in_group =
1626 cache()->GetCandidateEndpointsForDelivery(kGroupKey12_);
1627 EXPECT_EQ(1u, endpoints_in_group.size());
1628 }
1629
TEST_P(ReportingCacheTest,EvictLeastImportantEndpoint)1630 TEST_P(ReportingCacheTest, EvictLeastImportantEndpoint) {
1631 LoadReportingClients();
1632
1633 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, MakeURL(0), kExpires1_,
1634 OriginSubdomains::DEFAULT, 1 /* priority*/,
1635 1 /* weight */));
1636 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, MakeURL(1), kExpires1_,
1637 OriginSubdomains::DEFAULT, 2 /* priority */,
1638 2 /* weight */));
1639 // This endpoint will be evicted because it is lowest priority and lowest
1640 // weight.
1641 ASSERT_TRUE(SetEndpointInCache(kGroupKey11_, MakeURL(2), kExpires1_,
1642 OriginSubdomains::DEFAULT, 2 /* priority */,
1643 1 /* weight */));
1644
1645 // max_endpoints_per_origin is set to 3.
1646 ASSERT_EQ(policy().max_endpoints_per_origin, cache()->GetEndpointCount());
1647
1648 // Insert one more endpoint in a different group; eviction should be
1649 // triggered and the least important endpoint should be deleted.
1650 SetEndpointInCache(kGroupKey12_, kEndpoint1_, kExpires1_);
1651 EXPECT_EQ(policy().max_endpoints_per_origin, cache()->GetEndpointCount());
1652
1653 EXPECT_TRUE(FindEndpointInCache(kGroupKey11_, MakeURL(0)));
1654 EXPECT_TRUE(FindEndpointInCache(kGroupKey11_, MakeURL(1)));
1655 EXPECT_FALSE(FindEndpointInCache(kGroupKey11_, MakeURL(2)));
1656 EXPECT_TRUE(FindEndpointInCache(kGroupKey12_, kEndpoint1_));
1657 }
1658
TEST_P(ReportingCacheTest,EvictEndpointsOverGlobalLimitFromStalestClient)1659 TEST_P(ReportingCacheTest, EvictEndpointsOverGlobalLimitFromStalestClient) {
1660 LoadReportingClients();
1661
1662 // Set enough endpoints to reach the global endpoint limit.
1663 for (size_t i = 0; i < policy().max_endpoint_count; ++i) {
1664 ReportingEndpointGroupKey group_key(kNak_, url::Origin::Create(MakeURL(i)),
1665 kGroup1_);
1666 ASSERT_TRUE(SetEndpointInCache(group_key, MakeURL(i), kExpires1_));
1667 EXPECT_EQ(i + 1, cache()->GetEndpointCount());
1668 clock()->Advance(base::Minutes(1));
1669 }
1670 EXPECT_EQ(policy().max_endpoint_count, cache()->GetEndpointCount());
1671
1672 // Insert one more endpoint for a different origin; eviction should be
1673 // triggered and the stalest client should be evicted from (and in this case
1674 // deleted).
1675 SetEndpointInCache(kGroupKey11_, kEndpoint1_, kExpires1_);
1676 EXPECT_EQ(policy().max_endpoint_count, cache()->GetEndpointCount());
1677 EXPECT_FALSE(ClientExistsInCacheForOrigin(url::Origin::Create(MakeURL(0))));
1678 for (size_t i = 1; i < policy().max_endpoint_count; ++i) {
1679 EXPECT_TRUE(ClientExistsInCacheForOrigin(url::Origin::Create(MakeURL(i))));
1680 }
1681 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin1_));
1682 }
1683
TEST_P(ReportingCacheTest,AddClientsLoadedFromStore)1684 TEST_P(ReportingCacheTest, AddClientsLoadedFromStore) {
1685 if (!store())
1686 return;
1687
1688 base::Time now = clock()->Now();
1689
1690 std::vector<ReportingEndpoint> endpoints;
1691 endpoints.emplace_back(kGroupKey11_,
1692 ReportingEndpoint::EndpointInfo{kEndpoint1_});
1693 endpoints.emplace_back(kGroupKey22_,
1694 ReportingEndpoint::EndpointInfo{kEndpoint2_});
1695 endpoints.emplace_back(kGroupKey11_,
1696 ReportingEndpoint::EndpointInfo{kEndpoint2_});
1697 endpoints.emplace_back(kGroupKey21_,
1698 ReportingEndpoint::EndpointInfo{kEndpoint1_});
1699 std::vector<CachedReportingEndpointGroup> groups;
1700 groups.emplace_back(kGroupKey21_, OriginSubdomains::DEFAULT,
1701 now + base::Minutes(2) /* expires */,
1702 now /* last_used */);
1703 groups.emplace_back(kGroupKey11_, OriginSubdomains::DEFAULT,
1704 now + base::Minutes(1) /* expires */,
1705 now /* last_used */);
1706 groups.emplace_back(kGroupKey22_, OriginSubdomains::DEFAULT,
1707 now + base::Minutes(3) /* expires */,
1708 now /* last_used */);
1709 store()->SetPrestoredClients(endpoints, groups);
1710
1711 LoadReportingClients();
1712
1713 EXPECT_EQ(4u, cache()->GetEndpointCount());
1714 EXPECT_EQ(3u, cache()->GetEndpointGroupCountForTesting());
1715 EXPECT_TRUE(EndpointExistsInCache(kGroupKey11_, kEndpoint1_));
1716 EXPECT_TRUE(EndpointExistsInCache(kGroupKey11_, kEndpoint2_));
1717 EXPECT_TRUE(EndpointExistsInCache(kGroupKey21_, kEndpoint1_));
1718 EXPECT_TRUE(EndpointExistsInCache(kGroupKey22_, kEndpoint2_));
1719 EXPECT_TRUE(EndpointGroupExistsInCache(
1720 kGroupKey11_, OriginSubdomains::DEFAULT, now + base::Minutes(1)));
1721 EXPECT_TRUE(EndpointGroupExistsInCache(
1722 kGroupKey21_, OriginSubdomains::DEFAULT, now + base::Minutes(2)));
1723 EXPECT_TRUE(EndpointGroupExistsInCache(
1724 kGroupKey22_, OriginSubdomains::DEFAULT, now + base::Minutes(3)));
1725 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin1_));
1726 EXPECT_TRUE(ClientExistsInCacheForOrigin(kOrigin2_));
1727 }
1728
TEST_P(ReportingCacheTest,AddStoredClientsWithDifferentNetworkAnonymizationKeys)1729 TEST_P(ReportingCacheTest,
1730 AddStoredClientsWithDifferentNetworkAnonymizationKeys) {
1731 if (!store())
1732 return;
1733
1734 base::Time now = clock()->Now();
1735
1736 // This should create 4 different clients, for (2 origins) x (2 NAKs).
1737 // Intentionally in a weird order to check sorting.
1738 std::vector<ReportingEndpoint> endpoints;
1739 endpoints.emplace_back(kGroupKey11_,
1740 ReportingEndpoint::EndpointInfo{kEndpoint1_});
1741 endpoints.emplace_back(kGroupKey21_,
1742 ReportingEndpoint::EndpointInfo{kEndpoint1_});
1743 endpoints.emplace_back(kOtherGroupKey21_,
1744 ReportingEndpoint::EndpointInfo{kEndpoint1_});
1745 endpoints.emplace_back(kOtherGroupKey11_,
1746 ReportingEndpoint::EndpointInfo{kEndpoint1_});
1747 std::vector<CachedReportingEndpointGroup> groups;
1748 groups.emplace_back(kGroupKey21_, OriginSubdomains::DEFAULT,
1749 now /* expires */, now /* last_used */);
1750 groups.emplace_back(kOtherGroupKey21_, OriginSubdomains::DEFAULT,
1751 now /* expires */, now /* last_used */);
1752 groups.emplace_back(kOtherGroupKey11_, OriginSubdomains::DEFAULT,
1753 now /* expires */, now /* last_used */);
1754 groups.emplace_back(kGroupKey11_, OriginSubdomains::DEFAULT,
1755 now /* expires */, now /* last_used */);
1756
1757 store()->SetPrestoredClients(endpoints, groups);
1758
1759 LoadReportingClients();
1760
1761 EXPECT_EQ(4u, cache()->GetEndpointCount());
1762 EXPECT_EQ(4u, cache()->GetEndpointGroupCountForTesting());
1763 EXPECT_EQ(4u, cache()->GetClientCountForTesting());
1764 EXPECT_TRUE(EndpointExistsInCache(kGroupKey11_, kEndpoint1_));
1765 EXPECT_TRUE(EndpointExistsInCache(kGroupKey21_, kEndpoint1_));
1766 EXPECT_TRUE(EndpointExistsInCache(kOtherGroupKey11_, kEndpoint1_));
1767 EXPECT_TRUE(EndpointExistsInCache(kOtherGroupKey21_, kEndpoint1_));
1768 EXPECT_TRUE(
1769 EndpointGroupExistsInCache(kGroupKey11_, OriginSubdomains::DEFAULT));
1770 EXPECT_TRUE(
1771 EndpointGroupExistsInCache(kGroupKey21_, OriginSubdomains::DEFAULT));
1772 EXPECT_TRUE(
1773 EndpointGroupExistsInCache(kOtherGroupKey11_, OriginSubdomains::DEFAULT));
1774 EXPECT_TRUE(
1775 EndpointGroupExistsInCache(kOtherGroupKey21_, OriginSubdomains::DEFAULT));
1776 EXPECT_TRUE(cache()->ClientExistsForTesting(
1777 kGroupKey11_.network_anonymization_key, kGroupKey11_.origin));
1778 EXPECT_TRUE(cache()->ClientExistsForTesting(
1779 kGroupKey21_.network_anonymization_key, kGroupKey21_.origin));
1780 EXPECT_TRUE(cache()->ClientExistsForTesting(
1781 kOtherGroupKey11_.network_anonymization_key, kOtherGroupKey11_.origin));
1782 EXPECT_TRUE(cache()->ClientExistsForTesting(
1783 kOtherGroupKey21_.network_anonymization_key, kOtherGroupKey21_.origin));
1784 }
1785
TEST_P(ReportingCacheTest,DoNotStoreMoreThanLimits)1786 TEST_P(ReportingCacheTest, DoNotStoreMoreThanLimits) {
1787 if (!store())
1788 return;
1789
1790 base::Time now = clock()->Now();
1791
1792 // We hardcode the number of endpoints in this test, so we need to manually
1793 // update the test when |max_endpoint_count| changes. You'll need to
1794 // add/remove elements to |endpoints| when that happens.
1795 EXPECT_EQ(5u, policy().max_endpoint_count) << "You need to update this test "
1796 << "to reflect a change in "
1797 << "max_endpoint_count";
1798
1799 std::vector<ReportingEndpoint> endpoints;
1800 endpoints.emplace_back(kGroupKey11_,
1801 ReportingEndpoint::EndpointInfo{kEndpoint1_});
1802 endpoints.emplace_back(kGroupKey11_,
1803 ReportingEndpoint::EndpointInfo{kEndpoint2_});
1804 endpoints.emplace_back(kGroupKey11_,
1805 ReportingEndpoint::EndpointInfo{kEndpoint3_});
1806 endpoints.emplace_back(kGroupKey11_,
1807 ReportingEndpoint::EndpointInfo{kEndpoint4_});
1808 endpoints.emplace_back(kGroupKey22_,
1809 ReportingEndpoint::EndpointInfo{kEndpoint1_});
1810 endpoints.emplace_back(kGroupKey22_,
1811 ReportingEndpoint::EndpointInfo{kEndpoint2_});
1812 endpoints.emplace_back(kGroupKey22_,
1813 ReportingEndpoint::EndpointInfo{kEndpoint3_});
1814 endpoints.emplace_back(kGroupKey22_,
1815 ReportingEndpoint::EndpointInfo{kEndpoint4_});
1816 std::vector<CachedReportingEndpointGroup> groups;
1817 groups.emplace_back(kGroupKey11_, OriginSubdomains::DEFAULT,
1818 now /* expires */, now /* last_used */);
1819 groups.emplace_back(kGroupKey22_, OriginSubdomains::DEFAULT,
1820 now /* expires */, now /* last_used */);
1821 store()->SetPrestoredClients(endpoints, groups);
1822
1823 LoadReportingClients();
1824
1825 EXPECT_GE(5u, cache()->GetEndpointCount());
1826 EXPECT_GE(2u, cache()->GetEndpointGroupCountForTesting());
1827 }
1828
TEST_P(ReportingCacheTest,DoNotLoadMismatchedGroupsAndEndpoints)1829 TEST_P(ReportingCacheTest, DoNotLoadMismatchedGroupsAndEndpoints) {
1830 if (!store())
1831 return;
1832
1833 base::Time now = clock()->Now();
1834
1835 std::vector<ReportingEndpoint> endpoints;
1836 // This endpoint has no corresponding endpoint group
1837 endpoints.emplace_back(kGroupKey11_,
1838 ReportingEndpoint::EndpointInfo{kEndpoint1_});
1839 endpoints.emplace_back(kGroupKey21_,
1840 ReportingEndpoint::EndpointInfo{kEndpoint1_});
1841 // This endpoint has no corresponding endpoint group
1842 endpoints.emplace_back(kGroupKey22_,
1843 ReportingEndpoint::EndpointInfo{kEndpoint1_});
1844 std::vector<CachedReportingEndpointGroup> groups;
1845 // This endpoint group has no corresponding endpoint
1846 groups.emplace_back(kGroupKey12_, OriginSubdomains::DEFAULT,
1847 now /* expires */, now /* last_used */);
1848 groups.emplace_back(kGroupKey21_, OriginSubdomains::DEFAULT,
1849 now /* expires */, now /* last_used */);
1850 // This endpoint group has no corresponding endpoint
1851 groups.emplace_back(ReportingEndpointGroupKey(kNak_, kOrigin2_, "last_group"),
1852 OriginSubdomains::DEFAULT, now /* expires */,
1853 now /* last_used */);
1854 store()->SetPrestoredClients(endpoints, groups);
1855
1856 LoadReportingClients();
1857
1858 EXPECT_GE(1u, cache()->GetEndpointCount());
1859 EXPECT_GE(1u, cache()->GetEndpointGroupCountForTesting());
1860 EXPECT_TRUE(EndpointExistsInCache(kGroupKey21_, kEndpoint1_));
1861 }
1862
1863 // This test verifies that we preserve the last_used field when storing clients
1864 // loaded from disk. We don't have direct access into individual cache elements,
1865 // so we test this indirectly by triggering a cache eviction and verifying that
1866 // a stale element (i.e., one older than a week, by default) is selected for
1867 // eviction. If last_used weren't populated then presumably that element
1868 // wouldn't be evicted. (Or rather, it would only have a 25% chance of being
1869 // evicted and this test would then be flaky.)
TEST_P(ReportingCacheTest,StoreLastUsedProperly)1870 TEST_P(ReportingCacheTest, StoreLastUsedProperly) {
1871 if (!store())
1872 return;
1873
1874 base::Time now = clock()->Now();
1875
1876 // We hardcode the number of endpoints in this test, so we need to manually
1877 // update the test when |max_endpoints_per_origin| changes. You'll need to
1878 // add/remove elements to |endpoints| and |grups| when that happens.
1879 EXPECT_EQ(3u, policy().max_endpoints_per_origin)
1880 << "You need to update this test to reflect a change in "
1881 "max_endpoints_per_origin";
1882
1883 // We need more than three endpoints to trigger eviction.
1884 std::vector<ReportingEndpoint> endpoints;
1885 ReportingEndpointGroupKey group1(kNak_, kOrigin1_, "1");
1886 ReportingEndpointGroupKey group2(kNak_, kOrigin1_, "2");
1887 ReportingEndpointGroupKey group3(kNak_, kOrigin1_, "3");
1888 ReportingEndpointGroupKey group4(kNak_, kOrigin1_, "4");
1889 endpoints.emplace_back(group1, ReportingEndpoint::EndpointInfo{kEndpoint1_});
1890 endpoints.emplace_back(group2, ReportingEndpoint::EndpointInfo{kEndpoint1_});
1891 endpoints.emplace_back(group3, ReportingEndpoint::EndpointInfo{kEndpoint1_});
1892 endpoints.emplace_back(group4, ReportingEndpoint::EndpointInfo{kEndpoint1_});
1893 std::vector<CachedReportingEndpointGroup> groups;
1894 groups.emplace_back(group1, OriginSubdomains::DEFAULT, now /* expires */,
1895 now /* last_used */);
1896 groups.emplace_back(group2, OriginSubdomains::DEFAULT, now /* expires */,
1897 now /* last_used */);
1898 // Stale last_used on group "3" should cause us to select it for eviction
1899 groups.emplace_back(group3, OriginSubdomains::DEFAULT, now /* expires */,
1900 base::Time() /* last_used */);
1901 groups.emplace_back(group4, OriginSubdomains::DEFAULT, now /* expires */,
1902 now /* last_used */);
1903 store()->SetPrestoredClients(endpoints, groups);
1904
1905 LoadReportingClients();
1906
1907 EXPECT_TRUE(EndpointExistsInCache(group1, kEndpoint1_));
1908 EXPECT_TRUE(EndpointExistsInCache(group2, kEndpoint1_));
1909 EXPECT_FALSE(EndpointExistsInCache(group3, kEndpoint1_));
1910 EXPECT_TRUE(EndpointExistsInCache(group4, kEndpoint1_));
1911 }
1912
TEST_P(ReportingCacheTest,DoNotAddDuplicatedEntriesFromStore)1913 TEST_P(ReportingCacheTest, DoNotAddDuplicatedEntriesFromStore) {
1914 if (!store())
1915 return;
1916
1917 base::Time now = clock()->Now();
1918
1919 std::vector<ReportingEndpoint> endpoints;
1920 endpoints.emplace_back(kGroupKey11_,
1921 ReportingEndpoint::EndpointInfo{kEndpoint1_});
1922 endpoints.emplace_back(kGroupKey22_,
1923 ReportingEndpoint::EndpointInfo{kEndpoint2_});
1924 endpoints.emplace_back(kGroupKey11_,
1925 ReportingEndpoint::EndpointInfo{kEndpoint1_});
1926 std::vector<CachedReportingEndpointGroup> groups;
1927 groups.emplace_back(kGroupKey11_, OriginSubdomains::DEFAULT,
1928 now + base::Minutes(1) /* expires */,
1929 now /* last_used */);
1930 groups.emplace_back(kGroupKey22_, OriginSubdomains::DEFAULT,
1931 now + base::Minutes(3) /* expires */,
1932 now /* last_used */);
1933 groups.emplace_back(kGroupKey11_, OriginSubdomains::DEFAULT,
1934 now + base::Minutes(1) /* expires */,
1935 now /* last_used */);
1936 store()->SetPrestoredClients(endpoints, groups);
1937
1938 LoadReportingClients();
1939
1940 EXPECT_EQ(2u, cache()->GetEndpointCount());
1941 EXPECT_EQ(2u, cache()->GetEndpointGroupCountForTesting());
1942 EXPECT_TRUE(EndpointExistsInCache(kGroupKey11_, kEndpoint1_));
1943 EXPECT_TRUE(EndpointExistsInCache(kGroupKey22_, kEndpoint2_));
1944 EXPECT_TRUE(EndpointGroupExistsInCache(
1945 kGroupKey11_, OriginSubdomains::DEFAULT, now + base::Minutes(1)));
1946 EXPECT_TRUE(EndpointGroupExistsInCache(
1947 kGroupKey22_, OriginSubdomains::DEFAULT, now + base::Minutes(3)));
1948 }
1949
TEST_P(ReportingCacheTest,GetIsolationInfoForEndpoint)1950 TEST_P(ReportingCacheTest, GetIsolationInfoForEndpoint) {
1951 LoadReportingClients();
1952
1953 NetworkAnonymizationKey network_anonymization_key1 =
1954 kIsolationInfo1_.network_anonymization_key();
1955
1956 // Set up a V1 endpoint for this origin.
1957 cache()->SetV1EndpointForTesting(
1958 ReportingEndpointGroupKey(network_anonymization_key1, *kReportingSource_,
1959 kOrigin1_, kGroup1_),
1960 *kReportingSource_, kIsolationInfo1_, kUrl1_);
1961
1962 // Set up a V0 endpoint group for this origin.
1963 ReportingEndpointGroupKey group_key_11 = ReportingEndpointGroupKey(
1964 network_anonymization_key1, kOrigin1_, kGroup1_);
1965 ASSERT_TRUE(SetEndpointInCache(group_key_11, kEndpoint1_, kExpires1_));
1966
1967 // For a V1 endpoint, ensure that the isolation info matches exactly what was
1968 // passed in.
1969 ReportingEndpoint endpoint =
1970 cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup1_);
1971 EXPECT_TRUE(endpoint);
1972 IsolationInfo isolation_info_for_document =
1973 cache()->GetIsolationInfoForEndpoint(endpoint);
1974 EXPECT_TRUE(isolation_info_for_document.IsEqualForTesting(kIsolationInfo1_));
1975 EXPECT_EQ(isolation_info_for_document.request_type(),
1976 IsolationInfo::RequestType::kOther);
1977
1978 // For a V0 endpoint, ensure that site_for_cookies is null and that the NAK
1979 // matches the cached endpoint.
1980 ReportingEndpoint network_endpoint =
1981 cache()->GetEndpointForTesting(group_key_11, kEndpoint1_);
1982 EXPECT_TRUE(network_endpoint);
1983 IsolationInfo isolation_info_for_network =
1984 cache()->GetIsolationInfoForEndpoint(network_endpoint);
1985 EXPECT_EQ(isolation_info_for_network.request_type(),
1986 IsolationInfo::RequestType::kOther);
1987 EXPECT_EQ(isolation_info_for_network.network_anonymization_key(),
1988 network_endpoint.group_key.network_anonymization_key);
1989 EXPECT_TRUE(isolation_info_for_network.site_for_cookies().IsNull());
1990 }
1991
TEST_P(ReportingCacheTest,GetV1ReportingEndpointsForOrigin)1992 TEST_P(ReportingCacheTest, GetV1ReportingEndpointsForOrigin) {
1993 const base::UnguessableToken reporting_source_2 =
1994 base::UnguessableToken::Create();
1995 LoadReportingClients();
1996
1997 NetworkAnonymizationKey network_anonymization_key_1 =
1998 kIsolationInfo1_.network_anonymization_key();
1999 NetworkAnonymizationKey network_anonymization_key_2 =
2000 kIsolationInfo2_.network_anonymization_key();
2001
2002 // Store endpoints from different origins in cache
2003 cache()->SetV1EndpointForTesting(
2004 ReportingEndpointGroupKey(network_anonymization_key_1, *kReportingSource_,
2005 kOrigin1_, kGroup1_),
2006 *kReportingSource_, kIsolationInfo1_, kUrl1_);
2007 cache()->SetV1EndpointForTesting(
2008 ReportingEndpointGroupKey(network_anonymization_key_1, *kReportingSource_,
2009 kOrigin1_, kGroup2_),
2010 *kReportingSource_, kIsolationInfo1_, kUrl2_);
2011 cache()->SetV1EndpointForTesting(
2012 ReportingEndpointGroupKey(network_anonymization_key_2, reporting_source_2,
2013 kOrigin2_, kGroup1_),
2014 reporting_source_2, kIsolationInfo2_, kUrl2_);
2015
2016 // Retrieve endpoints by origin and ensure they match expectations
2017 auto endpoints = cache()->GetV1ReportingEndpointsByOrigin();
2018 EXPECT_EQ(2u, endpoints.size());
2019 auto origin_1_endpoints = endpoints.at(kOrigin1_);
2020 EXPECT_EQ(2u, origin_1_endpoints.size());
2021 EXPECT_EQ(ReportingEndpointGroupKey(network_anonymization_key_1,
2022 *kReportingSource_, kOrigin1_, kGroup1_),
2023 origin_1_endpoints[0].group_key);
2024 EXPECT_EQ(kUrl1_, origin_1_endpoints[0].info.url);
2025 EXPECT_EQ(ReportingEndpointGroupKey(network_anonymization_key_1,
2026 *kReportingSource_, kOrigin1_, kGroup2_),
2027 origin_1_endpoints[1].group_key);
2028 EXPECT_EQ(kUrl2_, origin_1_endpoints[1].info.url);
2029 auto origin_2_endpoints = endpoints.at(kOrigin2_);
2030 EXPECT_EQ(1u, origin_2_endpoints.size());
2031 EXPECT_EQ(ReportingEndpointGroupKey(network_anonymization_key_2,
2032 reporting_source_2, kOrigin2_, kGroup1_),
2033 origin_2_endpoints[0].group_key);
2034 EXPECT_EQ(kUrl2_, origin_2_endpoints[0].info.url);
2035 }
2036
2037 INSTANTIATE_TEST_SUITE_P(ReportingCacheStoreTest,
2038 ReportingCacheTest,
2039 testing::Bool());
2040
2041 } // namespace
2042 } // namespace net
2043