Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/nightly-e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
# Discord coverage with cross-talk assertions. See issue #1903.
# sandbox-survival-e2e Sandbox survival across gateway restarts (onboard, inference,
# gateway stop/start, verify sandbox + workspace + inference).
# double-onboard-e2e Two sandboxes alive at once — second must auto-allocate a free
# dashboard port. Guards #2174 (crash on second onboard) and #849
# (first sandbox destroyed by second). Fake OpenAI endpoint.
# hermes-e2e Hermes Agent E2E — install → onboard --agent hermes → health
# probe → live inference. Validates the multi-agent architecture.
# skip-permissions-e2e Validates --dangerously-skip-permissions activates the permissive
Expand Down Expand Up @@ -268,6 +271,34 @@ jobs:
path: /tmp/nemoclaw-e2e-install.log
if-no-files-found: ignore

# ── Double-onboard E2E ───────────────────────────────────────
# Two sandboxes alive at once: first takes the default dashboard port,
# second must auto-allocate to the next free port. Guards #2174 (crash
# on second onboard) and #849 (first sandbox destroyed by second). Uses
# a local fake OpenAI-compatible endpoint — no NVIDIA_API_KEY required.
double-onboard-e2e:
if: github.repository == 'NVIDIA/NemoClaw'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Run double-onboard E2E test
env:
NEMOCLAW_NON_INTERACTIVE: "1"
NEMOCLAW_ACCEPT_THIRD_PARTY_SOFTWARE: "1"
GITHUB_TOKEN: ${{ github.token }}
run: bash test/e2e/test-double-onboard.sh

- name: Upload install log on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: double-onboard-install-log
path: /tmp/nemoclaw-e2e-install.log
if-no-files-found: ignore

# ── Hermes Agent E2E ─────────────────────────────────────────
# Validates the multi-agent architecture by onboarding with --agent hermes,
# verifying the Hermes health probe, and running live inference through the
Expand Down Expand Up @@ -673,6 +704,7 @@ jobs:
messaging-providers-e2e,
token-rotation-e2e,
sandbox-survival-e2e,
double-onboard-e2e,
hermes-e2e,
skip-permissions-e2e,
sandbox-operations-e2e,
Expand Down
21 changes: 21 additions & 0 deletions test/e2e/test-double-onboard.sh
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,27 @@ else
fail "First sandbox '$SANDBOX_A' disappeared after creating '$SANDBOX_B' (regression: #849)"
fi

# #2174 regression: B must auto-allocate to a different dashboard port,
# surface it in nemoclaw list, and not collide with A's 18789.
if grep -q "allocated port" <<<"$output3"; then
pass "Second-sandbox onboard logged auto-allocation (#2174)"
else
fail "Second-sandbox onboard did not log 'allocated port' — auto-alloc may not have fired (#2174)"
fi

LIST_LOG="$(mktemp)"
run_nemoclaw list >"$LIST_LOG" 2>&1 || true
list_output="$(cat "$LIST_LOG")"
rm -f "$LIST_LOG"

dashboard_ports_in_list="$(grep -oE 'dashboard: http://127\.0\.0\.1:[0-9]+' <<<"$list_output" | awk -F: '{print $NF}' | sort -u)"
distinct_count="$(wc -l <<<"$dashboard_ports_in_list" | tr -d ' ')"
if [ "$distinct_count" = "2" ]; then
pass "nemoclaw list shows two distinct dashboard ports (#2174)"
else
fail "nemoclaw list did not show two distinct dashboard ports (got $distinct_count: $(tr '\n' ' ' <<<"$dashboard_ports_in_list"))"
fi

# ══════════════════════════════════════════════════════════════════
# Phase 5: Stale registry reconciliation
# ══════════════════════════════════════════════════════════════════
Expand Down
Loading