diff --git a/coderd/notifications/manager_test.go b/coderd/notifications/manager_test.go index ddbdb0b518d90..53aa8f1354ec4 100644 --- a/coderd/notifications/manager_test.go +++ b/coderd/notifications/manager_test.go @@ -12,10 +12,12 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/xerrors" + "cdr.dev/slog" + "cdr.dev/slog/sloggers/slogtest" + "github.com/coder/coder/v2/coderd/database/dbtestutil" "github.com/coder/quartz" "github.com/coder/serpent" - "github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbgen" @@ -32,24 +34,25 @@ func TestBufferedUpdates(t *testing.T) { // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) - interceptor := &syncInterceptor{Store: api.Database} + interceptor := &syncInterceptor{Store: store} santa := &santaHandler{} cfg := defaultNotificationsConfig(database.NotificationMethodSmtp) cfg.StoreSyncInterval = serpent.Duration(time.Hour) // Ensure we don't sync the store automatically. // GIVEN: a manager which will pass or fail notifications based on their "nice" labels - mgr, err := notifications.NewManager(cfg, interceptor, defaultHelpers(), createMetrics(), api.Logger.Named("notifications-manager")) + mgr, err := notifications.NewManager(cfg, interceptor, defaultHelpers(), createMetrics(), logger.Named("notifications-manager")) require.NoError(t, err) mgr.WithHandlers(map[database.NotificationMethod]notifications.Handler{ database.NotificationMethodSmtp: santa, }) - enq, err := notifications.NewStoreEnqueuer(cfg, interceptor, defaultHelpers(), api.Logger.Named("notifications-enqueuer"), quartz.NewReal()) + enq, err := notifications.NewStoreEnqueuer(cfg, interceptor, defaultHelpers(), logger.Named("notifications-enqueuer"), quartz.NewReal()) require.NoError(t, err) - user := dbgen.User(t, api.Database, database.User{}) + user := dbgen.User(t, store, database.User{}) // WHEN: notifications are enqueued which should succeed and fail _, err = enq.Enqueue(ctx, user.ID, notifications.TemplateWorkspaceDeleted, map[string]string{"nice": "true", "i": "0"}, "") // Will succeed. @@ -103,7 +106,8 @@ func TestBuildPayload(t *testing.T) { // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) // GIVEN: a set of helpers to be injected into the templates const label = "Click here!" @@ -115,7 +119,7 @@ func TestBuildPayload(t *testing.T) { } // GIVEN: an enqueue interceptor which returns mock metadata - interceptor := newEnqueueInterceptor(api.Database, + interceptor := newEnqueueInterceptor(store, // Inject custom message metadata to influence the payload construction. func() database.FetchNewMessageMetadataRow { // Inject template actions which use injected help functions. @@ -137,7 +141,7 @@ func TestBuildPayload(t *testing.T) { } }) - enq, err := notifications.NewStoreEnqueuer(defaultNotificationsConfig(database.NotificationMethodSmtp), interceptor, helpers, api.Logger.Named("notifications-enqueuer"), quartz.NewReal()) + enq, err := notifications.NewStoreEnqueuer(defaultNotificationsConfig(database.NotificationMethodSmtp), interceptor, helpers, logger.Named("notifications-enqueuer"), quartz.NewReal()) require.NoError(t, err) // WHEN: a notification is enqueued @@ -160,10 +164,11 @@ func TestStopBeforeRun(t *testing.T) { // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) // GIVEN: a standard manager - mgr, err := notifications.NewManager(defaultNotificationsConfig(database.NotificationMethodSmtp), api.Database, defaultHelpers(), createMetrics(), api.Logger.Named("notifications-manager")) + mgr, err := notifications.NewManager(defaultNotificationsConfig(database.NotificationMethodSmtp), store, defaultHelpers(), createMetrics(), logger.Named("notifications-manager")) require.NoError(t, err) // THEN: validate that the manager can be stopped safely without Run() having been called yet diff --git a/coderd/notifications/metrics_test.go b/coderd/notifications/metrics_test.go index 294eccc31c891..31cce65026643 100644 --- a/coderd/notifications/metrics_test.go +++ b/coderd/notifications/metrics_test.go @@ -15,11 +15,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "cdr.dev/slog" + "cdr.dev/slog/sloggers/slogtest" "github.com/coder/quartz" - "github.com/coder/serpent" - "github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbtestutil" @@ -39,7 +39,8 @@ func TestMetrics(t *testing.T) { // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) reg := prometheus.NewRegistry() metrics := notifications.NewMetrics(reg) @@ -59,7 +60,7 @@ func TestMetrics(t *testing.T) { cfg.RetryInterval = serpent.Duration(time.Millisecond * 50) cfg.StoreSyncInterval = serpent.Duration(time.Millisecond * 100) // Twice as long as fetch interval to ensure we catch pending updates. - mgr, err := notifications.NewManager(cfg, api.Database, defaultHelpers(), metrics, api.Logger.Named("manager")) + mgr, err := notifications.NewManager(cfg, store, defaultHelpers(), metrics, logger.Named("manager")) require.NoError(t, err) t.Cleanup(func() { assert.NoError(t, mgr.Stop(ctx)) @@ -69,10 +70,10 @@ func TestMetrics(t *testing.T) { method: handler, }) - enq, err := notifications.NewStoreEnqueuer(cfg, api.Database, defaultHelpers(), api.Logger.Named("enqueuer"), quartz.NewReal()) + enq, err := notifications.NewStoreEnqueuer(cfg, store, defaultHelpers(), logger.Named("enqueuer"), quartz.NewReal()) require.NoError(t, err) - user := createSampleUser(t, api.Database) + user := createSampleUser(t, store) // Build fingerprints for the two different series we expect. methodTemplateFP := fingerprintLabels(notifications.LabelMethod, string(method), notifications.LabelTemplateID, template.String()) @@ -212,7 +213,8 @@ func TestPendingUpdatesMetric(t *testing.T) { // SETUP // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) reg := prometheus.NewRegistry() metrics := notifications.NewMetrics(reg) @@ -225,12 +227,12 @@ func TestPendingUpdatesMetric(t *testing.T) { cfg.RetryInterval = serpent.Duration(time.Hour) // Delay retries so they don't interfere. cfg.StoreSyncInterval = serpent.Duration(time.Millisecond * 100) - syncer := &syncInterceptor{Store: api.Database} + syncer := &syncInterceptor{Store: store} interceptor := newUpdateSignallingInterceptor(syncer) mClock := quartz.NewMock(t) trap := mClock.Trap().NewTicker("Manager", "storeSync") defer trap.Close() - mgr, err := notifications.NewManager(cfg, interceptor, defaultHelpers(), metrics, api.Logger.Named("manager"), + mgr, err := notifications.NewManager(cfg, interceptor, defaultHelpers(), metrics, logger.Named("manager"), notifications.WithTestClock(mClock)) require.NoError(t, err) t.Cleanup(func() { @@ -241,10 +243,10 @@ func TestPendingUpdatesMetric(t *testing.T) { method: handler, }) - enq, err := notifications.NewStoreEnqueuer(cfg, api.Database, defaultHelpers(), api.Logger.Named("enqueuer"), quartz.NewReal()) + enq, err := notifications.NewStoreEnqueuer(cfg, store, defaultHelpers(), logger.Named("enqueuer"), quartz.NewReal()) require.NoError(t, err) - user := createSampleUser(t, api.Database) + user := createSampleUser(t, store) // WHEN: 2 notifications are enqueued, one of which will fail and one which will succeed _, err = enq.Enqueue(ctx, user.ID, template, map[string]string{"type": "success"}, "test") // this will succeed @@ -296,7 +298,8 @@ func TestInflightDispatchesMetric(t *testing.T) { // SETUP // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) reg := prometheus.NewRegistry() metrics := notifications.NewMetrics(reg) @@ -311,7 +314,7 @@ func TestInflightDispatchesMetric(t *testing.T) { cfg.RetryInterval = serpent.Duration(time.Hour) // Delay retries so they don't interfere. cfg.StoreSyncInterval = serpent.Duration(time.Millisecond * 100) - mgr, err := notifications.NewManager(cfg, api.Database, defaultHelpers(), metrics, api.Logger.Named("manager")) + mgr, err := notifications.NewManager(cfg, store, defaultHelpers(), metrics, logger.Named("manager")) require.NoError(t, err) t.Cleanup(func() { assert.NoError(t, mgr.Stop(ctx)) @@ -326,10 +329,10 @@ func TestInflightDispatchesMetric(t *testing.T) { method: barrier, }) - enq, err := notifications.NewStoreEnqueuer(cfg, api.Database, defaultHelpers(), api.Logger.Named("enqueuer"), quartz.NewReal()) + enq, err := notifications.NewStoreEnqueuer(cfg, store, defaultHelpers(), logger.Named("enqueuer"), quartz.NewReal()) require.NoError(t, err) - user := createSampleUser(t, api.Database) + user := createSampleUser(t, store) // WHEN: notifications are enqueued which will succeed (and be delayed during dispatch) for i := 0; i < msgCount; i++ { @@ -374,7 +377,8 @@ func TestCustomMethodMetricCollection(t *testing.T) { // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) var ( reg = prometheus.NewRegistry() @@ -389,7 +393,7 @@ func TestCustomMethodMetricCollection(t *testing.T) { ) // GIVEN: a template whose notification method differs from the default. - out, err := api.Database.UpdateNotificationTemplateMethodByID(ctx, database.UpdateNotificationTemplateMethodByIDParams{ + out, err := store.UpdateNotificationTemplateMethodByID(ctx, database.UpdateNotificationTemplateMethodByIDParams{ ID: template, Method: database.NullNotificationMethod{NotificationMethod: customMethod, Valid: true}, }) @@ -398,7 +402,7 @@ func TestCustomMethodMetricCollection(t *testing.T) { // WHEN: two notifications (each with different templates) are enqueued. cfg := defaultNotificationsConfig(defaultMethod) - mgr, err := notifications.NewManager(cfg, api.Database, defaultHelpers(), metrics, api.Logger.Named("manager")) + mgr, err := notifications.NewManager(cfg, store, defaultHelpers(), metrics, logger.Named("manager")) require.NoError(t, err) t.Cleanup(func() { assert.NoError(t, mgr.Stop(ctx)) @@ -411,10 +415,10 @@ func TestCustomMethodMetricCollection(t *testing.T) { customMethod: webhookHandler, }) - enq, err := notifications.NewStoreEnqueuer(cfg, api.Database, defaultHelpers(), api.Logger.Named("enqueuer"), quartz.NewReal()) + enq, err := notifications.NewStoreEnqueuer(cfg, store, defaultHelpers(), logger.Named("enqueuer"), quartz.NewReal()) require.NoError(t, err) - user := createSampleUser(t, api.Database) + user := createSampleUser(t, store) _, err = enq.Enqueue(ctx, user.ID, template, map[string]string{"type": "success"}, "test") require.NoError(t, err) diff --git a/coderd/notifications/notifications_test.go b/coderd/notifications/notifications_test.go index 61862826acca1..fea0b0f2f49f4 100644 --- a/coderd/notifications/notifications_test.go +++ b/coderd/notifications/notifications_test.go @@ -35,6 +35,7 @@ import ( "golang.org/x/xerrors" "cdr.dev/slog" + "cdr.dev/slog/sloggers/slogtest" "github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbauthz" @@ -71,24 +72,25 @@ func TestBasicNotificationRoundtrip(t *testing.T) { // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) method := database.NotificationMethodSmtp // GIVEN: a manager with standard config but a faked dispatch handler handler := &fakeHandler{} - interceptor := &syncInterceptor{Store: api.Database} + interceptor := &syncInterceptor{Store: store} cfg := defaultNotificationsConfig(method) cfg.RetryInterval = serpent.Duration(time.Hour) // Ensure retries don't interfere with the test - mgr, err := notifications.NewManager(cfg, interceptor, defaultHelpers(), createMetrics(), api.Logger.Named("manager")) + mgr, err := notifications.NewManager(cfg, interceptor, defaultHelpers(), createMetrics(), logger.Named("manager")) require.NoError(t, err) mgr.WithHandlers(map[database.NotificationMethod]notifications.Handler{method: handler}) t.Cleanup(func() { assert.NoError(t, mgr.Stop(ctx)) }) - enq, err := notifications.NewStoreEnqueuer(cfg, api.Database, defaultHelpers(), api.Logger.Named("enqueuer"), quartz.NewReal()) + enq, err := notifications.NewStoreEnqueuer(cfg, store, defaultHelpers(), logger.Named("enqueuer"), quartz.NewReal()) require.NoError(t, err) - user := createSampleUser(t, api.Database) + user := createSampleUser(t, store) // WHEN: 2 messages are enqueued sid, err := enq.Enqueue(ctx, user.ID, notifications.TemplateWorkspaceDeleted, map[string]string{"type": "success"}, "test") @@ -113,13 +115,13 @@ func TestBasicNotificationRoundtrip(t *testing.T) { }, testutil.WaitLong, testutil.IntervalFast) // THEN: we verify that the store contains notifications in their expected state - success, err := api.Database.GetNotificationMessagesByStatus(ctx, database.GetNotificationMessagesByStatusParams{ + success, err := store.GetNotificationMessagesByStatus(ctx, database.GetNotificationMessagesByStatusParams{ Status: database.NotificationMessageStatusSent, Limit: 10, }) require.NoError(t, err) require.Len(t, success, 1) - failed, err := api.Database.GetNotificationMessagesByStatus(ctx, database.GetNotificationMessagesByStatusParams{ + failed, err := store.GetNotificationMessagesByStatus(ctx, database.GetNotificationMessagesByStatusParams{ Status: database.NotificationMessageStatusTemporaryFailure, Limit: 10, }) @@ -134,7 +136,8 @@ func TestSMTPDispatch(t *testing.T) { // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) // start mock SMTP server mockSMTPSrv := smtpmock.New(smtpmock.ConfigurationAttr{ @@ -155,17 +158,17 @@ func TestSMTPDispatch(t *testing.T) { Smarthost: serpent.HostPort{Host: "localhost", Port: fmt.Sprintf("%d", mockSMTPSrv.PortNumber())}, Hello: "localhost", } - handler := newDispatchInterceptor(dispatch.NewSMTPHandler(cfg.SMTP, defaultHelpers(), api.Logger.Named("smtp"))) - mgr, err := notifications.NewManager(cfg, api.Database, defaultHelpers(), createMetrics(), api.Logger.Named("manager")) + handler := newDispatchInterceptor(dispatch.NewSMTPHandler(cfg.SMTP, defaultHelpers(), logger.Named("smtp"))) + mgr, err := notifications.NewManager(cfg, store, defaultHelpers(), createMetrics(), logger.Named("manager")) require.NoError(t, err) mgr.WithHandlers(map[database.NotificationMethod]notifications.Handler{method: handler}) t.Cleanup(func() { assert.NoError(t, mgr.Stop(ctx)) }) - enq, err := notifications.NewStoreEnqueuer(cfg, api.Database, defaultHelpers(), api.Logger.Named("enqueuer"), quartz.NewReal()) + enq, err := notifications.NewStoreEnqueuer(cfg, store, defaultHelpers(), logger.Named("enqueuer"), quartz.NewReal()) require.NoError(t, err) - user := createSampleUser(t, api.Database) + user := createSampleUser(t, store) // WHEN: a message is enqueued msgID, err := enq.Enqueue(ctx, user.ID, notifications.TemplateWorkspaceDeleted, map[string]string{}, "test") @@ -195,7 +198,8 @@ func TestWebhookDispatch(t *testing.T) { // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) sent := make(chan dispatch.WebhookPayload, 1) // Mock server to simulate webhook endpoint. @@ -220,12 +224,12 @@ func TestWebhookDispatch(t *testing.T) { cfg.Webhook = codersdk.NotificationsWebhookConfig{ Endpoint: *serpent.URLOf(endpoint), } - mgr, err := notifications.NewManager(cfg, api.Database, defaultHelpers(), createMetrics(), api.Logger.Named("manager")) + mgr, err := notifications.NewManager(cfg, store, defaultHelpers(), createMetrics(), logger.Named("manager")) require.NoError(t, err) t.Cleanup(func() { assert.NoError(t, mgr.Stop(ctx)) }) - enq, err := notifications.NewStoreEnqueuer(cfg, api.Database, defaultHelpers(), api.Logger.Named("enqueuer"), quartz.NewReal()) + enq, err := notifications.NewStoreEnqueuer(cfg, store, defaultHelpers(), logger.Named("enqueuer"), quartz.NewReal()) require.NoError(t, err) const ( @@ -233,7 +237,7 @@ func TestWebhookDispatch(t *testing.T) { name = "Robert McBobbington" username = "bob" ) - user := dbgen.User(t, api.Database, database.User{ + user := dbgen.User(t, store, database.User{ Email: email, Username: username, Name: name, @@ -276,7 +280,8 @@ func TestBackpressure(t *testing.T) { // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) // Mock server to simulate webhook endpoint. var received atomic.Int32 @@ -314,19 +319,19 @@ func TestBackpressure(t *testing.T) { cfg.StoreSyncInterval = serpent.Duration(syncInterval) cfg.StoreSyncBufferSize = serpent.Int64(2) - handler := newDispatchInterceptor(dispatch.NewWebhookHandler(cfg.Webhook, api.Logger.Named("webhook"))) + handler := newDispatchInterceptor(dispatch.NewWebhookHandler(cfg.Webhook, logger.Named("webhook"))) // Intercept calls to submit the buffered updates to the store. - storeInterceptor := &syncInterceptor{Store: api.Database} + storeInterceptor := &syncInterceptor{Store: store} // GIVEN: a notification manager whose updates will be intercepted - mgr, err := notifications.NewManager(cfg, storeInterceptor, defaultHelpers(), createMetrics(), api.Logger.Named("manager")) + mgr, err := notifications.NewManager(cfg, storeInterceptor, defaultHelpers(), createMetrics(), logger.Named("manager")) require.NoError(t, err) mgr.WithHandlers(map[database.NotificationMethod]notifications.Handler{method: handler}) - enq, err := notifications.NewStoreEnqueuer(cfg, api.Database, defaultHelpers(), api.Logger.Named("enqueuer"), quartz.NewReal()) + enq, err := notifications.NewStoreEnqueuer(cfg, store, defaultHelpers(), logger.Named("enqueuer"), quartz.NewReal()) require.NoError(t, err) - user := createSampleUser(t, api.Database) + user := createSampleUser(t, store) // WHEN: a set of notifications are enqueued, which causes backpressure due to the batchSize which can be processed per fetch const totalMessages = 30 @@ -367,7 +372,8 @@ func TestRetries(t *testing.T) { const maxAttempts = 3 // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) // GIVEN: a mock HTTP server which will receive webhooksand a map to track the dispatch attempts @@ -412,21 +418,21 @@ func TestRetries(t *testing.T) { cfg.RetryInterval = serpent.Duration(time.Second) // query uses second-precision cfg.FetchInterval = serpent.Duration(time.Millisecond * 100) - handler := newDispatchInterceptor(dispatch.NewWebhookHandler(cfg.Webhook, api.Logger.Named("webhook"))) + handler := newDispatchInterceptor(dispatch.NewWebhookHandler(cfg.Webhook, logger.Named("webhook"))) // Intercept calls to submit the buffered updates to the store. - storeInterceptor := &syncInterceptor{Store: api.Database} + storeInterceptor := &syncInterceptor{Store: store} - mgr, err := notifications.NewManager(cfg, storeInterceptor, defaultHelpers(), createMetrics(), api.Logger.Named("manager")) + mgr, err := notifications.NewManager(cfg, storeInterceptor, defaultHelpers(), createMetrics(), logger.Named("manager")) require.NoError(t, err) t.Cleanup(func() { assert.NoError(t, mgr.Stop(ctx)) }) mgr.WithHandlers(map[database.NotificationMethod]notifications.Handler{method: handler}) - enq, err := notifications.NewStoreEnqueuer(cfg, api.Database, defaultHelpers(), api.Logger.Named("enqueuer"), quartz.NewReal()) + enq, err := notifications.NewStoreEnqueuer(cfg, store, defaultHelpers(), logger.Named("enqueuer"), quartz.NewReal()) require.NoError(t, err) - user := createSampleUser(t, api.Database) + user := createSampleUser(t, store) // WHEN: a few notifications are enqueued, which will all fail until their final retry (determined by the mock server) const msgCount = 5 @@ -460,7 +466,8 @@ func TestExpiredLeaseIsRequeued(t *testing.T) { // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) // GIVEN: a manager which has its updates intercepted and paused until measurements can be taken @@ -475,18 +482,18 @@ func TestExpiredLeaseIsRequeued(t *testing.T) { cfg.LeasePeriod = serpent.Duration(leasePeriod) cfg.DispatchTimeout = serpent.Duration(leasePeriod - time.Millisecond) - noopInterceptor := newNoopStoreSyncer(api.Database) + noopInterceptor := newNoopStoreSyncer(store) // nolint:gocritic // Unit test. mgrCtx, cancelManagerCtx := context.WithCancel(dbauthz.AsSystemRestricted(context.Background())) t.Cleanup(cancelManagerCtx) - mgr, err := notifications.NewManager(cfg, noopInterceptor, defaultHelpers(), createMetrics(), api.Logger.Named("manager")) + mgr, err := notifications.NewManager(cfg, noopInterceptor, defaultHelpers(), createMetrics(), logger.Named("manager")) require.NoError(t, err) - enq, err := notifications.NewStoreEnqueuer(cfg, api.Database, defaultHelpers(), api.Logger.Named("enqueuer"), quartz.NewReal()) + enq, err := notifications.NewStoreEnqueuer(cfg, store, defaultHelpers(), logger.Named("enqueuer"), quartz.NewReal()) require.NoError(t, err) - user := createSampleUser(t, api.Database) + user := createSampleUser(t, store) // WHEN: a few notifications are enqueued which will all succeed var msgs []string @@ -507,7 +514,7 @@ func TestExpiredLeaseIsRequeued(t *testing.T) { cancelManagerCtx() // Fetch any messages currently in "leased" status, and verify that they're exactly the ones we enqueued. - leased, err := api.Database.GetNotificationMessagesByStatus(ctx, database.GetNotificationMessagesByStatusParams{ + leased, err := store.GetNotificationMessagesByStatus(ctx, database.GetNotificationMessagesByStatusParams{ Status: database.NotificationMessageStatusLeased, Limit: msgCount, }) @@ -527,9 +534,9 @@ func TestExpiredLeaseIsRequeued(t *testing.T) { // Start a new notification manager. // Intercept calls to submit the buffered updates to the store. - storeInterceptor := &syncInterceptor{Store: api.Database} + storeInterceptor := &syncInterceptor{Store: store} handler := newDispatchInterceptor(&fakeHandler{}) - mgr, err = notifications.NewManager(cfg, storeInterceptor, defaultHelpers(), createMetrics(), api.Logger.Named("manager")) + mgr, err = notifications.NewManager(cfg, storeInterceptor, defaultHelpers(), createMetrics(), logger.Named("manager")) require.NoError(t, err) mgr.WithHandlers(map[database.NotificationMethod]notifications.Handler{method: handler}) @@ -546,7 +553,7 @@ func TestExpiredLeaseIsRequeued(t *testing.T) { }, testutil.WaitLong, testutil.IntervalFast) // Validate that no more messages are in "leased" status. - leased, err = api.Database.GetNotificationMessagesByStatus(ctx, database.GetNotificationMessagesByStatusParams{ + leased, err = store.GetNotificationMessagesByStatus(ctx, database.GetNotificationMessagesByStatusParams{ Status: database.NotificationMessageStatusLeased, Limit: msgCount, }) @@ -558,7 +565,8 @@ func TestExpiredLeaseIsRequeued(t *testing.T) { func TestInvalidConfig(t *testing.T) { t.Parallel() - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) // GIVEN: invalid config with dispatch period <= lease period const ( @@ -570,7 +578,7 @@ func TestInvalidConfig(t *testing.T) { cfg.DispatchTimeout = serpent.Duration(leasePeriod) // WHEN: the manager is created with invalid config - _, err := notifications.NewManager(cfg, api.Database, defaultHelpers(), createMetrics(), api.Logger.Named("manager")) + _, err := notifications.NewManager(cfg, store, defaultHelpers(), createMetrics(), logger.Named("manager")) // THEN: the manager will fail to be created, citing invalid config as error require.ErrorIs(t, err, notifications.ErrInvalidDispatchTimeout) @@ -583,29 +591,30 @@ func TestNotifierPaused(t *testing.T) { // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) // Prepare the test. handler := &fakeHandler{} method := database.NotificationMethodSmtp - user := createSampleUser(t, api.Database) + user := createSampleUser(t, store) const fetchInterval = time.Millisecond * 100 cfg := defaultNotificationsConfig(method) cfg.FetchInterval = serpent.Duration(fetchInterval) - mgr, err := notifications.NewManager(cfg, api.Database, defaultHelpers(), createMetrics(), api.Logger.Named("manager")) + mgr, err := notifications.NewManager(cfg, store, defaultHelpers(), createMetrics(), logger.Named("manager")) require.NoError(t, err) mgr.WithHandlers(map[database.NotificationMethod]notifications.Handler{method: handler}) t.Cleanup(func() { assert.NoError(t, mgr.Stop(ctx)) }) - enq, err := notifications.NewStoreEnqueuer(cfg, api.Database, defaultHelpers(), api.Logger.Named("enqueuer"), quartz.NewReal()) + enq, err := notifications.NewStoreEnqueuer(cfg, store, defaultHelpers(), logger.Named("enqueuer"), quartz.NewReal()) require.NoError(t, err) // Pause the notifier. settingsJSON, err := json.Marshal(&codersdk.NotificationsSettings{NotifierPaused: true}) require.NoError(t, err) - err = api.Database.UpsertNotificationsSettings(ctx, string(settingsJSON)) + err = store.UpsertNotificationsSettings(ctx, string(settingsJSON)) require.NoError(t, err) // Start the manager so that notifications are processed, except it will be paused at this point. @@ -618,7 +627,7 @@ func TestNotifierPaused(t *testing.T) { require.NoError(t, err) // Ensure we have a pending message and it's the expected one. - pendingMessages, err := api.Database.GetNotificationMessagesByStatus(ctx, database.GetNotificationMessagesByStatusParams{ + pendingMessages, err := store.GetNotificationMessagesByStatus(ctx, database.GetNotificationMessagesByStatusParams{ Status: database.NotificationMessageStatusPending, Limit: 10, }) @@ -639,7 +648,7 @@ func TestNotifierPaused(t *testing.T) { // Unpause the notifier. settingsJSON, err = json.Marshal(&codersdk.NotificationsSettings{NotifierPaused: false}) require.NoError(t, err) - err = api.Database.UpsertNotificationsSettings(ctx, string(settingsJSON)) + err = store.UpsertNotificationsSettings(ctx, string(settingsJSON)) require.NoError(t, err) // Notifier is running again, message should be dequeued. @@ -1287,17 +1296,18 @@ func TestDisabledBeforeEnqueue(t *testing.T) { // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) // GIVEN: an enqueuer & a sample user cfg := defaultNotificationsConfig(database.NotificationMethodSmtp) - enq, err := notifications.NewStoreEnqueuer(cfg, api.Database, defaultHelpers(), api.Logger.Named("enqueuer"), quartz.NewReal()) + enq, err := notifications.NewStoreEnqueuer(cfg, store, defaultHelpers(), logger.Named("enqueuer"), quartz.NewReal()) require.NoError(t, err) - user := createSampleUser(t, api.Database) + user := createSampleUser(t, store) // WHEN: the user has a preference set to not receive the "workspace deleted" notification templateID := notifications.TemplateWorkspaceDeleted - n, err := api.Database.UpdateUserNotificationPreferences(ctx, database.UpdateUserNotificationPreferencesParams{ + n, err := store.UpdateUserNotificationPreferences(ctx, database.UpdateUserNotificationPreferencesParams{ UserID: user.ID, NotificationTemplateIds: []uuid.UUID{templateID}, Disableds: []bool{true}, @@ -1322,20 +1332,21 @@ func TestDisabledAfterEnqueue(t *testing.T) { // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) method := database.NotificationMethodSmtp cfg := defaultNotificationsConfig(method) - mgr, err := notifications.NewManager(cfg, api.Database, defaultHelpers(), createMetrics(), api.Logger.Named("manager")) + mgr, err := notifications.NewManager(cfg, store, defaultHelpers(), createMetrics(), logger.Named("manager")) require.NoError(t, err) t.Cleanup(func() { assert.NoError(t, mgr.Stop(ctx)) }) - enq, err := notifications.NewStoreEnqueuer(cfg, api.Database, defaultHelpers(), api.Logger.Named("enqueuer"), quartz.NewReal()) + enq, err := notifications.NewStoreEnqueuer(cfg, store, defaultHelpers(), logger.Named("enqueuer"), quartz.NewReal()) require.NoError(t, err) - user := createSampleUser(t, api.Database) + user := createSampleUser(t, store) // GIVEN: a notification is enqueued which has not (yet) been disabled templateID := notifications.TemplateWorkspaceDeleted @@ -1343,7 +1354,7 @@ func TestDisabledAfterEnqueue(t *testing.T) { require.NoError(t, err) // Disable the notification template. - n, err := api.Database.UpdateUserNotificationPreferences(ctx, database.UpdateUserNotificationPreferencesParams{ + n, err := store.UpdateUserNotificationPreferences(ctx, database.UpdateUserNotificationPreferencesParams{ UserID: user.ID, NotificationTemplateIds: []uuid.UUID{templateID}, Disableds: []bool{true}, @@ -1356,7 +1367,7 @@ func TestDisabledAfterEnqueue(t *testing.T) { // THEN: the message should not be sent, and must be set to "inhibited" require.EventuallyWithT(t, func(ct *assert.CollectT) { - m, err := api.Database.GetNotificationMessagesByStatus(ctx, database.GetNotificationMessagesByStatusParams{ + m, err := store.GetNotificationMessagesByStatus(ctx, database.GetNotificationMessagesByStatusParams{ Status: database.NotificationMessageStatusInhibited, Limit: 10, }) @@ -1378,7 +1389,8 @@ func TestCustomNotificationMethod(t *testing.T) { // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) received := make(chan uuid.UUID, 1) @@ -1417,7 +1429,7 @@ func TestCustomNotificationMethod(t *testing.T) { defaultMethod = database.NotificationMethodSmtp customMethod = database.NotificationMethodWebhook ) - out, err := api.Database.UpdateNotificationTemplateMethodByID(ctx, database.UpdateNotificationTemplateMethodByIDParams{ + out, err := store.UpdateNotificationTemplateMethodByID(ctx, database.UpdateNotificationTemplateMethodByIDParams{ ID: template, Method: database.NullNotificationMethod{NotificationMethod: customMethod, Valid: true}, }) @@ -1435,17 +1447,17 @@ func TestCustomNotificationMethod(t *testing.T) { Endpoint: *serpent.URLOf(endpoint), } - mgr, err := notifications.NewManager(cfg, api.Database, defaultHelpers(), createMetrics(), api.Logger.Named("manager")) + mgr, err := notifications.NewManager(cfg, store, defaultHelpers(), createMetrics(), logger.Named("manager")) require.NoError(t, err) t.Cleanup(func() { _ = mgr.Stop(ctx) }) - enq, err := notifications.NewStoreEnqueuer(cfg, api.Database, defaultHelpers(), api.Logger, quartz.NewReal()) + enq, err := notifications.NewStoreEnqueuer(cfg, store, defaultHelpers(), logger.Named("enqueuer"), quartz.NewReal()) require.NoError(t, err) // WHEN: a notification of that template is enqueued, it should be delivered with the configured method - not the default. - user := createSampleUser(t, api.Database) + user := createSampleUser(t, store) msgID, err := enq.Enqueue(ctx, user.ID, template, map[string]string{}, "test") require.NoError(t, err) @@ -1518,12 +1530,13 @@ func TestNotificationDuplicates(t *testing.T) { // nolint:gocritic // Unit test. ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - _, _, api := coderdtest.NewWithAPI(t, nil) + store, _ := dbtestutil.NewDB(t) + logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) method := database.NotificationMethodSmtp cfg := defaultNotificationsConfig(method) - mgr, err := notifications.NewManager(cfg, api.Database, defaultHelpers(), createMetrics(), api.Logger.Named("manager")) + mgr, err := notifications.NewManager(cfg, store, defaultHelpers(), createMetrics(), logger.Named("manager")) require.NoError(t, err) t.Cleanup(func() { assert.NoError(t, mgr.Stop(ctx)) @@ -1533,9 +1546,9 @@ func TestNotificationDuplicates(t *testing.T) { mClock := quartz.NewMock(t) mClock.Set(time.Date(2024, 1, 15, 9, 0, 0, 0, time.UTC)) - enq, err := notifications.NewStoreEnqueuer(cfg, api.Database, defaultHelpers(), api.Logger.Named("enqueuer"), mClock) + enq, err := notifications.NewStoreEnqueuer(cfg, store, defaultHelpers(), logger.Named("enqueuer"), mClock) require.NoError(t, err) - user := createSampleUser(t, api.Database) + user := createSampleUser(t, store) // GIVEN: two notifications are enqueued with identical properties. _, err = enq.Enqueue(ctx, user.ID, notifications.TemplateWorkspaceDeleted, 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