1
/// Initializes the standard logger for tests. Output is routed through the test
2
/// harness so it is captured rather than printed unconditionally.
3
16647
pub fn test_logger() {
4
16647
    if !cfg!(miri) {
5
16647
        // Ignore double initialisations in tests since tests are ran in parallel.
6
16647
        let _ = env_logger::builder().is_test(true).try_init();
7
16647
    }
8
16647
}
9

            
10
2
pub fn test_threads<C, F, G>(num_threads: usize, init_function: G, test_function: F)
11
2
where
12
2
    C: Send + 'static,
13
2
    F: Fn(&mut C) + Copy + Send + Sync + 'static,
14
2
    G: Fn() -> C,
15
{
16
2
    test_logger();
17

            
18
2
    let mut threads = vec![];
19

            
20
2
    for _ in 0..num_threads {
21
7
        let mut init = init_function();
22
7
        threads.push(std::thread::spawn(move || {
23
7
            test_function(&mut init);
24
7
        }));
25
    }
26

            
27
    // Propagate a worker panic so a failing assertion fails the test instead of
28
    // being silently swallowed.
29
7
    for thread in threads {
30
7
        thread.join().unwrap();
31
7
    }
32
2
}