From 15219cae2868586460c0a95b9a131f90a262c70a Mon Sep 17 00:00:00 2001 From: Nicolas DUBIEN Date: Mon, 28 Oct 2024 18:49:39 +0000 Subject: [PATCH 1/4] =?UTF-8?q?=E2=9C=85(jest)=20Make=20tests=20running=20?= =?UTF-8?q?concurrently?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They used to be running in a concurrent fashion in the past. But we stopped doing it due to a recent regression on the stability of our CI with Node 23. The regression being still noticeabl even without it and because of the cost of not doing the runs in a concurrent fashion, we move back to concurrent execution. --- packages/jest/test/jest-fast-check.spec.ts | 58 +++++++++++----------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/packages/jest/test/jest-fast-check.spec.ts b/packages/jest/test/jest-fast-check.spec.ts index dc4ca2f1720..dcd7e2bbecb 100644 --- a/packages/jest/test/jest-fast-check.spec.ts +++ b/packages/jest/test/jest-fast-check.spec.ts @@ -55,7 +55,7 @@ describe.each([ ])('$specName', ({ runnerName, useWorkers, testRunner }) => { const options = { useWorkers, testRunner }; - it('should pass on successful no prop mode', async () => { + it.concurrent('should pass on successful no prop mode', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner('successful no prop', () => { @@ -71,7 +71,7 @@ describe.each([ expect(out).toMatch(/[√✓] successful no prop/); }); - it('should fail on failing no prop mode', async () => { + it.concurrent('should fail on failing no prop mode', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner('failing no prop', () => { @@ -88,7 +88,7 @@ describe.each([ }); if (useWorkers) { - it('should fail on property blocking the main thread', async () => { + it.concurrent('should fail on property blocking the main thread', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.prop([fc.nat()], { timeout: 500 })('property block main thread', () => { @@ -105,7 +105,7 @@ describe.each([ }); } - it('should pass on truthy synchronous property', async () => { + it.concurrent('should pass on truthy synchronous property', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.prop([fc.string(), fc.string(), fc.string()])('property pass sync', (a, b, c) => { @@ -121,7 +121,7 @@ describe.each([ expect(out).toMatch(/[√✓] property pass sync \(with seed=-?\d+\)/); }); - it('should pass on truthy asynchronous property', async () => { + it.concurrent('should pass on truthy asynchronous property', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.prop([fc.string(), fc.string(), fc.string()])('property pass async', async (a, b, c) => { @@ -138,7 +138,7 @@ describe.each([ expect(out).toMatch(/[√✓] property pass async \(with seed=-?\d+\)/); }); - it('should fail on falsy synchronous property', async () => { + it.concurrent('should fail on falsy synchronous property', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.prop([fc.nat()])('property fail sync', (a) => { @@ -155,7 +155,7 @@ describe.each([ expect(out).toMatch(/[×✕] property fail sync \(with seed=-?\d+\)/); }); - it('should fail on falsy asynchronous property', async () => { + it.concurrent('should fail on falsy asynchronous property', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.prop([fc.nat()])('property fail async', async (a) => { @@ -173,7 +173,7 @@ describe.each([ expect(out).toMatch(/[×✕] property fail async \(with seed=-?\d+\)/); }); - it('should pass on truthy record-based property', async () => { + it.concurrent('should pass on truthy record-based property', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.prop({ a: fc.string(), b: fc.string(), c: fc.string() })('property pass record', ({ a, b, c }) => { @@ -192,7 +192,7 @@ describe.each([ expect(out).toMatch(/[√✓] property pass record \(with seed=-?\d+\)/); }); - it('should fail on falsy record-based property', async () => { + it.concurrent('should fail on falsy record-based property', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.prop({ a: fc.string(), b: fc.string(), c: fc.string() })('property fail record', ({ a, b, c }) => { @@ -209,7 +209,7 @@ describe.each([ expect(out).toMatch(/[×✕] property fail record \(with seed=-?\d+\)/); }); - it('should fail on falsy record-based property with seed', async () => { + it.concurrent('should fail on falsy record-based property with seed', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.prop({ a: fc.string(), b: fc.string(), c: fc.string() }, { seed: 4869 })( @@ -227,7 +227,7 @@ describe.each([ expect(out).toMatch(/[×✕] property fail record seeded \(with seed=4869\)/); }); - it('should fail with locally requested seed', async () => { + it.concurrent('should fail with locally requested seed', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.prop([fc.constant(null)], { seed: 4242 })('property fail with locally requested seed', (_unused) => false); @@ -242,7 +242,7 @@ describe.each([ expect(out).toMatch(/[×✕] property fail with locally requested seed \(with seed=4242\)/); }); - it('should fail with globally requested seed', async () => { + it.concurrent('should fail with globally requested seed', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { fc.configureGlobal({ seed: 4848 }); @@ -258,7 +258,7 @@ describe.each([ expect(out).toMatch(/[×✕] property fail with globally requested seed \(with seed=4848\)/); }); - it('should fail with seed requested at jest level', async () => { + it.concurrent('should fail with seed requested at jest level', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.prop([fc.constant(null)])('property fail with globally requested seed', (_unused) => false); @@ -274,7 +274,7 @@ describe.each([ }); describe('.skip', () => { - it('should never be executed', async () => { + it.concurrent('should never be executed', async () => { // Arrange const { jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.skip.prop([fc.constant(null)])('property never executed', (_unused) => false); @@ -291,7 +291,7 @@ describe.each([ if (testRunner === undefined) { describe('.failing', () => { - it('should fail on successful no prop mode', async () => { + it.concurrent('should fail on successful no prop mode', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.failing('successful no prop', () => { @@ -307,7 +307,7 @@ describe.each([ expect(out).toMatch(/[×✕] successful no prop/); }); - it('should pass on failing no prop mode', async () => { + it.concurrent('should pass on failing no prop mode', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.failing('failing no prop', () => { @@ -323,7 +323,7 @@ describe.each([ expect(out).toMatch(/[√✓] failing no prop/); }); - it('should pass because failing', async () => { + it.concurrent('should pass because failing', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.failing.prop([fc.constant(null)])('property pass because failing', async (_unused) => false); @@ -337,7 +337,7 @@ describe.each([ expect(out).toMatch(/[√✓] property pass because failing \(with seed=-?\d+\)/); }); - it('should fail because passing', async () => { + it.concurrent('should fail because passing', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.failing.prop([fc.constant(null)])('property fail because passing', async (_unused) => true); @@ -354,7 +354,7 @@ describe.each([ } describe('.concurrent', () => { - it('should pass on truthy property', async () => { + it.concurrent('should pass on truthy property', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.concurrent.prop([fc.constant(null)])('property pass on truthy property', (_unused) => true); @@ -368,7 +368,7 @@ describe.each([ expect(out).toMatch(/[√✓] property pass on truthy property \(with seed=-?\d+\)/); }); - it('should fail on falsy property', async () => { + it.concurrent('should fail on falsy property', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.concurrent.prop([fc.constant(null)])('property fail on falsy property', (_unused) => false); @@ -385,7 +385,7 @@ describe.each([ if (testRunner === undefined) { describe('.failing', () => { - it('should pass because failing', async () => { + it.concurrent('should pass because failing', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.concurrent.failing.prop([fc.constant(null)])( @@ -402,7 +402,7 @@ describe.each([ expect(out).toMatch(/[√✓] property pass because failing \(with seed=-?\d+\)/); }); - it('should fail because passing', async () => { + it.concurrent('should fail because passing', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.concurrent.failing.prop([fc.constant(null)])( @@ -423,7 +423,7 @@ describe.each([ }); describe('timeout', () => { - it('should fail as test takes longer than global Jest timeout', async () => { + it.concurrent('should fail as test takes longer than global Jest timeout', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.prop([fc.nat()])('property takes longer than global Jest timeout', async () => { @@ -440,7 +440,7 @@ describe.each([ expect(out).toMatch(/[×✕] property takes longer than global Jest timeout/); }); - it('should fail as test takes longer than Jest local timeout', async () => { + it.concurrent('should fail as test takes longer than Jest local timeout', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.prop([fc.nat()])( @@ -461,7 +461,7 @@ describe.each([ expect(out).toMatch(/[×✕] property takes longer than Jest local timeout/); }); - it('should fail as test takes longer than Jest config timeout', async () => { + it.concurrent('should fail as test takes longer than Jest config timeout', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile( runnerName, @@ -482,7 +482,7 @@ describe.each([ expect(out).toMatch(/[×✕] property takes longer than Jest config timeout/); }); - it('should fail as test takes longer than Jest setTimeout', async () => { + it.concurrent('should fail as test takes longer than Jest setTimeout', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { if (typeof jest !== 'undefined') { @@ -502,7 +502,7 @@ describe.each([ expect(out).toMatch(/[×✕] property takes longer than Jest setTimeout/); }); - it('should fail as test takes longer than Jest CLI timeout', async () => { + it.concurrent('should fail as test takes longer than Jest CLI timeout', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { runner.prop([fc.nat()])('property takes longer than Jest CLI timeout', async () => { @@ -519,7 +519,7 @@ describe.each([ expect(out).toMatch(/[×✕] property takes longer than Jest CLI timeout/); }); - it('should fail but favor local Jest timeout over Jest setTimeout', async () => { + it.concurrent('should fail but favor local Jest timeout over Jest setTimeout', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { if (typeof jest !== 'undefined') { @@ -543,7 +543,7 @@ describe.each([ expect(out).toMatch(/[×✕] property favor local Jest timeout over Jest setTimeout/); }); - it('should fail but favor Jest setTimeout over Jest CLI timeout', async () => { + it.concurrent('should fail but favor Jest setTimeout over Jest CLI timeout', async () => { // Arrange const { specFileName, jestConfigRelativePath } = await writeToFile(runnerName, options, () => { if (typeof jest !== 'undefined') { From 4b27efc1535b8a2bdc8d7521a4c8deb5632a75fe Mon Sep 17 00:00:00 2001 From: Nicolas DUBIEN Date: Tue, 29 Oct 2024 08:06:00 +0000 Subject: [PATCH 2/4] bump time to 120s --- packages/jest/vitest.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest/vitest.config.ts b/packages/jest/vitest.config.ts index 711163dca5a..5ca11490a16 100644 --- a/packages/jest/vitest.config.ts +++ b/packages/jest/vitest.config.ts @@ -2,7 +2,7 @@ import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { - testTimeout: 60000, // 60s + testTimeout: 120000, // 120s include: ['**/test/*.{test,spec}.?(c|m)[jt]s?(x)'], }, }); From 53757bbc5d74a6a674a600432e73247123d213f6 Mon Sep 17 00:00:00 2001 From: Nicolas DUBIEN Date: Tue, 29 Oct 2024 08:22:28 +0000 Subject: [PATCH 3/4] workaround v23 of node for jest tests --- packages/jest/vitest.config.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/jest/vitest.config.ts b/packages/jest/vitest.config.ts index 5ca11490a16..877ba1a8213 100644 --- a/packages/jest/vitest.config.ts +++ b/packages/jest/vitest.config.ts @@ -1,8 +1,11 @@ import { defineConfig } from 'vitest/config'; +const major = Number(process.versions.node.split('.')[0]); + export default defineConfig({ test: { - testTimeout: 120000, // 120s + testTimeout: 60000, // 60s include: ['**/test/*.{test,spec}.?(c|m)[jt]s?(x)'], + retry: major === 23 ? 3 : undefined, }, }); From a10166a6c2b877c18895f4d852872bdb716079b2 Mon Sep 17 00:00:00 2001 From: Nicolas DUBIEN Date: Tue, 29 Oct 2024 09:33:49 +0100 Subject: [PATCH 4/4] Update packages/jest/vitest.config.ts --- packages/jest/vitest.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest/vitest.config.ts b/packages/jest/vitest.config.ts index 877ba1a8213..f1673dbe922 100644 --- a/packages/jest/vitest.config.ts +++ b/packages/jest/vitest.config.ts @@ -6,6 +6,6 @@ export default defineConfig({ test: { testTimeout: 60000, // 60s include: ['**/test/*.{test,spec}.?(c|m)[jt]s?(x)'], - retry: major === 23 ? 3 : undefined, + retry: major === 23 ? 5 : undefined, }, });