Skip to content

feat(tests): SDK compatibility E2E test framework and quality gates (#864)#883

Closed
sparkzky wants to merge 4 commits into
TencentCloud:masterfrom
sparkzky:feat/sdk-compat-e2e-864
Closed

feat(tests): SDK compatibility E2E test framework and quality gates (#864)#883
sparkzky wants to merge 4 commits into
TencentCloud:masterfrom
sparkzky:feat/sdk-compat-e2e-864

Conversation

@sparkzky

Copy link
Copy Markdown

Summary

Build a first-class SDK compatibility E2E test framework for CubeSandbox, enabling the same user-facing scenarios to be validated across both the cubesandbox native Python SDK and e2b-compatible Python SDKs.

Resolves #864.

Changes

1. SDK Compatibility E2E Framework

Added tests/e2e/sdk_compat/ with a complete pytest-based framework:

  • Adapter layer (adapters/): SandboxAdapter ABC with 16 backend-neutral methods. CubeSandboxAdapter and E2BAdapter wrap each SDK, normalizing return types and behavioral differences (e.g., E2B raises exceptions on non-zero exit codes vs CubeSandbox returns results).
  • Capability markers (framework/capabilities.py): requires_capability marker auto-skips unsupported tests — E2B backend correctly skips set_timeout, pause_resume, and proxy_url with zero branching inside test bodies.
  • Preflight checks (framework/preflight.py): session-scoped validation of CubeAPI health and template readiness, with early exit to avoid wasting resources.
  • Structured reporting (framework/reporting.py): JSONL events for preflight, sandbox create/cleanup, and test results (backend, sandbox ID, duration, outcome, error diagnostics).
  • Safe cleanup (framework/cleanup.py): safe_kill never raises — REST DELETE fallback, original test failure always preserved.

2. Nine Capability Domains, 44 Backend-Neutral Test Cases

Domain Tests Coverage
lifecycle 6 create, info, kill, set_timeout, pause/resume
commands 8 stdout/stderr/exit_code, env, cwd, special chars, multiline/large output, missing binary
filesystem 10 read/write, overwrite, exists, list, make_dir, remove, nested dirs, cross-API interop
run_code 8 expression, stdout, kernel state, multiline blocks, string/list output, imports, error reporting
metadata 2 env var propagation, cross-API metadata interop
errors 2 info after kill, double-kill idempotency
concurrency 2 sequential reuse, parallel sandbox isolation
network 3 DNS resolution, HTTP/HTTPS egress
proxy 3 CubeProxy routing (commands, filesystem, run_code)

3. SDK Bug Fix

E2E tests discovered Sandbox.connect() sent an empty JSON body {}, but the CubeAPI /connect endpoint requires a timeout field. Fixed to send {"timeout": <value>}.

4. CI Workflow

.github/workflows/sdk-compat-e2e.yml:

  • PR gate: validates test collection (imports, parametrization, marker registration)
  • Live E2E: optional --run-e2e run when deployment secrets are configured

Verification

Dual-backend E2E run against a local PVM deployment:

SDK_E2E_BACKENDS=e2b,cubesandbox pytest --run-e2e

82 passed, 6 skipped in 32.17s
  • cubesandbox backend: 44 passed (all green)
  • e2b backend: 38 passed + 6 skipped (marker correctly skips CubeSandbox-only capabilities)
  • SDK unit tests: 196 passed (no regressions)

Usage

cd tests/e2e/sdk_compat
pip install -r requirements.txt

# PR gate (cubesandbox backend by default)
CUBE_API_URL=http://<api-url> CUBE_TEMPLATE_ID=<tpl-id> \
CUBE_PROXY_NODE_IP=<node-ip> pytest --run-e2e

# Dual-SDK compatibility check
SDK_E2E_BACKENDS=e2b,cubesandbox pytest --run-e2e

Autonomously-by: omp:zai/glm-5.2

sparkzky added 4 commits July 10, 2026 16:31
Add a first-class pytest-based SDK compatibility E2E test framework under
tests/e2e/sdk_compat/. The same backend-neutral test cases run against
both the CubeSandbox Python SDK and E2B-compatible Python SDKs.

Framework components:
- Adapter layer (SandboxAdapter ABC) abstracts SDK differences into a
  shared interface: create, info, commands, files, run_code, pause/resume,
  set_timeout, kill
- Capability markers skip unsupported backends without branching in tests
- Preflight checks validate API health + template readiness before runs
- JSONL structured reporting for diagnostics
- Best-effort sandbox cleanup with REST fallback
- Default PR gate runs cubesandbox backend; SDK_E2E_BACKENDS for dual-SDK

Coverage domains (38 tests across 7 domains):
- lifecycle: create, info, kill, set_timeout, pause/resume
- commands: stdout/stderr/exit_code, env, cwd, special chars, multiline,
  large output, missing binary
- filesystem: read/write, overwrite, multiline, exists, list, make_dir,
  remove, cross-API interoperability
- run_code: expression text, stdout, kernel state, multiline blocks,
  string/list output, imports, error reporting
- metadata: env var propagation, cross-API metadata interoperability
- errors: info-after-kill, double-kill idempotency
- concurrency: sequential reuse, parallel sandbox isolation

CI workflow (.github/workflows/sdk-compat-e2e.yml) validates test
collection on PRs touching sdk_compat or the Python SDK; optional live
E2E job runs when deployment secrets are configured.

Autonomously-by: omp:zai/glm-5.2
Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
The CubeAPI /connect endpoint requires a `timeout` field in the request
body. The SDK was sending `{}`, causing a 400 "missing field `timeout`"
on every connect-after-pause call.

Sandbox.connect() now accepts an optional `timeout` parameter (defaults
to config.timeout) and includes it in the POST body.

Discovered by the SDK compat E2E pause/resume tests against a live
CubeSandbox deployment — all 38 E2E tests pass after this fix.

Autonomously-by: omp:zai/glm-5.2
Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
Complete the capability domain coverage listed in issue TencentCloud#864:
- cases/network/: DNS resolution, HTTP/HTTPS egress (requires_internet)
- cases/proxy/: CubeProxy routing for filesystem, commands, run_code
  (requires_capability proxy_url, requires_cubeproxy)

44 tests across all 9 domains, all passing against live deployment.

Autonomously-by: omp:zai/glm-5.2
Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
E2B SDK 2.30+ validates the API key format client-side (requires e2b_
prefix + hex). Self-hosted CubeSandbox deployments with auth disabled
accept any key at the server level, but the SDK rejects non-conforming
keys before sending the request.

Use a format-valid placeholder key so dual-backend E2E tests work
against local deployments without a real E2B account.

Verified: 82 passed, 6 skipped (cubesandbox-only capabilities) across
both backends.

Autonomously-by: omp:zai/glm-5.2
Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
@fslongjin

Copy link
Copy Markdown
Member

duplicated with: #835

@fslongjin fslongjin added the duplicate This issue or pull request already exists label Jul 10, 2026
@sparkzky sparkzky closed this Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

duplicate This issue or pull request already exists

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] SDK compatibility E2E test framework and quality gates

2 participants