Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / core / browser_options.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 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 util
15 from telemetry.core import wpr_modes
16 from telemetry.core.platform.profiler import profiler_finder
17
18 util.AddDirToPythonPath(
19     util.GetChromiumSrcDir(), 'third_party', 'webpagereplay')
20 import net_configs  # pylint: disable=F0401
21
22
23 class BrowserFinderOptions(optparse.Values):
24   """Options to be used for discovering a browser."""
25
26   def __init__(self, browser_type=None):
27     optparse.Values.__init__(self)
28
29     self.browser_type = browser_type
30     self.browser_executable = None
31     self.chrome_root = None
32     self.android_device = None
33     self.cros_ssh_identity = None
34
35     self.extensions_to_load = []
36
37     # If set, copy the generated profile to this path on exit.
38     self.output_profile_path = None
39
40     self.cros_remote = None
41
42     self.profiler = None
43     self.verbosity = 0
44
45     self.browser_options = BrowserOptions()
46     self.output_file = None
47
48     self.android_rndis = False
49     self.no_performance_mode = False
50
51   def __repr__(self):
52     return str(sorted(self.__dict__.items()))
53
54   def Copy(self):
55     return copy.deepcopy(self)
56
57   def CreateParser(self, *args, **kwargs):
58     parser = optparse.OptionParser(*args, **kwargs)
59
60     # Selection group
61     group = optparse.OptionGroup(parser, 'Which browser to use')
62     group.add_option('--browser',
63         dest='browser_type',
64         default=None,
65         help='Browser type to run, '
66              'in order of priority. Supported values: list,%s' %
67              ','.join(browser_finder.FindAllBrowserTypes(self)))
68     group.add_option('--browser-executable',
69         dest='browser_executable',
70         help='The exact browser to run.')
71     group.add_option('--chrome-root',
72         dest='chrome_root',
73         help='Where to look for chrome builds.'
74              'Defaults to searching parent dirs by default.')
75     group.add_option('--device',
76         dest='android_device',
77         help='The android device ID to use'
78              'If not specified, only 0 or 1 connected devices are supported.')
79     group.add_option('--target-arch',
80         dest='target_arch',
81         help='The target architecture of the browser. Options available are: '
82              'x64, x86_64, arm, arm64 and mips. '
83              'Defaults to the default architecture of the platform if omitted.')
84     group.add_option(
85         '--remote',
86         dest='cros_remote',
87         help='The IP address of a remote ChromeOS device to use.')
88     identity = None
89     testing_rsa = os.path.join(
90         util.GetChromiumSrcDir(),
91         'third_party', 'chromite', 'ssh_keys', 'testing_rsa')
92     if os.path.exists(testing_rsa):
93       identity = testing_rsa
94     group.add_option('--identity',
95         dest='cros_ssh_identity',
96         default=identity,
97         help='The identity file to use when ssh\'ing into the ChromeOS device')
98     parser.add_option_group(group)
99
100     # Debugging options
101     group = optparse.OptionGroup(parser, 'When things go wrong')
102     profiler_choices = profiler_finder.GetAllAvailableProfilers()
103     group.add_option(
104         '--profiler', default=None, type='choice',
105         choices=profiler_choices,
106         help='Record profiling data using this tool. Supported values: ' +
107              ', '.join(profiler_choices))
108     group.add_option(
109         '--interactive', dest='interactive', action='store_true',
110         help='Let the user interact with the page; the actions specified for '
111              'the page are not run.')
112     group.add_option(
113         '-v', '--verbose', action='count', dest='verbosity',
114         help='Increase verbosity level (repeat as needed)')
115     group.add_option('--print-bootstrap-deps',
116                      action='store_true',
117                      help='Output bootstrap deps list.')
118     group.add_option('--disable-crash-service',
119                      dest='disable_crash_service',
120                      default=False,
121                      action='store_true',
122                      help='Whether to disable crash service. NOTE: this flag '
123                      'is added temporarily for crbug.com/424024, and will be '
124                      'deprecated as soon as the bug is marked fixed.')
125     parser.add_option_group(group)
126
127     # Platform options
128     group = optparse.OptionGroup(parser, 'Platform options')
129     group.add_option('--no-performance-mode', action='store_true',
130         help='Some platforms run on "full performance mode" where the '
131         'test is executed at maximum CPU speed in order to minimize noise '
132         '(specially important for dashboards / continuous builds). '
133         'This option prevents Telemetry from tweaking such platform settings.')
134     group.add_option('--android-rndis', dest='android_rndis', default=False,
135         action='store_true', help='Use RNDIS forwarding on Android.')
136     group.add_option('--no-android-rndis', dest='android_rndis',
137         action='store_false', help='Do not use RNDIS forwarding on Android.'
138         ' [default]')
139     parser.add_option_group(group)
140
141     # Browser options.
142     self.browser_options.AddCommandLineArgs(parser)
143
144     real_parse = parser.parse_args
145     def ParseArgs(args=None):
146       defaults = parser.get_default_values()
147       for k, v in defaults.__dict__.items():
148         if k in self.__dict__ and self.__dict__[k] != None:
149           continue
150         self.__dict__[k] = v
151       ret = real_parse(args, self) # pylint: disable=E1121
152
153       if self.verbosity >= 2:
154         logging.getLogger().setLevel(logging.DEBUG)
155       elif self.verbosity:
156         logging.getLogger().setLevel(logging.INFO)
157       else:
158         logging.getLogger().setLevel(logging.WARNING)
159
160       if self.browser_executable and not self.browser_type:
161         self.browser_type = 'exact'
162       if self.browser_type == 'list':
163         try:
164           types = browser_finder.GetAllAvailableBrowserTypes(self)
165         except browser_finder.BrowserFinderException, ex:
166           sys.stderr.write('ERROR: ' + str(ex))
167           sys.exit(1)
168         sys.stdout.write('Available browsers:\n')
169         sys.stdout.write('  %s\n' % '\n  '.join(types))
170         sys.exit(0)
171
172       # Parse browser options.
173       self.browser_options.UpdateFromParseResults(self)
174
175       return ret
176     parser.parse_args = ParseArgs
177     return parser
178
179   def AppendExtraBrowserArgs(self, args):
180     self.browser_options.AppendExtraBrowserArgs(args)
181
182   def MergeDefaultValues(self, defaults):
183     for k, v in defaults.__dict__.items():
184       self.ensure_value(k, v)
185
186 class BrowserOptions(object):
187   """Options to be used for launching a browser."""
188   def __init__(self):
189     self.browser_type = None
190     self.show_stdout = False
191
192     # When set to True, the browser will use the default profile.  Telemetry
193     # will not provide an alternate profile directory.
194     self.dont_override_profile = False
195     self.profile_dir = None
196     self.profile_type = None
197     self._extra_browser_args = set()
198     self.extra_wpr_args = []
199     self.wpr_mode = wpr_modes.WPR_OFF
200     self.netsim = None
201
202     self.disable_background_networking = True
203     self.no_proxy_server = False
204     self.browser_user_agent_type = None
205
206     self.clear_sytem_cache_for_browser_and_profile_on_start = False
207     self.startup_url = 'about:blank'
208
209     # Background pages of built-in component extensions can interfere with
210     # performance measurements.
211     self.disable_component_extensions_with_background_pages = True
212
213     # Whether to use the new code path for choosing an ephemeral port for
214     # DevTools. The bots set this to true. When Chrome 37 reaches stable,
215     # remove this setting and the old code path. http://crbug.com/379980
216     self.use_devtools_active_port = False
217
218   def __repr__(self):
219     return str(sorted(self.__dict__.items()))
220
221   @classmethod
222   def AddCommandLineArgs(cls, parser):
223
224     ############################################################################
225     # Please do not add any more options here without first discussing with    #
226     # a telemetry owner. This is not the right place for platform-specific     #
227     # options.                                                                 #
228     ############################################################################
229
230     group = optparse.OptionGroup(parser, 'Browser options')
231     profile_choices = profile_types.GetProfileTypes()
232     group.add_option('--profile-type',
233         dest='profile_type',
234         type='choice',
235         default='clean',
236         choices=profile_choices,
237         help=('The user profile to use. A clean profile is used by default. '
238               'Supported values: ' + ', '.join(profile_choices)))
239     group.add_option('--profile-dir',
240         dest='profile_dir',
241         help='Profile directory to launch the browser with. '
242              'A clean profile is used by default')
243     group.add_option('--extra-browser-args',
244         dest='extra_browser_args_as_string',
245         help='Additional arguments to pass to the browser when it starts')
246     group.add_option('--extra-wpr-args',
247         dest='extra_wpr_args_as_string',
248         help=('Additional arguments to pass to Web Page Replay. '
249               'See third_party/webpagereplay/replay.py for usage.'))
250     group.add_option('--netsim', default=None, type='choice',
251         choices=net_configs.NET_CONFIG_NAMES,
252         help=('Run benchmark under simulated network conditions. '
253               'Will prompt for sudo. Supported values: ' +
254               ', '.join(net_configs.NET_CONFIG_NAMES)))
255     group.add_option('--show-stdout',
256         action='store_true',
257         help='When possible, will display the stdout of the process')
258     # This hidden option is to be removed, and the older code path deleted,
259     # once Chrome 37 reaches Stable. http://crbug.com/379980
260     group.add_option('--use-devtools-active-port',
261         action='store_true',
262         help=optparse.SUPPRESS_HELP)
263     parser.add_option_group(group)
264
265     group = optparse.OptionGroup(parser, 'Compatibility options')
266     group.add_option('--gtest_output',
267         help='Ignored argument for compatibility with runtest.py harness')
268     parser.add_option_group(group)
269
270     group = optparse.OptionGroup(parser, 'Synthetic gesture options')
271     synthetic_gesture_source_type_choices = [ 'default', 'mouse', 'touch' ]
272     group.add_option('--synthetic-gesture-source-type',
273         dest='synthetic_gesture_source_type',
274         default='default', type='choice',
275         choices=synthetic_gesture_source_type_choices,
276         help='Specify the source type for synthetic gestures. Note that some ' +
277              'actions only support a specific source type. ' +
278              'Supported values: ' +
279              ', '.join(synthetic_gesture_source_type_choices))
280     parser.add_option_group(group)
281
282
283   def UpdateFromParseResults(self, finder_options):
284     """Copies our options from finder_options"""
285     browser_options_list = [
286         'disable_crash_service',
287         'extra_browser_args_as_string',
288         'extra_wpr_args_as_string',
289         'netsim',
290         'profile_dir',
291         'profile_type',
292         'show_stdout',
293         'synthetic_gesture_source_type',
294         'use_devtools_active_port',
295         ]
296     for o in browser_options_list:
297       a = getattr(finder_options, o, None)
298       if a is not None:
299         setattr(self, o, a)
300         delattr(finder_options, o)
301
302     self.browser_type = finder_options.browser_type
303
304     if hasattr(self, 'extra_browser_args_as_string'): # pylint: disable=E1101
305       tmp = shlex.split(
306         self.extra_browser_args_as_string) # pylint: disable=E1101
307       self.AppendExtraBrowserArgs(tmp)
308       delattr(self, 'extra_browser_args_as_string')
309     if hasattr(self, 'extra_wpr_args_as_string'): # pylint: disable=E1101
310       tmp = shlex.split(
311         self.extra_wpr_args_as_string) # pylint: disable=E1101
312       self.extra_wpr_args.extend(tmp)
313       delattr(self, 'extra_wpr_args_as_string')
314     if self.profile_type == 'default':
315       self.dont_override_profile = True
316
317     if self.profile_dir and self.profile_type != 'clean':
318       logging.critical(
319           "It's illegal to specify both --profile-type and --profile-dir.\n"
320           "For more information see: http://goo.gl/ngdGD5")
321       sys.exit(1)
322
323     if self.profile_dir and not os.path.isdir(self.profile_dir):
324       logging.critical(
325           "Directory specified by --profile-dir (%s) doesn't exist "
326           "or isn't a directory.\n"
327           "For more information see: http://goo.gl/ngdGD5" % self.profile_dir)
328       sys.exit(1)
329
330     if not self.profile_dir:
331       self.profile_dir = profile_types.GetProfileDir(self.profile_type)
332
333     # This deferred import is necessary because browser_options is imported in
334     # telemetry/telemetry/__init__.py.
335     from telemetry.core.backends.chrome import chrome_browser_options
336     finder_options.browser_options = (
337         chrome_browser_options.CreateChromeBrowserOptions(self))
338
339   @property
340   def extra_browser_args(self):
341     return self._extra_browser_args
342
343   def AppendExtraBrowserArgs(self, args):
344     if isinstance(args, list):
345       self._extra_browser_args.update(args)
346     else:
347       self._extra_browser_args.add(args)