From 991bd373628b16ccbdb14013280909e7a0d1f12f Mon Sep 17 00:00:00 2001 From: Sandy Tao Date: Thu, 16 Oct 2025 16:15:46 -0700 Subject: [PATCH] fix(scripts): Improve deflake script isolation and unskip test (#11325) --- integration-tests/ctrl-c-exit.test.ts | 2 +- scripts/deflake.js | 65 ++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 12 deletions(-) diff --git a/integration-tests/ctrl-c-exit.test.ts b/integration-tests/ctrl-c-exit.test.ts index bdb4d12ccf..24af7c47d6 100644 --- a/integration-tests/ctrl-c-exit.test.ts +++ b/integration-tests/ctrl-c-exit.test.ts @@ -8,7 +8,7 @@ import { describe, it, expect } from 'vitest'; import * as os from 'node:os'; import { TestRig } from './test-helper.js'; -describe.skip('Ctrl+C exit', () => { +describe('Ctrl+C exit', () => { it('should exit gracefully on second Ctrl+C', async () => { const rig = new TestRig(); await rig.setup('should exit gracefully on second Ctrl+C'); diff --git a/scripts/deflake.js b/scripts/deflake.js index fcceced389..798af10d77 100644 --- a/scripts/deflake.js +++ b/scripts/deflake.js @@ -5,12 +5,21 @@ */ import { spawn } from 'node:child_process'; +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; import yargs from 'yargs'; import { hideBin } from 'yargs/helpers'; // Script to deflake tests // Ex. npm run deflake -- --command="npm run test:e2e -- --test-name-pattern 'extension'" --runs=3 +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const projectRoot = path.resolve(__dirname, '..'); +const dockerIgnorePath = path.join(projectRoot, '.dockerignore'); + +const DOCKERIGNORE_CONTENT = `.integration-tests`.trim(); + /** * Runs a command and streams its output to the console. * @param {string} command The command string to execute (e.g., 'npm run test:e2e -- --watch'). @@ -25,6 +34,7 @@ function runCommand(cmd, args = []) { const child = spawn(cmd, args, { shell: true, stdio: 'inherit', + env: { ...process.env }, }); child.on('close', (code) => { @@ -58,23 +68,56 @@ async function main() { const ARGS = argv._; let failures = 0; + const backupDockerIgnorePath = dockerIgnorePath + '.bak'; + let originalDockerIgnoreRenamed = false; + console.log(`--- Starting Deflake Run (${NUM_RUNS} iterations) ---`); - for (let i = 1; i <= NUM_RUNS; i++) { - console.log(`\n[RUN ${i}/${NUM_RUNS}]`); + try { try { - // 3. Await the asynchronous command run - const exitCode = await runCommand(COMMAND, ARGS); + // Try to rename to back up an existing .dockerignore + await fs.rename(dockerIgnorePath, backupDockerIgnorePath); + originalDockerIgnoreRenamed = true; + } catch (err) { + // If the file doesn't exist, that's fine. Otherwise, rethrow. + if (err.code !== 'ENOENT') throw err; + } - if (exitCode === 0) { - console.log('✅ Run PASS'); - } else { - console.log(`❌ Run FAIL (Exit Code: ${exitCode})`); + // Create the temporary .dockerignore for this run. + await fs.writeFile(dockerIgnorePath, DOCKERIGNORE_CONTENT); + + for (let i = 1; i <= NUM_RUNS; i++) { + console.log(`\n[RUN ${i}/${NUM_RUNS}]`); + + try { + const exitCode = await runCommand(COMMAND, ARGS); + + if (exitCode === 0) { + console.log('✅ Run PASS'); + } else { + console.log(`❌ Run FAIL (Exit Code: ${exitCode})`); + failures++; + } + } catch (error) { + console.error('❌ Run FAIL (Execution Error)', error); failures++; } - } catch (error) { - console.error('❌ Run FAIL (Execution Error)', error); - failures++; + } + } finally { + try { + // Clean up the temporary .dockerignore + await fs.unlink(dockerIgnorePath); + } catch (err) { + console.error('Failed to remove temporary .dockerignore:', err); + } + + if (originalDockerIgnoreRenamed) { + try { + // Restore the original .dockerignore if it was backed up. + await fs.rename(backupDockerIgnorePath, dockerIgnorePath); + } catch (err) { + console.error('Failed to restore original .dockerignore:', err); + } } }