원클릭으로
test-e2e-openshell
Run end-to-end tests for the openshell backend using real container and API calls
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Run end-to-end tests for the openshell backend using real container and API calls
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | test-e2e-openshell |
| description | Run end-to-end tests for the openshell backend using real container and API calls |
Run full lifecycle tests of the OpenShell backend across harnesses and auth modes. All tests run inside a privileged container.
Each section below is independent. Run whichever sections match your environment and skip the rest.
Present the following default container images to the user and ask them to confirm or override each one before proceeding:
| Role | Default image | Variable |
|---|---|---|
| CI image | quay.io/aipcc/agentic-ci/openshell | $CI_IMAGE |
| Claude sandbox | quay.io/aipcc/agentic-ci/claude-sandbox | $CLAUDE_SANDBOX_IMAGE |
| OpenCode sandbox | quay.io/aipcc/agentic-ci/opencode-sandbox | $OPENCODE_SANDBOX_IMAGE |
Also ask for:
$API_KEY_FILE.Per-section requirements:
~/.config/gcloud/application_default_credentials.json and
ANTHROPIC_VERTEX_PROJECT_ID + CLOUD_ML_REGION set in the environment.OpenShell requires --privileged for nested podman (user namespace mapping,
overlay mounts, network namespace creation). All agentic-ci commands run
inside this outer container.
podman rm -f openshell-e2e 2>/dev/null || true
podman run -d --name openshell-e2e \
--privileged \
-v "$(pwd):/workspace:ro,z" \
-v ~/.config/gcloud:/host-gcloud:ro,z \
-v "$API_KEY_FILE:/host-api-key:ro,z" \
$CI_IMAGE \
sleep infinity
podman exec openshell-e2e bash -c '
mkdir -p ~/.config/gcloud
cp /host-gcloud/application_default_credentials.json ~/.config/gcloud/
cd /workspace && uv pip install --system --no-cache .
'
If the sandbox images are on a registry, the container's podman will pull them automatically during sandbox creation. If they are only available locally (not pushed to any registry), copy them into the container's podman storage:
podman save $CLAUDE_SANDBOX_IMAGE -o /tmp/openshell-claude.tar
podman save $OPENCODE_SANDBOX_IMAGE -o /tmp/openshell-opencode.tar
podman cp /tmp/openshell-claude.tar openshell-e2e:/tmp/
podman cp /tmp/openshell-opencode.tar openshell-e2e:/tmp/
podman exec openshell-e2e bash -c '
podman load -i /tmp/openshell-claude.tar
podman load -i /tmp/openshell-opencode.tar
rm -f /tmp/openshell-*.tar
'
rm -f /tmp/openshell-claude.tar /tmp/openshell-opencode.tar
Verify:
podman exec openshell-e2e openshell --version shows version outputpodman exec openshell-e2e agentic-ci --help prints usagepodman exec openshell-e2e podman images lists both sandbox imagesThe gateway and sandbox state must be fully reset between tests. Run this before each new section:
podman exec openshell-e2e bash -c '
pids=$(ss -tlnp | grep 17670 | grep -oP "pid=\K[0-9]+" 2>/dev/null)
[ -n "$pids" ] && kill -9 $pids 2>/dev/null
pkill -9 -f "podman system" 2>/dev/null
sleep 1
podman rm -af 2>/dev/null
podman network rm openshell 2>/dev/null
rm -rf ~/.config/openshell ~/.local/state/openshell
'
Use haiku to keep cost down. The model name format varies by harness:
| Harness | Vertex AI model | API key model |
|---|---|---|
| Claude Code | claude-haiku-4-5 | claude-haiku-4-5 |
| OpenCode | google-vertex/claude-haiku-4-5@20251001 | anthropic/claude-haiku-4-5-20251001 |
Claude Code sends a context_management field that Vertex AI's rawPredict
rejects with HTTP 400. This is an upstream OpenShell bug
(NVIDIA/OpenShell#1752).
The workaround is CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1, which
agentic-ci now sets automatically in the sandbox env script.
See docs/openshell-vertex-streaming-bug.md for details.
Requires GCP ADC credentials and ANTHROPIC_VERTEX_PROJECT_ID.
podman exec \
-e ANTHROPIC_VERTEX_PROJECT_ID=<your-project-id> \
-e CLOUD_ML_REGION=global \
-e SANDBOX_IMAGE="$CLAUDE_SANDBOX_IMAGE" \
openshell-e2e bash -c '
agentic-ci run \
--backend openshell \
--harness claude-code \
--image "$SANDBOX_IMAGE" \
--model claude-haiku-4-5 \
--no-otel \
"Respond with exactly: A1_OK"
'
Verify:
Auth: Vertex AIStarting OpenShell gateway (or already running)Creating Vertex AI provider (or already exists)Created sandbox: ciRunning Claude Code (claude-haiku-4-5) via openshell backendA1_OK$0.04)Agent exit code: 0Sandbox deleted and Gateway stopped at the endRun cleanup first.
podman exec \
-e "ANTHROPIC_API_KEY=$(cat "$API_KEY_FILE")" \
-e SANDBOX_IMAGE="$CLAUDE_SANDBOX_IMAGE" \
openshell-e2e bash -c '
agentic-ci run \
--backend openshell \
--harness claude-code \
--image "$SANDBOX_IMAGE" \
--model claude-haiku-4-5 \
--no-otel \
"Respond with exactly: B1_OK"
'
Verify:
Auth: API keyCreating Anthropic API key providerB1_OKAgent exit code: 0Requires GCP ADC credentials and ANTHROPIC_VERTEX_PROJECT_ID.
Run cleanup first.
podman exec \
-e ANTHROPIC_VERTEX_PROJECT_ID=<your-project-id> \
-e CLOUD_ML_REGION=global \
-e SANDBOX_IMAGE="$OPENCODE_SANDBOX_IMAGE" \
openshell-e2e bash -c '
agentic-ci run \
--backend openshell \
--harness opencode \
--image "$SANDBOX_IMAGE" \
--model "google-vertex/claude-haiku-4-5@20251001" \
--no-otel \
"Respond with exactly: C1_OK"
'
Verify:
Harness: OpenCode and Auth: Vertex AIModel: claude-haiku-4-5 (prefix stripped)Agent exit code: 0Run cleanup first.
podman exec \
-e "ANTHROPIC_API_KEY=$(cat "$API_KEY_FILE")" \
-e SANDBOX_IMAGE="$OPENCODE_SANDBOX_IMAGE" \
openshell-e2e bash -c '
agentic-ci run \
--backend openshell \
--harness opencode \
--image "$SANDBOX_IMAGE" \
--model "anthropic/claude-haiku-4-5-20251001" \
--no-otel \
"Respond with exactly: D1_OK"
'
Verify:
Harness: OpenCode and Auth: API keyD1_OKAgent exit code: 0Verifies that the OpenShell backend uploads the workdir into the sandbox, the agent can modify files inside it, and changes are downloaded back to the host after the run completes. Uses Vertex AI auth and Claude Code.
Run cleanup first.
Create a temporary directory with a seed file:
podman exec openshell-e2e bash -c '
mkdir -p /tmp/workdir-test
echo red > /tmp/workdir-test/color.txt
'
Verify:
podman exec openshell-e2e cat /tmp/workdir-test/color.txt
Should print red.
podman exec \
-e ANTHROPIC_VERTEX_PROJECT_ID=<your-project-id> \
-e CLOUD_ML_REGION=global \
-e SANDBOX_IMAGE="$CLAUDE_SANDBOX_IMAGE" \
openshell-e2e bash -c '
agentic-ci run \
--backend openshell \
--harness claude-code \
--image "$SANDBOX_IMAGE" \
--model claude-haiku-4-5 \
--workdir /tmp/workdir-test \
--no-otel \
"Overwrite the file color.txt with exactly the word blue (no newline, no quotes). Do not create any other files."
'
Verify:
Uploading workdirDownloading workdirAgent exit code: 0podman exec openshell-e2e cat /tmp/workdir-test/color.txt
The file should now contain blue, not red. This confirms the full
round-trip: the workdir was uploaded into the sandbox, the agent modified
it, and the changes were downloaded back to the host.
podman exec openshell-e2e rm -rf /tmp/workdir-test
Verifies that the sandbox-local OTEL collector receives metrics from the agent and prints a token/cost summary. Uses Vertex AI auth and Claude Code (the only harness that supports OTEL).
The OpenShell sandbox network isolation prevents reaching an external OTEL collector, so agentic-ci embeds a lightweight OTLP receiver inside the sandbox on localhost. After the run, the OTEL log is downloaded from the sandbox and the summary is printed on the host.
Run cleanup first.
podman exec \
-e ANTHROPIC_VERTEX_PROJECT_ID=<your-project-id> \
-e CLOUD_ML_REGION=global \
-e SANDBOX_IMAGE="$CLAUDE_SANDBOX_IMAGE" \
openshell-e2e bash -c '
cd /tmp/e2e-workdir && \
agentic-ci run \
--backend openshell \
--harness claude-code \
--image "$SANDBOX_IMAGE" \
--model claude-haiku-4-5 \
"Respond with exactly: F1_OK"
'
Note: no --no-otel flag.
Verify:
Running Claude Code (claude-haiku-4-5) via openshell backendF1_OK in the responseToken/Cost Summary (OpenTelemetry) section$0.04)Agent exit code: 0Sandbox deleted and Gateway stopped at the endCheck that the OTEL JSONL log contains /v1/traces records — these are
what agentic-ci mlflow-push needs. The JSONL file is copied to the
CI artifact directory or stays in the run directory:
podman exec openshell-e2e bash -c '
JSONL=$(ls -t /tmp/agentic-ci-run.*/claude-otel.jsonl 2>/dev/null | head -1)
echo "JSONL file: $JSONL"
grep -c "/v1/traces" "$JSONL"
'
Verify:
podman exec openshell-e2e bash -c '
JSONL=$(ls -t /tmp/agentic-ci-run.*/claude-otel.jsonl 2>/dev/null | head -1)
grep "/v1/traces" "$JSONL" | head -1 | python3 -m json.tool
'
"path" containing /v1/traces"payload" with "resourceSpans" arrayVerifies that a plugin skill loads and executes correctly inside the
sandbox. Uses the git-shallow-clone skill from the odh-ai-helpers
plugin to clone a repo into /tmp and confirm the result.
Requires GCP ADC credentials and ANTHROPIC_VERTEX_PROJECT_ID.
Run cleanup first.
podman exec \
-e ANTHROPIC_VERTEX_PROJECT_ID=<your-project-id> \
-e CLOUD_ML_REGION=global \
-e SANDBOX_IMAGE="$CLAUDE_SANDBOX_IMAGE" \
openshell-e2e bash -c '
mkdir -p /tmp/e2e-workdir && cd /tmp/e2e-workdir && \
agentic-ci run \
--backend openshell \
--harness claude-code \
--image "$SANDBOX_IMAGE" \
--model claude-haiku-4-5 \
--no-otel \
"Use the /odh-ai-helpers:git-shallow-clone skill to shallow-clone https://github.com/opendatahub-io/agentic-ci.git into /tmp/agentic-ci. After the clone completes, run: ls /tmp/agentic-ci and print the output, then respond with exactly: SKILL_OK"
'
Verify:
Plugins: line includes odh-ai-helpersSkill tool invocation for odh-ai-helpers:git-shallow-cloneBash tool call running git clonels /tmp/agentic-ci with repo contents (e.g. src, pyproject.toml, Makefile)SKILL_OKAgent exit code: 0Same test as Section G but with API key auth.
Run cleanup first.
podman exec \
-e "ANTHROPIC_API_KEY=$(cat "$API_KEY_FILE")" \
-e SANDBOX_IMAGE="$CLAUDE_SANDBOX_IMAGE" \
openshell-e2e bash -c '
mkdir -p /tmp/e2e-workdir && cd /tmp/e2e-workdir && \
agentic-ci run \
--backend openshell \
--harness claude-code \
--image "$SANDBOX_IMAGE" \
--model claude-haiku-4-5 \
--no-otel \
"Use the /odh-ai-helpers:git-shallow-clone skill to shallow-clone https://github.com/opendatahub-io/agentic-ci.git into /tmp/agentic-ci. After the clone completes, run: ls /tmp/agentic-ci and print the output, then respond with exactly: SKILL_OK"
'
Verify:
Auth: API keyPlugins: line includes odh-ai-helpersSkill tool invocation for odh-ai-helpers:git-shallow-clonels /tmp/agentic-ci with repo contents (e.g. src, pyproject.toml, Makefile)SKILL_OKAgent exit code: 0podman rm -f openshell-e2e
Execute sections in order (A through H), running the cleanup step before each section. Skip sections whose prerequisites are not met. If any step fails, check the gateway log inside the container:
podman exec openshell-e2e bash -c 'cat ~/.local/state/openshell/gateway-*.log'
Run end-to-end tests for the podman backend using real container and API calls
Investigate infrastructure-level failures in the agentic-ci framework. Covers container backend issues, skill engine errors, forge MR/PR failures, and gate problems. Use when the container failed, MR operations broke, or the skill engine returned errors.
Cut a new agentic-ci release: bump version, open PR, wait for approval and checks, merge, tag, and push.