96 lines
2.0 KiB
Go
96 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
func main() {
|
|
// Read URLs from environment variable
|
|
urlsEnv := os.Getenv("TARGET_URLS")
|
|
if urlsEnv == "" {
|
|
log.Fatal("TARGET_URLS environment variable is not set")
|
|
}
|
|
|
|
// Parse comma-delimited URLs
|
|
urls := strings.Split(urlsEnv, ",")
|
|
for i := range urls {
|
|
urls[i] = strings.TrimSpace(urls[i])
|
|
}
|
|
|
|
if len(urls) == 0 {
|
|
log.Fatal("No URLs provided")
|
|
}
|
|
|
|
fmt.Printf("Starting load test on %d URLs\n", len(urls))
|
|
fmt.Println("URLs:", urls)
|
|
fmt.Println("Press Ctrl+C to stop\n")
|
|
|
|
// Counters
|
|
var (
|
|
totalRequests uint64
|
|
successCount uint64
|
|
errorCount uint64
|
|
)
|
|
|
|
// WaitGroup to track all goroutines
|
|
var wg sync.WaitGroup
|
|
|
|
// Start time
|
|
startTime := time.Now()
|
|
|
|
// Spawn a goroutine for each URL
|
|
for _, url := range urls {
|
|
wg.Add(1)
|
|
go func(targetURL string) {
|
|
defer wg.Done()
|
|
|
|
client := &http.Client{Timeout: time.Second}
|
|
for {
|
|
resp, err := client.Get(targetURL)
|
|
atomic.AddUint64(&totalRequests, 1)
|
|
|
|
if err != nil {
|
|
fmt.Printf("error: %s => %v\n", targetURL, err)
|
|
atomic.AddUint64(&errorCount, 1)
|
|
continue
|
|
}
|
|
|
|
_ = resp.Body.Close()
|
|
|
|
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
|
|
atomic.AddUint64(&successCount, 1)
|
|
} else {
|
|
fmt.Printf("bad status: %s => %d\n", targetURL, resp.StatusCode)
|
|
atomic.AddUint64(&errorCount, 1)
|
|
}
|
|
}
|
|
}(url)
|
|
}
|
|
|
|
// Progress reporter
|
|
go func() {
|
|
ticker := time.NewTicker(1 * time.Second)
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
<-ticker.C
|
|
elapsed := time.Since(startTime).Seconds()
|
|
requests := atomic.LoadUint64(&totalRequests)
|
|
success := atomic.LoadUint64(&successCount)
|
|
errors := atomic.LoadUint64(&errorCount)
|
|
fmt.Printf("Elapsed: %.0fs | Requests: %d | Success: %d | Errors: %d | Rate: %.0f req/s\n",
|
|
elapsed, requests, success, errors, float64(requests)/elapsed)
|
|
}
|
|
}()
|
|
|
|
// Wait for all goroutines (runs forever until killed)
|
|
wg.Wait()
|
|
}
|