Skip to content
This repository has been archived by the owner on May 13, 2019. It is now read-only.

Commit

Permalink
Check in resources/scripts for coverage generation
Browse files Browse the repository at this point in the history
Add patch files that enable coverage generation for Node core
as well as a simple script for rendering a table of nightly
coverage results.

Ref: #36

PR-URL: #38
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
  • Loading branch information
addaleax authored and mhdawson committed Nov 1, 2016
1 parent 766a90e commit d41c55d
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 0 deletions.
23 changes: 23 additions & 0 deletions coverage/gcovr-patches.diff
@@ -0,0 +1,23 @@
diff --git a/scripts/gcovr b/scripts/gcovr
index 034779c86d29..e68b239c424f 100755
--- a/scripts/gcovr
+++ b/scripts/gcovr
@@ -496,7 +496,7 @@ def process_gcov_data(data_fname, covdata, options):
if filtered_fname is None:
if options.verbose:
sys.stdout.write(" Filtering coverage data for file %s\n" % fname)
- return
+ #return
#
# Return if the filename matches the exclude pattern
#
@@ -2141,6 +2141,9 @@ if options.objdir:
for i in range(0, len(options.exclude)):
options.exclude[i] = re.compile(options.exclude[i])

+if options.output is not None:
+ options.output = os.path.abspath(options.output)
+
if options.root is not None:
if not options.root:
sys.stderr.write(
78 changes: 78 additions & 0 deletions coverage/generate-index-html.py
@@ -0,0 +1,78 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

with open('out/index.csv') as index:
index_csv = filter(lambda line: line, index.read().split('\n'))

with open('out/index.html', 'w') as out:
out.write(
'''
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Node.js Core Coverage</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700" type="text/css">
<link rel="stylesheet" href="https://code.getmdl.io/1.1.3/material.yellow-indigo.min.css" />
<style media="screen" type="text/css">
.table-container {
display: flex;
justify-content: center;
margin-top: 50px;
}
</style>
</head>
<body>
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
<header class="mdl-layout__header">
<div class="mdl-layout__header-row">
<!-- Title -->
<span class="mdl-layout-title">Node.js Core Coverage</span>
<!-- Add spacer, to align navigation to the right -->
<div class="mdl-layout-spacer"></div>
<!-- Navigation. We hide it in small screens. -->
<nav class="mdl-navigation mdl-layout--large-screen-only">
<a class="mdl-navigation__link" href="https://github.com/nodejs/node">Node.js Core</a>
<a class="mdl-navigation__link" href="https://github.com/addaleax/node-core-coverage">Project</a>
</nav>
</div>
</header>
<div class="mdl-layout__drawer">
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="https://github.com/nodejs/node">Node.js Core</a>
<a class="mdl-navigation__link" href="https://github.com/addaleax/node-core-coverage">Project</a>
</nav>
</div>
<main class="table-container mdl-layout__content">
<div class="page-content">
<table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp">
<thead>
<tr>
<th>Date</th>
<th>HEAD</th>
<th>JS Coverage</th>
<th>C++ Coverage</th>
</tr>
</thead>
<tbody>
''')
for line in reversed(index_csv):
jscov, cxxcov, date, sha = line.split(',')
out.write('''
<tr>
<td>{0}</td>
<td><a href="https://github.com/nodejs/node/commit/{1}">{1}</a></td>
<td><a href="coverage-{1}/index.html">{2:05.2f}&nbsp;%</a></td>
<td><a href="coverage-{1}/cxxcoverage.html">{3:05.2f}&nbsp;%</a></td>
</tr>'''.format(date, sha, float(jscov), float(cxxcov)))
out.write('''
</tbody>
</table>
</div>
</main>
<script defer src="https://code.getmdl.io/1.1.3/material.min.js"></script>
</body>
</html>''')
146 changes: 146 additions & 0 deletions coverage/patches.diff
@@ -0,0 +1,146 @@
diff --git a/.gitignore b/.gitignore
index c7361af80c79..e56b7f913845 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,8 @@ node_g
icu_config.gypi

/out
+/coverage
+/lib_

# various stuff that VC++ produces/uses
Debug/
diff --git a/lib/internal/bootstrap_node.js b/lib/internal/bootstrap_node.js
index 27f05a4fcf14..ae0fed9e1c00 100644
--- a/lib/internal/bootstrap_node.js
+++ b/lib/internal/bootstrap_node.js
@@ -42,6 +42,7 @@
NativeModule.require('internal/process/stdio').setup();
_process.setupKillAndExit();
_process.setupSignalHandlers();
+ 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.
diff --git a/lib/internal/process/write-coverage.js b/lib/internal/process/write-coverage.js
new file mode 100644
index 000000000000..666939bc3389
--- /dev/null
+++ b/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() {
+ var reallyReallyExit = process.reallyExit;
+
+ process.reallyExit = function(code) {
+ writeCoverage();
+ reallyReallyExit(code);
+ };
+
+ process.on('exit', writeCoverage);
+}
+
+exports.setup = setup;
diff --git a/node.gyp b/node.gyp
index 05a5530a2b14..fb8f865efe8a 100644
--- a/node.gyp
+++ b/node.gyp
@@ -80,6 +80,7 @@
'lib/internal/process/promises.js',
'lib/internal/process/stdio.js',
'lib/internal/process/warning.js',
+ 'lib/internal/process/write-coverage.js',
'lib/internal/process.js',
'lib/internal/readline.js',
'lib/internal/repl.js',
@@ -479,7 +480,13 @@
[ 'OS=="freebsd" or OS=="linux"', {
'ldflags': [ '-Wl,-z,noexecstack',
'-Wl,--whole-archive <(V8_BASE)',
- '-Wl,--no-whole-archive' ]
+ '-Wl,--no-whole-archive',
+ '--coverage',
+ '-g',
+ '-O0' ],
+ 'cflags': [ '--coverage',
+ '-g',
+ '-O0' ]
}],
[ 'OS=="sunos"', {
'ldflags': [ '-Wl,-M,/usr/lib/ld/map.noexstk' ],
diff --git a/test/common.js b/test/common.js
index 5aefdc3bcee5..750c134d33ab 100644
--- a/test/common.js
+++ b/test/common.js
@@ -258,6 +258,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

@@ -348,7 +351,7 @@ function leakedGlobals() {
if (-1 === knownGlobals.indexOf(global[val]))
leaked.push(val);

- return leaked;
+ return leaked.filter((varname) => !/^__cov/.test(varname));
}
exports.leakedGlobals = leakedGlobals;

diff --git a/test/parallel/test-fs-sync-fd-leak.js b/test/parallel/test-fs-sync-fd-leak.js
index f7cfd25f4b9b..80ad8cf6b705 100644
--- a/test/parallel/test-fs-sync-fd-leak.js
+++ b/test/parallel/test-fs-sync-fd-leak.js
@@ -1,8 +1,13 @@
'use strict';
-require('../common');
+const common = require('../common');
var assert = require('assert');
var fs = require('fs');

+if (global.__coverage__) {
+ common.skip('Not working with coverage');
+ return;
+}
+
// ensure that (read|write|append)FileSync() closes the file descriptor
fs.openSync = function() {
return 42;

0 comments on commit d41c55d

Please sign in to comment.