Author: Andy Green Date: Sat Oct 03 10:24:57 2026 +0100 npro-core, npro-test: let Miri run the tests, without the heaviest Miri interprets the tests for a target sai has no builder for, a big-endian or a 32-bit one, which is where byte order and the size of usize could make the same code behave differently. It is about a thousand times slower than native. Four tests do bulk work that byte order and word size do not bear on: - the exhaustive UTF-8 sweep; - SHA-1 of a million bytes; - parsing 4097 steps of transcript; - reading every vendored transcript. Those four are ignored under cfg(miri), with the reason given. Native runs keep all of them, and the million-byte SHA-1 vector moves to a test of its own so that the other RFC 3174 vectors still run under Miri. With that, the whole suite runs under Miri in about two minutes per target: 31 tests, all passing, for s390x (big-endian) and i686 (32-bit). Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_019kg5Eemy68ZaqDBcUJQG6J diff --git a/crates/npro-core/src/sha1.rs b/crates/npro-core/src/sha1.rs index 76913f0..7c0fa33 100644 --- a/crates/npro-core/src/sha1.rs +++ b/crates/npro-core/src/sha1.rs @@ -189,16 +189,24 @@ mod tests { "84983e441c3bd26ebaae4aa1f95129e5e54670f1" ); assert_eq!( - hex(Sha1::digest(&vec![b'a'; 1_000_000])), - "34aa973cd4c4daa4f61eeb2bdbad27316534016f" - ); - assert_eq!( hex(Sha1::digest(b"")), "da39a3ee5e6b4b0d3255bfef95601890afd80709" ); } #[test] + #[cfg_attr( + miri, + ignore = "a million bytes: native runs keep it, Miri runs the shorter vectors" + )] + fn rfc_3174_a_million_a() { + assert_eq!( + hex(Sha1::digest(&vec![b'a'; 1_000_000])), + "34aa973cd4c4daa4f61eeb2bdbad27316534016f" + ); + } + + #[test] fn padding_at_every_block_boundary() { // lengths around 55 / 56 / 64 bytes put the 0x80 and the length in // the last block or the next one: digests of 'a' repeated n times, diff --git a/crates/npro-core/src/utf8.rs b/crates/npro-core/src/utf8.rs index 0a7f14e..155e541 100644 --- a/crates/npro-core/src/utf8.rs +++ b/crates/npro-core/src/utf8.rs @@ -149,6 +149,10 @@ mod tests { } #[test] + #[cfg_attr( + miri, + ignore = "millions of cases: native runs keep it, Miri runs the targeted ones" + )] fn agrees_with_the_standard_library_on_every_short_sequence() { for a in 0..=255u8 { assert_eq!(whole(&[a]), oracle(&[a]), "{a:02x}"); diff --git a/crates/npro-test/src/transcript.rs b/crates/npro-test/src/transcript.rs index a23d527..4171ad1 100644 --- a/crates/npro-test/src/transcript.rs +++ b/crates/npro-test/src/transcript.rs @@ -621,6 +621,10 @@ mod tests { } #[test] + #[cfg_attr( + miri, + ignore = "megabytes of text: native runs keep it, Miri runs the small cases" + )] fn refuses_too_many_steps_and_too_much_text() { let many = vec![r#"{"t": 0, "rx": ""}"#; MAX_STEPS + 1].join(","); assert!(matches!(refused(&with_steps(&many)), Error::TooManySteps)); diff --git a/crates/npro-test/tests/vendored.rs b/crates/npro-test/tests/vendored.rs index 2cd4b2d..d95ed0b 100644 --- a/crates/npro-test/tests/vendored.rs +++ b/crates/npro-test/tests/vendored.rs @@ -3,6 +3,10 @@ use npro_test::{Side, StepKind, vendored}; #[test] +#[cfg_attr( + miri, + ignore = "hundreds of kilobytes of transcripts: native runs keep it" +)] fn every_vendored_transcript_reads() { let all = vendored().unwrap();