Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,15 @@ jobs:
tar -xzf /tmp/helm.tgz -C /tmp
sudo mv /tmp/linux-amd64/helm /usr/local/bin/helm
helm version
# ci-go-mod-prefetch FP-GMP-1a: F15/F16's Python tests launch go build /
# go test subprocesses. Their modules are fetched here, in setup, into
# Go's ordinary module cache for this job, which those subprocesses
# inherit; a module-proxy error fails this step before the measured
# pytest starts, instead of surfacing as a product test failure. No
# condition, retry or failure tolerance: the default shell's nonzero exit
# fails the job. Pinned exactly in tests/functional/test_manifests.py.
- name: Download Go modules for F15/F16
run: go mod download
# FP-M6-31 A10(v): runtime env hygiene immediately before the guard's own
# pytest process (ordinary import mode; a PYTHONPATH would own the guard).
- name: FP-M6-31 A10(v) environment hygiene before functional pytest
Expand Down
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,47 @@ services/worker/.venv/bin/python -m pytest \
go test ./tests/functional/... -timeout 300s
```

*Go module cache for F15/F16.* F15
(`tests/functional/test_m6_go_config_env_interpolation.py`) and F16
(`tests/functional/test_m6_audit_completeness.py`) launch `go build` /
`go test` subprocesses that inherit the caller's `GOMODCACHE` unchanged, or
Go's default (`go env GOMODCACHE`) when it is unset. The tests never choose
another cache path and never skip work based on what the cache holds. CI's
`functional` job fills that cache with a `go mod download` setup step before
its hygiene gate and pytest, so a module-proxy error fails setup, not a test.
Do the same locally before the tier: `go mod download` from the repository
root.

Inside a jail or sandbox whose default module-cache location is not writable,
the launcher or caller owns the cache: create or mount an absolute, writable
directory, export `GOMODCACHE` to it **into the jail and into the pytest
process**, and make the current module graph available there, either by a
successful `go mod download` while a module source is reachable or by mounting
a prefilled cache. Check it before starting pytest, and stop at setup if any
check fails:

```bash
export GOMODCACHE=/abs/writable/go-mod # stays set for the pytest below
mkdir -p "$GOMODCACHE"
touch "$GOMODCACHE/.write-probe" && rm "$GOMODCACHE/.write-probe" \
|| { echo "GOMODCACHE is not writable; stopping at setup" >&2; exit 1; }
[ "$(go env GOMODCACHE)" = "$GOMODCACHE" ] \
|| { echo "GOMODCACHE does not reach go env; stopping at setup" >&2; exit 1; }
# Module source reachable: fill the cache. Prefilled mount, no source:
# GOPROXY=off go mod download (proves the mount holds the whole graph)
go mod download \
|| { echo "cannot provide Go modules; stopping at setup" >&2; exit 1; }
services/worker/.venv/bin/python -m pytest \
tests/functional/test_m6_go_config_env_interpolation.py -v
```

This is local runner configuration, never an `env:` entry in
`.github/workflows/ci.yml` (its Go jobs declare no `GO*` key).
`scripts/integration-test.sh py` inherits the caller's environment and needs
nothing cache-specific. The review-runner image is one example of
environment-owned setup: `deploy/review-runner/Dockerfile` sets
`GOMODCACHE=/opt/review-go/pkg/mod` and preloads it at image build.

See [`tests/delivery/README.md`](tests/delivery/README.md) for what the
delivery tier asserts (Dockerfiles, charts, compose files, docs, `ci.yml`).

Expand Down
1 change: 0 additions & 1 deletion tests/functional/test_m6_audit_completeness.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,6 @@ def _run_go_f16_test(postgres_dsn: str, test_name: str, *, audit: bool, refresh:
if refresh:
env["F16_REFRESH_DSN"] = dsn
env["GOCACHE"] = env.get("GOCACHE", "/tmp/go-cache")
env["GOMODCACHE"] = env.get("GOMODCACHE", "/tmp/go-mod")
proc = subprocess.run(
[
"go",
Expand Down
3 changes: 0 additions & 3 deletions tests/functional/test_m6_go_config_env_interpolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
def _build(bin_path: Path, package: str) -> None:
env = os.environ.copy()
env["GOCACHE"] = "/tmp/go-cache"
env["GOMODCACHE"] = env.get("GOMODCACHE", "/tmp/go-mod")
env["CGO_ENABLED"] = "0"
proc = subprocess.run(
["go", "build", "-o", str(bin_path), package],
Expand All @@ -37,7 +36,6 @@ def test_probe_config_interpolates_bootstrap_token(tmp_path):
# Package-level Load asserts the resolved value (not just "no parse error").
env = os.environ.copy()
env["GOCACHE"] = "/tmp/go-cache"
env["GOMODCACHE"] = env.get("GOMODCACHE", "/tmp/go-mod")
env["BOOTSTRAP_TOKEN"] = "tok-from-env-f15"
proc = subprocess.run(
[
Expand Down Expand Up @@ -93,7 +91,6 @@ def test_probe_gateway_config_interpolates_postgres_dsn(tmp_path):
"""Real probe-gateway config.Load resolves ${PG_DSN} with YAML-significant chars."""
env = os.environ.copy()
env["GOCACHE"] = "/tmp/go-cache"
env["GOMODCACHE"] = env.get("GOMODCACHE", "/tmp/go-mod")
# HASH_PW / adversarial values are set inside the unit test via t.Setenv;
# also set here so a subprocess-visible env matches production compose shape.
env["HASH_PW"] = "p@ss #word"
Expand Down
Loading
Loading