• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
Checkpoint(const char * message,const base::TimeTicks & start_time)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:
WaitForHistoryTask()38   WaitForHistoryTask() {
39   }
40 
RunOnDBThread(history::HistoryBackend * backend,history::HistoryDatabase * db)41   virtual bool RunOnDBThread(history::HistoryBackend* backend,
42                              history::HistoryDatabase* db) {
43     return true;
44   }
45 
DoneRunOnMainThread()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:
HistoryEnumerator(HistoryService * history)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 
OnURL(const GURL & url)69   virtual void OnURL(const GURL& url) {
70     urls_.push_back(url);
71   }
72 
OnComplete(bool success)73   virtual void OnComplete(bool success) {
74     BrowserThread::PostTask(
75         BrowserThread::UI,
76         FROM_HERE,
77         new MessageLoop::QuitTask());
78   }
79 
urls()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:
GetPrefs()90   PrefService* GetPrefs() {
91     return GetProfile()->GetPrefs();
92   }
93 
GetProfile()94   Profile* GetProfile() {
95     return browser()->GetProfile();
96   }
97 
GetHistoryService()98   HistoryService* GetHistoryService() {
99     return GetProfile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
100   }
101 
GetHistoryContents()102   std::vector<GURL> GetHistoryContents() {
103     HistoryEnumerator enumerator(GetHistoryService());
104     return enumerator.urls();
105   }
106 
GetTestUrl()107   GURL GetTestUrl() {
108     return ui_test_utils::GetTestUrl(
109         FilePath(FilePath::kCurrentDirectory),
110         FilePath(FILE_PATH_LITERAL("title2.html")));
111   }
112 
WaitForHistoryBackendToRun()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 
ExpectEmptyHistory()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).
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,SavingHistoryEnabled)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,SavingHistoryDisabled)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,SavingHistoryEnabledThenDisabled)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,SavingHistoryDisabledThenEnabled)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