mirror of
https://github.com/hatchet-dev/hatchet.git
synced 2026-03-06 07:58:35 -06:00
[hotfix] CLI arg to specify average duration per event threshold for loadtest to succeed (#2300)
* CLI arg to specify average duration per event threshold for loadtest to succeed * add tolerance * fix failing load go test
This commit is contained in:
@@ -13,7 +13,7 @@ type avgResult struct {
|
||||
}
|
||||
|
||||
func do(config LoadTestConfig) error {
|
||||
l.Info().Msgf("testing with duration=%s, eventsPerSecond=%d, delay=%s, wait=%s, concurrency=%d", config.Duration, config.Events, config.Delay, config.Wait, config.Concurrency)
|
||||
l.Info().Msgf("testing with duration=%s, eventsPerSecond=%d, delay=%s, wait=%s, concurrency=%d, averageDurationThreshold=%s", config.Duration, config.Events, config.Delay, config.Wait, config.Concurrency, config.AverageDurationThreshold)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
@@ -115,6 +115,17 @@ func do(config LoadTestConfig) error {
|
||||
return fmt.Errorf("❌ emitted and unique executed counts do not match: %d != %d", int64(config.EventFanout)*emitted, uniques)
|
||||
}
|
||||
|
||||
// Add a small tolerance (1% or 1ms, whichever is smaller)
|
||||
tolerance := config.AverageDurationThreshold / 100 // 1% tolerance
|
||||
if tolerance > time.Millisecond {
|
||||
tolerance = time.Millisecond
|
||||
}
|
||||
thresholdWithTolerance := config.AverageDurationThreshold + tolerance
|
||||
|
||||
if finalDurationResult.avg > thresholdWithTolerance {
|
||||
return fmt.Errorf("❌ average duration per executed event is greater than the threshold (with tolerance): %s > %s (threshold: %s, tolerance: %s)", finalDurationResult.avg, thresholdWithTolerance, config.AverageDurationThreshold, tolerance)
|
||||
}
|
||||
|
||||
log.Printf("✅ success")
|
||||
|
||||
return nil
|
||||
|
||||
@@ -36,110 +36,116 @@ func TestLoadCLI(t *testing.T) {
|
||||
{
|
||||
name: "test simple workflow",
|
||||
config: LoadTestConfig{
|
||||
Duration: 240 * time.Second,
|
||||
Events: 10,
|
||||
Delay: 0 * time.Second,
|
||||
Wait: 60 * time.Second,
|
||||
Concurrency: 0,
|
||||
Slots: 100,
|
||||
FailureRate: 0.0,
|
||||
PayloadSize: "0kb",
|
||||
EventFanout: 1,
|
||||
DagSteps: 1,
|
||||
RlKeys: 0,
|
||||
RlLimit: 0,
|
||||
RlDurationUnit: "",
|
||||
Duration: 240 * time.Second,
|
||||
Events: 10,
|
||||
Delay: 0 * time.Second,
|
||||
Wait: 60 * time.Second,
|
||||
Concurrency: 0,
|
||||
Slots: 100,
|
||||
FailureRate: 0.0,
|
||||
PayloadSize: "0kb",
|
||||
EventFanout: 1,
|
||||
DagSteps: 1,
|
||||
RlKeys: 0,
|
||||
RlLimit: 0,
|
||||
RlDurationUnit: "",
|
||||
AverageDurationThreshold: 200 * time.Millisecond,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "test with DAG",
|
||||
config: LoadTestConfig{
|
||||
Duration: 240 * time.Second,
|
||||
Events: 10,
|
||||
Delay: 0 * time.Second,
|
||||
Wait: 60 * time.Second,
|
||||
Concurrency: 0,
|
||||
Slots: 100,
|
||||
FailureRate: 0.0,
|
||||
PayloadSize: "0kb",
|
||||
EventFanout: 1,
|
||||
DagSteps: 2,
|
||||
RlKeys: 0,
|
||||
RlLimit: 0,
|
||||
RlDurationUnit: "",
|
||||
Duration: 240 * time.Second,
|
||||
Events: 10,
|
||||
Delay: 0 * time.Second,
|
||||
Wait: 60 * time.Second,
|
||||
Concurrency: 0,
|
||||
Slots: 100,
|
||||
FailureRate: 0.0,
|
||||
PayloadSize: "0kb",
|
||||
EventFanout: 1,
|
||||
DagSteps: 2,
|
||||
RlKeys: 0,
|
||||
RlLimit: 0,
|
||||
RlDurationUnit: "",
|
||||
AverageDurationThreshold: 200 * time.Millisecond,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "test with event fanout",
|
||||
config: LoadTestConfig{
|
||||
Duration: 240 * time.Second,
|
||||
Events: 10,
|
||||
Delay: 0 * time.Second,
|
||||
Wait: 60 * time.Second,
|
||||
Concurrency: 0,
|
||||
Slots: 100,
|
||||
FailureRate: 0.0,
|
||||
PayloadSize: "0kb",
|
||||
EventFanout: 2,
|
||||
DagSteps: 1,
|
||||
RlKeys: 0,
|
||||
RlLimit: 0,
|
||||
RlDurationUnit: "",
|
||||
Duration: 240 * time.Second,
|
||||
Events: 10,
|
||||
Delay: 0 * time.Second,
|
||||
Wait: 60 * time.Second,
|
||||
Concurrency: 0,
|
||||
Slots: 100,
|
||||
FailureRate: 0.0,
|
||||
PayloadSize: "0kb",
|
||||
EventFanout: 2,
|
||||
DagSteps: 1,
|
||||
RlKeys: 0,
|
||||
RlLimit: 0,
|
||||
RlDurationUnit: "",
|
||||
AverageDurationThreshold: 200 * time.Millisecond,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "test with global concurrency key",
|
||||
config: LoadTestConfig{
|
||||
Duration: 240 * time.Second,
|
||||
Events: 10,
|
||||
Delay: 0 * time.Second,
|
||||
Wait: 60 * time.Second,
|
||||
Concurrency: 10,
|
||||
Slots: 100,
|
||||
FailureRate: 0.0,
|
||||
PayloadSize: "0kb",
|
||||
EventFanout: 1,
|
||||
DagSteps: 1,
|
||||
RlKeys: 0,
|
||||
RlLimit: 0,
|
||||
RlDurationUnit: "",
|
||||
Duration: 240 * time.Second,
|
||||
Events: 10,
|
||||
Delay: 0 * time.Second,
|
||||
Wait: 60 * time.Second,
|
||||
Concurrency: 10,
|
||||
Slots: 100,
|
||||
FailureRate: 0.0,
|
||||
PayloadSize: "0kb",
|
||||
EventFanout: 1,
|
||||
DagSteps: 1,
|
||||
RlKeys: 0,
|
||||
RlLimit: 0,
|
||||
RlDurationUnit: "",
|
||||
AverageDurationThreshold: 200 * time.Millisecond,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "test for many queued events and little worker throughput",
|
||||
config: LoadTestConfig{
|
||||
Duration: 240 * time.Second,
|
||||
Events: 10,
|
||||
Delay: 0 * time.Second,
|
||||
WorkerDelay: 120 * time.Second, // will write 1200 events before the worker is ready
|
||||
Wait: 120 * time.Second,
|
||||
Concurrency: 0,
|
||||
Slots: 100,
|
||||
FailureRate: 0.0,
|
||||
PayloadSize: "0kb",
|
||||
EventFanout: 1,
|
||||
DagSteps: 1,
|
||||
RlKeys: 0,
|
||||
RlLimit: 0,
|
||||
RlDurationUnit: "",
|
||||
Duration: 240 * time.Second,
|
||||
Events: 10,
|
||||
Delay: 0 * time.Second,
|
||||
WorkerDelay: 120 * time.Second, // will write 1200 events before the worker is ready
|
||||
Wait: 120 * time.Second,
|
||||
Concurrency: 0,
|
||||
Slots: 100,
|
||||
FailureRate: 0.0,
|
||||
PayloadSize: "0kb",
|
||||
EventFanout: 1,
|
||||
DagSteps: 1,
|
||||
RlKeys: 0,
|
||||
RlLimit: 0,
|
||||
RlDurationUnit: "",
|
||||
AverageDurationThreshold: 200 * time.Millisecond,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "test with rate limits",
|
||||
config: LoadTestConfig{
|
||||
Duration: 240 * time.Second,
|
||||
Events: 10,
|
||||
Delay: 0 * time.Second,
|
||||
Wait: 60 * time.Second,
|
||||
Concurrency: 0,
|
||||
Slots: 100,
|
||||
FailureRate: 0.0,
|
||||
PayloadSize: "0kb",
|
||||
EventFanout: 1,
|
||||
DagSteps: 1,
|
||||
RlKeys: 10,
|
||||
RlLimit: 100,
|
||||
RlDurationUnit: "second",
|
||||
Duration: 240 * time.Second,
|
||||
Events: 10,
|
||||
Delay: 0 * time.Second,
|
||||
Wait: 60 * time.Second,
|
||||
Concurrency: 0,
|
||||
Slots: 100,
|
||||
FailureRate: 0.0,
|
||||
PayloadSize: "0kb",
|
||||
EventFanout: 1,
|
||||
DagSteps: 1,
|
||||
RlKeys: 10,
|
||||
RlLimit: 100,
|
||||
RlDurationUnit: "second",
|
||||
AverageDurationThreshold: 200 * time.Millisecond,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -19,21 +19,22 @@ var l zerolog.Logger
|
||||
|
||||
// LoadTestConfig holds all configuration for the load test
|
||||
type LoadTestConfig struct {
|
||||
Namespace string
|
||||
Events int
|
||||
Concurrency int
|
||||
Duration time.Duration
|
||||
Wait time.Duration
|
||||
Delay time.Duration
|
||||
WorkerDelay time.Duration
|
||||
Slots int
|
||||
FailureRate float32
|
||||
PayloadSize string
|
||||
EventFanout int
|
||||
DagSteps int
|
||||
RlKeys int
|
||||
RlLimit int
|
||||
RlDurationUnit string
|
||||
Namespace string
|
||||
Events int
|
||||
Concurrency int
|
||||
Duration time.Duration
|
||||
Wait time.Duration
|
||||
Delay time.Duration
|
||||
WorkerDelay time.Duration
|
||||
Slots int
|
||||
FailureRate float32
|
||||
PayloadSize string
|
||||
EventFanout int
|
||||
DagSteps int
|
||||
RlKeys int
|
||||
RlLimit int
|
||||
RlDurationUnit string
|
||||
AverageDurationThreshold time.Duration
|
||||
}
|
||||
|
||||
func main() {
|
||||
@@ -81,6 +82,7 @@ func main() {
|
||||
loadtest.Flags().IntVar(&config.RlLimit, "rlLimit", 0, "rlLimit specifies the rate limit")
|
||||
loadtest.Flags().StringVar(&config.RlDurationUnit, "rlDurationUnit", "second", "rlDurationUnit specifies the duration unit for the rate limit (second, minute, hour)")
|
||||
loadtest.Flags().StringVarP(&logLevel, "level", "l", "info", "logLevel specifies the log level (debug, info, warn, error)")
|
||||
loadtest.Flags().DurationVar(&config.AverageDurationThreshold, "averageDurationThreshold", 100*time.Millisecond, "averageDurationThreshold specifies the threshold for the average duration per executed event to be considered a success")
|
||||
|
||||
cmd := &cobra.Command{Use: "app"}
|
||||
cmd.AddCommand(loadtest)
|
||||
|
||||
Reference in New Issue
Block a user