Skip to content

Commit e113b9e

Browse files
committed
add more modes to stresstest
1 parent 6951457 commit e113b9e

1 file changed

Lines changed: 57 additions & 7 deletions

File tree

stresstest.c

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,44 @@
2020

2121
const 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

3662
int 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

Comments
 (0)