Monorepo for Tangled tangled.org
11

Configure Feed

Select the types of activity you want to include in your feed.

at master 8.8 kB View raw
1use std::num::NonZeroUsize; 2use std::time::Duration; 3 4use bobbin_sim::workloads::{ 5 CancelMidHydration, CancelMidHydrationConfig, ColdStartUnderLiveLoad, 6 ColdStartUnderLiveLoadConfig, ConcurrentReadsDuringReplay, ConcurrentReadsDuringReplayConfig, 7 FrameBurst, HydrantDisconnectBarrage, HydrantDisconnectBarrageConfig, SlingshotFlap, 8 SlingshotFlapConfig, 9}; 10use bobbin_sim::{LeakOutcome, LeakRunConfig, Workload, run_leak_check}; 11 12const PARALLELISM_SWEEP: &[usize] = &[1, 4, 16, 64]; 13const SEEDS: &[u64] = &[1, 7, 42, 1337]; 14 15#[test] 16fn frame_burst_is_byte_deterministic_across_parallelism_sweep() { 17 for &par in PARALLELISM_SWEEP { 18 for &seed in SEEDS { 19 let parallelism = NonZeroUsize::new(par).unwrap(); 20 let config = LeakRunConfig { 21 seed, 22 parallelism, 23 max_virtual_runtime: Duration::from_secs(30), 24 mem_ws_capacity: 4096, 25 warming_buffer_enabled: true, 26 }; 27 let factory = || -> Box<dyn Workload> { Box::new(FrameBurst::new(64)) }; 28 let result = run_leak_check(config.clone(), factory); 29 assert!( 30 result.passed(), 31 "frame-burst leak at par={par} seed={seed}: {:?}", 32 result.outcome, 33 ); 34 match &result.outcome { 35 LeakOutcome::Match => {} 36 other => panic!("non-match outcome despite passed(): {other:?}"), 37 } 38 assert_eq!( 39 result.first_report.events_processed, 64, 40 "frame-burst should process all 64 frames at par={par} seed={seed}", 41 ); 42 } 43 } 44} 45 46#[test] 47fn cancel_mid_hydration_is_byte_deterministic() { 48 for &par in PARALLELISM_SWEEP { 49 for &seed in SEEDS { 50 let parallelism = NonZeroUsize::new(par).unwrap(); 51 let config = LeakRunConfig { 52 seed, 53 parallelism, 54 max_virtual_runtime: Duration::from_secs(60), 55 mem_ws_capacity: 4096, 56 warming_buffer_enabled: true, 57 }; 58 let factory = || -> Box<dyn Workload> { 59 Box::new(CancelMidHydration::new(CancelMidHydrationConfig { 60 frames: 200, 61 cancel_at_events: 50, 62 slingshot_latency_ms: 50, 63 frame_pace_us: 100, 64 })) 65 }; 66 let result = run_leak_check(config.clone(), factory); 67 assert!( 68 result.passed(), 69 "cancel-mid-hydration leak at par={par} seed={seed}: {:?}", 70 result.outcome, 71 ); 72 match &result.outcome { 73 LeakOutcome::Match => {} 74 other => panic!("non-match outcome despite passed(): {other:?}"), 75 } 76 } 77 } 78} 79 80#[test] 81fn hydrant_disconnect_barrage_is_byte_deterministic() { 82 for &par in PARALLELISM_SWEEP { 83 for &seed in SEEDS { 84 let parallelism = NonZeroUsize::new(par).unwrap(); 85 let config = LeakRunConfig { 86 seed, 87 parallelism, 88 max_virtual_runtime: Duration::from_secs(60), 89 mem_ws_capacity: 4096, 90 warming_buffer_enabled: true, 91 }; 92 let factory = || -> Box<dyn Workload> { 93 Box::new(HydrantDisconnectBarrage::new( 94 HydrantDisconnectBarrageConfig { 95 frames: 256, 96 disconnect_after_frames_per_session: vec![50, 80, 60], 97 }, 98 )) 99 }; 100 let result = run_leak_check(config.clone(), factory); 101 assert!( 102 result.passed(), 103 "hydrant-disconnect-barrage leak at par={par} seed={seed}: {:?}", 104 result.outcome, 105 ); 106 assert_eq!( 107 result.first_report.events_processed, 256, 108 "expected all 256 frames processed", 109 ); 110 } 111 } 112} 113 114#[test] 115fn cold_start_under_live_load_is_byte_deterministic() { 116 for &par in PARALLELISM_SWEEP { 117 for &seed in SEEDS { 118 let parallelism = NonZeroUsize::new(par).unwrap(); 119 let config = LeakRunConfig { 120 seed, 121 parallelism, 122 max_virtual_runtime: Duration::from_secs(60), 123 mem_ws_capacity: 4096, 124 warming_buffer_enabled: true, 125 }; 126 let factory = || -> Box<dyn Workload> { 127 Box::new(ColdStartUnderLiveLoad::new(ColdStartUnderLiveLoadConfig { 128 replay_frames: 200, 129 live_frames: 50, 130 live_pace_us: 1_000, 131 replay_pace_us: 0, 132 })) 133 }; 134 let result = run_leak_check(config.clone(), factory); 135 assert!( 136 result.passed(), 137 "cold-start-under-live-load leak at par={par} seed={seed}: {:?}", 138 result.outcome, 139 ); 140 assert_eq!( 141 result.first_report.events_processed, 250, 142 "expected 250 (replay+live) frames", 143 ); 144 assert_eq!( 145 result.first_report.edge_count, 250, 146 "diversified owners should yield 250 distinct edge keys", 147 ); 148 } 149 } 150} 151 152#[test] 153fn concurrent_reads_during_replay_is_byte_deterministic() { 154 for &par in PARALLELISM_SWEEP { 155 for &seed in SEEDS { 156 let parallelism = NonZeroUsize::new(par).unwrap(); 157 let config = LeakRunConfig { 158 seed, 159 parallelism, 160 max_virtual_runtime: Duration::from_secs(60), 161 mem_ws_capacity: 4096, 162 warming_buffer_enabled: true, 163 }; 164 let factory = || -> Box<dyn Workload> { 165 Box::new(ConcurrentReadsDuringReplay::new( 166 ConcurrentReadsDuringReplayConfig { 167 follow_frames: 200, 168 frame_pace_us: 100, 169 read_pace_us: 1_000, 170 }, 171 )) 172 }; 173 let result = run_leak_check(config.clone(), factory); 174 assert!( 175 result.passed(), 176 "concurrent-reads-during-replay leak at par={par} seed={seed}: {:?}", 177 result.outcome, 178 ); 179 assert_eq!( 180 result.first_report.events_processed, 200, 181 "expected 200 follow frames processed", 182 ); 183 } 184 } 185} 186 187#[test] 188fn slingshot_flap_short_brownout_is_byte_deterministic() { 189 for &par in &[4usize, 16, 64] { 190 for &seed in &[7u64, 99] { 191 let parallelism = NonZeroUsize::new(par).unwrap(); 192 let config = LeakRunConfig { 193 seed, 194 parallelism, 195 max_virtual_runtime: Duration::from_secs(30), 196 mem_ws_capacity: 4096, 197 warming_buffer_enabled: true, 198 }; 199 let factory = || -> Box<dyn Workload> { 200 Box::new(SlingshotFlap::new(SlingshotFlapConfig { 201 cross_did_stars: 50, 202 normal_latency_ms: 2, 203 brownout_start_ms: 0, 204 brownout_duration_ms: 100, 205 brownout_latency_ms: 50, 206 brownout_enabled: true, 207 hydrant_send_timeout_ms: 30_000, 208 hydrant_frame_pace_us: 0, 209 omit_target_repos: false, 210 emit_live_promotion_frame: false, 211 })) 212 }; 213 let result = run_leak_check(config.clone(), factory); 214 assert!( 215 result.passed(), 216 "slingshot-flap leak at par={par} seed={seed}: {:?}", 217 result.outcome, 218 ); 219 assert_eq!( 220 result.first_report.events_processed, 100, 221 "expected 100 (50 stars + 50 repos) frames processed", 222 ); 223 assert!( 224 result.first_report.warming_buffer.enqueued_total > 0, 225 "expected the buffer path to exercise during warming at par={par} seed={seed}, got snapshot={:?}", 226 result.first_report.warming_buffer, 227 ); 228 assert_eq!( 229 result.first_report.warming_buffer.enqueued_total, 230 result.first_report.warming_buffer.drained_observe_total, 231 "every parked star must drain via observe at par={par} seed={seed}, got snapshot={:?}", 232 result.first_report.warming_buffer, 233 ); 234 } 235 } 236}