Skip to content

Commit

Permalink
Implement support for multi address singular strings with separator i…
Browse files Browse the repository at this point in the history
…n configuration
  • Loading branch information
oleg-ssvlabs committed Feb 12, 2025
1 parent a7748e4 commit 4b437e7
Show file tree
Hide file tree
Showing 3 changed files with 229 additions and 18 deletions.
29 changes: 19 additions & 10 deletions configs/benchmark.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package configs
import (
"errors"
"net/url"
"strings"
"time"

"github.com/ssvlabs/ssv-pulse/internal/platform/network"
Expand Down Expand Up @@ -107,25 +108,33 @@ func (b *Benchmark) Validate() (bool, error) {
b.Consensus.Metrics.Client.Enabled ||
b.Consensus.Metrics.Latency.Enabled {
var urls []string
for _, addr := range b.Consensus.Addresses {
url, err := sanitizeURL(addr)
if err != nil {
return false, errors.Join(err, errors.New("consensus client address was not a valid URL"))
for _, addrString := range b.Consensus.Addresses {
//configuration supports both yaml arrays and multi address strings with semicolon as separator
addresses := strings.Split(addrString, ";")
for _, addr := range addresses {
url, err := sanitizeURL(addr)
if err != nil {
return false, errors.Join(err, errors.New("consensus client address was not a valid URL"))
}
urls = append(urls, url)
}
urls = append(urls, url)
}

b.Consensus.Addresses = urls
}

if b.Execution.Metrics.Peers.Enabled || b.Execution.Metrics.Latency.Enabled {
var urls []string
for _, addr := range b.Execution.Addresses {
url, err := sanitizeURL(addr)
if err != nil {
return false, errors.Join(err, errors.New("execution client address was not a valid URL"))
for _, addrString := range b.Execution.Addresses {
//configuration supports both yaml arrays and multi address strings with semicolon as separator
addresses := strings.Split(addrString, ";")
for _, addr := range addresses {
url, err := sanitizeURL(addr)
if err != nil {
return false, errors.Join(err, errors.New("execution client address was not a valid URL"))
}
urls = append(urls, url)
}
urls = append(urls, url)
}

b.Execution.Addresses = urls
Expand Down
198 changes: 198 additions & 0 deletions configs/benchmark_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
package configs

import (
"strings"
"testing"
)

func TestBenchmark_Validate(t *testing.T) {
tests := []struct {
name string
cfg Benchmark
want bool
wantErr bool
errMsg string
}{
{
name: "Valid config with consensus metrics",
cfg: Benchmark{
Consensus: Consensus{
Addresses: []string{"http://localhost:8545"},
Metrics: ConsensusMetrics{
Peers: Metric{Enabled: true},
},
},
Network: "mainnet",
},
want: true,
wantErr: false,
},
{
name: "Valid config with consensus metrics",
cfg: Benchmark{
Consensus: Consensus{
Addresses: []string{"http://localhost:8545"},
Metrics: ConsensusMetrics{
Peers: Metric{Enabled: true},
},
},
Network: "mainnet",
},
want: true,
wantErr: false,
},
{
name: "Valid config with execution metrics",
cfg: Benchmark{
Execution: Execution{
Addresses: []string{"http://localhost:8545"},
Metrics: ExecutionMetrics{
Peers: Metric{Enabled: true},
},
},
Network: "mainnet",
},
want: true,
wantErr: false,
},
{
name: "Valid config with SSV metrics",
cfg: Benchmark{
SSV: SSV{
Address: "http://localhost:8545",
Metrics: SSVMetrics{
Peers: Metric{Enabled: true},
},
},
Network: "mainnet",
},
want: true,
wantErr: false,
},
{
name: "Invalid network name",
cfg: Benchmark{
Network: "invalid",
},
want: false,
wantErr: true,
errMsg: "network name was not valid",
},
{
name: "Multiple consensus addresses with separator",
cfg: Benchmark{
Consensus: Consensus{
Addresses: []string{"http://localhost:8545;http://localhost:8546"},
Metrics: ConsensusMetrics{
Peers: Metric{Enabled: true},
},
},
Network: "mainnet",
},
want: true,
wantErr: false,
},
{
name: "Single consensus address",
cfg: Benchmark{
Consensus: Consensus{
Addresses: []string{"http://localhost:8545"},
Metrics: ConsensusMetrics{
Peers: Metric{Enabled: true},
},
},
Network: "mainnet",
},
want: true,
wantErr: false,
},
{
name: "Multiple separate consensus addresses",
cfg: Benchmark{
Consensus: Consensus{
Addresses: []string{"http://localhost:8545", "http://localhost:8546", "http://localhost:8547"},
Metrics: ConsensusMetrics{
Peers: Metric{Enabled: true},
},
},
Network: "mainnet",
},
want: true,
wantErr: false,
},
{
name: "Semicolon separated consensus addresses",
cfg: Benchmark{
Consensus: Consensus{
Addresses: []string{"http://localhost:8545;http://localhost:8546;http://localhost:8547"},
Metrics: ConsensusMetrics{
Peers: Metric{Enabled: true},
},
},
Network: "mainnet",
},
want: true,
wantErr: false,
},
{
name: "Single execution address",
cfg: Benchmark{
Execution: Execution{
Addresses: []string{"http://localhost:8545"},
Metrics: ExecutionMetrics{
Peers: Metric{Enabled: true},
},
},
Network: "mainnet",
},
want: true,
wantErr: false,
},
{
name: "Multiple separate execution addresses",
cfg: Benchmark{
Execution: Execution{
Addresses: []string{"http://localhost:8545", "http://localhost:8546", "http://localhost:8547"},
Metrics: ExecutionMetrics{
Peers: Metric{Enabled: true},
},
},
Network: "mainnet",
},
want: true,
wantErr: false,
},
{
name: "Semicolon separated execution addresses",
cfg: Benchmark{
Execution: Execution{
Addresses: []string{"http://localhost:8545;http://localhost:8546;http://localhost:8547"},
Metrics: ExecutionMetrics{
Peers: Metric{Enabled: true},
},
},
Network: "mainnet",
},
want: true,
wantErr: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := tt.cfg.Validate()
if (err != nil) != tt.wantErr {
t.Errorf("Benchmark.Validate() error = %v, wantErr %v", err, tt.wantErr)
return
}
if tt.wantErr && err != nil {
if !strings.Contains(err.Error(), tt.errMsg) {
t.Errorf("error message = %v, want to contain %v", err, tt.errMsg)
}
}
if got != tt.want {
t.Errorf("Benchmark.Validate() = %v, want %v", got, tt.want)
}
})
}
}
20 changes: 12 additions & 8 deletions configs/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ benchmark:
port: 8080

consensus:
# Can be a single address or a collection of addresses. Both formats are supported:
# `address: http://127.0.0.1:8080` and `address: [http://127.0.0.1:8080, http://127.0.0.2:8080]`.
address: []
# Can be a single address, a collection of addresses, or a multi-address string separated by semicolons (;). Supported formats:
# `address: http://127.0.0.1:8080`
# `address: [http://127.0.0.1:8080, http://127.0.0.2:8080]`
# `address: http://127.0.0.1:8080;http://127.0.0.2:8080`
address:
metrics:
client:
enabled: true
Expand All @@ -19,16 +21,18 @@ benchmark:
enabled: true

execution:
# Can be a single address or a collection of addresses. Both formats are supported:
# `address: http://127.0.0.1:8080` and `address: [http://127.0.0.1:8080, http://127.0.0.2:8080]`.
address: []
# Can be a single address, a collection of addresses, or a multi-address string separated by semicolons (;). Supported formats:
# `address: http://127.0.0.1:8080`
# `address: [http://127.0.0.1:8080, http://127.0.0.2:8080]`
# `address: http://127.0.0.1:8080;http://127.0.0.2:8080`
address:
metrics:
peers:
enabled: true

ssv:
address:
metrics:
address:
metrics:
peers:
enabled: true
connections:
Expand Down

0 comments on commit 4b437e7

Please sign in to comment.