xref: /aosp_15_r20/external/cronet/net/reporting/reporting_cache_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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