From 2228f47aaae30b2b06f18f1f9401a762b0a5dd27 Mon Sep 17 00:00:00 2001 From: "Molecule AI Dev Engineer A (Kimi)" Date: Wed, 10 Jun 2026 14:34:43 +0000 Subject: [PATCH] fix(e2e): shared ConfigVolumeName helpers prevent KI-013 drift (SEV-2499) Extracts shell SSOT helpers for container/volume names in tests/e2e/_lib.sh: e2e_container_name, e2e_config_volume_name, e2e_session_volume_name, e2e_workspace_volume_name These bash helpers are cross-referenced to their Go equivalents in provisioner.go so the naming contract is explicit in both languages. Updates test_local_provision_lifecycle_e2e.sh to use the helpers so the test seed and the provisioner can never drift again. Refs #2499 Co-Authored-By: Claude Opus 4.8 --- tests/e2e/_lib.sh | 41 +++++++++++++++++++ .../e2e/test_local_provision_lifecycle_e2e.sh | 14 +++---- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/tests/e2e/_lib.sh b/tests/e2e/_lib.sh index f287be514..be21d129c 100755 --- a/tests/e2e/_lib.sh +++ b/tests/e2e/_lib.sh @@ -106,6 +106,47 @@ except Exception: -H "X-Confirm-Name: $name" ${curl_args[@]+"${curl_args[@]}"} > /dev/null || true } +# --------------------------------------------------------------------------- +# Docker container / volume naming helpers (KI-013 / SEV-2499). +# +# KI-013 changed workspace container and volume names from truncated 12-char +# IDs to full UUIDs. These helpers are the bash SSOT for that naming scheme. +# They MUST be kept in sync with the Go equivalents in: +# workspace-server/internal/provisioner/provisioner.go +# +# ContainerName(workspaceID) -> ws- +# ConfigVolumeName(workspaceID) -> ws--configs +# ClaudeSessionVolumeName(wsID) -> ws--claude-sessions +# buildWorkspaceMount(wsID) -> ws--workspace +# +# The drift-guard script .gitea/scripts/lint-e2e-ki013-container-names.sh +# fails CI if any e2e script uses bash substring truncation in a ws-* context. +# --------------------------------------------------------------------------- + +# e2e_container_name returns the Docker container name for a workspace. +# Keep in sync with provisioner.ContainerName. +e2e_container_name() { + echo "ws-${1}" +} + +# e2e_config_volume_name returns the Docker named volume for a workspace's +# /configs directory. Keep in sync with provisioner.ConfigVolumeName. +e2e_config_volume_name() { + echo "ws-${1}-configs" +} + +# e2e_session_volume_name returns the Docker named volume for a workspace's +# Claude Code session directory. Keep in sync with provisioner.ClaudeSessionVolumeName. +e2e_session_volume_name() { + echo "ws-${1}-claude-sessions" +} + +# e2e_workspace_volume_name returns the Docker named volume for a workspace's +# /workspace directory. Keep in sync with buildWorkspaceMount in provisioner.go. +e2e_workspace_volume_name() { + echo "ws-${1}-workspace" +} + e2e_cleanup_all_workspaces() { # GET /workspaces (list) is AdminAuth-gated (router.go:165). Send the platform # admin bearer if one is set so the list doesn't 401 → empty → no cleanup. diff --git a/tests/e2e/test_local_provision_lifecycle_e2e.sh b/tests/e2e/test_local_provision_lifecycle_e2e.sh index 1fa325799..772f215f4 100755 --- a/tests/e2e/test_local_provision_lifecycle_e2e.sh +++ b/tests/e2e/test_local_provision_lifecycle_e2e.sh @@ -191,7 +191,7 @@ except Exception: } container_running() { # container_running -> echoes name if running - docker ps --filter "name=ws-${1}" --filter "status=running" --format '{{.Names}}' 2>/dev/null | head -1 + docker ps --filter "name=$(e2e_container_name "$1")" --filter "status=running" --format '{{.Names}}' 2>/dev/null | head -1 } diagnose_provision() { @@ -224,11 +224,11 @@ cleanup() { # SCOPED teardown — only the workspace this test created. Never a blanket # sweep (other dev workspaces may be live on this shared daemon). e2e_delete_workspace "$WSID" "" >/dev/null 2>&1 || true - docker rm -f "ws-${WSID}" >/dev/null 2>&1 || true + docker rm -f "$(e2e_container_name "$WSID")" >/dev/null 2>&1 || true docker volume rm -f \ - "ws-${WSID}-configs" "ws-${WSID}-claude-sessions" \ - "ws-${WSID}-workspace" >/dev/null 2>&1 || true - echo "cleaned workspace $WSID + ws-${WSID} container/volumes" + "$(e2e_config_volume_name "$WSID")" "$(e2e_session_volume_name "$WSID")" \ + "$(e2e_workspace_volume_name "$WSID")" >/dev/null 2>&1 || true + echo "cleaned workspace $WSID + $(e2e_container_name "$WSID") container/volumes" fi # Restore the cache tag to whatever it pointed at before we retagged it, so a # stub run doesn't leave the real claude-code tag aliased to the stub. @@ -347,7 +347,7 @@ if [ -z "$WSID" ]; then exit 1 fi pass "workspace created: $WSID" -CONFIG_VOL="ws-${WSID}-configs" +CONFIG_VOL="$(e2e_config_volume_name "$WSID")" # Mint a workspace bearer for the WorkspaceAuth-gated secret + /restart calls. WTOKEN=$(e2e_mint_workspace_token "$WSID" || true) @@ -453,7 +453,7 @@ done check "workspace reached online (status=$STATUS)" "online" "$STATUS" if [ "$FAIL" -gt 0 ]; then diagnose_provision "$WSID"; echo "=== Results: $PASS passed, $FAIL failed ==="; exit 1; fi RUN=$(container_running "$WSID") -if [ -n "$RUN" ]; then pass "container running: $RUN"; else fail "no running ws-${WSID} container" "docker ps shows none"; fi +if [ -n "$RUN" ]; then pass "container running: $RUN"; else fail "no running $(e2e_container_name "$WSID") container" "docker ps shows none"; fi echo "" # ---------------------------------------------------------------------------- -- 2.52.0