sandbox-conformance: hold the committed pack to what the builders emit #422
4 changed files with 44 additions and 44 deletions
|
|
@ -258,7 +258,9 @@ pub struct Attestation {
|
|||
pub audit_prev: Option<ContentId>,
|
||||
/// How confinement was established (SPEC §7.9). Meaningful at S1–S5, where
|
||||
/// the tier is otherwise host-asserted with no in-band evidence; MUST be
|
||||
/// absent at S0, which is unconfined by definition.
|
||||
/// absent at S0, which is unconfined by definition. Omitted from the
|
||||
/// serialized form when absent, as from the signed core (§7.9).
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub mechanism: Option<Mechanism>,
|
||||
/// Evidence bounding where the run could **not** have executed (SPEC §7.7).
|
||||
///
|
||||
|
|
|
|||
|
|
@ -12,51 +12,11 @@ use sandbox_conformance::vectors;
|
|||
fn main() -> std::io::Result<()> {
|
||||
let dir = vectors::vectors_dir();
|
||||
std::fs::create_dir_all(&dir)?;
|
||||
|
||||
let write = |name: &str, json: String| -> std::io::Result<()> {
|
||||
for (name, bytes) in vectors::rendered() {
|
||||
let path = dir.join(name);
|
||||
std::fs::write(&path, json + "\n")?;
|
||||
std::fs::write(&path, bytes)?;
|
||||
println!("wrote {}", path.display());
|
||||
Ok(())
|
||||
};
|
||||
|
||||
write(
|
||||
"content_addressing.json",
|
||||
serde_json::to_string_pretty(&vectors::content_vectors()).unwrap(),
|
||||
)?;
|
||||
write(
|
||||
"capability.json",
|
||||
serde_json::to_string_pretty(&vectors::capability_vectors()).unwrap(),
|
||||
)?;
|
||||
write(
|
||||
"receipt.json",
|
||||
serde_json::to_string_pretty(&vectors::receipt_vector()).unwrap(),
|
||||
)?;
|
||||
write(
|
||||
"attestation.json",
|
||||
serde_json::to_string_pretty(&vectors::attestation_vector()).unwrap(),
|
||||
)?;
|
||||
write(
|
||||
"tier.json",
|
||||
serde_json::to_string_pretty(&vectors::tier_vectors()).unwrap(),
|
||||
)?;
|
||||
write(
|
||||
"durable.json",
|
||||
serde_json::to_string_pretty(&vectors::durable_vector()).unwrap(),
|
||||
)?;
|
||||
write(
|
||||
"negative.json",
|
||||
serde_json::to_string_pretty(&vectors::negative_pack()).unwrap(),
|
||||
)?;
|
||||
write(
|
||||
"confidential.json",
|
||||
serde_json::to_string_pretty(&vectors::confidential_pack()).unwrap(),
|
||||
)?;
|
||||
write(
|
||||
"flow.json",
|
||||
serde_json::to_string_pretty(&vectors::flow_vectors()).unwrap(),
|
||||
)?;
|
||||
|
||||
}
|
||||
println!("\nRegenerated conformance vectors. Verify with `cargo test -p sandbox-conformance`.");
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -714,6 +714,25 @@ mod tests {
|
|||
assert_eq!(report.results.len(), 13);
|
||||
}
|
||||
|
||||
/// The committed pack is exactly what the builders emit, file for file
|
||||
/// and byte for byte. The file-backed checks prove each committed file is
|
||||
/// valid; this proves it is the current one. Without it, a change to a
|
||||
/// builder or to a type's serialized shape left the published pack behind,
|
||||
/// and nothing noticed: `"mechanism": null` sat unpublished in the
|
||||
/// attestation and negative packs for a release.
|
||||
#[test]
|
||||
fn the_committed_pack_is_what_the_builders_emit() {
|
||||
use vectors::*;
|
||||
let rendered = rendered();
|
||||
let names: Vec<&str> = rendered.iter().map(|(n, _)| *n).collect();
|
||||
let listed: Vec<&str> = FILES.iter().map(|(n, _)| *n).collect();
|
||||
assert_eq!(names, listed, "the rendered set is the listed set");
|
||||
for (name, bytes) in rendered {
|
||||
let committed = std::fs::read_to_string(vectors_dir().join(name)).unwrap();
|
||||
assert!(committed == bytes, "{name} differs from what the builders emit: run gen_vectors and commit the result");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector_builders_round_trip_in_memory() {
|
||||
// The reference's own vector builders must satisfy their own checkers
|
||||
|
|
|
|||
|
|
@ -997,6 +997,25 @@ pub fn vectors_dir() -> std::path::PathBuf {
|
|||
.join("../../../conformance/v1")
|
||||
}
|
||||
|
||||
/// Every committed vector file, by name, as the `gen_vectors` binary writes
|
||||
/// it: the pretty JSON of its builder and a final newline. A test holds the
|
||||
/// committed pack to this, so the builders and the published files cannot
|
||||
/// part.
|
||||
pub fn rendered() -> Vec<(&'static str, String)> {
|
||||
let pretty = |v: serde_json::Result<String>| v.expect("a vector serializes") + "\n";
|
||||
vec![
|
||||
("content_addressing.json", pretty(serde_json::to_string_pretty(&content_vectors()))),
|
||||
("capability.json", pretty(serde_json::to_string_pretty(&capability_vectors()))),
|
||||
("receipt.json", pretty(serde_json::to_string_pretty(&receipt_vector()))),
|
||||
("attestation.json", pretty(serde_json::to_string_pretty(&attestation_vector()))),
|
||||
("tier.json", pretty(serde_json::to_string_pretty(&tier_vectors()))),
|
||||
("durable.json", pretty(serde_json::to_string_pretty(&durable_vector()))),
|
||||
("negative.json", pretty(serde_json::to_string_pretty(&negative_pack()))),
|
||||
("confidential.json", pretty(serde_json::to_string_pretty(&confidential_pack()))),
|
||||
("flow.json", pretty(serde_json::to_string_pretty(&flow_vectors()))),
|
||||
]
|
||||
}
|
||||
|
||||
pub const FILES: [(&str, &str); 9] = [
|
||||
("content_addressing.json", "C1"),
|
||||
("capability.json", "C2"),
|
||||
|
|
|
|||
Loading…
Reference in a new issue