package httpapi import ( "testing" "time" ) // 同一 requestId 并发时只能有一个执行者,其余请求等首次结束后回放其结果。 func TestIdempotencyStoreSerializesSameKey(t *testing.T) { store := newIdempotencyStore(time.Minute) leader, _ := store.begin("k") if !leader { t.Fatal("首个请求应拿到执行权") } done := make(chan struct{}) go func() { leader, wait := store.begin("k") if leader { t.Error("并发同 key 不应拿到执行权") } <-wait close(done) }() // 等 goroutine 进入等待后再检查它不会提前返回。 time.Sleep(20 * time.Millisecond) select { case <-done: t.Fatal("未释放执行权前等待者不应返回") default: } store.end("k") select { case <-done: case <-time.After(time.Second): t.Fatal("释放执行权后应唤醒等待者") } // 释放后应能重新拿到执行权。 if leader, _ := store.begin("k"); !leader { t.Fatal("执行权释放后应可再次获取") } store.end("k") }