Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // This file provides reliablity test which runs under UI test framework. The | 5 // This file provides reliablity test which runs under UI test framework. The |
| 6 // test is intended to run within QEMU environment. | 6 // test is intended to run within QEMU environment. |
| 7 // | 7 // |
| 8 // Usage 1: reliability_test | 8 // Usage 1: reliability_test |
| 9 // Upon invocation, it visits a hard coded list of sample URLs. This is mainly | 9 // Upon invocation, it visits a hard coded list of sample URLs. This is mainly |
| 10 // used by buildbot, to verify reliability_test itself runs ok. | 10 // used by buildbot, to verify reliability_test itself runs ok. |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 // --iterations=num: goes through the list of URLs constructed in usage 2 or 3 | 24 // --iterations=num: goes through the list of URLs constructed in usage 2 or 3 |
| 25 // num times. | 25 // num times. |
| 26 // --continuousload: continuously visits the list of URLs without restarting | 26 // --continuousload: continuously visits the list of URLs without restarting |
| 27 // browser for each page load. | 27 // browser for each page load. |
| 28 // --memoryusage: prints out memory usage when visiting each page. | 28 // --memoryusage: prints out memory usage when visiting each page. |
| 29 // --endurl=url: visits the specified url in the end. | 29 // --endurl=url: visits the specified url in the end. |
| 30 // --logfile=filepath: saves the visit log to the specified path. | 30 // --logfile=filepath: saves the visit log to the specified path. |
| 31 // --nopagedown: won't simulate page down key presses after page load. | 31 // --nopagedown: won't simulate page down key presses after page load. |
| 32 // --noclearprofile: do not clear profile dir before firing up each time. | 32 // --noclearprofile: do not clear profile dir before firing up each time. |
| 33 // --savedebuglog: save Chrome, V8, and test debug log for each page loaded. | 33 // --savedebuglog: save Chrome, V8, and test debug log for each page loaded. |
| 34 // --searchdumpsbypid: Look for crash dumps by browser process id. | |
| 35 // "crash_dir/pid/" | |
| 34 | 36 |
| 35 #include <fstream> | 37 #include <fstream> |
| 36 #include <vector> | 38 #include <vector> |
| 37 | 39 |
| 38 #include "base/command_line.h" | 40 #include "base/command_line.h" |
| 39 #include "base/environment.h" | 41 #include "base/environment.h" |
| 40 #include "base/file_path.h" | 42 #include "base/file_path.h" |
| 41 #include "base/file_util.h" | 43 #include "base/file_util.h" |
| 42 #include "base/file_version_info.h" | 44 #include "base/file_version_info.h" |
| 43 #include "base/i18n/time_formatting.h" | 45 #include "base/i18n/time_formatting.h" |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 58 #include "chrome/common/chrome_version_info.h" | 60 #include "chrome/common/chrome_version_info.h" |
| 59 #include "chrome/common/json_pref_store.h" | 61 #include "chrome/common/json_pref_store.h" |
| 60 #include "chrome/common/logging_chrome.h" | 62 #include "chrome/common/logging_chrome.h" |
| 61 #include "chrome/common/pref_names.h" | 63 #include "chrome/common/pref_names.h" |
| 62 #include "chrome/common/render_messages.h" | 64 #include "chrome/common/render_messages.h" |
| 63 #include "chrome/common/url_constants.h" | 65 #include "chrome/common/url_constants.h" |
| 64 #include "chrome/test/automation/automation_proxy.h" | 66 #include "chrome/test/automation/automation_proxy.h" |
| 65 #include "chrome/test/automation/browser_proxy.h" | 67 #include "chrome/test/automation/browser_proxy.h" |
| 66 #include "chrome/test/automation/tab_proxy.h" | 68 #include "chrome/test/automation/tab_proxy.h" |
| 67 #include "chrome/test/automation/window_proxy.h" | 69 #include "chrome/test/automation/window_proxy.h" |
| 70 #include "chrome/test/base/chrome_process_util.h" | |
| 68 #include "chrome/test/ui/ui_test.h" | 71 #include "chrome/test/ui/ui_test.h" |
| 69 #include "net/base/net_util.h" | 72 #include "net/base/net_util.h" |
| 70 #include "ui/base/keycodes/keyboard_codes.h" | 73 #include "ui/base/keycodes/keyboard_codes.h" |
| 71 #include "v8/include/v8-testing.h" | 74 #include "v8/include/v8-testing.h" |
| 72 | 75 |
| 73 namespace { | 76 namespace { |
| 74 | 77 |
| 75 // See comments at the beginning of the file for the definition of switches. | 78 // See comments at the beginning of the file for the definition of switches. |
| 76 const char kSiteSwitch[] = "site"; | 79 const char kSiteSwitch[] = "site"; |
| 77 const char kStartPageSwitch[] = "startpage"; | 80 const char kStartPageSwitch[] = "startpage"; |
| 78 const char kEndPageSwitch[] = "endpage"; | 81 const char kEndPageSwitch[] = "endpage"; |
| 79 const char kListSwitch[] = "list"; | 82 const char kListSwitch[] = "list"; |
| 80 const char kStartIndexSwitch[] = "startline"; | 83 const char kStartIndexSwitch[] = "startline"; |
| 81 const char kEndIndexSwitch[] = "endline"; | 84 const char kEndIndexSwitch[] = "endline"; |
| 82 const char kIterationSwitch[] = "iterations"; | 85 const char kIterationSwitch[] = "iterations"; |
| 83 const char kContinuousLoadSwitch[] = "continuousload"; | 86 const char kContinuousLoadSwitch[] = "continuousload"; |
| 84 const char kMemoryUsageSwitch[] = "memoryusage"; | 87 const char kMemoryUsageSwitch[] = "memoryusage"; |
| 85 const char kEndURLSwitch[] = "endurl"; | 88 const char kEndURLSwitch[] = "endurl"; |
| 86 const char kLogFileSwitch[] = "logfile"; | 89 const char kLogFileSwitch[] = "logfile"; |
| 87 const char kNoPageDownSwitch[] = "nopagedown"; | 90 const char kNoPageDownSwitch[] = "nopagedown"; |
| 88 const char kNoClearProfileSwitch[] = "noclearprofile"; | 91 const char kNoClearProfileSwitch[] = "noclearprofile"; |
| 89 const char kSaveDebugLogSwitch[] = "savedebuglog"; | 92 const char kSaveDebugLogSwitch[] = "savedebuglog"; |
| 90 const char kStressOptSwitch[] = "stress-opt"; | 93 const char kStressOptSwitch[] = "stress-opt"; |
| 91 const char kStressDeoptSwitch[] = "stress-deopt"; | 94 const char kStressDeoptSwitch[] = "stress-deopt"; |
| 95 const char kSearchDumpsByPid[] = "search-dumps-by-pid"; | |
| 92 | 96 |
| 93 const char kDefaultServerUrl[] = "http://urllist.com"; | 97 const char kDefaultServerUrl[] = "http://urllist.com"; |
| 94 std::string g_server_url; | 98 std::string g_server_url; |
| 95 const char kTestPage1[] = "page1.html"; | 99 const char kTestPage1[] = "page1.html"; |
| 96 const char kTestPage2[] = "page2.html"; | 100 const char kTestPage2[] = "page2.html"; |
| 97 | 101 |
| 98 // These are copied from v8 definitions as we cannot include them. | 102 // These are copied from v8 definitions as we cannot include them. |
| 99 const char kV8LogFileSwitch[] = "logfile"; | 103 const char kV8LogFileSwitch[] = "logfile"; |
| 100 const char kV8LogFileDefaultName[] = "v8.log"; | 104 const char kV8LogFileDefaultName[] = "v8.log"; |
| 101 | 105 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 113 bool g_continuous_load = false; | 117 bool g_continuous_load = false; |
| 114 bool g_browser_existing = false; | 118 bool g_browser_existing = false; |
| 115 bool g_page_down = true; | 119 bool g_page_down = true; |
| 116 bool g_clear_profile = true; | 120 bool g_clear_profile = true; |
| 117 std::string g_end_url; | 121 std::string g_end_url; |
| 118 FilePath g_log_file_path; | 122 FilePath g_log_file_path; |
| 119 bool g_save_debug_log = false; | 123 bool g_save_debug_log = false; |
| 120 FilePath g_chrome_log_path; | 124 FilePath g_chrome_log_path; |
| 121 FilePath g_v8_log_path; | 125 FilePath g_v8_log_path; |
| 122 FilePath g_test_log_path; | 126 FilePath g_test_log_path; |
| 123 bool g_stand_alone = false; | 127 bool g_stand_alone = false; |
|
sky
2012/11/02 15:03:04
None of the these are global. They shouldn't have
| |
| 124 bool g_stress_opt = false; | 128 bool g_stress_opt = false; |
| 125 bool g_stress_deopt = false; | 129 bool g_stress_deopt = false; |
| 130 bool g_search_dumps_by_pid = false; | |
| 126 | 131 |
| 127 void ReportHandler(const std::string& str) { | 132 void ReportHandler(const std::string& str) { |
| 128 // Ignore report events. | 133 // Ignore report events. |
| 129 } | 134 } |
| 130 | 135 |
| 131 void SetPageRange(const CommandLine& parsed_command_line) { | 136 void SetPageRange(const CommandLine& parsed_command_line) { |
| 132 // If calling into this function, we are running as a standalone program. | 137 // If calling into this function, we are running as a standalone program. |
| 133 g_stand_alone = true; | 138 g_stand_alone = true; |
| 134 | 139 |
| 135 // Since we use --enable-dcheck for reliability tests, suppress the error | 140 // Since we use --enable-dcheck for reliability tests, suppress the error |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 217 parsed_command_line.GetSwitchValuePath(switches::kJavaScriptFlags)); | 222 parsed_command_line.GetSwitchValuePath(switches::kJavaScriptFlags)); |
| 218 if (v8_command_line.HasSwitch(kV8LogFileSwitch)) { | 223 if (v8_command_line.HasSwitch(kV8LogFileSwitch)) { |
| 219 g_v8_log_path = v8_command_line.GetSwitchValuePath(kV8LogFileSwitch); | 224 g_v8_log_path = v8_command_line.GetSwitchValuePath(kV8LogFileSwitch); |
| 220 if (!file_util::AbsolutePath(&g_v8_log_path)) | 225 if (!file_util::AbsolutePath(&g_v8_log_path)) |
| 221 g_v8_log_path = FilePath(); | 226 g_v8_log_path = FilePath(); |
| 222 } | 227 } |
| 223 } | 228 } |
| 224 } | 229 } |
| 225 } | 230 } |
| 226 | 231 |
| 227 if (parsed_command_line.HasSwitch(kStressOptSwitch)) { | 232 if (parsed_command_line.HasSwitch(kStressOptSwitch)) |
| 228 g_stress_opt = true; | 233 g_stress_opt = true; |
| 229 } | 234 |
| 230 if (parsed_command_line.HasSwitch(kStressDeoptSwitch)) { | 235 if (parsed_command_line.HasSwitch(kStressDeoptSwitch)) |
| 231 g_stress_deopt = true; | 236 g_stress_deopt = true; |
| 232 } | 237 |
| 238 if (parsed_command_line.HasSwitch(kSearchDumpsByPid)) | |
| 239 g_search_dumps_by_pid = true; | |
| 233 } | 240 } |
| 234 | 241 |
| 235 class PageLoadTest : public UITest { | 242 class PageLoadTest : public UITest { |
| 236 public: | 243 public: |
| 237 enum NavigationResult { | 244 enum NavigationResult { |
| 238 NAVIGATION_ERROR = 0, | 245 NAVIGATION_ERROR = 0, |
| 239 NAVIGATION_SUCCESS, | 246 NAVIGATION_SUCCESS, |
| 240 NAVIGATION_AUTH_NEEDED, | 247 NAVIGATION_AUTH_NEEDED, |
| 241 NAVIGATION_TIME_OUT, | 248 NAVIGATION_TIME_OUT, |
| 242 }; | 249 }; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 316 test_log << base::TimeFormatFriendlyDateAndTime(time_now) << std::endl; | 323 test_log << base::TimeFormatFriendlyDateAndTime(time_now) << std::endl; |
| 317 | 324 |
| 318 // Make sure the browser is running. | 325 // Make sure the browser is running. |
| 319 EnsureBrowserAndServer(); | 326 EnsureBrowserAndServer(); |
| 320 | 327 |
| 321 // Log Browser Launched time. | 328 // Log Browser Launched time. |
| 322 time_now = base::Time::Now(); | 329 time_now = base::Time::Now(); |
| 323 test_log << "browser_launched_seconds="; | 330 test_log << "browser_launched_seconds="; |
| 324 test_log << (time_now.ToDoubleT() - time_start) << std::endl; | 331 test_log << (time_now.ToDoubleT() - time_start) << std::endl; |
| 325 | 332 |
| 333 // Create crash dump directory with pid. | |
| 334 if (g_search_dumps_by_pid) { | |
| 335 actual_crash_dumps_dir_path_ = FilePath(crash_dumps_dir_path_); | |
| 336 ChromeProcessList processes = | |
| 337 GetRunningChromeProcesses(browser_process_id()); | |
| 338 if (!processes.empty()) | |
| 339 actual_crash_dumps_dir_path_ = actual_crash_dumps_dir_path_.Append( | |
| 340 base::Int64ToString16(*processes.begin())); | |
| 341 } | |
| 342 | |
| 326 int result = AUTOMATION_MSG_NAVIGATION_ERROR; | 343 int result = AUTOMATION_MSG_NAVIGATION_ERROR; |
| 327 // This is essentially what NavigateToURL does except we don't fire | 344 // This is essentially what NavigateToURL does except we don't fire |
| 328 // assertion when page loading fails. We log the result instead. | 345 // assertion when page loading fails. We log the result instead. |
| 329 { | 346 { |
| 330 // TabProxy should be released before Browser is closed. | 347 // TabProxy should be released before Browser is closed. |
| 331 scoped_refptr<TabProxy> tab_proxy(GetActiveTab()); | 348 scoped_refptr<TabProxy> tab_proxy(GetActiveTab()); |
| 332 if (tab_proxy.get()) | 349 if (tab_proxy.get()) |
| 333 result = tab_proxy->NavigateToURL(url); | 350 result = tab_proxy->NavigateToURL(url); |
| 334 | 351 |
| 335 if (result == AUTOMATION_MSG_NAVIGATION_SUCCESS) { | 352 if (result == AUTOMATION_MSG_NAVIGATION_SUCCESS) { |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 686 FilePath crash_dump_file_path(crash_dumps_dir_path_); | 703 FilePath crash_dump_file_path(crash_dumps_dir_path_); |
| 687 crash_dump_file_path = crash_dump_file_path.Append(crash_dump_file_name); | 704 crash_dump_file_path = crash_dump_file_path.Append(crash_dump_file_name); |
| 688 FilePath crash_text_file_path = | 705 FilePath crash_text_file_path = |
| 689 crash_dump_file_path.ReplaceExtension(FILE_PATH_LITERAL("txt")); | 706 crash_dump_file_path.ReplaceExtension(FILE_PATH_LITERAL("txt")); |
| 690 | 707 |
| 691 ASSERT_TRUE(file_util::DieFileDie(crash_dump_file_path, false)); | 708 ASSERT_TRUE(file_util::DieFileDie(crash_dump_file_path, false)); |
| 692 ASSERT_TRUE(file_util::DieFileDie(crash_text_file_path, false)); | 709 ASSERT_TRUE(file_util::DieFileDie(crash_text_file_path, false)); |
| 693 } | 710 } |
| 694 | 711 |
| 695 bool HasNewCrashDumps() { | 712 bool HasNewCrashDumps() { |
| 696 file_util::FileEnumerator enumerator(crash_dumps_dir_path_, | 713 file_util::FileEnumerator enumerator(actual_crash_dumps_dir_path_, |
| 697 false, // not recursive | 714 false, // not recursive |
| 698 file_util::FileEnumerator::FILES); | 715 file_util::FileEnumerator::FILES); |
| 699 for (FilePath path = enumerator.Next(); !path.value().empty(); | 716 for (FilePath path = enumerator.Next(); !path.value().empty(); |
| 700 path = enumerator.Next()) { | 717 path = enumerator.Next()) { |
| 701 if (path.MatchesExtension(FILE_PATH_LITERAL(".dmp")) && | 718 if (path.MatchesExtension(FILE_PATH_LITERAL(".dmp")) && |
| 702 !crash_dumps_[path.BaseName()]) { | 719 !crash_dumps_[path.BaseName()]) { |
| 703 return true; | 720 return true; |
| 704 } | 721 } |
| 705 } | 722 } |
| 706 | 723 |
| 707 return false; | 724 return false; |
| 708 } | 725 } |
| 709 | 726 |
| 710 // Check whether there are new .dmp files. Return the list and optionally | 727 // Check whether there are new .dmp files. Return the list and optionally |
| 711 // delete them afterwards. | 728 // delete them afterwards. |
| 712 void CollectNewCrashDumps(std::vector<FilePath>& new_crash_dumps, | 729 void CollectNewCrashDumps(std::vector<FilePath>& new_crash_dumps, |
| 713 NavigationMetrics* metrics, | 730 NavigationMetrics* metrics, |
| 714 bool delete_dumps) { | 731 bool delete_dumps) { |
| 715 int num_dumps = 0; | 732 int num_dumps = 0; |
| 716 | 733 file_util::FileEnumerator enumerator(actual_crash_dumps_dir_path_, |
| 717 file_util::FileEnumerator enumerator(crash_dumps_dir_path_, | |
| 718 false, // not recursive | 734 false, // not recursive |
| 719 file_util::FileEnumerator::FILES); | 735 file_util::FileEnumerator::FILES); |
| 720 for (FilePath path = enumerator.Next(); !path.value().empty(); | 736 for (FilePath path = enumerator.Next(); !path.value().empty(); |
| 721 path = enumerator.Next()) { | 737 path = enumerator.Next()) { |
| 722 if (path.MatchesExtension(FILE_PATH_LITERAL(".dmp")) && | 738 if (path.MatchesExtension(FILE_PATH_LITERAL(".dmp")) && |
| 723 !crash_dumps_[path.BaseName()]) { | 739 !crash_dumps_[path.BaseName()]) { |
| 724 crash_dumps_[path.BaseName()] = true; | 740 crash_dumps_[path.BaseName()] = true; |
| 725 FilePath crash_dump_file_path(crash_dumps_dir_path_); | 741 FilePath crash_dump_file_path(actual_crash_dumps_dir_path_); |
| 726 crash_dump_file_path = crash_dump_file_path.Append(path.BaseName()); | 742 crash_dump_file_path = crash_dump_file_path.Append(path.BaseName()); |
| 727 new_crash_dumps.push_back(crash_dump_file_path); | 743 new_crash_dumps.push_back(crash_dump_file_path); |
| 728 if (delete_dumps) | 744 if (delete_dumps) |
| 729 DeleteCrashDump(path.BaseName()); | 745 DeleteCrashDump(path.BaseName()); |
| 730 num_dumps++; | 746 num_dumps++; |
| 731 } | 747 } |
| 732 } | 748 } |
| 733 if (metrics) | 749 if (metrics) |
| 734 metrics->crash_dump_count = num_dumps; | 750 metrics->crash_dump_count = num_dumps; |
| 735 } | 751 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 775 FilePath test_dir; | 791 FilePath test_dir; |
| 776 PathService::Get(chrome::DIR_TEST_DATA, &test_dir); | 792 PathService::Get(chrome::DIR_TEST_DATA, &test_dir); |
| 777 test_dir = test_dir.AppendASCII("reliability"); | 793 test_dir = test_dir.AppendASCII("reliability"); |
| 778 test_dir = test_dir.AppendASCII("sample_pages"); | 794 test_dir = test_dir.AppendASCII("sample_pages"); |
| 779 return test_dir; | 795 return test_dir; |
| 780 } | 796 } |
| 781 | 797 |
| 782 // The pathname of Chrome's crash dumps directory. | 798 // The pathname of Chrome's crash dumps directory. |
| 783 FilePath crash_dumps_dir_path_; | 799 FilePath crash_dumps_dir_path_; |
| 784 | 800 |
| 801 // The actual crash dumps directory that will be used. | |
| 802 FilePath actual_crash_dumps_dir_path_; | |
| 803 | |
| 785 // The set of all the crash dumps we have seen. Each crash generates a | 804 // The set of all the crash dumps we have seen. Each crash generates a |
| 786 // .dmp and a .txt file in the crash dumps directory. We only store the | 805 // .dmp and a .txt file in the crash dumps directory. We only store the |
| 787 // .dmp files in this set. | 806 // .dmp files in this set. |
| 788 // | 807 // |
| 789 // The set is implemented as a std::map. The key is the file name, and | 808 // The set is implemented as a std::map. The key is the file name, and |
| 790 // the value is false (the file is not in the set) or true (the file is | 809 // the value is false (the file is not in the set) or true (the file is |
| 791 // in the set). The initial value for any key in std::map is 0 (false), | 810 // in the set). The initial value for any key in std::map is 0 (false), |
| 792 // which in this case means a new file is not in the set initially, | 811 // which in this case means a new file is not in the set initially, |
| 793 // exactly the semantics we want. | 812 // exactly the semantics we want. |
| 794 std::map<FilePath, bool> crash_dumps_; | 813 std::map<FilePath, bool> crash_dumps_; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 812 if (!g_end_url.empty()) { | 831 if (!g_end_url.empty()) { |
| 813 NavigateToURLLogResult( | 832 NavigateToURLLogResult( |
| 814 g_end_url, log_file, NULL, g_continuous_load, false); | 833 g_end_url, log_file, NULL, g_continuous_load, false); |
| 815 } | 834 } |
| 816 | 835 |
| 817 log_file.close(); | 836 log_file.close(); |
| 818 } | 837 } |
| 819 | 838 |
| 820 } // namespace | 839 } // namespace |
| 821 | 840 |
| OLD | NEW |