package http import ( "io" "net/http" "net/http/httptest" "strconv" "sync" "testing" "github.com/golang-jwt/jwt/v5" "hyapp/pkg/logx" "hyapp/services/gateway-service/internal/auth" ) var benchmarkLogOnce sync.Once type benchmarkResponseWriter struct { header http.Header status int } func newBenchmarkResponseWriter() *benchmarkResponseWriter { return &benchmarkResponseWriter{header: make(http.Header)} } func (w *benchmarkResponseWriter) Header() http.Header { return w.header } func (w *benchmarkResponseWriter) Write(payload []byte) (int, error) { return len(payload), nil } func (w *benchmarkResponseWriter) WriteHeader(statusCode int) { w.status = statusCode } func (w *benchmarkResponseWriter) reset() { for key := range w.header { delete(w.header, key) } w.status = 0 } func benchmarkGatewayRouter() http.Handler { benchmarkLogOnce.Do(func() { _ = logx.Init(logx.Config{Service: "gateway-service", Env: "bench", Level: "error", Output: io.Discard}) }) handler := NewHandlerWithClients(&fakeRoomClient{}, nil, &fakeUserIdentityClient{ resolveByDisplay: map[string]int64{"10001": 10001}, }, &fakeUserProfileClient{}) handler.SetMessageInboxClient(&fakeMessageInboxClient{}) handler.SetUserSocialClient(&fakeUserSocialClient{}) return handler.Routes(auth.NewVerifier("secret")) } func benchmarkGatewayToken(b *testing.B, userID int64) string { b.Helper() token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "user_id": strconv.FormatInt(userID, 10), "app_code": "lalu", "sid": "bench-session", "profile_completed": true, "onboarding_status": "completed", }) signed, err := token.SignedString([]byte("secret")) if err != nil { b.Fatalf("sign benchmark token failed: %v", err) } return signed } func benchmarkGatewayRoute(b *testing.B, router http.Handler, method string, path string, token string) { b.Helper() request := httptest.NewRequest(method, path, nil) request.Header.Set("X-App-Code", "lalu") if token != "" { request.Header.Set("Authorization", "Bearer "+token) } writer := newBenchmarkResponseWriter() b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { writer.reset() router.ServeHTTP(writer, request) if writer.status != http.StatusOK { b.Fatalf("status = %d, want 200", writer.status) } } } func BenchmarkGatewayResolveDisplayUserIDRoute(b *testing.B) { benchmarkGatewayRoute(b, benchmarkGatewayRouter(), http.MethodGet, "/api/v1/users/by-display-user-id/10001", "") } func BenchmarkGatewayMessageReadRoute(b *testing.B) { token := benchmarkGatewayToken(b, 42) benchmarkGatewayRoute(b, benchmarkGatewayRouter(), http.MethodPost, "/api/v1/messages/msg-10001/read", token) } func BenchmarkGatewayUserSocialRoute(b *testing.B) { token := benchmarkGatewayToken(b, 42) benchmarkGatewayRoute(b, benchmarkGatewayRouter(), http.MethodPost, "/api/v1/users/10002/friend-requests/accept", token) }