- 数据库默认文件 filecodebox.db → fileshare.db(config.go 默认值与全部文档/编排同步)
- Go module filecodebox → fileshare(全部 import 同步,build/vet/test 全绿)
- 应用版本 APP_VERSION 2.5.6 → 26.9(health 接口已验证返回 26.9)
- deploy 编排统一:compose 项目名、Postgres 默认凭据、minio 桶名、env 注释
- JWT issuer、存储临时目录前缀、web 包名同步 fileshare
- CI:镜像 tag 以 APP_VERSION 为唯一版本源,main/tag 推送即发布
${VER} + latest;tag 触发时校验 tag 名与 APP_VERSION 一致,防错版
- 本地开发库文件已改名 fileshare.db(含 -shm/-wal 清理)
67 lines
1.9 KiB
Go
67 lines
1.9 KiB
Go
package middleware
|
||
|
||
import (
|
||
"context"
|
||
"net/http/httptest"
|
||
"testing"
|
||
"time"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
|
||
"fileshare/internal/cache"
|
||
)
|
||
|
||
// failingCache 模拟缓存故障(Get/Incr 均返回非 ErrNotFound 错误)。
|
||
type failingCache struct{ cache.Cache }
|
||
|
||
func (f *failingCache) Get(_ context.Context, _ string) (string, error) {
|
||
return "", context.DeadlineExceeded
|
||
}
|
||
func (f *failingCache) Set(_ context.Context, _, _ string, _ time.Duration) error {
|
||
return context.DeadlineExceeded
|
||
}
|
||
func (f *failingCache) Incr(_ context.Context, _ string, _ time.Duration) (int64, error) {
|
||
return 0, context.DeadlineExceeded
|
||
}
|
||
|
||
func newLimiterTest(c *gin.Context, cacheImpl cache.Cache, count int) *RateLimiter {
|
||
return NewRateLimiter(cacheImpl, map[string]LimitRule{
|
||
LimitLogin: {Count: count, Window: time.Minute},
|
||
})
|
||
}
|
||
|
||
func ginTestContext() *gin.Context {
|
||
gin.SetMode(gin.TestMode)
|
||
c, _ := gin.CreateTestContext(httptest.NewRecorder())
|
||
c.Request = httptest.NewRequest("POST", "/admin/login", nil)
|
||
return c
|
||
}
|
||
|
||
// TestRateLimiterFallbackOnCacheFailure L9:缓存故障时限流降级为进程内计数,
|
||
// 超过上限后 Check 拒绝(此前 fail-open 会一直放行)。
|
||
func TestRateLimiterFallbackOnCacheFailure(t *testing.T) {
|
||
c := ginTestContext()
|
||
rl := newLimiterTest(c, &failingCache{cache.NewMemory()}, 3)
|
||
for i := 0; i < 3; i++ {
|
||
if ok, _ := rl.Check(c, LimitLogin); !ok {
|
||
t.Fatalf("第 %d 次检查不应拒绝", i+1)
|
||
}
|
||
rl.Add(c, LimitLogin)
|
||
}
|
||
if ok, _ := rl.Check(c, LimitLogin); ok {
|
||
t.Fatal("缓存故障降级下,超过上限后 Check 应拒绝(fail-close)")
|
||
}
|
||
}
|
||
|
||
// TestRateLimiterNormalCacheCounting 正常缓存路径行为不变。
|
||
func TestRateLimiterNormalCacheCounting(t *testing.T) {
|
||
c := ginTestContext()
|
||
rl := newLimiterTest(c, cache.NewMemory(), 2)
|
||
for i := 0; i < 2; i++ {
|
||
rl.Add(c, LimitLogin)
|
||
}
|
||
if ok, _ := rl.Check(c, LimitLogin); ok {
|
||
t.Fatal("达到上限后 Check 应拒绝")
|
||
}
|
||
}
|