fix(testing): add timeout to runCommandUntil to prevent hanging tests#34148
fix(testing): add timeout to runCommandUntil to prevent hanging tests#34148FrozenPandaz merged 15 commits intomasterfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
✅ Deploy Preview for nx-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
View your CI Pipeline Execution ↗ for commit 75a59a7
☁️ Nx Cloud last updated this comment at |
fae8d6f to
e5cba86
Compare
e5cba86 to
966bcc3
Compare
966bcc3 to
44fb056
Compare
b9635a2 to
ac7bf70
Compare
|
@copilot Can you update the global-setup.ts file in e2e-utils to use environment variables rather than the npm config commands so that the setup and teardown do not polute other e2e tests which may be running? |
|
@FrozenPandaz I've opened a new pull request, #34240, to work on those changes. Once the pull request is ready, I'll request review from you. |
68e3c43 to
2c164ab
Compare
## Current Behavior
The `runCommandUntil` e2e utility waits indefinitely for expected
output, causing tests to hang for hours in CI when servers fail to start
or produce different output. Additionally, `global-setup.ts` uses `npm
config set/delete` commands that modify global npm configuration,
polluting concurrent e2e test environments.
## Expected Behavior
Tests should timeout with clear error messages, and e2e setup should not
interfere with parallel test execution.
## Changes
### runCommandUntil timeout
- Added optional `timeout` parameter (default: 5 seconds)
- On timeout: kills process, logs collected output, rejects with
descriptive error
- Updated tests requiring longer startup time to pass explicit timeout
values
```typescript
// Existing tests work unchanged with 5s default
await runCommandUntil(`nx serve app`, (output) => output.includes('ready'));
// Tests needing more time specify explicit timeout
await runCommandUntil(`nx serve app`, (output) => output.includes('ready'), {
timeout: 30000
});
```
### global-setup environment isolation
- Replaced `execSync('npm config set ...')` with
`process.env['npm_config_//localhost:4873/:_authToken']`
- Replaced `execSync('npm config delete ...')` with `delete
process.env[...]` in teardown
- Removed unnecessary `npm config get registry` diagnostic call
- Environment variables are process-scoped and don't affect concurrent
test runs
<!-- START COPILOT CODING AGENT TIPS -->
---
💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.
---------
Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: FrozenPandaz <[email protected]>
Co-authored-by: FrozenPandaz <[email protected]>
748eba8 to
75a59a7
Compare
There was a problem hiding this comment.
Important
At least one additional CI pipeline execution has run since the conclusion below was written and it may no longer be applicable.
Nx Cloud is proposing a fix for your failed CI:
We removed the explicit Gradle daemon stop command from the test setup to fix the race condition where daemons were being terminated during active test execution. This change prevents the "Gradle build daemon has been stopped: stop command received" error by allowing daemons to run continuously throughout the test suite.
Warning
❌ We could not verify this fix.
diff --git a/e2e/gradle/src/utils/create-gradle-project.ts b/e2e/gradle/src/utils/create-gradle-project.ts
index e7bcdceea8..2f768684f3 100644
--- a/e2e/gradle/src/utils/create-gradle-project.ts
+++ b/e2e/gradle/src/utils/create-gradle-project.ts
@@ -48,11 +48,8 @@ export function createGradleProject(
}
try {
- e2eConsoleLogger(
- runCommand(`${gradleCommand} --stop`, {
- cwd,
- })
- );
+ // Run clean without stopping daemons first to avoid race conditions
+ // where subsequent test executions try to use a daemon that's being stopped
e2eConsoleLogger(
runCommand(`${gradleCommand} clean`, {
cwd,
Or Apply changes locally with:
npx nx-cloud apply-locally xYs1-plzG
Apply fix locally with your editor ↗ View interactive diff ↗
🎓 Learn more about Self-Healing CI on nx.dev
…#34148) ## Current Behavior The `runCommandUntil` e2e utility function waits indefinitely for the expected output to appear. If the output never appears (e.g., server fails to start, different output format, port conflict), the test hangs forever, causing CI jobs to run for hours before being killed. ## Expected Behavior The function should timeout after a configurable duration and fail with a clear error message showing what output was received. ## Related Issue(s) Fixes hanging e2e tests observed in CI (e.g., `e2e-node:e2e-ci--src/node-server.test.ts` hung for 1h 21m). ## Changes - Added optional `timeout` parameter to `runCommandUntil` opts (default: 5 seconds) - On timeout: kills the process, logs the collected output, and rejects with a clear error - Existing call sites work unchanged; tests needing more startup time can pass `{ timeout: 30000 }` --------- Co-authored-by: Copilot <[email protected]> Co-authored-by: FrozenPandaz <[email protected]> Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com> Co-authored-by: FrozenPandaz <[email protected]>
|
This pull request has already been merged/closed. If you experience issues related to these changes, please open a new issue referencing this pull request. |
Current Behavior
The
runCommandUntile2e utility function waits indefinitely for the expected output to appear. If the output never appears (e.g., server fails to start, different output format, port conflict), the test hangs forever, causing CI jobs to run for hours before being killed.Expected Behavior
The function should timeout after a configurable duration and fail with a clear error message showing what output was received.
Related Issue(s)
Fixes hanging e2e tests observed in CI (e.g.,
e2e-node:e2e-ci--src/node-server.test.tshung for 1h 21m).Changes
timeoutparameter torunCommandUntilopts (default: 5 seconds){ timeout: 30000 }