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