1 // Copyright 2019 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/extras/sqlite/sqlite_persistent_reporting_and_nel_store.h"
6
7 #include <memory>
8 #include <vector>
9
10 #include "base/files/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/functional/bind.h"
13 #include "base/run_loop.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "base/task/sequenced_task_runner.h"
16 #include "base/task/single_thread_task_runner.h"
17 #include "base/task/thread_pool.h"
18 #include "base/test/bind.h"
19 #include "base/test/metrics/histogram_tester.h"
20 #include "base/test/scoped_feature_list.h"
21 #include "base/test/simple_test_clock.h"
22 #include "base/threading/thread_restrictions.h"
23 #include "base/time/time.h"
24 #include "net/base/features.h"
25 #include "net/base/network_anonymization_key.h"
26 #include "net/network_error_logging/network_error_logging_service.h"
27 #include "net/reporting/reporting_test_util.h"
28 #include "net/test/test_with_task_environment.h"
29 #include "sql/database.h"
30 #include "sql/meta_table.h"
31 #include "testing/gtest/include/gtest/gtest.h"
32
33 namespace net {
34
35 namespace {
36
37 const base::FilePath::CharType kReportingAndNELStoreFilename[] =
38 FILE_PATH_LITERAL("ReportingAndNEL");
39
40 const IPAddress kServerIP = IPAddress(192, 168, 0, 1);
41 const std::string kHeader = "{\"report_to\":\"group\",\"max_age\":86400}";
42 const std::string kHeaderMaxAge0 = "{\"report_to\":\"group\",\"max_age\":0}";
43 const std::string kGroupName1 = "group1";
44 const std::string kGroupName2 = "group2";
45 const base::Time kExpires = base::Time::Now() + base::Days(7);
46
47 enum class Op { kAdd, kDelete, kUpdate, kUpdateDetails };
48
49 struct TestCase {
50 std::vector<Op> operations;
51 size_t expected_queue_length;
52 };
53
54 // Testcases for coalescing of pending operations. In each case, the given
55 // sequence of operations should be coalesced down to |expected_queue_length|
56 // actual operations queued.
57 const std::vector<TestCase> kCoalescingTestcases = {
58 {{Op::kAdd, Op::kDelete}, 1u},
59 {{Op::kUpdate, Op::kDelete}, 1u},
60 {{Op::kAdd, Op::kUpdate, Op::kDelete}, 1u},
61 {{Op::kUpdate, Op::kUpdate}, 1u},
62 {{Op::kAdd, Op::kUpdate, Op::kUpdate}, 2u},
63 {{Op::kDelete, Op::kAdd}, 2u},
64 {{Op::kDelete, Op::kAdd, Op::kUpdate}, 3u},
65 {{Op::kDelete, Op::kAdd, Op::kUpdate, Op::kUpdate}, 3u},
66 {{Op::kDelete, Op::kDelete}, 1u},
67 {{Op::kDelete, Op::kAdd, Op::kDelete}, 1u},
68 {{Op::kDelete, Op::kAdd, Op::kUpdate, Op::kDelete}, 1u}};
69
70 // This is for Reporting endpoint groups, which have both UPDATE_DETAILS and
71 // UPDATE_ACCESS_TIME. These additional testcases test that UPDATE_DETAILS
72 // overwrites UPDATE_ACCESS_TIME, but not vice versa.
73 const std::vector<TestCase> kCoalescingTestcasesForUpdateDetails = {
74 {{Op::kUpdateDetails, Op::kDelete}, 1u},
75 {{Op::kAdd, Op::kUpdateDetails, Op::kDelete}, 1u},
76 {{Op::kUpdateDetails, Op::kUpdateDetails}, 1u},
77 {{Op::kUpdate, Op::kUpdateDetails}, 1u},
78 {{Op::kUpdateDetails, Op::kUpdate}, 2u},
79 {{Op::kAdd, Op::kUpdateDetails, Op::kUpdate}, 3u},
80 {{Op::kAdd, Op::kUpdateDetails, Op::kUpdate, Op::kUpdateDetails}, 2u},
81 {{Op::kDelete, Op::kAdd, Op::kUpdateDetails}, 3u},
82 {{Op::kDelete, Op::kAdd, Op::kUpdateDetails, Op::kUpdateDetails}, 3u},
83 {{Op::kDelete, Op::kAdd, Op::kUpdate, Op::kUpdateDetails}, 3u},
84 {{Op::kDelete, Op::kAdd, Op::kUpdateDetails, Op::kUpdate}, 4u}};
85
86 } // namespace
87
88 class SQLitePersistentReportingAndNelStoreTest
89 : public TestWithTaskEnvironment {
90 public:
SQLitePersistentReportingAndNelStoreTest()91 SQLitePersistentReportingAndNelStoreTest() {
92 feature_list_.InitAndEnableFeature(
93 features::kPartitionNelAndReportingByNetworkIsolationKey);
94 }
95
CreateStore()96 void CreateStore() {
97 store_ = std::make_unique<SQLitePersistentReportingAndNelStore>(
98 temp_dir_.GetPath().Append(kReportingAndNELStoreFilename),
99 client_task_runner_, background_task_runner_);
100 }
101
DestroyStore()102 void DestroyStore() {
103 store_.reset();
104 // Make sure we wait until the destructor has run by running all
105 // TaskEnvironment tasks.
106 RunUntilIdle();
107 }
108
109 // Call this on a brand new database that should have nothing stored in it.
InitializeStore()110 void InitializeStore() {
111 std::vector<NetworkErrorLoggingService::NelPolicy> nel_policies;
112 LoadNelPolicies(&nel_policies);
113 EXPECT_EQ(0u, nel_policies.size());
114
115 // One load should be sufficient to initialize the database, but we might as
116 // well load everything to check that there is nothing in the database.
117 std::vector<ReportingEndpoint> endpoints;
118 std::vector<CachedReportingEndpointGroup> groups;
119 LoadReportingClients(&endpoints, &groups);
120 EXPECT_EQ(0u, endpoints.size());
121 EXPECT_EQ(0u, groups.size());
122 }
123
LoadNelPolicies(std::vector<NetworkErrorLoggingService::NelPolicy> * policies_out)124 void LoadNelPolicies(
125 std::vector<NetworkErrorLoggingService::NelPolicy>* policies_out) {
126 base::RunLoop run_loop;
127 store_->LoadNelPolicies(base::BindOnce(
128 &SQLitePersistentReportingAndNelStoreTest::OnNelPoliciesLoaded,
129 base::Unretained(this), &run_loop, policies_out));
130 run_loop.Run();
131 }
132
OnNelPoliciesLoaded(base::RunLoop * run_loop,std::vector<NetworkErrorLoggingService::NelPolicy> * policies_out,std::vector<NetworkErrorLoggingService::NelPolicy> policies)133 void OnNelPoliciesLoaded(
134 base::RunLoop* run_loop,
135 std::vector<NetworkErrorLoggingService::NelPolicy>* policies_out,
136 std::vector<NetworkErrorLoggingService::NelPolicy> policies) {
137 policies_out->swap(policies);
138 run_loop->Quit();
139 }
140
LoadReportingClients(std::vector<ReportingEndpoint> * endpoints_out,std::vector<CachedReportingEndpointGroup> * groups_out)141 void LoadReportingClients(
142 std::vector<ReportingEndpoint>* endpoints_out,
143 std::vector<CachedReportingEndpointGroup>* groups_out) {
144 base::RunLoop run_loop;
145 store_->LoadReportingClients(base::BindOnce(
146 &SQLitePersistentReportingAndNelStoreTest::OnReportingClientsLoaded,
147 base::Unretained(this), &run_loop, endpoints_out, groups_out));
148 run_loop.Run();
149 }
150
OnReportingClientsLoaded(base::RunLoop * run_loop,std::vector<ReportingEndpoint> * endpoints_out,std::vector<CachedReportingEndpointGroup> * groups_out,std::vector<ReportingEndpoint> endpoints,std::vector<CachedReportingEndpointGroup> groups)151 void OnReportingClientsLoaded(
152 base::RunLoop* run_loop,
153 std::vector<ReportingEndpoint>* endpoints_out,
154 std::vector<CachedReportingEndpointGroup>* groups_out,
155 std::vector<ReportingEndpoint> endpoints,
156 std::vector<CachedReportingEndpointGroup> groups) {
157 endpoints_out->swap(endpoints);
158 groups_out->swap(groups);
159 run_loop->Quit();
160 }
161
ReadRawDBContents()162 std::string ReadRawDBContents() {
163 std::string contents;
164 if (!base::ReadFileToString(
165 temp_dir_.GetPath().Append(kReportingAndNELStoreFilename),
166 &contents)) {
167 return std::string();
168 }
169 return contents;
170 }
171
WithinOneMicrosecond(base::Time t1,base::Time t2)172 bool WithinOneMicrosecond(base::Time t1, base::Time t2) {
173 base::TimeDelta delta = t1 - t2;
174 return delta.magnitude() < base::Microseconds(1);
175 }
176
WaitOnEvent(base::WaitableEvent * event)177 void WaitOnEvent(base::WaitableEvent* event) {
178 base::ScopedAllowBaseSyncPrimitivesForTesting allow_base_sync_primitives;
179 event->Wait();
180 }
181
SetUp()182 void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
183
TearDown()184 void TearDown() override { DestroyStore(); }
185
MakeNelPolicy(const NetworkAnonymizationKey & network_anonymization_key,const url::Origin & origin,base::Time last_used)186 NetworkErrorLoggingService::NelPolicy MakeNelPolicy(
187 const NetworkAnonymizationKey& network_anonymization_key,
188 const url::Origin& origin,
189 base::Time last_used) {
190 NetworkErrorLoggingService::NelPolicy policy;
191 policy.key = NetworkErrorLoggingService::NelPolicyKey(
192 network_anonymization_key, origin);
193 policy.received_ip_address = IPAddress::IPv4Localhost();
194 policy.report_to = "group";
195 policy.expires = kExpires;
196 policy.success_fraction = 0.0;
197 policy.failure_fraction = 1.0;
198 policy.include_subdomains = false;
199 policy.last_used = last_used;
200 return policy;
201 }
202
MakeReportingEndpoint(const NetworkAnonymizationKey & network_anonymization_key,const url::Origin & origin,const std::string & group_name,const GURL & url,int priority=ReportingEndpoint::EndpointInfo::kDefaultPriority,int weight=ReportingEndpoint::EndpointInfo::kDefaultWeight)203 ReportingEndpoint MakeReportingEndpoint(
204 const NetworkAnonymizationKey& network_anonymization_key,
205 const url::Origin& origin,
206 const std::string& group_name,
207 const GURL& url,
208 int priority = ReportingEndpoint::EndpointInfo::kDefaultPriority,
209 int weight = ReportingEndpoint::EndpointInfo::kDefaultWeight) {
210 ReportingEndpoint::EndpointInfo info;
211 info.url = url;
212 info.priority = priority;
213 info.weight = weight;
214 ReportingEndpoint endpoint(
215 ReportingEndpointGroupKey(network_anonymization_key, origin,
216 group_name),
217 std::move(info));
218 return endpoint;
219 }
220
MakeReportingEndpointGroup(const NetworkAnonymizationKey & network_anonymization_key,const url::Origin & origin,const std::string & group_name,base::Time last_used,OriginSubdomains include_subdomains=OriginSubdomains::DEFAULT,base::Time expires=kExpires)221 CachedReportingEndpointGroup MakeReportingEndpointGroup(
222 const NetworkAnonymizationKey& network_anonymization_key,
223 const url::Origin& origin,
224 const std::string& group_name,
225 base::Time last_used,
226 OriginSubdomains include_subdomains = OriginSubdomains::DEFAULT,
227 base::Time expires = kExpires) {
228 return CachedReportingEndpointGroup(
229 ReportingEndpointGroupKey(network_anonymization_key, origin,
230 group_name),
231 include_subdomains, expires, last_used);
232 }
233
234 protected:
235 base::test::ScopedFeatureList feature_list_;
236
237 // Use origins distinct from those used in origin fields of keys, to avoid any
238 // risk of tests passing due to comparing origins that are the same but come
239 // from different sources.
240 const NetworkAnonymizationKey kNak1_ =
241 NetworkAnonymizationKey::CreateCrossSite(
242 SchemefulSite(GURL("https://top-frame-origin-nak1.test")));
243 const NetworkAnonymizationKey kNak2_ =
244 NetworkAnonymizationKey::CreateCrossSite(
245 SchemefulSite(GURL("https://top-frame-origin-nak2.test")));
246
247 base::ScopedTempDir temp_dir_;
248 std::unique_ptr<SQLitePersistentReportingAndNelStore> store_;
249 const scoped_refptr<base::SequencedTaskRunner> client_task_runner_ =
250 base::SingleThreadTaskRunner::GetCurrentDefault();
251 const scoped_refptr<base::SequencedTaskRunner> background_task_runner_ =
252 base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()});
253 };
254
TEST_F(SQLitePersistentReportingAndNelStoreTest,CreateDBAndTables)255 TEST_F(SQLitePersistentReportingAndNelStoreTest, CreateDBAndTables) {
256 CreateStore();
257 InitializeStore();
258 EXPECT_NE(nullptr, store_.get());
259 std::string contents = ReadRawDBContents();
260 EXPECT_NE("", contents);
261 EXPECT_NE(std::string::npos, contents.find("nel_policies"));
262 EXPECT_NE(std::string::npos, contents.find("reporting_endpoints"));
263 EXPECT_NE(std::string::npos, contents.find("reporting_endpoint_groups"));
264 }
265
TEST_F(SQLitePersistentReportingAndNelStoreTest,TestInvalidMetaTableRecovery)266 TEST_F(SQLitePersistentReportingAndNelStoreTest, TestInvalidMetaTableRecovery) {
267 CreateStore();
268 InitializeStore();
269 base::Time now = base::Time::Now();
270 NetworkErrorLoggingService::NelPolicy policy1 = MakeNelPolicy(
271 kNak1_, url::Origin::Create(GURL("https://www.foo.test")), now);
272 store_->AddNelPolicy(policy1);
273
274 // Close and reopen the database.
275 DestroyStore();
276 CreateStore();
277
278 // Load the stored policy.
279 std::vector<NetworkErrorLoggingService::NelPolicy> policies;
280 LoadNelPolicies(&policies);
281 ASSERT_EQ(1u, policies.size());
282 EXPECT_EQ(policy1.key, policies[0].key);
283 EXPECT_EQ(policy1.received_ip_address, policies[0].received_ip_address);
284 EXPECT_EQ(policy1.report_to, policies[0].report_to);
285 EXPECT_TRUE(WithinOneMicrosecond(policy1.expires, policies[0].expires));
286 EXPECT_EQ(policy1.include_subdomains, policies[0].include_subdomains);
287 EXPECT_EQ(policy1.success_fraction, policies[0].success_fraction);
288 EXPECT_EQ(policy1.failure_fraction, policies[0].failure_fraction);
289 EXPECT_TRUE(WithinOneMicrosecond(policy1.last_used, policies[0].last_used));
290 DestroyStore();
291 policies.clear();
292
293 // Now corrupt the meta table.
294 {
295 sql::Database db;
296 ASSERT_TRUE(
297 db.Open(temp_dir_.GetPath().Append(kReportingAndNELStoreFilename)));
298 sql::MetaTable meta_table;
299 ASSERT_TRUE(meta_table.Init(&db, 1, 1));
300 ASSERT_TRUE(db.Execute("DELETE FROM meta"));
301 db.Close();
302 }
303
304 base::HistogramTester hist_tester;
305
306 // Upon loading, the database should be reset to a good, blank state.
307 CreateStore();
308 LoadNelPolicies(&policies);
309 ASSERT_EQ(0U, policies.size());
310
311 hist_tester.ExpectUniqueSample("ReportingAndNEL.CorruptMetaTableRecovered",
312 true, 1);
313
314 // Verify that, after, recovery, the database persists properly.
315 NetworkErrorLoggingService::NelPolicy policy2 = MakeNelPolicy(
316 kNak2_, url::Origin::Create(GURL("https://www.bar.test")), now);
317 store_->AddNelPolicy(policy2);
318 DestroyStore();
319
320 CreateStore();
321 LoadNelPolicies(&policies);
322 ASSERT_EQ(1u, policies.size());
323 EXPECT_EQ(policy2.key, policies[0].key);
324 EXPECT_EQ(policy2.received_ip_address, policies[0].received_ip_address);
325 EXPECT_EQ(policy2.report_to, policies[0].report_to);
326 EXPECT_TRUE(WithinOneMicrosecond(policy2.expires, policies[0].expires));
327 EXPECT_EQ(policy2.include_subdomains, policies[0].include_subdomains);
328 EXPECT_EQ(policy2.success_fraction, policies[0].success_fraction);
329 EXPECT_EQ(policy2.failure_fraction, policies[0].failure_fraction);
330 EXPECT_TRUE(WithinOneMicrosecond(policy2.last_used, policies[0].last_used));
331 }
332
TEST_F(SQLitePersistentReportingAndNelStoreTest,PersistNelPolicy)333 TEST_F(SQLitePersistentReportingAndNelStoreTest, PersistNelPolicy) {
334 CreateStore();
335 InitializeStore();
336 base::Time now = base::Time::Now();
337 NetworkErrorLoggingService::NelPolicy policy = MakeNelPolicy(
338 kNak1_, url::Origin::Create(GURL("https://www.foo.test")), now);
339 store_->AddNelPolicy(policy);
340
341 // Close and reopen the database.
342 DestroyStore();
343 CreateStore();
344
345 // Load the stored policy.
346 std::vector<NetworkErrorLoggingService::NelPolicy> policies;
347 LoadNelPolicies(&policies);
348 ASSERT_EQ(1u, policies.size());
349 EXPECT_EQ(policy.key, policies[0].key);
350 EXPECT_EQ(policy.received_ip_address, policies[0].received_ip_address);
351 EXPECT_EQ(policy.report_to, policies[0].report_to);
352 EXPECT_TRUE(WithinOneMicrosecond(policy.expires, policies[0].expires));
353 EXPECT_EQ(policy.include_subdomains, policies[0].include_subdomains);
354 EXPECT_EQ(policy.success_fraction, policies[0].success_fraction);
355 EXPECT_EQ(policy.failure_fraction, policies[0].failure_fraction);
356 EXPECT_TRUE(WithinOneMicrosecond(policy.last_used, policies[0].last_used));
357 }
358
TEST_F(SQLitePersistentReportingAndNelStoreTest,LoadFailed)359 TEST_F(SQLitePersistentReportingAndNelStoreTest, LoadFailed) {
360 // Inject a db initialization failure by creating a directory where the db
361 // file should be.
362 ASSERT_TRUE(base::CreateDirectory(
363 temp_dir_.GetPath().Append(kReportingAndNELStoreFilename)));
364 store_ = std::make_unique<SQLitePersistentReportingAndNelStore>(
365 temp_dir_.GetPath().Append(kReportingAndNELStoreFilename),
366 client_task_runner_, background_task_runner_);
367
368 // InitializeStore() checks that we receive empty vectors of NEL policies,
369 // reporting endpoints, and reporting endpoint groups, signifying the failure
370 // to load.
371 InitializeStore();
372 }
373
TEST_F(SQLitePersistentReportingAndNelStoreTest,UpdateNelPolicyAccessTime)374 TEST_F(SQLitePersistentReportingAndNelStoreTest, UpdateNelPolicyAccessTime) {
375 CreateStore();
376 InitializeStore();
377 base::Time now = base::Time::Now();
378 NetworkErrorLoggingService::NelPolicy policy = MakeNelPolicy(
379 kNak1_, url::Origin::Create(GURL("https://www.foo.test")), now);
380 store_->AddNelPolicy(policy);
381
382 policy.last_used = now + base::Days(1);
383 store_->UpdateNelPolicyAccessTime(policy);
384
385 // Close and reopen the database.
386 DestroyStore();
387 CreateStore();
388
389 // Load the stored policy.
390 std::vector<NetworkErrorLoggingService::NelPolicy> policies;
391 LoadNelPolicies(&policies);
392 ASSERT_EQ(1u, policies.size());
393 EXPECT_EQ(policy.key, policies[0].key);
394 EXPECT_TRUE(WithinOneMicrosecond(policy.last_used, policies[0].last_used));
395 }
396
TEST_F(SQLitePersistentReportingAndNelStoreTest,DeleteNelPolicy)397 TEST_F(SQLitePersistentReportingAndNelStoreTest, DeleteNelPolicy) {
398 CreateStore();
399 InitializeStore();
400 base::Time now = base::Time::Now();
401 NetworkErrorLoggingService::NelPolicy policy1 = MakeNelPolicy(
402 kNak1_, url::Origin::Create(GURL("https://www.foo.test")), now);
403 NetworkErrorLoggingService::NelPolicy policy2 = MakeNelPolicy(
404 kNak2_, url::Origin::Create(GURL("https://www.bar.test")), now);
405 store_->AddNelPolicy(policy1);
406 store_->AddNelPolicy(policy2);
407
408 store_->DeleteNelPolicy(policy1);
409
410 // Close and reopen the database.
411 DestroyStore();
412 CreateStore();
413
414 // |policy1| is no longer in the database but |policy2| remains.
415 std::vector<NetworkErrorLoggingService::NelPolicy> policies;
416 LoadNelPolicies(&policies);
417 ASSERT_EQ(1u, policies.size());
418 EXPECT_EQ(policy2.key, policies[0].key);
419
420 // Delete after having closed and reopened.
421 store_->DeleteNelPolicy(policy2);
422 DestroyStore();
423 CreateStore();
424
425 // |policy2| is also gone.
426 policies.clear();
427 LoadNelPolicies(&policies);
428 EXPECT_EQ(0u, policies.size());
429 }
430
TEST_F(SQLitePersistentReportingAndNelStoreTest,NelPolicyUniquenessConstraint)431 TEST_F(SQLitePersistentReportingAndNelStoreTest,
432 NelPolicyUniquenessConstraint) {
433 const url::Origin kOrigin1 =
434 url::Origin::Create(GURL("https://www.bar.test"));
435 const url::Origin kOrigin2 =
436 url::Origin::Create(GURL("https://www.foo.test"));
437
438 CreateStore();
439 InitializeStore();
440 base::Time now = base::Time::Now();
441 base::Time later = now + base::Days(1);
442
443 // Add 3 entries, 2 identical except for NAK, 2 identical except for origin.
444 // Entries should not conflict with each other. These are added in lexical
445 // order.
446 NetworkErrorLoggingService::NelPolicy policy1 =
447 MakeNelPolicy(kNak1_, kOrigin1, now);
448 NetworkErrorLoggingService::NelPolicy policy2 =
449 MakeNelPolicy(kNak1_, kOrigin2, now);
450 NetworkErrorLoggingService::NelPolicy policy3 =
451 MakeNelPolicy(kNak2_, kOrigin1, now);
452 store_->AddNelPolicy(policy1);
453 store_->AddNelPolicy(policy2);
454 store_->AddNelPolicy(policy3);
455
456 // Add policies that are identical except for expiration time. These should
457 // trigger a warning an fail to execute.
458 NetworkErrorLoggingService::NelPolicy policy4 =
459 MakeNelPolicy(kNak1_, kOrigin1, later);
460 NetworkErrorLoggingService::NelPolicy policy5 =
461 MakeNelPolicy(kNak1_, kOrigin2, later);
462 NetworkErrorLoggingService::NelPolicy policy6 =
463 MakeNelPolicy(kNak2_, kOrigin1, later);
464 store_->AddNelPolicy(policy4);
465 store_->AddNelPolicy(policy5);
466 store_->AddNelPolicy(policy6);
467
468 // Close and reopen the database.
469 DestroyStore();
470 CreateStore();
471
472 std::vector<NetworkErrorLoggingService::NelPolicy> policies;
473 LoadNelPolicies(&policies);
474
475 // Only the first 3 policies should be in the store.
476
477 ASSERT_EQ(3u, policies.size());
478
479 EXPECT_EQ(policy1.key, policies[0].key);
480 EXPECT_TRUE(WithinOneMicrosecond(policy1.last_used, policies[0].last_used));
481
482 EXPECT_EQ(policy2.key, policies[1].key);
483 EXPECT_TRUE(WithinOneMicrosecond(policy2.last_used, policies[1].last_used));
484
485 EXPECT_EQ(policy3.key, policies[2].key);
486 EXPECT_TRUE(WithinOneMicrosecond(policy3.last_used, policies[2].last_used));
487 }
488
TEST_F(SQLitePersistentReportingAndNelStoreTest,CoalesceNelPolicyOperations)489 TEST_F(SQLitePersistentReportingAndNelStoreTest, CoalesceNelPolicyOperations) {
490 NetworkErrorLoggingService::NelPolicy policy =
491 MakeNelPolicy(kNak1_, url::Origin::Create(GURL("https://www.foo.test")),
492 base::Time::Now());
493
494 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
495 base::WaitableEvent::InitialState::NOT_SIGNALED);
496
497 for (const TestCase& testcase : kCoalescingTestcases) {
498 CreateStore();
499 base::RunLoop run_loop;
500 store_->LoadNelPolicies(base::BindLambdaForTesting(
501 [&](std::vector<NetworkErrorLoggingService::NelPolicy>) {
502 run_loop.Quit();
503 }));
504 run_loop.Run();
505
506 // Wedge the background thread to make sure it doesn't start consuming the
507 // queue.
508 background_task_runner_->PostTask(
509 FROM_HERE,
510 base::BindOnce(&SQLitePersistentReportingAndNelStoreTest::WaitOnEvent,
511 base::Unretained(this), &event));
512
513 // Now run the ops, and check how much gets queued.
514 for (const Op op : testcase.operations) {
515 switch (op) {
516 case Op::kAdd:
517 store_->AddNelPolicy(policy);
518 break;
519
520 case Op::kDelete:
521 store_->DeleteNelPolicy(policy);
522 break;
523
524 case Op::kUpdate:
525 store_->UpdateNelPolicyAccessTime(policy);
526 break;
527
528 default:
529 NOTREACHED();
530 break;
531 }
532 }
533
534 EXPECT_EQ(testcase.expected_queue_length,
535 store_->GetQueueLengthForTesting());
536
537 event.Signal();
538 RunUntilIdle();
539 }
540 }
541
TEST_F(SQLitePersistentReportingAndNelStoreTest,DontCoalesceUnrelatedNelPolicies)542 TEST_F(SQLitePersistentReportingAndNelStoreTest,
543 DontCoalesceUnrelatedNelPolicies) {
544 CreateStore();
545 InitializeStore();
546
547 base::Time now = base::Time::Now();
548 NetworkErrorLoggingService::NelPolicy policy1 = MakeNelPolicy(
549 kNak1_, url::Origin::Create(GURL("https://www.foo.test")), now);
550 // Only has different host.
551 NetworkErrorLoggingService::NelPolicy policy2 = MakeNelPolicy(
552 kNak1_, url::Origin::Create(GURL("https://www.bar.test")), now);
553 // Only has different NetworkAnonymizationKey.
554 NetworkErrorLoggingService::NelPolicy policy3 = MakeNelPolicy(
555 kNak2_, url::Origin::Create(GURL("https://www.foo.test")), now);
556
557 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
558 base::WaitableEvent::InitialState::NOT_SIGNALED);
559
560 // Wedge the background thread to make sure it doesn't start consuming the
561 // queue.
562 background_task_runner_->PostTask(
563 FROM_HERE,
564 base::BindOnce(&SQLitePersistentReportingAndNelStoreTest::WaitOnEvent,
565 base::Unretained(this), &event));
566
567 // Delete on |policy2| and |policy3| should not cancel addition of unrelated
568 // |policy1|.
569 store_->AddNelPolicy(policy1);
570 store_->DeleteNelPolicy(policy2);
571 store_->DeleteNelPolicy(policy3);
572 EXPECT_EQ(3u, store_->GetQueueLengthForTesting());
573
574 event.Signal();
575 RunUntilIdle();
576 }
577
TEST_F(SQLitePersistentReportingAndNelStoreTest,DontPersistNelPoliciesWithTransientNetworkAnonymizationKeys)578 TEST_F(SQLitePersistentReportingAndNelStoreTest,
579 DontPersistNelPoliciesWithTransientNetworkAnonymizationKeys) {
580 CreateStore();
581 InitializeStore();
582
583 base::Time now = base::Time::Now();
584 NetworkErrorLoggingService::NelPolicy policy =
585 MakeNelPolicy(NetworkAnonymizationKey::CreateTransient(),
586 url::Origin::Create(GURL("https://www.foo.test")), now);
587
588 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
589 base::WaitableEvent::InitialState::NOT_SIGNALED);
590
591 // Wedge the background thread to make sure it doesn't start consuming the
592 // queue.
593 background_task_runner_->PostTask(
594 FROM_HERE,
595 base::BindOnce(&SQLitePersistentReportingAndNelStoreTest::WaitOnEvent,
596 base::Unretained(this), &event));
597
598 store_->AddNelPolicy(policy);
599 EXPECT_EQ(0u, store_->GetQueueLengthForTesting());
600 store_->UpdateNelPolicyAccessTime(policy);
601 EXPECT_EQ(0u, store_->GetQueueLengthForTesting());
602 store_->DeleteNelPolicy(policy);
603 EXPECT_EQ(0u, store_->GetQueueLengthForTesting());
604
605 event.Signal();
606 RunUntilIdle();
607
608 // Close and reopen the database.
609 DestroyStore();
610 CreateStore();
611
612 std::vector<NetworkErrorLoggingService::NelPolicy> policies;
613 LoadNelPolicies(&policies);
614 EXPECT_EQ(0u, policies.size());
615 }
616
TEST_F(SQLitePersistentReportingAndNelStoreTest,NelPoliciesRestoredWithNetworkAnonymizationKeysDisabled)617 TEST_F(SQLitePersistentReportingAndNelStoreTest,
618 NelPoliciesRestoredWithNetworkAnonymizationKeysDisabled) {
619 CreateStore();
620 InitializeStore();
621
622 base::Time now = base::Time::Now();
623 // Policy with non-empty NetworkAnonymizationKey.
624 NetworkErrorLoggingService::NelPolicy policy = MakeNelPolicy(
625 kNak1_, url::Origin::Create(GURL("https://www.foo.test")), now);
626
627 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
628 base::WaitableEvent::InitialState::NOT_SIGNALED);
629
630 // Wedge the background thread to make sure it doesn't start consuming the
631 // queue.
632 background_task_runner_->PostTask(
633 FROM_HERE,
634 base::BindOnce(&SQLitePersistentReportingAndNelStoreTest::WaitOnEvent,
635 base::Unretained(this), &event));
636
637 store_->AddNelPolicy(policy);
638 EXPECT_EQ(1u, store_->GetQueueLengthForTesting());
639
640 event.Signal();
641 RunUntilIdle();
642
643 // Close the database, disable kPartitionNelAndReportingByNetworkIsolationKey,
644 // and re-open it.
645 DestroyStore();
646 base::test::ScopedFeatureList feature_list;
647 feature_list.InitAndDisableFeature(
648 features::kPartitionNelAndReportingByNetworkIsolationKey);
649 CreateStore();
650 std::vector<NetworkErrorLoggingService::NelPolicy> policies;
651 LoadNelPolicies(&policies);
652
653 // No entries should be restored.
654 ASSERT_EQ(0u, policies.size());
655
656 // Now reload the store with kPartitionNelAndReportingByNetworkIsolationKey
657 // enabled again.
658 DestroyStore();
659 feature_list.Reset();
660 CreateStore();
661 LoadNelPolicies(&policies);
662
663 // The entry is back!
664 ASSERT_EQ(1u, policies.size());
665 EXPECT_EQ(policy.key, policies[0].key);
666 EXPECT_TRUE(WithinOneMicrosecond(policy.expires, policies[0].expires));
667 }
668
669 // These tests test that a SQLitePersistentReportingAndNelStore
670 // can be used by a NetworkErrorLoggingService to persist NEL policies.
671 class SQLitePersistNelTest : public SQLitePersistentReportingAndNelStoreTest {
672 public:
673 SQLitePersistNelTest() = default;
674
SetUp()675 void SetUp() override {
676 SQLitePersistentReportingAndNelStoreTest::SetUp();
677 SetUpNetworkErrorLoggingService();
678 }
679
TearDown()680 void TearDown() override {
681 service_->OnShutdown();
682 service_.reset();
683 reporting_service_.reset();
684 SQLitePersistentReportingAndNelStoreTest::TearDown();
685 }
686
SetUpNetworkErrorLoggingService()687 void SetUpNetworkErrorLoggingService() {
688 CreateStore();
689 service_ = NetworkErrorLoggingService::Create(store_.get());
690 reporting_service_ = std::make_unique<TestReportingService>();
691 service_->SetReportingService(reporting_service_.get());
692 service_->SetClockForTesting(&clock_);
693 }
694
SimulateRestart()695 void SimulateRestart() {
696 TearDown();
697 SetUpNetworkErrorLoggingService();
698 }
699
MakeRequestDetails(const NetworkAnonymizationKey & network_anonymization_key,const GURL & url,Error error_type)700 NetworkErrorLoggingService::RequestDetails MakeRequestDetails(
701 const NetworkAnonymizationKey& network_anonymization_key,
702 const GURL& url,
703 Error error_type) {
704 NetworkErrorLoggingService::RequestDetails details;
705
706 details.network_anonymization_key = network_anonymization_key;
707 details.uri = url;
708 details.referrer = GURL("https://referrer.com/");
709 details.user_agent = "Mozilla/1.0";
710 details.server_ip = kServerIP;
711 details.method = "GET";
712 details.status_code = 0;
713 details.elapsed_time = base::Seconds(1);
714 details.type = error_type;
715 details.reporting_upload_depth = 0;
716
717 return details;
718 }
719
720 protected:
721 base::SimpleTestClock clock_;
722 std::unique_ptr<NetworkErrorLoggingService> service_;
723 std::unique_ptr<TestReportingService> reporting_service_;
724 };
725
TEST_F(SQLitePersistNelTest,AddAndRetrieveNelPolicy)726 TEST_F(SQLitePersistNelTest, AddAndRetrieveNelPolicy) {
727 const GURL kUrl("https://www.foo.test");
728 const url::Origin kOrigin = url::Origin::Create(kUrl);
729 const NetworkErrorLoggingService::NelPolicyKey kKey(kNak1_, kOrigin);
730
731 service_->OnHeader(kNak1_, kOrigin, kServerIP, kHeader);
732 RunUntilIdle();
733
734 EXPECT_EQ(1u, service_->GetPolicyKeysForTesting().count(kKey));
735 SimulateRestart();
736
737 service_->OnRequest(MakeRequestDetails(kNak1_, kUrl, ERR_INVALID_RESPONSE));
738 RunUntilIdle();
739
740 EXPECT_EQ(1u, service_->GetPolicyKeysForTesting().count(kKey));
741
742 EXPECT_THAT(reporting_service_->reports(),
743 testing::ElementsAre(ReportUrlIs(kUrl)));
744 }
745
TEST_F(SQLitePersistNelTest,AddAndDeleteNelPolicy)746 TEST_F(SQLitePersistNelTest, AddAndDeleteNelPolicy) {
747 const GURL kUrl("https://www.foo.test");
748 const url::Origin kOrigin = url::Origin::Create(kUrl);
749 const NetworkErrorLoggingService::NelPolicyKey kKey(kNak1_, kOrigin);
750
751 service_->OnHeader(kNak1_, kOrigin, kServerIP, kHeader);
752 RunUntilIdle();
753
754 EXPECT_EQ(1u, service_->GetPolicyKeysForTesting().count(kKey));
755 SimulateRestart();
756
757 // Deletes the stored policy.
758 service_->OnHeader(kNak1_, kOrigin, kServerIP, kHeaderMaxAge0);
759 RunUntilIdle();
760
761 EXPECT_EQ(0u, service_->GetPolicyKeysForTesting().count(kKey));
762 SimulateRestart();
763
764 service_->OnRequest(MakeRequestDetails(kNak1_, kUrl, ERR_INVALID_RESPONSE));
765 RunUntilIdle();
766
767 EXPECT_EQ(0u, service_->GetPolicyKeysForTesting().count(kKey));
768 EXPECT_EQ(0u, reporting_service_->reports().size());
769 }
770
TEST_F(SQLitePersistNelTest,ExpirationTimeIsPersisted)771 TEST_F(SQLitePersistNelTest, ExpirationTimeIsPersisted) {
772 const GURL kUrl("https://www.foo.test");
773 const url::Origin kOrigin = url::Origin::Create(kUrl);
774 const NetworkAnonymizationKey kNak;
775
776 service_->OnHeader(kNak, kOrigin, kServerIP, kHeader);
777 RunUntilIdle();
778
779 // Makes the policy we just added expired.
780 clock_.Advance(base::Seconds(86401));
781
782 SimulateRestart();
783
784 service_->OnRequest(MakeRequestDetails(kNak, kUrl, ERR_INVALID_RESPONSE));
785 RunUntilIdle();
786
787 EXPECT_EQ(0u, reporting_service_->reports().size());
788
789 // Add the policy again so that it is not expired.
790 service_->OnHeader(kNak, kOrigin, kServerIP, kHeader);
791
792 SimulateRestart();
793
794 service_->OnRequest(MakeRequestDetails(kNak, kUrl, ERR_INVALID_RESPONSE));
795 RunUntilIdle();
796
797 EXPECT_THAT(reporting_service_->reports(),
798 testing::ElementsAre(ReportUrlIs(kUrl)));
799 }
800
TEST_F(SQLitePersistNelTest,OnRequestUpdatesAccessTime)801 TEST_F(SQLitePersistNelTest, OnRequestUpdatesAccessTime) {
802 const GURL kUrl("https://www.foo.test");
803 const url::Origin kOrigin = url::Origin::Create(kUrl);
804
805 service_->OnHeader(kNak1_, kOrigin, kServerIP, kHeader);
806 RunUntilIdle();
807
808 SimulateRestart();
809
810 // Update the access time by sending a request.
811 clock_.Advance(base::Seconds(100));
812 service_->OnRequest(MakeRequestDetails(kNak1_, kUrl, ERR_INVALID_RESPONSE));
813 RunUntilIdle();
814
815 EXPECT_THAT(reporting_service_->reports(),
816 testing::ElementsAre(ReportUrlIs(kUrl)));
817
818 SimulateRestart();
819 // Check that the policy's access time has been updated.
820 base::Time now = clock_.Now();
821 NetworkErrorLoggingService::NelPolicy policy =
822 MakeNelPolicy(kNak1_, kOrigin, now);
823 std::vector<NetworkErrorLoggingService::NelPolicy> policies;
824 LoadNelPolicies(&policies);
825 ASSERT_EQ(1u, policies.size());
826 EXPECT_EQ(policy.key, policies[0].key);
827 EXPECT_TRUE(WithinOneMicrosecond(policy.last_used, policies[0].last_used));
828 }
829
TEST_F(SQLitePersistNelTest,RemoveSomeBrowsingData)830 TEST_F(SQLitePersistNelTest, RemoveSomeBrowsingData) {
831 const GURL kUrl1("https://www.foo.test");
832 const url::Origin kOrigin1 = url::Origin::Create(kUrl1);
833 const url::Origin kOrigin2 =
834 url::Origin::Create(GURL("https://www.bar.test"));
835 const NetworkErrorLoggingService::NelPolicyKey kKey1(kNak1_, kOrigin1);
836 const NetworkErrorLoggingService::NelPolicyKey kKey2(kNak2_, kOrigin2);
837
838 service_->OnHeader(kNak1_, kOrigin1, kServerIP, kHeader);
839 service_->OnHeader(kNak2_, kOrigin2, kServerIP, kHeader);
840 RunUntilIdle();
841
842 SimulateRestart();
843
844 service_->OnRequest(MakeRequestDetails(kNak1_, kUrl1, ERR_INVALID_RESPONSE));
845 RunUntilIdle();
846
847 ASSERT_EQ(1u, service_->GetPolicyKeysForTesting().count(kKey1));
848 ASSERT_EQ(1u, service_->GetPolicyKeysForTesting().count(kKey2));
849 EXPECT_THAT(reporting_service_->reports(),
850 testing::ElementsAre(ReportUrlIs(kUrl1)));
851
852 SimulateRestart();
853
854 service_->RemoveBrowsingData(base::BindRepeating(
855 [](const std::string& host, const url::Origin& origin) {
856 return origin.host() == host;
857 },
858 kOrigin1.host()));
859 RunUntilIdle();
860
861 EXPECT_EQ(0u, service_->GetPolicyKeysForTesting().count(kKey1));
862 EXPECT_EQ(1u, service_->GetPolicyKeysForTesting().count(kKey2));
863
864 SimulateRestart();
865
866 service_->OnRequest(MakeRequestDetails(kNak1_, kUrl1, ERR_INVALID_RESPONSE));
867 RunUntilIdle();
868 EXPECT_EQ(0u, service_->GetPolicyKeysForTesting().count(kKey1));
869 EXPECT_EQ(1u, service_->GetPolicyKeysForTesting().count(kKey2));
870 EXPECT_EQ(0u, reporting_service_->reports().size());
871 }
872
TEST_F(SQLitePersistNelTest,RemoveAllBrowsingData)873 TEST_F(SQLitePersistNelTest, RemoveAllBrowsingData) {
874 const GURL kUrl1("https://www.foo.test");
875 const url::Origin kOrigin1 = url::Origin::Create(kUrl1);
876 const GURL kUrl2("https://www.bar.test");
877 const url::Origin kOrigin2 = url::Origin::Create(kUrl2);
878 const NetworkErrorLoggingService::NelPolicyKey kKey1(kNak1_, kOrigin1);
879 const NetworkErrorLoggingService::NelPolicyKey kKey2(kNak2_, kOrigin2);
880
881 service_->OnHeader(kNak1_, kOrigin1, kServerIP, kHeader);
882 service_->OnHeader(kNak2_, kOrigin2, kServerIP, kHeader);
883 RunUntilIdle();
884
885 SimulateRestart();
886
887 service_->OnRequest(MakeRequestDetails(kNak1_, kUrl1, ERR_INVALID_RESPONSE));
888 service_->OnRequest(MakeRequestDetails(kNak2_, kUrl2, ERR_INVALID_RESPONSE));
889 RunUntilIdle();
890
891 ASSERT_EQ(1u, service_->GetPolicyKeysForTesting().count(kKey1));
892 ASSERT_EQ(1u, service_->GetPolicyKeysForTesting().count(kKey2));
893 EXPECT_THAT(reporting_service_->reports(),
894 testing::ElementsAre(ReportUrlIs(kUrl1), ReportUrlIs(kUrl2)));
895
896 SimulateRestart();
897
898 service_->RemoveAllBrowsingData();
899 RunUntilIdle();
900
901 EXPECT_EQ(0u, service_->GetPolicyKeysForTesting().count(kKey1));
902 EXPECT_EQ(0u, service_->GetPolicyKeysForTesting().count(kKey2));
903
904 SimulateRestart();
905
906 service_->OnRequest(MakeRequestDetails(kNak1_, kUrl1, ERR_INVALID_RESPONSE));
907 service_->OnRequest(MakeRequestDetails(kNak2_, kUrl2, ERR_INVALID_RESPONSE));
908 RunUntilIdle();
909 EXPECT_EQ(0u, service_->GetPolicyKeysForTesting().count(kKey1));
910 EXPECT_EQ(0u, service_->GetPolicyKeysForTesting().count(kKey2));
911 EXPECT_EQ(0u, reporting_service_->reports().size());
912 }
913
TEST_F(SQLitePersistentReportingAndNelStoreTest,PersistReportingClients)914 TEST_F(SQLitePersistentReportingAndNelStoreTest, PersistReportingClients) {
915 const url::Origin kOrigin = url::Origin::Create(GURL("https://www.foo.test"));
916
917 CreateStore();
918 InitializeStore();
919 base::Time now = base::Time::Now();
920 ReportingEndpoint endpoint = MakeReportingEndpoint(
921 kNak1_, kOrigin, kGroupName1, GURL("https://endpoint.test/1"));
922 CachedReportingEndpointGroup group =
923 MakeReportingEndpointGroup(kNak1_, kOrigin, kGroupName1, now);
924
925 store_->AddReportingEndpoint(endpoint);
926 store_->AddReportingEndpointGroup(group);
927
928 // Close and reopen the database.
929 DestroyStore();
930 CreateStore();
931
932 // Load the stored clients.
933 std::vector<ReportingEndpoint> endpoints;
934 std::vector<CachedReportingEndpointGroup> groups;
935 LoadReportingClients(&endpoints, &groups);
936 ASSERT_EQ(1u, endpoints.size());
937 EXPECT_EQ(endpoint.group_key.network_anonymization_key,
938 endpoints[0].group_key.network_anonymization_key);
939 EXPECT_EQ(endpoint.group_key.origin, endpoints[0].group_key.origin);
940 EXPECT_EQ(endpoint.group_key.group_name, endpoints[0].group_key.group_name);
941 EXPECT_EQ(endpoint.info.url, endpoints[0].info.url);
942 EXPECT_EQ(endpoint.info.priority, endpoints[0].info.priority);
943 EXPECT_EQ(endpoint.info.weight, endpoints[0].info.weight);
944 ASSERT_EQ(1u, groups.size());
945 EXPECT_EQ(group.group_key.network_anonymization_key,
946 groups[0].group_key.network_anonymization_key);
947 EXPECT_EQ(group.group_key.origin, groups[0].group_key.origin);
948 EXPECT_EQ(group.group_key.group_name, groups[0].group_key.group_name);
949 EXPECT_EQ(group.include_subdomains, groups[0].include_subdomains);
950 EXPECT_TRUE(WithinOneMicrosecond(group.expires, groups[0].expires));
951 EXPECT_TRUE(WithinOneMicrosecond(group.last_used, groups[0].last_used));
952 }
953
TEST_F(SQLitePersistentReportingAndNelStoreTest,UpdateReportingEndpointGroupAccessTime)954 TEST_F(SQLitePersistentReportingAndNelStoreTest,
955 UpdateReportingEndpointGroupAccessTime) {
956 CreateStore();
957 InitializeStore();
958 base::Time now = base::Time::Now();
959 CachedReportingEndpointGroup group = MakeReportingEndpointGroup(
960 kNak1_, url::Origin::Create(GURL("https://www.foo.test")), kGroupName1,
961 now);
962
963 store_->AddReportingEndpointGroup(group);
964
965 group.last_used = now + base::Days(1);
966 store_->UpdateReportingEndpointGroupAccessTime(group);
967
968 // Close and reopen the database.
969 DestroyStore();
970 CreateStore();
971
972 std::vector<ReportingEndpoint> endpoints;
973 std::vector<CachedReportingEndpointGroup> groups;
974 LoadReportingClients(&endpoints, &groups);
975 ASSERT_EQ(1u, groups.size());
976 EXPECT_EQ(group.group_key.network_anonymization_key,
977 groups[0].group_key.network_anonymization_key);
978 EXPECT_EQ(group.group_key.origin, groups[0].group_key.origin);
979 EXPECT_EQ(group.group_key.group_name, groups[0].group_key.group_name);
980 EXPECT_TRUE(WithinOneMicrosecond(group.last_used, groups[0].last_used));
981 }
982
TEST_F(SQLitePersistentReportingAndNelStoreTest,UpdateReportingEndpointDetails)983 TEST_F(SQLitePersistentReportingAndNelStoreTest,
984 UpdateReportingEndpointDetails) {
985 CreateStore();
986 InitializeStore();
987 ReportingEndpoint endpoint = MakeReportingEndpoint(
988 kNak1_, url::Origin::Create(GURL("https://www.foo.test")), kGroupName1,
989 GURL("https://endpoint.test/1"));
990
991 store_->AddReportingEndpoint(endpoint);
992
993 endpoint.info.priority = 10;
994 endpoint.info.weight = 10;
995 store_->UpdateReportingEndpointDetails(endpoint);
996
997 // Close and reopen the database.
998 DestroyStore();
999 CreateStore();
1000
1001 std::vector<ReportingEndpoint> endpoints;
1002 std::vector<CachedReportingEndpointGroup> groups;
1003 LoadReportingClients(&endpoints, &groups);
1004 ASSERT_EQ(1u, endpoints.size());
1005 EXPECT_EQ(endpoint.group_key.network_anonymization_key,
1006 endpoints[0].group_key.network_anonymization_key);
1007 EXPECT_EQ(endpoint.group_key.origin, endpoints[0].group_key.origin);
1008 EXPECT_EQ(endpoint.group_key.group_name, endpoints[0].group_key.group_name);
1009 EXPECT_EQ(endpoint.info.url, endpoints[0].info.url);
1010 EXPECT_EQ(endpoint.info.priority, endpoints[0].info.priority);
1011 EXPECT_EQ(endpoint.info.weight, endpoints[0].info.weight);
1012 }
1013
TEST_F(SQLitePersistentReportingAndNelStoreTest,UpdateReportingEndpointGroupDetails)1014 TEST_F(SQLitePersistentReportingAndNelStoreTest,
1015 UpdateReportingEndpointGroupDetails) {
1016 CreateStore();
1017 InitializeStore();
1018 base::Time now = base::Time::Now();
1019 CachedReportingEndpointGroup group = MakeReportingEndpointGroup(
1020 kNak1_, url::Origin::Create(GURL("https://www.foo.test")), kGroupName1,
1021 now, OriginSubdomains::EXCLUDE, kExpires);
1022
1023 store_->AddReportingEndpointGroup(group);
1024
1025 group.last_used = now + base::Days(1);
1026 group.expires = kExpires + base::Days(1);
1027 group.include_subdomains = OriginSubdomains::INCLUDE;
1028 store_->UpdateReportingEndpointGroupDetails(group);
1029
1030 // Close and reopen the database.
1031 DestroyStore();
1032 CreateStore();
1033
1034 std::vector<ReportingEndpoint> endpoints;
1035 std::vector<CachedReportingEndpointGroup> groups;
1036 LoadReportingClients(&endpoints, &groups);
1037 ASSERT_EQ(1u, groups.size());
1038 EXPECT_EQ(group.group_key.network_anonymization_key,
1039 groups[0].group_key.network_anonymization_key);
1040 EXPECT_EQ(group.group_key.origin, groups[0].group_key.origin);
1041 EXPECT_EQ(group.group_key.group_name, groups[0].group_key.group_name);
1042 EXPECT_EQ(group.include_subdomains, groups[0].include_subdomains);
1043 EXPECT_TRUE(WithinOneMicrosecond(group.expires, groups[0].expires));
1044 EXPECT_TRUE(WithinOneMicrosecond(group.last_used, groups[0].last_used));
1045 }
1046
TEST_F(SQLitePersistentReportingAndNelStoreTest,DeleteReportingEndpoint)1047 TEST_F(SQLitePersistentReportingAndNelStoreTest, DeleteReportingEndpoint) {
1048 CreateStore();
1049 InitializeStore();
1050 ReportingEndpoint endpoint1 = MakeReportingEndpoint(
1051 kNak1_, url::Origin::Create(GURL("https://www.foo.test")), kGroupName1,
1052 GURL("https://endpoint.test/1"));
1053 ReportingEndpoint endpoint2 = MakeReportingEndpoint(
1054 kNak2_, url::Origin::Create(GURL("https://www.bar.test")), kGroupName2,
1055 GURL("https://endpoint.test/2"));
1056
1057 store_->AddReportingEndpoint(endpoint1);
1058 store_->AddReportingEndpoint(endpoint2);
1059
1060 store_->DeleteReportingEndpoint(endpoint1);
1061
1062 // Close and reopen the database.
1063 DestroyStore();
1064 CreateStore();
1065
1066 std::vector<ReportingEndpoint> endpoints;
1067 std::vector<CachedReportingEndpointGroup> groups;
1068 LoadReportingClients(&endpoints, &groups);
1069 ASSERT_EQ(1u, endpoints.size());
1070 EXPECT_EQ(endpoint2.info.url, endpoints[0].info.url);
1071
1072 store_->DeleteReportingEndpoint(endpoint2);
1073 DestroyStore();
1074 CreateStore();
1075
1076 endpoints.clear();
1077 LoadReportingClients(&endpoints, &groups);
1078 EXPECT_EQ(0u, endpoints.size());
1079 }
1080
TEST_F(SQLitePersistentReportingAndNelStoreTest,DeleteReportingEndpointGroup)1081 TEST_F(SQLitePersistentReportingAndNelStoreTest, DeleteReportingEndpointGroup) {
1082 CreateStore();
1083 InitializeStore();
1084 base::Time now = base::Time::Now();
1085 CachedReportingEndpointGroup group1 = MakeReportingEndpointGroup(
1086 kNak1_, url::Origin::Create(GURL("https://www.foo.test")), kGroupName1,
1087 now);
1088 CachedReportingEndpointGroup group2 = MakeReportingEndpointGroup(
1089 kNak2_, url::Origin::Create(GURL("https://www.bar.test")), kGroupName2,
1090 now);
1091
1092 store_->AddReportingEndpointGroup(group1);
1093 store_->AddReportingEndpointGroup(group2);
1094
1095 store_->DeleteReportingEndpointGroup(group1);
1096
1097 // Close and reopen the database.
1098 DestroyStore();
1099 CreateStore();
1100
1101 std::vector<ReportingEndpoint> endpoints;
1102 std::vector<CachedReportingEndpointGroup> groups;
1103 LoadReportingClients(&endpoints, &groups);
1104 ASSERT_EQ(1u, groups.size());
1105 EXPECT_EQ(group2.group_key.group_name, groups[0].group_key.group_name);
1106
1107 store_->DeleteReportingEndpointGroup(group2);
1108 DestroyStore();
1109 CreateStore();
1110
1111 groups.clear();
1112 LoadReportingClients(&endpoints, &groups);
1113 EXPECT_EQ(0u, groups.size());
1114 }
1115
TEST_F(SQLitePersistentReportingAndNelStoreTest,ReportingEndpointUniquenessConstraint)1116 TEST_F(SQLitePersistentReportingAndNelStoreTest,
1117 ReportingEndpointUniquenessConstraint) {
1118 const url::Origin kOrigin1 =
1119 url::Origin::Create(GURL("https://www.bar.test"));
1120 const url::Origin kOrigin2 =
1121 url::Origin::Create(GURL("https://www.foo.test"));
1122 const GURL kEndpoint("https://endpoint.test/1");
1123
1124 CreateStore();
1125 InitializeStore();
1126
1127 // Add 3 entries, 2 identical except for NAK, 2 identical except for origin.
1128 // Entries should not conflict with each other. These are added in lexical
1129 // order.
1130 ReportingEndpoint endpoint1 =
1131 MakeReportingEndpoint(kNak1_, kOrigin1, kGroupName1, kEndpoint,
1132 1 /* priority */, 1 /* weight */);
1133 ReportingEndpoint endpoint2 =
1134 MakeReportingEndpoint(kNak1_, kOrigin2, kGroupName1, kEndpoint,
1135 2 /* priority */, 2 /* weight */);
1136 ReportingEndpoint endpoint3 =
1137 MakeReportingEndpoint(kNak2_, kOrigin2, kGroupName1, kEndpoint,
1138 3 /* priority */, 3 /* weight */);
1139 store_->AddReportingEndpoint(endpoint1);
1140 store_->AddReportingEndpoint(endpoint2);
1141 store_->AddReportingEndpoint(endpoint3);
1142
1143 // Add entries that are identical except for expiration time. These should
1144 // trigger a warning an fail to execute.
1145 ReportingEndpoint endpoint4 =
1146 MakeReportingEndpoint(kNak1_, kOrigin1, kGroupName1, kEndpoint,
1147 4 /* priority */, 4 /* weight */);
1148 ReportingEndpoint endpoint5 =
1149 MakeReportingEndpoint(kNak1_, kOrigin2, kGroupName1, kEndpoint,
1150 5 /* priority */, 5 /* weight */);
1151 ReportingEndpoint endpoint6 =
1152 MakeReportingEndpoint(kNak2_, kOrigin2, kGroupName1, kEndpoint,
1153 6 /* priority */, 6 /* weight */);
1154 store_->AddReportingEndpoint(endpoint4);
1155 store_->AddReportingEndpoint(endpoint5);
1156 store_->AddReportingEndpoint(endpoint6);
1157
1158 DestroyStore();
1159 CreateStore();
1160
1161 std::vector<ReportingEndpoint> endpoints;
1162 std::vector<CachedReportingEndpointGroup> groups;
1163 LoadReportingClients(&endpoints, &groups);
1164
1165 // Only the first 3 endpoints should be in the store.
1166
1167 ASSERT_EQ(3u, endpoints.size());
1168
1169 EXPECT_EQ(endpoint1.group_key, endpoints[0].group_key);
1170 EXPECT_EQ(endpoint1.info.url, endpoints[0].info.url);
1171 EXPECT_EQ(endpoint1.info.priority, endpoints[0].info.priority);
1172 EXPECT_EQ(endpoint1.info.weight, endpoints[0].info.weight);
1173
1174 EXPECT_EQ(endpoint2.group_key, endpoints[1].group_key);
1175 EXPECT_EQ(endpoint2.info.url, endpoints[1].info.url);
1176 EXPECT_EQ(endpoint2.info.priority, endpoints[1].info.priority);
1177 EXPECT_EQ(endpoint2.info.weight, endpoints[1].info.weight);
1178
1179 EXPECT_EQ(endpoint3.group_key, endpoints[2].group_key);
1180 EXPECT_EQ(endpoint3.info.url, endpoints[2].info.url);
1181 EXPECT_EQ(endpoint3.info.priority, endpoints[2].info.priority);
1182 EXPECT_EQ(endpoint3.info.weight, endpoints[2].info.weight);
1183 }
1184
TEST_F(SQLitePersistentReportingAndNelStoreTest,ReportingEndpointGroupUniquenessConstraint)1185 TEST_F(SQLitePersistentReportingAndNelStoreTest,
1186 ReportingEndpointGroupUniquenessConstraint) {
1187 const url::Origin kOrigin1 =
1188 url::Origin::Create(GURL("https://www.bar.test"));
1189 const url::Origin kOrigin2 =
1190 url::Origin::Create(GURL("https://www.foo.test"));
1191
1192 CreateStore();
1193 InitializeStore();
1194
1195 base::Time now = base::Time::Now();
1196 base::Time later = now + base::Days(7);
1197
1198 // Add 3 entries, 2 identical except for NAK, 2 identical except for origin.
1199 // Entries should not conflict with each other. These are added in lexical
1200 // order.
1201 CachedReportingEndpointGroup group1 =
1202 MakeReportingEndpointGroup(kNak1_, kOrigin1, kGroupName1, now);
1203 CachedReportingEndpointGroup group2 =
1204 MakeReportingEndpointGroup(kNak1_, kOrigin2, kGroupName1, now);
1205 CachedReportingEndpointGroup group3 =
1206 MakeReportingEndpointGroup(kNak2_, kOrigin1, kGroupName1, now);
1207 store_->AddReportingEndpointGroup(group1);
1208 store_->AddReportingEndpointGroup(group2);
1209 store_->AddReportingEndpointGroup(group3);
1210
1211 // Add entries that are identical except for expiration time. These should
1212 // trigger a warning an fail to execute.
1213 CachedReportingEndpointGroup group4 =
1214 MakeReportingEndpointGroup(kNak1_, kOrigin1, kGroupName1, later);
1215 CachedReportingEndpointGroup group5 =
1216 MakeReportingEndpointGroup(kNak1_, kOrigin2, kGroupName1, later);
1217 CachedReportingEndpointGroup group6 =
1218 MakeReportingEndpointGroup(kNak2_, kOrigin1, kGroupName1, later);
1219 store_->AddReportingEndpointGroup(group4);
1220 store_->AddReportingEndpointGroup(group5);
1221 store_->AddReportingEndpointGroup(group6);
1222
1223 DestroyStore();
1224 CreateStore();
1225
1226 std::vector<ReportingEndpoint> endpoints;
1227 std::vector<CachedReportingEndpointGroup> groups;
1228 LoadReportingClients(&endpoints, &groups);
1229
1230 // Only the first 3 endpoints should be in the store.
1231
1232 ASSERT_EQ(3u, groups.size());
1233
1234 EXPECT_EQ(group1.group_key, groups[0].group_key);
1235 EXPECT_EQ(group1.include_subdomains, groups[0].include_subdomains);
1236 EXPECT_TRUE(WithinOneMicrosecond(group1.expires, groups[0].expires));
1237 EXPECT_TRUE(WithinOneMicrosecond(group1.last_used, groups[0].last_used));
1238
1239 EXPECT_EQ(group2.group_key, groups[1].group_key);
1240 EXPECT_EQ(group2.include_subdomains, groups[1].include_subdomains);
1241 EXPECT_TRUE(WithinOneMicrosecond(group2.expires, groups[1].expires));
1242 EXPECT_TRUE(WithinOneMicrosecond(group2.last_used, groups[1].last_used));
1243
1244 EXPECT_EQ(group3.group_key, groups[2].group_key);
1245 EXPECT_EQ(group3.include_subdomains, groups[2].include_subdomains);
1246 EXPECT_TRUE(WithinOneMicrosecond(group3.expires, groups[2].expires));
1247 EXPECT_TRUE(WithinOneMicrosecond(group3.last_used, groups[2].last_used));
1248 }
1249
TEST_F(SQLitePersistentReportingAndNelStoreTest,CoalesceReportingEndpointOperations)1250 TEST_F(SQLitePersistentReportingAndNelStoreTest,
1251 CoalesceReportingEndpointOperations) {
1252 ReportingEndpoint endpoint = MakeReportingEndpoint(
1253 kNak1_, url::Origin::Create(GURL("https://www.foo.test")), kGroupName1,
1254 GURL("https://endpoint.test/1"));
1255
1256 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1257 base::WaitableEvent::InitialState::NOT_SIGNALED);
1258
1259 for (const TestCase& testcase : kCoalescingTestcases) {
1260 CreateStore();
1261 base::RunLoop run_loop;
1262 store_->LoadReportingClients(base::BindLambdaForTesting(
1263 [&](std::vector<ReportingEndpoint>,
1264 std::vector<CachedReportingEndpointGroup>) { run_loop.Quit(); }));
1265 run_loop.Run();
1266
1267 // Wedge the background thread to make sure it doesn't start consuming the
1268 // queue.
1269 background_task_runner_->PostTask(
1270 FROM_HERE,
1271 base::BindOnce(&SQLitePersistentReportingAndNelStoreTest::WaitOnEvent,
1272 base::Unretained(this), &event));
1273
1274 // Now run the ops, and check how much gets queued.
1275 for (const Op op : testcase.operations) {
1276 switch (op) {
1277 case Op::kAdd:
1278 store_->AddReportingEndpoint(endpoint);
1279 break;
1280
1281 case Op::kDelete:
1282 store_->DeleteReportingEndpoint(endpoint);
1283 break;
1284
1285 case Op::kUpdate:
1286 // Endpoints only have UPDATE_DETAILS, so in this case we use kUpdate
1287 // for that.
1288 store_->UpdateReportingEndpointDetails(endpoint);
1289 break;
1290
1291 default:
1292 NOTREACHED();
1293 break;
1294 }
1295 }
1296
1297 EXPECT_EQ(testcase.expected_queue_length,
1298 store_->GetQueueLengthForTesting());
1299
1300 event.Signal();
1301 RunUntilIdle();
1302 }
1303 }
1304
TEST_F(SQLitePersistentReportingAndNelStoreTest,DontCoalesceUnrelatedReportingEndpoints)1305 TEST_F(SQLitePersistentReportingAndNelStoreTest,
1306 DontCoalesceUnrelatedReportingEndpoints) {
1307 CreateStore();
1308 InitializeStore();
1309
1310 ReportingEndpoint endpoint1 = MakeReportingEndpoint(
1311 kNak1_, url::Origin::Create(GURL("https://www.foo.test")), kGroupName1,
1312 GURL("https://endpoint.test/1"));
1313 // Only has different host.
1314 ReportingEndpoint endpoint2 = MakeReportingEndpoint(
1315 kNak1_, url::Origin::Create(GURL("https://www.bar.test")), kGroupName1,
1316 GURL("https://endpoint.test/2"));
1317 // Only has different NetworkAnonymizationKey.
1318 ReportingEndpoint endpoint3 = MakeReportingEndpoint(
1319 kNak2_, url::Origin::Create(GURL("https://www.foo.test")), kGroupName1,
1320 GURL("https://endpoint.test/3"));
1321
1322 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1323 base::WaitableEvent::InitialState::NOT_SIGNALED);
1324
1325 // Wedge the background thread to make sure it doesn't start consuming the
1326 // queue.
1327 background_task_runner_->PostTask(
1328 FROM_HERE,
1329 base::BindOnce(&SQLitePersistentReportingAndNelStoreTest::WaitOnEvent,
1330 base::Unretained(this), &event));
1331
1332 // Delete on |endpoint2| and |endpoint3| should not cancel addition of
1333 // unrelated |endpoint1|.
1334 store_->AddReportingEndpoint(endpoint1);
1335 store_->DeleteReportingEndpoint(endpoint2);
1336 store_->DeleteReportingEndpoint(endpoint3);
1337 EXPECT_EQ(3u, store_->GetQueueLengthForTesting());
1338
1339 event.Signal();
1340 RunUntilIdle();
1341 }
1342
TEST_F(SQLitePersistentReportingAndNelStoreTest,CoalesceReportingEndpointGroupOperations)1343 TEST_F(SQLitePersistentReportingAndNelStoreTest,
1344 CoalesceReportingEndpointGroupOperations) {
1345 base::Time now = base::Time::Now();
1346 CachedReportingEndpointGroup group = MakeReportingEndpointGroup(
1347 kNak1_, url::Origin::Create(GURL("https://www.foo.test")), kGroupName1,
1348 now);
1349
1350 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1351 base::WaitableEvent::InitialState::NOT_SIGNALED);
1352
1353 for (const TestCase& testcase : kCoalescingTestcases) {
1354 CreateStore();
1355 base::RunLoop run_loop;
1356 store_->LoadReportingClients(base::BindLambdaForTesting(
1357 [&](std::vector<ReportingEndpoint>,
1358 std::vector<CachedReportingEndpointGroup>) { run_loop.Quit(); }));
1359 run_loop.Run();
1360
1361 // Wedge the background thread to make sure it doesn't start consuming the
1362 // queue.
1363 background_task_runner_->PostTask(
1364 FROM_HERE,
1365 base::BindOnce(&SQLitePersistentReportingAndNelStoreTest::WaitOnEvent,
1366 base::Unretained(this), &event));
1367
1368 // Now run the ops, and check how much gets queued.
1369 for (const Op op : testcase.operations) {
1370 switch (op) {
1371 case Op::kAdd:
1372 store_->AddReportingEndpointGroup(group);
1373 break;
1374
1375 case Op::kDelete:
1376 store_->DeleteReportingEndpointGroup(group);
1377 break;
1378
1379 case Op::kUpdate:
1380 store_->UpdateReportingEndpointGroupAccessTime(group);
1381 break;
1382
1383 default:
1384 NOTREACHED();
1385 break;
1386 }
1387 }
1388
1389 EXPECT_EQ(testcase.expected_queue_length,
1390 store_->GetQueueLengthForTesting());
1391
1392 event.Signal();
1393 RunUntilIdle();
1394 }
1395
1396 // Additional test cases for UPDATE_DETAILS.
1397 for (const TestCase& testcase : kCoalescingTestcasesForUpdateDetails) {
1398 CreateStore();
1399 base::RunLoop run_loop;
1400 store_->LoadReportingClients(base::BindLambdaForTesting(
1401 [&](std::vector<ReportingEndpoint>,
1402 std::vector<CachedReportingEndpointGroup>) { run_loop.Quit(); }));
1403 run_loop.Run();
1404
1405 // Wedge the background thread to make sure it doesn't start consuming the
1406 // queue.
1407 background_task_runner_->PostTask(
1408 FROM_HERE,
1409 base::BindOnce(&SQLitePersistentReportingAndNelStoreTest::WaitOnEvent,
1410 base::Unretained(this), &event));
1411
1412 // Now run the ops, and check how much gets queued.
1413 for (const Op op : testcase.operations) {
1414 switch (op) {
1415 case Op::kAdd:
1416 store_->AddReportingEndpointGroup(group);
1417 break;
1418
1419 case Op::kDelete:
1420 store_->DeleteReportingEndpointGroup(group);
1421 break;
1422
1423 case Op::kUpdate:
1424 store_->UpdateReportingEndpointGroupAccessTime(group);
1425 break;
1426
1427 case Op::kUpdateDetails:
1428 store_->UpdateReportingEndpointGroupDetails(group);
1429 break;
1430 }
1431 }
1432
1433 EXPECT_EQ(testcase.expected_queue_length,
1434 store_->GetQueueLengthForTesting());
1435
1436 event.Signal();
1437 RunUntilIdle();
1438 }
1439 }
1440
TEST_F(SQLitePersistentReportingAndNelStoreTest,DontCoalesceUnrelatedReportingEndpointGroups)1441 TEST_F(SQLitePersistentReportingAndNelStoreTest,
1442 DontCoalesceUnrelatedReportingEndpointGroups) {
1443 CreateStore();
1444 InitializeStore();
1445
1446 base::Time now = base::Time::Now();
1447 CachedReportingEndpointGroup group1 = MakeReportingEndpointGroup(
1448 kNak1_, url::Origin::Create(GURL("https://www.foo.test")), kGroupName1,
1449 now);
1450 // Only has different host.
1451 CachedReportingEndpointGroup group2 = MakeReportingEndpointGroup(
1452 kNak1_, url::Origin::Create(GURL("https://www.bar.test")), kGroupName1,
1453 now);
1454 // Only has different NetworkAnonymizationKey.
1455 CachedReportingEndpointGroup group3 = MakeReportingEndpointGroup(
1456 kNak2_, url::Origin::Create(GURL("https://www.foo.test")), kGroupName1,
1457 now);
1458
1459 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1460 base::WaitableEvent::InitialState::NOT_SIGNALED);
1461
1462 // Wedge the background thread to make sure it doesn't start consuming the
1463 // queue.
1464 background_task_runner_->PostTask(
1465 FROM_HERE,
1466 base::BindOnce(&SQLitePersistentReportingAndNelStoreTest::WaitOnEvent,
1467 base::Unretained(this), &event));
1468
1469 // Delete on |group2| and |group3| should not cancel addition of unrelated
1470 // |group1|.
1471 store_->AddReportingEndpointGroup(group1);
1472 store_->DeleteReportingEndpointGroup(group2);
1473 store_->DeleteReportingEndpointGroup(group3);
1474 EXPECT_EQ(3u, store_->GetQueueLengthForTesting());
1475
1476 event.Signal();
1477 RunUntilIdle();
1478 }
1479
TEST_F(SQLitePersistentReportingAndNelStoreTest,DontPersistReportingEndpointsWithTransientNetworkAnonymizationKeys)1480 TEST_F(SQLitePersistentReportingAndNelStoreTest,
1481 DontPersistReportingEndpointsWithTransientNetworkAnonymizationKeys) {
1482 CreateStore();
1483 InitializeStore();
1484
1485 ReportingEndpoint endpoint =
1486 MakeReportingEndpoint(NetworkAnonymizationKey::CreateTransient(),
1487 url::Origin::Create(GURL("https://www.foo.test")),
1488 kGroupName1, GURL("https://endpoint.test/1"));
1489
1490 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1491 base::WaitableEvent::InitialState::NOT_SIGNALED);
1492
1493 // Wedge the background thread to make sure it doesn't start consuming the
1494 // queue.
1495 background_task_runner_->PostTask(
1496 FROM_HERE,
1497 base::BindOnce(&SQLitePersistentReportingAndNelStoreTest::WaitOnEvent,
1498 base::Unretained(this), &event));
1499
1500 store_->AddReportingEndpoint(endpoint);
1501 EXPECT_EQ(0u, store_->GetQueueLengthForTesting());
1502 store_->UpdateReportingEndpointDetails(endpoint);
1503 EXPECT_EQ(0u, store_->GetQueueLengthForTesting());
1504 store_->DeleteReportingEndpoint(endpoint);
1505 EXPECT_EQ(0u, store_->GetQueueLengthForTesting());
1506
1507 event.Signal();
1508 RunUntilIdle();
1509
1510 // Close and reopen the database.
1511 DestroyStore();
1512 CreateStore();
1513
1514 std::vector<ReportingEndpoint> endpoints;
1515 std::vector<CachedReportingEndpointGroup> groups;
1516 LoadReportingClients(&endpoints, &groups);
1517 ASSERT_EQ(0u, endpoints.size());
1518 }
1519
TEST_F(SQLitePersistentReportingAndNelStoreTest,DontPersistReportingEndpointGroupsWithTransientNetworkAnonymizationKeys)1520 TEST_F(
1521 SQLitePersistentReportingAndNelStoreTest,
1522 DontPersistReportingEndpointGroupsWithTransientNetworkAnonymizationKeys) {
1523 CreateStore();
1524 InitializeStore();
1525
1526 base::Time now = base::Time::Now();
1527 CachedReportingEndpointGroup group = MakeReportingEndpointGroup(
1528 NetworkAnonymizationKey::CreateTransient(),
1529 url::Origin::Create(GURL("https://www.foo.test")), kGroupName1, now);
1530
1531 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1532 base::WaitableEvent::InitialState::NOT_SIGNALED);
1533
1534 // Wedge the background thread to make sure it doesn't start consuming the
1535 // queue.
1536 background_task_runner_->PostTask(
1537 FROM_HERE,
1538 base::BindOnce(&SQLitePersistentReportingAndNelStoreTest::WaitOnEvent,
1539 base::Unretained(this), &event));
1540
1541 store_->AddReportingEndpointGroup(group);
1542 EXPECT_EQ(0u, store_->GetQueueLengthForTesting());
1543 store_->UpdateReportingEndpointGroupAccessTime(group);
1544 EXPECT_EQ(0u, store_->GetQueueLengthForTesting());
1545 store_->UpdateReportingEndpointGroupDetails(group);
1546 EXPECT_EQ(0u, store_->GetQueueLengthForTesting());
1547 store_->DeleteReportingEndpointGroup(group);
1548 EXPECT_EQ(0u, store_->GetQueueLengthForTesting());
1549
1550 event.Signal();
1551 RunUntilIdle();
1552
1553 // Close and reopen the database.
1554 DestroyStore();
1555 CreateStore();
1556
1557 std::vector<ReportingEndpoint> endpoints;
1558 std::vector<CachedReportingEndpointGroup> groups;
1559 LoadReportingClients(&endpoints, &groups);
1560 ASSERT_EQ(0u, groups.size());
1561 }
1562
TEST_F(SQLitePersistentReportingAndNelStoreTest,ReportingEndpointsRestoredWithNetworkAnonymizationKeysDisabled)1563 TEST_F(SQLitePersistentReportingAndNelStoreTest,
1564 ReportingEndpointsRestoredWithNetworkAnonymizationKeysDisabled) {
1565 CreateStore();
1566 InitializeStore();
1567
1568 // Endpoint with non-empty NetworkAnonymizationKey.
1569 ReportingEndpoint endpoint = MakeReportingEndpoint(
1570 kNak1_, url::Origin::Create(GURL("https://www.foo.test")), kGroupName1,
1571 GURL("https://endpoint.test/"));
1572
1573 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1574 base::WaitableEvent::InitialState::NOT_SIGNALED);
1575
1576 // Wedge the background thread to make sure it doesn't start consuming the
1577 // queue.
1578 background_task_runner_->PostTask(
1579 FROM_HERE,
1580 base::BindOnce(&SQLitePersistentReportingAndNelStoreTest::WaitOnEvent,
1581 base::Unretained(this), &event));
1582
1583 store_->AddReportingEndpoint(endpoint);
1584 EXPECT_EQ(1u, store_->GetQueueLengthForTesting());
1585
1586 event.Signal();
1587 RunUntilIdle();
1588
1589 // Close the database, disable kPartitionNelAndReportingByNetworkIsolationKey,
1590 // and re-open it.
1591 DestroyStore();
1592 base::test::ScopedFeatureList feature_list;
1593 feature_list.InitAndDisableFeature(
1594 features::kPartitionNelAndReportingByNetworkIsolationKey);
1595 CreateStore();
1596
1597 std::vector<ReportingEndpoint> endpoints;
1598 std::vector<CachedReportingEndpointGroup> groups;
1599 LoadReportingClients(&endpoints, &groups);
1600 // No entries should be restored.
1601 ASSERT_EQ(0u, endpoints.size());
1602
1603 // Now reload the store with kPartitionNelAndReportingByNetworkIsolationKey
1604 // enabled again.
1605 DestroyStore();
1606 feature_list.Reset();
1607 CreateStore();
1608 LoadReportingClients(&endpoints, &groups);
1609
1610 // The entry is back!
1611 ASSERT_EQ(1u, endpoints.size());
1612 EXPECT_EQ(endpoint.group_key, endpoints[0].group_key);
1613 EXPECT_EQ(endpoint.info.url, endpoints[0].info.url);
1614 EXPECT_EQ(endpoint.info.priority, endpoints[0].info.priority);
1615 EXPECT_EQ(endpoint.info.weight, endpoints[0].info.weight);
1616 }
1617
TEST_F(SQLitePersistentReportingAndNelStoreTest,ReportingEndpointGroupsRestoredWithNetworkAnonymizationKeysDisabled)1618 TEST_F(SQLitePersistentReportingAndNelStoreTest,
1619 ReportingEndpointGroupsRestoredWithNetworkAnonymizationKeysDisabled) {
1620 CreateStore();
1621 InitializeStore();
1622
1623 const url::Origin kOrigin = url::Origin::Create(GURL("https://www.foo.test"));
1624
1625 CreateStore();
1626 InitializeStore();
1627 base::Time now = base::Time::Now();
1628 // Group with non-empty NetworkAnonymizationKey.
1629 CachedReportingEndpointGroup group =
1630 MakeReportingEndpointGroup(kNak1_, kOrigin, kGroupName1, now);
1631
1632 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1633 base::WaitableEvent::InitialState::NOT_SIGNALED);
1634
1635 // Wedge the background thread to make sure it doesn't start consuming the
1636 // queue.
1637 background_task_runner_->PostTask(
1638 FROM_HERE,
1639 base::BindOnce(&SQLitePersistentReportingAndNelStoreTest::WaitOnEvent,
1640 base::Unretained(this), &event));
1641
1642 store_->AddReportingEndpointGroup(group);
1643 EXPECT_EQ(1u, store_->GetQueueLengthForTesting());
1644
1645 event.Signal();
1646 RunUntilIdle();
1647
1648 // Close the database, disable kPartitionNelAndReportingByNetworkIsolationKey,
1649 // and re-open it.
1650 DestroyStore();
1651 base::test::ScopedFeatureList feature_list;
1652 feature_list.InitAndDisableFeature(
1653 features::kPartitionNelAndReportingByNetworkIsolationKey);
1654 CreateStore();
1655
1656 std::vector<ReportingEndpoint> endpoints;
1657 std::vector<CachedReportingEndpointGroup> groups;
1658 // No entries should be restored.
1659 LoadReportingClients(&endpoints, &groups);
1660 EXPECT_TRUE(groups.empty());
1661
1662 // Now reload the store with kPartitionNelAndReportingByNetworkIsolationKey
1663 // enabled again.
1664 DestroyStore();
1665 feature_list.Reset();
1666 CreateStore();
1667 LoadReportingClients(&endpoints, &groups);
1668
1669 // The entry is back!
1670 ASSERT_EQ(1u, groups.size());
1671 EXPECT_EQ(group.group_key, groups[0].group_key);
1672 EXPECT_EQ(group.include_subdomains, groups[0].include_subdomains);
1673 EXPECT_TRUE(WithinOneMicrosecond(group.expires, groups[0].expires));
1674 EXPECT_TRUE(WithinOneMicrosecond(group.last_used, groups[0].last_used));
1675 }
1676
1677 } // namespace net
1678