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