A figure is held to the offer's uncertainty, wider or narrower than the receipt's own. The texts give that: a declared standard uncertainty bounds nothing (energy-measurement 2.1 and 2.3); ModelBased, Estimator and a receipt of no class declare none, so a comparison has nothing to read for them; and with the declaration in the rule, what a hop writes of its figure would buy a verdict or cost one. A receipt graded below its offer is already held this way, its evidence read beside the verdict. The code read it so and no vector held the wider direction: every offer vector's counter declared the offer's own 20,000 ppm, but for the largest uncertainty, which is narrower. A verifier taking the wider of the two, or guarding a figure by a declaration past the offer's, passed the corpus. Three vectors now hold both directions in both verifiers: a declaration of 500,000 ppm at the figure is within, one of 1,000 ppm at the edge is within, and one of 500,000 ppm a microjoule past the edge with no flag is refused. Every earlier vector is unchanged. Co-Authored-By: Claude Opus 5.5 <[email protected]>
286 lines
18 KiB
Rust
286 lines
18 KiB
Rust
//! `wai.route.record` (extensions/route-record.md): the committed corpus
|
|
//! `live-conformance/routes/vectors.json` regenerates byte for byte from its seeds and is the
|
|
//! only file there besides its README; every vector gets the outcome it states; every reason
|
|
//! the extension adds and every code it reuses refuses a vector; the accepted vectors are the
|
|
//! cases §10 names, of version 1 and of version 2; a record a router seals verifies, and an
|
|
//! edit of any of its documents or of the record is refused; and §8 lists exactly the reasons
|
|
//! the reference reports.
|
|
#![cfg(feature = "route_record")]
|
|
|
|
use std::collections::BTreeSet;
|
|
use std::path::PathBuf;
|
|
|
|
use serde_json::Value;
|
|
use wai::route_record::{self, corpus, Reason};
|
|
|
|
fn wai_dir() -> PathBuf {
|
|
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..")
|
|
}
|
|
|
|
fn committed() -> String {
|
|
std::fs::read_to_string(wai_dir().join("live-conformance/routes/vectors.json")).expect("the corpus")
|
|
}
|
|
|
|
fn doc() -> Value {
|
|
serde_json::from_str(&committed()).unwrap()
|
|
}
|
|
|
|
fn vector(d: &Value, name: &str) -> Value {
|
|
d["vectors"].as_array().unwrap().iter().find(|v| v["name"] == name).unwrap_or_else(|| panic!("no vector {name}")).clone()
|
|
}
|
|
|
|
#[test]
|
|
fn the_committed_corpus_regenerates_from_its_seeds() {
|
|
assert!(committed() == corpus::generate().expect("the corpus generates"), "live-conformance/routes/vectors.json differs from `wai_route_record_vectors gen`");
|
|
let mut files: Vec<String> = std::fs::read_dir(wai_dir().join("live-conformance/routes")).unwrap().flatten().map(|e| e.file_name().to_string_lossy().into_owned()).collect();
|
|
files.sort();
|
|
assert_eq!(files, ["README.md", "vectors.json"]);
|
|
}
|
|
|
|
#[test]
|
|
fn every_vector_gets_its_stated_outcome() {
|
|
let fails = corpus::verify_corpus(&committed());
|
|
assert!(fails.is_empty(), "{}", fails.join("\n"));
|
|
}
|
|
|
|
#[test]
|
|
fn the_corpus_refuses_every_reason() {
|
|
let d = doc();
|
|
let seen: BTreeSet<&str> = d["vectors"].as_array().unwrap().iter().filter_map(|v| v["outcome"]["reason"].as_str()).collect();
|
|
for r in Reason::ALL.iter().chain(Reason::REUSED.iter()) {
|
|
assert!(seen.contains(r.code()), "nothing in the corpus is refused {r}");
|
|
}
|
|
}
|
|
|
|
/// §10's third-party vectors: what each record states is read, in the order of its hops, and a
|
|
/// record is only as good as its signature and its hop.
|
|
#[test]
|
|
fn the_third_party_vectors_are_the_cases_section_10_names() {
|
|
let d = doc();
|
|
let outcome = |name: &str| vector(&d, name)["outcome"].clone();
|
|
let one = outcome("third_party_served_on_the_operators_account");
|
|
assert_eq!(one["outcome"], "accept");
|
|
let read = &one["third_party"][0];
|
|
assert_eq!((read["hop"].as_u64(), read["account"].as_str(), read["usage"]["unit"].as_str(), &read["charge"]), (Some(1), Some("operator"), Some("subpixels"), &Value::Null));
|
|
assert_eq!(outcome("third_party_served_with_the_providers_charge_and_its_job")["third_party"][0]["charge"]["amount"], "0.0345");
|
|
let billed = outcome("third_party_a_failure_the_provider_bills_beside_a_served_hop");
|
|
assert_eq!(billed["third_party"][0]["usage"]["quantity"], 1_000, "what the provider bills for a failure");
|
|
assert_eq!(billed["third_party"].as_array().unwrap().len(), 2);
|
|
assert!(outcome("third_party_a_failure_it_does_not_bill")["third_party"][0]["usage"].is_null());
|
|
let hops: Vec<u64> = outcome("third_party_records_given_out_of_order")["third_party"].as_array().unwrap().iter().map(|t| t["hop"].as_u64().unwrap()).collect();
|
|
assert_eq!(hops, [1, 2], "the order of their hops, not of the document");
|
|
assert_eq!(outcome("third_party_on_the_customers_account")["third_party"][0]["account"], "customer");
|
|
assert_eq!(outcome("third_party_under_a_record_of_version_2")["outcome"], "accept");
|
|
assert_eq!(outcome("third_party_no_record_given")["third_party"], serde_json::json!([]));
|
|
// A document with no such member reads as before, its outcome with none.
|
|
assert!(outcome("v3_served_one_output").get("third_party").is_none());
|
|
// A kept response holds a signed link's URL without its query, and a fraction as its text.
|
|
let kept = vector(&d, "third_party_a_response_as_a_record_keeps_it");
|
|
let text = kept["document"]["third_party"][0].as_str().unwrap();
|
|
assert!(text.contains("https://cdn.provider.example/v.mp4\"") && !text.contains("bearer") && text.contains("\"0.4\""));
|
|
// The three reasons, each from a control of one defect.
|
|
for (name, reason) in [
|
|
("third_party_a_key_stated", "third_party_invalid"),
|
|
("third_party_a_url_with_its_query", "third_party_invalid"),
|
|
("third_party_a_response_keeping_a_signed_link", "third_party_invalid"),
|
|
("third_party_another_routers", "third_party_mismatch"),
|
|
("third_party_a_usage_in_another_unit", "third_party_mismatch"),
|
|
("third_party_outputs_the_receipt_does_not_name", "third_party_output_mismatch"),
|
|
("third_party_another_number_than_the_attempts_count", "third_party_output_mismatch"),
|
|
] {
|
|
assert_eq!(outcome(name)["reason"], reason, "{name}");
|
|
}
|
|
}
|
|
|
|
/// The accepted vectors are §10's: a billed first try, a failover whose failed hop is unmetered
|
|
/// and not billed, a hop past the deadline not billed, every allowed survivor failed, no
|
|
/// survivor at all, each way a decision is decided, and every limit removing a candidate.
|
|
#[test]
|
|
fn the_accepted_vectors_are_the_cases_section_10_names() {
|
|
let d = doc();
|
|
let o = |n: &str| vector(&d, n)["outcome"].clone();
|
|
let first = o("served_first_try");
|
|
assert_eq!((first["served"]["endpoint"].as_str(), first["billed"].as_u64(), first["deadline"].as_str()), (Some("im.alpha"), Some(1), Some("met")));
|
|
assert_eq!(first["unmetered"], serde_json::json!([]));
|
|
let fo = o("failover_after_a_server_error");
|
|
assert_eq!((fo["served"]["hop"].as_u64(), fo["billed"].as_u64()), (Some(2), Some(2)));
|
|
assert_eq!(fo["unmetered"], serde_json::json!([1]), "the failed hop's receipt states the unmetered marker");
|
|
let late = o("served_after_the_deadline");
|
|
assert_eq!((late["billed"].clone(), late["deadline"].as_str()), (Value::Null, Some("missed")));
|
|
let failed = o("every_allowed_survivor_failed");
|
|
assert_eq!((failed["served"].clone(), failed["billed"].clone()), (Value::Null, Value::Null));
|
|
assert_eq!(failed["order"].as_array().unwrap().len(), 3, "three survivors, two allowed");
|
|
assert_eq!(o("no_candidate_survives")["decision"]["decided_by"], "none");
|
|
for (n, by) in [
|
|
("served_first_try", "price"),
|
|
("decided_by_the_targets", "targets"),
|
|
("decided_by_the_sort", "ttfb"),
|
|
("an_unknown_energy_ranks_last", "energy"),
|
|
("decided_by_the_endpoint", "endpoint"),
|
|
("decided_by_quality", "quality"),
|
|
("decided_by_the_policys_second_key", "quality"),
|
|
("only_survivor", "only_survivor"),
|
|
] {
|
|
assert_eq!(o(n)["decision"]["decided_by"], by, "{n}");
|
|
}
|
|
assert_eq!(o("an_unknown_energy_ranks_last")["order"].as_array().unwrap().last().unwrap(), "av1.beta", "the survivor with no energy figure ranks last");
|
|
assert_eq!(o("receipts_not_checked")["receipts"], "not_checked");
|
|
let mut limits = BTreeSet::new();
|
|
for v in d["vectors"].as_array().unwrap().iter().filter(|v| v["outcome"]["outcome"] == "accept") {
|
|
for r in v["outcome"]["removed"].as_array().unwrap() {
|
|
for l in r["limits"].as_array().unwrap() {
|
|
limits.insert(l.as_str().unwrap().to_string());
|
|
}
|
|
}
|
|
}
|
|
assert_eq!(limits, route_record::LIMITS.iter().map(|l| l.to_string()).collect::<BTreeSet<_>>(), "every limit removes a candidate");
|
|
}
|
|
|
|
/// Version 2's accepted vectors are §10's: each endpoint ranked by what one served job costs at
|
|
/// it, failures included (an endpoint that fails ranked after one of the same list price, a
|
|
/// cheaper one that fails more after both, the unmeasured, the thin basis and the failed one
|
|
/// after every measured endpoint); a decode at its own price; the time to first byte and the
|
|
/// targets read per successful job; the ceiling the list cost; a book with no failure measured
|
|
/// ranked by the list cost; and the served hop's outputs, one or three, stated in the outcome.
|
|
#[test]
|
|
fn the_version_2_vectors_are_the_cases_section_10_names() {
|
|
let d = doc();
|
|
let o = |n: &str| vector(&d, n)["outcome"].clone();
|
|
let order = |n: &str| -> Vec<String> { o(n)["order"].as_array().unwrap().iter().map(|x| x.as_str().unwrap().to_string()).collect() };
|
|
let cost = o("v2_ranked_by_the_expected_cost");
|
|
assert_eq!(order("v2_ranked_by_the_expected_cost"), ["im.alpha", "im.eta", "im.iota", "im.beta", "im.zeta", "im.theta", "im.gamma", "im.epsilon", "im.delta", "av1.alpha"]);
|
|
assert_eq!(cost["decision"], serde_json::json!({"decided_by": "price", "runner_up": "im.eta"}));
|
|
assert_eq!(cost["served"]["outputs"].as_array().unwrap().len(), 1);
|
|
assert_eq!(order("v2_a_decode_at_its_own_price"), ["im.alpha", "im.beta"], "the decodes alone, each at its own price, under a cap the encodes exceed");
|
|
assert_eq!(order("v2_ranked_by_the_expected_time_to_first_byte")[..6], ["im.theta", "im.iota", "im.alpha", "im.zeta", "im.beta", "im.eta"]);
|
|
assert_eq!(o("v2_the_targets_read_the_expected_time_to_first_byte")["decision"], serde_json::json!({"decided_by": "targets", "runner_up": "im.alpha"}));
|
|
assert!(order("v2_the_ceiling_reads_the_list_cost").contains(&"im.zeta".to_string()), "a list cost under the ceiling survives whatever its failures add");
|
|
assert!(!order("v2_the_ceiling_reads_the_list_cost").contains(&"im.theta".to_string()));
|
|
assert_eq!(order("v2_no_failure_measured_ranks_by_the_list_cost")[..4], ["im.gamma", "im.epsilon", "im.zeta", "im.delta"]);
|
|
assert_eq!(o("v2_served_three_outputs")["served"]["outputs"].as_array().unwrap().len(), 3);
|
|
let fo = o("v2_failover_whose_failed_hop_delivered_nothing");
|
|
assert_eq!((fo["served"]["endpoint"].as_str(), fo["billed"].as_u64()), (Some("im.eta"), Some(2)));
|
|
let late = o("v2_served_after_the_deadline");
|
|
assert_eq!((late["billed"].clone(), late["deadline"].as_str(), late["served"]["outputs"].as_array().map(Vec::len)), (Value::Null, Some("missed"), Some(1)));
|
|
assert_eq!(o("v2_receipts_not_checked")["receipts"], "not_checked");
|
|
// Version 1's outcomes state no outputs.
|
|
assert!(o("served_first_try")["served"].get("outputs").is_none());
|
|
}
|
|
|
|
/// §10's offer vectors: a delivery's route's receipt is held to the offer its decision states, a
|
|
/// figure past one declared uncertainty carrying its hop's flag, and the outcome says which.
|
|
#[test]
|
|
fn a_delivery_is_held_to_its_offer() {
|
|
let d = doc();
|
|
let conformance = |name: &str| vector(&d, name)["outcome"]["deliveries"].as_array().unwrap().last().unwrap()["conformance"].clone();
|
|
for (name, verdict, energy, grade) in [
|
|
("offer_a_receipt_below_its_figure", "within", Some(5_500_000u64), "measured"),
|
|
("offer_a_receipt_one_uncertainty_above", "within", Some(6_120_000), "measured"),
|
|
("offer_a_figure_that_rounds_down_to_the_edge", "within", Some(6_120_000), "measured"),
|
|
("offer_a_receipt_above_it_and_flagged", "exceeded", Some(6_120_001), "measured"),
|
|
("offer_a_figure_that_rounds_up_past_the_edge_and_flagged", "exceeded", Some(6_120_002), "measured"),
|
|
("offer_a_receipt_unmetered", "unmetered", None, "projected"),
|
|
("offer_of_no_figure", "no_figure", Some(6_000_000), "measured"),
|
|
("offer_a_model_figure_at_its_figure", "within", Some(6_000_000), "derived"),
|
|
("offer_a_model_figure_above_it_and_flagged", "exceeded", Some(6_000_001), "derived"),
|
|
("offer_a_weaker_receipt_than_its_offer", "within", Some(5_500_000), "derived"),
|
|
("offer_a_receipt_declaring_more_than_its_offer", "within", Some(6_000_000), "measured"),
|
|
("offer_a_receipt_declaring_less_at_the_edge", "within", Some(6_120_000), "measured"),
|
|
] {
|
|
let c = conformance(name);
|
|
assert_eq!(c["verdict"], verdict, "{name}");
|
|
assert_eq!(c["energy"].as_u64(), energy, "{name}");
|
|
assert_eq!(c["grade"], grade, "{name}");
|
|
assert!(c["receipt"].is_string(), "{name}");
|
|
}
|
|
assert_eq!(conformance("offer_no_receipt_given")["verdict"], "not_checked");
|
|
// The offer is the route's entry, and a decision of version 1 states none.
|
|
let offer = &vector(&d, "offer_a_receipt_below_its_figure")["outcome"]["deliveries"][0]["offer"];
|
|
assert_eq!(*offer, serde_json::json!({"entry": 0, "unit": "bytes", "quantity": 3_000_000_000u64, "cost": 60_000, "energy": 6_000_000, "energy_class": "OnChipCounter", "energy_ppm": 20_000, "grade": "measured"}));
|
|
assert!(vector(&d, "offer_where_no_route_survives")["outcome"]["deliveries"][0]["offer"].is_null());
|
|
let chained = vector(&d, "offer_after_a_decision_of_version_1");
|
|
assert!(chained["outcome"]["deliveries"][0].get("offer").is_none(), "a decision of version 1 states no offer");
|
|
assert_eq!(chained["outcome"]["deliveries"][1]["conformance"]["verdict"], "within");
|
|
// The planted faults: above the offer unflagged, a flag on what holds, a grade above the offer.
|
|
for (name, reason) in [
|
|
("offer_a_receipt_above_it_without_the_flag", "delivery_price_unflagged"),
|
|
("offer_a_microjoule_past_without_the_flag", "delivery_price_unflagged"),
|
|
("offer_a_model_figure_a_microjoule_above", "delivery_price_unflagged"),
|
|
("offer_a_declaration_wider_than_the_figure_past_it", "delivery_price_unflagged"),
|
|
("offer_flagged_one_uncertainty_above", "delivery_price_misflagged"),
|
|
("offer_flagged_unmetered", "delivery_price_misflagged"),
|
|
("offer_a_measured_receipt_on_a_model_offer", "delivery_grade_exceeded"),
|
|
("offer_a_measured_receipt_above_and_flagged_on_a_model_offer", "delivery_grade_exceeded"),
|
|
] {
|
|
assert_eq!(vector(&d, name)["outcome"]["reason"], reason, "{name}");
|
|
}
|
|
}
|
|
|
|
/// No record rests on a price book of version 3 (§3.4), so no seal writes one: each panics and
|
|
/// signs nothing, where a book of version 2 seals as it did.
|
|
#[test]
|
|
fn a_router_seals_no_record_on_a_price_book_of_version_3() {
|
|
use route_record::{Policy, PriceBook, Request, seal, seal_committed, seal_delivered};
|
|
let d = doc();
|
|
let key = ed25519_dalek::SigningKey::from_bytes(&[7; 32]);
|
|
let read = |name: &str| {
|
|
let v = &vector(&d, name)["document"];
|
|
let text = |k: &str| v[k].as_str().unwrap().to_string();
|
|
(Request::read(&text("request")).unwrap(), PriceBook::read(&text("pricebook")).unwrap(), Policy::read(&text("policy")).unwrap())
|
|
};
|
|
let outputs = [[1u8; 32]];
|
|
let (r, b, p) = read("a_record_on_a_price_book_of_version_3");
|
|
assert_eq!(b.version, route_record::BOOK_VERSION_3);
|
|
let refused = |name: &str, seal: &dyn Fn() -> Value| {
|
|
let said = std::panic::catch_unwind(std::panic::AssertUnwindSafe(seal)).expect_err(name);
|
|
assert!(said.downcast_ref::<String>().map(String::as_str).or(said.downcast_ref::<&str>().copied()).is_some_and(|s| s.contains("no record rests on a price book of version 3")), "{name}");
|
|
};
|
|
refused("seal", &|| seal(&key, &r, &b, &p, 1, &[]));
|
|
refused("seal_delivered", &|| seal_delivered(&key, &r, &b, &p, 1, &[], &outputs));
|
|
refused("seal_committed", &|| seal_committed(&key, &r, &b, &p, 1, &[], &outputs));
|
|
let (_, two, _) = read("v2_ranked_by_the_expected_cost");
|
|
assert_eq!(seal_delivered(&key, &r, &two, &p, 1, &[], &outputs)["version"], 2);
|
|
assert_eq!(seal_committed(&key, &r, &two, &p, 1, &[], &outputs)["version"], 3);
|
|
}
|
|
|
|
/// A record verifies only against the documents it was routed from: each of them, and the
|
|
/// record, changed by one byte is refused.
|
|
#[test]
|
|
fn a_record_is_bound_to_its_documents() {
|
|
let d = doc();
|
|
for name in ["served_first_try", "v2_ranked_by_the_expected_cost"] {
|
|
let good = vector(&d, name)["document"].clone();
|
|
assert!(route_record::verify(&good).is_ok());
|
|
for member in ["request", "pricebook", "policy", "record"] {
|
|
let t = good[member].as_str().unwrap();
|
|
// A digit of a figure, changed: still a document, no longer the one routed.
|
|
let at = t.find(|c: char| c.is_ascii_digit() && c != '0').unwrap();
|
|
let mut b = t.as_bytes().to_vec();
|
|
b[at] = if b[at] == b'9' { b'8' } else { b[at] + 1 };
|
|
let mut x = good.clone();
|
|
x[member] = Value::from(String::from_utf8(b).unwrap());
|
|
assert!(route_record::verify(&x).is_err(), "{name}: {member} changed");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// `wai route verify` (the catalogue's `route.verify`) prints a document's outcome, the
|
|
/// corpus's, and exits 0 when the record is accepted and 1 when it is refused.
|
|
#[test]
|
|
fn route_verify_prints_the_outcome_and_exits_by_it() {
|
|
let d = doc();
|
|
let dir = std::env::temp_dir().join(format!("wai-route-verify-{}", std::process::id()));
|
|
std::fs::create_dir_all(&dir).unwrap();
|
|
for (name, code) in [("failover_after_a_server_error", 0), ("a_failed_hop_billed", 1), ("a_hop_receipt_not_given", 1), ("v2_served_three_outputs", 0), ("v2_a_receipt_moved_from_another_job", 1)] {
|
|
let v = vector(&d, name);
|
|
let p = dir.join(format!("{name}.json"));
|
|
std::fs::write(&p, serde_json::to_vec(&v["document"]).unwrap()).unwrap();
|
|
let o = std::process::Command::new(env!("CARGO_BIN_EXE_wai")).args(["route", "verify"]).arg(&p).output().unwrap();
|
|
assert_eq!(o.status.code(), Some(code), "{name}: {}", String::from_utf8_lossy(&o.stderr));
|
|
let got: Value = serde_json::from_slice(&o.stdout).unwrap();
|
|
assert_eq!(got, v["outcome"], "{name}");
|
|
}
|
|
let o = std::process::Command::new(env!("CARGO_BIN_EXE_wai")).args(["route", "verify"]).arg(dir.join("none.json")).output().unwrap();
|
|
assert_ne!(o.status.code(), Some(0), "a document that is not there is no accepted record");
|
|
std::fs::remove_dir_all(&dir).ok();
|
|
}
|