OLD | NEW |
---|---|
(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 "base/file_util.h" | |
6 #include "base/path_service.h" | |
7 #include "base/string_split.h" | |
8 #include "base/string_util.h" | |
9 #include "base/threading/sequenced_worker_pool.h" | |
10 #include "base/utf_string_conversions.h" | |
11 #include "chrome/app/chrome_command_ids.h" | |
12 #include "chrome/browser/browser_process.h" | |
13 #include "chrome/browser/page_cycler/page_cycler.h" | |
14 #include "chrome/common/chrome_paths.h" | |
15 #include "chrome/common/url_constants.h" | |
16 #include "chrome/test/base/browser_with_test_window_test.h" | |
17 #include "chrome/test/base/testing_pref_service.h" | |
18 #include "content/public/browser/render_view_host.h" | |
19 #include "content/test/test_browser_thread.h" | |
20 #include "net/base/net_errors.h" | |
21 #include "testing/gmock/include/gmock/gmock.h" | |
22 #include "testing/gtest/include/gtest/gtest.h" | |
23 | |
24 using ::testing::_; | |
25 using ::testing::Invoke; | |
26 using content::RenderViewHost; | |
27 using content::TestBrowserThread; | |
28 using content::WebContentsObserver; | |
29 using file_util::ContentsEqual; | |
30 using file_util::PathExists; | |
31 | |
32 namespace { | |
33 const int kFrameID = 1; | |
34 const bool kIsMainFrame = true; | |
35 const GURL kAboutURL = GURL(chrome::kAboutBlankURL); | |
36 const int kSingleIteration = 1; | |
37 | |
38 bool LinesAreEqual(std::vector<std::string>& file_a, | |
39 std::vector<std::string>& file_b) { | |
40 if (file_a.size() != file_b.size()) | |
Aaron Boodman
2012/05/29 21:39:08
I believe that you can just use std::equal?
Aaron Boodman
2012/05/30 01:08:42
In case this wasn't clear, I meant you can just us
Devlin
2012/05/30 01:45:15
Done.
| |
41 return false; | |
42 | |
43 for (std::vector<std::string>::const_iterator it_a = file_a.begin(), | |
44 it_b = file_b.begin(); it_a != file_a.end() && it_b != file_b.end(); | |
45 ++it_a, ++it_b) { | |
46 if (*it_a != *it_b) | |
47 return false; | |
48 } | |
49 return true; | |
50 } | |
51 | |
52 // Read the file, and generate a vector of strings. | |
53 std::vector<std::string> GetLinesFromFile(FilePath file) { | |
54 std::string file_contents; | |
55 CHECK(file_util::ReadFileToString(file, &file_contents)); | |
56 if (file_contents[file_contents.size() - 1] == '\n') { | |
Aaron Boodman
2012/05/29 21:39:08
No curly brace is required here.
Devlin
2012/05/30 01:45:15
Done.
| |
57 file_contents = file_contents.substr(0, file_contents.size() - 1); | |
Aaron Boodman
2012/05/29 21:39:08
file_contents.resize()
Devlin
2012/05/30 01:45:15
Done.
| |
58 } | |
59 | |
60 std::vector<std::string> lines; | |
61 base::SplitString(file_contents, '\n', &lines); | |
62 | |
63 return lines; | |
64 } | |
65 | |
66 } // namespace | |
67 | |
68 class MockPageCycler : public PageCycler { | |
69 public: | |
70 MockPageCycler(Browser* browser, FilePath urls_file, FilePath errors_file) | |
71 : PageCycler(browser, urls_file) { | |
72 set_errors_file(errors_file); | |
73 } | |
74 | |
75 MockPageCycler(Browser* browser, | |
76 FilePath urls_file, | |
77 FilePath errors_file, | |
78 FilePath stats_file) | |
79 : PageCycler(browser, urls_file) { | |
80 set_stats_file(stats_file); | |
81 set_errors_file(errors_file); | |
82 } | |
83 | |
84 MOCK_METHOD3(DidFinishLoad, void(int64 frame_id, | |
85 const GURL& validated_url, | |
86 bool is_main_frame)); | |
87 MOCK_METHOD6(DidFailProvisionalLoad, void(int64 frame_id, | |
88 bool is_main_frame, | |
89 const GURL& validated_url, | |
90 int error_code, | |
91 const string16& error_description, | |
92 RenderViewHost* render_view_host)); | |
93 MOCK_METHOD1(RenderViewGone, void(base::TerminationStatus status)); | |
94 | |
95 void PageCyclerDidFailProvisionalLoad( | |
96 int64 frame_id, | |
97 bool is_main_frame, | |
98 const GURL& validated_url, | |
99 int error_code, | |
100 const string16& error_description, | |
101 RenderViewHost* render_view_host) { | |
102 PageCycler::DidFailProvisionalLoad(frame_id, is_main_frame, | |
103 validated_url, | |
104 error_code, error_description, | |
105 render_view_host); | |
106 } | |
107 | |
108 void PageCyclerDidFinishLoad(int64 frame_id, | |
109 const GURL& validated_url, | |
110 bool is_main_frame) { | |
111 PageCycler::DidFinishLoad(frame_id, validated_url, is_main_frame); | |
112 } | |
113 | |
114 private: | |
115 virtual ~MockPageCycler() {} | |
116 DISALLOW_COPY_AND_ASSIGN(MockPageCycler); | |
117 }; | |
118 | |
119 class PageCyclerTest : public BrowserWithTestWindowTest { | |
120 public: | |
121 PageCyclerTest() {} | |
122 ~PageCyclerTest() {} | |
123 | |
124 virtual void SetUp() OVERRIDE; | |
125 void FailProvisionalLoad(int error_code, string16& error_description); | |
126 void FinishLoad(); | |
127 void RunPageCycler(int total_iterations); | |
128 void PumpLoop(); | |
129 void CloseBrowser(); | |
130 | |
131 MockPageCycler* page_cycler() { | |
132 return page_cycler_.get(); | |
133 } | |
134 | |
135 void set_page_cycler(MockPageCycler* page_cycler) { | |
136 page_cycler_ = page_cycler; | |
137 observers_.AddObserver(page_cycler); | |
138 } | |
139 | |
140 const std::vector<GURL>* urls_for_test() { | |
141 return page_cycler_->urls_for_test(); | |
142 } | |
143 | |
144 FilePath stats_output_file_path() { | |
145 return test_data_dir_.AppendASCII("stats_output"); | |
146 } | |
147 | |
148 FilePath abort_expected_file_path() { | |
149 return test_data_dir_.AppendASCII("abort_expected"); | |
150 } | |
151 | |
152 FilePath errors_output_file_path() { | |
153 return test_data_dir_.AppendASCII("errors_output"); | |
154 } | |
155 | |
156 FilePath errors_expected_file_path() { | |
157 return test_data_dir_.AppendASCII("errors_expected"); | |
158 } | |
159 | |
160 FilePath about_url_file_path() { | |
161 return test_data_dir_.AppendASCII("about_url"); | |
162 } | |
163 | |
164 private: | |
165 ObserverList<WebContentsObserver> observers_; | |
166 scoped_refptr<MockPageCycler> page_cycler_; | |
167 FilePath test_data_dir_; | |
168 }; | |
169 | |
170 void PageCyclerTest::SetUp() { | |
171 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_); | |
172 test_data_dir_ = test_data_dir_.AppendASCII("page_cycler"); | |
173 | |
174 BrowserWithTestWindowTest::SetUp(); | |
175 AddTab(browser(), kAboutURL); | |
176 ASSERT_FALSE(browser()->GetSelectedWebContents() == NULL); | |
177 } | |
178 | |
179 void PageCyclerTest::FailProvisionalLoad(int error_code, | |
180 string16& error_description) { | |
181 FOR_EACH_OBSERVER(WebContentsObserver, | |
182 observers_, | |
183 DidFailProvisionalLoad(kFrameID, kIsMainFrame, kAboutURL, error_code, | |
184 error_description, NULL)); | |
185 PumpLoop(); | |
186 } | |
187 | |
188 void PageCyclerTest::FinishLoad() { | |
189 FOR_EACH_OBSERVER(WebContentsObserver, | |
190 observers_, | |
191 DidFinishLoad(kFrameID, kAboutURL, kIsMainFrame)); | |
192 PumpLoop(); | |
193 } | |
194 | |
195 void PageCyclerTest::RunPageCycler(int total_iterations) { | |
196 page_cycler_->Run(total_iterations); | |
197 PumpLoop(); | |
198 } | |
199 | |
200 void PageCyclerTest::PumpLoop() { | |
201 content::BrowserThread::GetBlockingPool()->FlushForTesting(); | |
202 message_loop()->RunAllPending(); | |
203 } | |
204 | |
205 void PageCyclerTest::CloseBrowser() { | |
206 browser()->OnWindowClosing(); | |
207 DestroyBrowser(); | |
208 PumpLoop(); | |
209 } | |
210 | |
211 TEST_F(PageCyclerTest, FailProvisionalLoads) { | |
212 ASSERT_TRUE(PathExists(errors_expected_file_path())); | |
213 ASSERT_TRUE(PathExists(about_url_file_path())); | |
214 | |
215 set_page_cycler(new MockPageCycler(browser(), | |
216 about_url_file_path(), | |
217 errors_output_file_path())); | |
218 RunPageCycler(kSingleIteration); | |
219 | |
220 // Page cycler expects browser to automatically start loading the first page. | |
221 EXPECT_CALL(*page_cycler(), DidFinishLoad(kFrameID, kAboutURL, kIsMainFrame)) | |
222 .WillOnce(Invoke(page_cycler(), | |
223 &MockPageCycler::PageCyclerDidFinishLoad)); | |
224 FinishLoad(); | |
225 | |
226 // DNS server fail error message. | |
227 string16 error_string = | |
228 string16(ASCIIToUTF16(net::ErrorToString(net::ERR_DNS_SERVER_FAILED))); | |
229 EXPECT_CALL(*page_cycler(), | |
230 DidFailProvisionalLoad(kFrameID, kIsMainFrame, _, | |
231 net::ERR_DNS_SERVER_FAILED, error_string, | |
232 _)) | |
233 .WillOnce(Invoke(page_cycler(), | |
234 &MockPageCycler::PageCyclerDidFailProvisionalLoad)); | |
235 FailProvisionalLoad(net::ERR_DNS_SERVER_FAILED, error_string); | |
236 | |
237 // DNS time-out error message. | |
238 error_string = string16( | |
239 ASCIIToUTF16(net::ErrorToString(net::ERR_DNS_TIMED_OUT))); | |
240 EXPECT_CALL(*page_cycler(), | |
241 DidFailProvisionalLoad(kFrameID, | |
242 kIsMainFrame, _, net::ERR_DNS_TIMED_OUT, | |
243 error_string, _)) | |
244 .WillOnce(Invoke(page_cycler(), | |
245 &MockPageCycler::PageCyclerDidFailProvisionalLoad)); | |
246 | |
247 FailProvisionalLoad(net::ERR_DNS_TIMED_OUT, error_string); | |
248 | |
249 // DNS time-out error message. | |
250 error_string = string16( | |
251 ASCIIToUTF16(net::ErrorToString(net::ERR_INVALID_URL))); | |
252 EXPECT_CALL(*page_cycler(), | |
253 DidFailProvisionalLoad(kFrameID, kIsMainFrame, _, | |
254 net::ERR_INVALID_URL, error_string, _)) | |
255 .WillOnce(Invoke(page_cycler(), | |
256 &MockPageCycler::PageCyclerDidFailProvisionalLoad)); | |
257 FailProvisionalLoad(net::ERR_INVALID_URL, error_string); | |
258 | |
259 PumpLoop(); | |
260 | |
261 std::vector<std::string> errors_output = | |
262 GetLinesFromFile(errors_output_file_path()); | |
263 std::vector<std::string> errors_expected = | |
264 GetLinesFromFile(errors_expected_file_path()); | |
265 ASSERT_TRUE(LinesAreEqual(errors_output, errors_expected)); | |
Aaron Boodman
2012/05/29 21:39:08
Why not just compare the file contents as strings?
Devlin
2012/05/30 01:45:15
Done.
| |
266 file_util::Delete(errors_output_file_path(), false); | |
Aaron Boodman
2012/05/29 21:39:08
Did you consider using ScopedTempDir here too?
Devlin
2012/05/30 01:45:15
Done.
| |
267 } | |
268 | |
269 TEST_F(PageCyclerTest, StatsFile) { | |
270 const int kNumLoads = 4; | |
271 | |
272 ASSERT_TRUE(PathExists(errors_expected_file_path())); | |
273 ASSERT_TRUE(PathExists(about_url_file_path())); | |
274 | |
275 if (PathExists(stats_output_file_path())) | |
276 file_util::Delete(stats_output_file_path(), false); | |
277 ASSERT_FALSE(PathExists(stats_output_file_path())); | |
278 | |
279 set_page_cycler(new MockPageCycler(browser(), about_url_file_path(), | |
280 errors_output_file_path())); | |
281 page_cycler()->set_stats_file(stats_output_file_path()); | |
282 RunPageCycler(kSingleIteration); | |
283 | |
284 for (int i = 0; i < kNumLoads; ++i) { | |
285 EXPECT_CALL(*page_cycler(), DidFinishLoad( | |
286 kFrameID, kAboutURL, kIsMainFrame)) | |
287 .WillOnce(Invoke(page_cycler(), | |
288 &MockPageCycler::PageCyclerDidFinishLoad)); | |
289 FinishLoad(); | |
290 } | |
291 | |
292 PumpLoop(); | |
293 EXPECT_FALSE(PathExists(errors_output_file_path())); | |
294 ASSERT_TRUE(PathExists(stats_output_file_path())); | |
295 file_util::Delete(stats_output_file_path(), false); | |
296 } | |
297 | |
298 TEST_F(PageCyclerTest, KillBrowserAndAbort) { | |
299 ASSERT_TRUE(PathExists(abort_expected_file_path())); | |
300 ASSERT_TRUE(PathExists(errors_expected_file_path())); | |
301 ASSERT_TRUE(PathExists(about_url_file_path())); | |
302 | |
303 set_page_cycler(new MockPageCycler(browser(), | |
304 about_url_file_path(), | |
305 errors_output_file_path())); | |
306 RunPageCycler(kSingleIteration); | |
307 | |
308 EXPECT_CALL(*page_cycler(), DidFinishLoad(kFrameID, kAboutURL, kIsMainFrame)) | |
309 .WillOnce(Invoke(page_cycler(), | |
310 &MockPageCycler::PageCyclerDidFinishLoad)); | |
311 message_loop()->RunAllPending(); | |
312 | |
313 FinishLoad(); | |
314 | |
315 CloseBrowser(); | |
316 PumpLoop(); | |
317 std::vector<std::string> errors_output = | |
318 GetLinesFromFile(errors_output_file_path()); | |
319 std::vector<std::string> abort_expected = | |
320 GetLinesFromFile(abort_expected_file_path()); | |
321 ASSERT_TRUE(LinesAreEqual(errors_output, abort_expected)); | |
322 file_util::Delete(errors_output_file_path(), false); | |
323 } | |
324 | |
325 TEST_F(PageCyclerTest, MultipleIterations) { | |
326 const int kMultipleIterations = 3; | |
327 const int kNumLoads = 10; | |
328 | |
329 ASSERT_TRUE(PathExists(about_url_file_path())); | |
330 | |
331 set_page_cycler(new MockPageCycler(browser(), | |
332 about_url_file_path(), | |
333 errors_output_file_path())); | |
334 page_cycler()->set_stats_file(stats_output_file_path()); | |
335 RunPageCycler(kMultipleIterations); | |
336 | |
337 EXPECT_CALL(*page_cycler(), DidFinishLoad(kFrameID, kAboutURL, kIsMainFrame)) | |
338 .WillRepeatedly(Invoke(page_cycler(), | |
339 &MockPageCycler::PageCyclerDidFinishLoad)); | |
340 | |
341 for (int i = 0; i < kNumLoads; ++i) | |
342 FinishLoad(); | |
343 | |
344 PumpLoop(); | |
345 EXPECT_FALSE(PathExists(errors_output_file_path())); | |
346 ASSERT_TRUE(PathExists(stats_output_file_path())); | |
347 file_util::Delete(stats_output_file_path(), false); | |
348 } | |
OLD | NEW |