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