Skip to content

Commit 72551b4

Browse files
authored
Merge pull request #737 from GeorgeTsagk/loadtest-push-metrics-updated
Loadtesting metrics, updated
2 parents 72b93f8 + 8f2499d commit 72551b4

File tree

4 files changed

+169
-6
lines changed

4 files changed

+169
-6
lines changed

itest/loadtest/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
## Description
2+
3+
This directory (`itest/loadtest`) includes all files and data related to running
4+
the loadtesting suite for taproot assets daemon. These tests use the existing
5+
itest framework to run against real external running daemons.
6+
7+
The configuration file needs to be named `loadtest.conf` and must be placed on
8+
the working directory in order for the loadtest executable to detect it. A
9+
sample configuration can be found in `loadtest-sample.conf` which includes all
10+
the fields that are required for the tests to run successfully. This includes
11+
connection credentials for the tapd & lnd nodes, as well as a bitcoind backend.
12+
13+
For further tracking and metrics, a prometheus gateway is configured and used by
14+
the loadtests in order to submit any desired data in-flight.
15+
16+
## Building
17+
18+
To create the loadtest executable run `make build-loadtest`. This will
19+
create a `loadtest` binary in your working directory which you can run, given
20+
that you have a correct `loadtest.conf` in the same directory.
21+
22+
The executable will consult the appropriate fields of `loadtest.conf` and it's
23+
going to run the defined test case with the respective config.
24+
25+
Example: To run a mint loadtest which mints batches of `450` assets we will
26+
define `test-case="mint"` and `mint-test-batch-size=450` in our `loadtest.conf`.
27+
28+
## Using dev-resources docker setup
29+
30+
You can use any kind of external running daemon, as long as it's reachable. The
31+
easiest way to spin up some nodes from scratch for the purpose of the loadtests
32+
is to run the `dev-resources/docker-regtest` setup and use `alice`,
33+
`alice-tapd`, `bob`, `bob-tapd` and the single `bitcoind` instance.

itest/loadtest/config.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,17 @@ type BitcoinConfig struct {
5858
TLSPath string `long:"tlspath" description:"Path to btcd's TLS certificate, if TLS is enabled"`
5959
}
6060

61+
// PrometheusGatewayConfig defines exported config options for connecting to the
62+
// Prometheus PushGateway.
63+
type PrometheusGatewayConfig struct {
64+
// nolint: lll
65+
Enabled bool `long:"enabled" description:"Enable pushing metrics to Prometheus PushGateway"`
66+
// nolint: lll
67+
Host string `long:"host" description:"Prometheus PushGateway host address"`
68+
Port int `long:"port" description:"Prometheus PushGateway port"`
69+
PushURL string
70+
}
71+
6172
// Config holds the main configuration for the performance testing binary.
6273
type Config struct {
6374
// TestCases is a comma separated list of test cases that will be
@@ -97,6 +108,12 @@ type Config struct {
97108

98109
// TestTimeout is the timeout for each test.
99110
TestTimeout time.Duration `long:"test-timeout" description:"the timeout for each test"`
111+
112+
// PrometheusGateway is the configuration for the Prometheus
113+
// PushGateway.
114+
//
115+
// nolint: lll
116+
PrometheusGateway *PrometheusGatewayConfig `group:"prometheus-gateway" namespace:"prometheus-gateway" description:"Prometheus PushGateway configuration"`
100117
}
101118

102119
// DefaultConfig returns the default configuration for the performance testing
@@ -120,6 +137,11 @@ func DefaultConfig() Config {
120137
SendType: taprpc.AssetType_COLLECTIBLE,
121138
TestSuiteTimeout: defaultSuiteTimeout,
122139
TestTimeout: defaultTestTimeout,
140+
PrometheusGateway: &PrometheusGatewayConfig{
141+
Enabled: false,
142+
Host: "localhost",
143+
Port: 9091,
144+
},
123145
}
124146
}
125147

