blob: 419d5be30f9d7b2208cd70724ef704d4235d417f [file] [log] [blame]
[email protected]02798a982012-01-27 00:45:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
avi5dd91f82015-12-25 22:30:465#include <stddef.h>
6#include <stdint.h>
7
initial.commit09911bf2008-07-26 23:55:298#include <cstdio>
dcheng3f767dc32016-04-25 22:54:229#include <memory>
[email protected]c38831a12011-10-28 12:44:4910#include <string>
11#include <vector>
initial.commit09911bf2008-07-26 23:55:2912
Sebastien Marchand53801a32019-01-25 16:26:1113#include "base/bind.h"
thestig819adcc82014-09-10 22:24:5314#include "base/files/file_util.h"
Greg Thompson5310924e22019-11-04 20:22:0215#include "base/files/scoped_temp_dir.h"
skyostilb0daa012015-06-02 19:03:4816#include "base/location.h"
avi5dd91f82015-12-25 22:30:4617#include "base/macros.h"
Antonio Gomesb3dd5fc2020-05-25 22:53:2718#include "base/optional.h"
[email protected]27730162013-07-23 14:51:5519#include "base/process/process_handle.h"
[email protected]ec04d3f2013-06-06 21:31:3920#include "base/run_loop.h"
skyostilb0daa012015-06-02 19:03:4821#include "base/single_thread_task_runner.h"
[email protected]c72674b2013-06-11 04:16:4322#include "base/strings/string_util.h"
gab7966d312016-05-11 20:35:0123#include "base/threading/thread_task_runner_handle.h"
[email protected]bbd8da92013-06-28 02:12:2024#include "base/time/time.h"
sammcaa222762016-09-21 07:30:4225#include "base/timer/mock_timer.h"
[email protected]1f371fa2013-01-23 00:35:1426#include "components/visitedlink/browser/visitedlink_delegate.h"
27#include "components/visitedlink/browser/visitedlink_event_listener.h"
Robert Sesekffeae8e2019-11-26 17:10:1528#include "components/visitedlink/browser/visitedlink_writer.h"
sammcaa222762016-09-21 07:30:4229#include "components/visitedlink/common/visitedlink.mojom.h"
Robert Sesekffeae8e2019-11-26 17:10:1530#include "components/visitedlink/renderer/visitedlink_reader.h"
[email protected]ec04d3f2013-06-06 21:31:3931#include "content/public/browser/browser_thread.h"
[email protected]ad50def52011-10-19 23:17:0732#include "content/public/browser/notification_service.h"
[email protected]0d6e9bd2011-10-18 04:29:1633#include "content/public/browser/notification_types.h"
Gabriel Charettec7108742019-08-23 03:31:4034#include "content/public/test/browser_task_environment.h"
[email protected]08a932d52012-06-03 21:42:1235#include "content/public/test/mock_render_process_host.h"
[email protected]4c3d9d62013-01-09 22:37:2036#include "content/public/test/test_browser_context.h"
[email protected]b1e3f202012-06-04 14:45:5037#include "content/public/test/test_renderer_host.h"
mtomaszf7d99a5c2014-09-15 16:23:4638#include "content/public/test/test_utils.h"
Julie Jeongeun Kim8ab180f72019-09-25 09:25:4639#include "mojo/public/cpp/bindings/pending_receiver.h"
40#include "mojo/public/cpp/bindings/receiver_set.h"
initial.commit09911bf2008-07-26 23:55:2941#include "testing/gtest/include/gtest/gtest.h"
[email protected]e3b599e2013-07-05 07:15:1742#include "url/gurl.h"
initial.commit09911bf2008-07-26 23:55:2943
[email protected]631bb742011-11-02 11:29:3944using content::BrowserThread;
[email protected]eddd886702012-03-16 14:53:2345using content::MockRenderProcessHost;
[email protected]c0257382012-03-12 20:15:3446using content::RenderViewHostTester;
[email protected]631bb742011-11-02 11:29:3947
Matt Falkenhagen24abf7822017-12-15 23:55:1148namespace content {
49class SiteInstance;
50}
51
[email protected]ab3eaeed2013-05-17 00:18:4452namespace visitedlink {
[email protected]1f371fa2013-01-23 00:35:1453
initial.commit09911bf2008-07-26 23:55:2954namespace {
55
[email protected]4c3d9d62013-01-09 22:37:2056typedef std::vector<GURL> URLs;
57
initial.commit09911bf2008-07-26 23:55:2958// a nice long URL that we can append numbers to to get new URLs
Eric Seckler4364b052019-11-21 21:37:5559const char kTestPrefix[] =
60 "http://www.google.com/products/foo/index.html?id=45028640526508376&seq=";
61constexpr int kTestCount = 1000;
initial.commit09911bf2008-07-26 23:55:2962
63// Returns a test URL for index |i|
64GURL TestURL(int i) {
Eric Seckler4364b052019-11-21 21:37:5565 return GURL(base::StringPrintf("%s%d", kTestPrefix, i));
initial.commit09911bf2008-07-26 23:55:2966}
67
Robert Sesekffeae8e2019-11-26 17:10:1568std::vector<VisitedLinkReader*> g_readers;
[email protected]4c3d9d62013-01-09 22:37:2069
70class TestVisitedLinkDelegate : public VisitedLinkDelegate {
71 public:
dcheng00ea022b2014-10-21 11:24:5672 void RebuildTable(const scoped_refptr<URLEnumerator>& enumerator) override;
[email protected]4c3d9d62013-01-09 22:37:2073
74 void AddURLForRebuild(const GURL& url);
75
76 private:
[email protected]4c3d9d62013-01-09 22:37:2077 URLs rebuild_urls_;
78};
79
[email protected]4c3d9d62013-01-09 22:37:2080void TestVisitedLinkDelegate::RebuildTable(
81 const scoped_refptr<URLEnumerator>& enumerator) {
82 for (URLs::const_iterator itr = rebuild_urls_.begin();
Ken Rockot4a16adb2019-12-17 07:31:4283 itr != rebuild_urls_.end(); ++itr)
[email protected]4c3d9d62013-01-09 22:37:2084 enumerator->OnURL(*itr);
85 enumerator->OnComplete(true);
86}
87
88void TestVisitedLinkDelegate::AddURLForRebuild(const GURL& url) {
89 rebuild_urls_.push_back(url);
90}
91
Robert Sesekffeae8e2019-11-26 17:10:1592class TestURLIterator : public VisitedLinkWriter::URLIterator {
[email protected]4c3d9d62013-01-09 22:37:2093 public:
94 explicit TestURLIterator(const URLs& urls);
95
dcheng00ea022b2014-10-21 11:24:5696 const GURL& NextURL() override;
97 bool HasNextURL() const override;
[email protected]4c3d9d62013-01-09 22:37:2098
99 private:
100 URLs::const_iterator iterator_;
101 URLs::const_iterator end_;
102};
103
104TestURLIterator::TestURLIterator(const URLs& urls)
Ken Rockot4a16adb2019-12-17 07:31:42105 : iterator_(urls.begin()), end_(urls.end()) {}
[email protected]4c3d9d62013-01-09 22:37:20106
107const GURL& TestURLIterator::NextURL() {
108 return *(iterator_++);
109}
110
111bool TestURLIterator::HasNextURL() const {
112 return iterator_ != end_;
113}
[email protected]dba45e32013-01-04 20:27:15114
[email protected]3e90d4a2009-07-03 17:38:39115} // namespace
116
Robert Sesekffeae8e2019-11-26 17:10:15117class TrackingVisitedLinkEventListener : public VisitedLinkWriter::Listener {
[email protected]3e90d4a2009-07-03 17:38:39118 public:
119 TrackingVisitedLinkEventListener()
Ken Rockot4a16adb2019-12-17 07:31:42120 : reset_count_(0), completely_reset_count_(0), add_count_(0) {}
[email protected]3e90d4a2009-07-03 17:38:39121
Ken Rockotaeb7eca2018-03-30 16:40:09122 void NewTable(base::ReadOnlySharedMemoryRegion* table_region) override {
123 if (table_region->IsValid()) {
Robert Sesekffeae8e2019-11-26 17:10:15124 for (std::vector<VisitedLinkReader>::size_type i = 0;
125 i < g_readers.size(); i++) {
126 g_readers[i]->UpdateVisitedLinks(table_region->Duplicate());
[email protected]3e90d4a2009-07-03 17:38:39127 }
initial.commit09911bf2008-07-26 23:55:29128 }
129 }
dcheng00ea022b2014-10-21 11:24:56130 void Add(VisitedLinkCommon::Fingerprint) override { add_count_++; }
sathaf37203d2015-12-15 15:10:42131 void Reset(bool invalidate_hashes) override {
132 if (invalidate_hashes)
133 completely_reset_count_++;
134 else
135 reset_count_++;
136 }
initial.commit09911bf2008-07-26 23:55:29137
[email protected]3e90d4a2009-07-03 17:38:39138 void SetUp() {
139 reset_count_ = 0;
140 add_count_ = 0;
141 }
142
143 int reset_count() const { return reset_count_; }
sathaf37203d2015-12-15 15:10:42144 int completely_reset_count() { return completely_reset_count_; }
[email protected]3e90d4a2009-07-03 17:38:39145 int add_count() const { return add_count_; }
146
147 private:
148 int reset_count_;
sathaf37203d2015-12-15 15:10:42149 int completely_reset_count_;
[email protected]3e90d4a2009-07-03 17:38:39150 int add_count_;
151};
[email protected]c2c998c2009-01-27 19:08:39152
[email protected]583844c2011-08-27 00:38:35153class VisitedLinkTest : public testing::Test {
initial.commit09911bf2008-07-26 23:55:29154 protected:
initial.commit09911bf2008-07-26 23:55:29155 // Initializes the visited link objects. Pass in the size that you want a
156 // freshly created table to be. 0 means use the default.
157 //
158 // |suppress_rebuild| is set when we're not testing rebuilding, see
Robert Sesekffeae8e2019-11-26 17:10:15159 // the VisitedLinkWriter constructor.
sathaf37203d2015-12-15 15:10:42160 //
161 // |wait_for_io_complete| wait for result of async loading.
162 bool InitVisited(int initial_size,
163 bool suppress_rebuild,
164 bool wait_for_io_complete) {
initial.commit09911bf2008-07-26 23:55:29165 // Initialize the visited link system.
Robert Sesekffeae8e2019-11-26 17:10:15166 writer_.reset(new VisitedLinkWriter(new TrackingVisitedLinkEventListener(),
167 &delegate_, true, suppress_rebuild,
168 visited_file_, initial_size));
169 bool result = writer_->Init();
sathaf37203d2015-12-15 15:10:42170 if (result && wait_for_io_complete) {
171 // Wait for all pending file I/O to be completed.
Gabriel Charette01507a22017-09-27 21:30:08172 content::RunAllTasksUntilIdle();
sathaf37203d2015-12-15 15:10:42173 }
174 return result;
initial.commit09911bf2008-07-26 23:55:29175 }
176
177 // May be called multiple times (some tests will do this to clear things,
178 // and TearDown will do this to make sure eveything is shiny before quitting.
179 void ClearDB() {
Robert Sesekffeae8e2019-11-26 17:10:15180 writer_.reset(nullptr);
initial.commit09911bf2008-07-26 23:55:29181
[email protected]3189013e2012-01-19 04:11:57182 // Wait for all pending file I/O to be completed.
Gabriel Charette01507a22017-09-27 21:30:08183 content::RunAllTasksUntilIdle();
initial.commit09911bf2008-07-26 23:55:29184 }
185
186 // Loads the database from disk and makes sure that the same URLs are present
187 // as were generated by TestIO_Create(). This also checks the URLs with a
Robert Sesekffeae8e2019-11-26 17:10:15188 // reader to make sure it reads the data properly.
initial.commit09911bf2008-07-26 23:55:29189 void Reload() {
190 // Clean up after our caller, who may have left the database open.
191 ClearDB();
192
sathaf37203d2015-12-15 15:10:42193 ASSERT_TRUE(InitVisited(0, true, true));
194
Robert Sesekffeae8e2019-11-26 17:10:15195 writer_->DebugValidate();
initial.commit09911bf2008-07-26 23:55:29196
197 // check that the table has the proper number of entries
Robert Sesekffeae8e2019-11-26 17:10:15198 int used_count = writer_->GetUsedCount();
Eric Seckler4364b052019-11-21 21:37:55199 ASSERT_EQ(used_count, kTestCount);
initial.commit09911bf2008-07-26 23:55:29200
Robert Sesekffeae8e2019-11-26 17:10:15201 // Create a reader database.
202 VisitedLinkReader reader;
203 reader.UpdateVisitedLinks(
204 writer_->mapped_table_memory().region.Duplicate());
205 g_readers.push_back(&reader);
initial.commit09911bf2008-07-26 23:55:29206
207 bool found;
Eric Seckler4364b052019-11-21 21:37:55208 for (int i = 0; i < kTestCount; i++) {
initial.commit09911bf2008-07-26 23:55:29209 GURL cur = TestURL(i);
Robert Sesekffeae8e2019-11-26 17:10:15210 found = writer_->IsVisited(cur);
211 EXPECT_TRUE(found) << "URL " << i << "not found in writer.";
initial.commit09911bf2008-07-26 23:55:29212
Robert Sesekffeae8e2019-11-26 17:10:15213 found = reader.IsVisited(cur);
214 EXPECT_TRUE(found) << "URL " << i << "not found in reader.";
initial.commit09911bf2008-07-26 23:55:29215 }
216
217 // test some random URL so we know that it returns false sometimes too
Robert Sesekffeae8e2019-11-26 17:10:15218 found = writer_->IsVisited(GURL("http://unfound.site/"));
initial.commit09911bf2008-07-26 23:55:29219 ASSERT_FALSE(found);
Robert Sesekffeae8e2019-11-26 17:10:15220 found = reader.IsVisited(GURL("http://unfound.site/"));
initial.commit09911bf2008-07-26 23:55:29221 ASSERT_FALSE(found);
222
Robert Sesekffeae8e2019-11-26 17:10:15223 writer_->DebugValidate();
initial.commit09911bf2008-07-26 23:55:29224
Robert Sesekffeae8e2019-11-26 17:10:15225 g_readers.clear();
initial.commit09911bf2008-07-26 23:55:29226 }
227
228 // testing::Test
dcheng30a1b1542014-10-29 21:27:50229 void SetUp() override {
[email protected]f708ed12010-09-23 12:18:34230 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
231
vabr8c498ea42016-09-15 12:41:58232 history_dir_ = temp_dir_.GetPath().AppendASCII("VisitedLinkTest");
[email protected]426d1c92013-12-03 20:08:54233 ASSERT_TRUE(base::CreateDirectory(history_dir_));
initial.commit09911bf2008-07-26 23:55:29234
[email protected]c2c998c2009-01-27 19:08:39235 visited_file_ = history_dir_.Append(FILE_PATH_LITERAL("VisitedLinks"));
initial.commit09911bf2008-07-26 23:55:29236 }
237
Greg Thompson5310924e22019-11-04 20:22:02238 void TearDown() override {
239 ClearDB();
240 ASSERT_TRUE(temp_dir_.Delete());
241 }
[email protected]f0a51fb52009-03-05 12:46:38242
[email protected]ea1a3f62012-11-16 20:34:23243 base::ScopedTempDir temp_dir_;
[email protected]f708ed12010-09-23 12:18:34244
initial.commit09911bf2008-07-26 23:55:29245 // Filenames for the services;
[email protected]9e275712013-02-10 19:20:14246 base::FilePath history_dir_;
247 base::FilePath visited_file_;
initial.commit09911bf2008-07-26 23:55:29248
Robert Sesekffeae8e2019-11-26 17:10:15249 std::unique_ptr<VisitedLinkWriter> writer_;
[email protected]4c3d9d62013-01-09 22:37:20250 TestVisitedLinkDelegate delegate_;
Gabriel Charette798fde72019-08-20 22:24:04251 content::BrowserTaskEnvironment task_environment_;
initial.commit09911bf2008-07-26 23:55:29252};
253
initial.commit09911bf2008-07-26 23:55:29254// This test creates and reads some databases to make sure the data is
255// preserved throughout those operations.
256TEST_F(VisitedLinkTest, DatabaseIO) {
sathaf37203d2015-12-15 15:10:42257 ASSERT_TRUE(InitVisited(0, true, true));
initial.commit09911bf2008-07-26 23:55:29258
Eric Seckler4364b052019-11-21 21:37:55259 for (int i = 0; i < kTestCount; i++)
Robert Sesekffeae8e2019-11-26 17:10:15260 writer_->AddURL(TestURL(i));
initial.commit09911bf2008-07-26 23:55:29261
262 // Test that the database was written properly
263 Reload();
264}
265
Eric Seckler4364b052019-11-21 21:37:55266// This test fills a database using AddURLs() and verifies that it can be read
267// back correctly.
268TEST_F(VisitedLinkTest, DatabaseIOAddURLs) {
269 ASSERT_TRUE(InitVisited(0, true, true));
270
271 constexpr int kHalfCount = kTestCount / 2;
272
273 // Add urls in pairs of two. Simulates calls to AddURLs() after navigations
274 // with redirects.
275 for (int i = 0; i < (kHalfCount - 1); i += 2)
Robert Sesekffeae8e2019-11-26 17:10:15276 writer_->AddURLs({TestURL(i), TestURL(i + 1)});
Eric Seckler4364b052019-11-21 21:37:55277
278 // Add a big vector of URLs, exceeding kBulkOperationThreshold.
279 std::vector<GURL> urls;
Robert Sesekffeae8e2019-11-26 17:10:15280 static_assert(kHalfCount > VisitedLinkWriter::kBulkOperationThreshold,
Eric Seckler4364b052019-11-21 21:37:55281 "kBulkOperationThreshold not exceeded");
282 for (int i = kHalfCount; i < kTestCount; i++)
283 urls.push_back(TestURL(i));
Robert Sesekffeae8e2019-11-26 17:10:15284 writer_->AddURLs(urls);
Eric Seckler4364b052019-11-21 21:37:55285
286 // Test that the database was written properly.
287 Reload();
288}
289
initial.commit09911bf2008-07-26 23:55:29290// Checks that we can delete things properly when there are collisions.
291TEST_F(VisitedLinkTest, Delete) {
avi5dd91f82015-12-25 22:30:46292 static const int32_t kInitialSize = 17;
sathaf37203d2015-12-15 15:10:42293 ASSERT_TRUE(InitVisited(kInitialSize, true, true));
initial.commit09911bf2008-07-26 23:55:29294
295 // Add a cluster from 14-17 wrapping around to 0. These will all hash to the
296 // same value.
[email protected]c2c998c2009-01-27 19:08:39297 const VisitedLinkCommon::Fingerprint kFingerprint0 = kInitialSize * 0 + 14;
298 const VisitedLinkCommon::Fingerprint kFingerprint1 = kInitialSize * 1 + 14;
299 const VisitedLinkCommon::Fingerprint kFingerprint2 = kInitialSize * 2 + 14;
300 const VisitedLinkCommon::Fingerprint kFingerprint3 = kInitialSize * 3 + 14;
301 const VisitedLinkCommon::Fingerprint kFingerprint4 = kInitialSize * 4 + 14;
Robert Sesekffeae8e2019-11-26 17:10:15302 writer_->AddFingerprint(kFingerprint0, false); // @14
303 writer_->AddFingerprint(kFingerprint1, false); // @15
304 writer_->AddFingerprint(kFingerprint2, false); // @16
305 writer_->AddFingerprint(kFingerprint3, false); // @0
306 writer_->AddFingerprint(kFingerprint4, false); // @1
initial.commit09911bf2008-07-26 23:55:29307
308 // Deleting 14 should move the next value up one slot (we do not specify an
309 // order).
Robert Sesekffeae8e2019-11-26 17:10:15310 EXPECT_EQ(kFingerprint3, writer_->hash_table_[0]);
311 writer_->DeleteFingerprint(kFingerprint3, false);
[email protected]c2c998c2009-01-27 19:08:39312 VisitedLinkCommon::Fingerprint zero_fingerprint = 0;
Robert Sesekffeae8e2019-11-26 17:10:15313 EXPECT_EQ(zero_fingerprint, writer_->hash_table_[1]);
314 EXPECT_NE(zero_fingerprint, writer_->hash_table_[0]);
initial.commit09911bf2008-07-26 23:55:29315
316 // Deleting the other four should leave the table empty.
Robert Sesekffeae8e2019-11-26 17:10:15317 writer_->DeleteFingerprint(kFingerprint0, false);
318 writer_->DeleteFingerprint(kFingerprint1, false);
319 writer_->DeleteFingerprint(kFingerprint2, false);
320 writer_->DeleteFingerprint(kFingerprint4, false);
initial.commit09911bf2008-07-26 23:55:29321
Robert Sesekffeae8e2019-11-26 17:10:15322 EXPECT_EQ(0, writer_->used_items_);
initial.commit09911bf2008-07-26 23:55:29323 for (int i = 0; i < kInitialSize; i++)
Robert Sesekffeae8e2019-11-26 17:10:15324 EXPECT_EQ(zero_fingerprint, writer_->hash_table_[i])
325 << "Hash table has values in it.";
initial.commit09911bf2008-07-26 23:55:29326}
327
Eric Seckler4364b052019-11-21 21:37:55328// When we delete more than kBulkOperationThreshold we trigger different
329// behavior where the entire file is rewritten.
initial.commit09911bf2008-07-26 23:55:29330TEST_F(VisitedLinkTest, BigDelete) {
sathaf37203d2015-12-15 15:10:42331 ASSERT_TRUE(InitVisited(16381, true, true));
initial.commit09911bf2008-07-26 23:55:29332
333 // Add the base set of URLs that won't be deleted.
334 // Reload() will test for these.
Eric Seckler4364b052019-11-21 21:37:55335 for (int32_t i = 0; i < kTestCount; i++)
Robert Sesekffeae8e2019-11-26 17:10:15336 writer_->AddURL(TestURL(i));
initial.commit09911bf2008-07-26 23:55:29337
338 // Add more URLs than necessary to trigger this case.
Robert Sesekffeae8e2019-11-26 17:10:15339 const int kTestDeleteCount = VisitedLinkWriter::kBulkOperationThreshold + 2;
[email protected]4c3d9d62013-01-09 22:37:20340 URLs urls_to_delete;
Eric Seckler4364b052019-11-21 21:37:55341 for (int32_t i = kTestCount; i < kTestCount + kTestDeleteCount; i++) {
initial.commit09911bf2008-07-26 23:55:29342 GURL url(TestURL(i));
Robert Sesekffeae8e2019-11-26 17:10:15343 writer_->AddURL(url);
[email protected]4c3d9d62013-01-09 22:37:20344 urls_to_delete.push_back(url);
initial.commit09911bf2008-07-26 23:55:29345 }
346
[email protected]4c3d9d62013-01-09 22:37:20347 TestURLIterator iterator(urls_to_delete);
Robert Sesekffeae8e2019-11-26 17:10:15348 writer_->DeleteURLs(&iterator);
349 writer_->DebugValidate();
initial.commit09911bf2008-07-26 23:55:29350
351 Reload();
352}
353
354TEST_F(VisitedLinkTest, DeleteAll) {
sathaf37203d2015-12-15 15:10:42355 ASSERT_TRUE(InitVisited(0, true, true));
initial.commit09911bf2008-07-26 23:55:29356
357 {
Robert Sesekffeae8e2019-11-26 17:10:15358 VisitedLinkReader reader;
359 reader.UpdateVisitedLinks(
360 writer_->mapped_table_memory().region.Duplicate());
361 g_readers.push_back(&reader);
initial.commit09911bf2008-07-26 23:55:29362
363 // Add the test URLs.
Eric Seckler4364b052019-11-21 21:37:55364 for (int i = 0; i < kTestCount; i++) {
Robert Sesekffeae8e2019-11-26 17:10:15365 writer_->AddURL(TestURL(i));
366 ASSERT_EQ(i + 1, writer_->GetUsedCount());
initial.commit09911bf2008-07-26 23:55:29367 }
Robert Sesekffeae8e2019-11-26 17:10:15368 writer_->DebugValidate();
initial.commit09911bf2008-07-26 23:55:29369
Robert Sesekffeae8e2019-11-26 17:10:15370 // Make sure the reader picked up the adds.
Eric Seckler4364b052019-11-21 21:37:55371 for (int i = 0; i < kTestCount; i++)
Robert Sesekffeae8e2019-11-26 17:10:15372 EXPECT_TRUE(reader.IsVisited(TestURL(i)));
initial.commit09911bf2008-07-26 23:55:29373
Robert Sesekffeae8e2019-11-26 17:10:15374 // Clear the table and make sure the reader picked it up.
375 writer_->DeleteAllURLs();
376 EXPECT_EQ(0, writer_->GetUsedCount());
Eric Seckler4364b052019-11-21 21:37:55377 for (int i = 0; i < kTestCount; i++) {
Robert Sesekffeae8e2019-11-26 17:10:15378 EXPECT_FALSE(writer_->IsVisited(TestURL(i)));
379 EXPECT_FALSE(reader.IsVisited(TestURL(i)));
initial.commit09911bf2008-07-26 23:55:29380 }
381
382 // Close the database.
Robert Sesekffeae8e2019-11-26 17:10:15383 g_readers.clear();
initial.commit09911bf2008-07-26 23:55:29384 ClearDB();
385 }
386
387 // Reopen and validate.
sathaf37203d2015-12-15 15:10:42388 ASSERT_TRUE(InitVisited(0, true, true));
Robert Sesekffeae8e2019-11-26 17:10:15389 writer_->DebugValidate();
390 EXPECT_EQ(0, writer_->GetUsedCount());
Eric Seckler4364b052019-11-21 21:37:55391 for (int i = 0; i < kTestCount; i++)
Robert Sesekffeae8e2019-11-26 17:10:15392 EXPECT_FALSE(writer_->IsVisited(TestURL(i)));
initial.commit09911bf2008-07-26 23:55:29393}
394
Robert Sesekffeae8e2019-11-26 17:10:15395// This tests that the writer correctly resizes its tables when it gets too
396// full, notifies its readers of the change, and updates the disk.
initial.commit09911bf2008-07-26 23:55:29397TEST_F(VisitedLinkTest, Resizing) {
398 // Create a very small database.
avi5dd91f82015-12-25 22:30:46399 const int32_t initial_size = 17;
sathaf37203d2015-12-15 15:10:42400 ASSERT_TRUE(InitVisited(initial_size, true, true));
initial.commit09911bf2008-07-26 23:55:29401
Robert Sesekffeae8e2019-11-26 17:10:15402 // ...and a reader
403 VisitedLinkReader reader;
404 reader.UpdateVisitedLinks(writer_->mapped_table_memory().region.Duplicate());
405 g_readers.push_back(&reader);
initial.commit09911bf2008-07-26 23:55:29406
Robert Sesekffeae8e2019-11-26 17:10:15407 int32_t used_count = writer_->GetUsedCount();
initial.commit09911bf2008-07-26 23:55:29408 ASSERT_EQ(used_count, 0);
409
Eric Seckler4364b052019-11-21 21:37:55410 for (int i = 0; i < kTestCount; i++) {
Robert Sesekffeae8e2019-11-26 17:10:15411 writer_->AddURL(TestURL(i));
412 used_count = writer_->GetUsedCount();
initial.commit09911bf2008-07-26 23:55:29413 ASSERT_EQ(i + 1, used_count);
414 }
415
416 // Verify that the table got resized sufficiently.
avi5dd91f82015-12-25 22:30:46417 int32_t table_size;
initial.commit09911bf2008-07-26 23:55:29418 VisitedLinkCommon::Fingerprint* table;
Robert Sesekffeae8e2019-11-26 17:10:15419 writer_->GetUsageStatistics(&table_size, &table);
420 used_count = writer_->GetUsedCount();
initial.commit09911bf2008-07-26 23:55:29421 ASSERT_GT(table_size, used_count);
Eric Seckler4364b052019-11-21 21:37:55422 ASSERT_EQ(used_count, kTestCount)
423 << "table count doesn't match the # of things we added";
initial.commit09911bf2008-07-26 23:55:29424
Robert Sesekffeae8e2019-11-26 17:10:15425 // Verify that the reader got the resize message and has the same
initial.commit09911bf2008-07-26 23:55:29426 // table information.
avi5dd91f82015-12-25 22:30:46427 int32_t child_table_size;
initial.commit09911bf2008-07-26 23:55:29428 VisitedLinkCommon::Fingerprint* child_table;
Robert Sesekffeae8e2019-11-26 17:10:15429 reader.GetUsageStatistics(&child_table_size, &child_table);
initial.commit09911bf2008-07-26 23:55:29430 ASSERT_EQ(table_size, child_table_size);
avi5dd91f82015-12-25 22:30:46431 for (int32_t i = 0; i < table_size; i++) {
initial.commit09911bf2008-07-26 23:55:29432 ASSERT_EQ(table[i], child_table[i]);
433 }
434
Robert Sesekffeae8e2019-11-26 17:10:15435 writer_->DebugValidate();
436 g_readers.clear();
initial.commit09911bf2008-07-26 23:55:29437
438 // This tests that the file is written correctly by reading it in using
439 // a new database.
440 Reload();
441}
442
443// Tests that if the database doesn't exist, it will be rebuilt from history.
444TEST_F(VisitedLinkTest, Rebuild) {
initial.commit09911bf2008-07-26 23:55:29445 // Add half of our URLs to history. This needs to be done before we
446 // initialize the visited link DB.
Eric Seckler4364b052019-11-21 21:37:55447 int history_count = kTestCount / 2;
initial.commit09911bf2008-07-26 23:55:29448 for (int i = 0; i < history_count; i++)
[email protected]4c3d9d62013-01-09 22:37:20449 delegate_.AddURLForRebuild(TestURL(i));
initial.commit09911bf2008-07-26 23:55:29450
451 // Initialize the visited link DB. Since the visited links file doesn't exist
452 // and we don't suppress history rebuilding, this will load from history.
sathaf37203d2015-12-15 15:10:42453 ASSERT_TRUE(InitVisited(0, false, false));
initial.commit09911bf2008-07-26 23:55:29454
455 // While the table is rebuilding, add the rest of the URLs to the visited
456 // link system. This isn't guaranteed to happen during the rebuild, so we
457 // can't be 100% sure we're testing the right thing, but in practice is.
458 // All the adds above will generally take some time queuing up on the
459 // history thread, and it will take a while to catch up to actually
460 // processing the rebuild that has queued behind it. We will generally
461 // finish adding all of the URLs before it has even found the first URL.
Eric Seckler4364b052019-11-21 21:37:55462 for (int i = history_count; i < kTestCount; i++)
Robert Sesekffeae8e2019-11-26 17:10:15463 writer_->AddURL(TestURL(i));
initial.commit09911bf2008-07-26 23:55:29464
465 // Add one more and then delete it.
Robert Sesekffeae8e2019-11-26 17:10:15466 writer_->AddURL(TestURL(kTestCount));
[email protected]4c3d9d62013-01-09 22:37:20467 URLs urls_to_delete;
Eric Seckler4364b052019-11-21 21:37:55468 urls_to_delete.push_back(TestURL(kTestCount));
[email protected]4c3d9d62013-01-09 22:37:20469 TestURLIterator iterator(urls_to_delete);
Robert Sesekffeae8e2019-11-26 17:10:15470 writer_->DeleteURLs(&iterator);
initial.commit09911bf2008-07-26 23:55:29471
472 // Wait for the rebuild to complete. The task will terminate the message
473 // loop when the rebuild is done. There's no chance that the rebuild will
474 // complete before we set the task because the rebuild completion message
475 // is posted to the message loop; until we Run() it, rebuild can not
476 // complete.
[email protected]ec04d3f2013-06-06 21:31:39477 base::RunLoop run_loop;
Robert Sesekffeae8e2019-11-26 17:10:15478 writer_->set_rebuild_complete_task(run_loop.QuitClosure());
[email protected]ec04d3f2013-06-06 21:31:39479 run_loop.Run();
initial.commit09911bf2008-07-26 23:55:29480
481 // Test that all URLs were written to the database properly.
482 Reload();
483
484 // Make sure the extra one was *not* written (Reload won't test this).
Robert Sesekffeae8e2019-11-26 17:10:15485 EXPECT_FALSE(writer_->IsVisited(TestURL(kTestCount)));
initial.commit09911bf2008-07-26 23:55:29486}
[email protected]3e90d4a2009-07-03 17:38:39487
[email protected]aed132ed2009-08-19 22:44:12488// Test that importing a large number of URLs will work
489TEST_F(VisitedLinkTest, BigImport) {
sathaf37203d2015-12-15 15:10:42490 ASSERT_TRUE(InitVisited(0, false, false));
[email protected]aed132ed2009-08-19 22:44:12491
492 // Before the table rebuilds, add a large number of URLs
Robert Sesekffeae8e2019-11-26 17:10:15493 int total_count = VisitedLinkWriter::kDefaultTableSize + 10;
[email protected]aed132ed2009-08-19 22:44:12494 for (int i = 0; i < total_count; i++)
Robert Sesekffeae8e2019-11-26 17:10:15495 writer_->AddURL(TestURL(i));
[email protected]aed132ed2009-08-19 22:44:12496
497 // Wait for the rebuild to complete.
[email protected]ec04d3f2013-06-06 21:31:39498 base::RunLoop run_loop;
Robert Sesekffeae8e2019-11-26 17:10:15499 writer_->set_rebuild_complete_task(run_loop.QuitClosure());
[email protected]ec04d3f2013-06-06 21:31:39500 run_loop.Run();
[email protected]aed132ed2009-08-19 22:44:12501
502 // Ensure that the right number of URLs are present
Robert Sesekffeae8e2019-11-26 17:10:15503 int used_count = writer_->GetUsedCount();
[email protected]aed132ed2009-08-19 22:44:12504 ASSERT_EQ(used_count, total_count);
505}
506
[email protected]3e90d4a2009-07-03 17:38:39507TEST_F(VisitedLinkTest, Listener) {
sathaf37203d2015-12-15 15:10:42508 ASSERT_TRUE(InitVisited(0, true, true));
509
510 TrackingVisitedLinkEventListener* listener =
Robert Sesekffeae8e2019-11-26 17:10:15511 static_cast<TrackingVisitedLinkEventListener*>(writer_->GetListener());
sathaf37203d2015-12-15 15:10:42512
Robert Sesekffeae8e2019-11-26 17:10:15513 // Verify that VisitedLinkWriter::Listener::Reset(true) was never called when
sathaf37203d2015-12-15 15:10:42514 // the table was created.
515 EXPECT_EQ(0, listener->completely_reset_count());
[email protected]3e90d4a2009-07-03 17:38:39516
517 // Add test URLs.
Eric Seckler4364b052019-11-21 21:37:55518 for (int i = 0; i < kTestCount; i++) {
Robert Sesekffeae8e2019-11-26 17:10:15519 writer_->AddURL(TestURL(i));
520 ASSERT_EQ(i + 1, writer_->GetUsedCount());
[email protected]3e90d4a2009-07-03 17:38:39521 }
522
[email protected]3e90d4a2009-07-03 17:38:39523 // Delete an URL.
[email protected]4c3d9d62013-01-09 22:37:20524 URLs urls_to_delete;
525 urls_to_delete.push_back(TestURL(0));
526 TestURLIterator iterator(urls_to_delete);
Robert Sesekffeae8e2019-11-26 17:10:15527 writer_->DeleteURLs(&iterator);
[email protected]4c3d9d62013-01-09 22:37:20528
[email protected]3e90d4a2009-07-03 17:38:39529 // ... and all of the remaining ones.
Robert Sesekffeae8e2019-11-26 17:10:15530 writer_->DeleteAllURLs();
[email protected]3e90d4a2009-07-03 17:38:39531
Robert Sesekffeae8e2019-11-26 17:10:15532 // Verify that VisitedLinkWriter::Listener::Add was called for each added URL.
Eric Seckler4364b052019-11-21 21:37:55533 EXPECT_EQ(kTestCount, listener->add_count());
Robert Sesekffeae8e2019-11-26 17:10:15534 // Verify that VisitedLinkWriter::Listener::Reset was called both when one and
[email protected]3e90d4a2009-07-03 17:38:39535 // all URLs are deleted.
[email protected]b42e6d82012-11-02 02:44:56536 EXPECT_EQ(2, listener->reset_count());
sathaf37203d2015-12-15 15:10:42537
538 ClearDB();
539
540 ASSERT_TRUE(InitVisited(0, true, true));
541
542 listener =
Robert Sesekffeae8e2019-11-26 17:10:15543 static_cast<TrackingVisitedLinkEventListener*>(writer_->GetListener());
544 // Verify that VisitedLinkWriter::Listener::Reset(true) was called when the
sathaf37203d2015-12-15 15:10:42545 // table was loaded.
546 EXPECT_EQ(1, listener->completely_reset_count());
[email protected]3e90d4a2009-07-03 17:38:39547}
548
sammcaa222762016-09-21 07:30:42549class VisitCountingContext : public mojom::VisitedLinkNotificationSink {
[email protected]3e90d4a2009-07-03 17:38:39550 public:
[email protected]28a66e252013-01-25 07:54:02551 VisitCountingContext()
[email protected]3e90d4a2009-07-03 17:38:39552 : add_count_(0),
553 add_event_count_(0),
[email protected]c2134fb2013-01-23 04:28:52554 reset_event_count_(0),
sathaf37203d2015-12-15 15:10:42555 completely_reset_event_count_(0),
Lukasz Anforowicz2b2699732018-04-12 18:49:10556 new_table_count_(0) {}
[email protected]3e90d4a2009-07-03 17:38:39557
sammcaa222762016-09-21 07:30:42558 void Bind(mojo::ScopedMessagePipeHandle handle) {
Julie Jeongeun Kim8ab180f72019-09-25 09:25:46559 receiver_.Add(this,
560 mojo::PendingReceiver<mojom::VisitedLinkNotificationSink>(
561 std::move(handle)));
[email protected]3e90d4a2009-07-03 17:38:39562 }
563
sammcaa222762016-09-21 07:30:42564 void WaitForUpdate() {
565 base::RunLoop run_loop;
566 quit_closure_ = run_loop.QuitClosure();
567 run_loop.Run();
[email protected]3e90d4a2009-07-03 17:38:39568 }
569
Julie Jeongeun Kim8ab180f72019-09-25 09:25:46570 void WaitForNoUpdate() { receiver_.FlushForTesting(); }
sammcaa222762016-09-21 07:30:42571
Julie Jeongeun Kim8ab180f72019-09-25 09:25:46572 mojo::ReceiverSet<mojom::VisitedLinkNotificationSink>& binding() {
573 return receiver_;
sathaf37203d2015-12-15 15:10:42574 }
575
sammcaa222762016-09-21 07:30:42576 void NotifyUpdate() {
577 if (!quit_closure_.is_null())
Daniel Cheng83563bc2019-04-30 23:50:24578 std::move(quit_closure_).Run();
sammcaa222762016-09-21 07:30:42579 }
580
581 void UpdateVisitedLinks(
Ken Rockotaeb7eca2018-03-30 16:40:09582 base::ReadOnlySharedMemoryRegion table_region) override {
[email protected]c2134fb2013-01-23 04:28:52583 new_table_count_++;
sammcaa222762016-09-21 07:30:42584 NotifyUpdate();
585 }
586
587 void AddVisitedLinks(const std::vector<uint64_t>& link_hashes) override {
588 add_count_ += link_hashes.size();
589 add_event_count_++;
590 NotifyUpdate();
591 }
592
593 void ResetVisitedLinks(bool invalidate_cached_hashes) override {
594 if (invalidate_cached_hashes)
595 completely_reset_event_count_++;
596 else
597 reset_event_count_++;
598 NotifyUpdate();
[email protected]c2134fb2013-01-23 04:28:52599 }
600
[email protected]3e90d4a2009-07-03 17:38:39601 int add_count() const { return add_count_; }
602 int add_event_count() const { return add_event_count_; }
603 int reset_event_count() const { return reset_event_count_; }
sathaf37203d2015-12-15 15:10:42604 int completely_reset_event_count() const {
605 return completely_reset_event_count_;
606 }
[email protected]c2134fb2013-01-23 04:28:52607 int new_table_count() const { return new_table_count_; }
[email protected]3e90d4a2009-07-03 17:38:39608
609 private:
610 int add_count_;
611 int add_event_count_;
612 int reset_event_count_;
sathaf37203d2015-12-15 15:10:42613 int completely_reset_event_count_;
[email protected]c2134fb2013-01-23 04:28:52614 int new_table_count_;
sammcaa222762016-09-21 07:30:42615
Ken Rockot4a16adb2019-12-17 07:31:42616 base::OnceClosure quit_closure_;
Julie Jeongeun Kim8ab180f72019-09-25 09:25:46617 mojo::ReceiverSet<mojom::VisitedLinkNotificationSink> receiver_;
Lukasz Anforowicz2b2699732018-04-12 18:49:10618
619 DISALLOW_COPY_AND_ASSIGN(VisitCountingContext);
[email protected]3e90d4a2009-07-03 17:38:39620};
621
[email protected]f3b1a082011-11-18 00:34:30622// Stub out as little as possible, borrowing from RenderProcessHost.
[email protected]b6a2f8de2012-01-31 17:28:49623class VisitRelayingRenderProcessHost : public MockRenderProcessHost {
[email protected]3e90d4a2009-07-03 17:38:39624 public:
[email protected]3d7474ff2011-07-27 17:47:37625 explicit VisitRelayingRenderProcessHost(
sammcaa222762016-09-21 07:30:42626 content::BrowserContext* browser_context,
627 VisitCountingContext* context)
Bo Liueb218ee2018-03-21 20:24:35628 : MockRenderProcessHost(browser_context) {
Ken Rockot4a16adb2019-12-17 07:31:42629 OverrideBinderForTesting(mojom::VisitedLinkNotificationSink::Name_,
630 base::BindRepeating(&VisitCountingContext::Bind,
631 base::Unretained(context)));
[email protected]ad50def52011-10-19 23:17:07632 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:27633 content::NOTIFICATION_RENDERER_PROCESS_CREATED,
[email protected]6c2381d2011-10-19 02:52:53634 content::Source<RenderProcessHost>(this),
[email protected]ad50def52011-10-19 23:17:07635 content::NotificationService::NoDetails());
[email protected]3e90d4a2009-07-03 17:38:39636 }
dcheng00ea022b2014-10-21 11:24:56637 ~VisitRelayingRenderProcessHost() override {
[email protected]ad50def52011-10-19 23:17:07638 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:27639 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
[email protected]f3b1a082011-11-18 00:34:30640 content::Source<content::RenderProcessHost>(this),
[email protected]ad50def52011-10-19 23:17:07641 content::NotificationService::NoDetails());
[email protected]3e90d4a2009-07-03 17:38:39642 }
643
[email protected]3e90d4a2009-07-03 17:38:39644 private:
[email protected]3e90d4a2009-07-03 17:38:39645 DISALLOW_COPY_AND_ASSIGN(VisitRelayingRenderProcessHost);
646};
647
648class VisitedLinkRenderProcessHostFactory
[email protected]f3b1a082011-11-18 00:34:30649 : public content::RenderProcessHostFactory {
[email protected]3e90d4a2009-07-03 17:38:39650 public:
sammcaa222762016-09-21 07:30:42651 VisitedLinkRenderProcessHostFactory() : context_(new VisitCountingContext) {}
dcheng00ea022b2014-10-21 11:24:56652 content::RenderProcessHost* CreateRenderProcessHost(
Matt Falkenhagen24abf7822017-12-15 23:55:11653 content::BrowserContext* browser_context,
Lucas Furukawa Gadani0a70be92019-06-28 17:31:26654 content::SiteInstance* site_instance) override {
Dave Tapuska65a04872020-11-12 18:12:34655 auto rph = std::make_unique<VisitRelayingRenderProcessHost>(browser_context,
656 context_.get());
657 content::RenderProcessHost* result = rph.get();
658 processes_.push_back(std::move(rph));
659 return result;
[email protected]3e90d4a2009-07-03 17:38:39660 }
661
sammcaa222762016-09-21 07:30:42662 VisitCountingContext* context() { return context_.get(); }
663
Dave Tapuska65a04872020-11-12 18:12:34664 void DeleteRenderProcessHosts() { processes_.clear(); }
665
[email protected]3e90d4a2009-07-03 17:38:39666 private:
Dave Tapuska65a04872020-11-12 18:12:34667 std::list<std::unique_ptr<VisitRelayingRenderProcessHost>> processes_;
sammcaa222762016-09-21 07:30:42668 std::unique_ptr<VisitCountingContext> context_;
[email protected]3e90d4a2009-07-03 17:38:39669 DISALLOW_COPY_AND_ASSIGN(VisitedLinkRenderProcessHostFactory);
670};
671
[email protected]28a66e252013-01-25 07:54:02672class VisitedLinkEventsTest : public content::RenderViewHostTestHarness {
[email protected]3e90d4a2009-07-03 17:38:39673 public:
dcheng30a1b1542014-10-29 21:27:50674 void SetUp() override {
[email protected]9a46725f2012-10-24 18:25:48675 SetRenderProcessHostFactory(&vc_rph_factory_);
[email protected]4c3d9d62013-01-09 22:37:20676 content::RenderViewHostTestHarness::SetUp();
[email protected]3e90d4a2009-07-03 17:38:39677 }
678
wkorman1c17345b2015-11-12 03:02:42679 void TearDown() override {
Robert Sesekffeae8e2019-11-26 17:10:15680 // Explicitly destroy the writer before proceeding with the rest
wkorman1c17345b2015-11-12 03:02:42681 // of teardown because it posts a task to close a file handle, and
682 // we need to make sure we've finished all file related work
683 // before our superclass sets about destroying the scoped temp
684 // directory.
Robert Sesekffeae8e2019-11-26 17:10:15685 writer_.reset();
Dave Tapuska65a04872020-11-12 18:12:34686 DeleteContents();
687 vc_rph_factory_.DeleteRenderProcessHosts();
wkorman1c17345b2015-11-12 03:02:42688 RenderViewHostTestHarness::TearDown();
689 }
690
Sylvain Defresne330d05c2019-08-07 12:36:37691 std::unique_ptr<content::BrowserContext> CreateBrowserContext() override {
692 auto context = std::make_unique<content::TestBrowserContext>();
Robert Sesekffeae8e2019-11-26 17:10:15693 CreateVisitedLinkWriter(context.get());
[email protected]cc99c9f2013-07-15 12:26:09694 return context;
695 }
696
sammcaa222762016-09-21 07:30:42697 VisitCountingContext* context() { return vc_rph_factory_.context(); }
[email protected]3e90d4a2009-07-03 17:38:39698
Robert Sesekffeae8e2019-11-26 17:10:15699 VisitedLinkWriter* writer() const { return writer_.get(); }
[email protected]5016ee12012-10-26 23:56:31700
[email protected]3e90d4a2009-07-03 17:38:39701 protected:
Robert Sesekffeae8e2019-11-26 17:10:15702 void CreateVisitedLinkWriter(content::BrowserContext* browser_context) {
tzik57c66e32018-07-02 08:02:57703 timer_.reset(new base::MockOneShotTimer());
Robert Sesekffeae8e2019-11-26 17:10:15704 writer_.reset(new VisitedLinkWriter(browser_context, &delegate_, true));
705 static_cast<VisitedLinkEventListener*>(writer_->GetListener())
sammcaa222762016-09-21 07:30:42706 ->SetCoalesceTimerForTest(timer_.get());
Robert Sesekffeae8e2019-11-26 17:10:15707 writer_->Init();
sathaf37203d2015-12-15 15:10:42708 }
709
[email protected]3e90d4a2009-07-03 17:38:39710 VisitedLinkRenderProcessHostFactory vc_rph_factory_;
711
[email protected]4c3d9d62013-01-09 22:37:20712 TestVisitedLinkDelegate delegate_;
tzik57c66e32018-07-02 08:02:57713 std::unique_ptr<base::MockOneShotTimer> timer_;
Robert Sesekffeae8e2019-11-26 17:10:15714 std::unique_ptr<VisitedLinkWriter> writer_;
[email protected]3e90d4a2009-07-03 17:38:39715};
716
wkorman1c17345b2015-11-12 03:02:42717TEST_F(VisitedLinkEventsTest, Coalescence) {
sathaf37203d2015-12-15 15:10:42718 // Waiting complete rebuild the table.
Gabriel Charette01507a22017-09-27 21:30:08719 content::RunAllTasksUntilIdle();
sathaf37203d2015-12-15 15:10:42720
sathaf37203d2015-12-15 15:10:42721 // After rebuild table expect reset event.
722 EXPECT_EQ(1, context()->reset_event_count());
723
Robert Sesekffeae8e2019-11-26 17:10:15724 // add some URLs to writer.
[email protected]3e90d4a2009-07-03 17:38:39725 // Add a few URLs.
Robert Sesekffeae8e2019-11-26 17:10:15726 writer()->AddURL(GURL("http://acidtests.org/"));
727 writer()->AddURL(GURL("http://google.com/"));
728 writer()->AddURL(GURL("http://chromium.org/"));
[email protected]3e90d4a2009-07-03 17:38:39729 // Just for kicks, add a duplicate URL. This shouldn't increase the resulting
Robert Sesekffeae8e2019-11-26 17:10:15730 writer()->AddURL(GURL("http://acidtests.org/"));
sammcaa222762016-09-21 07:30:42731 ASSERT_TRUE(timer_->IsRunning());
732 timer_->Fire();
[email protected]3e90d4a2009-07-03 17:38:39733
sammcaa222762016-09-21 07:30:42734 context()->WaitForUpdate();
[email protected]3e90d4a2009-07-03 17:38:39735
736 // We now should have 3 entries added in 1 event.
[email protected]28a66e252013-01-25 07:54:02737 EXPECT_EQ(3, context()->add_count());
738 EXPECT_EQ(1, context()->add_event_count());
[email protected]3e90d4a2009-07-03 17:38:39739
740 // Test whether the coalescing continues by adding a few more URLs.
Robert Sesekffeae8e2019-11-26 17:10:15741 writer()->AddURL(GURL("http://google.com/chrome/"));
742 writer()->AddURL(GURL("http://webkit.org/"));
743 writer()->AddURL(GURL("http://acid3.acidtests.org/"));
[email protected]3e90d4a2009-07-03 17:38:39744
sammcaa222762016-09-21 07:30:42745 ASSERT_TRUE(timer_->IsRunning());
746 timer_->Fire();
747 context()->WaitForUpdate();
[email protected]3e90d4a2009-07-03 17:38:39748
749 // We should have 6 entries added in 2 events.
[email protected]28a66e252013-01-25 07:54:02750 EXPECT_EQ(6, context()->add_count());
751 EXPECT_EQ(2, context()->add_event_count());
[email protected]3e90d4a2009-07-03 17:38:39752
753 // Test whether duplicate entries produce add events.
Robert Sesekffeae8e2019-11-26 17:10:15754 writer()->AddURL(GURL("http://acidtests.org/"));
sammcaa222762016-09-21 07:30:42755 EXPECT_FALSE(timer_->IsRunning());
756 context()->WaitForNoUpdate();
[email protected]3e90d4a2009-07-03 17:38:39757
758 // We should have no change in results.
[email protected]28a66e252013-01-25 07:54:02759 EXPECT_EQ(6, context()->add_count());
760 EXPECT_EQ(2, context()->add_event_count());
[email protected]3e90d4a2009-07-03 17:38:39761
762 // Ensure that the coalescing does not resume after resetting.
Robert Sesekffeae8e2019-11-26 17:10:15763 writer()->AddURL(GURL("http://build.chromium.org/"));
sammcaa222762016-09-21 07:30:42764 EXPECT_TRUE(timer_->IsRunning());
Robert Sesekffeae8e2019-11-26 17:10:15765 writer()->DeleteAllURLs();
sammcaa222762016-09-21 07:30:42766 EXPECT_FALSE(timer_->IsRunning());
767 context()->WaitForNoUpdate();
[email protected]3e90d4a2009-07-03 17:38:39768
769 // We should have no change in results except for one new reset event.
[email protected]28a66e252013-01-25 07:54:02770 EXPECT_EQ(6, context()->add_count());
771 EXPECT_EQ(2, context()->add_event_count());
sathaf37203d2015-12-15 15:10:42772 EXPECT_EQ(2, context()->reset_event_count());
[email protected]3e90d4a2009-07-03 17:38:39773}
774
[email protected]7fa7dd52011-04-24 01:09:42775TEST_F(VisitedLinkEventsTest, Basics) {
Aaron Colwell40563522021-02-18 17:14:35776 RenderViewHostTester::For(rvh())->CreateTestRenderView();
[email protected]6e8d64642009-08-10 15:27:19777
sathaf37203d2015-12-15 15:10:42778 // Waiting complete rebuild the table.
Gabriel Charette01507a22017-09-27 21:30:08779 content::RunAllTasksUntilIdle();
sathaf37203d2015-12-15 15:10:42780
sathaf37203d2015-12-15 15:10:42781 // After rebuild table expect reset event.
782 EXPECT_EQ(1, context()->reset_event_count());
783
[email protected]3e90d4a2009-07-03 17:38:39784 // Add a few URLs.
Robert Sesekffeae8e2019-11-26 17:10:15785 writer()->AddURL(GURL("http://acidtests.org/"));
786 writer()->AddURL(GURL("http://google.com/"));
787 writer()->AddURL(GURL("http://chromium.org/"));
sammcaa222762016-09-21 07:30:42788 ASSERT_TRUE(timer_->IsRunning());
789 timer_->Fire();
790 context()->WaitForUpdate();
[email protected]3e90d4a2009-07-03 17:38:39791
792 // We now should have 1 add event.
[email protected]28a66e252013-01-25 07:54:02793 EXPECT_EQ(1, context()->add_event_count());
sathaf37203d2015-12-15 15:10:42794 EXPECT_EQ(1, context()->reset_event_count());
[email protected]3e90d4a2009-07-03 17:38:39795
Robert Sesekffeae8e2019-11-26 17:10:15796 writer()->DeleteAllURLs();
[email protected]3e90d4a2009-07-03 17:38:39797
sammcaa222762016-09-21 07:30:42798 EXPECT_FALSE(timer_->IsRunning());
799 context()->WaitForNoUpdate();
[email protected]3e90d4a2009-07-03 17:38:39800
801 // We should have no change in add results, plus one new reset event.
[email protected]28a66e252013-01-25 07:54:02802 EXPECT_EQ(1, context()->add_event_count());
sathaf37203d2015-12-15 15:10:42803 EXPECT_EQ(2, context()->reset_event_count());
[email protected]3e90d4a2009-07-03 17:38:39804}
805
[email protected]7fa7dd52011-04-24 01:09:42806TEST_F(VisitedLinkEventsTest, TabVisibility) {
Aaron Colwell40563522021-02-18 17:14:35807 RenderViewHostTester::For(rvh())->CreateTestRenderView();
[email protected]3e90d4a2009-07-03 17:38:39808
sathaf37203d2015-12-15 15:10:42809 // Waiting complete rebuild the table.
Gabriel Charette01507a22017-09-27 21:30:08810 content::RunAllTasksUntilIdle();
sathaf37203d2015-12-15 15:10:42811
sathaf37203d2015-12-15 15:10:42812 // After rebuild table expect reset event.
813 EXPECT_EQ(1, context()->reset_event_count());
814
[email protected]3e90d4a2009-07-03 17:38:39815 // Simulate tab becoming inactive.
bsepf3b00fa52017-02-11 00:06:38816 RenderViewHostTester::For(rvh())->SimulateWasHidden();
[email protected]3e90d4a2009-07-03 17:38:39817
818 // Add a few URLs.
Robert Sesekffeae8e2019-11-26 17:10:15819 writer()->AddURL(GURL("http://acidtests.org/"));
820 writer()->AddURL(GURL("http://google.com/"));
821 writer()->AddURL(GURL("http://chromium.org/"));
sammcaa222762016-09-21 07:30:42822 ASSERT_TRUE(timer_->IsRunning());
823 timer_->Fire();
824 context()->WaitForNoUpdate();
[email protected]3e90d4a2009-07-03 17:38:39825
826 // We shouldn't have any events.
[email protected]28a66e252013-01-25 07:54:02827 EXPECT_EQ(0, context()->add_event_count());
sathaf37203d2015-12-15 15:10:42828 EXPECT_EQ(1, context()->reset_event_count());
[email protected]3e90d4a2009-07-03 17:38:39829
830 // Simulate the tab becoming active.
bsepf3b00fa52017-02-11 00:06:38831 RenderViewHostTester::For(rvh())->SimulateWasShown();
sammcaa222762016-09-21 07:30:42832 context()->WaitForUpdate();
[email protected]3e90d4a2009-07-03 17:38:39833
834 // We should now have 3 add events, still no reset events.
[email protected]28a66e252013-01-25 07:54:02835 EXPECT_EQ(1, context()->add_event_count());
sathaf37203d2015-12-15 15:10:42836 EXPECT_EQ(1, context()->reset_event_count());
[email protected]3e90d4a2009-07-03 17:38:39837
838 // Deactivate the tab again.
bsepf3b00fa52017-02-11 00:06:38839 RenderViewHostTester::For(rvh())->SimulateWasHidden();
[email protected]3e90d4a2009-07-03 17:38:39840
841 // Add a bunch of URLs (over 50) to exhaust the link event buffer.
842 for (int i = 0; i < 100; i++)
Robert Sesekffeae8e2019-11-26 17:10:15843 writer()->AddURL(TestURL(i));
[email protected]3e90d4a2009-07-03 17:38:39844
sammcaa222762016-09-21 07:30:42845 ASSERT_TRUE(timer_->IsRunning());
846 timer_->Fire();
847 context()->WaitForNoUpdate();
[email protected]3e90d4a2009-07-03 17:38:39848
849 // Again, no change in events until tab is active.
[email protected]28a66e252013-01-25 07:54:02850 EXPECT_EQ(1, context()->add_event_count());
sathaf37203d2015-12-15 15:10:42851 EXPECT_EQ(1, context()->reset_event_count());
[email protected]3e90d4a2009-07-03 17:38:39852
853 // Activate the tab.
bsepf3b00fa52017-02-11 00:06:38854 RenderViewHostTester::For(rvh())->SimulateWasShown();
sammcaa222762016-09-21 07:30:42855 EXPECT_FALSE(timer_->IsRunning());
856 context()->WaitForUpdate();
[email protected]3e90d4a2009-07-03 17:38:39857
858 // We should have only one more reset event.
[email protected]28a66e252013-01-25 07:54:02859 EXPECT_EQ(1, context()->add_event_count());
sathaf37203d2015-12-15 15:10:42860 EXPECT_EQ(2, context()->reset_event_count());
[email protected]3e90d4a2009-07-03 17:38:39861}
[email protected]1f371fa2013-01-23 00:35:14862
[email protected]c2134fb2013-01-23 04:28:52863// Tests that VisitedLink ignores renderer process creation notification for a
[email protected]28a66e252013-01-25 07:54:02864// different context.
[email protected]c2134fb2013-01-23 04:28:52865TEST_F(VisitedLinkEventsTest, IgnoreRendererCreationFromDifferentContext) {
sammcaa222762016-09-21 07:30:42866 content::TestBrowserContext different_context;
867 VisitCountingContext counting_context;
868 VisitRelayingRenderProcessHost different_process_host(&different_context,
869 &counting_context);
[email protected]c2134fb2013-01-23 04:28:52870
Lukasz Anforowicz2b2699732018-04-12 18:49:10871 size_t old_size = counting_context.binding().size();
[email protected]c2134fb2013-01-23 04:28:52872 content::NotificationService::current()->Notify(
873 content::NOTIFICATION_RENDERER_PROCESS_CREATED,
874 content::Source<content::RenderProcessHost>(&different_process_host),
875 content::NotificationService::NoDetails());
Lukasz Anforowicz2b2699732018-04-12 18:49:10876 size_t new_size = counting_context.binding().size();
877 EXPECT_EQ(old_size, new_size);
[email protected]c2134fb2013-01-23 04:28:52878}
879
sathaf37203d2015-12-15 15:10:42880class VisitedLinkCompletelyResetEventTest : public VisitedLinkEventsTest {
881 public:
Sylvain Defresne330d05c2019-08-07 12:36:37882 std::unique_ptr<content::BrowserContext> CreateBrowserContext() override {
883 auto context = std::make_unique<content::TestBrowserContext>();
884 CreateVisitedLinkFile(context.get());
Robert Sesekffeae8e2019-11-26 17:10:15885 CreateVisitedLinkWriter(context.get());
sathaf37203d2015-12-15 15:10:42886 return context;
887 }
888
889 void CreateVisitedLinkFile(content::BrowserContext* browser_context) {
890 base::FilePath visited_file =
891 browser_context->GetPath().Append(FILE_PATH_LITERAL("Visited Links"));
Robert Sesekffeae8e2019-11-26 17:10:15892 std::unique_ptr<VisitedLinkWriter> writer(
893 new VisitedLinkWriter(new TrackingVisitedLinkEventListener(),
sathaf37203d2015-12-15 15:10:42894 &delegate_, true, true, visited_file, 0));
Robert Sesekffeae8e2019-11-26 17:10:15895 writer->Init();
sathaf37203d2015-12-15 15:10:42896 // Waiting complete create the table.
Gabriel Charette01507a22017-09-27 21:30:08897 content::RunAllTasksUntilIdle();
sathaf37203d2015-12-15 15:10:42898
Robert Sesekffeae8e2019-11-26 17:10:15899 writer.reset();
sathaf37203d2015-12-15 15:10:42900 // Wait for all pending file I/O to be completed.
Gabriel Charette01507a22017-09-27 21:30:08901 content::RunAllTasksUntilIdle();
sathaf37203d2015-12-15 15:10:42902 }
903};
904
905TEST_F(VisitedLinkCompletelyResetEventTest, LoadTable) {
906 // Waiting complete loading the table.
Gabriel Charette01507a22017-09-27 21:30:08907 content::RunAllTasksUntilIdle();
sathaf37203d2015-12-15 15:10:42908
sammcaa222762016-09-21 07:30:42909 context()->binding().FlushForTesting();
sathaf37203d2015-12-15 15:10:42910
911 // After load table expect completely reset event.
912 EXPECT_EQ(1, context()->completely_reset_event_count());
913}
914
[email protected]ab3eaeed2013-05-17 00:18:44915} // namespace visitedlink