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 <memory>
6 #include <string>
7 #include <vector>
8
9 #include "base/functional/bind.h"
10 #include "base/functional/callback.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/test/scoped_feature_list.h"
13 #include "base/test/simple_test_clock.h"
14 #include "base/test/values_test_util.h"
15 #include "base/time/time.h"
16 #include "base/values.h"
17 #include "net/base/features.h"
18 #include "net/base/ip_address.h"
19 #include "net/base/net_errors.h"
20 #include "net/base/network_anonymization_key.h"
21 #include "net/base/schemeful_site.h"
22 #include "net/network_error_logging/mock_persistent_nel_store.h"
23 #include "net/network_error_logging/network_error_logging_service.h"
24 #include "net/reporting/reporting_test_util.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "url/gurl.h"
27 #include "url/origin.h"
28
29 namespace net {
30 namespace {
31
32 // The tests are parametrized on a boolean value which represents whether or not
33 // to use a MockPersistentNelStore.
34 // If a MockPersistentNelStore is used, then calls to
35 // NetworkErrorLoggingService::OnHeader(), OnRequest(),
36 // QueueSignedExchangeReport(), RemoveBrowsingData(), and
37 // RemoveAllBrowsingData() will block until the store finishes loading.
38 // Therefore, for tests that should run synchronously (i.e. tests that don't
39 // specifically test the asynchronous/deferred task behavior), FinishLoading()
40 // must be called after the first call to one of the above methods.
41 class NetworkErrorLoggingServiceTest : public ::testing::TestWithParam<bool> {
42 protected:
43 using NelPolicyKey = NetworkErrorLoggingService::NelPolicyKey;
44
NetworkErrorLoggingServiceTest()45 NetworkErrorLoggingServiceTest() {
46 feature_list_.InitAndEnableFeature(
47 features::kPartitionNelAndReportingByNetworkIsolationKey);
48
49 if (GetParam()) {
50 store_ = std::make_unique<MockPersistentNelStore>();
51 } else {
52 store_.reset(nullptr);
53 }
54 service_ = NetworkErrorLoggingService::Create(store_.get());
55 CreateReportingService();
56 }
57
CreateReportingService()58 void CreateReportingService() {
59 DCHECK(!reporting_service_);
60
61 reporting_service_ = std::make_unique<TestReportingService>();
62 service_->SetReportingService(reporting_service_.get());
63 }
64
MakeRequestDetails(const NetworkAnonymizationKey & network_anonymization_key,const GURL & url,Error error_type,std::string method="GET",int status_code=0,IPAddress server_ip=IPAddress ())65 NetworkErrorLoggingService::RequestDetails MakeRequestDetails(
66 const NetworkAnonymizationKey& network_anonymization_key,
67 const GURL& url,
68 Error error_type,
69 std::string method = "GET",
70 int status_code = 0,
71 IPAddress server_ip = IPAddress()) {
72 NetworkErrorLoggingService::RequestDetails details;
73
74 details.network_anonymization_key = network_anonymization_key;
75 details.uri = url;
76 details.referrer = kReferrer_;
77 details.user_agent = kUserAgent_;
78 details.server_ip = server_ip.IsValid() ? server_ip : kServerIP_;
79 details.method = std::move(method);
80 details.status_code = status_code;
81 details.elapsed_time = base::Seconds(1);
82 details.type = error_type;
83 details.reporting_upload_depth = 0;
84
85 return details;
86 }
87
88 NetworkErrorLoggingService::SignedExchangeReportDetails
MakeSignedExchangeReportDetails(const NetworkAnonymizationKey & network_anonymization_key,bool success,const std::string & type,const GURL & outer_url,const GURL & inner_url,const GURL & cert_url,const IPAddress & server_ip_address)89 MakeSignedExchangeReportDetails(
90 const NetworkAnonymizationKey& network_anonymization_key,
91 bool success,
92 const std::string& type,
93 const GURL& outer_url,
94 const GURL& inner_url,
95 const GURL& cert_url,
96 const IPAddress& server_ip_address) {
97 NetworkErrorLoggingService::SignedExchangeReportDetails details;
98 details.network_anonymization_key = network_anonymization_key;
99 details.success = success;
100 details.type = type;
101 details.outer_url = outer_url;
102 details.inner_url = inner_url;
103 details.cert_url = cert_url;
104 details.referrer = kReferrer_.spec();
105 details.server_ip_address = server_ip_address;
106 details.protocol = "http/1.1";
107 details.method = "GET";
108 details.status_code = 200;
109 details.elapsed_time = base::Milliseconds(1234);
110 details.user_agent = kUserAgent_;
111 return details;
112 }
service()113 NetworkErrorLoggingService* service() { return service_.get(); }
store()114 MockPersistentNelStore* store() { return store_.get(); }
reports()115 const std::vector<TestReportingService::Report>& reports() {
116 return reporting_service_->reports();
117 }
118
119 // These methods are design so that using them together will create unique
120 // Origin, NetworkAnonymizationKey pairs, but they do return repeated values
121 // when called separately, so they can be used to ensure that reports are
122 // keyed on both NAK and Origin.
MakeOrigin(size_t index)123 url::Origin MakeOrigin(size_t index) {
124 GURL url(base::StringPrintf("https://example%zd.com/", index / 2));
125 return url::Origin::Create(url);
126 }
MakeNetworkAnonymizationKey(size_t index)127 NetworkAnonymizationKey MakeNetworkAnonymizationKey(size_t index) {
128 SchemefulSite site(
129 GURL(base::StringPrintf("https://example%zd.com/", (index + 1) / 2)));
130 return NetworkAnonymizationKey::CreateSameSite(site);
131 }
132
MakePolicy(const NetworkAnonymizationKey & network_anonymization_key,const url::Origin & origin,base::Time expires=base::Time (),base::Time last_used=base::Time ())133 NetworkErrorLoggingService::NelPolicy MakePolicy(
134 const NetworkAnonymizationKey& network_anonymization_key,
135 const url::Origin& origin,
136 base::Time expires = base::Time(),
137 base::Time last_used = base::Time()) {
138 NetworkErrorLoggingService::NelPolicy policy;
139 policy.key = NelPolicyKey(network_anonymization_key, origin);
140 policy.expires = expires;
141 policy.last_used = last_used;
142
143 return policy;
144 }
145
146 // Returns whether the NetworkErrorLoggingService has a policy corresponding
147 // to |network_anonymization_key| and |origin|. Returns true if so, even if
148 // the policy is expired.
HasPolicy(const NetworkAnonymizationKey & network_anonymization_key,const url::Origin & origin)149 bool HasPolicy(const NetworkAnonymizationKey& network_anonymization_key,
150 const url::Origin& origin) {
151 std::set<NelPolicyKey> all_policy_keys =
152 service_->GetPolicyKeysForTesting();
153 return all_policy_keys.find(NelPolicyKey(network_anonymization_key,
154 origin)) != all_policy_keys.end();
155 }
156
PolicyCount()157 size_t PolicyCount() { return service_->GetPolicyKeysForTesting().size(); }
158
159 // Makes the rest of the test run synchronously.
FinishLoading(bool load_success)160 void FinishLoading(bool load_success) {
161 if (store())
162 store()->FinishLoading(load_success);
163 }
164
165 base::test::ScopedFeatureList feature_list_;
166
167 const GURL kUrl_ = GURL("https://example.com/path");
168 const GURL kUrlDifferentPort_ = GURL("https://example.com:4433/path");
169 const GURL kUrlSubdomain_ = GURL("https://subdomain.example.com/path");
170 const GURL kUrlDifferentHost_ = GURL("https://somewhere-else.com/path");
171 const GURL kUrlEtld_ = GURL("https://co.uk/foo.html");
172
173 const GURL kInnerUrl_ = GURL("https://example.net/path");
174 const GURL kCertUrl_ = GURL("https://example.com/cert_path");
175
176 const IPAddress kServerIP_ = IPAddress(192, 168, 0, 1);
177 const IPAddress kOtherServerIP_ = IPAddress(192, 168, 0, 2);
178 const url::Origin kOrigin_ = url::Origin::Create(kUrl_);
179 const url::Origin kOriginDifferentPort_ =
180 url::Origin::Create(kUrlDifferentPort_);
181 const url::Origin kOriginSubdomain_ = url::Origin::Create(kUrlSubdomain_);
182 const url::Origin kOriginDifferentHost_ =
183 url::Origin::Create(kUrlDifferentHost_);
184 const url::Origin kOriginEtld_ = url::Origin::Create(kUrlEtld_);
185 const NetworkAnonymizationKey kNak_ =
186 NetworkAnonymizationKey::CreateSameSite(SchemefulSite(kOrigin_));
187 const NetworkAnonymizationKey kOtherNak_ =
188 NetworkAnonymizationKey::CreateSameSite(
189 SchemefulSite(kOriginDifferentHost_));
190
191 const std::string kHeader_ = "{\"report_to\":\"group\",\"max_age\":86400}";
192 const std::string kHeaderSuccessFraction0_ =
193 "{\"report_to\":\"group\",\"max_age\":86400,\"success_fraction\":0.0}";
194 const std::string kHeaderSuccessFraction1_ =
195 "{\"report_to\":\"group\",\"max_age\":86400,\"success_fraction\":1.0}";
196 const std::string kHeaderIncludeSubdomains_ =
197 "{\"report_to\":\"group\",\"max_age\":86400,\"include_subdomains\":true}";
198 const std::string kHeaderIncludeSubdomainsAndSuccess_ =
199 "{\"report_to\":\"group\",\"max_age\":86400,\"include_subdomains\":true,"
200 "\"success_fraction\":1.0}";
201 const std::string kHeaderMaxAge0_ = "{\"max_age\":0}";
202 const std::string kHeaderTooLong_ =
203 "{\"report_to\":\"group\",\"max_age\":86400,\"junk\":\"" +
204 std::string(32 * 1024, 'a') + "\"}";
205 const std::string kHeaderTooDeep_ =
206 "{\"report_to\":\"group\",\"max_age\":86400,\"junk\":[[[[[[[[[[]]]]]]]]]]"
207 "}";
208
209 const std::string kUserAgent_ = "Mozilla/1.0";
210 const std::string kGroup_ = "group";
211
212 const std::string kType_ = NetworkErrorLoggingService::kReportType;
213
214 const GURL kReferrer_ = GURL("https://referrer.com/");
215
216 // |store_| needs to outlive |service_|.
217 std::unique_ptr<MockPersistentNelStore> store_;
218 std::unique_ptr<NetworkErrorLoggingService> service_;
219 std::unique_ptr<TestReportingService> reporting_service_;
220 };
221
ExpectDictDoubleValue(double expected_value,const base::Value::Dict & value,const std::string & key)222 void ExpectDictDoubleValue(double expected_value,
223 const base::Value::Dict& value,
224 const std::string& key) {
225 std::optional<double> double_value = value.FindDouble(key);
226 ASSERT_TRUE(double_value) << key;
227 EXPECT_DOUBLE_EQ(expected_value, *double_value) << key;
228 }
229
TEST_P(NetworkErrorLoggingServiceTest,CreateService)230 TEST_P(NetworkErrorLoggingServiceTest, CreateService) {
231 // Service is created by default in the test fixture..
232 EXPECT_TRUE(service());
233 }
234
TEST_P(NetworkErrorLoggingServiceTest,NoReportingService)235 TEST_P(NetworkErrorLoggingServiceTest, NoReportingService) {
236 service_ = NetworkErrorLoggingService::Create(store_.get());
237
238 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
239
240 // Make the rest of the test run synchronously.
241 FinishLoading(true /* load_success */);
242
243 // Should not crash.
244 service()->OnRequest(
245 MakeRequestDetails(kNak_, kUrl_, ERR_CONNECTION_REFUSED));
246 }
247
TEST_P(NetworkErrorLoggingServiceTest,NoPolicy)248 TEST_P(NetworkErrorLoggingServiceTest, NoPolicy) {
249 service()->OnRequest(
250 MakeRequestDetails(kNak_, kUrl_, ERR_CONNECTION_REFUSED));
251
252 // Make the rest of the test run synchronously.
253 FinishLoading(true /* load_success */);
254
255 EXPECT_TRUE(reports().empty());
256 }
257
TEST_P(NetworkErrorLoggingServiceTest,PolicyKeyMatchesNakAndOrigin)258 TEST_P(NetworkErrorLoggingServiceTest, PolicyKeyMatchesNakAndOrigin) {
259 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
260
261 // Make the rest of the test run synchronously.
262 FinishLoading(true /* load_success */);
263
264 // Wrong NAK and origin.
265 service()->OnRequest(MakeRequestDetails(kOtherNak_, kUrlDifferentHost_,
266 ERR_CONNECTION_REFUSED));
267 EXPECT_TRUE(reports().empty());
268
269 // Wrong NAK.
270 service()->OnRequest(
271 MakeRequestDetails(kOtherNak_, kUrl_, ERR_CONNECTION_REFUSED));
272 EXPECT_TRUE(reports().empty());
273
274 // Wrong origin.
275 service()->OnRequest(
276 MakeRequestDetails(kNak_, kUrlDifferentHost_, ERR_CONNECTION_REFUSED));
277 EXPECT_TRUE(reports().empty());
278
279 // Correct key.
280 service()->OnRequest(
281 MakeRequestDetails(kNak_, kUrl_, ERR_CONNECTION_REFUSED));
282 EXPECT_EQ(1u, reports().size());
283 EXPECT_EQ(kUrl_, reports()[0].url);
284 EXPECT_EQ(kNak_, reports()[0].network_anonymization_key);
285 EXPECT_EQ(kUserAgent_, reports()[0].user_agent);
286 EXPECT_EQ(kGroup_, reports()[0].group);
287 EXPECT_EQ(kType_, reports()[0].type);
288 }
289
TEST_P(NetworkErrorLoggingServiceTest,PolicyKeyMatchesNakAndOriginIncludeSubdomains)290 TEST_P(NetworkErrorLoggingServiceTest,
291 PolicyKeyMatchesNakAndOriginIncludeSubdomains) {
292 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderIncludeSubdomains_);
293
294 // Make the rest of the test run synchronously.
295 FinishLoading(true /* load_success */);
296
297 // Wrong NAK and origin.
298 service()->OnRequest(MakeRequestDetails(kOtherNak_, kUrlDifferentHost_,
299 ERR_CONNECTION_REFUSED));
300 EXPECT_TRUE(reports().empty());
301
302 // Wrong NAK (same origin).
303 service()->OnRequest(
304 MakeRequestDetails(kOtherNak_, kUrl_, ERR_CONNECTION_REFUSED));
305 EXPECT_TRUE(reports().empty());
306
307 // Wrong NAK (subdomain).
308 service()->OnRequest(
309 MakeRequestDetails(kOtherNak_, kUrlSubdomain_, ERR_CONNECTION_REFUSED));
310 EXPECT_TRUE(reports().empty());
311
312 // Wrong origin.
313 service()->OnRequest(
314 MakeRequestDetails(kNak_, kUrlDifferentHost_, ERR_CONNECTION_REFUSED));
315 EXPECT_TRUE(reports().empty());
316
317 // Correct key, successful request (same origin).
318 service()->OnRequest(MakeRequestDetails(kNak_, kUrl_, OK));
319 EXPECT_TRUE(reports().empty());
320
321 // Correct key, non-DNS error (same origin).
322 service()->OnRequest(
323 MakeRequestDetails(kNak_, kUrl_, ERR_CONNECTION_REFUSED));
324 EXPECT_EQ(1u, reports().size());
325 EXPECT_EQ(kUrl_, reports()[0].url);
326 EXPECT_EQ(kNak_, reports()[0].network_anonymization_key);
327 EXPECT_EQ(kUserAgent_, reports()[0].user_agent);
328 EXPECT_EQ(kGroup_, reports()[0].group);
329 EXPECT_EQ(kType_, reports()[0].type);
330
331 // Correct key, successful request (subdomain).
332 service()->OnRequest(MakeRequestDetails(kNak_, kUrlSubdomain_, OK));
333 EXPECT_EQ(1u, reports().size());
334
335 // Correct key, non-DNS error (subdomain).
336 service()->OnRequest(
337 MakeRequestDetails(kNak_, kUrlSubdomain_, ERR_CONNECTION_REFUSED));
338 EXPECT_EQ(1u, reports().size());
339
340 // Correct key, DNS error (subdomain).
341 service()->OnRequest(
342 MakeRequestDetails(kNak_, kUrlSubdomain_, ERR_NAME_NOT_RESOLVED));
343 EXPECT_EQ(2u, reports().size());
344 EXPECT_EQ(kUrlSubdomain_, reports()[1].url);
345 EXPECT_EQ(kNak_, reports()[1].network_anonymization_key);
346 EXPECT_EQ(kUserAgent_, reports()[1].user_agent);
347 EXPECT_EQ(kGroup_, reports()[1].group);
348 EXPECT_EQ(kType_, reports()[1].type);
349 }
350
TEST_P(NetworkErrorLoggingServiceTest,PolicyKeyMatchesNakAndOriginIncludeSubdomainsAndSuccess)351 TEST_P(NetworkErrorLoggingServiceTest,
352 PolicyKeyMatchesNakAndOriginIncludeSubdomainsAndSuccess) {
353 service()->OnHeader(kNak_, kOrigin_, kServerIP_,
354 kHeaderIncludeSubdomainsAndSuccess_);
355
356 // Make the rest of the test run synchronously.
357 FinishLoading(true /* load_success */);
358
359 // Wrong NAK and origin.
360 service()->OnRequest(MakeRequestDetails(kOtherNak_, kUrlDifferentHost_,
361 ERR_CONNECTION_REFUSED));
362 EXPECT_TRUE(reports().empty());
363
364 // Wrong NAK (same origin).
365 service()->OnRequest(
366 MakeRequestDetails(kOtherNak_, kUrl_, ERR_CONNECTION_REFUSED));
367 EXPECT_TRUE(reports().empty());
368
369 // Wrong NAK (subdomain).
370 service()->OnRequest(
371 MakeRequestDetails(kOtherNak_, kUrlSubdomain_, ERR_CONNECTION_REFUSED));
372 EXPECT_TRUE(reports().empty());
373
374 // Wrong origin.
375 service()->OnRequest(
376 MakeRequestDetails(kNak_, kUrlDifferentHost_, ERR_CONNECTION_REFUSED));
377 EXPECT_TRUE(reports().empty());
378
379 // Correct key, successful request (same origin).
380 service()->OnRequest(MakeRequestDetails(kNak_, kUrl_, OK));
381 EXPECT_EQ(1u, reports().size());
382 EXPECT_EQ(kUrl_, reports()[0].url);
383 EXPECT_EQ(kNak_, reports()[0].network_anonymization_key);
384 EXPECT_EQ(kUserAgent_, reports()[0].user_agent);
385 EXPECT_EQ(kGroup_, reports()[0].group);
386 EXPECT_EQ(kType_, reports()[0].type);
387
388 // Correct key, non-DNS error (same origin).
389 service()->OnRequest(
390 MakeRequestDetails(kNak_, kUrl_, ERR_CONNECTION_REFUSED));
391 EXPECT_EQ(2u, reports().size());
392 EXPECT_EQ(kUrl_, reports()[1].url);
393 EXPECT_EQ(kNak_, reports()[1].network_anonymization_key);
394 EXPECT_EQ(kUserAgent_, reports()[1].user_agent);
395 EXPECT_EQ(kGroup_, reports()[1].group);
396 EXPECT_EQ(kType_, reports()[1].type);
397
398 // Correct key (subdomain).
399 service()->OnRequest(
400 MakeRequestDetails(kNak_, kUrlSubdomain_, ERR_NAME_NOT_RESOLVED));
401 EXPECT_EQ(3u, reports().size());
402 EXPECT_EQ(kUrlSubdomain_, reports()[2].url);
403 EXPECT_EQ(kNak_, reports()[2].network_anonymization_key);
404 EXPECT_EQ(kUserAgent_, reports()[2].user_agent);
405 EXPECT_EQ(kGroup_, reports()[2].group);
406 EXPECT_EQ(kType_, reports()[2].type);
407
408 // Correct key, successful request (subdomain).
409 service()->OnRequest(MakeRequestDetails(kNak_, kUrlSubdomain_, OK));
410 EXPECT_EQ(3u, reports().size());
411
412 // Correct key, successful request on mismatched IP (subdomain).
413 service()->OnRequest(MakeRequestDetails(kNak_, kUrlSubdomain_, OK, "GET", 200,
414 kOtherServerIP_));
415 ASSERT_EQ(3u, reports().size());
416 }
417
TEST_P(NetworkErrorLoggingServiceTest,NetworkAnonymizationKeyDisabled)418 TEST_P(NetworkErrorLoggingServiceTest, NetworkAnonymizationKeyDisabled) {
419 base::test::ScopedFeatureList feature_list;
420 feature_list.InitAndDisableFeature(
421 features::kPartitionNelAndReportingByNetworkIsolationKey);
422
423 // Need to re-create the service, since it caches the feature value on
424 // creation.
425 service_ = NetworkErrorLoggingService::Create(store_.get());
426 reporting_service_ = std::make_unique<TestReportingService>();
427 service_->SetReportingService(reporting_service_.get());
428
429 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
430
431 // Make the rest of the test run synchronously.
432 FinishLoading(true /* load_success */);
433
434 // Wrong NAK, but a report should be generated anyways.
435 service()->OnRequest(
436 MakeRequestDetails(kOtherNak_, kUrl_, ERR_CONNECTION_REFUSED));
437 EXPECT_EQ(1u, reports().size());
438 EXPECT_EQ(kUrl_, reports()[0].url);
439 EXPECT_EQ(NetworkAnonymizationKey(), reports()[0].network_anonymization_key);
440 EXPECT_EQ(kUserAgent_, reports()[0].user_agent);
441 EXPECT_EQ(kGroup_, reports()[0].group);
442 EXPECT_EQ(kType_, reports()[0].type);
443 }
444
TEST_P(NetworkErrorLoggingServiceTest,JsonTooLong)445 TEST_P(NetworkErrorLoggingServiceTest, JsonTooLong) {
446 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderTooLong_);
447
448 // Make the rest of the test run synchronously.
449 FinishLoading(true /* load_success */);
450
451 service()->OnRequest(
452 MakeRequestDetails(kNak_, kUrl_, ERR_CONNECTION_REFUSED));
453
454 EXPECT_TRUE(reports().empty());
455 }
456
TEST_P(NetworkErrorLoggingServiceTest,JsonTooDeep)457 TEST_P(NetworkErrorLoggingServiceTest, JsonTooDeep) {
458 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderTooDeep_);
459
460 // Make the rest of the test run synchronously.
461 FinishLoading(true /* load_success */);
462
463 service()->OnRequest(
464 MakeRequestDetails(kNak_, kUrl_, ERR_CONNECTION_REFUSED));
465
466 EXPECT_TRUE(reports().empty());
467 }
468
TEST_P(NetworkErrorLoggingServiceTest,IncludeSubdomainsEtldRejected)469 TEST_P(NetworkErrorLoggingServiceTest, IncludeSubdomainsEtldRejected) {
470 service()->OnHeader(kNak_, kOriginEtld_, kServerIP_,
471 kHeaderIncludeSubdomains_);
472
473 // Make the rest of the test run synchronously.
474 FinishLoading(true /* load_success */);
475
476 EXPECT_EQ(0u, PolicyCount());
477
478 service()->OnRequest(
479 MakeRequestDetails(kNak_, kUrlEtld_, ERR_CONNECTION_REFUSED));
480
481 EXPECT_TRUE(reports().empty());
482 }
483
TEST_P(NetworkErrorLoggingServiceTest,NonIncludeSubdomainsEtldAccepted)484 TEST_P(NetworkErrorLoggingServiceTest, NonIncludeSubdomainsEtldAccepted) {
485 service()->OnHeader(kNak_, kOriginEtld_, kServerIP_, kHeader_);
486
487 // Make the rest of the test run synchronously.
488 FinishLoading(true /* load_success */);
489
490 EXPECT_EQ(1u, PolicyCount());
491
492 service()->OnRequest(
493 MakeRequestDetails(kNak_, kUrlEtld_, ERR_CONNECTION_REFUSED));
494
495 EXPECT_EQ(1u, reports().size());
496 EXPECT_EQ(kUrlEtld_, reports()[0].url);
497 }
498
TEST_P(NetworkErrorLoggingServiceTest,SuccessReportQueued)499 TEST_P(NetworkErrorLoggingServiceTest, SuccessReportQueued) {
500 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
501
502 // Make the rest of the test run synchronously.
503 FinishLoading(true /* load_success */);
504
505 service()->OnRequest(MakeRequestDetails(kNak_, kUrl_, OK));
506
507 ASSERT_EQ(1u, reports().size());
508 EXPECT_EQ(kUrl_, reports()[0].url);
509 EXPECT_EQ(kNak_, reports()[0].network_anonymization_key);
510 EXPECT_EQ(kUserAgent_, reports()[0].user_agent);
511 EXPECT_EQ(kGroup_, reports()[0].group);
512 EXPECT_EQ(kType_, reports()[0].type);
513 EXPECT_EQ(0, reports()[0].depth);
514
515 const base::Value* body = reports()[0].body.get();
516 ASSERT_TRUE(body);
517 ASSERT_TRUE(body->is_dict());
518 const base::Value::Dict& body_dict = body->GetDict();
519
520 base::ExpectDictStringValue(kReferrer_.spec(), body_dict,
521 NetworkErrorLoggingService::kReferrerKey);
522 // TODO(juliatuttle): Extract these constants.
523 ExpectDictDoubleValue(1.0, body_dict,
524 NetworkErrorLoggingService::kSamplingFractionKey);
525 base::ExpectDictStringValue(kServerIP_.ToString(), body_dict,
526 NetworkErrorLoggingService::kServerIpKey);
527 base::ExpectDictStringValue("", body_dict,
528 NetworkErrorLoggingService::kProtocolKey);
529 base::ExpectDictStringValue("GET", body_dict,
530 NetworkErrorLoggingService::kMethodKey);
531 base::ExpectDictIntegerValue(0, body_dict,
532 NetworkErrorLoggingService::kStatusCodeKey);
533 base::ExpectDictIntegerValue(1000, body_dict,
534 NetworkErrorLoggingService::kElapsedTimeKey);
535 base::ExpectDictStringValue("application", body_dict,
536 NetworkErrorLoggingService::kPhaseKey);
537 base::ExpectDictStringValue("ok", body_dict,
538 NetworkErrorLoggingService::kTypeKey);
539 }
540
TEST_P(NetworkErrorLoggingServiceTest,FailureReportQueued)541 TEST_P(NetworkErrorLoggingServiceTest, FailureReportQueued) {
542 static const std::string kHeaderFailureFraction1 =
543 "{\"report_to\":\"group\",\"max_age\":86400,\"failure_fraction\":1.0}";
544 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderFailureFraction1);
545
546 // Make the rest of the test run synchronously.
547 FinishLoading(true /* load_success */);
548
549 service()->OnRequest(
550 MakeRequestDetails(kNak_, kUrl_, ERR_CONNECTION_REFUSED));
551
552 ASSERT_EQ(1u, reports().size());
553 EXPECT_EQ(kUrl_, reports()[0].url);
554 EXPECT_EQ(kNak_, reports()[0].network_anonymization_key);
555 EXPECT_EQ(kUserAgent_, reports()[0].user_agent);
556 EXPECT_EQ(kGroup_, reports()[0].group);
557 EXPECT_EQ(kType_, reports()[0].type);
558 EXPECT_EQ(0, reports()[0].depth);
559
560 const base::Value* body = reports()[0].body.get();
561 ASSERT_TRUE(body);
562 ASSERT_TRUE(body->is_dict());
563 const base::Value::Dict& body_dict = body->GetDict();
564
565 base::ExpectDictStringValue(kReferrer_.spec(), body_dict,
566 NetworkErrorLoggingService::kReferrerKey);
567 // TODO(juliatuttle): Extract these constants.
568 ExpectDictDoubleValue(1.0, body_dict,
569 NetworkErrorLoggingService::kSamplingFractionKey);
570 base::ExpectDictStringValue(kServerIP_.ToString(), body_dict,
571 NetworkErrorLoggingService::kServerIpKey);
572 base::ExpectDictStringValue("", body_dict,
573 NetworkErrorLoggingService::kProtocolKey);
574 base::ExpectDictStringValue("GET", body_dict,
575 NetworkErrorLoggingService::kMethodKey);
576 base::ExpectDictIntegerValue(0, body_dict,
577 NetworkErrorLoggingService::kStatusCodeKey);
578 base::ExpectDictIntegerValue(1000, body_dict,
579 NetworkErrorLoggingService::kElapsedTimeKey);
580 base::ExpectDictStringValue("connection", body_dict,
581 NetworkErrorLoggingService::kPhaseKey);
582 base::ExpectDictStringValue("tcp.refused", body_dict,
583 NetworkErrorLoggingService::kTypeKey);
584 }
585
TEST_P(NetworkErrorLoggingServiceTest,UnknownFailureReportQueued)586 TEST_P(NetworkErrorLoggingServiceTest, UnknownFailureReportQueued) {
587 static const std::string kHeaderFailureFraction1 =
588 "{\"report_to\":\"group\",\"max_age\":86400,\"failure_fraction\":1.0}";
589 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderFailureFraction1);
590
591 // Make the rest of the test run synchronously.
592 FinishLoading(true /* load_success */);
593
594 // This error code happens to not be mapped to a NEL report `type` field
595 // value.
596 service()->OnRequest(MakeRequestDetails(kNak_, kUrl_, ERR_FILE_NO_SPACE));
597
598 ASSERT_EQ(1u, reports().size());
599 const base::Value* body = reports()[0].body.get();
600 ASSERT_TRUE(body);
601 ASSERT_TRUE(body->is_dict());
602 const base::Value::Dict& body_dict = body->GetDict();
603 base::ExpectDictStringValue("application", body_dict,
604 NetworkErrorLoggingService::kPhaseKey);
605 base::ExpectDictStringValue("unknown", body_dict,
606 NetworkErrorLoggingService::kTypeKey);
607 }
608
TEST_P(NetworkErrorLoggingServiceTest,UnknownCertFailureReportQueued)609 TEST_P(NetworkErrorLoggingServiceTest, UnknownCertFailureReportQueued) {
610 static const std::string kHeaderFailureFraction1 =
611 "{\"report_to\":\"group\",\"max_age\":86400,\"failure_fraction\":1.0}";
612 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderFailureFraction1);
613
614 // Make the rest of the test run synchronously.
615 FinishLoading(true /* load_success */);
616
617 // This error code happens to not be mapped to a NEL report `type` field
618 // value. Because it's a certificate error, we'll set the `phase` to be
619 // `connection`.
620 service()->OnRequest(
621 MakeRequestDetails(kNak_, kUrl_, ERR_CERT_NON_UNIQUE_NAME));
622
623 ASSERT_EQ(1u, reports().size());
624 const base::Value* body = reports()[0].body.get();
625 ASSERT_TRUE(body);
626 ASSERT_TRUE(body->is_dict());
627 const base::Value::Dict& body_dict = body->GetDict();
628 base::ExpectDictStringValue("connection", body_dict,
629 NetworkErrorLoggingService::kPhaseKey);
630 base::ExpectDictStringValue("unknown", body_dict,
631 NetworkErrorLoggingService::kTypeKey);
632 }
633
TEST_P(NetworkErrorLoggingServiceTest,HttpErrorReportQueued)634 TEST_P(NetworkErrorLoggingServiceTest, HttpErrorReportQueued) {
635 static const std::string kHeaderFailureFraction1 =
636 "{\"report_to\":\"group\",\"max_age\":86400,\"failure_fraction\":1.0}";
637 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderFailureFraction1);
638
639 // Make the rest of the test run synchronously.
640 FinishLoading(true /* load_success */);
641
642 service()->OnRequest(MakeRequestDetails(kNak_, kUrl_, OK, "GET", 504));
643
644 ASSERT_EQ(1u, reports().size());
645 EXPECT_EQ(kUrl_, reports()[0].url);
646 EXPECT_EQ(kNak_, reports()[0].network_anonymization_key);
647 EXPECT_EQ(kUserAgent_, reports()[0].user_agent);
648 EXPECT_EQ(kGroup_, reports()[0].group);
649 EXPECT_EQ(kType_, reports()[0].type);
650 EXPECT_EQ(0, reports()[0].depth);
651
652 const base::Value* body = reports()[0].body.get();
653 ASSERT_TRUE(body);
654 ASSERT_TRUE(body->is_dict());
655 const base::Value::Dict& body_dict = body->GetDict();
656
657 base::ExpectDictStringValue(kReferrer_.spec(), body_dict,
658 NetworkErrorLoggingService::kReferrerKey);
659 // TODO(juliatuttle): Extract these constants.
660 ExpectDictDoubleValue(1.0, body_dict,
661 NetworkErrorLoggingService::kSamplingFractionKey);
662 base::ExpectDictStringValue(kServerIP_.ToString(), body_dict,
663 NetworkErrorLoggingService::kServerIpKey);
664 base::ExpectDictStringValue("", body_dict,
665 NetworkErrorLoggingService::kProtocolKey);
666 base::ExpectDictStringValue("GET", body_dict,
667 NetworkErrorLoggingService::kMethodKey);
668 base::ExpectDictIntegerValue(504, body_dict,
669 NetworkErrorLoggingService::kStatusCodeKey);
670 base::ExpectDictIntegerValue(1000, body_dict,
671 NetworkErrorLoggingService::kElapsedTimeKey);
672 base::ExpectDictStringValue("application", body_dict,
673 NetworkErrorLoggingService::kPhaseKey);
674 base::ExpectDictStringValue("http.error", body_dict,
675 NetworkErrorLoggingService::kTypeKey);
676 }
677
TEST_P(NetworkErrorLoggingServiceTest,SuccessReportDowngraded)678 TEST_P(NetworkErrorLoggingServiceTest, SuccessReportDowngraded) {
679 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
680
681 // Make the rest of the test run synchronously.
682 FinishLoading(true /* load_success */);
683
684 service()->OnRequest(
685 MakeRequestDetails(kNak_, kUrl_, OK, "GET", 200, kOtherServerIP_));
686
687 ASSERT_EQ(1u, reports().size());
688 EXPECT_EQ(kUrl_, reports()[0].url);
689 EXPECT_EQ(kNak_, reports()[0].network_anonymization_key);
690 EXPECT_EQ(kGroup_, reports()[0].group);
691 EXPECT_EQ(kType_, reports()[0].type);
692 EXPECT_EQ(0, reports()[0].depth);
693
694 const base::Value* body = reports()[0].body.get();
695 ASSERT_TRUE(body);
696 ASSERT_TRUE(body->is_dict());
697 const base::Value::Dict& body_dict = body->GetDict();
698
699 base::ExpectDictStringValue(kReferrer_.spec(), body_dict,
700 NetworkErrorLoggingService::kReferrerKey);
701 ExpectDictDoubleValue(1.0, body_dict,
702 NetworkErrorLoggingService::kSamplingFractionKey);
703 base::ExpectDictStringValue(kOtherServerIP_.ToString(), body_dict,
704 NetworkErrorLoggingService::kServerIpKey);
705 base::ExpectDictStringValue("", body_dict,
706 NetworkErrorLoggingService::kProtocolKey);
707 base::ExpectDictStringValue("GET", body_dict,
708 NetworkErrorLoggingService::kMethodKey);
709 base::ExpectDictIntegerValue(0, body_dict,
710 NetworkErrorLoggingService::kStatusCodeKey);
711 base::ExpectDictIntegerValue(0, body_dict,
712 NetworkErrorLoggingService::kElapsedTimeKey);
713 base::ExpectDictStringValue("dns", body_dict,
714 NetworkErrorLoggingService::kPhaseKey);
715 base::ExpectDictStringValue("dns.address_changed", body_dict,
716 NetworkErrorLoggingService::kTypeKey);
717 }
718
TEST_P(NetworkErrorLoggingServiceTest,FailureReportDowngraded)719 TEST_P(NetworkErrorLoggingServiceTest, FailureReportDowngraded) {
720 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
721
722 // Make the rest of the test run synchronously.
723 FinishLoading(true /* load_success */);
724
725 service()->OnRequest(MakeRequestDetails(kNak_, kUrl_, ERR_CONNECTION_REFUSED,
726 "GET", 200, kOtherServerIP_));
727
728 ASSERT_EQ(1u, reports().size());
729 EXPECT_EQ(kUrl_, reports()[0].url);
730 EXPECT_EQ(kNak_, reports()[0].network_anonymization_key);
731 EXPECT_EQ(kGroup_, reports()[0].group);
732 EXPECT_EQ(kType_, reports()[0].type);
733 EXPECT_EQ(0, reports()[0].depth);
734
735 const base::Value* body = reports()[0].body.get();
736 ASSERT_TRUE(body);
737 ASSERT_TRUE(body->is_dict());
738 const base::Value::Dict& body_dict = body->GetDict();
739
740 base::ExpectDictStringValue(kReferrer_.spec(), body_dict,
741 NetworkErrorLoggingService::kReferrerKey);
742 ExpectDictDoubleValue(1.0, body_dict,
743 NetworkErrorLoggingService::kSamplingFractionKey);
744 base::ExpectDictStringValue(kOtherServerIP_.ToString(), body_dict,
745 NetworkErrorLoggingService::kServerIpKey);
746 base::ExpectDictStringValue("", body_dict,
747 NetworkErrorLoggingService::kProtocolKey);
748 base::ExpectDictStringValue("GET", body_dict,
749 NetworkErrorLoggingService::kMethodKey);
750 base::ExpectDictIntegerValue(0, body_dict,
751 NetworkErrorLoggingService::kStatusCodeKey);
752 base::ExpectDictIntegerValue(0, body_dict,
753 NetworkErrorLoggingService::kElapsedTimeKey);
754 base::ExpectDictStringValue("dns", body_dict,
755 NetworkErrorLoggingService::kPhaseKey);
756 base::ExpectDictStringValue("dns.address_changed", body_dict,
757 NetworkErrorLoggingService::kTypeKey);
758 }
759
TEST_P(NetworkErrorLoggingServiceTest,HttpErrorReportDowngraded)760 TEST_P(NetworkErrorLoggingServiceTest, HttpErrorReportDowngraded) {
761 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
762
763 // Make the rest of the test run synchronously.
764 FinishLoading(true /* load_success */);
765
766 service()->OnRequest(
767 MakeRequestDetails(kNak_, kUrl_, OK, "GET", 504, kOtherServerIP_));
768
769 ASSERT_EQ(1u, reports().size());
770 EXPECT_EQ(kUrl_, reports()[0].url);
771 EXPECT_EQ(kNak_, reports()[0].network_anonymization_key);
772 EXPECT_EQ(kGroup_, reports()[0].group);
773 EXPECT_EQ(kType_, reports()[0].type);
774 EXPECT_EQ(0, reports()[0].depth);
775
776 const base::Value* body = reports()[0].body.get();
777 ASSERT_TRUE(body);
778 ASSERT_TRUE(body->is_dict());
779 const base::Value::Dict& body_dict = body->GetDict();
780
781 base::ExpectDictStringValue(kReferrer_.spec(), body_dict,
782 NetworkErrorLoggingService::kReferrerKey);
783 ExpectDictDoubleValue(1.0, body_dict,
784 NetworkErrorLoggingService::kSamplingFractionKey);
785 base::ExpectDictStringValue(kOtherServerIP_.ToString(), body_dict,
786 NetworkErrorLoggingService::kServerIpKey);
787 base::ExpectDictStringValue("", body_dict,
788 NetworkErrorLoggingService::kProtocolKey);
789 base::ExpectDictStringValue("GET", body_dict,
790 NetworkErrorLoggingService::kMethodKey);
791 base::ExpectDictIntegerValue(0, body_dict,
792 NetworkErrorLoggingService::kStatusCodeKey);
793 base::ExpectDictIntegerValue(0, body_dict,
794 NetworkErrorLoggingService::kElapsedTimeKey);
795 base::ExpectDictStringValue("dns", body_dict,
796 NetworkErrorLoggingService::kPhaseKey);
797 base::ExpectDictStringValue("dns.address_changed", body_dict,
798 NetworkErrorLoggingService::kTypeKey);
799 }
800
TEST_P(NetworkErrorLoggingServiceTest,DNSFailureReportNotDowngraded)801 TEST_P(NetworkErrorLoggingServiceTest, DNSFailureReportNotDowngraded) {
802 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
803
804 // Make the rest of the test run synchronously.
805 FinishLoading(true /* load_success */);
806
807 service()->OnRequest(MakeRequestDetails(kNak_, kUrl_, ERR_NAME_NOT_RESOLVED,
808 "GET", 0, kOtherServerIP_));
809
810 ASSERT_EQ(1u, reports().size());
811 EXPECT_EQ(kUrl_, reports()[0].url);
812 EXPECT_EQ(kNak_, reports()[0].network_anonymization_key);
813 EXPECT_EQ(kGroup_, reports()[0].group);
814 EXPECT_EQ(kType_, reports()[0].type);
815 EXPECT_EQ(0, reports()[0].depth);
816
817 const base::Value* body = reports()[0].body.get();
818 ASSERT_TRUE(body);
819 ASSERT_TRUE(body->is_dict());
820 const base::Value::Dict& body_dict = body->GetDict();
821
822 base::ExpectDictStringValue(kReferrer_.spec(), body_dict,
823 NetworkErrorLoggingService::kReferrerKey);
824 ExpectDictDoubleValue(1.0, body_dict,
825 NetworkErrorLoggingService::kSamplingFractionKey);
826 base::ExpectDictStringValue(kOtherServerIP_.ToString(), body_dict,
827 NetworkErrorLoggingService::kServerIpKey);
828 base::ExpectDictStringValue("", body_dict,
829 NetworkErrorLoggingService::kProtocolKey);
830 base::ExpectDictStringValue("GET", body_dict,
831 NetworkErrorLoggingService::kMethodKey);
832 base::ExpectDictIntegerValue(0, body_dict,
833 NetworkErrorLoggingService::kStatusCodeKey);
834 base::ExpectDictIntegerValue(1000, body_dict,
835 NetworkErrorLoggingService::kElapsedTimeKey);
836 base::ExpectDictStringValue("dns", body_dict,
837 NetworkErrorLoggingService::kPhaseKey);
838 base::ExpectDictStringValue("dns.name_not_resolved", body_dict,
839 NetworkErrorLoggingService::kTypeKey);
840 }
841
TEST_P(NetworkErrorLoggingServiceTest,SuccessPOSTReportQueued)842 TEST_P(NetworkErrorLoggingServiceTest, SuccessPOSTReportQueued) {
843 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
844
845 // Make the rest of the test run synchronously.
846 FinishLoading(true /* load_success */);
847
848 service()->OnRequest(MakeRequestDetails(kNak_, kUrl_, OK, "POST"));
849
850 ASSERT_EQ(1u, reports().size());
851 EXPECT_EQ(kUrl_, reports()[0].url);
852 EXPECT_EQ(kNak_, reports()[0].network_anonymization_key);
853 EXPECT_EQ(kGroup_, reports()[0].group);
854 EXPECT_EQ(kType_, reports()[0].type);
855 EXPECT_EQ(0, reports()[0].depth);
856
857 const base::Value* body = reports()[0].body.get();
858 ASSERT_TRUE(body);
859 ASSERT_TRUE(body->is_dict());
860 const base::Value::Dict& body_dict = body->GetDict();
861
862 base::ExpectDictStringValue(kReferrer_.spec(), body_dict,
863 NetworkErrorLoggingService::kReferrerKey);
864 ExpectDictDoubleValue(1.0, body_dict,
865 NetworkErrorLoggingService::kSamplingFractionKey);
866 base::ExpectDictStringValue(kServerIP_.ToString(), body_dict,
867 NetworkErrorLoggingService::kServerIpKey);
868 base::ExpectDictStringValue("", body_dict,
869 NetworkErrorLoggingService::kProtocolKey);
870 base::ExpectDictStringValue("POST", body_dict,
871 NetworkErrorLoggingService::kMethodKey);
872 base::ExpectDictStringValue("application", body_dict,
873 NetworkErrorLoggingService::kPhaseKey);
874 base::ExpectDictStringValue("ok", body_dict,
875 NetworkErrorLoggingService::kTypeKey);
876 }
877
TEST_P(NetworkErrorLoggingServiceTest,MaxAge0)878 TEST_P(NetworkErrorLoggingServiceTest, MaxAge0) {
879 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
880
881 // Make the rest of the test run synchronously.
882 FinishLoading(true /* load_success */);
883
884 EXPECT_EQ(1u, PolicyCount());
885
886 // Max_age of 0 removes the policy.
887 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderMaxAge0_);
888 EXPECT_EQ(0u, PolicyCount());
889
890 service()->OnRequest(
891 MakeRequestDetails(kNak_, kUrl_, ERR_CONNECTION_REFUSED));
892
893 EXPECT_TRUE(reports().empty());
894 }
895
TEST_P(NetworkErrorLoggingServiceTest,SuccessFraction0)896 TEST_P(NetworkErrorLoggingServiceTest, SuccessFraction0) {
897 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderSuccessFraction0_);
898
899 // Make the rest of the test run synchronously.
900 FinishLoading(true /* load_success */);
901
902 // Each network error has a 0% chance of being reported. Fire off several and
903 // verify that no reports are produced.
904 constexpr size_t kReportCount = 100;
905 for (size_t i = 0; i < kReportCount; ++i)
906 service()->OnRequest(MakeRequestDetails(kNak_, kUrl_, OK));
907
908 EXPECT_TRUE(reports().empty());
909 }
910
TEST_P(NetworkErrorLoggingServiceTest,SuccessFractionHalf)911 TEST_P(NetworkErrorLoggingServiceTest, SuccessFractionHalf) {
912 // Include a different value for failure_fraction to ensure that we copy the
913 // right value into sampling_fraction.
914 static const std::string kHeaderSuccessFractionHalf =
915 "{\"report_to\":\"group\",\"max_age\":86400,\"success_fraction\":0.5,"
916 "\"failure_fraction\":0.25}";
917 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderSuccessFractionHalf);
918
919 // Make the rest of the test run synchronously.
920 FinishLoading(true /* load_success */);
921
922 // Each network error has a 50% chance of being reported. Fire off several
923 // and verify that some requests were reported and some weren't. (We can't
924 // verify exact counts because each decision is made randomly.)
925 constexpr size_t kReportCount = 100;
926 for (size_t i = 0; i < kReportCount; ++i)
927 service()->OnRequest(MakeRequestDetails(kNak_, kUrl_, OK));
928
929 // If our random selection logic is correct, there is a 2^-100 chance that
930 // every single report above was skipped. If this check fails, it's much more
931 // likely that our code is wrong.
932 EXPECT_FALSE(reports().empty());
933
934 // There's also a 2^-100 chance that every single report was logged. Same as
935 // above, that's much more likely to be a code error.
936 EXPECT_GT(kReportCount, reports().size());
937
938 for (const auto& report : reports()) {
939 const base::Value::Dict* body_dict = report.body->GetIfDict();
940 ASSERT_TRUE(body_dict);
941 // Our header includes a different value for failure_fraction, so that this
942 // check verifies that we copy the correct fraction into sampling_fraction.
943 ExpectDictDoubleValue(0.5, *body_dict,
944 NetworkErrorLoggingService::kSamplingFractionKey);
945 }
946 }
947
TEST_P(NetworkErrorLoggingServiceTest,FailureFraction0)948 TEST_P(NetworkErrorLoggingServiceTest, FailureFraction0) {
949 static const std::string kHeaderFailureFraction0 =
950 "{\"report_to\":\"group\",\"max_age\":86400,\"failure_fraction\":0.0}";
951 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderFailureFraction0);
952
953 // Make the rest of the test run synchronously.
954 FinishLoading(true /* load_success */);
955
956 // Each network error has a 0% chance of being reported. Fire off several and
957 // verify that no reports are produced.
958 constexpr size_t kReportCount = 100;
959 for (size_t i = 0; i < kReportCount; ++i)
960 service()->OnRequest(
961 MakeRequestDetails(kNak_, kUrl_, ERR_CONNECTION_REFUSED));
962
963 EXPECT_TRUE(reports().empty());
964 }
965
TEST_P(NetworkErrorLoggingServiceTest,FailureFractionHalf)966 TEST_P(NetworkErrorLoggingServiceTest, FailureFractionHalf) {
967 // Include a different value for success_fraction to ensure that we copy the
968 // right value into sampling_fraction.
969 static const std::string kHeaderFailureFractionHalf =
970 "{\"report_to\":\"group\",\"max_age\":86400,\"failure_fraction\":0.5,"
971 "\"success_fraction\":0.25}";
972 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderFailureFractionHalf);
973
974 // Make the rest of the test run synchronously.
975 FinishLoading(true /* load_success */);
976
977 // Each network error has a 50% chance of being reported. Fire off several
978 // and verify that some requests were reported and some weren't. (We can't
979 // verify exact counts because each decision is made randomly.)
980 constexpr size_t kReportCount = 100;
981 for (size_t i = 0; i < kReportCount; ++i)
982 service()->OnRequest(
983 MakeRequestDetails(kNak_, kUrl_, ERR_CONNECTION_REFUSED));
984
985 // If our random selection logic is correct, there is a 2^-100 chance that
986 // every single report above was skipped. If this check fails, it's much more
987 // likely that our code is wrong.
988 EXPECT_FALSE(reports().empty());
989
990 // There's also a 2^-100 chance that every single report was logged. Same as
991 // above, that's much more likely to be a code error.
992 EXPECT_GT(kReportCount, reports().size());
993
994 for (const auto& report : reports()) {
995 const base::Value::Dict* body_dict = report.body->GetIfDict();
996 ASSERT_TRUE(body_dict);
997 ExpectDictDoubleValue(0.5, *body_dict,
998 NetworkErrorLoggingService::kSamplingFractionKey);
999 }
1000 }
1001
TEST_P(NetworkErrorLoggingServiceTest,ExcludeSubdomainsDoesntMatchDifferentPort)1002 TEST_P(NetworkErrorLoggingServiceTest,
1003 ExcludeSubdomainsDoesntMatchDifferentPort) {
1004 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1005
1006 // Make the rest of the test run synchronously.
1007 FinishLoading(true /* load_success */);
1008
1009 service()->OnRequest(
1010 MakeRequestDetails(kNak_, kUrlDifferentPort_, ERR_CONNECTION_REFUSED));
1011
1012 EXPECT_TRUE(reports().empty());
1013 }
1014
TEST_P(NetworkErrorLoggingServiceTest,ExcludeSubdomainsDoesntMatchSubdomain)1015 TEST_P(NetworkErrorLoggingServiceTest, ExcludeSubdomainsDoesntMatchSubdomain) {
1016 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1017
1018 // Make the rest of the test run synchronously.
1019 FinishLoading(true /* load_success */);
1020
1021 service()->OnRequest(
1022 MakeRequestDetails(kNak_, kUrlSubdomain_, ERR_CONNECTION_REFUSED));
1023
1024 EXPECT_TRUE(reports().empty());
1025 }
1026
TEST_P(NetworkErrorLoggingServiceTest,IncludeSubdomainsMatchesDifferentPort)1027 TEST_P(NetworkErrorLoggingServiceTest, IncludeSubdomainsMatchesDifferentPort) {
1028 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderIncludeSubdomains_);
1029
1030 // Make the rest of the test run synchronously.
1031 FinishLoading(true /* load_success */);
1032
1033 service()->OnRequest(
1034 MakeRequestDetails(kNak_, kUrlDifferentPort_, ERR_NAME_NOT_RESOLVED));
1035
1036 ASSERT_EQ(1u, reports().size());
1037 EXPECT_EQ(kUrlDifferentPort_, reports()[0].url);
1038 }
1039
TEST_P(NetworkErrorLoggingServiceTest,IncludeSubdomainsMatchesSubdomain)1040 TEST_P(NetworkErrorLoggingServiceTest, IncludeSubdomainsMatchesSubdomain) {
1041 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderIncludeSubdomains_);
1042
1043 // Make the rest of the test run synchronously.
1044 FinishLoading(true /* load_success */);
1045
1046 service()->OnRequest(
1047 MakeRequestDetails(kNak_, kUrlSubdomain_, ERR_NAME_NOT_RESOLVED));
1048
1049 ASSERT_EQ(1u, reports().size());
1050 }
1051
TEST_P(NetworkErrorLoggingServiceTest,IncludeSubdomainsDoesntMatchSuperdomain)1052 TEST_P(NetworkErrorLoggingServiceTest,
1053 IncludeSubdomainsDoesntMatchSuperdomain) {
1054 service()->OnHeader(kNak_, kOriginSubdomain_, kServerIP_,
1055 kHeaderIncludeSubdomains_);
1056
1057 // Make the rest of the test run synchronously.
1058 FinishLoading(true /* load_success */);
1059
1060 service()->OnRequest(MakeRequestDetails(kNak_, kUrl_, ERR_NAME_NOT_RESOLVED));
1061
1062 EXPECT_TRUE(reports().empty());
1063 }
1064
TEST_P(NetworkErrorLoggingServiceTest,IncludeSubdomainsDoesntReportConnectionError)1065 TEST_P(NetworkErrorLoggingServiceTest,
1066 IncludeSubdomainsDoesntReportConnectionError) {
1067 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderIncludeSubdomains_);
1068
1069 // Make the rest of the test run synchronously.
1070 FinishLoading(true /* load_success */);
1071
1072 service()->OnRequest(
1073 MakeRequestDetails(kNak_, kUrlSubdomain_, ERR_CONNECTION_REFUSED));
1074
1075 EXPECT_TRUE(reports().empty());
1076 }
1077
TEST_P(NetworkErrorLoggingServiceTest,IncludeSubdomainsDoesntReportApplicationError)1078 TEST_P(NetworkErrorLoggingServiceTest,
1079 IncludeSubdomainsDoesntReportApplicationError) {
1080 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderIncludeSubdomains_);
1081
1082 // Make the rest of the test run synchronously.
1083 FinishLoading(true /* load_success */);
1084
1085 service()->OnRequest(
1086 MakeRequestDetails(kNak_, kUrlSubdomain_, ERR_INVALID_HTTP_RESPONSE));
1087
1088 EXPECT_TRUE(reports().empty());
1089 }
1090
TEST_P(NetworkErrorLoggingServiceTest,IncludeSubdomainsDoesntReportSuccess)1091 TEST_P(NetworkErrorLoggingServiceTest, IncludeSubdomainsDoesntReportSuccess) {
1092 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderIncludeSubdomains_);
1093
1094 // Make the rest of the test run synchronously.
1095 FinishLoading(true /* load_success */);
1096
1097 service()->OnRequest(MakeRequestDetails(kNak_, kUrlSubdomain_, OK));
1098
1099 EXPECT_TRUE(reports().empty());
1100 }
1101
TEST_P(NetworkErrorLoggingServiceTest,IncludeSubdomainsReportsSameOriginSuccess)1102 TEST_P(NetworkErrorLoggingServiceTest,
1103 IncludeSubdomainsReportsSameOriginSuccess) {
1104 static const std::string kHeaderIncludeSubdomainsSuccess1 =
1105 "{\"report_to\":\"group\",\"max_age\":86400,"
1106 "\"include_subdomains\":true,\"success_fraction\":1.0}";
1107 service()->OnHeader(kNak_, kOrigin_, kServerIP_,
1108 kHeaderIncludeSubdomainsSuccess1);
1109
1110 // Make the rest of the test run synchronously.
1111 FinishLoading(true /* load_success */);
1112
1113 service()->OnRequest(MakeRequestDetails(kNak_, kUrl_, OK));
1114
1115 ASSERT_EQ(1u, reports().size());
1116 EXPECT_EQ(kUrl_, reports()[0].url);
1117 }
1118
TEST_P(NetworkErrorLoggingServiceTest,RemoveAllBrowsingData)1119 TEST_P(NetworkErrorLoggingServiceTest, RemoveAllBrowsingData) {
1120 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1121
1122 // Make the rest of the test run synchronously.
1123 FinishLoading(true /* load_success */);
1124
1125 EXPECT_EQ(1u, PolicyCount());
1126 EXPECT_TRUE(HasPolicy(kNak_, kOrigin_));
1127
1128 service()->RemoveAllBrowsingData();
1129
1130 service()->OnRequest(
1131 MakeRequestDetails(kNak_, kUrl_, ERR_CONNECTION_REFUSED));
1132
1133 EXPECT_EQ(0u, PolicyCount());
1134 EXPECT_FALSE(HasPolicy(kNak_, kOrigin_));
1135 EXPECT_TRUE(reports().empty());
1136 }
1137
TEST_P(NetworkErrorLoggingServiceTest,RemoveSomeBrowsingData)1138 TEST_P(NetworkErrorLoggingServiceTest, RemoveSomeBrowsingData) {
1139 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1140
1141 // Make the rest of the test run synchronously.
1142 FinishLoading(true /* load_success */);
1143
1144 service()->OnHeader(kNak_, kOriginDifferentHost_, kServerIP_, kHeader_);
1145 EXPECT_EQ(2u, PolicyCount());
1146
1147 // Remove policy for kOrigin_ but not kOriginDifferentHost_
1148 service()->RemoveBrowsingData(
1149 base::BindRepeating([](const url::Origin& origin) -> bool {
1150 return origin.host() == "example.com";
1151 }));
1152 EXPECT_EQ(1u, PolicyCount());
1153 EXPECT_TRUE(HasPolicy(kNak_, kOriginDifferentHost_));
1154 EXPECT_FALSE(HasPolicy(kNak_, kOrigin_));
1155
1156 service()->OnRequest(
1157 MakeRequestDetails(kNak_, kUrl_, ERR_CONNECTION_REFUSED));
1158
1159 EXPECT_TRUE(reports().empty());
1160
1161 service()->OnRequest(
1162 MakeRequestDetails(kNak_, kUrlDifferentHost_, ERR_CONNECTION_REFUSED));
1163
1164 ASSERT_EQ(1u, reports().size());
1165 }
1166
TEST_P(NetworkErrorLoggingServiceTest,Nested)1167 TEST_P(NetworkErrorLoggingServiceTest, Nested) {
1168 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1169
1170 // Make the rest of the test run synchronously.
1171 FinishLoading(true /* load_success */);
1172
1173 NetworkErrorLoggingService::RequestDetails details =
1174 MakeRequestDetails(kNak_, kUrl_, ERR_CONNECTION_REFUSED);
1175 details.reporting_upload_depth =
1176 NetworkErrorLoggingService::kMaxNestedReportDepth;
1177 service()->OnRequest(details);
1178
1179 ASSERT_EQ(1u, reports().size());
1180 EXPECT_EQ(NetworkErrorLoggingService::kMaxNestedReportDepth,
1181 reports()[0].depth);
1182 }
1183
TEST_P(NetworkErrorLoggingServiceTest,NestedTooDeep)1184 TEST_P(NetworkErrorLoggingServiceTest, NestedTooDeep) {
1185 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1186
1187 // Make the rest of the test run synchronously.
1188 FinishLoading(true /* load_success */);
1189
1190 NetworkErrorLoggingService::RequestDetails details =
1191 MakeRequestDetails(kNak_, kUrl_, ERR_CONNECTION_REFUSED);
1192 details.reporting_upload_depth =
1193 NetworkErrorLoggingService::kMaxNestedReportDepth + 1;
1194 service()->OnRequest(details);
1195
1196 EXPECT_TRUE(reports().empty());
1197 }
1198
TEST_P(NetworkErrorLoggingServiceTest,StatusAsValue)1199 TEST_P(NetworkErrorLoggingServiceTest, StatusAsValue) {
1200 // The expiration times will be bogus, but we need a reproducible value for
1201 // this test.
1202 base::SimpleTestClock clock;
1203 service()->SetClockForTesting(&clock);
1204 // The clock is initialized to the "zero" or origin point of the Time class.
1205 // This sets the clock's Time to the equivalent of the "zero" or origin point
1206 // of the TimeTicks class, so that the serialized value produced by
1207 // NetLog::TimeToString is consistent across restarts.
1208 base::TimeDelta delta_from_origin =
1209 base::Time::UnixEpoch().since_origin() -
1210 base::TimeTicks::UnixEpoch().since_origin();
1211 clock.Advance(delta_from_origin);
1212
1213 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
1214
1215 // Make the rest of the test run synchronously.
1216 FinishLoading(true /* load_success */);
1217
1218 service()->OnHeader(kNak_, kOriginDifferentHost_, kServerIP_, kHeader_);
1219 service()->OnHeader(kOtherNak_, kOriginSubdomain_, kServerIP_,
1220 kHeaderIncludeSubdomains_);
1221 const std::string kHeaderWrongTypes =
1222 ("{\"report_to\":\"group\","
1223 "\"max_age\":86400,"
1224 // We'll ignore each of these fields because they're the wrong type.
1225 // We'll use a default value instead.
1226 "\"include_subdomains\":\"true\","
1227 "\"success_fraction\": \"1.0\","
1228 "\"failure_fraction\": \"0.0\"}");
1229 service()->OnHeader(
1230 kNak_, url::Origin::Create(GURL("https://invalid-types.example.com")),
1231 kServerIP_, kHeaderWrongTypes);
1232
1233 base::Value actual = service()->StatusAsValue();
1234 base::Value expected = base::test::ParseJson(R"json(
1235 {
1236 "originPolicies": [
1237 {
1238 "NetworkAnonymizationKey": "https://example.com same_site",
1239 "origin": "https://example.com",
1240 "includeSubdomains": false,
1241 "expires": "86400000",
1242 "reportTo": "group",
1243 "successFraction": 1.0,
1244 "failureFraction": 1.0,
1245 },
1246 {
1247 "NetworkAnonymizationKey": "https://example.com same_site",
1248 "origin": "https://invalid-types.example.com",
1249 "includeSubdomains": false,
1250 "expires": "86400000",
1251 "reportTo": "group",
1252 "successFraction": 0.0,
1253 "failureFraction": 1.0,
1254 },
1255 {
1256 "NetworkAnonymizationKey": "https://example.com same_site",
1257 "origin": "https://somewhere-else.com",
1258 "includeSubdomains": false,
1259 "expires": "86400000",
1260 "reportTo": "group",
1261 "successFraction": 0.0,
1262 "failureFraction": 1.0,
1263 },
1264 {
1265 "NetworkAnonymizationKey": "https://somewhere-else.com same_site",
1266 "origin": "https://subdomain.example.com",
1267 "includeSubdomains": true,
1268 "expires": "86400000",
1269 "reportTo": "group",
1270 "successFraction": 0.0,
1271 "failureFraction": 1.0,
1272 },
1273 ]
1274 }
1275 )json");
1276 EXPECT_EQ(expected, actual);
1277 }
1278
TEST_P(NetworkErrorLoggingServiceTest,InvalidHeaderData)1279 TEST_P(NetworkErrorLoggingServiceTest, InvalidHeaderData) {
1280 service()->OnHeader(kNak_, kOrigin_, kServerIP_, "0");
1281 }
1282
1283 TEST_P(NetworkErrorLoggingServiceTest, NoReportingService_SignedExchange) {
1284 service_ = NetworkErrorLoggingService::Create(store_.get());
1285
1286 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1287
1288 // Make the rest of the test run synchronously.
1289 FinishLoading(true /* load_success */);
1290
1291 // Should not crash
1292 service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
1293 kNak_, false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
1294 }
1295
1296 TEST_P(NetworkErrorLoggingServiceTest, NoPolicyForOrigin_SignedExchange) {
1297 service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
1298 kNak_, false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
1299
1300 // Make the rest of the test run synchronously.
1301 FinishLoading(true /* load_success */);
1302
1303 EXPECT_TRUE(reports().empty());
1304 }
1305
1306 TEST_P(NetworkErrorLoggingServiceTest, SuccessFraction0_SignedExchange) {
1307 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderSuccessFraction0_);
1308
1309 // Make the rest of the test run synchronously.
1310 FinishLoading(true /* load_success */);
1311
1312 // Each network error has a 0% chance of being reported. Fire off several and
1313 // verify that no reports are produced.
1314 constexpr size_t kReportCount = 100;
1315 for (size_t i = 0; i < kReportCount; ++i) {
1316 service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
1317 kNak_, true, "ok", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
1318 }
1319
1320 EXPECT_TRUE(reports().empty());
1321 }
1322
1323 TEST_P(NetworkErrorLoggingServiceTest, SuccessReportQueued_SignedExchange) {
1324 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
1325
1326 // Make the rest of the test run synchronously.
1327 FinishLoading(true /* load_success */);
1328
1329 service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
1330 kNak_, true, "ok", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
1331 ASSERT_EQ(1u, reports().size());
1332 EXPECT_EQ(kUrl_, reports()[0].url);
1333 EXPECT_EQ(kNak_, reports()[0].network_anonymization_key);
1334 EXPECT_EQ(kUserAgent_, reports()[0].user_agent);
1335 EXPECT_EQ(kGroup_, reports()[0].group);
1336 EXPECT_EQ(kType_, reports()[0].type);
1337 EXPECT_EQ(0, reports()[0].depth);
1338
1339 const base::Value* body = reports()[0].body.get();
1340 ASSERT_TRUE(body);
1341 ASSERT_TRUE(body->is_dict());
1342 const base::Value::Dict& body_dict = body->GetDict();
1343
1344 base::ExpectDictStringValue(kReferrer_.spec(), body_dict,
1345 NetworkErrorLoggingService::kReferrerKey);
1346 ExpectDictDoubleValue(1.0, body_dict,
1347 NetworkErrorLoggingService::kSamplingFractionKey);
1348 base::ExpectDictStringValue(kServerIP_.ToString(), body_dict,
1349 NetworkErrorLoggingService::kServerIpKey);
1350 base::ExpectDictStringValue("http/1.1", body_dict,
1351 NetworkErrorLoggingService::kProtocolKey);
1352 base::ExpectDictStringValue("GET", body_dict,
1353 NetworkErrorLoggingService::kMethodKey);
1354 base::ExpectDictIntegerValue(200, body_dict,
1355 NetworkErrorLoggingService::kStatusCodeKey);
1356 base::ExpectDictIntegerValue(1234, body_dict,
1357 NetworkErrorLoggingService::kElapsedTimeKey);
1358 base::ExpectDictStringValue(
1359 NetworkErrorLoggingService::kSignedExchangePhaseValue, body_dict,
1360 NetworkErrorLoggingService::kPhaseKey);
1361 base::ExpectDictStringValue("ok", body_dict,
1362 NetworkErrorLoggingService::kTypeKey);
1363
1364 const base::Value::Dict* sxg_body =
1365 body_dict.FindDict(NetworkErrorLoggingService::kSignedExchangeBodyKey);
1366 ASSERT_TRUE(sxg_body);
1367
1368 base::ExpectDictStringValue(kUrl_.spec(), *sxg_body,
1369 NetworkErrorLoggingService::kOuterUrlKey);
1370 base::ExpectDictStringValue(kInnerUrl_.spec(), *sxg_body,
1371 NetworkErrorLoggingService::kInnerUrlKey);
1372 base::ExpectStringValue(
1373 kCertUrl_.spec(),
1374 sxg_body->Find(NetworkErrorLoggingService::kCertUrlKey)->GetList()[0]);
1375 }
1376
1377 TEST_P(NetworkErrorLoggingServiceTest, FailureReportQueued_SignedExchange) {
1378 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1379
1380 // Make the rest of the test run synchronously.
1381 FinishLoading(true /* load_success */);
1382
1383 service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
1384 kNak_, false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
1385 ASSERT_EQ(1u, reports().size());
1386 EXPECT_EQ(kUrl_, reports()[0].url);
1387 EXPECT_EQ(kNak_, reports()[0].network_anonymization_key);
1388 EXPECT_EQ(kUserAgent_, reports()[0].user_agent);
1389 EXPECT_EQ(kGroup_, reports()[0].group);
1390 EXPECT_EQ(kType_, reports()[0].type);
1391 EXPECT_EQ(0, reports()[0].depth);
1392
1393 const base::Value* body = reports()[0].body.get();
1394 ASSERT_TRUE(body);
1395 ASSERT_TRUE(body->is_dict());
1396 const base::Value::Dict& body_dict = body->GetDict();
1397
1398 base::ExpectDictStringValue(kReferrer_.spec(), body_dict,
1399 NetworkErrorLoggingService::kReferrerKey);
1400 ExpectDictDoubleValue(1.0, body_dict,
1401 NetworkErrorLoggingService::kSamplingFractionKey);
1402 base::ExpectDictStringValue(kServerIP_.ToString(), body_dict,
1403 NetworkErrorLoggingService::kServerIpKey);
1404 base::ExpectDictStringValue("http/1.1", body_dict,
1405 NetworkErrorLoggingService::kProtocolKey);
1406 base::ExpectDictStringValue("GET", body_dict,
1407 NetworkErrorLoggingService::kMethodKey);
1408 base::ExpectDictIntegerValue(200, body_dict,
1409 NetworkErrorLoggingService::kStatusCodeKey);
1410 base::ExpectDictIntegerValue(1234, body_dict,
1411 NetworkErrorLoggingService::kElapsedTimeKey);
1412 base::ExpectDictStringValue(
1413 NetworkErrorLoggingService::kSignedExchangePhaseValue, body_dict,
1414 NetworkErrorLoggingService::kPhaseKey);
1415 base::ExpectDictStringValue("sxg.failed", body_dict,
1416 NetworkErrorLoggingService::kTypeKey);
1417
1418 const base::Value::Dict* sxg_body =
1419 body_dict.FindDict(NetworkErrorLoggingService::kSignedExchangeBodyKey);
1420 ASSERT_TRUE(sxg_body);
1421
1422 base::ExpectDictStringValue(kUrl_.spec(), *sxg_body,
1423 NetworkErrorLoggingService::kOuterUrlKey);
1424 base::ExpectDictStringValue(kInnerUrl_.spec(), *sxg_body,
1425 NetworkErrorLoggingService::kInnerUrlKey);
1426 base::ExpectStringValue(
1427 kCertUrl_.spec(),
1428 sxg_body->Find(NetworkErrorLoggingService::kCertUrlKey)->GetList()[0]);
1429 }
1430
1431 TEST_P(NetworkErrorLoggingServiceTest, MismatchingSubdomain_SignedExchange) {
1432 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderIncludeSubdomains_);
1433
1434 // Make the rest of the test run synchronously.
1435 FinishLoading(true /* load_success */);
1436
1437 service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
1438 kNak_, false, "sxg.failed", kUrlSubdomain_, kInnerUrl_, kCertUrl_,
1439 kServerIP_));
1440 EXPECT_TRUE(reports().empty());
1441 }
1442
1443 TEST_P(NetworkErrorLoggingServiceTest, MismatchingIPAddress_SignedExchange) {
1444 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1445
1446 // Make the rest of the test run synchronously.
1447 FinishLoading(true /* load_success */);
1448
1449 service()->QueueSignedExchangeReport(
1450 MakeSignedExchangeReportDetails(kNak_, false, "sxg.failed", kUrl_,
1451 kInnerUrl_, kCertUrl_, kOtherServerIP_));
1452 EXPECT_TRUE(reports().empty());
1453 }
1454
1455 TEST_P(NetworkErrorLoggingServiceTest,
1456 SignedExchangeNetworkAnonymizationKeyDisabled) {
1457 base::test::ScopedFeatureList feature_list;
1458 feature_list.InitAndDisableFeature(
1459 features::kPartitionNelAndReportingByNetworkIsolationKey);
1460
1461 // Need to re-create the service, since it caches the feature value on
1462 // creation.
1463 service_ = NetworkErrorLoggingService::Create(store_.get());
1464 reporting_service_ = std::make_unique<TestReportingService>();
1465 service_->SetReportingService(reporting_service_.get());
1466
1467 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
1468
1469 // Make the rest of the test run synchronously.
1470 FinishLoading(true /* load_success */);
1471
1472 // Wrong NAK, but a report should be generated anyways.
1473 service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
1474 kOtherNak_, true, "ok", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
1475
1476 ASSERT_EQ(1u, reports().size());
1477 EXPECT_EQ(kUrl_, reports()[0].url);
1478 EXPECT_EQ(NetworkAnonymizationKey(), reports()[0].network_anonymization_key);
1479 EXPECT_EQ(kUserAgent_, reports()[0].user_agent);
1480 EXPECT_EQ(kGroup_, reports()[0].group);
1481 EXPECT_EQ(kType_, reports()[0].type);
1482 EXPECT_EQ(0, reports()[0].depth);
1483 }
1484
1485 // When the max number of policies is exceeded, first try to remove expired
1486 // policies before evicting the least recently used unexpired policy.
1487 TEST_P(NetworkErrorLoggingServiceTest, EvictAllExpiredPoliciesFirst) {
1488 base::SimpleTestClock clock;
1489 service()->SetClockForTesting(&clock);
1490
1491 // Add 100 policies then make them expired.
1492 for (size_t i = 0; i < 100; ++i) {
1493 service()->OnHeader(MakeNetworkAnonymizationKey(i), MakeOrigin(i),
1494 kServerIP_, kHeader_);
1495 }
1496 // Make the rest of the test run synchronously.
1497 FinishLoading(true /* load_success */);
1498
1499 EXPECT_EQ(100u, PolicyCount());
1500 clock.Advance(base::Seconds(86401)); // max_age is 86400 sec
1501 // Expired policies are allowed to linger before hitting the policy limit.
1502 EXPECT_EQ(100u, PolicyCount());
1503
1504 // Reach the max policy limit.
1505 for (size_t i = 100; i < NetworkErrorLoggingService::kMaxPolicies; ++i) {
1506 service()->OnHeader(MakeNetworkAnonymizationKey(i), MakeOrigin(i),
1507 kServerIP_, kHeader_);
1508 }
1509 EXPECT_EQ(NetworkErrorLoggingService::kMaxPolicies, PolicyCount());
1510
1511 // Add one more policy to trigger eviction of only the expired policies.
1512 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1513 EXPECT_EQ(NetworkErrorLoggingService::kMaxPolicies - 100 + 1, PolicyCount());
1514 }
1515
1516 TEST_P(NetworkErrorLoggingServiceTest, EvictLeastRecentlyUsedPolicy) {
1517 base::SimpleTestClock clock;
1518 service()->SetClockForTesting(&clock);
1519
1520 // A policy's |last_used| is updated when it is added
1521 for (size_t i = 0; i < NetworkErrorLoggingService::kMaxPolicies; ++i) {
1522 service()->OnHeader(MakeNetworkAnonymizationKey(i), MakeOrigin(i),
1523 kServerIP_, kHeader_);
1524 clock.Advance(base::Seconds(1));
1525 }
1526 // Make the rest of the test run synchronously.
1527 FinishLoading(true /* load_success */);
1528
1529 EXPECT_EQ(PolicyCount(), NetworkErrorLoggingService::kMaxPolicies);
1530
1531 // Set another policy which triggers eviction. None of the policies have
1532 // expired, so the least recently used (i.e. least recently added) policy
1533 // should be evicted.
1534 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1535 clock.Advance(base::Seconds(1));
1536 EXPECT_EQ(PolicyCount(), NetworkErrorLoggingService::kMaxPolicies);
1537
1538 EXPECT_FALSE(
1539 HasPolicy(MakeNetworkAnonymizationKey(0), MakeOrigin(0))); // evicted
1540 std::set<NelPolicyKey> all_policy_keys = service()->GetPolicyKeysForTesting();
1541 for (size_t i = 1; i < NetworkErrorLoggingService::kMaxPolicies; ++i) {
1542 // Avoid n calls to HasPolicy(), which would be O(n^2).
1543 NelPolicyKey key(MakeNetworkAnonymizationKey(i), MakeOrigin(i));
1544 EXPECT_EQ(1u, all_policy_keys.count(key));
1545 }
1546 EXPECT_TRUE(HasPolicy(kNak_, kOrigin_));
1547
1548 // Now use the policies in reverse order starting with kOrigin_, then add
1549 // another policy to trigger eviction, to check that the stalest policy is
1550 // identified correctly.
1551 service()->OnRequest(
1552 MakeRequestDetails(kNak_, kOrigin_.GetURL(), ERR_CONNECTION_REFUSED));
1553 clock.Advance(base::Seconds(1));
1554 for (size_t i = NetworkErrorLoggingService::kMaxPolicies - 1; i >= 1; --i) {
1555 service()->OnRequest(MakeRequestDetails(MakeNetworkAnonymizationKey(i),
1556 MakeOrigin(i).GetURL(),
1557 ERR_CONNECTION_REFUSED));
1558 clock.Advance(base::Seconds(1));
1559 }
1560 service()->OnHeader(kNak_, kOriginSubdomain_, kServerIP_, kHeader_);
1561 EXPECT_EQ(PolicyCount(), NetworkErrorLoggingService::kMaxPolicies);
1562
1563 EXPECT_FALSE(HasPolicy(kNak_, kOrigin_)); // evicted
1564 all_policy_keys = service()->GetPolicyKeysForTesting();
1565 for (size_t i = NetworkErrorLoggingService::kMaxPolicies - 1; i >= 1; --i) {
1566 // Avoid n calls to HasPolicy(), which would be O(n^2).
1567 NelPolicyKey key(MakeNetworkAnonymizationKey(i), MakeOrigin(i));
1568 EXPECT_EQ(1u, all_policy_keys.count(key));
1569 }
1570 EXPECT_TRUE(HasPolicy(kNak_, kOriginSubdomain_)); // most recently added
1571
1572 // Note: This test advances the clock by ~2000 seconds, which is below the
1573 // specified max_age of 86400 seconds, so none of the policies expire during
1574 // this test.
1575 }
1576
1577 TEST_P(NetworkErrorLoggingServiceTest, SendsCommandsToStoreSynchronous) {
1578 if (!store())
1579 return;
1580
1581 MockPersistentNelStore::CommandList expected_commands;
1582 NetworkErrorLoggingService::NelPolicy policy1 = MakePolicy(kNak_, kOrigin_);
1583 NetworkErrorLoggingService::NelPolicy policy2 =
1584 MakePolicy(kNak_, kOriginDifferentHost_);
1585 std::vector<NetworkErrorLoggingService::NelPolicy> prestored_policies = {
1586 policy1, policy2};
1587 store()->SetPrestoredPolicies(std::move(prestored_policies));
1588
1589 // The first call to any of the public methods triggers a load.
1590 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1591 expected_commands.emplace_back(
1592 MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
1593 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1594
1595 // Make the rest of the test run synchronously.
1596 FinishLoading(true /* load_success */);
1597 // DoOnHeader() should now execute.
1598 expected_commands.emplace_back(
1599 MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy1);
1600 expected_commands.emplace_back(
1601 MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy1);
1602 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1603
1604 service()->OnRequest(
1605 MakeRequestDetails(kNak_, kOrigin_.GetURL(), ERR_CONNECTION_REFUSED));
1606 expected_commands.emplace_back(
1607 MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy1);
1608 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1609
1610 service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
1611 kNak_, false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
1612 expected_commands.emplace_back(
1613 MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy1);
1614 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1615
1616 // Removes policy1 but not policy2.
1617 EXPECT_EQ(2, store()->StoredPoliciesCount());
1618 service()->RemoveBrowsingData(
1619 base::BindRepeating([](const url::Origin& origin) -> bool {
1620 return origin.host() == "example.com";
1621 }));
1622 expected_commands.emplace_back(
1623 MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy1);
1624 expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
1625 EXPECT_EQ(1, store()->StoredPoliciesCount());
1626 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1627
1628 service()->RemoveAllBrowsingData();
1629 expected_commands.emplace_back(
1630 MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy2);
1631 expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
1632 EXPECT_EQ(0, store()->StoredPoliciesCount());
1633 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1634 }
1635
1636 TEST_P(NetworkErrorLoggingServiceTest, DuplicateEntriesInStore) {
1637 if (!store())
1638 return;
1639
1640 NetworkErrorLoggingService::NelPolicy policy1 = MakePolicy(kNak_, kOrigin_);
1641 NetworkErrorLoggingService::NelPolicy policy2 = policy1;
1642 std::vector<NetworkErrorLoggingService::NelPolicy> prestored_policies = {
1643 policy1, policy2};
1644 store()->SetPrestoredPolicies(std::move(prestored_policies));
1645
1646 // The first call to any of the public methods triggers a load.
1647 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1648 EXPECT_TRUE(store()->VerifyCommands({MockPersistentNelStore::Command(
1649 MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES)}));
1650 FinishLoading(/*load_success=*/true);
1651
1652 EXPECT_EQ(service()->GetPolicyKeysForTesting().size(), 1u);
1653 }
1654
1655 // Same as the above test, except that all the tasks are queued until loading
1656 // is complete.
1657 TEST_P(NetworkErrorLoggingServiceTest, SendsCommandsToStoreDeferred) {
1658 if (!store())
1659 return;
1660
1661 MockPersistentNelStore::CommandList expected_commands;
1662 NetworkErrorLoggingService::NelPolicy policy1 = MakePolicy(kNak_, kOrigin_);
1663 NetworkErrorLoggingService::NelPolicy policy2 =
1664 MakePolicy(kNak_, kOriginDifferentHost_);
1665 std::vector<NetworkErrorLoggingService::NelPolicy> prestored_policies = {
1666 policy1, policy2};
1667 store()->SetPrestoredPolicies(std::move(prestored_policies));
1668
1669 // The first call to any of the public methods triggers a load.
1670 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1671 expected_commands.emplace_back(
1672 MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
1673 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1674
1675 service()->OnRequest(
1676 MakeRequestDetails(kNak_, kOrigin_.GetURL(), ERR_CONNECTION_REFUSED));
1677 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1678
1679 service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
1680 kNak_, false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
1681 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1682
1683 // Removes policy1 but not policy2.
1684 service()->RemoveBrowsingData(
1685 base::BindRepeating([](const url::Origin& origin) -> bool {
1686 return origin.host() == "example.com";
1687 }));
1688 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1689
1690 service()->RemoveAllBrowsingData();
1691 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1692
1693 // The store has not yet been told to remove the policies because the tasks
1694 // to remove browsing data were queued pending initialization.
1695 EXPECT_EQ(2, store()->StoredPoliciesCount());
1696
1697 FinishLoading(true /* load_success */);
1698 // DoOnHeader()
1699 expected_commands.emplace_back(
1700 MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy1);
1701 expected_commands.emplace_back(
1702 MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy1);
1703 // DoOnRequest()
1704 expected_commands.emplace_back(
1705 MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy1);
1706 // DoQueueSignedExchangeReport()
1707 expected_commands.emplace_back(
1708 MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy1);
1709 // DoRemoveBrowsingData()
1710 expected_commands.emplace_back(
1711 MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy1);
1712 expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
1713 // DoRemoveAllBrowsingData()
1714 expected_commands.emplace_back(
1715 MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy2);
1716 expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
1717 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1718 }
1719
1720 // These two tests check that if loading fails, the commands should still
1721 // be sent to the store; the actual store impl will just ignore them.
1722 TEST_P(NetworkErrorLoggingServiceTest,
1723 SendsCommandsToStoreSynchronousLoadFailed) {
1724 if (!store())
1725 return;
1726
1727 MockPersistentNelStore::CommandList expected_commands;
1728 NetworkErrorLoggingService::NelPolicy policy1 = MakePolicy(kNak_, kOrigin_);
1729 NetworkErrorLoggingService::NelPolicy policy2 =
1730 MakePolicy(kNak_, kOriginDifferentHost_);
1731 std::vector<NetworkErrorLoggingService::NelPolicy> prestored_policies = {
1732 policy1, policy2};
1733 store()->SetPrestoredPolicies(std::move(prestored_policies));
1734
1735 // The first call to any of the public methods triggers a load.
1736 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1737 expected_commands.emplace_back(
1738 MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
1739 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1740
1741 // Make the rest of the test run synchronously.
1742 FinishLoading(false /* load_success */);
1743 // DoOnHeader() should now execute.
1744 // Because the load failed, there will be no policies in memory, so the store
1745 // is not told to delete anything.
1746 expected_commands.emplace_back(
1747 MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy1);
1748 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1749
1750 service()->OnRequest(
1751 MakeRequestDetails(kNak_, kOrigin_.GetURL(), ERR_CONNECTION_REFUSED));
1752 expected_commands.emplace_back(
1753 MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy1);
1754 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1755
1756 service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
1757 kNak_, false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
1758 expected_commands.emplace_back(
1759 MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy1);
1760 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1761
1762 // Removes policy1 but not policy2.
1763 service()->RemoveBrowsingData(
1764 base::BindRepeating([](const url::Origin& origin) -> bool {
1765 return origin.host() == "example.com";
1766 }));
1767 expected_commands.emplace_back(
1768 MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy1);
1769 expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
1770 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1771
1772 service()->RemoveAllBrowsingData();
1773 // We failed to load policy2 from the store, so there is nothing to remove
1774 // here.
1775 expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
1776 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1777 }
1778
1779 TEST_P(NetworkErrorLoggingServiceTest, SendsCommandsToStoreDeferredLoadFailed) {
1780 if (!store())
1781 return;
1782
1783 MockPersistentNelStore::CommandList expected_commands;
1784 NetworkErrorLoggingService::NelPolicy policy1 = MakePolicy(kNak_, kOrigin_);
1785 NetworkErrorLoggingService::NelPolicy policy2 =
1786 MakePolicy(kNak_, kOriginDifferentHost_);
1787 std::vector<NetworkErrorLoggingService::NelPolicy> prestored_policies = {
1788 policy1, policy2};
1789 store()->SetPrestoredPolicies(std::move(prestored_policies));
1790
1791 // The first call to any of the public methods triggers a load.
1792 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1793 expected_commands.emplace_back(
1794 MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
1795 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1796
1797 service()->OnRequest(
1798 MakeRequestDetails(kNak_, kOrigin_.GetURL(), ERR_CONNECTION_REFUSED));
1799 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1800
1801 service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
1802 kNak_, false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
1803 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1804
1805 // Removes policy1 but not policy2.
1806 service()->RemoveBrowsingData(
1807 base::BindRepeating([](const url::Origin& origin) -> bool {
1808 return origin.host() == "example.com";
1809 }));
1810 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1811
1812 service()->RemoveAllBrowsingData();
1813 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1814
1815 FinishLoading(false /* load_success */);
1816 // DoOnHeader()
1817 // Because the load failed, there will be no policies in memory, so the store
1818 // is not told to delete anything.
1819 expected_commands.emplace_back(
1820 MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy1);
1821 // DoOnRequest()
1822 expected_commands.emplace_back(
1823 MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy1);
1824 // DoQueueSignedExchangeReport()
1825 expected_commands.emplace_back(
1826 MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy1);
1827 // DoRemoveBrowsingData()
1828 expected_commands.emplace_back(
1829 MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy1);
1830 expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
1831 // DoRemoveAllBrowsingData()
1832 // We failed to load policy2 from the store, so there is nothing to remove
1833 // here.
1834 expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
1835 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1836 }
1837
1838 TEST_P(NetworkErrorLoggingServiceTest, FlushesStoreOnDestruction) {
1839 auto store = std::make_unique<MockPersistentNelStore>();
1840 std::unique_ptr<NetworkErrorLoggingService> service =
1841 NetworkErrorLoggingService::Create(store.get());
1842
1843 MockPersistentNelStore::CommandList expected_commands;
1844
1845 service->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1846 expected_commands.emplace_back(
1847 MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
1848 EXPECT_TRUE(store->VerifyCommands(expected_commands));
1849
1850 store->FinishLoading(false /* load_success */);
1851 expected_commands.emplace_back(
1852 MockPersistentNelStore::Command::Type::ADD_NEL_POLICY,
1853 MakePolicy(kNak_, kOrigin_));
1854 EXPECT_TRUE(store->VerifyCommands(expected_commands));
1855
1856 // Store should be flushed on destruction of service.
1857 service.reset();
1858 expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
1859 EXPECT_TRUE(store->VerifyCommands(expected_commands));
1860 }
1861
1862 TEST_P(NetworkErrorLoggingServiceTest,
1863 DoesntFlushStoreOnDestructionBeforeLoad) {
1864 auto store = std::make_unique<MockPersistentNelStore>();
1865 std::unique_ptr<NetworkErrorLoggingService> service =
1866 NetworkErrorLoggingService::Create(store.get());
1867
1868 service.reset();
1869 EXPECT_EQ(0u, store->GetAllCommands().size());
1870 }
1871
1872 TEST_P(NetworkErrorLoggingServiceTest, DoNothingIfShutDown) {
1873 if (!store())
1874 return;
1875
1876 MockPersistentNelStore::CommandList expected_commands;
1877
1878 // The first call to any of the public methods triggers a load.
1879 service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_);
1880 expected_commands.emplace_back(
1881 MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
1882 EXPECT_TRUE(store()->VerifyCommands(expected_commands));
1883
1884 service()->OnRequest(
1885 MakeRequestDetails(kNak_, kOrigin_.GetURL(), ERR_CONNECTION_REFUSED));
1886 service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
1887 kNak_, false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
1888 service()->RemoveBrowsingData(
1889 base::BindRepeating([](const url::Origin& origin) -> bool {
1890 return origin.host() == "example.com";
1891 }));
1892 service()->RemoveAllBrowsingData();
1893
1894 // Finish loading after the service has been shut down.
1895 service()->OnShutdown();
1896 FinishLoading(true /* load_success */);
1897
1898 // Only the LOAD command should have been sent to the store.
1899 EXPECT_EQ(1u, store()->GetAllCommands().size());
1900 EXPECT_EQ(0u, PolicyCount());
1901 EXPECT_EQ(0u, reports().size());
1902 }
1903
1904 INSTANTIATE_TEST_SUITE_P(NetworkErrorLoggingServiceStoreTest,
1905 NetworkErrorLoggingServiceTest,
1906 testing::Bool());
1907
1908 } // namespace
1909 } // namespace net
1910