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

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

Issue 113591: Fix Acid3 Test 48: LINKTEST, Chromium side.... (Closed) Base URL: svn://chrome-svn.corp.google.com/chrome/trunk/src/
Patch Set: Made waiting more bearable. Created 11 years, 5 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
« no previous file with comments | « chrome/browser/visitedlink_perftest.cc ('k') | chrome/chrome.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <vector> 5 #include <vector>
6 #include <string> 6 #include <string>
7 #include <cstdio> 7 #include <cstdio>
8 8
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/path_service.h" 11 #include "base/path_service.h"
12 #include "base/process_util.h" 12 #include "base/process_util.h"
13 #include "base/shared_memory.h" 13 #include "base/shared_memory.h"
14 #include "base/string_util.h" 14 #include "base/string_util.h"
15 #include "chrome/browser/visitedlink_master.h" 15 #include "chrome/browser/visitedlink_master.h"
16 #include "chrome/browser/visitedlink_event_listener.h"
17 #include "chrome/browser/renderer_host/browser_render_process_host.h"
18 #include "chrome/browser/renderer_host/test_render_view_host.h"
19 #include "chrome/common/render_messages.h"
16 #include "chrome/renderer/visitedlink_slave.h" 20 #include "chrome/renderer/visitedlink_slave.h"
17 #include "googleurl/src/gurl.h" 21 #include "googleurl/src/gurl.h"
18 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
19 23
20 namespace { 24 namespace {
21 25
22 // a nice long URL that we can append numbers to to get new URLs 26 // a nice long URL that we can append numbers to to get new URLs
23 const char g_test_prefix[] = 27 const char g_test_prefix[] =
24 "http://www.google.com/products/foo/index.html?id=45028640526508376&seq="; 28 "http://www.google.com/products/foo/index.html?id=45028640526508376&seq=";
25 const int g_test_count = 1000; 29 const int g_test_count = 1000;
26 30
27 // Returns a test URL for index |i| 31 // Returns a test URL for index |i|
28 GURL TestURL(int i) { 32 GURL TestURL(int i) {
29 return GURL(StringPrintf("%s%d", g_test_prefix, i)); 33 return GURL(StringPrintf("%s%d", g_test_prefix, i));
30 } 34 }
31 35
32 std::vector<VisitedLinkSlave*> g_slaves; 36 std::vector<VisitedLinkSlave*> g_slaves;
33 37
34 VisitedLinkMaster::PostNewTableEvent SynchronousBroadcastNewTableEvent; 38 } // namespace
35 void SynchronousBroadcastNewTableEvent(base::SharedMemory* table) { 39
36 if (table) { 40 class TrackingVisitedLinkEventListener : public VisitedLinkMaster::Listener {
37 for (std::vector<VisitedLinkSlave>::size_type i = 0; 41 public:
38 i < g_slaves.size(); i++) { 42 TrackingVisitedLinkEventListener()
39 base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle(); 43 : reset_count_(0),
40 table->ShareToProcess(base::GetCurrentProcessHandle(), &new_handle); 44 add_count_(0) {}
41 g_slaves[i]->Init(new_handle); 45
46 virtual void NewTable(base::SharedMemory* table) {
47 if (table) {
48 for (std::vector<VisitedLinkSlave>::size_type i = 0;
49 i < g_slaves.size(); i++) {
50 base::SharedMemoryHandle new_handle = base::SharedMemory::NULLHandle();
51 table->ShareToProcess(base::GetCurrentProcessHandle(), &new_handle);
52 g_slaves[i]->Init(new_handle);
53 }
42 } 54 }
43 } 55 }
44 } 56 virtual void Add(VisitedLinkCommon::Fingerprint) { add_count_++; }
57 virtual void Reset() { reset_count_++; }
45 58
46 } // namespace 59 void SetUp() {
60 reset_count_ = 0;
61 add_count_ = 0;
62 }
63
64 int reset_count() const { return reset_count_; }
65 int add_count() const { return add_count_; }
66
67 private:
68 int reset_count_;
69 int add_count_;
70 };
47 71
48 class VisitedLinkTest : public testing::Test { 72 class VisitedLinkTest : public testing::Test {
49 protected: 73 protected:
50 // Initialize the history system. This should be called before InitVisited(). 74 // Initialize the history system. This should be called before InitVisited().
51 bool InitHistory() { 75 bool InitHistory() {
52 history_service_ = new HistoryService; 76 history_service_ = new HistoryService;
53 return history_service_->Init(history_dir_, NULL); 77 return history_service_->Init(history_dir_, NULL);
54 } 78 }
55 79
56 // Initializes the visited link objects. Pass in the size that you want a 80 // Initializes the visited link objects. Pass in the size that you want a
57 // freshly created table to be. 0 means use the default. 81 // freshly created table to be. 0 means use the default.
58 // 82 //
59 // |suppress_rebuild| is set when we're not testing rebuilding, see 83 // |suppress_rebuild| is set when we're not testing rebuilding, see
60 // the VisitedLinkMaster constructor. 84 // the VisitedLinkMaster constructor.
61 bool InitVisited(int initial_size, bool suppress_rebuild) { 85 bool InitVisited(int initial_size, bool suppress_rebuild) {
62 // Initialize the visited link system. 86 // Initialize the visited link system.
63 master_.reset(new VisitedLinkMaster(NULL, 87 master_.reset(new VisitedLinkMaster(NULL, &listener_, history_service_,
64 SynchronousBroadcastNewTableEvent, 88 suppress_rebuild, visited_file_,
65 history_service_, suppress_rebuild, 89 initial_size));
66 visited_file_, initial_size));
67 return master_->Init(); 90 return master_->Init();
68 } 91 }
69 92
70 // May be called multiple times (some tests will do this to clear things, 93 // May be called multiple times (some tests will do this to clear things,
71 // and TearDown will do this to make sure eveything is shiny before quitting. 94 // and TearDown will do this to make sure eveything is shiny before quitting.
72 void ClearDB() { 95 void ClearDB() {
73 if (master_.get()) 96 if (master_.get())
74 master_.reset(NULL); 97 master_.reset(NULL);
75 98
76 if (history_service_.get()) { 99 if (history_service_.get()) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 } 154 }
132 155
133 // testing::Test 156 // testing::Test
134 virtual void SetUp() { 157 virtual void SetUp() {
135 PathService::Get(base::DIR_TEMP, &history_dir_); 158 PathService::Get(base::DIR_TEMP, &history_dir_);
136 history_dir_ = history_dir_.Append(FILE_PATH_LITERAL("VisitedLinkTest")); 159 history_dir_ = history_dir_.Append(FILE_PATH_LITERAL("VisitedLinkTest"));
137 file_util::Delete(history_dir_, true); 160 file_util::Delete(history_dir_, true);
138 file_util::CreateDirectory(history_dir_); 161 file_util::CreateDirectory(history_dir_);
139 162
140 visited_file_ = history_dir_.Append(FILE_PATH_LITERAL("VisitedLinks")); 163 visited_file_ = history_dir_.Append(FILE_PATH_LITERAL("VisitedLinks"));
164 listener_.SetUp();
141 } 165 }
142 166
143 virtual void TearDown() { 167 virtual void TearDown() {
144 ClearDB(); 168 ClearDB();
145 file_util::Delete(history_dir_, true); 169 file_util::Delete(history_dir_, true);
146 } 170 }
147 171
148 MessageLoop message_loop_; 172 MessageLoop message_loop_;
149 173
150 // Filenames for the services; 174 // Filenames for the services;
151 FilePath history_dir_; 175 FilePath history_dir_;
152 FilePath visited_file_; 176 FilePath visited_file_;
153 177
154 scoped_ptr<VisitedLinkMaster> master_; 178 scoped_ptr<VisitedLinkMaster> master_;
155 scoped_refptr<HistoryService> history_service_; 179 scoped_refptr<HistoryService> history_service_;
180 TrackingVisitedLinkEventListener listener_;
156 }; 181 };
157 182
158 // This test creates and reads some databases to make sure the data is 183 // This test creates and reads some databases to make sure the data is
159 // preserved throughout those operations. 184 // preserved throughout those operations.
160 TEST_F(VisitedLinkTest, DatabaseIO) { 185 TEST_F(VisitedLinkTest, DatabaseIO) {
161 ASSERT_TRUE(InitHistory()); 186 ASSERT_TRUE(InitHistory());
162 ASSERT_TRUE(InitVisited(0, true)); 187 ASSERT_TRUE(InitVisited(0, true));
163 188
164 for (int i = 0; i < g_test_count; i++) 189 for (int i = 0; i < g_test_count; i++)
165 master_->AddURL(TestURL(i)); 190 master_->AddURL(TestURL(i));
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 // complete. 391 // complete.
367 master_->set_rebuild_complete_task(new MessageLoop::QuitTask); 392 master_->set_rebuild_complete_task(new MessageLoop::QuitTask);
368 MessageLoop::current()->Run(); 393 MessageLoop::current()->Run();
369 394
370 // Test that all URLs were written to the database properly. 395 // Test that all URLs were written to the database properly.
371 Reload(); 396 Reload();
372 397
373 // Make sure the extra one was *not* written (Reload won't test this). 398 // Make sure the extra one was *not* written (Reload won't test this).
374 EXPECT_FALSE(master_->IsVisited(TestURL(g_test_count))); 399 EXPECT_FALSE(master_->IsVisited(TestURL(g_test_count)));
375 } 400 }
401
402 TEST_F(VisitedLinkTest, Listener) {
403 ASSERT_TRUE(InitHistory());
404 ASSERT_TRUE(InitVisited(0, true));
405
406 // Add test URLs.
407 for (int i = 0; i < g_test_count; i++) {
408 master_->AddURL(TestURL(i));
409 ASSERT_EQ(i + 1, master_->GetUsedCount());
410 }
411
412 std::set<GURL> deleted_urls;
413 deleted_urls.insert(TestURL(0));
414 // Delete an URL.
415 master_->DeleteURLs(deleted_urls);
416 // ... and all of the remaining ones.
417 master_->DeleteAllURLs();
418
419 // Verify that VisitedLinkMaster::Listener::Add was called for each added URL.
420 EXPECT_EQ(g_test_count, listener_.add_count());
421 // Verify that VisitedLinkMaster::Listener::Reset was called both when one and
422 // all URLs are deleted.
423 EXPECT_EQ(2, listener_.reset_count());
424 }
425
426 class VisitCountingProfile : public TestingProfile {
427 public:
428 explicit VisitCountingProfile(VisitedLinkEventListener* event_listener)
429 : add_count_(0),
430 add_event_count_(0),
431 reset_event_count_(0),
432 event_listener_(event_listener) {}
433
434 virtual VisitedLinkMaster* GetVisitedLinkMaster() {
435 if (!visited_link_master_.get()) {
436 visited_link_master_.reset(
437 new VisitedLinkMaster(NULL, event_listener_, this));
438 visited_link_master_->Init();
439 }
440 return visited_link_master_.get();
441 }
442
443 void CountAddEvent(int by) {
444 add_count_ += by;
445 add_event_count_++;
446 }
447
448 void CountResetEvent() {
449 reset_event_count_++;
450 }
451
452 VisitedLinkMaster* master() const { return visited_link_master_.get(); }
453 int add_count() const { return add_count_; }
454 int add_event_count() const { return add_event_count_; }
455 int reset_event_count() const { return reset_event_count_; }
456
457 private:
458 int add_count_;
459 int add_event_count_;
460 int reset_event_count_;
461 VisitedLinkEventListener* event_listener_;
462 scoped_ptr<VisitedLinkMaster> visited_link_master_;
463 };
464
465 class VisitCountingRenderProcessHost : public MockRenderProcessHost {
466 public:
467 explicit VisitCountingRenderProcessHost(Profile* profile)
468 : MockRenderProcessHost(profile) {}
469
470 virtual void AddVisitedLinks(
471 const VisitedLinkCommon::Fingerprints& visited_links) {
472 VisitCountingProfile* counting_profile =
473 static_cast<VisitCountingProfile*>(profile());
474 counting_profile->CountAddEvent(visited_links.size());
475 }
476 virtual void ResetVisitedLinks() {
477 VisitCountingProfile* counting_profile =
478 static_cast<VisitCountingProfile*>(profile());
479 counting_profile->CountResetEvent();
480 }
481
482 private:
483 DISALLOW_COPY_AND_ASSIGN(VisitCountingRenderProcessHost);
484 };
485
486 // Stub out as little as possible, borrowing from MockRenderProcessHost.
487 class VisitRelayingRenderProcessHost : public BrowserRenderProcessHost {
488 public:
489 explicit VisitRelayingRenderProcessHost(Profile* profile)
490 : BrowserRenderProcessHost(profile) {
491 static int prev_id = 0;
492 SetProcessID(++prev_id);
493 }
494 virtual ~VisitRelayingRenderProcessHost() {
495 RemoveFromList();
496 }
497
498 virtual bool Init() { return true; }
499
500 virtual void CancelResourceRequests(int render_widget_id) {
501 }
502
503 virtual void CrossSiteClosePageACK(int new_render_process_host_id,
504 int new_request_id) {
505 }
506
507 virtual bool WaitForPaintMsg(int render_widget_id,
508 const base::TimeDelta& max_delay,
509 IPC::Message* msg) {
510 return false;
511 }
512
513 virtual bool Send(IPC::Message* msg) {
514 VisitCountingProfile* counting_profile =
515 static_cast<VisitCountingProfile*>(profile());
516
517 if (msg->type() == ViewMsg_VisitedLink_Add::ID)
518 counting_profile->CountAddEvent(1);
519 else if (msg->type() == ViewMsg_VisitedLink_Reset::ID)
520 counting_profile->CountResetEvent();
521
522 delete msg;
523 return true;
524 }
525
526 virtual void SetBackgrounded(bool backgrounded) {
527 backgrounded_ = backgrounded;
528 }
529
530 private:
531 int add_relay_count_;
532 int reset_relay_count_;
533
534 DISALLOW_COPY_AND_ASSIGN(VisitRelayingRenderProcessHost);
535 };
536
537 class VisitedLinkRenderProcessHostFactory
538 : public MockRenderProcessHostFactory {
539 public:
540 VisitedLinkRenderProcessHostFactory()
541 : MockRenderProcessHostFactory(),
542 relay_mode_(false) {}
543 virtual RenderProcessHost* CreateRenderProcessHost(Profile* profile) const {
544 if (relay_mode_)
545 return new VisitRelayingRenderProcessHost(profile);
546 else
547 return new VisitCountingRenderProcessHost(profile);
548 }
549
550 void set_relay_mode(bool mode) { relay_mode_ = mode; }
551
552 private:
553 bool relay_mode_;
554
555 DISALLOW_COPY_AND_ASSIGN(VisitedLinkRenderProcessHostFactory);
556 };
557
558 class VisitedLinkEventsTest : public RenderViewHostTestHarness {
559 public:
560 VisitedLinkEventsTest() : RenderViewHostTestHarness() {}
561 virtual void SetFactoryMode() {}
562 virtual void SetUp() {
563 SetFactoryMode();
564 event_listener_.reset(new VisitedLinkEventListener());
565 rvh_factory_.set_render_process_host_factory(&vc_rph_factory_);
566 profile_.reset(new VisitCountingProfile(event_listener_.get()));
567 RenderViewHostTestHarness::SetUp();
568 }
569
570 VisitCountingProfile* profile() const {
571 return static_cast<VisitCountingProfile*>(profile_.get());
572 }
573
574 void WaitForCoalescense() {
575 // Let the timer fire.
576 MessageLoop::current()->PostDelayedTask(FROM_HERE,
577 new MessageLoop::QuitTask(), 110);
578 MessageLoop::current()->Run();
579 }
580
581 protected:
582 VisitedLinkRenderProcessHostFactory vc_rph_factory_;
583
584 private:
585 scoped_ptr<VisitedLinkEventListener> event_listener_;
586
587 DISALLOW_COPY_AND_ASSIGN(VisitedLinkEventsTest);
588 };
589
590 class VisitedLinkRelayTest : public VisitedLinkEventsTest {
591 public:
592 virtual void SetFactoryMode() { vc_rph_factory_.set_relay_mode(true); }
593 };
594
595 TEST_F(VisitedLinkEventsTest, Coalescense) {
596 // add some URLs to master.
597 VisitedLinkMaster* master = profile_->GetVisitedLinkMaster();
598 // Add a few URLs.
599 master->AddURL(GURL("http://acidtests.org/"));
600 master->AddURL(GURL("http://google.com/"));
601 master->AddURL(GURL("http://chromium.org/"));
602 // Just for kicks, add a duplicate URL. This shouldn't increase the resulting
603 master->AddURL(GURL("http://acidtests.org/"));
604
605 // Make sure that coalescing actually occurs. There should be no links or
606 // events received by the renderer.
607 EXPECT_EQ(0, profile()->add_count());
608 EXPECT_EQ(0, profile()->add_event_count());
609
610 WaitForCoalescense();
611
612 // We now should have 3 entries added in 1 event.
613 EXPECT_EQ(3, profile()->add_count());
614 EXPECT_EQ(1, profile()->add_event_count());
615
616 // Test whether the coalescing continues by adding a few more URLs.
617 master->AddURL(GURL("http://google.com/chrome/"));
618 master->AddURL(GURL("http://webkit.org/"));
619 master->AddURL(GURL("http://acid3.acidtests.org/"));
620
621 WaitForCoalescense();
622
623 // We should have 6 entries added in 2 events.
624 EXPECT_EQ(6, profile()->add_count());
625 EXPECT_EQ(2, profile()->add_event_count());
626
627 // Test whether duplicate entries produce add events.
628 master->AddURL(GURL("http://acidtests.org/"));
629
630 WaitForCoalescense();
631
632 // We should have no change in results.
633 EXPECT_EQ(6, profile()->add_count());
634 EXPECT_EQ(2, profile()->add_event_count());
635
636 // Ensure that the coalescing does not resume after resetting.
637 master->AddURL(GURL("http://build.chromium.org/"));
638 master->DeleteAllURLs();
639
640 WaitForCoalescense();
641
642 // We should have no change in results except for one new reset event.
643 EXPECT_EQ(6, profile()->add_count());
644 EXPECT_EQ(2, profile()->add_event_count());
645 EXPECT_EQ(1, profile()->reset_event_count());
646 }
647
648 TEST_F(VisitedLinkRelayTest, Basics) {
649 VisitedLinkMaster* master = profile_->GetVisitedLinkMaster();
650 // Add a few URLs.
651 master->AddURL(GURL("http://acidtests.org/"));
652 master->AddURL(GURL("http://google.com/"));
653 master->AddURL(GURL("http://chromium.org/"));
654
655 WaitForCoalescense();
656
657 // We now should have 1 add event.
658 EXPECT_EQ(1, profile()->add_event_count());
659 EXPECT_EQ(0, profile()->reset_event_count());
660
661 master->DeleteAllURLs();
662
663 WaitForCoalescense();
664
665 // We should have no change in add results, plus one new reset event.
666 EXPECT_EQ(1, profile()->add_event_count());
667 EXPECT_EQ(1, profile()->reset_event_count());
668 }
669
670 TEST_F(VisitedLinkRelayTest, TabVisibility) {
671 VisitedLinkMaster* master = profile_->GetVisitedLinkMaster();
672
673 // Simulate tab becoming inactive.
674 rvh()->WasHidden();
675
676 // Add a few URLs.
677 master->AddURL(GURL("http://acidtests.org/"));
678 master->AddURL(GURL("http://google.com/"));
679 master->AddURL(GURL("http://chromium.org/"));
680
681 WaitForCoalescense();
682
683 // We shouldn't have any events.
684 EXPECT_EQ(0, profile()->add_event_count());
685 EXPECT_EQ(0, profile()->reset_event_count());
686
687 // Simulate the tab becoming active.
688 rvh()->WasRestored();
689
690 // We should now have 3 add events, still no reset events.
691 EXPECT_EQ(1, profile()->add_event_count());
692 EXPECT_EQ(0, profile()->reset_event_count());
693
694 // Deactivate the tab again.
695 rvh()->WasHidden();
696
697 // Add a bunch of URLs (over 50) to exhaust the link event buffer.
698 for (int i = 0; i < 100; i++)
699 master->AddURL(TestURL(i));
700
701 WaitForCoalescense();
702
703 // Again, no change in events until tab is active.
704 EXPECT_EQ(1, profile()->add_event_count());
705 EXPECT_EQ(0, profile()->reset_event_count());
706
707 // Activate the tab.
708 rvh()->WasRestored();
709
710 // We should have only one more reset event.
711 EXPECT_EQ(1, profile()->add_event_count());
712 EXPECT_EQ(1, profile()->reset_event_count());
713 }
OLDNEW
« no previous file with comments | « chrome/browser/visitedlink_perftest.cc ('k') | chrome/chrome.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698