返回 DeepSeek-Reasonix
session_catalog_rebuild_timeout_test.go
根目录 / desktop / session_catalog_rebuild_timeout_test.go
1 package main
2
3 import (
4 "errors"
5 "os"
6 "path/filepath"
7 "testing"
8 "time"
9
10 "reasonix/internal/config"
11 "reasonix/internal/sessioncatalog"
12 )
13
14 func TestRebuildSessionCatalogDoesNotReplaceBeforeOldReconcileStops(t *testing.T) {
15 isolateDesktopUserDirs(t)
16 dir := config.SessionDir()
17 if err := os.MkdirAll(dir, 0o755); err != nil {
18 t.Fatal(err)
19 }
20
21 app := NewApp()
22 app.startSessionCatalog()
23 oldCatalog := waitForSessionCatalogForTest(t, app, nil)
24 t.Cleanup(func() { app.stopSessionCatalog(time.Second) })
25
26 catalogPath := sessioncatalog.DefaultPath()
27 before, err := os.Stat(catalogPath)
28 if err != nil {
29 t.Fatal(err)
30 }
31 started := make(chan struct{})
32 release := make(chan struct{})
33 finished := make(chan struct{})
34 app.catalogReconcileHook = func(sessioncatalog.DirectoryTarget) {
35 close(started)
36 <-release
37 }
38 app.catalogReconcileDoneHook = func(sessioncatalog.DirectoryTarget) { close(finished) }
39 if !app.requestSessionCatalogReconcile(dir) {
40 t.Fatal("explicit reconcile was not scheduled")
41 }
42 <-started
43
44 stopTimeout := 25 * time.Millisecond
45 err = app.rebuildSessionCatalog(stopTimeout)
46 if !errors.Is(err, errSessionCatalogStopTimeout) {
47 close(release)
48 t.Fatalf("rebuild error = %v, want stop deadline error", err)
49 }
50 if app.catalogRebuilding.Load() {
51 close(release)
52 t.Fatal("timed-out rebuild left rebuilding set")
53 }
54 after, err := os.Stat(catalogPath)
55 if err != nil {
56 close(release)
57 t.Fatal(err)
58 }
59 if !os.SameFile(before, after) {
60 close(release)
61 t.Fatal("rebuild replaced the live projection before the old reconcile stopped")
62 }
63 if backups, err := filepath.Glob(catalogPath + ".replaced-*"); err != nil || len(backups) != 0 {
64 close(release)
65 t.Fatalf("replacement backups after aborted rebuild = %v, err = %v", backups, err)
66 }
67
68 close(release)
69 select {
70 case <-finished:
71 case <-time.After(5 * time.Second):
72 t.Fatal("old reconcile did not finish after release")
73 }
74 assertSessionCatalogWatcherRunning(t, app)
75 _ = waitForSessionCatalogForTest(t, app, oldCatalog)
76 }
77
77 lines GO