• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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