//! `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 = 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 = 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::>(), "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 { 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::().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(); }