test: fix flaky test-watch-mode-kill-signal-* · nodejs/node@3139834
@@ -27,20 +27,40 @@ const child = spawn(
2727);
28282929let stdout = '';
30+let firstGrandchildPid;
3031child.stdout.on('data', (data) => {
31-stdout += `${data}`;
32-if (/__(SIGINT|SIGTERM) received__/.test(stdout)) {
32+const dataStr = data.toString();
33+console.log(`[STDOUT] ${dataStr}`);
34+stdout += `${dataStr}`;
35+const match = dataStr.match(/__(SIGINT|SIGTERM) received__ (\d+)/);
36+if (match && match[2] === firstGrandchildPid) {
37+console.log(`[PARENT] Sending kill signal to watcher process: ${child.pid}`);
3338child.kill();
3439}
3540});
364142+// After the write triggers a restart of the grandchild, the newly spawned second
43+// grandchild can post another 'script ready' message before the stdout from the first
44+// grandchild is relayed by the watcher and processed by this parent process to kill
45+// the watcher. If we write again and trigger another restart, we can
46+// end up in an infinite loop and never receive the stdout of the grandchildren in time.
47+// Only write once to verify the first grandchild process receives the expected signal.
48+// We don't care about the subsequent grandchild processes.
3749child.on('message', (msg) => {
38-if (msg === 'script ready') {
39-writeFileSync(indexPath, indexContents);
50+console.log(`[MESSAGE]`, msg);
51+if (!firstGrandchildPid && typeof msg === 'string') {
52+const match = msg.match(/script ready (\d+)/);
53+if (match) {
54+firstGrandchildPid = match[1]; // This is the first grandchild
55+writeFileSync(indexPath, indexContents);
56+}
4057}
4158});
42594360await once(child, 'exit');
446145-assert.match(stdout, /__SIGINT received__/);
46-assert.doesNotMatch(stdout, /__SIGTERM received__/);
62+// The second grandchild, if there is one, could receive SIGTERM if it's killed as a
63+// consequence of the parent being killed in this process instead of being killed by the
64+// parent for file changes. Here we only care about the first grandchild.
65+assert.match(stdout, new RegExp(`__SIGINT received__ ${firstGrandchildPid}`));
66+assert.doesNotMatch(stdout, new RegExp(`__SIGTERM received__ ${firstGrandchildPid}`));