Files
netbird/client/internal/profilemanager/active_state_test.go
T
Theodor Midtlien 4c19226342 [client] Use POSIX style file read/write of json for windows (#7631)
* Use POSIX-like file read/write of json for windows + tests: allow renaming an open file.
2026-09-24 10:23:50 +02:00

77 lines
2.0 KiB
Go

package profilemanager
import (
"fmt"
"sync"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// Regression test: a concurrent Get and Set of the ActiveProfileState will
// fail on Windows since the write is a temp file renamed over an open file.
// Windows will refuse to replace a file another handle holds open by default.
func TestActiveProfileState_ReadsDoNotBreakAConcurrentWrite(t *testing.T) {
withTempConfigDir(t, func(configDir string) {
withPatchedGlobals(t, configDir, func() {
sm := &ServiceManager{}
require.NoError(t, sm.CreateDefaultProfile())
require.NoError(t, sm.SetActiveProfileStateToDefault())
const switched = ID("0123456789abcdef0123456789abcdef")
const rounds = 50
var wg sync.WaitGroup
errs := make(chan error, 128)
for i := 0; i < 8; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for r := 0; r < rounds; r++ {
state, err := sm.GetActiveProfileState()
if err != nil {
errs <- fmt.Errorf("read: %w", err)
return
}
if state.ID != defaultProfileName && state.ID != switched {
errs <- fmt.Errorf("read: active profile is %q, which no writer wrote", state.ID)
return
}
}
}()
}
for i := 0; i < 2; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for r := 0; r < rounds; r++ {
id := switched
if r%2 == 0 {
id = defaultProfileName
}
if err := sm.SetActiveProfileState(&ActiveProfileState{ID: id, Username: "testuser"}); err != nil {
errs <- fmt.Errorf("switch: %w", err)
return
}
}
}()
}
wg.Wait()
close(errs)
for err := range errs {
assert.NoError(t, err, "a switch and a read of the active profile state must not collide")
}
state, err := sm.GetActiveProfileState()
require.NoError(t, err)
assert.Contains(t, []ID{defaultProfileName, switched}, state.ID,
"the file holds whichever switch landed last, not a mix of the two")
})
})
}