1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
use std::time::Duration;
use rand::{random, Closed01};
fn apply_jitter(duration: Duration, jitter: f64) -> Duration {
let secs = (duration.as_secs() as f64) * jitter;
let nanos = (duration.subsec_nanos() as f64) * jitter;
let millis = (secs * 1000f64) + (nanos / 1000000f64);
Duration::from_millis(millis as u64)
}
pub fn jitter(duration: Duration) -> Duration {
let Closed01(jitter) = random();
apply_jitter(duration, jitter)
}
#[test]
fn apply_jitter_quickcheck() {
extern crate quickcheck;
#[derive(Clone, Debug)]
struct ArbitraryJitter(f64);
impl quickcheck::Arbitrary for ArbitraryJitter {
fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> Self {
let Closed01(jitter) = g.gen();
ArbitraryJitter(jitter)
}
}
fn rounds_correctly(millis: u64, arb_jitter: ArbitraryJitter) -> bool {
let ArbitraryJitter(jitter) = arb_jitter;
let millis_with_jitter = ((millis as f64) * jitter) as u64;
let duration_with_jitter = apply_jitter(Duration::from_millis(millis), jitter);
duration_with_jitter == Duration::from_millis(millis_with_jitter)
}
quickcheck::quickcheck(rounds_correctly as fn(u64, ArbitraryJitter) -> bool)
}