summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Wright <fw@fwright.net>2016-03-15 16:52:09 -0700
committerEric S. Raymond <esr@thyrsus.com>2016-03-15 20:31:21 -0400
commit45d873ea3a6e2122900d2b785b7cd131a7759569 (patch)
treefcf4ec267deb74a759262d38a96aff009671d2af
parent1829ba9c5106340b83be4a6dc5d69b37421bc98c (diff)
downloadgpsd-45d873ea3a6e2122900d2b785b7cd131a7759569.tar.gz
Adds support for Python coveraging.
This extends the "coveraging" option to apply coveraging to any Python programs executed during the build. It adds a new option "python_coverage" to allow configuring the command to be used for applying coveraging to Python programs, with a default value of "coverage run" (which is typically appropriate, provided that the coverage package is installed). Setting this to the null string disables Python coveraging. If "python_coverage" has its default value and parallel builds are enabled, "--parallel-mode" is automatically appended to the coverage command. If a non-default coverage command is used, it's the user's responsibility to handle parallelism appropriately. Note that this does not apply coveraging to generated Python code. This also adds the coverage result files to .gitignore, including the C coverage files which weren't there previously. TESTED: Ran "scons check" as well as sample cases of regress-driver -b and -v, both with and without coveraging. Also verified that it works with the full path to the tool supplied as the python_coverage option.
-rw-r--r--.gitignore5
-rw-r--r--SConstruct25
-rw-r--r--build.txt12
-rwxr-xr-xregress-driver6
4 files changed, 43 insertions, 5 deletions
diff --git a/.gitignore b/.gitignore
index a1258021..2783e449 100644
--- a/.gitignore
+++ b/.gitignore
@@ -148,6 +148,11 @@ devtools/.flocktest.ini
# QT stuff
libQgpsmm.prl
libQgpsmm/binaries/*
+# C coverage-related files
+*.gcda
+# Python coverage-related files/directories
+.coverage*
+htmlcov/
# misc files
nohup.out
*.bak
diff --git a/SConstruct b/SConstruct
index 08272421..32d7e1f3 100644
--- a/SConstruct
+++ b/SConstruct
@@ -194,6 +194,8 @@ nonboolopts = (
("target", "", "cross-development target"),
("sysroot", "", "cross-development system root"),
("qt_versioned", "", "version for versioned Qt"),
+ ("python_coverage", "coverage run",
+ "coverage command for Python progs"),
)
for (name, default, help) in nonboolopts:
opts.Add(name, help, default)
@@ -863,6 +865,23 @@ if env["qt"] and env["shared"]:
else:
qt_env = None
+# Set up for Python coveraging if needed
+if env['coveraging'] and env['python_coverage'] and not (cleaning or helping):
+ pycov_default = opts.options[opts.keys().index('python_coverage')].default
+ pycov_current = env['python_coverage']
+ pycov_list = pycov_current.split()
+ if env.GetOption('num_jobs') > 1 and pycov_current == pycov_default:
+ pycov_list.append('--parallel-mode')
+ # May need absolute path to coveraging tool if 'PythonXX' is prefixed
+ pycov_path = env.WhereIs(pycov_list[0])
+ if pycov_path:
+ pycov_list[0] = pycov_path
+ env['PYTHON_COVERAGE'] = ' '.join(pycov_list)
+ env['ENV']['PYTHON_COVERAGE'] = ' '.join(pycov_list)
+ else:
+ announce('Python coverage tool not found - disabling Python coverage.')
+ env['python_coverage'] = '' # So we see it in the options
+
## Two shared libraries provide most of the code for the C programs
libgps_version_soname = libgps_version_current - libgps_version_age
@@ -1559,7 +1578,7 @@ else:
# SCons to install up to date versions of gpsfake and gpsctl if it can
# find older versions of them in a directory on your $PATH.
gps_herald = Utility('gps-herald', [gpsd, gpsctl, python_built_extensions],
- ':; $SRCDIR/gpsfake -T')
+ ':; $PYTHON_COVERAGE $SRCDIR/gpsfake -T')
gps_log_pattern = os.path.join('test', 'daemon', '*.log')
gps_logs = glob.glob(gps_log_pattern)
gps_names = [os.path.split(x)[-1][:-4] for x in gps_logs]
@@ -1704,7 +1723,7 @@ if not env['python']:
else:
maidenhead_locator_regress = Utility('maidenhead-locator-regress', [python_built_extensions], [
'@echo "Testing the Maidenhead Locator conversion..."',
- '$SRCDIR/test_maidenhead.py >/dev/null',
+ '$PYTHON_COVERAGE $SRCDIR/test_maidenhead.py >/dev/null',
])
# Regression-test the calendar functions
@@ -1983,6 +2002,8 @@ env.Clean(clean_misc, all_manpages)
env.Clean(clean_misc, glob.glob('*.pyc') + glob.glob('gps/*.pyc'))
# Clean coverage and profiling files
env.Clean(clean_misc, glob.glob('*.gcno') + glob.glob('*.gcda'))
+# Clean Python coverage files
+env.Clean(clean_misc, glob.glob('.coverage*') + ['htmlcov/'])
# Other misc items
env.Clean(clean_misc, ['config.log', 'contrib/ppscheck', 'TAGS'])
diff --git a/build.txt b/build.txt
index 67aa96b7..ef7916b3 100644
--- a/build.txt
+++ b/build.txt
@@ -371,6 +371,18 @@ Because the output from the various jobs is interleaved, it may be more
difficult to understand error results with multiple jobs. In that event,
simply rerun without the -j option for more straightforward output.
+If coveraging is enabled (coveraging=yes), then Python programs run
+during testing are run via Python coveraging. This prefixes the relevant
+commands with the content of the python_coverage option, whose default
+value of "coverage run" is appropriate if the standard Python coverage
+package is installed and accessible in the command path. It can be
+set to a different value if necessary, or set to the empty string to
+disable Python coveraging. The latter happens automatically (with a
+message) if the tool cannot be found. When running multiple jobs with
+"-j", if python_coverage has its default value, "--parallel" is automatically
+appended to the command. With a non-default setting, accomodating
+parallelism is the user's responsibility.
+
For instructions on how to live-test the software, see the file INSTALL.
== Reverting to a clean state ==
diff --git a/regress-driver b/regress-driver
index e64bc304..0ca349bc 100755
--- a/regress-driver
+++ b/regress-driver
@@ -129,7 +129,7 @@ case $mode in
then
trap 'rm -f ${TMP}/test-$$.chk; exit $errors' EXIT HUP INT TERM
case $testing in
- daemon) TMPDIR=${TMP} ${PYTHON} ${GPSD_HOME}/gpsfake -s 38400 -1 -p $opts ${f} | ${GPSFILTER} ${ALTFILTER} >${TMP}/test-$$.chk ;;
+ daemon) TMPDIR=${TMP} ${PYTHON} ${PYTHON_COVERAGE} ${GPSD_HOME}/gpsfake -s 38400 -1 -p $opts ${f} | ${GPSFILTER} ${ALTFILTER} >${TMP}/test-$$.chk ;;
clientlib) ${GPSD_HOME}/test_libgps -b <${f} >${TMP}/test-$$.chk ;;
esac
if [ "${ALTFILTER}" ]
@@ -185,7 +185,7 @@ case $mode in
[ $quiet = true ] || echo "Rebuilding $testing regressions..." >&2
for f in $*; do
case $testing in
- daemon) ${PYTHON} ${GPSD_HOME}/gpsfake -s 38400 -1 -p $opts ${f} | ${GPSFILTER} >${f}.chk;;
+ daemon) ${PYTHON} ${PYTHON_COVERAGE} ${GPSD_HOME}/gpsfake -s 38400 -1 -p $opts ${f} | ${GPSFILTER} >${f}.chk;;
clientlib) ${GPSD_HOME}/test_libgps -b <${f} >${f}.chk ;;
esac
done
@@ -195,7 +195,7 @@ case $mode in
[ $quiet = true ] || echo "Viewing..." >&2
for f in $*; do
case $testing in
- daemon) ${PYTHON} ${GPSD_HOME}/gpsfake -s 38400 -1 -p $opts ${f} | ${GPSFILTER} ;;
+ daemon) ${PYTHON} ${PYTHON_COVERAGE} ${GPSD_HOME}/gpsfake -s 38400 -1 -p $opts ${f} | ${GPSFILTER} ;;
clientlib) ${GPSD_HOME}/libgps -b <${f} ;;
esac
done