OLD | NEW |
| (Empty) |
1 // Copyright 2014 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 <set> | |
6 #include <utility> | |
7 #include <vector> | |
8 | |
9 #include "base/message_loop/message_loop.h" | |
10 #include "base/strings/utf_string_conversions.h" | |
11 #include "chrome/browser/predictors/predictor_database.h" | |
12 #include "chrome/browser/predictors/resource_prefetch_predictor_tables.h" | |
13 #include "chrome/test/base/testing_profile.h" | |
14 #include "content/public/test/test_browser_thread.h" | |
15 #include "sql/statement.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 namespace predictors { | |
19 | |
20 class ResourcePrefetchPredictorTablesTest : public testing::Test { | |
21 public: | |
22 ResourcePrefetchPredictorTablesTest(); | |
23 virtual ~ResourcePrefetchPredictorTablesTest(); | |
24 virtual void SetUp() OVERRIDE; | |
25 virtual void TearDown() OVERRIDE; | |
26 | |
27 protected: | |
28 void TestGetAllData(); | |
29 void TestUpdateData(); | |
30 void TestDeleteData(); | |
31 void TestDeleteSingleDataPoint(); | |
32 void TestDeleteAllData(); | |
33 | |
34 base::MessageLoop loop_; | |
35 content::TestBrowserThread db_thread_; | |
36 TestingProfile profile_; | |
37 scoped_ptr<PredictorDatabase> db_; | |
38 scoped_refptr<ResourcePrefetchPredictorTables> tables_; | |
39 | |
40 private: | |
41 typedef ResourcePrefetchPredictorTables::ResourceRow ResourceRow; | |
42 typedef std::vector<ResourceRow> ResourceRows; | |
43 typedef ResourcePrefetchPredictorTables::PrefetchData PrefetchData; | |
44 typedef ResourcePrefetchPredictorTables::PrefetchDataMap PrefetchDataMap; | |
45 | |
46 // Initializes the tables, |test_url_data_| and |test_host_data_|. | |
47 void InitializeSampleData(); | |
48 | |
49 // Checks that the input PrefetchData are the same, although the resources | |
50 // can be in different order. | |
51 void TestPrefetchDataAreEqual(const PrefetchDataMap& lhs, | |
52 const PrefetchDataMap& rhs) const; | |
53 void TestResourceRowsAreEqual(const ResourceRows& lhs, | |
54 const ResourceRows& rhs) const; | |
55 | |
56 void AddKey(PrefetchDataMap* m, const std::string& key) const; | |
57 | |
58 // Useful for debugging test. | |
59 void PrintPrefetchData(const PrefetchData& data) const { | |
60 LOG(ERROR) << "[" << data.key_type << "," << data.primary_key | |
61 << "," << data.last_visit.ToInternalValue() << "]"; | |
62 for (ResourceRows::const_iterator it = data.resources.begin(); | |
63 it != data.resources.end(); ++it) { | |
64 LOG(ERROR) << "\t\t" << it->resource_url << "\t" << it->resource_type | |
65 << "\t" << it->number_of_hits << "\t" << it->number_of_misses | |
66 << "\t" << it->consecutive_misses | |
67 << "\t" << it->average_position | |
68 << "\t" << it->score; | |
69 } | |
70 } | |
71 | |
72 PrefetchDataMap test_url_data_; | |
73 PrefetchDataMap test_host_data_; | |
74 }; | |
75 | |
76 class ResourcePrefetchPredictorTablesReopenTest | |
77 : public ResourcePrefetchPredictorTablesTest { | |
78 public: | |
79 virtual void SetUp() OVERRIDE { | |
80 // Write data to the table, and then reopen the db. | |
81 ResourcePrefetchPredictorTablesTest::SetUp(); | |
82 ResourcePrefetchPredictorTablesTest::TearDown(); | |
83 | |
84 db_.reset(new PredictorDatabase(&profile_)); | |
85 loop_.RunUntilIdle(); | |
86 tables_ = db_->resource_prefetch_tables(); | |
87 } | |
88 }; | |
89 | |
90 ResourcePrefetchPredictorTablesTest::ResourcePrefetchPredictorTablesTest() | |
91 : loop_(base::MessageLoop::TYPE_DEFAULT), | |
92 db_thread_(content::BrowserThread::DB, &loop_), | |
93 db_(new PredictorDatabase(&profile_)), | |
94 tables_(db_->resource_prefetch_tables()) { | |
95 loop_.RunUntilIdle(); | |
96 } | |
97 | |
98 ResourcePrefetchPredictorTablesTest::~ResourcePrefetchPredictorTablesTest() { | |
99 } | |
100 | |
101 void ResourcePrefetchPredictorTablesTest::SetUp() { | |
102 tables_->DeleteAllData(); | |
103 InitializeSampleData(); | |
104 } | |
105 | |
106 void ResourcePrefetchPredictorTablesTest::TearDown() { | |
107 tables_ = NULL; | |
108 db_.reset(); | |
109 loop_.RunUntilIdle(); | |
110 } | |
111 | |
112 void ResourcePrefetchPredictorTablesTest::TestGetAllData() { | |
113 PrefetchDataMap actual_url_data, actual_host_data; | |
114 tables_->GetAllData(&actual_url_data, &actual_host_data); | |
115 | |
116 TestPrefetchDataAreEqual(test_url_data_, actual_url_data); | |
117 TestPrefetchDataAreEqual(test_host_data_, actual_host_data); | |
118 } | |
119 | |
120 void ResourcePrefetchPredictorTablesTest::TestDeleteData() { | |
121 std::vector<std::string> urls_to_delete, hosts_to_delete; | |
122 urls_to_delete.push_back("http://www.google.com"); | |
123 urls_to_delete.push_back("http://www.yahoo.com"); | |
124 hosts_to_delete.push_back("www.yahoo.com"); | |
125 | |
126 tables_->DeleteData(urls_to_delete, hosts_to_delete); | |
127 | |
128 PrefetchDataMap actual_url_data, actual_host_data; | |
129 tables_->GetAllData(&actual_url_data, &actual_host_data); | |
130 | |
131 PrefetchDataMap expected_url_data, expected_host_data; | |
132 AddKey(&expected_url_data, "http://www.reddit.com"); | |
133 AddKey(&expected_host_data, "www.facebook.com"); | |
134 | |
135 TestPrefetchDataAreEqual(expected_url_data, actual_url_data); | |
136 TestPrefetchDataAreEqual(expected_host_data, actual_host_data); | |
137 } | |
138 | |
139 void ResourcePrefetchPredictorTablesTest::TestDeleteSingleDataPoint() { | |
140 // Delete a URL. | |
141 tables_->DeleteSingleDataPoint("http://www.reddit.com", | |
142 PREFETCH_KEY_TYPE_URL); | |
143 | |
144 PrefetchDataMap actual_url_data, actual_host_data; | |
145 tables_->GetAllData(&actual_url_data, &actual_host_data); | |
146 | |
147 PrefetchDataMap expected_url_data; | |
148 AddKey(&expected_url_data, "http://www.google.com"); | |
149 AddKey(&expected_url_data, "http://www.yahoo.com"); | |
150 | |
151 TestPrefetchDataAreEqual(expected_url_data, actual_url_data); | |
152 TestPrefetchDataAreEqual(test_host_data_, actual_host_data); | |
153 | |
154 // Delete a host. | |
155 tables_->DeleteSingleDataPoint("www.facebook.com", PREFETCH_KEY_TYPE_HOST); | |
156 actual_url_data.clear(); | |
157 actual_host_data.clear(); | |
158 tables_->GetAllData(&actual_url_data, &actual_host_data); | |
159 | |
160 PrefetchDataMap expected_host_data; | |
161 AddKey(&expected_host_data, "www.yahoo.com"); | |
162 | |
163 TestPrefetchDataAreEqual(expected_url_data, actual_url_data); | |
164 TestPrefetchDataAreEqual(expected_host_data, actual_host_data); | |
165 } | |
166 | |
167 void ResourcePrefetchPredictorTablesTest::TestUpdateData() { | |
168 PrefetchData google(PREFETCH_KEY_TYPE_URL, "http://www.google.com"); | |
169 google.last_visit = base::Time::FromInternalValue(10); | |
170 google.resources.push_back(ResourceRow(std::string(), | |
171 "http://www.google.com/style.css", | |
172 content::RESOURCE_TYPE_STYLESHEET, | |
173 6, | |
174 2, | |
175 0, | |
176 1.0)); | |
177 google.resources.push_back(ResourceRow(std::string(), | |
178 "http://www.google.com/image.png", | |
179 content::RESOURCE_TYPE_IMAGE, | |
180 6, | |
181 4, | |
182 1, | |
183 4.2)); | |
184 google.resources.push_back(ResourceRow(std::string(), | |
185 "http://www.google.com/a.xml", | |
186 content::RESOURCE_TYPE_LAST_TYPE, | |
187 1, | |
188 0, | |
189 0, | |
190 6.1)); | |
191 google.resources | |
192 .push_back(ResourceRow(std::string(), | |
193 "http://www.resources.google.com/script.js", | |
194 content::RESOURCE_TYPE_SCRIPT, | |
195 12, | |
196 0, | |
197 0, | |
198 8.5)); | |
199 | |
200 PrefetchData yahoo(PREFETCH_KEY_TYPE_HOST, "www.yahoo.com"); | |
201 yahoo.last_visit = base::Time::FromInternalValue(7); | |
202 yahoo.resources.push_back(ResourceRow(std::string(), | |
203 "http://www.yahoo.com/image.png", | |
204 content::RESOURCE_TYPE_IMAGE, | |
205 120, | |
206 1, | |
207 1, | |
208 10.0)); | |
209 | |
210 tables_->UpdateData(google, yahoo); | |
211 | |
212 PrefetchDataMap actual_url_data, actual_host_data; | |
213 tables_->GetAllData(&actual_url_data, &actual_host_data); | |
214 | |
215 PrefetchDataMap expected_url_data, expected_host_data; | |
216 AddKey(&expected_url_data, "http://www.reddit.com"); | |
217 AddKey(&expected_url_data, "http://www.yahoo.com"); | |
218 expected_url_data.insert(std::make_pair("http://www.google.com", google)); | |
219 | |
220 AddKey(&expected_host_data, "www.facebook.com"); | |
221 expected_host_data.insert(std::make_pair("www.yahoo.com", yahoo)); | |
222 | |
223 TestPrefetchDataAreEqual(expected_url_data, actual_url_data); | |
224 TestPrefetchDataAreEqual(expected_host_data, actual_host_data); | |
225 } | |
226 | |
227 void ResourcePrefetchPredictorTablesTest::TestDeleteAllData() { | |
228 tables_->DeleteAllData(); | |
229 | |
230 PrefetchDataMap actual_url_data, actual_host_data; | |
231 tables_->GetAllData(&actual_url_data, &actual_host_data); | |
232 EXPECT_TRUE(actual_url_data.empty()); | |
233 EXPECT_TRUE(actual_host_data.empty()); | |
234 } | |
235 | |
236 void ResourcePrefetchPredictorTablesTest::TestPrefetchDataAreEqual( | |
237 const PrefetchDataMap& lhs, | |
238 const PrefetchDataMap& rhs) const { | |
239 EXPECT_EQ(lhs.size(), rhs.size()); | |
240 | |
241 for (PrefetchDataMap::const_iterator rhs_it = rhs.begin(); | |
242 rhs_it != rhs.end(); ++rhs_it) { | |
243 PrefetchDataMap::const_iterator lhs_it = lhs.find(rhs_it->first); | |
244 ASSERT_TRUE(lhs_it != lhs.end()) << rhs_it->first; | |
245 | |
246 TestResourceRowsAreEqual(lhs_it->second.resources, | |
247 rhs_it->second.resources); | |
248 } | |
249 } | |
250 | |
251 void ResourcePrefetchPredictorTablesTest::TestResourceRowsAreEqual( | |
252 const ResourceRows& lhs, | |
253 const ResourceRows& rhs) const { | |
254 EXPECT_EQ(lhs.size(), rhs.size()); | |
255 | |
256 std::set<GURL> resources_seen; | |
257 for (ResourceRows::const_iterator rhs_it = rhs.begin(); | |
258 rhs_it != rhs.end(); ++rhs_it) { | |
259 const GURL& resource = rhs_it->resource_url; | |
260 EXPECT_FALSE(ContainsKey(resources_seen, resource)); | |
261 | |
262 for (ResourceRows::const_iterator lhs_it = lhs.begin(); | |
263 lhs_it != lhs.end(); ++lhs_it) { | |
264 if (*rhs_it == *lhs_it) { | |
265 resources_seen.insert(resource); | |
266 break; | |
267 } | |
268 } | |
269 EXPECT_TRUE(ContainsKey(resources_seen, resource)); | |
270 } | |
271 EXPECT_EQ(lhs.size(), resources_seen.size()); | |
272 } | |
273 | |
274 void ResourcePrefetchPredictorTablesTest::AddKey(PrefetchDataMap* m, | |
275 const std::string& key) const { | |
276 PrefetchDataMap::const_iterator it = test_url_data_.find(key); | |
277 if (it != test_url_data_.end()) { | |
278 m->insert(std::make_pair(it->first, it->second)); | |
279 return; | |
280 } | |
281 it = test_host_data_.find(key); | |
282 ASSERT_TRUE(it != test_host_data_.end()); | |
283 m->insert(std::make_pair(it->first, it->second)); | |
284 } | |
285 | |
286 void ResourcePrefetchPredictorTablesTest::InitializeSampleData() { | |
287 { // Url data. | |
288 PrefetchData google(PREFETCH_KEY_TYPE_URL, "http://www.google.com"); | |
289 google.last_visit = base::Time::FromInternalValue(1); | |
290 google.resources.push_back(ResourceRow(std::string(), | |
291 "http://www.google.com/style.css", | |
292 content::RESOURCE_TYPE_STYLESHEET, | |
293 5, | |
294 2, | |
295 1, | |
296 1.1)); | |
297 google.resources.push_back(ResourceRow(std::string(), | |
298 "http://www.google.com/script.js", | |
299 content::RESOURCE_TYPE_SCRIPT, | |
300 4, | |
301 0, | |
302 1, | |
303 2.1)); | |
304 google.resources.push_back(ResourceRow(std::string(), | |
305 "http://www.google.com/image.png", | |
306 content::RESOURCE_TYPE_IMAGE, | |
307 6, | |
308 3, | |
309 0, | |
310 2.2)); | |
311 google.resources.push_back(ResourceRow(std::string(), | |
312 "http://www.google.com/a.font", | |
313 content::RESOURCE_TYPE_LAST_TYPE, | |
314 2, | |
315 0, | |
316 0, | |
317 5.1)); | |
318 google.resources | |
319 .push_back(ResourceRow(std::string(), | |
320 "http://www.resources.google.com/script.js", | |
321 content::RESOURCE_TYPE_SCRIPT, | |
322 11, | |
323 0, | |
324 0, | |
325 8.5)); | |
326 | |
327 PrefetchData reddit(PREFETCH_KEY_TYPE_URL, "http://www.reddit.com"); | |
328 reddit.last_visit = base::Time::FromInternalValue(2); | |
329 reddit.resources | |
330 .push_back(ResourceRow(std::string(), | |
331 "http://reddit-resource.com/script1.js", | |
332 content::RESOURCE_TYPE_SCRIPT, | |
333 4, | |
334 0, | |
335 1, | |
336 1.0)); | |
337 reddit.resources | |
338 .push_back(ResourceRow(std::string(), | |
339 "http://reddit-resource.com/script2.js", | |
340 content::RESOURCE_TYPE_SCRIPT, | |
341 2, | |
342 0, | |
343 0, | |
344 2.1)); | |
345 | |
346 PrefetchData yahoo(PREFETCH_KEY_TYPE_URL, "http://www.yahoo.com"); | |
347 yahoo.last_visit = base::Time::FromInternalValue(3); | |
348 yahoo.resources.push_back(ResourceRow(std::string(), | |
349 "http://www.google.com/image.png", | |
350 content::RESOURCE_TYPE_IMAGE, | |
351 20, | |
352 1, | |
353 0, | |
354 10.0)); | |
355 | |
356 test_url_data_.clear(); | |
357 test_url_data_.insert(std::make_pair("http://www.google.com", google)); | |
358 test_url_data_.insert(std::make_pair("http://www.reddit.com", reddit)); | |
359 test_url_data_.insert(std::make_pair("http://www.yahoo.com", yahoo)); | |
360 | |
361 PrefetchData empty_host_data(PREFETCH_KEY_TYPE_HOST, std::string()); | |
362 tables_->UpdateData(google, empty_host_data); | |
363 tables_->UpdateData(reddit, empty_host_data); | |
364 tables_->UpdateData(yahoo, empty_host_data); | |
365 } | |
366 | |
367 { // Host data. | |
368 PrefetchData facebook(PREFETCH_KEY_TYPE_HOST, "www.facebook.com"); | |
369 facebook.last_visit = base::Time::FromInternalValue(4); | |
370 facebook.resources | |
371 .push_back(ResourceRow(std::string(), | |
372 "http://www.facebook.com/style.css", | |
373 content::RESOURCE_TYPE_STYLESHEET, | |
374 5, | |
375 2, | |
376 1, | |
377 1.1)); | |
378 facebook.resources | |
379 .push_back(ResourceRow(std::string(), | |
380 "http://www.facebook.com/script.js", | |
381 content::RESOURCE_TYPE_SCRIPT, | |
382 4, | |
383 0, | |
384 1, | |
385 2.1)); | |
386 facebook.resources | |
387 .push_back(ResourceRow(std::string(), | |
388 "http://www.facebook.com/image.png", | |
389 content::RESOURCE_TYPE_IMAGE, | |
390 6, | |
391 3, | |
392 0, | |
393 2.2)); | |
394 facebook.resources.push_back(ResourceRow(std::string(), | |
395 "http://www.facebook.com/a.font", | |
396 content::RESOURCE_TYPE_LAST_TYPE, | |
397 2, | |
398 0, | |
399 0, | |
400 5.1)); | |
401 facebook.resources | |
402 .push_back(ResourceRow(std::string(), | |
403 "http://www.resources.facebook.com/script.js", | |
404 content::RESOURCE_TYPE_SCRIPT, | |
405 11, | |
406 0, | |
407 0, | |
408 8.5)); | |
409 | |
410 PrefetchData yahoo(PREFETCH_KEY_TYPE_HOST, "www.yahoo.com"); | |
411 yahoo.last_visit = base::Time::FromInternalValue(5); | |
412 yahoo.resources.push_back(ResourceRow(std::string(), | |
413 "http://www.google.com/image.png", | |
414 content::RESOURCE_TYPE_IMAGE, | |
415 20, | |
416 1, | |
417 0, | |
418 10.0)); | |
419 | |
420 test_host_data_.clear(); | |
421 test_host_data_.insert(std::make_pair("www.facebook.com", facebook)); | |
422 test_host_data_.insert(std::make_pair("www.yahoo.com", yahoo)); | |
423 | |
424 PrefetchData empty_url_data(PREFETCH_KEY_TYPE_URL, std::string()); | |
425 tables_->UpdateData(empty_url_data, facebook); | |
426 tables_->UpdateData(empty_url_data, yahoo); | |
427 } | |
428 } | |
429 | |
430 // Test cases. | |
431 | |
432 TEST_F(ResourcePrefetchPredictorTablesTest, GetAllData) { | |
433 TestGetAllData(); | |
434 } | |
435 | |
436 TEST_F(ResourcePrefetchPredictorTablesTest, UpdateData) { | |
437 TestUpdateData(); | |
438 } | |
439 | |
440 TEST_F(ResourcePrefetchPredictorTablesTest, DeleteData) { | |
441 TestDeleteData(); | |
442 } | |
443 | |
444 TEST_F(ResourcePrefetchPredictorTablesTest, DeleteSingleDataPoint) { | |
445 TestDeleteSingleDataPoint(); | |
446 } | |
447 | |
448 TEST_F(ResourcePrefetchPredictorTablesTest, DeleteAllData) { | |
449 TestDeleteAllData(); | |
450 } | |
451 | |
452 TEST_F(ResourcePrefetchPredictorTablesReopenTest, GetAllData) { | |
453 TestGetAllData(); | |
454 } | |
455 | |
456 TEST_F(ResourcePrefetchPredictorTablesReopenTest, UpdateData) { | |
457 TestUpdateData(); | |
458 } | |
459 | |
460 TEST_F(ResourcePrefetchPredictorTablesReopenTest, DeleteData) { | |
461 TestDeleteData(); | |
462 } | |
463 | |
464 TEST_F(ResourcePrefetchPredictorTablesReopenTest, DeleteSingleDataPoint) { | |
465 TestDeleteSingleDataPoint(); | |
466 } | |
467 | |
468 TEST_F(ResourcePrefetchPredictorTablesReopenTest, DeleteAllData) { | |
469 TestDeleteAllData(); | |
470 } | |
471 | |
472 } // namespace predictors | |
OLD | NEW |