@@ -156,6 +178,28 @@ func LoadConfig() (*Config, error) {
156178
// of it with sane defaults.
157179
func ValidateConfig(cfg Config) (*Config, error) {
158180
// TODO (positiveblue): add validation logic.
181+
182+
// Validate Prometheus PushGateway configuration.
183+
if cfg.PrometheusGateway.Enabled {
184+
gatewayHost := cfg.PrometheusGateway.Host
185+
gatewayPort := cfg.PrometheusGateway.Port
186+
187+
if gatewayHost == "" {
188+
return nil, fmt.Errorf(
189+
"gateway hostname may not be empty",
190+
)
191+
}
192+
193+
if gatewayPort == 0 {
194+
return nil, fmt.Errorf("gateway port is not set")
195+
}
196+
197+
// Construct the endpoint for Prometheus PushGateway.
198+
cfg.PrometheusGateway.PushURL = fmt.Sprintf(
199+
"%s:%d", gatewayHost, gatewayPort,
200+
)
201+
}
202+
159203
return &cfg, nil
160204
}
161205

itest/loadtest/load_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,30 @@ package loadtest
44

55
import (
66
"context"
7+
"fmt"
78
"testing"
9+
"time"
810

11+
"github.com/prometheus/client_golang/prometheus"
12+
"github.com/prometheus/client_golang/prometheus/push"
913
"github.com/stretchr/testify/require"
1014
)
1115

16+
var (
17+
testDuration = prometheus.NewGaugeVec(
18+
prometheus.GaugeOpts{
19+
Name: "test_duration_seconds",
20+
Help: "Duration of the test execution, in seconds",
21+
},
22+
[]string{"test_name"},
23+
)
24+
)
25+
26+
func init() {
27+
// Register the metric with Prometheus's default registry.
28+
prometheus.MustRegister(testDuration)
29+
}
30+
1231
type testCase struct {
1332
name string
1433
fn func(t *testing.T, ctx context.Context, cfg *Config)
@@ -48,6 +67,9 @@ func TestPerformance(t *testing.T) {
4867
continue
4968
}
5069

70+
// Record the start time of the test case.
71+
startTime := time.Now()
72+
5173
success := t.Run(tc.name, func(tt *testing.T) {
5274
ctxt, cancel := context.WithTimeout(
5375
ctxt, cfg.TestTimeout,
@@ -59,6 +81,33 @@ func TestPerformance(t *testing.T) {
5981
if !success {
6082
t.Fatalf("test case %v failed", tc.name)
6183
}
84+
85+
// Calculate the test duration and push metrics if the test case succeeded.
86+
if cfg.PrometheusGateway.Enabled {
87+
duration := time.Since(startTime).Seconds()
88+
89+
timeTag := fmt.Sprintf("%d", time.Now().Unix())
90+
91+
label := tc.name + timeTag
92+
93+
// Update the metric with the test duration.
94+
testDuration.WithLabelValues(label).Set(duration)
95+
96+
t.Logf("Pushing testDuration %v with label %v to gateway", duration, label)
97+
98+
// Create a new pusher to push the metrics.
99+
pusher := push.New(cfg.PrometheusGateway.PushURL, "load_test").
100+
Collector(testDuration)
101+
102+
// Push the metrics to Prometheus PushGateway.
103+
if err := pusher.Add(); err != nil {
104+
t.Logf("Could not push metrics to Prometheus PushGateway: %v",
105+
err)
106+
} else {
107+
t.Logf("Metrics pushed for test case '%s': duration = %v seconds",
108+
tc.name, duration)
109+
}
110+
}
62111
}
63112
}
64113

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,56 @@
1+
# Network the nodes are connected to
2+
network=regtest
3+
4+
# The name of the test case to run. Example "send" or "mint"
5+
test-case="mint"
6+
7+
# Batch size for mint test
8+
mint-test-batch-size=5
9+
10+
# Number of send operations to perform for send test
11+
send-test-num-sends=5
12+
13+
# Number of assets to send in each send operation for send test
14+
send-test-num-assets=1
15+
16+
# Timeout for the entire test suite
17+
test-suite-timeout=120m
18+
19+
# Timeout for each test
20+
test-timeout=10m
21+
122
[bitcoin]
223
bitcoin.host="localhost"
324
bitcoin.port=18443
425
bitcoin.user=lightning
526
bitcoin.password=lightning
627

28+
729
[alice]
830
alice.tapd.name=alice
931
alice.tapd.host="localhost"
10-
alice.tapd.port=10029
11-
alice.tapd.tlspath=path-to-alice/.tapd/tls.cert
12-
alice.tapd.macpath=path-to-alice/.tapd/data/regtest/admin.macaroon
32+
alice.tapd.port=XXX
33+
alice.tapd.tlspath=/path/to/tls.cert
34+
alice.tapd.macpath=/path/to/admin.macaroon
35+
alice.lnd.name=alice_lnd
36+
alice.lnd.host="localhost"
37+
alice.lnd.port=XXX
38+
alice.lnd.tlspath=/path/to/tls.cert
39+
alice.lnd.macpath=/path/to/admin.macaroon
1340

1441
[bob]
1542
bob.tapd.name=bob
1643
bob.tapd.host="localhost"
17-
bob.tapd.port=10032
18-
bob.tapd.tlspath=path-to-bob/.tapd/tls.cert
19-
bob.tapd.macpath=path-to-bob/.tapd/data/regtest/admin.macaroon
44+
bob.tapd.port=XXX
45+
bob.tapd.tlspath=/path/to/tls.cert
46+
bob.tapd.macpath=/path/to/admin.macaroon
47+
bob.lnd.name=bob_lnd
48+
bob.lnd.host="localhost"
49+
bob.lnd.port=XXX
50+
bob.lnd.tlspath=/path/to/tls.cert
51+
bob.lnd.macpath=/path/to/admin.macaroon
52+
53+
[prometheus-gateway]
54+
prometheus-gateway.enabled=true
55+
prometheus-gateway.host=prometheus-gateway-host
56+
prometheus-gateway.port=9091

0 commit comments

Comments
 (0)