package config import ( "context" "errors" "os" "path/filepath" "strings" "sync" "testing" ) func TestConfigCASAndMetadataIsolation(t *testing.T) { store := NewStore(filepath.Join(t.TempDir(), "config.yaml"), "") m, err := NewManager(context.Background(), store) if err != nil { t.Fatal(err) } a, _ := m.Load(nil) b, _ := m.Load(nil) if a.Revision == "" { t.Fatal("missing revision") } if err = m.SaveLastAgentModelHash(nil, "model-new"); err != nil { t.Fatal(err) } a.CLIHTTPSListenAddr = "127.0.0.1:39099" first, err := m.Save(nil, a) if err != nil { t.Fatal(err) } if first.LastAgentModelHash != "model-new" { t.Fatal("UI overwrote backend metadata") } b.HomeMetrics.RefreshIntervalSeconds = 11 if _, err = m.Save(nil, b); !errors.Is(err, ErrConfigConflict) { t.Fatalf("stale save accepted: %v", err) } current, _ := m.Load(nil) if current.CLIHTTPSListenAddr != "127.0.0.1:39099" { t.Fatal("CLI port lost") } data, _ := os.ReadFile(store.Path()) if strings.Contains(string(data), "revision:") { t.Fatal("revision persisted in YAML") } if current.Revision == a.Revision { t.Fatal("revision did not change") } } func TestConcurrentSavesHaveExactlyOneWinner(t *testing.T) { store := NewStore(filepath.Join(t.TempDir(), "config.yaml"), "") m, err := NewManager(context.Background(), store) if err != nil { t.Fatal(err) } a, _ := m.Load(nil) b := cloneConfig(a) a.HomeMetrics.RefreshIntervalSeconds = 11 b.HomeMetrics.RefreshIntervalSeconds = 12 var wg sync.WaitGroup results := make(chan error, 2) for _, cfg := range []Config{a, b} { wg.Add(1) go func(c Config) { defer wg.Done(); _, err := m.Save(nil, c); results <- err }(cfg) } wg.Wait() close(results) success, conflict := 0, 0 for err := range results { if err == nil { success++ } else if errors.Is(err, ErrConfigConflict) { conflict++ } else { t.Fatal(err) } } if success != 1 || conflict != 1 { t.Fatalf("success=%d conflict=%d", success, conflict) } }