Module tor_basic_utils::test_rng
source · [−]Expand description
Code for deterministic and/or reproducible use of PRNGs in tests.
Often in testing we want to test a random scenario, but we want to be sure of our ability to reproduce the scenario if the test fails.
To achieve this, just have your test use testing_rng()
in place of
rand::thread_rng()
. Then the test will (by default) choose a new random
seed for every run, and print that seed to standard output. If the test
fails, the seed will be displayed as part of the failure message, and you
will be able to use it to recreate the same PRNG seed as the one that caused
the failure.
If you’re running your tests in a situation where deterministic behavior is key, you can also enable this via the environment.
The run-time behavior is controlled using the ARTI_TEST_PRNG
variable; you
can set it to any of the following:
random
for a randomly seeded PRNG. (This is the default).deterministic
for an arbitrary seed that is the same on every run of the program. (You can use this in cases where even a tiny chance of stochastic behavior in your tests is unacceptable.)- A hexadecimal string, to specify a given seed to re-use from a previous test run.
WARNING
This is for testing only! Never ever use it in non-testing code. Doing so may compromise your security.
You may wish to use clippy’s disallowed-methods
lint to ensure you aren’t
using it outside of your tests.
Examples
Here’s a simple example, of a test that verifies that integer sorting works correctly by shuffling a short sequence and then re-sorting it.
use tor_basic_utils::test_rng::testing_rng;
use rand::{seq::SliceRandom};
let mut rng = testing_rng();
let mut v = vec![-10, -3, 0, 1, 2, 3];
v.shuffle(&mut rng);
v.sort();
assert_eq!(&v, &[-10, -3, 0, 1, 2, 3])
Here’s a trickier example of how you might write a test to override the default behavior. (For example, you might want to do this if the test is unreliable and you don’t have time to hunt down the issues.)
use tor_basic_utils::test_rng::Config;
let mut rng = Config::from_env()
.unwrap_or(Config::Deterministic)
.into_rng();