-
Notifications
You must be signed in to change notification settings - Fork 6
fix(scripts): eliminate repository-linter test race #824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,26 @@ | ||
| import { defineConfig } from 'vitest/config' | ||
|
|
||
| // `fileParallelism: false` is load-bearing, not a performance knob. | ||
| // | ||
| // Several of these suites mutate the real repo tree while they run: | ||
| // `lint-no-dead-package-paths.test.mjs` creates and deletes probe package | ||
| // directories inside the packages tree (`lint-untracked-probe`, | ||
| // `lint-dead-shell-probe`), and `lint-no-hardcoded-runners.test.mjs` walks that | ||
| // same tree and writes an `allowlist-probe.mjs` into `scripts/`. Run in | ||
| // parallel, one suite's scratch state lands inside another's scan — which is | ||
| // how a clean tree produced an `ENOENT: scandir` on a probe directory and a CI | ||
| // failure that pointed at nothing. | ||
| // | ||
| // Note the probe names are deliberately written WITHOUT their directory prefix: | ||
| // the sibling `lint-no-dead-package-paths` linter flags that shape when the | ||
| // directory does not exist, and these only exist mid-test. | ||
| // | ||
| // These are eleven small files; serialising them costs a second and removes | ||
| // the whole class of cross-suite filesystem race. | ||
| export default defineConfig({ | ||
| test: { include: ['scripts/__tests__/**/*.test.mjs'], pool: 'forks' }, | ||
| test: { | ||
| include: ['scripts/__tests__/**/*.test.mjs'], | ||
| pool: 'forks', | ||
| fileParallelism: false, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [single-source: codex] import { describe, expect, it } from 'vitest'
import scriptsVitestConfig from '../vitest.config.mjs'
describe('scripts vitest config', () => {
it('keeps script test files serialized', () => {
expect(scriptsVitestConfig.test.fileParallelism).toBe(false)
})
})Passes on the current config, fails if script tests are allowed back into parallel. |
||
| }, | ||
| }) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[2 models: claude, codex] The new ENOENT arm in
walk()— the whole point of this PR — has no test. Both arms are new and uncovered:ENOENT-> silently skip, any other code -> rethrow. A future change that turns "vanished directory means nothing to lint" back into an exit-1 crash would still pass the existing suite. The sibling suite already pins the analogous "linter could not run" contract (lint-no-dead-package-paths.test.mjs:162, exit 2 when git is unavailable), so the precedent exists.Since
walkisn't exported, the subprocess style this file already uses fits — copy the script into a probe withreaddirstubbed to throwENOENTand assert exit 0 /OK:Passes with the fix; fails (or throws a raw
ENOENTstack) if the try/catch is reverted. Ideally add a second case stubbing a non-ENOENT code (e.g.EACCES) to pin the rethrow arm too — otherwise it can silently rot into a swallow.