Skip to content

Commit 4f2eaf0

Browse files
committed
handle result and process individually and explicitly
1 parent abf3603 commit 4f2eaf0

File tree

1 file changed

+60
-36
lines changed

1 file changed

+60
-36
lines changed

packages/core/src/test/shared/utilities/processUtils.test.ts

Lines changed: 60 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ import * as os from 'os'
88
import * as path from 'path'
99
import * as sinon from 'sinon'
1010
import { makeTemporaryToolkitFolder, tryRemoveFolder } from '../../../shared/filesystemUtilities'
11-
import { ChildProcess, ChildProcessTracker, eof, ProcessStats } from '../../../shared/utilities/processUtils'
11+
import {
12+
ChildProcess,
13+
ChildProcessResult,
14+
ChildProcessTracker,
15+
eof,
16+
ProcessStats,
17+
} from '../../../shared/utilities/processUtils'
1218
import { sleep } from '../../../shared/utilities/timeoutUtils'
1319
import { Timeout, waitUntil } from '../../../shared/utilities/timeoutUtils'
1420
import { fs } from '../../../shared'
@@ -356,21 +362,24 @@ describe('ChildProcess', async function () {
356362
}
357363
})
358364

365+
interface RunningProcess {
366+
childProcess: ChildProcess
367+
result: Promise<ChildProcessResult>
368+
}
369+
359370
function getSleepCmd() {
360371
return isWin() ? 'timeout' : 'sleep'
361372
}
362373

