Skip to content

Commit

Permalink
test: add addon tests for RegisterSignalHandler()
Browse files Browse the repository at this point in the history
Ensure coverage for the different combinations of arguments.

PR-URL: #27775
Refs: #27246
Reviewed-By: Ben Noordhuis <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Rich Trott <[email protected]>
  • Loading branch information
addaleax committed Jun 14, 2019
1 parent 89b3237 commit 039cfdc
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 0 deletions.
7 changes: 7 additions & 0 deletions test/abort/test-addon-register-signal-handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict';
require('../common');

// This is a sibling test to test/addons/register-signal-handler/

process.env.ALLOW_CRASHES = true;
require('../addons/register-signal-handler/test');
36 changes: 36 additions & 0 deletions test/addons/register-signal-handler/binding.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#ifndef _WIN32
#include <node.h>
#include <v8.h>
#include <uv.h>
#include <assert.h>
#include <unistd.h>

using v8::Boolean;
using v8::FunctionCallbackInfo;
using v8::Int32;
using v8::Value;

void Handler(int signo, siginfo_t* siginfo, void* ucontext) {
char signo_char = signo;
int written;
do {
written = write(1, &signo_char, 1); // write() is signal-safe.
} while (written == -1 && errno == EINTR);
assert(written == 1);
}

void RegisterSignalHandler(const FunctionCallbackInfo<Value>& args) {
assert(args[0]->IsInt32());
assert(args[1]->IsBoolean());

int32_t signo = args[0].As<Int32>()->Value();
bool reset_handler = args[1].As<Boolean>()->Value();

node::RegisterSignalHandler(signo, Handler, reset_handler);
}

NODE_MODULE_INIT() {
NODE_SET_METHOD(exports, "registerSignalHandler", RegisterSignalHandler);
}

#endif // _WIN32
9 changes: 9 additions & 0 deletions test/addons/register-signal-handler/binding.gyp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
'targets': [
{
'target_name': 'binding',
'sources': [ 'binding.cc' ],
'includes': ['../common.gypi'],
}
]
}
56 changes: 56 additions & 0 deletions test/addons/register-signal-handler/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use strict';
const common = require('../../common');
if (common.isWindows)
common.skip('No RegisterSignalHandler() on Windows');

const assert = require('assert');
const fs = require('fs');
const path = require('path');
const { signals } = require('os').constants;
const { spawnSync } = require('child_process');

const bindingPath = path.resolve(
__dirname, 'build', common.buildType, 'binding.node');

if (!fs.existsSync(bindingPath))
common.skip('binding not built yet');

const binding = require(bindingPath);

if (process.argv[2] === 'child') {
const signo = +process.argv[3];
const reset = process.argv[4] === 'reset';
const count = +process.argv[5];

binding.registerSignalHandler(signo, reset);
for (let i = 0; i < count; i++)
process.kill(process.pid, signo);
return;
}

for (const raiseSignal of [ 'SIGABRT', 'SIGSEGV' ]) {
const signo = signals[raiseSignal];
for (const { reset, count, stderr, code, signal } of [
{ reset: true, count: 1, stderr: [signo], code: 0, signal: null },
{ reset: true, count: 2, stderr: [signo], code: null, signal: raiseSignal },
{ reset: false, count: 1, stderr: [signo], code: 0, signal: null },
{ reset: false, count: 2, stderr: [signo, signo], code: 0, signal: null }
]) {
// We do not want to generate core files when running this test as an
// addon test. We require this file as an abort test as well, though,
// with ALLOW_CRASHES set.
if (signal !== null && !process.env.ALLOW_CRASHES)
continue;
// reset_handler does not work with SIGSEGV.
if (reset && signo === signals.SIGSEGV)
continue;

const args = [__filename, 'child', signo, reset ? 'reset' : '', count];
console.log(`Running: node ${args.join(' ')}`);
const result = spawnSync(
process.execPath, args, { stdio: ['inherit', 'pipe', 'inherit'] });
assert.strictEqual(result.status, code);
assert.strictEqual(result.signal, signal);
assert.deepStrictEqual([...result.stdout], stderr);
}
}

0 comments on commit 039cfdc

Please sign in to comment.