summaryrefslogtreecommitdiff
path: root/chromium/net/network_error_logging
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-07-31 15:50:41 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-08-30 12:35:23 +0000
commit7b2ffa587235a47d4094787d72f38102089f402a (patch)
tree30e82af9cbab08a7fa028bb18f4f2987a3f74dfa /chromium/net/network_error_logging
parentd94af01c90575348c4e81a418257f254b6f8d225 (diff)
downloadqtwebengine-chromium-7b2ffa587235a47d4094787d72f38102089f402a.tar.gz
BASELINE: Update Chromium to 76.0.3809.94
Change-Id: I321c3f5f929c105aec0f98c5091ef6108822e647 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/net/network_error_logging')
-rw-r--r--chromium/net/network_error_logging/mock_persistent_nel_store.cc70
-rw-r--r--chromium/net/network_error_logging/mock_persistent_nel_store.h52
-rw-r--r--chromium/net/network_error_logging/mock_persistent_nel_store_unittest.cc168
-rw-r--r--chromium/net/network_error_logging/network_error_logging_service.cc413
-rw-r--r--chromium/net/network_error_logging/network_error_logging_service.h40
-rw-r--r--chromium/net/network_error_logging/network_error_logging_service_unittest.cc583
-rw-r--r--chromium/net/network_error_logging/network_error_logging_test_util.cc2
-rw-r--r--chromium/net/network_error_logging/network_error_logging_test_util.h3
-rw-r--r--chromium/net/network_error_logging/persistent_reporting_and_nel_store.h4
9 files changed, 941 insertions, 394 deletions
diff --git a/chromium/net/network_error_logging/mock_persistent_nel_store.cc b/chromium/net/network_error_logging/mock_persistent_nel_store.cc
index 1f0fa8ceb43..9de31285f7f 100644
--- a/chromium/net/network_error_logging/mock_persistent_nel_store.cc
+++ b/chromium/net/network_error_logging/mock_persistent_nel_store.cc
@@ -8,82 +8,82 @@
namespace net {
-MockPersistentNELStore::Command::Command(
+MockPersistentNelStore::Command::Command(
Type type,
- NELPoliciesLoadedCallback loaded_callback)
+ NelPoliciesLoadedCallback loaded_callback)
: type(type), loaded_callback(std::move(loaded_callback)) {}
-MockPersistentNELStore::Command::Command(
+MockPersistentNelStore::Command::Command(
Type type,
- const NetworkErrorLoggingService::NELPolicy& policy)
+ const NetworkErrorLoggingService::NelPolicy& policy)
: type(type), origin(policy.origin) {}
-MockPersistentNELStore::Command::Command(Type type) : type(type) {}
+MockPersistentNelStore::Command::Command(Type type) : type(type) {}
-MockPersistentNELStore::Command::Command(const Command& other)
+MockPersistentNelStore::Command::Command(const Command& other)
: type(other.type), origin(other.origin) {}
-MockPersistentNELStore::Command::Command(Command&& other) = default;
+MockPersistentNelStore::Command::Command(Command&& other) = default;
-MockPersistentNELStore::Command::~Command() = default;
+MockPersistentNelStore::Command::~Command() = default;
-bool operator==(const MockPersistentNELStore::Command& lhs,
- const MockPersistentNELStore::Command& rhs) {
+bool operator==(const MockPersistentNelStore::Command& lhs,
+ const MockPersistentNelStore::Command& rhs) {
if (lhs.type != rhs.type)
return false;
switch (lhs.type) {
// For LOAD_NEL_POLICIES and FLUSH, just check the type.
- case MockPersistentNELStore::Command::Type::LOAD_NEL_POLICIES:
- case MockPersistentNELStore::Command::Type::FLUSH:
+ case MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES:
+ case MockPersistentNelStore::Command::Type::FLUSH:
return true;
// For ADD_NEL_POLICY, UPDATE_NEL_POLICY, and DELETE_NEL_POLICY,
// additionally check the policy's origin.
- case MockPersistentNELStore::Command::Type::ADD_NEL_POLICY:
- case MockPersistentNELStore::Command::Type::UPDATE_NEL_POLICY:
- case MockPersistentNELStore::Command::Type::DELETE_NEL_POLICY:
+ case MockPersistentNelStore::Command::Type::ADD_NEL_POLICY:
+ case MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY:
+ case MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY:
return (lhs.origin == rhs.origin);
}
}
-bool operator!=(const MockPersistentNELStore::Command& lhs,
- const MockPersistentNELStore::Command& rhs) {
+bool operator!=(const MockPersistentNelStore::Command& lhs,
+ const MockPersistentNelStore::Command& rhs) {
return !(lhs == rhs);
}
-MockPersistentNELStore::MockPersistentNELStore()
+MockPersistentNelStore::MockPersistentNelStore()
: load_started_(false), policy_count_(0), queued_policy_count_delta_(0) {}
-MockPersistentNELStore::~MockPersistentNELStore() = default;
+MockPersistentNelStore::~MockPersistentNelStore() = default;
-void MockPersistentNELStore::LoadNELPolicies(
- NELPoliciesLoadedCallback loaded_callback) {
+void MockPersistentNelStore::LoadNelPolicies(
+ NelPoliciesLoadedCallback loaded_callback) {
DCHECK(!load_started_);
command_list_.emplace_back(Command::Type::LOAD_NEL_POLICIES,
std::move(loaded_callback));
load_started_ = true;
}
-void MockPersistentNELStore::AddNELPolicy(
- const NetworkErrorLoggingService::NELPolicy& policy) {
+void MockPersistentNelStore::AddNelPolicy(
+ const NetworkErrorLoggingService::NelPolicy& policy) {
DCHECK(load_started_);
command_list_.emplace_back(Command::Type::ADD_NEL_POLICY, policy);
++queued_policy_count_delta_;
}
-void MockPersistentNELStore::UpdateNELPolicyAccessTime(
- const NetworkErrorLoggingService::NELPolicy& policy) {
+void MockPersistentNelStore::UpdateNelPolicyAccessTime(
+ const NetworkErrorLoggingService::NelPolicy& policy) {
DCHECK(load_started_);
command_list_.emplace_back(Command::Type::UPDATE_NEL_POLICY, policy);
}
-void MockPersistentNELStore::DeleteNELPolicy(
- const NetworkErrorLoggingService::NELPolicy& policy) {
+void MockPersistentNelStore::DeleteNelPolicy(
+ const NetworkErrorLoggingService::NelPolicy& policy) {
DCHECK(load_started_);
command_list_.emplace_back(Command::Type::DELETE_NEL_POLICY, policy);
--queued_policy_count_delta_;
}
-void MockPersistentNELStore::Flush() {
+void MockPersistentNelStore::Flush() {
// Can be called before |load_started_| is true, if the
// NetworkErrorLoggingService is destroyed before getting a chance to load.
command_list_.emplace_back(Command::Type::FLUSH);
@@ -91,15 +91,15 @@ void MockPersistentNELStore::Flush() {
queued_policy_count_delta_ = 0;
}
-void MockPersistentNELStore::SetPrestoredPolicies(
- std::vector<NetworkErrorLoggingService::NELPolicy> policies) {
+void MockPersistentNelStore::SetPrestoredPolicies(
+ std::vector<NetworkErrorLoggingService::NelPolicy> policies) {
DCHECK(!load_started_);
DCHECK_EQ(0, policy_count_);
policy_count_ += policies.size();
prestored_policies_.swap(policies);
}
-void MockPersistentNELStore::FinishLoading(bool load_success) {
+void MockPersistentNelStore::FinishLoading(bool load_success) {
DCHECK(load_started_);
for (size_t i = 0; i < command_list_.size(); ++i) {
Command& command = command_list_[i];
@@ -112,7 +112,7 @@ void MockPersistentNELStore::FinishLoading(bool load_success) {
std::move(command.loaded_callback).Run(std::move(prestored_policies_));
} else {
std::move(command.loaded_callback)
- .Run(std::vector<NetworkErrorLoggingService::NELPolicy>());
+ .Run(std::vector<NetworkErrorLoggingService::NelPolicy>());
}
}
if (i > 0) {
@@ -122,17 +122,17 @@ void MockPersistentNELStore::FinishLoading(bool load_success) {
}
}
-bool MockPersistentNELStore::VerifyCommands(
+bool MockPersistentNelStore::VerifyCommands(
const CommandList& expected_commands) const {
return command_list_ == expected_commands;
}
-MockPersistentNELStore::CommandList MockPersistentNELStore::GetAllCommands()
+MockPersistentNelStore::CommandList MockPersistentNelStore::GetAllCommands()
const {
return command_list_;
}
-std::string MockPersistentNELStore::GetDebugString() const {
+std::string MockPersistentNelStore::GetDebugString() const {
std::ostringstream s;
for (const Command& command : command_list_) {
diff --git a/chromium/net/network_error_logging/mock_persistent_nel_store.h b/chromium/net/network_error_logging/mock_persistent_nel_store.h
index 9f0d180a25f..cbf2f52add0 100644
--- a/chromium/net/network_error_logging/mock_persistent_nel_store.h
+++ b/chromium/net/network_error_logging/mock_persistent_nel_store.h
@@ -15,14 +15,14 @@
namespace net {
-// A NetworkErrorLoggingService::PersistentNELStore implementation that stashes
+// A NetworkErrorLoggingService::PersistentNelStore implementation that stashes
// the received commands in order in a vector, to be checked by tests.
// Simulates loading pre-existing stored policies, which can be provided
// using SetLoadExpectation().
-class MockPersistentNELStore
- : public NetworkErrorLoggingService::PersistentNELStore {
+class MockPersistentNelStore
+ : public NetworkErrorLoggingService::PersistentNelStore {
public:
- // Represents a command that has been passed to the MockPersistentNELStore.
+ // Represents a command that has been passed to the MockPersistentNelStore.
struct Command {
enum class Type {
LOAD_NEL_POLICIES,
@@ -33,10 +33,10 @@ class MockPersistentNELStore
};
// Constructor for LOAD_NEL_POLICIES commands.
- Command(Type type, NELPoliciesLoadedCallback loaded_callback);
+ Command(Type type, NelPoliciesLoadedCallback loaded_callback);
// Constructor for ADD_NEL_POLICY, UPDATE_NEL_POLICY, and DELETE_NEL_POLICY
// commands.
- Command(Type type, const NetworkErrorLoggingService::NELPolicy& policy);
+ Command(Type type, const NetworkErrorLoggingService::NelPolicy& policy);
// Constructor for FLUSH commands.
Command(Type type);
@@ -54,28 +54,28 @@ class MockPersistentNELStore
// The supplied callback to be run when loading is complete. (Only applies
// for load commands).
- NELPoliciesLoadedCallback loaded_callback;
+ NelPoliciesLoadedCallback loaded_callback;
};
using CommandList = std::vector<Command>;
- MockPersistentNELStore();
- ~MockPersistentNELStore() override;
-
- // PersistentNELStore implementation:
- void LoadNELPolicies(NELPoliciesLoadedCallback loaded_callback) override;
- void AddNELPolicy(
- const NetworkErrorLoggingService::NELPolicy& policy) override;
- void UpdateNELPolicyAccessTime(
- const NetworkErrorLoggingService::NELPolicy& policy) override;
- void DeleteNELPolicy(
- const NetworkErrorLoggingService::NELPolicy& policy) override;
+ MockPersistentNelStore();
+ ~MockPersistentNelStore() override;
+
+ // PersistentNelStore implementation:
+ void LoadNelPolicies(NelPoliciesLoadedCallback loaded_callback) override;
+ void AddNelPolicy(
+ const NetworkErrorLoggingService::NelPolicy& policy) override;
+ void UpdateNelPolicyAccessTime(
+ const NetworkErrorLoggingService::NelPolicy& policy) override;
+ void DeleteNelPolicy(
+ const NetworkErrorLoggingService::NelPolicy& policy) override;
void Flush() override;
// Simulates pre-existing policies that were stored previously. Should only be
// called once, at the beginning of the test before any other method calls.
void SetPrestoredPolicies(
- std::vector<NetworkErrorLoggingService::NELPolicy> policies);
+ std::vector<NetworkErrorLoggingService::NelPolicy> policies);
// Simulate finishing loading policies by executing the loaded_callback of the
// first LOAD_NEL_POLICIES command (which should also be the only
@@ -102,9 +102,9 @@ class MockPersistentNELStore
CommandList command_list_;
// Simulated pre-existing stored policies.
- std::vector<NetworkErrorLoggingService::NELPolicy> prestored_policies_;
+ std::vector<NetworkErrorLoggingService::NelPolicy> prestored_policies_;
- // Set when LoadNELPolicies() is called.
+ // Set when LoadNelPolicies() is called.
bool load_started_;
// Simulates the total number of policies that would be stored in the store.
@@ -115,13 +115,13 @@ class MockPersistentNELStore
// called. Reset to 0 when Flush() is called.
int queued_policy_count_delta_;
- DISALLOW_COPY_AND_ASSIGN(MockPersistentNELStore);
+ DISALLOW_COPY_AND_ASSIGN(MockPersistentNelStore);
};
-bool operator==(const MockPersistentNELStore::Command& lhs,
- const MockPersistentNELStore::Command& rhs);
-bool operator!=(const MockPersistentNELStore::Command& lhs,
- const MockPersistentNELStore::Command& rhs);
+bool operator==(const MockPersistentNelStore::Command& lhs,
+ const MockPersistentNelStore::Command& rhs);
+bool operator!=(const MockPersistentNelStore::Command& lhs,
+ const MockPersistentNelStore::Command& rhs);
} // namespace net
diff --git a/chromium/net/network_error_logging/mock_persistent_nel_store_unittest.cc b/chromium/net/network_error_logging/mock_persistent_nel_store_unittest.cc
index 3c976afa7a0..2835df49cb4 100644
--- a/chromium/net/network_error_logging/mock_persistent_nel_store_unittest.cc
+++ b/chromium/net/network_error_logging/mock_persistent_nel_store_unittest.cc
@@ -17,8 +17,8 @@ namespace net {
namespace {
const url::Origin kOrigin = url::Origin::Create(GURL("https://example.test/"));
-NetworkErrorLoggingService::NELPolicy MakePolicyForOrigin(url::Origin origin) {
- NetworkErrorLoggingService::NELPolicy policy;
+NetworkErrorLoggingService::NelPolicy MakePolicyForOrigin(url::Origin origin) {
+ NetworkErrorLoggingService::NelPolicy policy;
policy.origin = std::move(origin);
policy.expires = base::Time();
policy.last_used = base::Time();
@@ -26,34 +26,34 @@ NetworkErrorLoggingService::NELPolicy MakePolicyForOrigin(url::Origin origin) {
return policy;
}
-void RunClosureOnNELPoliciesLoaded(
+void RunClosureOnNelPoliciesLoaded(
base::OnceClosure closure,
- std::vector<NetworkErrorLoggingService::NELPolicy>* policies_out,
- std::vector<NetworkErrorLoggingService::NELPolicy> loaded_policies) {
+ std::vector<NetworkErrorLoggingService::NelPolicy>* policies_out,
+ std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies) {
std::move(closure).Run();
loaded_policies.swap(*policies_out);
}
-// Makes a NELPoliciesLoadedCallback that will fail if it's never run before
+// Makes a NelPoliciesLoadedCallback that will fail if it's never run before
// destruction.
-MockPersistentNELStore::NELPoliciesLoadedCallback
-MakeExpectedRunNELPoliciesLoadedCallback(
- std::vector<NetworkErrorLoggingService::NELPolicy>* policies_out) {
+MockPersistentNelStore::NelPoliciesLoadedCallback
+MakeExpectedRunNelPoliciesLoadedCallback(
+ std::vector<NetworkErrorLoggingService::NelPolicy>* policies_out) {
base::OnceClosure closure = base::MakeExpectedRunClosure(FROM_HERE);
- return base::BindOnce(&RunClosureOnNELPoliciesLoaded, std::move(closure),
+ return base::BindOnce(&RunClosureOnNelPoliciesLoaded, std::move(closure),
policies_out);
}
// Test that FinishLoading() runs the callback.
-TEST(MockPersistentNELStoreTest, FinishLoading) {
- MockPersistentNELStore store;
- MockPersistentNELStore::CommandList expected_commands;
- std::vector<NetworkErrorLoggingService::NELPolicy> loaded_policies;
+TEST(MockPersistentNelStoreTest, FinishLoading) {
+ MockPersistentNelStore store;
+ MockPersistentNelStore::CommandList expected_commands;
+ std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
- store.LoadNELPolicies(
- MakeExpectedRunNELPoliciesLoadedCallback(&loaded_policies));
+ store.LoadNelPolicies(
+ MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
expected_commands.emplace_back(
- MockPersistentNELStore::Command::Type::LOAD_NEL_POLICIES);
+ MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
store.FinishLoading(true /* load_success */);
EXPECT_EQ(0u, loaded_policies.size());
@@ -65,20 +65,20 @@ TEST(MockPersistentNELStoreTest, FinishLoading) {
// Test should not crash because the callback has been run.
}
-TEST(MockPersistentNELStoreTest, PreStoredPolicies) {
- MockPersistentNELStore store;
- MockPersistentNELStore::CommandList expected_commands;
- std::vector<NetworkErrorLoggingService::NELPolicy> loaded_policies;
+TEST(MockPersistentNelStoreTest, PreStoredPolicies) {
+ MockPersistentNelStore store;
+ MockPersistentNelStore::CommandList expected_commands;
+ std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
- std::vector<NetworkErrorLoggingService::NELPolicy> prestored_policies = {
+ std::vector<NetworkErrorLoggingService::NelPolicy> prestored_policies = {
MakePolicyForOrigin(kOrigin)};
store.SetPrestoredPolicies(std::move(prestored_policies));
EXPECT_EQ(1, store.StoredPoliciesCount());
- store.LoadNELPolicies(
- MakeExpectedRunNELPoliciesLoadedCallback(&loaded_policies));
+ store.LoadNelPolicies(
+ MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
expected_commands.emplace_back(
- MockPersistentNELStore::Command::Type::LOAD_NEL_POLICIES);
+ MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
store.FinishLoading(true /* load_success */);
ASSERT_EQ(1u, loaded_policies.size());
EXPECT_EQ(kOrigin, loaded_policies[0].origin);
@@ -89,20 +89,20 @@ TEST(MockPersistentNELStoreTest, PreStoredPolicies) {
}
// Failed load should yield empty vector of policies.
-TEST(MockPersistentNELStoreTest, FailedLoad) {
- MockPersistentNELStore store;
- MockPersistentNELStore::CommandList expected_commands;
- std::vector<NetworkErrorLoggingService::NELPolicy> loaded_policies;
+TEST(MockPersistentNelStoreTest, FailedLoad) {
+ MockPersistentNelStore store;
+ MockPersistentNelStore::CommandList expected_commands;
+ std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
- std::vector<NetworkErrorLoggingService::NELPolicy> prestored_policies = {
+ std::vector<NetworkErrorLoggingService::NelPolicy> prestored_policies = {
MakePolicyForOrigin(kOrigin)};
store.SetPrestoredPolicies(std::move(prestored_policies));
EXPECT_EQ(1, store.StoredPoliciesCount());
- store.LoadNELPolicies(
- MakeExpectedRunNELPoliciesLoadedCallback(&loaded_policies));
+ store.LoadNelPolicies(
+ MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
expected_commands.emplace_back(
- MockPersistentNELStore::Command::Type::LOAD_NEL_POLICIES);
+ MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
store.FinishLoading(false /* load_success */);
// The pre-stored policy is not returned because loading failed.
EXPECT_EQ(0u, loaded_policies.size());
@@ -112,30 +112,30 @@ TEST(MockPersistentNELStoreTest, FailedLoad) {
EXPECT_EQ("LOAD; ", store.GetDebugString());
}
-TEST(MockPersistentNELStoreTest, Add) {
- MockPersistentNELStore store;
- MockPersistentNELStore::CommandList expected_commands;
- std::vector<NetworkErrorLoggingService::NELPolicy> loaded_policies;
+TEST(MockPersistentNelStoreTest, Add) {
+ MockPersistentNelStore store;
+ MockPersistentNelStore::CommandList expected_commands;
+ std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
- store.LoadNELPolicies(
- MakeExpectedRunNELPoliciesLoadedCallback(&loaded_policies));
+ store.LoadNelPolicies(
+ MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
expected_commands.emplace_back(
- MockPersistentNELStore::Command::Type::LOAD_NEL_POLICIES);
+ MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
EXPECT_EQ(1u, store.GetAllCommands().size());
store.FinishLoading(true /* load_success */);
EXPECT_EQ(0u, loaded_policies.size());
- NetworkErrorLoggingService::NELPolicy policy = MakePolicyForOrigin(kOrigin);
- store.AddNELPolicy(policy);
+ NetworkErrorLoggingService::NelPolicy policy = MakePolicyForOrigin(kOrigin);
+ store.AddNelPolicy(policy);
expected_commands.emplace_back(
- MockPersistentNELStore::Command::Type::ADD_NEL_POLICY, policy);
+ MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy);
// Add operation will be queued; the policy has not actually been stored yet
EXPECT_EQ(0, store.StoredPoliciesCount());
EXPECT_EQ(2u, store.GetAllCommands().size());
store.Flush();
- expected_commands.emplace_back(MockPersistentNELStore::Command::Type::FLUSH);
+ expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
EXPECT_EQ(1, store.StoredPoliciesCount());
EXPECT_EQ(3u, store.GetAllCommands().size());
@@ -144,33 +144,33 @@ TEST(MockPersistentNELStoreTest, Add) {
store.GetDebugString());
}
-TEST(MockPersistentNELStoreTest, AddThenDelete) {
- MockPersistentNELStore store;
- MockPersistentNELStore::CommandList expected_commands;
- std::vector<NetworkErrorLoggingService::NELPolicy> loaded_policies;
+TEST(MockPersistentNelStoreTest, AddThenDelete) {
+ MockPersistentNelStore store;
+ MockPersistentNelStore::CommandList expected_commands;
+ std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
- store.LoadNELPolicies(
- MakeExpectedRunNELPoliciesLoadedCallback(&loaded_policies));
+ store.LoadNelPolicies(
+ MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
expected_commands.emplace_back(
- MockPersistentNELStore::Command::Type::LOAD_NEL_POLICIES);
+ MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
EXPECT_EQ(1u, store.GetAllCommands().size());
store.FinishLoading(true /* load_success */);
EXPECT_EQ(0u, loaded_policies.size());
- NetworkErrorLoggingService::NELPolicy policy = MakePolicyForOrigin(kOrigin);
- store.AddNELPolicy(policy);
+ NetworkErrorLoggingService::NelPolicy policy = MakePolicyForOrigin(kOrigin);
+ store.AddNelPolicy(policy);
expected_commands.emplace_back(
- MockPersistentNELStore::Command::Type::ADD_NEL_POLICY, policy);
+ MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy);
EXPECT_EQ(2u, store.GetAllCommands().size());
- store.DeleteNELPolicy(policy);
+ store.DeleteNelPolicy(policy);
expected_commands.emplace_back(
- MockPersistentNELStore::Command::Type::DELETE_NEL_POLICY, policy);
+ MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy);
EXPECT_EQ(3u, store.GetAllCommands().size());
store.Flush();
- expected_commands.emplace_back(MockPersistentNELStore::Command::Type::FLUSH);
+ expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
EXPECT_EQ(0, store.StoredPoliciesCount());
EXPECT_EQ(4u, store.GetAllCommands().size());
@@ -182,38 +182,38 @@ TEST(MockPersistentNELStoreTest, AddThenDelete) {
store.GetDebugString());
}
-TEST(MockPersistentNELStoreTest, AddFlushThenDelete) {
- MockPersistentNELStore store;
- MockPersistentNELStore::CommandList expected_commands;
- std::vector<NetworkErrorLoggingService::NELPolicy> loaded_policies;
+TEST(MockPersistentNelStoreTest, AddFlushThenDelete) {
+ MockPersistentNelStore store;
+ MockPersistentNelStore::CommandList expected_commands;
+ std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
- store.LoadNELPolicies(
- MakeExpectedRunNELPoliciesLoadedCallback(&loaded_policies));
+ store.LoadNelPolicies(
+ MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
expected_commands.emplace_back(
- MockPersistentNELStore::Command::Type::LOAD_NEL_POLICIES);
+ MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
EXPECT_EQ(1u, store.GetAllCommands().size());
store.FinishLoading(true /* load_success */);
EXPECT_EQ(0u, loaded_policies.size());
- NetworkErrorLoggingService::NELPolicy policy = MakePolicyForOrigin(kOrigin);
- store.AddNELPolicy(policy);
+ NetworkErrorLoggingService::NelPolicy policy = MakePolicyForOrigin(kOrigin);
+ store.AddNelPolicy(policy);
expected_commands.emplace_back(
- MockPersistentNELStore::Command::Type::ADD_NEL_POLICY, policy);
+ MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy);
EXPECT_EQ(2u, store.GetAllCommands().size());
store.Flush();
- expected_commands.emplace_back(MockPersistentNELStore::Command::Type::FLUSH);
+ expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
EXPECT_EQ(1, store.StoredPoliciesCount());
EXPECT_EQ(3u, store.GetAllCommands().size());
- store.DeleteNELPolicy(policy);
+ store.DeleteNelPolicy(policy);
expected_commands.emplace_back(
- MockPersistentNELStore::Command::Type::DELETE_NEL_POLICY, policy);
+ MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy);
EXPECT_EQ(4u, store.GetAllCommands().size());
store.Flush();
- expected_commands.emplace_back(MockPersistentNELStore::Command::Type::FLUSH);
+ expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
EXPECT_EQ(0, store.StoredPoliciesCount());
EXPECT_EQ(5u, store.GetAllCommands().size());
@@ -225,32 +225,32 @@ TEST(MockPersistentNELStoreTest, AddFlushThenDelete) {
store.GetDebugString());
}
-TEST(MockPersistentNELStoreTest, AddThenUpdate) {
- MockPersistentNELStore store;
- MockPersistentNELStore::CommandList expected_commands;
- std::vector<NetworkErrorLoggingService::NELPolicy> loaded_policies;
+TEST(MockPersistentNelStoreTest, AddThenUpdate) {
+ MockPersistentNelStore store;
+ MockPersistentNelStore::CommandList expected_commands;
+ std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
- store.LoadNELPolicies(
- MakeExpectedRunNELPoliciesLoadedCallback(&loaded_policies));
+ store.LoadNelPolicies(
+ MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
expected_commands.emplace_back(
- MockPersistentNELStore::Command::Type::LOAD_NEL_POLICIES);
+ MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
EXPECT_EQ(1u, store.GetAllCommands().size());
store.FinishLoading(true /* load_success */);
- NetworkErrorLoggingService::NELPolicy policy = MakePolicyForOrigin(kOrigin);
- store.AddNELPolicy(policy);
+ NetworkErrorLoggingService::NelPolicy policy = MakePolicyForOrigin(kOrigin);
+ store.AddNelPolicy(policy);
expected_commands.emplace_back(
- MockPersistentNELStore::Command::Type::ADD_NEL_POLICY, policy);
+ MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy);
EXPECT_EQ(2u, store.GetAllCommands().size());
- store.UpdateNELPolicyAccessTime(policy);
+ store.UpdateNelPolicyAccessTime(policy);
expected_commands.emplace_back(
- MockPersistentNELStore::Command::Type::UPDATE_NEL_POLICY, policy);
+ MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy);
EXPECT_EQ(3u, store.GetAllCommands().size());
store.Flush();
- expected_commands.emplace_back(MockPersistentNELStore::Command::Type::FLUSH);
+ expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
EXPECT_EQ(1, store.StoredPoliciesCount());
EXPECT_EQ(4u, store.GetAllCommands().size());
diff --git a/chromium/net/network_error_logging/network_error_logging_service.cc b/chromium/net/network_error_logging/network_error_logging_service.cc
index aa875fb26b4..43c699c8be8 100644
--- a/chromium/net/network_error_logging/network_error_logging_service.cc
+++ b/chromium/net/network_error_logging/network_error_logging_service.cc
@@ -9,6 +9,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
@@ -180,11 +181,17 @@ void RecordSignedExchangeRequestOutcome(
class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
public:
- explicit NetworkErrorLoggingServiceImpl(PersistentNELStore* store)
- : store_(store) {}
+ explicit NetworkErrorLoggingServiceImpl(PersistentNelStore* store)
+ : store_(store),
+ started_loading_policies_(false),
+ initialized_(false),
+ weak_factory_(this) {
+ if (!PoliciesArePersisted())
+ initialized_ = true;
+ }
~NetworkErrorLoggingServiceImpl() override {
- if (store_)
+ if (PoliciesArePersisted() && initialized_)
store_->Flush();
}
@@ -193,9 +200,6 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
void OnHeader(const url::Origin& origin,
const IPAddress& received_ip_address,
const std::string& value) override {
- if (shut_down_)
- return;
-
// NEL is only available to secure origins, so don't permit insecure origins
// to set policies.
if (!origin.GetURL().SchemeIsCryptographic()) {
@@ -203,10 +207,184 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
return;
}
- NELPolicy policy;
+ base::Time header_received_time = clock_->Now();
+ // base::Unretained is safe because the callback gets stored in
+ // task_backlog_, so the callback will not outlive |*this|.
+ DoOrBacklogTask(base::BindOnce(
+ &NetworkErrorLoggingServiceImpl::DoOnHeader, base::Unretained(this),
+ origin, received_ip_address, value, header_received_time));
+ }
+
+ void OnRequest(RequestDetails details) override {
+ // This method is only called on secure requests.
+ DCHECK(details.uri.SchemeIsCryptographic());
+
+ if (!reporting_service_) {
+ RecordRequestOutcome(RequestOutcome::kDiscardedNoReportingService);
+ return;
+ }
+
+ base::Time request_received_time = clock_->Now();
+ // base::Unretained is safe because the callback gets stored in
+ // task_backlog_, so the callback will not outlive |*this|.
+ DoOrBacklogTask(base::BindOnce(&NetworkErrorLoggingServiceImpl::DoOnRequest,
+ base::Unretained(this), std::move(details),
+ request_received_time));
+ }
+
+ void QueueSignedExchangeReport(SignedExchangeReportDetails details) override {
+ if (!reporting_service_) {
+ RecordSignedExchangeRequestOutcome(
+ RequestOutcome::kDiscardedNoReportingService);
+ return;
+ }
+ if (!details.outer_url.SchemeIsCryptographic()) {
+ RecordSignedExchangeRequestOutcome(
+ RequestOutcome::kDiscardedInsecureOrigin);
+ return;
+ }
+
+ base::Time request_received_time = clock_->Now();
+ // base::Unretained is safe because the callback gets stored in
+ // task_backlog_, so the callback will not outlive |*this|.
+ DoOrBacklogTask(base::BindOnce(
+ &NetworkErrorLoggingServiceImpl::DoQueueSignedExchangeReport,
+ base::Unretained(this), std::move(details), request_received_time));
+ }
+
+ void RemoveBrowsingData(const base::RepeatingCallback<bool(const GURL&)>&
+ origin_filter) override {
+ // base::Unretained is safe because the callback gets stored in
+ // task_backlog_, so the callback will not outlive |*this|.
+ DoOrBacklogTask(
+ base::BindOnce(&NetworkErrorLoggingServiceImpl::DoRemoveBrowsingData,
+ base::Unretained(this), origin_filter));
+ }
+
+ void RemoveAllBrowsingData() override {
+ // base::Unretained is safe because the callback gets stored in
+ // task_backlog_, so the callback will not outlive |*this|.
+ DoOrBacklogTask(
+ base::BindOnce(&NetworkErrorLoggingServiceImpl::DoRemoveAllBrowsingData,
+ base::Unretained(this)));
+ }
+
+ base::Value StatusAsValue() const override {
+ base::Value dict(base::Value::Type::DICTIONARY);
+ std::vector<base::Value> policy_list;
+ // We wanted sorted (or at least reproducible) output; luckily, policies_ is
+ // a std::map, and therefore already sorted.
+ for (const auto& origin_and_policy : policies_) {
+ const auto& origin = origin_and_policy.first;
+ const auto& policy = origin_and_policy.second;
+ base::Value policy_dict(base::Value::Type::DICTIONARY);
+ policy_dict.SetKey("origin", base::Value(origin.Serialize()));
+ policy_dict.SetKey("includeSubdomains",
+ base::Value(policy.include_subdomains));
+ policy_dict.SetKey("reportTo", base::Value(policy.report_to));
+ policy_dict.SetKey("expires",
+ base::Value(NetLog::TimeToString(policy.expires)));
+ policy_dict.SetKey("successFraction",
+ base::Value(policy.success_fraction));
+ policy_dict.SetKey("failureFraction",
+ base::Value(policy.failure_fraction));
+ policy_list.push_back(std::move(policy_dict));
+ }
+ dict.SetKey("originPolicies", base::Value(std::move(policy_list)));
+ return dict;
+ }
+
+ std::set<url::Origin> GetPolicyOriginsForTesting() override {
+ std::set<url::Origin> origins;
+ for (const auto& entry : policies_) {
+ origins.insert(entry.first);
+ }
+ return origins;
+ }
+
+ private:
+ // Map from origin to origin's (owned) policy.
+ // Would be unordered_map, but url::Origin has no hash.
+ using PolicyMap = std::map<url::Origin, NelPolicy>;
+
+ // Wildcard policies are policies for which the include_subdomains flag is
+ // set.
+ //
+ // Wildcard policies are accessed by domain name, not full origin, so there
+ // can be multiple wildcard policies per domain name.
+ //
+ // This is a map from domain name to the set of pointers to wildcard policies
+ // in that domain.
+ //
+ // Policies in the map are unowned; they are pointers to the original in the
+ // PolicyMap.
+ using WildcardPolicyMap = std::map<std::string, std::set<const NelPolicy*>>;
+
+ PolicyMap policies_;
+ WildcardPolicyMap wildcard_policies_;
+
+ // The persistent store in which NEL policies will be stored to disk, if not
+ // null. If |store_| is null, then NEL policies will be in-memory only.
+ // The store is owned by the URLRequestContext because Reporting also needs
+ // access to it.
+ PersistentNelStore* store_;
+
+ // Set to true when we have told the store to load NEL policies. This is to
+ // make sure we don't try to load policies multiple times.
+ bool started_loading_policies_;
+
+ // Set to true when the NEL service has been initialized. Before
+ // initialization is complete, commands to the NEL service (i.e. public
+ // method calls) are stashed away in |task_backlog_|, to be executed once
+ // initialization is complete. Initialization is complete automatically if
+ // there is no PersistentNelStore. If there is a store, then initialization is
+ // complete when the NEL policies have finished being loaded from the store
+ // (either successfully or unsuccessfully).
+ bool initialized_;
+
+ // Backlog of tasks waiting on initialization.
+ std::vector<base::OnceClosure> task_backlog_;
+
+ base::WeakPtrFactory<NetworkErrorLoggingServiceImpl> weak_factory_;
+
+ bool PoliciesArePersisted() const { return store_ != nullptr; }
+
+ void DoOrBacklogTask(base::OnceClosure task) {
+ if (shut_down_)
+ return;
+
+ FetchAllPoliciesFromStoreIfNecessary();
+
+ if (!initialized_) {
+ task_backlog_.push_back(std::move(task));
+ return;
+ }
+
+ std::move(task).Run();
+ }
+
+ void ExecuteBacklog() {
+ DCHECK(initialized_);
+
+ if (shut_down_)
+ return;
+
+ for (base::OnceClosure& task : task_backlog_) {
+ std::move(task).Run();
+ }
+ task_backlog_.clear();
+ }
+
+ void DoOnHeader(const url::Origin& origin,
+ const IPAddress& received_ip_address,
+ const std::string& value,
+ base::Time header_received_time) {
+ DCHECK(initialized_);
+
+ NelPolicy policy;
policy.origin = origin;
policy.received_ip_address = received_ip_address;
- policy.last_used = clock_->Now();
+ policy.last_used = header_received_time;
HeaderOutcome outcome = ParseHeader(value, clock_->Now(), &policy);
RecordHeaderOutcome(outcome);
if (outcome != HeaderOutcome::SET && outcome != HeaderOutcome::REMOVED)
@@ -224,9 +402,7 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
return;
DVLOG(1) << "Received NEL policy for " << origin;
- auto inserted = policies_.insert(std::make_pair(origin, policy));
- DCHECK(inserted.second);
- MaybeAddWildcardPolicy(origin, &inserted.first->second);
+ AddPolicy(std::move(policy));
// Evict policies if the policy limit is exceeded.
if (policies_.size() > kMaxPolicies) {
@@ -237,27 +413,18 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
}
}
- void OnRequest(RequestDetails details) override {
- if (shut_down_)
- return;
-
- if (!reporting_service_) {
- RecordRequestOutcome(RequestOutcome::kDiscardedNoReportingService);
- return;
- }
-
- // This method is only called on secure requests.
- DCHECK(details.uri.SchemeIsCryptographic());
+ void DoOnRequest(RequestDetails details, base::Time request_received_time) {
+ DCHECK(reporting_service_);
+ DCHECK(initialized_);
auto report_origin = url::Origin::Create(details.uri);
- const NELPolicy* policy = FindPolicyForOrigin(report_origin);
+ const NelPolicy* policy = FindPolicyForOrigin(report_origin);
if (!policy) {
RecordRequestOutcome(RequestOutcome::kDiscardedNoOriginPolicy);
return;
}
- // Mark the policy used.
- policy->last_used = clock_->Now();
+ MarkPolicyUsed(policy, request_received_time);
Error type = details.type;
// It is expected for Reporting uploads to terminate with ERR_ABORTED, since
@@ -329,31 +496,19 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
RecordRequestOutcome(RequestOutcome::kQueued);
}
- void QueueSignedExchangeReport(
- const SignedExchangeReportDetails& details) override {
- if (shut_down_)
- return;
+ void DoQueueSignedExchangeReport(SignedExchangeReportDetails details,
+ base::Time request_received_time) {
+ DCHECK(reporting_service_);
- if (!reporting_service_) {
- RecordSignedExchangeRequestOutcome(
- RequestOutcome::kDiscardedNoReportingService);
- return;
- }
- if (!details.outer_url.SchemeIsCryptographic()) {
- RecordSignedExchangeRequestOutcome(
- RequestOutcome::kDiscardedInsecureOrigin);
- return;
- }
const auto report_origin = url::Origin::Create(details.outer_url);
- const NELPolicy* policy = FindPolicyForOrigin(report_origin);
+ const NelPolicy* policy = FindPolicyForOrigin(report_origin);
if (!policy) {
RecordSignedExchangeRequestOutcome(
RequestOutcome::kDiscardedNoOriginPolicy);
return;
}
- // Mark the policy used.
- policy->last_used = clock_->Now();
+ MarkPolicyUsed(policy, request_received_time);
if (IsMismatchingSubdomainReport(*policy, report_origin)) {
RecordSignedExchangeRequestOutcome(
@@ -386,8 +541,9 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
RecordSignedExchangeRequestOutcome(RequestOutcome::kQueued);
}
- void RemoveBrowsingData(const base::RepeatingCallback<bool(const GURL&)>&
- origin_filter) override {
+ void DoRemoveBrowsingData(
+ const base::RepeatingCallback<bool(const GURL&)>& origin_filter) {
+ DCHECK(initialized_);
for (auto it = policies_.begin(); it != policies_.end();) {
const url::Origin& origin = it->first;
// Remove policies matching the filter.
@@ -397,77 +553,27 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
++it;
}
}
+ if (PoliciesArePersisted())
+ store_->Flush();
}
- void RemoveAllBrowsingData() override {
- wildcard_policies_.clear();
- policies_.clear();
- }
-
- base::Value StatusAsValue() const override {
- base::Value dict(base::Value::Type::DICTIONARY);
- std::vector<base::Value> policy_list;
- // We wanted sorted (or at least reproducible) output; luckily, policies_ is
- // a std::map, and therefore already sorted.
- for (const auto& origin_and_policy : policies_) {
- const auto& origin = origin_and_policy.first;
- const auto& policy = origin_and_policy.second;
- base::Value policy_dict(base::Value::Type::DICTIONARY);
- policy_dict.SetKey("origin", base::Value(origin.Serialize()));
- policy_dict.SetKey("includeSubdomains",
- base::Value(policy.include_subdomains));
- policy_dict.SetKey("reportTo", base::Value(policy.report_to));
- policy_dict.SetKey("expires",
- base::Value(NetLog::TimeToString(policy.expires)));
- policy_dict.SetKey("successFraction",
- base::Value(policy.success_fraction));
- policy_dict.SetKey("failureFraction",
- base::Value(policy.failure_fraction));
- policy_list.push_back(std::move(policy_dict));
+ void DoRemoveAllBrowsingData() {
+ DCHECK(initialized_);
+ if (PoliciesArePersisted()) {
+ // TODO(chlily): Add a DeleteAllNelPolicies command to PersistentNelStore.
+ for (auto origin_and_policy : policies_) {
+ store_->DeleteNelPolicy(origin_and_policy.second);
+ }
+ store_->Flush();
}
- dict.SetKey("originPolicies", base::Value(std::move(policy_list)));
- return dict;
- }
- std::set<url::Origin> GetPolicyOriginsForTesting() override {
- std::set<url::Origin> origins;
- for (const auto& entry : policies_) {
- origins.insert(entry.first);
- }
- return origins;
+ wildcard_policies_.clear();
+ policies_.clear();
}
- private:
- // Map from origin to origin's (owned) policy.
- // Would be unordered_map, but url::Origin has no hash.
- using PolicyMap = std::map<url::Origin, NELPolicy>;
-
- // Wildcard policies are policies for which the include_subdomains flag is
- // set.
- //
- // Wildcard policies are accessed by domain name, not full origin, so there
- // can be multiple wildcard policies per domain name.
- //
- // This is a map from domain name to the set of pointers to wildcard policies
- // in that domain.
- //
- // Policies in the map are unowned; they are pointers to the original in the
- // PolicyMap.
- using WildcardPolicyMap = std::map<std::string, std::set<const NELPolicy*>>;
-
- PolicyMap policies_;
- WildcardPolicyMap wildcard_policies_;
-
- // The persistent store in which NEL policies will be stored to disk, if not
- // null. If |store_| is null, then NEL policies will be in-memory only.
- // The store is owned by the URLRequestContext because Reporting also needs
- // access to it.
- // TODO(chlily): Implement.
- PersistentNELStore* store_;
-
HeaderOutcome ParseHeader(const std::string& json_value,
base::Time now,
- NELPolicy* policy_out) const {
+ NelPolicy* policy_out) const {
DCHECK(policy_out);
if (json_value.size() > kMaxJsonSize)
@@ -528,13 +634,15 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
}
}
- const NELPolicy* FindPolicyForOrigin(const url::Origin& origin) const {
+ const NelPolicy* FindPolicyForOrigin(const url::Origin& origin) const {
+ DCHECK(initialized_);
+
auto it = policies_.find(origin);
if (it != policies_.end() && clock_->Now() < it->second.expires)
return &it->second;
std::string domain = origin.host();
- const NELPolicy* wildcard_policy = nullptr;
+ const NelPolicy* wildcard_policy = nullptr;
while (!wildcard_policy && !domain.empty()) {
wildcard_policy = FindWildcardPolicyForDomain(domain);
domain = GetSuperdomain(domain);
@@ -543,7 +651,7 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
return wildcard_policy;
}
- const NELPolicy* FindWildcardPolicyForDomain(
+ const NelPolicy* FindWildcardPolicyForDomain(
const std::string& domain) const {
DCHECK(!domain.empty());
@@ -568,8 +676,27 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
return nullptr;
}
+ // There must be no pre-existing policy for |policy.origin|. Returns iterator
+ // to the inserted policy.
+ PolicyMap::iterator AddPolicy(NelPolicy policy) {
+ // If |initialized_| is false, then we are calling this from
+ // OnPoliciesLoaded(), which means we don't want to add the given policy to
+ // the store because we have just loaded it from there.
+ if (PoliciesArePersisted() && initialized_)
+ store_->AddNelPolicy(policy);
+
+ auto iter_and_result =
+ policies_.insert(std::make_pair(policy.origin, std::move(policy)));
+ DCHECK(iter_and_result.second);
+
+ const NelPolicy& inserted_policy = iter_and_result.first->second;
+ MaybeAddWildcardPolicy(inserted_policy.origin, &inserted_policy);
+
+ return iter_and_result.first;
+ }
+
void MaybeAddWildcardPolicy(const url::Origin& origin,
- const NELPolicy* policy) {
+ const NelPolicy* policy) {
DCHECK(policy);
DCHECK_EQ(policy, &policies_[origin]);
@@ -584,12 +711,16 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
// Returns the iterator to the next element.
PolicyMap::iterator RemovePolicy(PolicyMap::iterator policy_it) {
DCHECK(policy_it != policies_.end());
- NELPolicy* policy = &policy_it->second;
+ NelPolicy* policy = &policy_it->second;
MaybeRemoveWildcardPolicy(policy);
+
+ if (PoliciesArePersisted() && initialized_)
+ store_->DeleteNelPolicy(*policy);
+
return policies_.erase(policy_it);
}
- void MaybeRemoveWildcardPolicy(const NELPolicy* policy) {
+ void MaybeRemoveWildcardPolicy(const NelPolicy* policy) {
DCHECK(policy);
if (!policy->include_subdomains)
@@ -607,6 +738,12 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
wildcard_policies_.erase(wildcard_it);
}
+ void MarkPolicyUsed(const NelPolicy* policy, base::Time time_used) const {
+ policy->last_used = time_used;
+ if (PoliciesArePersisted() && initialized_)
+ store_->UpdateNelPolicyAccessTime(*policy);
+ }
+
void RemoveAllExpiredPolicies() {
for (auto it = policies_.begin(); it != policies_.end();) {
if (it->second.expires < clock_->Now()) {
@@ -679,13 +816,13 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
return std::move(body);
}
- bool IsMismatchingSubdomainReport(const NELPolicy& policy,
+ bool IsMismatchingSubdomainReport(const NelPolicy& policy,
const url::Origin& report_origin) const {
return policy.include_subdomains && (policy.origin != report_origin);
}
// Returns a valid value of matching fraction iff the event should be sampled.
- base::Optional<double> SampleAndReturnFraction(const NELPolicy& policy,
+ base::Optional<double> SampleAndReturnFraction(const NelPolicy& policy,
bool success) const {
const double sampling_fraction =
success ? policy.success_fraction : policy.failure_fraction;
@@ -701,16 +838,51 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
return base::nullopt;
return sampling_fraction;
}
+
+ void FetchAllPoliciesFromStoreIfNecessary() {
+ if (!PoliciesArePersisted() || started_loading_policies_)
+ return;
+
+ started_loading_policies_ = true;
+ FetchAllPoliciesFromStore();
+ }
+
+ void FetchAllPoliciesFromStore() {
+ DCHECK(PoliciesArePersisted());
+ DCHECK(!initialized_);
+
+ store_->LoadNelPolicies(
+ base::BindOnce(&NetworkErrorLoggingServiceImpl::OnPoliciesLoaded,
+ weak_factory_.GetWeakPtr()));
+ }
+
+ // This is called when loading from the store is complete, regardless of
+ // success or failure.
+ // DB initialization may have failed, in which case we will receive an empty
+ // vector from the PersistentNelStore. This is indistinguishable from a
+ // successful load that happens to not yield any policies, but in
+ // either case we still want to go through the task backlog.
+ void OnPoliciesLoaded(std::vector<NelPolicy> loaded_policies) {
+ DCHECK(PoliciesArePersisted());
+ DCHECK(!initialized_);
+
+ // TODO(chlily): Toss any expired policies we encounter.
+ for (NelPolicy& policy : loaded_policies) {
+ AddPolicy(std::move(policy));
+ }
+ initialized_ = true;
+ ExecuteBacklog();
+ }
};
} // namespace
-NetworkErrorLoggingService::NELPolicy::NELPolicy() = default;
+NetworkErrorLoggingService::NelPolicy::NelPolicy() = default;
-NetworkErrorLoggingService::NELPolicy::NELPolicy(const NELPolicy& other) =
+NetworkErrorLoggingService::NelPolicy::NelPolicy(const NelPolicy& other) =
default;
-NetworkErrorLoggingService::NELPolicy::~NELPolicy() = default;
+NetworkErrorLoggingService::NelPolicy::~NelPolicy() = default;
NetworkErrorLoggingService::RequestDetails::RequestDetails() = default;
@@ -807,7 +979,7 @@ void NetworkErrorLoggingService::RecordRequestDiscardedForInsecureOrigin() {
// static
std::unique_ptr<NetworkErrorLoggingService> NetworkErrorLoggingService::Create(
- PersistentNELStore* store) {
+ PersistentNelStore* store) {
return std::make_unique<NetworkErrorLoggingServiceImpl>(store);
}
@@ -815,12 +987,13 @@ NetworkErrorLoggingService::~NetworkErrorLoggingService() = default;
void NetworkErrorLoggingService::SetReportingService(
ReportingService* reporting_service) {
+ DCHECK(!reporting_service_);
reporting_service_ = reporting_service;
}
void NetworkErrorLoggingService::OnShutdown() {
shut_down_ = true;
- SetReportingService(nullptr);
+ reporting_service_ = nullptr;
}
void NetworkErrorLoggingService::SetClockForTesting(const base::Clock* clock) {
diff --git a/chromium/net/network_error_logging/network_error_logging_service.h b/chromium/net/network_error_logging/network_error_logging_service.h
index 642e2fc9932..7f38335b83c 100644
--- a/chromium/net/network_error_logging/network_error_logging_service.h
+++ b/chromium/net/network_error_logging/network_error_logging_service.h
@@ -41,13 +41,13 @@ namespace net {
class NET_EXPORT NetworkErrorLoggingService {
public:
- class PersistentNELStore;
+ class PersistentNelStore;
// NEL policy set by an origin.
- struct NET_EXPORT NELPolicy {
- NELPolicy();
- NELPolicy(const NELPolicy& other);
- ~NELPolicy();
+ struct NET_EXPORT NelPolicy {
+ NelPolicy();
+ NelPolicy(const NelPolicy& other);
+ ~NelPolicy();
url::Origin origin;
IPAddress received_ip_address = IPAddress();
@@ -201,7 +201,7 @@ class NET_EXPORT NetworkErrorLoggingService {
// NEL policies are persisted to disk if |store| is not null.
// The store, if given, should outlive |*this|.
static std::unique_ptr<NetworkErrorLoggingService> Create(
- PersistentNELStore* store);
+ PersistentNelStore* store);
virtual ~NetworkErrorLoggingService();
@@ -227,7 +227,7 @@ class NET_EXPORT NetworkErrorLoggingService {
// Queues a Signed Exchange report.
virtual void QueueSignedExchangeReport(
- const SignedExchangeReportDetails& details) = 0;
+ SignedExchangeReportDetails details) = 0;
// Removes browsing data (origin policies) associated with any origin for
// which |origin_filter| returns true.
@@ -241,10 +241,12 @@ class NET_EXPORT NetworkErrorLoggingService {
// Sets the ReportingService that will be used to queue network error reports.
// If |nullptr| is passed, reports will be queued locally or discarded.
// |reporting_service| must outlive the NetworkErrorLoggingService.
+ // Should not be called again if previously called with a non-null pointer.
void SetReportingService(ReportingService* reporting_service);
- // Shuts down the NEL service so that no more requests or headers are
- // processed and no more reports are queued.
+ // Shuts down the NEL service, so that no more requests or headers can be
+ // processed, no more reports are queued, and browsing data can no longer be
+ // cleared.
void OnShutdown();
// Sets a base::Clock (used to track policy expiration) for tests.
@@ -272,32 +274,32 @@ class NET_EXPORT NetworkErrorLoggingService {
};
// Persistent storage for NEL policies.
-class NET_EXPORT NetworkErrorLoggingService::PersistentNELStore {
+class NET_EXPORT NetworkErrorLoggingService::PersistentNelStore {
public:
- using NELPoliciesLoadedCallback =
- base::OnceCallback<void(std::vector<NELPolicy>)>;
+ using NelPoliciesLoadedCallback =
+ base::OnceCallback<void(std::vector<NelPolicy>)>;
- PersistentNELStore() = default;
- virtual ~PersistentNELStore() = default;
+ PersistentNelStore() = default;
+ virtual ~PersistentNelStore() = default;
// Initializes the store and retrieves stored NEL policies. This will be
// called only once at startup.
- virtual void LoadNELPolicies(NELPoliciesLoadedCallback loaded_callback) = 0;
+ virtual void LoadNelPolicies(NelPoliciesLoadedCallback loaded_callback) = 0;
// Adds a NEL policy to the store.
- virtual void AddNELPolicy(const NELPolicy& policy) = 0;
+ virtual void AddNelPolicy(const NelPolicy& policy) = 0;
// Updates the access time of the NEL policy in the store.
- virtual void UpdateNELPolicyAccessTime(const NELPolicy& policy) = 0;
+ virtual void UpdateNelPolicyAccessTime(const NelPolicy& policy) = 0;
// Deletes a NEL policy from the store.
- virtual void DeleteNELPolicy(const NELPolicy& policy) = 0;
+ virtual void DeleteNelPolicy(const NelPolicy& policy) = 0;
// Flushes the store.
virtual void Flush() = 0;
private:
- DISALLOW_COPY_AND_ASSIGN(PersistentNELStore);
+ DISALLOW_COPY_AND_ASSIGN(PersistentNelStore);
};
} // namespace net
diff --git a/chromium/net/network_error_logging/network_error_logging_service_unittest.cc b/chromium/net/network_error_logging/network_error_logging_service_unittest.cc
index 8e274fd5370..c1203fc9eae 100644
--- a/chromium/net/network_error_logging/network_error_logging_service_unittest.cc
+++ b/chromium/net/network_error_logging/network_error_logging_service_unittest.cc
@@ -18,8 +18,7 @@
#include "net/base/net_errors.h"
#include "net/network_error_logging/mock_persistent_nel_store.h"
#include "net/network_error_logging/network_error_logging_service.h"
-#include "net/reporting/reporting_policy.h"
-#include "net/reporting/reporting_service.h"
+#include "net/reporting/reporting_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -27,102 +26,20 @@
namespace net {
namespace {
-class TestReportingService : public ReportingService {
- public:
- struct Report {
- Report() = default;
-
- Report(Report&& other)
- : url(other.url),
- user_agent(other.user_agent),
- group(other.group),
- type(other.type),
- body(std::move(other.body)),
- depth(other.depth) {}
-
- Report(const GURL& url,
- const std::string& user_agent,
- const std::string& group,
- const std::string& type,
- std::unique_ptr<const base::Value> body,
- int depth)
- : url(url),
- user_agent(user_agent),
- group(group),
- type(type),
- body(std::move(body)),
- depth(depth) {}
-
- ~Report() = default;
-
- GURL url;
- std::string user_agent;
- std::string group;
- std::string type;
- std::unique_ptr<const base::Value> body;
- int depth;
-
- private:
- DISALLOW_COPY(Report);
- };
-
- TestReportingService() = default;
-
- const std::vector<Report>& reports() const { return reports_; }
-
- // ReportingService implementation:
-
- ~TestReportingService() override = default;
-
- void QueueReport(const GURL& url,
- const std::string& user_agent,
- const std::string& group,
- const std::string& type,
- std::unique_ptr<const base::Value> body,
- int depth) override {
- reports_.push_back(
- Report(url, user_agent, group, type, std::move(body), depth));
- }
-
- void ProcessHeader(const GURL& url,
- const std::string& header_value) override {
- NOTREACHED();
- }
-
- void RemoveBrowsingData(int data_type_mask,
- const base::RepeatingCallback<bool(const GURL&)>&
- origin_filter) override {
- NOTREACHED();
- }
-
- void RemoveAllBrowsingData(int data_type_mask) override { NOTREACHED(); }
-
- void OnShutdown() override {}
-
- const ReportingPolicy& GetPolicy() const override {
- NOTREACHED();
- return dummy_policy_;
- }
-
- ReportingContext* GetContextForTesting() const override {
- NOTREACHED();
- return nullptr;
- }
-
- private:
- std::vector<Report> reports_;
- ReportingPolicy dummy_policy_;
-
- DISALLOW_COPY_AND_ASSIGN(TestReportingService);
-};
-
// The tests are parametrized on a boolean value which represents whether or not
-// to use a MockPersistentNELStore.
+// to use a MockPersistentNelStore.
+// If a MockPersistentNelStore is used, then calls to
+// NetworkErrorLoggingService::OnHeader(), OnRequest(),
+// QueueSignedExchangeReport(), RemoveBrowsingData(), and
+// RemoveAllBrowsingData() will block until the store finishes loading.
+// Therefore, for tests that should run synchronously (i.e. tests that don't
+// specifically test the asynchronous/deferred task behavior), FinishLoading()
+// must be called after the first call to one of the above methods.
class NetworkErrorLoggingServiceTest : public ::testing::TestWithParam<bool> {
protected:
NetworkErrorLoggingServiceTest() {
if (GetParam()) {
- store_ = std::make_unique<MockPersistentNELStore>();
+ store_ = std::make_unique<MockPersistentNelStore>();
} else {
store_.reset(nullptr);
}
@@ -137,13 +54,6 @@ class NetworkErrorLoggingServiceTest : public ::testing::TestWithParam<bool> {
service_->SetReportingService(reporting_service_.get());
}
- void DestroyReportingService() {
- DCHECK(reporting_service_);
-
- service_->SetReportingService(nullptr);
- reporting_service_.reset();
- }
-
NetworkErrorLoggingService::RequestDetails MakeRequestDetails(
GURL url,
Error error_type,
@@ -188,7 +98,7 @@ class NetworkErrorLoggingServiceTest : public ::testing::TestWithParam<bool> {
return details;
}
NetworkErrorLoggingService* service() { return service_.get(); }
- MockPersistentNELStore* store() { return store_.get(); }
+ MockPersistentNelStore* store() { return store_.get(); }
const std::vector<TestReportingService::Report>& reports() {
return reporting_service_->reports();
}
@@ -198,6 +108,18 @@ class NetworkErrorLoggingServiceTest : public ::testing::TestWithParam<bool> {
return url::Origin::Create(url);
}
+ NetworkErrorLoggingService::NelPolicy MakePolicyForOrigin(
+ url::Origin origin,
+ base::Time expires = base::Time(),
+ base::Time last_used = base::Time()) {
+ NetworkErrorLoggingService::NelPolicy policy;
+ policy.origin = std::move(origin);
+ policy.expires = expires;
+ policy.last_used = last_used;
+
+ return policy;
+ }
+
// Returns whether the NetworkErrorLoggingService has a policy corresponding
// to |origin|. Returns true if so, even if the policy is expired.
bool HasPolicyForOrigin(const url::Origin& origin) {
@@ -208,6 +130,12 @@ class NetworkErrorLoggingServiceTest : public ::testing::TestWithParam<bool> {
size_t PolicyCount() { return service_->GetPolicyOriginsForTesting().size(); }
+ // Makes the rest of the test run synchronously.
+ void FinishLoading(bool load_success) {
+ if (store())
+ store()->FinishLoading(load_success);
+ }
+
const GURL kUrl_ = GURL("https://example.com/path");
const GURL kUrlDifferentPort_ = GURL("https://example.com:4433/path");
const GURL kUrlSubdomain_ = GURL("https://subdomain.example.com/path");
@@ -247,9 +175,8 @@ class NetworkErrorLoggingServiceTest : public ::testing::TestWithParam<bool> {
const GURL kReferrer_ = GURL("https://referrer.com/");
- private:
// |store_| needs to outlive |service_|.
- std::unique_ptr<MockPersistentNELStore> store_;
+ std::unique_ptr<MockPersistentNelStore> store_;
std::unique_ptr<NetworkErrorLoggingService> service_;
std::unique_ptr<TestReportingService> reporting_service_;
};
@@ -268,22 +195,32 @@ TEST_P(NetworkErrorLoggingServiceTest, CreateService) {
}
TEST_P(NetworkErrorLoggingServiceTest, NoReportingService) {
- DestroyReportingService();
+ service_ = NetworkErrorLoggingService::Create(store_.get());
service()->OnHeader(kOrigin_, kServerIP_, kHeader_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
+ // Should not crash.
service()->OnRequest(MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED));
}
TEST_P(NetworkErrorLoggingServiceTest, NoPolicyForOrigin) {
service()->OnRequest(MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED));
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
EXPECT_TRUE(reports().empty());
}
TEST_P(NetworkErrorLoggingServiceTest, JsonTooLong) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderTooLong_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED));
EXPECT_TRUE(reports().empty());
@@ -292,6 +229,9 @@ TEST_P(NetworkErrorLoggingServiceTest, JsonTooLong) {
TEST_P(NetworkErrorLoggingServiceTest, JsonTooDeep) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderTooDeep_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED));
EXPECT_TRUE(reports().empty());
@@ -300,6 +240,9 @@ TEST_P(NetworkErrorLoggingServiceTest, JsonTooDeep) {
TEST_P(NetworkErrorLoggingServiceTest, SuccessReportQueued) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(MakeRequestDetails(kUrl_, OK));
ASSERT_EQ(1u, reports().size());
@@ -337,6 +280,9 @@ TEST_P(NetworkErrorLoggingServiceTest, FailureReportQueued) {
"{\"report_to\":\"group\",\"max_age\":86400,\"failure_fraction\":1.0}";
service()->OnHeader(kOrigin_, kServerIP_, kHeaderFailureFraction1);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED));
ASSERT_EQ(1u, reports().size());
@@ -374,6 +320,9 @@ TEST_P(NetworkErrorLoggingServiceTest, UnknownFailureReportQueued) {
"{\"report_to\":\"group\",\"max_age\":86400,\"failure_fraction\":1.0}";
service()->OnHeader(kOrigin_, kServerIP_, kHeaderFailureFraction1);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
// This error code happens to not be mapped to a NEL report `type` field
// value.
service()->OnRequest(MakeRequestDetails(kUrl_, ERR_FILE_NO_SPACE));
@@ -392,6 +341,9 @@ TEST_P(NetworkErrorLoggingServiceTest, UnknownCertFailureReportQueued) {
"{\"report_to\":\"group\",\"max_age\":86400,\"failure_fraction\":1.0}";
service()->OnHeader(kOrigin_, kServerIP_, kHeaderFailureFraction1);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
// This error code happens to not be mapped to a NEL report `type` field
// value. Because it's a certificate error, we'll set the `phase` to be
// `connection`.
@@ -411,6 +363,9 @@ TEST_P(NetworkErrorLoggingServiceTest, HttpErrorReportQueued) {
"{\"report_to\":\"group\",\"max_age\":86400,\"failure_fraction\":1.0}";
service()->OnHeader(kOrigin_, kServerIP_, kHeaderFailureFraction1);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(MakeRequestDetails(kUrl_, OK, "GET", 504));
ASSERT_EQ(1u, reports().size());
@@ -446,6 +401,9 @@ TEST_P(NetworkErrorLoggingServiceTest, HttpErrorReportQueued) {
TEST_P(NetworkErrorLoggingServiceTest, SuccessReportDowngraded) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(
MakeRequestDetails(kUrl_, OK, "GET", 200, kOtherServerIP_));
@@ -480,6 +438,9 @@ TEST_P(NetworkErrorLoggingServiceTest, SuccessReportDowngraded) {
TEST_P(NetworkErrorLoggingServiceTest, FailureReportDowngraded) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED, "GET",
200, kOtherServerIP_));
@@ -514,6 +475,9 @@ TEST_P(NetworkErrorLoggingServiceTest, FailureReportDowngraded) {
TEST_P(NetworkErrorLoggingServiceTest, HttpErrorReportDowngraded) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(
MakeRequestDetails(kUrl_, OK, "GET", 504, kOtherServerIP_));
@@ -548,6 +512,9 @@ TEST_P(NetworkErrorLoggingServiceTest, HttpErrorReportDowngraded) {
TEST_P(NetworkErrorLoggingServiceTest, DNSFailureReportNotDowngraded) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(MakeRequestDetails(kUrl_, ERR_NAME_NOT_RESOLVED, "GET",
0, kOtherServerIP_));
@@ -582,6 +549,9 @@ TEST_P(NetworkErrorLoggingServiceTest, DNSFailureReportNotDowngraded) {
TEST_P(NetworkErrorLoggingServiceTest, SuccessPOSTReportQueued) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(MakeRequestDetails(kUrl_, OK, "POST"));
ASSERT_EQ(1u, reports().size());
@@ -610,6 +580,10 @@ TEST_P(NetworkErrorLoggingServiceTest, SuccessPOSTReportQueued) {
TEST_P(NetworkErrorLoggingServiceTest, MaxAge0) {
service()->OnHeader(kOrigin_, kServerIP_, kHeader_);
+
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
EXPECT_EQ(1u, PolicyCount());
// Max_age of 0 removes the policy.
@@ -624,6 +598,9 @@ TEST_P(NetworkErrorLoggingServiceTest, MaxAge0) {
TEST_P(NetworkErrorLoggingServiceTest, SuccessFraction0) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction0_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
// Each network error has a 0% chance of being reported. Fire off several and
// verify that no reports are produced.
constexpr size_t kReportCount = 100;
@@ -641,6 +618,9 @@ TEST_P(NetworkErrorLoggingServiceTest, SuccessFractionHalf) {
"\"failure_fraction\":0.25}";
service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFractionHalf);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
// Each network error has a 50% chance of being reported. Fire off several
// and verify that some requests were reported and some weren't. (We can't
// verify exact counts because each decision is made randomly.)
@@ -672,6 +652,9 @@ TEST_P(NetworkErrorLoggingServiceTest, FailureFraction0) {
"{\"report_to\":\"group\",\"max_age\":86400,\"failure_fraction\":0.0}";
service()->OnHeader(kOrigin_, kServerIP_, kHeaderFailureFraction0);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
// Each network error has a 0% chance of being reported. Fire off several and
// verify that no reports are produced.
constexpr size_t kReportCount = 100;
@@ -689,6 +672,9 @@ TEST_P(NetworkErrorLoggingServiceTest, FailureFractionHalf) {
"\"success_fraction\":0.25}";
service()->OnHeader(kOrigin_, kServerIP_, kHeaderFailureFractionHalf);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
// Each network error has a 50% chance of being reported. Fire off several
// and verify that some requests were reported and some weren't. (We can't
// verify exact counts because each decision is made randomly.)
@@ -717,6 +703,9 @@ TEST_P(NetworkErrorLoggingServiceTest,
ExcludeSubdomainsDoesntMatchDifferentPort) {
service()->OnHeader(kOrigin_, kServerIP_, kHeader_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(
MakeRequestDetails(kUrlDifferentPort_, ERR_CONNECTION_REFUSED));
@@ -726,6 +715,9 @@ TEST_P(NetworkErrorLoggingServiceTest,
TEST_P(NetworkErrorLoggingServiceTest, ExcludeSubdomainsDoesntMatchSubdomain) {
service()->OnHeader(kOrigin_, kServerIP_, kHeader_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(
MakeRequestDetails(kUrlSubdomain_, ERR_CONNECTION_REFUSED));
@@ -735,6 +727,9 @@ TEST_P(NetworkErrorLoggingServiceTest, ExcludeSubdomainsDoesntMatchSubdomain) {
TEST_P(NetworkErrorLoggingServiceTest, IncludeSubdomainsMatchesDifferentPort) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderIncludeSubdomains_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(
MakeRequestDetails(kUrlDifferentPort_, ERR_NAME_NOT_RESOLVED));
@@ -745,6 +740,9 @@ TEST_P(NetworkErrorLoggingServiceTest, IncludeSubdomainsMatchesDifferentPort) {
TEST_P(NetworkErrorLoggingServiceTest, IncludeSubdomainsMatchesSubdomain) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderIncludeSubdomains_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(
MakeRequestDetails(kUrlSubdomain_, ERR_NAME_NOT_RESOLVED));
@@ -755,6 +753,9 @@ TEST_P(NetworkErrorLoggingServiceTest,
IncludeSubdomainsDoesntMatchSuperdomain) {
service()->OnHeader(kOriginSubdomain_, kServerIP_, kHeaderIncludeSubdomains_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(MakeRequestDetails(kUrl_, ERR_NAME_NOT_RESOLVED));
EXPECT_TRUE(reports().empty());
@@ -764,6 +765,9 @@ TEST_P(NetworkErrorLoggingServiceTest,
IncludeSubdomainsDoesntReportConnectionError) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderIncludeSubdomains_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(
MakeRequestDetails(kUrlSubdomain_, ERR_CONNECTION_REFUSED));
@@ -774,6 +778,9 @@ TEST_P(NetworkErrorLoggingServiceTest,
IncludeSubdomainsDoesntReportApplicationError) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderIncludeSubdomains_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(
MakeRequestDetails(kUrlSubdomain_, ERR_INVALID_HTTP_RESPONSE));
@@ -783,6 +790,9 @@ TEST_P(NetworkErrorLoggingServiceTest,
TEST_P(NetworkErrorLoggingServiceTest, IncludeSubdomainsDoesntReportSuccess) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderIncludeSubdomains_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(MakeRequestDetails(kUrlSubdomain_, OK));
EXPECT_TRUE(reports().empty());
@@ -795,6 +805,9 @@ TEST_P(NetworkErrorLoggingServiceTest,
"\"include_subdomains\":true,\"success_fraction\":1.0}";
service()->OnHeader(kOrigin_, kServerIP_, kHeaderIncludeSubdomainsSuccess1);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnRequest(MakeRequestDetails(kUrl_, OK));
ASSERT_EQ(1u, reports().size());
@@ -803,6 +816,10 @@ TEST_P(NetworkErrorLoggingServiceTest,
TEST_P(NetworkErrorLoggingServiceTest, RemoveAllBrowsingData) {
service()->OnHeader(kOrigin_, kServerIP_, kHeader_);
+
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
EXPECT_EQ(1u, PolicyCount());
EXPECT_TRUE(HasPolicyForOrigin(kOrigin_));
@@ -817,6 +834,10 @@ TEST_P(NetworkErrorLoggingServiceTest, RemoveAllBrowsingData) {
TEST_P(NetworkErrorLoggingServiceTest, RemoveSomeBrowsingData) {
service()->OnHeader(kOrigin_, kServerIP_, kHeader_);
+
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnHeader(kOriginDifferentHost_, kServerIP_, kHeader_);
EXPECT_EQ(2u, PolicyCount());
@@ -842,6 +863,9 @@ TEST_P(NetworkErrorLoggingServiceTest, RemoveSomeBrowsingData) {
TEST_P(NetworkErrorLoggingServiceTest, Nested) {
service()->OnHeader(kOrigin_, kServerIP_, kHeader_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
NetworkErrorLoggingService::RequestDetails details =
MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED);
details.reporting_upload_depth =
@@ -856,6 +880,9 @@ TEST_P(NetworkErrorLoggingServiceTest, Nested) {
TEST_P(NetworkErrorLoggingServiceTest, NestedTooDeep) {
service()->OnHeader(kOrigin_, kServerIP_, kHeader_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
NetworkErrorLoggingService::RequestDetails details =
MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED);
details.reporting_upload_depth =
@@ -880,6 +907,10 @@ TEST_P(NetworkErrorLoggingServiceTest, StatusAsValue) {
clock.Advance(delta_from_origin);
service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
+
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->OnHeader(kOriginDifferentHost_, kServerIP_, kHeader_);
service()->OnHeader(kOriginSubdomain_, kServerIP_, kHeaderIncludeSubdomains_);
const std::string kHeaderWrongTypes =
@@ -938,9 +969,14 @@ TEST_P(NetworkErrorLoggingServiceTest, StatusAsValue) {
}
TEST_P(NetworkErrorLoggingServiceTest, NoReportingService_SignedExchange) {
- DestroyReportingService();
+ service_ = NetworkErrorLoggingService::Create(store_.get());
service()->OnHeader(kOrigin_, kServerIP_, kHeader_);
+
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
+ // Should not crash
service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
}
@@ -948,12 +984,19 @@ TEST_P(NetworkErrorLoggingServiceTest, NoReportingService_SignedExchange) {
TEST_P(NetworkErrorLoggingServiceTest, NoPolicyForOrigin_SignedExchange) {
service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
+
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
EXPECT_TRUE(reports().empty());
}
TEST_P(NetworkErrorLoggingServiceTest, SuccessFraction0_SignedExchange) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction0_);
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
// Each network error has a 0% chance of being reported. Fire off several and
// verify that no reports are produced.
constexpr size_t kReportCount = 100;
@@ -967,6 +1010,10 @@ TEST_P(NetworkErrorLoggingServiceTest, SuccessFraction0_SignedExchange) {
TEST_P(NetworkErrorLoggingServiceTest, SuccessReportQueued_SignedExchange) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction1_);
+
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
true, "ok", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
ASSERT_EQ(1u, reports().size());
@@ -1013,6 +1060,10 @@ TEST_P(NetworkErrorLoggingServiceTest, SuccessReportQueued_SignedExchange) {
TEST_P(NetworkErrorLoggingServiceTest, FailureReportQueued_SignedExchange) {
service()->OnHeader(kOrigin_, kServerIP_, kHeader_);
+
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
ASSERT_EQ(1u, reports().size());
@@ -1059,6 +1110,10 @@ TEST_P(NetworkErrorLoggingServiceTest, FailureReportQueued_SignedExchange) {
TEST_P(NetworkErrorLoggingServiceTest, MismatchingSubdomain_SignedExchange) {
service()->OnHeader(kOrigin_, kServerIP_, kHeaderIncludeSubdomains_);
+
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
false, "sxg.failed", kUrlSubdomain_, kInnerUrl_, kCertUrl_, kServerIP_));
EXPECT_TRUE(reports().empty());
@@ -1066,6 +1121,10 @@ TEST_P(NetworkErrorLoggingServiceTest, MismatchingSubdomain_SignedExchange) {
TEST_P(NetworkErrorLoggingServiceTest, MismatchingIPAddress_SignedExchange) {
service()->OnHeader(kOrigin_, kServerIP_, kHeader_);
+
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kOtherServerIP_));
EXPECT_TRUE(reports().empty());
@@ -1081,6 +1140,9 @@ TEST_P(NetworkErrorLoggingServiceTest, EvictAllExpiredPoliciesFirst) {
for (size_t i = 0; i < 100; ++i) {
service()->OnHeader(MakeOrigin(i), kServerIP_, kHeader_);
}
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+
EXPECT_EQ(100u, PolicyCount());
clock.Advance(base::TimeDelta::FromSeconds(86401)); // max_age is 86400 sec
// Expired policies are allowed to linger before hitting the policy limit.
@@ -1106,6 +1168,8 @@ TEST_P(NetworkErrorLoggingServiceTest, EvictLeastRecentlyUsedPolicy) {
service()->OnHeader(MakeOrigin(i), kServerIP_, kHeader_);
clock.Advance(base::TimeDelta::FromSeconds(1));
}
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
EXPECT_EQ(PolicyCount(), NetworkErrorLoggingService::kMaxPolicies);
@@ -1152,6 +1216,315 @@ TEST_P(NetworkErrorLoggingServiceTest, EvictLeastRecentlyUsedPolicy) {
// this test.
}
+TEST_P(NetworkErrorLoggingServiceTest, SendsCommandsToStoreSynchronous) {
+ if (!store())
+ return;
+
+ MockPersistentNelStore::CommandList expected_commands;
+ NetworkErrorLoggingService::NelPolicy policy1 = MakePolicyForOrigin(kOrigin_);
+ NetworkErrorLoggingService::NelPolicy policy2 =
+ MakePolicyForOrigin(kOriginDifferentHost_);
+ std::vector<NetworkErrorLoggingService::NelPolicy> prestored_policies = {
+ policy1, policy2};
+ store()->SetPrestoredPolicies(std::move(prestored_policies));
+
+ // The first call to any of the public methods triggers a load.
+ service()->OnHeader(kOrigin_, kServerIP_, kHeader_);
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ // Make the rest of the test run synchronously.
+ FinishLoading(true /* load_success */);
+ // DoOnHeader() should now execute.
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy1);
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy1);
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ service()->OnRequest(
+ MakeRequestDetails(kOrigin_.GetURL(), ERR_CONNECTION_REFUSED));
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy1);
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
+ false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy1);
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ // Removes policy1 but not policy2.
+ EXPECT_EQ(2, store()->StoredPoliciesCount());
+ service()->RemoveBrowsingData(
+ base::BindRepeating([](const GURL& origin) -> bool {
+ return origin.host() == "example.com";
+ }));
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy1);
+ expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
+ EXPECT_EQ(1, store()->StoredPoliciesCount());
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ service()->RemoveAllBrowsingData();
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy2);
+ expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
+ EXPECT_EQ(0, store()->StoredPoliciesCount());
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+}
+
+// Same as the above test, except that all the tasks are queued until loading
+// is complete.
+TEST_P(NetworkErrorLoggingServiceTest, SendsCommandsToStoreDeferred) {
+ if (!store())
+ return;
+
+ MockPersistentNelStore::CommandList expected_commands;
+ NetworkErrorLoggingService::NelPolicy policy1 = MakePolicyForOrigin(kOrigin_);
+ NetworkErrorLoggingService::NelPolicy policy2 =
+ MakePolicyForOrigin(kOriginDifferentHost_);
+ std::vector<NetworkErrorLoggingService::NelPolicy> prestored_policies = {
+ policy1, policy2};
+ store()->SetPrestoredPolicies(std::move(prestored_policies));
+
+ // The first call to any of the public methods triggers a load.
+ service()->OnHeader(kOrigin_, kServerIP_, kHeader_);
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ service()->OnRequest(
+ MakeRequestDetails(kOrigin_.GetURL(), ERR_CONNECTION_REFUSED));
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
+ false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ // Removes policy1 but not policy2.
+ service()->RemoveBrowsingData(
+ base::BindRepeating([](const GURL& origin) -> bool {
+ return origin.host() == "example.com";
+ }));
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ service()->RemoveAllBrowsingData();
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ // The store has not yet been told to remove the policies because the tasks
+ // to remove browsing data were queued pending initialization.
+ EXPECT_EQ(2, store()->StoredPoliciesCount());
+
+ FinishLoading(true /* load_success */);
+ // DoOnHeader()
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy1);
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy1);
+ // DoOnRequest()
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy1);
+ // DoQueueSignedExchangeReport()
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy1);
+ // DoRemoveBrowsingData()
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy1);
+ expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
+ // DoRemoveAllBrowsingData()
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy2);
+ expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+}
+
+// These two tests check that if loading fails, the commands should still
+// be sent to the store; the actual store impl will just ignore them.
+TEST_P(NetworkErrorLoggingServiceTest,
+ SendsCommandsToStoreSynchronousLoadFailed) {
+ if (!store())
+ return;
+
+ MockPersistentNelStore::CommandList expected_commands;
+ NetworkErrorLoggingService::NelPolicy policy1 = MakePolicyForOrigin(kOrigin_);
+ NetworkErrorLoggingService::NelPolicy policy2 =
+ MakePolicyForOrigin(kOriginDifferentHost_);
+ std::vector<NetworkErrorLoggingService::NelPolicy> prestored_policies = {
+ policy1, policy2};
+ store()->SetPrestoredPolicies(std::move(prestored_policies));
+
+ // The first call to any of the public methods triggers a load.
+ service()->OnHeader(kOrigin_, kServerIP_, kHeader_);
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ // Make the rest of the test run synchronously.
+ FinishLoading(false /* load_success */);
+ // DoOnHeader() should now execute.
+ // Because the load failed, there will be no policies in memory, so the store
+ // is not told to delete anything.
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy1);
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+ LOG(INFO) << store()->GetDebugString();
+
+ service()->OnRequest(
+ MakeRequestDetails(kOrigin_.GetURL(), ERR_CONNECTION_REFUSED));
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy1);
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
+ false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy1);
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ // Removes policy1 but not policy2.
+ service()->RemoveBrowsingData(
+ base::BindRepeating([](const GURL& origin) -> bool {
+ return origin.host() == "example.com";
+ }));
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy1);
+ expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ service()->RemoveAllBrowsingData();
+ // We failed to load policy2 from the store, so there is nothing to remove
+ // here.
+ expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+}
+
+TEST_P(NetworkErrorLoggingServiceTest, SendsCommandsToStoreDeferredLoadFailed) {
+ if (!store())
+ return;
+
+ MockPersistentNelStore::CommandList expected_commands;
+ NetworkErrorLoggingService::NelPolicy policy1 = MakePolicyForOrigin(kOrigin_);
+ NetworkErrorLoggingService::NelPolicy policy2 =
+ MakePolicyForOrigin(kOriginDifferentHost_);
+ std::vector<NetworkErrorLoggingService::NelPolicy> prestored_policies = {
+ policy1, policy2};
+ store()->SetPrestoredPolicies(std::move(prestored_policies));
+
+ // The first call to any of the public methods triggers a load.
+ service()->OnHeader(kOrigin_, kServerIP_, kHeader_);
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ service()->OnRequest(
+ MakeRequestDetails(kOrigin_.GetURL(), ERR_CONNECTION_REFUSED));
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
+ false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ // Removes policy1 but not policy2.
+ service()->RemoveBrowsingData(
+ base::BindRepeating([](const GURL& origin) -> bool {
+ return origin.host() == "example.com";
+ }));
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ service()->RemoveAllBrowsingData();
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ FinishLoading(false /* load_success */);
+ // DoOnHeader()
+ // Because the load failed, there will be no policies in memory, so the store
+ // is not told to delete anything.
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy1);
+ // DoOnRequest()
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy1);
+ // DoQueueSignedExchangeReport()
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy1);
+ // DoRemoveBrowsingData()
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy1);
+ expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
+ // DoRemoveAllBrowsingData()
+ // We failed to load policy2 from the store, so there is nothing to remove
+ // here.
+ expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+}
+
+TEST_P(NetworkErrorLoggingServiceTest, FlushesStoreOnDestruction) {
+ auto store = std::make_unique<MockPersistentNelStore>();
+ std::unique_ptr<NetworkErrorLoggingService> service =
+ NetworkErrorLoggingService::Create(store.get());
+
+ MockPersistentNelStore::CommandList expected_commands;
+
+ service->OnHeader(kOrigin_, kServerIP_, kHeader_);
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
+ EXPECT_TRUE(store->VerifyCommands(expected_commands));
+
+ store->FinishLoading(false /* load_success */);
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::ADD_NEL_POLICY,
+ MakePolicyForOrigin(kOrigin_));
+ EXPECT_TRUE(store->VerifyCommands(expected_commands));
+
+ // Store should be flushed on destruction of service.
+ service.reset();
+ expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
+ EXPECT_TRUE(store->VerifyCommands(expected_commands));
+}
+
+TEST_P(NetworkErrorLoggingServiceTest,
+ DoesntFlushStoreOnDestructionBeforeLoad) {
+ auto store = std::make_unique<MockPersistentNelStore>();
+ std::unique_ptr<NetworkErrorLoggingService> service =
+ NetworkErrorLoggingService::Create(store.get());
+
+ service.reset();
+ EXPECT_EQ(0u, store->GetAllCommands().size());
+}
+
+TEST_P(NetworkErrorLoggingServiceTest, DoNothingIfShutDown) {
+ if (!store())
+ return;
+
+ MockPersistentNelStore::CommandList expected_commands;
+
+ // The first call to any of the public methods triggers a load.
+ service()->OnHeader(kOrigin_, kServerIP_, kHeader_);
+ expected_commands.emplace_back(
+ MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
+ EXPECT_TRUE(store()->VerifyCommands(expected_commands));
+
+ service()->OnRequest(
+ MakeRequestDetails(kOrigin_.GetURL(), ERR_CONNECTION_REFUSED));
+ service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails(
+ false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_));
+ service()->RemoveBrowsingData(
+ base::BindRepeating([](const GURL& origin) -> bool {
+ return origin.host() == "example.com";
+ }));
+ service()->RemoveAllBrowsingData();
+
+ // Finish loading after the service has been shut down.
+ service()->OnShutdown();
+ FinishLoading(true /* load_success */);
+
+ // Only the LOAD command should have been sent to the store.
+ EXPECT_EQ(1u, store()->GetAllCommands().size());
+ EXPECT_EQ(0u, PolicyCount());
+ EXPECT_EQ(0u, reports().size());
+}
+
INSTANTIATE_TEST_SUITE_P(NetworkErrorLoggingServiceStoreTest,
NetworkErrorLoggingServiceTest,
testing::Bool());
diff --git a/chromium/net/network_error_logging/network_error_logging_test_util.cc b/chromium/net/network_error_logging/network_error_logging_test_util.cc
index 54d637613d9..a75a06d8e49 100644
--- a/chromium/net/network_error_logging/network_error_logging_test_util.cc
+++ b/chromium/net/network_error_logging/network_error_logging_test_util.cc
@@ -33,7 +33,7 @@ void TestNetworkErrorLoggingService::OnRequest(RequestDetails details) {
}
void TestNetworkErrorLoggingService::QueueSignedExchangeReport(
- const SignedExchangeReportDetails& details) {}
+ SignedExchangeReportDetails details) {}
void TestNetworkErrorLoggingService::RemoveBrowsingData(
const base::RepeatingCallback<bool(const GURL&)>& origin_filter) {}
diff --git a/chromium/net/network_error_logging/network_error_logging_test_util.h b/chromium/net/network_error_logging/network_error_logging_test_util.h
index 3eb29c3c4e8..c6af9416b29 100644
--- a/chromium/net/network_error_logging/network_error_logging_test_util.h
+++ b/chromium/net/network_error_logging/network_error_logging_test_util.h
@@ -48,8 +48,7 @@ class TestNetworkErrorLoggingService : public NetworkErrorLoggingService {
const IPAddress& received_ip_address,
const std::string& value) override;
void OnRequest(RequestDetails details) override;
- void QueueSignedExchangeReport(
- const SignedExchangeReportDetails& details) override;
+ void QueueSignedExchangeReport(SignedExchangeReportDetails details) override;
void RemoveBrowsingData(
const base::RepeatingCallback<bool(const GURL&)>& origin_filter) override;
void RemoveAllBrowsingData() override;
diff --git a/chromium/net/network_error_logging/persistent_reporting_and_nel_store.h b/chromium/net/network_error_logging/persistent_reporting_and_nel_store.h
index ac97e912776..49ae5848770 100644
--- a/chromium/net/network_error_logging/persistent_reporting_and_nel_store.h
+++ b/chromium/net/network_error_logging/persistent_reporting_and_nel_store.h
@@ -11,9 +11,9 @@
namespace net {
// Stores Reporting reports, Reporting clients, and NEL policies.
-class NET_EXPORT PersistentReportingAndNELStore
+class NET_EXPORT PersistentReportingAndNelStore
: public ReportingCache::PersistentReportingStore,
- public NetworkErrorLoggingService::PersistentNELStore {};
+ public NetworkErrorLoggingService::PersistentNelStore {};
} // namespace net