[IMP] runbot: add coverage xml export

When coverage is computed, a post command is used to generate the HTML
report. In order to use the coverage result locally the HTML report is
not enough.

With this commit, an XML report is also generated. It's a single xml
file, downloadable from the build result web page.

The _post_install_command method is renamed into its plural form because
it was useless to return only one command.
This commit is contained in:
Christophe Monniez 2020-02-26 10:28:13 +01:00
parent 820adae5ac
commit 3918d266fa
3 changed files with 13 additions and 9 deletions

View File

@ -270,7 +270,7 @@ def tests(args):
if args.coverage:
omit = ['--omit', '*__manifest__.py']
python_params = [ '-m', 'coverage', 'run', '--branch', '--source', '/data/build'] + omit
posts = [['python%s' % py_version, "-m", "coverage", "html", "-d", "/data/build/coverage", "--ignore-errors"]]
posts = [['python%s' % py_version, "-m", "coverage", "html", "-d", "/data/build/coverage", "--ignore-errors"], ['python%s' % py_version, "-m", "coverage", "xml", "--ignore-errors"]]
os.makedirs(os.path.join(args.build_dir, 'coverage'), exist_ok=True)
elif args.flamegraph:
flame_log = '/data/build/logs/flame.log'

View File

@ -388,7 +388,7 @@ class ConfigStep(models.Model):
if extra_params:
cmd.extend(shlex.split(extra_params))
cmd.posts.append(self._post_install_command(build, modules_to_install, py_version)) # coverage post, extra-checks, ...
cmd.posts.extend(self._post_install_commands(build, modules_to_install, py_version)) # coverage post, extra-checks, ...
dump_dir = '/data/build/logs/%s/' % db_name
sql_dest = '%s/dump.sql' % dump_dir
filestore_path = '/data/build/datadir/filestore/%s' % db_name
@ -421,6 +421,10 @@ class ConfigStep(models.Model):
kwargs['log_type'] = 'link'
build._log('', **kwargs)
if self.coverage:
message = 'Coverage xml: $$fa-download'
build._log('end_job', message, log_type='link', path='/data/build/logs/coverage.xml')
if self.flamegraph:
link = self._perf_data_url(build, 'log.gz')
message = 'Flamegraph data: $$fa-download$$'
@ -433,14 +437,16 @@ class ConfigStep(models.Model):
def _modules_to_install(self, build):
return set(build._get_modules_to_test(modules_patterns=self.install_modules))
def _post_install_command(self, build, modules_to_install, py_version=None):
def _post_install_commands(self, build, modules_to_install, py_version=None):
cmds = []
if self.coverage:
py_version = py_version if py_version is not None else build._get_py_version()
# prepare coverage result
cov_path = build._path('coverage')
os.makedirs(cov_path, exist_ok=True)
return ['python%s' % py_version, "-m", "coverage", "html", "-d", "/data/build/coverage", "--ignore-errors"]
return []
cmds.append(['python%s' % py_version, "-m", "coverage", "html", "-d", "/data/build/coverage", "--ignore-errors"])
cmds.append(['python%s' % py_version, "-m", "coverage", "xml", "-o", "/data/build/logs/coverage.xml", "--ignore-errors"])
return cmds
def _perfs_data_path(self, ext='log'):
return '/data/build/logs/flame_%s.%s' % (self.name, ext)

View File

@ -153,12 +153,10 @@ class TestBuildConfigStep(RunbotCase):
})
def docker_run(cmd, log_path, *args, **kwargs):
cmds = cmd.build().split(' && ')
dest = self.parent_build.dest
self.assertEqual(cmd.pres, [['sudo', 'pip3', 'install', '-r', 'bar/requirements.txt']])
self.assertEqual(cmd.cmd[:10], ['python3', '-m', 'coverage', 'run', '--branch', '--source', '/data/build', '--omit', '*__manifest__.py', 'bar/server.py'])
#['bar/server.py', '--addons-path', 'bar', '--no-xmlrpcs', '--no-netrpc', '-d', '08732-master-d0d0ca-coverage', '--test-enable', '--stop-after-init', '--log-level=test', '--max-cron-threads=0']
self.assertEqual(cmd.posts, [['python3', '-m', 'coverage', 'html', '-d', '/data/build/coverage', '--ignore-errors']])
self.assertIn(['python3', '-m', 'coverage', 'html', '-d', '/data/build/coverage', '--ignore-errors'], cmd.posts)
self.assertIn(['python3', '-m', 'coverage', 'xml', '-o', '/data/build/logs/coverage.xml', '--ignore-errors'], cmd.posts)
self.assertEqual(log_path, 'dev/null/logpath')
self.patchers['docker_run'].side_effect = docker_run