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