Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: chrome/browser/visitedlink/visitedlink_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698