Skip to content

Commit

Permalink
test_runner: fix watch mode race condition
Browse files Browse the repository at this point in the history
PR-URL: #52954
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
  • Loading branch information
MoLow authored and marco-ippolito committed Jun 17, 2024
1 parent 84da6a5 commit 293179c
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 7 deletions.
18 changes: 12 additions & 6 deletions lib/internal/test_runner/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ const { createInterface } = require('readline');
const { deserializeError } = require('internal/error_serdes');
const { Buffer } = require('buffer');
const { FilesWatcher } = require('internal/watch_mode/files_watcher');
const { queueMicrotask } = require('internal/process/task_queues');
const console = require('internal/console/global');
const {
codes: {
Expand Down Expand Up @@ -420,10 +419,16 @@ function runTestFile(path, filesWatcher, opts) {
if (watchMode) {
filesWatcher.runningProcesses.delete(path);
filesWatcher.runningSubtests.delete(path);
if (filesWatcher.runningSubtests.size === 0) {
opts.root.reporter[kEmitMessage]('test:watch:drained');
queueMicrotask(() => opts.root.postRun());
}
(async () => {
try {
await subTestEnded;
} finally {
if (filesWatcher.runningSubtests.size === 0) {
opts.root.reporter[kEmitMessage]('test:watch:drained');
opts.root.postRun();
}
}
})();
}

if (code !== 0 || signal !== null) {
Expand All @@ -442,7 +447,8 @@ function runTestFile(path, filesWatcher, opts) {
throw err;
}
});
return subtest.start();
const subTestEnded = subtest.start();
return subTestEnded;
}

function watchFiles(testFiles, opts) {
Expand Down
15 changes: 14 additions & 1 deletion test/parallel/test-runner-watch-mode.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Flags: --expose-internals
import * as common from '../common/index.mjs';
import { describe, it } from 'node:test';
import assert from 'node:assert';
import { spawn } from 'node:child_process';
import { writeFileSync } from 'node:fs';
import util from 'internal/util';
Expand Down Expand Up @@ -36,21 +37,33 @@ async function testWatch({ fileToUpdate, file }) {
['--watch', '--test', file ? fixturePaths[file] : undefined].filter(Boolean),
{ encoding: 'utf8', stdio: 'pipe', cwd: tmpdir.path });
let stdout = '';
let currentRun = '';
const runs = [];

child.stdout.on('data', (data) => {
stdout += data.toString();
const testRuns = stdout.match(/ - test has ran/g);
currentRun += data.toString();
const testRuns = stdout.match(/# duration_ms\s\d+/g);
if (testRuns?.length >= 1) ran1.resolve();
if (testRuns?.length >= 2) ran2.resolve();
});

await ran1.promise;
runs.push(currentRun);
currentRun = '';
const content = fixtureContent[fileToUpdate];
const path = fixturePaths[fileToUpdate];
const interval = setInterval(() => writeFileSync(path, content), common.platformTimeout(1000));
await ran2.promise;
runs.push(currentRun);
clearInterval(interval);
child.kill();
for (const run of runs) {
assert.match(run, /# tests 1/);
assert.match(run, /# pass 1/);
assert.match(run, /# fail 0/);
assert.match(run, /# cancelled 0/);
}
}

describe('test runner watch mode', () => {
Expand Down

0 comments on commit 293179c

Please sign in to comment.