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 |