Skip to content

Commit 039cfdc

Browse files
committed
test: add addon tests for RegisterSignalHandler()
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]>
1 parent 89b3237 commit 039cfdc

File tree

4 files changed

+108
-0
lines changed

4 files changed

+108
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
require('../common');
3+
4+
// This is a sibling test to test/addons/register-signal-handler/
5+
6+
process.env.ALLOW_CRASHES = true;
7+
require('../addons/register-signal-handler/test');
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#ifndef _WIN32
2+
#include <node.h>
3+
#include <v8.h>
4+
#include <uv.h>
5+
#include <assert.h>
6+
#include <unistd.h>
7+
8+
using v8::Boolean;
9+
using v8::FunctionCallbackInfo;
10+
using v8::Int32;
11+
using v8::Value;
12+
13+
void Handler(int signo, siginfo_t* siginfo, void* ucontext) {
14+
char signo_char = signo;
15+
int written;
16+
do {
17+
written = write(1, &signo_char, 1); // write() is signal-safe.
18+
} while (written == -1 && errno == EINTR);
19+
assert(written == 1);
20+
}
21+
22+
void RegisterSignalHandler(const FunctionCallbackInfo<Value>& args) {
23+
assert(args[0]->IsInt32());
24+
assert(args[1]->IsBoolean());
25+
26+
int32_t signo = args[0].As<Int32>()->Value();
27+
bool reset_handler = args[1].As<Boolean>()->Value();
28+
29+
node::RegisterSignalHandler(signo, Handler, reset_handler);
30+
}
31+
32+
NODE_MODULE_INIT() {
33+
NODE_SET_METHOD(exports, "registerSignalHandler", RegisterSignalHandler);
34+
}
35+
36+
#endif // _WIN32
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
'targets': [
3+
{
4+
'target_name': 'binding',
5+
'sources': [ 'binding.cc' ],
6+
'includes': ['../common.gypi'],
7+
}
8+
]
9+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
'use strict';
2+
const common = require('../../common');
3+
if (common.isWindows)
4+
common.skip('No RegisterSignalHandler() on Windows');
5+
6+
const assert = require('assert');
7+
const fs = require('fs');
8+
const path = require('path');
9+
const { signals } = require('os').constants;
10+
const { spawnSync } = require('child_process');
11+
12+
const bindingPath = path.resolve(
13+
__dirname, 'build', common.buildType, 'binding.node');
14+
15+
if (!fs.existsSync(bindingPath))
16+
common.skip('binding not built yet');
17+
18+
const binding = require(bindingPath);
19+
20+
if (process.argv[2] === 'child') {
21+
const signo = +process.argv[3];
22+
const reset = process.argv[4] === 'reset';
23+
const count = +process.argv[5];
24+
25+
binding.registerSignalHandler(signo, reset);
26+
for (let i = 0; i < count; i++)
27+
process.kill(process.pid, signo);
28+
return;
29+
}
30+
31+
for (const raiseSignal of [ 'SIGABRT', 'SIGSEGV' ]) {
32+
const signo = signals[raiseSignal];
33+
for (const { reset, count, stderr, code, signal } of [
34+
{ reset: true, count: 1, stderr: [signo], code: 0, signal: null },
35+
{ reset: true, count: 2, stderr: [signo], code: null, signal: raiseSignal },
36+
{ reset: false, count: 1, stderr: [signo], code: 0, signal: null },
37+
{ reset: false, count: 2, stderr: [signo, signo], code: 0, signal: null }
38+
]) {
39+
// We do not want to generate core files when running this test as an
40+
// addon test. We require this file as an abort test as well, though,
41+
// with ALLOW_CRASHES set.
42+
if (signal !== null && !process.env.ALLOW_CRASHES)
43+
continue;
44+
// reset_handler does not work with SIGSEGV.
45+
if (reset && signo === signals.SIGSEGV)
46+
continue;
47+
48+
const args = [__filename, 'child', signo, reset ? 'reset' : '', count];
49+
console.log(`Running: node ${args.join(' ')}`);
50+
const result = spawnSync(
51+
process.execPath, args, { stdio: ['inherit', 'pipe', 'inherit'] });
52+
assert.strictEqual(result.status, code);
53+
assert.strictEqual(result.signal, signal);
54+
assert.deepStrictEqual([...result.stdout], stderr);
55+
}
56+
}

0 commit comments

Comments
 (0)