OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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 | |
7 #include "base/file_util.h" | |
8 #include "base/files/file_path.h" | |
9 #include "base/message_loop/message_loop.h" | |
10 #include "base/strings/utf_string_conversions.h" | |
11 #include "chrome/browser/history/text_database_manager.h" | |
12 #include "chrome/browser/history/visit_database.h" | |
13 #include "sql/connection.h" | |
14 #include "testing/gtest/include/gtest/gtest.h" | |
15 | |
16 using base::Time; | |
17 using base::TimeDelta; | |
18 using base::TimeTicks; | |
19 | |
20 namespace history { | |
21 | |
22 namespace { | |
23 | |
24 const char* kURL1 = "http://www.google.com/asdf"; | |
25 const char* kTitle1 = "Google A"; | |
26 const char* kBody1 = "FOO page one."; | |
27 | |
28 const char* kURL2 = "http://www.google.com/qwer"; | |
29 const char* kTitle2 = "Google B"; | |
30 const char* kBody2 = "FOO two."; | |
31 | |
32 const char* kURL3 = "http://www.google.com/zxcv"; | |
33 const char* kTitle3 = "Google C"; | |
34 const char* kBody3 = "FOO drei"; | |
35 | |
36 const char* kURL4 = "http://www.google.com/hjkl"; | |
37 const char* kTitle4 = "Google D"; | |
38 const char* kBody4 = "FOO lalala four."; | |
39 | |
40 const char* kURL5 = "http://www.google.com/uiop"; | |
41 const char* kTitle5 = "Google cinq"; | |
42 const char* kBody5 = "FOO page one."; | |
43 | |
44 // This provides a simple implementation of a URL+VisitDatabase using an | |
45 // in-memory sqlite connection. The text database manager expects to be able to | |
46 // update the visit database to keep in sync. | |
47 class InMemDB : public URLDatabase, public VisitDatabase { | |
48 public: | |
49 InMemDB() { | |
50 EXPECT_TRUE(db_.OpenInMemory()); | |
51 CreateURLTable(false); | |
52 InitVisitTable(); | |
53 } | |
54 virtual ~InMemDB() { | |
55 } | |
56 | |
57 private: | |
58 virtual sql::Connection& GetDB() OVERRIDE { return db_; } | |
59 | |
60 sql::Connection db_; | |
61 | |
62 DISALLOW_COPY_AND_ASSIGN(InMemDB); | |
63 }; | |
64 | |
65 // Adds all the pages once, and the first page once more in the next month. | |
66 // The times of all the pages will be filled into |*times|. | |
67 void AddAllPages(TextDatabaseManager& manager, VisitDatabase* visit_db, | |
68 std::vector<Time>* times) { | |
69 Time::Exploded exploded; | |
70 memset(&exploded, 0, sizeof(Time::Exploded)); | |
71 | |
72 // Put the visits in two different months so it will query across databases. | |
73 exploded.year = 2008; | |
74 exploded.month = 1; | |
75 exploded.day_of_month = 3; | |
76 | |
77 VisitRow visit_row; | |
78 visit_row.url_id = 1; | |
79 visit_row.visit_time = Time::FromUTCExploded(exploded); | |
80 visit_row.referring_visit = 0; | |
81 visit_row.transition = content::PageTransitionFromInt(0); | |
82 visit_row.segment_id = 0; | |
83 visit_row.is_indexed = false; | |
84 visit_db->AddVisit(&visit_row, SOURCE_BROWSED); | |
85 | |
86 times->push_back(visit_row.visit_time); | |
87 manager.AddPageData(GURL(kURL1), visit_row.url_id, visit_row.visit_id, | |
88 visit_row.visit_time, UTF8ToUTF16(kTitle1), | |
89 UTF8ToUTF16(kBody1)); | |
90 | |
91 exploded.day_of_month++; | |
92 visit_row.url_id = 2; | |
93 visit_row.visit_time = Time::FromUTCExploded(exploded); | |
94 visit_db->AddVisit(&visit_row, SOURCE_BROWSED); | |
95 times->push_back(visit_row.visit_time); | |
96 manager.AddPageData(GURL(kURL2), visit_row.url_id, visit_row.visit_id, | |
97 visit_row.visit_time, UTF8ToUTF16(kTitle2), | |
98 UTF8ToUTF16(kBody2)); | |
99 | |
100 exploded.day_of_month++; | |
101 visit_row.url_id = 2; | |
102 visit_row.visit_time = Time::FromUTCExploded(exploded); | |
103 visit_db->AddVisit(&visit_row, SOURCE_BROWSED); | |
104 times->push_back(visit_row.visit_time); | |
105 manager.AddPageData(GURL(kURL3), visit_row.url_id, visit_row.visit_id, | |
106 visit_row.visit_time, UTF8ToUTF16(kTitle3), | |
107 UTF8ToUTF16(kBody3)); | |
108 | |
109 // Put the next ones in the next month. | |
110 exploded.month++; | |
111 visit_row.url_id = 2; | |
112 visit_row.visit_time = Time::FromUTCExploded(exploded); | |
113 visit_db->AddVisit(&visit_row, SOURCE_BROWSED); | |
114 times->push_back(visit_row.visit_time); | |
115 manager.AddPageData(GURL(kURL4), visit_row.url_id, visit_row.visit_id, | |
116 visit_row.visit_time, UTF8ToUTF16(kTitle4), | |
117 UTF8ToUTF16(kBody4)); | |
118 | |
119 exploded.day_of_month++; | |
120 visit_row.url_id = 2; | |
121 visit_row.visit_time = Time::FromUTCExploded(exploded); | |
122 visit_db->AddVisit(&visit_row, SOURCE_BROWSED); | |
123 times->push_back(visit_row.visit_time); | |
124 manager.AddPageData(GURL(kURL5), visit_row.url_id, visit_row.visit_id, | |
125 visit_row.visit_time, UTF8ToUTF16(kTitle5), | |
126 UTF8ToUTF16(kBody5)); | |
127 | |
128 // Put the first one in again in the second month. | |
129 exploded.day_of_month++; | |
130 visit_row.url_id = 2; | |
131 visit_row.visit_time = Time::FromUTCExploded(exploded); | |
132 visit_db->AddVisit(&visit_row, SOURCE_BROWSED); | |
133 times->push_back(visit_row.visit_time); | |
134 manager.AddPageData(GURL(kURL1), visit_row.url_id, visit_row.visit_id, | |
135 visit_row.visit_time, UTF8ToUTF16(kTitle1), | |
136 UTF8ToUTF16(kBody1)); | |
137 } | |
138 | |
139 bool ResultsHaveURL(const std::vector<TextDatabase::Match>& results, | |
140 const char* url) { | |
141 GURL gurl(url); | |
142 for (size_t i = 0; i < results.size(); i++) { | |
143 if (results[i].url == gurl) | |
144 return true; | |
145 } | |
146 return false; | |
147 } | |
148 | |
149 } // namespace | |
150 | |
151 class TextDatabaseManagerTest : public testing::Test { | |
152 public: | |
153 // Called manually by the test so it can report failure to initialize. | |
154 bool Init() { | |
155 return file_util::CreateNewTempDirectory( | |
156 FILE_PATH_LITERAL("TestSearchTest"), &dir_); | |
157 } | |
158 | |
159 protected: | |
160 virtual void SetUp() { | |
161 } | |
162 | |
163 virtual void TearDown() { | |
164 base::DeleteFile(dir_, true); | |
165 } | |
166 | |
167 base::MessageLoop message_loop_; | |
168 | |
169 // Directory containing the databases. | |
170 base::FilePath dir_; | |
171 }; | |
172 | |
173 // Tests basic querying. | |
174 TEST_F(TextDatabaseManagerTest, InsertQuery) { | |
175 ASSERT_TRUE(Init()); | |
176 InMemDB visit_db; | |
177 TextDatabaseManager manager(dir_, &visit_db, &visit_db); | |
178 ASSERT_TRUE(manager.Init(NULL)); | |
179 | |
180 std::vector<Time> times; | |
181 AddAllPages(manager, &visit_db, ×); | |
182 | |
183 QueryOptions options; | |
184 options.begin_time = times[0] - TimeDelta::FromDays(100); | |
185 options.end_time = times[times.size() - 1] + TimeDelta::FromDays(100); | |
186 std::vector<TextDatabase::Match> results; | |
187 Time first_time_searched; | |
188 manager.GetTextMatches(UTF8ToUTF16("FOO"), options, | |
189 &results, &first_time_searched); | |
190 | |
191 // We should have matched every page. | |
192 EXPECT_EQ(6U, results.size()); | |
193 EXPECT_TRUE(ResultsHaveURL(results, kURL1)); | |
194 EXPECT_TRUE(ResultsHaveURL(results, kURL2)); | |
195 EXPECT_TRUE(ResultsHaveURL(results, kURL3)); | |
196 EXPECT_TRUE(ResultsHaveURL(results, kURL4)); | |
197 EXPECT_TRUE(ResultsHaveURL(results, kURL5)); | |
198 | |
199 // The first time searched should have been the first page's time or before | |
200 // (it could have eliminated some time for us). | |
201 EXPECT_TRUE(first_time_searched <= times[0]); | |
202 } | |
203 | |
204 // Tests that adding page components piecemeal will get them added properly. | |
205 // This does not supply a visit to update, this mode is used only by the unit | |
206 // tests right now, but we test it anyway. | |
207 TEST_F(TextDatabaseManagerTest, InsertCompleteNoVisit) { | |
208 ASSERT_TRUE(Init()); | |
209 InMemDB visit_db; | |
210 TextDatabaseManager manager(dir_, &visit_db, &visit_db); | |
211 ASSERT_TRUE(manager.Init(NULL)); | |
212 | |
213 // First add one without a visit. | |
214 const GURL url(kURL1); | |
215 manager.AddPageURL(url, 0, 0, Time::Now()); | |
216 manager.AddPageTitle(url, UTF8ToUTF16(kTitle1)); | |
217 manager.AddPageContents(url, UTF8ToUTF16(kBody1)); | |
218 | |
219 // Check that the page got added. | |
220 QueryOptions options; | |
221 std::vector<TextDatabase::Match> results; | |
222 Time first_time_searched; | |
223 | |
224 manager.GetTextMatches(UTF8ToUTF16("FOO"), options, | |
225 &results, &first_time_searched); | |
226 ASSERT_EQ(1U, results.size()); | |
227 EXPECT_EQ(kTitle1, UTF16ToUTF8(results[0].title)); | |
228 } | |
229 | |
230 // Like InsertCompleteNoVisit but specifies a visit to update. We check that the | |
231 // visit was updated properly. | |
232 TEST_F(TextDatabaseManagerTest, InsertCompleteVisit) { | |
233 ASSERT_TRUE(Init()); | |
234 InMemDB visit_db; | |
235 TextDatabaseManager manager(dir_, &visit_db, &visit_db); | |
236 ASSERT_TRUE(manager.Init(NULL)); | |
237 | |
238 // First add a visit to a page. We can just make up a URL ID since there is | |
239 // not actually any URL database around. | |
240 VisitRow visit; | |
241 visit.url_id = 1; | |
242 visit.visit_time = Time::Now(); | |
243 visit.referring_visit = 0; | |
244 visit.transition = content::PAGE_TRANSITION_LINK; | |
245 visit.segment_id = 0; | |
246 visit.is_indexed = false; | |
247 visit_db.AddVisit(&visit, SOURCE_BROWSED); | |
248 | |
249 // Add a full text indexed entry for that visit. | |
250 const GURL url(kURL2); | |
251 manager.AddPageURL(url, visit.url_id, visit.visit_id, visit.visit_time); | |
252 manager.AddPageContents(url, UTF8ToUTF16(kBody2)); | |
253 manager.AddPageTitle(url, UTF8ToUTF16(kTitle2)); | |
254 | |
255 // Check that the page got added. | |
256 QueryOptions options; | |
257 std::vector<TextDatabase::Match> results; | |
258 Time first_time_searched; | |
259 | |
260 manager.GetTextMatches(UTF8ToUTF16("FOO"), options, | |
261 &results, &first_time_searched); | |
262 ASSERT_EQ(1U, results.size()); | |
263 EXPECT_EQ(kTitle2, UTF16ToUTF8(results[0].title)); | |
264 | |
265 // Check that the visit got updated for its new indexed state. | |
266 VisitRow out_visit; | |
267 ASSERT_TRUE(visit_db.GetRowForVisit(visit.visit_id, &out_visit)); | |
268 EXPECT_TRUE(out_visit.is_indexed); | |
269 } | |
270 | |
271 // Tests that partial inserts that expire are added to the database. | |
272 TEST_F(TextDatabaseManagerTest, InsertPartial) { | |
273 ASSERT_TRUE(Init()); | |
274 InMemDB visit_db; | |
275 TextDatabaseManager manager(dir_, &visit_db, &visit_db); | |
276 ASSERT_TRUE(manager.Init(NULL)); | |
277 | |
278 // Add the first one with just a URL. | |
279 GURL url1(kURL1); | |
280 manager.AddPageURL(url1, 0, 0, Time::Now()); | |
281 | |
282 // Now add a second one with a URL and title. | |
283 GURL url2(kURL2); | |
284 manager.AddPageURL(url2, 0, 0, Time::Now()); | |
285 manager.AddPageTitle(url2, UTF8ToUTF16(kTitle2)); | |
286 | |
287 // The third one has a URL and body. | |
288 GURL url3(kURL3); | |
289 manager.AddPageURL(url3, 0, 0, Time::Now()); | |
290 manager.AddPageContents(url3, UTF8ToUTF16(kBody3)); | |
291 | |
292 // Expire stuff very fast. This assumes that the time between the first | |
293 // AddPageURL and this line is less than the expiration time (20 seconds). | |
294 TimeTicks added_time = TimeTicks::Now(); | |
295 TimeTicks expire_time = added_time + TimeDelta::FromSeconds(5); | |
296 manager.FlushOldChangesForTime(expire_time); | |
297 | |
298 // Do a query, nothing should be added yet. | |
299 QueryOptions options; | |
300 std::vector<TextDatabase::Match> results; | |
301 Time first_time_searched; | |
302 manager.GetTextMatches(UTF8ToUTF16("google"), options, | |
303 &results, &first_time_searched); | |
304 ASSERT_EQ(0U, results.size()); | |
305 | |
306 // Compute a time threshold that will cause everything to be flushed, and | |
307 // poke at the manager's internals to cause this to happen. | |
308 expire_time = added_time + TimeDelta::FromDays(1); | |
309 manager.FlushOldChangesForTime(expire_time); | |
310 | |
311 // Now we should have all 3 URLs added. | |
312 manager.GetTextMatches(UTF8ToUTF16("google"), options, | |
313 &results, &first_time_searched); | |
314 ASSERT_EQ(3U, results.size()); | |
315 EXPECT_TRUE(ResultsHaveURL(results, kURL1)); | |
316 EXPECT_TRUE(ResultsHaveURL(results, kURL2)); | |
317 EXPECT_TRUE(ResultsHaveURL(results, kURL3)); | |
318 } | |
319 | |
320 // Tests that partial inserts (due to timeouts) will still get updated if the | |
321 // data comes in later. | |
322 TEST_F(TextDatabaseManagerTest, PartialComplete) { | |
323 ASSERT_TRUE(Init()); | |
324 InMemDB visit_db; | |
325 TextDatabaseManager manager(dir_, &visit_db, &visit_db); | |
326 ASSERT_TRUE(manager.Init(NULL)); | |
327 | |
328 Time added_time = Time::Now(); | |
329 GURL url(kURL1); | |
330 | |
331 // We have to have the URL in the URL and visit databases for this test to | |
332 // work. | |
333 URLRow url_row(url); | |
334 url_row.set_title(UTF8ToUTF16("chocolate")); | |
335 URLID url_id = visit_db.AddURL(url_row); | |
336 ASSERT_TRUE(url_id); | |
337 VisitRow visit_row; | |
338 visit_row.url_id = url_id; | |
339 visit_row.visit_time = added_time; | |
340 visit_db.AddVisit(&visit_row, SOURCE_BROWSED); | |
341 | |
342 // Add a URL with no title or body, and say that it expired. | |
343 manager.AddPageURL(url, 0, 0, added_time); | |
344 TimeTicks expire_time = TimeTicks::Now() + TimeDelta::FromDays(1); | |
345 manager.FlushOldChangesForTime(expire_time); | |
346 | |
347 // Add the title. We should be able to query based on that. The title in the | |
348 // URL row we set above should not come into the picture. | |
349 manager.AddPageTitle(url, UTF8ToUTF16("Some unique title")); | |
350 Time first_time_searched; | |
351 QueryOptions options; | |
352 std::vector<TextDatabase::Match> results; | |
353 manager.GetTextMatches(UTF8ToUTF16("unique"), options, | |
354 &results, &first_time_searched); | |
355 EXPECT_EQ(1U, results.size()); | |
356 manager.GetTextMatches(UTF8ToUTF16("chocolate"), options, | |
357 &results, &first_time_searched); | |
358 EXPECT_EQ(0U, results.size()); | |
359 | |
360 // Now add the body, which should be queryable. | |
361 manager.AddPageContents(url, UTF8ToUTF16("Very awesome body")); | |
362 manager.GetTextMatches(UTF8ToUTF16("awesome"), options, &results, &first_time_
searched); | |
363 EXPECT_EQ(1U, results.size()); | |
364 | |
365 // Adding the body will actually copy the title from the URL table rather | |
366 // than the previously indexed row (we made them not match above). This isn't | |
367 // necessarily what we want, but it's how it's implemented, and we don't want | |
368 // to regress it. | |
369 manager.GetTextMatches(UTF8ToUTF16("chocolate"), options, &results, &first_tim
e_searched); | |
370 EXPECT_EQ(1U, results.size()); | |
371 } | |
372 | |
373 // Tests that changes get properly committed to disk. | |
374 TEST_F(TextDatabaseManagerTest, Writing) { | |
375 ASSERT_TRUE(Init()); | |
376 | |
377 QueryOptions options; | |
378 std::vector<TextDatabase::Match> results; | |
379 Time first_time_searched; | |
380 | |
381 InMemDB visit_db; | |
382 | |
383 // Create the manager and write some stuff to it. | |
384 { | |
385 TextDatabaseManager manager(dir_, &visit_db, &visit_db); | |
386 ASSERT_TRUE(manager.Init(NULL)); | |
387 | |
388 std::vector<Time> times; | |
389 AddAllPages(manager, &visit_db, ×); | |
390 | |
391 // We should have matched every page. | |
392 manager.GetTextMatches(UTF8ToUTF16("FOO"), options, &results, &first_time_se
arched); | |
393 EXPECT_EQ(6U, results.size()); | |
394 } | |
395 results.clear(); | |
396 | |
397 // Recreate the manager and make sure it finds the written stuff. | |
398 { | |
399 TextDatabaseManager manager(dir_, &visit_db, &visit_db); | |
400 ASSERT_TRUE(manager.Init(NULL)); | |
401 | |
402 // We should have matched every page again. | |
403 manager.GetTextMatches(UTF8ToUTF16("FOO"), options, | |
404 &results, &first_time_searched); | |
405 EXPECT_EQ(6U, results.size()); | |
406 } | |
407 } | |
408 | |
409 // Tests that changes get properly committed to disk, as in the Writing test | |
410 // above, but when there is a transaction around the adds. | |
411 TEST_F(TextDatabaseManagerTest, WritingTransaction) { | |
412 ASSERT_TRUE(Init()); | |
413 | |
414 QueryOptions options; | |
415 std::vector<TextDatabase::Match> results; | |
416 Time first_time_searched; | |
417 | |
418 InMemDB visit_db; | |
419 | |
420 // Create the manager and write some stuff to it. | |
421 { | |
422 TextDatabaseManager manager(dir_, &visit_db, &visit_db); | |
423 ASSERT_TRUE(manager.Init(NULL)); | |
424 | |
425 std::vector<Time> times; | |
426 manager.BeginTransaction(); | |
427 AddAllPages(manager, &visit_db, ×); | |
428 // "Forget" to commit, it should be autocommittedd for us. | |
429 | |
430 // We should have matched every page. | |
431 manager.GetTextMatches(UTF8ToUTF16("FOO"), options, | |
432 &results, &first_time_searched); | |
433 EXPECT_EQ(6U, results.size()); | |
434 } | |
435 results.clear(); | |
436 | |
437 // Recreate the manager and make sure it finds the written stuff. | |
438 { | |
439 TextDatabaseManager manager(dir_, &visit_db, &visit_db); | |
440 ASSERT_TRUE(manager.Init(NULL)); | |
441 | |
442 // We should have matched every page again. | |
443 manager.GetTextMatches(UTF8ToUTF16("FOO"), options, | |
444 &results, &first_time_searched); | |
445 EXPECT_EQ(6U, results.size()); | |
446 } | |
447 } | |
448 | |
449 // Tests querying where the maximum number of items is met. | |
450 TEST_F(TextDatabaseManagerTest, QueryMax) { | |
451 ASSERT_TRUE(Init()); | |
452 InMemDB visit_db; | |
453 TextDatabaseManager manager(dir_, &visit_db, &visit_db); | |
454 ASSERT_TRUE(manager.Init(NULL)); | |
455 | |
456 std::vector<Time> times; | |
457 AddAllPages(manager, &visit_db, ×); | |
458 | |
459 string16 foo = UTF8ToUTF16("FOO"); | |
460 | |
461 QueryOptions options; | |
462 options.begin_time = times[0] - TimeDelta::FromDays(100); | |
463 options.end_time = times[times.size() - 1] + TimeDelta::FromDays(100); | |
464 options.max_count = 2; | |
465 std::vector<TextDatabase::Match> results; | |
466 Time first_time_searched; | |
467 manager.GetTextMatches(foo, options, &results, &first_time_searched); | |
468 | |
469 // We should have gotten the last two pages as results (the first page is | |
470 // also the last). | |
471 EXPECT_EQ(2U, results.size()); | |
472 EXPECT_TRUE(first_time_searched <= times[4]); | |
473 EXPECT_TRUE(ResultsHaveURL(results, kURL5)); | |
474 EXPECT_TRUE(ResultsHaveURL(results, kURL1)); | |
475 | |
476 // Asking for 4 pages, the first one should be in another DB. | |
477 options.max_count = 4; | |
478 manager.GetTextMatches(foo, options, &results, &first_time_searched); | |
479 | |
480 EXPECT_EQ(4U, results.size()); | |
481 EXPECT_TRUE(first_time_searched <= times[4]); | |
482 EXPECT_TRUE(ResultsHaveURL(results, kURL3)); | |
483 EXPECT_TRUE(ResultsHaveURL(results, kURL4)); | |
484 EXPECT_TRUE(ResultsHaveURL(results, kURL5)); | |
485 EXPECT_TRUE(ResultsHaveURL(results, kURL1)); | |
486 } | |
487 | |
488 // Tests querying backwards in time in chunks. | |
489 TEST_F(TextDatabaseManagerTest, QueryBackwards) { | |
490 ASSERT_TRUE(Init()); | |
491 InMemDB visit_db; | |
492 TextDatabaseManager manager(dir_, &visit_db, &visit_db); | |
493 ASSERT_TRUE(manager.Init(NULL)); | |
494 | |
495 std::vector<Time> times; | |
496 AddAllPages(manager, &visit_db, ×); | |
497 | |
498 string16 foo = UTF8ToUTF16("FOO"); | |
499 | |
500 // First do a query for all time, but with a max of 2. This will give us the | |
501 // last two results and will tell us where to start searching when we want | |
502 // to go back in time. | |
503 QueryOptions options; | |
504 options.begin_time = times[0] - TimeDelta::FromDays(100); | |
505 options.end_time = times[times.size() - 1] + TimeDelta::FromDays(100); | |
506 options.max_count = 2; | |
507 std::vector<TextDatabase::Match> results; | |
508 Time first_time_searched; | |
509 manager.GetTextMatches(foo, options, &results, &first_time_searched); | |
510 | |
511 // Check that we got the last two results. | |
512 EXPECT_EQ(2U, results.size()); | |
513 EXPECT_TRUE(first_time_searched <= times[4]); | |
514 EXPECT_TRUE(ResultsHaveURL(results, kURL5)); | |
515 EXPECT_TRUE(ResultsHaveURL(results, kURL1)); | |
516 | |
517 // Query the previous two URLs and make sure we got the correct ones. | |
518 options.end_time = first_time_searched; | |
519 manager.GetTextMatches(foo, options, &results, &first_time_searched); | |
520 EXPECT_EQ(2U, results.size()); | |
521 EXPECT_TRUE(first_time_searched <= times[2]); | |
522 EXPECT_TRUE(ResultsHaveURL(results, kURL3)); | |
523 EXPECT_TRUE(ResultsHaveURL(results, kURL4)); | |
524 | |
525 // Query the previous two URLs... | |
526 options.end_time = first_time_searched; | |
527 manager.GetTextMatches(foo, options, &results, &first_time_searched); | |
528 EXPECT_EQ(2U, results.size()); | |
529 EXPECT_TRUE(first_time_searched <= times[0]); | |
530 EXPECT_TRUE(ResultsHaveURL(results, kURL2)); | |
531 EXPECT_TRUE(ResultsHaveURL(results, kURL1)); | |
532 | |
533 // Try to query some more, there should be no results. | |
534 options.end_time = first_time_searched; | |
535 manager.GetTextMatches(foo, options, &results, &first_time_searched); | |
536 EXPECT_EQ(0U, results.size()); | |
537 } | |
538 | |
539 // Tests deletion of uncommitted entries. | |
540 TEST_F(TextDatabaseManagerTest, DeleteUncommitted) { | |
541 ASSERT_TRUE(Init()); | |
542 InMemDB visit_db; | |
543 TextDatabaseManager manager(dir_, &visit_db, &visit_db); | |
544 ASSERT_TRUE(manager.Init(NULL)); | |
545 | |
546 manager.AddPageURL(GURL(kURL1), 0, 0, Time::FromInternalValue(1)); | |
547 manager.AddPageURL(GURL(kURL2), 0, 0, Time::FromInternalValue(2)); | |
548 manager.AddPageURL(GURL(kURL3), 0, 0, Time::FromInternalValue(3)); | |
549 manager.AddPageURL(GURL(kURL4), 0, 0, Time::FromInternalValue(4)); | |
550 manager.AddPageURL(GURL(kURL5), 0, 0, Time::FromInternalValue(5)); | |
551 | |
552 EXPECT_EQ(5u, manager.GetUncommittedEntryCountForTest()); | |
553 | |
554 // Should delete the first two entries. | |
555 manager.DeleteFromUncommitted(std::set<GURL>(), | |
556 Time::FromInternalValue(1), | |
557 Time::FromInternalValue(3)); | |
558 | |
559 EXPECT_EQ(3u, manager.GetUncommittedEntryCountForTest()); | |
560 | |
561 // Should delete the third entry. | |
562 { | |
563 std::set<GURL> urls; | |
564 urls.insert(GURL(kURL3)); | |
565 manager.DeleteFromUncommitted(urls, Time(), Time()); | |
566 } | |
567 | |
568 EXPECT_EQ(2u, manager.GetUncommittedEntryCountForTest()); | |
569 } | |
570 | |
571 // Tests deletion of uncommitted entries by time. | |
572 TEST_F(TextDatabaseManagerTest, DeleteUncommittedForTimes) { | |
573 ASSERT_TRUE(Init()); | |
574 InMemDB visit_db; | |
575 TextDatabaseManager manager(dir_, &visit_db, &visit_db); | |
576 ASSERT_TRUE(manager.Init(NULL)); | |
577 | |
578 manager.AddPageURL(GURL(kURL1), 0, 0, Time::FromInternalValue(2)); | |
579 manager.AddPageURL(GURL(kURL2), 0, 0, Time::FromInternalValue(3)); | |
580 manager.AddPageURL(GURL(kURL3), 0, 0, Time::FromInternalValue(4)); | |
581 manager.AddPageURL(GURL(kURL4), 0, 0, Time::FromInternalValue(5)); | |
582 manager.AddPageURL(GURL(kURL5), 0, 0, Time::FromInternalValue(6)); | |
583 | |
584 EXPECT_EQ(5u, manager.GetUncommittedEntryCountForTest()); | |
585 | |
586 std::vector<base::Time> times; | |
587 times.push_back(Time::FromInternalValue(9)); | |
588 times.push_back(Time::FromInternalValue(7)); | |
589 times.push_back(Time::FromInternalValue(5)); | |
590 times.push_back(Time::FromInternalValue(5)); | |
591 times.push_back(Time::FromInternalValue(3)); | |
592 times.push_back(Time::FromInternalValue(1)); | |
593 manager.DeleteFromUncommittedForTimes(times); | |
594 | |
595 EXPECT_EQ(3u, manager.GetUncommittedEntryCountForTest()); | |
596 } | |
597 | |
598 } // namespace history | |
OLD | NEW |