2020
2121const char help [] =
2222 "Usage:\n"
23- " stresstest [-2] [-c] [-g] [-n ] [-r rate]\n"
23+ " stresstest [-2] [-c] [-g] [-m] [-n] [-R ] [-r rate]\n"
2424 " stresstest -h\n"
2525 "\n"
2626 " -h print this help message and exit\n"
2727 " -2 output two waves\n"
2828 " -c randomly chunk the output\n"
2929 " -g occasionally output garbage\n"
30+ " -m output realistic metrics (CPU/bandwidth-like, random spikes)\n"
3031 " -n output negative values\n"
32+ " -R output uniformly random values across the full range\n"
3133 " -r rate sample rate in samples/s (default: 100)\n"
3234 " -s seed set random seed\n" ;
3335
34- const char optstring [] = "h2cgnr:s:" ;
36+ const char optstring [] = "h2cgmnRr:s:" ;
37+
38+ // Return a uniformly random value in [lo, hi].
39+ static double rand_range (double lo , double hi ) {
40+ return lo + ((double )rand () / RAND_MAX ) * (hi - lo );
41+ }
42+
43+ // Generate one realistic metrics sample. Models a mean-reverting baseline
44+ // (Ornstein-Uhlenbeck-style random walk) with occasional sharp spikes that
45+ // rise instantly and decay exponentially -- resembling CPU/bandwidth load.
46+ // State is carried in *level and *spike so multiple series stay independent.
47+ static double metric_sample (double * level , double * spike ) {
48+ const double target = 20.0 ; // baseline the walk reverts toward
49+ const double theta = 0.02 ; // reversion strength
50+ const double sigma = 1.5 ; // baseline jitter amplitude
51+ const double decay = 0.85 ; // spike decay per sample (~6 samples to 1/e)
52+
53+ double noise = ((double )rand () / RAND_MAX ) * 2.0 - 1.0 ; // -1..1
54+ * level += theta * (target - * level ) + sigma * noise ;
55+ * spike *= decay ;
56+ if (rand () < RAND_MAX / 100 ) // ~1% chance of a new spike
57+ * spike += 30.0 + (rand () % 50 ); // magnitude 30..79
58+ double value = * level + * spike ;
59+ return value < 0 ? 0 : value ; // load is never negative
60+ }
3561
3662int main (int argc , char * argv []) {
3763 char buffer [1024 ];
@@ -40,6 +66,8 @@ int main(int argc, char *argv[]) {
4066 bool two_waves = false;
4167 bool chunked = false;
4268 bool add_garbage = false;
69+ bool metrics = false;
70+ bool super_random = false;
4371 bool output_negative = false;
4472 double rate = 100 ;
4573 unsigned int seed = time (NULL );
@@ -59,9 +87,15 @@ int main(int argc, char *argv[]) {
5987 case 'g' :
6088 add_garbage = true;
6189 break ;
90+ case 'm' :
91+ metrics = true;
92+ break ;
6293 case 'n' :
6394 output_negative = true;
6495 break ;
96+ case 'R' :
97+ super_random = true;
98+ break ;
6599 case 'r' :
66100 rate = atof (optarg );
67101 break ;
@@ -81,15 +115,31 @@ int main(int argc, char *argv[]) {
81115 const useconds_t delay = 1e6 / rate ;
82116 srand (seed );
83117
118+ double level1 = 20.0 , spike1 = 0.0 ; // metrics state, series 1
119+ double level2 = 20.0 , spike2 = 0.0 ; // metrics state, series 2
120+ const double rmin = output_negative ? -100.0 : 0.0 ; // -R range
121+ const double rmax = 100.0 ;
122+
84123 for (unsigned int n = 0 ;; n += 5 ) {
85- buffer_pos += sprintf (buffer + buffer_pos , "%.1f\n" ,
86- (sin (n * M_PI / 180 ) * 5 ) + (output_negative ? 0 : 5 ));
124+ double wave1 ;
125+ if (metrics )
126+ wave1 = metric_sample (& level1 , & spike1 );
127+ else if (super_random )
128+ wave1 = rand_range (rmin , rmax );
129+ else
130+ wave1 = (sin (n * M_PI / 180 ) * 5 ) + (output_negative ? 0 : 5 );
131+ buffer_pos += sprintf (buffer + buffer_pos , "%.1f\n" , wave1 );
87132 if (add_garbage && rand () <= RAND_MAX / 5 )
88133 buffer_pos += sprintf (buffer + buffer_pos , "garbage " );
89134 if (two_waves ) {
90- buffer_pos +=
91- sprintf (buffer + buffer_pos , "%.1f\n" ,
92- (cos (n * M_PI / 180 ) * 5 ) + (output_negative ? 0 : 5 ));
135+ double wave2 ;
136+ if (metrics )
137+ wave2 = metric_sample (& level2 , & spike2 );
138+ else if (super_random )
139+ wave2 = rand_range (rmin , rmax );
140+ else
141+ wave2 = (cos (n * M_PI / 180 ) * 5 ) + (output_negative ? 0 : 5 );
142+ buffer_pos += sprintf (buffer + buffer_pos , "%.1f\n" , wave2 );
93143 if (add_garbage && rand () <= RAND_MAX / 5 )
94144 buffer_pos += sprintf (buffer + buffer_pos , "garbage " );
95145 }
0 commit comments