Skip to content

perf: batch chroot integration tests to reduce container overhead#845

Merged
Mossaka merged 3 commits intomainfrom
feat/optimize-chroot-tests
Feb 13, 2026
Merged

perf: batch chroot integration tests to reduce container overhead#845
Mossaka merged 3 commits intomainfrom
feat/optimize-chroot-tests

Conversation

@Mossaka
Copy link
Collaborator

@Mossaka Mossaka commented Feb 13, 2026

Summary

  • Adds tests/fixtures/batch-runner.ts — a utility that batches multiple shell commands into a single AWF container invocation with structured delimiters, then parses per-command results
  • Refactors all 5 chroot test files to batch commands sharing the same allowDomains config, while preserving individual test reporting in Jest
  • Removes serial CI dependency (needs: test-chroot-languages) from test-chroot-procfs and test-chroot-edge-cases jobs, allowing 3 of 4 jobs to start immediately in parallel

Invocation counts

Test File Before After Saved
chroot-languages 20 4 16
chroot-edge-cases 19 8 11
chroot-procfs 8 2 6
chroot-package-managers 23 12 11
chroot-copilot-home 3 1 2
Total 73 ~27 ~46

At ~15-25s container overhead per invocation, this saves ~11-19 minutes of pure Docker lifecycle time.

Tests that require individual invocations (exit code propagation, blocking tests, different containerWorkDir options) remain unbatched.

Test plan

  • npm run build passes
  • npm run lint passes (0 errors)
  • npm test — all 785 unit tests pass
  • CI: chroot-languages job passes
  • CI: chroot-edge-cases job passes
  • CI: chroot-procfs job passes
  • CI: chroot-package-managers job passes

🤖 Generated with Claude Code

Each chroot test previously spawned a fresh Docker container pair (Squid +
Agent), adding ~15-25s of overhead per test. With ~73 tests, container
lifecycle alone accounted for 17-29 minutes.

This introduces a batch runner utility that combines multiple commands
sharing the same allowDomains config into a single AWF invocation with
structured output delimiters. Individual test cases still appear in Jest
output via beforeAll/test pattern.

Changes:
- Add tests/fixtures/batch-runner.ts: generates batched shell scripts,
  parses per-command results from delimited output
- Refactor all 5 chroot test files to batch compatible commands:
  - chroot-languages: 20 → 4 invocations
  - chroot-edge-cases: 19 → 8 invocations
  - chroot-procfs: 8 → 2 invocations
  - chroot-package-managers: 23 → 12 invocations
  - chroot-copilot-home: 3 → 1 invocation
- Remove needs: test-chroot-languages from procfs and edge-cases CI jobs
  so 3 of 4 jobs run in parallel immediately

Total: ~73 → ~27 AWF invocations (~63% reduction)
Estimated time saved: 11-19 minutes of container overhead

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 13, 2026 22:24
@github-actions
Copy link
Contributor

github-actions bot commented Feb 13, 2026

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@github-actions
Copy link
Contributor

github-actions bot commented Feb 13, 2026

🎬 THE ENDSmoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨

@github-actions
Copy link
Contributor

github-actions bot commented Feb 13, 2026

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

@github-actions
Copy link
Contributor

github-actions bot commented Feb 13, 2026

✅ Coverage Check Passed

Overall Coverage

Metric Base PR Delta
Lines 82.82% 82.97% 📈 +0.15%
Statements 82.81% 82.96% 📈 +0.15%
Functions 82.74% 82.74% ➡️ +0.00%
Branches 74.87% 74.97% 📈 +0.10%
📁 Per-file Coverage Changes (1 files)
File Lines (Before → After) Statements (Before → After)
src/docker-manager.ts 84.7% → 85.3% (+0.61%) 84.1% → 84.7% (+0.59%)

Coverage comparison generated by scripts/ci/compare-coverage.ts

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR reduces Docker container startup overhead in the chroot integration test suite by batching multiple shell commands into fewer AWF invocations, while keeping per-test assertions in Jest. It also updates the CI workflow to run more of the chroot jobs in parallel.

Changes:

  • Added a runBatch utility to execute multiple commands in one AWF container run and parse per-command results.
  • Refactored 5 chroot integration test files to use batching where allowDomains/options are shared.
  • Removed workflow job dependencies so /proc and edge-case chroot tests can start without waiting on language tests.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/fixtures/batch-runner.ts New batching helper that generates a delimited bash script and parses per-command stdout/exit codes.
