From a8cbc7369cde02c132fd904c16171af7dad04d94 Mon Sep 17 00:00:00 2001 From: Senthilnathan Date: Wed, 1 Apr 2026 21:00:15 +0530 Subject: [PATCH] [bench] Replace AWK tx/s script with b.ReportMetric Add test.ReportTxPerSecond(b) helper and call it from all benchmarks. Cap batch benchmarks to exactly b.N transactions for accurate reporting. Remove bench-tx-per-sec.awk and Makefile AWK pipes. Signed-off-by: Senthilnathan --- Makefile | 24 +++++++++---------- loadgen/metrics/tracker_test.go | 2 ++ loadgen/workload/stream_test.go | 2 ++ scripts/bench-tx-per-sec.awk | 14 ----------- .../dependencygraph/manager_test.go | 9 ++++--- service/sidecar/mapping_test.go | 4 +++- service/sidecar/notify_test.go | 1 + service/vc/preparer_test.go | 10 ++++---- utils/deliverorderer/verify_test.go | 2 ++ utils/serialization/envelope_wrapper_test.go | 5 ++-- utils/test/benchmark.go | 15 ++++++++++++ 11 files changed, 52 insertions(+), 36 deletions(-) delete mode 100644 scripts/bench-tx-per-sec.awk create mode 100644 utils/test/benchmark.go diff --git a/Makefile b/Makefile index dc64fd8b7..5891b620b 100644 --- a/Makefile +++ b/Makefile @@ -208,33 +208,33 @@ kill-test-docker: FORCE # Benchmarks ######################### -# Run a load generation benchmarks with added TX/sec column. +# Run load generation benchmarks. bench-loadgen: FORCE - $(go_cmd) test ./loadgen/... -bench "Benchmark.*" -run="^$$" | awk -f scripts/bench-tx-per-sec.awk + $(go_cmd) test ./loadgen/... -bench "Benchmark.*" -run="^$$" -# Run dependency detector benchmarks with added op/sec column. +# Run dependency detector benchmarks. bench-dep: FORCE - $(go_cmd) test ./service/coordinator/dependencygraph/... -timeout 60m -bench "BenchmarkDependencyGraph.*" -run="^$$" | awk -f scripts/bench-tx-per-sec.awk + $(go_cmd) test ./service/coordinator/dependencygraph/... -timeout 60m -bench "BenchmarkDependencyGraph.*" -run="^$$" -# Run dependency detector benchmarks with added op/sec column. +# Run preparer benchmarks. bench-preparer: FORCE - $(go_cmd) test ./service/vc/... -bench "BenchmarkPrepare.*" -run "^$$" | awk -f scripts/bench-tx-per-sec.awk + $(go_cmd) test ./service/vc/... -bench "BenchmarkPrepare.*" -run "^$$" -# Run signature benchmarks with added op/sec column. +# Run signature benchmarks. bench-sign: FORCE - $(go_cmd) test ./utils/signature/... -bench ".*" -run "^$$" | awk -f scripts/bench-tx-per-sec.awk + $(go_cmd) test ./utils/signature/... -bench ".*" -run "^$$" -# Run sidecar benchmarks with added op/sec column. +# Run sidecar benchmarks. bench-sidecar: FORCE - $(go_cmd) test ./service/sidecar/... -bench "Benchmark.*" -run "^$$" | awk -f scripts/bench-tx-per-sec.awk + $(go_cmd) test ./service/sidecar/... -bench "Benchmark.*" -run "^$$" # Run serialization benchmarks. bench-serialization: FORCE $(go_cmd) test ./utils/serialization/... -bench "Benchmark.*" -run "^$$" -# Run deliver benchmarks with added op/sec column. +# Run deliver benchmarks. bench-deliver: FORCE - $(go_cmd) test ./utils/deliverorderer/... -bench "Benchmark.*" -run "^$$" | awk -f scripts/bench-tx-per-sec.awk + $(go_cmd) test ./utils/deliverorderer/... -bench "Benchmark.*" -run "^$$" ######################### # Code Generation diff --git a/loadgen/metrics/tracker_test.go b/loadgen/metrics/tracker_test.go index 3e0f68a13..6f1dadad3 100644 --- a/loadgen/metrics/tracker_test.go +++ b/loadgen/metrics/tracker_test.go @@ -17,6 +17,7 @@ import ( "github.com/stretchr/testify/require" "github.com/hyperledger/fabric-x-committer/utils" + "github.com/hyperledger/fabric-x-committer/utils/test" ) //nolint:gocognit // cognitive complexity 24 > 15 @@ -89,6 +90,7 @@ func BenchmarkLatencyTrackerPortion(b *testing.B) { for _, txID := range txIDs { sampler(txID) } + test.ReportTxPerSecond(b) }) } } diff --git a/loadgen/workload/stream_test.go b/loadgen/workload/stream_test.go index e54b1811a..f2c666f74 100644 --- a/loadgen/workload/stream_test.go +++ b/loadgen/workload/stream_test.go @@ -106,6 +106,7 @@ func BenchmarkGenTx(b *testing.B) { txs := g.Consume(ctx, param) sum += len(txs) } + test.ReportTxPerSecond(b) }) } @@ -125,6 +126,7 @@ func BenchmarkGenQuery(b *testing.B) { q := g.Consume(ctx, ConsumeParameters{RequestedItems: request}) sum += len(q) } + test.ReportTxPerSecond(b) }) } diff --git a/scripts/bench-tx-per-sec.awk b/scripts/bench-tx-per-sec.awk deleted file mode 100644 index fc8e0dc18..000000000 --- a/scripts/bench-tx-per-sec.awk +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -# -# Copyright IBM Corp. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -# - -# This script adds a TX/sec column to the benchmark output. -{ - if ($NF ~ /ns\/op/) { - ops=1e9/$(NF-1); - printf "%s\t%'.0f TX/sec\n", $0, ops - } else print $0 -} diff --git a/service/coordinator/dependencygraph/manager_test.go b/service/coordinator/dependencygraph/manager_test.go index 50d0f198d..2678f606f 100644 --- a/service/coordinator/dependencygraph/manager_test.go +++ b/service/coordinator/dependencygraph/manager_test.go @@ -90,7 +90,7 @@ func BenchmarkDependencyGraph(b *testing.B) { PrometheusMetricsProvider: monitoring.NewProvider(), }) - txPoll := workload.GenerateTransactions(b, p, max(b.N*3, batchSize*3)) + txPoll := workload.GenerateTransactions(b, p, max(b.N, batchSize)) ctx := b.Context() outCtx := channel.NewReader(ctx, out) @@ -120,10 +120,12 @@ func BenchmarkDependencyGraph(b *testing.B) { // Generates the load to the manager's queue. go func() { var i uint64 - for ctx.Err() == nil && len(txPoll) > 0 { - take := min(batchSize, len(txPoll)) + remaining := b.N + for ctx.Err() == nil && remaining > 0 { + take := min(batchSize, len(txPoll), remaining) batch := workload.MapToCoordinatorBatch(i, txPoll[:take]) txPoll = txPoll[take:] + remaining -= take inCtx.Write(&TransactionBatch{ ID: i, Txs: batch.Txs, @@ -145,6 +147,7 @@ func BenchmarkDependencyGraph(b *testing.B) { total += len(batch) } b.StopTimer() + test.ReportTxPerSecond(b) }) } }) diff --git a/service/sidecar/mapping_test.go b/service/sidecar/mapping_test.go index b7c9a6810..4619ada44 100644 --- a/service/sidecar/mapping_test.go +++ b/service/sidecar/mapping_test.go @@ -18,6 +18,7 @@ import ( "github.com/hyperledger/fabric-x-committer/api/servicepb" "github.com/hyperledger/fabric-x-committer/loadgen/workload" "github.com/hyperledger/fabric-x-committer/utils" + "github.com/hyperledger/fabric-x-committer/utils/test" ) func BenchmarkMapOneBlock(b *testing.B) { @@ -29,6 +30,7 @@ func BenchmarkMapOneBlock(b *testing.B) { b.ResetTimer() mappedBlock, err := mapBlock(block, &txIDToHeight) b.StopTimer() + test.ReportTxPerSecond(b) require.NoError(b, err, "This can never occur unless there is a bug in the relay.") require.NotNil(b, mappedBlock) } @@ -65,7 +67,7 @@ func BenchmarkMapBlockSize(b *testing.B) { } blockIdx++ } - b.ReportMetric(float64(b.N)/b.Elapsed().Seconds(), "tx/s") + test.ReportTxPerSecond(b) }) } } diff --git a/service/sidecar/notify_test.go b/service/sidecar/notify_test.go index 62e42f12b..f21a8f3dc 100644 --- a/service/sidecar/notify_test.go +++ b/service/sidecar/notify_test.go @@ -90,6 +90,7 @@ func BenchmarkNotifier(b *testing.B) { notifiedCount += len(res.TxStatusEvents) } b.StopTimer() + test.ReportTxPerSecond(b) } type notifierTestEnv struct { diff --git a/service/vc/preparer_test.go b/service/vc/preparer_test.go index 16b8a01d3..20f7e8cac 100644 --- a/service/vc/preparer_test.go +++ b/service/vc/preparer_test.go @@ -681,7 +681,6 @@ func requireEqualMapOfLists[K comparable, V any](t *testing.T, expected, actual } } -//nolint:gocognit // single method for simplicity. func BenchmarkPrepare(b *testing.B) { flogging.ActivateSpec("fatal") @@ -698,7 +697,7 @@ func BenchmarkPrepare(b *testing.B) { return p.run(ctx, w) }, nil) - txPoll := workload.GenerateTransactions(b, nil, max(b.N*3, batchSize*3)) + txPoll := workload.GenerateTransactions(b, nil, max(b.N, batchSize)) inCtx := channel.NewWriter(b.Context(), txBatch) outCtx := channel.NewReader(b.Context(), preparedTxs) @@ -706,10 +705,12 @@ func BenchmarkPrepare(b *testing.B) { // Generates the load to the preparer's queue. go func() { var i uint64 - for b.Context().Err() == nil && len(txPoll) > 0 { - take := min(batchSize, len(txPoll)) + remaining := b.N + for b.Context().Err() == nil && remaining > 0 { + take := min(batchSize, len(txPoll), remaining) inCtx.Write(workload.MapToVcBatch(i, txPoll[:take])) txPoll = txPoll[take:] + remaining -= take i++ } }() @@ -723,6 +724,7 @@ func BenchmarkPrepare(b *testing.B) { total += len(batch.txIDToHeight) } b.StopTimer() + test.ReportTxPerSecond(b) }) } } diff --git a/utils/deliverorderer/verify_test.go b/utils/deliverorderer/verify_test.go index d6edadd2d..18c620d36 100644 --- a/utils/deliverorderer/verify_test.go +++ b/utils/deliverorderer/verify_test.go @@ -22,6 +22,7 @@ import ( "github.com/hyperledger/fabric-x-committer/loadgen/workload" "github.com/hyperledger/fabric-x-committer/utils/deliver" + "github.com/hyperledger/fabric-x-committer/utils/test" "github.com/hyperledger/fabric-x-committer/utils/testcrypto" ) @@ -48,6 +49,7 @@ func BenchmarkVerifyBlock(b *testing.B) { require.NoError(b, verErr) } b.StopTimer() + test.ReportTxPerSecond(b) }) } } diff --git a/utils/serialization/envelope_wrapper_test.go b/utils/serialization/envelope_wrapper_test.go index 2367d28bc..c500e31cb 100644 --- a/utils/serialization/envelope_wrapper_test.go +++ b/utils/serialization/envelope_wrapper_test.go @@ -17,6 +17,7 @@ import ( "github.com/hyperledger/fabric-x-committer/loadgen/workload" "github.com/hyperledger/fabric-x-committer/utils/serialization" + "github.com/hyperledger/fabric-x-committer/utils/test" ) // TestUnwrapEnvelopeLite tests UnwrapEnvelopeLite with well-formed input. @@ -198,7 +199,7 @@ func BenchmarkUnwrapEnvelope(b *testing.B) { b.Fatal(err) } } - b.ReportMetric(float64(b.N)/b.Elapsed().Seconds(), "tx/s") + test.ReportTxPerSecond(b) } func BenchmarkUnwrapEnvelopeLite(b *testing.B) { @@ -210,7 +211,7 @@ func BenchmarkUnwrapEnvelopeLite(b *testing.B) { b.Fatal(err) } } - b.ReportMetric(float64(b.N)/b.Elapsed().Seconds(), "tx/s") + test.ReportTxPerSecond(b) } // loadgenEnvelopes generates realistic serialized envelopes using the load diff --git a/utils/test/benchmark.go b/utils/test/benchmark.go new file mode 100644 index 000000000..cb9ea47cd --- /dev/null +++ b/utils/test/benchmark.go @@ -0,0 +1,15 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package test + +import "testing" + +// ReportTxPerSecond reports a tx/s custom metric on the benchmark. +func ReportTxPerSecond(b *testing.B) { + b.Helper() + b.ReportMetric(float64(b.N)/b.Elapsed().Seconds(), "tx/s") +}