Files
coder/coderd/autobuild/notify/notifier_test.go
Cian Johnston 7b88776403 chore(testutil): add testutil.GoleakOptions (#16070)
- Adds `testutil.GoleakOptions` and consolidates existing options to
this location
- Pre-emptively adds required ignore for this Dependabot PR to pass CI
https://github.com/coder/coder/pull/16066
2025-01-08 15:38:37 +00:00

127 lines
3.1 KiB
Go

package notify_test
import (
"testing"
"time"
"github.com/stretchr/testify/require"
"go.uber.org/goleak"
"github.com/coder/coder/v2/coderd/autobuild/notify"
"github.com/coder/coder/v2/testutil"
"github.com/coder/quartz"
)
func TestNotifier(t *testing.T) {
t.Parallel()
now := time.Date(2022, 5, 13, 0, 0, 0, 0, time.UTC)
testCases := []struct {
Name string
Countdown []time.Duration
PollInterval time.Duration
NTicks int
ConditionDeadline time.Time
NumConditions int
NumCallbacks int
}{
{
Name: "zero deadline",
Countdown: durations(),
PollInterval: time.Second,
NTicks: 0,
ConditionDeadline: time.Time{},
NumConditions: 1,
NumCallbacks: 0,
},
{
Name: "no calls",
Countdown: durations(),
PollInterval: time.Second,
NTicks: 0,
ConditionDeadline: now,
NumConditions: 1,
NumCallbacks: 0,
},
{
Name: "exactly one call",
Countdown: durations(time.Second),
PollInterval: time.Second,
NTicks: 1,
ConditionDeadline: now.Add(time.Second),
NumConditions: 2,
NumCallbacks: 1,
},
{
Name: "two calls",
Countdown: durations(4*time.Second, 2*time.Second),
PollInterval: time.Second,
NTicks: 5,
ConditionDeadline: now.Add(5 * time.Second),
NumConditions: 6,
NumCallbacks: 2,
},
{
Name: "wrong order should not matter",
Countdown: durations(2*time.Second, 4*time.Second),
PollInterval: time.Second,
NTicks: 5,
ConditionDeadline: now.Add(5 * time.Second),
NumConditions: 6,
NumCallbacks: 2,
},
{
Name: "ssh autostop notify",
Countdown: durations(5*time.Minute, time.Minute),
PollInterval: 30 * time.Second,
NTicks: 120,
ConditionDeadline: now.Add(30 * time.Minute),
NumConditions: 121,
NumCallbacks: 2,
},
}
for _, testCase := range testCases {
testCase := testCase
t.Run(testCase.Name, func(t *testing.T) {
t.Parallel()
ctx := testutil.Context(t, testutil.WaitShort)
mClock := quartz.NewMock(t)
mClock.Set(now).MustWait(ctx)
numConditions := 0
numCalls := 0
cond := func(time.Time) (time.Time, func()) {
numConditions++
return testCase.ConditionDeadline, func() {
numCalls++
}
}
trap := mClock.Trap().TickerFunc("notifier", "poll")
defer trap.Close()
n := notify.New(cond, testCase.PollInterval, testCase.Countdown, notify.WithTestClock(mClock))
defer n.Close()
trap.MustWait(ctx).Release() // ensure ticker started
for i := 0; i < testCase.NTicks; i++ {
interval, w := mClock.AdvanceNext()
w.MustWait(ctx)
require.Equal(t, testCase.PollInterval, interval)
}
require.Equal(t, testCase.NumCallbacks, numCalls)
require.Equal(t, testCase.NumConditions, numConditions)
})
}
}
func durations(ds ...time.Duration) []time.Duration {
return ds
}
func TestMain(m *testing.M) {
goleak.VerifyTestMain(m, testutil.GoleakOptions...)
}