test(e2e): the npm HEAD-fill row, and two rows' reads behind the harness surface
What this adds
One npm catalog row, the reads behind two more, and a correction to a limitation entry whose stated reason was measurably false.
e2e.npm.remote.tarball-head-fillsimplemented, withregistry.Version.LastDownloadedAtand the shared polling helpers ine2e/bootstrap/counters.goit needs.- Two rows' tests without their scenario ids, in
e2e/bootstrap/harness/npm_counters_test.go. See below. - The counter limitation re-filed as the two cadences it actually is.
The entry that was wrong
### A counter is not in the response claimed the figures are absent from every response
and that a read races the drain. Both halves are false: artifacts_count,
downloads_count and size_bytes are all required on the Repository schema, and the
race is what AwaitCounters and AssertCountersHold already handle — three container
counter rows are implemented against them. The entry is deleted and replaced by
### A counter settles on a cadence the rig does not shorten, which names the two real
clocks: lifecycle.sweep_interval at 5 minutes and
storage_accounting.reconciliation_interval at an hour, against a 30-second poll.
downloads_count is not the column these rows want. Its only writer is
MavenRepositoryStore.BumpRepoDownloadCount, reached only from Maven's archive GET. An
npm test asserting it stayed at 0 could not fail. The rows read last_downloaded_at on
the cached version instead, and each carries a positive control — a delivering
fresh-hit GET that must move the record — so a column nothing writes cannot satisfy the
negative.
Two rows carry tests but no scenario id
e2e.npm.remote.tarball-conditional and e2e.npm.lifecycle.repository-storage-counters
stay uncovered, because each cell has a clause this suite cannot reach: a storage read
that leaves no trace outside the process, and a purge that waits out a 5-minute sweep.
Rather than assert the reachable parts and mark the rows covered, the tests moved to the
harness surface declaring no id, and both clauses are indexed. e2e/README.md's
"A scenario id is a subtest name, and a client surface holds only those" is what decides
where they live.
One line of rig values (lifecycle: sweep_interval) makes both this row and the
management-delete row writable — named as the Lifted by on the entry.
A precedent that needs its own decision
e2e.npm.remote.tarball-name-rejected is implemented and is narrowed two ways. Its
"answered before any cache lookup" clause is unasserted, and — larger — its cell
enumerates four file-name shapes that must be refused (.., /, a backslash, a control
byte) while the test drives one address covering two of them. No %5c, no %00. Left
untouched here; it is its own change and its own decision.
Reviewable LOC
9 files, +619/−33. Past 500, and the harness-surface file is the bulk of it.
| Group | +/− |
|---|---|
e2e/bootstrap/harness/npm_counters_test.go |
+356 |
e2e/bootstrap/counters.go shared helpers |
+79/−2 |
e2e/bootstrap/npm/remote_test.go |
+37 |
| harness clients | +29/−7 |
patterns.go |
+8 |
docs (limitations.md, npm.md, e2e/README.md) |
+110/−24 |
If it should be split, the cut is the conditional test (~110) from the counter journey (~245).
Verification
e2e-catalog check: 0 disagreements.go build -tags=e2e ./e2e/...,go test ./e2e/...: pass.golangci-lint --build-tags=e2eat the pinned 2.13.2: 0 issues.check-comment-caps.shand--base origin/main: both OK.
Unverified against a live caproni rig. The counter journey's footprint arithmetic in particular has never been run against real bytes.