Files
杭州明婳科技 0c9f256dfc feat(v1.1.0): HA & Manager 化
对应体检报告 #10-#24,一次性完成 v1.1.0 全部 13 项:

- #10 storage/cache/redis/jwt/logger 五组件 Manager 化(XxxManager + DefaultXxx + SetDefaultXxxManager,包级 facade 保留兼容)
- #11 删除 wire 包 + 清理 StartServerWithPort/GracefulShutdown 双轨
- #12 Lifecycle Hooks(OnInit/OnStart/OnReady/OnStop)
- #13 Server 参数配置化(timeout/TLS/unix_socket/response_mode)
- #14 JWTConfig.Expire 改 time.Duration + 删 AppConfig.TokenExpire
- #15 response Mode 开关(ModeBusiness/ModeREST)
- #16 Config.Validate 启动期校验
- #17 livez/readyz 探针路由
- #18 Prometheus metrics 中间件 + /metrics
- #19 请求级 Timeout 中间件
- #21 主库探活 + replica 健康剔除
- #22 App.Go + in-flight goroutine 管理
- #24 RequestID 默认装入 + #23 核对

Breaking:删 wire、删 TokenExpire、JWTConfig.Expire 类型变更、删双轨函数。
详见 CHANGELOG 升级说明。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 10:41:05 +08:00

73 lines
1.6 KiB
Go

package middleware_test
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/EthanCodeCraft/xlgo-core/middleware"
"github.com/gin-gonic/gin"
)
func TestTimeoutAllowsFastHandler(t *testing.T) {
gin.SetMode(gin.TestMode)
r := gin.New()
r.Use(middleware.Timeout(time.Second))
r.GET("/ok", func(c *gin.Context) {
c.Status(http.StatusOK)
})
w := httptest.NewRecorder()
r.ServeHTTP(w, httptest.NewRequest("GET", "/ok", nil))
if w.Code != http.StatusOK {
t.Errorf("status = %d, want 200", w.Code)
}
}
func TestTimeoutCancelsSlowHandler(t *testing.T) {
gin.SetMode(gin.TestMode)
r := gin.New()
r.Use(middleware.Timeout(50 * time.Millisecond))
r.GET("/slow", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
// 超时取消生效
return
case <-time.After(time.Second):
t.Error("handler should have been cancelled by timeout")
}
})
w := httptest.NewRecorder()
done := make(chan struct{})
go func() {
r.ServeHTTP(w, httptest.NewRequest("GET", "/slow", nil))
close(done)
}()
select {
case <-done:
case <-time.After(2 * time.Second):
t.Fatal("request did not return in time")
}
}
func TestTimeoutZeroDisables(t *testing.T) {
gin.SetMode(gin.TestMode)
r := gin.New()
r.Use(middleware.Timeout(0)) // 不启用
ctxCancelled := false
r.GET("/x", func(c *gin.Context) {
ctxCancelled = c.Request.Context() == context.Background()
_ = ctxCancelled
c.Status(http.StatusOK)
})
w := httptest.NewRecorder()
r.ServeHTTP(w, httptest.NewRequest("GET", "/x", nil))
if w.Code != http.StatusOK {
t.Errorf("status = %d, want 200", w.Code)
}
}