Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / page / record_wpr.py
1 # Copyright 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 import logging
6 import sys
7
8 from telemetry import benchmark
9 from telemetry.core import browser_options
10 from telemetry.core import discover
11 from telemetry.core import util
12 from telemetry.core import wpr_modes
13 from telemetry.page import page_runner
14 from telemetry.page import page_set
15 from telemetry.page import page_test
16 from telemetry.page import profile_creator
17 from telemetry.page import test_expectations
18 from telemetry.results import results_options
19
20
21 class RecorderPageTest(page_test.PageTest):  # pylint: disable=W0223
22   def __init__(self, action_names):
23     super(RecorderPageTest, self).__init__()
24     self._action_names = action_names
25     self.page_test = None
26
27   def CanRunForPage(self, page):
28     return page.url.startswith('http')
29
30   def WillNavigateToPage(self, page, tab):
31     """Override to ensure all resources are fetched from network."""
32     tab.ClearCache(force=False)
33     if self.page_test:
34       self.page_test.options = self.options
35       self.page_test.WillNavigateToPage(page, tab)
36
37   def DidNavigateToPage(self, page, tab):
38     if self.page_test:
39       self.page_test.DidNavigateToPage(page, tab)
40
41   def WillRunActions(self, page, tab):
42     if self.page_test:
43       self.page_test.WillRunActions(page, tab)
44
45   def DidRunActions(self, page, tab):
46     if self.page_test:
47       self.page_test.DidRunActions(page, tab)
48
49   def ValidateAndMeasurePage(self, page, tab, results):
50     if self.page_test:
51       self.page_test.ValidateAndMeasurePage(page, tab, results)
52
53   def RunPage(self, page, tab, results):
54     tab.WaitForDocumentReadyStateToBeComplete()
55     util.WaitFor(tab.HasReachedQuiescence, 30)
56
57     if self.page_test:
58       self._action_name_to_run = self.page_test.action_name_to_run
59       self.page_test.RunPage(page, tab, results)
60       return
61
62     should_reload = False
63     # Run the actions on the page for all available measurements.
64     for action_name in self._action_names:
65       # Skip this action if it is not defined
66       if not hasattr(page, action_name):
67         continue
68       # Reload the page between actions to start with a clean slate.
69       if should_reload:
70         self.RunNavigateSteps(page, tab)
71       self._action_name_to_run = action_name
72       super(RecorderPageTest, self).RunPage(page, tab, results)
73       should_reload = True
74
75   def RunNavigateSteps(self, page, tab):
76     if self.page_test:
77       self.page_test.RunNavigateSteps(page, tab)
78     else:
79       super(RecorderPageTest, self).RunNavigateSteps(page, tab)
80
81
82 def FindAllActionNames(base_dir):
83   """Returns a set of of all action names used in our measurements."""
84   action_names = set()
85   # Get all PageTests except for ProfileCreators (see crbug.com/319573)
86   for _, cls in discover.DiscoverClasses(
87       base_dir, base_dir, page_test.PageTest).items():
88     if not issubclass(cls, profile_creator.ProfileCreator):
89       action_name = cls().action_name_to_run
90       if action_name:
91         action_names.add(action_name)
92   return action_names
93
94
95 def _MaybeGetInstanceOfClass(target, base_dir, cls):
96   if isinstance(target, cls):
97     return target
98   classes = discover.DiscoverClasses(base_dir, base_dir, cls,
99                                      index_by_class_name=True)
100   return classes[target]() if target in classes else None
101
102
103 class WprRecorder(object):
104
105   def __init__(self, base_dir, target, args=None):
106     action_names_to_run = FindAllActionNames(base_dir)
107     self._record_page_test = RecorderPageTest(action_names_to_run)
108     self._options = self._CreateOptions()
109
110     self._benchmark = _MaybeGetInstanceOfClass(target, base_dir,
111                                                benchmark.Benchmark)
112     if self._benchmark is not None:
113       self._record_page_test.page_test = self._benchmark.test()
114     self._parser = self._options.CreateParser(usage='%prog <PageSet|Benchmark>')
115     self._AddCommandLineArgs()
116     self._ParseArgs(args)
117     self._ProcessCommandLineArgs()
118     self._page_set = self._GetPageSet(base_dir, target)
119
120   @property
121   def options(self):
122     return self._options
123
124   def _CreateOptions(self):
125     options = browser_options.BrowserFinderOptions()
126     options.browser_options.wpr_mode = wpr_modes.WPR_RECORD
127     options.browser_options.no_proxy_server = True
128     return options
129
130   def CreateResults(self):
131     if self._benchmark is not None:
132       benchmark_metadata = self._benchmark.GetMetadata()
133     else:
134       benchmark_metadata = benchmark.BenchmarkMetadata('record_wpr')
135
136     return results_options.CreateResults(benchmark_metadata, self._options)
137
138   def _AddCommandLineArgs(self):
139     page_runner.AddCommandLineArgs(self._parser)
140     if self._benchmark is not None:
141       self._benchmark.AddCommandLineArgs(self._parser)
142       self._benchmark.SetArgumentDefaults(self._parser)
143     self._SetArgumentDefaults()
144
145   def _SetArgumentDefaults(self):
146     self._parser.set_defaults(**{'output_format': 'none'})
147
148   def _ParseArgs(self, args=None):
149     args_to_parse = sys.argv[1:] if args is None else args
150     self._parser.parse_args(args_to_parse)
151
152   def _ProcessCommandLineArgs(self):
153     page_runner.ProcessCommandLineArgs(self._parser, self._options)
154     if self._benchmark is not None:
155       self._benchmark.ProcessCommandLineArgs(self._parser, self._options)
156
157   def _GetPageSet(self, base_dir, target):
158     if self._benchmark is not None:
159       return self._benchmark.CreatePageSet(self._options)
160     ps = _MaybeGetInstanceOfClass(target, base_dir, page_set.PageSet)
161     if ps is None:
162       self._parser.print_usage()
163       sys.exit(1)
164     return ps
165
166   def Record(self, results):
167     self._page_set.wpr_archive_info.AddNewTemporaryRecording()
168     self._record_page_test.CustomizeBrowserOptions(self._options)
169     page_runner.Run(self._record_page_test, self._page_set,
170         test_expectations.TestExpectations(), self._options, results)
171
172   def HandleResults(self, results):
173     if results.failures or results.skipped_values:
174       logging.warning('Some pages failed and/or were skipped. The recording '
175                       'has not been updated for these pages.')
176     results.PrintSummary()
177     self._page_set.wpr_archive_info.AddRecordedPages(
178         results.pages_that_succeeded)
179
180
181 def Main(base_dir):
182   quick_args = [a for a in sys.argv[1:] if not a.startswith('-')]
183   if len(quick_args) != 1:
184     print >> sys.stderr, 'Usage: record_wpr <PageSet|Benchmark>\n'
185     sys.exit(1)
186   target = quick_args.pop()
187   wpr_recorder = WprRecorder(base_dir, target)
188   results = wpr_recorder.CreateResults()
189   wpr_recorder.Record(results)
190   wpr_recorder.HandleResults(results)
191   return min(255, len(results.failures))