Skip to content

Commit 2b61da2

Browse files
alexdimaCopilot
andcommitted
ci: run all unit test files from last to first (temporary, do not merge)
Order stress test for #342237: loads the test files in their usual order, then runs them from last to first, in one process and in parallel workers, on Linux, macOS and Windows. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 1e83ccf commit 2b61da2

8 files changed

Lines changed: 133 additions & 22 deletions

File tree

‎.github/workflows/pr-darwin-test.yml‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,17 +149,21 @@ jobs:
149149
sleep 5
150150
done
151151
152+
# TEMPORARY (order stress test): run the test files from last to first, in one process or in parallel workers
152153
- name: 🧪 Run unit tests (Electron)
153154
if: ${{ inputs.electron_tests && inputs.unit_tests }}
154-
timeout-minutes: 15
155-
run: ./scripts/test.sh --tfs "Unit Tests" --workers
155+
timeout-minutes: 30
156+
run: ./scripts/test.sh --tfs "Unit Tests" ${{ contains(inputs.job_name, 'Parallel') && '--workers' || '' }}
156157
env:
158+
VSCODE_TEST_REVERSE_FILES: '1'
157159
VSCODE_SKIP_PRELAUNCH: '1'
158160

159161
- name: 🧪 Run unit tests (node.js)
160-
if: ${{ inputs.electron_tests && inputs.unit_tests }}
161-
timeout-minutes: 15
162-
run: npm run test-node -- --workers
162+
if: ${{ !cancelled() && inputs.electron_tests && inputs.unit_tests }}
163+
timeout-minutes: 30
164+
run: npm run test-node -- ${{ contains(inputs.job_name, 'Parallel') && '--workers' || '' }}
165+
env:
166+
VSCODE_TEST_REVERSE_FILES: '1'
163167

164168
- name: 🧪 Run unit tests (Browser, Webkit)
165169
if: ${{ inputs.browser_tests && inputs.unit_tests }}

‎.github/workflows/pr-linux-test.yml‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -301,18 +301,22 @@ jobs:
301301
sleep 5
302302
done
303303
304+
# TEMPORARY (order stress test): run the test files from last to first, in one process or in parallel workers
304305
- name: 🧪 Run unit tests (Electron)
305306
if: ${{ inputs.electron_tests && inputs.unit_tests }}
306-
timeout-minutes: 15
307-
run: ./scripts/test.sh --tfs "Unit Tests" --workers
307+
timeout-minutes: 30
308+
run: ./scripts/test.sh --tfs "Unit Tests" ${{ contains(inputs.job_name, 'Parallel') && '--workers' || '' }}
308309
env:
310+
VSCODE_TEST_REVERSE_FILES: '1'
309311
DISPLAY: ":10"
310312
VSCODE_SKIP_PRELAUNCH: '1'
311313

312314
- name: 🧪 Run unit tests (node.js)
313-
if: ${{ inputs.electron_tests && inputs.unit_tests }}
314-
timeout-minutes: 15
315-
run: npm run test-node -- --workers
315+
if: ${{ !cancelled() && inputs.electron_tests && inputs.unit_tests }}
316+
timeout-minutes: 30
317+
run: npm run test-node -- ${{ contains(inputs.job_name, 'Parallel') && '--workers' || '' }}
318+
env:
319+
VSCODE_TEST_REVERSE_FILES: '1'
316320

317321
- name: 🧪 Run unit tests (Browser, Chromium)
318322
if: ${{ inputs.browser_tests && inputs.unit_tests }}

‎.github/workflows/pr-win32-test.yml‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,19 +187,23 @@ jobs:
187187
}
188188
}
189189
190+
# TEMPORARY (order stress test): run the test files from last to first, in one process or in parallel workers
190191
- name: 🧪 Run unit tests (Electron)
191192
if: ${{ inputs.electron_tests && inputs.unit_tests }}
192-
timeout-minutes: 15
193+
timeout-minutes: 30
193194
shell: pwsh
194-
run: .\scripts\test.bat --tfs "Unit Tests" --workers
195+
run: .\scripts\test.bat --tfs "Unit Tests" ${{ contains(inputs.job_name, 'Parallel') && '--workers' || '' }}
195196
env:
197+
VSCODE_TEST_REVERSE_FILES: '1'
196198
VSCODE_SKIP_PRELAUNCH: '1'
197199

