11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ciconst common = require('../common'); 31cb0ef41Sopenharmony_ci 41cb0ef41Sopenharmony_ciif (common.isWindows) 51cb0ef41Sopenharmony_ci common.skip('no signals in Windows'); 61cb0ef41Sopenharmony_ciif (!common.isMainThread) 71cb0ef41Sopenharmony_ci common.skip('No signal handling available in Workers'); 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ciconst assert = require('assert'); 101cb0ef41Sopenharmony_ciconst initHooks = require('./init-hooks'); 111cb0ef41Sopenharmony_ciconst { checkInvocations } = require('./hook-checks'); 121cb0ef41Sopenharmony_ciconst exec = require('child_process').exec; 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ciconst hooks = initHooks(); 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_cihooks.enable(); 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ci// Keep the event loop open so process doesn't exit before receiving signals. 191cb0ef41Sopenharmony_ciconst interval = setInterval(() => {}, 9999); 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ciprocess.on('SIGUSR2', common.mustCall(onsigusr2, 2)); 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ciconst as = hooks.activitiesOfTypes('SIGNALWRAP'); 241cb0ef41Sopenharmony_ciassert.strictEqual(as.length, 1); 251cb0ef41Sopenharmony_ciconst signal1 = as[0]; 261cb0ef41Sopenharmony_ciassert.strictEqual(signal1.type, 'SIGNALWRAP'); 271cb0ef41Sopenharmony_ciassert.strictEqual(typeof signal1.uid, 'number'); 281cb0ef41Sopenharmony_ciassert.strictEqual(typeof signal1.triggerAsyncId, 'number'); 291cb0ef41Sopenharmony_cicheckInvocations(signal1, { init: 1 }, 'when SIGUSR2 handler is set up'); 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_cilet count = 0; 321cb0ef41Sopenharmony_ciexec(`kill -USR2 ${process.pid}`); 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_cilet signal2; 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_cifunction onsigusr2() { 371cb0ef41Sopenharmony_ci count++; 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci if (count === 1) { 401cb0ef41Sopenharmony_ci // first invocation 411cb0ef41Sopenharmony_ci checkInvocations( 421cb0ef41Sopenharmony_ci signal1, { init: 1, before: 1 }, 431cb0ef41Sopenharmony_ci ' signal1: when first SIGUSR2 handler is called for the first time'); 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci // Trigger same signal handler again 461cb0ef41Sopenharmony_ci exec(`kill -USR2 ${process.pid}`); 471cb0ef41Sopenharmony_ci } else { 481cb0ef41Sopenharmony_ci // second invocation 491cb0ef41Sopenharmony_ci checkInvocations( 501cb0ef41Sopenharmony_ci signal1, { init: 1, before: 2, after: 1 }, 511cb0ef41Sopenharmony_ci 'signal1: when first SIGUSR2 handler is called for the second time'); 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci // Install another signal handler 541cb0ef41Sopenharmony_ci process.removeAllListeners('SIGUSR2'); 551cb0ef41Sopenharmony_ci process.on('SIGUSR2', common.mustCall(onsigusr2Again)); 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci const as = hooks.activitiesOfTypes('SIGNALWRAP'); 581cb0ef41Sopenharmony_ci // The isTTY checks are needed to allow test to work whether run with 591cb0ef41Sopenharmony_ci // test.py or directly with the node executable. The third signal event 601cb0ef41Sopenharmony_ci // listener is the SIGWINCH handler that node installs when it thinks 611cb0ef41Sopenharmony_ci // process.stdout is a tty. 621cb0ef41Sopenharmony_ci const expectedLen = 2 + (!!process.stdout.isTTY || !!process.stderr.isTTY); 631cb0ef41Sopenharmony_ci assert.strictEqual(as.length, expectedLen); 641cb0ef41Sopenharmony_ci signal2 = as[expectedLen - 1]; // Last item in the array. 651cb0ef41Sopenharmony_ci assert.strictEqual(signal2.type, 'SIGNALWRAP'); 661cb0ef41Sopenharmony_ci assert.strictEqual(typeof signal2.uid, 'number'); 671cb0ef41Sopenharmony_ci assert.strictEqual(typeof signal2.triggerAsyncId, 'number'); 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci checkInvocations( 701cb0ef41Sopenharmony_ci signal1, { init: 1, before: 2, after: 1 }, 711cb0ef41Sopenharmony_ci 'signal1: when second SIGUSR2 handler is set up'); 721cb0ef41Sopenharmony_ci checkInvocations( 731cb0ef41Sopenharmony_ci signal2, { init: 1 }, 741cb0ef41Sopenharmony_ci 'signal2: when second SIGUSR2 handler is setup'); 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci exec(`kill -USR2 ${process.pid}`); 771cb0ef41Sopenharmony_ci } 781cb0ef41Sopenharmony_ci} 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_cifunction onsigusr2Again() { 811cb0ef41Sopenharmony_ci clearInterval(interval); 821cb0ef41Sopenharmony_ci setImmediate(() => { 831cb0ef41Sopenharmony_ci checkInvocations( 841cb0ef41Sopenharmony_ci signal1, { init: 1, before: 2, after: 2, destroy: 1 }, 851cb0ef41Sopenharmony_ci 'signal1: when second SIGUSR2 handler is called'); 861cb0ef41Sopenharmony_ci checkInvocations( 871cb0ef41Sopenharmony_ci signal2, { init: 1, before: 1 }, 881cb0ef41Sopenharmony_ci 'signal2: when second SIGUSR2 handler is called'); 891cb0ef41Sopenharmony_ci }); 901cb0ef41Sopenharmony_ci} 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ciprocess.on('exit', onexit); 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_cifunction onexit() { 951cb0ef41Sopenharmony_ci hooks.disable(); 961cb0ef41Sopenharmony_ci hooks.sanityCheck('SIGNALWRAP'); 971cb0ef41Sopenharmony_ci checkInvocations( 981cb0ef41Sopenharmony_ci signal1, { init: 1, before: 2, after: 2, destroy: 1 }, 991cb0ef41Sopenharmony_ci 'signal1: when second SIGUSR2 process exits'); 1001cb0ef41Sopenharmony_ci // Second signal not destroyed yet since its event listener is still active 1011cb0ef41Sopenharmony_ci checkInvocations( 1021cb0ef41Sopenharmony_ci signal2, { init: 1, before: 1, after: 1 }, 1031cb0ef41Sopenharmony_ci 'signal2: when second SIGUSR2 process exits'); 1041cb0ef41Sopenharmony_ci} 105