363-
// ChildProcess.stop is non-async and doesn't wait for the process to be stopped.
364-
async function stopAndWait(cp: ChildProcess, clock: FakeTimers.InstalledClock) {
365-
cp.stop(true)
366-
await clock.tickAsync(ChildProcess.stopTimeout * 2)
367-
assert.ok(cp.stopped, `Failed to stop process with id: ${cp.pid()}`)
374+
async function stopAndWait(runningProcess: RunningProcess): Promise<void> {
375+
runningProcess.childProcess.stop(true)
376+
await runningProcess.result
368377
}
369378

370-
function startSleepProcess(timeout: number = 90) {
379+
function startSleepProcess(timeout: number = 90): RunningProcess {
371380
const childProcess = new ChildProcess(getSleepCmd(), [timeout.toString()])
372-
childProcess.run().catch(() => assert.fail('sleep command threw an error'))
373-
return childProcess
381+
const result = childProcess.run().catch(() => assert.fail('sleep command threw an error'))
382+
return { childProcess, result }
374383
}
375384

376385
describe('ChildProcessTracker', function () {
@@ -395,41 +404,51 @@ describe('ChildProcessTracker', function () {
395404

396405
it(`removes stopped processes every ${ChildProcessTracker.pollingInterval / 1000} seconds`, async function () {
397406
// Start a 'sleep' command, check it only removes after we stop it.
398-
const childProcess = startSleepProcess()
399-
tracker.add(childProcess)
400-
assert.strictEqual(tracker.has(childProcess), true, 'failed to add sleep command')
407+
const runningProcess = startSleepProcess()
408+
tracker.add(runningProcess.childProcess)
409+
assert.strictEqual(tracker.has(runningProcess.childProcess), true, 'failed to add sleep command')
401410

402411
await clock.tickAsync(ChildProcessTracker.pollingInterval)
403-
assert.strictEqual(tracker.has(childProcess), true, 'process was mistakenly removed')
404-
await stopAndWait(childProcess, clock)
412+
assert.strictEqual(tracker.has(runningProcess.childProcess), true, 'process was mistakenly removed')
413+
await stopAndWait(runningProcess)
405414

406415
await clock.tickAsync(ChildProcessTracker.pollingInterval)
407-
assert.strictEqual(tracker.has(childProcess), false, 'process was not removed after stopping')
416+
assert.strictEqual(tracker.has(runningProcess.childProcess), false, 'process was not removed after stopping')
408417
})
409418
for (const _ of Array.from({ length: 1000 })) {
410419
it('multiple processes from same command are tracked seperately', async function () {
411-
const childProcess1 = startSleepProcess()
412-
const childProcess2 = startSleepProcess()
413-
tracker.add(childProcess1)
414-
tracker.add(childProcess2)
420+
const runningProcess1 = startSleepProcess()
421+
const runningProcess2 = startSleepProcess()
422+
tracker.add(runningProcess1.childProcess)
423+
tracker.add(runningProcess2.childProcess)
415424

416-
assert.strictEqual(tracker.has(childProcess1), true, 'Missing first process')
417-
assert.strictEqual(tracker.has(childProcess2), true, 'Missing second process')
425+
assert.strictEqual(tracker.has(runningProcess1.childProcess), true, 'Missing first process')
426+
assert.strictEqual(tracker.has(runningProcess2.childProcess), true, 'Missing second process')
418427

419-
await stopAndWait(childProcess1, clock)
428+
await stopAndWait(runningProcess1)
420429
await clock.tickAsync(ChildProcessTracker.pollingInterval)
421-
if (tracker.has(childProcess1)) {
422-
console.log('process: %O', childProcess1)
423-
console.log('tracker: %O', tracker)
424-
}
425-
assert.strictEqual(tracker.has(childProcess2), true, 'second process was mistakenly removed')
426-
assert.strictEqual(tracker.has(childProcess1), false, 'first process was not removed after stopping it')
430+
assert.strictEqual(tracker.has(runningProcess2.childProcess), true, 'second process was mistakenly removed')
431+
assert.strictEqual(
432+
tracker.has(runningProcess1.childProcess),
433+
false,
434+
'first process was not removed after stopping it'
435+
)
436+
437+
await stopAndWait(runningProcess2)
438+
await clock.tickAsync(ChildProcessTracker.pollingInterval)
439+
assert.strictEqual(
440+
tracker.has(runningProcess2.childProcess),
441+
false,
442+
'second process was not removed after stopping it'
443+
)
444+
445+
assert.strictEqual(tracker.size(), 0, 'expected tracker to be empty')
427446
})
428447
}
429448

430449
it('logs a warning message when system usage exceeds threshold', async function () {
431-
const childProcess = startSleepProcess()
432-
tracker.add(childProcess)
450+
const runningProcess = startSleepProcess()
451+
tracker.add(runningProcess.childProcess)
433452

434453
const highCpu: ProcessStats = {
435454
cpu: ChildProcessTracker.thresholds.cpu + 1,
@@ -448,24 +467,27 @@ describe('ChildProcessTracker', function () {
448467
usageMock.resolves(highMemory)
449468
await clock.tickAsync(ChildProcessTracker.pollingInterval)
450469
assertLogsContain('exceeded memory threshold', false, 'warn')
470+
471+
await stopAndWait(runningProcess)
451472
})
452473

453474
it('includes pid in logs', async function () {
454-
const childProcess = startSleepProcess()
455-
tracker.add(childProcess)
475+
const runningProcess = startSleepProcess()
476+
tracker.add(runningProcess.childProcess)
456477

457478
usageMock.resolves({
458479
cpu: ChildProcessTracker.thresholds.cpu + 1,
459480
memory: 0,
460481
})
461482

462483
await clock.tickAsync(ChildProcessTracker.pollingInterval)
463-
assertLogsContain(childProcess.pid().toString(), false, 'warn')
484+
assertLogsContain(runningProcess.childProcess.pid().toString(), false, 'warn')
485+
486+
await stopAndWait(runningProcess)
464487
})
465488

466489
it('does not log for processes within threshold', async function () {
467-
const childProcess = new ChildProcess(getSleepCmd(), ['90'])
468-
childProcess.run().catch(() => assert.fail('sleep command threw an error'))
490+
const runningProcess = startSleepProcess()
469491

470492
usageMock.resolves({
471493
cpu: ChildProcessTracker.thresholds.cpu - 1,
@@ -474,6 +496,8 @@ describe('ChildProcessTracker', function () {
474496

475497
await clock.tickAsync(ChildProcessTracker.pollingInterval)
476498

477-
assert.throws(() => assertLogsContain(childProcess.pid().toString(), false, 'warn'))
499+
assert.throws(() => assertLogsContain(runningProcess.childProcess.pid().toString(), false, 'warn'))
500+
501+
await stopAndWait(runningProcess)
478502
})
479503
})

0 commit comments

Comments
 (0)