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/command_line.h" | |
6 #include "base/file_path.h" | |
7 #include "base/file_util.h" | |
8 #include "base/path_service.h" | |
9 #include "base/string_split.h" | |
10 #include "base/string_util.h" | |
11 #include "base/threading/sequenced_worker_pool.h" | |
12 #include "chrome/browser/browser_process.h" | |
13 #include "chrome/browser/page_cycler/page_cycler.h" | |
14 #include "chrome/browser/profiles/profile.h" | |
15 #include "chrome/browser/profiles/profile_manager.h" | |
16 #include "chrome/browser/ui/browser_list.h" | |
17 #include "chrome/common/chrome_notification_types.h" | |
18 #include "chrome/common/chrome_paths.h" | |
19 #include "chrome/common/chrome_switches.h" | |
20 #include "chrome/test/base/in_process_browser_test.h" | |
21 #include "chrome/test/base/testing_profile.h" | |
22 #include "chrome/test/base/ui_test_utils.h" | |
23 #include "content/public/browser/notification_observer.h" | |
24 #include "content/public/browser/notification_registrar.h" | |
25 #include "content/public/browser/notification_service.h" | |
26 #include "content/public/common/content_switches.h" | |
27 #include "content/public/common/url_constants.h" | |
28 #include "googleurl/src/gurl.h" | |
29 | |
30 // Basic PageCyclerBrowserTest structure; used in testing most of PageCycler's | |
31 // functionality. | |
32 class PageCyclerBrowserTest : public content::NotificationObserver, | |
33 public InProcessBrowserTest { | |
34 public: | |
35 virtual void CleanUpOnMainThread() { | |
36 file_util::Delete(temp_path_, true); // recursive. | |
37 } | |
38 | |
39 // Initialize file paths within a temporary directory; this should be | |
40 // empty and nonexistent. | |
41 virtual void InitFilePaths(FilePath temp_path) { | |
42 temp_path_ = temp_path; | |
43 urls_file_ = temp_path.AppendASCII("urls_file"); | |
44 errors_file_ = temp_path.AppendASCII("errors"); | |
45 stats_file_ = temp_path.AppendASCII("stats"); | |
46 | |
47 ASSERT_FALSE(file_util::PathExists(urls_file_)); | |
48 ASSERT_FALSE(file_util::PathExists(errors_file_)); | |
49 ASSERT_FALSE(file_util::PathExists(stats_file_)); | |
50 } | |
51 | |
52 // Initialize a PageCycler using either the base fields, or using provided | |
53 // ones. | |
54 void InitPageCycler() { | |
55 page_cycler_ = new PageCycler(browser(), urls_file()); | |
56 page_cycler_->set_errors_file(errors_file()); | |
57 page_cycler_->set_stats_file(stats_file()); | |
58 } | |
59 void InitPageCycler(FilePath urls_file, | |
Aaron Boodman
2012/05/29 21:39:08
Insert blank line here.
Devlin
2012/05/30 01:45:15
Done.
| |
60 FilePath errors_file, | |
61 FilePath stats_file) { | |
62 page_cycler_ = new PageCycler(browser(), urls_file); | |
63 page_cycler_->set_errors_file(errors_file); | |
64 page_cycler_->set_stats_file(stats_file); | |
65 } | |
66 | |
67 void RegisterForNotifications() { | |
68 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSED, | |
69 content::NotificationService::AllSources()); | |
70 } | |
71 | |
72 // Get a collection of basic urls which are stored in the test directory. | |
73 // NOTE: |test_server| must be started first! | |
74 std::vector<GURL> GetURLs() { | |
75 std::vector<GURL> urls; | |
76 urls.push_back(test_server()->GetURL("files/page_cycler/basic_html.html")); | |
77 urls.push_back(test_server()->GetURL("files/page_cycler/basic_js.html")); | |
78 urls.push_back(test_server()->GetURL("files/page_cycler/basic_css.html")); | |
79 return urls; | |
80 } | |
81 | |
82 // Read the errors file, and generate a vector of error strings. | |
83 std::vector<std::string> GetErrorsFromFile() { | |
84 std::string error_file_contents; | |
85 CHECK(file_util::ReadFileToString(errors_file_, | |
86 &error_file_contents)); | |
87 if (error_file_contents[error_file_contents.size() - 1] == '\n') { | |
88 error_file_contents = | |
89 error_file_contents.substr(0, error_file_contents.size() - 1); | |
90 } | |
91 | |
92 std::vector<std::string> errors; | |
93 base::SplitString(error_file_contents, '\n', &errors); | |
94 | |
95 return errors; | |
96 } | |
97 | |
98 // Convert a vector of GURLs into a newline-separated string, ready to be | |
99 // written to the urls file for PageCycler to use. | |
100 std::string GetStringFromURLs(std::vector<GURL> urls) { | |
101 std::string urls_string; | |
102 for (std::vector<GURL>::const_iterator iter = urls.begin(); | |
103 iter != urls.end(); ++iter) | |
104 urls_string.append(iter->spec() + "\n"); | |
105 return urls_string; | |
106 } | |
107 | |
108 // content::NotificationObserver. | |
109 virtual void Observe(int type, | |
110 const content::NotificationSource& source, | |
111 const content::NotificationDetails& details) { | |
112 switch (type) { | |
113 case chrome::NOTIFICATION_BROWSER_CLOSED: | |
114 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); | |
115 break; | |
116 default: | |
117 NOTREACHED(); | |
118 break; | |
119 } | |
120 } | |
121 | |
122 FilePath urls_file() { return urls_file_; } | |
123 FilePath errors_file() { return errors_file_; } | |
124 FilePath stats_file() { return stats_file_; } | |
125 PageCycler* page_cycler() { return page_cycler_; } | |
126 | |
127 protected: | |
128 FilePath temp_path_; | |
129 FilePath urls_file_; | |
130 FilePath errors_file_; | |
131 FilePath stats_file_; | |
132 PageCycler* page_cycler_; | |
Aaron Boodman
2012/05/29 21:39:08
Please create a constructor so that this can be in
Devlin
2012/05/30 01:45:15
Done.
| |
133 content::NotificationRegistrar registrar_; | |
134 }; | |
135 | |
136 // Structure used for testing PageCycler's ability to playback a series of | |
137 // URLs given a cache directory. | |
138 class PageCyclerCachedBrowserTest : public PageCyclerBrowserTest { | |
139 public: | |
140 // For a cached test, we use the provided user data directory from the test | |
141 // directory. | |
142 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { | |
143 InProcessBrowserTest::SetUpCommandLine(command_line); | |
144 | |
145 FilePath test_dir; | |
146 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir)); | |
147 test_dir = test_dir.AppendASCII("page_cycler"); | |
148 | |
149 FilePath source_data_dir = test_dir.AppendASCII("cached_data_dir"); | |
150 CHECK(file_util::PathExists(source_data_dir)); | |
151 | |
152 CHECK(user_data_dir_.CreateUniqueTempDir()); | |
153 | |
154 FilePath dest_data_dir = | |
155 user_data_dir_.path().AppendASCII("cached_data_dir"); | |
156 CHECK(!file_util::PathExists(dest_data_dir)); | |
157 | |
158 CHECK(file_util::CopyDirectory(source_data_dir, | |
159 user_data_dir_.path(), | |
160 true)); // recursive. | |
161 CHECK(file_util::PathExists(dest_data_dir)); | |
162 | |
163 command_line->AppendSwitchPath(switches::kUserDataDir, | |
164 dest_data_dir); | |
Aaron Boodman
2012/05/29 21:39:08
This should line up with the first param.
Devlin
2012/05/30 01:45:15
Done.
| |
165 command_line->AppendSwitch(switches::kPlaybackMode); | |
166 } | |
167 | |
168 virtual void CleanUpOnMainThread() { | |
169 file_util::Delete(user_data_dir_.path(), true); // recursive | |
170 PageCyclerBrowserTest::CleanUpOnMainThread(); | |
171 } | |
172 | |
173 // Initialize the file paths to use the UserDataDir's urls file, instead | |
174 // of one to be written. | |
175 virtual void InitFilePaths(FilePath temp_path) OVERRIDE { | |
176 urls_file_ = user_data_dir_.path().AppendASCII("cached_data_dir") | |
177 .AppendASCII("urls"); | |
178 errors_file_ = temp_path.AppendASCII("errors"); | |
179 stats_file_ = temp_path.AppendASCII("stats"); | |
180 | |
181 ASSERT_TRUE(file_util::PathExists(urls_file_)); | |
182 ASSERT_FALSE(file_util::PathExists(errors_file_)); | |
183 ASSERT_FALSE(file_util::PathExists(stats_file_)); | |
184 } | |
185 | |
186 private: | |
187 // The directory storing the copy of the UserDataDir. | |
188 ScopedTempDir user_data_dir_; | |
189 }; | |
190 | |
191 // Structure used to test PageCycler's ability to record the all necessary | |
192 // information to revisit a series of URLs. | |
193 class PageCyclerRecordingBrowserTest : public PageCyclerBrowserTest { | |
194 public: | |
195 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { | |
196 InProcessBrowserTest::SetUpCommandLine(command_line); | |
197 | |
198 CHECK(user_data_dir_.CreateUniqueTempDir()); | |
199 CHECK(file_util::PathExists(user_data_dir_.path())); | |
200 | |
201 command_line->AppendSwitchPath(switches::kUserDataDir, | |
202 user_data_dir_.path()); | |
203 // We have to be in record mode for these tests to work. | |
204 command_line->AppendSwitch(switches::kRecordMode); | |
205 } | |
206 | |
207 virtual void CleanUpOnMainThread() { | |
208 file_util::Delete(user_data_dir_.path(), true); // recursive | |
209 PageCyclerBrowserTest::CleanUpOnMainThread(); | |
210 } | |
211 | |
212 const FilePath& user_data_dir() { return user_data_dir_.path(); } | |
213 | |
214 private: | |
215 ScopedTempDir user_data_dir_; | |
216 }; | |
217 | |
218 // Sanity check; iterate through a series of URLs and make sure there are no | |
219 // errors. | |
220 IN_PROC_BROWSER_TEST_F(PageCyclerBrowserTest, BasicTest) { | |
221 const size_t kNumIterations = 3; | |
222 ScopedTempDir temp; | |
223 ASSERT_TRUE(temp.CreateUniqueTempDir()); | |
224 | |
225 RegisterForNotifications(); | |
226 InitFilePaths(temp.path()); | |
227 | |
228 ASSERT_TRUE(test_server()->Start()); | |
229 | |
230 std::string urls_string = GetStringFromURLs(GetURLs());; | |
231 | |
232 ASSERT_TRUE(file_util::WriteFile(urls_file(), urls_string.c_str(), | |
233 urls_string.size())); | |
234 | |
235 InitPageCycler(); | |
236 page_cycler()->Run(kNumIterations); | |
237 | |
238 ui_test_utils::RunMessageLoop(); | |
239 ASSERT_FALSE(file_util::PathExists(errors_file())); | |
240 ASSERT_TRUE(file_util::PathExists(stats_file())); | |
241 } | |
242 | |
243 // Test to make sure that PageCycler will recognize unvisitable URLs, and will | |
244 // handle them appropriately. | |
245 IN_PROC_BROWSER_TEST_F(PageCyclerBrowserTest, UnvisitableURL) { | |
246 const size_t kNumIterations = 3; | |
247 const char kFakeURL[] = "http://www.pleasenoonehavethisurlanytimeinthenext" | |
248 "century.com/gibberish"; | |
249 ScopedTempDir temp; | |
250 ASSERT_TRUE(temp.CreateUniqueTempDir()); | |
251 | |
252 RegisterForNotifications(); | |
253 InitFilePaths(temp.path()); | |
254 | |
255 ASSERT_TRUE(test_server()->Start()); | |
256 | |
257 std::vector<GURL> urls = GetURLs(); | |
258 urls.push_back(GURL(kFakeURL)); | |
259 std::string urls_string = GetStringFromURLs(urls); | |
260 | |
261 ASSERT_TRUE(file_util::WriteFile(urls_file(), urls_string.c_str(), | |
262 urls_string.size())); | |
263 | |
264 InitPageCycler(); | |
265 page_cycler()->Run(kNumIterations); | |
266 | |
267 ui_test_utils::RunMessageLoop(); | |
268 ASSERT_TRUE(file_util::PathExists(errors_file())); | |
269 ASSERT_TRUE(file_util::PathExists(stats_file())); | |
270 | |
271 std::vector<std::string> errors = GetErrorsFromFile(); | |
272 | |
273 size_t num_errors = errors.size(); | |
274 ASSERT_EQ(kNumIterations, num_errors); | |
275 | |
276 // Check that each error message contains the fake URL (i.e., that it wasn't | |
277 // from a valid URL, and that the fake URL was caught each time). | |
278 for (std::vector<std::string>::const_iterator iter = errors.begin(); | |
279 iter != errors.end(); ++iter) { | |
280 ASSERT_NE(iter->find(kFakeURL), std::string::npos); | |
281 } | |
282 } | |
283 | |
284 // Test that PageCycler will remove an invalid URL prior to running. | |
285 IN_PROC_BROWSER_TEST_F(PageCyclerBrowserTest, InvalidURL) { | |
286 const size_t kNumIterations = 1; | |
287 const char kBadURL[] = "notarealurl"; | |
288 | |
289 ScopedTempDir temp; | |
290 ASSERT_TRUE(temp.CreateUniqueTempDir()); | |
291 | |
292 RegisterForNotifications(); | |
293 InitFilePaths(temp.path()); | |
294 | |
295 ASSERT_TRUE(test_server()->Start()); | |
296 | |
297 std::string urls_string = GetStringFromURLs(GetURLs()); | |
298 urls_string.append(kBadURL).append("\n"); | |
299 | |
300 ASSERT_TRUE(file_util::WriteFile(urls_file(), urls_string.c_str(), | |
301 urls_string.size())); | |
302 | |
303 InitPageCycler(); | |
304 page_cycler()->Run(kNumIterations); | |
305 | |
306 ui_test_utils::RunMessageLoop(); | |
307 ASSERT_TRUE(file_util::PathExists(errors_file())); | |
308 ASSERT_TRUE(file_util::PathExists(stats_file())); | |
309 | |
310 std::vector<std::string> errors = GetErrorsFromFile(); | |
311 ASSERT_EQ(1u, errors.size()); | |
312 | |
313 std::string expected_error = "Omitting invalid URL: "; | |
314 expected_error.append(kBadURL).append("."); | |
315 | |
316 ASSERT_FALSE(errors[0].compare(expected_error)); | |
317 } | |
318 | |
319 // Test that PageCycler will remove a Chrome Error URL prior to running. | |
320 IN_PROC_BROWSER_TEST_F(PageCyclerBrowserTest, ChromeErrorURL) { | |
321 const size_t kNumIterations = 1; | |
322 ScopedTempDir temp; | |
323 ASSERT_TRUE(temp.CreateUniqueTempDir()); | |
324 | |
325 RegisterForNotifications(); | |
326 InitFilePaths(temp.path()); | |
327 | |
328 ASSERT_TRUE(test_server()->Start()); | |
329 | |
330 std::vector<GURL> urls = GetURLs(); | |
331 urls.push_back(GURL(content::kUnreachableWebDataURL)); | |
332 std::string urls_string = GetStringFromURLs(urls); | |
333 | |
334 ASSERT_TRUE(file_util::WriteFile(urls_file(), urls_string.c_str(), | |
335 urls_string.size())); | |
336 | |
337 InitPageCycler(); | |
338 page_cycler()->Run(kNumIterations); | |
339 | |
340 ui_test_utils::RunMessageLoop(); | |
341 ASSERT_TRUE(file_util::PathExists(errors_file())); | |
342 ASSERT_TRUE(file_util::PathExists(stats_file())); | |
343 | |
344 std::vector<std::string> errors = GetErrorsFromFile(); | |
345 ASSERT_EQ(1u, errors.size()); | |
346 | |
347 std::string expected_error = "Chrome error pages are not allowed as urls. " | |
348 "Omitting url: "; | |
349 expected_error.append(content::kUnreachableWebDataURL).append("."); | |
350 | |
351 ASSERT_FALSE(errors[0].compare(expected_error)); | |
352 } | |
353 | |
354 // Test that PageCycler will visit all the urls from a cache directory | |
355 // successfully while in playback mode. | |
356 IN_PROC_BROWSER_TEST_F(PageCyclerCachedBrowserTest, PlaybackMode) { | |
357 const size_t kNumIterations = 1; | |
358 ScopedTempDir temp; | |
359 ASSERT_TRUE(temp.CreateUniqueTempDir()); | |
360 | |
361 RegisterForNotifications(); | |
362 InitFilePaths(temp.path()); | |
363 | |
364 InitPageCycler(); | |
365 | |
366 page_cycler()->Run(kNumIterations); | |
367 | |
368 ui_test_utils::RunMessageLoop(); | |
369 ASSERT_TRUE(file_util::PathExists(stats_file())); | |
370 ASSERT_FALSE(file_util::PathExists(errors_file())); | |
371 } | |
372 | |
373 // Test that PageCycler will have a cache miss if a URL is missing from the | |
374 // cache directory while in playback mode. | |
375 IN_PROC_BROWSER_TEST_F(PageCyclerCachedBrowserTest, URLNotInCache) { | |
376 const size_t kNumIterations = 1; | |
377 const char kCacheMissURL[] = "http://www.images.google.com/"; | |
378 | |
379 ScopedTempDir temp; | |
380 ASSERT_TRUE(temp.CreateUniqueTempDir()); | |
381 | |
382 RegisterForNotifications(); | |
383 InitFilePaths(temp.path()); | |
384 | |
385 std::string urls_string; | |
386 ASSERT_TRUE(file_util::ReadFileToString(urls_file(), | |
387 &urls_string)); | |
388 | |
389 urls_string.append("\n").append(kCacheMissURL); | |
390 FilePath new_urls_file = temp.path().AppendASCII("urls"); | |
391 ASSERT_FALSE(file_util::PathExists(new_urls_file)); | |
392 | |
393 ASSERT_TRUE(file_util::WriteFile(new_urls_file, urls_string.c_str(), | |
394 urls_string.size())); | |
395 | |
396 InitPageCycler(new_urls_file, errors_file(), stats_file()); | |
397 page_cycler()->Run(kNumIterations); | |
398 | |
399 ui_test_utils::RunMessageLoop(); | |
400 ASSERT_TRUE(file_util::PathExists(errors_file())); | |
401 ASSERT_TRUE(file_util::PathExists(stats_file())); | |
402 | |
403 std::vector<std::string> errors = GetErrorsFromFile(); | |
404 ASSERT_EQ(1u, errors.size()); | |
405 | |
406 std::string expected_error; | |
407 expected_error.append("Failed to load the page at: ") | |
408 .append(kCacheMissURL) | |
409 .append(": The requested entry was not found in the cache."); | |
410 | |
411 ASSERT_FALSE(errors[0].compare(expected_error)); | |
412 } | |
413 | |
414 // Test that PageCycler will record properly. | |
415 // NOTE: This test operates by comparing the size of a generated cache | |
Aaron Boodman
2012/05/29 21:39:08
This is probably going to be too brittle. Also I w
Devlin
2012/05/30 01:45:15
Skipped for now; will look into a better way of do
| |
416 // directory to a previously-generated cache directory. If the way or | |
417 // amount Chrome caches pages changes significantly, this test will fail. | |
418 // If this happens, please update the cache directory in | |
419 // chrome/test/data/page_cycler. | |
420 IN_PROC_BROWSER_TEST_F(PageCyclerRecordingBrowserTest, RecordMode) { | |
421 const size_t kNumIterations = 1; | |
422 ScopedTempDir temp; | |
423 ASSERT_TRUE(temp.CreateUniqueTempDir()); | |
424 | |
425 RegisterForNotifications(); | |
426 InitFilePaths(temp.path()); | |
427 | |
428 ASSERT_TRUE(test_server()->Start()); | |
429 std::string urls_string = GetStringFromURLs(GetURLs()); | |
430 | |
431 ASSERT_TRUE(file_util::WriteFile(urls_file(), urls_string.c_str(), | |
432 urls_string.size())); | |
433 | |
434 InitPageCycler(); | |
435 page_cycler()->Run(kNumIterations); | |
436 | |
437 ui_test_utils::RunMessageLoop(); | |
438 ASSERT_FALSE(file_util::PathExists(errors_file())); | |
439 ASSERT_TRUE(file_util::PathExists(stats_file())); | |
440 | |
441 FilePath test_cache_dir = user_data_dir().AppendASCII("Default") | |
442 .AppendASCII("Cache"); | |
443 ASSERT_TRUE(file_util::PathExists(test_cache_dir)); | |
444 | |
445 FilePath expected_cache_dir; | |
446 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &expected_cache_dir)); | |
447 expected_cache_dir = expected_cache_dir.AppendASCII("page_cycler") | |
448 .AppendASCII("expected_cache"); | |
449 ASSERT_TRUE(file_util::PathExists(test_cache_dir)); | |
450 | |
451 ASSERT_EQ(file_util::ComputeDirectorySize(expected_cache_dir), | |
452 file_util::ComputeDirectorySize(test_cache_dir)); | |
453 } | |
OLD | NEW |