Skip to content

test(onboard): speed up dashboard curl mocks#3374

Merged
cv merged 6 commits into
mainfrom
perf/onboard-test-mocks
May 12, 2026
Merged

test(onboard): speed up dashboard curl mocks#3374
cv merged 6 commits into
mainfrom
perf/onboard-test-mocks

Conversation

@cv
Copy link
Copy Markdown
Collaborator

@cv cv commented May 12, 2026

Summary

Extracts shared onboard script curl mock handling and uses it across generated onboard child-process test scripts. The helper returns HTTP 200 for dashboard health probes so mocked createSandbox flows no longer burn the full dashboard readiness timeout. It also lowers the default CLI test timeout to 5s so future accidental sleeps fail fast, with explicit 10s allowances for the three known Ollama installer-selection outliers.

Changes

  • Added test/helpers/onboard-script-mocks.cjs with reusable command normalization and sandbox curl mock handling.
  • Replaced duplicated inline sandbox exec/curl mock branches in test/onboard.test.ts with the shared helper.
  • Preserved generic sandbox curl behavior via defaultCurlOutput while ensuring dashboard /health probes return an HTTP status code.
  • Lowered the default CLI test timeout from 15s to 5s in test/helpers/timeouts.ts.
  • Marked the three known test/onboard-selection.test.ts Ollama install-selection cases with explicit 10s timeouts.

Type of Change

  • 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)

Verification

npm test was attempted but currently fails in installer-integration at test/install-preflight.test.ts (skips onboarding when shared host preflight detects Docker is missing), unrelated to this test-only change; leaving that box unchecked.

  • npx prek run --all-files passes
  • npm test passes
  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed
  • Docs updated for user-facing behavior changes
  • make docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Carlos Villela cvillela@nvidia.com

Summary by CodeRabbit

  • Tests
    • Added a reusable helper to mock sandbox-executed curl calls and standardize probe outputs across tests.
    • Reduced the default test timeout from 15s to 5s.
    • Added explicit timeouts to multiple onboarding and CLI tests (10s and 15s) to stabilize timing-sensitive scenarios.
    • Tightened CLI test deadline calculations for streaming/log-follow behavior.
    • Adjusted a temp-files test to validate behavior using the user home directory.

Review Change Stack

@cv cv self-assigned this May 12, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

📝 Walkthrough

Walkthrough

Adds a CommonJS test helper to normalize and mock sandbox exec curl calls, refactors multiple onboard test harnesses to use it, lowers the default test timeout, and sets explicit per-test timeouts for selection and CLI tests; adjusts one temp-files test directory location.

Changes

Mock Helper and Test Integration

Layer / File(s) Summary
Mock Helper Module
test/helpers/onboard-script-mocks.cjs
Introduces normalizeCommand() to stringify and normalize command inputs, hasOwn() utility, and mockSandboxExecCurl() which conditionally returns mock responses for sandbox exec curl invocations with health/code detection and defaultCurlOutput/override support.
Test Harness Refactoring
test/onboard.test.ts
Adds onboardScriptMocksPath and updates multiple embedded runner.runCapture handlers to delegate sandbox exec curl stubbing to mockSandboxExecCurl, using defaultCurlOutput: "ok" at several call sites.
Default Test Timeout
test/helpers/timeouts.ts
Changes DEFAULT_TEST_TIMEOUT_MS from 15_000 to 5_000, affecting exported testTimeout and testTimeoutOptions defaults.
Per-test Timeouts
test/onboard-selection.test.ts
Adds { timeout: 10_000 } to three it(...) tests to increase their per-test timeout.
Temp-files test location
src/lib/onboard/temp-files.test.ts
Creates the outside-temp test directory under os.homedir() instead of process.cwd() for the matching-prefix outside-tempdir assertion.
CLI test timeouts
test/cli.test.ts
Adds testTimeoutOptions(15_000) and testTimeoutOptions(10_000) wrappers to CLI tests and updates polling/deadline calculations to derive windows from the explicit budgets.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I’m a rabbit with a tiny mock,
I tidy commands with a gentle hop,
Curl checks shared across the lot,
Timeouts trimmed and tests set not—
Hooray for tidy test-bed rock! 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'test(onboard): speed up dashboard curl mocks' clearly and specifically describes the main change: extracting and optimizing dashboard curl mocking for onboard tests through a new shared helper module.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/onboard-test-mocks

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 12, 2026

E2E Advisor Recommendation

Required E2E: None
Optional E2E: None

Workflow run

Full advisor summary

Pi Semantic E2E Advisor

Failed: pi exited with status 1; see /home/runner/work/NemoClaw/NemoClaw/artifacts/e2e-advisor/e2e-advisor-pi-raw-output.txt

@cv cv added v0.0.40 Release target v0.0.39 Release target labels May 12, 2026
@cv cv requested review from ericksoa and jyaunches May 12, 2026 00:55
@cv cv removed the v0.0.39 Release target label May 12, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
test/cli.test.ts (1)

2197-2198: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Timeout math now collapses polling windows to ~1s after the default reduction.

Line 2197, Line 2261, and Line 2278 still derive windows from testTimeout() (default), so with a 5s default the loop budget gets clamped to 1s even though these tests are explicitly set to 10s. This is likely to reintroduce CI flakes.

Suggested fix
-      const pollTimeoutMs = Math.min(testTimeout(10_000), Math.max(1_000, testTimeout() - 5_000));
+      const pollTimeoutMs = testTimeout(10_000);
...
-      const pollTimeoutMs = Math.min(testTimeout(10_000), Math.max(1_000, testTimeout() - 5_000));
+      const pollTimeoutMs = testTimeout(10_000);
...
-      const termDeadline = Date.now() + Math.min(testTimeout(5_000), Math.max(1_000, testTimeout() - 5_000));
+      const termDeadline = Date.now() + testTimeout(5_000);

