package serverutil import ( "context" "crypto/rand" "fmt" "net/http" "net/http/httptest" "testing" "time" "git.autistici.org/ai3/go-common/clientutil" ) type TestRequest struct { Data []string `json:"data"` } type TestObject struct { Name string `json:"name"` Host string `json:"host"` Timestamp time.Time `json:"timestamp"` PubKey []byte `json:"pubkey"` } type TestResponse struct { Objects []*TestObject `json:"objects"` } func fastRandomBytes(n int) []byte { b := make([]byte, n) rand.Read(b) // nolint: errcheck return b } func makeTestHandler() http.HandlerFunc { // Generate a large-ish random response. var resp TestResponse now := time.Now() n := 256 resp.Objects = make([]*TestObject, 0, n) for i := 0; i < n; i++ { resp.Objects = append(resp.Objects, &TestObject{ Name: fmt.Sprintf("test-object-%06d", i+1), Host: "host-452-ff-bb", Timestamp: now, PubKey: fastRandomBytes(256), }) } return func(w http.ResponseWriter, httpReq *http.Request) { var req TestRequest if !DecodeJSONRequest(w, httpReq, &req) { return } EncodeJSONResponse(w, &resp) } } const apiPath = "/api/v1/random" func makeTestRequest() *TestRequest { var req TestRequest n := 256 req.Data = make([]string, 0, n) for i := 0; i < n; i++ { req.Data = append(req.Data, fmt.Sprintf("data-item-%06d", i)) } return &req } func makeSingleRequest(backend clientutil.Backend, req *TestRequest) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() var resp TestResponse return backend.Call(ctx, "", apiPath, &req, &resp) } func runHTTPTest(t *testing.T, config *ServerConfig) { mux := http.NewServeMux() mux.HandleFunc(apiPath, makeTestHandler()) h, _, err := config.buildHTTPHandler(mux) if err != nil { t.Fatal(err) } srv := httptest.NewServer(h) defer srv.Close() backend, err := clientutil.NewBackend(&clientutil.BackendConfig{ URL: srv.URL, }) if err != nil { t.Fatalf("NewBackend() error: %v", err) } defer backend.Close() if err := makeSingleRequest(backend, makeTestRequest()); err != nil { t.Fatal(err) } } func TestHTTP(t *testing.T) { runHTTPTest(t, &ServerConfig{}) } func TestHTTP_Compression(t *testing.T) { runHTTPTest(t, &ServerConfig{ EnableCompression: true, }) } func BenchmarkLoad(b *testing.B) { mux := http.NewServeMux() mux.HandleFunc(apiPath, makeTestHandler()) config := &ServerConfig{ EnableCompression: true, } h, _, _ := config.buildHTTPHandler(mux) srv := httptest.NewServer(h) defer srv.Close() backend, err := clientutil.NewBackend(&clientutil.BackendConfig{ URL: srv.URL, }) if err != nil { b.Fatalf("NewBackend() error: %v", err) } defer backend.Close() req := makeTestRequest() // Run clients. b.SetParallelism(100) b.RunParallel(func(pb *testing.PB) { for pb.Next() { makeSingleRequest(backend, req) // nolint: errcheck } }) }