W3-7, public part. cache-conformance/: tests.json (C1–C13, R1–R5 as MUST tests of §9 and the sidecar rules, S1–S2 informative), driver.py (stages the corpus behind an origin and runs the tests against a cache; standard library and _blake3.py only), mutators.py (flip, gzip, truncate, vary: one §9 defect each), run.sh (the reference origin must pass every MUST test; each control must be caught by the tests named for it; labelled caches run where an environment provides /opt/wai-cache, and the summary says when none did) and a README. Reports name a cache by label, package version and configuration digest only. The private harness image is not in this repository. The reference origin gains what the tests need of it: If-Range by strong comparison, a live-edge prefix served with a shorter max-age, §8.4's Cache-Control for the key log and grants, and a request counter (--count-hits) for the informative tests. .github/workflows/wai-http.yml: the falsify job (every patch caught, every Python mutation caught, the differential) and the cache-conformance job (reports uploaded as an artifact). wai-conformance.yml: `http` joins the build, the library tests, the corpus loop (wai_http_vectors), the feature-alone and wasm32 checks; http_verify.py joins the independent verifiers. wai_http_vectors verify now names a case whose evaluation panics. http-delivery.md writes byte spans in words where a half-open interval read as link text to the section-reference check. Co-Authored-By: Claude Opus 5.5 <[email protected]>
25 lines
3.8 KiB
JSON
25 lines
3.8 KiB
JSON
{
|
|
"note": "The tests driver.py runs against an HTTP cache that fronts an origin serving wai/http-conformance's objects (extensions/http-delivery.md §9). A MUST test failing means the cache, as configured, does not meet §9; an informative test reports what the cache did.",
|
|
"tests": [
|
|
{ "id": "C1", "name": "whole_identity", "level": "MUST", "rule": "§9 rule 1", "what": "a GET of an object, cold and then again, returns exactly the object's bytes" },
|
|
{ "id": "C2", "name": "headers_kept", "level": "MUST", "rule": "§9 rule 3", "what": "a 200 keeps the origin's ETag, Content-Type and Cache-Control, and a Content-Length of the object's length" },
|
|
{ "id": "C3", "name": "range_from_stored", "level": "MUST", "rule": "§9 rule 2", "what": "after a whole GET, a single range is answered 206 with exactly those bytes and Content-Range bytes a-b/n" },
|
|
{ "id": "C4", "name": "range_cold", "level": "MUST", "rule": "§9 rule 2, §5.3", "what": "a single range on an object not yet fetched is answered 206 with exactly those bytes, or 200 with the whole object" },
|
|
{ "id": "C5", "name": "suffix_and_open_ranges", "level": "MUST", "rule": "§9 rule 2", "what": "bytes=-N and bytes=A- are answered with exactly those bytes" },
|
|
{ "id": "C6", "name": "unsatisfiable", "level": "MUST", "rule": "§9 rule 2", "what": "a range starting at the object's length is answered 416 with Content-Range bytes */n" },
|
|
{ "id": "C7", "name": "no_coding", "level": "MUST", "rule": "§9 rule 1", "what": "with Accept-Encoding offering codings, the object comes back with no Content-Encoding and its exact bytes" },
|
|
{ "id": "C8", "name": "if_range_strong", "level": "MUST", "rule": "§9 rule 5", "what": "If-Range with the object's ETag gets 206; with a weak form of it, or another ETag, the whole object" },
|
|
{ "id": "C9", "name": "no_vary_by_header", "level": "MUST", "rule": "§9 rule 4", "what": "requests that differ in User-Agent, Accept-Language and Accept get the same bytes, with no Vary" },
|
|
{ "id": "C10", "name": "head_proof_kept", "level": "MUST", "rule": "§9 rule 6, §6.2", "what": "a head proof is returned byte for byte with its immutable Cache-Control" },
|
|
{ "id": "C11", "name": "alias", "level": "MUST", "rule": "§5.2, §9 rule 1", "what": "an alias returns the object's exact bytes and its ETag" },
|
|
{ "id": "C12", "name": "live_edge_max_age", "level": "MUST", "rule": "§5.3, §9 rule 3", "what": "an object listed at a live edge keeps its shorter max-age and its bytes, whole and by range" },
|
|
{ "id": "C13", "name": "no_vary_cors", "level": "MUST", "rule": "§5.3, §9 rule 4", "what": "a request with Origin gets Access-Control-Allow-Origin: * and no Vary: Origin" },
|
|
{ "id": "R1", "name": "index_revalidated", "level": "MUST", "rule": "§9 rule 6, §8.2", "what": "a receipt index changed at the origin is returned changed on the next request" },
|
|
{ "id": "R2", "name": "receipt_file_kept", "level": "MUST", "rule": "§9 rule 6, §8.1", "what": "a receipt file is returned byte for byte with its immutable Cache-Control" },
|
|
{ "id": "R3", "name": "playlist_receipt_kept", "level": "MUST", "rule": "§9 rule 6, §8.6", "what": "a playlist receipt is returned byte for byte" },
|
|
{ "id": "R4", "name": "key_log_max_age", "level": "MUST", "rule": "§9 rule 6, §8.4", "what": "the key log is returned byte for byte with its Cache-Control" },
|
|
{ "id": "R5", "name": "parameter_set_kept", "level": "MUST", "rule": "§9 rule 6, §8.5", "what": "a parameter set named by its digest is returned byte for byte and hashes to its name" },
|
|
{ "id": "S1", "name": "stored", "level": "informative", "rule": "§9", "what": "a second GET of an object is answered without reaching the origin" },
|
|
{ "id": "S2", "name": "range_stored", "level": "informative", "rule": "§9 rule 2", "what": "a range after a whole GET is answered without reaching the origin" }
|
|
]
|
|
}
|