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}