1'use strict'; 2 3const common = require('../common'); 4const assert = require('assert'); 5const { spawn } = require('child_process'); 6const fixtures = require('../common/fixtures'); 7 8const aliveScript = fixtures.path('child-process-stay-alive-forever.js'); 9{ 10 // Verify that passing an AbortSignal works 11 const controller = new AbortController(); 12 const { signal } = controller; 13 14 const cp = spawn(process.execPath, [aliveScript], { 15 signal, 16 }); 17 18 cp.on('exit', common.mustCall((code, killSignal) => { 19 assert.strictEqual(code, null); 20 assert.strictEqual(killSignal, 'SIGTERM'); 21 })); 22 23 cp.on('error', common.mustCall((e) => { 24 assert.strictEqual(e.name, 'AbortError'); 25 })); 26 27 controller.abort(); 28} 29 30{ 31 // Verify that passing an AbortSignal with custom abort error works 32 const controller = new AbortController(); 33 const { signal } = controller; 34 const cp = spawn(process.execPath, [aliveScript], { 35 signal, 36 }); 37 38 cp.on('exit', common.mustCall((code, killSignal) => { 39 assert.strictEqual(code, null); 40 assert.strictEqual(killSignal, 'SIGTERM'); 41 })); 42 43 cp.on('error', common.mustCall((e) => { 44 assert.strictEqual(e.name, 'AbortError'); 45 assert.strictEqual(e.cause.name, 'Error'); 46 assert.strictEqual(e.cause.message, 'boom'); 47 })); 48 49 controller.abort(new Error('boom')); 50} 51 52{ 53 const controller = new AbortController(); 54 const { signal } = controller; 55 const cp = spawn(process.execPath, [aliveScript], { 56 signal, 57 }); 58 59 cp.on('exit', common.mustCall((code, killSignal) => { 60 assert.strictEqual(code, null); 61 assert.strictEqual(killSignal, 'SIGTERM'); 62 })); 63 64 cp.on('error', common.mustCall((e) => { 65 assert.strictEqual(e.name, 'AbortError'); 66 assert.strictEqual(e.cause, 'boom'); 67 })); 68 69 controller.abort('boom'); 70} 71 72{ 73 // Verify that passing an already-aborted signal works. 74 const signal = AbortSignal.abort(); 75 76 const cp = spawn(process.execPath, [aliveScript], { 77 signal, 78 }); 79 cp.on('exit', common.mustCall((code, killSignal) => { 80 assert.strictEqual(code, null); 81 assert.strictEqual(killSignal, 'SIGTERM'); 82 })); 83 84 cp.on('error', common.mustCall((e) => { 85 assert.strictEqual(e.name, 'AbortError'); 86 })); 87} 88 89{ 90 // Verify that passing an already-aborted signal with custom abort error 91 // works. 92 const signal = AbortSignal.abort(new Error('boom')); 93 const cp = spawn(process.execPath, [aliveScript], { 94 signal, 95 }); 96 cp.on('exit', common.mustCall((code, killSignal) => { 97 assert.strictEqual(code, null); 98 assert.strictEqual(killSignal, 'SIGTERM'); 99 })); 100 101 cp.on('error', common.mustCall((e) => { 102 assert.strictEqual(e.name, 'AbortError'); 103 assert.strictEqual(e.cause.name, 'Error'); 104 assert.strictEqual(e.cause.message, 'boom'); 105 })); 106} 107 108{ 109 const signal = AbortSignal.abort('boom'); 110 const cp = spawn(process.execPath, [aliveScript], { 111 signal, 112 }); 113 cp.on('exit', common.mustCall((code, killSignal) => { 114 assert.strictEqual(code, null); 115 assert.strictEqual(killSignal, 'SIGTERM'); 116 })); 117 118 cp.on('error', common.mustCall((e) => { 119 assert.strictEqual(e.name, 'AbortError'); 120 assert.strictEqual(e.cause, 'boom'); 121 })); 122} 123 124{ 125 // Verify that waiting a bit and closing works 126 const controller = new AbortController(); 127 const { signal } = controller; 128 129 const cp = spawn(process.execPath, [aliveScript], { 130 signal, 131 }); 132 133 cp.on('exit', common.mustCall((code, killSignal) => { 134 assert.strictEqual(code, null); 135 assert.strictEqual(killSignal, 'SIGTERM'); 136 })); 137 138 cp.on('error', common.mustCall((e) => { 139 assert.strictEqual(e.name, 'AbortError'); 140 })); 141 142 setTimeout(() => controller.abort(), 1); 143} 144 145{ 146 // Test passing a different killSignal 147 const controller = new AbortController(); 148 const { signal } = controller; 149 150 const cp = spawn(process.execPath, [aliveScript], { 151 signal, 152 killSignal: 'SIGKILL', 153 }); 154 155 cp.on('exit', common.mustCall((code, killSignal) => { 156 assert.strictEqual(code, null); 157 assert.strictEqual(killSignal, 'SIGKILL'); 158 })); 159 160 cp.on('error', common.mustCall((e) => { 161 assert.strictEqual(e.name, 'AbortError'); 162 })); 163 164 setTimeout(() => controller.abort(), 1); 165} 166 167{ 168 // Test aborting a cp before close but after exit 169 const controller = new AbortController(); 170 const { signal } = controller; 171 172 const cp = spawn(process.execPath, [aliveScript], { 173 signal, 174 }); 175 176 cp.on('exit', common.mustCall(() => { 177 controller.abort(); 178 })); 179 180 cp.on('error', common.mustNotCall()); 181 182 setTimeout(() => cp.kill(), 1); 183} 184