返回 DeepSeek-Reasonix
pairing_test.go
根目录 / internal / bot / pairing_test.go
1 package bot
2
3 import (
4 "fmt"
5 "sync"
6 "testing"
7 "time"
8 )
9
10 // Guards pairingMu + the atomic savePairingFile: concurrent offerPairing
11 // dispatch goroutines used to load-modify-save pairing.json without a lock and
12 // overwrite each other's requests. Run with -race.
13 func TestCreateOrRefreshPairingRequestConcurrent(t *testing.T) {
14 t.Setenv("REASONIX_HOME", t.TempDir())
15 cfg := PairingConfig{Enabled: true, RequestTTL: time.Hour, MaxPendingPerPlatform: 64}
16
17 const workers = 8
18 var wg sync.WaitGroup
19 errs := make(chan error, workers)
20 for i := 0; i < workers; i++ {
21 wg.Add(1)
22 go func(i int) {
23 defer wg.Done()
24 msg := InboundMessage{
25 Platform: PlatformFeishu,
26 ChatType: ChatDM,
27 ChatID: fmt.Sprintf("chat-%d", i),
28 UserID: fmt.Sprintf("user-%d", i),
29 }
30 for j := 0; j < 5; j++ {
31 if _, _, err := CreateOrRefreshPairingRequest(msg, cfg); err != nil {
32 errs <- err
33 return
34 }
35 }
36 }(i)
37 }
38 wg.Wait()
39 close(errs)
40 for err := range errs {
41 t.Fatalf("concurrent pairing request failed: %v", err)
42 }
43
44 reqs, err := ListPairingRequests()
45 if err != nil {
46 t.Fatalf("list pairing requests: %v", err)
47 }
48 if len(reqs) != workers {
49 t.Fatalf("pairing store lost concurrent writes: got %d requests, want %d", len(reqs), workers)
50 }
51 }
52
52 lines GO