- add sources.
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / core / browser_options.py
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 import copy
6 import logging
7 import optparse
8 import os
9 import shlex
10 import sys
11
12 from telemetry.core import browser_finder
13 from telemetry.core import profile_types
14 from telemetry.core import repeat_options
15 from telemetry.core import util
16 from telemetry.core import wpr_modes
17 from telemetry.core.platform.profiler import profiler_finder
18
19
20 class BrowserFinderOptions(optparse.Values):
21   """Options to be used for discovering a browser."""
22
23   def __init__(self, browser_type=None):
24     optparse.Values.__init__(self)
25
26     self.browser_type = browser_type
27     self.browser_executable = None
28     self.chrome_root = None
29     self.android_device = None
30     self.cros_ssh_identity = None
31
32     self.extensions_to_load = []
33
34     # If set, copy the generated profile to this path on exit.
35     self.output_profile_path = None
36
37     self.cros_remote = None
38
39     self.profiler = None
40     self.verbosity = 0
41
42     self.page_filter = None
43     self.page_filter_exclude = None
44
45     self.repeat_options = repeat_options.RepeatOptions()
46     self.browser_options = BrowserOptions()
47     self.output_file = None
48     self.skip_navigate_on_repeat = False
49
50     self.android_rndis = False
51
52   def Copy(self):
53     return copy.deepcopy(self)
54
55   def CreateParser(self, *args, **kwargs):
56     parser = optparse.OptionParser(*args, **kwargs)
57
58     # Selection group
59     group = optparse.OptionGroup(parser, 'Which browser to use')
60     group.add_option('--browser',
61         dest='browser_type',
62         default=None,
63         help='Browser type to run, '
64              'in order of priority. Supported values: list,%s' %
65              browser_finder.ALL_BROWSER_TYPES)
66     group.add_option('--browser-executable',
67         dest='browser_executable',
68         help='The exact browser to run.')
69     group.add_option('--chrome-root',
70         dest='chrome_root',
71         help='Where to look for chrome builds.'
72              'Defaults to searching parent dirs by default.')
73     group.add_option('--device',
74         dest='android_device',
75         help='The android device ID to use'
76              'If not specified, only 0 or 1 connected devcies are supported.')
77     group.add_option(
78         '--remote',
79         dest='cros_remote',
80         help='The IP address of a remote ChromeOS device to use.')
81     identity = None
82     testing_rsa = os.path.join(
83         util.GetChromiumSrcDir(),
84         'third_party', 'chromite', 'ssh_keys', 'testing_rsa')
85     if os.path.exists(testing_rsa):
86       identity = testing_rsa
87     group.add_option('--identity',
88         dest='cros_ssh_identity',
89         default=identity,
90         help='The identity file to use when ssh\'ing into the ChromeOS device')
91     parser.add_option_group(group)
92
93     # Page set options
94     group = optparse.OptionGroup(parser, 'Page set options')
95     group.add_option('--pageset-shuffle', action='store_true',
96         dest='pageset_shuffle',
97         help='Shuffle the order of pages within a pageset.')
98     group.add_option('--pageset-shuffle-order-file',
99         dest='pageset_shuffle_order_file', default=None,
100         help='Filename of an output of a previously run test on the current ' +
101         'pageset. The tests will run in the same order again, overriding ' +
102         'what is specified by --page-repeat and --pageset-repeat.')
103     parser.add_option_group(group)
104
105     group = optparse.OptionGroup(parser, 'Web Page Replay options')
106     group.add_option('--allow-live-sites',
107         dest='allow_live_sites', action='store_true',
108         help='Run against live sites if the Web Page Replay archives don\'t '
109              'exist. Without this flag, the test will just fail instead '
110              'of running against live sites.')
111     parser.add_option_group(group)
112
113     # Debugging options
114     group = optparse.OptionGroup(parser, 'When things go wrong')
115     profiler_choices = profiler_finder.GetAllAvailableProfilers()
116     group.add_option(
117       '--profiler', default=None, type='choice',
118       choices=profiler_choices,
119       help=('Record profiling data using this tool. Supported values: ' +
120             ', '.join(profiler_choices)))
121     group.add_option(
122       '-v', '--verbose', action='count', dest='verbosity',
123       help='Increase verbosity level (repeat as needed)')
124     group.add_option('--print-bootstrap-deps',
125                      action='store_true',
126                      help='Output bootstrap deps list.')
127     parser.add_option_group(group)
128
129     # Platform options
130     group = optparse.OptionGroup(parser, 'Platform options')
131     group.add_option('--no-performance-mode', action='store_true',
132         help='Some platforms run on "full performance mode" where the '
133         'test is executed at maximum CPU speed in order to minimize noise '
134         '(specially important for dashboards / continuous builds). '
135         'This option prevents Telemetry from tweaking such platform settings.')
136     group.add_option('--android-rndis', dest='android_rndis', default=False,
137         action='store_true', help='Use RNDIS forwarding on Android.')
138     group.add_option('--no-android-rndis', dest='android_rndis',
139         action='store_false', help='Do not use RNDIS forwarding on Android.'
140         ' [default]')
141     parser.add_option_group(group)
142
143     # Repeat options.
144     self.repeat_options.AddCommandLineOptions(parser)
145
146     # Browser options.
147     self.browser_options.AddCommandLineOptions(parser)
148
149     real_parse = parser.parse_args
150     def ParseArgs(args=None):
151       defaults = parser.get_default_values()
152       for k, v in defaults.__dict__.items():
153         if k in self.__dict__ and self.__dict__[k] != None:
154           continue
155         self.__dict__[k] = v
156       ret = real_parse(args, self) # pylint: disable=E1121
157
158       if self.verbosity >= 2:
159         logging.getLogger().setLevel(logging.DEBUG)
160       elif self.verbosity:
161         logging.getLogger().setLevel(logging.INFO)
162       else:
163         logging.getLogger().setLevel(logging.WARNING)
164
165       if self.browser_executable and not self.browser_type:
166         self.browser_type = 'exact'
167       if self.browser_type == 'list':
168         try:
169           types = browser_finder.GetAllAvailableBrowserTypes(self)
170         except browser_finder.BrowserFinderException, ex:
171           sys.stderr.write('ERROR: ' + str(ex))
172           sys.exit(1)
173         sys.stdout.write('Available browsers:\n')
174         sys.stdout.write('  %s\n' % '\n  '.join(types))
175         sys.exit(0)
176
177       # Parse repeat options.
178       self.repeat_options.UpdateFromParseResults(self, parser)
179
180       # Parse browser options.
181       self.browser_options.UpdateFromParseResults(self)
182
183       return ret
184     parser.parse_args = ParseArgs
185     return parser
186
187   def AppendExtraBrowserArgs(self, args):
188     self.browser_options.AppendExtraBrowserArgs(args)
189
190   def MergeDefaultValues(self, defaults):
191     for k, v in defaults.__dict__.items():
192       self.ensure_value(k, v)
193
194 class BrowserOptions(object):
195   """Options to be used for launching a browser."""
196   def __init__(self):
197     self.browser_type = None
198     self.show_stdout = False
199
200     # When set to True, the browser will use the default profile.  Telemetry
201     # will not provide an alternate profile directory.
202     self.dont_override_profile = False
203     self.profile_dir = None
204     self.profile_type = None
205     self._extra_browser_args = set()
206     self.extra_wpr_args = []
207     self.wpr_mode = wpr_modes.WPR_OFF
208
209     self.no_proxy_server = False
210     self.browser_user_agent_type = None
211
212     self.clear_sytem_cache_for_browser_and_profile_on_start = False
213     self.startup_url = None
214
215     self.keep_test_server_ports = False
216
217     # Background pages of built-in component extensions can interfere with
218     # performance measurements.
219     self.disable_component_extensions_with_background_pages = True
220
221   def AddCommandLineOptions(self, parser):
222     group = optparse.OptionGroup(parser, 'Browser options')
223     profile_choices = profile_types.GetProfileTypes()
224     group.add_option('--profile-type',
225         dest='profile_type',
226         type='choice',
227         default='clean',
228         choices=profile_choices,
229         help=('The user profile to use. A clean profile is used by default. '
230               'Supported values: ' + ', '.join(profile_choices)))
231     group.add_option('--profile-dir',
232         dest='profile_dir',
233         help='Profile directory to launch the browser with. '
234              'A clean profile is used by default')
235     group.add_option('--extra-browser-args',
236         dest='extra_browser_args_as_string',
237         help='Additional arguments to pass to the browser when it starts')
238     group.add_option('--extra-wpr-args',
239         dest='extra_wpr_args_as_string',
240         help=('Additional arguments to pass to Web Page Replay. '
241               'See third_party/webpagereplay/replay.py for usage.'))
242     group.add_option('--show-stdout',
243         action='store_true',
244         help='When possible, will display the stdout of the process')
245     parser.add_option_group(group)
246
247     # Android options. TODO(achuith): Move to AndroidBrowserOptions.
248     group = optparse.OptionGroup(parser, 'Android options')
249     group.add_option('--keep_test_server_ports',
250         action='store_true',
251         help='Indicates the test server ports must be kept. When this is run '
252              'via a sharder the test server ports should be kept and should '
253              'not be reset.')
254     parser.add_option_group(group)
255
256     group = optparse.OptionGroup(parser, 'Compatibility options')
257     group.add_option('--gtest_output',
258         help='Ignored argument for compatibility with runtest.py harness')
259     parser.add_option_group(group)
260
261
262   def UpdateFromParseResults(self, finder_options):
263     """Copies our options from finder_options"""
264     browser_options_list = [
265         'profile_type', 'profile_dir',
266         'extra_browser_args_as_string', 'extra_wpr_args_as_string',
267         'show_stdout'
268         ]
269     for o in browser_options_list:
270       a = getattr(finder_options, o, None)
271       if a is not None:
272         setattr(self, o, a)
273         delattr(finder_options, o)
274
275     self.browser_type = finder_options.browser_type
276
277     if hasattr(self, 'extra_browser_args_as_string'): # pylint: disable=E1101
278       tmp = shlex.split(
279         self.extra_browser_args_as_string) # pylint: disable=E1101
280       self.AppendExtraBrowserArgs(tmp)
281       delattr(self, 'extra_browser_args_as_string')
282     if hasattr(self, 'extra_wpr_args_as_string'): # pylint: disable=E1101
283       tmp = shlex.split(
284         self.extra_wpr_args_as_string) # pylint: disable=E1101
285       self.extra_wpr_args.extend(tmp)
286       delattr(self, 'extra_wpr_args_as_string')
287     if self.profile_type == 'default':
288       self.dont_override_profile = True
289
290     if self.profile_dir and self.profile_type != 'clean':
291       raise Exception("It's illegal to specify both --profile-type and"
292           " --profile-dir.")
293
294     if self.profile_dir and not os.path.isdir(self.profile_dir):
295       raise Exception("Directory specified by --profile-dir (%s) doesn't"
296           " exist or isn't a directory." % (self.profile_dir))
297
298     if not self.profile_dir:
299       self.profile_dir = profile_types.GetProfileDir(self.profile_type)
300
301     # This deferred import is necessary because browser_options is imported in
302     # telemetry/telemetry/__init__.py.
303     from telemetry.core.backends.chrome import chrome_browser_options
304     finder_options.browser_options = (
305         chrome_browser_options.CreateChromeBrowserOptions(self))
306
307   @property
308   def extra_browser_args(self):
309     return self._extra_browser_args
310
311   def AppendExtraBrowserArgs(self, args):
312     if isinstance(args, list):
313       self._extra_browser_args.update(args)
314     else:
315       self._extra_browser_args.add(args)