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