package config import ( "fmt" "path/filepath" "sync" "testing" ) func TestSetConfigValueConcurrentUpdatesPreserveEveryKey(t *testing.T) { home := t.TempDir() isolateConfigHome(t, home) t.Setenv("USERPROFILE", home) t.Setenv("APPDATA", home) t.Setenv("XDG_CONFIG_HOME", filepath.Join(home, ".config")) const updates = 24 start := make(chan struct{}) errs := make(chan error, updates) var wg sync.WaitGroup for i := 0; i < updates; i++ { wg.Add(1) go func(i int) { defer wg.Done() <-start key := fmt.Sprintf("cor06-option-%02d", i) value := fmt.Sprintf("value-%02d", i) if err := SetConfigValue(key, []string{value}, true); err != nil { errs <- err } }(i) } close(start) wg.Wait() close(errs) for err := range errs { t.Fatal(err) } configPath := GetConfigPath() parsed, err := ParseConfig(configPath) if err != nil { t.Fatal(err) } for i := 0; i < updates; i++ { key := fmt.Sprintf("cor06-option-%02d", i) want := fmt.Sprintf("value-%02d", i) if got := parsed[key]; len(got) != 1 || got[0] != want { t.Errorf("%s = %v, want [%s]", key, got, want) } } temps, err := filepath.Glob(filepath.Join(filepath.Dir(configPath), ".mpv.conf.tmp-*")) if err != nil { t.Fatal(err) } if len(temps) != 0 { t.Fatalf("temporary files remain after concurrent updates: %v", temps) } }