mirror of
https://github.com/nprasad2077/NBA_Go.git
synced 2026-09-22 14:05:13 +00:00
132 lines
3.0 KiB
Go
132 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"sync"
|
|
"time"
|
|
"log"
|
|
"flag"
|
|
"os"
|
|
)
|
|
|
|
// Response struct to track which server handled the request
|
|
type Response struct {
|
|
StatusCode int
|
|
Body string
|
|
Duration time.Duration
|
|
Error error
|
|
}
|
|
|
|
func main() {
|
|
// Define command line flags
|
|
numRequests := flag.Int("n", 100, "Number of requests to send")
|
|
concurrency := flag.Int("c", 10, "Number of concurrent requests")
|
|
endpoint := flag.String("url", "http://localhost:8080/api/player/advanced", "API endpoint to test")
|
|
logFile := flag.String("log", "loadtest.log", "Log file path")
|
|
flag.Parse()
|
|
|
|
// Setup logging
|
|
f, err := os.OpenFile(*logFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
|
if err != nil {
|
|
log.Fatalf("Error opening log file: %v", err)
|
|
}
|
|
defer f.Close()
|
|
log.SetOutput(f)
|
|
|
|
fmt.Printf("Starting load test with %d requests, %d concurrent\n", *numRequests, *concurrency)
|
|
fmt.Printf("Testing endpoint: %s\n", *endpoint)
|
|
|
|
// Channel to collect results
|
|
results := make(chan Response, *numRequests)
|
|
|
|
// Use a WaitGroup to manage concurrency
|
|
var wg sync.WaitGroup
|
|
|
|
// Semaphore to limit concurrency
|
|
sem := make(chan bool, *concurrency)
|
|
|
|
// Start the timer
|
|
startTime := time.Now()
|
|
|
|
// Launch goroutines for requests
|
|
for i := 0; i < *numRequests; i++ {
|
|
wg.Add(1)
|
|
go func(id int) {
|
|
defer wg.Done()
|
|
|
|
// Acquire semaphore
|
|
sem <- true
|
|
defer func() { <-sem }()
|
|
|
|
// Make the request
|
|
start := time.Now()
|
|
resp, err := http.Get(*endpoint)
|
|
duration := time.Since(start)
|
|
|
|
result := Response{
|
|
Duration: duration,
|
|
Error: err,
|
|
}
|
|
|
|
if err != nil {
|
|
log.Printf("Request %d failed: %v", id, err)
|
|
results <- result
|
|
return
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
log.Printf("Failed to read response body: %v", err)
|
|
result.Error = err
|
|
results <- result
|
|
return
|
|
}
|
|
|
|
result.StatusCode = resp.StatusCode
|
|
result.Body = string(body)
|
|
results <- result
|
|
|
|
// Log request details
|
|
log.Printf("Request %d: Status=%d, Time=%v",
|
|
id, resp.StatusCode, duration)
|
|
}(i)
|
|
}
|
|
|
|
// Close the results channel when all requests are done
|
|
go func() {
|
|
wg.Wait()
|
|
close(results)
|
|
}()
|
|
|
|
// Process results
|
|
var successCount, errorCount int
|
|
var totalDuration time.Duration
|
|
|
|
for result := range results {
|
|
if result.Error != nil {
|
|
errorCount++
|
|
} else if result.StatusCode == 200 {
|
|
successCount++
|
|
totalDuration += result.Duration
|
|
} else {
|
|
errorCount++
|
|
}
|
|
}
|
|
|
|
// Calculate statistics
|
|
totalTime := time.Since(startTime)
|
|
avgDuration := totalDuration / time.Duration(successCount)
|
|
requestsPerSecond := float64(*numRequests) / totalTime.Seconds()
|
|
|
|
// Print summary
|
|
fmt.Printf("\nLoad Test Summary:\n")
|
|
fmt.Printf("Total Requests: %d\n", *numRequests)
|
|
fmt.Printf("Successful Requests: %d\n", successCount)
|
|
fmt.Printf("Failed Requests: %d\n", errorCount)
|
|
fmt.Printf("Total Time: %v\n", totalTime)
|
|
fmt.Printf("Average Response Time: %v\n", avgDuration)
|
|
fmt.Printf("Requests Per Second: %.2f\n", requestsPerSecond)
|
|
} |