You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Two unrelated **flaky test** fixes surfaced while stabilizing CI for the
snapshot work (#6011). Test-only; no `src` changes.
## 1. `@eggjs/multipart` — `ENOTEMPTY` teardown race
`file-mode.test.ts` flaked on macOS Node 24 (passing on every other
matrix job):
```
Error: ENOTEMPTY: directory not empty, rmdir '.../egg-multipart-tmp/multipart-file-mode-demo/2026/06/28/05'
```
`fs.rm(tmpdir, { force: true, recursive: true })` defaults to
`maxRetries: 0`, so a transient `ENOTEMPTY` (a file in a date-bucket dir
mid recursive-removal — async per-request cleanup draining / APFS
latency) throws and fails the suite. The production `clean_tmpdir`
schedule already swallows these; only the 7 test teardowns are fragile.
**Fix:** add `maxRetries: 3` to all 7.
## 2. `@eggjs/scripts` — flaky `stop.test.ts` start readiness
`Test scripts (ubuntu-22)` failed in `stop.test.ts`:
```
AssertionError: expected 'Starting custom-framework application…' to match /custom-framework started on http:\/\/…/
```
`stop.test.ts` waited a fixed **1s** for a 2-worker egg app to boot
before asserting its `started on http://…` log — while every sibling
`start-without-demon-*.test.ts` waits **10s**. On a loaded runner 1s
isn't enough. **Fix:** replace the fixed `scheduler.wait(waitTime)`
before each startup/shutdown assertion with a `waitFor(getText, pattern,
timeout)` poll (`test/utils.ts`) that returns as soon as the expected
output appears (up to 10s) — race-free and faster than a fixed delay.
Windows keeps the fixed settle for the signal-driven shutdown checks
(SIGTERM isn't handled there).
## Verification
- multipart: the 7 teardowns now retry; affected tests pass locally.
- scripts: `stop.test.ts` passes locally after build (8 passed, 1
skipped).
Re Gemini's review on the multipart hunks: it claimed Vitest runs
`afterAll` in registration order — that's incorrect (default
`sequence.hooks: 'stack'` → reverse; verified empirically on v4.1.9), so
the current teardown already removes the tmpdir **last** (after
`server.close()`/`app.close()`); the suggested reorder would move
`fs.rm` first and reintroduce the race. Replied inline on each thread.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Tests**
* Improved cleanup reliability across multipart-related test suites by
adding additional retry behavior when removing temporary directories
during teardown.
* Updated process lifecycle checks in test runs to wait for specific
startup/shutdown output instead of relying on fixed timing, reducing
flaky boot/shutdown timing.
* Introduced a reusable polling helper to detect expected log output
within a timeout.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
0 commit comments