blob: 2835df49cb428d2765bacb3aac2425687ebcba46 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string>
#include "base/location.h"
#include "base/test/bind_test_util.h"
#include "net/network_error_logging/mock_persistent_nel_store.h"
#include "net/network_error_logging/network_error_logging_service.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace net {
namespace {
const url::Origin kOrigin = url::Origin::Create(GURL("https://example.test/"));
NetworkErrorLoggingService::NelPolicy MakePolicyForOrigin(url::Origin origin) {
NetworkErrorLoggingService::NelPolicy policy;
policy.origin = std::move(origin);
policy.expires = base::Time();
policy.last_used = base::Time();
return policy;
}
void RunClosureOnNelPoliciesLoaded(
base::OnceClosure closure,
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
// destruction.
MockPersistentNelStore::NelPoliciesLoadedCallback
MakeExpectedRunNelPoliciesLoadedCallback(
std::vector<NetworkErrorLoggingService::NelPolicy>* policies_out) {
base::OnceClosure closure = base::MakeExpectedRunClosure(FROM_HERE);
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;
store.LoadNelPolicies(
MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
expected_commands.emplace_back(
MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
store.FinishLoading(true /* load_success */);
EXPECT_EQ(0u, loaded_policies.size());
EXPECT_EQ(1u, store.GetAllCommands().size());
EXPECT_TRUE(store.VerifyCommands(expected_commands));
EXPECT_EQ("LOAD; ", store.GetDebugString());
// 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;
std::vector<NetworkErrorLoggingService::NelPolicy> prestored_policies = {
MakePolicyForOrigin(kOrigin)};
store.SetPrestoredPolicies(std::move(prestored_policies));
EXPECT_EQ(1, store.StoredPoliciesCount());
store.LoadNelPolicies(
MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
expected_commands.emplace_back(
MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
store.FinishLoading(true /* load_success */);
ASSERT_EQ(1u, loaded_policies.size());
EXPECT_EQ(kOrigin, loaded_policies[0].origin);
EXPECT_EQ(1u, store.GetAllCommands().size());
EXPECT_TRUE(store.VerifyCommands(expected_commands));
EXPECT_EQ("LOAD; ", store.GetDebugString());
}
// Failed load should yield empty vector of policies.
TEST(MockPersistentNelStoreTest, FailedLoad) {
MockPersistentNelStore store;
MockPersistentNelStore::CommandList expected_commands;
std::vector<NetworkErrorLoggingService::NelPolicy> loaded_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));
expected_commands.emplace_back(
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());
EXPECT_EQ(1u, store.GetAllCommands().size());
EXPECT_TRUE(store.VerifyCommands(expected_commands));
EXPECT_EQ("LOAD; ", store.GetDebugString());
}
TEST(MockPersistentNelStoreTest, Add) {
MockPersistentNelStore store;
MockPersistentNelStore::CommandList expected_commands;
std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
store.LoadNelPolicies(
MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
expected_commands.emplace_back(
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);
expected_commands.emplace_back(
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);
EXPECT_EQ(1, store.StoredPoliciesCount());
EXPECT_EQ(3u, store.GetAllCommands().size());
EXPECT_TRUE(store.VerifyCommands(expected_commands));
EXPECT_EQ("LOAD; ADD(" + kOrigin.Serialize() + "); FLUSH; ",
store.GetDebugString());
}
TEST(MockPersistentNelStoreTest, AddThenDelete) {
MockPersistentNelStore store;
MockPersistentNelStore::CommandList expected_commands;
std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
store.LoadNelPolicies(
MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
expected_commands.emplace_back(
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);
expected_commands.emplace_back(
MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy);
EXPECT_EQ(2u, store.GetAllCommands().size());
store.DeleteNelPolicy(policy);
expected_commands.emplace_back(
MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy);
EXPECT_EQ(3u, store.GetAllCommands().size());
store.Flush();
expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
EXPECT_EQ(0, store.StoredPoliciesCount());
EXPECT_EQ(4u, store.GetAllCommands().size());
EXPECT_TRUE(store.VerifyCommands(expected_commands));
EXPECT_EQ("LOAD; ADD(" + kOrigin.Serialize() +
"); "
"DELETE(" +
kOrigin.Serialize() + "); FLUSH; ",
store.GetDebugString());
}
TEST(MockPersistentNelStoreTest, AddFlushThenDelete) {
MockPersistentNelStore store;
MockPersistentNelStore::CommandList expected_commands;
std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
store.LoadNelPolicies(
MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
expected_commands.emplace_back(
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);
expected_commands.emplace_back(
MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy);
EXPECT_EQ(2u, store.GetAllCommands().size());
store.Flush();
expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
EXPECT_EQ(1, store.StoredPoliciesCount());
EXPECT_EQ(3u, store.GetAllCommands().size());
store.DeleteNelPolicy(policy);
expected_commands.emplace_back(
MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy);
EXPECT_EQ(4u, store.GetAllCommands().size());
store.Flush();
expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
EXPECT_EQ(0, store.StoredPoliciesCount());
EXPECT_EQ(5u, store.GetAllCommands().size());
EXPECT_TRUE(store.VerifyCommands(expected_commands));
EXPECT_EQ("LOAD; ADD(" + kOrigin.Serialize() +
"); FLUSH; "
"DELETE(" +
kOrigin.Serialize() + "); FLUSH; ",
store.GetDebugString());
}
TEST(MockPersistentNelStoreTest, AddThenUpdate) {
MockPersistentNelStore store;
MockPersistentNelStore::CommandList expected_commands;
std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
store.LoadNelPolicies(
MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
expected_commands.emplace_back(
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);
expected_commands.emplace_back(
MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy);
EXPECT_EQ(2u, store.GetAllCommands().size());
store.UpdateNelPolicyAccessTime(policy);
expected_commands.emplace_back(
MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy);
EXPECT_EQ(3u, store.GetAllCommands().size());
store.Flush();
expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
EXPECT_EQ(1, store.StoredPoliciesCount());
EXPECT_EQ(4u, store.GetAllCommands().size());
EXPECT_TRUE(store.VerifyCommands(expected_commands));
EXPECT_EQ("LOAD; ADD(" + kOrigin.Serialize() +
"); "
"UPDATE(" +
kOrigin.Serialize() + "); FLUSH; ",
store.GetDebugString());
}
} // namespace
} // namespace net