test(e2e): assert the counters a remote container fill moves

Adds the namespace-statistics client method the suite was missing, and asserts every clause of e2e.oci.remote.fill-storage-counters that the rig can reach.

The row stays not started on purpose. Read the next section before the diff — a test that lands without flipping its Status looks like an oversight and is not one.

Why the Status does not move

Two of the row's six clause groups cannot be reached, so a test bearing the scenario's exact name would make the catalog claim coverage it does not have. README defines implemented as "the suite contains a test with the scenario's exact name", so the way to assert real substance without that claim is to declare no scenario id — the same shape e2e/bootstrap/harness/npm_counters_test.go already uses.

Clause group Reachable Why
repository size_bytes, artifacts_count yes lands on the counter drain, lowered to 2s in the rig, inside AwaitCounters' 30s bound
namespace deduplicated_size_bytes, components_count yes, once this method exists getNamespaceStatistics is live and wired
"a reconciliation pass then moves no counter" no 1h interval, the rig does not lower it, no RunOnStart, no API trigger. Recorded in #1282 (closed)
the re-tag clause no needs a cached tag to go stale, and cache_validity_hours is an integer with minimum: 0 where 0 means never revalidate — so the smallest revalidating window is one hour

That last one is a new finding: it is the cache-age floor, a different limitation from the reconciliation one, and neither #1282 (closed) nor the investigation that preceded this MR identified it as reaching this row.

Narrowing the cell to drop both clauses would let the Status move, and narrowing a cell is an operator decision rather than this MR's to take. If that decision lands, flipping is a one-commit change from here.

What this adds

File Change
e2e/internal/registry/registry.go NamespaceStatistics type, wire struct, and Client.NamespaceStatistics
e2e/internal/registry/registry_test.go four unit tests for it
e2e/bootstrap/counters.go repository and namespace read/await/hold pairs over an awaitCounters and a countersAfterHold generic, which the pre-existing helpers now delegate to as well
e2e/bootstrap/oci/remote_counters_test.go the test

Neither deduplicated_size_bytes nor components_count appeared anywhere under e2e/ before this, so the namespace half of every counter row was unreadable. Field names and shapes were confirmed against api/openapi/v1.yaml.

The row's counter arithmetic was re-derived clause by clause against internal/format/oci/remote_fill_emit.go rather than taken from the row text, because the row asserts which counts move and which do not, and a wrong "moves neither" passes vacuously.

Why namespace assertions are sound here

Harness.NewFixture derives a slug per test from names.For(testName) and seeds its own namespace ((*Harness).NewFixture in e2e/internal/hosted/hosted.go — the target merge moved it there out of e2e/bootstrap/harness.go, which now aliases bootstrap.Fixture to hosted.Fixture), so the bootstrap profile does not share one namespace. That is the opposite of the authz profile, where DefaultOrganizationStrategy is SharedOrganization and a namespace-scoped assertion would see another test's writes.

The test lives in e2e/bootstrap/oci/ rather than harness/ — the usual home for no-scenario-id tests — because the mirror machinery it needs (manifestMirror, readManifest, readBlob) lives in oci_test, and copying it would violate the warning in counters.go's own header about two copies drifting.

One inconsistency left out of scope

api/openapi/v1.yaml's endpoint-level prose says the stored namespace figures "follow that pass rather than the live count", while the schema says the drain writes them and reconciliation only corrects a lag. The schema is what the code does; the endpoint prose is misleading. Fixing it is not this MR's job.

Verification

Gate Result
e2e-catalog generate -check exit 0
e2e-catalog check disagreements 0; 211 / 185 / 154 and authorable 0, all unchanged by design
go vet -tags=e2e ./e2e/... exit 0 (the compile gate; go build skips _test.go)
go test -tags=e2e -run XXX -exec /bin/true ./e2e/... exit 0, builds and links
go test ./e2e/internal/registry/... ok
golangci-lint run --build-tags=e2e (pinned 2.13) 0 issues.
scripts/ci/check-comment-caps.sh OK

No Markdown is touched, so no vale or markdownlint run applies.

What a rig run still has to prove

No rig was available. The four counter deltas, the refetch hold, and the per-tick pairing assumption are unverified against a live drain. Compilation, linking, linting and the unit tests all pass.

Edited by Suleimi Ahmed

Merge request reports

Loading
Loading