Skip to content

Commit 8410d69

Browse files
committed
fix: address review feedback on mixed benchmark test
- fail test on waitForMetricTarget timeout instead of silently continuing - bump default NumSpammers from 2 to 4 to satisfy mixed workload minimum - replace time.Sleep with metric polling for contract deployment readiness - add panic guard to distributeSpammers for total < 4 - add table-driven unit tests for distributeSpammers
1 parent e5073ee commit 8410d69

4 files changed

Lines changed: 88 additions & 8 deletions

File tree

test/e2e/benchmark/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func newBenchConfig(serviceName string) benchConfig {
4141
SlotDuration: envOrDefault("BENCH_SLOT_DURATION", "250ms"),
4242
GasLimit: envOrDefault("BENCH_GAS_LIMIT", ""),
4343
ScrapeInterval: envOrDefault("BENCH_SCRAPE_INTERVAL", "1s"),
44-
NumSpammers: envInt("BENCH_NUM_SPAMMERS", 2),
44+
NumSpammers: envInt("BENCH_NUM_SPAMMERS", 4),
4545
CountPerSpammer: envInt("BENCH_COUNT_PER_SPAMMER", 5000),
4646
Throughput: envInt("BENCH_THROUGHPUT", 200),
4747
WarmupTxs: envInt("BENCH_WARMUP_TXS", 200),
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//go:build evm
2+
3+
package benchmark
4+
5+
import (
6+
"testing"
7+
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestDistributeSpammers(t *testing.T) {
12+
tests := []struct {
13+
name string
14+
total int
15+
pcts [4]int
16+
expected [4]int
17+
}{
18+
{
19+
name: "minimum total equals types",
20+
total: 4,
21+
pcts: [4]int{40, 30, 20, 10},
22+
expected: [4]int{1, 1, 1, 1},
23+
},
24+
{
25+
name: "equal percentages",
26+
total: 8,
27+
pcts: [4]int{25, 25, 25, 25},
28+
expected: [4]int{2, 2, 2, 2},
29+
},
30+
{
31+
name: "default mix 8 spammers",
32+
total: 8,
33+
pcts: [4]int{40, 30, 20, 10},
34+
expected: [4]int{3, 2, 2, 1},
35+
},
36+
{
37+
name: "large total distributes proportionally",
38+
total: 104,
39+
pcts: [4]int{40, 30, 20, 10},
40+
expected: [4]int{41, 31, 21, 11},
41+
},
42+
{
43+
name: "sum of counts equals total",
44+
total: 7,
45+
pcts: [4]int{40, 30, 20, 10},
46+
expected: [4]int{2, 2, 2, 1},
47+
},
48+
{
49+
name: "5 spammers with uneven split",
50+
total: 5,
51+
pcts: [4]int{40, 30, 20, 10},
52+
expected: [4]int{2, 1, 1, 1},
53+
},
54+
}
55+
56+
for _, tt := range tests {
57+
t.Run(tt.name, func(t *testing.T) {
58+
result := distributeSpammers(tt.total, tt.pcts)
59+
require.Equal(t, tt.expected, result)
60+
61+
sum := result[0] + result[1] + result[2] + result[3]
62+
require.Equal(t, tt.total, sum, "sum of distributed spammers must equal total")
63+
64+
for i, c := range result {
65+
require.GreaterOrEqual(t, c, 1, "type %d must have at least 1 spammer", i)
66+
}
67+
})
68+
}
69+
}
70+
71+
func TestDistributeSpammersPanicsOnLowTotal(t *testing.T) {
72+
require.Panics(t, func() {
73+
distributeSpammers(3, [4]int{40, 30, 20, 10})
74+
})
75+
require.Panics(t, func() {
76+
distributeSpammers(0, [4]int{25, 25, 25, 25})
77+
})
78+
}

test/e2e/benchmark/helpers.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -471,11 +471,9 @@ func waitForMetricTarget(t testing.TB, name string, poll func() (float64, error)
471471
}
472472
select {
473473
case <-ctx.Done():
474-
t.Logf("metric %s: context cancelled (target %.0f)", name, target)
475-
return
474+
t.Fatalf("metric %s: context cancelled (target %.0f)", name, target)
476475
case <-timer.C:
477-
t.Logf("metric %s did not reach target %.0f within %v", name, target, timeout)
478-
return
476+
t.Fatalf("metric %s did not reach target %.0f within %v", name, target, timeout)
479477
case <-ticker.C:
480478
}
481479
}

test/e2e/benchmark/mixed_workload_test.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,6 @@ func (s *SpamoorSuite) TestMixedWorkload() {
150150
}
151151
}
152152

153-
// allow time for contract deployments (uniswap, gasburner, storage)
154-
time.Sleep(5 * time.Second)
155153
requireSpammersRunning(t, e.spamoorAPI, spammerIDs)
156154

157155
pollSentTotal := func() (float64, error) {
@@ -161,6 +159,9 @@ func (s *SpamoorSuite) TestMixedWorkload() {
161159
}
162160
return sumCounter(metrics["spamoor_transactions_sent_total"]), nil
163161
}
162+
163+
// wait for at least one tx per spammer to confirm contract deployments are done
164+
waitForMetricTarget(t, "spamoor_transactions_sent_total (deploy)", pollSentTotal, float64(len(spammerIDs)), cfg.WaitTimeout)
164165
waitForMetricTarget(t, "spamoor_transactions_sent_total (warmup)", pollSentTotal, float64(cfg.WarmupTxs), cfg.WaitTimeout)
165166

166167
e.traces.resetStartTime()
@@ -209,12 +210,15 @@ func (s *SpamoorSuite) TestMixedWorkload() {
209210
// proportionally to pcts using the largest-remainder method. Each type
210211
// gets at least 1 spammer. total must be >= 4.
211212
func distributeSpammers(total int, pcts [4]int) [4]int {
213+
if total < 4 {
214+
panic(fmt.Sprintf("distributeSpammers: total must be >= 4, got %d", total))
215+
}
212216
var counts [4]int
213217
for i := range counts {
214218
counts[i] = 1
215219
}
216220
remaining := total - 4
217-
if remaining <= 0 {
221+
if remaining == 0 {
218222
return counts
219223
}
220224

0 commit comments

Comments
 (0)