Skip to content

Commit f24cb5c

Browse files
authored
fix: prevent test flakiness (coder#14467)
Signed-off-by: Danny Kopping <danny@coder.com>
1 parent c597c92 commit f24cb5c

File tree

1 file changed

+24
-16
lines changed

1 file changed

+24
-16
lines changed

coderd/notifications/notifications_test.go

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ func TestNotifierPaused(t *testing.T) {
576576
ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong))
577577
_, _, api := coderdtest.NewWithAPI(t, nil)
578578

579-
// Prepare the test
579+
// Prepare the test.
580580
handler := &fakeHandler{}
581581
method := database.NotificationMethodSmtp
582582
user := createSampleUser(t, api.Database)
@@ -593,32 +593,39 @@ func TestNotifierPaused(t *testing.T) {
593593
enq, err := notifications.NewStoreEnqueuer(cfg, api.Database, defaultHelpers(), api.Logger.Named("enqueuer"), quartz.NewReal())
594594
require.NoError(t, err)
595595

596-
mgr.Run(ctx)
597-
598596
// Pause the notifier.
599597
settingsJSON, err := json.Marshal(&codersdk.NotificationsSettings{NotifierPaused: true})
600598
require.NoError(t, err)
601599
err = api.Database.UpsertNotificationsSettings(ctx, string(settingsJSON))
602600
require.NoError(t, err)
603601

602+
// Start the manager so that notifications are processed, except it will be paused at this point.
603+
// If it is started before pausing, there's a TOCTOU possibility between checking whether the notifier is paused or
604+
// not, and processing the messages (see notifier.run).
605+
mgr.Run(ctx)
606+
604607
// Notifier is paused, enqueue the next message.
605608
sid, err := enq.Enqueue(ctx, user.ID, notifications.TemplateWorkspaceDeleted, map[string]string{"type": "success", "i": "1"}, "test")
606609
require.NoError(t, err)
607610

608-
// Sleep for a few fetch intervals to be sure we aren't getting false-positives in the next step.
609-
// TODO: use quartz instead.
610-
time.Sleep(fetchInterval * 5)
611-
612611
// Ensure we have a pending message and it's the expected one.
612+
pendingMessages, err := api.Database.GetNotificationMessagesByStatus(ctx, database.GetNotificationMessagesByStatusParams{
613+
Status: database.NotificationMessageStatusPending,
614+
Limit: 10,
615+
})
616+
require.NoError(t, err)
617+
require.Len(t, pendingMessages, 1)
618+
require.Equal(t, pendingMessages[0].ID.String(), sid.String())
619+
620+
// Wait a few fetch intervals to be sure that no new notifications are being sent.
621+
// TODO: use quartz instead.
622+
// nolint:gocritic // These magic numbers are fine.
613623
require.Eventually(t, func() bool {
614-
pendingMessages, err := api.Database.GetNotificationMessagesByStatus(ctx, database.GetNotificationMessagesByStatusParams{
615-
Status: database.NotificationMessageStatusPending,
616-
Limit: 10,
617-
})
618-
assert.NoError(t, err)
619-
return len(pendingMessages) == 1 &&
620-
pendingMessages[0].ID.String() == sid.String()
621-
}, testutil.WaitShort, testutil.IntervalFast)
624+
handler.mu.RLock()
625+
defer handler.mu.RUnlock()
626+
627+
return len(handler.succeeded)+len(handler.failed) == 0
628+
}, fetchInterval*5, testutil.IntervalFast)
622629

623630
// Unpause the notifier.
624631
settingsJSON, err = json.Marshal(&codersdk.NotificationsSettings{NotifierPaused: false})
@@ -627,11 +634,12 @@ func TestNotifierPaused(t *testing.T) {
627634
require.NoError(t, err)
628635

629636
// Notifier is running again, message should be dequeued.
637+
// nolint:gocritic // These magic numbers are fine.
630638
require.Eventually(t, func() bool {
631639
handler.mu.RLock()
632640
defer handler.mu.RUnlock()
633641
return slices.Contains(handler.succeeded, sid.String())
634-
}, testutil.WaitShort, testutil.IntervalFast)
642+
}, fetchInterval*5, testutil.IntervalFast)
635643
}
636644

637645
//go:embed events.go

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy