Home | History | Annotate | Download | only in history
      1 // Copyright (c) 2010 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 <vector>
      6 
      7 #include "base/message_loop.h"
      8 #include "chrome/browser/history/history.h"
      9 #include "chrome/browser/prefs/pref_service.h"
     10 #include "chrome/browser/profiles/profile.h"
     11 #include "chrome/browser/ui/browser.h"
     12 #include "chrome/common/pref_names.h"
     13 #include "chrome/test/in_process_browser_test.h"
     14 #include "chrome/test/ui_test_utils.h"
     15 #include "content/browser/browser_thread.h"
     16 #include "googleurl/src/gurl.h"
     17 
     18 namespace {
     19 
     20 // Helper to debug intermittent test hangs/timeouts.
     21 // TODO(phajdan.jr): remove when http://crbug.com/57994 is fixed.
     22 void Checkpoint(const char* message, const base::TimeTicks& start_time) {
     23   LOG(INFO) << message << " : "
     24             << (base::TimeTicks::Now() - start_time).InMilliseconds()
     25             << " ms" << std::flush;
     26 }
     27 
     28 // Note: WaitableEvent is not used for synchronization between the main thread
     29 // and history backend thread because the history subsystem posts tasks back
     30 // to the main thread. Had we tried to Signal an event in such a task
     31 // and Wait for it on the main thread, the task would not run at all because
     32 // the main thread would be blocked on the Wait call, resulting in a deadlock.
     33 
     34 // A task to be scheduled on the history backend thread.
     35 // Notifies the main thread after all history backend thread tasks have run.
     36 class WaitForHistoryTask : public HistoryDBTask {
     37  public:
     38   WaitForHistoryTask() {
     39   }
     40 
     41   virtual bool RunOnDBThread(history::HistoryBackend* backend,
     42                              history::HistoryDatabase* db) {
     43     return true;
     44   }
     45 
     46   virtual void DoneRunOnMainThread() {
     47     MessageLoop::current()->Quit();
     48   }
     49 
     50  private:
     51   DISALLOW_COPY_AND_ASSIGN(WaitForHistoryTask);
     52 };
     53 
     54 // Enumerates all history contents on the backend thread.
     55 class HistoryEnumerator : public HistoryService::URLEnumerator {
     56  public:
     57   explicit HistoryEnumerator(HistoryService* history) {
     58     EXPECT_TRUE(history);
     59     if (!history)
     60       return;
     61 
     62     BrowserThread::PostTask(
     63         BrowserThread::UI,
     64         FROM_HERE,
     65         NewRunnableMethod(history, &HistoryService::IterateURLs, this));
     66     ui_test_utils::RunMessageLoop();
     67   }
     68 
     69   virtual void OnURL(const GURL& url) {
     70     urls_.push_back(url);
     71   }
     72 
     73   virtual void OnComplete(bool success) {
     74     BrowserThread::PostTask(
     75         BrowserThread::UI,
     76         FROM_HERE,
     77         new MessageLoop::QuitTask());
     78   }
     79 
     80   std::vector<GURL>& urls() { return urls_; }
     81 
     82  private:
     83   std::vector<GURL> urls_;
     84 
     85   DISALLOW_COPY_AND_ASSIGN(HistoryEnumerator);
     86 };
     87 
     88 class HistoryBrowserTest : public InProcessBrowserTest {
     89  protected:
     90   PrefService* GetPrefs() {
     91     return GetProfile()->GetPrefs();
     92   }
     93 
     94   Profile* GetProfile() {
     95     return browser()->GetProfile();
     96   }
     97 
     98   HistoryService* GetHistoryService() {
     99     return GetProfile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
    100   }
    101 
    102   std::vector<GURL> GetHistoryContents() {
    103     HistoryEnumerator enumerator(GetHistoryService());
    104     return enumerator.urls();
    105   }
    106 
    107   GURL GetTestUrl() {
    108     return ui_test_utils::GetTestUrl(
    109         FilePath(FilePath::kCurrentDirectory),
    110         FilePath(FILE_PATH_LITERAL("title2.html")));
    111   }
    112 
    113   void WaitForHistoryBackendToRun() {
    114     CancelableRequestConsumerTSimple<int> request_consumer;
    115     scoped_refptr<HistoryDBTask> task(new WaitForHistoryTask());
    116     HistoryService* history = GetHistoryService();
    117     BrowserThread::PostTask(BrowserThread::UI,
    118                             FROM_HERE,
    119                             NewRunnableMethod(history,
    120                                               &HistoryService::ScheduleDBTask,
    121                                               task,
    122                                               &request_consumer));
    123     ui_test_utils::RunMessageLoop();
    124   }
    125 
    126   void ExpectEmptyHistory() {
    127     std::vector<GURL> urls(GetHistoryContents());
    128     EXPECT_EQ(0U, urls.size());
    129   }
    130 };
    131 
    132 // Test that the browser history is saved (default setting).
    133 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, SavingHistoryEnabled) {
    134   EXPECT_FALSE(GetPrefs()->GetBoolean(prefs::kSavingBrowserHistoryDisabled));
    135 
    136   EXPECT_TRUE(GetProfile()->GetHistoryService(Profile::EXPLICIT_ACCESS));
    137   EXPECT_TRUE(GetProfile()->GetHistoryService(Profile::IMPLICIT_ACCESS));
    138 
    139   ui_test_utils::WaitForHistoryToLoad(browser());
    140   ExpectEmptyHistory();
    141 
    142   ui_test_utils::NavigateToURL(browser(), GetTestUrl());
    143   WaitForHistoryBackendToRun();
    144 
    145   {
    146     std::vector<GURL> urls(GetHistoryContents());
    147     ASSERT_EQ(1U, urls.size());
    148     EXPECT_EQ(GetTestUrl().spec(), urls[0].spec());
    149   }
    150 }
    151 
    152 // Test that disabling saving browser history really works.
    153 // TODO(phajdan.jr): remove debug code when http://crbug.com/57994 is fixed.
    154 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, SavingHistoryDisabled) {
    155   base::TimeTicks start_time = base::TimeTicks::Now();
    156 
    157   GetPrefs()->SetBoolean(prefs::kSavingBrowserHistoryDisabled, true);
    158 
    159   EXPECT_TRUE(GetProfile()->GetHistoryService(Profile::EXPLICIT_ACCESS));
    160   EXPECT_FALSE(GetProfile()->GetHistoryService(Profile::IMPLICIT_ACCESS));
    161 
    162   Checkpoint("Before waiting for history to load", start_time);
    163   ui_test_utils::WaitForHistoryToLoad(browser());
    164   Checkpoint("After waiting for history to load", start_time);
    165   ExpectEmptyHistory();
    166   Checkpoint("After checking history", start_time);
    167 
    168   ui_test_utils::NavigateToURL(browser(), GetTestUrl());
    169   Checkpoint("After NavigateToURL", start_time);
    170   WaitForHistoryBackendToRun();
    171   Checkpoint("After waiting for history backend to run", start_time);
    172   ExpectEmptyHistory();
    173   Checkpoint("After second check", start_time);
    174 }
    175 
    176 // Test that changing the pref takes effect immediately
    177 // when the browser is running.
    178 // TODO(phajdan.jr): remove debug code when http://crbug.com/57994 is fixed.
    179 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, SavingHistoryEnabledThenDisabled) {
    180   base::TimeTicks start_time = base::TimeTicks::Now();
    181 
    182   EXPECT_FALSE(GetPrefs()->GetBoolean(prefs::kSavingBrowserHistoryDisabled));
    183 
    184   Checkpoint("Before waiting for history to load", start_time);
    185   ui_test_utils::WaitForHistoryToLoad(browser());
    186   Checkpoint("After waiting for history to load", start_time);
    187 
    188   ui_test_utils::NavigateToURL(browser(), GetTestUrl());
    189   Checkpoint("After first NavigateToURL", start_time);
    190   WaitForHistoryBackendToRun();
    191   Checkpoint("After waiting for history backend to run", start_time);
    192 
    193   {
    194     std::vector<GURL> urls(GetHistoryContents());
    195     Checkpoint("After first GetHistoryContents", start_time);
    196     ASSERT_EQ(1U, urls.size());
    197     EXPECT_EQ(GetTestUrl().spec(), urls[0].spec());
    198   }
    199 
    200   GetPrefs()->SetBoolean(prefs::kSavingBrowserHistoryDisabled, true);
    201 
    202   ui_test_utils::NavigateToURL(browser(), GetTestUrl());
    203   Checkpoint("After second NavigateToURL", start_time);
    204   WaitForHistoryBackendToRun();
    205   Checkpoint("After waiting for history backend to run (2nd time)", start_time);
    206 
    207   {
    208     // No additional entries should be present in the history.
    209     std::vector<GURL> urls(GetHistoryContents());
    210     Checkpoint("After second GetHistoryContents", start_time);
    211     ASSERT_EQ(1U, urls.size());
    212     EXPECT_EQ(GetTestUrl().spec(), urls[0].spec());
    213   }
    214 }
    215 
    216 // Test that changing the pref takes effect immediately
    217 // when the browser is running.
    218 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, SavingHistoryDisabledThenEnabled) {
    219   GetPrefs()->SetBoolean(prefs::kSavingBrowserHistoryDisabled, true);
    220 
    221   ui_test_utils::WaitForHistoryToLoad(browser());
    222   ExpectEmptyHistory();
    223 
    224   ui_test_utils::NavigateToURL(browser(), GetTestUrl());
    225   WaitForHistoryBackendToRun();
    226   ExpectEmptyHistory();
    227 
    228   GetPrefs()->SetBoolean(prefs::kSavingBrowserHistoryDisabled, false);
    229 
    230   ui_test_utils::NavigateToURL(browser(), GetTestUrl());
    231   WaitForHistoryBackendToRun();
    232 
    233   {
    234     std::vector<GURL> urls(GetHistoryContents());
    235     ASSERT_EQ(1U, urls.size());
    236     EXPECT_EQ(GetTestUrl().spec(), urls[0].spec());
    237   }
    238 }
    239 
    240 }  // namespace
    241