115 lines
3.3 KiB
Go
115 lines
3.3 KiB
Go
package logging
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func TestFormatCPATraceID(t *testing.T) {
|
|
selectedAt := time.Date(2026, time.July, 17, 21, 58, 49, 0, time.UTC)
|
|
got := FormatCPATraceID(selectedAt, "auth-index", "request1")
|
|
if want := "20260717215849-auth-index-request1"; got != want {
|
|
t.Fatalf("FormatCPATraceID() = %q, want %q", got, want)
|
|
}
|
|
|
|
for _, test := range []struct {
|
|
name string
|
|
selectedAt time.Time
|
|
authIndex string
|
|
requestID string
|
|
}{
|
|
{name: "zero time", authIndex: "auth-index", requestID: "request1"},
|
|
{name: "empty auth index", selectedAt: selectedAt, requestID: "request1"},
|
|
{name: "empty request ID", selectedAt: selectedAt, authIndex: "auth-index"},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
if gotEmpty := FormatCPATraceID(test.selectedAt, test.authIndex, test.requestID); gotEmpty != "" {
|
|
t.Fatalf("FormatCPATraceID() = %q, want empty", gotEmpty)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCPATraceIDMiddlewareRequiresAuthIndexBeforeResponseCommit(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
engine := gin.New()
|
|
engine.Use(CPATraceIDMiddleware())
|
|
engine.GET("/selected", func(c *gin.Context) {
|
|
SetGinRequestID(c, "1234abcd")
|
|
SetGinCPATraceID(c, "auth-index")
|
|
c.Status(http.StatusOK)
|
|
})
|
|
engine.GET("/unselected", func(c *gin.Context) {
|
|
SetGinRequestID(c, "1234abcd")
|
|
SetGinCPATraceID(c, "")
|
|
c.Status(http.StatusOK)
|
|
})
|
|
engine.GET("/committed", func(c *gin.Context) {
|
|
SetGinRequestID(c, "1234abcd")
|
|
c.Writer.WriteHeaderNow()
|
|
SetGinCPATraceID(c, "auth-index")
|
|
})
|
|
|
|
t.Run("writes selected auth trace", func(t *testing.T) {
|
|
recorder := httptest.NewRecorder()
|
|
engine.ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/selected", nil))
|
|
|
|
traceID := recorder.Header().Get(CPATraceIDHeader)
|
|
if len(traceID) != len("20060102150405-auth-index-1234abcd") {
|
|
t.Fatalf("trace ID = %q, unexpected length", traceID)
|
|
}
|
|
if got := traceID[15:]; got != "auth-index-1234abcd" {
|
|
t.Fatalf("trace suffix = %q, want %q", got, "auth-index-1234abcd")
|
|
}
|
|
})
|
|
|
|
t.Run("skips empty auth index", func(t *testing.T) {
|
|
recorder := httptest.NewRecorder()
|
|
engine.ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/unselected", nil))
|
|
|
|
if got := recorder.Header().Get(CPATraceIDHeader); got != "" {
|
|
t.Fatalf("trace ID = %q, want empty", got)
|
|
}
|
|
})
|
|
|
|
t.Run("skips committed response", func(t *testing.T) {
|
|
recorder := httptest.NewRecorder()
|
|
engine.ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/committed", nil))
|
|
|
|
if got := recorder.Header().Get(CPATraceIDHeader); got != "" {
|
|
t.Fatalf("trace ID = %q, want empty", got)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestCPATraceIDConcurrentSelectionAndResponseCommit(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
engine := gin.New()
|
|
engine.Use(CPATraceIDMiddleware())
|
|
engine.GET("/race", func(c *gin.Context) {
|
|
SetGinRequestID(c, "1234abcd")
|
|
traceCallback := GinCPATraceIDCallback(c)
|
|
start := make(chan struct{})
|
|
done := make(chan struct{})
|
|
go func() {
|
|
defer close(done)
|
|
<-start
|
|
traceCallback("auth-index")
|
|
}()
|
|
close(start)
|
|
_, _ = c.Writer.Write([]byte("\n"))
|
|
<-done
|
|
})
|
|
|
|
for range 100 {
|
|
recorder := httptest.NewRecorder()
|
|
engine.ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/race", nil))
|
|
if recorder.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, want %d", recorder.Code, http.StatusOK)
|
|
}
|
|
}
|
|
}
|