OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | |
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 "components/previews/core/previews_opt_out_store_sql.h" | |
6 | |
7 #include <map> | |
8 #include <memory> | |
9 #include <string> | |
10 | |
11 #include "base/bind.h" | |
12 #include "base/command_line.h" | |
13 #include "base/files/file_path.h" | |
14 #include "base/files/file_util.h" | |
15 #include "base/files/scoped_temp_dir.h" | |
16 #include "base/memory/ptr_util.h" | |
17 #include "base/message_loop/message_loop.h" | |
18 #include "base/run_loop.h" | |
19 #include "base/strings/string_number_conversions.h" | |
20 #include "base/test/histogram_tester.h" | |
21 #include "base/test/simple_test_clock.h" | |
22 #include "base/threading/thread_task_runner_handle.h" | |
23 #include "base/time/time.h" | |
24 #include "components/previews/core/previews_black_list_item.h" | |
25 #include "components/previews/core/previews_opt_out_store.h" | |
26 #include "sql/test/test_helpers.h" | |
27 #include "testing/gtest/include/gtest/gtest.h" | |
28 | |
29 namespace previews { | |
30 | |
31 namespace { | |
32 | |
33 const base::FilePath::CharType kOptOutFilename[] = FILE_PATH_LITERAL("OptOut"); | |
34 | |
35 } // namespace | |
36 | |
37 class PreviewsOptOutStoreSQLTest : public testing::Test { | |
38 public: | |
39 PreviewsOptOutStoreSQLTest() {} | |
40 ~PreviewsOptOutStoreSQLTest() override {} | |
41 | |
42 // Called when |store_| is done loading. | |
43 void OnLoaded(std::unique_ptr<BlackListItemMap> black_list_map) { | |
44 black_list_map_ = std::move(black_list_map); | |
45 } | |
46 | |
47 // Initializes the store and get the data from it. | |
48 void Load() { | |
49 store_->LoadBlackList(base::Bind(&PreviewsOptOutStoreSQLTest::OnLoaded, | |
50 base::Unretained(this))); | |
51 base::RunLoop().RunUntilIdle(); | |
52 } | |
53 | |
54 // Destroys the database connection and |store_|. | |
55 void DestroyStore() { | |
56 store_.reset(); | |
57 base::RunLoop().RunUntilIdle(); | |
58 } | |
59 | |
60 // Creates a store that operates on one thread. | |
61 void Create() { | |
62 store_ = base::MakeUnique<PreviewsOptOutStoreSQL>( | |
63 base::ThreadTaskRunnerHandle::Get(), | |
64 base::ThreadTaskRunnerHandle::Get(), | |
65 temp_dir_.GetPath().Append(kOptOutFilename)); | |
66 } | |
67 | |
68 // Sets up initialization of |store_|. | |
69 void CreateAndLoad() { | |
70 Create(); | |
71 Load(); | |
72 } | |
73 | |
74 // Creates a directory for the test. | |
75 void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); } | |
76 | |
77 // Delete |store_| if it hasn't been deleted. | |
78 void TearDown() override { DestroyStore(); } | |
79 | |
80 protected: | |
81 base::HistogramTester histogram_tester_; | |
82 | |
83 base::MessageLoop message_loop_; | |
84 | |
85 // The backing SQL store. | |
86 std::unique_ptr<PreviewsOptOutStoreSQL> store_; | |
87 | |
88 // The map returned from |store_|. | |
89 std::unique_ptr<BlackListItemMap> black_list_map_; | |
90 | |
91 // The directory for the database. | |
92 base::ScopedTempDir temp_dir_; | |
93 }; | |
94 | |
95 TEST_F(PreviewsOptOutStoreSQLTest, TestErrorRecovery) { | |
96 // Creates the database and corrupt to test the recovery method. | |
97 std::string test_host = "host.com"; | |
98 CreateAndLoad(); | |
99 store_->AddPreviewNavigation(true, test_host, PreviewsType::OFFLINE, | |
100 base::Time::Now()); | |
101 base::RunLoop().RunUntilIdle(); | |
102 DestroyStore(); | |
103 | |
104 // Corrupts the database by adjusting the header size. | |
105 EXPECT_TRUE(sql::test::CorruptSizeInHeader( | |
106 temp_dir_.GetPath().Append(kOptOutFilename))); | |
107 base::RunLoop().RunUntilIdle(); | |
108 | |
109 CreateAndLoad(); | |
110 // The data should be recovered. | |
111 EXPECT_EQ(1U, black_list_map_->size()); | |
112 auto iter = black_list_map_->find(test_host); | |
113 | |
114 EXPECT_NE(black_list_map_->end(), iter); | |
115 EXPECT_EQ(1U, iter->second->OptOutRecordsSizeForTesting()); | |
116 } | |
117 | |
118 TEST_F(PreviewsOptOutStoreSQLTest, TestPersistance) { | |
119 // Tests if data is stored as expected in the SQLite database. | |
120 std::string test_host = "host.com"; | |
121 CreateAndLoad(); | |
122 histogram_tester_.ExpectUniqueSample("Previews.OptOut.DBRowCount", 0, 1); | |
123 base::Time now = base::Time::Now(); | |
124 store_->AddPreviewNavigation(true, test_host, PreviewsType::OFFLINE, now); | |
125 base::RunLoop().RunUntilIdle(); | |
126 | |
127 // Replace the store effectively destroying the current one and forcing it | |
128 // to write its data to disk. | |
129 DestroyStore(); | |
130 | |
131 // Reload and test for persistence | |
132 CreateAndLoad(); | |
133 EXPECT_EQ(1U, black_list_map_->size()); | |
134 auto iter = black_list_map_->find(test_host); | |
135 | |
136 EXPECT_NE(black_list_map_->end(), iter); | |
137 EXPECT_EQ(1U, iter->second->OptOutRecordsSizeForTesting()); | |
138 EXPECT_EQ(now, iter->second->most_recent_opt_out_time().value()); | |
tbansal1
2016/11/07 17:10:26
why not check other fields too e.g., hostname?
RyanSturm
2016/11/07 18:24:29
hostname isn't stored in the item and this item is
tbansal1
2016/11/07 18:27:15
Acknowledged.
| |
139 histogram_tester_.ExpectBucketCount("Previews.OptOut.DBRowCount", 1, 1); | |
140 histogram_tester_.ExpectTotalCount("Previews.OptOut.DBRowCount", 2); | |
141 } | |
142 | |
143 TEST_F(PreviewsOptOutStoreSQLTest, TestMaxRows) { | |
144 // Tests that the number of rows are culled down to the row limit at each | |
145 // load. | |
146 std::string test_host_a = "host_a.com"; | |
147 std::string test_host_b = "host_b.com"; | |
148 std::string test_host_c = "host_c.com"; | |
149 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | |
150 size_t row_limit = 2; | |
151 std::string row_limit_string = base::SizeTToString(row_limit); | |
152 command_line->AppendSwitchASCII("previews-max-opt-out-rows", | |
153 row_limit_string); | |
154 CreateAndLoad(); | |
155 histogram_tester_.ExpectUniqueSample("Previews.OptOut.DBRowCount", 0, 1); | |
156 base::SimpleTestClock clock; | |
157 | |
158 // Create three different entries with different hosts. | |
159 store_->AddPreviewNavigation(true, test_host_a, PreviewsType::OFFLINE, | |
160 clock.Now()); | |
161 clock.Advance(base::TimeDelta::FromSeconds(1)); | |
162 | |
163 store_->AddPreviewNavigation(true, test_host_b, PreviewsType::OFFLINE, | |
164 clock.Now()); | |
165 base::Time host_b_time = clock.Now(); | |
166 clock.Advance(base::TimeDelta::FromSeconds(1)); | |
167 | |
168 store_->AddPreviewNavigation(false, test_host_c, PreviewsType::OFFLINE, | |
169 clock.Now()); | |
170 base::RunLoop().RunUntilIdle(); | |
171 // Replace the store effectively destroying the current one and forcing it | |
172 // to write its data to disk. | |
173 DestroyStore(); | |
174 | |
175 // Reload and test for persistence | |
176 CreateAndLoad(); | |
177 histogram_tester_.ExpectBucketCount("Previews.OptOut.DBRowCount", | |
178 static_cast<int>(row_limit) + 1, 1); | |
179 // The delete happens after the load, so it is possible to load more than | |
180 // |row_limit| into the in memory map. | |
181 EXPECT_EQ(row_limit + 1, black_list_map_->size()); | |
182 | |
183 DestroyStore(); | |
184 CreateAndLoad(); | |
185 histogram_tester_.ExpectBucketCount("Previews.OptOut.DBRowCount", | |
186 static_cast<int>(row_limit), 1); | |
187 | |
188 EXPECT_EQ(row_limit, black_list_map_->size()); | |
189 auto iter_host_b = black_list_map_->find(test_host_b); | |
190 auto iter_host_c = black_list_map_->find(test_host_c); | |
191 | |
192 EXPECT_EQ(black_list_map_->end(), black_list_map_->find(test_host_a)); | |
193 EXPECT_NE(black_list_map_->end(), iter_host_b); | |
194 EXPECT_NE(black_list_map_->end(), iter_host_c); | |
195 EXPECT_EQ(host_b_time, | |
196 iter_host_b->second->most_recent_opt_out_time().value()); | |
197 EXPECT_EQ(1U, iter_host_b->second->OptOutRecordsSizeForTesting()); | |
198 histogram_tester_.ExpectTotalCount("Previews.OptOut.DBRowCount", 3); | |
199 } | |
200 | |
201 TEST_F(PreviewsOptOutStoreSQLTest, TestMaxRowsPerHost) { | |
202 // Tests that each host is limited to |row_limit| rows. | |
203 std::string test_host = "host.com"; | |
204 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | |
205 size_t row_limit = 2; | |
206 std::string row_limit_string = base::SizeTToString(row_limit); | |
207 command_line->AppendSwitchASCII("previews-max-opt-out-rows-per-host", | |
208 row_limit_string); | |
209 CreateAndLoad(); | |
210 histogram_tester_.ExpectUniqueSample("Previews.OptOut.DBRowCount", 0, 1); | |
tbansal1
2016/11/07 17:10:27
Put this in a for loop of size |row_limit|?
RyanSturm
2016/11/07 18:24:29
Done.
| |
211 base::SimpleTestClock clock; | |
212 | |
213 store_->AddPreviewNavigation(true, test_host, PreviewsType::OFFLINE, | |
214 clock.Now()); | |
215 clock.Advance(base::TimeDelta::FromSeconds(1)); | |
216 | |
217 base::Time last_opt_out_time = clock.Now(); | |
218 store_->AddPreviewNavigation(true, test_host, PreviewsType::OFFLINE, | |
219 last_opt_out_time); | |
220 clock.Advance(base::TimeDelta::FromSeconds(1)); | |
221 | |
222 store_->AddPreviewNavigation(false, test_host, PreviewsType::OFFLINE, | |
223 clock.Now()); | |
224 | |
225 base::RunLoop().RunUntilIdle(); | |
226 // Replace the store effectively destroying the current one and forcing it | |
227 // to write its data to disk. | |
228 DestroyStore(); | |
tbansal1
2016/11/07 17:10:26
Add:
EXPECT_EQ(row_limit, iter->second->OptOutReco
RyanSturm
2016/11/07 18:24:29
There's no way to get the iter without calling Cre
| |
229 | |
230 // Reload and test for persistence | |
tbansal1
2016/11/07 17:10:26
missing period at end.
RyanSturm
2016/11/07 18:24:29
Done.
| |
231 CreateAndLoad(); | |
232 histogram_tester_.ExpectBucketCount("Previews.OptOut.DBRowCount", | |
233 static_cast<int>(row_limit), 1); | |
234 | |
235 EXPECT_EQ(1U, black_list_map_->size()); | |
236 auto iter = black_list_map_->find(test_host); | |
237 | |
238 EXPECT_NE(black_list_map_->end(), iter); | |
239 EXPECT_EQ(last_opt_out_time, | |
240 iter->second->most_recent_opt_out_time().value()); | |
241 EXPECT_EQ(row_limit, iter->second->OptOutRecordsSizeForTesting()); | |
tbansal1
2016/11/07 17:10:26
Is it possible to check that the older entries wer
RyanSturm
2016/11/07 18:24:29
The combination of line 239/240 and 245 should gua
tbansal1
2016/11/07 18:27:15
Acknowledged.
| |
242 clock.Advance(base::TimeDelta::FromSeconds(1)); | |
243 // If both entries' opt out states are stored correctly, then this should not | |
244 // be black listed. | |
245 EXPECT_FALSE(iter->second->IsBlackListed(clock.Now())); | |
246 histogram_tester_.ExpectTotalCount("Previews.OptOut.DBRowCount", 2); | |
247 } | |
248 | |
249 } // namespace net | |
OLD | NEW |