Skip to content

Commit

Permalink
Convert testcases to use tap
Browse files Browse the repository at this point in the history
  • Loading branch information
richardlau committed Nov 9, 2016
1 parent 94a1125 commit 8296c3c
Show file tree
Hide file tree
Showing 11 changed files with 194 additions and 199 deletions.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@
"Richard Chamberlain <richard_chamberlain@uk.ibm.com> (https://github.com/rnchamberlain)"
],
"scripts": {
"test": "node test/autorun.js"
"test": "tap test/test*.js"
},
"bugs": {
"url": "https://github.com/nodejs/nodereport/issues"
},
"devDependencies": {
"tap": "^8.0.0"
}
}
129 changes: 0 additions & 129 deletions test/autorun.js

This file was deleted.

36 changes: 36 additions & 0 deletions test/common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use strict';

const fs = require('fs');

const REPORT_SECTIONS = [
'NodeReport',
'JavaScript Stack Trace',
'JavaScript Heap',
'System Information'
];

exports.findReports = (pid) => {
// Default filenames are of the form NodeReport.<date>.<time>.<pid>.<seq>.txt
const format = '^NodeReport\\.\\d+\\.\\d+\\.' + pid + '\\.\\d+\\.txt$';
const filePattern = new RegExp(format);
const files = fs.readdirSync('.');
return files.filter((file) => filePattern.test(file));
};

exports.validate = (t, report, pid) => {
t.test('Validating ' + report, (t) => {
fs.readFile(report, (err, data) => {
const reportContents = data.toString();
const plan = REPORT_SECTIONS.length + (pid ? 1 : 0);
t.plan(plan);
if (pid) {
t.match(reportContents, new RegExp('Process ID: ' + pid),
'Checking report contains expected process ID ' + pid);
}
REPORT_SECTIONS.forEach((section) => {
t.match(reportContents, new RegExp('==== ' + section),
'Checking report contains ' + section + ' section');
});
});
});
};
21 changes: 21 additions & 0 deletions test/test-api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict';

// Testcase to produce NodeReport via API call
if (process.argv[2] === 'child') {
const nodereport = require('../');
nodereport.triggerReport();
} else {
const common = require('./common.js');
const spawn = require('child_process').spawn;
const tap = require('tap');

const child = spawn(process.execPath, [__filename, 'child']);
child.on('exit', (code) => {
tap.plan(3);
tap.equal(code, 0, 'Process exited cleanly');
const reports = common.findReports(child.pid);
tap.equal(reports.length, 1, 'Found reports ' + reports);
const report = reports[0];
common.validate(tap, report, child.pid);
});
}
36 changes: 36 additions & 0 deletions test/test-exception.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use strict';

// Testcase to produce NodeReport on uncaught exception
if (process.argv[2] === 'child') {
require('../').setEvents('exception');

function myException(request, response) {
const m = '*** exception.js: testcase exception thrown from myException()';
throw new UserException(m);
}

function UserException(message) {
this.message = message;
this.name = 'UserException';
}

myException();
} else {
const common = require('./common.js');
const spawn = require('child_process').spawn;
const tap = require('tap');

const child = spawn(process.execPath, [__filename, 'child']);
child.on('exit', (code, signal) => {
const expectedExitCode = process.platform === 'win32' ? 3221225477 : null;
const expectedSignal = process.platform === 'win32' ? null : 'SIGILL';
tap.plan(4);
tap.equal(code, expectedExitCode, 'Process should not exit cleanly');
tap.equal(signal, expectedSignal,
'Process should exit with expected signal ');
const reports = common.findReports(child.pid);
tap.equal(reports.length, 1, 'Found reports ' + reports);
const report = reports[0];
common.validate(tap, report, child.pid);
});
}
33 changes: 33 additions & 0 deletions test/test-fatal-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict';

// Testcase to produce NodeReport on fatal error (javascript heap OOM)
if (process.argv[2] === 'child') {
require('../').setEvents('fatalerror');

const list = [];
while (true) {
const record = new MyRecord();
list.push(record);
}

function MyRecord() {
this.name = 'foo';
this.id = 128;
this.account = 98454324;
}
} else {
const common = require('./common.js');
const spawn = require('child_process').spawn;
const tap = require('tap');

const args = ['--max-old-space-size=20', __filename, 'child'];
const child = spawn(process.execPath, args);
child.on('exit', (code) => {
tap.plan(3);
tap.notEqual(code, 0, 'Process should not exit cleanly');
const reports = common.findReports(child.pid);
tap.equal(reports.length, 1, 'Found reports ' + reports);
const report = reports[0];
common.validate(tap, report, child.pid);
});
}
64 changes: 64 additions & 0 deletions test/test-signal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
'use strict';

// Testcase to produce NodeReport on signal interrupting a js busy-loop,
// showing it is interruptible.
if (process.argv[2] === 'child') {
require('../').setEvents('signal');

// Exit on loss of parent process
process.on('disconnect', () => process.exit(2));

function busyLoop() {
var list = [];
for (var i = 0; i < 1e10; i++) {
for (var j = 0; j < 1000; j++) {
list.push(new MyRecord());
}
for (var k = 0; k < 1000; k++) {
list[k].id += 1;
list[k].account += 2;
}
for (var l = 0; l < 1000; l++) {
list.pop();
}
}
}

function MyRecord() {
this.name = 'foo';
this.id = 128;
this.account = 98454324;
}

process.send('child started', busyLoop);
} else {
const common = require('./common.js');
const fork = require('child_process').fork;
const tap = require('tap');

if (process.platform === 'win32') {
tap.fail('Unsupported on Windows', { skip: true });
return;
}

const child = fork(__filename, ['child'], { silent: true });
// Wait for child to indicate it is ready before sending signal
child.on('message', () => child.kill('SIGUSR2'));
var stderr = '';
child.stderr.on('data', (chunk) => {
stderr += chunk;
// Terminate the child after the report has been written
if (stderr.includes('Node.js report completed')) {
child.kill('SIGTERM');
}
});
child.on('exit', (code, signal) => {
tap.plan(4);
tap.equal(code, null, 'Process should not exit cleanly');
tap.equal(signal, 'SIGTERM', 'Process should exit with expected signal');
const reports = common.findReports(child.pid);
tap.equal(reports.length, 1, 'Found reports ' + reports);
const report = reports[0];
common.validate(tap, report, child.pid);
});
}
10 changes: 0 additions & 10 deletions test/test_1.js

This file was deleted.

15 changes: 0 additions & 15 deletions test/test_2.js

This file was deleted.

16 changes: 0 additions & 16 deletions test/test_3.js

This file was deleted.

Loading

0 comments on commit 8296c3c

Please sign in to comment.