Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ lk perf agent-load-test \
--agent-name test-agent \
--echo-speech-delay 10s \
--duration 5m
--attribute key1=value1
```

The above simulates 5 concurrent rooms, where each room has:
Expand Down
40 changes: 40 additions & 0 deletions cmd/lk/perf.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package main

import (
"context"
"encoding/json"
"log"
"maps"
"os"
"time"

"github.com/go-logr/logr"
Expand Down Expand Up @@ -107,6 +110,15 @@ var (
Usage: "`TIME` duration to run, 1m, 1h (by default will run until canceled)",
Value: 0,
},
&cli.StringSliceFlag{
Name: "attribute",
Usage: "set attributes in key=value format, can be used multiple times",
},
&cli.StringFlag{
Name: "attribute-file",
Usage: "read attributes from a `JSON` file",
TakesFile: true,
},
},
},
},
Expand Down Expand Up @@ -236,6 +248,33 @@ func agentLoadTest(ctx context.Context, cmd *cli.Command) error {
}
_ = raiseULimit()

participantAttributes, err := parseKeyValuePairs(cmd, "attribute")
if err != nil {
log.Printf("failed to parse participant attributes: %v", err)
return err
}

// Read attributes from JSON file if specified
if attrFile := cmd.String("attribute-file"); attrFile != "" {
fileData, err := os.ReadFile(attrFile)
if err != nil {
log.Printf("failed to read attribute file: %v", err)
return err
}

var fileAttrs map[string]string
if err := json.Unmarshal(fileData, &fileAttrs); err != nil {
log.Printf("failed to parse attribute file as JSON: %v", err)
return err
}

// Add attributes from file to the existing ones
if participantAttributes == nil {
participantAttributes = make(map[string]string)
}
maps.Copy(participantAttributes, fileAttrs)
}

params := loadtester.AgentLoadTestParams{
URL: pc.URL,
APIKey: pc.APIKey,
Expand All @@ -244,6 +283,7 @@ func agentLoadTest(ctx context.Context, cmd *cli.Command) error {
AgentName: cmd.String("agent-name"),
EchoSpeechDelay: cmd.Duration("echo-speech-delay"),
Duration: cmd.Duration("duration"),
ParticipantAttributes: participantAttributes,
}

test := loadtester.NewAgentLoadTest(params)
Expand Down
1 change: 1 addition & 0 deletions pkg/loadtester/agentloadtest.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type AgentLoadTestParams struct {
URL string
APIKey string
APISecret string
ParticipantAttributes map[string]string
}

type AgentLoadTest struct {
Expand Down
1 change: 1 addition & 0 deletions pkg/loadtester/agentloadtester.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ func (r *LoadTestRoom) start(roomName string) error {
APISecret: r.params.APISecret,
RoomName: roomName,
ParticipantIdentity: identity,
ParticipantAttributes: r.params.ParticipantAttributes,
})
if err == nil {
break
Expand Down
Loading