test: add addon tests for RegisterSignalHandler()
Ensure coverage for the different combinations of arguments. PR-URL: https://github.com/nodejs/node/pull/27775 Refs: https://github.com/nodejs/node/pull/27246 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
This commit is contained in:
parent
89b32378c8
commit
039cfdc838
7
test/abort/test-addon-register-signal-handler.js
Normal file
7
test/abort/test-addon-register-signal-handler.js
Normal file
@ -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
test/addons/register-signal-handler/binding.cc
Normal file
36
test/addons/register-signal-handler/binding.cc
Normal file
@ -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
test/addons/register-signal-handler/binding.gyp
Normal file
9
test/addons/register-signal-handler/binding.gyp
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'binding',
|
||||
'sources': [ 'binding.cc' ],
|
||||
'includes': ['../common.gypi'],
|
||||
}
|
||||
]
|
||||
}
|
56
test/addons/register-signal-handler/test.js
Normal file
56
test/addons/register-signal-handler/test.js
Normal file
@ -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);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user