1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <string>
6
7 #include "base/location.h"
8 #include "base/strings/strcat.h"
9 #include "base/test/bind.h"
10 #include "net/base/network_anonymization_key.h"
11 #include "net/base/schemeful_site.h"
12 #include "net/network_error_logging/mock_persistent_nel_store.h"
13 #include "net/network_error_logging/network_error_logging_service.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "url/gurl.h"
16 #include "url/origin.h"
17
18 namespace net {
19
20 namespace {
21
MakePolicy(const url::Origin & origin,const net::NetworkAnonymizationKey & network_anonymization_key)22 NetworkErrorLoggingService::NelPolicy MakePolicy(
23 const url::Origin& origin,
24 const net::NetworkAnonymizationKey& network_anonymization_key) {
25 NetworkErrorLoggingService::NelPolicy policy;
26 policy.key = NetworkErrorLoggingService::NelPolicyKey(
27 network_anonymization_key, origin);
28 policy.expires = base::Time();
29 policy.last_used = base::Time();
30
31 return policy;
32 }
33
RunClosureOnNelPoliciesLoaded(base::OnceClosure closure,std::vector<NetworkErrorLoggingService::NelPolicy> * policies_out,std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies)34 void RunClosureOnNelPoliciesLoaded(
35 base::OnceClosure closure,
36 std::vector<NetworkErrorLoggingService::NelPolicy>* policies_out,
37 std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies) {
38 std::move(closure).Run();
39 loaded_policies.swap(*policies_out);
40 }
41
42 // Makes a NelPoliciesLoadedCallback that will fail if it's never run before
43 // destruction.
44 MockPersistentNelStore::NelPoliciesLoadedCallback
MakeExpectedRunNelPoliciesLoadedCallback(std::vector<NetworkErrorLoggingService::NelPolicy> * policies_out)45 MakeExpectedRunNelPoliciesLoadedCallback(
46 std::vector<NetworkErrorLoggingService::NelPolicy>* policies_out) {
47 base::OnceClosure closure = base::MakeExpectedRunClosure(FROM_HERE);
48 return base::BindOnce(&RunClosureOnNelPoliciesLoaded, std::move(closure),
49 policies_out);
50 }
51
52 class MockPersistentNelStoreTest : public testing::Test {
53 public:
54 MockPersistentNelStoreTest() = default;
55 ~MockPersistentNelStoreTest() override = default;
56
57 protected:
58 const url::Origin origin_ =
59 url::Origin::Create(GURL("https://example.test/"));
60 const NetworkAnonymizationKey network_anonymization_key_ =
61 NetworkAnonymizationKey::CreateCrossSite(
62 SchemefulSite(GURL("https://foo.test/")));
63 const NetworkErrorLoggingService::NelPolicy nel_policy_ =
64 MakePolicy(origin_, network_anonymization_key_);
65 };
66
67 // Test that FinishLoading() runs the callback.
TEST_F(MockPersistentNelStoreTest,FinishLoading)68 TEST_F(MockPersistentNelStoreTest, FinishLoading) {
69 MockPersistentNelStore store;
70 MockPersistentNelStore::CommandList expected_commands;
71 std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
72
73 store.LoadNelPolicies(
74 MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
75 expected_commands.emplace_back(
76 MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
77
78 store.FinishLoading(true /* load_success */);
79 EXPECT_EQ(0u, loaded_policies.size());
80
81 EXPECT_EQ(1u, store.GetAllCommands().size());
82 EXPECT_TRUE(store.VerifyCommands(expected_commands));
83
84 // Test should not crash because the callback has been run.
85 }
86
TEST_F(MockPersistentNelStoreTest,PreStoredPolicies)87 TEST_F(MockPersistentNelStoreTest, PreStoredPolicies) {
88 const url::Origin origin_ =
89 url::Origin::Create(GURL("https://example.test/"));
90
91 MockPersistentNelStore store;
92 MockPersistentNelStore::CommandList expected_commands;
93 std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
94
95 std::vector<NetworkErrorLoggingService::NelPolicy> prestored_policies = {
96 nel_policy_};
97 store.SetPrestoredPolicies(std::move(prestored_policies));
98 EXPECT_EQ(1, store.StoredPoliciesCount());
99
100 store.LoadNelPolicies(
101 MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
102 expected_commands.emplace_back(
103 MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
104 store.FinishLoading(true /* load_success */);
105 ASSERT_EQ(1u, loaded_policies.size());
106 EXPECT_EQ(origin_, loaded_policies[0].key.origin);
107 EXPECT_EQ(network_anonymization_key_,
108 loaded_policies[0].key.network_anonymization_key);
109
110 EXPECT_EQ(1u, store.GetAllCommands().size());
111 EXPECT_TRUE(store.VerifyCommands(expected_commands));
112 }
113
114 // Failed load should yield empty vector of policies.
TEST_F(MockPersistentNelStoreTest,FailedLoad)115 TEST_F(MockPersistentNelStoreTest, FailedLoad) {
116 MockPersistentNelStore store;
117 MockPersistentNelStore::CommandList expected_commands;
118 std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
119
120 std::vector<NetworkErrorLoggingService::NelPolicy> prestored_policies = {
121 nel_policy_};
122 store.SetPrestoredPolicies(std::move(prestored_policies));
123 EXPECT_EQ(1, store.StoredPoliciesCount());
124
125 store.LoadNelPolicies(
126 MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
127 expected_commands.emplace_back(
128 MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
129 store.FinishLoading(false /* load_success */);
130 // The pre-stored policy is not returned because loading failed.
131 EXPECT_EQ(0u, loaded_policies.size());
132
133 EXPECT_EQ(1u, store.GetAllCommands().size());
134 EXPECT_TRUE(store.VerifyCommands(expected_commands));
135 }
136
TEST_F(MockPersistentNelStoreTest,Add)137 TEST_F(MockPersistentNelStoreTest, Add) {
138 MockPersistentNelStore store;
139 MockPersistentNelStore::CommandList expected_commands;
140 std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
141
142 store.LoadNelPolicies(
143 MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
144 expected_commands.emplace_back(
145 MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
146 EXPECT_EQ(1u, store.GetAllCommands().size());
147
148 store.FinishLoading(true /* load_success */);
149 EXPECT_EQ(0u, loaded_policies.size());
150
151 NetworkErrorLoggingService::NelPolicy policy = nel_policy_;
152 store.AddNelPolicy(policy);
153 expected_commands.emplace_back(
154 MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy);
155 // Add operation will be queued; the policy has not actually been stored yet
156 EXPECT_EQ(0, store.StoredPoliciesCount());
157 EXPECT_EQ(2u, store.GetAllCommands().size());
158
159 store.Flush();
160 expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
161 EXPECT_EQ(1, store.StoredPoliciesCount());
162
163 EXPECT_EQ(3u, store.GetAllCommands().size());
164 EXPECT_TRUE(store.VerifyCommands(expected_commands));
165 }
166
TEST_F(MockPersistentNelStoreTest,AddThenDelete)167 TEST_F(MockPersistentNelStoreTest, AddThenDelete) {
168 MockPersistentNelStore store;
169 MockPersistentNelStore::CommandList expected_commands;
170 std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
171
172 store.LoadNelPolicies(
173 MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
174 expected_commands.emplace_back(
175 MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
176 EXPECT_EQ(1u, store.GetAllCommands().size());
177
178 store.FinishLoading(true /* load_success */);
179 EXPECT_EQ(0u, loaded_policies.size());
180
181 NetworkErrorLoggingService::NelPolicy policy = nel_policy_;
182 store.AddNelPolicy(policy);
183 expected_commands.emplace_back(
184 MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy);
185 EXPECT_EQ(2u, store.GetAllCommands().size());
186
187 store.DeleteNelPolicy(policy);
188 expected_commands.emplace_back(
189 MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy);
190 EXPECT_EQ(3u, store.GetAllCommands().size());
191
192 store.Flush();
193 expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
194 EXPECT_EQ(0, store.StoredPoliciesCount());
195 EXPECT_EQ(4u, store.GetAllCommands().size());
196
197 EXPECT_TRUE(store.VerifyCommands(expected_commands));
198 }
199
TEST_F(MockPersistentNelStoreTest,AddFlushThenDelete)200 TEST_F(MockPersistentNelStoreTest, AddFlushThenDelete) {
201 MockPersistentNelStore store;
202 MockPersistentNelStore::CommandList expected_commands;
203 std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
204
205 store.LoadNelPolicies(
206 MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
207 expected_commands.emplace_back(
208 MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
209 EXPECT_EQ(1u, store.GetAllCommands().size());
210
211 store.FinishLoading(true /* load_success */);
212 EXPECT_EQ(0u, loaded_policies.size());
213
214 NetworkErrorLoggingService::NelPolicy policy = nel_policy_;
215 store.AddNelPolicy(policy);
216 expected_commands.emplace_back(
217 MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy);
218 EXPECT_EQ(2u, store.GetAllCommands().size());
219
220 store.Flush();
221 expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
222 EXPECT_EQ(1, store.StoredPoliciesCount());
223 EXPECT_EQ(3u, store.GetAllCommands().size());
224
225 store.DeleteNelPolicy(policy);
226 expected_commands.emplace_back(
227 MockPersistentNelStore::Command::Type::DELETE_NEL_POLICY, policy);
228 EXPECT_EQ(4u, store.GetAllCommands().size());
229
230 store.Flush();
231 expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
232 EXPECT_EQ(0, store.StoredPoliciesCount());
233 EXPECT_EQ(5u, store.GetAllCommands().size());
234
235 EXPECT_TRUE(store.VerifyCommands(expected_commands));
236 }
237
TEST_F(MockPersistentNelStoreTest,AddThenUpdate)238 TEST_F(MockPersistentNelStoreTest, AddThenUpdate) {
239 MockPersistentNelStore store;
240 MockPersistentNelStore::CommandList expected_commands;
241 std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
242
243 store.LoadNelPolicies(
244 MakeExpectedRunNelPoliciesLoadedCallback(&loaded_policies));
245 expected_commands.emplace_back(
246 MockPersistentNelStore::Command::Type::LOAD_NEL_POLICIES);
247 EXPECT_EQ(1u, store.GetAllCommands().size());
248
249 store.FinishLoading(true /* load_success */);
250
251 NetworkErrorLoggingService::NelPolicy policy = nel_policy_;
252 store.AddNelPolicy(policy);
253 expected_commands.emplace_back(
254 MockPersistentNelStore::Command::Type::ADD_NEL_POLICY, policy);
255 EXPECT_EQ(2u, store.GetAllCommands().size());
256
257 store.UpdateNelPolicyAccessTime(policy);
258 expected_commands.emplace_back(
259 MockPersistentNelStore::Command::Type::UPDATE_NEL_POLICY, policy);
260 EXPECT_EQ(3u, store.GetAllCommands().size());
261
262 store.Flush();
263 expected_commands.emplace_back(MockPersistentNelStore::Command::Type::FLUSH);
264 EXPECT_EQ(1, store.StoredPoliciesCount());
265 EXPECT_EQ(4u, store.GetAllCommands().size());
266
267 EXPECT_TRUE(store.VerifyCommands(expected_commands));
268 }
269
270 } // namespace
271
272 } // namespace net
273