Skip to main content

moonpool_sim/providers/
sim_providers.rs

1//! Simulation providers bundle implementation.
2
3use std::net::IpAddr;
4
5use moonpool_core::{Providers, TokioTaskProvider};
6
7use crate::network::SimNetworkProvider;
8use crate::sim::WeakSimWorld;
9use crate::storage::SimStorageProvider;
10
11use super::{SimRandomProvider, SimTimeProvider};
12
13/// Simulation providers bundle for deterministic testing.
14///
15/// This struct bundles all simulation-based providers into a single
16/// instance that implements [`Providers`]. Each bundle is scoped to a
17/// specific process IP for per-process storage fault injection.
18///
19/// ## Usage
20///
21/// ```rust,ignore
22/// use moonpool_sim::{SimWorld, SimProviders, Providers};
23///
24/// let sim = SimWorld::new();
25/// let ip: std::net::IpAddr = "10.0.1.1".parse().unwrap();
26/// let providers = SimProviders::new(sim.downgrade(), 42, ip);
27///
28/// // Access individual providers
29/// let network = providers.network();
30/// let storage = providers.storage();
31/// ```
32///
33/// ## Implementation Notes
34///
35/// - Uses `SimNetworkProvider` for simulated TCP connections
36/// - Uses `SimTimeProvider` for logical/simulated time
37/// - Uses `TokioTaskProvider` for task spawning (same as production)
38/// - Uses `SimRandomProvider` for seeded deterministic randomness
39/// - Uses `SimStorageProvider` for simulated file I/O with per-process fault injection
40#[derive(Clone)]
41pub struct SimProviders {
42    network: SimNetworkProvider,
43    time: SimTimeProvider,
44    task: TokioTaskProvider,
45    random: SimRandomProvider,
46    storage: SimStorageProvider,
47}
48
49impl SimProviders {
50    /// Create a new simulation providers bundle scoped to a process IP.
51    ///
52    /// # Arguments
53    ///
54    /// * `sim` - Weak reference to the simulation world
55    /// * `seed` - Seed for deterministic random number generation
56    /// * `ip` - IP address of the owning process (for per-process storage scoping)
57    pub fn new(sim: WeakSimWorld, seed: u64, ip: IpAddr) -> Self {
58        Self {
59            network: SimNetworkProvider::new(sim.clone()),
60            time: SimTimeProvider::new(sim.clone()),
61            task: TokioTaskProvider,
62            random: SimRandomProvider::new(seed),
63            storage: SimStorageProvider::new(sim, ip),
64        }
65    }
66}
67
68impl Providers for SimProviders {
69    type Network = SimNetworkProvider;
70    type Time = SimTimeProvider;
71    type Task = TokioTaskProvider;
72    type Random = SimRandomProvider;
73
74    fn network(&self) -> &Self::Network {
75        &self.network
76    }
77
78    fn time(&self) -> &Self::Time {
79        &self.time
80    }
81
82    fn task(&self) -> &Self::Task {
83        &self.task
84    }
85
86    fn random(&self) -> &Self::Random {
87        &self.random
88    }
89
90    type Storage = SimStorageProvider;
91
92    fn storage(&self) -> &Self::Storage {
93        &self.storage
94    }
95}