diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 666f7f57..6f283e09 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,4 +1,7 @@ -use super::getrandom_impl; +use super::{getrandom_impl, getrandom_uninit_impl}; +use core::mem::MaybeUninit; +#[cfg(not(feature = "custom"))] +use getrandom::Error; #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; @@ -6,10 +9,19 @@ use wasm_bindgen_test::wasm_bindgen_test as test; #[cfg(feature = "test-in-browser")] wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); +#[cfg(not(feature = "custom"))] +fn wrapped_getrandom(dest: &mut [u8]) -> Result<&mut [u8], Error> { + getrandom_impl(dest).map(|()| dest) +} + +// Test that APIs are happy with zero-length requests #[test] fn test_zero() { - // Test that APIs are happy with zero-length requests - getrandom_impl(&mut [0u8; 0]).unwrap(); + getrandom_impl(&mut []).unwrap(); +} +#[test] +fn test_zero_uninit() { + getrandom_uninit_impl(&mut []).unwrap(); } // Return the number of bits in which s1 and s2 differ @@ -23,26 +35,38 @@ fn num_diff_bits(s1: &[u8], s2: &[u8]) -> usize { } // Tests the quality of calling getrandom on two large buffers -#[test] + #[cfg(not(feature = "custom"))] -fn test_diff() { - let mut v1 = [0u8; 1000]; - getrandom_impl(&mut v1).unwrap(); +fn test_diff_large(initial: T, f: impl Fn(&mut [T]) -> Result<&mut [u8], Error>) { + let mut v1 = [initial; 1000]; + let r1 = f(&mut v1).unwrap(); - let mut v2 = [0u8; 1000]; - getrandom_impl(&mut v2).unwrap(); + let mut v2 = [initial; 1000]; + let r2 = f(&mut v2).unwrap(); // Between 3.5 and 4.5 bits per byte should differ. Probability of failure: // ~ 2^(-94) = 2 * CDF[BinomialDistribution[8000, 0.5], 3500] - let d = num_diff_bits(&v1, &v2); + let d = num_diff_bits(r1, r2); assert!(d > 3500); assert!(d < 4500); } -// Tests the quality of calling getrandom repeatedly on small buffers +#[cfg(not(feature = "custom"))] #[test] +fn test_large() { + test_diff_large(0u8, wrapped_getrandom); +} + #[cfg(not(feature = "custom"))] -fn test_small() { +#[test] +fn test_large_uninit() { + test_diff_large(MaybeUninit::uninit(), getrandom_uninit_impl); +} + +// Tests the quality of calling getrandom repeatedly on small buffers + +#[cfg(not(feature = "custom"))] +fn test_diff_small(initial: T, f: impl Fn(&mut [T]) -> Result<&mut [u8], Error>) { // For each buffer size, get at least 256 bytes and check that between // 3 and 5 bits per byte differ. Probability of failure: // ~ 2^(-91) = 64 * 2 * CDF[BinomialDistribution[8*256, 0.5], 3*256] @@ -50,25 +74,43 @@ fn test_small() { let mut num_bytes = 0; let mut diff_bits = 0; while num_bytes < 256 { - let mut s1 = vec![0u8; size]; - getrandom_impl(&mut s1).unwrap(); - let mut s2 = vec![0u8; size]; - getrandom_impl(&mut s2).unwrap(); + let mut s1 = vec![initial; size]; + let r1 = f(&mut s1).unwrap(); + let mut s2 = vec![initial; size]; + let r2 = f(&mut s2).unwrap(); num_bytes += size; - diff_bits += num_diff_bits(&s1, &s2); + diff_bits += num_diff_bits(r1, r2); } assert!(diff_bits > 3 * num_bytes); assert!(diff_bits < 5 * num_bytes); } } +#[cfg(not(feature = "custom"))] +#[test] +fn test_small() { + test_diff_small(0u8, wrapped_getrandom); +} + +#[cfg(not(feature = "custom"))] +#[test] +fn test_small_unnit() { + test_diff_small(MaybeUninit::uninit(), getrandom_uninit_impl); +} + #[test] fn test_huge() { let mut huge = [0u8; 100_000]; getrandom_impl(&mut huge).unwrap(); } +#[test] +fn test_huge_uninit() { + let mut huge = [MaybeUninit::uninit(); 100_000]; + getrandom_uninit_impl(&mut huge).unwrap(); +} + // On WASM, the thread API always fails/panics #[cfg(not(target_arch = "wasm32"))] #[test] diff --git a/tests/custom.rs b/tests/custom.rs index b085094b..8919ccdd 100644 --- a/tests/custom.rs +++ b/tests/custom.rs @@ -34,7 +34,7 @@ fn super_insecure_rng(buf: &mut [u8]) -> Result<(), Error> { register_custom_getrandom!(super_insecure_rng); -use getrandom::getrandom as getrandom_impl; +use getrandom::{getrandom as getrandom_impl, getrandom_uninit as getrandom_uninit_impl}; mod common; #[test] diff --git a/tests/normal.rs b/tests/normal.rs index 5fff13b3..69d57155 100644 --- a/tests/normal.rs +++ b/tests/normal.rs @@ -7,5 +7,5 @@ )))] // Use the normal getrandom implementation on this architecture. -use getrandom::getrandom as getrandom_impl; +use getrandom::{getrandom as getrandom_impl, getrandom_uninit as getrandom_uninit_impl}; mod common; diff --git a/tests/rdrand.rs b/tests/rdrand.rs index a355c31e..ac17fa4c 100644 --- a/tests/rdrand.rs +++ b/tests/rdrand.rs @@ -3,6 +3,7 @@ // rdrand.rs expects to be part of the getrandom main crate, so we need these // additional imports to get rdrand.rs to compile. +use core::mem::MaybeUninit; use getrandom::Error; #[macro_use] extern crate cfg_if; @@ -13,10 +14,15 @@ mod rdrand; #[path = "../src/util.rs"] mod util; -// The rdrand implementation has the signature of getrandom_uninit(), but our -// tests expect getrandom_impl() to have the signature of getrandom(). +use crate::util::slice_assume_init_mut; + fn getrandom_impl(dest: &mut [u8]) -> Result<(), Error> { rdrand::getrandom_inner(unsafe { util::slice_as_uninit_mut(dest) })?; Ok(()) } +fn getrandom_uninit_impl(dest: &mut [MaybeUninit]) -> Result<&mut [u8], Error> { + rdrand::getrandom_inner(dest)?; + Ok(unsafe { slice_assume_init_mut(dest) }) +} + mod common;