198200
- name: 🧪 Run unit tests (node.js)
199-
if: ${{ inputs.electron_tests && inputs.unit_tests }}
200-
timeout-minutes: 15
201+
if: ${{ !cancelled() && inputs.electron_tests && inputs.unit_tests }}
202+
timeout-minutes: 30
201203
shell: pwsh
202-
run: npm run test-node -- --workers
204+
run: npm run test-node -- ${{ contains(inputs.job_name, 'Parallel') && '--workers' || '' }}
205+
env:
206+
VSCODE_TEST_REVERSE_FILES: '1'
203207

204208
- name: 🧪 Run unit tests (Browser, Chromium)
205209
if: ${{ inputs.browser_tests && inputs.unit_tests }}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
name: Unit tests from last to first (temporary, do not merge)
2+
3+
# TEMPORARY (order stress test): runs all Electron and node.js unit test files from last to first,
4+
# in one process (Serial) and in parallel worker processes (Parallel), on every platform.
5+
6+
on:
7+
push:
8+
branches:
9+
- agents/tmp-unit-reverse-order
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
linux-serial:
16+
name: Linux
17+
uses: ./.github/workflows/pr-linux-test.yml
18+
with:
19+
job_name: Reverse-Serial
20+
electron_tests: true
21+
integration_tests: false
22+
smoke_tests: false
23+
24+
linux-parallel:
25+
name: Linux
26+
uses: ./.github/workflows/pr-linux-test.yml
27+
with:
28+
job_name: Reverse-Parallel
29+
electron_tests: true
30+
integration_tests: false
31+
smoke_tests: false
32+
33+
macos-serial:
34+
name: macOS
35+
uses: ./.github/workflows/pr-darwin-test.yml
36+
with:
37+
job_name: Reverse-Serial
38+
electron_tests: true
39+
integration_tests: false
40+
smoke_tests: false
41+
42+
macos-parallel:
43+
name: macOS
44+
uses: ./.github/workflows/pr-darwin-test.yml
45+
with:
46+
job_name: Reverse-Parallel
47+
electron_tests: true
48+
integration_tests: false
49+
smoke_tests: false
50+
51+
windows-serial:
52+
name: Windows
53+
uses: ./.github/workflows/pr-win32-test.yml
54+
with:
55+
job_name: Reverse-Serial
56+
electron_tests: true
57+
integration_tests: false
58+
smoke_tests: false
59+
60+
windows-parallel:
61+
name: Windows
62+
uses: ./.github/workflows/pr-win32-test.yml
63+
with:
64+
job_name: Reverse-Parallel
65+
electron_tests: true
66+
integration_tests: false
67+
smoke_tests: false

‎test/unit/electron/index.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,9 @@ app.on('ready', async () => {
351351
}
352352
});
353353

354+
// TEMPORARY (order stress test): proves in the log that the test files run from last to first
355+
ipcMain.on('tmp-order-log', (_, message) => console.log(message));
356+
354357
// We need to provide a basic `ISandboxConfiguration`
355358
// for our preload script to function properly because
356359
// some of our types depend on it (e.g. product.ts).

‎test/unit/electron/renderer.js‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ const path = require('path');
6666
const glob = require('glob');
6767
const util = require('util');
6868
const coverage = require('../coverage');
69-
const { trackTestFiles, distributeTestFiles } = require('../parallel.ts');
69+
const { trackTestFiles, distributeTestFiles, reverseTestFiles } = require('../parallel.ts');
7070
const { pathToFileURL } = require('url');
7171

7272
// Disabled custom inspect. See #38847
@@ -462,11 +462,17 @@ async function runTests(opts) {
462462
mocha.timeout(opts.timeout);
463463
}
464464

465-
const testFiles = opts.workerDir ? trackTestFiles(mocha.suite) : undefined;
465+
// TEMPORARY (order stress test): VSCODE_TEST_REVERSE_FILES runs the test files from last to first
466+
const reverse = !!process.env.VSCODE_TEST_REVERSE_FILES;
467+
let testFiles = opts.workerDir || reverse ? trackTestFiles(mocha.suite) : undefined;
466468

467469
await loadTests(opts);
468470

