package servlet import ( "io" "log" "net/http" "net/http/httptest" "regexp" "testing" "time" ) func TestNewServlet(t *testing.T) { port := ":8080" srv := NewServlet(port) if srv.Port != port { t.Errorf("Expected port %s, got %s", port, srv.Port) } if srv.Router.Routes != nil { t.Error("Expected Routes to be nil") } if srv.ErrorRoutes == nil { t.Error("Expected ErrorRoutes to be initialized") } } func TestServletServeTraffic(t *testing.T) { // Create a new servlet srv := NewServlet(":8080") // Add a test route srv.Router.AddRoute(&VinegarWebRoute{ Pattern: regexp.MustCompile("/test"), Handler: func(w http.ResponseWriter, r *http.Request) { log.Printf("We got into the handler\n") msg := []byte("hello") l, err := w.Write(msg) log.Printf("Wrote %d bytes\n", l) if err != nil { srv.errors <- err } }, }) // Start the server in a goroutine go srv.Start() defer srv.Shutdown() // Make a request to the test route res, err := http.Get("http://localhost:8080/test") if err != nil { t.Fatal(err) } // Verify successful response if res.StatusCode != http.StatusOK { t.Errorf("Expected status OK, got %d", res.StatusCode) } body, _ := io.ReadAll(res.Body) res.Body.Close() if string(body) != "hello" { t.Errorf("Unexpected response body [%s]", string(body)) } } func TestApiRoute(t *testing.T) { // Create a new API route route := NewApiRoute(nil, "/hello") // Add a handler for GET requests route.AddGetHandler(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("hello")) }) // Create a request req, _ := http.NewRequest(http.MethodGet, "localhost:8080/hello", nil) // Create a ResponseRecorder to record the response rr := httptest.NewRecorder() // Call the handler route.VinegarRoute.Handler(rr, req) // Check the status code if status := rr.Code; status != http.StatusOK { t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK) } // Check the response body expected := "hello" if rr.Body.String() != expected { t.Errorf("handler returned unexpected body: got %v want %v", rr.Body.String(), expected) } } func TestApiRouteStress(t *testing.T) { route := NewApiRoute(nil, "/hello") route.AddGetHandler(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("hello")) }) n := 1000 // number of requests c := make(chan struct{}, n) // concurrency control start := time.Now() for i := 0; i < n; i++ { go func() { // Create a request req, _ := http.NewRequest(http.MethodGet, "localhost:8080/hello", nil) // Create a ResponseRecorder to record the response rr := httptest.NewRecorder() // Call the handler route.VinegarRoute.Handler(rr, req) c <- struct{}{} }() } // wait for requests to complete for i := 0; i < n; i++ { <-c } elapsed := time.Since(start) // Print performance stats log.Printf("Completed %d requests in %s", n, elapsed) avg := elapsed / time.Duration(n) log.Printf("Average request time: %s", avg) requestsPerSec := float64(n) / elapsed.Seconds() log.Printf("Requests per second: %f", requestsPerSec) }