Also applies to: 2261-2262, 2278-2278

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/cli.test.ts` around lines 2197 - 2198, The polling timeout math uses
testTimeout() (the default) when computing poll windows, which collapses the
loop budget to ~1s; update the expressions that compute pollTimeoutMs and
deadline to use the explicit test timeout (testTimeout(10_000)) rather than
testTimeout() so the 10s test setting is honored (i.e., replace testTimeout()
with testTimeout(10_000) in the pollTimeoutMs/deadline calculation and apply the
same fix to the other occurrences that compute polling windows).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@test/cli.test.ts`:
- Around line 2197-2198: The polling timeout math uses testTimeout() (the
default) when computing poll windows, which collapses the loop budget to ~1s;
update the expressions that compute pollTimeoutMs and deadline to use the
explicit test timeout (testTimeout(10_000)) rather than testTimeout() so the 10s
test setting is honored (i.e., replace testTimeout() with testTimeout(10_000) in
the pollTimeoutMs/deadline calculation and apply the same fix to the other
occurrences that compute polling windows).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a2847c0f-fb0d-4557-a3ee-ea882feeea64

📥 Commits

Reviewing files that changed from the base of the PR and between 1e72a2b and baf3e4a.

📒 Files selected for processing (2)
  • src/lib/onboard/temp-files.test.ts
  • test/cli.test.ts

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/cli.test.ts`:
- Around line 2197-2199: The current polling budget uses the full testBudgetMs
(10_000) across both pre- and post-SIGTERM phases which can exhaust the test
timeout; change the poll timeout calculation to reserve a safety buffer (e.g.,
subtract 2000ms or a configurable SLACK_MS) so both phases never collectively
consume the entire budget. Update the computation that sets pollTimeoutMs and
deadline (variables testBudgetMs, pollTimeoutMs, deadline) to compute
pollTimeoutMs = Math.min(testBudgetMs - SLACK_MS, Math.max(1_000, testBudgetMs -
5_000)) (ensuring non-negative) or otherwise subtract SLACK_MS before using
testBudgetMs for a second-phase deadline; apply the same change at the other
occurrences noted (the blocks around the other three locations).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: cb6222eb-636f-45f9-a395-573cde68b623

📥 Commits

Reviewing files that changed from the base of the PR and between baf3e4a and c59b03e.

📒 Files selected for processing (1)
  • test/cli.test.ts

Comment thread test/cli.test.ts
Comment on lines +2197 to 2199
const testBudgetMs = testTimeout(10_000);
const pollTimeoutMs = Math.min(testBudgetMs, Math.max(1_000, testBudgetMs - 5_000));
const deadline = Date.now() + pollTimeoutMs;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid consuming the full 10s budget across both polling phases.

In the SIGTERM test, you budget ~5s before SIGTERM and another ~5s after SIGTERM. That can hit the full 10_000ms test timeout with almost no setup/assertion slack and cause CI flakes.

Suggested adjustment
+      const testStartMs = Date.now();
       let calls: string[] = [];
       const testBudgetMs = testTimeout(10_000);
       const pollTimeoutMs = Math.min(testBudgetMs, Math.max(1_000, testBudgetMs - 5_000));
-      const deadline = Date.now() + pollTimeoutMs;
+      const deadline = Date.now() + pollTimeoutMs;
       while (Date.now() < deadline) {
         calls = readCalls();
         if (
           calls.includes("logs alpha -n 200 --source all --tail") &&
           calls.includes("sandbox exec -n alpha -- tail -n 200 -f /tmp/gateway.log")
         ) {
           break;
         }
         await new Promise((resolve) => setTimeout(resolve, 100));
       }

       expect(calls).toContain("logs alpha -n 200 --source all --tail");
       expect(calls).toContain("sandbox exec -n alpha -- tail -n 200 -f /tmp/gateway.log");
       child.kill("SIGTERM");

       let callsAfterTerm: string[] = [];
-      const termTimeoutMs = Math.min(testBudgetMs, Math.max(1_000, testBudgetMs - 5_000));
+      const elapsedMs = Date.now() - testStartMs;
+      const remainingBudgetMs = Math.max(1_000, testBudgetMs - elapsedMs - 250);
+      const termTimeoutMs = remainingBudgetMs;
       const termDeadline = Date.now() + termTimeoutMs;
       while (Date.now() < termDeadline) {
         callsAfterTerm = readCalls();
         if (callsAfterTerm.some((call) => call.endsWith("term-start")) || hasExited) {
           break;
         }
         await new Promise((resolve) => setTimeout(resolve, 50));
       }

Also applies to: 2262-2265, 2280-2282

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/cli.test.ts` around lines 2197 - 2199, The current polling budget uses
the full testBudgetMs (10_000) across both pre- and post-SIGTERM phases which
can exhaust the test timeout; change the poll timeout calculation to reserve a
safety buffer (e.g., subtract 2000ms or a configurable SLACK_MS) so both phases
never collectively consume the entire budget. Update the computation that sets
pollTimeoutMs and deadline (variables testBudgetMs, pollTimeoutMs, deadline) to
compute pollTimeoutMs = Math.min(testBudgetMs - SLACK_MS, Math.max(1_000,
testBudgetMs - 5_000)) (ensuring non-negative) or otherwise subtract SLACK_MS
before using testBudgetMs for a second-phase deadline; apply the same change at
the other occurrences noted (the blocks around the other three locations).

@cv cv merged commit 4b47ab4 into main May 12, 2026
27 checks passed
@cv cv deleted the perf/onboard-test-mocks branch May 27, 2026 21:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v0.0.40 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants