| 1 | package main |
| 2 | |
| 3 | import "testing" |
| 4 | |
| 5 | func TestSetDefaultModelConcurrentTabModelUpdateIsRaceFree(t *testing.T) { |
| 6 | isolateDesktopUserDirs(t) |
| 7 | oldRef, newRef := configureSwitchableDefaultModels(t) |
| 8 | |
| 9 | app := NewApp() |
| 10 | tab := testTab("default-model-race", globalWorkspaceRoot()) |
| 11 | tab.Scope = "global" |
| 12 | tab.model = oldRef |
| 13 | tab.sink = &tabEventSink{tabID: tab.ID, app: app} |
| 14 | app.tabs = map[string]*WorkspaceTab{tab.ID: tab} |
| 15 | app.tabOrder = []string{tab.ID} |
| 16 | app.activeTabID = tab.ID |
| 17 | t.Cleanup(func() { |
| 18 | if tab.Ctrl != nil { |
| 19 | tab.Ctrl.Close() |
| 20 | } |
| 21 | }) |
| 22 | |
| 23 | started := make(chan struct{}) |
| 24 | stop := make(chan struct{}) |
| 25 | done := make(chan struct{}) |
| 26 | go func() { |
| 27 | defer close(done) |
| 28 | app.mu.Lock() |
| 29 | tab.model = oldRef |
| 30 | app.mu.Unlock() |
| 31 | close(started) |
| 32 | for { |
| 33 | select { |
| 34 | case <-stop: |
| 35 | return |
| 36 | default: |
| 37 | app.mu.Lock() |
| 38 | tab.model = oldRef |
| 39 | app.mu.Unlock() |
| 40 | } |
| 41 | } |
| 42 | }() |
| 43 | <-started |
| 44 | |
| 45 | err := app.SetDefaultModel(newRef) |
| 46 | close(stop) |
| 47 | <-done |
| 48 | if err != nil { |
| 49 | t.Fatalf("SetDefaultModel: %v", err) |
| 50 | } |
| 51 | } |
| 52 |