tests/integration/chroot-procfs.test.ts Batches quick /proc checks and Java /proc validation into two AWF invocations.
tests/integration/chroot-package-managers.test.ts Batches package-manager commands by shared domain allowlists to reduce invocations.
tests/integration/chroot-languages.test.ts Batches quick language/version checks into one invocation; keeps longer compile tests unbatched.
tests/integration/chroot-edge-cases.test.ts Batches general localhost-only checks; keeps workdir/exit-code/network tests individual.
tests/integration/chroot-copilot-home.test.ts Batches Copilot home directory write/permission checks into a single invocation.
.github/workflows/test-chroot.yml Removes needs: test-chroot-languages from /proc and edge-case jobs to increase CI parallelism.
Comments suppressed due to low confidence (1)

tests/fixtures/batch-runner.ts:72

  • parseResults builds a RegExp using cmd.name without escaping it. If a name contains regex metacharacters (e.g., ., +, ?, [), the exit marker match can be incorrect or fail entirely. Escape cmd.name for regex (similar to how EXIT is escaped) or validate names to a restricted character set before use.
    const startToken = `${START}${cmd.name}${DELIM_END}`;
    const exitPattern = new RegExp(`${EXIT.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}${cmd.name}:(\\d+)${DELIM_END}`);

    const startIdx = stdout.indexOf(startToken);
    const exitMatch = stdout.match(exitPattern);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 47 to 56
function generateScript(commands: BatchCommand[]): string {
return commands.map(cmd => {
// Each command runs in a subshell so failures don't abort the batch.
// stdout and stderr are merged (2>&1) so we capture everything.
// A blank echo before the EXIT marker ensures a newline separator.
return [
`echo "${START}${cmd.name}${DELIM_END}"`,
`(${cmd.command}) 2>&1`,
`echo ""`,
`echo "${EXIT}${cmd.name}:$?${DELIM_END}"`,
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

cmd.name is interpolated directly into a double-quoted echo in the generated bash script. If a caller passes a name containing characters like ", $, backticks, or newlines, it can break the script and/or spoof delimiter lines, which will corrupt parsing. Consider validating name against a strict safe pattern (e.g., ^[A-Za-z0-9_\-]+$) and throwing early (or properly escaping for bash) before generating the script.

This issue also appears on line 68 of the same file.

Copilot uses AI. Check for mistakes.
Comment on lines +71 to +82
const startIdx = stdout.indexOf(startToken);
const exitMatch = stdout.match(exitPattern);

if (startIdx === -1 || !exitMatch) {
// Command output not found – likely the batch was killed early
results.set(cmd.name, { stdout: '', exitCode: -1 });
continue;
}

const contentStart = startIdx + startToken.length;
const contentEnd = stdout.indexOf(exitMatch[0], contentStart) - 1; // -1 for the blank line
const cmdStdout = stdout.slice(contentStart, contentEnd).trim();
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

exitMatch is found via stdout.match(exitPattern), which returns the first match in the whole batch output. If commands contains duplicate names, the second instance will reuse the first instance's exit marker; then stdout.indexOf(exitMatch[0], contentStart) can be -1 and slicing will produce incorrect output/exitCode. Either enforce unique names up front (throw on duplicates) or change parsing to search for the exit marker after the corresponding start token.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Contributor

Node.js Build Test Results

Project Install Tests Status
clsx PASS PASS
execa PASS PASS
p-limit PASS PASS

Overall: PASS

All Node.js test projects successfully installed dependencies and passed their test suites.

AI generated by Build Test Node.js

@github-actions
Copy link
Contributor

C++ Build Test Results

Project CMake Build Status
fmt PASS
json PASS

Overall: PASS

All C++ projects built successfully.

AI generated by Build Test C++

@github-actions
Copy link
Contributor

Smoke Test Results

Last 2 merged PRs:

  • fix: add roles: all to smoke-codex workflow
  • fix(squid): add api-proxy support (ports 10000/10001, IP 172.30.0.30)

✅ GitHub MCP
✅ Playwright (page title: "GitHub · Change is constant. GitHub keeps you ahead. · GitHub")
✅ File writing
✅ Bash tool

Overall: PASS

AI generated by Smoke Claude

@github-actions
Copy link
Contributor

Deno Build Test Results

Project Tests Status
oak 1/1 ✅ PASS
std 1/1 ✅ PASS

Overall: ✅ PASS

All Deno tests completed successfully.

AI generated by Build Test Deno

@github-actions
Copy link
Contributor

Smoke Test Results (Copilot) ✅

Last 2 merged PRs:

✅ GitHub MCP: Retrieved PR data
✅ Playwright: Page title contains "GitHub"
✅ File Write: Created test file successfully
✅ Bash Tool: Verified file contents

Overall: PASS

cc @Mossaka

AI generated by Smoke Copilot

@github-actions
Copy link
Contributor

Go Build Test Results

Project Download Tests Status
color 1/1 PASS
env 1/1 PASS
uuid 1/1 PASS

Overall: PASS

All Go projects successfully downloaded dependencies and passed their tests.

AI generated by Build Test Go

@github-actions
Copy link
Contributor

Bun Build Test Results

Project Install Tests Status
elysia 1/1 PASS
hono 1/1 PASS

Overall: PASS

All Bun projects built and tested successfully.

AI generated by Build Test Bun

@github-actions
Copy link
Contributor

.NET Build Test Results

Project Restore Build Run Status
hello-world PASS
json-parse PASS

Overall: PASS

All .NET projects successfully restored dependencies, built, and ran without errors.

AI generated by Build Test .NET

@github-actions
Copy link
Contributor

Merged PRs: fix: add roles: all to smoke-codex workflow; fix(ci): add missing ANTHROPIC_API_KEY to detection job
GitHub MCP (last 2 merged PRs): ✅
safeinputs-gh pr list: ✅
Playwright title check: ✅
Tavily search: ❌
File write + cat: ✅
Discussion comment: ✅
Build (npm ci && npm run build): ✅
Overall: FAIL

AI generated by Smoke Codex

@github-actions
Copy link
Contributor

Rust Build Test Results

Project Build Tests Status
fd 1/1 PASS
zoxide 1/1 PASS

Overall: PASS

All Rust projects built and tested successfully.

AI generated by Build Test Rust

@github-actions
Copy link
Contributor

Java Build Test Results ✅

All Java projects compiled and tested successfully through the AWF firewall.

Project Compile Tests Status
gson 1/1 PASS
caffeine 1/1 PASS

Overall: PASS

Configuration Notes

  • Maven proxy configured with IP address 172.30.0.10:3128 in ~/.m2/settings.xml
  • Successfully downloaded dependencies from Maven Central through Squid proxy
  • All tests executed without errors

AI generated by Build Test Java

@github-actions
Copy link
Contributor

github-actions bot commented Feb 13, 2026

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

@github-actions
Copy link
Contributor

github-actions bot commented Feb 13, 2026

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@github-actions
Copy link
Contributor

C++ Build Test Results

Project CMake Build Status
fmt PASS
json PASS

Overall: PASS

All C++ projects built successfully.

AI generated by Build Test C++

@github-actions
Copy link
Contributor

Build Test Results: Node.js

All Node.js test projects passed successfully! ✅

Project Install Tests Status
clsx PASS PASS
execa PASS PASS
p-limit PASS PASS

Overall: PASS

AI generated by Build Test Node.js

@github-actions
Copy link
Contributor

Smoke Test Results 🟢

✅ GitHub MCP: #843, #841
✅ Playwright: GitHub page verified
✅ File Write: /tmp/gh-aw/agent/smoke-test-copilot-22005253118.txt
✅ Bash: File verified

Status: PASS

cc @Mossaka

AI generated by Smoke Copilot

@github-actions
Copy link
Contributor

Bun Build Test Results

Project Install Tests Status
elysia 1/1 PASS ✅
hono 1/1 PASS ✅

Overall: PASS ✅

All Bun projects installed and tested successfully.

AI generated by Build Test Bun

@github-actions
Copy link
Contributor

.NET Build Test Results

Project Restore Build Run Status
hello-world PASS
json-parse PASS

Overall: PASS

All .NET projects built and ran successfully. NuGet package restore completed without errors.

AI generated by Build Test .NET

@github-actions
Copy link
Contributor

Go Build Test Results

Project Download Tests Status
color 1/1 PASS
env 1/1 PASS
uuid 1/1 PASS

Overall: PASS

All Go projects successfully downloaded dependencies and passed their test suites.

AI generated by Build Test Go

@github-actions
Copy link
Contributor

Rust Build Test Results

Project Build Tests Status
fd 1/1 PASS
zoxide 1/1 PASS

Overall: PASS

All Rust projects built and tested successfully.

AI generated by Build Test Rust

@github-actions
Copy link
Contributor

PR titles: fix: fix API proxy sidecar bugs preventing Anthropic-only usage | fix: add roles: all to smoke-codex workflow
GitHub MCP (last 2 merged PRs): ✅
safeinputs-gh PR list: ✅
Playwright title check: ✅
Tavily search: ❌ (tool unavailable)
File write: ✅
Bash cat verify: ✅
Discussion comment: ✅
Build (npm ci && npm run build): ✅
Overall: FAIL

AI generated by Smoke Codex

@github-actions
Copy link
Contributor

Java Build Test Results ✅

Project Compile Tests Status
gson 1/1 PASS
caffeine 1/1 PASS

Overall: PASS

All Java projects compiled and tested successfully through the firewall.

AI generated by Build Test Java

@github-actions
Copy link
Contributor

github-actions bot commented Feb 13, 2026

🎬 THE ENDSmoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨

@github-actions
Copy link
Contributor

github-actions bot commented Feb 13, 2026

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@github-actions
Copy link
Contributor

github-actions bot commented Feb 13, 2026

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

@github-actions
Copy link
Contributor

Bun Build Test Results ✅

Project Install Tests Status
elysia 1/1 PASS
hono 1/1 PASS

Overall: PASS

All Bun projects built and tested successfully.

AI generated by Build Test Bun

@github-actions
Copy link
Contributor

C++ Build Test Results

Project CMake Build Status
fmt PASS
json PASS

Overall: PASS

All C++ projects built successfully.

AI generated by Build Test C++

@github-actions
Copy link
Contributor

Smoke Test Results (Claude)

Last 2 Merged PRs:

Test Results:

  • ✅ GitHub MCP: Retrieved PR data
  • ✅ Playwright: GitHub page loaded (title verified)
  • ✅ File Write: Created smoke-test-claude-22006106402.txt
  • ✅ Bash: File content verified

Status: PASS

AI generated by Smoke Claude

@github-actions
Copy link
Contributor

Build Test: Go - Results

Project Download Tests Status
color 1/1 PASS
env 1/1 PASS
uuid 1/1 PASS

Overall: PASS

All Go projects successfully downloaded dependencies and passed tests.

AI generated by Build Test Go

@github-actions
Copy link
Contributor

.NET Build Test Results

Project Restore Build Run Status
hello-world PASS
json-parse PASS

Overall: PASS

All .NET projects successfully restored, built, and ran.

AI generated by Build Test .NET

@github-actions
Copy link
Contributor

Deno Build Test Results

Project Tests Status
oak 1/1 ✅ PASS
std 1/1 ✅ PASS

Overall: ✅ PASS

All Deno tests completed successfully.

AI generated by Build Test Deno

@github-actions
Copy link
Contributor

Java Build Test Results

Project Compile Tests Status
gson 1/1 PASS
caffeine 1/1 PASS

Overall: PASS

All Java projects compiled successfully and all tests passed.

AI generated by Build Test Java

@github-actions
Copy link
Contributor

Rust Build Test Results

Project Build Tests Status
fd 1/1 PASS
zoxide 1/1 PASS

Overall: PASS

All Rust projects built and tested successfully.

AI generated by Build Test Rust

@github-actions
Copy link
Contributor

Smoke Test Results (Copilot)

Recent PRs:

Test Results:

  • ✅ GitHub MCP: Retrieved 2 merged PRs
  • ❌ Playwright: GitHub blocked automated access (timeout)
  • ✅ File Write: Created test file successfully
  • ✅ Bash Tool: Verified file content

Status: PARTIAL - 3/4 tests passed (Playwright blocked by GitHub anti-bot)

cc @Mossaka

AI generated by Smoke Copilot

@github-actions
Copy link
Contributor

PR titles:
perf: batch chroot integration tests to reduce container overhead
feat: kong proxy for codex
Tests: MCP-merged ✅ | gh-pr-list ✅ | Playwright ✅ | Tavily ❌
Tests: File-write ✅ | File-read ✅ | Discussion ✅ | Build ✅
Overall: FAIL

AI generated by Smoke Codex

@Mossaka Mossaka merged commit 89456df into main Feb 13, 2026
84 checks passed
@Mossaka Mossaka deleted the feat/optimize-chroot-tests branch February 13, 2026 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant