package repository import ( "testing" "time" ) // TestNextIDWhileWriteLocked 回归测试:调用方持有写锁时 NextID 不能死锁。 // // 历史问题:NextID 内部用 d.mu 加锁,而 CaptureAppVolumeForHour 先 db.Lock() // 再 db.NextID(),Go 的 sync.RWMutex 不可重入,导致该 goroutine 永久持有写锁, // 所有读库接口(登录、列表)全部挂起,而 /health 仍然正常。 func TestNextIDWhileWriteLocked(t *testing.T) { db := &JsonDB{sequences: map[string]uint{}} db.Lock() done := make(chan uint, 1) go func() { done <- db.NextID("test") }() select { case id := <-done: db.Unlock() if id != 1 { t.Fatalf("first id = %d, want 1", id) } case <-time.After(2 * time.Second): db.Unlock() t.Fatal("NextID deadlocked while write lock is held") } // 解锁后继续分配应递增 if id := db.NextID("test"); id != 2 { t.Fatalf("second id = %d, want 2", id) } }