stratus/
utils.rs

1use std::time::Duration;
2
3use tokio::time::Instant;
4
5/// Amount of bytes in one GB (technically, GiB).
6pub const GIGABYTE: usize = 1024 * 1024 * 1024;
7
8pub fn calculate_tps_and_bpm(duration: Duration, transaction_count: usize, block_count: usize) -> (f64, f64) {
9    let seconds_elapsed = duration.as_secs_f64() + f64::EPSILON;
10    let tps = transaction_count as f64 / seconds_elapsed;
11    let blocks_per_minute = block_count as f64 / (seconds_elapsed / 60.0);
12    (tps, blocks_per_minute)
13}
14
15pub fn calculate_tps(duration: Duration, transaction_count: usize) -> f64 {
16    let seconds_elapsed = duration.as_secs_f64() + f64::EPSILON;
17    transaction_count as f64 / seconds_elapsed
18}
19
20pub struct DropTimer {
21    instant: Instant,
22    scope_name: &'static str,
23}
24
25impl DropTimer {
26    pub fn start(scope_name: &'static str) -> Self {
27        Self {
28            instant: Instant::now(),
29            scope_name,
30        }
31    }
32}
33
34impl Drop for DropTimer {
35    fn drop(&mut self) {
36        tracing::info!(ran_for = ?self.instant.elapsed(), "Timer: '{}' finished", self.scope_name);
37    }
38}
39
40#[cfg(test)]
41pub mod test_utils {
42    use anyhow::Context;
43    use fake::Fake;
44    use fake::Faker;
45    use glob::glob;
46    use rand::SeedableRng;
47    use rand::rngs::SmallRng;
48
49    fn deterministic_rng() -> SmallRng {
50        SeedableRng::seed_from_u64(0)
51    }
52
53    /// Fake the first `size` values of type `T` using the default seed.
54    ///
55    /// Multiple calls of this (for the same `T` and `size`) will return the same list.
56    pub fn fake_list<T: fake::Dummy<Faker>>(size: usize) -> Vec<T> {
57        let mut rng = deterministic_rng();
58        (0..size).map(|_| Faker.fake_with_rng::<T, _>(&mut rng)).collect()
59    }
60
61    /// Fake the first `T` value in the default seed.
62    ///
63    /// Multiple calls of this (for the same `T`) will return the same value.
64    pub fn fake_first<T: fake::Dummy<Faker>>() -> T {
65        let mut rng = deterministic_rng();
66        Faker.fake_with_rng::<T, _>(&mut rng)
67    }
68
69    pub fn glob_to_string_paths(pattern: impl AsRef<str>) -> anyhow::Result<Vec<String>> {
70        let pattern = pattern.as_ref();
71
72        let iter = glob(pattern).with_context(|| format!("failed to parse glob pattern: {pattern}"))?;
73        let mut paths = vec![];
74
75        for entry in iter {
76            let entry = entry.with_context(|| format!("failed to read glob entry with pattern: {pattern}"))?;
77            let path = entry.to_str().with_context(|| format!("failed to convert path to string: {entry:?}"))?;
78            paths.push(path.to_owned());
79        }
80
81        Ok(paths)
82    }
83}