moonpool_sim/network/config.rs
1//! # Network Chaos Configuration
2//!
3//! This module provides configuration for network chaos testing, following
4//! FoundationDB's battle-tested simulation approach and TigerBeetle's deterministic
5//! testing patterns.
6//!
7//! ## Connection Failure Modes
8//!
9//! | Failure | Config Field | Default | Real-World Scenario |
10//! |---------|--------------|---------|---------------------|
11//! | Random close | `random_close_probability` | 0.001% | Reconnection logic, message redelivery, connection pooling |
12//! | Asymmetric close | `random_close_explicit_ratio` | 30% explicit | Half-closed sockets, FIN vs RST handling |
13//! | Connect failure | `connect_failure_mode` | Probabilistic | Connection establishment retries, timeout handling |
14//! | Connection cut | Manual via `cut_connection()` | N/A | Temporary network outages, transient failures |
15//!
16//! ## Network Latency & Congestion
17//!
18//! | Delay Type | Config Field | Default | Real-World Scenario |
19//! |------------|--------------|---------|---------------------|
20//! | Operation latency | `bind/accept/connect/read/write_latency` | Various ranges | Timeout settings, async operation ordering |
21//! | Latency distribution | `latency_distribution` | Uniform | Tail latency testing, P99 behavior |
22//! | Slow latency | `slow_latency_probability` | 0.1% | 99.9th percentile testing |
23//! | Write clogging | `clog_probability` + `clog_duration` | 0%, 100-300ms | Backpressure handling, flow control |
24//! | Read clogging | Same as write | Same | Symmetric flow control |
25//! | Clock drift | `clock_drift_enabled` + `clock_drift_max` | true, 100ms | Lease expiration, distributed consensus, TTL handling |
26//! | Buggified delay | `buggified_delay_enabled` + `buggified_delay_max` | true, 100ms | Race conditions, timing-dependent bugs |
27//! | Handshake delay | `handshake_delay_enabled` + `handshake_delay_max` | true, 10ms | TLS negotiation, connection startup overhead |
28//!
29//! ## Network Partitions
30//!
31//! | Partition Type | Config/Method | Default | Real-World Scenario |
32//! |----------------|---------------|---------|---------------------|
33//! | Random partition | `partition_probability` + `partition_duration` | 0%, 200ms-2s | Split-brain, quorum loss, leader election |
34//! | Bi-directional | `partition_pair()` | Manual | Complete isolation between nodes |
35//! | Send-only block | `partition_send_from()` | Manual | Asymmetric network failures |
36//! | Recv-only block | `partition_recv_to()` | Manual | Asymmetric network failures |
37//! | Partition strategy | `partition_strategy` | Random | Different failure patterns (uniform, isolate) |
38//!
39//! ## Data Integrity Faults
40//!
41//! | Fault | Config Field | Default | Real-World Scenario |
42//! |-------|--------------|---------|---------------------|
43//! | Bit flip | `bit_flip_probability` + `bit_flip_min/max_bits` | 0.01%, 1-32 bits | CRC/checksum validation, data corruption detection |
44//!
45//! ## Half-Open Connection Simulation
46//!
47//! | State | Method | Real-World Scenario |
48//! |-------|--------|---------------------|
49//! | Peer crash | `simulate_peer_crash()` | TCP keepalive, heartbeat detection, silent failures |
50//! | Half-open detection | `should_half_open_error()` | Timeout-based failure detection |
51//!
52//! ## Partial Write Simulation
53//!
54//! | Feature | Config Field | Default | Real-World Scenario |
55//! |---------|--------------|---------|---------------------|
56//! | Short writes | `partial_write_max_bytes` | 1000 bytes | TCP fragmentation handling, message framing |
57//!
58//! ## Stable Connections
59//!
60//! | Feature | Method | Real-World Scenario |
61//! |---------|--------|---------------------|
62//! | Mark stable | `mark_connection_stable()` | Exempt supervision from chaos, parent-child connections |
63//!
64//! ## Configuration Examples
65//!
66//! ### Fast Local Testing (No Chaos)
67//! ```rust
68//! use moonpool_sim::network::{NetworkConfiguration, ChaosConfiguration};
69//!
70//! let config = NetworkConfiguration::fast_local();
71//! // All chaos disabled, minimal latencies
72//! ```
73//!
74//! ### Full Chaos Testing
75//! ```rust
76//! use moonpool_sim::network::{NetworkConfiguration, ChaosConfiguration};
77//!
78//! let config = NetworkConfiguration::random_for_seed();
79//! // Randomized chaos parameters for comprehensive testing
80//! ```
81//!
82//! ### Custom Configuration
83//! ```rust
84//! use moonpool_sim::network::{NetworkConfiguration, ChaosConfiguration, LatencyDistribution, PartitionStrategy};
85//! use std::time::Duration;
86//!
87//! let mut config = NetworkConfiguration::default();
88//! config.chaos.latency_distribution = LatencyDistribution::Bimodal;
89//! config.chaos.partition_strategy = PartitionStrategy::IsolateSingle;
90//! config.chaos.partition_probability = 0.05; // 5%
91//! ```
92//!
93//! ## FDB/TigerBeetle References
94//!
95//! - Random close: FDB sim2.actor.cpp:580-605
96//! - Latency distribution: FDB sim2.actor.cpp:317-329 (`halfLatency()`)
97//! - Partitions: FDB SimClogging, TigerBeetle partition modes
98//! - Bit flips: FDB FlowTransport.actor.cpp:1297
99//! - Clock drift: FDB sim2.actor.cpp:1058-1064
100//! - Connect failures: FDB sim2.actor.cpp:1243-1250
101
102use crate::sim::rng::{sim_random_range, sim_random_range_or_default};
103use std::ops::Range;
104use std::time::Duration;
105
106/// Latency distribution mode for network operations.
107///
108/// Controls how latencies are sampled for network operations.
109/// FDB ref: sim2.actor.cpp:317-329 (`halfLatency()`)
110///
111/// # Real-World Scenario
112///
113/// Real networks exhibit bimodal latency patterns where most operations are fast,
114/// but a small percentage experience significantly higher latency (tail latency).
115/// This is crucial for testing:
116/// - P99/P99.9 latency handling
117/// - Timeout tuning
118/// - Retry logic under tail latency conditions
119#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
120pub enum LatencyDistribution {
121 /// Uniform distribution within the configured range.
122 /// All latencies equally likely within [min, max].
123 #[default]
124 Uniform,
125
126 /// Bimodal distribution matching FDB's halfLatency() pattern.
127 /// - 99.9% of operations: fast latency (within configured range)
128 /// - 0.1% of operations: slow latency (multiplied by `slow_latency_multiplier`)
129 ///
130 /// FDB ref: sim2.actor.cpp:317-329
131 Bimodal,
132}
133
134/// Network partition strategy for chaos testing.
135///
136/// Controls how nodes are selected for partitioning during chaos testing.
137/// TigerBeetle ref: packet_simulator.zig:12-488
138///
139/// # Real-World Scenario
140///
141/// Different partition strategies test different failure modes:
142/// - Random: General chaos, unpredictable failures
143/// - UniformSize: Tests various quorum sizes and split scenarios
144/// - IsolateSingle: Tests single-node isolation (common in production)
145#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
146pub enum PartitionStrategy {
147 /// Random IP pairs selected for partitioning.
148 /// Current behavior - randomly selects which connections to partition.
149 #[default]
150 Random,
151
152 /// Uniform size partitions - randomly choose partition size from 1 to n-1 nodes.
153 /// TigerBeetle pattern: creates partitions of varying sizes to test different
154 /// quorum scenarios.
155 UniformSize,
156
157 /// Isolate single node - always partition exactly one node from the rest.
158 /// Tests the common production scenario where a single node becomes unreachable.
159 IsolateSingle,
160}
161
162/// Connection establishment failure mode for fault injection.
163///
164/// Controls how connection attempts fail during chaos testing.
165/// FDB ref: sim2.actor.cpp:1243-1250 (SIM_CONNECT_ERROR_MODE)
166#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
167pub enum ConnectFailureMode {
168 /// Disabled - no connection failures injected
169 #[default]
170 Disabled,
171 /// Always fail with `ConnectionRefused` when buggified
172 AlwaysFail,
173 /// Probabilistic: 50% fail with `ConnectionRefused`, 50% hang forever
174 Probabilistic,
175}
176
177impl ConnectFailureMode {
178 /// Create a random failure mode for chaos testing
179 pub fn random_for_seed() -> Self {
180 match sim_random_range(0..3) {
181 0 => Self::Disabled,
182 1 => Self::AlwaysFail,
183 _ => Self::Probabilistic,
184 }
185 }
186}
187
188/// Configuration for chaos injection in simulations.
189///
190/// This struct contains all settings related to fault injection and chaos testing,
191/// following FoundationDB's BUGGIFY patterns for deterministic testing.
192#[derive(Debug, Clone)]
193pub struct ChaosConfiguration {
194 /// Clogging probability for individual writes (0.0 - 1.0)
195 pub clog_probability: f64,
196 /// Duration range for clog delays
197 pub clog_duration: Range<Duration>,
198
199 /// Network partition probability (0.0 - 1.0)
200 pub partition_probability: f64,
201 /// Duration range for network partitions
202 pub partition_duration: Range<Duration>,
203
204 /// Bit flip probability for packet corruption (0.0 - 1.0)
205 pub bit_flip_probability: f64,
206 /// Minimum number of bits to flip (power-law distribution lower bound)
207 pub bit_flip_min_bits: u32,
208 /// Maximum number of bits to flip (power-law distribution upper bound)
209 pub bit_flip_max_bits: u32,
210 /// Cooldown duration after bit flip to prevent excessive corruption
211 pub bit_flip_cooldown: Duration,
212
213 /// Maximum bytes for partial write simulation (BUGGIFY truncates writes to 0-max_bytes)
214 /// Following FDB's approach of truncating writes to test TCP backpressure handling
215 pub partial_write_max_bytes: usize,
216
217 /// Random connection close probability per I/O operation (0.0 - 1.0)
218 /// FDB default: 0.00001 (0.001%) - see sim2.actor.cpp:584
219 pub random_close_probability: f64,
220
221 /// Cooldown duration after a random close event (prevents cascading failures)
222 /// FDB uses connectionFailuresDisableDuration - see sim2.actor.cpp:583
223 pub random_close_cooldown: Duration,
224
225 /// Ratio of explicit exceptions vs silent failures (0.0 - 1.0)
226 /// FDB default: 0.3 (30% explicit) - see sim2.actor.cpp:602
227 pub random_close_explicit_ratio: f64,
228
229 /// Enable clock drift simulation
230 /// When enabled, timer() can return a time up to clock_drift_max ahead of now()
231 /// FDB ref: sim2.actor.cpp:1058-1064
232 pub clock_drift_enabled: bool,
233
234 /// Maximum clock drift (default 100ms per FDB)
235 /// timer() can be up to this much ahead of now()
236 pub clock_drift_max: Duration,
237
238 /// Enable buggified delays on sleep/timer operations
239 /// When enabled, 25% of sleep operations get extra delay
240 /// FDB ref: sim2.actor.cpp:1100-1105
241 pub buggified_delay_enabled: bool,
242
243 /// Maximum additional delay for buggified sleep (default 100ms)
244 /// Uses power-law distribution: max_delay * pow(random01(), 1000.0)
245 /// FDB ref: sim2.actor.cpp:1104
246 pub buggified_delay_max: Duration,
247
248 /// Probability of adding buggified delay (default 25% per FDB)
249 pub buggified_delay_probability: f64,
250
251 /// Connection establishment failure mode (per FDB)
252 /// FDB ref: sim2.actor.cpp:1243-1250 (SIM_CONNECT_ERROR_MODE)
253 pub connect_failure_mode: ConnectFailureMode,
254
255 /// Probability of connect failure when Probabilistic mode is enabled (default 50%)
256 pub connect_failure_probability: f64,
257
258 /// Latency distribution mode for network operations.
259 ///
260 /// Controls whether latencies follow a uniform or bimodal distribution.
261 /// FDB ref: sim2.actor.cpp:317-329 (`halfLatency()`)
262 ///
263 /// # Real-World Scenario
264 /// Bimodal latency tests tail latency handling (P99/P99.9).
265 pub latency_distribution: LatencyDistribution,
266
267 /// Probability of a slow latency sample when using bimodal distribution (0.0 - 1.0).
268 /// FDB default: 0.001 (0.1%) - see sim2.actor.cpp:319
269 ///
270 /// # Real-World Scenario
271 /// Tests handling of 99.9th percentile latencies.
272 pub slow_latency_probability: f64,
273
274 /// Multiplier for slow latencies in bimodal distribution.
275 /// FDB: slow latency is up to 10x normal latency
276 ///
277 /// # Real-World Scenario
278 /// Simulates network congestion, GC pauses, or cross-datacenter hops.
279 pub slow_latency_multiplier: f64,
280
281 /// Enable handshake delay simulation on new connections.
282 /// FDB ref: connectHandshake():389 adds `delay(0.01 * random01())`
283 ///
284 /// # Real-World Scenario
285 /// Simulates TLS negotiation, connection establishment overhead.
286 pub handshake_delay_enabled: bool,
287
288 /// Maximum handshake delay (default 10ms per FDB).
289 /// Applied once when a connection is established.
290 ///
291 /// # Real-World Scenario
292 /// Tests connection pool warm-up, startup latency.
293 pub handshake_delay_max: Duration,
294
295 /// Network partition strategy.
296 /// Controls how nodes are selected for partitioning.
297 /// TigerBeetle ref: packet_simulator.zig partition modes
298 ///
299 /// # Real-World Scenario
300 /// Different strategies test different failure scenarios:
301 /// - Random: unpredictable chaos
302 /// - UniformSize: various quorum sizes
303 /// - IsolateSingle: single node isolation (common in production)
304 pub partition_strategy: PartitionStrategy,
305}
306
307impl Default for ChaosConfiguration {
308 fn default() -> Self {
309 Self {
310 clog_probability: 0.0,
311 clog_duration: Duration::from_millis(100)..Duration::from_millis(300),
312 partition_probability: 0.0,
313 partition_duration: Duration::from_millis(200)..Duration::from_secs(2),
314 bit_flip_probability: 0.0001, // 0.01% - matches FDB's BUGGIFY_WITH_PROB(0.0001)
315 bit_flip_min_bits: 1,
316 bit_flip_max_bits: 32,
317 bit_flip_cooldown: Duration::ZERO, // No cooldown by default for maximum chaos
318 partial_write_max_bytes: 1000, // Matches FDB's randomInt(0, 1000)
319 random_close_probability: 0.00001, // 0.001% - matches FDB's sim2.actor.cpp:584
320 random_close_cooldown: Duration::from_secs(5), // Reasonable default
321 random_close_explicit_ratio: 0.3, // 30% explicit - matches FDB's sim2.actor.cpp:602
322 clock_drift_enabled: true, // Enable by default for chaos testing
323 clock_drift_max: Duration::from_millis(100), // FDB default: 0.1 seconds
324 buggified_delay_enabled: true, // Enable by default for chaos testing
325 buggified_delay_max: Duration::from_millis(100), // FDB: MAX_BUGGIFIED_DELAY
326 buggified_delay_probability: 0.25, // FDB: random01() < 0.25
327 connect_failure_mode: ConnectFailureMode::Probabilistic, // FDB: SIM_CONNECT_ERROR_MODE = 2
328 connect_failure_probability: 0.5, // FDB: random01() > 0.5
329 latency_distribution: LatencyDistribution::default(),
330 slow_latency_probability: 0.001, // 0.1% per FDB halfLatency()
331 slow_latency_multiplier: 10.0, // 10x normal latency
332 handshake_delay_enabled: true,
333 handshake_delay_max: Duration::from_millis(10), // FDB: 0.01 * random01()
334 partition_strategy: PartitionStrategy::default(),
335 }
336 }
337}
338
339impl ChaosConfiguration {
340 /// Create a configuration with all chaos disabled (for fast local testing)
341 pub fn disabled() -> Self {
342 Self {
343 clog_probability: 0.0,
344 clog_duration: Duration::ZERO..Duration::ZERO,
345 partition_probability: 0.0,
346 partition_duration: Duration::ZERO..Duration::ZERO,
347 bit_flip_probability: 0.0,
348 bit_flip_min_bits: 1,
349 bit_flip_max_bits: 32,
350 bit_flip_cooldown: Duration::ZERO,
351 partial_write_max_bytes: 1000,
352 random_close_probability: 0.0,
353 random_close_cooldown: Duration::ZERO,
354 random_close_explicit_ratio: 0.3,
355 clock_drift_enabled: false,
356 clock_drift_max: Duration::from_millis(100),
357 buggified_delay_enabled: false,
358 buggified_delay_max: Duration::from_millis(100),
359 buggified_delay_probability: 0.25,
360 connect_failure_mode: ConnectFailureMode::Disabled,
361 connect_failure_probability: 0.5,
362 latency_distribution: LatencyDistribution::Uniform, // No bimodal for fast testing
363 slow_latency_probability: 0.0, // No slow latencies
364 slow_latency_multiplier: 1.0, // No multiplier
365 handshake_delay_enabled: false, // No handshake delays
366 handshake_delay_max: Duration::ZERO,
367 partition_strategy: PartitionStrategy::Random, // Default strategy
368 }
369 }
370
371 /// Create a randomized chaos configuration for seed-based testing
372 pub fn random_for_seed() -> Self {
373 Self {
374 clog_probability: sim_random_range(0..20) as f64 / 100.0, // 0-20% for clogging
375 clog_duration: Duration::from_micros(sim_random_range(50000..300000))
376 ..Duration::from_micros(sim_random_range(100000..500000)),
377 partition_probability: sim_random_range(0..15) as f64 / 100.0, // 0-15% (lower than faults)
378 partition_duration: Duration::from_millis(sim_random_range(100..1000))
379 ..Duration::from_millis(sim_random_range(500..3000)),
380 // Bit flip probability range: 0.001% to 0.02% (very low, like FDB)
381 bit_flip_probability: sim_random_range(1..20) as f64 / 100000.0,
382 bit_flip_min_bits: 1,
383 bit_flip_max_bits: 32,
384 bit_flip_cooldown: Duration::from_millis(sim_random_range(0..100)),
385 partial_write_max_bytes: sim_random_range(100..2000), // Vary max bytes for different scenarios
386 // Random close probability: 0.0001% to 0.01% (very low, like FDB)
387 random_close_probability: sim_random_range(1..100) as f64 / 1000000.0,
388 random_close_cooldown: Duration::from_millis(sim_random_range(1000..10000)),
389 random_close_explicit_ratio: sim_random_range(20..40) as f64 / 100.0, // 20-40%
390 clock_drift_enabled: true,
391 clock_drift_max: Duration::from_millis(sim_random_range(50..150)), // 50-150ms
392 buggified_delay_enabled: true,
393 buggified_delay_max: Duration::from_millis(sim_random_range(50..150)), // 50-150ms
394 buggified_delay_probability: sim_random_range(20..30) as f64 / 100.0, // 20-30%
395 connect_failure_mode: ConnectFailureMode::random_for_seed(),
396 connect_failure_probability: sim_random_range(40..60) as f64 / 100.0, // 40-60%
397 // Randomly choose latency distribution (50% uniform, 50% bimodal)
398 latency_distribution: if sim_random_range(0..2) == 0 {
399 LatencyDistribution::Uniform
400 } else {
401 LatencyDistribution::Bimodal
402 },
403 slow_latency_probability: sim_random_range(1..5) as f64 / 1000.0, // 0.1% to 0.5%
404 slow_latency_multiplier: sim_random_range(5..20) as f64, // 5x to 20x
405 handshake_delay_enabled: true,
406 handshake_delay_max: Duration::from_millis(sim_random_range(5..20)), // 5-20ms
407 // Randomly choose partition strategy
408 partition_strategy: match sim_random_range(0..3) {
409 0 => PartitionStrategy::Random,
410 1 => PartitionStrategy::UniformSize,
411 _ => PartitionStrategy::IsolateSingle,
412 },
413 }
414 }
415}
416
417/// Configuration for network simulation parameters
418#[derive(Debug, Clone)]
419pub struct NetworkConfiguration {
420 /// Latency range for bind operations
421 pub bind_latency: Range<Duration>,
422 /// Latency range for accept operations
423 pub accept_latency: Range<Duration>,
424 /// Latency range for connect operations
425 pub connect_latency: Range<Duration>,
426 /// Latency range for read operations
427 pub read_latency: Range<Duration>,
428 /// Latency range for write operations
429 pub write_latency: Range<Duration>,
430
431 /// Chaos injection configuration
432 pub chaos: ChaosConfiguration,
433}
434
435impl Default for NetworkConfiguration {
436 fn default() -> Self {
437 Self {
438 bind_latency: Duration::from_micros(50)..Duration::from_micros(150),
439 accept_latency: Duration::from_millis(1)..Duration::from_millis(6),
440 connect_latency: Duration::from_millis(1)..Duration::from_millis(11),
441 read_latency: Duration::from_micros(10)..Duration::from_micros(60),
442 write_latency: Duration::from_micros(100)..Duration::from_micros(600),
443 chaos: ChaosConfiguration::default(),
444 }
445 }
446}
447
448/// Sample a random duration from a range
449pub fn sample_duration(range: &Range<Duration>) -> Duration {
450 let start_nanos = range.start.as_nanos() as u64;
451 let end_nanos = range.end.as_nanos() as u64;
452 let random_nanos = sim_random_range_or_default(start_nanos..end_nanos);
453 Duration::from_nanos(random_nanos)
454}
455
456/// Sample a random duration with bimodal distribution support.
457///
458/// FDB ref: sim2.actor.cpp:317-329 (`halfLatency()`)
459///
460/// When `distribution` is `Bimodal`:
461/// - 99.9% of samples use normal latency (within `range`)
462/// - 0.1% of samples use slow latency (multiplied by `slow_multiplier`)
463///
464/// # Parameters
465/// - `range`: The base latency range
466/// - `chaos`: Chaos configuration with distribution settings
467///
468/// # Real-World Scenario
469/// Bimodal latency tests tail latency handling:
470/// - Most requests complete quickly
471/// - Rare requests experience significant delays (P99.9)
472pub fn sample_duration_bimodal(range: &Range<Duration>, chaos: &ChaosConfiguration) -> Duration {
473 use crate::sim::rng::sim_random;
474
475 let base_duration = sample_duration(range);
476
477 match chaos.latency_distribution {
478 LatencyDistribution::Uniform => base_duration,
479 LatencyDistribution::Bimodal => {
480 // FDB pattern: 99.9% fast, 0.1% slow
481 if sim_random::<f64>() < chaos.slow_latency_probability {
482 // Slow path: multiply by slow_latency_multiplier
483 let slow_nanos =
484 (base_duration.as_nanos() as f64 * chaos.slow_latency_multiplier) as u64;
485 tracing::trace!(
486 "Bimodal slow latency: {:?} -> {:?}",
487 base_duration,
488 Duration::from_nanos(slow_nanos)
489 );
490 Duration::from_nanos(slow_nanos)
491 } else {
492 base_duration
493 }
494 }
495 }
496}
497
498/// Sample a handshake delay based on chaos configuration.
499///
500/// FDB ref: connectHandshake():389 adds `delay(0.01 * random01())`
501///
502/// Returns `Duration::ZERO` if handshake delays are disabled.
503pub fn sample_handshake_delay(chaos: &ChaosConfiguration) -> Duration {
504 use crate::sim::rng::sim_random;
505
506 if !chaos.handshake_delay_enabled || chaos.handshake_delay_max == Duration::ZERO {
507 return Duration::ZERO;
508 }
509
510 // FDB pattern: 0.01 * random01() = up to 10ms
511 let random_factor = sim_random::<f64>();
512 Duration::from_nanos((chaos.handshake_delay_max.as_nanos() as f64 * random_factor) as u64)
513}
514
515impl NetworkConfiguration {
516 /// Create a new network configuration with default settings
517 pub fn new() -> Self {
518 Self::default()
519 }
520
521 /// Create a randomized network configuration for chaos testing
522 pub fn random_for_seed() -> Self {
523 Self {
524 bind_latency: Duration::from_micros(sim_random_range(10..200))
525 ..Duration::from_micros(sim_random_range(50..300)),
526 accept_latency: Duration::from_micros(sim_random_range(1000..10000))
527 ..Duration::from_micros(sim_random_range(5000..15000)),
528 connect_latency: Duration::from_micros(sim_random_range(1000..50000))
529 ..Duration::from_micros(sim_random_range(10000..100000)),
530 read_latency: Duration::from_micros(sim_random_range(5..100))
531 ..Duration::from_micros(sim_random_range(50..200)),
532 write_latency: Duration::from_micros(sim_random_range(50..1000))
533 ..Duration::from_micros(sim_random_range(200..2000)),
534 chaos: ChaosConfiguration::random_for_seed(),
535 }
536 }
537
538 /// Create a configuration optimized for fast local testing
539 pub fn fast_local() -> Self {
540 let one_us = Duration::from_micros(1);
541 let ten_us = Duration::from_micros(10);
542 Self {
543 bind_latency: one_us..one_us,
544 accept_latency: ten_us..ten_us,
545 connect_latency: ten_us..ten_us,
546 read_latency: one_us..one_us,
547 write_latency: one_us..one_us,
548 chaos: ChaosConfiguration::disabled(),
549 }
550 }
551}