469-
if (testFiles) {
471+
if (testFiles && reverse) {
472+
testFiles = reverseTestFiles(mocha.suite, testFiles);
473+
ipcRenderer.send('tmp-order-log', `TEMPORARY: running ${testFiles.size} test files from last to first, starting with ${[...testFiles.keys()][0]}`);
474+
}
475+
if (testFiles && opts.workerDir) {
470476
distributeTestFiles(mocha.suite, testFiles, { workerId: opts.worker, workerDir: opts.workerDir });
471477
}
472478

‎test/unit/node/index.js‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { fileURLToPath, pathToFileURL } from 'url';
2020
import semver from 'semver';
2121
import parallel from '../parallel.ts';
2222

23-
const { getWorkerCount, removeArgument, runInWorkers, trackTestFiles, distributeTestFiles } = parallel;
23+
const { getWorkerCount, removeArgument, runInWorkers, trackTestFiles, distributeTestFiles, reverseTestFiles } = parallel;
2424

2525
/**
2626
* @type {{ build: boolean; run: string; runGlob: string; coverage: boolean; help: boolean; coverageFormats: string | string[]; coveragePath: string; timeout?: string; workers?: string; worker?: string; workerDir?: string; }}
@@ -161,7 +161,9 @@ function main() {
161161
timeout: args.timeout ?? (IS_CI ? 30000 : 5000)
162162
});
163163

164-
const testFiles = args.workerDir ? trackTestFiles(runner.suite) : undefined;
164+
// TEMPORARY (order stress test): VSCODE_TEST_REVERSE_FILES runs the test files from last to first
165+
const reverse = !!process.env.VSCODE_TEST_REVERSE_FILES;
166+
let testFiles = args.workerDir || reverse ? trackTestFiles(runner.suite) : undefined;
165167

166168
/**
167169
* @param modules
@@ -257,7 +259,11 @@ function main() {
257259
unexpectedErrors.push((err && err.message ? err.message : err) + '\n' + stack);
258260
});
259261

260-
if (testFiles) {
262+
if (testFiles && reverse) {
263+
testFiles = reverseTestFiles(runner.suite, testFiles);
264+
console.log(`TEMPORARY: running ${testFiles.size} test files from last to first, starting with ${[...testFiles.keys()][0]}`);
265+
}
266+
if (testFiles && args.workerDir) {
261267
distributeTestFiles(runner.suite, testFiles, { workerId: args.worker ?? '', workerDir: args.workerDir ?? '' });
262268
}
263269

‎test/unit/parallel.ts‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,23 @@ function distributeTestFiles(root: Suite, files: Map<string, ITestFile>, { worke
247247
});
248248
}
249249

250+
/**
251+
* TEMPORARY (order stress test): makes the test files run from last to first. They are still
252+
* loaded in their usual order, so only the order in which they run changes.
253+
* @returns the files in reverse order, which is also the order in which workers claim them
254+
*/
255+
function reverseTestFiles(root: Suite, files: Map<string, ITestFile>): Map<string, ITestFile> {
256+
const reversed = new Map([...files].reverse());
257+
const fileSuites = new Set([...files.values()].flatMap(file => file.suites));
258+
const fileTests = new Set([...files.values()].flatMap(file => file.tests));
259+
const firstFileSuite = root.suites.findIndex(suite => fileSuites.has(suite));
260+
const otherSuitesBefore = root.suites.filter((suite, i) => !fileSuites.has(suite) && (firstFileSuite === -1 || i < firstFileSuite));
261+
const otherSuitesAfter = root.suites.filter((suite, i) => !fileSuites.has(suite) && firstFileSuite !== -1 && i > firstFileSuite);
262+
root.suites = [...otherSuitesBefore, ...[...reversed.values()].flatMap(file => file.suites), ...otherSuitesAfter];
263+
root.tests = [...root.tests.filter(test => !fileTests.has(test)), ...[...reversed.values()].flatMap(file => file.tests)];
264+
return reversed;
265+
}
266+
250267
/**
251268
* @returns a promise that resolves once the data is flushed, so exiting does not truncate it
252269
*/
@@ -259,4 +276,4 @@ function formatDuration(ms: number): string {
259276
return seconds >= 60 ? `${Math.floor(seconds / 60)}m ${seconds % 60}s` : `${seconds}s`;
260277
}
261278

262-
module.exports = { getWorkerCount, removeArgument, runInWorkers, trackTestFiles, distributeTestFiles };
279+
module.exports = { getWorkerCount, removeArgument, runInWorkers, trackTestFiles, distributeTestFiles, reverseTestFiles };

0 commit comments

Comments
 (0)