types/lazy: add (*SyncValue[T]).SetForTest method

It is sometimes necessary to change a global lazy.SyncValue for the duration of a test. This PR adds a (*SyncValue[T]).SetForTest method to facilitate that.

Updates #12687

Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
Nick Khyl
2024-07-19 15:29:25 -05:00
committed by Nick Khyl
parent d500a92926
commit 5d09649b0b
2 changed files with 223 additions and 0 deletions

View File

@@ -154,3 +154,34 @@ func SyncFuncErr[T any](fill func() (T, error)) func() (T, error) {
return v, err
}
}
// TB is a subset of testing.TB that we use to set up test helpers.
// It's defined here to avoid pulling in the testing package.
type TB interface {
Helper()
Cleanup(func())
}
// SetForTest sets z's value and error.
// It's used in tests only and reverts z's state back when tb and all its
// subtests complete.
// It is not safe for concurrent use and must not be called concurrently with
// any SyncValue methods, including another call to itself.
func (z *SyncValue[T]) SetForTest(tb TB, val T, err error) {
tb.Helper()
z.once.Do(func() {})
oldErr, oldVal := z.err.Load(), z.v
z.v = val
if err != nil {
z.err.Store(ptr.To(err))
} else {
z.err.Store(nilErrPtr)
}
tb.Cleanup(func() {
z.v = oldVal
z.err.Store(oldErr)
})
}