Browse Source

build: add code coverage to make

PR-URL: https://github.com/nodejs/node/pull/10856
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
v7.x
Wayne Andrews 8 years ago
committed by Anna Henningsen
parent
commit
bc9c381027
No known key found for this signature in database GPG Key ID: D8B9F5AEAE84E4CF
  1. 67
      Makefile
  2. 2
      lib/internal/bootstrap_node.js
  3. 46
      lib/internal/process/write-coverage.js
  4. 1
      node.gyp
  5. 9
      test/common.js

67
Makefile

@ -10,6 +10,7 @@ TEST_CI_ARGS ?=
STAGINGSERVER ?= node-www
LOGLEVEL ?= silent
OSTYPE := $(shell uname -s | tr '[A-Z]' '[a-z]')
COVTESTS ?= test
ifdef JOBS
PARALLEL_ARGS = -j $(JOBS)
@ -113,6 +114,69 @@ distclean:
check: test
# Remove files generated by running coverage, put the non-instrumented lib back
# in place
coverage-clean:
if [ -d lib_ ]; then rm -rf lib; mv lib_ lib; fi
-rm -rf node_modules
-rm -rf gcovr testing
-rm -rf out/$(BUILDTYPE)/.coverage
-rm -rf .cov_tmp coverage
-rm -f out/$(BUILDTYPE)/obj.target/node/src/*.gcda
-rm -f out/$(BUILDTYPE)/obj.target/node/src/tracing/*.gcda
-rm -f out/$(BUILDTYPE)/obj.target/node/src/*.gcno
-rm -f out/$(BUILDTYPE)/obj.target/node/src/tracing*.gcno
# Build and test with code coverage reporting. Leave the lib directory
# instrumented for any additional runs the user may want to make.
# For C++ coverage reporting, this needs to be run in conjunction with configure
# --coverage. html coverage reports will be created under coverage/
coverage: coverage-test
coverage-build: all
mkdir -p node_modules
if [ ! -d node_modules/istanbul-merge ]; then \
$(NODE) ./deps/npm install istanbul-merge; fi
if [ ! -d node_modules/nyc ]; then $(NODE) ./deps/npm install nyc; fi
if [ ! -d gcovr ]; then git clone --depth=1 \
--single-branch git://github.com/gcovr/gcovr.git; fi
if [ ! -d testing ]; then git clone --depth=1 \
--single-branch https://github.com/nodejs/testing.git; fi
if [ ! -f gcovr/scripts/gcovr.orig ]; then \
(cd gcovr && patch -N -p1 < \
"$(CURDIR)/testing/coverage/gcovr-patches.diff"); fi
if [ -d lib_ ]; then rm -rf lib; mv lib_ lib; fi
mv lib lib_
$(NODE) ./node_modules/.bin/nyc instrument lib_/ lib/
$(MAKE)
coverage-test: coverage-build
-rm -rf out/$(BUILDTYPE)/.coverage
-rm -rf .cov_tmp
-rm -f out/$(BUILDTYPE)/obj.target/node/src/*.gcda
-rm -f out/$(BUILDTYPE)/obj.target/node/src/tracing/*.gcda
-$(MAKE) $(COVTESTS)
mv lib lib__
mv lib_ lib
mkdir -p coverage .cov_tmp
$(NODE) ./node_modules/.bin/istanbul-merge --out \
.cov_tmp/libcov.json 'out/Release/.coverage/coverage-*.json'
(cd lib && .$(NODE) ../node_modules/.bin/nyc report \
--temp-directory "$(CURDIR)/.cov_tmp" -r html \
--report-dir "../coverage")
-(cd out && "../gcovr/scripts/gcovr" --gcov-exclude='.*deps' \
--gcov-exclude='.*usr' -v -r Release/obj.target/node \
--html --html-detail -o ../coverage/cxxcoverage.html)
mv lib lib_
mv lib__ lib
@echo -n "Javascript coverage %: "
@grep -B1 Lines coverage/index.html | head -n1 \
| sed 's/<[^>]*>//g'| sed 's/ //g'
@echo -n "C++ coverage %: "
@grep -A3 Lines coverage/cxxcoverage.html | grep style \
| sed 's/<[^>]*>//g'| sed 's/ //g'
cctest: all
@out/$(BUILDTYPE)/$@
@ -781,4 +845,5 @@ endif
bench-all bench bench-misc bench-array bench-buffer bench-net \
bench-http bench-fs bench-tls cctest run-ci test-v8 test-v8-intl \
test-v8-benchmarks test-v8-all v8 lint-ci bench-ci jslint-ci doc-only \
$(TARBALL)-headers test-ci test-ci-native test-ci-js build-ci clear-stalled
$(TARBALL)-headers test-ci test-ci-native test-ci-js build-ci clear-stalled \
coverage-clean coverage-build coverage-test coverage

2
lib/internal/bootstrap_node.js

@ -44,6 +44,8 @@
NativeModule.require('internal/process/stdio').setup();
_process.setupKillAndExit();
_process.setupSignalHandlers();
if (global.__coverage__)
NativeModule.require('internal/process/write-coverage').setup();
// Do not initialize channel in debugger agent, it deletes env variable
// and the main thread won't see it.

46
lib/internal/process/write-coverage.js

@ -0,0 +1,46 @@
'use strict';
const process = require('process');
const path = require('path');
const fs = require('fs');
const mkdirSync = fs.mkdirSync;
const writeFileSync = fs.writeFileSync;
var isWritingCoverage = false;
function writeCoverage() {
if (isWritingCoverage || !global.__coverage__) {
return;
}
isWritingCoverage = true;
const dirname = path.join(path.dirname(process.execPath), '.coverage');
const filename = `coverage-${process.pid}-${Date.now()}.json`;
try {
mkdirSync(dirname);
} catch (err) {
if (err.code !== 'EEXIST') {
console.error(err);
return;
}
}
const target = path.join(dirname, filename);
const coverageInfo = JSON.stringify(global.__coverage__);
try {
writeFileSync(target, coverageInfo);
} catch (err) {
console.error(err);
}
}
function setup() {
const reallyReallyExit = process.reallyExit;
process.reallyExit = function(code) {
writeCoverage();
reallyReallyExit(code);
};
process.on('exit', writeCoverage);
}
exports.setup = setup;

1
node.gyp

@ -93,6 +93,7 @@
'lib/internal/process/warning.js',
'lib/internal/process.js',
'lib/internal/querystring.js',
'lib/internal/process/write-coverage.js',
'lib/internal/readline.js',
'lib/internal/repl.js',
'lib/internal/socket_list.js',

9
test/common.js

@ -284,6 +284,9 @@ exports.platformTimeout = function(ms) {
if (process.config.target_defaults.default_configuration === 'Debug')
ms = 2 * ms;
if (global.__coverage__)
ms = 4 * ms;
if (exports.isAix)
return 2 * ms; // default localhost speed is slower on AIX
@ -381,7 +384,11 @@ function leakedGlobals() {
if (!knownGlobals.includes(global[val]))
leaked.push(val);
return leaked;
if (global.__coverage__) {
return leaked.filter((varname) => !/^(cov_|__cov)/.test(varname));
} else {
return leaked;
}
}
exports.leakedGlobals = leakedGlobals;

Loading…
Cancel
Save