Skip to content

Commit

Permalink
Merge pull request #18636 from edx/jmbowman/TE-2659
Browse files Browse the repository at this point in the history
TE-2659 Fix coverage with remote xdist workers
  • Loading branch information
jmbowman committed Jul 24, 2018
2 parents 18edbf6 + 2580e08 commit c158a31
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 13 deletions.
29 changes: 29 additions & 0 deletions pavelib/utils/envs.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from lazy import lazy
from path import Path as path
from paver.easy import sh
from six.moves import configparser

from pavelib.utils.cmd import django_cmd

Expand Down Expand Up @@ -251,6 +252,22 @@ def get_django_setting(cls, django_setting, system, settings=None):
)
return unicode(value).strip()

@classmethod
def covered_modules(cls):
"""
List the source modules listed in .coveragerc for which coverage
will be measured.
"""
coveragerc = configparser.RawConfigParser()
coveragerc.read(cls.PYTHON_COVERAGERC)
modules = coveragerc.get('run', 'source')
result = []
for module in modules.split('\n'):
module = module.strip()
if module:
result.append(module)
return result

@lazy
def env_tokens(self):
"""
Expand Down Expand Up @@ -295,3 +312,15 @@ def feature_flags(self):
Return a dictionary of feature flags configured by the environment.
"""
return self.env_tokens.get('FEATURES', dict())

@classmethod
def rsync_dirs(cls):
"""
List the directories that should be synced during pytest-xdist
execution. Needs to include all modules for which coverage is
measured, not just the tests being run.
"""
result = set()
for module in cls.covered_modules():
result.add(module.split('/')[0])
return result
40 changes: 27 additions & 13 deletions pavelib/utils/test/suites/pytest_suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,23 @@ def __init__(self, *args, **kwargs):

self.processes = int(self.processes)

def _under_coverage_cmd(self, cmd):
"""
If self.run_under_coverage is True, it returns the arg 'cmd'
altered to be run under coverage. It returns the command
unaltered otherwise.
"""
if self.run_under_coverage:
if self.xdist_ip_addresses:
for module in Env.covered_modules():
cmd.append('--cov')
cmd.append(module)
else:
cmd.append('--cov')
cmd.append('--cov-report=')

return cmd

@property
def cmd(self):
if self.django_toxenv:
Expand Down Expand Up @@ -148,12 +165,8 @@ def cmd(self):
xdist_string = '--tx ssh=ubuntu@{}//python="source /edx/app/edxapp/edxapp_env; ' \
'python"//chdir="/edx/app/edxapp/edx-platform"'.format(ip)
cmd.append(xdist_string)
already_synced_dirs = set()
for test_path in self.test_id.split():
test_root_dir = test_path.split('/')[0]
if test_root_dir not in already_synced_dirs:
cmd.append('--rsyncdir {}'.format(test_root_dir))
already_synced_dirs.add(test_root_dir)
for rsync_dir in Env.rsync_dirs():
cmd.append('--rsyncdir {}'.format(rsync_dir))
else:
if self.processes == -1:
cmd.append('-n auto')
Expand Down Expand Up @@ -256,12 +269,8 @@ def cmd(self):
xdist_string = '--tx ssh=ubuntu@{}//python="source /edx/app/edxapp/edxapp_env; ' \
'python"//chdir="/edx/app/edxapp/edx-platform"'.format(ip)
cmd.append(xdist_string)
already_synced_dirs = set()
for test_path in self.test_id.split():
test_root_dir = test_path.split('/')[0]
if test_root_dir not in already_synced_dirs:
cmd.append('--rsyncdir {}'.format(test_root_dir))
already_synced_dirs.add(test_root_dir)
for rsync_dir in Env.rsync_dirs():
cmd.append('--rsyncdir {}'.format(rsync_dir))

if self.eval_attr:
cmd.append("-a '{}'".format(self.eval_attr))
Expand All @@ -277,7 +286,12 @@ def _under_coverage_cmd(self, cmd):
unaltered otherwise.
"""
if self.run_under_coverage:
cmd.append('--cov')
if self.xdist_ip_addresses:
for module in Env.covered_modules():
cmd.append('--cov')
cmd.append(module)
else:
cmd.append('--cov')
if self.append_coverage:
cmd.append('--cov-append')
cmd.append('--cov-report=')
Expand Down

0 comments on commit c158a31

Please sign in to comment.