15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstdio> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/memory/shared_memory.h" 119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 13a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/process_handle.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/run_loop.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/visitedlink/browser/visitedlink_delegate.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/visitedlink/browser/visitedlink_event_listener.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/visitedlink/browser/visitedlink_master.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/visitedlink/common/visitedlink_messages.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/visitedlink/renderer/visitedlink_slave.h" 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/mock_render_process_host.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/test/test_browser_context.h" 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_renderer_host.h" 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/test/test_utils.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::MockRenderProcessHost; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHostTester; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace visitedlink { 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef std::vector<GURL> URLs; 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a nice long URL that we can append numbers to to get new URLs 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char g_test_prefix[] = 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "http://www.google.com/products/foo/index.html?id=45028640526508376&seq="; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int g_test_count = 1000; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns a test URL for index |i| 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL TestURL(int i) { 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GURL(base::StringPrintf("%s%d", g_test_prefix, i)); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::vector<VisitedLinkSlave*> g_slaves; 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestVisitedLinkDelegate : public VisitedLinkDelegate { 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void RebuildTable( 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const scoped_refptr<URLEnumerator>& enumerator) OVERRIDE; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void AddURLForRebuild(const GURL& url); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLs rebuild_urls_; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestVisitedLinkDelegate::RebuildTable( 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const scoped_refptr<URLEnumerator>& enumerator) { 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (URLs::const_iterator itr = rebuild_urls_.begin(); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) itr != rebuild_urls_.end(); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++itr) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enumerator->OnURL(*itr); 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enumerator->OnComplete(true); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestVisitedLinkDelegate::AddURLForRebuild(const GURL& url) { 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rebuild_urls_.push_back(url); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestURLIterator : public VisitedLinkMaster::URLIterator { 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit TestURLIterator(const URLs& urls); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual const GURL& NextURL() OVERRIDE; 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool HasNextURL() const OVERRIDE; 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLs::const_iterator iterator_; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLs::const_iterator end_; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TestURLIterator::TestURLIterator(const URLs& urls) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : iterator_(urls.begin()), 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) end_(urls.end()) { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const GURL& TestURLIterator::NextURL() { 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return *(iterator_++); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TestURLIterator::HasNextURL() const { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return iterator_ != end_; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TrackingVisitedLinkEventListener : public VisitedLinkMaster::Listener { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrackingVisitedLinkEventListener() 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : reset_count_(0), 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_count_(0) {} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void NewTable(base::SharedMemory* table) OVERRIDE { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (table) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<VisitedLinkSlave>::size_type i = 0; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i < g_slaves.size(); i++) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) table->ShareToProcess(base::GetCurrentProcessHandle(), &new_handle); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_slaves[i]->OnUpdateVisitedLinks(new_handle); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Add(VisitedLinkCommon::Fingerprint) OVERRIDE { add_count_++; } 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Reset() OVERRIDE { reset_count_++; } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetUp() { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reset_count_ = 0; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_count_ = 0; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int reset_count() const { return reset_count_; } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int add_count() const { return add_count_; } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int reset_count_; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int add_count_; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VisitedLinkTest : public testing::Test { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes the visited link objects. Pass in the size that you want a 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // freshly created table to be. 0 means use the default. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |suppress_rebuild| is set when we're not testing rebuilding, see 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the VisitedLinkMaster constructor. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool InitVisited(int initial_size, bool suppress_rebuild) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the visited link system. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_.reset(new VisitedLinkMaster(new TrackingVisitedLinkEventListener(), 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &delegate_, 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) suppress_rebuild, visited_file_, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_size)); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return master_->Init(); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // May be called multiple times (some tests will do this to clear things, 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and TearDown will do this to make sure eveything is shiny before quitting. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ClearDB() { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (master_.get()) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_.reset(NULL); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait for all pending file I/O to be completed. 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci content::RunAllBlockingPoolTasksUntilIdle(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Loads the database from disk and makes sure that the same URLs are present 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as were generated by TestIO_Create(). This also checks the URLs with a 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // slave to make sure it reads the data properly. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Reload() { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clean up after our caller, who may have left the database open. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearDB(); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(InitVisited(0, true)); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->DebugValidate(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // check that the table has the proper number of entries 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int used_count = master_->GetUsedCount(); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(used_count, g_test_count); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a slave database. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitedLinkSlave slave; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->shared_memory()->ShareToProcess( 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::GetCurrentProcessHandle(), &new_handle); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slave.OnUpdateVisitedLinks(new_handle); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_slaves.push_back(&slave); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool found; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < g_test_count; i++) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL cur = TestURL(i); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found = master_->IsVisited(cur); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(found) << "URL " << i << "not found in master."; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found = slave.IsVisited(cur); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(found) << "URL " << i << "not found in slave."; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // test some random URL so we know that it returns false sometimes too 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found = master_->IsVisited(GURL("http://unfound.site/")); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(found); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found = slave.IsVisited(GURL("http://unfound.site/")); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(found); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->DebugValidate(); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_slaves.clear(); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // testing::Test 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history_dir_ = temp_dir_.path().AppendASCII("VisitedLinkTest"); 213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASSERT_TRUE(base::CreateDirectory(history_dir_)); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visited_file_ = history_dir_.Append(FILE_PATH_LITERAL("VisitedLinks")); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearDB(); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ScopedTempDir temp_dir_; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Filenames for the services; 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath history_dir_; 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath visited_file_; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<VisitedLinkMaster> master_; 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestVisitedLinkDelegate delegate_; 230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::TestBrowserThreadBundle thread_bundle_; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test creates and reads some databases to make sure the data is 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// preserved throughout those operations. 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VisitedLinkTest, DatabaseIO) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(InitVisited(0, true)); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < g_test_count; i++) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->AddURL(TestURL(i)); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that the database was written properly 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reload(); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that we can delete things properly when there are collisions. 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VisitedLinkTest, Delete) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int32 kInitialSize = 17; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(InitVisited(kInitialSize, true)); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add a cluster from 14-17 wrapping around to 0. These will all hash to the 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // same value. 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const VisitedLinkCommon::Fingerprint kFingerprint0 = kInitialSize * 0 + 14; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const VisitedLinkCommon::Fingerprint kFingerprint1 = kInitialSize * 1 + 14; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const VisitedLinkCommon::Fingerprint kFingerprint2 = kInitialSize * 2 + 14; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const VisitedLinkCommon::Fingerprint kFingerprint3 = kInitialSize * 3 + 14; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const VisitedLinkCommon::Fingerprint kFingerprint4 = kInitialSize * 4 + 14; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->AddFingerprint(kFingerprint0, false); // @14 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->AddFingerprint(kFingerprint1, false); // @15 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->AddFingerprint(kFingerprint2, false); // @16 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->AddFingerprint(kFingerprint3, false); // @0 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->AddFingerprint(kFingerprint4, false); // @1 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deleting 14 should move the next value up one slot (we do not specify an 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // order). 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kFingerprint3, master_->hash_table_[0]); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->DeleteFingerprint(kFingerprint3, false); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitedLinkCommon::Fingerprint zero_fingerprint = 0; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(zero_fingerprint, master_->hash_table_[1]); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(zero_fingerprint, master_->hash_table_[0]); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deleting the other four should leave the table empty. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->DeleteFingerprint(kFingerprint0, false); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->DeleteFingerprint(kFingerprint1, false); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->DeleteFingerprint(kFingerprint2, false); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->DeleteFingerprint(kFingerprint4, false); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, master_->used_items_); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kInitialSize; i++) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(zero_fingerprint, master_->hash_table_[i]) << 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Hash table has values in it."; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When we delete more than kBigDeleteThreshold we trigger different behavior 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// where the entire file is rewritten. 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VisitedLinkTest, BigDelete) { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(InitVisited(16381, true)); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the base set of URLs that won't be deleted. 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reload() will test for these. 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int32 i = 0; i < g_test_count; i++) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->AddURL(TestURL(i)); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add more URLs than necessary to trigger this case. 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kTestDeleteCount = VisitedLinkMaster::kBigDeleteThreshold + 2; 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLs urls_to_delete; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int32 i = g_test_count; i < g_test_count + kTestDeleteCount; i++) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(TestURL(i)); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->AddURL(url); 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) urls_to_delete.push_back(url); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestURLIterator iterator(urls_to_delete); 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) master_->DeleteURLs(&iterator); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->DebugValidate(); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reload(); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VisitedLinkTest, DeleteAll) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(InitVisited(0, true)); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitedLinkSlave slave; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->shared_memory()->ShareToProcess( 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::GetCurrentProcessHandle(), &new_handle); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slave.OnUpdateVisitedLinks(new_handle); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_slaves.push_back(&slave); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the test URLs. 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < g_test_count; i++) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->AddURL(TestURL(i)); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(i + 1, master_->GetUsedCount()); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->DebugValidate(); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the slave picked up the adds. 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < g_test_count; i++) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(slave.IsVisited(TestURL(i))); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the table and make sure the slave picked it up. 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->DeleteAllURLs(); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, master_->GetUsedCount()); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < g_test_count; i++) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(master_->IsVisited(TestURL(i))); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(slave.IsVisited(TestURL(i))); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close the database. 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_slaves.clear(); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearDB(); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reopen and validate. 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(InitVisited(0, true)); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->DebugValidate(); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, master_->GetUsedCount()); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < g_test_count; i++) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(master_->IsVisited(TestURL(i))); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This tests that the master correctly resizes its tables when it gets too 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// full, notifies its slaves of the change, and updates the disk. 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VisitedLinkTest, Resizing) { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a very small database. 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int32 initial_size = 17; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(InitVisited(initial_size, true)); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ...and a slave 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitedLinkSlave slave; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->shared_memory()->ShareToProcess( 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::GetCurrentProcessHandle(), &new_handle); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slave.OnUpdateVisitedLinks(new_handle); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_slaves.push_back(&slave); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 used_count = master_->GetUsedCount(); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(used_count, 0); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < g_test_count; i++) { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->AddURL(TestURL(i)); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) used_count = master_->GetUsedCount(); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(i + 1, used_count); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that the table got resized sufficiently. 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 table_size; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitedLinkCommon::Fingerprint* table; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->GetUsageStatistics(&table_size, &table); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) used_count = master_->GetUsedCount(); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GT(table_size, used_count); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(used_count, g_test_count) << 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "table count doesn't match the # of things we added"; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that the slave got the resize message and has the same 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // table information. 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 child_table_size; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitedLinkCommon::Fingerprint* child_table; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slave.GetUsageStatistics(&child_table_size, &child_table); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(table_size, child_table_size); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int32 i = 0; i < table_size; i++) { 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(table[i], child_table[i]); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->DebugValidate(); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_slaves.clear(); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This tests that the file is written correctly by reading it in using 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a new database. 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reload(); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that if the database doesn't exist, it will be rebuilt from history. 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VisitedLinkTest, Rebuild) { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add half of our URLs to history. This needs to be done before we 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialize the visited link DB. 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int history_count = g_test_count / 2; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < history_count; i++) 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate_.AddURLForRebuild(TestURL(i)); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the visited link DB. Since the visited links file doesn't exist 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and we don't suppress history rebuilding, this will load from history. 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(InitVisited(0, false)); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // While the table is rebuilding, add the rest of the URLs to the visited 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // link system. This isn't guaranteed to happen during the rebuild, so we 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can't be 100% sure we're testing the right thing, but in practice is. 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All the adds above will generally take some time queuing up on the 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // history thread, and it will take a while to catch up to actually 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // processing the rebuild that has queued behind it. We will generally 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // finish adding all of the URLs before it has even found the first URL. 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = history_count; i < g_test_count; i++) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->AddURL(TestURL(i)); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add one more and then delete it. 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->AddURL(TestURL(g_test_count)); 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLs urls_to_delete; 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) urls_to_delete.push_back(TestURL(g_test_count)); 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestURLIterator iterator(urls_to_delete); 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) master_->DeleteURLs(&iterator); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait for the rebuild to complete. The task will terminate the message 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // loop when the rebuild is done. There's no chance that the rebuild will 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // complete before we set the task because the rebuild completion message 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is posted to the message loop; until we Run() it, rebuild can not 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // complete. 437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::RunLoop run_loop; 438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) master_->set_rebuild_complete_task(run_loop.QuitClosure()); 439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) run_loop.Run(); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that all URLs were written to the database properly. 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reload(); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the extra one was *not* written (Reload won't test this). 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(master_->IsVisited(TestURL(g_test_count))); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that importing a large number of URLs will work 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VisitedLinkTest, BigImport) { 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(InitVisited(0, false)); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Before the table rebuilds, add a large number of URLs 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int total_count = VisitedLinkMaster::kDefaultTableSize + 10; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < total_count; i++) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->AddURL(TestURL(i)); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait for the rebuild to complete. 458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::RunLoop run_loop; 459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) master_->set_rebuild_complete_task(run_loop.QuitClosure()); 460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) run_loop.Run(); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the right number of URLs are present 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int used_count = master_->GetUsedCount(); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(used_count, total_count); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VisitedLinkTest, Listener) { 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(InitVisited(0, true)); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add test URLs. 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < g_test_count; i++) { 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->AddURL(TestURL(i)); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(i + 1, master_->GetUsedCount()); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete an URL. 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLs urls_to_delete; 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) urls_to_delete.push_back(TestURL(0)); 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestURLIterator iterator(urls_to_delete); 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) master_->DeleteURLs(&iterator); 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ... and all of the remaining ones. 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master_->DeleteAllURLs(); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrackingVisitedLinkEventListener* listener = 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<TrackingVisitedLinkEventListener*>(master_->GetListener()); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that VisitedLinkMaster::Listener::Add was called for each added URL. 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(g_test_count, listener->add_count()); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that VisitedLinkMaster::Listener::Reset was called both when one and 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // all URLs are deleted. 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2, listener->reset_count()); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class VisitCountingContext : public content::TestBrowserContext { 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VisitCountingContext() 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : add_count_(0), 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_event_count_(0), 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reset_event_count_(0), 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_table_count_(0) {} 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CountAddEvent(int by) { 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_count_ += by; 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_event_count_++; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CountResetEvent() { 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reset_event_count_++; 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void CountNewTable() { 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_table_count_++; 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int add_count() const { return add_count_; } 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int add_event_count() const { return add_event_count_; } 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int reset_event_count() const { return reset_event_count_; } 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int new_table_count() const { return new_table_count_; } 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int add_count_; 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int add_event_count_; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int reset_event_count_; 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int new_table_count_; 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Stub out as little as possible, borrowing from RenderProcessHost. 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VisitRelayingRenderProcessHost : public MockRenderProcessHost { 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit VisitRelayingRenderProcessHost( 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserContext* browser_context) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : MockRenderProcessHost(browser_context), widgets_(0) { 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NOTIFICATION_RENDERER_PROCESS_CREATED, 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<RenderProcessHost>(this), 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::NoDetails()); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~VisitRelayingRenderProcessHost() { 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<content::RenderProcessHost>(this), 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::NoDetails()); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void WidgetRestored() OVERRIDE { widgets_++; } 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void WidgetHidden() OVERRIDE { widgets_--; } 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int VisibleWidgetCount() const OVERRIDE { return widgets_; } 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Send(IPC::Message* msg) OVERRIDE { 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VisitCountingContext* counting_context = 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<VisitCountingContext*>( 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetBrowserContext()); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (msg->type() == ChromeViewMsg_VisitedLink_Add::ID) { 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(*msg); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<uint64> fingerprints; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(IPC::ReadParam(msg, &iter, &fingerprints)); 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) counting_context->CountAddEvent(fingerprints.size()); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (msg->type() == ChromeViewMsg_VisitedLink_Reset::ID) { 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) counting_context->CountResetEvent(); 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (msg->type() == ChromeViewMsg_VisitedLink_NewTable::ID) { 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) counting_context->CountNewTable(); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete msg; 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int widgets_; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(VisitRelayingRenderProcessHost); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VisitedLinkRenderProcessHostFactory 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public content::RenderProcessHostFactory { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitedLinkRenderProcessHostFactory() 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : content::RenderProcessHostFactory() {} 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual content::RenderProcessHost* CreateRenderProcessHost( 582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::BrowserContext* browser_context, 583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::SiteInstance* site_instance) const OVERRIDE { 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new VisitRelayingRenderProcessHost(browser_context); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(VisitedLinkRenderProcessHostFactory); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class VisitedLinkEventsTest : public content::RenderViewHostTestHarness { 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetRenderProcessHostFactory(&vc_rph_factory_); 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::RenderViewHostTestHarness::SetUp(); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual content::BrowserContext* CreateBrowserContext() OVERRIDE { 5997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch VisitCountingContext* context = new VisitCountingContext(); 6007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch master_.reset(new VisitedLinkMaster(context, &delegate_, true)); 6017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch master_->Init(); 6027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return context; 6037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 6047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 6057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch VisitCountingContext* context() { 6067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return static_cast<VisitCountingContext*>(browser_context()); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitedLinkMaster* master() const { 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return master_.get(); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WaitForCoalescense() { 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let the timer fire. 615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // 616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(ajwong): This is horrid! What is the right synchronization method? 617868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::RunLoop run_loop; 618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 620868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) run_loop.QuitClosure(), 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(110)); 622868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) run_loop.Run(); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitedLinkRenderProcessHostFactory vc_rph_factory_; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestVisitedLinkDelegate delegate_; 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<VisitedLinkMaster> master_; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VisitedLinkEventsTest, Coalescense) { 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // add some URLs to master. 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add a few URLs. 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->AddURL(GURL("http://acidtests.org/")); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->AddURL(GURL("http://google.com/")); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->AddURL(GURL("http://chromium.org/")); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Just for kicks, add a duplicate URL. This shouldn't increase the resulting 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->AddURL(GURL("http://acidtests.org/")); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure that coalescing actually occurs. There should be no links or 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // events received by the renderer. 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, context()->add_count()); 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, context()->add_event_count()); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForCoalescense(); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We now should have 3 entries added in 1 event. 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(3, context()->add_count()); 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, context()->add_event_count()); 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test whether the coalescing continues by adding a few more URLs. 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->AddURL(GURL("http://google.com/chrome/")); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->AddURL(GURL("http://webkit.org/")); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->AddURL(GURL("http://acid3.acidtests.org/")); 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForCoalescense(); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have 6 entries added in 2 events. 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(6, context()->add_count()); 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(2, context()->add_event_count()); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test whether duplicate entries produce add events. 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->AddURL(GURL("http://acidtests.org/")); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForCoalescense(); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have no change in results. 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(6, context()->add_count()); 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(2, context()->add_event_count()); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the coalescing does not resume after resetting. 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->AddURL(GURL("http://build.chromium.org/")); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->DeleteAllURLs(); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForCoalescense(); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have no change in results except for one new reset event. 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(6, context()->add_count()); 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(2, context()->add_event_count()); 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, context()->reset_event_count()); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VisitedLinkEventsTest, Basics) { 686cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RenderViewHostTester::For(rvh())->CreateRenderView( 687cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::string16(), MSG_ROUTING_NONE, MSG_ROUTING_NONE, -1, false); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add a few URLs. 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->AddURL(GURL("http://acidtests.org/")); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->AddURL(GURL("http://google.com/")); 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->AddURL(GURL("http://chromium.org/")); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForCoalescense(); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We now should have 1 add event. 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, context()->add_event_count()); 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, context()->reset_event_count()); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->DeleteAllURLs(); 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForCoalescense(); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have no change in add results, plus one new reset event. 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, context()->add_event_count()); 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, context()->reset_event_count()); 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VisitedLinkEventsTest, TabVisibility) { 710cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RenderViewHostTester::For(rvh())->CreateRenderView( 711cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::string16(), MSG_ROUTING_NONE, MSG_ROUTING_NONE, -1, false); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Simulate tab becoming inactive. 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderViewHostTester::For(rvh())->SimulateWasHidden(); 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add a few URLs. 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->AddURL(GURL("http://acidtests.org/")); 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->AddURL(GURL("http://google.com/")); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->AddURL(GURL("http://chromium.org/")); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForCoalescense(); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We shouldn't have any events. 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, context()->add_event_count()); 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, context()->reset_event_count()); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Simulate the tab becoming active. 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderViewHostTester::For(rvh())->SimulateWasShown(); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should now have 3 add events, still no reset events. 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, context()->add_event_count()); 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, context()->reset_event_count()); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deactivate the tab again. 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderViewHostTester::For(rvh())->SimulateWasHidden(); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add a bunch of URLs (over 50) to exhaust the link event buffer. 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 100; i++) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) master()->AddURL(TestURL(i)); 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForCoalescense(); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Again, no change in events until tab is active. 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, context()->add_event_count()); 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, context()->reset_event_count()); 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Activate the tab. 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderViewHostTester::For(rvh())->SimulateWasShown(); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have only one more reset event. 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, context()->add_event_count()); 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, context()->reset_event_count()); 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that VisitedLink ignores renderer process creation notification for a 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// different context. 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(VisitedLinkEventsTest, IgnoreRendererCreationFromDifferentContext) { 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VisitCountingContext different_context; 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VisitRelayingRenderProcessHost different_process_host(&different_context); 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::NotificationService::current()->Notify( 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::NOTIFICATION_RENDERER_PROCESS_CREATED, 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<content::RenderProcessHost>(&different_process_host), 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::NotificationService::NoDetails()); 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WaitForCoalescense(); 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, different_context.new_table_count()); 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 77090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace visitedlink 771