Bug 1381069 - Remove ccov gcda files after talos browser initialization (production only); r=jmaher

MozReview-Commit-ID: 5V5xghMqfzY

--HG--
extra : rebase_source : 18e46b05f134db8a96e52c3330c56ad88efa96f4
This commit is contained in:
Rob Wood 2017-12-20 18:38:23 -05:00
parent 1a111ee852
commit e3c4440392
5 changed files with 110 additions and 2 deletions

View File

@ -371,6 +371,8 @@ class Talos(TestingMixin, MercurialScript, BlobUploadMixin, TooltoolMixin,
options += args
if 'talos_extra_options' in self.config:
options += self.config['talos_extra_options']
if self.config.get('code_coverage', False):
options.extend(['--code-coverage'])
return options
def populate_webroot(self):

View File

@ -180,6 +180,12 @@ def create_parser(mach_interface=False):
debug_options.add_argument('--debugger-args', default=None, metavar='params',
help='Command-line arguments to pass to the debugger itself; split'
'as the Bourne shell would.')
add_arg('--code-coverage', action="store_true",
dest='code_coverage',
help='Remove any existing ccov gcda output files after browser'
' initialization but before starting the tests. NOTE:'
' Currently only supported in production.')
add_logging_group(parser)
return parser

View File

@ -8,6 +8,7 @@ Set up a browser environment before running a test.
from __future__ import absolute_import, print_function
import os
import shutil
import tempfile
import mozfile
@ -185,12 +186,87 @@ class FFSetup(object):
try:
mozfile.remove(self._tmp_dir)
except Exception as e:
print("Exception while removing profile directory: %s" % self._tmp_dir)
print(e)
LOG.info("Exception while removing profile directory: %s" % self._tmp_dir)
LOG.info(e)
if self.gecko_profile:
self.gecko_profile.clean()
def collect_or_clean_ccov(self, clean=False):
# NOTE: Currently only supported when running in production
if not self.browser_config.get('develop', False):
# first see if we an find any ccov files at the ccov output dirs
if clean:
LOG.info("Cleaning ccov files before starting the talos test")
else:
LOG.info("Collecting ccov files that were generated during the talos test")
gcov_prefix = os.getenv('GCOV_PREFIX', None)
js_ccov_dir = os.getenv('JS_CODE_COVERAGE_OUTPUT_DIR', None)
gcda_archive_folder_name = 'gcda-archive'
_gcda_files_found = []
for _ccov_env in [gcov_prefix, js_ccov_dir]:
if _ccov_env is not None:
# ccov output dir env vars exist; now search for gcda files to remove
_ccov_path = os.path.abspath(_ccov_env)
if os.path.exists(_ccov_path):
# now walk through and look for gcda files
LOG.info("Recursive search for gcda files in: %s" % _ccov_path)
for root, dirs, files in os.walk(_ccov_path):
for next_file in files:
if next_file.endswith(".gcda"):
# don't want to move or delete files in our 'gcda-archive'
if root.find(gcda_archive_folder_name) == -1:
_gcda_files_found.append(os.path.join(root, next_file))
else:
LOG.info("The ccov env var path doesn't exist: %s" % str(_ccov_path))
# now clean or collect gcda files accordingly
if clean:
# remove ccov data
LOG.info("Found %d gcda files to clean. Deleting..." % (len(_gcda_files_found)))
for _gcda in _gcda_files_found:
try:
mozfile.remove(_gcda)
except Exception as e:
LOG.info("Exception while removing file: %s" % _gcda)
LOG.info(e)
LOG.info("Finished cleaning ccov gcda files")
else:
# copy gcda files to archive folder to be collected later
gcda_archive_top = os.path.join(gcov_prefix,
gcda_archive_folder_name,
self.test_config['name'])
LOG.info("Found %d gcda files to collect. Moving to gcda archive %s"
% (len(_gcda_files_found), str(gcda_archive_top)))
if not os.path.exists(gcda_archive_top):
try:
os.makedirs(gcda_archive_top)
except OSError:
LOG.critical("Unable to make gcda archive folder %s" % gcda_archive_top)
for _gcda in _gcda_files_found:
# want to copy the existing directory strucutre but put it under archive-dir
# need to remove preceeding '/' from _gcda file name so can join the path
gcda_archive_file = os.path.join(gcov_prefix,
gcda_archive_folder_name,
self.test_config['name'],
_gcda.strip(gcov_prefix + "//"))
gcda_archive_dest = os.path.dirname(gcda_archive_file)
# create archive folder, mirroring structure
if not os.path.exists(gcda_archive_dest):
try:
os.makedirs(gcda_archive_dest)
except OSError:
LOG.critical("Unable to make archive folder %s" % gcda_archive_dest)
# now copy the file there
try:
shutil.copy(_gcda, gcda_archive_dest)
except Exception as e:
LOG.info("Error copying %s to %s" % (str(_gcda), str(gcda_archive_dest)))
LOG.info(e)
LOG.info("Finished collecting ccov gcda files. Copied to: %s" % gcda_archive_top)
def __enter__(self):
LOG.info('Initialising browser for %s test...'
% self.test_config['name'])
@ -204,6 +280,13 @@ class FFSetup(object):
raise
self._init_gecko_profile()
LOG.info('Browser initialized.')
# remove ccov files before actual tests start
if self.browser_config.get('code_coverage', False):
# if the Firefox build was instrumented for ccov, initializing the browser
# will have caused ccov to output some gcda files; in order to have valid
# ccov data for the talos test we want to remove these files before starting
# the actual talos test(s)
self.collect_or_clean_ccov(clean=True)
return self
def __exit__(self, type, value, tb):

View File

@ -118,6 +118,18 @@ def run_tests(config, browser_config):
if browser_config['subtests']:
browser_config['preferences']['talos.subtests'] = browser_config['subtests']
# If --code-coverage files are expected, set flag in browser config so ffsetup knows
# that it needs to delete any ccov files resulting from browser initialization
# NOTE: This is only supported in production; local setup of ccov folders and
# data collection not supported yet, so if attempting to run with --code-coverage
# flag locally, that is not supported yet
if config.get('code_coverage', False):
if browser_config['develop']:
raise TalosError('Aborting: talos --code-coverage flag is only '
'supported in production')
else:
browser_config['code_coverage'] = True
# set defaults
testdate = config.get('testdate', '')

View File

@ -291,5 +291,10 @@ class TTest(object):
for key, value in c.items():
LOG.debug('COUNTER %r: %s' % (key, value))
# if running against a code-coverage instrumented build, move the
# produced gcda files to a folder where they will be collected later
if browser_config.get('code_coverage', False):
setup.collect_or_clean_ccov()
# return results
return test_results