"""ORCH-058 TC-07/08: static guarantees of the Strategy-B provenance plumbing. These assert the *shape* of the deploy artefacts that can't be unit-tested by running them (they shell out to docker/ssh on the host): * TC-07 — the deploy hook fail-closes BEFORE `docker tag` when the staging image's git-revision label != EXPECTED_REVISION (exit 1), and the new `--build-staging` rebuild mode stamps GIT_SHA into the image. * TC-08 — the Dockerfile declares `ARG GIT_SHA` and stamps it into the `org.opencontainers.image.revision` OCI label (the anchor B reads). """ import pathlib _ROOT = pathlib.Path(__file__).resolve().parents[1] _HOOK = _ROOT / "scripts" / "orchestrator-deploy-hook.sh" _DOCKERFILE = _ROOT / "Dockerfile" def _build_staging_block() -> str: """Return only the body of the hook's ``--build-staging`` branch, so the contract assertions below cannot be satisfied by lookalike strings elsewhere in the script (e.g. the NORMAL DEPLOY recreate). The block runs from the ``--build-staging`` guard up to the NORMAL DEPLOY section header.""" text = _HOOK.read_text(encoding="utf-8") start = text.index('"${1:-}" == "--build-staging"') end = text.index("NORMAL DEPLOY mode", start) return text[start:end] # --------------------------------------------------------------------------- # TC-07: hook fail-closed provenance guard + --build-staging rebuild mode # --------------------------------------------------------------------------- def test_tc07_hook_has_fail_closed_provenance_guard(): text = _HOOK.read_text(encoding="utf-8") # The label key the hook inspects must be the OCI revision label. assert 'REVISION_LABEL="org.opencontainers.image.revision"' in text # EXPECTED_REVISION is read (default unset -> backward compatible). assert 'EXPECTED_REVISION="${EXPECTED_REVISION:-}"' in text # The guard must inspect the source image's label and normalise . assert "docker image inspect --format" in text assert '""' in text # Fail-closed: empty OR mismatch -> abort with exit 1. assert '-z "$IMG_REV" || "$IMG_REV" != "$EXPECTED_REVISION"' in text def test_tc07_provenance_guard_precedes_docker_tag(): """The fail-closed `exit 1` must sit BEFORE the `docker tag` retag line.""" text = _HOOK.read_text(encoding="utf-8") guard = text.index("$EXPECTED_REVISION") retag = text.index('docker tag "$SOURCE_IMAGE" "$TARGET_IMAGE"') assert guard < retag, "provenance guard must run before the prod retag" def test_tc07_build_staging_mode_stamps_git_sha(): text = _HOOK.read_text(encoding="utf-8") # The new Strategy-A rebuild mode exists and is keyed on --build-staging. assert '"${1:-}" == "--build-staging"' in text # It rebuilds the staging image stamping the validated commit as a build-arg. assert 'docker build --build-arg GIT_SHA="$GIT_SHA"' in text def test_tc07_build_staging_builds_from_caller_context_not_repo(): """Contract (caller <-> hook): --build-staging must build from the caller-supplied BUILD_CONTEXT (the validated worktree), NOT the prod clone. Regression guard for the P0 deadlock: the block must honour the caller's GIT_SHA (BUILD_CONTEXT/GIT_SHA defaulting) and must NOT recompute the SHA from the host clone's HEAD (`git rev-parse HEAD`) — on the deploy-staging -> deploy edge `main` HEAD != validated SHA, which would stamp the wrong revision label and deadlock the Strategy-B guard. """ block = _build_staging_block() # Build context is the caller-supplied worktree, defaulting to $REPO. assert 'BUILD_CONTEXT="${BUILD_CONTEXT:-$REPO}"' in block assert 'docker build --build-arg GIT_SHA="$GIT_SHA" -t "$TARGET_IMAGE" "$BUILD_CONTEXT"' in block # Honour the caller's GIT_SHA; never hard-build against the prod clone. assert 'GIT_SHA="${GIT_SHA:-}"' in block assert 'docker build --build-arg GIT_SHA="$GIT_SHA" -t "$TARGET_IMAGE" "$REPO"' not in block # Must NOT recompute the validated SHA from the host clone's HEAD. assert "git rev-parse HEAD" not in block def test_tc07_build_staging_recreates_and_health_checks_8501(): """AC-4: --build-staging must recreate the staging container on the fresh image and validate it (health-check), so rebuild_staging_image's rc=0 truly means "rebuilt AND healthy". A bare `docker build` + exit 0 would make the freshness verdict a lie.""" block = _build_staging_block() # Recreate the staging service on the freshly built image. assert 'docker compose --profile "$COMPOSE_PROFILE" up -d --no-build "$TARGET_SERVICE"' in block # Validate the fresh container before reporting success. assert 'health_check 10 6 "build-staging-health"' in block # Health failure surfaces as a non-zero exit (FAILED contract preserved). assert "exit 1" in block # --------------------------------------------------------------------------- # TC-08: Dockerfile stamps the OCI revision label from a build-arg # --------------------------------------------------------------------------- def test_tc08_dockerfile_stamps_revision_label(): text = _DOCKERFILE.read_text(encoding="utf-8") assert "ARG GIT_SHA" in text assert "LABEL org.opencontainers.image.revision=$GIT_SHA" in text