Skip to content

Commit 8909bb6

Browse files
committed
test done
1 parent 52aafac commit 8909bb6

File tree

2 files changed

+50
-22
lines changed

2 files changed

+50
-22
lines changed

coderd/notifications/reports/generator.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,15 @@ func reportFailedWorkspaceBuilds(ctx context.Context, logger slog.Logger, db dat
113113
return statsRows[i].TemplateName < statsRows[j].TemplateName
114114
})
115115

116-
reportRecipients := map[uuid.UUID]bool{}
116+
reportGeneratedNow := map[uuid.UUID]bool{}
117117
for _, stats := range statsRows {
118118
var failedBuilds []database.GetFailedWorkspaceBuildsByTemplateIDRow
119119
reportData := map[string]any{}
120120

121121
if stats.FailedBuilds > 0 {
122122
failedBuilds, err = db.GetFailedWorkspaceBuildsByTemplateID(ctx, database.GetFailedWorkspaceBuildsByTemplateIDParams{
123123
TemplateID: stats.TemplateID,
124-
Since: dbtime.Time(now).UTC(),
124+
Since: dbtime.Time(since).UTC(),
125125
})
126126
if err != nil {
127127
logger.Error(ctx, "unable to fetch failed workspace builds", slog.F("template_id", stats.TemplateID), slog.Error(err))
@@ -150,13 +150,13 @@ func reportFailedWorkspaceBuilds(ctx context.Context, logger slog.Logger, db dat
150150

151151
if !reportLog.LastGeneratedAt.IsZero() && reportLog.LastGeneratedAt.Add(failedWorkspaceBuildsReportFrequencyDays*24*time.Hour).After(now) {
152152
// report generated recently, no need to send it now
153-
reportRecipients[templateAdmin.ID] = true
154153
continue
155154
}
156155

156+
reportGeneratedNow[templateAdmin.ID] = true
157+
157158
if len(failedBuilds) == 0 {
158159
// no failed workspace builds, no need to send the report
159-
reportRecipients[templateAdmin.ID] = true
160160
continue
161161
}
162162

@@ -176,11 +176,10 @@ func reportFailedWorkspaceBuilds(ctx context.Context, logger slog.Logger, db dat
176176
); err != nil {
177177
logger.Warn(ctx, "failed to send a report with failed workspace builds", slog.Error(err))
178178
}
179-
reportRecipients[templateAdmin.ID] = true
180179
}
181180
}
182181

183-
for recipient := range reportRecipients {
182+
for recipient := range reportGeneratedNow {
184183
err = db.UpsertReportGeneratorLog(ctx, database.UpsertReportGeneratorLogParams{
185184
UserID: recipient,
186185
NotificationTemplateID: notifications.TemplateWorkspaceBuildsFailedReport,

coderd/notifications/reports/generator_internal_test.go

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,26 +98,26 @@ func TestReportFailedWorkspaceBuilds(t *testing.T) {
9898

9999
// Workspace builds
100100
w1wb1pj := dbgen.ProvisionerJob(t, db, ps, database.ProvisionerJob{OrganizationID: org.ID, Error: jobError, ErrorCode: jobErrorCode, CompletedAt: sql.NullTime{Time: now.Add(-6 * dayDuration), Valid: true}})
101-
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w1.ID, BuildNumber: 1, TemplateVersionID: t1v1.ID, JobID: w1wb1pj.ID, Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
101+
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w1.ID, BuildNumber: 1, TemplateVersionID: t1v1.ID, JobID: w1wb1pj.ID, CreatedAt: now.Add(-6 * dayDuration), Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
102102
w1wb2pj := dbgen.ProvisionerJob(t, db, ps, database.ProvisionerJob{OrganizationID: org.ID, CompletedAt: sql.NullTime{Time: now.Add(-5 * dayDuration), Valid: true}})
103-
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w1.ID, BuildNumber: 2, TemplateVersionID: t1v2.ID, JobID: w1wb2pj.ID, Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
103+
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w1.ID, BuildNumber: 2, TemplateVersionID: t1v2.ID, JobID: w1wb2pj.ID, CreatedAt: now.Add(-5 * dayDuration), Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
104104
w1wb3pj := dbgen.ProvisionerJob(t, db, ps, database.ProvisionerJob{OrganizationID: org.ID, Error: jobError, ErrorCode: jobErrorCode, CompletedAt: sql.NullTime{Time: now.Add(-4 * dayDuration), Valid: true}})
105-
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w1.ID, BuildNumber: 3, TemplateVersionID: t1v2.ID, JobID: w1wb3pj.ID, Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
105+
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w1.ID, BuildNumber: 3, TemplateVersionID: t1v2.ID, JobID: w1wb3pj.ID, CreatedAt: now.Add(-4 * dayDuration), Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
106106

107107
w2wb1pj := dbgen.ProvisionerJob(t, db, ps, database.ProvisionerJob{OrganizationID: org.ID, CompletedAt: sql.NullTime{Time: now.Add(-5 * dayDuration), Valid: true}})
108-
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w2.ID, BuildNumber: 4, TemplateVersionID: t2v1.ID, JobID: w2wb1pj.ID, Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
108+
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w2.ID, BuildNumber: 4, TemplateVersionID: t2v1.ID, JobID: w2wb1pj.ID, CreatedAt: now.Add(-5 * dayDuration), Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
109109
w2wb2pj := dbgen.ProvisionerJob(t, db, ps, database.ProvisionerJob{OrganizationID: org.ID, Error: jobError, ErrorCode: jobErrorCode, CompletedAt: sql.NullTime{Time: now.Add(-4 * dayDuration), Valid: true}})
110-
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w2.ID, BuildNumber: 5, TemplateVersionID: t2v2.ID, JobID: w2wb2pj.ID, Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
110+
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w2.ID, BuildNumber: 5, TemplateVersionID: t2v2.ID, JobID: w2wb2pj.ID, CreatedAt: now.Add(-4 * dayDuration), Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
111111
w2wb3pj := dbgen.ProvisionerJob(t, db, ps, database.ProvisionerJob{OrganizationID: org.ID, Error: jobError, ErrorCode: jobErrorCode, CompletedAt: sql.NullTime{Time: now.Add(-3 * dayDuration), Valid: true}})
112-
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w2.ID, BuildNumber: 6, TemplateVersionID: t2v2.ID, JobID: w2wb3pj.ID, Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
112+
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w2.ID, BuildNumber: 6, TemplateVersionID: t2v2.ID, JobID: w2wb3pj.ID, CreatedAt: now.Add(-3 * dayDuration), Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
113113

114114
w3wb1pj := dbgen.ProvisionerJob(t, db, ps, database.ProvisionerJob{OrganizationID: org.ID, Error: jobError, ErrorCode: jobErrorCode, CompletedAt: sql.NullTime{Time: now.Add(-3 * dayDuration), Valid: true}})
115-
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w3.ID, BuildNumber: 7, TemplateVersionID: t1v1.ID, JobID: w3wb1pj.ID, Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
115+
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w3.ID, BuildNumber: 7, TemplateVersionID: t1v1.ID, JobID: w3wb1pj.ID, CreatedAt: now.Add(-3 * dayDuration), Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
116116

117117
w4wb1pj := dbgen.ProvisionerJob(t, db, ps, database.ProvisionerJob{OrganizationID: org.ID, Error: jobError, ErrorCode: jobErrorCode, CompletedAt: sql.NullTime{Time: now.Add(-6 * dayDuration), Valid: true}})
118-
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w4.ID, BuildNumber: 8, TemplateVersionID: t2v1.ID, JobID: w4wb1pj.ID, Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
119-
w4wb2pj := dbgen.ProvisionerJob(t, db, ps, database.ProvisionerJob{OrganizationID: org.ID, CompletedAt: sql.NullTime{Time: now.Add(-1 * dayDuration), Valid: true}})
120-
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w4.ID, BuildNumber: 9, TemplateVersionID: t2v2.ID, JobID: w4wb2pj.ID, Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
118+
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w4.ID, BuildNumber: 8, TemplateVersionID: t2v1.ID, JobID: w4wb1pj.ID, CreatedAt: now.Add(-6 * dayDuration), Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
119+
w4wb2pj := dbgen.ProvisionerJob(t, db, ps, database.ProvisionerJob{OrganizationID: org.ID, CompletedAt: sql.NullTime{Time: now.Add(-dayDuration), Valid: true}})
120+
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w4.ID, BuildNumber: 9, TemplateVersionID: t2v2.ID, JobID: w4wb2pj.ID, CreatedAt: now.Add(-dayDuration), Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
121121

122122
// Database is ready, so we can clear notifications queue
123123
notifEnq.Clear()
@@ -165,8 +165,14 @@ func TestReportFailedWorkspaceBuilds(t *testing.T) {
165165
require.Equal(t, notifEnq.Sent[3].Data["report_frequency"], "week")
166166
// require.Contains(t, notifEnq.Sent[0].Data["template_versions"], "?")
167167

168-
// Given: 6 days later (less than report frequency)
168+
// Given: 6 days later (less than report frequency), and failed build
169169
clk.Advance(6 * dayDuration).MustWait(context.Background())
170+
171+
now = clk.Now()
172+
173+
w1wb4pj := dbgen.ProvisionerJob(t, db, ps, database.ProvisionerJob{OrganizationID: org.ID, Error: jobError, ErrorCode: jobErrorCode, CompletedAt: sql.NullTime{Time: now.Add(-dayDuration), Valid: true}})
174+
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{WorkspaceID: w1.ID, BuildNumber: 4, TemplateVersionID: t1v2.ID, JobID: w1wb4pj.ID, CreatedAt: now.Add(-dayDuration), Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonInitiator})
175+
170176
notifEnq.Clear()
171177

172178
// When
@@ -175,6 +181,34 @@ func TestReportFailedWorkspaceBuilds(t *testing.T) {
175181

176182
// Then
177183
require.Empty(t, notifEnq.Sent) // no notifications as it is too early.
184+
185+
// Given: 1 day 1 hour later
186+
clk.Advance(dayDuration + time.Hour).MustWait(context.Background())
187+
notifEnq.Clear()
188+
189+
// When
190+
err = reportFailedWorkspaceBuilds(ctx, logger, authedDB(db, logger), notifEnq, clk)
191+
require.NoError(t, err)
192+
193+
// Then
194+
require.Len(t, notifEnq.Sent, 2) // this time a failed job should be reported
195+
require.Equal(t, notifEnq.Sent[0].UserID, templateAdmin1.ID)
196+
require.Equal(t, notifEnq.Sent[0].TemplateID, notifications.TemplateWorkspaceBuildsFailedReport)
197+
require.Equal(t, notifEnq.Sent[0].Labels["template_name"], t1.Name)
198+
require.Equal(t, notifEnq.Sent[0].Labels["template_display_name"], t1.DisplayName)
199+
require.Equal(t, notifEnq.Sent[0].Data["failed_builds"], int64(1))
200+
require.Equal(t, notifEnq.Sent[0].Data["total_builds"], int64(1))
201+
require.Equal(t, notifEnq.Sent[0].Data["report_frequency"], "week")
202+
// require.Contains(t, notifEnq.Sent[0].Data["template_versions"], "?")
203+
204+
require.Equal(t, notifEnq.Sent[1].UserID, templateAdmin2.ID)
205+
require.Equal(t, notifEnq.Sent[1].TemplateID, notifications.TemplateWorkspaceBuildsFailedReport)
206+
require.Equal(t, notifEnq.Sent[1].Labels["template_name"], t1.Name)
207+
require.Equal(t, notifEnq.Sent[1].Labels["template_display_name"], t1.DisplayName)
208+
require.Equal(t, notifEnq.Sent[1].Data["failed_builds"], int64(1))
209+
require.Equal(t, notifEnq.Sent[1].Data["total_builds"], int64(1))
210+
require.Equal(t, notifEnq.Sent[1].Data["report_frequency"], "week")
211+
// require.Contains(t, notifEnq.Sent[1].Data["template_versions"], "?")
178212
})
179213

180214
t.Run("NoFailedBuilds_TemplateAdminIn_NoReport", func(t *testing.T) {
@@ -187,11 +221,6 @@ func TestReportFailedWorkspaceBuilds(t *testing.T) {
187221
// TODO
188222
})
189223

190-
t.Run("StaleFailedBuilds_TemplateAdminOptIn_NoReport_Cleanup", func(t *testing.T) {
191-
t.Parallel()
192-
// TODO
193-
})
194-
195224
t.Run("FreshTemplate_FailedBuilds_TemplateAdminIn_NoReport", func(t *testing.T) {
196225
t.Parallel()
197226
// TODO

0 commit comments

Comments
 (0)