--- a/testing/talos/talos/ttest.py
+++ b/testing/talos/talos/ttest.py
@@ -37,17 +37,17 @@ class TTest(object):
def check_for_crashes(self, browser_config, minidump_dir, test_name):
# check for minidumps
found = mozcrash.check_for_crashes(minidump_dir,
browser_config['symbols_path'],
test_name=test_name)
mozfile.remove(minidump_dir)
if found:
- raise TalosCrash("Found crashes after test run, terminating test")
+ raise TalosCrash('Found crashes after test run, terminating test')
def runTest(self, browser_config, test_config):
"""
Runs an url based test on the browser as specified in the
browser_config dictionary
Args:
browser_config: Dictionary of configuration options for the
@@ -57,51 +57,51 @@ class TTest(object):
"""
with FFSetup(browser_config, test_config) as setup:
return self._runTest(browser_config, test_config, setup)
@staticmethod
def _get_counter_prefix():
- if platform.system() == "Linux":
+ if platform.system() == 'Linux':
return 'linux'
- elif platform.system() in ("Windows", "Microsoft"):
+ elif platform.system() in ('Windows', 'Microsoft'):
if '6.1' in platform.version(): # w7
return 'w7'
elif '6.2' in platform.version(): # w8
return 'w8'
# Bug 1264325 - FIXME: with python 2.7.11: reports win8 instead of 8.1
elif '6.3' in platform.version():
return 'w8'
# Bug 1264325 - FIXME: with python 2.7.11: reports win8 instead of 10
elif '10.0' in platform.version():
return 'w8'
else:
raise TalosError('unsupported windows version')
- elif platform.system() == "Darwin":
+ elif platform.system() == 'Darwin':
return 'mac'
def _runTest(self, browser_config, test_config, setup):
minidump_dir = os.path.join(setup.profile_dir, 'minidumps')
counters = test_config.get('%s_counters' % self._get_counter_prefix(), [])
resolution = test_config['resolution']
# add the mainthread_io to the environment variable, as defined
# in test.py configs
here = os.path.dirname(os.path.realpath(__file__))
if test_config['mainthread']:
- mainthread_io = os.path.join(here, "mainthread_io.log")
+ mainthread_io = os.path.join(here, 'mainthread_io.log')
setup.env['MOZ_MAIN_THREAD_IO_LOG'] = mainthread_io
if browser_config['disable_stylo']:
if browser_config['stylothreads']:
- raise TalosError("--disable-stylo conflicts with --stylo-threads")
+ raise TalosError('--disable-stylo conflicts with --stylo-threads')
if browser_config['enable_stylo']:
- raise TalosError("--disable-stylo conflicts with --enable-stylo")
+ raise TalosError('--disable-stylo conflicts with --enable-stylo')
# As we transition to Stylo, we need to set env vars and output data properly
if browser_config['enable_stylo']:
setup.env['STYLO_FORCE_ENABLED'] = '1'
if browser_config['disable_stylo']:
setup.env['STYLO_FORCE_DISABLED'] = '1'
# During the Stylo transition, measure different number of threads
@@ -119,68 +119,71 @@ class TTest(object):
global_counters = {}
if browser_config.get('xperf_path'):
for c in test_config.get('xperf_counters', []):
global_counters[c] = []
if test_config['shutdown']:
global_counters['shutdown'] = []
if test_config.get('responsiveness') and \
- platform.system() != "Darwin":
+ platform.system() != 'Darwin':
# ignore osx for now as per bug 1245793
setup.env['MOZ_INSTRUMENT_EVENT_LOOP'] = '1'
setup.env['MOZ_INSTRUMENT_EVENT_LOOP_THRESHOLD'] = '20'
setup.env['MOZ_INSTRUMENT_EVENT_LOOP_INTERVAL'] = '10'
global_counters['responsiveness'] = []
setup.env['JSGC_DISABLE_POISONING'] = '1'
setup.env['MOZ_DISABLE_NONLOCAL_CONNECTIONS'] = '1'
# if using mitmproxy we must allow access to 'external' sites
if browser_config.get('mitmproxy', False):
- LOG.info("Using mitmproxy so setting MOZ_DISABLE_NONLOCAL_CONNECTIONS to 0")
+ LOG.info('Using mitmproxy so setting MOZ_DISABLE_NONLOCAL_CONNECTIONS to 0')
setup.env['MOZ_DISABLE_NONLOCAL_CONNECTIONS'] = '0'
# instantiate an object to hold test results
test_results = results.TestResults(
test_config,
global_counters,
browser_config.get('framework')
)
for i in range(test_config['cycles']):
- LOG.info("Running cycle %d/%d for %s test..."
+ LOG.info('Running cycle %d/%d for %s test...'
% (i+1, test_config['cycles'], test_config['name']))
# remove the browser error file
mozfile.remove(browser_config['error_filename'])
# reinstall any file whose stability we need to ensure across
# the cycles
if test_config.get('reinstall', ''):
for keep in test_config['reinstall']:
origin = os.path.join(test_config['profile_path'],
keep)
dest = os.path.join(setup.profile_dir, keep)
- LOG.debug("Reinstalling %s on top of %s"
+ LOG.debug('Reinstalling %s on top of %s'
% (origin, dest))
shutil.copy(origin, dest)
# Run the test
timeout = test_config.get('timeout', 7200) # 2 hours default
if setup.gecko_profile:
# When profiling, give the browser some extra time
# to dump the profile.
timeout += 5 * 60
command_args = utils.GenerateBrowserCommandLine(
- browser_config["browser_path"],
- browser_config["extra_args"],
+ browser_config['browser_path'],
+ browser_config['extra_args'],
setup.profile_dir,
test_config['url'],
+ browser_config['debug'],
+ browser_config['debugger'],
+ browser_config['debugger_args'],
profiling_info=(setup.gecko_profile.profiling_info
if setup.gecko_profile else None)
)
mainthread_error_count = 0
if test_config['setup']:
# Generate bcontroller.json for xperf
talosconfig.generateTalosConfig(command_args,
@@ -212,31 +215,31 @@ class TTest(object):
self.check_for_crashes(browser_config, minidump_dir,
test_config['name'])
raise
finally:
if counter_management:
counter_management.stop()
if test_config['mainthread']:
- rawlog = os.path.join(here, "mainthread_io.log")
+ rawlog = os.path.join(here, 'mainthread_io.log')
if os.path.exists(rawlog):
processedlog = \
os.path.join(here, 'mainthread_io.json')
xre_path = \
os.path.dirname(browser_config['browser_path'])
mtio_py = os.path.join(here, 'mainthreadio.py')
command = ['python', mtio_py, rawlog,
processedlog, xre_path]
mtio = subprocess.Popen(command,
env=os.environ.copy(),
stdout=subprocess.PIPE)
output, stderr = mtio.communicate()
for line in output.split('\n'):
- if line.strip() == "":
+ if line.strip() == '':
continue
print(line)
mainthread_error_count += 1
mozfile.remove(rawlog)
if test_config['cleanup']:
# HACK: add the pid to support xperf where we require
@@ -254,18 +257,18 @@ class TTest(object):
for fname in ('sessionstore.js', '.parentlock',
'sessionstore.bak'):
mozfile.remove(os.path.join(setup.profile_dir, fname))
# check for xperf errors
if os.path.exists(browser_config['error_filename']) or \
mainthread_error_count > 0:
raise TalosRegression(
- "Talos has found a regression, if you have questions"
- " ask for help in irc on #perf"
+ 'Talos has found a regression, if you have questions'
+ ' ask for help in irc on #perf'
)
# add the results from the browser output
test_results.add(
'\n'.join(pcontext.output),
counter_results=(counter_management.results()
if counter_management
else None)
@@ -278,12 +281,12 @@ class TTest(object):
test_config['name'])
# include global (cross-cycle) counters
test_results.all_counter_results.extend(
[{key: value} for key, value in global_counters.items()]
)
for c in test_results.all_counter_results:
for key, value in c.items():
- LOG.debug("COUNTER %r: %s" % (key, value))
+ LOG.debug('COUNTER %r: %s' % (key, value))
# return results
return test_results
--- a/testing/talos/talos/utils.py
+++ b/testing/talos/talos/utils.py
@@ -26,17 +26,17 @@ class Timer(object):
self._start_time = 0
self.start()
def start(self):
self._start_time = time.time()
def elapsed(self):
seconds = time.time() - self._start_time
- return time.strftime("%H:%M:%S", time.gmtime(seconds))
+ return time.strftime('%H:%M:%S', time.gmtime(seconds))
class TalosError(Exception):
"Errors found while running the talos harness."
class TalosRegression(Exception):
"""When a regression is detected at runtime, report it properly
@@ -113,22 +113,52 @@ def urlsplit(url, default_scheme='file')
def parse_pref(value):
"""parse a preference value from a string"""
from mozprofile.prefs import Preferences
return Preferences.cast(value)
-def GenerateBrowserCommandLine(browser_path, extra_args, profile_dir,
- url, profiling_info=None):
+def GenerateBrowserCommandLine(browser_path, extra_args, profile_dir, url,
+ debug, debugger, debugger_args, profiling_info=None):
# TODO: allow for spaces in file names on Windows
command_args = [browser_path.strip()]
- if platform.system() == "Darwin":
+
+ if debug or debugger or debugger_args:
+ import mozdebug
+
+ if not debugger:
+ # No debugger name was provided. Look for the default ones on
+ # current OS.
+ debugger = mozdebug.get_default_debugger_name(mozdebug.DebuggerSearch.KeepLooking)
+
+ debuggerInfo = None
+ if debugger:
+ debuggerInfo = mozdebug.get_debugger_info(debugger, debugger_args)
+
+ if debuggerInfo is None:
+ raise TalosError('Could not find a suitable debugger in your PATH.')
+
+ # Parameters come from the CLI. We need to convert them before
+ # their use.
+ if debugger_args:
+ from mozbuild import shellutil
+ try:
+ debugger_args = shellutil.split(debugger_args)
+ except shellutil.MetaCharacterException as e:
+ raise TalosError(
+ "The --debugger_args you passed require a real shell to parse them."
+ "(We can't handle the %r character.)" % e.char)
+
+ # Prepend the debugger args.
+ command_args = [debuggerInfo.path] + debuggerInfo.args + command_args
+
+ if platform.system() == 'Darwin':
command_args.extend(['-foreground'])
if isinstance(extra_args, list):
command_args.extend(extra_args)
elif extra_args.strip():
command_args.extend([extra_args])