package web import ( "strconv" "testing" ) // fillupCache 是全局的、只写不清的内存缓存:长期运行必须有上限, // 否则站点换了几轮数据集之后 map 会一路涨下去,把 1C1G 的机器吃干净。 func TestFillupCacheIsBounded(t *testing.T) { fillupMu.Lock() savedCache, savedOrder := fillupCache, fillupOrder fillupCache, fillupOrder = map[int64]fillupHint{}, nil fillupMu.Unlock() t.Cleanup(func() { fillupMu.Lock() fillupCache, fillupOrder = savedCache, savedOrder fillupMu.Unlock() }) total := fillupCacheMax + fillupCacheMax/2 for i := 0; i < total; i++ { fillupCachePut(int64(i), fillupHint{Act: strconv.Itoa(i)}) } fillupMu.Lock() size, order := len(fillupCache), len(fillupOrder) fillupMu.Unlock() if size > fillupCacheMax { t.Fatalf("缓存条目应被限制在 %d 以内,实际 %d(又变成无界增长了)", fillupCacheMax, size) } if order != size { t.Fatalf("淘汰后 order 应与 cache 等长:order=%d cache=%d", order, size) } if _, ok := fillupHintOf(int64(total - 1)); !ok { t.Error("最后写入的条目不该被淘汰") } if _, ok := fillupHintOf(0); ok { t.Error("最旧的条目应当已被淘汰") } // 覆盖写同一个键不该让 order 重复记账(否则 order 会比 cache 长,淘汰时错删)。 before := order fillupCachePut(int64(total-1), fillupHint{Act: "again"}) fillupMu.Lock() after := len(fillupOrder) fillupMu.Unlock() if after != before { t.Errorf("重复写同一个键不该增加 order 长度:%d -> %d", before, after) } }