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 "net/reporting/mock_persistent_reporting_store.h"
6
7 #include <vector>
8
9 #include "base/location.h"
10 #include "base/test/bind.h"
11 #include "base/time/time.h"
12 #include "net/base/network_anonymization_key.h"
13 #include "net/reporting/reporting_endpoint.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
22 using CommandType = MockPersistentReportingStore::Command::Type;
23
24 struct ReportingData {
25 ReportingEndpoint endpoint;
26 CachedReportingEndpointGroup group;
27 };
28
GetReportingData()29 ReportingData GetReportingData() {
30 const url::Origin kOrigin =
31 url::Origin::Create(GURL("https://example.test/"));
32 const char kGroupName[] = "groupname";
33 const ReportingEndpointGroupKey kGroupKey(NetworkAnonymizationKey(), kOrigin,
34 kGroupName);
35 const ReportingEndpoint kEndpoint(kGroupKey,
36 {GURL("https://endpoint.test/reports")});
37 const CachedReportingEndpointGroup kGroup(
38 kGroupKey, OriginSubdomains::DEFAULT, base::Time::Now() + base::Days(1),
39 base::Time::Now());
40 return {kEndpoint, kGroup};
41 }
42
RunClosureOnClientsLoaded(base::OnceClosure closure,std::vector<ReportingEndpoint> * endpoints_out,std::vector<CachedReportingEndpointGroup> * groups_out,std::vector<ReportingEndpoint> loaded_endpoints,std::vector<CachedReportingEndpointGroup> loaded_groups)43 void RunClosureOnClientsLoaded(
44 base::OnceClosure closure,
45 std::vector<ReportingEndpoint>* endpoints_out,
46 std::vector<CachedReportingEndpointGroup>* groups_out,
47 std::vector<ReportingEndpoint> loaded_endpoints,
48 std::vector<CachedReportingEndpointGroup> loaded_groups) {
49 std::move(closure).Run();
50 loaded_endpoints.swap(*endpoints_out);
51 loaded_groups.swap(*groups_out);
52 }
53
54 // Makes a ReportingClientsLoadedCallback that will fail if it's never run
55 // before destruction.
56 MockPersistentReportingStore::ReportingClientsLoadedCallback
MakeExpectedRunReportingClientsLoadedCallback(std::vector<ReportingEndpoint> * endpoints_out,std::vector<CachedReportingEndpointGroup> * groups_out)57 MakeExpectedRunReportingClientsLoadedCallback(
58 std::vector<ReportingEndpoint>* endpoints_out,
59 std::vector<CachedReportingEndpointGroup>* groups_out) {
60 base::OnceClosure closure = base::MakeExpectedRunClosure(FROM_HERE);
61 return base::BindOnce(&RunClosureOnClientsLoaded, std::move(closure),
62 endpoints_out, groups_out);
63 }
64
65 // Test that FinishLoading() runs the callback.
TEST(MockPersistentReportingStoreTest,FinishLoading)66 TEST(MockPersistentReportingStoreTest, FinishLoading) {
67 MockPersistentReportingStore store;
68 MockPersistentReportingStore::CommandList expected_commands;
69 std::vector<ReportingEndpoint> loaded_endpoints;
70 std::vector<CachedReportingEndpointGroup> loaded_groups;
71
72 store.LoadReportingClients(MakeExpectedRunReportingClientsLoadedCallback(
73 &loaded_endpoints, &loaded_groups));
74 expected_commands.emplace_back(CommandType::LOAD_REPORTING_CLIENTS);
75
76 store.FinishLoading(true /* load_success */);
77 EXPECT_EQ(0u, loaded_endpoints.size());
78 EXPECT_EQ(0u, loaded_groups.size());
79
80 EXPECT_TRUE(store.VerifyCommands(expected_commands));
81 // Test should not crash because the callback has been run.
82 }
83
TEST(MockPersistentReportingStoreTest,PreStoredClients)84 TEST(MockPersistentReportingStoreTest, PreStoredClients) {
85 MockPersistentReportingStore store;
86 MockPersistentReportingStore::CommandList expected_commands;
87 std::vector<ReportingEndpoint> loaded_endpoints;
88 std::vector<CachedReportingEndpointGroup> loaded_groups;
89
90 const auto reporting_data = GetReportingData();
91 store.SetPrestoredClients({reporting_data.endpoint}, {reporting_data.group});
92 EXPECT_EQ(1, store.StoredEndpointsCount());
93 EXPECT_EQ(1, store.StoredEndpointGroupsCount());
94
95 store.LoadReportingClients(MakeExpectedRunReportingClientsLoadedCallback(
96 &loaded_endpoints, &loaded_groups));
97 expected_commands.emplace_back(CommandType::LOAD_REPORTING_CLIENTS);
98
99 store.FinishLoading(true /* load_success */);
100 EXPECT_EQ(1u, loaded_endpoints.size());
101 EXPECT_EQ(1u, loaded_groups.size());
102
103 EXPECT_TRUE(store.VerifyCommands(expected_commands));
104 }
105
106 // Failed load should yield empty vectors of endpoints and endpoint groups.
TEST(MockPersistentReportingStoreTest,FailedLoad)107 TEST(MockPersistentReportingStoreTest, FailedLoad) {
108 MockPersistentReportingStore store;
109 MockPersistentReportingStore::CommandList expected_commands;
110 std::vector<ReportingEndpoint> loaded_endpoints;
111 std::vector<CachedReportingEndpointGroup> loaded_groups;
112
113 const auto reporting_data = GetReportingData();
114 store.SetPrestoredClients({reporting_data.endpoint}, {reporting_data.group});
115 EXPECT_EQ(1, store.StoredEndpointsCount());
116 EXPECT_EQ(1, store.StoredEndpointGroupsCount());
117
118 store.LoadReportingClients(MakeExpectedRunReportingClientsLoadedCallback(
119 &loaded_endpoints, &loaded_groups));
120 expected_commands.emplace_back(CommandType::LOAD_REPORTING_CLIENTS);
121
122 store.FinishLoading(false /* load_success */);
123 EXPECT_EQ(0u, loaded_endpoints.size());
124 EXPECT_EQ(0u, loaded_groups.size());
125
126 EXPECT_TRUE(store.VerifyCommands(expected_commands));
127 }
128
TEST(MockPersistentReportingStoreTest,AddFlushDeleteFlush)129 TEST(MockPersistentReportingStoreTest, AddFlushDeleteFlush) {
130 MockPersistentReportingStore store;
131 MockPersistentReportingStore::CommandList expected_commands;
132 std::vector<ReportingEndpoint> loaded_endpoints;
133 std::vector<CachedReportingEndpointGroup> loaded_groups;
134
135 store.LoadReportingClients(MakeExpectedRunReportingClientsLoadedCallback(
136 &loaded_endpoints, &loaded_groups));
137 expected_commands.emplace_back(CommandType::LOAD_REPORTING_CLIENTS);
138 EXPECT_EQ(1u, store.GetAllCommands().size());
139
140 store.FinishLoading(true /* load_success */);
141 EXPECT_EQ(0u, loaded_endpoints.size());
142 EXPECT_EQ(0u, loaded_groups.size());
143 EXPECT_EQ(0, store.StoredEndpointsCount());
144 EXPECT_EQ(0, store.StoredEndpointGroupsCount());
145
146 const auto reporting_data = GetReportingData();
147 store.AddReportingEndpoint(reporting_data.endpoint);
148 expected_commands.emplace_back(CommandType::ADD_REPORTING_ENDPOINT,
149 reporting_data.endpoint);
150 EXPECT_EQ(2u, store.GetAllCommands().size());
151
152 store.AddReportingEndpointGroup(reporting_data.group);
153 expected_commands.emplace_back(CommandType::ADD_REPORTING_ENDPOINT_GROUP,
154 reporting_data.group);
155 EXPECT_EQ(3u, store.GetAllCommands().size());
156
157 store.Flush();
158 expected_commands.emplace_back(CommandType::FLUSH);
159 EXPECT_EQ(4u, store.GetAllCommands().size());
160 EXPECT_EQ(1, store.StoredEndpointsCount());
161 EXPECT_EQ(1, store.StoredEndpointGroupsCount());
162
163 store.DeleteReportingEndpoint(reporting_data.endpoint);
164 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
165 reporting_data.endpoint);
166 EXPECT_EQ(5u, store.GetAllCommands().size());
167
168 store.DeleteReportingEndpointGroup(reporting_data.group);
169 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT_GROUP,
170 reporting_data.group);
171 EXPECT_EQ(6u, store.GetAllCommands().size());
172
173 store.Flush();
174 expected_commands.emplace_back(CommandType::FLUSH);
175 EXPECT_EQ(7u, store.GetAllCommands().size());
176 EXPECT_EQ(0, store.StoredEndpointsCount());
177 EXPECT_EQ(0, store.StoredEndpointGroupsCount());
178
179 EXPECT_TRUE(store.VerifyCommands(expected_commands));
180
181 EXPECT_EQ(1, store.CountCommands(CommandType::LOAD_REPORTING_CLIENTS));
182 EXPECT_EQ(
183 0, store.CountCommands(CommandType::UPDATE_REPORTING_ENDPOINT_DETAILS));
184 }
185
TEST(MockPersistentReportingStoreTest,CountCommands)186 TEST(MockPersistentReportingStoreTest, CountCommands) {
187 MockPersistentReportingStore store;
188
189 std::vector<ReportingEndpoint> loaded_endpoints;
190 std::vector<CachedReportingEndpointGroup> loaded_groups;
191 store.LoadReportingClients(MakeExpectedRunReportingClientsLoadedCallback(
192 &loaded_endpoints, &loaded_groups));
193 store.FinishLoading(true /* load_success */);
194
195 const auto reporting_data = GetReportingData();
196 store.AddReportingEndpoint(reporting_data.endpoint);
197 store.AddReportingEndpointGroup(reporting_data.group);
198 store.Flush();
199
200 store.DeleteReportingEndpoint(reporting_data.endpoint);
201 store.DeleteReportingEndpointGroup(reporting_data.group);
202 store.Flush();
203
204 EXPECT_EQ(1, store.CountCommands(CommandType::LOAD_REPORTING_CLIENTS));
205 EXPECT_EQ(1, store.CountCommands(CommandType::ADD_REPORTING_ENDPOINT));
206 EXPECT_EQ(1, store.CountCommands(CommandType::ADD_REPORTING_ENDPOINT_GROUP));
207 EXPECT_EQ(0, store.CountCommands(
208 CommandType::UPDATE_REPORTING_ENDPOINT_GROUP_ACCESS_TIME));
209 EXPECT_EQ(
210 0, store.CountCommands(CommandType::UPDATE_REPORTING_ENDPOINT_DETAILS));
211 EXPECT_EQ(0, store.CountCommands(
212 CommandType::UPDATE_REPORTING_ENDPOINT_GROUP_DETAILS));
213 EXPECT_EQ(1, store.CountCommands(CommandType::DELETE_REPORTING_ENDPOINT));
214 EXPECT_EQ(1,
215 store.CountCommands(CommandType::DELETE_REPORTING_ENDPOINT_GROUP));
216 EXPECT_EQ(2, store.CountCommands(CommandType::FLUSH));
217 }
218
219 } // namespace
220
221 } // namespace net
222