add ramp and change seconds to microseconds

This commit is contained in:
cubixle
2021-08-04 19:36:59 +01:00
parent cb8d79fca3
commit 4cde4072b9
6 changed files with 37 additions and 27 deletions

View File

@@ -11,7 +11,7 @@ func main() {
l1.WithTarget("https://remoteukjobs.com"), l1.WithTarget("https://remoteukjobs.com"),
l1.WithRunFunc(l1.DefaultHTTPTester), l1.WithRunFunc(l1.DefaultHTTPTester),
l1.WithMaxParrellConns(10), l1.WithMaxParrellConns(10),
l1.WithMaxConns(6000), l1.WithMaxConns(30),
) )
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)

View File

@@ -17,12 +17,15 @@ func DefaultHTTPTester(target string) *Result {
return result return result
} }
req.Header.Add("accept-encoding", "gzip, deflate, br")
req.Header.Add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0")
startTime := time.Now() startTime := time.Now()
rsp, err := client.Do(req) rsp, err := client.Do(req)
if err != nil { if err != nil {
result.Error = err result.Error = err
} }
result.CompletedIn = time.Since(startTime).Seconds() result.CompletedIn = float64(time.Since(startTime).Milliseconds())
result.StatusCode = rsp.StatusCode result.StatusCode = rsp.StatusCode
return result return result

12
l1.go
View File

@@ -15,6 +15,7 @@ type Runner struct {
RunTime time.Duration RunTime time.Duration
RunFunc F RunFunc F
Target string Target string
RampUp int
results []*Result results []*Result
} }
@@ -24,6 +25,7 @@ func NewRunner(opts ...Opt) (*Runner, error) {
Timeout: 30 * time.Second, Timeout: 30 * time.Second,
MaxParrellConnections: 10, MaxParrellConnections: 10,
MaxConnections: 10, MaxConnections: 10,
RampUp: 0,
} }
for _, o := range opts { for _, o := range opts {
@@ -46,10 +48,18 @@ func (r *Runner) Execute() {
for i := 0; i < r.MaxConnections; i++ { for i := 0; i < r.MaxConnections; i++ {
tasks = append(tasks, &Task{Target: r.Target, F: r.RunFunc}) tasks = append(tasks, &Task{Target: r.Target, F: r.RunFunc})
} }
waitDuration := 0
if r.RampUp > 0 {
waitDuration = r.RampUp / len(tasks)
}
// create the pool and process the tasks. // create the pool and process the tasks.
pool := newPool(tasks, r.MaxParrellConnections) pool := newPool(tasks, r.MaxParrellConnections, waitDuration)
// the tasks are updated in memory so we don't expect a return here. // the tasks are updated in memory so we don't expect a return here.
pool.run() pool.run()
for _, t := range tasks { for _, t := range tasks {
r.results = append(r.results, t.Result) r.results = append(r.results, t.Result)
} }

View File

@@ -40,3 +40,9 @@ func WithRunFunc(f F) Opt {
r.RunFunc = f r.RunFunc = f
} }
} }
func WithRampUp(seconds int) Opt {
return func(r *Runner) {
r.RampUp = seconds
}
}

View File

@@ -2,6 +2,7 @@ package l1
import ( import (
"sync" "sync"
"time"
) )
type Task struct { type Task struct {
@@ -13,16 +14,18 @@ type Task struct {
type pool struct { type pool struct {
tasks []*Task tasks []*Task
concurrency int concurrency int
rampUpDuration int
tasksChan chan *Task tasksChan chan *Task
wg sync.WaitGroup wg sync.WaitGroup
} }
func newPool(tasks []*Task, concurrency int) *pool { func newPool(tasks []*Task, concurrency, rampUpDuration int) *pool {
return &pool{ return &pool{
tasks: tasks, tasks: tasks,
concurrency: concurrency, concurrency: concurrency,
tasksChan: make(chan *Task), tasksChan: make(chan *Task),
rampUpDuration: rampUpDuration,
} }
} }
@@ -32,9 +35,11 @@ func (p *pool) run() {
go p.work() go p.work()
} }
p.wg.Add(len(p.tasks))
for _, t := range p.tasks { for _, t := range p.tasks {
p.tasksChan <- t p.tasksChan <- t
p.wg.Add(1)
time.Sleep(time.Duration((1000 * p.rampUpDuration) * int(time.Millisecond)))
} }
close(p.tasksChan) close(p.tasksChan)

View File

@@ -20,14 +20,7 @@ type Result struct {
} }
func (r *results) RequestPerSecond() float64 { func (r *results) RequestPerSecond() float64 {
totalCompletedIn := float64(0) totalCompletedIn := r.CompletedTime() / 1000
for _, res := range r.Results {
if res.Error != nil {
continue
}
totalCompletedIn += res.CompletedIn
}
return float64(len(r.Results)) / totalCompletedIn return float64(len(r.Results)) / totalCompletedIn
} }
@@ -62,14 +55,7 @@ func (r *results) SuccessfulCount() int {
} }
func (r *results) AvgResponseTime() float64 { func (r *results) AvgResponseTime() float64 {
totalCompletedIn := float64(0) totalCompletedIn := r.CompletedTime()
for _, res := range r.Results {
if res.Error != nil {
continue
}
totalCompletedIn += res.CompletedIn
}
return totalCompletedIn / float64(len(r.Results)) return totalCompletedIn / float64(len(r.Results))
} }
@@ -97,7 +83,7 @@ func (r *results) Print() {
fmt.Printf("Load testing %s\n", r.Target) fmt.Printf("Load testing %s\n", r.Target)
fmt.Println("") fmt.Println("")
fmt.Printf("Request per second: %.2f\n", r.RequestPerSecond()) fmt.Printf("Request per second: %.2f\n", r.RequestPerSecond())
fmt.Printf("Average response time: %.2f seconds\n", r.AvgResponseTime()) fmt.Printf("Average response time: %.0f ms\n", r.AvgResponseTime())
fmt.Printf("Success count: %d\n", r.SuccessfulCount()) fmt.Printf("Success count: %d\n", r.SuccessfulCount())
fmt.Printf("Error count: %d\n", r.ErrorCount()) fmt.Printf("Error count: %d\n", r.ErrorCount())
fmt.Println("") fmt.Println("")