| 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/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| 11 #include "base/path_service.h" | 11 #include "base/path_service.h" |
| 12 #include "base/process_util.h" | 12 #include "base/process_util.h" |
| 13 #include "base/shared_memory.h" | 13 #include "base/shared_memory.h" |
| 14 #include "base/string_util.h" | 14 #include "base/string_util.h" |
| 15 #include "base/time.h" | 15 #include "base/time.h" |
| 16 #include "chrome/browser/visitedlink/visitedlink_delegate.h" |
| 16 #include "chrome/browser/visitedlink/visitedlink_event_listener.h" | 17 #include "chrome/browser/visitedlink/visitedlink_event_listener.h" |
| 17 #include "chrome/browser/visitedlink/visitedlink_master.h" | 18 #include "chrome/browser/visitedlink/visitedlink_master.h" |
| 18 #include "chrome/browser/visitedlink/visitedlink_master_factory.h" | |
| 19 #include "chrome/common/render_messages.h" | 19 #include "chrome/common/render_messages.h" |
| 20 #include "chrome/renderer/visitedlink_slave.h" | 20 #include "chrome/renderer/visitedlink_slave.h" |
| 21 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 21 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
| 22 #include "chrome/test/base/testing_profile.h" | 22 #include "chrome/test/base/testing_profile.h" |
| 23 #include "content/public/browser/notification_service.h" | 23 #include "content/public/browser/notification_service.h" |
| 24 #include "content/public/browser/notification_types.h" | 24 #include "content/public/browser/notification_types.h" |
| 25 #include "content/public/test/mock_render_process_host.h" | 25 #include "content/public/test/mock_render_process_host.h" |
| 26 #include "content/public/test/test_browser_context.h" |
| 26 #include "content/public/test/test_browser_thread.h" | 27 #include "content/public/test/test_browser_thread.h" |
| 27 #include "content/public/test/test_renderer_host.h" | 28 #include "content/public/test/test_renderer_host.h" |
| 28 #include "googleurl/src/gurl.h" | 29 #include "googleurl/src/gurl.h" |
| 29 #include "testing/gtest/include/gtest/gtest.h" | 30 #include "testing/gtest/include/gtest/gtest.h" |
| 30 | 31 |
| 31 using content::BrowserThread; | 32 using content::BrowserThread; |
| 32 using content::MockRenderProcessHost; | 33 using content::MockRenderProcessHost; |
| 33 using content::RenderViewHostTester; | 34 using content::RenderViewHostTester; |
| 34 | 35 |
| 35 namespace { | 36 namespace { |
| 36 | 37 |
| 38 typedef std::vector<GURL> URLs; |
| 39 |
| 37 // a nice long URL that we can append numbers to to get new URLs | 40 // a nice long URL that we can append numbers to to get new URLs |
| 38 const char g_test_prefix[] = | 41 const char g_test_prefix[] = |
| 39 "http://www.google.com/products/foo/index.html?id=45028640526508376&seq="; | 42 "http://www.google.com/products/foo/index.html?id=45028640526508376&seq="; |
| 40 const int g_test_count = 1000; | 43 const int g_test_count = 1000; |
| 41 | 44 |
| 42 // Returns a test URL for index |i| | 45 // Returns a test URL for index |i| |
| 43 GURL TestURL(int i) { | 46 GURL TestURL(int i) { |
| 44 return GURL(StringPrintf("%s%d", g_test_prefix, i)); | 47 return GURL(StringPrintf("%s%d", g_test_prefix, i)); |
| 45 } | 48 } |
| 46 | 49 |
| 47 ProfileKeyedService* BuildVisitedLinkMaster(Profile* profile) { | |
| 48 VisitedLinkMaster* master = new VisitedLinkMaster(profile); | |
| 49 master->Init(); | |
| 50 return master; | |
| 51 } | |
| 52 | |
| 53 std::vector<VisitedLinkSlave*> g_slaves; | 50 std::vector<VisitedLinkSlave*> g_slaves; |
| 54 | 51 |
| 52 // ========================== TestVisitedLinkDelegate ========================== |
| 53 class TestVisitedLinkDelegate : public VisitedLinkDelegate { |
| 54 public: |
| 55 virtual bool AreEquivalentContexts( |
| 56 content::BrowserContext* context1, |
| 57 content::BrowserContext* context2) OVERRIDE; |
| 58 virtual void RebuildTable(URLEnumerator* enumerator) OVERRIDE; |
| 59 |
| 60 void AddURLForRebuild(const GURL& url); |
| 61 |
| 62 private: |
| 63 |
| 64 URLs rebuild_urls_; |
| 65 }; |
| 66 |
| 67 bool TestVisitedLinkDelegate::AreEquivalentContexts( |
| 68 content::BrowserContext* context1, content::BrowserContext* context2) { |
| 69 DCHECK_EQ(context1, context2); |
| 70 return true; // Test only has one profile. |
| 71 } |
| 72 |
| 73 void TestVisitedLinkDelegate::RebuildTable(URLEnumerator* enumerator) { |
| 74 for (URLs::const_iterator itr = rebuild_urls_.begin(); |
| 75 itr != rebuild_urls_.end(); |
| 76 ++itr) |
| 77 enumerator->OnURL(*itr); |
| 78 enumerator->OnComplete(true); |
| 79 } |
| 80 |
| 81 void TestVisitedLinkDelegate::AddURLForRebuild(const GURL& url) { |
| 82 rebuild_urls_.push_back(url); |
| 83 } |
| 84 // ======================== TestVisitedLinkDelegate End ======================== |
| 85 |
| 86 // ============================== TestURLIterator ============================== |
| 87 class TestURLIterator : public VisitedLinkMaster::URLIterator { |
| 88 public: |
| 89 explicit TestURLIterator(const URLs& urls); |
| 90 |
| 91 virtual const GURL NextURL() OVERRIDE; |
| 92 virtual bool HasNextURL() const OVERRIDE; |
| 93 |
| 94 private: |
| 95 URLs::const_iterator iterator_; |
| 96 URLs::const_iterator end_; |
| 97 }; |
| 98 |
| 99 TestURLIterator::TestURLIterator(const URLs& urls) |
| 100 : iterator_(urls.begin()), |
| 101 end_(urls.end()) { |
| 102 } |
| 103 |
| 104 const GURL TestURLIterator::NextURL() { |
| 105 return *(iterator_++); |
| 106 } |
| 107 |
| 108 bool TestURLIterator::HasNextURL() const { |
| 109 return iterator_ != end_; |
| 110 } |
| 111 // ============================ TestURLIterator End ============================ |
| 112 |
| 55 } // namespace | 113 } // namespace |
| 56 | 114 |
| 57 class TrackingVisitedLinkEventListener : public VisitedLinkMaster::Listener { | 115 class TrackingVisitedLinkEventListener : public VisitedLinkMaster::Listener { |
| 58 public: | 116 public: |
| 59 TrackingVisitedLinkEventListener() | 117 TrackingVisitedLinkEventListener() |
| 60 : reset_count_(0), | 118 : reset_count_(0), |
| 61 add_count_(0) {} | 119 add_count_(0) {} |
| 62 | 120 |
| 63 virtual void NewTable(base::SharedMemory* table) { | 121 virtual void NewTable(base::SharedMemory* table) { |
| 64 if (table) { | 122 if (table) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 84 private: | 142 private: |
| 85 int reset_count_; | 143 int reset_count_; |
| 86 int add_count_; | 144 int add_count_; |
| 87 }; | 145 }; |
| 88 | 146 |
| 89 class VisitedLinkTest : public testing::Test { | 147 class VisitedLinkTest : public testing::Test { |
| 90 protected: | 148 protected: |
| 91 VisitedLinkTest() | 149 VisitedLinkTest() |
| 92 : ui_thread_(BrowserThread::UI, &message_loop_), | 150 : ui_thread_(BrowserThread::UI, &message_loop_), |
| 93 file_thread_(BrowserThread::FILE, &message_loop_) {} | 151 file_thread_(BrowserThread::FILE, &message_loop_) {} |
| 94 // Initialize the history system. This should be called before InitVisited(). | |
| 95 bool InitHistory() { | |
| 96 history_service_.reset(new HistoryService); | |
| 97 return history_service_->Init(history_dir_, NULL); | |
| 98 } | |
| 99 | |
| 100 // Initializes the visited link objects. Pass in the size that you want a | 152 // Initializes the visited link objects. Pass in the size that you want a |
| 101 // freshly created table to be. 0 means use the default. | 153 // freshly created table to be. 0 means use the default. |
| 102 // | 154 // |
| 103 // |suppress_rebuild| is set when we're not testing rebuilding, see | 155 // |suppress_rebuild| is set when we're not testing rebuilding, see |
| 104 // the VisitedLinkMaster constructor. | 156 // the VisitedLinkMaster constructor. |
| 105 bool InitVisited(int initial_size, bool suppress_rebuild) { | 157 bool InitVisited(int initial_size, bool suppress_rebuild) { |
| 106 // Initialize the visited link system. | 158 // Initialize the visited link system. |
| 107 master_.reset(new VisitedLinkMaster(new TrackingVisitedLinkEventListener(), | 159 master_.reset(new VisitedLinkMaster(new TrackingVisitedLinkEventListener(), |
| 108 history_service_.get(), | 160 &delegate_, |
| 109 suppress_rebuild, visited_file_, | 161 suppress_rebuild, visited_file_, |
| 110 initial_size)); | 162 initial_size)); |
| 111 return master_->Init(); | 163 return master_->Init(); |
| 112 } | 164 } |
| 113 | 165 |
| 114 // May be called multiple times (some tests will do this to clear things, | 166 // May be called multiple times (some tests will do this to clear things, |
| 115 // and TearDown will do this to make sure eveything is shiny before quitting. | 167 // and TearDown will do this to make sure eveything is shiny before quitting. |
| 116 void ClearDB() { | 168 void ClearDB() { |
| 117 if (master_.get()) | 169 if (master_.get()) |
| 118 master_.reset(NULL); | 170 master_.reset(NULL); |
| 119 | 171 |
| 120 if (history_service_.get()) { | |
| 121 history_service_->SetOnBackendDestroyTask(MessageLoop::QuitClosure()); | |
| 122 history_service_->Cleanup(); | |
| 123 history_service_.reset(); | |
| 124 | |
| 125 // Wait for the backend class to terminate before deleting the files and | |
| 126 // moving to the next test. Note: if this never terminates, somebody is | |
| 127 // probably leaking a reference to the history backend, so it never calls | |
| 128 // our destroy task. | |
| 129 MessageLoop::current()->Run(); | |
| 130 } | |
| 131 | |
| 132 // Wait for all pending file I/O to be completed. | 172 // Wait for all pending file I/O to be completed. |
| 133 BrowserThread::GetBlockingPool()->FlushForTesting(); | 173 BrowserThread::GetBlockingPool()->FlushForTesting(); |
| 134 } | 174 } |
| 135 | 175 |
| 136 // Loads the database from disk and makes sure that the same URLs are present | 176 // Loads the database from disk and makes sure that the same URLs are present |
| 137 // as were generated by TestIO_Create(). This also checks the URLs with a | 177 // as were generated by TestIO_Create(). This also checks the URLs with a |
| 138 // slave to make sure it reads the data properly. | 178 // slave to make sure it reads the data properly. |
| 139 void Reload() { | 179 void Reload() { |
| 140 // Clean up after our caller, who may have left the database open. | 180 // Clean up after our caller, who may have left the database open. |
| 141 ClearDB(); | 181 ClearDB(); |
| 142 | 182 |
| 143 ASSERT_TRUE(InitHistory()); | |
| 144 ASSERT_TRUE(InitVisited(0, true)); | 183 ASSERT_TRUE(InitVisited(0, true)); |
| 145 master_->DebugValidate(); | 184 master_->DebugValidate(); |
| 146 | 185 |
| 147 // check that the table has the proper number of entries | 186 // check that the table has the proper number of entries |
| 148 int used_count = master_->GetUsedCount(); | 187 int used_count = master_->GetUsedCount(); |
| 149 ASSERT_EQ(used_count, g_test_count); | 188 ASSERT_EQ(used_count, g_test_count); |
| 150 | 189 |
| 151 // Create a slave database. | 190 // Create a slave database. |
| 152 VisitedLinkSlave slave; | 191 VisitedLinkSlave slave; |
| 153 base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); | 192 base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 | 234 |
| 196 MessageLoop message_loop_; | 235 MessageLoop message_loop_; |
| 197 content::TestBrowserThread ui_thread_; | 236 content::TestBrowserThread ui_thread_; |
| 198 content::TestBrowserThread file_thread_; | 237 content::TestBrowserThread file_thread_; |
| 199 | 238 |
| 200 // Filenames for the services; | 239 // Filenames for the services; |
| 201 FilePath history_dir_; | 240 FilePath history_dir_; |
| 202 FilePath visited_file_; | 241 FilePath visited_file_; |
| 203 | 242 |
| 204 scoped_ptr<VisitedLinkMaster> master_; | 243 scoped_ptr<VisitedLinkMaster> master_; |
| 205 scoped_ptr<HistoryService> history_service_; | 244 TestVisitedLinkDelegate delegate_; |
| 206 }; | 245 }; |
| 207 | 246 |
| 208 // This test creates and reads some databases to make sure the data is | 247 // This test creates and reads some databases to make sure the data is |
| 209 // preserved throughout those operations. | 248 // preserved throughout those operations. |
| 210 TEST_F(VisitedLinkTest, DatabaseIO) { | 249 TEST_F(VisitedLinkTest, DatabaseIO) { |
| 211 ASSERT_TRUE(InitHistory()); | |
| 212 ASSERT_TRUE(InitVisited(0, true)); | 250 ASSERT_TRUE(InitVisited(0, true)); |
| 213 | 251 |
| 214 for (int i = 0; i < g_test_count; i++) | 252 for (int i = 0; i < g_test_count; i++) |
| 215 master_->AddURL(TestURL(i)); | 253 master_->AddURL(TestURL(i)); |
| 216 | 254 |
| 217 // Test that the database was written properly | 255 // Test that the database was written properly |
| 218 Reload(); | 256 Reload(); |
| 219 } | 257 } |
| 220 | 258 |
| 221 // Checks that we can delete things properly when there are collisions. | 259 // Checks that we can delete things properly when there are collisions. |
| 222 TEST_F(VisitedLinkTest, Delete) { | 260 TEST_F(VisitedLinkTest, Delete) { |
| 223 static const int32 kInitialSize = 17; | 261 static const int32 kInitialSize = 17; |
| 224 ASSERT_TRUE(InitHistory()); | |
| 225 ASSERT_TRUE(InitVisited(kInitialSize, true)); | 262 ASSERT_TRUE(InitVisited(kInitialSize, true)); |
| 226 | 263 |
| 227 // Add a cluster from 14-17 wrapping around to 0. These will all hash to the | 264 // Add a cluster from 14-17 wrapping around to 0. These will all hash to the |
| 228 // same value. | 265 // same value. |
| 229 const VisitedLinkCommon::Fingerprint kFingerprint0 = kInitialSize * 0 + 14; | 266 const VisitedLinkCommon::Fingerprint kFingerprint0 = kInitialSize * 0 + 14; |
| 230 const VisitedLinkCommon::Fingerprint kFingerprint1 = kInitialSize * 1 + 14; | 267 const VisitedLinkCommon::Fingerprint kFingerprint1 = kInitialSize * 1 + 14; |
| 231 const VisitedLinkCommon::Fingerprint kFingerprint2 = kInitialSize * 2 + 14; | 268 const VisitedLinkCommon::Fingerprint kFingerprint2 = kInitialSize * 2 + 14; |
| 232 const VisitedLinkCommon::Fingerprint kFingerprint3 = kInitialSize * 3 + 14; | 269 const VisitedLinkCommon::Fingerprint kFingerprint3 = kInitialSize * 3 + 14; |
| 233 const VisitedLinkCommon::Fingerprint kFingerprint4 = kInitialSize * 4 + 14; | 270 const VisitedLinkCommon::Fingerprint kFingerprint4 = kInitialSize * 4 + 14; |
| 234 master_->AddFingerprint(kFingerprint0, false); // @14 | 271 master_->AddFingerprint(kFingerprint0, false); // @14 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 253 | 290 |
| 254 EXPECT_EQ(0, master_->used_items_); | 291 EXPECT_EQ(0, master_->used_items_); |
| 255 for (int i = 0; i < kInitialSize; i++) | 292 for (int i = 0; i < kInitialSize; i++) |
| 256 EXPECT_EQ(zero_fingerprint, master_->hash_table_[i]) << | 293 EXPECT_EQ(zero_fingerprint, master_->hash_table_[i]) << |
| 257 "Hash table has values in it."; | 294 "Hash table has values in it."; |
| 258 } | 295 } |
| 259 | 296 |
| 260 // When we delete more than kBigDeleteThreshold we trigger different behavior | 297 // When we delete more than kBigDeleteThreshold we trigger different behavior |
| 261 // where the entire file is rewritten. | 298 // where the entire file is rewritten. |
| 262 TEST_F(VisitedLinkTest, BigDelete) { | 299 TEST_F(VisitedLinkTest, BigDelete) { |
| 263 ASSERT_TRUE(InitHistory()); | |
| 264 ASSERT_TRUE(InitVisited(16381, true)); | 300 ASSERT_TRUE(InitVisited(16381, true)); |
| 265 | 301 |
| 266 // Add the base set of URLs that won't be deleted. | 302 // Add the base set of URLs that won't be deleted. |
| 267 // Reload() will test for these. | 303 // Reload() will test for these. |
| 268 for (int32 i = 0; i < g_test_count; i++) | 304 for (int32 i = 0; i < g_test_count; i++) |
| 269 master_->AddURL(TestURL(i)); | 305 master_->AddURL(TestURL(i)); |
| 270 | 306 |
| 271 // Add more URLs than necessary to trigger this case. | 307 // Add more URLs than necessary to trigger this case. |
| 272 const int kTestDeleteCount = VisitedLinkMaster::kBigDeleteThreshold + 2; | 308 const int kTestDeleteCount = VisitedLinkMaster::kBigDeleteThreshold + 2; |
| 273 history::URLRows urls_to_delete; | 309 URLs urls_to_delete; |
| 274 for (int32 i = g_test_count; i < g_test_count + kTestDeleteCount; i++) { | 310 for (int32 i = g_test_count; i < g_test_count + kTestDeleteCount; i++) { |
| 275 GURL url(TestURL(i)); | 311 GURL url(TestURL(i)); |
| 276 master_->AddURL(url); | 312 master_->AddURL(url); |
| 277 urls_to_delete.push_back(history::URLRow(url)); | 313 urls_to_delete.push_back(url); |
| 278 } | 314 } |
| 279 | 315 |
| 280 master_->DeleteURLs(urls_to_delete); | 316 TestURLIterator iterator(urls_to_delete); |
| 317 master_->DeleteURLs(&iterator); |
| 281 master_->DebugValidate(); | 318 master_->DebugValidate(); |
| 282 | 319 |
| 283 Reload(); | 320 Reload(); |
| 284 } | 321 } |
| 285 | 322 |
| 286 TEST_F(VisitedLinkTest, DeleteAll) { | 323 TEST_F(VisitedLinkTest, DeleteAll) { |
| 287 ASSERT_TRUE(InitHistory()); | |
| 288 ASSERT_TRUE(InitVisited(0, true)); | 324 ASSERT_TRUE(InitVisited(0, true)); |
| 289 | 325 |
| 290 { | 326 { |
| 291 VisitedLinkSlave slave; | 327 VisitedLinkSlave slave; |
| 292 base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); | 328 base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); |
| 293 master_->shared_memory()->ShareToProcess( | 329 master_->shared_memory()->ShareToProcess( |
| 294 base::GetCurrentProcessHandle(), &new_handle); | 330 base::GetCurrentProcessHandle(), &new_handle); |
| 295 slave.OnUpdateVisitedLinks(new_handle); | 331 slave.OnUpdateVisitedLinks(new_handle); |
| 296 g_slaves.push_back(&slave); | 332 g_slaves.push_back(&slave); |
| 297 | 333 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 313 EXPECT_FALSE(master_->IsVisited(TestURL(i))); | 349 EXPECT_FALSE(master_->IsVisited(TestURL(i))); |
| 314 EXPECT_FALSE(slave.IsVisited(TestURL(i))); | 350 EXPECT_FALSE(slave.IsVisited(TestURL(i))); |
| 315 } | 351 } |
| 316 | 352 |
| 317 // Close the database. | 353 // Close the database. |
| 318 g_slaves.clear(); | 354 g_slaves.clear(); |
| 319 ClearDB(); | 355 ClearDB(); |
| 320 } | 356 } |
| 321 | 357 |
| 322 // Reopen and validate. | 358 // Reopen and validate. |
| 323 ASSERT_TRUE(InitHistory()); | |
| 324 ASSERT_TRUE(InitVisited(0, true)); | 359 ASSERT_TRUE(InitVisited(0, true)); |
| 325 master_->DebugValidate(); | 360 master_->DebugValidate(); |
| 326 EXPECT_EQ(0, master_->GetUsedCount()); | 361 EXPECT_EQ(0, master_->GetUsedCount()); |
| 327 for (int i = 0; i < g_test_count; i++) | 362 for (int i = 0; i < g_test_count; i++) |
| 328 EXPECT_FALSE(master_->IsVisited(TestURL(i))); | 363 EXPECT_FALSE(master_->IsVisited(TestURL(i))); |
| 329 } | 364 } |
| 330 | 365 |
| 331 // This tests that the master correctly resizes its tables when it gets too | 366 // This tests that the master correctly resizes its tables when it gets too |
| 332 // full, notifies its slaves of the change, and updates the disk. | 367 // full, notifies its slaves of the change, and updates the disk. |
| 333 TEST_F(VisitedLinkTest, Resizing) { | 368 TEST_F(VisitedLinkTest, Resizing) { |
| 334 // Create a very small database. | 369 // Create a very small database. |
| 335 const int32 initial_size = 17; | 370 const int32 initial_size = 17; |
| 336 ASSERT_TRUE(InitHistory()); | |
| 337 ASSERT_TRUE(InitVisited(initial_size, true)); | 371 ASSERT_TRUE(InitVisited(initial_size, true)); |
| 338 | 372 |
| 339 // ...and a slave | 373 // ...and a slave |
| 340 VisitedLinkSlave slave; | 374 VisitedLinkSlave slave; |
| 341 base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); | 375 base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); |
| 342 master_->shared_memory()->ShareToProcess( | 376 master_->shared_memory()->ShareToProcess( |
| 343 base::GetCurrentProcessHandle(), &new_handle); | 377 base::GetCurrentProcessHandle(), &new_handle); |
| 344 slave.OnUpdateVisitedLinks(new_handle); | 378 slave.OnUpdateVisitedLinks(new_handle); |
| 345 g_slaves.push_back(&slave); | 379 g_slaves.push_back(&slave); |
| 346 | 380 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 375 master_->DebugValidate(); | 409 master_->DebugValidate(); |
| 376 g_slaves.clear(); | 410 g_slaves.clear(); |
| 377 | 411 |
| 378 // This tests that the file is written correctly by reading it in using | 412 // This tests that the file is written correctly by reading it in using |
| 379 // a new database. | 413 // a new database. |
| 380 Reload(); | 414 Reload(); |
| 381 } | 415 } |
| 382 | 416 |
| 383 // Tests that if the database doesn't exist, it will be rebuilt from history. | 417 // Tests that if the database doesn't exist, it will be rebuilt from history. |
| 384 TEST_F(VisitedLinkTest, Rebuild) { | 418 TEST_F(VisitedLinkTest, Rebuild) { |
| 385 ASSERT_TRUE(InitHistory()); | |
| 386 | |
| 387 // Add half of our URLs to history. This needs to be done before we | 419 // Add half of our URLs to history. This needs to be done before we |
| 388 // initialize the visited link DB. | 420 // initialize the visited link DB. |
| 389 int history_count = g_test_count / 2; | 421 int history_count = g_test_count / 2; |
| 390 for (int i = 0; i < history_count; i++) | 422 for (int i = 0; i < history_count; i++) |
| 391 history_service_->AddPage( | 423 delegate_.AddURLForRebuild(TestURL(i)); |
| 392 TestURL(i), base::Time::Now(), history::SOURCE_BROWSED); | |
| 393 | 424 |
| 394 // Initialize the visited link DB. Since the visited links file doesn't exist | 425 // Initialize the visited link DB. Since the visited links file doesn't exist |
| 395 // and we don't suppress history rebuilding, this will load from history. | 426 // and we don't suppress history rebuilding, this will load from history. |
| 396 ASSERT_TRUE(InitVisited(0, false)); | 427 ASSERT_TRUE(InitVisited(0, false)); |
| 397 | 428 |
| 398 // While the table is rebuilding, add the rest of the URLs to the visited | 429 // While the table is rebuilding, add the rest of the URLs to the visited |
| 399 // link system. This isn't guaranteed to happen during the rebuild, so we | 430 // link system. This isn't guaranteed to happen during the rebuild, so we |
| 400 // can't be 100% sure we're testing the right thing, but in practice is. | 431 // can't be 100% sure we're testing the right thing, but in practice is. |
| 401 // All the adds above will generally take some time queuing up on the | 432 // All the adds above will generally take some time queuing up on the |
| 402 // history thread, and it will take a while to catch up to actually | 433 // history thread, and it will take a while to catch up to actually |
| 403 // processing the rebuild that has queued behind it. We will generally | 434 // processing the rebuild that has queued behind it. We will generally |
| 404 // finish adding all of the URLs before it has even found the first URL. | 435 // finish adding all of the URLs before it has even found the first URL. |
| 405 for (int i = history_count; i < g_test_count; i++) | 436 for (int i = history_count; i < g_test_count; i++) |
| 406 master_->AddURL(TestURL(i)); | 437 master_->AddURL(TestURL(i)); |
| 407 | 438 |
| 408 // Add one more and then delete it. | 439 // Add one more and then delete it. |
| 409 master_->AddURL(TestURL(g_test_count)); | 440 master_->AddURL(TestURL(g_test_count)); |
| 410 history::URLRows deleted_urls; | 441 URLs urls_to_delete; |
| 411 deleted_urls.push_back(history::URLRow(TestURL(g_test_count))); | 442 urls_to_delete.push_back(TestURL(g_test_count)); |
| 412 master_->DeleteURLs(deleted_urls); | 443 TestURLIterator iterator(urls_to_delete); |
| 444 master_->DeleteURLs(&iterator); |
| 413 | 445 |
| 414 // Wait for the rebuild to complete. The task will terminate the message | 446 // Wait for the rebuild to complete. The task will terminate the message |
| 415 // loop when the rebuild is done. There's no chance that the rebuild will | 447 // loop when the rebuild is done. There's no chance that the rebuild will |
| 416 // complete before we set the task because the rebuild completion message | 448 // complete before we set the task because the rebuild completion message |
| 417 // is posted to the message loop; until we Run() it, rebuild can not | 449 // is posted to the message loop; until we Run() it, rebuild can not |
| 418 // complete. | 450 // complete. |
| 419 master_->set_rebuild_complete_task(MessageLoop::QuitClosure()); | 451 master_->set_rebuild_complete_task(MessageLoop::QuitClosure()); |
| 420 MessageLoop::current()->Run(); | 452 MessageLoop::current()->Run(); |
| 421 | 453 |
| 422 // Test that all URLs were written to the database properly. | 454 // Test that all URLs were written to the database properly. |
| 423 Reload(); | 455 Reload(); |
| 424 | 456 |
| 425 // Make sure the extra one was *not* written (Reload won't test this). | 457 // Make sure the extra one was *not* written (Reload won't test this). |
| 426 EXPECT_FALSE(master_->IsVisited(TestURL(g_test_count))); | 458 EXPECT_FALSE(master_->IsVisited(TestURL(g_test_count))); |
| 427 } | 459 } |
| 428 | 460 |
| 429 // Test that importing a large number of URLs will work | 461 // Test that importing a large number of URLs will work |
| 430 TEST_F(VisitedLinkTest, BigImport) { | 462 TEST_F(VisitedLinkTest, BigImport) { |
| 431 ASSERT_TRUE(InitHistory()); | |
| 432 ASSERT_TRUE(InitVisited(0, false)); | 463 ASSERT_TRUE(InitVisited(0, false)); |
| 433 | 464 |
| 434 // Before the table rebuilds, add a large number of URLs | 465 // Before the table rebuilds, add a large number of URLs |
| 435 int total_count = VisitedLinkMaster::kDefaultTableSize + 10; | 466 int total_count = VisitedLinkMaster::kDefaultTableSize + 10; |
| 436 for (int i = 0; i < total_count; i++) | 467 for (int i = 0; i < total_count; i++) |
| 437 master_->AddURL(TestURL(i)); | 468 master_->AddURL(TestURL(i)); |
| 438 | 469 |
| 439 // Wait for the rebuild to complete. | 470 // Wait for the rebuild to complete. |
| 440 master_->set_rebuild_complete_task(MessageLoop::QuitClosure()); | 471 master_->set_rebuild_complete_task(MessageLoop::QuitClosure()); |
| 441 MessageLoop::current()->Run(); | 472 MessageLoop::current()->Run(); |
| 442 | 473 |
| 443 // Ensure that the right number of URLs are present | 474 // Ensure that the right number of URLs are present |
| 444 int used_count = master_->GetUsedCount(); | 475 int used_count = master_->GetUsedCount(); |
| 445 ASSERT_EQ(used_count, total_count); | 476 ASSERT_EQ(used_count, total_count); |
| 446 } | 477 } |
| 447 | 478 |
| 448 TEST_F(VisitedLinkTest, Listener) { | 479 TEST_F(VisitedLinkTest, Listener) { |
| 449 ASSERT_TRUE(InitHistory()); | |
| 450 ASSERT_TRUE(InitVisited(0, true)); | 480 ASSERT_TRUE(InitVisited(0, true)); |
| 451 | 481 |
| 452 // Add test URLs. | 482 // Add test URLs. |
| 453 for (int i = 0; i < g_test_count; i++) { | 483 for (int i = 0; i < g_test_count; i++) { |
| 454 master_->AddURL(TestURL(i)); | 484 master_->AddURL(TestURL(i)); |
| 455 ASSERT_EQ(i + 1, master_->GetUsedCount()); | 485 ASSERT_EQ(i + 1, master_->GetUsedCount()); |
| 456 } | 486 } |
| 457 | 487 |
| 458 history::URLRows deleted_urls; | |
| 459 deleted_urls.push_back(history::URLRow(TestURL(0))); | |
| 460 // Delete an URL. | 488 // Delete an URL. |
| 461 master_->DeleteURLs(deleted_urls); | 489 URLs urls_to_delete; |
| 490 urls_to_delete.push_back(TestURL(0)); |
| 491 TestURLIterator iterator(urls_to_delete); |
| 492 master_->DeleteURLs(&iterator); |
| 493 |
| 462 // ... and all of the remaining ones. | 494 // ... and all of the remaining ones. |
| 463 master_->DeleteAllURLs(); | 495 master_->DeleteAllURLs(); |
| 464 | 496 |
| 465 TrackingVisitedLinkEventListener* listener = | 497 TrackingVisitedLinkEventListener* listener = |
| 466 static_cast<TrackingVisitedLinkEventListener*>(master_->GetListener()); | 498 static_cast<TrackingVisitedLinkEventListener*>(master_->GetListener()); |
| 467 | 499 |
| 468 // Verify that VisitedLinkMaster::Listener::Add was called for each added URL. | 500 // Verify that VisitedLinkMaster::Listener::Add was called for each added URL. |
| 469 EXPECT_EQ(g_test_count, listener->add_count()); | 501 EXPECT_EQ(g_test_count, listener->add_count()); |
| 470 // Verify that VisitedLinkMaster::Listener::Reset was called both when one and | 502 // Verify that VisitedLinkMaster::Listener::Reset was called both when one and |
| 471 // all URLs are deleted. | 503 // all URLs are deleted. |
| 472 EXPECT_EQ(2, listener->reset_count()); | 504 EXPECT_EQ(2, listener->reset_count()); |
| 473 } | 505 } |
| 474 | 506 |
| 507 // TODO(boliu): Inherit content::TestBrowserContext when componentized. |
| 475 class VisitCountingProfile : public TestingProfile { | 508 class VisitCountingProfile : public TestingProfile { |
| 476 public: | 509 public: |
| 477 VisitCountingProfile() | 510 VisitCountingProfile() |
| 478 : add_count_(0), | 511 : add_count_(0), |
| 479 add_event_count_(0), | 512 add_event_count_(0), |
| 480 reset_event_count_(0) {} | 513 reset_event_count_(0) {} |
| 481 | 514 |
| 482 void CountAddEvent(int by) { | 515 void CountAddEvent(int by) { |
| 483 add_count_ += by; | 516 add_count_ += by; |
| 484 add_event_count_++; | 517 add_event_count_++; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 content::NotificationService::NoDetails()); | 549 content::NotificationService::NoDetails()); |
| 517 } | 550 } |
| 518 | 551 |
| 519 virtual void WidgetRestored() OVERRIDE { widgets_++; } | 552 virtual void WidgetRestored() OVERRIDE { widgets_++; } |
| 520 virtual void WidgetHidden() OVERRIDE { widgets_--; } | 553 virtual void WidgetHidden() OVERRIDE { widgets_--; } |
| 521 virtual int VisibleWidgetCount() const OVERRIDE { return widgets_; } | 554 virtual int VisibleWidgetCount() const OVERRIDE { return widgets_; } |
| 522 | 555 |
| 523 virtual bool Send(IPC::Message* msg) OVERRIDE { | 556 virtual bool Send(IPC::Message* msg) OVERRIDE { |
| 524 VisitCountingProfile* counting_profile = | 557 VisitCountingProfile* counting_profile = |
| 525 static_cast<VisitCountingProfile*>( | 558 static_cast<VisitCountingProfile*>( |
| 526 Profile::FromBrowserContext(GetBrowserContext())); | 559 GetBrowserContext()); |
| 527 | 560 |
| 528 if (msg->type() == ChromeViewMsg_VisitedLink_Add::ID) { | 561 if (msg->type() == ChromeViewMsg_VisitedLink_Add::ID) { |
| 529 PickleIterator iter(*msg); | 562 PickleIterator iter(*msg); |
| 530 std::vector<uint64> fingerprints; | 563 std::vector<uint64> fingerprints; |
| 531 CHECK(IPC::ReadParam(msg, &iter, &fingerprints)); | 564 CHECK(IPC::ReadParam(msg, &iter, &fingerprints)); |
| 532 counting_profile->CountAddEvent(fingerprints.size()); | 565 counting_profile->CountAddEvent(fingerprints.size()); |
| 533 } else if (msg->type() == ChromeViewMsg_VisitedLink_Reset::ID) { | 566 } else if (msg->type() == ChromeViewMsg_VisitedLink_Reset::ID) { |
| 534 counting_profile->CountResetEvent(); | 567 counting_profile->CountResetEvent(); |
| 535 } | 568 } |
| 536 | 569 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 552 virtual content::RenderProcessHost* CreateRenderProcessHost( | 585 virtual content::RenderProcessHost* CreateRenderProcessHost( |
| 553 content::BrowserContext* browser_context) const OVERRIDE { | 586 content::BrowserContext* browser_context) const OVERRIDE { |
| 554 return new VisitRelayingRenderProcessHost(browser_context); | 587 return new VisitRelayingRenderProcessHost(browser_context); |
| 555 } | 588 } |
| 556 | 589 |
| 557 private: | 590 private: |
| 558 | 591 |
| 559 DISALLOW_COPY_AND_ASSIGN(VisitedLinkRenderProcessHostFactory); | 592 DISALLOW_COPY_AND_ASSIGN(VisitedLinkRenderProcessHostFactory); |
| 560 }; | 593 }; |
| 561 | 594 |
| 595 // TODO(boliu): Inherit content::RenderViewHostTestHarness when componentized. |
| 562 class VisitedLinkEventsTest : public ChromeRenderViewHostTestHarness { | 596 class VisitedLinkEventsTest : public ChromeRenderViewHostTestHarness { |
| 563 public: | 597 public: |
| 564 VisitedLinkEventsTest() | 598 VisitedLinkEventsTest() |
| 565 : ui_thread_(BrowserThread::UI, &message_loop_), | 599 : ui_thread_(BrowserThread::UI, &message_loop_), |
| 566 file_thread_(BrowserThread::FILE, &message_loop_) {} | 600 file_thread_(BrowserThread::FILE, &message_loop_) {} |
| 567 virtual ~VisitedLinkEventsTest() {} | 601 virtual ~VisitedLinkEventsTest() {} |
| 568 virtual void SetUp() { | 602 virtual void SetUp() { |
| 569 browser_context_.reset(new VisitCountingProfile()); | 603 browser_context_.reset(new VisitCountingProfile()); |
| 570 profile()->CreateHistoryService(true, false); | 604 master_.reset(new VisitedLinkMaster(profile(), &delegate_)); |
| 571 master_ = static_cast<VisitedLinkMaster*>( | 605 master_->Init(); |
| 572 VisitedLinkMasterFactory::GetInstance()-> | |
| 573 SetTestingFactoryAndUse(profile(), BuildVisitedLinkMaster)); | |
| 574 SetRenderProcessHostFactory(&vc_rph_factory_); | 606 SetRenderProcessHostFactory(&vc_rph_factory_); |
| 575 ChromeRenderViewHostTestHarness::SetUp(); | 607 content::RenderViewHostTestHarness::SetUp(); |
| 576 } | 608 } |
| 577 | 609 |
| 578 VisitCountingProfile* profile() const { | 610 VisitCountingProfile* profile() const { |
| 579 return static_cast<VisitCountingProfile*>(browser_context_.get()); | 611 return static_cast<VisitCountingProfile*>(browser_context_.get()); |
| 580 } | 612 } |
| 581 | 613 |
| 582 VisitedLinkMaster* master() const { | 614 VisitedLinkMaster* master() const { |
| 583 return master_; | 615 return master_.get(); |
| 584 } | 616 } |
| 585 | 617 |
| 586 void WaitForCoalescense() { | 618 void WaitForCoalescense() { |
| 587 // Let the timer fire. | 619 // Let the timer fire. |
| 588 MessageLoop::current()->PostDelayedTask( | 620 MessageLoop::current()->PostDelayedTask( |
| 589 FROM_HERE, | 621 FROM_HERE, |
| 590 MessageLoop::QuitClosure(), | 622 MessageLoop::QuitClosure(), |
| 591 base::TimeDelta::FromMilliseconds(110)); | 623 base::TimeDelta::FromMilliseconds(110)); |
| 592 MessageLoop::current()->Run(); | 624 MessageLoop::current()->Run(); |
| 593 } | 625 } |
| 594 | 626 |
| 595 protected: | 627 protected: |
| 596 VisitedLinkRenderProcessHostFactory vc_rph_factory_; | 628 VisitedLinkRenderProcessHostFactory vc_rph_factory_; |
| 597 | 629 |
| 598 private: | 630 private: |
| 599 VisitedLinkMaster* master_; | 631 TestVisitedLinkDelegate delegate_; |
| 632 scoped_ptr<VisitedLinkMaster> master_; |
| 600 content::TestBrowserThread ui_thread_; | 633 content::TestBrowserThread ui_thread_; |
| 601 content::TestBrowserThread file_thread_; | 634 content::TestBrowserThread file_thread_; |
| 602 | 635 |
| 603 DISALLOW_COPY_AND_ASSIGN(VisitedLinkEventsTest); | 636 DISALLOW_COPY_AND_ASSIGN(VisitedLinkEventsTest); |
| 604 }; | 637 }; |
| 605 | 638 |
| 606 TEST_F(VisitedLinkEventsTest, Coalescense) { | 639 TEST_F(VisitedLinkEventsTest, Coalescense) { |
| 607 // add some URLs to master. | 640 // add some URLs to master. |
| 608 // Add a few URLs. | 641 // Add a few URLs. |
| 609 master()->AddURL(GURL("http://acidtests.org/")); | 642 master()->AddURL(GURL("http://acidtests.org/")); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 | 682 |
| 650 WaitForCoalescense(); | 683 WaitForCoalescense(); |
| 651 | 684 |
| 652 // We should have no change in results except for one new reset event. | 685 // We should have no change in results except for one new reset event. |
| 653 EXPECT_EQ(6, profile()->add_count()); | 686 EXPECT_EQ(6, profile()->add_count()); |
| 654 EXPECT_EQ(2, profile()->add_event_count()); | 687 EXPECT_EQ(2, profile()->add_event_count()); |
| 655 EXPECT_EQ(1, profile()->reset_event_count()); | 688 EXPECT_EQ(1, profile()->reset_event_count()); |
| 656 } | 689 } |
| 657 | 690 |
| 658 TEST_F(VisitedLinkEventsTest, Basics) { | 691 TEST_F(VisitedLinkEventsTest, Basics) { |
| 659 rvh_tester()->CreateRenderView(string16(), | 692 RenderViewHostTester::For(rvh())->CreateRenderView(string16(), |
| 660 MSG_ROUTING_NONE, | 693 MSG_ROUTING_NONE, |
| 661 -1); | 694 -1); |
| 662 | 695 |
| 663 // Add a few URLs. | 696 // Add a few URLs. |
| 664 master()->AddURL(GURL("http://acidtests.org/")); | 697 master()->AddURL(GURL("http://acidtests.org/")); |
| 665 master()->AddURL(GURL("http://google.com/")); | 698 master()->AddURL(GURL("http://google.com/")); |
| 666 master()->AddURL(GURL("http://chromium.org/")); | 699 master()->AddURL(GURL("http://chromium.org/")); |
| 667 | 700 |
| 668 WaitForCoalescense(); | 701 WaitForCoalescense(); |
| 669 | 702 |
| 670 // We now should have 1 add event. | 703 // We now should have 1 add event. |
| 671 EXPECT_EQ(1, profile()->add_event_count()); | 704 EXPECT_EQ(1, profile()->add_event_count()); |
| 672 EXPECT_EQ(0, profile()->reset_event_count()); | 705 EXPECT_EQ(0, profile()->reset_event_count()); |
| 673 | 706 |
| 674 master()->DeleteAllURLs(); | 707 master()->DeleteAllURLs(); |
| 675 | 708 |
| 676 WaitForCoalescense(); | 709 WaitForCoalescense(); |
| 677 | 710 |
| 678 // We should have no change in add results, plus one new reset event. | 711 // We should have no change in add results, plus one new reset event. |
| 679 EXPECT_EQ(1, profile()->add_event_count()); | 712 EXPECT_EQ(1, profile()->add_event_count()); |
| 680 EXPECT_EQ(1, profile()->reset_event_count()); | 713 EXPECT_EQ(1, profile()->reset_event_count()); |
| 681 } | 714 } |
| 682 | 715 |
| 683 TEST_F(VisitedLinkEventsTest, TabVisibility) { | 716 TEST_F(VisitedLinkEventsTest, TabVisibility) { |
| 684 rvh_tester()->CreateRenderView(string16(), | 717 RenderViewHostTester::For(rvh())->CreateRenderView(string16(), |
| 685 MSG_ROUTING_NONE, | 718 MSG_ROUTING_NONE, |
| 686 -1); | 719 -1); |
| 687 | 720 |
| 688 // Simulate tab becoming inactive. | 721 // Simulate tab becoming inactive. |
| 689 rvh_tester()->SimulateWasHidden(); | 722 RenderViewHostTester::For(rvh())->SimulateWasHidden(); |
| 690 | 723 |
| 691 // Add a few URLs. | 724 // Add a few URLs. |
| 692 master()->AddURL(GURL("http://acidtests.org/")); | 725 master()->AddURL(GURL("http://acidtests.org/")); |
| 693 master()->AddURL(GURL("http://google.com/")); | 726 master()->AddURL(GURL("http://google.com/")); |
| 694 master()->AddURL(GURL("http://chromium.org/")); | 727 master()->AddURL(GURL("http://chromium.org/")); |
| 695 | 728 |
| 696 WaitForCoalescense(); | 729 WaitForCoalescense(); |
| 697 | 730 |
| 698 // We shouldn't have any events. | 731 // We shouldn't have any events. |
| 699 EXPECT_EQ(0, profile()->add_event_count()); | 732 EXPECT_EQ(0, profile()->add_event_count()); |
| 700 EXPECT_EQ(0, profile()->reset_event_count()); | 733 EXPECT_EQ(0, profile()->reset_event_count()); |
| 701 | 734 |
| 702 // Simulate the tab becoming active. | 735 // Simulate the tab becoming active. |
| 703 rvh_tester()->SimulateWasShown(); | 736 RenderViewHostTester::For(rvh())->SimulateWasShown(); |
| 704 | 737 |
| 705 // We should now have 3 add events, still no reset events. | 738 // We should now have 3 add events, still no reset events. |
| 706 EXPECT_EQ(1, profile()->add_event_count()); | 739 EXPECT_EQ(1, profile()->add_event_count()); |
| 707 EXPECT_EQ(0, profile()->reset_event_count()); | 740 EXPECT_EQ(0, profile()->reset_event_count()); |
| 708 | 741 |
| 709 // Deactivate the tab again. | 742 // Deactivate the tab again. |
| 710 rvh_tester()->SimulateWasHidden(); | 743 RenderViewHostTester::For(rvh())->SimulateWasHidden(); |
| 711 | 744 |
| 712 // Add a bunch of URLs (over 50) to exhaust the link event buffer. | 745 // Add a bunch of URLs (over 50) to exhaust the link event buffer. |
| 713 for (int i = 0; i < 100; i++) | 746 for (int i = 0; i < 100; i++) |
| 714 master()->AddURL(TestURL(i)); | 747 master()->AddURL(TestURL(i)); |
| 715 | 748 |
| 716 WaitForCoalescense(); | 749 WaitForCoalescense(); |
| 717 | 750 |
| 718 // Again, no change in events until tab is active. | 751 // Again, no change in events until tab is active. |
| 719 EXPECT_EQ(1, profile()->add_event_count()); | 752 EXPECT_EQ(1, profile()->add_event_count()); |
| 720 EXPECT_EQ(0, profile()->reset_event_count()); | 753 EXPECT_EQ(0, profile()->reset_event_count()); |
| 721 | 754 |
| 722 // Activate the tab. | 755 // Activate the tab. |
| 723 rvh_tester()->SimulateWasShown(); | 756 RenderViewHostTester::For(rvh())->SimulateWasShown(); |
| 724 | 757 |
| 725 // We should have only one more reset event. | 758 // We should have only one more reset event. |
| 726 EXPECT_EQ(1, profile()->add_event_count()); | 759 EXPECT_EQ(1, profile()->add_event_count()); |
| 727 EXPECT_EQ(1, profile()->reset_event_count()); | 760 EXPECT_EQ(1, profile()->reset_event_count()); |
| 728 } | 761 } |
| OLD | NEW |