11cb0ef41Sopenharmony_ciimport * as common from '../common/index.mjs'; 21cb0ef41Sopenharmony_ciimport * as fixtures from '../common/fixtures.mjs'; 31cb0ef41Sopenharmony_ciimport assert from 'node:assert'; 41cb0ef41Sopenharmony_ciimport { describe, it } from 'node:test'; 51cb0ef41Sopenharmony_ciimport { writeFileSync, readFileSync } from 'node:fs'; 61cb0ef41Sopenharmony_ciimport { setTimeout } from 'node:timers/promises'; 71cb0ef41Sopenharmony_ciimport { NodeInstance } from '../common/inspector-helper.js'; 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ciif (common.isIBMi) 111cb0ef41Sopenharmony_ci common.skip('IBMi does not support `fs.watch()`'); 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cicommon.skipIfInspectorDisabled(); 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_cilet gettingDebuggedPid = false; 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ciasync function getDebuggedPid(instance, waitForLog = true) { 181cb0ef41Sopenharmony_ci gettingDebuggedPid = true; 191cb0ef41Sopenharmony_ci const session = await instance.connectInspectorSession(); 201cb0ef41Sopenharmony_ci await session.send({ method: 'Runtime.enable' }); 211cb0ef41Sopenharmony_ci if (waitForLog) { 221cb0ef41Sopenharmony_ci await session.waitForConsoleOutput('log', 'safe to debug now'); 231cb0ef41Sopenharmony_ci } 241cb0ef41Sopenharmony_ci const { value: innerPid } = (await session.send({ 251cb0ef41Sopenharmony_ci 'method': 'Runtime.evaluate', 'params': { 'expression': 'process.pid' } 261cb0ef41Sopenharmony_ci })).result; 271cb0ef41Sopenharmony_ci session.disconnect(); 281cb0ef41Sopenharmony_ci gettingDebuggedPid = false; 291cb0ef41Sopenharmony_ci return innerPid; 301cb0ef41Sopenharmony_ci} 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_cifunction restart(file) { 331cb0ef41Sopenharmony_ci writeFileSync(file, readFileSync(file)); 341cb0ef41Sopenharmony_ci const interval = setInterval(() => { 351cb0ef41Sopenharmony_ci if (!gettingDebuggedPid) { 361cb0ef41Sopenharmony_ci writeFileSync(file, readFileSync(file)); 371cb0ef41Sopenharmony_ci } 381cb0ef41Sopenharmony_ci }, common.platformTimeout(500)); 391cb0ef41Sopenharmony_ci return () => clearInterval(interval); 401cb0ef41Sopenharmony_ci} 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_cidescribe('watch mode - inspect', () => { 431cb0ef41Sopenharmony_ci it('should start debugger on inner process', async () => { 441cb0ef41Sopenharmony_ci const file = fixtures.path('watch-mode/inspect.js'); 451cb0ef41Sopenharmony_ci const instance = new NodeInstance(['--inspect=0', '--watch'], undefined, file); 461cb0ef41Sopenharmony_ci let stderr = ''; 471cb0ef41Sopenharmony_ci const stdout = []; 481cb0ef41Sopenharmony_ci instance.on('stderr', (data) => { stderr += data; }); 491cb0ef41Sopenharmony_ci instance.on('stdout', (data) => { stdout.push(data); }); 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci const pids = [instance.pid]; 521cb0ef41Sopenharmony_ci pids.push(await getDebuggedPid(instance)); 531cb0ef41Sopenharmony_ci instance.resetPort(); 541cb0ef41Sopenharmony_ci const stopRestarting = restart(file); 551cb0ef41Sopenharmony_ci pids.push(await getDebuggedPid(instance)); 561cb0ef41Sopenharmony_ci stopRestarting(); 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci await setTimeout(common.platformTimeout(500)); 591cb0ef41Sopenharmony_ci await instance.kill(); 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci // There should be a process per restart and one per parent process. 621cb0ef41Sopenharmony_ci // Message about Debugger should appear once per restart. 631cb0ef41Sopenharmony_ci // On some systems restart can happen multiple times. 641cb0ef41Sopenharmony_ci const restarts = stdout.filter((line) => line === 'safe to debug now').length; 651cb0ef41Sopenharmony_ci assert.ok(stderr.match(/Debugger listening on ws:\/\//g).length >= restarts); 661cb0ef41Sopenharmony_ci assert.ok(new Set(pids).size >= restarts + 1); 671cb0ef41Sopenharmony_ci }); 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci it('should prevent attaching debugger with SIGUSR1 to outer process', { skip: common.isWindows }, async () => { 701cb0ef41Sopenharmony_ci const file = fixtures.path('watch-mode/inspect_with_signal.js'); 711cb0ef41Sopenharmony_ci const instance = new NodeInstance(['--inspect-port=0', '--watch'], undefined, file); 721cb0ef41Sopenharmony_ci let stderr = ''; 731cb0ef41Sopenharmony_ci instance.on('stderr', (data) => { stderr += data; }); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci const loggedPid = await new Promise((resolve) => { 761cb0ef41Sopenharmony_ci instance.on('stdout', (data) => { 771cb0ef41Sopenharmony_ci const matches = data.match(/pid is (\d+)/); 781cb0ef41Sopenharmony_ci if (matches) resolve(Number(matches[1])); 791cb0ef41Sopenharmony_ci }); 801cb0ef41Sopenharmony_ci }); 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci process.kill(instance.pid, 'SIGUSR1'); 841cb0ef41Sopenharmony_ci process.kill(loggedPid, 'SIGUSR1'); 851cb0ef41Sopenharmony_ci const debuggedPid = await getDebuggedPid(instance, false); 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci await instance.kill(); 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci // Message about Debugger should only appear once in inner process. 901cb0ef41Sopenharmony_ci assert.strictEqual(stderr.match(/Debugger listening on ws:\/\//g).length, 1); 911cb0ef41Sopenharmony_ci assert.strictEqual(loggedPid, debuggedPid); 921cb0ef41Sopenharmony_ci }); 931cb0ef41Sopenharmony_ci}); 94