You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2019/10/14 21:00:07 UTC

[allura] 02/09: [#8336] Run coverage with parallel processing still

This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8336
in repository https://gitbox.apache.org/repos/asf/allura.git

commit d4b95f7df33e4a0cfd017527df22a6eebda42cb2
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Fri Oct 11 15:53:55 2019 -0400

    [#8336] Run coverage with parallel processing still
---
 .gitignore                               |  1 +
 Allura/setup.cfg                         |  5 +++
 AlluraTest/setup.cfg                     |  5 +--
 ForgeActivity/setup.cfg                  |  5 +++
 ForgeBlog/setup.cfg                      |  5 +++
 ForgeChat/setup.cfg                      |  5 +++
 ForgeDiscussion/setup.cfg                |  5 +++
 ForgeGit/setup.cfg                       |  5 +++
 ForgeImporters/setup.cfg                 | 14 ++++++++
 ForgeLink/setup.cfg                      |  5 +++
 ForgeSVN/setup.cfg                       |  5 +++
 {AlluraTest => ForgeShortUrl}/setup.cfg  |  2 +-
 ForgeTracker/setup.cfg                   |  5 +++
 {AlluraTest => ForgeUserStats}/setup.cfg |  2 +-
 ForgeWiki/setup.cfg                      |  5 +++
 requirements-dev.in                      |  1 +
 requirements-dev.txt                     |  3 +-
 run_tests                                | 56 +++++++++++++++++++++++---------
 18 files changed, 111 insertions(+), 23 deletions(-)

diff --git a/.gitignore b/.gitignore
index 24fcd7d..64cac24 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,7 @@ download/*
 install/*
 */.test-data/*
 */.coverage
+coverage.xml
 solr_config/core0/data/
 solr_config/core1/data/
 var/
diff --git a/Allura/setup.cfg b/Allura/setup.cfg
index 527abf5..3398fc4 100644
--- a/Allura/setup.cfg
+++ b/Allura/setup.cfg
@@ -46,3 +46,8 @@ domain = allura
 input_file = allura/i18n/allura.pot
 output_dir = allura/i18n
 previous = true
+
+[coverage:run]
+parallel=true
+concurrency=multiprocessing
+source=allura,../AlluraTest/alluratest
\ No newline at end of file
diff --git a/AlluraTest/setup.cfg b/AlluraTest/setup.cfg
index 0f1091a..14bf9ca 100644
--- a/AlluraTest/setup.cfg
+++ b/AlluraTest/setup.cfg
@@ -4,10 +4,7 @@ max-line-length = 119
 [flake8]
 max-line-length = 119
 
-[egg_info]
-tag_build = dev0
-
 [coverage:run]
 parallel=true
 concurrency=multiprocessing
-source=../Allura/allura,forgeblog
\ No newline at end of file
+source=../Allura/allura,alluratest
\ No newline at end of file
diff --git a/ForgeActivity/setup.cfg b/ForgeActivity/setup.cfg
index f054a10..989542f 100644
--- a/ForgeActivity/setup.cfg
+++ b/ForgeActivity/setup.cfg
@@ -6,3 +6,8 @@ max-line-length = 119
 
 [egg_info]
 tag_build = dev0
+
+[coverage:run]
+parallel=true
+concurrency=multiprocessing
+source=../Allura/allura,forgeactivity
\ No newline at end of file
diff --git a/ForgeBlog/setup.cfg b/ForgeBlog/setup.cfg
index f054a10..0f1091a 100644
--- a/ForgeBlog/setup.cfg
+++ b/ForgeBlog/setup.cfg
@@ -6,3 +6,8 @@ max-line-length = 119
 
 [egg_info]
 tag_build = dev0
+
+[coverage:run]
+parallel=true
+concurrency=multiprocessing
+source=../Allura/allura,forgeblog
\ No newline at end of file
diff --git a/ForgeChat/setup.cfg b/ForgeChat/setup.cfg
index f054a10..62fb310 100644
--- a/ForgeChat/setup.cfg
+++ b/ForgeChat/setup.cfg
@@ -6,3 +6,8 @@ max-line-length = 119
 
 [egg_info]
 tag_build = dev0
+
+[coverage:run]
+parallel=true
+concurrency=multiprocessing
+source=../Allura/allura,forgechat
\ No newline at end of file
diff --git a/ForgeDiscussion/setup.cfg b/ForgeDiscussion/setup.cfg
index f054a10..cad5dc7 100644
--- a/ForgeDiscussion/setup.cfg
+++ b/ForgeDiscussion/setup.cfg
@@ -6,3 +6,8 @@ max-line-length = 119
 
 [egg_info]
 tag_build = dev0
+
+[coverage:run]
+parallel=true
+concurrency=multiprocessing
+source=../Allura/allura,forgediscussion
\ No newline at end of file
diff --git a/ForgeGit/setup.cfg b/ForgeGit/setup.cfg
index f054a10..5b182c6 100644
--- a/ForgeGit/setup.cfg
+++ b/ForgeGit/setup.cfg
@@ -6,3 +6,8 @@ max-line-length = 119
 
 [egg_info]
 tag_build = dev0
+
+[coverage:run]
+parallel=true
+concurrency=multiprocessing
+source=../Allura/allura,forgegit
\ No newline at end of file
diff --git a/ForgeImporters/setup.cfg b/ForgeImporters/setup.cfg
new file mode 100644
index 0000000..c66965b
--- /dev/null
+++ b/ForgeImporters/setup.cfg
@@ -0,0 +1,14 @@
+[pep8]
+max-line-length = 119
+
+[flake8]
+max-line-length = 119
+
+[egg_info]
+tag_build = dev0
+
+[coverage:run]
+parallel=true
+concurrency=multiprocessing
+# include tracker & wiki since importer leverages some of their code
+source=../Allura/allura,forgeimporters,../ForgeTracker/forgetracker,../ForgeWiki/forgewiki
\ No newline at end of file
diff --git a/ForgeLink/setup.cfg b/ForgeLink/setup.cfg
index f054a10..580ae47 100644
--- a/ForgeLink/setup.cfg
+++ b/ForgeLink/setup.cfg
@@ -6,3 +6,8 @@ max-line-length = 119
 
 [egg_info]
 tag_build = dev0
+
+[coverage:run]
+parallel=true
+concurrency=multiprocessing
+source=../Allura/allura,forgelink
\ No newline at end of file
diff --git a/ForgeSVN/setup.cfg b/ForgeSVN/setup.cfg
index f054a10..2eced00 100644
--- a/ForgeSVN/setup.cfg
+++ b/ForgeSVN/setup.cfg
@@ -6,3 +6,8 @@ max-line-length = 119
 
 [egg_info]
 tag_build = dev0
+
+[coverage:run]
+parallel=true
+concurrency=multiprocessing
+source=../Allura/allura,forgesvn
\ No newline at end of file
diff --git a/AlluraTest/setup.cfg b/ForgeShortUrl/setup.cfg
similarity index 80%
copy from AlluraTest/setup.cfg
copy to ForgeShortUrl/setup.cfg
index 0f1091a..dcf1311 100644
--- a/AlluraTest/setup.cfg
+++ b/ForgeShortUrl/setup.cfg
@@ -10,4 +10,4 @@ tag_build = dev0
 [coverage:run]
 parallel=true
 concurrency=multiprocessing
-source=../Allura/allura,forgeblog
\ No newline at end of file
+source=../Allura/allura,forgeshorturl
\ No newline at end of file
diff --git a/ForgeTracker/setup.cfg b/ForgeTracker/setup.cfg
index f054a10..e9b9a0c 100644
--- a/ForgeTracker/setup.cfg
+++ b/ForgeTracker/setup.cfg
@@ -6,3 +6,8 @@ max-line-length = 119
 
 [egg_info]
 tag_build = dev0
+
+[coverage:run]
+parallel=true
+concurrency=multiprocessing
+source=../Allura/allura,forgetracker,../AlluraTest/alluratest
\ No newline at end of file
diff --git a/AlluraTest/setup.cfg b/ForgeUserStats/setup.cfg
similarity index 79%
copy from AlluraTest/setup.cfg
copy to ForgeUserStats/setup.cfg
index 0f1091a..f25f83d 100644
--- a/AlluraTest/setup.cfg
+++ b/ForgeUserStats/setup.cfg
@@ -10,4 +10,4 @@ tag_build = dev0
 [coverage:run]
 parallel=true
 concurrency=multiprocessing
-source=../Allura/allura,forgeblog
\ No newline at end of file
+source=../Allura/allura,forgeuserstats
\ No newline at end of file
diff --git a/ForgeWiki/setup.cfg b/ForgeWiki/setup.cfg
index f054a10..7e4ece2 100644
--- a/ForgeWiki/setup.cfg
+++ b/ForgeWiki/setup.cfg
@@ -6,3 +6,8 @@ max-line-length = 119
 
 [egg_info]
 tag_build = dev0
+
+[coverage:run]
+parallel=true
+concurrency=multiprocessing
+source=../Allura/allura,forgewiki
\ No newline at end of file
diff --git a/requirements-dev.in b/requirements-dev.in
index 309f1ad..506e184 100644
--- a/requirements-dev.in
+++ b/requirements-dev.in
@@ -6,3 +6,4 @@ q==2.3
 sphinx-argparse==0.2.5
 sphinx-rtd-theme==0.1.6
 sphinxcontrib-programoutput==0.8
+coverage
\ No newline at end of file
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 374bf9b..0621a1a 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -9,6 +9,7 @@ babel==2.7.0              # via sphinx
 certifi==2019.6.16        # via requests
 chardet==3.0.4            # via requests
 click==7.0                # via pip-tools
+coverage==4.5.4
 docutils==0.15.2          # via sphinx
 idna==2.8                 # via requests
 imagesize==1.1.0          # via sphinx
@@ -32,4 +33,4 @@ typing==3.7.4             # via sphinx
 urllib3==1.25.3           # via requests
 
 # The following packages are considered to be unsafe in a requirements file:
-# setuptools==41.2.0        # via sphinx
+# setuptools==41.4.0        # via sphinx
diff --git a/run_tests b/run_tests
index 03c2e47..119e63b 100755
--- a/run_tests
+++ b/run_tests
@@ -112,14 +112,11 @@ def check_packages(packages):
 
 
 def run_tests_in_parallel(options, nosetests_args):
-    # coverage and multiproc plugins not compatible
-    use_multiproc = '--with-coverage' not in nosetests_args
-
     def get_pkg_path(pkg):
         return ALT_PKG_PATHS.get(pkg, '')
 
     def get_multiproc_args(pkg):
-        if not use_multiproc or options.concurrent_tests == 1:
+        if options.concurrent_tests == 1:
             return ''
         return ('--processes={procs_per_suite} --process-timeout={proc_timeout}'.format(
             procs_per_suite=options.concurrent_tests,
@@ -127,7 +124,7 @@ def run_tests_in_parallel(options, nosetests_args):
             if pkg not in NOT_MULTIPROC_SAFE else '')
 
     def get_concurrent_suites():
-        if use_multiproc or '-n' in sys.argv:
+        if '-n' in sys.argv:
             return options.concurrent_suites
         return CPUS
 
@@ -135,34 +132,61 @@ def run_tests_in_parallel(options, nosetests_args):
     env = dict(os.environ,
                NOSE_IGNORE_CONFIG_FILES='1')
     for package in check_packages(options.packages):
-        cover_package = package.lower()
-        our_nosetests_args = copy(nosetests_args)
-        our_nosetests_args.append('--cover-package={}'.format(cover_package))
-        cmd = "nosetests {pkg_path} {nosetests_args} {multiproc_args}".format(
+        runner = 'nosetests'
+        if options.coverage:
+            # This is the recommended way to run coverage + nose  https://coverage.readthedocs.io/en/latest/faq.html
+            runner = 'coverage run $(which nosetests)'
+            """
+            And using config settings in setup.cfg seems to work well with parallel processes
+            Otherwise need to run with a complex setup like:
+                PYTHONPATH=/tmp/cov coverage run --rcfile /tmp/cov/.covrc
+            And /tmp/cov/sitecustomize.py containing:
+                import os
+                os.environ['COVERAGE_PROCESS_START'] = '/tmp/cov/.covrc'
+                import coverage
+                coverage.process_startup()
+            """
+
+        multiproc_args = get_multiproc_args(package)
+        cmd = "{runner} {pkg_path} {nosetests_args} {multiproc_args}".format(
+            runner=runner,
             pkg_path=get_pkg_path(package),
-            nosetests_args=' '.join(our_nosetests_args),
-            multiproc_args=get_multiproc_args(package),
+            nosetests_args=' '.join(nosetests_args),
+            multiproc_args=multiproc_args,
         )
+        if options.coverage:
+            cmd += ' && coverage combine'  # merge separate files present from multiprocessing config being on
+            cmd += ' && coverage report --include=./* --omit="*/tests/*"'
         cmds.append((cmd, dict(cwd=package, env=env)))
 
     # TODO: add a way to include this or not; and add xml output for Jenkins
     cmds.append(('npm run lint-es6', {}))
-    return run_many(cmds, processes=get_concurrent_suites())
+
+    ret_codes = run_many(cmds, processes=get_concurrent_suites())
+
+    if options.coverage and not any(ret_codes) and len(options.packages) > 1:
+        subprocess.call('rm .coverage', shell=True)
+        subprocess.check_call('cp --backup=numbered */.coverage .', shell=True)
+        subprocess.check_call('coverage combine --append', shell=True)
+        report_cmd = "coverage report --omit='*/tests/*'"
+        subprocess.check_call(report_cmd, shell=True)
+        print('\nFor HTML coverage report run: {}'.format(report_cmd.replace(' report', ' html')))
+
+    return ret_codes
 
 
 def parse_args():
     parser = argparse.ArgumentParser(
         formatter_class=argparse.RawDescriptionHelpFormatter,
-        epilog=textwrap.dedent('''
-                                        All additional arguments are passed along to nosetests
-                                          (e.g. -v --with-coverage)
-                                        Note: --cover-package will be set automatically to the appropriate value'''))
+        epilog='''All additional arguments are passed along to nosetests (e.g. -v)''')
     parser.add_argument('-n', help='Number of test suites to run concurrently in separate '
                                    'processes. Default: # CPUs / 4',
                         dest='concurrent_suites', type=int, default=CONCURRENT_SUITES)
     parser.add_argument('-m', help='Number of tests to run concurrently in separate '
                                    'processes, per suite. Default: # CPUs / # concurrent suites',
                         dest='concurrent_tests', type=int, default=CONCURRENT_TESTS)
+    parser.add_argument('--coverage', action='store_true',
+                        help='Collect code coverage details, and report')
     parser.add_argument(
         '-p', help='List of packages to run tests on. Default: all',
         dest='packages', choices=get_packages(), default=get_packages(),