diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 342f2e0386..dfa92cf659 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ env: RUST_BACKTRACE: 1 # Pin the nightly toolchain to prevent breakage. # This should be occasionally updated. - RUST_NIGHTLY_TOOLCHAIN: nightly-2022-07-10 + RUST_NIGHTLY_TOOLCHAIN: nightly-2022-09-15 CDN: https://dnglbrstg7yg.cloudfront.net # enable unstable features for testing S2N_UNSTABLE_CRYPTO_OPT_TX: 100 @@ -647,4 +647,3 @@ jobs: ./scripts/typos --format json | tee /tmp/typos.json | jq -rs '.[] | "::error file=\(.path),line=\(.line_num),col=\(.byte_offset)::\(.typo) should be \"" + (.corrections // [] | join("\" or \"") + "\"")' cat /tmp/typos.json ! grep -q '[^[:space:]]' /tmp/typos.json - diff --git a/.github/workflows/netbench.yml b/.github/workflows/netbench.yml index 0e07f4b653..2bfed5b37a 100644 --- a/.github/workflows/netbench.yml +++ b/.github/workflows/netbench.yml @@ -15,7 +15,7 @@ env: RUST_BACKTRACE: 1 # Pin the nightly toolchain to prevent breakage. # This should be occasionally updated. - RUST_NIGHTLY_TOOLCHAIN: nightly-2022-07-10 + RUST_NIGHTLY_TOOLCHAIN: nightly-2022-09-15 CDN: https://dnglbrstg7yg.cloudfront.net # enable unstable features for testing S2N_UNSTABLE_CRYPTO_OPT_TX: 100 diff --git a/quic/s2n-quic-core/Cargo.toml b/quic/s2n-quic-core/Cargo.toml index f2e7e04f28..ee0f71b809 100644 --- a/quic/s2n-quic-core/Cargo.toml +++ b/quic/s2n-quic-core/Cargo.toml @@ -44,39 +44,3 @@ futures-test = "0.3" ip_network = "0.4" plotters = { version = "0.3", default-features = false, features = ["svg_backend", "line_series"] } s2n-codec = { path = "../../common/s2n-codec", features = ["testing"] } - -# TODO remove this once this is fixed: https://github.com/model-checking/kani/issues/473 -[target.'cfg(kani)'.dependencies] -bolero = "0.7" -bolero-generator = "0.7" - -[[test]] -name = "crypto" -path = "tests/crypto/fuzz_target.rs" -harness = false - -[[test]] -name = "frame" -path = "tests/frame/fuzz_target.rs" -harness = false - -[[test]] -name = "packet" -path = "tests/packet/fuzz_target.rs" -harness = false -required-features = ["testing"] - -[[test]] -name = "transport_parameters" -path = "tests/transport_parameters/fuzz_target.rs" -harness = false - -[[test]] -name = "varint" -path = "tests/varint/fuzz_target.rs" -harness = false - -[[test]] -name = "recovery-simulation" -path = "tests/recovery/simulation.rs" -required-features = ["testing"] diff --git a/quic/s2n-quic-core/tests/crypto/corpus.tar.gz b/quic/s2n-quic-core/src/crypto/__fuzz__/crypto__tests__round_trip/corpus.tar.gz similarity index 100% rename from quic/s2n-quic-core/tests/crypto/corpus.tar.gz rename to quic/s2n-quic-core/src/crypto/__fuzz__/crypto__tests__round_trip/corpus.tar.gz diff --git a/quic/s2n-quic-core/src/crypto/mod.rs b/quic/s2n-quic-core/src/crypto/mod.rs index afacddf6c6..9119f0af02 100644 --- a/quic/s2n-quic-core/src/crypto/mod.rs +++ b/quic/s2n-quic-core/src/crypto/mod.rs @@ -145,6 +145,9 @@ pub mod retry; pub mod tls; pub mod zero_rtt; +#[cfg(test)] +mod tests; + pub use application::*; pub use error::*; pub use handshake::*; diff --git a/quic/s2n-quic-core/tests/crypto/fuzz_target.rs b/quic/s2n-quic-core/src/crypto/tests.rs similarity index 88% rename from quic/s2n-quic-core/tests/crypto/fuzz_target.rs rename to quic/s2n-quic-core/src/crypto/tests.rs index 3d34cde188..ac43733ae7 100644 --- a/quic/s2n-quic-core/tests/crypto/fuzz_target.rs +++ b/quic/s2n-quic-core/src/crypto/tests.rs @@ -1,17 +1,19 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -use bolero::{check, generator::*}; -use core::mem::size_of; -use s2n_codec::{DecoderBufferMut, EncoderBuffer}; -use s2n_quic_core::{ +use crate::{ crypto::{CryptoError, HeaderKey, HeaderProtectionMask, Key, ProtectedPayload}, packet::number::{PacketNumber, PacketNumberSpace}, varint::VarInt, }; +use bolero::{check, generator::*}; +use core::mem::size_of; +use s2n_codec::{DecoderBufferMut, EncoderBuffer}; use std::convert::TryInto; -fn main() { +#[test] +#[cfg_attr(miri, ignore)] // This test is too expensive for miri to complete in a reasonable amount of time +fn round_trip() { check!() .with_generator(( gen() @@ -54,7 +56,7 @@ fn fuzz_unprotect( let payload = ProtectedPayload::new(header_len, payload.into_less_safe_slice()); let (truncated_packet_number, payload) = - s2n_quic_core::crypto::unprotect(&FuzzCrypto, largest_packet_number.space(), payload)?; + crate::crypto::unprotect(&FuzzCrypto, largest_packet_number.space(), payload)?; let packet_number = truncated_packet_number.expand(largest_packet_number); @@ -64,7 +66,7 @@ fn fuzz_unprotect( .filter(|actual| truncated_packet_number.eq(actual)) .ok_or(CryptoError::DECODE_ERROR)?; - let (_header, _payload) = s2n_quic_core::crypto::decrypt(&FuzzCrypto, packet_number, payload)?; + let (_header, _payload) = crate::crypto::decrypt(&FuzzCrypto, packet_number, payload)?; Ok((packet_number, header_len)) } @@ -82,7 +84,7 @@ fn fuzz_protect( let truncated_packet_number = packet_number.truncate(largest_packet_number).unwrap(); let packet_number_len = truncated_packet_number.len(); - let (payload, _remaining) = s2n_quic_core::crypto::encrypt( + let (payload, _remaining) = crate::crypto::encrypt( &FuzzCrypto, packet_number, packet_number_len, @@ -90,7 +92,7 @@ fn fuzz_protect( payload, )?; - let _payload = s2n_quic_core::crypto::protect(&FuzzCrypto, payload)?; + let _payload = crate::crypto::protect(&FuzzCrypto, payload)?; Ok(()) } @@ -138,8 +140,8 @@ impl Key for FuzzCrypto { 0 } - fn cipher_suite(&self) -> s2n_quic_core::crypto::tls::CipherSuite { - s2n_quic_core::crypto::tls::CipherSuite::Unknown + fn cipher_suite(&self) -> crate::crypto::tls::CipherSuite { + crate::crypto::tls::CipherSuite::Unknown } } diff --git a/quic/s2n-quic-core/tests/frame/corpus.tar.gz b/quic/s2n-quic-core/src/frame/__fuzz__/frame__tests__round_trip/corpus.tar.gz similarity index 100% rename from quic/s2n-quic-core/tests/frame/corpus.tar.gz rename to quic/s2n-quic-core/src/frame/__fuzz__/frame__tests__round_trip/corpus.tar.gz diff --git a/quic/s2n-quic-core/src/frame/mod.rs b/quic/s2n-quic-core/src/frame/mod.rs index 00306d7ad1..c8c1ecab6b 100644 --- a/quic/s2n-quic-core/src/frame/mod.rs +++ b/quic/s2n-quic-core/src/frame/mod.rs @@ -17,6 +17,9 @@ pub mod ack_elicitation; pub mod congestion_controlled; pub mod path_validation; +#[cfg(test)] +mod tests; + //= https://www.rfc-editor.org/rfc/rfc9000#section-19 //# As described in Section 12.4, packets contain one or more frames. //# This section describes the format and semantics of the core QUIC diff --git a/quic/s2n-quic-core/tests/frame/fuzz_target.rs b/quic/s2n-quic-core/src/frame/tests.rs similarity index 93% rename from quic/s2n-quic-core/tests/frame/fuzz_target.rs rename to quic/s2n-quic-core/src/frame/tests.rs index 86eb8faed6..a56b31787d 100644 --- a/quic/s2n-quic-core/tests/frame/fuzz_target.rs +++ b/quic/s2n-quic-core/src/frame/tests.rs @@ -1,11 +1,12 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 +use crate::frame::FrameRef; use bolero::check; use s2n_codec::{assert_codec_round_trip_bytes_mut, Encoder, EncoderLenEstimator, EncoderValue}; -use s2n_quic_core::frame::FrameRef; -fn main() { +#[test] +fn round_trip() { check!().for_each(|input| { let mut input = input.to_vec(); let frames = assert_codec_round_trip_bytes_mut!(FrameRef, &mut input); diff --git a/quic/s2n-quic-core/tests/packet/corpus.tar.gz b/quic/s2n-quic-core/src/packet/__fuzz__/packet__tests__round_trip/corpus.tar.gz similarity index 100% rename from quic/s2n-quic-core/tests/packet/corpus.tar.gz rename to quic/s2n-quic-core/src/packet/__fuzz__/packet__tests__round_trip/corpus.tar.gz diff --git a/quic/s2n-quic-core/src/packet/mod.rs b/quic/s2n-quic-core/src/packet/mod.rs index 9cabcc0d2a..59ce52a825 100644 --- a/quic/s2n-quic-core/src/packet/mod.rs +++ b/quic/s2n-quic-core/src/packet/mod.rs @@ -28,6 +28,9 @@ pub mod long; pub mod number; pub mod stateless_reset; +#[cfg(test)] +mod tests; + pub use key_phase::{KeyPhase, ProtectedKeyPhase}; use connection::id::ConnectionInfo; diff --git a/quic/s2n-quic-core/tests/packet_number/corpus.tar.gz b/quic/s2n-quic-core/src/packet/number/__fuzz__/packet__number__tests__round_trip/corpus.tar.gz similarity index 100% rename from quic/s2n-quic-core/tests/packet_number/corpus.tar.gz rename to quic/s2n-quic-core/src/packet/number/__fuzz__/packet__number__tests__round_trip/corpus.tar.gz diff --git a/quic/s2n-quic-core/src/packet/number/mod.rs b/quic/s2n-quic-core/src/packet/number/mod.rs index 75a24a959b..3d30fcc3fe 100644 --- a/quic/s2n-quic-core/src/packet/number/mod.rs +++ b/quic/s2n-quic-core/src/packet/number/mod.rs @@ -62,6 +62,9 @@ pub mod map; #[cfg(feature = "alloc")] pub use map::Map; +#[cfg(test)] +mod tests; + //= https://www.rfc-editor.org/rfc/rfc9000#section-17.1 //# the sender MUST use a packet number size able to represent more than //# twice as large a range as the difference between the largest @@ -225,143 +228,3 @@ fn decode_packet_number( PacketNumber::from_varint(candidate_pn, space) } - -#[cfg(test)] -mod tests { - use super::*; - use bolero::check; - - fn new(value: VarInt) -> PacketNumber { - PacketNumberSpace::Initial.new_packet_number(value) - } - - /// This implementation tries to closely follow the RFC pseudo code so it's - /// easier to ensure it matches. - #[allow(clippy::blocks_in_if_conditions)] - fn rfc_decoder(largest_pn: u64, truncated_pn: u64, pn_nbits: usize) -> u64 { - use std::panic::catch_unwind as catch; - - //= https://www.rfc-editor.org/rfc/rfc9000#section-A.3 - //= type=test - //# DecodePacketNumber(largest_pn, truncated_pn, pn_nbits): - //# expected_pn = largest_pn + 1 - //# pn_win = 1 << pn_nbits - //# pn_hwin = pn_win / 2 - //# pn_mask = pn_win - 1 - //# // The incoming packet number should be greater than - //# // expected_pn - pn_hwin and less than or equal to - //# // expected_pn + pn_hwin - //# // - //# // This means we cannot just strip the trailing bits from - //# // expected_pn and add the truncated_pn because that might - //# // yield a value outside the window. - //# // - //# // The following code calculates a candidate value and - //# // makes sure it's within the packet number window. - //# // Note the extra checks to prevent overflow and underflow. - //# candidate_pn = (expected_pn & ~pn_mask) | truncated_pn - //# if candidate_pn <= expected_pn - pn_hwin and - //# candidate_pn < (1 << 62) - pn_win: - //# return candidate_pn + pn_win - //# if candidate_pn > expected_pn + pn_hwin and - //# candidate_pn >= pn_win: - //# return candidate_pn - pn_win - //# return candidate_pn - let expected_pn = largest_pn + 1; - let pn_win = 1 << pn_nbits; - let pn_hwin = pn_win / 2; - let pn_mask = pn_win - 1; - - let candidate_pn = (expected_pn & !pn_mask) | truncated_pn; - if catch(|| { - candidate_pn <= expected_pn.checked_sub(pn_hwin).unwrap() - && candidate_pn < (1u64 << 62).checked_sub(pn_win).unwrap() - }) - .unwrap_or_default() - { - return candidate_pn + pn_win; - } - - if catch(|| { - candidate_pn > expected_pn.checked_add(pn_hwin).unwrap() && candidate_pn >= pn_win - }) - .unwrap_or_default() - { - return candidate_pn - pn_win; - } - - candidate_pn - } - - #[test] - fn truncate_expand_test() { - check!() - .with_type() - .cloned() - .for_each(|(largest_pn, expected_pn)| { - let largest_pn = new(largest_pn); - let expected_pn = new(expected_pn); - if let Some(truncated_pn) = expected_pn.truncate(largest_pn) { - assert_eq!(expected_pn, truncated_pn.expand(largest_pn)); - } - }); - } - - #[test] - fn rfc_differential_test() { - check!() - .with_type() - .cloned() - .for_each(|(largest_pn, truncated_pn)| { - let largest_pn = new(largest_pn); - let space = largest_pn.space(); - let truncated_pn = TruncatedPacketNumber { - space, - value: truncated_pn, - }; - let rfc_value = rfc_decoder( - largest_pn.as_u64(), - truncated_pn.into_u64(), - truncated_pn.bitsize(), - ) - .min(VarInt::MAX.as_u64()); - let actual_value = truncated_pn.expand(largest_pn).as_u64(); - - assert_eq!( - actual_value, - rfc_value, - "diff: {}", - actual_value - .checked_sub(rfc_value) - .unwrap_or(rfc_value - actual_value) - ); - }); - } - - #[test] - fn example_test() { - macro_rules! example { - ($largest:expr, $truncated:expr, $expected:expr) => {{ - let largest = new(VarInt::from_u32($largest)); - let truncated = TruncatedPacketNumber::new($truncated, PacketNumberSpace::Initial); - let expected = new(VarInt::from_u32($expected)); - assert_eq!(truncated.expand(largest), expected); - }}; - } - - example!(0xa82e1b31, 0x9b32u16, 0xa82e9b32); - } - - #[test] - #[cfg_attr(miri, ignore)] // snapshot tests don't work on miri - fn size_of_snapshots() { - use core::mem::size_of; - use insta::assert_debug_snapshot; - - assert_debug_snapshot!("PacketNumber", size_of::()); - assert_debug_snapshot!("PacketNumberLen", size_of::()); - assert_debug_snapshot!("PacketNumberSpace", size_of::()); - assert_debug_snapshot!("ProtectedPacketNumber", size_of::()); - assert_debug_snapshot!("TruncatedPacketNumber", size_of::()); - } -} diff --git a/quic/s2n-quic-core/src/packet/number/tests.rs b/quic/s2n-quic-core/src/packet/number/tests.rs new file mode 100644 index 0000000000..4d1ea33add --- /dev/null +++ b/quic/s2n-quic-core/src/packet/number/tests.rs @@ -0,0 +1,231 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +use super::*; +use crate::{ + packet::number::{PacketNumber, PacketNumberSpace}, + varint::VarInt, +}; +use bolero::{check, generator::*}; +use s2n_codec::{testing::encode, DecoderBuffer}; + +#[test] +fn round_trip() { + check!() + .with_generator( + gen_packet_number_space() + .and_then(|space| (gen_packet_number(space), gen_packet_number(space))), + ) + .cloned() + .for_each(|(packet_number, largest_acked_packet_number)| { + // Try to encode the packet number to send + if let Some((mask, bytes)) = + encode_packet_number(packet_number, largest_acked_packet_number) + { + // If encoding was valid, assert that the information can be decoded + let actual_packet_number = + decode_packet_number(mask, bytes, largest_acked_packet_number).unwrap(); + assert_eq!(actual_packet_number, packet_number); + } + }); +} + +fn gen_packet_number_space() -> impl ValueGenerator { + (0u8..=2).map_gen(|id| match id { + 0 => PacketNumberSpace::Initial, + 1 => PacketNumberSpace::Handshake, + 2 => PacketNumberSpace::ApplicationData, + _ => unreachable!("invalid space id {:?}", id), + }) +} + +fn gen_packet_number(space: PacketNumberSpace) -> impl ValueGenerator { + gen().map(move |packet_number| { + space.new_packet_number(match VarInt::new(packet_number) { + Ok(packet_number) => packet_number, + Err(_) => VarInt::from_u32(packet_number as u32), + }) + }) +} + +fn encode_packet_number( + packet_number: PacketNumber, + largest_acked_packet_number: PacketNumber, +) -> Option<(u8, Vec)> { + let truncated_packet_number = packet_number.truncate(largest_acked_packet_number)?; + + let bytes = encode(&truncated_packet_number).unwrap(); + let mask = truncated_packet_number.len().into_packet_tag_mask(); + + Some((mask, bytes)) +} + +fn decode_packet_number( + packet_tag: u8, + packet_bytes: Vec, + largest_acked_packet_number: PacketNumber, +) -> Result { + // decode the packet number len from the packet tag + let packet_number_len = largest_acked_packet_number + .space() + .new_packet_number_len(packet_tag); + + // make sure the packet_tag has the same mask as the len + assert_eq!(packet_number_len.into_packet_tag_mask(), packet_tag); + assert_eq!(packet_number_len.bytesize(), packet_bytes.len()); + + // try decoding the truncated packet number from the packet bytes + let (truncated_packet_number, _) = packet_number_len + .decode_truncated_packet_number(DecoderBuffer::new(&packet_bytes)) + .map_err(|err| err.to_string())?; + + // make sure the packet_number_len round trips + assert_eq!(truncated_packet_number.len(), packet_number_len); + + // make sure the encoding matches the original bytes + assert_eq!(packet_bytes, encode(&truncated_packet_number).unwrap()); + + // try expanding the truncated packet number + let packet_number = truncated_packet_number.expand(largest_acked_packet_number); + + // try truncating the packet number + let actual_truncated_packet_number = packet_number + .truncate(largest_acked_packet_number) + .ok_or_else(|| "Could not truncate packet number".to_string())?; + + assert_eq!(actual_truncated_packet_number, truncated_packet_number); + + Ok(packet_number) +} + +fn new(value: VarInt) -> PacketNumber { + PacketNumberSpace::Initial.new_packet_number(value) +} + +/// This implementation tries to closely follow the RFC pseudo code so it's +/// easier to ensure it matches. +#[allow(clippy::blocks_in_if_conditions)] +fn rfc_decoder(largest_pn: u64, truncated_pn: u64, pn_nbits: usize) -> u64 { + use std::panic::catch_unwind as catch; + + //= https://www.rfc-editor.org/rfc/rfc9000#section-A.3 + //= type=test + //# DecodePacketNumber(largest_pn, truncated_pn, pn_nbits): + //# expected_pn = largest_pn + 1 + //# pn_win = 1 << pn_nbits + //# pn_hwin = pn_win / 2 + //# pn_mask = pn_win - 1 + //# // The incoming packet number should be greater than + //# // expected_pn - pn_hwin and less than or equal to + //# // expected_pn + pn_hwin + //# // + //# // This means we cannot just strip the trailing bits from + //# // expected_pn and add the truncated_pn because that might + //# // yield a value outside the window. + //# // + //# // The following code calculates a candidate value and + //# // makes sure it's within the packet number window. + //# // Note the extra checks to prevent overflow and underflow. + //# candidate_pn = (expected_pn & ~pn_mask) | truncated_pn + //# if candidate_pn <= expected_pn - pn_hwin and + //# candidate_pn < (1 << 62) - pn_win: + //# return candidate_pn + pn_win + //# if candidate_pn > expected_pn + pn_hwin and + //# candidate_pn >= pn_win: + //# return candidate_pn - pn_win + //# return candidate_pn + let expected_pn = largest_pn + 1; + let pn_win = 1 << pn_nbits; + let pn_hwin = pn_win / 2; + let pn_mask = pn_win - 1; + + let candidate_pn = (expected_pn & !pn_mask) | truncated_pn; + if catch(|| { + candidate_pn <= expected_pn.checked_sub(pn_hwin).unwrap() + && candidate_pn < (1u64 << 62).checked_sub(pn_win).unwrap() + }) + .unwrap_or_default() + { + return candidate_pn + pn_win; + } + + if catch(|| candidate_pn > expected_pn.checked_add(pn_hwin).unwrap() && candidate_pn >= pn_win) + .unwrap_or_default() + { + return candidate_pn - pn_win; + } + + candidate_pn +} + +#[test] +fn truncate_expand_test() { + check!() + .with_type() + .cloned() + .for_each(|(largest_pn, expected_pn)| { + let largest_pn = new(largest_pn); + let expected_pn = new(expected_pn); + if let Some(truncated_pn) = expected_pn.truncate(largest_pn) { + assert_eq!(expected_pn, truncated_pn.expand(largest_pn)); + } + }); +} + +#[test] +fn rfc_differential_test() { + check!() + .with_type() + .cloned() + .for_each(|(largest_pn, truncated_pn)| { + let largest_pn = new(largest_pn); + let space = largest_pn.space(); + let truncated_pn = TruncatedPacketNumber { + space, + value: truncated_pn, + }; + let rfc_value = rfc_decoder( + largest_pn.as_u64(), + truncated_pn.into_u64(), + truncated_pn.bitsize(), + ) + .min(VarInt::MAX.as_u64()); + let actual_value = truncated_pn.expand(largest_pn).as_u64(); + + assert_eq!( + actual_value, + rfc_value, + "diff: {}", + actual_value + .checked_sub(rfc_value) + .unwrap_or(rfc_value - actual_value) + ); + }); +} + +#[test] +fn example_test() { + macro_rules! example { + ($largest:expr, $truncated:expr, $expected:expr) => {{ + let largest = new(VarInt::from_u32($largest)); + let truncated = TruncatedPacketNumber::new($truncated, PacketNumberSpace::Initial); + let expected = new(VarInt::from_u32($expected)); + assert_eq!(truncated.expand(largest), expected); + }}; + } + + example!(0xa82e1b31, 0x9b32u16, 0xa82e9b32); +} + +#[test] +#[cfg_attr(miri, ignore)] // snapshot tests don't work on miri +fn size_of_snapshots() { + use core::mem::size_of; + use insta::assert_debug_snapshot; + + assert_debug_snapshot!("PacketNumber", size_of::()); + assert_debug_snapshot!("PacketNumberLen", size_of::()); + assert_debug_snapshot!("PacketNumberSpace", size_of::()); + assert_debug_snapshot!("ProtectedPacketNumber", size_of::()); + assert_debug_snapshot!("TruncatedPacketNumber", size_of::()); +} diff --git a/quic/s2n-quic-core/tests/packet/fuzz_target.rs b/quic/s2n-quic-core/src/packet/tests.rs similarity index 99% rename from quic/s2n-quic-core/tests/packet/fuzz_target.rs rename to quic/s2n-quic-core/src/packet/tests.rs index ddcc8c7dcb..c12ba814d6 100644 --- a/quic/s2n-quic-core/tests/packet/fuzz_target.rs +++ b/quic/s2n-quic-core/src/packet/tests.rs @@ -1,9 +1,7 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -use bolero::check; -use s2n_codec::{DecoderBufferMut, Encoder, EncoderBuffer}; -use s2n_quic_core::{ +use crate::{ connection::id::ConnectionInfo, crypto::key::testing, inet::SocketAddress, @@ -12,8 +10,11 @@ use s2n_quic_core::{ }, transport, }; +use bolero::check; +use s2n_codec::{DecoderBufferMut, Encoder, EncoderBuffer}; -fn main() { +#[test] +fn round_trip() { let mut encoder_data = vec![]; check!().for_each(move |data| { let mut data = data.to_vec(); diff --git a/quic/s2n-quic-core/src/packet/number/__fuzz__/recovery__sent_packets__test__differential/corpus.tar.gz b/quic/s2n-quic-core/src/recovery/__fuzz__/recovery__sent_packets__test__differential/corpus.tar.gz similarity index 100% rename from quic/s2n-quic-core/src/packet/number/__fuzz__/recovery__sent_packets__test__differential/corpus.tar.gz rename to quic/s2n-quic-core/src/recovery/__fuzz__/recovery__sent_packets__test__differential/corpus.tar.gz diff --git a/quic/s2n-quic-core/src/recovery/mod.rs b/quic/s2n-quic-core/src/recovery/mod.rs index 6e5810f5a8..1c8b0f70cb 100644 --- a/quic/s2n-quic-core/src/recovery/mod.rs +++ b/quic/s2n-quic-core/src/recovery/mod.rs @@ -15,6 +15,9 @@ mod pacing; mod rtt_estimator; mod sent_packets; +#[cfg(test)] +mod simulation; + //= https://www.rfc-editor.org/rfc/rfc9002#section-7.7 //# Senders SHOULD limit bursts to the initial congestion window; see //# Section 7.2. diff --git a/quic/s2n-quic-core/src/recovery/rtt_estimator.rs b/quic/s2n-quic-core/src/recovery/rtt_estimator.rs index 0559ca5c8a..b16922f3c1 100644 --- a/quic/s2n-quic-core/src/recovery/rtt_estimator.rs +++ b/quic/s2n-quic-core/src/recovery/rtt_estimator.rs @@ -719,6 +719,7 @@ mod test { } #[test] + #[cfg_attr(miri, ignore)] // This test is too expensive for miri to complete in a reasonable amount of time fn weighted_average_test() { bolero::check!() .with_type::<(u32, u32)>() diff --git a/quic/s2n-quic-core/tests/recovery/simulation.rs b/quic/s2n-quic-core/src/recovery/simulation.rs similarity index 99% rename from quic/s2n-quic-core/tests/recovery/simulation.rs rename to quic/s2n-quic-core/src/recovery/simulation.rs index 5e9c485a6a..add687cdae 100644 --- a/quic/s2n-quic-core/tests/recovery/simulation.rs +++ b/quic/s2n-quic-core/src/recovery/simulation.rs @@ -1,16 +1,16 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -use core::{fmt, ops::Range, time::Duration}; -use insta::assert_debug_snapshot; -use plotters::prelude::*; -use s2n_quic_core::{ +use crate::{ packet::number::PacketNumberSpace, path::MINIMUM_MTU, random, recovery::{CongestionController, CubicCongestionController, RttEstimator}, time::{Clock, NoopClock, Timestamp}, }; +use core::{fmt, ops::Range, time::Duration}; +use insta::assert_debug_snapshot; +use plotters::prelude::*; use std::{ env, path::{Path, PathBuf}, diff --git a/quic/s2n-quic-core/tests/recovery/snapshots/recovery_simulation__AppLimited1MB-CubicCongestionController.snap b/quic/s2n-quic-core/src/recovery/snapshots/s2n_quic_core__recovery__simulation__AppLimited1MB-CubicCongestionController.snap similarity index 97% rename from quic/s2n-quic-core/tests/recovery/snapshots/recovery_simulation__AppLimited1MB-CubicCongestionController.snap rename to quic/s2n-quic-core/src/recovery/snapshots/s2n_quic_core__recovery__simulation__AppLimited1MB-CubicCongestionController.snap index aae102ef80..090c041447 100644 --- a/quic/s2n-quic-core/tests/recovery/snapshots/recovery_simulation__AppLimited1MB-CubicCongestionController.snap +++ b/quic/s2n-quic-core/src/recovery/snapshots/s2n_quic_core__recovery__simulation__AppLimited1MB-CubicCongestionController.snap @@ -1,5 +1,6 @@ --- -source: quic/s2n-quic-core/tests/recovery/simulation.rs +source: quic/s2n-quic-core/src/recovery/simulation.rs +assertion_line: 149 expression: self --- Simulation { diff --git a/quic/s2n-quic-core/tests/recovery/snapshots/recovery_simulation__Lossat3MB-CubicCongestionController.snap b/quic/s2n-quic-core/src/recovery/snapshots/s2n_quic_core__recovery__simulation__Lossat3MB-CubicCongestionController.snap similarity index 97% rename from quic/s2n-quic-core/tests/recovery/snapshots/recovery_simulation__Lossat3MB-CubicCongestionController.snap rename to quic/s2n-quic-core/src/recovery/snapshots/s2n_quic_core__recovery__simulation__Lossat3MB-CubicCongestionController.snap index 031d3ec4d2..5bd8b388e8 100644 --- a/quic/s2n-quic-core/tests/recovery/snapshots/recovery_simulation__Lossat3MB-CubicCongestionController.snap +++ b/quic/s2n-quic-core/src/recovery/snapshots/s2n_quic_core__recovery__simulation__Lossat3MB-CubicCongestionController.snap @@ -1,5 +1,6 @@ --- -source: quic/s2n-quic-core/tests/recovery/simulation.rs +source: quic/s2n-quic-core/src/recovery/simulation.rs +assertion_line: 149 expression: self --- Simulation { diff --git a/quic/s2n-quic-core/tests/recovery/snapshots/recovery_simulation__Lossat3MBand2_75MB-CubicCongestionController.snap b/quic/s2n-quic-core/src/recovery/snapshots/s2n_quic_core__recovery__simulation__Lossat3MBand2_75MB-CubicCongestionController.snap similarity index 97% rename from quic/s2n-quic-core/tests/recovery/snapshots/recovery_simulation__Lossat3MBand2_75MB-CubicCongestionController.snap rename to quic/s2n-quic-core/src/recovery/snapshots/s2n_quic_core__recovery__simulation__Lossat3MBand2_75MB-CubicCongestionController.snap index cfa3c550ac..015f80ce13 100644 --- a/quic/s2n-quic-core/tests/recovery/snapshots/recovery_simulation__Lossat3MBand2_75MB-CubicCongestionController.snap +++ b/quic/s2n-quic-core/src/recovery/snapshots/s2n_quic_core__recovery__simulation__Lossat3MBand2_75MB-CubicCongestionController.snap @@ -1,5 +1,6 @@ --- -source: quic/s2n-quic-core/tests/recovery/simulation.rs +source: quic/s2n-quic-core/src/recovery/simulation.rs +assertion_line: 149 expression: self --- Simulation { diff --git a/quic/s2n-quic-core/tests/recovery/snapshots/recovery_simulation__MinimumWindow-CubicCongestionController.snap b/quic/s2n-quic-core/src/recovery/snapshots/s2n_quic_core__recovery__simulation__MinimumWindow-CubicCongestionController.snap similarity index 85% rename from quic/s2n-quic-core/tests/recovery/snapshots/recovery_simulation__MinimumWindow-CubicCongestionController.snap rename to quic/s2n-quic-core/src/recovery/snapshots/s2n_quic_core__recovery__simulation__MinimumWindow-CubicCongestionController.snap index 09001184e6..a44879db78 100644 --- a/quic/s2n-quic-core/tests/recovery/snapshots/recovery_simulation__MinimumWindow-CubicCongestionController.snap +++ b/quic/s2n-quic-core/src/recovery/snapshots/s2n_quic_core__recovery__simulation__MinimumWindow-CubicCongestionController.snap @@ -1,8 +1,7 @@ --- -source: quic/s2n-quic-core/tests/recovery/simulation.rs -assertion_line: 148 +source: quic/s2n-quic-core/src/recovery/simulation.rs +assertion_line: 149 expression: self - --- Simulation { name: "Minimum Window", diff --git a/quic/s2n-quic-core/tests/recovery/snapshots/recovery_simulation__SlowStartUnlimited-CubicCongestionController.snap b/quic/s2n-quic-core/src/recovery/snapshots/s2n_quic_core__recovery__simulation__SlowStartUnlimited-CubicCongestionController.snap similarity index 86% rename from quic/s2n-quic-core/tests/recovery/snapshots/recovery_simulation__SlowStartUnlimited-CubicCongestionController.snap rename to quic/s2n-quic-core/src/recovery/snapshots/s2n_quic_core__recovery__simulation__SlowStartUnlimited-CubicCongestionController.snap index 0101f191ec..fb9a0309a5 100644 --- a/quic/s2n-quic-core/tests/recovery/snapshots/recovery_simulation__SlowStartUnlimited-CubicCongestionController.snap +++ b/quic/s2n-quic-core/src/recovery/snapshots/s2n_quic_core__recovery__simulation__SlowStartUnlimited-CubicCongestionController.snap @@ -1,8 +1,7 @@ --- -source: quic/s2n-quic-core/tests/recovery/simulation.rs -assertion_line: 148 +source: quic/s2n-quic-core/src/recovery/simulation.rs +assertion_line: 149 expression: self - --- Simulation { name: "Slow Start Unlimited", diff --git a/quic/s2n-quic-core/src/slice.rs b/quic/s2n-quic-core/src/slice.rs index 446243f5c8..662eb15022 100644 --- a/quic/s2n-quic-core/src/slice.rs +++ b/quic/s2n-quic-core/src/slice.rs @@ -155,6 +155,7 @@ mod tests { #[cfg_attr(not(kani), test)] #[cfg_attr(kani, kani::proof)] #[cfg_attr(kani, kani::unwind(5))] + #[cfg_attr(miri, ignore)] // This test is too expensive for miri to complete in a reasonable amount of time fn vectored_copy_fuzz_test() { check!() .with_type::<( diff --git a/quic/s2n-quic-core/src/stream/iter.rs b/quic/s2n-quic-core/src/stream/iter.rs index fd3ff619ac..3127856a76 100644 --- a/quic/s2n-quic-core/src/stream/iter.rs +++ b/quic/s2n-quic-core/src/stream/iter.rs @@ -76,6 +76,7 @@ mod fuzz_target { use super::*; #[test] + #[cfg_attr(miri, ignore)] // This test is too expensive for miri to complete in a reasonable amount of time fn fuzz_builder() { bolero::check!() .with_type::<(StreamId, StreamId)>() diff --git a/quic/s2n-quic-core/tests/transport_parameters/corpus.tar.gz b/quic/s2n-quic-core/src/transport/parameters/__fuzz__/transport__parameters__tests__round_trip/corpus.tar.gz similarity index 100% rename from quic/s2n-quic-core/tests/transport_parameters/corpus.tar.gz rename to quic/s2n-quic-core/src/transport/parameters/__fuzz__/transport__parameters__tests__round_trip/corpus.tar.gz diff --git a/quic/s2n-quic-core/src/transport/parameters/mod.rs b/quic/s2n-quic-core/src/transport/parameters/mod.rs index 445e7a01b4..27126efa8b 100644 --- a/quic/s2n-quic-core/src/transport/parameters/mod.rs +++ b/quic/s2n-quic-core/src/transport/parameters/mod.rs @@ -19,6 +19,9 @@ use s2n_codec::{ DecoderBufferResult, DecoderError, DecoderValue, DecoderValueMut, Encoder, EncoderValue, }; +#[cfg(test)] +mod tests; + /// Trait for an transport parameter value pub trait TransportParameter: Sized { /// The ID or tag for the TransportParameter diff --git a/quic/s2n-quic-core/tests/transport_parameters/fuzz_target.rs b/quic/s2n-quic-core/src/transport/parameters/tests.rs similarity index 69% rename from quic/s2n-quic-core/tests/transport_parameters/fuzz_target.rs rename to quic/s2n-quic-core/src/transport/parameters/tests.rs index c731d92dff..0e010d8879 100644 --- a/quic/s2n-quic-core/tests/transport_parameters/fuzz_target.rs +++ b/quic/s2n-quic-core/src/transport/parameters/tests.rs @@ -1,11 +1,13 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 +use crate::transport::parameters::{ClientTransportParameters, ServerTransportParameters}; use bolero::check; use s2n_codec::assert_codec_round_trip_bytes; -use s2n_quic_core::transport::parameters::{ClientTransportParameters, ServerTransportParameters}; -fn main() { +#[test] +#[cfg_attr(miri, ignore)] // This test is too expensive for miri to complete in a reasonable amount of time +fn round_trip() { check!().for_each(|input| { if input.is_empty() { return; diff --git a/quic/s2n-quic-core/tests/varint/corpus.tar.gz b/quic/s2n-quic-core/src/varint/__fuzz__/varint__tests__round_trip/corpus.tar.gz similarity index 100% rename from quic/s2n-quic-core/tests/varint/corpus.tar.gz rename to quic/s2n-quic-core/src/varint/__fuzz__/varint__tests__round_trip/corpus.tar.gz diff --git a/quic/s2n-quic-core/src/varint/mod.rs b/quic/s2n-quic-core/src/varint/mod.rs index 8a6080990c..f1f789b085 100644 --- a/quic/s2n-quic-core/src/varint/mod.rs +++ b/quic/s2n-quic-core/src/varint/mod.rs @@ -10,6 +10,9 @@ use s2n_codec::{decoder_value, Encoder, EncoderValue}; #[cfg(any(test, feature = "generator"))] use bolero_generator::*; +#[cfg(test)] +mod tests; + //= https://www.rfc-editor.org/rfc/rfc9000#section-16 //# QUIC packets and frames commonly use a variable-length encoding for //# non-negative integer values. This encoding ensures that smaller @@ -101,58 +104,6 @@ fn encoding_size(x: u64) -> usize { } } -#[cfg(test)] -mod tests { - use super::*; - - #[test] - #[cfg_attr(miri, ignore)] // snapshot tests don't work on miri - fn table_snapshot_test() { - use insta::assert_debug_snapshot; - assert_debug_snapshot!("max_value", MAX_VARINT_VALUE); - - // These values are derived from the "usable bits" column in the table: V and V-1 - for i in [0, 1, 5, 6, 13, 14, 29, 30, 61] { - assert_debug_snapshot!(format!("table_2_pow_{}_", i), read_table(2u64.pow(i))); - } - } - - //= https://www.rfc-editor.org/rfc/rfc9000#section-A.1 - //# For example, the eight-byte sequence 0xc2197c5eff14e88c decodes to - //# the decimal value 151,288,809,941,952,652; the four-byte sequence - //# 0x9d7f3e7d decodes to 494,878,333; the two-byte sequence 0x7bbd - //# decodes to 15,293; and the single byte 0x25 decodes to 37 (as does - //# the two-byte sequence 0x4025). - - macro_rules! sequence_test { - ($name:ident($input:expr, $expected:expr)) => { - #[test] - fn $name() { - use s2n_codec::assert_codec_round_trip_value; - - let input = $input; - let expected = VarInt::new($expected).unwrap(); - let actual_bytes = assert_codec_round_trip_value!(VarInt, expected); - assert_eq!(&input[..], &actual_bytes[..]); - } - }; - } - - sequence_test!(eight_byte_sequence_test( - [0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c], - 151_288_809_941_952_652 - )); - - sequence_test!(four_byte_sequence_test( - [0x9d, 0x7f, 0x3e, 0x7d], - 494_878_333 - )); - - sequence_test!(two_byte_sequence_test([0x7b, 0xbd], 15293)); - - sequence_test!(one_byte_sequence_test([0x25], 37)); -} - // === API === #[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq, PartialOrd, Ord)] diff --git a/quic/s2n-quic-core/src/varint/tests.rs b/quic/s2n-quic-core/src/varint/tests.rs new file mode 100644 index 0000000000..c0e72ebe9d --- /dev/null +++ b/quic/s2n-quic-core/src/varint/tests.rs @@ -0,0 +1,70 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +use super::*; +use crate::varint::VarInt; +use bolero::check; +use s2n_codec::assert_codec_round_trip_bytes; + +#[test] +#[cfg_attr(miri, ignore)] // This test is too expensive for miri to complete in a reasonable amount of time +fn round_trip() { + check!().for_each(|input| { + for value in assert_codec_round_trip_bytes!(VarInt, input) { + let _ = value.checked_add(value); + let _ = value.checked_sub(value); + let _ = value.checked_mul(value); + let _ = value.checked_div(value); + let _ = value.saturating_add(value); + let _ = value.saturating_sub(value); + let _ = value.saturating_mul(value); + } + }); +} + +#[test] +#[cfg_attr(miri, ignore)] // snapshot tests don't work on miri +fn table_snapshot_test() { + use insta::assert_debug_snapshot; + assert_debug_snapshot!("max_value", MAX_VARINT_VALUE); + + // These values are derived from the "usable bits" column in the table: V and V-1 + for i in [0, 1, 5, 6, 13, 14, 29, 30, 61] { + assert_debug_snapshot!(format!("table_2_pow_{}_", i), read_table(2u64.pow(i))); + } +} + +//= https://www.rfc-editor.org/rfc/rfc9000#section-A.1 +//# For example, the eight-byte sequence 0xc2197c5eff14e88c decodes to +//# the decimal value 151,288,809,941,952,652; the four-byte sequence +//# 0x9d7f3e7d decodes to 494,878,333; the two-byte sequence 0x7bbd +//# decodes to 15,293; and the single byte 0x25 decodes to 37 (as does +//# the two-byte sequence 0x4025). + +macro_rules! sequence_test { + ($name:ident($input:expr, $expected:expr)) => { + #[test] + fn $name() { + use s2n_codec::assert_codec_round_trip_value; + + let input = $input; + let expected = VarInt::new($expected).unwrap(); + let actual_bytes = assert_codec_round_trip_value!(VarInt, expected); + assert_eq!(&input[..], &actual_bytes[..]); + } + }; +} + +sequence_test!(eight_byte_sequence_test( + [0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c], + 151_288_809_941_952_652 +)); + +sequence_test!(four_byte_sequence_test( + [0x9d, 0x7f, 0x3e, 0x7d], + 494_878_333 +)); + +sequence_test!(two_byte_sequence_test([0x7b, 0xbd], 15293)); + +sequence_test!(one_byte_sequence_test([0x25], 37)); diff --git a/quic/s2n-quic-core/tests/packet_number/fuzz_target.rs b/quic/s2n-quic-core/tests/packet_number/fuzz_target.rs deleted file mode 100644 index 374019388c..0000000000 --- a/quic/s2n-quic-core/tests/packet_number/fuzz_target.rs +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -use bolero::{check, generator::*}; -use s2n_codec::{testing::encode, DecoderBuffer}; -use s2n_quic_core::{ - packet::number::{PacketNumber, PacketNumberSpace}, - VarInt, -}; - -fn main() { - check!() - .with_generator( - gen_packet_number_space() - .and_then(|space| (gen_packet_number(space), gen_packet_number(space))), - ) - .cloned() - .for_each(|(packet_number, largest_acked_packet_number)| { - // Try to encode the packet number to send - if let Some((mask, bytes)) = - encode_packet_number(packet_number, largest_acked_packet_number) - { - // If encoding was valid, assert that the information can be decoded - let actual_packet_number = - decode_packet_number(mask, bytes, largest_acked_packet_number).unwrap(); - assert_eq!(actual_packet_number, packet_number); - } - }); -} - -fn gen_packet_number_space() -> impl ValueGenerator { - (0u8..=2).map_gen(|id| match id { - 0 => PacketNumberSpace::Initial, - 1 => PacketNumberSpace::Handshake, - 2 => PacketNumberSpace::ApplicationData, - _ => unreachable!("invalid space id {:?}", id), - }) -} - -fn gen_packet_number(space: PacketNumberSpace) -> impl ValueGenerator { - gen().map(move |packet_number| { - space.new_packet_number(match VarInt::new(packet_number) { - Ok(packet_number) => packet_number, - Err(_) => VarInt::from_u32(packet_number as u32), - }) - }) -} - -fn encode_packet_number( - packet_number: PacketNumber, - largest_acked_packet_number: PacketNumber, -) -> Option<(u8, Vec)> { - let truncated_packet_number = packet_number.truncate(largest_acked_packet_number)?; - - let bytes = encode(&truncated_packet_number).unwrap(); - let mask = truncated_packet_number.len().into_packet_tag_mask(); - - Some((mask, bytes)) -} - -fn decode_packet_number( - packet_tag: u8, - packet_bytes: Vec, - largest_acked_packet_number: PacketNumber, -) -> Result { - // decode the packet number len from the packet tag - let packet_number_len = largest_acked_packet_number - .space() - .new_packet_number_len(packet_tag); - - // make sure the packet_tag has the same mask as the len - assert_eq!(packet_number_len.into_packet_tag_mask(), packet_tag); - assert_eq!(packet_number_len.bytesize(), packet_bytes.len()); - - // try decoding the truncated packet number from the packet bytes - let (truncated_packet_number, _) = packet_number_len - .decode_truncated_packet_number(DecoderBuffer::new(&packet_bytes)) - .map_err(|err| err.to_string())?; - - // make sure the packet_number_len round trips - assert_eq!(truncated_packet_number.len(), packet_number_len); - - // make sure the encoding matches the original bytes - assert_eq!(packet_bytes, encode(&truncated_packet_number).unwrap()); - - // try expanding the truncated packet number - let packet_number = truncated_packet_number - .expand(largest_acked_packet_number) - .ok_or_else(|| "Could not expand truncated packet number".to_string())?; - - // try truncating the packet number - let actual_truncated_packet_number = packet_number - .truncate(largest_acked_packet_number) - .ok_or_else(|| "Could not truncate packet number".to_string())?; - - assert_eq!(actual_truncated_packet_number, truncated_packet_number); - - Ok(packet_number) -} diff --git a/quic/s2n-quic-core/tests/varint/fuzz_target.rs b/quic/s2n-quic-core/tests/varint/fuzz_target.rs deleted file mode 100644 index 1953f821a3..0000000000 --- a/quic/s2n-quic-core/tests/varint/fuzz_target.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -use bolero::check; -use s2n_codec::assert_codec_round_trip_bytes; -use s2n_quic_core::varint::VarInt; - -fn main() { - check!().for_each(|input| { - for value in assert_codec_round_trip_bytes!(VarInt, input) { - let _ = value.checked_add(value); - let _ = value.checked_sub(value); - let _ = value.checked_mul(value); - let _ = value.checked_div(value); - let _ = value.saturating_add(value); - let _ = value.saturating_sub(value); - let _ = value.saturating_mul(value); - } - }); -} diff --git a/quic/s2n-quic-crypto/Cargo.toml b/quic/s2n-quic-crypto/Cargo.toml index 5d4213865b..058c47cd77 100644 --- a/quic/s2n-quic-crypto/Cargo.toml +++ b/quic/s2n-quic-crypto/Cargo.toml @@ -31,8 +31,3 @@ hex-literal = "0.3" insta = { version = "1", features = ["json"] } pretty-hex = "0.3" s2n-quic-core = { path = "../s2n-quic-core", features = ["testing"] } - -[[test]] -name = "fuzz_target" -path = "tests/fuzz_target/main.rs" -harness = false diff --git a/quic/s2n-quic-crypto/tests/fuzz_target/main.rs b/quic/s2n-quic-crypto/src/tests.rs similarity index 93% rename from quic/s2n-quic-crypto/tests/fuzz_target/main.rs rename to quic/s2n-quic-crypto/src/tests.rs index 7159ca4640..cf6c077afc 100644 --- a/quic/s2n-quic-crypto/tests/fuzz_target/main.rs +++ b/quic/s2n-quic-crypto/src/tests.rs @@ -16,7 +16,8 @@ use s2n_quic_crypto::{ Algorithm, Prk, SecretPair, }; -fn main() { +#[test] +fn round_trip() { check!() .with_generator(( gen_crypto(), @@ -33,7 +34,7 @@ fn main() { } => { let (server_key, server_header_key) = server_keys; let (client_key, client_header_key) = client_keys; - assert!(test_round_trip( + assert!(check_round_trip( server_key, client_key, server_header_key, @@ -43,7 +44,7 @@ fn main() { payload ) .is_ok()); - assert!(test_round_trip( + assert!(check_round_trip( client_key, server_key, client_header_key, @@ -60,7 +61,7 @@ fn main() { } => { let (server_key, server_header_key) = server_keys; let (client_key, client_header_key) = client_keys; - assert!(test_round_trip( + assert!(check_round_trip( server_key, client_key, server_header_key, @@ -70,7 +71,7 @@ fn main() { payload ) .is_ok()); - assert!(test_round_trip( + assert!(check_round_trip( client_key, server_key, client_header_key, @@ -81,7 +82,7 @@ fn main() { ) .is_ok()); let server_key = server_key.update(); - assert!(test_round_trip( + assert!(check_round_trip( &server_key, client_key, server_header_key, @@ -91,7 +92,7 @@ fn main() { payload ) .is_err()); - assert!(test_round_trip( + assert!(check_round_trip( client_key, &server_key, client_header_key, @@ -102,7 +103,7 @@ fn main() { ) .is_err()); let client_key = client_key.update(); - assert!(test_round_trip( + assert!(check_round_trip( &server_key, &client_key, server_header_key, @@ -112,7 +113,7 @@ fn main() { payload ) .is_ok()); - assert!(test_round_trip( + assert!(check_round_trip( &client_key, &server_key, client_header_key, @@ -129,7 +130,7 @@ fn main() { } => { let (server_key, server_header_key) = server_keys; let (client_key, client_header_key) = client_keys; - assert!(test_round_trip( + assert!(check_round_trip( server_key, client_key, server_header_key, @@ -139,7 +140,7 @@ fn main() { payload ) .is_ok()); - assert!(test_round_trip( + assert!(check_round_trip( client_key, server_key, client_header_key, @@ -150,7 +151,7 @@ fn main() { ) .is_ok()); let server_key = server_key.update(); - assert!(test_round_trip( + assert!(check_round_trip( &server_key, client_key, server_header_key, @@ -160,7 +161,7 @@ fn main() { payload ) .is_err()); - assert!(test_round_trip( + assert!(check_round_trip( client_key, &server_key, client_header_key, @@ -171,7 +172,7 @@ fn main() { ) .is_err()); let client_key = client_key.update(); - assert!(test_round_trip( + assert!(check_round_trip( &server_key, &client_key, server_header_key, @@ -181,7 +182,7 @@ fn main() { payload ) .is_ok()); - assert!(test_round_trip( + assert!(check_round_trip( &client_key, &server_key, client_header_key, @@ -194,7 +195,7 @@ fn main() { } CryptoTest::ZeroRtt { ref keys } => { let (key, header_key) = keys; - assert!(test_round_trip( + assert!(check_round_trip( key, key, header_key, @@ -209,7 +210,7 @@ fn main() { }); } -fn test_round_trip( +fn check_round_trip( sealer_key: &K, opener: &K, sealer_header_key: &H, diff --git a/scripts/recovery-sim b/scripts/recovery-sim index c4a0eb9cd2..ad09fe396b 100755 --- a/scripts/recovery-sim +++ b/scripts/recovery-sim @@ -11,7 +11,7 @@ OUT=${1:-target/recovery-sim} mkdir -p $OUT OUT=$(realpath $OUT) -RECOVERY_SIM_DIR=$OUT cargo test -p s2n-quic-core --test recovery-simulation --features=testing -- --nocapture +RECOVERY_SIM_DIR=$OUT cargo test -p s2n-quic-core --lib recovery::simulation -- --nocapture cd $OUT # Generate an html file with a directory listing of all recovery simulations. -P is used to only include