76 lines
2.7 KiB
Go
76 lines
2.7 KiB
Go
package loadgen
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestRunExecutesFixedBoundedHTTPWorkload(t *testing.T) {
|
|
var requests atomic.Int64
|
|
server := httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
|
|
if request.Method != http.MethodPost || request.Header.Get("X-Scenario") != "fixed" {
|
|
t.Errorf("request = %s %q", request.Method, request.Header.Get("X-Scenario"))
|
|
}
|
|
body, err := io.ReadAll(request.Body)
|
|
if err != nil || string(body) != `{"count":1}` {
|
|
t.Errorf("request body = %q, error = %v", body, err)
|
|
}
|
|
requests.Add(1)
|
|
response.WriteHeader(http.StatusNoContent)
|
|
}))
|
|
defer server.Close()
|
|
|
|
report, err := Run(context.Background(), Options{
|
|
TargetURL: server.URL, Method: http.MethodPost, Headers: http.Header{"X-Scenario": {"fixed"}}, RequestBody: []byte(`{"count":1}`),
|
|
Requests: 12, Concurrency: 3, RequestTimeout: time.Second,
|
|
})
|
|
if err != nil || report.Requests != 12 || report.Completed != 12 || report.Succeeded != 12 || report.Failed != 0 ||
|
|
requests.Load() != 12 || report.Latency.P50UpperBound <= 0 || report.Runtime.NumCPU <= 0 {
|
|
t.Fatalf("Run() = (%+v, %v); handler requests=%d", report, err, requests.Load())
|
|
}
|
|
}
|
|
|
|
func TestRunClassifiesHTTPFailure(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, _ *http.Request) {
|
|
response.WriteHeader(http.StatusServiceUnavailable)
|
|
}))
|
|
defer server.Close()
|
|
|
|
report, err := Run(context.Background(), Options{
|
|
TargetURL: server.URL, Requests: 1, Concurrency: 1, RequestTimeout: time.Second,
|
|
})
|
|
if err != nil || report.Succeeded != 0 || report.Failed != 1 || report.Status5xx != 1 || report.Completed != 1 {
|
|
t.Fatalf("Run() = (%+v, %v)", report, err)
|
|
}
|
|
}
|
|
|
|
func TestRunTimeBoxedRateIsBounded(t *testing.T) {
|
|
var requests atomic.Int64
|
|
server := httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, _ *http.Request) {
|
|
requests.Add(1)
|
|
response.WriteHeader(http.StatusNoContent)
|
|
}))
|
|
defer server.Close()
|
|
|
|
report, err := Run(context.Background(), Options{
|
|
TargetURL: server.URL, Duration: 100 * time.Millisecond, Rate: 100, Concurrency: 2, RequestTimeout: time.Second,
|
|
})
|
|
if err != nil || report.Requests == 0 || report.Requests > 20 || report.Requests != report.Completed ||
|
|
report.Succeeded != report.Completed || requests.Load() != int64(report.Requests) {
|
|
t.Fatalf("Run() = (%+v, %v); handler requests=%d", report, err, requests.Load())
|
|
}
|
|
}
|
|
|
|
func TestRunRejectsUnboundedWorkload(t *testing.T) {
|
|
_, err := Run(context.Background(), Options{TargetURL: "http://127.0.0.1:8080", Concurrency: 1})
|
|
if !errors.Is(err, ErrInvalidOptions) {
|
|
t.Fatalf("Run(unbounded) error = %v, want ErrInvalidOptions", err)
|
|
}
|
|
}
|