Skip to content

Commit 4beeef7

Browse files
Fix profiles settings structure (#17)
- settings required a nesting structure - profile jsons didn't align with that
1 parent b32592d commit 4beeef7

9 files changed

Lines changed: 254 additions & 50 deletions

File tree

config/config.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package config
22

33
import (
4+
"encoding/json"
5+
"fmt"
46
"math/big"
7+
"time"
58
)
69

710
// LoadConfig stores the configuration for load-related settings.
@@ -16,6 +19,33 @@ type LoadConfig struct {
1619
Settings *Settings `json:"settings,omitempty"`
1720
}
1821

22+
// Duration wraps time.Duration to provide JSON unmarshaling support
23+
type Duration time.Duration
24+
25+
// UnmarshalJSON implements json.Unmarshaler for Duration
26+
func (d *Duration) UnmarshalJSON(data []byte) error {
27+
var s string
28+
if err := json.Unmarshal(data, &s); err != nil {
29+
return err
30+
}
31+
parsed, err := time.ParseDuration(s)
32+
if err != nil {
33+
return fmt.Errorf("invalid duration format: %w", err)
34+
}
35+
*d = Duration(parsed)
36+
return nil
37+
}
38+
39+
// ToDuration converts Duration back to time.Duration
40+
func (d Duration) ToDuration() time.Duration {
41+
return time.Duration(d)
42+
}
43+
44+
// MarshalJSON implements json.Marshaler for Duration
45+
func (d Duration) MarshalJSON() ([]byte, error) {
46+
return json.Marshal(time.Duration(d).String())
47+
}
48+
1949
// GetChainID returns the chain ID as a big.Int.
2050
func (c *LoadConfig) GetChainID() *big.Int {
2151
return big.NewInt(c.ChainID)

config/settings.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
type Settings struct {
1313
Workers int `json:"workers"`
1414
TPS float64 `json:"tps"`
15-
StatsInterval time.Duration `json:"statsInterval"`
15+
StatsInterval Duration `json:"statsInterval"`
1616
BufferSize int `json:"bufferSize"`
1717
DryRun bool `json:"dryRun"`
1818
Debug bool `json:"debug"`
@@ -28,7 +28,7 @@ func DefaultSettings() Settings {
2828
return Settings{
2929
Workers: 1,
3030
TPS: 0.0,
31-
StatsInterval: 10 * time.Second,
31+
StatsInterval: Duration(10 * time.Second),
3232
BufferSize: 1000,
3333
DryRun: false,
3434
Debug: false,
@@ -65,7 +65,7 @@ func InitializeViper(cmd *cobra.Command) error {
6565

6666
// Set defaults in Viper
6767
defaults := DefaultSettings()
68-
viper.SetDefault("statsInterval", defaults.StatsInterval)
68+
viper.SetDefault("statsInterval", defaults.StatsInterval.ToDuration())
6969
viper.SetDefault("bufferSize", defaults.BufferSize)
7070
viper.SetDefault("tps", defaults.TPS)
7171
viper.SetDefault("dryRun", defaults.DryRun)
@@ -98,7 +98,7 @@ func ResolveSettings() Settings {
9898
return Settings{
9999
Workers: viper.GetInt("workers"),
100100
TPS: viper.GetFloat64("tps"),
101-
StatsInterval: viper.GetDuration("statsInterval"),
101+
StatsInterval: Duration(viper.GetDuration("statsInterval")),
102102
BufferSize: viper.GetInt("bufferSize"),
103103
DryRun: viper.GetBool("dryRun"),
104104
Debug: viper.GetBool("debug"),

config/settings_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func TestArgumentPrecedence(t *testing.T) {
108108
settings := ResolveSettings()
109109

110110
// Verify expectations
111-
require.Equal(t, tt.expectedStats, settings.StatsInterval, "StatsInterval: expected %v, got %v", tt.expectedStats, settings.StatsInterval)
111+
require.Equal(t, tt.expectedStats, settings.StatsInterval.ToDuration(), "StatsInterval: expected %v, got %v", tt.expectedStats, settings.StatsInterval.ToDuration())
112112
require.Equal(t, tt.expectedWorkers, settings.Workers, "Workers: expected %d, got %d", tt.expectedWorkers, settings.Workers)
113113
require.Equal(t, tt.expectedTPS, settings.TPS, "TPS: expected %f, got %f", tt.expectedTPS, settings.TPS)
114114
})
@@ -121,7 +121,7 @@ func TestDefaultSettings(t *testing.T) {
121121
expected := Settings{
122122
Workers: 1,
123123
TPS: 0.0,
124-
StatsInterval: 10 * time.Second,
124+
StatsInterval: Duration(10 * time.Second),
125125
BufferSize: 1000,
126126
DryRun: false,
127127
Debug: false,

main.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ func runLoadTest(ctx context.Context, cmd *cobra.Command, args []string) error {
113113
log.Printf("👥 Workers per endpoint: %d", settings.Workers)
114114
log.Printf("🔧 Total workers: %d", len(cfg.Endpoints)*settings.Workers)
115115
log.Printf("📊 Scenarios: %d", len(cfg.Scenarios))
116-
log.Printf("⏱️ Stats interval: %v", settings.StatsInterval)
116+
log.Printf("⏱️ Stats interval: %v", settings.StatsInterval.ToDuration())
117117
log.Printf("📦 Buffer size per worker: %d", settings.BufferSize)
118118
if settings.TPS > 0 {
119119
log.Printf("📈 Transactions per second: %.2f", settings.TPS)
@@ -148,7 +148,7 @@ func runLoadTest(ctx context.Context, cmd *cobra.Command, args []string) error {
148148

149149
// Create statistics collector and logger
150150
collector := stats.NewCollector()
151-
logger := stats.NewLogger(collector, settings.StatsInterval, settings.Debug)
151+
logger := stats.NewLogger(collector, settings.StatsInterval.ToDuration(), settings.Debug)
152152
var ramper *sender.Ramper
153153

154154
err = service.Run(ctx, func(ctx context.Context, s service.Scope) error {
@@ -200,7 +200,7 @@ func runLoadTest(ctx context.Context, cmd *cobra.Command, args []string) error {
200200

201201
// Create and start user latency tracker if endpoints are available
202202
if len(cfg.Endpoints) > 0 && settings.TrackUserLatency {
203-
userLatencyTracker := stats.NewUserLatencyTracker(settings.StatsInterval)
203+
userLatencyTracker := stats.NewUserLatencyTracker(settings.StatsInterval.ToDuration())
204204
s.SpawnBgNamed("user latency tracker", func() error {
205205
return userLatencyTracker.Run(ctx, cfg.Endpoints[0])
206206
})
@@ -261,7 +261,7 @@ func runLoadTest(ctx context.Context, cmd *cobra.Command, args []string) error {
261261
sigChan := make(chan os.Signal, 1)
262262
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
263263

264-
log.Printf("📈 Logging statistics every %v (Press Ctrl+C to stop)", settings.StatsInterval)
264+
log.Printf("📈 Logging statistics every %v (Press Ctrl+C to stop)", settings.StatsInterval.ToDuration())
265265
if settings.DryRun {
266266
log.Printf("📝 Dry-run mode: Simulating requests without sending")
267267
}

profiles/evm_transfer.json

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,17 @@
1414
"weight": 1
1515
}
1616
],
17-
"workers": 1,
18-
"tps": 0,
19-
"statsInterval": "5s",
20-
"bufferSize": 1000,
21-
"dryRun": false,
22-
"debug": false,
23-
"trackReceipts": false,
24-
"trackBlocks": false,
25-
"trackUserLatency": false,
26-
"prewarm": false
17+
"settings": {
18+
"workers": 1,
19+
"tps": 0,
20+
"statsInterval": "5s",
21+
"bufferSize": 1000,
22+
"dryRun": false,
23+
"debug": false,
24+
"trackReceipts": false,
25+
"trackBlocks": false,
26+
"trackUserLatency": false,
27+
"prewarm": false,
28+
"rampUp": false
29+
}
2730
}

profiles/loadtest_default.json

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,17 @@
3030
"weight": 1
3131
}
3232
],
33-
"workers": 1,
34-
"tps": 0,
35-
"statsInterval": "5s",
36-
"bufferSize": 1000,
37-
"dryRun": false,
38-
"debug": false,
39-
"trackReceipts": false,
40-
"trackBlocks": false,
41-
"trackUserLatency": false,
42-
"prewarm": false
33+
"settings": {
34+
"workers": 1,
35+
"tps": 0,
36+
"statsInterval": "5s",
37+
"bufferSize": 1000,
38+
"dryRun": false,
39+
"debug": false,
40+
"trackReceipts": false,
41+
"trackBlocks": false,
42+
"trackUserLatency": false,
43+
"prewarm": false,
44+
"rampUp": false
45+
}
4346
}

profiles/local.json

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,17 @@
3030
"weight": 1
3131
}
3232
],
33-
"workers": 1,
34-
"tps": 0,
35-
"statsInterval": "5s",
36-
"bufferSize": 1000,
37-
"dryRun": false,
38-
"debug": false,
39-
"trackReceipts": false,
40-
"trackBlocks": false,
41-
"trackUserLatency": false,
42-
"prewarm": false
33+
"settings": {
34+
"workers": 1,
35+
"tps": 0,
36+
"statsInterval": "5s",
37+
"bufferSize": 1000,
38+
"dryRun": false,
39+
"debug": false,
40+
"trackReceipts": false,
41+
"trackBlocks": false,
42+
"trackUserLatency": false,
43+
"prewarm": false,
44+
"rampUp": false
45+
}
4346
}

profiles/local_docker.json

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,17 @@
1717
"weight": 1
1818
}
1919
],
20-
"workers": 1,
21-
"tps": 0,
22-
"statsInterval": "5s",
23-
"bufferSize": 1000,
24-
"dryRun": false,
25-
"debug": false,
26-
"trackReceipts": false,
27-
"trackBlocks": false,
28-
"trackUserLatency": false,
29-
"prewarm": false
20+
"settings": {
21+
"workers": 1,
22+
"tps": 0,
23+
"statsInterval": "5s",
24+
"bufferSize": 1000,
25+
"dryRun": false,
26+
"debug": false,
27+
"trackReceipts": false,
28+
"trackBlocks": false,
29+
"trackUserLatency": false,
30+
"prewarm": false,
31+
"rampUp": false
32+
}
3033
}

0 commit comments

Comments
 (0)