Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
81dc810
refactor: move spamoor benchmark into testify suite in test/e2e/bench…
chatton Feb 25, 2026
cc56590
merge main into cian/bench-refactor
chatton Feb 25, 2026
18fc15a
fix: correct BENCH_JSON_OUTPUT path for spamoor benchmark
chatton Feb 25, 2026
fccd9db
fix: place package pattern before test binary flags in benchmark CI
chatton Feb 25, 2026
ae525ca
fix: adjust evm-binary path for benchmark subpackage working directory
chatton Feb 25, 2026
039eaf7
wip: erc20 benchmark test
chatton Feb 25, 2026
85c9d2d
fix: exclude benchmark subpackage from make test-e2e
chatton Feb 25, 2026
fe8d166
fix: replace FilterLogs with header iteration and optimize spamoor co…
chatton Feb 26, 2026
99e3e42
fix: improve benchmark measurement window and reliability
chatton Feb 26, 2026
e4e06c5
fix: address PR review feedback for benchmark suite
chatton Mar 2, 2026
1c3b560
Merge branch 'main' into cian/bench-refactor
chatton Mar 2, 2026
03b9239
chore: specify http
chatton Mar 2, 2026
fe3ca23
chore: filter out benchmark tests from test-e2e
chatton Mar 2, 2026
8752fee
Merge branch 'main' into cian/bench-refactor
chatton Mar 2, 2026
06f532b
Merge branch 'cian/bench-refactor' into cian/erc20-benchmark
chatton Mar 2, 2026
560974a
Merge remote-tracking branch 'origin/main' into cian/erc20-benchmark
chatton Mar 2, 2026
054f2c6
refactor: centralize reth config and lower ERC20 spammer count
chatton Mar 2, 2026
26bb117
chore: collect all traces at once
chatton Mar 2, 2026
b88cae3
chore: self review
chatton Mar 2, 2026
272ab71
refactor: extract benchmark helpers to slim down ERC20 test body
chatton Mar 2, 2026
676e0d1
docs: add detailed documentation to benchmark helper methods
chatton Mar 2, 2026
f4949a1
ci: add ERC20 throughput benchmark job
chatton Mar 2, 2026
4c7b7e1
chore: remove span assertions
chatton Mar 2, 2026
6f56c80
chore: adding gas burner test
chatton Mar 2, 2026
3eb733a
chore: merge main
chatton Mar 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: address PR review feedback for benchmark suite
- make reth tag configurable via EV_RETH_TAG env var (default pr-140)
- fix OTLP config: remove duplicate env vars, use http/protobuf protocol
- use require.Eventually for host readiness polling
- rename requireHTTP to requireHostUp
- use non-fatal logging in resultWriter.flush deferred context
- fix stale doc comment (setupCommonEVMEnv -> SetupCommonEVMEnv)
- rename loop variable to avoid shadowing testing.TB convention
- add block/internal/executing/** to CI path trigger
- remove unused require import from output.go
  • Loading branch information
chatton committed Mar 2, 2026
commit e4e06c5f232361ffc58545c9a0cc45f17d28e732
1 change: 1 addition & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ permissions: {}
- 'test/e2e/evm_contract_bench_test.go'
- 'test/e2e/evm_test_common.go'
- 'test/e2e/sut_helper.go'
- 'block/internal/executing/**'
- '.github/workflows/benchmark.yml'
workflow_dispatch:

Expand Down
27 changes: 10 additions & 17 deletions test/e2e/benchmark/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,27 @@
package benchmark

import (
"fmt"
"net/http"
"testing"
"time"

"github.com/stretchr/testify/require"

dto "github.com/prometheus/client_model/go"
)

// requireHTTP polls a URL until it returns a 2xx status code or the timeout expires.
func requireHTTP(t testing.TB, url string, timeout time.Duration) {
// requireHostUp polls a URL until it returns a 2xx status code or the timeout expires.
func requireHostUp(t testing.TB, url string, timeout time.Duration) {
t.Helper()
client := &http.Client{Timeout: 200 * time.Millisecond}
deadline := time.Now().Add(timeout)
var lastErr error
for time.Now().Before(deadline) {
require.Eventually(t, func() bool {
resp, err := client.Get(url)
if err == nil {
_ = resp.Body.Close()
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
return
}
lastErr = fmt.Errorf("status %d", resp.StatusCode)
} else {
lastErr = err
if err != nil {
return false
}
time.Sleep(100 * time.Millisecond)
}
t.Fatalf("daemon not ready at %s: %v", url, lastErr)
_ = resp.Body.Close()
return resp.StatusCode >= 200 && resp.StatusCode < 300
}, timeout, 100*time.Millisecond, "daemon not ready at %s", url)
}

// sumCounter sums all counter values in a prometheus MetricFamily.
Expand Down
11 changes: 8 additions & 3 deletions test/e2e/benchmark/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"testing"

e2e "github.com/evstack/ev-node/test/e2e"
"github.com/stretchr/testify/require"
)

// entry matches the customSmallerIsBetter format for github-action-benchmark.
Expand Down Expand Up @@ -71,7 +70,13 @@ func (w *resultWriter) flush() {
}

data, err := json.MarshalIndent(w.entries, "", " ")
require.NoError(w.t, err, "failed to marshal benchmark JSON")
require.NoError(w.t, os.WriteFile(outputPath, data, 0644), "failed to write benchmark JSON to %s", outputPath)
if err != nil {
w.t.Logf("WARNING: failed to marshal benchmark JSON: %v", err)
return
}
if err := os.WriteFile(outputPath, data, 0644); err != nil {
w.t.Logf("WARNING: failed to write benchmark JSON to %s: %v", outputPath, err)
return
}
w.t.Logf("wrote %d benchmark entries to %s", len(w.entries), outputPath)
}
8 changes: 7 additions & 1 deletion test/e2e/benchmark/spamoor_smoke_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package benchmark

import (
"os"
"time"

"github.com/celestiaorg/tastora/framework/docker/evstack/spamoor"
Expand All @@ -17,8 +18,13 @@ func (s *SpamoorSuite) TestSpamoorSmoke() {
w := newResultWriter(t, "SpamoorSmoke")
defer w.flush()

// TODO: temporary hardcoded tag, will be replaced with a proper release tag
rethTag := os.Getenv("EV_RETH_TAG")
if rethTag == "" {
rethTag = "pr-140"
}
e := s.setupEnv(config{
rethTag: "pr-140",
rethTag: rethTag,
serviceName: "ev-node-smoke",
})
api := e.spamoorAPI
Expand Down
9 changes: 5 additions & 4 deletions test/e2e/benchmark/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,11 @@ func (s *SpamoorSuite) setupEnv(cfg config) *env {
evmEnv := e2e.SetupCommonEVMEnv(t, sut, s.dockerCli, s.networkID,
e2e.WithRethOpts(func(b *reth.NodeBuilder) {
b.WithTag(cfg.rethTag).WithEnv(
// ev-reth reads OTEL_EXPORTER_OTLP_ENDPOINT and passes it directly
// to with_endpoint(). opentelemetry-otlp v0.31 HTTP exporter does
// not auto-append /v1/traces, so the full path is required.
"OTEL_EXPORTER_OTLP_ENDPOINT="+jg.Internal.IngestHTTPEndpoint()+"/v1/traces",
"OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="+jg.Internal.IngestHTTPEndpoint()+"/v1/traces",
"OTEL_EXPORTER_OTLP_PROTOCOL=http",
"OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=http",
"OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf",
"RUST_LOG=debug",
"OTEL_SDK_DISABLED=false",
)
Expand Down Expand Up @@ -117,7 +118,7 @@ func (s *SpamoorSuite) setupEnv(cfg config) *env {
spInfo, err := spNode.GetNetworkInfo(ctx)
s.Require().NoError(err, "failed to get spamoor network info")
apiAddr := "http://127.0.0.1:" + spInfo.External.Ports.HTTP
requireHTTP(t, apiAddr+"/api/spammers", 30*time.Second)
requireHostUp(t, apiAddr+"/api/spammers", 30*time.Second)

return &env{
jaeger: jg,
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/benchmark/traces.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ func (j jaegerSpan) SpanDuration() time.Duration { return time.Duration(j.durati
// extractSpansFromTraces walks Jaeger's []any response and pulls out span operation names and durations.
func extractSpansFromTraces(traces []any) []jaegerSpan {
var out []jaegerSpan
for _, t := range traces {
traceMap, ok := t.(map[string]any)
for _, traceEntry := range traces {
traceMap, ok := traceEntry.(map[string]any)
if !ok {
continue
}
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/evm_test_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ func WithRethOpts(opts ...evmtest.RethNodeOpt) SetupOpt {
}
}

// setupCommonEVMEnv creates and initializes ev-reth instances, while also initializing the local ev-node instance
// SetupCommonEVMEnv creates and initializes ev-reth instances, while also initializing the local ev-node instance
// managed by sut. If a full node is also required, we can use the WithFullNode() additional option.
func SetupCommonEVMEnv(t testing.TB, sut *SystemUnderTest, client tastoratypes.TastoraDockerClient, networkID string, opts ...SetupOpt) *EVMEnv {
t.Helper()
Expand Down