返回 DeepSeek-Reasonix
jsonstore_windows_test.go
根目录 / internal / taskmonitor / jsonstore_windows_test.go
1 //go:build windows
2
3 package taskmonitor
4
5 import (
6 "context"
7 "os"
8 "path/filepath"
9 "testing"
10 "time"
11 )
12
13 func TestFileStoreSaveTaskWaitsForTransientSnapshotReader(t *testing.T) {
14 dir := t.TempDir()
15 store := NewFileStore(".reasonix/tasks")
16 ctx := context.Background()
17 now := time.Now()
18 snapshot := TaskSnapshot{SchemaVersion: 1, TaskID: "t1", SessionID: "s1", State: TaskStateRunning, Version: 1, CreatedAt: now, UpdatedAt: now}
19 if err := store.SaveTask(ctx, dir, snapshot); err != nil {
20 t.Fatal(err)
21 }
22 path := filepath.Join(dir, ".reasonix", "tasks", "t1", "snapshot.json")
23 reader, err := os.Open(path) // ordinary Windows readers omit delete sharing
24 if err != nil {
25 t.Fatal(err)
26 }
27 defer reader.Close()
28 snapshot.Version = 2
29 done := make(chan error, 1)
30 go func() { done <- store.SaveTask(ctx, dir, snapshot) }()
31 // Hold a real OS read handle across the first publication attempts. The
32 // operation must survive this bounded sharing violation, not fail the task
33 // control command or fall back to truncating the visible snapshot.
34 select {
35 case err := <-done:
36 t.Fatalf("save completed while the snapshot reader excluded replacement: %v", err)
37 case <-time.After(100 * time.Millisecond):
38 }
39 if err := reader.Close(); err != nil {
40 t.Fatal(err)
41 }
42 select {
43 case err := <-done:
44 if err != nil {
45 t.Fatal(err)
46 }
47 case <-time.After(5 * time.Second):
48 t.Fatal("snapshot publication did not resume after the reader closed")
49 }
50 got, err := store.GetTask(ctx, dir, "t1")
51 if err != nil || got == nil || got.Version != 2 {
52 t.Fatalf("published snapshot = %+v, err=%v", got, err)
53 }
54 }
55
55 lines GO