Nereus/apps/loadgen/main_test.go

106 lines
3.5 KiB
Go

package main
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"sync"
"testing"
)
func TestRequestWeighting(t *testing.T) {
var mu sync.Mutex
counts := make(map[string]int)
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
mu.Lock()
counts[r.Method+" "+r.URL.RequestURI()]++
mu.Unlock()
w.WriteHeader(http.StatusOK)
}))
defer server.Close()
g := &generator{client: server.Client(), target: server.URL, buoys: []string{"buoy-1"}, counts: make(map[string]int)}
for roll := range 100 {
g.sendRoll(context.Background(), roll)
}
want := map[string]int{
"GET /api/v1/readings": 60,
"POST /api/v1/readings": 25,
"GET /api/v1/readings/aggregate?window=1h": 15,
}
if fmt.Sprint(counts) != fmt.Sprint(want) {
t.Fatalf("request weighting = %v, want %v", counts, want)
}
}
func TestSeedEmptyAPI(t *testing.T) {
var mu sync.Mutex
created := 0
var posted []buoy
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodGet && r.URL.Path == "/api/v1/buoys":
_ = json.NewEncoder(w).Encode([]buoy{})
case r.Method == http.MethodPost && r.URL.Path == "/api/v1/buoys":
var input buoy
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
http.Error(w, "invalid buoy", http.StatusBadRequest)
return
}
mu.Lock()
created++
posted = append(posted, input)
id := fmt.Sprintf("buoy-%d", created)
mu.Unlock()
_ = json.NewEncoder(w).Encode(buoy{ID: id})
default:
http.NotFound(w, r)
}
}))
defer server.Close()
g := &generator{client: server.Client(), target: server.URL, counts: make(map[string]int)}
if err := g.seed(context.Background()); err != nil {
t.Fatalf("seed: %v", err)
}
if created != 42 || len(g.buoys) != 42 {
t.Fatalf("created %d buoys and retained %d IDs, want 42 and 42", created, len(g.buoys))
}
want := [][2]float64{{44.5, -9}, {44.2, -8}, {44.3, -7}, {44.4, -6}, {44.5, -5}, {44.6, -4}, {44.7, -3}, {44.5, -2}, {43.8, -2}, {43.5, -9.8}, {42.5, -10.2}, {41.5, -10.5}, {40.5, -10.8}, {39.5, -11}, {38.5, -11}, {37.5, -10.8}, {36.5, -10}, {35.9, -9}, {35.8, -8}, {35.7, -7}, {35.2, -7.5}, {35, -8.5}, {35.8, -4.5}, {36, -3.5}, {36.2, -2.5}, {36.5, -1.5}, {36.8, -.5}, {37.2, .5}, {37.7, 1.2}, {38.1, 2}, {38, 3}, {38.5, 4}, {39.5, 1}, {40, 1.5}, {40.5, 2}, {41, 2.7}, {41.5, 3.3}, {42, 3.8}, {42.5, 4.5}, {43, -9.8}, {41, -10.5}, {39, -10.8}}
for i, position := range want {
if posted[i].Latitude != position[0] || posted[i].Longitude != position[1] {
t.Errorf("buoy %d position = (%v, %v), want (%v, %v)", i, posted[i].Latitude, posted[i].Longitude, position[0], position[1])
}
}
}
func TestTrafficContinuesThroughHTTP500(t *testing.T) {
const requests = 30
var mu sync.Mutex
received := 0
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
mu.Lock()
received++
mu.Unlock()
http.Error(w, "unavailable", http.StatusInternalServerError)
}))
defer server.Close()
g := &generator{client: server.Client(), target: server.URL, buoys: []string{"buoy-1"}, counts: make(map[string]int)}
for roll := range requests {
g.sendRoll(context.Background(), roll)
}
mu.Lock()
got := received
mu.Unlock()
if got != requests {
t.Fatalf("received %d requests, want %d", got, requests)
}
if g.counts["500"] != requests {
t.Fatalf("recorded %d HTTP 500 responses, want %d", g.counts["500"], requests)
}
}