Repository: Pyomo/pyomo

Issue:
Export coverage from Jenkins jobs
We should augment the Jenkins tests to also push their coverage results to the codecov website.  I have set up the `codecov` client application, so (hopefully) the only thing left to do is for @whart222 to generate whatever tokens we need to include in the call to `codecov` to get the results pushed / merged into the master report.  See the codecov [documentation](https://github.com/codecov/example-python).

Other issues:
- Our current Jenkins tests only test master and not pull requests.  Should we look at adding that?
- Will the coverage information for PR be skewed because the PR coverage won't include the tests that require solvers (and are only run in Jenkins)?



Discussion:

Resolving patch:
diff --git a/admin/driver.py b/admin/driver.py
--- a/admin/driver.py
+++ b/admin/driver.py
@@ -192,7 +192,22 @@ def perform_tests(package, coverage=False, omit=None, cat='nightly'):
         cmd = [os.path.join( os.environ['WORKSPACE'],'python','bin','test.'+package ), '--cat', cat]
     cmd.append('-v')
     if coverage:
-        cmd.extend(['--coverage','--cover-erase'])
+        sitedir = os.path.join(
+            os.environ['WORKSPACE'],'python','lib',
+            'python'+'.'.join(map(str,sys.version_info[:2])),'site-packages')
+        pthfile = os.path.join(sitedir, 'run_coverage_at_startup.pth')
+        with open(pthfile, 'w') as FILE:
+            FILE.write('import coverage; coverage.process_startup()\n')
+        srcdir = os.path.join(os.environ['WORKSPACE'],'src','pyomo')
+        with open(os.path.join(srcdir, '.coveragerc'), 'r') as FILE:
+            coveragerc = FILE.readlines()
+        coveragerc.append("data_file=%s%s.coverage\n" % (srcdir, os.path.sep))
+        coveragerc_file = os.path.join(srcdir, 'coveragerc')
+        with open(coveragerc_file, 'w') as FILE:
+            FILE.write(''.join(coveragerc))
+        os.environ['COVERAGE_PROCESS_START'] = coveragerc_file
+        # The above supersedes the need for --coverage
+        #cmd.extend(['--coverage','--cover-erase'])
     if 'TEST_PACKAGES' in os.environ:
         cmd = cmd + re.split('[ \t]+', os.environ['TEST_PACKAGES'].strip())
     sys.stdout.write( "Running Command: %s\n" % " ".join(cmd) )
@@ -211,17 +226,34 @@ def perform_tests(package, coverage=False, omit=None, cat='nightly'):
     if not coverage:
         return
     os.chdir(os.path.join( os.environ['WORKSPACE'],'src','pyomo' ))
-    libdir = os.path.join( os.environ['WORKSPACE'],'python','lib','*' )
-    libdir = libdir + "," + os.path.join( libdir,'site-packages','*' )
-    if omit is not None:
-        omit = ","+omit
-    else:
-        omit = ""
-    covFName = os.path.join( os.environ['WORKSPACE'],'src','coverage.xml' )
+    cover_cmd=[os.path.join(os.environ['WORKSPACE'],'python','bin','coverage')]
     if platform == 'win':
-        cmd = [os.path.join( os.environ['WORKSPACE'],'python','bin','coverage.exe' ), 'xml', '--omit="%s%s"' % (libdir,omit), '-o', covFName ]
+        cover_cmd[0] += '.exe'
+    cmd = cover_cmd + ['combine']
+    sys.stdout.write( "Running Command: %s\n" % " ".join(cmd) )
+    sys.stdout.flush()
+    if platform == 'win':
+        sys.stdout.write( str(subprocess.call(['cmd','/c']+cmd)) + '\n' )
     else:
-        cmd = [os.path.join( os.environ['WORKSPACE'],'python','bin','coverage' ), 'xml', '--omit="%s%s"' % (libdir,omit), '-o', covFName ]
+        sys.stdout.write( str(subprocess.call(cmd)) + '\n' )
+
+    # We used to hard-code the ommission of the site-packages and the
+    # python libraries here.  That directive is now managed by the
+    # coveragerc file.  The commented code below is maintained strictly
+    # for historical reference.
+    #
+    #libdir = os.path.join( os.environ['WORKSPACE'],'python','lib','*' )
+    #libdir = libdir + "," + os.path.join( libdir,'site-packages','*' )
+    #if omit is not None:
+    #    omit = ","+omit
+    #else:
+    #    omit = ""
+
+    cmd = cover_cmd + ['xml']
+    if omit is not None:
+        cmd.append('--omit=%s' % (omit,))
+    covFName = os.path.join( os.environ['WORKSPACE'],'src','coverage.xml' )
+    cmd.extend(['-o', covFName])
     sys.stdout.write( "Running Command: %s\n" % " ".join(cmd) )
     sys.stdout.flush()
     if platform == 'win':
@@ -231,7 +263,9 @@ def perform_tests(package, coverage=False, omit=None, cat='nightly'):
         #sys.stdout.write( str(subprocess.call(['ls', '-la'])) + '\n')
         sys.stdout.write( str(subprocess.call(cmd)) + '\n' )
 
-    # NB: for Hudson source rendering to work correctly, the XML must include the relative path to the source filenames *from the project workspace*
+    # NB: for Hudson source rendering to work correctly, the XML must
+    # include the relative path to the source filenames *from the
+    # project workspace*
     try:
         keep(covFName, 'package', 'name', '.*\.tests', covFName)
         doc = xml.dom.minidom.parse(covFName)
diff --git a/admin/jenkins.py b/admin/jenkins.py
--- a/admin/jenkins.py
+++ b/admin/jenkins.py
@@ -55,12 +55,18 @@
 print("\nSystem PATH:\n\t%s" % os.environ['PATH'])
 print("\nPython path:\n\t%s" % sys.path)
 
-coverage_omit=','.join([
-    os.sep.join([os.environ['WORKSPACE'], 'src', 'pyomo', 'pyomo', '*', 'tests']),
-    'pyomo.*.tests',
-    os.sep.join([os.environ['WORKSPACE'], 'src', 'pyutilib.*']),
-    'pyutilib.*',
-])
+# We used to hard-code the ommission of tests and pyutilib here.  That
+# directive is now managed by the coveragerc file using slightly
+# different patterns.  The commented code below is maintained strictly
+# for historical reference.
+#
+#coverage_omit=','.join([
+#    os.sep.join([os.environ['WORKSPACE'], 'src', 'pyomo', 'pyomo', '*', 'tests']),
+#    'pyomo.*.tests',
+#    os.sep.join([os.environ['WORKSPACE'], 'src', 'pyutilib.*']),
+#    'pyutilib.*',
+#])
+coverage_omit = None
 
 pyomo_packages = [
     'pyomo.%s' % os.path.basename(x) for x in


Test patch: