1+ #! /usr/bin/env bash
2+ # 
3+ #  Continuous stress test: Run batches of 10 concurrent s3client_test.sh instances
4+ #  for 5 minutes, restarting immediately when batches complete
5+ # 
6+ set  -euo pipefail
7+ 
8+ BUILD_DIR=" /Users/stack/build_output" 
9+ CONCURRENT_INSTANCES=10
10+ TEST_DURATION_MINUTES=5
11+ TEST_DURATION_SECONDS=$(( TEST_DURATION_MINUTES *  60 )) 
12+ 
13+ #  Statistics tracking
14+ TOTAL_BATCHES=0
15+ TOTAL_INSTANCES=0
16+ TOTAL_SUCCESSFUL=0
17+ TOTAL_FAILED=0
18+ TOTAL_PORT_CONFLICTS=0
19+ START_TIME=$( date +%s) 
20+ END_TIME=$(( START_TIME +  TEST_DURATION_SECONDS)) 
21+ 
22+ echo  " $( date -Iseconds)   Starting continuous stress test for $TEST_DURATION_MINUTES  minutes" 
23+ echo  " $( date -Iseconds)   Each batch: $CONCURRENT_INSTANCES  concurrent instances" 
24+ echo  " $( date -Iseconds)   Will run until: $( date -Iseconds -r $END_TIME ) " 
25+ 
26+ #  Function to run a single batch of concurrent tests
27+ run_batch () {
28+     local  batch_num=" $1 " 
29+     local  batch_start_time=$( date +%s) 
30+     
31+     echo  " $( date -Iseconds)   ===== BATCH $batch_num : Starting $CONCURRENT_INSTANCES  concurrent instances =====" 
32+     
33+     #  Array to track PIDs for this batch
34+     local  PIDS=()
35+     local  batch_successful=0
36+     local  batch_failed=0
37+     local  batch_port_conflicts=0
38+     
39+     #  Start concurrent instances
40+     for  i  in  $( seq 1 $CONCURRENT_INSTANCES ) ;  do 
41+         local  instance_id=" ${batch_num} _${i} " 
42+         SCRATCH_DIR=$( mktemp -d " /tmp/stress_${instance_id} .XXXXXX" ) 
43+         
44+         #  Run s3client_test.sh in background
45+         (
46+             cd  fdbclient/tests
47+             if  ./s3client_test.sh " $BUILD_DIR "   " $SCRATCH_DIR "   >  " /tmp/stress_${instance_id} .log"   2>&1 ;  then 
48+                 echo  " $( date -Iseconds)   Instance ${instance_id}  SUCCESS" 
49+             else 
50+                 echo  " $( date -Iseconds)   Instance ${instance_id}  FAILED" 
51+             fi 
52+         ) & 
53+         
54+         PIDS+=($! )
55+         
56+         #  Very brief stagger to increase port conflicts
57+         sleep 0.1
58+     done 
59+     
60+     echo  " $( date -Iseconds)   Batch $batch_num : All instances started, waiting for completion..." 
61+     
62+     #  Wait for all instances in this batch
63+     for  i  in  " ${! PIDS[@]} " ;  do 
64+         local  pid=${PIDS[$i]} 
65+         local  instance_id=" ${batch_num} _$(( i+ 1 )) " 
66+         
67+         if  wait  " $pid " ;  then 
68+             (( batch_successful++ )) 
69+             echo  " $( date -Iseconds)   Instance ${instance_id}  (PID $pid ) completed successfully" 
70+         else 
71+             (( batch_failed++ )) 
72+             echo  " $( date -Iseconds)   Instance ${instance_id}  (PID $pid ) FAILED" 
73+         fi 
74+     done 
75+     
76+     #  Check for port conflicts in this batch
77+     for  i  in  $( seq 1 $CONCURRENT_INSTANCES ) ;  do 
78+         local  instance_id=" ${batch_num} _${i} " 
79+         if  [[ -f  " /tmp/stress_${instance_id} .log"   ]] &&  grep -q " Port.*already in use\|trying next port"   " /tmp/stress_${instance_id} .log" ;  then 
80+             (( batch_port_conflicts++ )) 
81+         fi 
82+     done 
83+     
84+     local  batch_end_time=$( date +%s) 
85+     local  batch_duration=$(( batch_end_time -  batch_start_time)) 
86+     
87+     #  Update global statistics
88+     (( TOTAL_BATCHES++ )) 
89+     TOTAL_INSTANCES=$(( TOTAL_INSTANCES +  CONCURRENT_INSTANCES)) 
90+     TOTAL_SUCCESSFUL=$(( TOTAL_SUCCESSFUL +  batch_successful)) 
91+     TOTAL_FAILED=$(( TOTAL_FAILED +  batch_failed)) 
92+     TOTAL_PORT_CONFLICTS=$(( TOTAL_PORT_CONFLICTS +  batch_port_conflicts)) 
93+     
94+     echo  " $( date -Iseconds)   Batch $batch_num  completed in ${batch_duration} s: ${batch_successful} /${CONCURRENT_INSTANCES}  successful, $batch_port_conflicts  port conflicts" 
95+     
96+     #  Check for orphaned processes
97+     local  orphaned_count=0
98+     if  pgrep -f " mocks3server\|MockS3Server"   > /dev/null 2>&1 ;  then 
99+         orphaned_count=$( pgrep -f " mocks3server\|MockS3Server"   |  wc -l) 
100+         echo  " $( date -Iseconds)   WARNING: $orphaned_count  orphaned MockS3Server processes detected!" 
101+         #  Kill orphaned processes
102+         pkill -f " mocks3server\|MockS3Server"   2> /dev/null ||  true 
103+     fi 
104+     
105+     #  Print running statistics
106+     local  current_time=$( date +%s) 
107+     local  elapsed_time=$(( current_time -  START_TIME)) 
108+     local  remaining_time=$(( END_TIME -  current_time)) 
109+     
110+     echo  " $( date -Iseconds)   === RUNNING STATS (${elapsed_time} s elapsed, ${remaining_time} s remaining) ===" 
111+     echo  "   Batches: $TOTAL_BATCHES " 
112+     echo  "   Total instances: $TOTAL_INSTANCES " 
113+     echo  "   Successful: $TOTAL_SUCCESSFUL  ($(( TOTAL_SUCCESSFUL *  100  /  TOTAL_INSTANCES))  %)" 
114+     echo  "   Failed: $TOTAL_FAILED " 
115+     echo  "   Port conflicts: $TOTAL_PORT_CONFLICTS " 
116+     echo  "   Success rate: $(( TOTAL_SUCCESSFUL *  100  /  TOTAL_INSTANCES))  %" 
117+     echo  " " 
118+ }
119+ 
120+ #  Main stress test loop
121+ batch_counter=1
122+ while  [[ $( date +%s)   -lt  $END_TIME  ]];  do 
123+     #  Check if we have enough time for another batch (estimate 30 seconds per batch)
124+     current_time=$( date +%s) 
125+     remaining_time=$(( END_TIME -  current_time)) 
126+     
127+     if  [[ $remaining_time  -lt  30 ]];  then 
128+         echo  " $( date -Iseconds)   Less than 30 seconds remaining, ending stress test" 
129+         break 
130+     fi 
131+     
132+     run_batch " $batch_counter " 
133+     (( batch_counter++ )) 
134+     
135+     #  Brief pause between batches to avoid overwhelming the system
136+     sleep 2
137+ done 
138+ 
139+ #  Final statistics
140+ echo  " $( date -Iseconds)   ===== FINAL STRESS TEST RESULTS =====" 
141+ echo  " Test duration: $TEST_DURATION_MINUTES  minutes" 
142+ echo  " Total batches completed: $TOTAL_BATCHES " 
143+ echo  " Total instances run: $TOTAL_INSTANCES " 
144+ echo  " Total successful: $TOTAL_SUCCESSFUL " 
145+ echo  " Total failed: $TOTAL_FAILED " 
146+ echo  " Total port conflicts detected: $TOTAL_PORT_CONFLICTS " 
147+ echo  " Overall success rate: $(( TOTAL_SUCCESSFUL *  100  /  TOTAL_INSTANCES))  %" 
148+ echo  " Average instances per batch: $(( TOTAL_INSTANCES /  TOTAL_BATCHES)) " 
149+ echo  " Port conflicts per batch: $(( TOTAL_PORT_CONFLICTS /  TOTAL_BATCHES)) " 
150+ 
151+ #  Final cleanup check
152+ if  pgrep -f " mocks3server\|MockS3Server"   > /dev/null 2>&1 ;  then 
153+     orphaned_count=$( pgrep -f " mocks3server\|MockS3Server"   |  wc -l) 
154+     echo  " WARNING: $orphaned_count  orphaned processes remain" 
155+     pkill -f " mocks3server\|MockS3Server"   2> /dev/null ||  true 
156+ else 
157+     echo  " ✅ Perfect cleanup - no orphaned processes" 
158+ fi 
159+ 
160+ echo  " $( date -Iseconds)   Continuous stress test completed!" 
161+ 
162+ #  Provide summary of what logs to check
163+ echo  " " 
164+ echo  " Log files created: /tmp/stress_*.log" 
165+ echo  " To check individual results: grep 'PASSED\\ |FAILED' /tmp/stress_*.log" 
166+ echo  " To check port conflicts: grep 'Port.*already in use' /tmp/stress_*.log" 
0 commit comments