Skip to content

Commit bc9c381

Browse files
CurryKittenaddaleax
authored andcommitted
build: add code coverage to make
PR-URL: #10856 Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
1 parent 9c45758 commit bc9c381

File tree

5 files changed

+123
-2
lines changed

5 files changed

+123
-2
lines changed

Makefile

+66-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ TEST_CI_ARGS ?=
1010
STAGINGSERVER ?= node-www
1111
LOGLEVEL ?= silent
1212
OSTYPE := $(shell uname -s | tr '[A-Z]' '[a-z]')
13+
COVTESTS ?= test
1314

1415
ifdef JOBS
1516
PARALLEL_ARGS = -j $(JOBS)
@@ -113,6 +114,69 @@ distclean:
113114

114115
check: test
115116

117+
# Remove files generated by running coverage, put the non-instrumented lib back
118+
# in place
119+
coverage-clean:
120+
if [ -d lib_ ]; then rm -rf lib; mv lib_ lib; fi
121+
-rm -rf node_modules
122+
-rm -rf gcovr testing
123+
-rm -rf out/$(BUILDTYPE)/.coverage
124+
-rm -rf .cov_tmp coverage
125+
-rm -f out/$(BUILDTYPE)/obj.target/node/src/*.gcda
126+
-rm -f out/$(BUILDTYPE)/obj.target/node/src/tracing/*.gcda
127+
-rm -f out/$(BUILDTYPE)/obj.target/node/src/*.gcno
128+
-rm -f out/$(BUILDTYPE)/obj.target/node/src/tracing*.gcno
129+
130+
# Build and test with code coverage reporting. Leave the lib directory
131+
# instrumented for any additional runs the user may want to make.
132+
# For C++ coverage reporting, this needs to be run in conjunction with configure
133+
# --coverage. html coverage reports will be created under coverage/
134+
135+
coverage: coverage-test
136+
137+
coverage-build: all
138+
mkdir -p node_modules
139+
if [ ! -d node_modules/istanbul-merge ]; then \
140+
$(NODE) ./deps/npm install istanbul-merge; fi
141+
if [ ! -d node_modules/nyc ]; then $(NODE) ./deps/npm install nyc; fi
142+
if [ ! -d gcovr ]; then git clone --depth=1 \
143+
--single-branch git://github.com/gcovr/gcovr.git; fi
144+
if [ ! -d testing ]; then git clone --depth=1 \
145+
--single-branch https://github.com/nodejs/testing.git; fi
146+
if [ ! -f gcovr/scripts/gcovr.orig ]; then \
147+
(cd gcovr && patch -N -p1 < \
148+
"$(CURDIR)/testing/coverage/gcovr-patches.diff"); fi
149+
if [ -d lib_ ]; then rm -rf lib; mv lib_ lib; fi
150+
mv lib lib_
151+
$(NODE) ./node_modules/.bin/nyc instrument lib_/ lib/
152+
$(MAKE)
153+
154+
coverage-test: coverage-build
155+
-rm -rf out/$(BUILDTYPE)/.coverage
156+
-rm -rf .cov_tmp
157+
-rm -f out/$(BUILDTYPE)/obj.target/node/src/*.gcda
158+
-rm -f out/$(BUILDTYPE)/obj.target/node/src/tracing/*.gcda
159+
-$(MAKE) $(COVTESTS)
160+
mv lib lib__
161+
mv lib_ lib
162+
mkdir -p coverage .cov_tmp
163+
$(NODE) ./node_modules/.bin/istanbul-merge --out \
164+
.cov_tmp/libcov.json 'out/Release/.coverage/coverage-*.json'
165+
(cd lib && .$(NODE) ../node_modules/.bin/nyc report \
166+
--temp-directory "$(CURDIR)/.cov_tmp" -r html \
167+
--report-dir "../coverage")
168+
-(cd out && "../gcovr/scripts/gcovr" --gcov-exclude='.*deps' \
169+
--gcov-exclude='.*usr' -v -r Release/obj.target/node \
170+
--html --html-detail -o ../coverage/cxxcoverage.html)
171+
mv lib lib_
172+
mv lib__ lib
173+
@echo -n "Javascript coverage %: "
174+
@grep -B1 Lines coverage/index.html | head -n1 \
175+
| sed 's/<[^>]*>//g'| sed 's/ //g'
176+
@echo -n "C++ coverage %: "
177+
@grep -A3 Lines coverage/cxxcoverage.html | grep style \
178+
| sed 's/<[^>]*>//g'| sed 's/ //g'
179+
116180
cctest: all
117181
@out/$(BUILDTYPE)/$@
118182

@@ -781,4 +845,5 @@ endif
781845
bench-all bench bench-misc bench-array bench-buffer bench-net \
782846
bench-http bench-fs bench-tls cctest run-ci test-v8 test-v8-intl \
783847
test-v8-benchmarks test-v8-all v8 lint-ci bench-ci jslint-ci doc-only \
784-
$(TARBALL)-headers test-ci test-ci-native test-ci-js build-ci clear-stalled
848+
$(TARBALL)-headers test-ci test-ci-native test-ci-js build-ci clear-stalled \
849+
coverage-clean coverage-build coverage-test coverage

lib/internal/bootstrap_node.js

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
NativeModule.require('internal/process/stdio').setup();
4545
_process.setupKillAndExit();
4646
_process.setupSignalHandlers();
47+
if (global.__coverage__)
48+
NativeModule.require('internal/process/write-coverage').setup();
4749

4850
// Do not initialize channel in debugger agent, it deletes env variable
4951
// and the main thread won't see it.
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
const process = require('process');
3+
const path = require('path');
4+
const fs = require('fs');
5+
const mkdirSync = fs.mkdirSync;
6+
const writeFileSync = fs.writeFileSync;
7+
8+
var isWritingCoverage = false;
9+
function writeCoverage() {
10+
if (isWritingCoverage || !global.__coverage__) {
11+
return;
12+
}
13+
isWritingCoverage = true;
14+
15+
const dirname = path.join(path.dirname(process.execPath), '.coverage');
16+
const filename = `coverage-${process.pid}-${Date.now()}.json`;
17+
try {
18+
mkdirSync(dirname);
19+
} catch (err) {
20+
if (err.code !== 'EEXIST') {
21+
console.error(err);
22+
return;
23+
}
24+
}
25+
26+
const target = path.join(dirname, filename);
27+
const coverageInfo = JSON.stringify(global.__coverage__);
28+
try {
29+
writeFileSync(target, coverageInfo);
30+
} catch (err) {
31+
console.error(err);
32+
}
33+
}
34+
35+
function setup() {
36+
const reallyReallyExit = process.reallyExit;
37+
38+
process.reallyExit = function(code) {
39+
writeCoverage();
40+
reallyReallyExit(code);
41+
};
42+
43+
process.on('exit', writeCoverage);
44+
}
45+
46+
exports.setup = setup;

node.gyp

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
'lib/internal/process/warning.js',
9494
'lib/internal/process.js',
9595
'lib/internal/querystring.js',
96+
'lib/internal/process/write-coverage.js',
9697
'lib/internal/readline.js',
9798
'lib/internal/repl.js',
9899
'lib/internal/socket_list.js',

test/common.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,9 @@ exports.platformTimeout = function(ms) {
284284
if (process.config.target_defaults.default_configuration === 'Debug')
285285
ms = 2 * ms;
286286

287+
if (global.__coverage__)
288+
ms = 4 * ms;
289+
287290
if (exports.isAix)
288291
return 2 * ms; // default localhost speed is slower on AIX
289292

@@ -381,7 +384,11 @@ function leakedGlobals() {
381384
if (!knownGlobals.includes(global[val]))
382385
leaked.push(val);
383386

384-
return leaked;
387+
if (global.__coverage__) {
388+
return leaked.filter((varname) => !/^(cov_|__cov)/.test(varname));
389+
} else {
390+
return leaked;
391+
}
385392
}
386393
exports.leakedGlobals = leakedGlobals;
387394

0 commit comments

Comments
 (0)