返回 DeepSeek-Reasonix
repair_generation_guard_test.go
根目录 / internal / sessioncatalog / repair_generation_guard_test.go
1 package sessioncatalog
2
3 import (
4 "context"
5 "errors"
6 "path/filepath"
7 "testing"
8 "time"
9
10 "reasonix/internal/agent"
11 )
12
13 func TestRepairBatchHoldsSourceGenerationThroughCommit(t *testing.T) {
14 ctx := context.Background()
15 now := time.Date(2026, 9, 1, 12, 0, 0, 0, time.UTC)
16 catalog, err := Open(ctx, Options{
17 Path: filepath.Join(t.TempDir(), "catalog.sqlite"), DisableRepair: true, Now: func() time.Time { return now },
18 })
19 if err != nil {
20 t.Fatal(err)
21 }
22 t.Cleanup(func() { _ = catalog.Close(context.Background()) })
23 path := filepath.Join(t.TempDir(), "commit-fence.jsonl")
24 seedRepairFenceRow(t, catalog, path)
25 items, err := catalog.claimDueRepairs(ctx, 1)
26 if err != nil || len(items) != 1 {
27 t.Fatalf("claimDueRepairs items=%d err=%v", len(items), err)
28 }
29 result := agent.SessionListingRepairResult{
30 Status: agent.SessionListingRepairApplied, Preview: "old", Turns: 1,
31 ContentFingerprint: sessionContentFingerprint(path), MetaFingerprint: fileFingerprint(agent.BranchMetaPath(path)),
32 }
33 catalog.testRepairBatchError = func(stage string) error {
34 if stage != "commit" {
35 return nil
36 }
37 _, unlock, lockErr := agent.TryLockSessionListingGeneration(path)
38 if unlock != nil {
39 unlock()
40 }
41 if !errors.Is(lockErr, agent.ErrSessionListingRepairBusy) {
42 return errors.New("source generation was not fenced through commit")
43 }
44 return nil
45 }
46 if err := catalog.applyRepairBatch(ctx, []repairOutcome{{item: items[0], result: result}}, map[string]DirectoryTarget{}); err != nil {
47 t.Fatal(err)
48 }
49 var state string
50 if err := catalog.db.QueryRowContext(ctx, `SELECT repair_state FROM catalog_sessions WHERE path_key=?`,
51 catalog.pathKey(path)).Scan(&state); err != nil {
52 t.Fatal(err)
53 }
54 if state != "complete" {
55 t.Fatalf("repair state = %s, want complete", state)
56 }
57 }
58
58 lines GO