test: add REST API E2E auth matrix and coverage tooling#746
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughTest specs for ChangesWebSocket Proxy Auth Test Refactor
E2E Test Infrastructure Refactoring and SDK Coverage Expansion
Estimated code review effort🎯 4 (Complex) | ⏱️ ~70 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Merging the substantive bits of #745 and #746 here so PR #724's deploy-app-services CI can actually push an otel-collector image: * otel-collector/builder-config.yaml: fix module paths after #730 moved everything under apps/ (was: ../../../api-client-go etc., now: ../../../apps/api-client-go). The OCB build was failing with `filepath does not exist: /boxlite/otel-collector/exporter`. (#745) * otel-collector/Dockerfile: apk add python3 make g++ so node-gyp can compile any musl-incompatible native add-on during workspace `yarn install`. Kept even after dropping dockerode below — small safety net in case future deps reintroduce a native build. (#745) * apps/package.json: drop unused dockerode + @types/dockerode. They were inherited from the Daytona import in #460 but never imported in source. Drops the dockerode -> docker-modem -> ssh2 -> cpu-features chain; cpu-features was the optional native addon that forced the toolchain workaround in the first place. (#746) * apps/yarn.lock: regenerated (-161 lines). * apps/api-client-go/api/openapi.yaml: regenerate to catch up with main's existing `assignedRoleIds.default: []` drift so the api-client-drift PR check passes.
|
Closing — see follow-up plan |
Merging the substantive bits of #745 and #746 here so PR #724's deploy-app-services CI can actually push an otel-collector image: * otel-collector/builder-config.yaml: fix module paths after #730 moved everything under apps/ (was: ../../../api-client-go etc., now: ../../../apps/api-client-go). The OCB build was failing with `filepath does not exist: /boxlite/otel-collector/exporter`. (#745) * otel-collector/Dockerfile: apk add python3 make g++ so node-gyp can compile any musl-incompatible native add-on during workspace `yarn install`. Kept even after dropping dockerode below — small safety net in case future deps reintroduce a native build. (#745) * apps/package.json: drop unused dockerode + @types/dockerode. They were inherited from the Daytona import in #460 but never imported in source. Drops the dockerode -> docker-modem -> ssh2 -> cpu-features chain; cpu-features was the optional native addon that forced the toolchain workaround in the first place. (#746) * apps/yarn.lock: regenerated (-161 lines). * apps/api-client-go/api/openapi.yaml: regenerate to catch up with main's existing `assignedRoleIds.default: []` drift so the api-client-drift PR check passes.
Merging the substantive bits of #745 and #746 here so PR #724's deploy-app-services CI can actually push an otel-collector image: * otel-collector/builder-config.yaml: fix module paths after #730 moved everything under apps/ (was: ../../../api-client-go etc., now: ../../../apps/api-client-go). The OCB build was failing with `filepath does not exist: /boxlite/otel-collector/exporter`. (#745) * otel-collector/Dockerfile: apk add python3 make g++ so node-gyp can compile any musl-incompatible native add-on during workspace `yarn install`. Kept even after dropping dockerode below — small safety net in case future deps reintroduce a native build. (#745) * apps/package.json: drop unused dockerode + @types/dockerode. They were inherited from the Daytona import in #460 but never imported in source. Drops the dockerode -> docker-modem -> ssh2 -> cpu-features chain; cpu-features was the optional native addon that forced the toolchain workaround in the first place. (#746) * apps/yarn.lock: regenerated (-161 lines). * apps/api-client-go/api/openapi.yaml: regenerate to catch up with main's existing `assignedRoleIds.default: []` drift so the api-client-drift PR check passes.
Merging the substantive bits of #745 and #746 here so PR #724's deploy-app-services CI can actually push an otel-collector image: * otel-collector/builder-config.yaml: fix module paths after #730 moved everything under apps/ (was: ../../../api-client-go etc., now: ../../../apps/api-client-go). The OCB build was failing with `filepath does not exist: /boxlite/otel-collector/exporter`. (#745) * otel-collector/Dockerfile: apk add python3 make g++ so node-gyp can compile any musl-incompatible native add-on during workspace `yarn install`. Kept even after dropping dockerode below — small safety net in case future deps reintroduce a native build. (#745) * apps/package.json: drop unused dockerode + @types/dockerode. They were inherited from the Daytona import in #460 but never imported in source. Drops the dockerode -> docker-modem -> ssh2 -> cpu-features chain; cpu-features was the optional native addon that forced the toolchain workaround in the first place. (#746) * apps/yarn.lock: regenerated (-161 lines). * apps/api-client-go/api/openapi.yaml: regenerate to catch up with main's existing `assignedRoleIds.default: []` drift so the api-client-drift PR check passes.
Merging the substantive bits of #745 and #746 here so PR #724's deploy-app-services CI can actually push an otel-collector image: * otel-collector/builder-config.yaml: fix module paths after #730 moved everything under apps/ (was: ../../../api-client-go etc., now: ../../../apps/api-client-go). The OCB build was failing with `filepath does not exist: /boxlite/otel-collector/exporter`. (#745) * otel-collector/Dockerfile: apk add python3 make g++ so node-gyp can compile any musl-incompatible native add-on during workspace `yarn install`. Kept even after dropping dockerode below — small safety net in case future deps reintroduce a native build. (#745) * apps/package.json: drop unused dockerode + @types/dockerode. They were inherited from the Daytona import in #460 but never imported in source. Drops the dockerode -> docker-modem -> ssh2 -> cpu-features chain; cpu-features was the optional native addon that forced the toolchain workaround in the first place. (#746) * apps/yarn.lock: regenerated (-161 lines). * apps/api-client-go/api/openapi.yaml: regenerate to catch up with main's existing `assignedRoleIds.default: []` drift so the api-client-drift PR check passes.
Merging the substantive bits of #745 and #746 here so PR #724's deploy-app-services CI can actually push an otel-collector image: * otel-collector/builder-config.yaml: fix module paths after #730 moved everything under apps/ (was: ../../../api-client-go etc., now: ../../../apps/api-client-go). The OCB build was failing with `filepath does not exist: /boxlite/otel-collector/exporter`. (#745) * otel-collector/Dockerfile: apk add python3 make g++ so node-gyp can compile any musl-incompatible native add-on during workspace `yarn install`. Kept even after dropping dockerode below — small safety net in case future deps reintroduce a native build. (#745) * apps/package.json: drop unused dockerode + @types/dockerode. They were inherited from the Daytona import in #460 but never imported in source. Drops the dockerode -> docker-modem -> ssh2 -> cpu-features chain; cpu-features was the optional native addon that forced the toolchain workaround in the first place. (#746) * apps/yarn.lock: regenerated (-161 lines). * apps/api-client-go/api/openapi.yaml: regenerate to catch up with main's existing `assignedRoleIds.default: []` drift so the api-client-drift PR check passes.
Merging the substantive bits of #745 and #746 here so PR #724's deploy-app-services CI can actually push an otel-collector image: * otel-collector/builder-config.yaml: fix module paths after #730 moved everything under apps/ (was: ../../../api-client-go etc., now: ../../../apps/api-client-go). The OCB build was failing with `filepath does not exist: /boxlite/otel-collector/exporter`. (#745) * otel-collector/Dockerfile: apk add python3 make g++ so node-gyp can compile any musl-incompatible native add-on during workspace `yarn install`. Kept even after dropping dockerode below — small safety net in case future deps reintroduce a native build. (#745) * apps/package.json: drop unused dockerode + @types/dockerode. They were inherited from the Daytona import in #460 but never imported in source. Drops the dockerode -> docker-modem -> ssh2 -> cpu-features chain; cpu-features was the optional native addon that forced the toolchain workaround in the first place. (#746) * apps/yarn.lock: regenerated (-161 lines). * apps/api-client-go/api/openapi.yaml: regenerate to catch up with main's existing `assignedRoleIds.default: []` drift so the api-client-drift PR check passes.
The chore stack's #745+#746 fold (f3355c2) inadvertently changed WORKDIR /boxlite/apps to WORKDIR /boxlite while leaving ENV GOWORK=/boxlite/apps/go.work unchanged. Subsequent `COPY apps/go.work ./` then lands the file at /boxlite/go.work (not /boxlite/apps/go.work), and `go -C otel-collector/exporter mod download` fails with: go: reading go.work: open ../../apps/go.work: no such file or directory main + apps/proxy/Dockerfile + apps/ssh-gateway/Dockerfile all use WORKDIR /boxlite/apps; restore that here. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merging the substantive bits of #745 and #746 here so PR #724's deploy-app-services CI can actually push an otel-collector image: * otel-collector/builder-config.yaml: fix module paths after #730 moved everything under apps/ (was: ../../../api-client-go etc., now: ../../../apps/api-client-go). The OCB build was failing with `filepath does not exist: /boxlite/otel-collector/exporter`. (#745) * otel-collector/Dockerfile: apk add python3 make g++ so node-gyp can compile any musl-incompatible native add-on during workspace `yarn install`. Kept even after dropping dockerode below — small safety net in case future deps reintroduce a native build. (#745) * apps/package.json: drop unused dockerode + @types/dockerode. They were inherited from the Daytona import in #460 but never imported in source. Drops the dockerode -> docker-modem -> ssh2 -> cpu-features chain; cpu-features was the optional native addon that forced the toolchain workaround in the first place. (#746) * apps/yarn.lock: regenerated (-161 lines). * apps/api-client-go/api/openapi.yaml: regenerate to catch up with main's existing `assignedRoleIds.default: []` drift so the api-client-drift PR check passes.
The chore stack's #745+#746 fold (f3355c2) inadvertently changed WORKDIR /boxlite/apps to WORKDIR /boxlite while leaving ENV GOWORK=/boxlite/apps/go.work unchanged. Subsequent `COPY apps/go.work ./` then lands the file at /boxlite/go.work (not /boxlite/apps/go.work), and `go -C otel-collector/exporter mod download` fails with: go: reading go.work: open ../../apps/go.work: no such file or directory main + apps/proxy/Dockerfile + apps/ssh-gateway/Dockerfile all use WORKDIR /boxlite/apps; restore that here. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…/apps The chore stack's #745+#746 fold (f3355c2) changed WORKDIR /boxlite/apps to WORKDIR /boxlite and rewrote builder-config.yaml paths to compensate (apps/otel-collector/exporter, ../../../apps/api-client-go). The earlier otel WORKDIR fix (5aa5340) restored WORKDIR /boxlite/apps but left builder-config still keyed off the /boxlite assumption — OCB now resolves `apps/otel-collector/exporter` relative to /boxlite/apps and looks for /boxlite/apps/apps/otel-collector/exporter (doubled apps/), failing with `invalid module configuration: filepath does not exist`. Restore main-aligned paths so OCB walks from /boxlite/apps: path: otel-collector/exporter replaces: ../../../api-client-go replaces: ../../../common-go Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merging the substantive bits of #745 and #746 here so PR #724's deploy-app-services CI can actually push an otel-collector image: * otel-collector/builder-config.yaml: fix module paths after #730 moved everything under apps/ (was: ../../../api-client-go etc., now: ../../../apps/api-client-go). The OCB build was failing with `filepath does not exist: /boxlite/otel-collector/exporter`. (#745) * otel-collector/Dockerfile: apk add python3 make g++ so node-gyp can compile any musl-incompatible native add-on during workspace `yarn install`. Kept even after dropping dockerode below — small safety net in case future deps reintroduce a native build. (#745) * apps/package.json: drop unused dockerode + @types/dockerode. They were inherited from the Daytona import in #460 but never imported in source. Drops the dockerode -> docker-modem -> ssh2 -> cpu-features chain; cpu-features was the optional native addon that forced the toolchain workaround in the first place. (#746) * apps/yarn.lock: regenerated (-161 lines). * apps/api-client-go/api/openapi.yaml: regenerate to catch up with main's existing `assignedRoleIds.default: []` drift so the api-client-drift PR check passes.
The chore stack's #745+#746 fold (f3355c2) inadvertently changed WORKDIR /boxlite/apps to WORKDIR /boxlite while leaving ENV GOWORK=/boxlite/apps/go.work unchanged. Subsequent `COPY apps/go.work ./` then lands the file at /boxlite/go.work (not /boxlite/apps/go.work), and `go -C otel-collector/exporter mod download` fails with: go: reading go.work: open ../../apps/go.work: no such file or directory main + apps/proxy/Dockerfile + apps/ssh-gateway/Dockerfile all use WORKDIR /boxlite/apps; restore that here. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…/apps The chore stack's #745+#746 fold (f3355c2) changed WORKDIR /boxlite/apps to WORKDIR /boxlite and rewrote builder-config.yaml paths to compensate (apps/otel-collector/exporter, ../../../apps/api-client-go). The earlier otel WORKDIR fix (5aa5340) restored WORKDIR /boxlite/apps but left builder-config still keyed off the /boxlite assumption — OCB now resolves `apps/otel-collector/exporter` relative to /boxlite/apps and looks for /boxlite/apps/apps/otel-collector/exporter (doubled apps/), failing with `invalid module configuration: filepath does not exist`. Restore main-aligned paths so OCB walks from /boxlite/apps: path: otel-collector/exporter replaces: ../../../api-client-go replaces: ../../../common-go Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merging the substantive bits of #745 and #746 here so PR #724's deploy-app-services CI can actually push an otel-collector image: * otel-collector/builder-config.yaml: fix module paths after #730 moved everything under apps/ (was: ../../../api-client-go etc., now: ../../../apps/api-client-go). The OCB build was failing with `filepath does not exist: /boxlite/otel-collector/exporter`. (#745) * otel-collector/Dockerfile: apk add python3 make g++ so node-gyp can compile any musl-incompatible native add-on during workspace `yarn install`. Kept even after dropping dockerode below — small safety net in case future deps reintroduce a native build. (#745) * apps/package.json: drop unused dockerode + @types/dockerode. They were inherited from the Daytona import in #460 but never imported in source. Drops the dockerode -> docker-modem -> ssh2 -> cpu-features chain; cpu-features was the optional native addon that forced the toolchain workaround in the first place. (#746) * apps/yarn.lock: regenerated (-161 lines). * apps/api-client-go/api/openapi.yaml: regenerate to catch up with main's existing `assignedRoleIds.default: []` drift so the api-client-drift PR check passes.
The chore stack's #745+#746 fold (f3355c2) inadvertently changed WORKDIR /boxlite/apps to WORKDIR /boxlite while leaving ENV GOWORK=/boxlite/apps/go.work unchanged. Subsequent `COPY apps/go.work ./` then lands the file at /boxlite/go.work (not /boxlite/apps/go.work), and `go -C otel-collector/exporter mod download` fails with: go: reading go.work: open ../../apps/go.work: no such file or directory main + apps/proxy/Dockerfile + apps/ssh-gateway/Dockerfile all use WORKDIR /boxlite/apps; restore that here. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…/apps The chore stack's #745+#746 fold (f3355c2) changed WORKDIR /boxlite/apps to WORKDIR /boxlite and rewrote builder-config.yaml paths to compensate (apps/otel-collector/exporter, ../../../apps/api-client-go). The earlier otel WORKDIR fix (5aa5340) restored WORKDIR /boxlite/apps but left builder-config still keyed off the /boxlite assumption — OCB now resolves `apps/otel-collector/exporter` relative to /boxlite/apps and looks for /boxlite/apps/apps/otel-collector/exporter (doubled apps/), failing with `invalid module configuration: filepath does not exist`. Restore main-aligned paths so OCB walks from /boxlite/apps: path: otel-collector/exporter replaces: ../../../api-client-go replaces: ../../../common-go Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merging the substantive bits of #745 and #746 here so PR #724's deploy-app-services CI can actually push an otel-collector image: * otel-collector/builder-config.yaml: fix module paths after #730 moved everything under apps/ (was: ../../../api-client-go etc., now: ../../../apps/api-client-go). The OCB build was failing with `filepath does not exist: /boxlite/otel-collector/exporter`. (#745) * otel-collector/Dockerfile: apk add python3 make g++ so node-gyp can compile any musl-incompatible native add-on during workspace `yarn install`. Kept even after dropping dockerode below — small safety net in case future deps reintroduce a native build. (#745) * apps/package.json: drop unused dockerode + @types/dockerode. They were inherited from the Daytona import in #460 but never imported in source. Drops the dockerode -> docker-modem -> ssh2 -> cpu-features chain; cpu-features was the optional native addon that forced the toolchain workaround in the first place. (#746) * apps/yarn.lock: regenerated (-161 lines). * apps/api-client-go/api/openapi.yaml: regenerate to catch up with main's existing `assignedRoleIds.default: []` drift so the api-client-drift PR check passes.
The chore stack's #745+#746 fold (f3355c2) inadvertently changed WORKDIR /boxlite/apps to WORKDIR /boxlite while leaving ENV GOWORK=/boxlite/apps/go.work unchanged. Subsequent `COPY apps/go.work ./` then lands the file at /boxlite/go.work (not /boxlite/apps/go.work), and `go -C otel-collector/exporter mod download` fails with: go: reading go.work: open ../../apps/go.work: no such file or directory main + apps/proxy/Dockerfile + apps/ssh-gateway/Dockerfile all use WORKDIR /boxlite/apps; restore that here. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…/apps The chore stack's #745+#746 fold (f3355c2) changed WORKDIR /boxlite/apps to WORKDIR /boxlite and rewrote builder-config.yaml paths to compensate (apps/otel-collector/exporter, ../../../apps/api-client-go). The earlier otel WORKDIR fix (5aa5340) restored WORKDIR /boxlite/apps but left builder-config still keyed off the /boxlite assumption — OCB now resolves `apps/otel-collector/exporter` relative to /boxlite/apps and looks for /boxlite/apps/apps/otel-collector/exporter (doubled apps/), failing with `invalid module configuration: filepath does not exist`. Restore main-aligned paths so OCB walks from /boxlite/apps: path: otel-collector/exporter replaces: ../../../api-client-go replaces: ../../../common-go Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merging the substantive bits of #745 and #746 here so PR #724's deploy-app-services CI can actually push an otel-collector image: * otel-collector/builder-config.yaml: fix module paths after #730 moved everything under apps/ (was: ../../../api-client-go etc., now: ../../../apps/api-client-go). The OCB build was failing with `filepath does not exist: /boxlite/otel-collector/exporter`. (#745) * otel-collector/Dockerfile: apk add python3 make g++ so node-gyp can compile any musl-incompatible native add-on during workspace `yarn install`. Kept even after dropping dockerode below — small safety net in case future deps reintroduce a native build. (#745) * apps/package.json: drop unused dockerode + @types/dockerode. They were inherited from the Daytona import in #460 but never imported in source. Drops the dockerode -> docker-modem -> ssh2 -> cpu-features chain; cpu-features was the optional native addon that forced the toolchain workaround in the first place. (#746) * apps/yarn.lock: regenerated (-161 lines). * apps/api-client-go/api/openapi.yaml: regenerate to catch up with main's existing `assignedRoleIds.default: []` drift so the api-client-drift PR check passes.
The chore stack's #745+#746 fold (f3355c2) inadvertently changed WORKDIR /boxlite/apps to WORKDIR /boxlite while leaving ENV GOWORK=/boxlite/apps/go.work unchanged. Subsequent `COPY apps/go.work ./` then lands the file at /boxlite/go.work (not /boxlite/apps/go.work), and `go -C otel-collector/exporter mod download` fails with: go: reading go.work: open ../../apps/go.work: no such file or directory main + apps/proxy/Dockerfile + apps/ssh-gateway/Dockerfile all use WORKDIR /boxlite/apps; restore that here. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…/apps The chore stack's #745+#746 fold (f3355c2) changed WORKDIR /boxlite/apps to WORKDIR /boxlite and rewrote builder-config.yaml paths to compensate (apps/otel-collector/exporter, ../../../apps/api-client-go). The earlier otel WORKDIR fix (5aa5340) restored WORKDIR /boxlite/apps but left builder-config still keyed off the /boxlite assumption — OCB now resolves `apps/otel-collector/exporter` relative to /boxlite/apps and looks for /boxlite/apps/apps/otel-collector/exporter (doubled apps/), failing with `invalid module configuration: filepath does not exist`. Restore main-aligned paths so OCB walks from /boxlite/apps: path: otel-collector/exporter replaces: ../../../api-client-go replaces: ../../../common-go Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merging the substantive bits of #745 and #746 here so PR #724's deploy-app-services CI can actually push an otel-collector image: * otel-collector/builder-config.yaml: fix module paths after #730 moved everything under apps/ (was: ../../../api-client-go etc., now: ../../../apps/api-client-go). The OCB build was failing with `filepath does not exist: /boxlite/otel-collector/exporter`. (#745) * otel-collector/Dockerfile: apk add python3 make g++ so node-gyp can compile any musl-incompatible native add-on during workspace `yarn install`. Kept even after dropping dockerode below — small safety net in case future deps reintroduce a native build. (#745) * apps/package.json: drop unused dockerode + @types/dockerode. They were inherited from the Daytona import in #460 but never imported in source. Drops the dockerode -> docker-modem -> ssh2 -> cpu-features chain; cpu-features was the optional native addon that forced the toolchain workaround in the first place. (#746) * apps/yarn.lock: regenerated (-161 lines). * apps/api-client-go/api/openapi.yaml: regenerate to catch up with main's existing `assignedRoleIds.default: []` drift so the api-client-drift PR check passes.
The chore stack's #745+#746 fold (f3355c2) inadvertently changed WORKDIR /boxlite/apps to WORKDIR /boxlite while leaving ENV GOWORK=/boxlite/apps/go.work unchanged. Subsequent `COPY apps/go.work ./` then lands the file at /boxlite/go.work (not /boxlite/apps/go.work), and `go -C otel-collector/exporter mod download` fails with: go: reading go.work: open ../../apps/go.work: no such file or directory main + apps/proxy/Dockerfile + apps/ssh-gateway/Dockerfile all use WORKDIR /boxlite/apps; restore that here. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…/apps The chore stack's #745+#746 fold (f3355c2) changed WORKDIR /boxlite/apps to WORKDIR /boxlite and rewrote builder-config.yaml paths to compensate (apps/otel-collector/exporter, ../../../apps/api-client-go). The earlier otel WORKDIR fix (5aa5340) restored WORKDIR /boxlite/apps but left builder-config still keyed off the /boxlite assumption — OCB now resolves `apps/otel-collector/exporter` relative to /boxlite/apps and looks for /boxlite/apps/apps/otel-collector/exporter (doubled apps/), failing with `invalid module configuration: filepath does not exist`. Restore main-aligned paths so OCB walks from /boxlite/apps: path: otel-collector/exporter replaces: ../../../api-client-go replaces: ../../../common-go Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tests that bypass the conftest box fixture and call the API directly were hardcoding alpine:3.23, which is no longer in the dev environment's supported image allowlist. Import DEFAULT_IMAGE from conftest so these tests exercise the intended validation path (cpu/memory/quota) rather than failing early on image validation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t on quota test - conftest.py: early-return in verify_runner_saw_all_boxes when BOXLITE_E2E_SKIP_PATH_VERIFY=1 (remote runs have no journalctl) - test_error_code_mapping.py: change test_resource_exhausted_over_cpu_quota xfail to strict=False — dev API rejects cpus=999 at DTO layer (400) before quota is consulted, causing unexpected XPASS Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…n quota rejection - test_path_verification.py: check /api presence + reject :8080 instead of requiring :3000, so tests work against both local and remote API - test_error_code_mapping.py: remove xfail on cpus=999 test — API correctly rejects illegal resource values at DTO boundary (400) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- test_path_verification.py: skip test_exec_reaches_runner_journal when BOXLITE_E2E_SKIP_PATH_VERIFY=1 (no local journalctl on remote runs) - test_error_code_mapping.py: accept "not started" / "not running" / "already stopped" in double-stop body (API returns "Box is not started") Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
test_exec_reaches_runner_journal relied on local journalctl to verify SDK→API→Runner chain, which fails on remote deployments. Replace with test_exec_roundtrip_proves_api_to_runner_chain that checks: 1. X-BoxLite-Api-Version header in create response (proves API layer) 2. exec stdout contains expected marker (proves runner executed it) Works against both local and remote API without any env-specific skip. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add exec/copy/errors drivers for Node, Go, C SDKs. Fix CLI tests: BOXLITE_PROFILE env, alphanumeric BOX_ID_RE, remove api-key skip, remove journalctl verification, remove stale xfail on detach. Copy tests xfail(strict) for #563. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5037578 to
939f3b6
Compare
…x, drop stale xfails Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
scripts/test/e2e/sdks/c/e2e_exec.c (1)
59-59:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win
strncpydoes not guarantee null-termination when source exceeds buffer.If
err->messageis >= 511 bytes,strncpywon't write a null terminator, anderr_msg[1..511]are uninitialized. Same pattern at line 97.Proposed fix
- if (err->message) strncpy(ctx->err_msg, err->message, sizeof(ctx->err_msg) - 1); + if (err->message) { + strncpy(ctx->err_msg, err->message, sizeof(ctx->err_msg) - 1); + ctx->err_msg[sizeof(ctx->err_msg) - 1] = '\0'; + }Apply the same fix at line 97 in
on_wait.🤖 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 `@scripts/test/e2e/sdks/c/e2e_exec.c` at line 59, The strncpy call when copying err->message to ctx->err_msg does not guarantee null-termination if the source string is equal to or longer than the buffer size, leaving the buffer without a proper string terminator. After calling strncpy with sizeof(ctx->err_msg) - 1, explicitly null-terminate the buffer by setting ctx->err_msg[sizeof(ctx->err_msg) - 1] = '\0'. Apply this same fix at both locations: the current line 59 and also at line 97 in the on_wait function where the same pattern exists.scripts/test/e2e/fixture_setup.py (1)
7-10:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUpdate stale setup text to match the new image and credential-path behavior.
Line 7 and Line 9 still describe
alpine:3.23and~/.boxlite, but Line 46 and Line 49 now use the pinned agent-base image andBOXLITE_HOMEoverride. Line 195 also logs a hardcoded path that may be wrong.Suggested patch
-Configures: - 1. Required snapshots active (alpine:3.23, ubuntu:22.04) +Configures: + 1. Required snapshots active (ghcr.io/boxlite-ai/boxlite-agent-base:20260605-p0-r3, ubuntu:22.04, ubuntu:24.04) 2. Admin org has non-zero per-box quotas - 3. `[profiles.p1]` in ~/.boxlite/credentials.toml points at the local API + 3. `[profiles.p1]` in credentials.toml (at $BOXLITE_HOME or ~/.boxlite) points at the local API @@ -def ensure_p1_profile(prefix: str): - """Write [profiles.p1] into ~/.boxlite/credentials.toml. Preserves +def ensure_p1_profile(prefix: str): + """Write [profiles.p1] into credentials.toml at CRED_PATH. Preserves other profiles.""" @@ - print(f" ~/.boxlite/credentials.toml: profile p1 → {API_URL} (prefix {prefix})") + print(f" {CRED_PATH}: profile p1/default → {API_URL} (prefix {prefix})")Also applies to: 46-51, 157-159, 195-195
🤖 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 `@scripts/test/e2e/fixture_setup.py` around lines 7 - 10, Update the docstring at the beginning of the file (lines 7-10) to accurately reflect the current implementation behavior. Replace the reference to alpine:3.23 with the correct pinned agent-base image that is actually being used in the fixture setup. Replace the hardcoded ~/.boxlite/credentials.toml path reference with the BOXLITE_HOME environment variable override approach that is shown in the actual setup code at lines 46-51. Also review line 195 where a path is being logged to ensure it reflects the current BOXLITE_HOME behavior and is not using a stale hardcoded path reference.scripts/test/e2e/cases/test_go_coverage.py (1)
55-58:⚠️ Potential issue | 🟠 MajorReplace
pytest.skip()withpytest.fail()for build failures in_run_go().On line 58 of
scripts/test/e2e/cases/test_go_coverage.py,pytest.skip()inside theCalledProcessErrorhandler masks real compilation errors in the Go SDK driver. Ifgois available, compile failures should fail the test, not skip it, to catch regressions.This same pattern exists in multiple test files (
test_c_entry.pyline 56,test_go_entry.pyline 44, andtest_c_coverage.pyline 72) and should be fixed consistently across all of them.Proposed fix for test_go_coverage.py
def _run_go(go_env, src_name: str) -> subprocess.CompletedProcess: try: bin_path = _build_go(src_name) except subprocess.CalledProcessError as e: - pytest.skip(f"go build {src_name} failed: {e.stderr[:400]}") + pytest.fail(f"go build {src_name} failed: {e.stderr[:400]}") return subprocess.run( [str(bin_path)], env=go_env, timeout=180, capture_output=True, text=True, )🤖 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 `@scripts/test/e2e/cases/test_go_coverage.py` around lines 55 - 58, In the exception handler for subprocess.CalledProcessError when calling _build_go(src_name) in the try-except block, replace the pytest.skip() call with pytest.fail() to ensure that Go build failures are properly reported as test failures rather than being silently skipped. This change should be applied consistently across all affected test files: test_go_coverage.py (around the _build_go call), test_c_entry.py (around the corresponding build call), test_go_entry.py (around the corresponding build call), and test_c_coverage.py (around the corresponding build call) to ensure that legitimate compilation errors are caught and reported instead of masked by skip behavior.scripts/test/e2e/cases/test_cli_entry.py (1)
66-72:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
whoamiassertion is too weak and can pass on failure output.This condition accepts output containing only
"boxlite", so messages like “not logged in to boxlite” can incorrectly pass.Proposed change
def test_cli_whoami_against_api(cli): """`boxlite auth whoami` must return identity + server info.""" r = run(cli, "auth", "whoami") out = r.stdout.lower() - assert "logged in" in out or "server" in out or "boxlite" in out, ( - f"whoami output doesn't look like an auth status: {r.stdout!r}" - ) + assert "not logged in" not in out, f"whoami reported unauthenticated state: {r.stdout!r}" + assert "server" in out, f"whoami missing server details: {r.stdout!r}" + assert ("logged in" in out or "authenticated" in out), ( + f"whoami missing authenticated identity signal: {r.stdout!r}" + )🤖 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 `@scripts/test/e2e/cases/test_cli_entry.py` around lines 66 - 72, The assertion in the test_cli_whoami_against_api function is too permissive because checking for just "boxlite" in the output can match failure messages like "not logged in to boxlite". Strengthen the assertion to only accept output that contains "logged in" or "server", which are the indicators of successful authentication status. Remove "boxlite" from the OR condition or restructure the assertion to require more specific keywords that guarantee a successful whoami response rather than just the presence of the application name.
🧹 Nitpick comments (7)
scripts/test/e2e/sdks/c/e2e_exec.c (2)
182-183: 💤 Low valueError results from
boxlite_execution_on_stdoutandboxlite_execution_waitare not checked.These calls pass
&errbut don't verify success. If either fails, the test could hang or produce misleading results.Proposed fix
- boxlite_execution_on_stdout(execution, on_stdout, &ectx, &err); - boxlite_execution_wait(execution, on_wait, &ectx, &err); + if (boxlite_execution_on_stdout(execution, on_stdout, &ectx, &err) != Ok) + DIE("execution_on_stdout: %d %s", err.code, err.message ? err.message : ""); + if (boxlite_execution_wait(execution, on_wait, &ectx, &err) != Ok) + DIE("execution_wait: %d %s", err.code, err.message ? err.message : "");🤖 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 `@scripts/test/e2e/sdks/c/e2e_exec.c` around lines 182 - 183, The calls to boxlite_execution_on_stdout and boxlite_execution_wait both pass an error pointer but do not check whether these operations succeeded. After each function call, verify the error status (check if err indicates a failure) and handle the error appropriately by logging it and skipping or terminating the test execution. This ensures that if either function fails, the test does not proceed with potentially invalid state or hang indefinitely.
132-132: 💤 Low valueConsider checking
pthread_createreturn value.If thread creation fails, the drain loop won't run and the program could hang waiting on condition variables. For robustness, check the return and handle failure.
Proposed fix
- pthread_create(&drain_tid, NULL, drain_loop, &drain_args); + if (pthread_create(&drain_tid, NULL, drain_loop, &drain_args) != 0) + DIE("pthread_create failed");🤖 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 `@scripts/test/e2e/sdks/c/e2e_exec.c` at line 132, The pthread_create call for creating the drain_tid thread does not check the return value for success or failure. Add a return value check after the pthread_create call to verify it returns 0, and implement error handling logic to exit or report the error if thread creation fails (non-zero return value), preventing potential hangs when the drain_loop function never executes.scripts/test/e2e/cases/test_cli_entry.py (1)
33-33: ⚡ Quick winMake box-id extraction deterministic for CLI output.
BOX_ID_RE.search(...)can capture unrelated alphanumeric fragments. Extract from a full line/token intended to be the id.Proposed change
-BOX_ID_RE = re.compile(r"[A-Za-z0-9]{8,36}") +BOX_ID_RE = re.compile(r"^[A-Za-z0-9-]{8,36}$") + +def _extract_box_id(stdout: str) -> str | None: + for line in stdout.splitlines(): + token = line.strip() + if BOX_ID_RE.fullmatch(token): + return token + return None @@ - m = BOX_ID_RE.search(r_run.stdout) - assert m, f"`boxlite run -d` did not print a uuid: {r_run.stdout!r}" - box_id = m.group(0) + box_id = _extract_box_id(r_run.stdout) + assert box_id, f"`boxlite run -d` did not print a box id: {r_run.stdout!r}" @@ - m = BOX_ID_RE.search(r_run.stdout) - assert m - box_id = m.group(0) + box_id = _extract_box_id(r_run.stdout) + assert box_idAlso applies to: 91-93, 123-125
🤖 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 `@scripts/test/e2e/cases/test_cli_entry.py` at line 33, The BOX_ID_RE regex pattern and its usage with .search() is too broad and can match unrelated alphanumeric fragments in the CLI output, making the extraction non-deterministic. Instead of using .search() which finds the pattern anywhere in a string, refactor the box-id extraction logic to extract from complete lines or tokens that are specifically intended to contain the box-id. Update the BOX_ID_RE pattern definition and all its usages (at the initial pattern definition, at lines 91-93, and at lines 123-125) to ensure the extraction targets the full intended identifier token rather than searching within arbitrary text.scripts/test/e2e/cases/test_c_entry.py (1)
28-28: ⚡ Quick winParse
BOX_IDfrom its marker, not from the first alphanumeric match.Current extraction can grab an unrelated token from stdout. Since this test expects a
BOX_IDmarker, parse that marker explicitly to avoid flaky cleanup/journal assertions.Proposed change
-BOX_ID_RE = re.compile(r"[A-Za-z0-9]{8,36}") +BOX_ID_RE = re.compile(r"^BOX_ID=([A-Za-z0-9-]{8,36})$", re.MULTILINE) @@ - m = BOX_ID_RE.search(r.stdout) + m = BOX_ID_RE.search(r.stdout) assert m, f"C driver did not print BOX_ID: {r.stdout!r}" - box_id = m.group(0) + box_id = m.group(1)Also applies to: 78-80
🤖 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 `@scripts/test/e2e/cases/test_c_entry.py` at line 28, The BOX_ID_RE regex pattern at line 28 is too broad and can match unrelated alphanumeric tokens from stdout, causing flaky test behavior. Modify the BOX_ID_RE pattern to explicitly include the BOX_ID marker (e.g., look for "BOX_ID" followed by its value) rather than matching any arbitrary 8-36 character alphanumeric string. Apply the same fix to the similar extraction logic at lines 78-80 to ensure consistent and reliable parsing of the BOX_ID marker.scripts/test/e2e/cases/test_go_entry.py (1)
21-21: ⚡ Quick winPrefer marker-based
BOX_IDparsing in Go entry test output.The current first-match regex can capture unrelated stdout content. Use explicit
BOX_ID=extraction to stabilize the assertion chain.Proposed change
-BOX_ID_RE = re.compile(r"[A-Za-z0-9]{8,36}") +BOX_ID_RE = re.compile(r"^BOX_ID=([A-Za-z0-9-]{8,36})$", re.MULTILINE) @@ - m = BOX_ID_RE.search(r.stdout) + m = BOX_ID_RE.search(r.stdout) assert m, f"go driver did not print BOX_ID: {r.stdout!r}" - box_id = m.group(0) + box_id = m.group(1)Also applies to: 68-70
🤖 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 `@scripts/test/e2e/cases/test_go_entry.py` at line 21, The BOX_ID_RE regex pattern at the BOX_ID_RE definition is too broad and can match unrelated stdout content, making the assertion unstable. Replace the pattern to explicitly match the BOX_ID= marker followed by the ID value instead of just matching any 8-36 character alphanumeric string. This will anchor the pattern to the explicit BOX_ID= prefix, ensuring it only captures the intended output. Apply the same fix to the related parsing logic in lines 68-70 where this pattern is used.scripts/test/e2e/cases/test_node_entry.py (1)
26-26: ⚡ Quick winParse Node driver
BOX_IDvia explicit marker capture.Generic regex search is brittle when stdout contains other long tokens. Marker-based extraction is safer for runner-journal verification.
Proposed change
-BOX_ID_RE = re.compile(r"[A-Za-z0-9]{8,36}") +BOX_ID_RE = re.compile(r"^BOX_ID=([A-Za-z0-9-]{8,36})$", re.MULTILINE) @@ - m = BOX_ID_RE.search(r.stdout) + m = BOX_ID_RE.search(r.stdout) assert m, f"node driver did not print BOX_ID: {r.stdout!r}" - box_id = m.group(0) + box_id = m.group(1)Also applies to: 75-77
🤖 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 `@scripts/test/e2e/cases/test_node_entry.py` at line 26, The BOX_ID_RE regex pattern is too generic and can match unintended tokens in stdout, making the extraction brittle. Replace the generic character pattern with an explicit marker-based capture that matches the actual format used by the Node driver to output BOX_ID (e.g., by including a specific prefix or delimiter that precedes the actual BOX_ID value). Apply this same marker-based approach consistently to all BOX_ID extraction locations, including the additional instances around lines 75-77 referenced in the comment, to ensure robust and reliable runner-journal verification across all extraction points.scripts/test/e2e/cases/test_cli_detach_recovery.py (1)
42-42: ⚡ Quick winUse strict box-id token extraction for detach/recovery flows.
The current regex search can match unrelated text in stdout. A full-token parse avoids flaky detach reuse checks and cleanup calls.
Proposed change
-BOX_ID_RE = re.compile(r"[A-Za-z0-9]{8,36}") +BOX_ID_RE = re.compile(r"^[A-Za-z0-9-]{8,36}$") + +def _extract_box_id(stdout: str) -> str | None: + for line in stdout.splitlines(): + token = line.strip() + if BOX_ID_RE.fullmatch(token): + return token + return None @@ - m = BOX_ID_RE.search(r_run.stdout) - assert m, f"`boxlite run -d` did not print a uuid: {r_run.stdout!r}" - box_id = m.group(0) + box_id = _extract_box_id(r_run.stdout) + assert box_id, f"`boxlite run -d` did not print a box id: {r_run.stdout!r}" @@ - m = BOX_ID_RE.search(r_run.stdout) - assert m - box_id = m.group(0) + box_id = _extract_box_id(r_run.stdout) + assert box_idAlso applies to: 74-77, 115-118
🤖 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 `@scripts/test/e2e/cases/test_cli_detach_recovery.py` at line 42, The BOX_ID_RE regex pattern is too loose and can match unrelated text in stdout, causing flaky detach and recovery operations. Replace the overly broad regex pattern at the BOX_ID_RE definition with a stricter pattern that matches the complete box-id token format using word boundaries or anchors. Then update all usages of BOX_ID_RE throughout the file (including the regex.search calls around lines 74-77 and 115-118) to perform full-token parsing instead of partial matches, ensuring only complete box-id tokens are extracted from the stdout output.
🤖 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 `@scripts/test/e2e/cases/test_cli_entry.py`:
- Around line 66-72: The assertion in the test_cli_whoami_against_api function
is too permissive because checking for just "boxlite" in the output can match
failure messages like "not logged in to boxlite". Strengthen the assertion to
only accept output that contains "logged in" or "server", which are the
indicators of successful authentication status. Remove "boxlite" from the OR
condition or restructure the assertion to require more specific keywords that
guarantee a successful whoami response rather than just the presence of the
application name.
In `@scripts/test/e2e/cases/test_go_coverage.py`:
- Around line 55-58: In the exception handler for subprocess.CalledProcessError
when calling _build_go(src_name) in the try-except block, replace the
pytest.skip() call with pytest.fail() to ensure that Go build failures are
properly reported as test failures rather than being silently skipped. This
change should be applied consistently across all affected test files:
test_go_coverage.py (around the _build_go call), test_c_entry.py (around the
corresponding build call), test_go_entry.py (around the corresponding build
call), and test_c_coverage.py (around the corresponding build call) to ensure
that legitimate compilation errors are caught and reported instead of masked by
skip behavior.
In `@scripts/test/e2e/fixture_setup.py`:
- Around line 7-10: Update the docstring at the beginning of the file (lines
7-10) to accurately reflect the current implementation behavior. Replace the
reference to alpine:3.23 with the correct pinned agent-base image that is
actually being used in the fixture setup. Replace the hardcoded
~/.boxlite/credentials.toml path reference with the BOXLITE_HOME environment
variable override approach that is shown in the actual setup code at lines
46-51. Also review line 195 where a path is being logged to ensure it reflects
the current BOXLITE_HOME behavior and is not using a stale hardcoded path
reference.
In `@scripts/test/e2e/sdks/c/e2e_exec.c`:
- Line 59: The strncpy call when copying err->message to ctx->err_msg does not
guarantee null-termination if the source string is equal to or longer than the
buffer size, leaving the buffer without a proper string terminator. After
calling strncpy with sizeof(ctx->err_msg) - 1, explicitly null-terminate the
buffer by setting ctx->err_msg[sizeof(ctx->err_msg) - 1] = '\0'. Apply this same
fix at both locations: the current line 59 and also at line 97 in the on_wait
function where the same pattern exists.
---
Nitpick comments:
In `@scripts/test/e2e/cases/test_c_entry.py`:
- Line 28: The BOX_ID_RE regex pattern at line 28 is too broad and can match
unrelated alphanumeric tokens from stdout, causing flaky test behavior. Modify
the BOX_ID_RE pattern to explicitly include the BOX_ID marker (e.g., look for
"BOX_ID" followed by its value) rather than matching any arbitrary 8-36
character alphanumeric string. Apply the same fix to the similar extraction
logic at lines 78-80 to ensure consistent and reliable parsing of the BOX_ID
marker.
In `@scripts/test/e2e/cases/test_cli_detach_recovery.py`:
- Line 42: The BOX_ID_RE regex pattern is too loose and can match unrelated text
in stdout, causing flaky detach and recovery operations. Replace the overly
broad regex pattern at the BOX_ID_RE definition with a stricter pattern that
matches the complete box-id token format using word boundaries or anchors. Then
update all usages of BOX_ID_RE throughout the file (including the regex.search
calls around lines 74-77 and 115-118) to perform full-token parsing instead of
partial matches, ensuring only complete box-id tokens are extracted from the
stdout output.
In `@scripts/test/e2e/cases/test_cli_entry.py`:
- Line 33: The BOX_ID_RE regex pattern and its usage with .search() is too broad
and can match unrelated alphanumeric fragments in the CLI output, making the
extraction non-deterministic. Instead of using .search() which finds the pattern
anywhere in a string, refactor the box-id extraction logic to extract from
complete lines or tokens that are specifically intended to contain the box-id.
Update the BOX_ID_RE pattern definition and all its usages (at the initial
pattern definition, at lines 91-93, and at lines 123-125) to ensure the
extraction targets the full intended identifier token rather than searching
within arbitrary text.
In `@scripts/test/e2e/cases/test_go_entry.py`:
- Line 21: The BOX_ID_RE regex pattern at the BOX_ID_RE definition is too broad
and can match unrelated stdout content, making the assertion unstable. Replace
the pattern to explicitly match the BOX_ID= marker followed by the ID value
instead of just matching any 8-36 character alphanumeric string. This will
anchor the pattern to the explicit BOX_ID= prefix, ensuring it only captures the
intended output. Apply the same fix to the related parsing logic in lines 68-70
where this pattern is used.
In `@scripts/test/e2e/cases/test_node_entry.py`:
- Line 26: The BOX_ID_RE regex pattern is too generic and can match unintended
tokens in stdout, making the extraction brittle. Replace the generic character
pattern with an explicit marker-based capture that matches the actual format
used by the Node driver to output BOX_ID (e.g., by including a specific prefix
or delimiter that precedes the actual BOX_ID value). Apply this same
marker-based approach consistently to all BOX_ID extraction locations, including
the additional instances around lines 75-77 referenced in the comment, to ensure
robust and reliable runner-journal verification across all extraction points.
In `@scripts/test/e2e/sdks/c/e2e_exec.c`:
- Around line 182-183: The calls to boxlite_execution_on_stdout and
boxlite_execution_wait both pass an error pointer but do not check whether these
operations succeeded. After each function call, verify the error status (check
if err indicates a failure) and handle the error appropriately by logging it and
skipping or terminating the test execution. This ensures that if either function
fails, the test does not proceed with potentially invalid state or hang
indefinitely.
- Line 132: The pthread_create call for creating the drain_tid thread does not
check the return value for success or failure. Add a return value check after
the pthread_create call to verify it returns 0, and implement error handling
logic to exit or report the error if thread creation fails (non-zero return
value), preventing potential hangs when the drain_loop function never executes.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 764b0f5d-408d-4798-afea-403875a94f3f
📒 Files selected for processing (21)
scripts/test/e2e/cases/conftest.pyscripts/test/e2e/cases/test_c_coverage.pyscripts/test/e2e/cases/test_c_entry.pyscripts/test/e2e/cases/test_cli_detach_recovery.pyscripts/test/e2e/cases/test_cli_entry.pyscripts/test/e2e/cases/test_exec_timeout.pyscripts/test/e2e/cases/test_go_coverage.pyscripts/test/e2e/cases/test_go_entry.pyscripts/test/e2e/cases/test_node_coverage.pyscripts/test/e2e/cases/test_node_entry.pyscripts/test/e2e/cases/test_quota_enforcement.pyscripts/test/e2e/cases/test_runner_concurrency.pyscripts/test/e2e/fixture_setup.pyscripts/test/e2e/sdks/c/e2e_basic.cscripts/test/e2e/sdks/c/e2e_exec.cscripts/test/e2e/sdks/go/e2e_basic.goscripts/test/e2e/sdks/go/e2e_copy.goscripts/test/e2e/sdks/go/e2e_exec_options.goscripts/test/e2e/sdks/node/e2e_basic.tsscripts/test/e2e/sdks/node/e2e_copy.tsscripts/test/e2e/sdks/node/e2e_exec.ts
💤 Files with no reviewable changes (2)
- scripts/test/e2e/cases/test_runner_concurrency.py
- scripts/test/e2e/cases/test_quota_enforcement.py
✅ Files skipped from review due to trivial changes (2)
- scripts/test/e2e/sdks/go/e2e_basic.go
- scripts/test/e2e/sdks/c/e2e_basic.c
There was a problem hiding this comment.
🧹 Nitpick comments (1)
scripts/test/e2e/cases/test_go_entry.py (1)
21-21: 💤 Low valueConsider adding word boundaries for more precise matching.
The simplified regex
[A-Za-z0-9]{12}will match the first 12 alphanumeric characters of any longer sequence. Adding word boundaries would ensure the match targets a standalone 12-character identifier, aligning with the intent to match exactly server IDs.♻️ Suggested improvement
-BOX_ID_RE = re.compile(r"[A-Za-z0-9]{12}") +BOX_ID_RE = re.compile(r"\b[A-Za-z0-9]{12}\b")🤖 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 `@scripts/test/e2e/cases/test_go_entry.py` at line 21, The BOX_ID_RE regex pattern lacks word boundaries, which allows it to match any 12 consecutive alphanumeric characters even when they appear as part of a longer sequence. Add word boundary anchors to the BOX_ID_RE pattern to ensure it matches only standalone 12-character server identifiers and not partial matches within longer strings of characters.
🤖 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.
Nitpick comments:
In `@scripts/test/e2e/cases/test_go_entry.py`:
- Line 21: The BOX_ID_RE regex pattern lacks word boundaries, which allows it to
match any 12 consecutive alphanumeric characters even when they appear as part
of a longer sequence. Add word boundary anchors to the BOX_ID_RE pattern to
ensure it matches only standalone 12-character server identifiers and not
partial matches within longer strings of characters.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: d27d2d7b-193a-43b2-b5ac-5eb0a9f67627
📒 Files selected for processing (5)
scripts/test/e2e/cases/test_c_entry.pyscripts/test/e2e/cases/test_cli_detach_recovery.pyscripts/test/e2e/cases/test_cli_entry.pyscripts/test/e2e/cases/test_go_entry.pyscripts/test/e2e/cases/test_node_entry.py
🚧 Files skipped from review as they are similar to previous changes (4)
- scripts/test/e2e/cases/test_node_entry.py
- scripts/test/e2e/cases/test_c_entry.py
- scripts/test/e2e/cases/test_cli_entry.py
- scripts/test/e2e/cases/test_cli_detach_recovery.py
…d authenticate signature - jest.config.ts: add nanoid v5 (ESM-only) to transformIgnorePatterns alongside uuid - boxlite-rest-routing.spec.ts: fix expected key from prefix back to tenant - boxlite-ws-proxy.service.spec.ts: pass urlTenant to authenticate() for JWT tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
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 `@apps/api/jest.config.ts`:
- Around line 14-16: The comment describing the transformIgnorePatterns
configuration incorrectly states that nanoid v5 ships as ESM-only, when it
actually ships as ESM-primary with CommonJS compatibility support. Update the
comment to accurately distinguish between uuid v14, which is strictly ESM-only,
and nanoid v5, which is ESM-primary but includes CommonJS compatibility options.
The rest of the comment explaining that ts-jest needs to down-level these
modules should remain unchanged.
🪄 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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: fb28e7f4-eaa1-4226-b5af-ed4f4f5d5319
📒 Files selected for processing (3)
apps/api/jest.config.tsapps/api/src/boxlite-rest/boxlite-rest-routing.spec.tsapps/api/src/boxlite-rest/boxlite-ws-proxy.service.spec.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/api/src/boxlite-rest/boxlite-ws-proxy.service.spec.ts
Addresses CodeQL findings from PR review:
- remove unused `import re` in test_{c,go,node}_coverage.py
- remove unused `from e2e_auth import auth_context` in test_cli_{entry,detach_recovery}.py
- remove unused `DEFAULT_IMAGE` import in test_path_verification.py
- add explanatory comment to bare except in test_path_verification.py
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5c8051d to
e2c2018
Compare
Explains how to run the E2E suite against dev/staging without local bootstrap — env vars, credentials.toml profile, and CI secret setup. Also updates the layout section with new SDK drivers and coverage files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Measures box creation latency through the full REST path by: 1. POST /boxes wall clock (client-side) 2. GET /boxes/:id/metrics (runner-reported create_duration_ms) 3. First exec latency after boot Emits schema v1.0 JSON report compatible with bench harness (#592). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| metrics["runner_create_ms"] = float(runner_m["create_duration_ms"]) | ||
| if runner_m.get("boot_duration_ms"): | ||
| metrics["runner_boot_ms"] = float(runner_m["boot_duration_ms"]) | ||
| except Exception: |
| }, timeout=30) | ||
| t_exec = time.monotonic() - t1 | ||
| metrics["first_exec_wall_ms"] = t_exec * 1000 | ||
| except Exception: |
| finally: | ||
| try: | ||
| api_request(ctx, "DELETE", f"boxes/{bid}", timeout=15) | ||
| except Exception: |
…andbox (#849) ## Why Two independent fixes that surface once the jailer is enabled by default (secure-by-default, #652). ### 1. `allow_net` allowlist silently sinkholes everything under the jailer gvproxy resolves `allow_net` hostnames **host-side** — `buildAllowNetDNSZones` (`dns_filter.go`) runs inside the **shim**, which the jailer wraps in **bwrap**. bwrap binds `/usr`, `/lib`, `/bin`, `/sbin` … **but not `/etc`**, so the sandbox has no `/etc/resolv.conf`. Every host-side lookup then fails, and each allow-listed host falls through to the catch-all `0.0.0.0` sinkhole. Result: with the jailer on, the allowlist **blocks everything — including the hosts it is meant to permit**. This is the secure-by-default root cause behind the `0.0.0.0` symptom in #645; #645's Go-side retry / longest-suffix / fail-closed changes don't address it (there's no resolver in the sandbox to retry against). **Fix:** bind `/etc/resolv.conf`, `/etc/hosts`, `/etc/nsswitch.conf` read-only so the Go resolver works. **Verified** on a real box (`--security enable --allow-net example.com`): | | before | after | |---|---|---| | `nslookup example.com` | `0.0.0.0` | `104.20.23.154` | ### 2. Drop `whoami_updates_stale_profile_path_prefix` `auth whoami` is a read-only diagnostic — it `GET`s `/v1/me` and prints the identity. This test additionally asserted whoami **persists** the refreshed `path_prefix` back into the stored credentials, a side effect a "show" command should not have (the prefix is captured at `auth login`). whoami has never written the profile, so the test has been red since #746. Drop the over-specified assertion rather than add a credential-mutating side effect. ## Test plan - [x] `nslookup`/resolution verified manually under `--security enable` (see table) - [ ] e2e-local network-secrets suite green <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved sandbox networking and name-resolution behavior so DNS lookups and host resolution work more reliably inside isolated environments. * Fixed an issue that could cause allowlisted host lookups to be blocked when system DNS configuration was unavailable in the sandbox. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Split from #817 — test-only changes.
Verification
Related
Summary by CodeRabbit
tenantfield for the canonical route while keeping legacy default-prefix behavior.nanoidduring tests.