Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: chrome/test/reliability/page_load_test.cc

Issue 23536051: GTTF: Remove unused reliability tests code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 // This file provides reliablity test which runs under UI test framework. The
6 // test is intended to run within QEMU environment.
7 //
8 // Usage 1: reliability_test
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.
11 //
12 // Usage 2: reliability_test --site=url --startpage=start --endpage=end [...]
13 // Upon invocation, it visits a list of URLs constructed as
14 // "http://url/page?id=k". (start <= k <= end).
15 //
16 // Usage 3: reliability_test --list=file --startline=start --endline=end [...]
17 // Upon invocation, it visits each of the URLs on line numbers between start
18 // and end, inclusive, stored in the input file. The line number starts from 1.
19 //
20 // If both "--site" and "--list" are provided, the "--site" set of arguments
21 // are ignored.
22 //
23 // Optional Switches:
24 // --iterations=num: goes through the list of URLs constructed in usage 2 or 3
25 // num times.
26 // --continuousload: continuously visits the list of URLs without restarting
27 // browser for each page load.
28 // --memoryusage: prints out memory usage when visiting each page.
29 // --endurl=url: visits the specified url in the end.
30 // --logfile=filepath: saves the visit log to the specified path.
31 // --noclearprofile: do not clear profile dir before firing up each time.
32 // --savedebuglog: save Chrome, V8, and test debug log for each page loaded.
33 // --searchdumpsbypid: Look for crash dumps by browser process id.
34 // "crash_dir/pid/"
35
36 #include <fstream>
37 #include <vector>
38
39 #include "base/command_line.h"
40 #include "base/environment.h"
41 #include "base/file_util.h"
42 #include "base/file_version_info.h"
43 #include "base/files/file_enumerator.h"
44 #include "base/files/file_path.h"
45 #include "base/i18n/time_formatting.h"
46 #include "base/memory/scoped_ptr.h"
47 #include "base/path_service.h"
48 #include "base/prefs/json_pref_store.h"
49 #include "base/prefs/pref_registry_simple.h"
50 #include "base/prefs/pref_service.h"
51 #include "base/process/kill.h"
52 #include "base/strings/string_number_conversions.h"
53 #include "base/strings/string_util.h"
54 #include "base/test/test_file_util.h"
55 #include "base/threading/platform_thread.h"
56 #include "base/time/time.h"
57 #include "chrome/browser/prefs/pref_service_mock_builder.h"
58 #include "chrome/common/automation_messages.h"
59 #include "chrome/common/chrome_constants.h"
60 #include "chrome/common/chrome_paths.h"
61 #include "chrome/common/chrome_switches.h"
62 #include "chrome/common/chrome_version_info.h"
63 #include "chrome/common/logging_chrome.h"
64 #include "chrome/common/net/url_fixer_upper.h"
65 #include "chrome/common/pref_names.h"
66 #include "chrome/common/render_messages.h"
67 #include "chrome/common/url_constants.h"
68 #include "chrome/test/automation/automation_proxy.h"
69 #include "chrome/test/automation/browser_proxy.h"
70 #include "chrome/test/automation/tab_proxy.h"
71 #include "chrome/test/automation/window_proxy.h"
72 #include "chrome/test/ui/ui_test.h"
73 #include "net/base/net_util.h"
74 #include "v8/include/v8-testing.h"
75
76 namespace {
77
78 // See comments at the beginning of the file for the definition of switches.
79 const char kSiteSwitch[] = "site";
80 const char kStartPageSwitch[] = "startpage";
81 const char kEndPageSwitch[] = "endpage";
82 const char kListSwitch[] = "list";
83 const char kStartIndexSwitch[] = "startline";
84 const char kEndIndexSwitch[] = "endline";
85 const char kIterationSwitch[] = "iterations";
86 const char kContinuousLoadSwitch[] = "continuousload";
87 const char kMemoryUsageSwitch[] = "memoryusage";
88 const char kEndURLSwitch[] = "endurl";
89 const char kLogFileSwitch[] = "logfile";
90 const char kNoPageDownSwitch[] = "nopagedown";
91 const char kNoClearProfileSwitch[] = "noclearprofile";
92 const char kSaveDebugLogSwitch[] = "savedebuglog";
93 const char kStressOptSwitch[] = "stress-opt";
94 const char kStressDeoptSwitch[] = "stress-deopt";
95
96 const char kDefaultServerUrl[] = "http://urllist.com";
97 std::string g_server_url;
98 const char kTestPage1[] = "page1.html";
99 const char kTestPage2[] = "page2.html";
100
101 // These are copied from v8 definitions as we cannot include them.
102 const char kV8LogFileSwitch[] = "logfile";
103 const char kV8LogFileDefaultName[] = "v8.log";
104
105 // String name of local chrome dll for looking up file information.
106 const wchar_t kChromeDll[] = L"chrome.dll";
107
108 bool g_append_page_id = false;
109 int32 g_start_page;
110 int32 g_end_page;
111 base::FilePath g_url_file_path;
112 int32 g_start_index = 1;
113 int32 g_end_index = kint32max;
114 int32 g_iterations = 1;
115 bool g_memory_usage = false;
116 bool g_continuous_load = false;
117 bool g_browser_existing = false;
118 bool g_clear_profile = true;
119 std::string g_end_url;
120 base::FilePath g_log_file_path;
121 bool g_save_debug_log = false;
122 base::FilePath g_chrome_log_path;
123 base::FilePath g_v8_log_path;
124 base::FilePath g_test_log_path;
125 bool g_stand_alone = false;
126 bool g_stress_opt = false;
127 bool g_stress_deopt = false;
128
129 void ReportHandler(const std::string& str) {
130 // Ignore report events.
131 }
132
133 void SetPageRange(const CommandLine& parsed_command_line) {
134 // If calling into this function, we are running as a standalone program.
135 g_stand_alone = true;
136
137 // Since we use --enable-dcheck for reliability tests, suppress the error
138 // dialog in the test process.
139 logging::SetLogReportHandler(ReportHandler);
140
141 if (parsed_command_line.HasSwitch(kStartPageSwitch)) {
142 ASSERT_TRUE(parsed_command_line.HasSwitch(kEndPageSwitch));
143 ASSERT_TRUE(
144 base::StringToInt(parsed_command_line.GetSwitchValueASCII(
145 kStartPageSwitch),
146 &g_start_page));
147 ASSERT_TRUE(
148 base::StringToInt(parsed_command_line.GetSwitchValueASCII(
149 kEndPageSwitch),
150 &g_end_page));
151 ASSERT_TRUE(g_start_page > 0 && g_end_page > 0);
152 ASSERT_TRUE(g_start_page < g_end_page);
153 g_append_page_id = true;
154 } else {
155 ASSERT_FALSE(parsed_command_line.HasSwitch(kEndPageSwitch));
156 }
157
158 if (parsed_command_line.HasSwitch(kSiteSwitch)) {
159 g_server_url = parsed_command_line.GetSwitchValueASCII(kSiteSwitch);
160 }
161
162 if (parsed_command_line.HasSwitch(kStartIndexSwitch)) {
163 ASSERT_TRUE(
164 base::StringToInt(parsed_command_line.GetSwitchValueASCII(
165 kStartIndexSwitch),
166 &g_start_index));
167 ASSERT_GT(g_start_index, 0);
168 }
169
170 if (parsed_command_line.HasSwitch(kEndIndexSwitch)) {
171 ASSERT_TRUE(
172 base::StringToInt(parsed_command_line.GetSwitchValueASCII(
173 kEndIndexSwitch),
174 &g_end_index));
175 ASSERT_GT(g_end_index, 0);
176 }
177
178 ASSERT_TRUE(g_end_index >= g_start_index);
179
180 if (parsed_command_line.HasSwitch(kListSwitch))
181 g_url_file_path = parsed_command_line.GetSwitchValuePath(kListSwitch);
182
183 if (parsed_command_line.HasSwitch(kIterationSwitch)) {
184 ASSERT_TRUE(
185 base::StringToInt(parsed_command_line.GetSwitchValueASCII(
186 kIterationSwitch),
187 &g_iterations));
188 ASSERT_GT(g_iterations, 0);
189 }
190
191 if (parsed_command_line.HasSwitch(kMemoryUsageSwitch))
192 g_memory_usage = true;
193
194 if (parsed_command_line.HasSwitch(kContinuousLoadSwitch))
195 g_continuous_load = true;
196
197 if (parsed_command_line.HasSwitch(kEndURLSwitch))
198 g_end_url = parsed_command_line.GetSwitchValueASCII(kEndURLSwitch);
199
200 if (parsed_command_line.HasSwitch(kLogFileSwitch))
201 g_log_file_path = parsed_command_line.GetSwitchValuePath(kLogFileSwitch);
202
203 if (parsed_command_line.HasSwitch(kNoClearProfileSwitch))
204 g_clear_profile = false;
205
206 if (parsed_command_line.HasSwitch(kSaveDebugLogSwitch)) {
207 g_save_debug_log = true;
208 g_chrome_log_path = logging::GetLogFileName();
209 // We won't get v8 log unless --no-sandbox is specified.
210 if (parsed_command_line.HasSwitch(switches::kNoSandbox)) {
211 PathService::Get(base::DIR_CURRENT, &g_v8_log_path);
212 g_v8_log_path = g_v8_log_path.AppendASCII(kV8LogFileDefaultName);
213 // The command line switch may override the default v8 log path.
214 if (parsed_command_line.HasSwitch(switches::kJavaScriptFlags)) {
215 CommandLine v8_command_line(
216 parsed_command_line.GetSwitchValuePath(switches::kJavaScriptFlags));
217 if (v8_command_line.HasSwitch(kV8LogFileSwitch)) {
218 g_v8_log_path = base::MakeAbsoluteFilePath(
219 v8_command_line.GetSwitchValuePath(kV8LogFileSwitch));
220 }
221 }
222 }
223 }
224
225 if (parsed_command_line.HasSwitch(kStressOptSwitch)) {
226 g_stress_opt = true;
227 }
228 if (parsed_command_line.HasSwitch(kStressDeoptSwitch)) {
229 g_stress_deopt = true;
230 }
231 }
232
233 class PageLoadTest : public UITest {
234 public:
235 enum NavigationResult {
236 NAVIGATION_ERROR = 0,
237 NAVIGATION_SUCCESS,
238 NAVIGATION_AUTH_NEEDED,
239 NAVIGATION_TIME_OUT,
240 };
241
242 typedef struct {
243 // These are results from the test automation that drives Chrome
244 NavigationResult result;
245 int crash_dump_count;
246 // These are stability metrics recorded by Chrome itself
247 bool browser_clean_exit;
248 int browser_launch_count;
249 int page_load_count;
250 int browser_crash_count;
251 int renderer_crash_count;
252 int plugin_crash_count;
253 } NavigationMetrics;
254
255 PageLoadTest() {
256 show_window_ = true;
257 SetPageRange(*CommandLine::ForCurrentProcess());
258 }
259
260 void EnsureBrowserAndServer() {
261 if (!g_browser_existing) {
262 LaunchBrowserAndServer();
263 g_browser_existing = true;
264 }
265 }
266
267 // Load a URL in a browser tab and perform a couple of page down events.
268 // url_string: The URL to navigate to. Accept URL as std::string here
269 // because the url may also act as a test id and needs to
270 // be logged in its original format even if invalid.
271 // log_file: Log file for test results and possible crash dump
272 // files. This file does not need to be opened in which
273 // case nothing is logged.
274 // metrics_output: Return metrics for the page load.
275 // keep_browser: Set to true if the browser should be kept open after
276 // loading the page.
277 // log_only_errors: Set to true if only errors should be logged otherwise
278 // successful navigations will also be logged.
279 bool NavigateToURLLogResult(const std::string& url_string,
280 std::ofstream& log_file,
281 NavigationMetrics* metrics_output,
282 bool keep_browser,
283 bool log_only_error) {
284 GURL url(url_string);
285 NavigationMetrics metrics = {NAVIGATION_ERROR};
286 std::ofstream test_log;
287
288 // Create a test log.
289 g_test_log_path = base::FilePath(FILE_PATH_LITERAL("test_log.log"));
290 test_log.open(g_test_log_path.value().c_str());
291
292 // Get the version of Chrome we're running.
293 std::string last_change;
294 #if defined(OS_WIN)
295 // Check file version info for chrome dll.
296 scoped_ptr<FileVersionInfo> file_info;
297 file_info.reset(
298 FileVersionInfo::CreateFileVersionInfo(base::FilePath(kChromeDll)));
299 last_change = WideToASCII(file_info->last_change());
300 #elif defined(OS_POSIX)
301 // TODO(fmeawad): On Mac, the version retrieved here belongs to the test
302 // module and not the chrome binary, need to be changed to chrome binary
303 // instead.
304 chrome::VersionInfo version_info;
305 last_change = version_info.LastChange();
306 #endif // !defined(OS_WIN)
307 test_log << "Last Change: ";
308 test_log << last_change << std::endl;
309
310 // Log timestamp for test start.
311 base::Time time_now = base::Time::Now();
312 double time_start = time_now.ToDoubleT();
313 test_log << "Test Start: ";
314 test_log << base::TimeFormatFriendlyDateAndTime(time_now) << std::endl;
315
316 // Make sure the browser is running.
317 EnsureBrowserAndServer();
318
319 // Log Browser Launched time.
320 time_now = base::Time::Now();
321 test_log << "browser_launched_seconds=";
322 test_log << (time_now.ToDoubleT() - time_start) << std::endl;
323
324 int result = AUTOMATION_MSG_NAVIGATION_ERROR;
325 // This is essentially what NavigateToURL does except we don't fire
326 // assertion when page loading fails. We log the result instead.
327 {
328 // TabProxy should be released before Browser is closed.
329 scoped_refptr<TabProxy> tab_proxy(GetActiveTab());
330 if (tab_proxy.get())
331 result = tab_proxy->NavigateToURL(url);
332 }
333
334 // Log navigate complete time.
335 time_now = base::Time::Now();
336 test_log << "navigate_complete_seconds=";
337 test_log << (time_now.ToDoubleT() - time_start) << std::endl;
338
339 if (!keep_browser) {
340 CloseBrowserAndServer();
341 g_browser_existing = false;
342 }
343
344 // Log end of test time.
345 time_now = base::Time::Now();
346 test_log << "total_duration_seconds=";
347 test_log << (time_now.ToDoubleT() - time_start) << std::endl;
348
349 // Get navigation result and metrics, and optionally write to the log file
350 // provided. The log format is:
351 // <url> <navigation_result> <browser_crash_count> <renderer_crash_count>
352 // <plugin_crash_count> <crash_dump_count> [chrome_log=<path>
353 // v8_log=<path>] crash_dump=<path>
354 switch (result) {
355 case AUTOMATION_MSG_NAVIGATION_ERROR:
356 metrics.result = NAVIGATION_ERROR;
357 break;
358 case AUTOMATION_MSG_NAVIGATION_SUCCESS:
359 metrics.result = NAVIGATION_SUCCESS;
360 break;
361 case AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED:
362 metrics.result = NAVIGATION_AUTH_NEEDED;
363 break;
364 default:
365 metrics.result = NAVIGATION_ERROR;
366 break;
367 }
368
369 // Get crash dumps - don't delete them if logging.
370 std::vector<base::FilePath> new_crash_dumps;
371 CollectNewCrashDumps(new_crash_dumps, &metrics, !log_file.is_open());
372
373 bool do_log = log_file.is_open() &&
374 (!log_only_error ||
375 metrics.result != NAVIGATION_SUCCESS ||
376 !new_crash_dumps.empty());
377 if (do_log) {
378 log_file << url_string;
379 switch (metrics.result) {
380 case NAVIGATION_ERROR:
381 log_file << " error";
382 break;
383 case NAVIGATION_SUCCESS:
384 log_file << " success";
385 break;
386 case NAVIGATION_AUTH_NEEDED:
387 log_file << " auth_needed";
388 break;
389 case NAVIGATION_TIME_OUT:
390 log_file << " timeout";
391 break;
392 default:
393 break;
394 }
395 }
396
397 #if !defined(OS_MACOSX) // Not used by mac chromebot.
398 // Get stability metrics recorded by Chrome itself.
399 GetStabilityMetrics(&metrics);
400 #endif
401
402 if (do_log) {
403 log_file << " " << metrics.browser_crash_count \
404 // The renderer crash count is flaky due to 1183283.
405 // Ignore the count since we also catch crash by
406 // crash_dump_count.
407 << " " << 0 \
408 << " " << metrics.plugin_crash_count \
409 << " " << metrics.crash_dump_count;
410 }
411
412 // Close test log.
413 test_log.close();
414
415 if (do_log && g_save_debug_log && !g_continuous_load)
416 SaveDebugLogs(log_file);
417
418 // Log revision information for Chrome build under test.
419 if (do_log)
420 log_file << " " << "revision=" << last_change;
421
422 if (do_log) {
423 for (size_t i = 0; i < new_crash_dumps.size(); i++)
424 log_file << " crash_dump=" << new_crash_dumps[i].value().c_str();
425 }
426
427 if (do_log)
428 log_file << std::endl;
429
430 if (metrics_output)
431 *metrics_output = metrics;
432
433 return do_log;
434 }
435
436 void NavigateThroughPageID(std::ofstream& log_file) {
437 if (g_append_page_id) {
438 // For usage 2
439 for (int i = g_start_page; i <= g_end_page; ++i) {
440 const char* server = g_server_url.empty() ? kDefaultServerUrl :
441 g_server_url.c_str();
442 std::string test_page_url(
443 base::StringPrintf("%s/page?id=%d", server, i));
444 NavigateToURLLogResult(
445 test_page_url, log_file, NULL, g_continuous_load, false);
446 }
447 } else {
448 // Don't run if running as a standalone program which is for distributed
449 // testing, to avoid mistakenly hitting web sites with many instances.
450 if (g_stand_alone)
451 return;
452 // For usage 1
453 NavigationMetrics metrics;
454
455 base::FilePath sample_data_dir = GetSampleDataDir();
456 base::FilePath test_page_1 = sample_data_dir.AppendASCII(kTestPage1);
457 base::FilePath test_page_2 = sample_data_dir.AppendASCII(kTestPage2);
458
459 GURL test_url_1 = net::FilePathToFileURL(test_page_1);
460 GURL test_url_2 = net::FilePathToFileURL(test_page_2);
461
462 // Convert back to string so that all calls to navigate are the same.
463 const std::string test_url_1_string = test_url_1.spec();
464 const std::string test_url_2_string = test_url_2.spec();
465
466 NavigateToURLLogResult(
467 test_url_1_string, log_file, &metrics, g_continuous_load, false);
468 // Verify everything is fine
469 EXPECT_EQ(NAVIGATION_SUCCESS, metrics.result);
470 EXPECT_EQ(0, metrics.crash_dump_count);
471 EXPECT_TRUE(metrics.browser_clean_exit);
472 EXPECT_EQ(1, metrics.browser_launch_count);
473 // Both starting page and test_url_1 are loaded.
474 EXPECT_EQ(2, metrics.page_load_count);
475 EXPECT_EQ(0, metrics.browser_crash_count);
476 EXPECT_EQ(0, metrics.renderer_crash_count);
477 EXPECT_EQ(0, metrics.plugin_crash_count);
478
479 // Go to "about:crash"
480 NavigateToURLLogResult(content::kChromeUICrashURL,
481 log_file,
482 &metrics,
483 g_continuous_load,
484 false);
485 // Found a crash dump
486 EXPECT_EQ(1, metrics.crash_dump_count) << kFailedNoCrashService;
487 // Browser did not crash, and exited cleanly.
488 EXPECT_TRUE(metrics.browser_clean_exit);
489 EXPECT_EQ(1, metrics.browser_launch_count);
490 // Only the renderer should have crashed.
491 EXPECT_EQ(0, metrics.browser_crash_count);
492 EXPECT_EQ(1, metrics.renderer_crash_count);
493 EXPECT_EQ(0, metrics.plugin_crash_count);
494
495 NavigateToURLLogResult(
496 test_url_2_string, log_file, &metrics, g_continuous_load, false);
497 // The data on previous crash should be cleared and we should get
498 // metrics for a successful page load.
499 EXPECT_EQ(NAVIGATION_SUCCESS, metrics.result);
500 EXPECT_EQ(0, metrics.crash_dump_count);
501 EXPECT_TRUE(metrics.browser_clean_exit);
502 EXPECT_EQ(1, metrics.browser_launch_count);
503 EXPECT_EQ(0, metrics.browser_crash_count);
504 EXPECT_EQ(0, metrics.renderer_crash_count);
505 EXPECT_EQ(0, metrics.plugin_crash_count);
506
507 // Verify metrics service does what we need when browser process crashes.
508 LaunchBrowserAndServer();
509 {
510 // TabProxy should be released before Browser is closed.
511 scoped_refptr<TabProxy> tab_proxy(GetActiveTab());
512 EXPECT_TRUE(tab_proxy.get());
513 if (tab_proxy.get()) {
514 EXPECT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS,
515 tab_proxy->NavigateToURL(GURL(test_url_1)));
516 }
517 }
518 // Kill browser process.
519 base::ProcessHandle browser_process = process();
520 base::KillProcess(browser_process, 0, false);
521
522 GetStabilityMetrics(&metrics);
523 // This is not a clean shutdown.
524 EXPECT_FALSE(metrics.browser_clean_exit);
525 EXPECT_EQ(1, metrics.browser_crash_count);
526 EXPECT_EQ(0, metrics.renderer_crash_count);
527 EXPECT_EQ(0, metrics.plugin_crash_count);
528 // Relaunch browser so UITest does not fire assertion during TearDown.
529 LaunchBrowserAndServer();
530 }
531 }
532
533 // For usage 3
534 void NavigateThroughURLList(std::ofstream& log_file) {
535 std::ifstream file(g_url_file_path.value().c_str());
536 ASSERT_TRUE(file.is_open());
537
538 for (int line_index = 1;
539 line_index <= g_end_index && !file.eof();
540 ++line_index) {
541 std::string url_str;
542 std::getline(file, url_str);
543
544 if (file.fail())
545 break;
546
547 if (g_start_index <= line_index) {
548 if (g_stress_opt || g_stress_deopt) {
549 // Make sure the browser is running to communicate the stress
550 // setting.
551 EnsureBrowserAndServer();
552 v8::Testing::StressType stress_type =
553 g_stress_opt
554 ? v8::Testing::kStressTypeOpt
555 : v8::Testing::kStressTypeDeopt;
556 scoped_refptr<TabProxy> tab_proxy(GetActiveTab());
557 if (tab_proxy.get()) {
558 tab_proxy->JavaScriptStressTestControl(
559 kJavaScriptStressTestSetStressRunType, stress_type);
560 }
561
562 bool success = true;
563 // Load each page a number of times and keep the same browser open
564 // for these loads. This loop will end if an error is encountered
565 // during one of the loads and the error logged.
566 for (int i = 0;
567 i < v8::Testing::GetStressRuns() && success;
568 i++) {
569 bool last_load = (i == (v8::Testing::GetStressRuns() - 1));
570 bool keep_browser = !last_load || g_continuous_load;
571 bool log_only_error = !last_load;
572 NavigationMetrics metrics;
573
574 scoped_refptr<TabProxy> tab_proxy(GetActiveTab());
575 if (tab_proxy.get()) {
576 tab_proxy->JavaScriptStressTestControl(
577 kJavaScriptStressTestPrepareStressRun, i);
578 }
579 bool did_log_error;
580 did_log_error = NavigateToURLLogResult(url_str,
581 log_file,
582 &metrics,
583 keep_browser,
584 log_only_error);
585 success = metrics.result == NAVIGATION_SUCCESS && !did_log_error;
586 }
587 } else {
588 NavigateToURLLogResult(
589 url_str, log_file, NULL, g_continuous_load, false);
590 }
591 }
592 }
593
594 file.close();
595 }
596
597 protected:
598 // Call the base class's SetUp method and initialize our own class members.
599 virtual void SetUp() {
600 // Set UI Test members before setting up browser.
601 clear_profile_ = g_clear_profile;
602
603 UITest::SetUp();
604 g_browser_existing = true;
605
606 // If 'BREAKPAD_DUMP_LOCATION' environment variable is set, use it instead.
607 scoped_ptr<base::Environment> env(base::Environment::Create());
608 std::string alternate_minidump_location;
609 if (env->GetVar("BREAKPAD_DUMP_LOCATION", &alternate_minidump_location)) {
610 crash_dumps_dir_path_ = base::FilePath::FromUTF8Unsafe(
611 alternate_minidump_location);
612 } else {
613 PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dumps_dir_path_);
614 }
615
616 base::FileEnumerator enumerator(crash_dumps_dir_path_,
617 false, // not recursive
618 base::FileEnumerator::FILES);
619 for (base::FilePath path = enumerator.Next(); !path.value().empty();
620 path = enumerator.Next()) {
621 if (path.MatchesExtension(FILE_PATH_LITERAL(".dmp")))
622 crash_dumps_[path.BaseName()] = true;
623 }
624 }
625
626 base::FilePath ConstructSavedDebugLogPath(
627 const base::FilePath& debug_log_path,
628 int index) {
629 std::string suffix("_");
630 suffix.append(base::IntToString(index));
631 return debug_log_path.InsertBeforeExtensionASCII(suffix);
632 }
633
634 void SaveDebugLog(const base::FilePath& log_path, const std::wstring& log_id,
635 std::ofstream& log_file, int index) {
636 if (!log_path.empty()) {
637 base::FilePath saved_log_file_path =
638 ConstructSavedDebugLogPath(log_path, index);
639 if (base::Move(log_path, saved_log_file_path)) {
640 log_file << " " << log_id << "=" << saved_log_file_path.value();
641 }
642 }
643 }
644
645 // Rename the chrome and v8 debug log files if existing, and save the file
646 // paths in the log_file provided.
647 void SaveDebugLogs(std::ofstream& log_file) {
648 static int url_count = 1;
649 SaveDebugLog(g_chrome_log_path, L"chrome_log", log_file, url_count);
650 SaveDebugLog(g_v8_log_path, L"v8_log", log_file, url_count);
651 SaveDebugLog(g_test_log_path, L"test_log", log_file, url_count);
652 url_count++;
653 }
654
655 // Delete a crash dump file.
656 void DeleteCrashDump(base::FilePath crash_dump_file_name) {
657 base::FilePath crash_dump_file_path(crash_dumps_dir_path_);
658 crash_dump_file_path = crash_dump_file_path.Append(crash_dump_file_name);
659 base::FilePath crash_text_file_path =
660 crash_dump_file_path.ReplaceExtension(FILE_PATH_LITERAL("txt"));
661
662 ASSERT_TRUE(file_util::DieFileDie(crash_dump_file_path, false));
663 ASSERT_TRUE(file_util::DieFileDie(crash_text_file_path, false));
664 }
665
666 bool HasNewCrashDumps() {
667 base::FileEnumerator enumerator(crash_dumps_dir_path_,
668 false, // not recursive
669 base::FileEnumerator::FILES);
670 for (base::FilePath path = enumerator.Next(); !path.value().empty();
671 path = enumerator.Next()) {
672 if (path.MatchesExtension(FILE_PATH_LITERAL(".dmp")) &&
673 !crash_dumps_[path.BaseName()]) {
674 return true;
675 }
676 }
677
678 return false;
679 }
680
681 // Check whether there are new .dmp files. Return the list and optionally
682 // delete them afterwards.
683 void CollectNewCrashDumps(std::vector<base::FilePath>& new_crash_dumps,
684 NavigationMetrics* metrics,
685 bool delete_dumps) {
686 int num_dumps = 0;
687 base::FileEnumerator enumerator(crash_dumps_dir_path_,
688 false, // not recursive
689 base::FileEnumerator::FILES);
690 for (base::FilePath path = enumerator.Next(); !path.value().empty();
691 path = enumerator.Next()) {
692 if (path.MatchesExtension(FILE_PATH_LITERAL(".dmp")) &&
693 !crash_dumps_[path.BaseName()]) {
694 crash_dumps_[path.BaseName()] = true;
695 base::FilePath crash_dump_file_path(crash_dumps_dir_path_);
696 crash_dump_file_path = crash_dump_file_path.Append(path.BaseName());
697 new_crash_dumps.push_back(crash_dump_file_path);
698 if (delete_dumps)
699 DeleteCrashDump(path.BaseName());
700 num_dumps++;
701 }
702 }
703 if (metrics)
704 metrics->crash_dump_count = num_dumps;
705 }
706
707 // Get a PrefService whose contents correspond to the Local State file
708 // that was saved by the app as it closed. The caller takes ownership of the
709 // returned PrefService object.
710 PrefService* GetLocalState(PrefRegistry* registry) {
711 base::FilePath path = user_data_dir().Append(chrome::kLocalStateFilename);
712 PrefServiceMockBuilder builder;
713 builder.WithUserFilePrefs(
714 path, base::MessageLoop::current()->message_loop_proxy().get());
715 return builder.Create(registry);
716 }
717
718 void GetStabilityMetrics(NavigationMetrics* metrics) {
719 if (!metrics)
720 return;
721 scoped_refptr<PrefRegistrySimple> registry = new PrefRegistrySimple();
722 registry->RegisterBooleanPref(prefs::kStabilityExitedCleanly, false);
723 registry->RegisterIntegerPref(prefs::kStabilityLaunchCount, -1);
724 registry->RegisterIntegerPref(prefs::kStabilityPageLoadCount, -1);
725 registry->RegisterIntegerPref(prefs::kStabilityCrashCount, 0);
726 registry->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0);
727
728 scoped_ptr<PrefService> local_state(GetLocalState(registry.get()));
729 if (!local_state.get())
730 return;
731
732 metrics->browser_clean_exit =
733 local_state->GetBoolean(prefs::kStabilityExitedCleanly);
734 metrics->browser_launch_count =
735 local_state->GetInteger(prefs::kStabilityLaunchCount);
736 metrics->page_load_count =
737 local_state->GetInteger(prefs::kStabilityPageLoadCount);
738 metrics->browser_crash_count =
739 local_state->GetInteger(prefs::kStabilityCrashCount);
740 metrics->renderer_crash_count =
741 local_state->GetInteger(prefs::kStabilityRendererCrashCount);
742 // TODO(huanr)
743 metrics->plugin_crash_count = 0;
744
745 if (!metrics->browser_clean_exit)
746 metrics->browser_crash_count++;
747 }
748
749 base::FilePath GetSampleDataDir() {
750 base::FilePath test_dir;
751 PathService::Get(chrome::DIR_TEST_DATA, &test_dir);
752 test_dir = test_dir.AppendASCII("reliability");
753 test_dir = test_dir.AppendASCII("sample_pages");
754 return test_dir;
755 }
756
757 // The pathname of Chrome's crash dumps directory.
758 base::FilePath crash_dumps_dir_path_;
759
760 // The set of all the crash dumps we have seen. Each crash generates a
761 // .dmp and a .txt file in the crash dumps directory. We only store the
762 // .dmp files in this set.
763 //
764 // The set is implemented as a std::map. The key is the file name, and
765 // the value is false (the file is not in the set) or true (the file is
766 // in the set). The initial value for any key in std::map is 0 (false),
767 // which in this case means a new file is not in the set initially,
768 // exactly the semantics we want.
769 std::map<base::FilePath, bool> crash_dumps_;
770 };
771
772 TEST_F(PageLoadTest, Reliability) {
773 std::ofstream log_file;
774
775 if (!g_log_file_path.empty()) {
776 log_file.open(g_log_file_path.value().c_str());
777 }
778
779 for (int k = 0; k < g_iterations; ++k) {
780 if (g_url_file_path.empty()) {
781 NavigateThroughPageID(log_file);
782 } else {
783 NavigateThroughURLList(log_file);
784 }
785 }
786
787 if (!g_end_url.empty()) {
788 NavigateToURLLogResult(
789 g_end_url, log_file, NULL, g_continuous_load, false);
790 }
791
792 log_file.close();
793 }
794
795 } // namespace
796
OLDNEW
« no previous file with comments | « chrome/test/reliability/automated_ui_tests.cc ('k') | chrome/tools/automated_ui_test_tools/ui_action_generator.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698