返回 DeepSeek-Reasonix
modelswitch_test.go
根目录 / internal / serve / modelswitch_test.go
1 package serve
2
3 import (
4 "sync"
5 "testing"
6
7 "reasonix/internal/control"
8 )
9
10 // TestControllerAccessorIsRaceSafe guards the switchModel concurrency contract:
11 // handlers read the controller through ctl() while a swap runs under the write
12 // lock. With the lock removed this fails under `go test -race` (the CI race job).
13 func TestControllerAccessorIsRaceSafe(t *testing.T) {
14 a, b := &control.Controller{}, &control.Controller{}
15 s := &Server{ctrl: a}
16
17 var wg sync.WaitGroup
18 for i := 0; i < 64; i++ {
19 wg.Add(1)
20 go func() {
21 defer wg.Done()
22 if got := s.ctl(); got != a && got != b {
23 t.Errorf("ctl() returned a pointer that was never set")
24 }
25 }()
26 }
27 for i := 0; i < 16; i++ {
28 wg.Add(1)
29 go func() {
30 defer wg.Done()
31 s.mu.Lock()
32 if s.ctrl == a {
33 s.ctrl = b
34 } else {
35 s.ctrl = a
36 }
37 s.mu.Unlock()
38 }()
39 }
40 wg.Wait()
41 }
42
42 lines GO