Files
Sudo-Ivan f471eeb1b6
All checks were successful
CI / build (push) Successful in 29s
Tests / test (push) Successful in 1m0s
Format tests
2025-12-26 22:35:49 -06:00

117 lines
2.7 KiB
Go

package main
import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"os/exec"
"path/filepath"
"sync"
"sync/atomic"
"time"
)
func main() {
dbPath := "./data"
if _, err := os.Stat(filepath.Join(dbPath, "osv.db")); os.IsNotExist(err) {
log.Fatal("Real database not found at data/osv.db, cannot run load test")
}
// Build server
log.Println("Building osv-server...")
buildCmd := exec.Command("go", "build", "-o", "bin/osv-server", "./cmd/osv-server")
if out, err := buildCmd.CombinedOutput(); err != nil {
log.Fatalf("Build failed: %v\n%s", err, out)
}
// Start server
log.Println("Starting osv-server...")
port := "9091"
serverCmd := exec.Command("./bin/osv-server", "-port", port, "-data-dir", dbPath)
serverCmd.Env = append(os.Environ(), "OSV_SILENT=true")
if err := serverCmd.Start(); err != nil {
log.Fatalf("Failed to start server: %v", err)
}
defer serverCmd.Process.Kill()
// Wait for server to be ready
time.Sleep(2 * time.Second)
log.Println("Starting load test...")
const (
concurrency = 200
duration = 10 * time.Second
)
var (
requests int64
errors int64
latencySum int64
latencyCount int64
)
queryReq := map[string]interface{}{
"package": map[string]interface{}{
"name": "requests",
"ecosystem": "PyPI",
},
"version": "2.28.0",
}
body, _ := json.Marshal(queryReq)
url := fmt.Sprintf("http://localhost:%s/v1/query", port)
start := time.Now()
var wg sync.WaitGroup
wg.Add(concurrency)
for i := 0; i < concurrency; i++ {
go func() {
defer wg.Done()
client := &http.Client{
Timeout: 5 * time.Second,
}
for time.Since(start) < duration {
reqStart := time.Now()
resp, err := client.Post(url, "application/json", bytes.NewBuffer(body))
if err != nil {
atomic.AddInt64(&errors, 1)
continue
}
if resp.StatusCode != http.StatusOK {
atomic.AddInt64(&errors, 1)
}
resp.Body.Close()
latency := time.Since(reqStart).Nanoseconds()
atomic.AddInt64(&latencySum, latency)
atomic.AddInt64(&latencyCount, 1)
atomic.AddInt64(&requests, 1)
}
}()
}
wg.Wait()
totalDuration := time.Since(start).Seconds()
rps := float64(requests) / totalDuration
fmt.Printf("\n--- Load Test Results ---\n")
fmt.Printf("Total Requests: %d\n", requests)
fmt.Printf("Total Errors: %d\n", errors)
fmt.Printf("Duration: %.2fs\n", totalDuration)
fmt.Printf("Avg RPS: %.2f\n", rps)
if latencyCount > 0 {
avgLatency := time.Duration(latencySum / latencyCount)
fmt.Printf("Avg Latency: %v\n", avgLatency)
}
fmt.Printf("-------------------------\n")
if rps < 1000 {
log.Printf("Warning: RPS is below target of 1000: %.2f", rps)
} else {
log.Printf("Success: RPS target met: %.2f", rps)
}
}