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.
5 #include "base/file_util.h"
6 #include "base/path_service.h"
7 #include "base/prefs/testing_pref_service.h"
8 #include "base/run_loop.h"
9 #include "base/strings/string_split.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/threading/sequenced_worker_pool.h"
13 #include "chrome/app/chrome_command_ids.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/page_cycler/page_cycler.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_list.h"
18 #include "chrome/browser/ui/tabs/tab_strip_model.h"
19 #include "chrome/common/chrome_paths.h"
20 #include "chrome/common/url_constants.h"
21 #include "chrome/test/base/browser_with_test_window_test.h"
22 #include "content/public/browser/render_view_host.h"
23 #include "content/public/test/test_browser_thread.h"
24 #include "net/base/net_errors.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
29 using ::testing::Invoke
;
30 using content::RenderViewHost
;
31 using content::TestBrowserThread
;
32 using content::WebContentsObserver
;
33 using base::ContentsEqual
;
34 using base::PathExists
;
37 const int kFrameID
= 1;
38 const bool kIsMainFrame
= true;
39 const GURL kAboutURL
= GURL(content::kAboutBlankURL
);
42 class MockPageCycler
: public PageCycler
{
44 MockPageCycler(Browser
* browser
, base::FilePath urls_file
,
45 base::FilePath errors_file
)
46 : PageCycler(browser
, urls_file
) {
47 set_errors_file(errors_file
);
50 MockPageCycler(Browser
* browser
,
51 base::FilePath urls_file
,
52 base::FilePath errors_file
,
53 base::FilePath stats_file
)
54 : PageCycler(browser
, urls_file
) {
55 set_stats_file(stats_file
);
56 set_errors_file(errors_file
);
59 MOCK_METHOD4(DidFinishLoad
, void(int64 frame_id
,
60 const GURL
& validated_url
,
62 RenderViewHost
* render_view_host
));
63 MOCK_METHOD6(DidFailProvisionalLoad
, void(int64 frame_id
,
65 const GURL
& validated_url
,
67 const string16
& error_description
,
68 RenderViewHost
* render_view_host
));
69 MOCK_METHOD1(RenderProcessGone
, void(base::TerminationStatus status
));
71 void PageCyclerDidFailProvisionalLoad(
74 const GURL
& validated_url
,
76 const string16
& error_description
,
77 RenderViewHost
* render_view_host
) {
78 PageCycler::DidFailProvisionalLoad(frame_id
, is_main_frame
,
80 error_code
, error_description
,
84 void PageCyclerDidFinishLoad(int64 frame_id
,
85 const GURL
& validated_url
,
87 RenderViewHost
* render_view_host
) {
88 PageCycler::DidFinishLoad(
89 frame_id
, validated_url
, is_main_frame
, render_view_host
);
93 // We need to override Finish() because the calls to exit the browser in a
94 // real PageCycler do not work in unittests (they interfere with later tests).
95 virtual void Finish() OVERRIDE
{
96 BrowserList::RemoveObserver(this);
100 virtual ~MockPageCycler() {}\
102 DISALLOW_COPY_AND_ASSIGN(MockPageCycler
);
105 class PageCyclerTest
: public BrowserWithTestWindowTest
{
110 virtual ~PageCyclerTest() {
113 virtual void SetUp() OVERRIDE
{
114 PathService::Get(chrome::DIR_TEST_DATA
, &test_data_dir_
);
115 test_data_dir_
= test_data_dir_
.AppendASCII("page_cycler");
117 BrowserWithTestWindowTest::SetUp();
118 AddTab(browser(), kAboutURL
);
119 ASSERT_FALSE(browser()->tab_strip_model()->GetActiveWebContents() == NULL
);
122 void InitFilePaths(const base::FilePath
& temp_path
) {
123 errors_file_
= temp_path
.AppendASCII("errors_file");
124 stats_file_
= temp_path
.AppendASCII("stats_file");
126 CHECK(!base::PathExists(errors_file_
));
127 CHECK(!base::PathExists(stats_file_
));
130 void FailProvisionalLoad(int error_code
, string16
& error_description
) {
134 DidFailProvisionalLoad(kFrameID
, kIsMainFrame
, kAboutURL
, error_code
,
135 error_description
, NULL
));
143 DidFinishLoad(kFrameID
, kAboutURL
, kIsMainFrame
, NULL
));
147 void RunPageCycler() {
153 content::BrowserThread::GetBlockingPool()->FlushForTesting();
154 base::RunLoop().RunUntilIdle();
157 void CloseBrowser() {
158 DestroyBrowserAndProfile();
162 MockPageCycler
* page_cycler() {
163 return page_cycler_
.get();
166 void set_page_cycler(MockPageCycler
* page_cycler
) {
167 page_cycler_
= page_cycler
;
168 observers_
.AddObserver(page_cycler
);
171 const std::vector
<GURL
>* urls_for_test() {
172 return page_cycler_
->urls_for_test();
175 base::FilePath
stats_file() {
179 base::FilePath
errors_file() {
183 base::FilePath
urls_file() {
184 return test_data_dir_
.AppendASCII("about_url");
187 base::FilePath
test_data_dir() {
188 return test_data_dir_
;
192 ObserverList
<WebContentsObserver
> observers_
;
193 scoped_refptr
<MockPageCycler
> page_cycler_
;
194 base::FilePath test_data_dir_
;
195 base::FilePath stats_file_
;
196 base::FilePath errors_file_
;
197 base::FilePath urls_file_
;
200 TEST_F(PageCyclerTest
, FailProvisionalLoads
) {
201 const base::FilePath errors_expected_file
=
202 test_data_dir().AppendASCII("errors_expected");
204 base::ScopedTempDir temp
;
205 ASSERT_TRUE(temp
.CreateUniqueTempDir());
206 InitFilePaths(temp
.path());
208 ASSERT_TRUE(PathExists(errors_expected_file
));
209 ASSERT_TRUE(PathExists(urls_file()));
211 set_page_cycler(new MockPageCycler(browser(),
216 // Page cycler expects browser to automatically start loading the first page.
217 EXPECT_CALL(*page_cycler(),
218 DidFinishLoad(kFrameID
, kAboutURL
, kIsMainFrame
, _
))
219 .WillOnce(Invoke(page_cycler(),
220 &MockPageCycler::PageCyclerDidFinishLoad
));
223 // DNS server fail error message.
224 string16 error_string
=
225 string16(ASCIIToUTF16(net::ErrorToString(net::ERR_DNS_SERVER_FAILED
)));
226 EXPECT_CALL(*page_cycler(),
227 DidFailProvisionalLoad(kFrameID
, kIsMainFrame
, _
,
228 net::ERR_DNS_SERVER_FAILED
, error_string
,
230 .WillOnce(Invoke(page_cycler(),
231 &MockPageCycler::PageCyclerDidFailProvisionalLoad
));
232 FailProvisionalLoad(net::ERR_DNS_SERVER_FAILED
, error_string
);
234 // DNS time-out error message.
235 error_string
= string16(
236 ASCIIToUTF16(net::ErrorToString(net::ERR_DNS_TIMED_OUT
)));
237 EXPECT_CALL(*page_cycler(),
238 DidFailProvisionalLoad(kFrameID
,
239 kIsMainFrame
, _
, net::ERR_DNS_TIMED_OUT
,
241 .WillOnce(Invoke(page_cycler(),
242 &MockPageCycler::PageCyclerDidFailProvisionalLoad
));
244 FailProvisionalLoad(net::ERR_DNS_TIMED_OUT
, error_string
);
246 // DNS time-out error message.
247 error_string
= string16(
248 ASCIIToUTF16(net::ErrorToString(net::ERR_INVALID_URL
)));
249 EXPECT_CALL(*page_cycler(),
250 DidFailProvisionalLoad(kFrameID
, kIsMainFrame
, _
,
251 net::ERR_INVALID_URL
, error_string
, _
))
252 .WillOnce(Invoke(page_cycler(),
253 &MockPageCycler::PageCyclerDidFailProvisionalLoad
));
254 FailProvisionalLoad(net::ERR_INVALID_URL
, error_string
);
258 std::string errors_output
;
259 std::string errors_expected
;
260 ASSERT_TRUE(base::ReadFileToString(errors_file(), &errors_output
));
261 ASSERT_TRUE(base::ReadFileToString(errors_expected_file
, &errors_expected
));
262 ASSERT_EQ(errors_output
, errors_expected
);
265 TEST_F(PageCyclerTest
, StatsFile
) {
266 const int kNumLoads
= 4;
268 base::ScopedTempDir temp
;
269 ASSERT_TRUE(temp
.CreateUniqueTempDir());
270 InitFilePaths(temp
.path());
272 ASSERT_TRUE(PathExists(urls_file()));
274 set_page_cycler(new MockPageCycler(browser(), urls_file(),
276 page_cycler()->set_stats_file(stats_file());
279 for (int i
= 0; i
< kNumLoads
; ++i
) {
280 EXPECT_CALL(*page_cycler(), DidFinishLoad(
281 kFrameID
, kAboutURL
, kIsMainFrame
, _
))
282 .WillOnce(Invoke(page_cycler(),
283 &MockPageCycler::PageCyclerDidFinishLoad
));
288 EXPECT_FALSE(PathExists(errors_file()));
289 ASSERT_TRUE(PathExists(stats_file()));
292 TEST_F(PageCyclerTest
, KillBrowserAndAbort
) {
293 const base::FilePath errors_expected_file
=
294 test_data_dir().AppendASCII("abort_expected");
296 base::ScopedTempDir temp
;
297 ASSERT_TRUE(temp
.CreateUniqueTempDir());
298 InitFilePaths(temp
.path());
300 ASSERT_TRUE(PathExists(errors_expected_file
));
301 ASSERT_TRUE(PathExists(urls_file()));
303 set_page_cycler(new MockPageCycler(browser(),
308 EXPECT_CALL(*page_cycler(),
309 DidFinishLoad(kFrameID
, kAboutURL
, kIsMainFrame
, _
))
310 .WillOnce(Invoke(page_cycler(),
311 &MockPageCycler::PageCyclerDidFinishLoad
));
312 base::RunLoop().RunUntilIdle();
319 std::string errors_output
;
320 std::string errors_expected
;
321 ASSERT_TRUE(base::ReadFileToString(errors_file(), &errors_output
));
322 ASSERT_TRUE(base::ReadFileToString(errors_expected_file
, &errors_expected
));
323 ASSERT_EQ(errors_output
, errors_expected
);
326 TEST_F(PageCyclerTest
, MultipleIterations
) {
327 const int kNumLoads
= 4;
329 base::ScopedTempDir temp
;
330 ASSERT_TRUE(temp
.CreateUniqueTempDir());
331 InitFilePaths(temp
.path());
333 ASSERT_TRUE(PathExists(urls_file()));
335 set_page_cycler(new MockPageCycler(browser(),
338 page_cycler()->set_stats_file(stats_file());
341 EXPECT_CALL(*page_cycler(),
342 DidFinishLoad(kFrameID
, kAboutURL
, kIsMainFrame
, _
))
343 .WillRepeatedly(Invoke(page_cycler(),
344 &MockPageCycler::PageCyclerDidFinishLoad
));
346 for (int i
= 0; i
< kNumLoads
; ++i
)
350 EXPECT_FALSE(PathExists(errors_file()));
351 ASSERT_TRUE(PathExists(stats_file()));