106 lines
3.4 KiB
Go
106 lines
3.4 KiB
Go
package loadsim
|
|
|
|
import (
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Protocol string
|
|
|
|
const (
|
|
ProtocolGB32960 Protocol = "gb32960"
|
|
ProtocolJT808 Protocol = "jt808"
|
|
ProtocolYutongMQTT Protocol = "yutong-mqtt"
|
|
|
|
DefaultJT808PhoneBase int64 = 139000000000
|
|
maxJT808Phone int64 = 999999999999
|
|
)
|
|
|
|
type Config struct {
|
|
Protocol Protocol
|
|
Addr string
|
|
Connections int
|
|
ConnectRatePerSecond int
|
|
SendInterval time.Duration
|
|
Duration time.Duration
|
|
Template string
|
|
SendFrames bool
|
|
JT808PhoneBase int64
|
|
DrainResponses bool
|
|
}
|
|
|
|
type FlagConfig struct {
|
|
protocol string
|
|
addr string
|
|
connections int
|
|
connectRate int
|
|
sendInterval time.Duration
|
|
duration time.Duration
|
|
template string
|
|
sendFrames bool
|
|
jt808PhoneBase int64
|
|
drainResponses bool
|
|
}
|
|
|
|
func RegisterFlags(fs *flag.FlagSet) *FlagConfig {
|
|
cfg := &FlagConfig{}
|
|
fs.StringVar(&cfg.protocol, "protocol", string(ProtocolJT808), "protocol: jt808, gb32960, yutong-mqtt")
|
|
fs.StringVar(&cfg.addr, "addr", "", "target host:port")
|
|
fs.IntVar(&cfg.connections, "connections", 1, "target concurrent connections")
|
|
fs.IntVar(&cfg.connectRate, "connect-rate", 100, "new connections per second")
|
|
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")
|
|
fs.Int64Var(&cfg.jt808PhoneBase, "jt808-phone-base", DefaultJT808PhoneBase, "first synthetic JT808 phone; one consecutive phone is assigned per connection")
|
|
fs.BoolVar(&cfg.drainResponses, "drain-responses", true, "continuously read protocol responses while frames are being sent")
|
|
return cfg
|
|
}
|
|
|
|
func (c *FlagConfig) Build() (Config, error) {
|
|
protocol := Protocol(strings.ToLower(strings.TrimSpace(c.protocol)))
|
|
switch protocol {
|
|
case ProtocolGB32960, ProtocolJT808, ProtocolYutongMQTT:
|
|
default:
|
|
return Config{}, fmt.Errorf("unsupported protocol %q", c.protocol)
|
|
}
|
|
if strings.TrimSpace(c.addr) == "" {
|
|
return Config{}, errors.New("addr is required")
|
|
}
|
|
if c.connections <= 0 {
|
|
return Config{}, errors.New("connections must be positive")
|
|
}
|
|
if c.connectRate <= 0 {
|
|
return Config{}, errors.New("connect-rate must be positive")
|
|
}
|
|
if c.sendInterval <= 0 {
|
|
return Config{}, errors.New("send-interval must be positive")
|
|
}
|
|
if c.duration <= 0 {
|
|
return Config{}, errors.New("duration must be positive")
|
|
}
|
|
if protocol == ProtocolJT808 {
|
|
if c.jt808PhoneBase <= 0 || c.jt808PhoneBase > maxJT808Phone {
|
|
return Config{}, errors.New("jt808-phone-base must be a positive 12-digit-or-shorter number")
|
|
}
|
|
if int64(c.connections-1) > maxJT808Phone-c.jt808PhoneBase {
|
|
return Config{}, errors.New("jt808 synthetic phone range exceeds 12 digits")
|
|
}
|
|
}
|
|
return Config{
|
|
Protocol: protocol,
|
|
Addr: strings.TrimSpace(c.addr),
|
|
Connections: c.connections,
|
|
ConnectRatePerSecond: c.connectRate,
|
|
SendInterval: c.sendInterval,
|
|
Duration: c.duration,
|
|
Template: strings.TrimSpace(c.template),
|
|
SendFrames: c.sendFrames,
|
|
JT808PhoneBase: c.jt808PhoneBase,
|
|
DrainResponses: c.drainResponses,
|
|
}, nil
|
|
}
|