stratus/
utils.rs

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use std::time::Duration;

use tokio::time::Instant;

/// Amount of bytes in one GB (technically, GiB).
pub const GIGABYTE: usize = 1024 * 1024 * 1024;

pub fn calculate_tps_and_bpm(duration: Duration, transaction_count: usize, block_count: usize) -> (f64, f64) {
    let seconds_elapsed = duration.as_secs_f64() + f64::EPSILON;
    let tps = transaction_count as f64 / seconds_elapsed;
    let blocks_per_minute = block_count as f64 / (seconds_elapsed / 60.0);
    (tps, blocks_per_minute)
}

pub fn calculate_tps(duration: Duration, transaction_count: usize) -> f64 {
    let seconds_elapsed = duration.as_secs_f64() + f64::EPSILON;
    transaction_count as f64 / seconds_elapsed
}

pub struct DropTimer {
    instant: Instant,
    scope_name: &'static str,
}

impl DropTimer {
    pub fn start(scope_name: &'static str) -> Self {
        Self {
            instant: Instant::now(),
            scope_name,
        }
    }
}

impl Drop for DropTimer {
    fn drop(&mut self) {
        tracing::info!(ran_for = ?self.instant.elapsed(), "Timer: '{}' finished", self.scope_name);
    }
}

#[cfg(test)]
pub mod test_utils {
    use anyhow::Context;
    use fake::Fake;
    use fake::Faker;
    use glob::glob;
    use rand::rngs::SmallRng;
    use rand::SeedableRng;

    fn deterministic_rng() -> SmallRng {
        SeedableRng::seed_from_u64(0)
    }

    /// Fake the first `size` values of type `T` using the default seed.
    ///
    /// Multiple calls of this (for the same `T` and `size`) will return the same list.
    pub fn fake_list<T: fake::Dummy<Faker>>(size: usize) -> Vec<T> {
        let mut rng = deterministic_rng();
        (0..size).map(|_| Faker.fake_with_rng::<T, _>(&mut rng)).collect()
    }

    /// Fake the first `T` value in the default seed.
    ///
    /// Multiple calls of this (for the same `T`) will return the same value.
    pub fn fake_first<T: fake::Dummy<Faker>>() -> T {
        let mut rng = deterministic_rng();
        Faker.fake_with_rng::<T, _>(&mut rng)
    }

    pub fn glob_to_string_paths(pattern: impl AsRef<str>) -> anyhow::Result<Vec<String>> {
        let pattern = pattern.as_ref();

        let iter = glob(pattern).with_context(|| format!("failed to parse glob pattern: {pattern}"))?;
        let mut paths = vec![];

        for entry in iter {
            let entry = entry.with_context(|| format!("failed to read glob entry with pattern: {pattern}"))?;
            let path = entry.to_str().with_context(|| format!("failed to convert path to string: {entry:?}"))?;
            paths.push(path.to_owned());
        }

        Ok(paths)
    }
}