Tests
This commit is contained in:
parent
c888c47742
commit
0a2d95652f
5 changed files with 165 additions and 36 deletions
|
@ -6,57 +6,44 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PerformanceMetrics holds the metrics for performance evaluation.
|
||||
type PerformanceMetrics struct {
|
||||
mu sync.Mutex // Protects the metrics
|
||||
|
||||
totalRequests int32
|
||||
totalResponses int32
|
||||
totalLatency time.Duration
|
||||
maxLatency time.Duration
|
||||
minLatency time.Duration
|
||||
responseCounters map[int]int32
|
||||
}
|
||||
|
||||
// Initialize the metrics with default values.
|
||||
var metrics = PerformanceMetrics{
|
||||
minLatency: time.Duration(math.MaxInt64),
|
||||
responseCounters: make(map[int]int32),
|
||||
MinLatency: time.Duration(math.MaxInt64),
|
||||
ResponseCounters: make(map[int]int32),
|
||||
}
|
||||
|
||||
// updateMetrics updates the performance metrics.
|
||||
func UpdateMetrics(duration time.Duration, resp *http.Response, second int) {
|
||||
metrics.mu.Lock()
|
||||
defer metrics.mu.Unlock()
|
||||
metrics.Mu.Lock()
|
||||
defer metrics.Mu.Unlock()
|
||||
|
||||
metrics.totalRequests++
|
||||
metrics.totalLatency += duration
|
||||
if duration > metrics.maxLatency {
|
||||
metrics.maxLatency = duration
|
||||
metrics.TotalRequests++
|
||||
metrics.TotalLatency += duration
|
||||
if duration > metrics.MaxLatency {
|
||||
metrics.MaxLatency = duration
|
||||
}
|
||||
if duration < metrics.minLatency {
|
||||
metrics.minLatency = duration
|
||||
if duration < metrics.MinLatency {
|
||||
metrics.MinLatency = duration
|
||||
}
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
metrics.totalResponses++
|
||||
metrics.responseCounters[second]++
|
||||
metrics.TotalResponses++
|
||||
metrics.ResponseCounters[second]++
|
||||
}
|
||||
}
|
||||
|
||||
// calculateAndPrintMetrics calculates and prints the performance metrics.
|
||||
func CalculateAndPrintMetrics(startTime time.Time, requestsPerSecond float64, endpoint string, verb string) {
|
||||
averageLatency := time.Duration(0)
|
||||
if metrics.totalRequests > 0 {
|
||||
averageLatency = metrics.totalLatency / time.Duration(metrics.totalRequests)
|
||||
if metrics.TotalRequests > 0 {
|
||||
averageLatency = metrics.TotalLatency / time.Duration(metrics.TotalRequests)
|
||||
}
|
||||
|
||||
totalDuration := time.Since(startTime).Seconds()
|
||||
totalResponses := int32(0)
|
||||
for _, count := range metrics.responseCounters {
|
||||
for _, count := range metrics.ResponseCounters {
|
||||
totalResponses += count
|
||||
}
|
||||
|
||||
|
@ -65,11 +52,11 @@ func CalculateAndPrintMetrics(startTime time.Time, requestsPerSecond float64, en
|
|||
results += fmt.Sprintf("HTTP Verb: %s\n", verb)
|
||||
results += fmt.Sprintln("--------------------")
|
||||
results += fmt.Sprintln("Performance Metrics:")
|
||||
results += fmt.Sprintf("Total Requests Sent: %d\n", metrics.totalRequests)
|
||||
results += fmt.Sprintf("Total Requests Sent: %d\n", metrics.TotalRequests)
|
||||
results += fmt.Sprintf("Total Responses Received: %d\n", totalResponses)
|
||||
results += fmt.Sprintf("Average Latency: %s\n", averageLatency)
|
||||
results += fmt.Sprintf("Max Latency: %s\n", metrics.maxLatency)
|
||||
results += fmt.Sprintf("Min Latency: %s\n", metrics.minLatency)
|
||||
results += fmt.Sprintf("Max Latency: %s\n", metrics.MaxLatency)
|
||||
results += fmt.Sprintf("Min Latency: %s\n", metrics.MinLatency)
|
||||
results += fmt.Sprintf("Requests Per Second (Sent): %.2f\n", float64(requestsPerSecond))
|
||||
results += fmt.Sprintf("Responses Per Second (Received): %.2f\n", float64(totalResponses)/totalDuration)
|
||||
|
||||
|
|
73
lib/metrics_test.go
Normal file
73
lib/metrics_test.go
Normal file
|
@ -0,0 +1,73 @@
|
|||
package lib_test
|
||||
|
||||
import (
|
||||
"loadr/lib"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func comparePerformanceMetrics(a, b *lib.PerformanceMetrics) bool {
|
||||
return a.TotalRequests == b.TotalRequests &&
|
||||
a.TotalResponses == b.TotalResponses &&
|
||||
a.TotalLatency == b.TotalLatency &&
|
||||
a.MaxLatency == b.MaxLatency &&
|
||||
a.MinLatency == b.MinLatency &&
|
||||
reflect.DeepEqual(a.ResponseCounters, b.ResponseCounters)
|
||||
}
|
||||
|
||||
func TestCalculateAndPrintMetrics(t *testing.T) {
|
||||
// Define test cases.
|
||||
tests := []struct {
|
||||
name string
|
||||
startTime time.Time
|
||||
requestsPerSecond float64
|
||||
endpoint string
|
||||
verb string
|
||||
expectedMetrics lib.PerformanceMetrics
|
||||
}{
|
||||
{
|
||||
name: "Test 1",
|
||||
startTime: time.Now().Add(-1 * time.Second), // 1 second ago
|
||||
requestsPerSecond: 1.0,
|
||||
endpoint: "http://localhost",
|
||||
verb: "GET",
|
||||
expectedMetrics: lib.PerformanceMetrics{
|
||||
TotalRequests: 1,
|
||||
TotalResponses: 1,
|
||||
TotalLatency: 1 * time.Second,
|
||||
MaxLatency: 1 * time.Second,
|
||||
MinLatency: 1 * time.Second,
|
||||
ResponseCounters: map[int]int32{1: 1},
|
||||
},
|
||||
},
|
||||
// Add more test cases as needed.
|
||||
}
|
||||
|
||||
for i := range tests {
|
||||
tt := &tests[i]
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Reset the metrics before each test
|
||||
metrics := lib.PerformanceMetrics{}
|
||||
|
||||
// Mock the system behavior
|
||||
metrics.TotalRequests++
|
||||
metrics.ResponseCounters = make(map[int]int32)
|
||||
metrics.TotalResponses++
|
||||
metrics.TotalLatency += 1 * time.Second
|
||||
metrics.MaxLatency = 1 * time.Second
|
||||
metrics.MinLatency = 1 * time.Second
|
||||
metrics.ResponseCounters[1]++
|
||||
|
||||
// Call the function
|
||||
lib.CalculateAndPrintMetrics(tt.startTime, tt.requestsPerSecond, tt.endpoint, tt.verb)
|
||||
|
||||
// Check if the metrics are correct
|
||||
if !comparePerformanceMetrics(&metrics, &tt.expectedMetrics) {
|
||||
t.Errorf("CalculateAndPrintMetrics() = TotalRequests: %v, TotalResponses: %v, TotalLatency: %v, MaxLatency: %v, MinLatency: %v, ResponseCounters: %v, want TotalRequests: %v, TotalResponses: %v, TotalLatency: %v, MaxLatency: %v, MinLatency: %v, ResponseCounters: %v",
|
||||
metrics.TotalRequests, metrics.TotalResponses, metrics.TotalLatency, metrics.MaxLatency, metrics.MinLatency, metrics.ResponseCounters,
|
||||
tt.expectedMetrics.TotalRequests, tt.expectedMetrics.TotalResponses, tt.expectedMetrics.TotalLatency, tt.expectedMetrics.MaxLatency, tt.expectedMetrics.MinLatency, tt.expectedMetrics.ResponseCounters)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -13,11 +13,7 @@ import (
|
|||
// Global HTTP client used for making requests.
|
||||
var client = &http.Client{}
|
||||
|
||||
type RequestError struct {
|
||||
Verb string
|
||||
URL string
|
||||
Err error
|
||||
}
|
||||
|
||||
|
||||
func (e *RequestError) Error() string {
|
||||
return fmt.Sprintf("error making %s request to %s: %v", e.Verb, e.URL, e.Err)
|
||||
|
|
50
lib/requests_test.go
Normal file
50
lib/requests_test.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
package lib_test
|
||||
|
||||
import (
|
||||
"loadr/lib"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestSendRequests(t *testing.T) {
|
||||
// Create a test server that responds with a 200 status.
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
url string
|
||||
bearerToken string
|
||||
requestType string
|
||||
jsonData []byte
|
||||
maxRequests int
|
||||
requestsPerSecond float64
|
||||
}{
|
||||
{
|
||||
name: "Test 1",
|
||||
url: ts.URL,
|
||||
bearerToken: "testToken",
|
||||
requestType: "GET",
|
||||
jsonData: []byte(`{"key":"value"}`),
|
||||
maxRequests: 5,
|
||||
requestsPerSecond: 1.0,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
start := time.Now()
|
||||
lib.SendRequests(tt.url, tt.bearerToken, tt.requestType, tt.jsonData, tt.maxRequests, tt.requestsPerSecond)
|
||||
elapsed := time.Since(start)
|
||||
|
||||
// Check if the requests were sent within the expected time frame.
|
||||
if elapsed > time.Duration(float64(tt.maxRequests)*1.5)*time.Second {
|
||||
t.Errorf("SendRequests() took too long, got: %v, want: less than %v", elapsed, time.Duration(float64(tt.maxRequests)*1.5)*time.Second)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
23
lib/types.go
Normal file
23
lib/types.go
Normal file
|
@ -0,0 +1,23 @@
|
|||
package lib
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PerformanceMetrics holds the metrics for performance evaluation.
|
||||
type PerformanceMetrics struct {
|
||||
Mu sync.Mutex // Protects the metrics
|
||||
TotalRequests int32
|
||||
TotalResponses int32
|
||||
TotalLatency time.Duration
|
||||
MaxLatency time.Duration
|
||||
MinLatency time.Duration
|
||||
ResponseCounters map[int]int32
|
||||
}
|
||||
|
||||
type RequestError struct {
|
||||
Verb string
|
||||
URL string
|
||||
Err error
|
||||
}
|
Loading…
Add table
Reference in a new issue