types/lazy: re-init SyncValue during test cleanup if it wasn't set before SetForTest

Updates #12687

Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
Nick Khyl 2024-07-23 19:34:03 -05:00 committed by Nick Khyl
parent ba7f2d129e
commit 43375c6efb
2 changed files with 23 additions and 3 deletions

View File

@ -170,8 +170,8 @@ type TB interface {
func (z *SyncValue[T]) SetForTest(tb TB, val T, err error) { func (z *SyncValue[T]) SetForTest(tb TB, val T, err error) {
tb.Helper() tb.Helper()
z.once.Do(func() {})
oldErr, oldVal := z.err.Load(), z.v oldErr, oldVal := z.err.Load(), z.v
z.once.Do(func() {})
z.v = val z.v = val
if err != nil { if err != nil {
@ -181,7 +181,11 @@ func (z *SyncValue[T]) SetForTest(tb TB, val T, err error) {
} }
tb.Cleanup(func() { tb.Cleanup(func() {
if oldErr == nil {
*z = SyncValue[T]{}
} else {
z.v = oldVal z.v = oldVal
z.err.Store(oldErr) z.err.Store(oldErr)
}
}) })
} }

View File

@ -290,6 +290,22 @@ func TestSyncValueSetForTest(t *testing.T) {
t.Fatalf("CleanupValue: got %v; want %v", gotCleanupValue, wantCleanupValue) t.Fatalf("CleanupValue: got %v; want %v", gotCleanupValue, wantCleanupValue)
} }
}) })
} else {
// Verify that if v wasn't set prior to SetForTest, it's
// reverted to a valid unset state during the test cleanup.
t.Cleanup(func() {
if _, _, ok := v.PeekErr(); ok {
t.Fatal("SyncValue is set after cleanup")
}
wantCleanupValue, wantCleanupErr := 42, errors.New("ka-boom")
gotCleanupValue, gotCleanupErr := v.GetErr(func() (int, error) { return wantCleanupValue, wantCleanupErr })
if gotCleanupErr != wantCleanupErr {
t.Fatalf("CleanupErr: got %v; want %v", gotCleanupErr, wantCleanupErr)
}
if gotCleanupValue != wantCleanupValue {
t.Fatalf("CleanupValue: got %v; want %v", gotCleanupValue, wantCleanupValue)
}
})
} }
// Set the test value and/or error. // Set the test value and/or error.