| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <cstdio> | 5 #include <cstdio> |
| 6 #include <string> | 6 #include <string> |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 bool TestURLIterator::HasNextURL() const { | 100 bool TestURLIterator::HasNextURL() const { |
| 101 return iterator_ != end_; | 101 return iterator_ != end_; |
| 102 } | 102 } |
| 103 | 103 |
| 104 } // namespace | 104 } // namespace |
| 105 | 105 |
| 106 class TrackingVisitedLinkEventListener : public VisitedLinkMaster::Listener { | 106 class TrackingVisitedLinkEventListener : public VisitedLinkMaster::Listener { |
| 107 public: | 107 public: |
| 108 TrackingVisitedLinkEventListener() | 108 TrackingVisitedLinkEventListener() |
| 109 : reset_count_(0), | 109 : reset_count_(0), |
| 110 completely_reset_count_(0), |
| 110 add_count_(0) {} | 111 add_count_(0) {} |
| 111 | 112 |
| 112 void NewTable(base::SharedMemory* table) override { | 113 void NewTable(base::SharedMemory* table) override { |
| 113 if (table) { | 114 if (table) { |
| 114 for (std::vector<VisitedLinkSlave>::size_type i = 0; | 115 for (std::vector<VisitedLinkSlave>::size_type i = 0; |
| 115 i < g_slaves.size(); i++) { | 116 i < g_slaves.size(); i++) { |
| 116 base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); | 117 base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); |
| 117 table->ShareToProcess(base::GetCurrentProcessHandle(), &new_handle); | 118 table->ShareToProcess(base::GetCurrentProcessHandle(), &new_handle); |
| 118 g_slaves[i]->OnUpdateVisitedLinks(new_handle); | 119 g_slaves[i]->OnUpdateVisitedLinks(new_handle); |
| 119 } | 120 } |
| 120 } | 121 } |
| 121 } | 122 } |
| 122 void Add(VisitedLinkCommon::Fingerprint) override { add_count_++; } | 123 void Add(VisitedLinkCommon::Fingerprint) override { add_count_++; } |
| 123 void Reset() override { reset_count_++; } | 124 void Reset(bool invalidate_hashes) override { |
| 125 if (invalidate_hashes) |
| 126 completely_reset_count_++; |
| 127 else |
| 128 reset_count_++; |
| 129 } |
| 124 | 130 |
| 125 void SetUp() { | 131 void SetUp() { |
| 126 reset_count_ = 0; | 132 reset_count_ = 0; |
| 127 add_count_ = 0; | 133 add_count_ = 0; |
| 128 } | 134 } |
| 129 | 135 |
| 130 int reset_count() const { return reset_count_; } | 136 int reset_count() const { return reset_count_; } |
| 137 int completely_reset_count() { return completely_reset_count_; } |
| 131 int add_count() const { return add_count_; } | 138 int add_count() const { return add_count_; } |
| 132 | 139 |
| 133 private: | 140 private: |
| 134 int reset_count_; | 141 int reset_count_; |
| 142 int completely_reset_count_; |
| 135 int add_count_; | 143 int add_count_; |
| 136 }; | 144 }; |
| 137 | 145 |
| 138 class VisitedLinkTest : public testing::Test { | 146 class VisitedLinkTest : public testing::Test { |
| 139 protected: | 147 protected: |
| 140 // Initializes the visited link objects. Pass in the size that you want a | 148 // Initializes the visited link objects. Pass in the size that you want a |
| 141 // freshly created table to be. 0 means use the default. | 149 // freshly created table to be. 0 means use the default. |
| 142 // | 150 // |
| 143 // |suppress_rebuild| is set when we're not testing rebuilding, see | 151 // |suppress_rebuild| is set when we're not testing rebuilding, see |
| 144 // the VisitedLinkMaster constructor. | 152 // the VisitedLinkMaster constructor. |
| 145 bool InitVisited(int initial_size, bool suppress_rebuild) { | 153 // |
| 154 // |wait_for_io_complete| wait for result of async loading. |
| 155 bool InitVisited(int initial_size, |
| 156 bool suppress_rebuild, |
| 157 bool wait_for_io_complete) { |
| 146 // Initialize the visited link system. | 158 // Initialize the visited link system. |
| 147 master_.reset(new VisitedLinkMaster(new TrackingVisitedLinkEventListener(), | 159 master_.reset(new VisitedLinkMaster(new TrackingVisitedLinkEventListener(), |
| 148 &delegate_, | 160 &delegate_, |
| 149 true, | 161 true, |
| 150 suppress_rebuild, visited_file_, | 162 suppress_rebuild, visited_file_, |
| 151 initial_size)); | 163 initial_size)); |
| 152 return master_->Init(); | 164 bool result = master_->Init(); |
| 165 if (result && wait_for_io_complete) { |
| 166 // Wait for all pending file I/O to be completed. |
| 167 content::RunAllBlockingPoolTasksUntilIdle(); |
| 168 } |
| 169 return result; |
| 153 } | 170 } |
| 154 | 171 |
| 155 // May be called multiple times (some tests will do this to clear things, | 172 // May be called multiple times (some tests will do this to clear things, |
| 156 // and TearDown will do this to make sure eveything is shiny before quitting. | 173 // and TearDown will do this to make sure eveything is shiny before quitting. |
| 157 void ClearDB() { | 174 void ClearDB() { |
| 158 if (master_.get()) | 175 if (master_.get()) |
| 159 master_.reset(NULL); | 176 master_.reset(NULL); |
| 160 | 177 |
| 161 // Wait for all pending file I/O to be completed. | 178 // Wait for all pending file I/O to be completed. |
| 162 content::RunAllBlockingPoolTasksUntilIdle(); | 179 content::RunAllBlockingPoolTasksUntilIdle(); |
| 163 } | 180 } |
| 164 | 181 |
| 165 // Loads the database from disk and makes sure that the same URLs are present | 182 // Loads the database from disk and makes sure that the same URLs are present |
| 166 // as were generated by TestIO_Create(). This also checks the URLs with a | 183 // as were generated by TestIO_Create(). This also checks the URLs with a |
| 167 // slave to make sure it reads the data properly. | 184 // slave to make sure it reads the data properly. |
| 168 void Reload() { | 185 void Reload() { |
| 169 // Clean up after our caller, who may have left the database open. | 186 // Clean up after our caller, who may have left the database open. |
| 170 ClearDB(); | 187 ClearDB(); |
| 171 | 188 |
| 172 ASSERT_TRUE(InitVisited(0, true)); | 189 ASSERT_TRUE(InitVisited(0, true, true)); |
| 190 |
| 173 master_->DebugValidate(); | 191 master_->DebugValidate(); |
| 174 | 192 |
| 175 // check that the table has the proper number of entries | 193 // check that the table has the proper number of entries |
| 176 int used_count = master_->GetUsedCount(); | 194 int used_count = master_->GetUsedCount(); |
| 177 ASSERT_EQ(used_count, g_test_count); | 195 ASSERT_EQ(used_count, g_test_count); |
| 178 | 196 |
| 179 // Create a slave database. | 197 // Create a slave database. |
| 180 VisitedLinkSlave slave; | 198 VisitedLinkSlave slave; |
| 181 base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); | 199 base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); |
| 182 master_->shared_memory()->ShareToProcess( | 200 master_->shared_memory()->ShareToProcess( |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 base::FilePath visited_file_; | 242 base::FilePath visited_file_; |
| 225 | 243 |
| 226 scoped_ptr<VisitedLinkMaster> master_; | 244 scoped_ptr<VisitedLinkMaster> master_; |
| 227 TestVisitedLinkDelegate delegate_; | 245 TestVisitedLinkDelegate delegate_; |
| 228 content::TestBrowserThreadBundle thread_bundle_; | 246 content::TestBrowserThreadBundle thread_bundle_; |
| 229 }; | 247 }; |
| 230 | 248 |
| 231 // This test creates and reads some databases to make sure the data is | 249 // This test creates and reads some databases to make sure the data is |
| 232 // preserved throughout those operations. | 250 // preserved throughout those operations. |
| 233 TEST_F(VisitedLinkTest, DatabaseIO) { | 251 TEST_F(VisitedLinkTest, DatabaseIO) { |
| 234 ASSERT_TRUE(InitVisited(0, true)); | 252 ASSERT_TRUE(InitVisited(0, true, true)); |
| 235 | 253 |
| 236 for (int i = 0; i < g_test_count; i++) | 254 for (int i = 0; i < g_test_count; i++) |
| 237 master_->AddURL(TestURL(i)); | 255 master_->AddURL(TestURL(i)); |
| 238 | 256 |
| 239 // Test that the database was written properly | 257 // Test that the database was written properly |
| 240 Reload(); | 258 Reload(); |
| 241 } | 259 } |
| 242 | 260 |
| 243 // Checks that we can delete things properly when there are collisions. | 261 // Checks that we can delete things properly when there are collisions. |
| 244 TEST_F(VisitedLinkTest, Delete) { | 262 TEST_F(VisitedLinkTest, Delete) { |
| 245 static const int32 kInitialSize = 17; | 263 static const int32 kInitialSize = 17; |
| 246 ASSERT_TRUE(InitVisited(kInitialSize, true)); | 264 ASSERT_TRUE(InitVisited(kInitialSize, true, true)); |
| 247 | 265 |
| 248 // Add a cluster from 14-17 wrapping around to 0. These will all hash to the | 266 // Add a cluster from 14-17 wrapping around to 0. These will all hash to the |
| 249 // same value. | 267 // same value. |
| 250 const VisitedLinkCommon::Fingerprint kFingerprint0 = kInitialSize * 0 + 14; | 268 const VisitedLinkCommon::Fingerprint kFingerprint0 = kInitialSize * 0 + 14; |
| 251 const VisitedLinkCommon::Fingerprint kFingerprint1 = kInitialSize * 1 + 14; | 269 const VisitedLinkCommon::Fingerprint kFingerprint1 = kInitialSize * 1 + 14; |
| 252 const VisitedLinkCommon::Fingerprint kFingerprint2 = kInitialSize * 2 + 14; | 270 const VisitedLinkCommon::Fingerprint kFingerprint2 = kInitialSize * 2 + 14; |
| 253 const VisitedLinkCommon::Fingerprint kFingerprint3 = kInitialSize * 3 + 14; | 271 const VisitedLinkCommon::Fingerprint kFingerprint3 = kInitialSize * 3 + 14; |
| 254 const VisitedLinkCommon::Fingerprint kFingerprint4 = kInitialSize * 4 + 14; | 272 const VisitedLinkCommon::Fingerprint kFingerprint4 = kInitialSize * 4 + 14; |
| 255 master_->AddFingerprint(kFingerprint0, false); // @14 | 273 master_->AddFingerprint(kFingerprint0, false); // @14 |
| 256 master_->AddFingerprint(kFingerprint1, false); // @15 | 274 master_->AddFingerprint(kFingerprint1, false); // @15 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 274 | 292 |
| 275 EXPECT_EQ(0, master_->used_items_); | 293 EXPECT_EQ(0, master_->used_items_); |
| 276 for (int i = 0; i < kInitialSize; i++) | 294 for (int i = 0; i < kInitialSize; i++) |
| 277 EXPECT_EQ(zero_fingerprint, master_->hash_table_[i]) << | 295 EXPECT_EQ(zero_fingerprint, master_->hash_table_[i]) << |
| 278 "Hash table has values in it."; | 296 "Hash table has values in it."; |
| 279 } | 297 } |
| 280 | 298 |
| 281 // When we delete more than kBigDeleteThreshold we trigger different behavior | 299 // When we delete more than kBigDeleteThreshold we trigger different behavior |
| 282 // where the entire file is rewritten. | 300 // where the entire file is rewritten. |
| 283 TEST_F(VisitedLinkTest, BigDelete) { | 301 TEST_F(VisitedLinkTest, BigDelete) { |
| 284 ASSERT_TRUE(InitVisited(16381, true)); | 302 ASSERT_TRUE(InitVisited(16381, true, true)); |
| 285 | 303 |
| 286 // Add the base set of URLs that won't be deleted. | 304 // Add the base set of URLs that won't be deleted. |
| 287 // Reload() will test for these. | 305 // Reload() will test for these. |
| 288 for (int32 i = 0; i < g_test_count; i++) | 306 for (int32 i = 0; i < g_test_count; i++) |
| 289 master_->AddURL(TestURL(i)); | 307 master_->AddURL(TestURL(i)); |
| 290 | 308 |
| 291 // Add more URLs than necessary to trigger this case. | 309 // Add more URLs than necessary to trigger this case. |
| 292 const int kTestDeleteCount = VisitedLinkMaster::kBigDeleteThreshold + 2; | 310 const int kTestDeleteCount = VisitedLinkMaster::kBigDeleteThreshold + 2; |
| 293 URLs urls_to_delete; | 311 URLs urls_to_delete; |
| 294 for (int32 i = g_test_count; i < g_test_count + kTestDeleteCount; i++) { | 312 for (int32 i = g_test_count; i < g_test_count + kTestDeleteCount; i++) { |
| 295 GURL url(TestURL(i)); | 313 GURL url(TestURL(i)); |
| 296 master_->AddURL(url); | 314 master_->AddURL(url); |
| 297 urls_to_delete.push_back(url); | 315 urls_to_delete.push_back(url); |
| 298 } | 316 } |
| 299 | 317 |
| 300 TestURLIterator iterator(urls_to_delete); | 318 TestURLIterator iterator(urls_to_delete); |
| 301 master_->DeleteURLs(&iterator); | 319 master_->DeleteURLs(&iterator); |
| 302 master_->DebugValidate(); | 320 master_->DebugValidate(); |
| 303 | 321 |
| 304 Reload(); | 322 Reload(); |
| 305 } | 323 } |
| 306 | 324 |
| 307 TEST_F(VisitedLinkTest, DeleteAll) { | 325 TEST_F(VisitedLinkTest, DeleteAll) { |
| 308 ASSERT_TRUE(InitVisited(0, true)); | 326 ASSERT_TRUE(InitVisited(0, true, true)); |
| 309 | 327 |
| 310 { | 328 { |
| 311 VisitedLinkSlave slave; | 329 VisitedLinkSlave slave; |
| 312 base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); | 330 base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); |
| 313 master_->shared_memory()->ShareToProcess( | 331 master_->shared_memory()->ShareToProcess( |
| 314 base::GetCurrentProcessHandle(), &new_handle); | 332 base::GetCurrentProcessHandle(), &new_handle); |
| 315 slave.OnUpdateVisitedLinks(new_handle); | 333 slave.OnUpdateVisitedLinks(new_handle); |
| 316 g_slaves.push_back(&slave); | 334 g_slaves.push_back(&slave); |
| 317 | 335 |
| 318 // Add the test URLs. | 336 // Add the test URLs. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 333 EXPECT_FALSE(master_->IsVisited(TestURL(i))); | 351 EXPECT_FALSE(master_->IsVisited(TestURL(i))); |
| 334 EXPECT_FALSE(slave.IsVisited(TestURL(i))); | 352 EXPECT_FALSE(slave.IsVisited(TestURL(i))); |
| 335 } | 353 } |
| 336 | 354 |
| 337 // Close the database. | 355 // Close the database. |
| 338 g_slaves.clear(); | 356 g_slaves.clear(); |
| 339 ClearDB(); | 357 ClearDB(); |
| 340 } | 358 } |
| 341 | 359 |
| 342 // Reopen and validate. | 360 // Reopen and validate. |
| 343 ASSERT_TRUE(InitVisited(0, true)); | 361 ASSERT_TRUE(InitVisited(0, true, true)); |
| 344 master_->DebugValidate(); | 362 master_->DebugValidate(); |
| 345 EXPECT_EQ(0, master_->GetUsedCount()); | 363 EXPECT_EQ(0, master_->GetUsedCount()); |
| 346 for (int i = 0; i < g_test_count; i++) | 364 for (int i = 0; i < g_test_count; i++) |
| 347 EXPECT_FALSE(master_->IsVisited(TestURL(i))); | 365 EXPECT_FALSE(master_->IsVisited(TestURL(i))); |
| 348 } | 366 } |
| 349 | 367 |
| 350 // This tests that the master correctly resizes its tables when it gets too | 368 // This tests that the master correctly resizes its tables when it gets too |
| 351 // full, notifies its slaves of the change, and updates the disk. | 369 // full, notifies its slaves of the change, and updates the disk. |
| 352 TEST_F(VisitedLinkTest, Resizing) { | 370 TEST_F(VisitedLinkTest, Resizing) { |
| 353 // Create a very small database. | 371 // Create a very small database. |
| 354 const int32 initial_size = 17; | 372 const int32 initial_size = 17; |
| 355 ASSERT_TRUE(InitVisited(initial_size, true)); | 373 ASSERT_TRUE(InitVisited(initial_size, true, true)); |
| 356 | 374 |
| 357 // ...and a slave | 375 // ...and a slave |
| 358 VisitedLinkSlave slave; | 376 VisitedLinkSlave slave; |
| 359 base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); | 377 base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); |
| 360 master_->shared_memory()->ShareToProcess( | 378 master_->shared_memory()->ShareToProcess( |
| 361 base::GetCurrentProcessHandle(), &new_handle); | 379 base::GetCurrentProcessHandle(), &new_handle); |
| 362 slave.OnUpdateVisitedLinks(new_handle); | 380 slave.OnUpdateVisitedLinks(new_handle); |
| 363 g_slaves.push_back(&slave); | 381 g_slaves.push_back(&slave); |
| 364 | 382 |
| 365 int32 used_count = master_->GetUsedCount(); | 383 int32 used_count = master_->GetUsedCount(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 // Tests that if the database doesn't exist, it will be rebuilt from history. | 419 // Tests that if the database doesn't exist, it will be rebuilt from history. |
| 402 TEST_F(VisitedLinkTest, Rebuild) { | 420 TEST_F(VisitedLinkTest, Rebuild) { |
| 403 // Add half of our URLs to history. This needs to be done before we | 421 // Add half of our URLs to history. This needs to be done before we |
| 404 // initialize the visited link DB. | 422 // initialize the visited link DB. |
| 405 int history_count = g_test_count / 2; | 423 int history_count = g_test_count / 2; |
| 406 for (int i = 0; i < history_count; i++) | 424 for (int i = 0; i < history_count; i++) |
| 407 delegate_.AddURLForRebuild(TestURL(i)); | 425 delegate_.AddURLForRebuild(TestURL(i)); |
| 408 | 426 |
| 409 // Initialize the visited link DB. Since the visited links file doesn't exist | 427 // Initialize the visited link DB. Since the visited links file doesn't exist |
| 410 // and we don't suppress history rebuilding, this will load from history. | 428 // and we don't suppress history rebuilding, this will load from history. |
| 411 ASSERT_TRUE(InitVisited(0, false)); | 429 ASSERT_TRUE(InitVisited(0, false, false)); |
| 412 | 430 |
| 413 // While the table is rebuilding, add the rest of the URLs to the visited | 431 // While the table is rebuilding, add the rest of the URLs to the visited |
| 414 // link system. This isn't guaranteed to happen during the rebuild, so we | 432 // link system. This isn't guaranteed to happen during the rebuild, so we |
| 415 // can't be 100% sure we're testing the right thing, but in practice is. | 433 // can't be 100% sure we're testing the right thing, but in practice is. |
| 416 // All the adds above will generally take some time queuing up on the | 434 // All the adds above will generally take some time queuing up on the |
| 417 // history thread, and it will take a while to catch up to actually | 435 // history thread, and it will take a while to catch up to actually |
| 418 // processing the rebuild that has queued behind it. We will generally | 436 // processing the rebuild that has queued behind it. We will generally |
| 419 // finish adding all of the URLs before it has even found the first URL. | 437 // finish adding all of the URLs before it has even found the first URL. |
| 420 for (int i = history_count; i < g_test_count; i++) | 438 for (int i = history_count; i < g_test_count; i++) |
| 421 master_->AddURL(TestURL(i)); | 439 master_->AddURL(TestURL(i)); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 438 | 456 |
| 439 // Test that all URLs were written to the database properly. | 457 // Test that all URLs were written to the database properly. |
| 440 Reload(); | 458 Reload(); |
| 441 | 459 |
| 442 // Make sure the extra one was *not* written (Reload won't test this). | 460 // Make sure the extra one was *not* written (Reload won't test this). |
| 443 EXPECT_FALSE(master_->IsVisited(TestURL(g_test_count))); | 461 EXPECT_FALSE(master_->IsVisited(TestURL(g_test_count))); |
| 444 } | 462 } |
| 445 | 463 |
| 446 // Test that importing a large number of URLs will work | 464 // Test that importing a large number of URLs will work |
| 447 TEST_F(VisitedLinkTest, BigImport) { | 465 TEST_F(VisitedLinkTest, BigImport) { |
| 448 ASSERT_TRUE(InitVisited(0, false)); | 466 ASSERT_TRUE(InitVisited(0, false, false)); |
| 449 | 467 |
| 450 // Before the table rebuilds, add a large number of URLs | 468 // Before the table rebuilds, add a large number of URLs |
| 451 int total_count = VisitedLinkMaster::kDefaultTableSize + 10; | 469 int total_count = VisitedLinkMaster::kDefaultTableSize + 10; |
| 452 for (int i = 0; i < total_count; i++) | 470 for (int i = 0; i < total_count; i++) |
| 453 master_->AddURL(TestURL(i)); | 471 master_->AddURL(TestURL(i)); |
| 454 | 472 |
| 455 // Wait for the rebuild to complete. | 473 // Wait for the rebuild to complete. |
| 456 base::RunLoop run_loop; | 474 base::RunLoop run_loop; |
| 457 master_->set_rebuild_complete_task(run_loop.QuitClosure()); | 475 master_->set_rebuild_complete_task(run_loop.QuitClosure()); |
| 458 run_loop.Run(); | 476 run_loop.Run(); |
| 459 | 477 |
| 460 // Ensure that the right number of URLs are present | 478 // Ensure that the right number of URLs are present |
| 461 int used_count = master_->GetUsedCount(); | 479 int used_count = master_->GetUsedCount(); |
| 462 ASSERT_EQ(used_count, total_count); | 480 ASSERT_EQ(used_count, total_count); |
| 463 } | 481 } |
| 464 | 482 |
| 465 TEST_F(VisitedLinkTest, Listener) { | 483 TEST_F(VisitedLinkTest, Listener) { |
| 466 ASSERT_TRUE(InitVisited(0, true)); | 484 ASSERT_TRUE(InitVisited(0, true, true)); |
| 485 |
| 486 TrackingVisitedLinkEventListener* listener = |
| 487 static_cast<TrackingVisitedLinkEventListener*>(master_->GetListener()); |
| 488 |
| 489 // Verify that VisitedLinkMaster::Listener::Reset(true) was never called when |
| 490 // the table was created. |
| 491 EXPECT_EQ(0, listener->completely_reset_count()); |
| 467 | 492 |
| 468 // Add test URLs. | 493 // Add test URLs. |
| 469 for (int i = 0; i < g_test_count; i++) { | 494 for (int i = 0; i < g_test_count; i++) { |
| 470 master_->AddURL(TestURL(i)); | 495 master_->AddURL(TestURL(i)); |
| 471 ASSERT_EQ(i + 1, master_->GetUsedCount()); | 496 ASSERT_EQ(i + 1, master_->GetUsedCount()); |
| 472 } | 497 } |
| 473 | 498 |
| 474 // Delete an URL. | 499 // Delete an URL. |
| 475 URLs urls_to_delete; | 500 URLs urls_to_delete; |
| 476 urls_to_delete.push_back(TestURL(0)); | 501 urls_to_delete.push_back(TestURL(0)); |
| 477 TestURLIterator iterator(urls_to_delete); | 502 TestURLIterator iterator(urls_to_delete); |
| 478 master_->DeleteURLs(&iterator); | 503 master_->DeleteURLs(&iterator); |
| 479 | 504 |
| 480 // ... and all of the remaining ones. | 505 // ... and all of the remaining ones. |
| 481 master_->DeleteAllURLs(); | 506 master_->DeleteAllURLs(); |
| 482 | 507 |
| 483 TrackingVisitedLinkEventListener* listener = | |
| 484 static_cast<TrackingVisitedLinkEventListener*>(master_->GetListener()); | |
| 485 | |
| 486 // Verify that VisitedLinkMaster::Listener::Add was called for each added URL. | 508 // Verify that VisitedLinkMaster::Listener::Add was called for each added URL. |
| 487 EXPECT_EQ(g_test_count, listener->add_count()); | 509 EXPECT_EQ(g_test_count, listener->add_count()); |
| 488 // Verify that VisitedLinkMaster::Listener::Reset was called both when one and | 510 // Verify that VisitedLinkMaster::Listener::Reset was called both when one and |
| 489 // all URLs are deleted. | 511 // all URLs are deleted. |
| 490 EXPECT_EQ(2, listener->reset_count()); | 512 EXPECT_EQ(2, listener->reset_count()); |
| 513 |
| 514 ClearDB(); |
| 515 |
| 516 ASSERT_TRUE(InitVisited(0, true, true)); |
| 517 |
| 518 listener = |
| 519 static_cast<TrackingVisitedLinkEventListener*>(master_->GetListener()); |
| 520 // Verify that VisitedLinkMaster::Listener::Reset(true) was called when the |
| 521 // table was loaded. |
| 522 EXPECT_EQ(1, listener->completely_reset_count()); |
| 491 } | 523 } |
| 492 | 524 |
| 493 class VisitCountingContext : public content::TestBrowserContext { | 525 class VisitCountingContext : public content::TestBrowserContext { |
| 494 public: | 526 public: |
| 495 VisitCountingContext() | 527 VisitCountingContext() |
| 496 : add_count_(0), | 528 : add_count_(0), |
| 497 add_event_count_(0), | 529 add_event_count_(0), |
| 498 reset_event_count_(0), | 530 reset_event_count_(0), |
| 531 completely_reset_event_count_(0), |
| 499 new_table_count_(0) {} | 532 new_table_count_(0) {} |
| 500 | 533 |
| 501 void CountAddEvent(int by) { | 534 void CountAddEvent(int by) { |
| 502 add_count_ += by; | 535 add_count_ += by; |
| 503 add_event_count_++; | 536 add_event_count_++; |
| 504 } | 537 } |
| 505 | 538 |
| 506 void CountResetEvent() { | 539 void CountResetEvent() { |
| 507 reset_event_count_++; | 540 reset_event_count_++; |
| 508 } | 541 } |
| 509 | 542 |
| 543 void CountCompletelyResetEvent() { |
| 544 completely_reset_event_count_++; |
| 545 } |
| 546 |
| 510 void CountNewTable() { | 547 void CountNewTable() { |
| 511 new_table_count_++; | 548 new_table_count_++; |
| 512 } | 549 } |
| 513 | 550 |
| 514 int add_count() const { return add_count_; } | 551 int add_count() const { return add_count_; } |
| 515 int add_event_count() const { return add_event_count_; } | 552 int add_event_count() const { return add_event_count_; } |
| 516 int reset_event_count() const { return reset_event_count_; } | 553 int reset_event_count() const { return reset_event_count_; } |
| 554 int completely_reset_event_count() const { |
| 555 return completely_reset_event_count_; |
| 556 } |
| 517 int new_table_count() const { return new_table_count_; } | 557 int new_table_count() const { return new_table_count_; } |
| 518 | 558 |
| 519 private: | 559 private: |
| 520 int add_count_; | 560 int add_count_; |
| 521 int add_event_count_; | 561 int add_event_count_; |
| 522 int reset_event_count_; | 562 int reset_event_count_; |
| 563 int completely_reset_event_count_; |
| 523 int new_table_count_; | 564 int new_table_count_; |
| 524 }; | 565 }; |
| 525 | 566 |
| 526 // Stub out as little as possible, borrowing from RenderProcessHost. | 567 // Stub out as little as possible, borrowing from RenderProcessHost. |
| 527 class VisitRelayingRenderProcessHost : public MockRenderProcessHost { | 568 class VisitRelayingRenderProcessHost : public MockRenderProcessHost { |
| 528 public: | 569 public: |
| 529 explicit VisitRelayingRenderProcessHost( | 570 explicit VisitRelayingRenderProcessHost( |
| 530 content::BrowserContext* browser_context) | 571 content::BrowserContext* browser_context) |
| 531 : MockRenderProcessHost(browser_context), widgets_(0) { | 572 : MockRenderProcessHost(browser_context), widgets_(0) { |
| 532 content::NotificationService::current()->Notify( | 573 content::NotificationService::current()->Notify( |
| (...skipping 16 matching lines...) Expand all Loading... |
| 549 VisitCountingContext* counting_context = | 590 VisitCountingContext* counting_context = |
| 550 static_cast<VisitCountingContext*>( | 591 static_cast<VisitCountingContext*>( |
| 551 GetBrowserContext()); | 592 GetBrowserContext()); |
| 552 | 593 |
| 553 if (msg->type() == ChromeViewMsg_VisitedLink_Add::ID) { | 594 if (msg->type() == ChromeViewMsg_VisitedLink_Add::ID) { |
| 554 base::PickleIterator iter(*msg); | 595 base::PickleIterator iter(*msg); |
| 555 std::vector<uint64> fingerprints; | 596 std::vector<uint64> fingerprints; |
| 556 CHECK(IPC::ReadParam(msg, &iter, &fingerprints)); | 597 CHECK(IPC::ReadParam(msg, &iter, &fingerprints)); |
| 557 counting_context->CountAddEvent(fingerprints.size()); | 598 counting_context->CountAddEvent(fingerprints.size()); |
| 558 } else if (msg->type() == ChromeViewMsg_VisitedLink_Reset::ID) { | 599 } else if (msg->type() == ChromeViewMsg_VisitedLink_Reset::ID) { |
| 559 counting_context->CountResetEvent(); | 600 base::PickleIterator iter(*msg); |
| 601 bool invalidate_hashes; |
| 602 CHECK(IPC::ReadParam(msg, &iter, &invalidate_hashes)); |
| 603 if (invalidate_hashes) |
| 604 counting_context->CountCompletelyResetEvent(); |
| 605 else |
| 606 counting_context->CountResetEvent(); |
| 560 } else if (msg->type() == ChromeViewMsg_VisitedLink_NewTable::ID) { | 607 } else if (msg->type() == ChromeViewMsg_VisitedLink_NewTable::ID) { |
| 561 counting_context->CountNewTable(); | 608 counting_context->CountNewTable(); |
| 562 } | 609 } |
| 563 | 610 |
| 564 delete msg; | 611 delete msg; |
| 565 return true; | 612 return true; |
| 566 } | 613 } |
| 567 | 614 |
| 568 private: | 615 private: |
| 569 int widgets_; | 616 int widgets_; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 598 // of teardown because it posts a task to close a file handle, and | 645 // of teardown because it posts a task to close a file handle, and |
| 599 // we need to make sure we've finished all file related work | 646 // we need to make sure we've finished all file related work |
| 600 // before our superclass sets about destroying the scoped temp | 647 // before our superclass sets about destroying the scoped temp |
| 601 // directory. | 648 // directory. |
| 602 master_.reset(); | 649 master_.reset(); |
| 603 RenderViewHostTestHarness::TearDown(); | 650 RenderViewHostTestHarness::TearDown(); |
| 604 } | 651 } |
| 605 | 652 |
| 606 content::BrowserContext* CreateBrowserContext() override { | 653 content::BrowserContext* CreateBrowserContext() override { |
| 607 VisitCountingContext* context = new VisitCountingContext(); | 654 VisitCountingContext* context = new VisitCountingContext(); |
| 608 master_.reset(new VisitedLinkMaster(context, &delegate_, true)); | 655 CreateVisitedLinkMaster(context); |
| 609 master_->Init(); | |
| 610 return context; | 656 return context; |
| 611 } | 657 } |
| 612 | 658 |
| 613 VisitCountingContext* context() { | 659 VisitCountingContext* context() { |
| 614 return static_cast<VisitCountingContext*>(browser_context()); | 660 return static_cast<VisitCountingContext*>(browser_context()); |
| 615 } | 661 } |
| 616 | 662 |
| 617 VisitedLinkMaster* master() const { | 663 VisitedLinkMaster* master() const { |
| 618 return master_.get(); | 664 return master_.get(); |
| 619 } | 665 } |
| 620 | 666 |
| 621 void WaitForCoalescence() { | 667 void WaitForCoalescence() { |
| 622 // Let the timer fire. | 668 // Let the timer fire. |
| 623 // | 669 // |
| 624 // TODO(ajwong): This is horrid! What is the right synchronization method? | 670 // TODO(ajwong): This is horrid! What is the right synchronization method? |
| 625 base::RunLoop run_loop; | 671 base::RunLoop run_loop; |
| 626 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 672 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 627 FROM_HERE, run_loop.QuitClosure(), | 673 FROM_HERE, run_loop.QuitClosure(), |
| 628 base::TimeDelta::FromMilliseconds(110)); | 674 base::TimeDelta::FromMilliseconds(110)); |
| 629 run_loop.Run(); | 675 run_loop.Run(); |
| 630 } | 676 } |
| 631 | 677 |
| 632 protected: | 678 protected: |
| 679 void CreateVisitedLinkMaster(content::BrowserContext* browser_context) { |
| 680 master_.reset(new VisitedLinkMaster(browser_context, &delegate_, true)); |
| 681 master_->Init(); |
| 682 } |
| 683 |
| 633 VisitedLinkRenderProcessHostFactory vc_rph_factory_; | 684 VisitedLinkRenderProcessHostFactory vc_rph_factory_; |
| 634 | 685 |
| 635 private: | |
| 636 TestVisitedLinkDelegate delegate_; | 686 TestVisitedLinkDelegate delegate_; |
| 637 scoped_ptr<VisitedLinkMaster> master_; | 687 scoped_ptr<VisitedLinkMaster> master_; |
| 638 }; | 688 }; |
| 639 | 689 |
| 640 TEST_F(VisitedLinkEventsTest, Coalescence) { | 690 TEST_F(VisitedLinkEventsTest, Coalescence) { |
| 691 // Waiting complete rebuild the table. |
| 692 content::RunAllBlockingPoolTasksUntilIdle(); |
| 693 |
| 694 WaitForCoalescence(); |
| 695 |
| 696 // After rebuild table expect reset event. |
| 697 EXPECT_EQ(1, context()->reset_event_count()); |
| 698 |
| 641 // add some URLs to master. | 699 // add some URLs to master. |
| 642 // Add a few URLs. | 700 // Add a few URLs. |
| 643 master()->AddURL(GURL("http://acidtests.org/")); | 701 master()->AddURL(GURL("http://acidtests.org/")); |
| 644 master()->AddURL(GURL("http://google.com/")); | 702 master()->AddURL(GURL("http://google.com/")); |
| 645 master()->AddURL(GURL("http://chromium.org/")); | 703 master()->AddURL(GURL("http://chromium.org/")); |
| 646 // Just for kicks, add a duplicate URL. This shouldn't increase the resulting | 704 // Just for kicks, add a duplicate URL. This shouldn't increase the resulting |
| 647 master()->AddURL(GURL("http://acidtests.org/")); | 705 master()->AddURL(GURL("http://acidtests.org/")); |
| 648 | 706 |
| 649 // Make sure that coalescing actually occurs. There should be no links or | 707 // Make sure that coalescing actually occurs. There should be no links or |
| 650 // events received by the renderer. | 708 // events received by the renderer. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 679 | 737 |
| 680 // Ensure that the coalescing does not resume after resetting. | 738 // Ensure that the coalescing does not resume after resetting. |
| 681 master()->AddURL(GURL("http://build.chromium.org/")); | 739 master()->AddURL(GURL("http://build.chromium.org/")); |
| 682 master()->DeleteAllURLs(); | 740 master()->DeleteAllURLs(); |
| 683 | 741 |
| 684 WaitForCoalescence(); | 742 WaitForCoalescence(); |
| 685 | 743 |
| 686 // We should have no change in results except for one new reset event. | 744 // We should have no change in results except for one new reset event. |
| 687 EXPECT_EQ(6, context()->add_count()); | 745 EXPECT_EQ(6, context()->add_count()); |
| 688 EXPECT_EQ(2, context()->add_event_count()); | 746 EXPECT_EQ(2, context()->add_event_count()); |
| 689 EXPECT_EQ(1, context()->reset_event_count()); | 747 EXPECT_EQ(2, context()->reset_event_count()); |
| 690 } | 748 } |
| 691 | 749 |
| 692 TEST_F(VisitedLinkEventsTest, Basics) { | 750 TEST_F(VisitedLinkEventsTest, Basics) { |
| 693 RenderViewHostTester::For(rvh())->CreateTestRenderView( | 751 RenderViewHostTester::For(rvh())->CreateTestRenderView( |
| 694 base::string16(), MSG_ROUTING_NONE, MSG_ROUTING_NONE, -1, false); | 752 base::string16(), MSG_ROUTING_NONE, MSG_ROUTING_NONE, -1, false); |
| 695 | 753 |
| 754 // Waiting complete rebuild the table. |
| 755 content::RunAllBlockingPoolTasksUntilIdle(); |
| 756 |
| 757 WaitForCoalescence(); |
| 758 |
| 759 // After rebuild table expect reset event. |
| 760 EXPECT_EQ(1, context()->reset_event_count()); |
| 761 |
| 696 // Add a few URLs. | 762 // Add a few URLs. |
| 697 master()->AddURL(GURL("http://acidtests.org/")); | 763 master()->AddURL(GURL("http://acidtests.org/")); |
| 698 master()->AddURL(GURL("http://google.com/")); | 764 master()->AddURL(GURL("http://google.com/")); |
| 699 master()->AddURL(GURL("http://chromium.org/")); | 765 master()->AddURL(GURL("http://chromium.org/")); |
| 700 | 766 |
| 701 WaitForCoalescence(); | 767 WaitForCoalescence(); |
| 702 | 768 |
| 703 // We now should have 1 add event. | 769 // We now should have 1 add event. |
| 704 EXPECT_EQ(1, context()->add_event_count()); | 770 EXPECT_EQ(1, context()->add_event_count()); |
| 705 EXPECT_EQ(0, context()->reset_event_count()); | 771 EXPECT_EQ(1, context()->reset_event_count()); |
| 706 | 772 |
| 707 master()->DeleteAllURLs(); | 773 master()->DeleteAllURLs(); |
| 708 | 774 |
| 709 WaitForCoalescence(); | 775 WaitForCoalescence(); |
| 710 | 776 |
| 711 // We should have no change in add results, plus one new reset event. | 777 // We should have no change in add results, plus one new reset event. |
| 712 EXPECT_EQ(1, context()->add_event_count()); | 778 EXPECT_EQ(1, context()->add_event_count()); |
| 713 EXPECT_EQ(1, context()->reset_event_count()); | 779 EXPECT_EQ(2, context()->reset_event_count()); |
| 714 } | 780 } |
| 715 | 781 |
| 716 TEST_F(VisitedLinkEventsTest, TabVisibility) { | 782 TEST_F(VisitedLinkEventsTest, TabVisibility) { |
| 717 RenderViewHostTester::For(rvh())->CreateTestRenderView( | 783 RenderViewHostTester::For(rvh())->CreateTestRenderView( |
| 718 base::string16(), MSG_ROUTING_NONE, MSG_ROUTING_NONE, -1, false); | 784 base::string16(), MSG_ROUTING_NONE, MSG_ROUTING_NONE, -1, false); |
| 719 | 785 |
| 786 // Waiting complete rebuild the table. |
| 787 content::RunAllBlockingPoolTasksUntilIdle(); |
| 788 |
| 789 WaitForCoalescence(); |
| 790 |
| 791 // After rebuild table expect reset event. |
| 792 EXPECT_EQ(1, context()->reset_event_count()); |
| 793 |
| 720 // Simulate tab becoming inactive. | 794 // Simulate tab becoming inactive. |
| 721 RenderViewHostTester::For(rvh())->SimulateWasHidden(); | 795 RenderViewHostTester::For(rvh())->SimulateWasHidden(); |
| 722 | 796 |
| 723 // Add a few URLs. | 797 // Add a few URLs. |
| 724 master()->AddURL(GURL("http://acidtests.org/")); | 798 master()->AddURL(GURL("http://acidtests.org/")); |
| 725 master()->AddURL(GURL("http://google.com/")); | 799 master()->AddURL(GURL("http://google.com/")); |
| 726 master()->AddURL(GURL("http://chromium.org/")); | 800 master()->AddURL(GURL("http://chromium.org/")); |
| 727 | 801 |
| 728 WaitForCoalescence(); | 802 WaitForCoalescence(); |
| 729 | 803 |
| 730 // We shouldn't have any events. | 804 // We shouldn't have any events. |
| 731 EXPECT_EQ(0, context()->add_event_count()); | 805 EXPECT_EQ(0, context()->add_event_count()); |
| 732 EXPECT_EQ(0, context()->reset_event_count()); | 806 EXPECT_EQ(1, context()->reset_event_count()); |
| 733 | 807 |
| 734 // Simulate the tab becoming active. | 808 // Simulate the tab becoming active. |
| 735 RenderViewHostTester::For(rvh())->SimulateWasShown(); | 809 RenderViewHostTester::For(rvh())->SimulateWasShown(); |
| 736 | 810 |
| 737 // We should now have 3 add events, still no reset events. | 811 // We should now have 3 add events, still no reset events. |
| 738 EXPECT_EQ(1, context()->add_event_count()); | 812 EXPECT_EQ(1, context()->add_event_count()); |
| 739 EXPECT_EQ(0, context()->reset_event_count()); | 813 EXPECT_EQ(1, context()->reset_event_count()); |
| 740 | 814 |
| 741 // Deactivate the tab again. | 815 // Deactivate the tab again. |
| 742 RenderViewHostTester::For(rvh())->SimulateWasHidden(); | 816 RenderViewHostTester::For(rvh())->SimulateWasHidden(); |
| 743 | 817 |
| 744 // Add a bunch of URLs (over 50) to exhaust the link event buffer. | 818 // Add a bunch of URLs (over 50) to exhaust the link event buffer. |
| 745 for (int i = 0; i < 100; i++) | 819 for (int i = 0; i < 100; i++) |
| 746 master()->AddURL(TestURL(i)); | 820 master()->AddURL(TestURL(i)); |
| 747 | 821 |
| 748 WaitForCoalescence(); | 822 WaitForCoalescence(); |
| 749 | 823 |
| 750 // Again, no change in events until tab is active. | 824 // Again, no change in events until tab is active. |
| 751 EXPECT_EQ(1, context()->add_event_count()); | 825 EXPECT_EQ(1, context()->add_event_count()); |
| 752 EXPECT_EQ(0, context()->reset_event_count()); | 826 EXPECT_EQ(1, context()->reset_event_count()); |
| 753 | 827 |
| 754 // Activate the tab. | 828 // Activate the tab. |
| 755 RenderViewHostTester::For(rvh())->SimulateWasShown(); | 829 RenderViewHostTester::For(rvh())->SimulateWasShown(); |
| 756 | 830 |
| 757 // We should have only one more reset event. | 831 // We should have only one more reset event. |
| 758 EXPECT_EQ(1, context()->add_event_count()); | 832 EXPECT_EQ(1, context()->add_event_count()); |
| 759 EXPECT_EQ(1, context()->reset_event_count()); | 833 EXPECT_EQ(2, context()->reset_event_count()); |
| 760 } | 834 } |
| 761 | 835 |
| 762 // Tests that VisitedLink ignores renderer process creation notification for a | 836 // Tests that VisitedLink ignores renderer process creation notification for a |
| 763 // different context. | 837 // different context. |
| 764 TEST_F(VisitedLinkEventsTest, IgnoreRendererCreationFromDifferentContext) { | 838 TEST_F(VisitedLinkEventsTest, IgnoreRendererCreationFromDifferentContext) { |
| 765 VisitCountingContext different_context; | 839 VisitCountingContext different_context; |
| 766 VisitRelayingRenderProcessHost different_process_host(&different_context); | 840 VisitRelayingRenderProcessHost different_process_host(&different_context); |
| 767 | 841 |
| 768 content::NotificationService::current()->Notify( | 842 content::NotificationService::current()->Notify( |
| 769 content::NOTIFICATION_RENDERER_PROCESS_CREATED, | 843 content::NOTIFICATION_RENDERER_PROCESS_CREATED, |
| 770 content::Source<content::RenderProcessHost>(&different_process_host), | 844 content::Source<content::RenderProcessHost>(&different_process_host), |
| 771 content::NotificationService::NoDetails()); | 845 content::NotificationService::NoDetails()); |
| 772 WaitForCoalescence(); | 846 WaitForCoalescence(); |
| 773 | 847 |
| 774 EXPECT_EQ(0, different_context.new_table_count()); | 848 EXPECT_EQ(0, different_context.new_table_count()); |
| 775 } | 849 } |
| 776 | 850 |
| 851 class VisitedLinkCompletelyResetEventTest : public VisitedLinkEventsTest { |
| 852 public: |
| 853 content::BrowserContext* CreateBrowserContext() override { |
| 854 VisitCountingContext* context = new VisitCountingContext(); |
| 855 CreateVisitedLinkFile(context); |
| 856 CreateVisitedLinkMaster(context); |
| 857 return context; |
| 858 } |
| 859 |
| 860 void CreateVisitedLinkFile(content::BrowserContext* browser_context) { |
| 861 base::FilePath visited_file = |
| 862 browser_context->GetPath().Append(FILE_PATH_LITERAL("Visited Links")); |
| 863 scoped_ptr<VisitedLinkMaster> master( |
| 864 new VisitedLinkMaster(new TrackingVisitedLinkEventListener(), |
| 865 &delegate_, true, true, visited_file, 0)); |
| 866 master->Init(); |
| 867 // Waiting complete create the table. |
| 868 content::RunAllBlockingPoolTasksUntilIdle(); |
| 869 |
| 870 master.reset(); |
| 871 // Wait for all pending file I/O to be completed. |
| 872 content::RunAllBlockingPoolTasksUntilIdle(); |
| 873 } |
| 874 }; |
| 875 |
| 876 TEST_F(VisitedLinkCompletelyResetEventTest, LoadTable) { |
| 877 // Waiting complete loading the table. |
| 878 content::RunAllBlockingPoolTasksUntilIdle(); |
| 879 |
| 880 WaitForCoalescence(); |
| 881 |
| 882 // After load table expect completely reset event. |
| 883 EXPECT_EQ(1, context()->completely_reset_event_count()); |
| 884 } |
| 885 |
| 777 } // namespace visitedlink | 886 } // namespace visitedlink |
| OLD | NEW |