Skip to content

Commit 14ba262

Browse files
committed
Cleanup common tests
Signed-off-by: Joe Richey <[email protected]>
1 parent f345775 commit 14ba262

File tree

5 files changed

+124
-133
lines changed

5 files changed

+124
-133
lines changed

src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,3 +404,10 @@ pub fn getrandom_uninit(dest: &mut [MaybeUninit<u8>]) -> Result<&mut [u8], Error
404404
// since it returned `Ok`.
405405
Ok(unsafe { slice_assume_init_mut(dest) })
406406
}
407+
408+
// Don't run normal unit tests when testing custom getrandom
409+
#[cfg(all(
410+
test,
411+
not(all(target_family = "wasm", target_os = "unknown", feature = "custom"))
412+
))]
413+
pub(crate) mod tests;

src/tests.rs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
//! Common tests and testing utilities
2+
extern crate std;
3+
4+
use crate::Error;
5+
use std::{mem::MaybeUninit, sync::mpsc, thread, vec, vec::Vec};
6+
7+
#[cfg(feature = "test-in-browser")]
8+
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
9+
10+
fn num_diff_bits(s1: &[u8], s2: &[u8]) -> usize {
11+
assert_eq!(s1.len(), s2.len());
12+
s1.iter()
13+
.zip(s2.iter())
14+
.map(|(a, b)| (a ^ b).count_ones() as usize)
15+
.sum()
16+
}
17+
18+
// A function which fills a buffer with random bytes.
19+
type FillFn<B> = fn(&mut [B]) -> Result<(), Error>;
20+
21+
// Helper trait for testing different `FillFn`s.
22+
pub(crate) trait Byte: Sized + 'static {
23+
fn make_vec(len: usize, fill: FillFn<Self>) -> Vec<u8>;
24+
}
25+
impl Byte for u8 {
26+
fn make_vec(len: usize, fill: FillFn<u8>) -> Vec<u8> {
27+
let mut v = vec![0; len];
28+
fill(&mut v).unwrap();
29+
v
30+
}
31+
}
32+
impl Byte for MaybeUninit<u8> {
33+
fn make_vec(len: usize, fill: FillFn<MaybeUninit<u8>>) -> Vec<u8> {
34+
// Using Vec::spare_capacity_mut more consistently gives us truly
35+
// uninitialized memory regardless of optimization level.
36+
let mut v = Vec::with_capacity(len);
37+
fill(v.spare_capacity_mut()).unwrap();
38+
unsafe { v.set_len(len) }
39+
v
40+
}
41+
}
42+
43+
// For calls of size `len`, count the number of bits which differ between calls
44+
// and check that between 3 and 5 bits per byte differ. Probability of failure:
45+
// ~ 10^(-30) = 2 * CDF[BinomialDistribution[8*256, 0.5], 3*256]
46+
pub(crate) fn check_bits<B: Byte>(len: usize, fill: FillFn<B>) {
47+
let mut num_bytes = 0;
48+
let mut diff_bits = 0;
49+
while num_bytes < 256 {
50+
let v1 = B::make_vec(len, fill);
51+
let v2 = B::make_vec(len, fill);
52+
53+
num_bytes += len;
54+
diff_bits += num_diff_bits(&v1, &v2);
55+
}
56+
57+
// When the custom feature is enabled, don't check RNG quality.
58+
assert!(diff_bits > 3 * num_bytes);
59+
assert!(diff_bits < 5 * num_bytes);
60+
}
61+
62+
pub(crate) fn check_multithreading<B: Byte>(fill: FillFn<B>) {
63+
let mut txs = vec![];
64+
for _ in 0..20 {
65+
let (tx, rx) = mpsc::channel();
66+
txs.push(tx);
67+
68+
thread::spawn(move || {
69+
// wait until all the tasks are ready to go.
70+
rx.recv().unwrap();
71+
for _ in 0..100 {
72+
check_bits(1000, fill);
73+
thread::yield_now();
74+
}
75+
});
76+
}
77+
78+
// start all the tasks
79+
for tx in txs.iter() {
80+
tx.send(()).unwrap();
81+
}
82+
}
83+
84+
macro_rules! define_tests {
85+
($fill:expr) => {
86+
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
87+
use wasm_bindgen_test::wasm_bindgen_test as test;
88+
89+
#[test]
90+
fn fill_zero() {
91+
$fill(&mut []).unwrap();
92+
}
93+
#[test]
94+
fn fill_small() {
95+
for len in 1..=64 {
96+
crate::tests::check_bits(len, $fill);
97+
}
98+
}
99+
#[test]
100+
fn fill_large() {
101+
crate::tests::check_bits(1_000, $fill);
102+
}
103+
#[test]
104+
fn fill_huge() {
105+
crate::tests::check_bits(1_000_000, $fill);
106+
}
107+
// On WASM, the thread API always fails/panics.
108+
#[test]
109+
#[cfg_attr(target_family = "wasm", ignore)]
110+
fn multithreading() {
111+
crate::tests::check_multithreading($fill)
112+
}
113+
};
114+
}
115+
pub(crate) use define_tests;
116+
117+
define_tests!(crate::getrandom);

tests/common/mod.rs

Lines changed: 0 additions & 100 deletions
This file was deleted.

tests/normal.rs

Lines changed: 0 additions & 11 deletions
This file was deleted.

tests/rdrand.rs

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)