Skip to content

Commit 1bfeddc

Browse files
test(e2e): accept completed OpenClaw TUI turns (#9444)
## Summary Preserve a successful OpenClaw launch when the TUI closes its input reader immediately after publishing the two required structured turns. The harness still requires the real child to exit zero; nonzero exits remain failures and now retain their bounded diagnostics. This follows the merged startup-message fix in #9422. Two focused current-main runs reproduced the newly exposed exit race after hosted inference, sandbox inference, recovery, and the launch-readiness producer had all passed: [run 32112329966](https://github.com/NVIDIA/NemoClaw/actions/runs/32112329966) and [run 32112353122](https://github.com/NVIDIA/NemoClaw/actions/runs/32112353122). ## Related Issue Follow-up to #9384 ## Changes - Treat the post-turn `/exit` write as best-effort after two ordered structured turns are already qualified. - Continue to wait for and require the actual TUI child exit status, reporting both a failed exit-command write and any nonzero child exit. - Keep cleanup diagnostics on stderr instead of redirecting the parent shell's stderr for the remainder of the session. - Extend the Linux delayed-input fixture to cover a clean TUI exit after the two required turns without increasing the test-file budget. ## Type of Change - [x] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates - [x] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [ ] Tests not applicable — justification: - [x] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [x] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: The change runs only after exact PTY identity, noncanonical input mode, and two ordered structured turns are proven. It does not retry input, relax PTY evidence, or accept a nonzero TUI exit. - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## DGX Station Hardware Evidence - [ ] Tested on DGX Station - Tested commit: Not applicable - Station profile/scenario: Not applicable - Result: Not applicable - Supporting evidence: Not applicable ## Verification - [x] PR description includes a `Signed-off-by:` line and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run validate:pr` passed after refreshing `origin/main` when hooks were skipped or unavailable - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — `vitest run --project e2e-support test/e2e/support/launch-agent-turn.test.ts` (19 passed; 24 Linux-only tests skipped locally) - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — not applicable to this focused live-E2E exit-path change; the targeted support suite, source-shape budget, growth guardrails, repository checks, secret scan, and CLI typecheck passed in `npm run validate:pr`. - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [ ] `npm run docs` builds without warnings (doc changes only) - [ ] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) --- Signed-off-by: Aaron Erickson <aerickson@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved launch cleanup and exit handling when terminal sessions close unexpectedly. * Exit commands now handle terminal closure more gracefully and provide clearer diagnostics when launches end unsuccessfully. * **Tests** * Updated delayed-input coverage to verify that sessions can complete cleanly after two turns. * Improved validation of successful completion when input becomes available later in the launch. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Aaron Erickson <aerickson@nvidia.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 7f7126e commit 1bfeddc

2 files changed

Lines changed: 16 additions & 2 deletions

File tree

test/e2e/live/launch-agent-turn.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1264,8 +1264,18 @@ if ! printf '%s\r' "$NEMOCLAW_LAUNCH_SECOND_INPUT" >&3; then
12641264
fi
12651265
wait_for_turn_count 2
12661266
1267+
exit_command_write_status=0
12671268
if [[ -n "$NEMOCLAW_LAUNCH_EXIT_COMMAND" ]]; then
1268-
printf '%s\r' "$NEMOCLAW_LAUNCH_EXIT_COMMAND" >&3
1269+
# The TUI may finish cleanly immediately after publishing the two required
1270+
# structured turns. Preserve that successful child status even when its
1271+
# input reader wins the race with the best-effort exit command.
1272+
trap '' PIPE
1273+
if printf '%s\r' "$NEMOCLAW_LAUNCH_EXIT_COMMAND" >&3; then
1274+
:
1275+
else
1276+
exit_command_write_status=$?
1277+
fi
1278+
trap - PIPE
12691279
else
12701280
# Some TUIs have no exit command. They may close the FIFO after the first
12711281
# interrupt, so ignore SIGPIPE while sending the second one.
@@ -1285,6 +1295,9 @@ fi
12851295
session_pid=""
12861296
12871297
if [[ "$launch_status" != 0 ]]; then
1298+
if [[ "$exit_command_write_status" != 0 ]]; then
1299+
echo "launch PTY closed before the exit command was submitted (status $exit_command_write_status)" >&2
1300+
fi
12881301
echo "launch exited with status $launch_status" >&2
12891302
terminal_diagnostic
12901303
exit "$launch_status"

test/e2e/support/launch-agent-turn.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,7 @@ if (process.argv[2] !== "tui") {
522522
const second = await ask();
523523
append("user", second);
524524
append("assistant", "second response");
525+
if (mode === "delayed-input-attachment") process.exit(0);
525526
const exitCommand = await ask();
526527
if (mode === "late-extra") append("user", firstInput);
527528
rl.close();
@@ -1042,7 +1043,7 @@ it.runIf(process.platform === "linux").each(["absent", "ansi", "reordered"] as c
10421043
);
10431044

10441045
it.runIf(process.platform === "linux")(
1045-
"waits for the OpenClaw TUI input mode before submitting PTY input (#9160)",
1046+
"waits for OpenClaw input mode and accepts a clean exit after two turns (#9160, #9384)",
10461047
() => {
10471048
const { baselineRemoved, result, ttyObserved } = runLaunchSessionFixture(
10481049
"delayed-input-attachment",

0 commit comments

Comments
 (0)