diff options
Diffstat (limited to 'third_party/rust/getrandom/tests')
-rw-r--r-- | third_party/rust/getrandom/tests/common/mod.rs | 100 | ||||
-rw-r--r-- | third_party/rust/getrandom/tests/custom.rs | 54 | ||||
-rw-r--r-- | third_party/rust/getrandom/tests/normal.rs | 11 | ||||
-rw-r--r-- | third_party/rust/getrandom/tests/rdrand.rs | 20 |
4 files changed, 185 insertions, 0 deletions
diff --git a/third_party/rust/getrandom/tests/common/mod.rs b/third_party/rust/getrandom/tests/common/mod.rs new file mode 100644 index 0000000000..666f7f5702 --- /dev/null +++ b/third_party/rust/getrandom/tests/common/mod.rs @@ -0,0 +1,100 @@ +use super::getrandom_impl; + +#[cfg(all(target_arch = "wasm32", target_os = "unknown"))] +use wasm_bindgen_test::wasm_bindgen_test as test; + +#[cfg(feature = "test-in-browser")] +wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); + +#[test] +fn test_zero() { + // Test that APIs are happy with zero-length requests + getrandom_impl(&mut [0u8; 0]).unwrap(); +} + +// Return the number of bits in which s1 and s2 differ +#[cfg(not(feature = "custom"))] +fn num_diff_bits(s1: &[u8], s2: &[u8]) -> usize { + assert_eq!(s1.len(), s2.len()); + s1.iter() + .zip(s2.iter()) + .map(|(a, b)| (a ^ b).count_ones() as usize) + .sum() +} + +// 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(); + + let mut v2 = [0u8; 1000]; + getrandom_impl(&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); + assert!(d > 3500); + assert!(d < 4500); +} + +// Tests the quality of calling getrandom repeatedly on small buffers +#[test] +#[cfg(not(feature = "custom"))] +fn test_small() { + // 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] + for size in 1..=64 { + 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(); + + num_bytes += size; + diff_bits += num_diff_bits(&s1, &s2); + } + assert!(diff_bits > 3 * num_bytes); + assert!(diff_bits < 5 * num_bytes); + } +} + +#[test] +fn test_huge() { + let mut huge = [0u8; 100_000]; + getrandom_impl(&mut huge).unwrap(); +} + +// On WASM, the thread API always fails/panics +#[cfg(not(target_arch = "wasm32"))] +#[test] +fn test_multithreading() { + extern crate std; + use std::{sync::mpsc::channel, thread, vec}; + + let mut txs = vec![]; + for _ in 0..20 { + let (tx, rx) = channel(); + txs.push(tx); + + thread::spawn(move || { + // wait until all the tasks are ready to go. + rx.recv().unwrap(); + let mut v = [0u8; 1000]; + + for _ in 0..100 { + getrandom_impl(&mut v).unwrap(); + thread::yield_now(); + } + }); + } + + // start all the tasks + for tx in txs.iter() { + tx.send(()).unwrap(); + } +} diff --git a/third_party/rust/getrandom/tests/custom.rs b/third_party/rust/getrandom/tests/custom.rs new file mode 100644 index 0000000000..b085094be8 --- /dev/null +++ b/third_party/rust/getrandom/tests/custom.rs @@ -0,0 +1,54 @@ +// Test that a custom handler works on wasm32-unknown-unknown +#![cfg(all( + target_arch = "wasm32", + target_os = "unknown", + feature = "custom", + not(feature = "js") +))] + +use wasm_bindgen_test::wasm_bindgen_test as test; + +use core::num::NonZeroU32; +use getrandom::{getrandom, register_custom_getrandom, Error}; + +fn len7_err() -> Error { + NonZeroU32::new(Error::INTERNAL_START + 7).unwrap().into() +} + +fn super_insecure_rng(buf: &mut [u8]) -> Result<(), Error> { + // `getrandom` guarantees it will not call any implementation if the output + // buffer is empty. + assert!(!buf.is_empty()); + // Length 7 buffers return a custom error + if buf.len() == 7 { + return Err(len7_err()); + } + // Otherwise, fill bytes based on input length + let mut start = buf.len() as u8; + for b in buf { + *b = start; + start = start.wrapping_mul(3); + } + Ok(()) +} + +register_custom_getrandom!(super_insecure_rng); + +use getrandom::getrandom as getrandom_impl; +mod common; + +#[test] +fn custom_rng_output() { + let mut buf = [0u8; 4]; + assert_eq!(getrandom(&mut buf), Ok(())); + assert_eq!(buf, [4, 12, 36, 108]); + + let mut buf = [0u8; 3]; + assert_eq!(getrandom(&mut buf), Ok(())); + assert_eq!(buf, [3, 9, 27]); +} + +#[test] +fn rng_err_output() { + assert_eq!(getrandom(&mut [0; 7]), Err(len7_err())); +} diff --git a/third_party/rust/getrandom/tests/normal.rs b/third_party/rust/getrandom/tests/normal.rs new file mode 100644 index 0000000000..5fff13b38e --- /dev/null +++ b/third_party/rust/getrandom/tests/normal.rs @@ -0,0 +1,11 @@ +// Don't test on custom wasm32-unknown-unknown +#![cfg(not(all( + target_arch = "wasm32", + target_os = "unknown", + feature = "custom", + not(feature = "js") +)))] + +// Use the normal getrandom implementation on this architecture. +use getrandom::getrandom as getrandom_impl; +mod common; diff --git a/third_party/rust/getrandom/tests/rdrand.rs b/third_party/rust/getrandom/tests/rdrand.rs new file mode 100644 index 0000000000..25678683f3 --- /dev/null +++ b/third_party/rust/getrandom/tests/rdrand.rs @@ -0,0 +1,20 @@ +// We only test the RDRAND-based RNG source on supported architectures. +#![cfg(any(target_arch = "x86_64", target_arch = "x86"))] + +// rdrand.rs expects to be part of the getrandom main crate, so we need these +// additional imports to get rdrand.rs to compile. +use getrandom::Error; +#[macro_use] +extern crate cfg_if; +#[path = "../src/rdrand.rs"] +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(). +fn getrandom_impl(dest: &mut [u8]) -> Result<(), Error> { + rdrand::getrandom_inner(unsafe { util::slice_as_uninit_mut(dest) })?; + Ok(()) +} +mod common; |