feat(go): add load simulator hold mode
This commit is contained in:
@@ -24,6 +24,7 @@ type Config struct {
|
||||
SendInterval time.Duration
|
||||
Duration time.Duration
|
||||
Template string
|
||||
SendFrames bool
|
||||
}
|
||||
|
||||
type FlagConfig struct {
|
||||
@@ -34,6 +35,7 @@ type FlagConfig struct {
|
||||
sendInterval time.Duration
|
||||
duration time.Duration
|
||||
template string
|
||||
sendFrames bool
|
||||
}
|
||||
|
||||
func RegisterFlags(fs *flag.FlagSet) *FlagConfig {
|
||||
@@ -45,6 +47,7 @@ func RegisterFlags(fs *flag.FlagSet) *FlagConfig {
|
||||
fs.DurationVar(&cfg.sendInterval, "send-interval", 10*time.Second, "frame send interval per connection")
|
||||
fs.DurationVar(&cfg.duration, "duration", 10*time.Minute, "load test duration")
|
||||
fs.StringVar(&cfg.template, "template", "", "frame template name")
|
||||
fs.BoolVar(&cfg.sendFrames, "send", true, "send protocol frames while connections are open")
|
||||
return cfg
|
||||
}
|
||||
|
||||
@@ -78,5 +81,6 @@ func (c *FlagConfig) Build() (Config, error) {
|
||||
SendInterval: c.sendInterval,
|
||||
Duration: c.duration,
|
||||
Template: strings.TrimSpace(c.template),
|
||||
SendFrames: c.sendFrames,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ func TestConfigFromFlagsParsesCapacityKnobs(t *testing.T) {
|
||||
"-send-interval", "5s",
|
||||
"-duration", "30m",
|
||||
"-template", "0200",
|
||||
"-send=false",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("parse flags: %v", err)
|
||||
@@ -49,6 +50,9 @@ func TestConfigFromFlagsParsesCapacityKnobs(t *testing.T) {
|
||||
if got.Template != "0200" {
|
||||
t.Fatalf("Template = %q", got.Template)
|
||||
}
|
||||
if got.SendFrames {
|
||||
t.Fatal("SendFrames = true, want false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigFromFlagsRejectsUnsafeValues(t *testing.T) {
|
||||
|
||||
@@ -37,6 +37,9 @@ func (r Runner) Run(ctx context.Context, cfg Config) (Stats, error) {
|
||||
if err != nil {
|
||||
return Stats{}, err
|
||||
}
|
||||
if !cfg.SendFrames {
|
||||
payload = nil
|
||||
}
|
||||
dial := r.Dial
|
||||
if dial == nil {
|
||||
dialer := &net.Dialer{Timeout: 5 * time.Second, KeepAlive: 30 * time.Second}
|
||||
@@ -68,7 +71,11 @@ func (r Runner) Run(ctx context.Context, cfg Config) (Stats, error) {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
defer conn.Close()
|
||||
writeLoop(runCtx, conn, payload, cfg.SendInterval, &stats)
|
||||
if cfg.SendFrames {
|
||||
writeLoop(runCtx, conn, payload, cfg.SendInterval, &stats)
|
||||
return
|
||||
}
|
||||
<-runCtx.Done()
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ func TestRunnerDialsTargetConnectionsAndWritesFrames(t *testing.T) {
|
||||
SendInterval: time.Millisecond,
|
||||
Duration: 5 * time.Millisecond,
|
||||
Template: "0200",
|
||||
SendFrames: true,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Run() error = %v", err)
|
||||
@@ -53,6 +54,41 @@ func TestRunnerDialsTargetConnectionsAndWritesFrames(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunnerCanHoldConnectionsWithoutWritingFrames(t *testing.T) {
|
||||
var writes atomic.Int64
|
||||
runner := Runner{
|
||||
Dial: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
return &recordingConn{
|
||||
write: func(p []byte) (int, error) {
|
||||
writes.Add(1)
|
||||
return len(p), nil
|
||||
},
|
||||
close: func() error { return nil },
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
||||
stats, err := runner.Run(context.Background(), Config{
|
||||
Protocol: ProtocolJT808,
|
||||
Addr: "127.0.0.1:808",
|
||||
Connections: 2,
|
||||
ConnectRatePerSecond: 1000,
|
||||
SendInterval: time.Millisecond,
|
||||
Duration: 5 * time.Millisecond,
|
||||
Template: "0200",
|
||||
SendFrames: false,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Run() error = %v", err)
|
||||
}
|
||||
if stats.ConnectionsOpened != 2 {
|
||||
t.Fatalf("ConnectionsOpened = %d, want 2", stats.ConnectionsOpened)
|
||||
}
|
||||
if stats.FramesWritten != 0 || writes.Load() != 0 {
|
||||
t.Fatalf("frames written stats=%d writes=%d, want 0", stats.FramesWritten, writes.Load())
|
||||
}
|
||||
}
|
||||
|
||||
type recordingConn struct {
|
||||
write func([]byte) (int, error)
|
||||
close func() error
|
||||
|
||||
Reference in New Issue
Block a user