diff --git a/crates/vize_marquette/tests/test_run_conformance.rs b/crates/vize_marquette/tests/test_run_conformance.rs new file mode 100644 index 000000000..510fce53f --- /dev/null +++ b/crates/vize_marquette/tests/test_run_conformance.rs @@ -0,0 +1,54 @@ +//! Cross-language conformance over the shared test-run evidence fixtures. +//! +//! The TypeScript package reads the same files, so both implementations must +//! agree on validation codes, canonical bytes, and the admitted fingerprint. + +use std::{fs, path::PathBuf}; + +use vize_marquette::{ + TestRunEvidence, canonical_test_run_json, parse_test_run_admission_id, test_run_admission_id, + test_run_fingerprint, +}; + +fn fixture(name: &str) -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("../../tests/fixtures/test-run-evidence") + .join(name) +} + +#[test] +fn accepts_the_shared_valid_record_and_matches_canonical_artifacts() { + let evidence: TestRunEvidence = + serde_json::from_slice(&fs::read(fixture("valid.json")).unwrap()).unwrap(); + assert!(evidence.validate().is_empty()); + + let canonical = canonical_test_run_json(&evidence).unwrap(); + let expected = fs::read_to_string(fixture("valid.canonical")).unwrap(); + assert_eq!(canonical.as_slice(), expected.trim().as_bytes()); + + let fingerprint = fs::read_to_string(fixture("valid.sha256")).unwrap(); + assert_eq!( + test_run_fingerprint(&evidence).unwrap().as_str(), + fingerprint.trim() + ); + + let admission_id = test_run_admission_id(&evidence).unwrap(); + assert_eq!( + parse_test_run_admission_id(&admission_id).unwrap(), + fingerprint.trim() + ); +} + +#[test] +fn returns_the_shared_invalid_diagnostic_codes() { + let evidence: TestRunEvidence = + serde_json::from_slice(&fs::read(fixture("invalid.json")).unwrap()).unwrap(); + let actual = evidence + .validate() + .into_iter() + .map(|diagnostic| diagnostic.code) + .collect::>(); + let expected: Vec = + serde_json::from_slice(&fs::read(fixture("invalid.expected.json")).unwrap()).unwrap(); + assert_eq!(actual, expected); +} diff --git a/tests/fixtures/test-run-evidence/invalid.expected.json b/tests/fixtures/test-run-evidence/invalid.expected.json new file mode 100644 index 000000000..6de824e1f --- /dev/null +++ b/tests/fixtures/test-run-evidence/invalid.expected.json @@ -0,0 +1,9 @@ +[ + "VIZE_MARQUETTE_103", + "VIZE_MARQUETTE_108", + "VIZE_MARQUETTE_125", + "VIZE_MARQUETTE_113", + "VIZE_MARQUETTE_128", + "VIZE_MARQUETTE_128", + "VIZE_MARQUETTE_127" +] diff --git a/tests/fixtures/test-run-evidence/invalid.json b/tests/fixtures/test-run-evidence/invalid.json new file mode 100644 index 000000000..2e7938a27 --- /dev/null +++ b/tests/fixtures/test-run-evidence/invalid.json @@ -0,0 +1,109 @@ +{ + "format": "vize.test-run.evidence", + "formatVersion": 1, + "id": "run-2026-07-21.001", + "application": "Example", + "environment": "production", + "contractFingerprint": "1111111111111111111111111111111111111111111111111111111111111111", + "sourceRevision": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "release": "0.298.0", + "artifact": { + "id": "web-bundle", + "fingerprint": "2222222222222222222222222222222222222222222222222222222222222222", + "sizeBytes": 4096 + }, + "startedAt": "2026-07-21T00:00:00.000Z", + "completedAt": "2026-07-21T00:10:00.000Z", + "validUntil": "2026-07-21T00:10:00.000Z", + "runner": { + "identity": "ci.runner-1", + "authenticationEvidence": { + "reference": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "fingerprint": "3333333333333333333333333333333333333333333333333333333333333333" + }, + "isolation": "ephemeral", + "invocationFingerprint": "4444444444444444444444444444444444444444444444444444444444444444", + "environmentEvidence": { + "reference": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "fingerprint": "5555555555555555555555555555555555555555555555555555555555555555" + }, + "environmentFingerprint": "6666666666666666666666666666666666666666666666666666666666666666" + }, + "selection": { + "targetIds": ["server", "web"], + "suiteIds": ["contract", "unit"] + }, + "targets": [ + { + "id": "web", + "kind": "web", + "environment": "production" + }, + { + "id": "server", + "kind": "server", + "environment": "production" + } + ], + "suites": [ + { + "id": "contract", + "targetId": "server", + "kind": "contract", + "shardIndex": 1, + "shardCount": 1, + "outcome": "passed", + "passed": 18, + "failed": 0, + "skipped": 0, + "retries": 0, + "durationMs": 42000, + "invocationFingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "report": { + "reference": "https://reports.example/latest", + "fingerprint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + }, + "log": { + "reference": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "fingerprint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "id": "unit", + "targetId": "web", + "kind": "unit", + "shardIndex": 1, + "shardCount": 2, + "outcome": "passed", + "passed": 56, + "failed": 0, + "skipped": 0, + "retries": 2, + "durationMs": 31000, + "invocationFingerprint": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "report": { + "reference": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "fingerprint": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + }, + "log": { + "reference": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "fingerprint": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + } + } + ], + "verification": { + "verifier": "release.verifier", + "completedAt": "2026-07-21T00:11:00.000Z", + "outcome": "accepted", + "targetCount": 2, + "suiteCount": 3, + "passed": 138, + "failed": 0, + "skipped": 0, + "retries": 0, + "evidence": { + "reference": "sha256:0000000000000000000000000000000000000000000000000000000000000000", + "fingerprint": "0000000000000000000000000000000000000000000000000000000000000000" + } + } +} diff --git a/tests/fixtures/test-run-evidence/valid.canonical b/tests/fixtures/test-run-evidence/valid.canonical new file mode 100644 index 000000000..5bedab2dc --- /dev/null +++ b/tests/fixtures/test-run-evidence/valid.canonical @@ -0,0 +1 @@ +{"format":"vize.test-run.evidence","formatVersion":1,"id":"run-2026-07-21.001","application":"example","environment":"production","contractFingerprint":"1111111111111111111111111111111111111111111111111111111111111111","sourceRevision":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","release":"0.298.0","artifact":{"id":"web-bundle","fingerprint":"2222222222222222222222222222222222222222222222222222222222222222","sizeBytes":4096},"startedAt":"2026-07-21T00:00:00.000Z","completedAt":"2026-07-21T00:10:00.000Z","validUntil":"2026-07-28T00:10:00.000Z","runner":{"identity":"ci.runner-1","authenticationEvidence":{"reference":"sha256:3333333333333333333333333333333333333333333333333333333333333333","fingerprint":"3333333333333333333333333333333333333333333333333333333333333333"},"isolation":"ephemeral","invocationFingerprint":"4444444444444444444444444444444444444444444444444444444444444444","environmentEvidence":{"reference":"sha256:5555555555555555555555555555555555555555555555555555555555555555","fingerprint":"5555555555555555555555555555555555555555555555555555555555555555"},"environmentFingerprint":"6666666666666666666666666666666666666666666666666666666666666666"},"selection":{"targetIds":["server","web"],"suiteIds":["contract","unit"]},"targets":[{"id":"server","kind":"server","environment":"production"},{"id":"web","kind":"web","environment":"production"}],"suites":[{"id":"contract","targetId":"server","kind":"contract","shardIndex":1,"shardCount":1,"outcome":"passed","passed":18,"failed":0,"skipped":0,"retries":0,"durationMs":42000,"invocationFingerprint":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","report":{"reference":"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","fingerprint":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"},"log":{"reference":"sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc","fingerprint":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"}},{"id":"unit","targetId":"web","kind":"unit","shardIndex":1,"shardCount":2,"outcome":"passed","passed":56,"failed":0,"skipped":0,"retries":0,"durationMs":31000,"invocationFingerprint":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd","report":{"reference":"sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee","fingerprint":"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"},"log":{"reference":"sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","fingerprint":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}},{"id":"unit","targetId":"web","kind":"unit","shardIndex":2,"shardCount":2,"outcome":"passed","passed":64,"failed":0,"skipped":0,"retries":0,"durationMs":30500,"invocationFingerprint":"7777777777777777777777777777777777777777777777777777777777777777","report":{"reference":"sha256:8888888888888888888888888888888888888888888888888888888888888888","fingerprint":"8888888888888888888888888888888888888888888888888888888888888888"},"log":{"reference":"sha256:9999999999999999999999999999999999999999999999999999999999999999","fingerprint":"9999999999999999999999999999999999999999999999999999999999999999"}}],"verification":{"verifier":"release.verifier","completedAt":"2026-07-21T00:11:00.000Z","outcome":"accepted","targetCount":2,"suiteCount":3,"passed":138,"failed":0,"skipped":0,"retries":0,"evidence":{"reference":"sha256:0000000000000000000000000000000000000000000000000000000000000000","fingerprint":"0000000000000000000000000000000000000000000000000000000000000000"}}} \ No newline at end of file diff --git a/tests/fixtures/test-run-evidence/valid.json b/tests/fixtures/test-run-evidence/valid.json new file mode 100644 index 000000000..773485da0 --- /dev/null +++ b/tests/fixtures/test-run-evidence/valid.json @@ -0,0 +1,131 @@ +{ + "format": "vize.test-run.evidence", + "formatVersion": 1, + "id": "run-2026-07-21.001", + "application": "example", + "environment": "production", + "contractFingerprint": "1111111111111111111111111111111111111111111111111111111111111111", + "sourceRevision": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "release": "0.298.0", + "artifact": { + "id": "web-bundle", + "fingerprint": "2222222222222222222222222222222222222222222222222222222222222222", + "sizeBytes": 4096 + }, + "startedAt": "2026-07-21T00:00:00.000Z", + "completedAt": "2026-07-21T00:10:00.000Z", + "validUntil": "2026-07-28T00:10:00.000Z", + "runner": { + "identity": "ci.runner-1", + "authenticationEvidence": { + "reference": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "fingerprint": "3333333333333333333333333333333333333333333333333333333333333333" + }, + "isolation": "ephemeral", + "invocationFingerprint": "4444444444444444444444444444444444444444444444444444444444444444", + "environmentEvidence": { + "reference": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "fingerprint": "5555555555555555555555555555555555555555555555555555555555555555" + }, + "environmentFingerprint": "6666666666666666666666666666666666666666666666666666666666666666" + }, + "selection": { + "targetIds": ["server", "web"], + "suiteIds": ["contract", "unit"] + }, + "targets": [ + { + "id": "web", + "kind": "web", + "environment": "production" + }, + { + "id": "server", + "kind": "server", + "environment": "production" + } + ], + "suites": [ + { + "id": "unit", + "targetId": "web", + "kind": "unit", + "shardIndex": 2, + "shardCount": 2, + "outcome": "passed", + "passed": 64, + "failed": 0, + "skipped": 0, + "retries": 0, + "durationMs": 30500, + "invocationFingerprint": "7777777777777777777777777777777777777777777777777777777777777777", + "report": { + "reference": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "fingerprint": "8888888888888888888888888888888888888888888888888888888888888888" + }, + "log": { + "reference": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "fingerprint": "9999999999999999999999999999999999999999999999999999999999999999" + } + }, + { + "id": "contract", + "targetId": "server", + "kind": "contract", + "shardIndex": 1, + "shardCount": 1, + "outcome": "passed", + "passed": 18, + "failed": 0, + "skipped": 0, + "retries": 0, + "durationMs": 42000, + "invocationFingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "report": { + "reference": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "fingerprint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + }, + "log": { + "reference": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "fingerprint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "id": "unit", + "targetId": "web", + "kind": "unit", + "shardIndex": 1, + "shardCount": 2, + "outcome": "passed", + "passed": 56, + "failed": 0, + "skipped": 0, + "retries": 0, + "durationMs": 31000, + "invocationFingerprint": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "report": { + "reference": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "fingerprint": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + }, + "log": { + "reference": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "fingerprint": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + } + } + ], + "verification": { + "verifier": "release.verifier", + "completedAt": "2026-07-21T00:11:00.000Z", + "outcome": "accepted", + "targetCount": 2, + "suiteCount": 3, + "passed": 138, + "failed": 0, + "skipped": 0, + "retries": 0, + "evidence": { + "reference": "sha256:0000000000000000000000000000000000000000000000000000000000000000", + "fingerprint": "0000000000000000000000000000000000000000000000000000000000000000" + } + } +} diff --git a/tests/fixtures/test-run-evidence/valid.sha256 b/tests/fixtures/test-run-evidence/valid.sha256 new file mode 100644 index 000000000..16a8d047c --- /dev/null +++ b/tests/fixtures/test-run-evidence/valid.sha256 @@ -0,0 +1 @@ +05d50948dac24df4c92e3ab6c67d96461fced0f28373d06e9a06755b2a40a85b