Mypal/testing/talos/talos/config.py

463 lines
16 KiB
Python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
import sys
import os
import copy
from mozlog.commandline import setup_logging
from talos import utils, test
from talos.cmdline import parse_args
class ConfigurationError(Exception):
pass
DEFAULTS = dict(
# args to pass to browser
extra_args='',
buildid='testbuildid',
init_url='getInfo.html',
env={'NO_EM_RESTART': '1'},
# base data for all tests
basetest=dict(
cycles=1,
profile_path='${talos}/base_profile',
responsiveness=False,
e10s=False,
sps_profile=False,
sps_profile_interval=1,
sps_profile_entries=100000,
resolution=1,
rss=False,
mainthread=False,
shutdown=False,
timeout=3600,
tpchrome=True,
tpcycles=10,
tpmozafterpaint=False,
tpdisable_e10s=False,
tpnoisy=True,
tppagecycles=1,
tploadnocache=False,
tpscrolltest=False,
tprender=False,
win_counters=[],
w7_counters=[],
linux_counters=[],
mac_counters=[],
xperf_counters=[],
setup=None,
cleanup=None,
),
# default preferences to run with
# these are updated with --extraPrefs from the commandline
# for extension scopes, see
# see https://developer.mozilla.org/en/Installing_extensions
preferences={
'app.update.enabled': False,
'browser.addon-watch.interval': -1, # Deactivate add-on watching
'browser.aboutHomeSnippets.updateUrl':
'https://127.0.0.1/about-dummy/',
'browser.bookmarks.max_backups': 0,
'browser.cache.disk.smart_size.enabled': False,
'browser.cache.disk.smart_size.first_run': False,
'browser.chrome.dynamictoolbar': False,
'browser.dom.window.dump.enabled': True,
'browser.EULA.override': True,
'browser.link.open_newwindow': 2,
'browser.reader.detectedFirstArticle': True,
'browser.shell.checkDefaultBrowser': False,
'browser.warnOnQuit': False,
'browser.tabs.remote.autostart': False,
'dom.allow_scripts_to_close_windows': True,
'dom.disable_open_during_load': False,
'dom.disable_window_flip': True,
'dom.disable_window_move_resize': True,
'dom.max_chrome_script_run_time': 0,
'dom.max_script_run_time': 0,
'extensions.autoDisableScopes': 10,
'extensions.checkCompatibility': False,
'extensions.enabledScopes': 5,
'extensions.update.notifyUser': False,
'hangmonitor.timeout': 0,
'network.proxy.http': 'localhost',
'network.proxy.http_port': 80,
'network.proxy.type': 1,
'security.enable_java': False,
'security.fileuri.strict_origin_policy': False,
'dom.send_after_paint_to_content': True,
'security.turn_off_all_security_so_that_viruses_can_'
'take_over_this_computer': True,
'browser.safebrowsing.provider.google.gethashURL':
'http://127.0.0.1/safebrowsing-dummy/gethash',
'browser.safebrowsing.provider.google.updateURL':
'http://127.0.0.1/safebrowsing-dummy/update',
'browser.safebrowsing.provider.mozilla.gethashURL':
'http://127.0.0.1/safebrowsing-dummy/gethash',
'browser.safebrowsing.provider.mozilla.updateURL':
'http://127.0.0.1/safebrowsing-dummy/update',
'privacy.trackingprotection.introURL':
'http://127.0.0.1/trackingprotection/tour',
'browser.safebrowsing.phishing.enabled': False,
'browser.safebrowsing.malware.enabled': False,
'browser.safebrowsing.forbiddenURIs.enabled': False,
'browser.safebrowsing.blockedURIs.enabled': False,
'privacy.trackingprotection.enabled': False,
'privacy.trackingprotection.pbmode.enabled': False,
'browser.search.isUS': True,
'browser.search.countryCode': 'US',
'browser.selfsupport.url':
'https://127.0.0.1/selfsupport-dummy/',
'extensions.update.url':
'http://127.0.0.1/extensions-dummy/updateURL',
'extensions.blocklist.enabled': False,
'extensions.blocklist.url':
'http://127.0.0.1/extensions-dummy/blocklistURL',
'extensions.update.enabled': False,
'extensions.webservice.discoverURL':
'http://127.0.0.1/extensions-dummy/discoveryURL',
'extensions.getAddons.maxResults': 0,
'extensions.getAddons.get.url':
'http://127.0.0.1/extensions-dummy/repositoryGetURL',
'extensions.getAddons.getWithPerformance.url':
'http://127.0.0.1/extensions-dummy'
'/repositoryGetWithPerformanceURL',
'extensions.getAddons.search.browseURL':
'http://127.0.0.1/extensions-dummy/repositoryBrowseURL',
'extensions.getAddons.search.url':
'http://127.0.0.1/extensions-dummy/repositorySearchURL',
'media.gmp-manager.url':
'http://127.0.0.1/gmpmanager-dummy/update.xml',
'media.gmp-manager.updateEnabled': False,
'extensions.systemAddon.update.url':
'http://127.0.0.1/dummy-system-addons.xml',
'media.navigator.enabled': True,
'media.peerconnection.enabled': True,
'media.navigator.permission.disabled': True,
'media.capturestream_hints.enabled': True,
'browser.contentHandlers.types.0.uri': 'http://127.0.0.1/rss?url=%s',
'browser.contentHandlers.types.1.uri': 'http://127.0.0.1/rss?url=%s',
'browser.contentHandlers.types.2.uri': 'http://127.0.0.1/rss?url=%s',
'browser.contentHandlers.types.3.uri': 'http://127.0.0.1/rss?url=%s',
'browser.contentHandlers.types.4.uri': 'http://127.0.0.1/rss?url=%s',
'browser.contentHandlers.types.5.uri': 'http://127.0.0.1/rss?url=%s',
'datareporting.healthreport.about.reportUrl':
'http://127.0.0.1/abouthealthreport/',
'datareporting.healthreport.documentServerURI':
'http://127.0.0.1/healthreport/',
'datareporting.policy.dataSubmissionPolicyBypassNotification': True,
'general.useragent.updates.enabled': False,
'browser.webapps.checkForUpdates': 0,
'browser.search.geoSpecificDefaults': False,
'browser.snippets.enabled': False,
'browser.snippets.syncPromo.enabled': False,
'toolkit.telemetry.server': 'https://127.0.0.1/telemetry-dummy/',
'experiments.manifest.uri':
'https://127.0.0.1/experiments-dummy/manifest',
'network.http.speculative-parallel-limit': 0,
'app.update.badge': False,
'lightweightThemes.selectedThemeID': "",
'devtools.webide.widget.enabled': False,
'devtools.webide.widget.inNavbarByDefault': False,
'devtools.chrome.enabled': False,
'devtools.debugger.remote-enabled': False,
'devtools.theme': "light",
'devtools.timeline.enabled': False,
'media.libavcodec.allow-obsolete': True
}
)
# keys to generated self.config that are global overrides to tests
GLOBAL_OVERRIDES = (
'cycles',
'sps_profile',
'sps_profile_interval',
'sps_profile_entries',
'rss',
'mainthread',
'shutdown',
'tpcycles',
'tpdelay',
'tppagecycles',
'tpmanifest',
'tptimeout',
'tpmozafterpaint',
)
CONF_VALIDATORS = []
def validator(func):
"""
A decorator that register configuration validators to execute against the
configuration.
They will be executed in the order of declaration.
"""
CONF_VALIDATORS.append(func)
return func
def convert_url(config, url):
webserver = config['webserver']
if not webserver:
return url
if '://' in url:
# assume a fully qualified url
return url
if '.html' in url:
url = 'http://%s/%s' % (webserver, url)
return url
@validator
def fix_xperf(config):
# BBB: remove doubly-quoted xperf values from command line
# (needed for buildbot)
# https://bugzilla.mozilla.org/show_bug.cgi?id=704654#c43
if config['xperf_path']:
xperf_path = config['xperf_path']
quotes = ('"', "'")
for quote in quotes:
if xperf_path.startswith(quote) and xperf_path.endswith(quote):
config['xperf_path'] = xperf_path[1:-1]
break
if not os.path.exists(config['xperf_path']):
raise ConfigurationError(
"xperf.exe cannot be found at the path specified")
@validator
def set_webserver(config):
# pick a free port
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', 0))
port = sock.getsockname()[1]
sock.close()
config['webserver'] = 'localhost:%d' % port
@validator
def update_prefs(config):
# if e10s is enabled, set prefs accordingly
if config['e10s']:
config['preferences']['browser.tabs.remote.autostart'] = True
config['preferences']['extensions.e10sBlocksEnabling'] = False
else:
config['preferences']['browser.tabs.remote.autostart'] = False
config['preferences']['browser.tabs.remote.autostart.1'] = False
config['preferences']['browser.tabs.remote.autostart.2'] = False
# update prefs from command line
prefs = config.pop('extraPrefs')
if prefs:
for arg in prefs:
k, v = arg.split('=', 1)
config['preferences'][k] = utils.parse_pref(v)
@validator
def fix_init_url(config):
if 'init_url' in config:
config['init_url'] = convert_url(config, config['init_url'])
def get_counters(config):
counters = set()
if config['rss']:
counters.add('Main_RSS')
return counters
def get_active_tests(config):
activeTests = config.pop('activeTests').strip().split(':')
# ensure tests are available
availableTests = test.test_dict()
if not set(activeTests).issubset(availableTests):
missing = [i for i in activeTests
if i not in availableTests]
raise ConfigurationError("No definition found for test(s): %s"
% missing)
# disabled DAMP on winXP: frequent hangs, <3% of devtools users on winXP
if utils.PLATFORM_TYPE == 'win_':
activeTests = [i for i in activeTests if i != 'damp']
return activeTests
def get_global_overrides(config):
global_overrides = {}
for key in GLOBAL_OVERRIDES:
# get global overrides for all tests
value = config[key]
if value is not None:
global_overrides[key] = value
if key != 'sps_profile':
config.pop(key)
# add noChrome to global overrides (HACK)
noChrome = config.pop('noChrome')
if noChrome:
global_overrides['tpchrome'] = False
# HACK: currently xperf tests post results to graph server and
# we want to ensure we don't publish shutdown numbers
# This is also hacked because "--noShutdown -> shutdown:True"
if config['xperf_path']:
global_overrides['shutdown'] = False
return global_overrides
def build_manifest(config, manifestName):
# read manifest lines
with open(manifestName, 'r') as fHandle:
manifestLines = fHandle.readlines()
# write modified manifest lines
with open(manifestName + '.develop', 'w') as newHandle:
for line in manifestLines:
newline = line.replace('localhost', config['webserver'])
newline = newline.replace('page_load_test', 'tests')
newHandle.write(newline)
newManifestName = manifestName + '.develop'
# return new manifest
return newManifestName
def get_test(config, global_overrides, counters, test_instance):
mozAfterPaint = getattr(test_instance, 'tpmozafterpaint', None)
test_instance.update(**global_overrides)
# update original value of mozAfterPaint, this could be 'false',
# so check for None
if mozAfterPaint is not None:
test_instance.tpmozafterpaint = mozAfterPaint
# fix up url
url = getattr(test_instance, 'url', None)
if url:
test_instance.url = utils.interpolate(convert_url(config, url))
# fix up tpmanifest
tpmanifest = getattr(test_instance, 'tpmanifest', None)
if tpmanifest:
test_instance.tpmanifest = \
build_manifest(config, utils.interpolate(tpmanifest))
# add any counters
if counters:
keys = ('linux_counters', 'mac_counters',
'win_counters', 'w7_counters', 'xperf_counters')
for key in keys:
if key not in test_instance.keys:
# only populate attributes that will be output
continue
if not isinstance(getattr(test_instance, key, None), list):
setattr(test_instance, key, [])
_counters = getattr(test_instance, key)
_counters.extend([counter for counter in counters
if counter not in _counters])
return dict(test_instance.items())
@validator
def tests(config):
counters = get_counters(config)
global_overrides = get_global_overrides(config)
activeTests = get_active_tests(config)
test_dict = test.test_dict()
tests = []
for test_name in activeTests:
test_class = test_dict[test_name]
tests.append(get_test(config, global_overrides, counters,
test_class()))
config['tests'] = tests
def get_browser_config(config):
required = ('preferences', 'extensions', 'browser_path', 'browser_wait',
'extra_args', 'buildid', 'env', 'init_url', 'webserver')
optional = {'bcontroller_config': '${talos}/bcontroller.json',
'branch_name': '',
'child_process': 'plugin-container',
'develop': False,
'e10s': False,
'process': '',
'framework': 'talos',
'repository': None,
'sourcestamp': None,
'symbols_path': None,
'test_timeout': 1200,
'xperf_path': None,
'error_filename': None,
}
browser_config = dict(title=config['title'])
browser_config.update(dict([(i, config[i]) for i in required]))
browser_config.update(dict([(i, config.get(i, j))
for i, j in optional.items()]))
return browser_config
def suites_conf():
import json
with open(os.path.join(os.path.dirname(utils.here),
'talos.json')) as f:
return json.load(f)['suites']
def get_config(argv=None):
argv = argv or sys.argv[1:]
cli_opts = parse_args(argv=argv)
if cli_opts.suite:
# read the suite config, update the args
try:
suite_conf = suites_conf()[cli_opts.suite]
except KeyError:
raise ConfigurationError('No such suite: %r' % cli_opts.suite)
argv += ['-a', ':'.join(suite_conf['tests'])]
argv += suite_conf.get('talos_options', [])
# args needs to be reparsed now
elif not cli_opts.activeTests:
raise ConfigurationError('--activeTests or --suite required!')
cli_opts = parse_args(argv=argv)
setup_logging("talos", cli_opts, {"tbpl": sys.stdout})
config = copy.deepcopy(DEFAULTS)
config.update(cli_opts.__dict__)
for validate in CONF_VALIDATORS:
validate(config)
# remove None Values
for k, v in config.items():
if v is None:
del config[k]
return config
def get_configs(argv=None):
config = get_config(argv=argv)
browser_config = get_browser_config(config)
return config, browser_config
if __name__ == '__main__':
cfgs = get_configs()
print(cfgs[0])
print
print(cfgs[1])