b0ee7da5be
Adds tests/ with a tiny bash assert harness, manifest fixtures, and a
runner. No framework dependency — each test file is self-contained
and exits 0 on pass / 1 on fail; tests/run_tests.sh aggregates.
Unit tests (no docker):
- pipelock_naming: container_name, proxy_url, proxy_host_port shape
- pipelock_classify: _pipelock_is_ipv4_literal classifier coverage
- pipelock_allowlist: bottle_allowlist + ssh hostnames/ip_cidrs/
trusted_domains + effective_allowlist union/dedup/sort, plus
rejection of non-string entries
- pipelock_yaml: emitter shape (mode/enforce/api_allowlist/forward_proxy/
dlp), conditional ssrf+trusted_domains blocks, secret hygiene
(manifest env values must not appear in YAML), file mode 600
Integration tests (require docker, skip cleanly otherwise):
- pipelock_image: pinned digest's ENTRYPOINT is /pipelock and CMD
contains 'run' and the binary --version succeeds — would catch a
future image bump that changes the launcher's argv contract
- pipelock_sidecar_smoke: docker create + cp YAML to /etc/pipelock.yaml
+ start, then probe /health — the regression test for the bug
where the YAML was written to /etc/pipelock/ (parent dir absent in
the distroless image)
- dry_run_plan: cli.sh start --dry-run shows the egress line,
counts the bottle's entry into the effective allowlist, prints
the dry-run banner, and creates zero docker resources
- orphan_cleanup: the cleanup primitives the start-flow trap depends
on (network_remove, pipelock_stop) are idempotent against
missing/never-existed resources, so the trap is safe even if
pipelock_start dies before everything is wired up
Assisted-by: Claude Code
41 lines
1.6 KiB
Bash
Executable File
41 lines
1.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Integration: verify the pinned pipelock image. Requires docker.
|
|
# - Pinned digest is reachable on the registry.
|
|
# - Image's ENTRYPOINT/CMD match what lib/pipelock.sh assumes
|
|
# (`/pipelock` and `run --listen 0.0.0.0:8888`).
|
|
# - The /pipelock binary actually runs (--version succeeds).
|
|
#
|
|
# This is the test that would have caught the runtime bug where the
|
|
# CMD shape diverged from what the launcher passed.
|
|
TEST_NAME="pipelock_image"
|
|
|
|
. "$(dirname "$0")/../lib/common.sh"
|
|
# shellcheck source=../../lib/log.sh
|
|
. "${REPO_ROOT}/lib/log.sh"
|
|
# shellcheck source=../../lib/pipelock.sh
|
|
. "${REPO_ROOT}/lib/pipelock.sh"
|
|
|
|
skip_test_if_no_docker
|
|
|
|
# Pull the pinned image (cheap if already cached).
|
|
if ! docker pull "$CLAUDE_BOTTLE_PIPELOCK_IMAGE" >/dev/null 2>&1; then
|
|
skip "could not pull ${CLAUDE_BOTTLE_PIPELOCK_IMAGE}"
|
|
exit 0
|
|
fi
|
|
|
|
# ENTRYPOINT must be the binary path lib/pipelock.sh expects.
|
|
entrypoint="$(docker image inspect "$CLAUDE_BOTTLE_PIPELOCK_IMAGE" --format '{{json .Config.Entrypoint}}')"
|
|
assert_contains "$entrypoint" "/pipelock" "entrypoint contains /pipelock"
|
|
|
|
# CMD must include `run` — the subcommand the launcher overrides via
|
|
# `docker create ... run --config ... --listen ...`. If a future image
|
|
# bumps the CMD shape, this fails loudly.
|
|
cmd="$(docker image inspect "$CLAUDE_BOTTLE_PIPELOCK_IMAGE" --format '{{json .Config.Cmd}}')"
|
|
assert_contains "$cmd" "run" "cmd contains 'run'"
|
|
|
|
# Binary actually runs.
|
|
ver="$(docker run --rm "$CLAUDE_BOTTLE_PIPELOCK_IMAGE" --version 2>&1 || true)"
|
|
assert_match "$ver" "[Pp]ipelock|2\\.[0-9]+\\.[0-9]+" "binary --version produces version-shaped output"
|
|
|
|
test_summary
|