Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1852953

Browse files
committed
WIP
1 parent 881dc5e commit 1852953

File tree

2 files changed

+148
-69
lines changed

2 files changed

+148
-69
lines changed

coderd/provisionerdserver/provisionerdserver.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,13 +1098,16 @@ func (s *server) FailJob(ctx context.Context, failJob *proto.FailedJob) (*proto.
10981098
func (s *server) notifyWorkspaceBuildFailed(ctx context.Context, workspace database.Workspace, build database.WorkspaceBuild) {
10991099
var reason string
11001100
if build.Reason.Valid() && build.Reason == database.BuildReasonInitiator {
1101-
return // failed workspace builds initiated by a user should not notify
1101+
return // failed workspace build initiated by a user should not notify
11021102
}
1103+
reason = "initiated by autobuild"
1104+
initiator := "autobuild"
11031105

11041106
if _, err := s.NotificationEnqueuer.Enqueue(ctx, workspace.OwnerID, notifications.WorkspaceAutobuildFailed,
11051107
map[string]string{
1106-
"name": workspace.Name,
1107-
"reason": reason,
1108+
"name": workspace.Name,
1109+
"initiator": initiator,
1110+
"reason": reason,
11081111
}, "provisionerdserver",
11091112
// Associate this notification with all the related entities.
11101113
workspace.ID, workspace.OwnerID, workspace.TemplateID, workspace.OrganizationID,
@@ -1561,7 +1564,7 @@ func (s *server) notifyWorkspaceDeleted(ctx context.Context, workspace database.
15611564
reason = "initiated by user"
15621565
case database.BuildReasonAutodelete:
15631566
reason = "autodeleted due to dormancy"
1564-
initiator = ""
1567+
initiator = "autobuild"
15651568
default:
15661569
reason = string(build.Reason)
15671570
}
@@ -1571,17 +1574,12 @@ func (s *server) notifyWorkspaceDeleted(ctx context.Context, workspace database.
15711574
slog.F("reason", reason), slog.F("workspace_id", workspace.ID), slog.F("build_id", build.ID))
15721575
}
15731576

1574-
labels := map[string]string{
1575-
"name": workspace.Name,
1576-
"reason": reason,
1577-
}
1578-
1579-
if initiator != "" {
1580-
labels["initiator"] = initiator
1581-
}
1582-
15831577
if _, err := s.NotificationEnqueuer.Enqueue(ctx, workspace.OwnerID, notifications.TemplateWorkspaceDeleted,
1584-
labels, "provisionerdserver",
1578+
map[string]string{
1579+
"name": workspace.Name,
1580+
"reason": reason,
1581+
"initiator": initiator,
1582+
}, "provisionerdserver",
15851583
// Associate this notification with all the related entities.
15861584
workspace.ID, workspace.OwnerID, workspace.TemplateID, workspace.OrganizationID,
15871585
); err != nil {

coderd/provisionerdserver/provisionerdserver_test.go

Lines changed: 136 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,41 +1569,146 @@ func TestInsertWorkspaceResource(t *testing.T) {
15691569
func TestNotifications(t *testing.T) {
15701570
t.Parallel()
15711571

1572-
t.Run("Workspace Events", func(t *testing.T) {
1572+
t.Run("Workspace deletion", func(t *testing.T) {
15731573
t.Parallel()
15741574

15751575
tests := []struct {
1576-
name string
1577-
1578-
buildReason database.BuildReason
1579-
buildFailed bool
1580-
shouldNotify bool
1581-
shouldSelfInitiate bool
1582-
shouldDeleteWorkspace bool
1576+
name string
1577+
deletionReason database.BuildReason
1578+
shouldNotify bool
1579+
shouldSelfInitiate bool
15831580
}{
15841581
{
1585-
name: "initiated by autodelete",
1586-
buildReason: database.BuildReasonAutodelete,
1587-
shouldNotify: true,
1588-
shouldDeleteWorkspace: true,
1582+
name: "initiated by autodelete",
1583+
deletionReason: database.BuildReasonAutodelete,
1584+
shouldNotify: true,
15891585
},
15901586
{
1591-
name: "initiated by self",
1592-
buildReason: database.BuildReasonInitiator,
1593-
shouldNotify: false,
1594-
shouldSelfInitiate: true,
1595-
shouldDeleteWorkspace: true,
1587+
name: "initiated by self",
1588+
deletionReason: database.BuildReasonInitiator,
1589+
shouldNotify: false,
1590+
shouldSelfInitiate: true,
15961591
},
15971592
{
1598-
name: "initiated by someone else",
1599-
buildReason: database.BuildReasonInitiator,
1600-
shouldNotify: true,
1601-
shouldDeleteWorkspace: true,
1593+
name: "initiated by someone else",
1594+
deletionReason: database.BuildReasonInitiator,
1595+
shouldNotify: true,
1596+
shouldSelfInitiate: false,
16021597
},
1598+
}
1599+
1600+
for _, tc := range tests {
1601+
t.Run(tc.name, func(t *testing.T) {
1602+
t.Parallel()
1603+
1604+
ctx := context.Background()
1605+
notifEnq := &fakeNotificationEnqueuer{}
1606+
1607+
srv, db, ps, pd := setup(t, false, &overrides{
1608+
notificationEnqueuer: notifEnq,
1609+
})
1610+
1611+
user := dbgen.User(t, db, database.User{})
1612+
initiator := user
1613+
if !tc.shouldSelfInitiate {
1614+
initiator = dbgen.User(t, db, database.User{})
1615+
}
1616+
1617+
template := dbgen.Template(t, db, database.Template{
1618+
Name: "template",
1619+
Provisioner: database.ProvisionerTypeEcho,
1620+
OrganizationID: pd.OrganizationID,
1621+
})
1622+
template, err := db.GetTemplateByID(ctx, template.ID)
1623+
require.NoError(t, err)
1624+
file := dbgen.File(t, db, database.File{CreatedBy: user.ID})
1625+
workspace := dbgen.Workspace(t, db, database.Workspace{
1626+
TemplateID: template.ID,
1627+
OwnerID: user.ID,
1628+
OrganizationID: pd.OrganizationID,
1629+
})
1630+
version := dbgen.TemplateVersion(t, db, database.TemplateVersion{
1631+
OrganizationID: pd.OrganizationID,
1632+
TemplateID: uuid.NullUUID{
1633+
UUID: template.ID,
1634+
Valid: true,
1635+
},
1636+
JobID: uuid.New(),
1637+
})
1638+
build := dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{
1639+
WorkspaceID: workspace.ID,
1640+
TemplateVersionID: version.ID,
1641+
InitiatorID: initiator.ID,
1642+
Transition: database.WorkspaceTransitionDelete,
1643+
Reason: tc.deletionReason,
1644+
})
1645+
job := dbgen.ProvisionerJob(t, db, ps, database.ProvisionerJob{
1646+
FileID: file.ID,
1647+
Type: database.ProvisionerJobTypeWorkspaceBuild,
1648+
Input: must(json.Marshal(provisionerdserver.WorkspaceProvisionJob{
1649+
WorkspaceBuildID: build.ID,
1650+
})),
1651+
OrganizationID: pd.OrganizationID,
1652+
})
1653+
_, err = db.AcquireProvisionerJob(ctx, database.AcquireProvisionerJobParams{
1654+
OrganizationID: pd.OrganizationID,
1655+
WorkerID: uuid.NullUUID{
1656+
UUID: pd.ID,
1657+
Valid: true,
1658+
},
1659+
Types: []database.ProvisionerType{database.ProvisionerTypeEcho},
1660+
})
1661+
require.NoError(t, err)
1662+
1663+
_, err = srv.CompleteJob(ctx, &proto.CompletedJob{
1664+
JobId: job.ID.String(),
1665+
Type: &proto.CompletedJob_WorkspaceBuild_{
1666+
WorkspaceBuild: &proto.CompletedJob_WorkspaceBuild{
1667+
State: []byte{},
1668+
Resources: []*sdkproto.Resource{{
1669+
Name: "example",
1670+
Type: "aws_instance",
1671+
}},
1672+
},
1673+
},
1674+
})
1675+
require.NoError(t, err)
1676+
1677+
workspace, err = db.GetWorkspaceByID(ctx, workspace.ID)
1678+
require.NoError(t, err)
1679+
require.True(t, workspace.Deleted)
1680+
1681+
if tc.shouldNotify {
1682+
// Validate that the notification was sent and contained the expected values.
1683+
require.Len(t, notifEnq.sent, 1)
1684+
require.Equal(t, notifEnq.sent[0].userID, user.ID)
1685+
require.Contains(t, notifEnq.sent[0].targets, template.ID)
1686+
require.Contains(t, notifEnq.sent[0].targets, workspace.ID)
1687+
require.Contains(t, notifEnq.sent[0].targets, workspace.OrganizationID)
1688+
require.Contains(t, notifEnq.sent[0].targets, user.ID)
1689+
if tc.deletionReason == database.BuildReasonInitiator {
1690+
require.Equal(t, notifEnq.sent[0].labels["initiator"], initiator.Username)
1691+
}
1692+
} else {
1693+
require.Len(t, notifEnq.sent, 0)
1694+
}
1695+
})
1696+
}
1697+
})
1698+
1699+
t.Run("Workspace autobuild failed", func(t *testing.T) {
1700+
t.Parallel()
1701+
1702+
tests := []struct {
1703+
name string
1704+
1705+
buildReason database.BuildReason
1706+
shouldNotify bool
1707+
shouldDeleteWorkspace bool
1708+
}{
16031709
{
16041710
name: "initiated by autostart but failed",
16051711
buildReason: database.BuildReasonAutostart,
1606-
buildFailed: true,
16071712
shouldNotify: true,
16081713
},
16091714
}
@@ -1617,17 +1722,13 @@ func TestNotifications(t *testing.T) {
16171722

16181723
// Otherwise `(*Server).FailJob` fails with:
16191724
// audit log - get build {"error": "sql: no rows in result set"}
1620-
ignoreLogErrors := tc.buildFailed
1621-
1725+
ignoreLogErrors := true
16221726
srv, db, ps, pd := setup(t, ignoreLogErrors, &overrides{
16231727
notificationEnqueuer: notifEnq,
16241728
})
16251729

16261730
user := dbgen.User(t, db, database.User{})
16271731
initiator := user
1628-
if !tc.shouldSelfInitiate {
1629-
initiator = dbgen.User(t, db, database.User{})
1630-
}
16311732

16321733
template := dbgen.Template(t, db, database.Template{
16331734
Name: "template",
@@ -1675,29 +1776,14 @@ func TestNotifications(t *testing.T) {
16751776
})
16761777
require.NoError(t, err)
16771778

1678-
if tc.buildFailed {
1679-
_, err = srv.FailJob(ctx, &proto.FailedJob{
1680-
JobId: job.ID.String(),
1681-
Type: &proto.FailedJob_WorkspaceBuild_{
1682-
WorkspaceBuild: &proto.FailedJob_WorkspaceBuild{
1683-
State: []byte{},
1684-
},
1685-
},
1686-
})
1687-
} else {
1688-
_, err = srv.CompleteJob(ctx, &proto.CompletedJob{
1689-
JobId: job.ID.String(),
1690-
Type: &proto.CompletedJob_WorkspaceBuild_{
1691-
WorkspaceBuild: &proto.CompletedJob_WorkspaceBuild{
1692-
State: []byte{},
1693-
Resources: []*sdkproto.Resource{{
1694-
Name: "example",
1695-
Type: "aws_instance",
1696-
}},
1697-
},
1779+
_, err = srv.FailJob(ctx, &proto.FailedJob{
1780+
JobId: job.ID.String(),
1781+
Type: &proto.FailedJob_WorkspaceBuild_{
1782+
WorkspaceBuild: &proto.FailedJob_WorkspaceBuild{
1783+
State: []byte{},
16981784
},
1699-
})
1700-
}
1785+
},
1786+
})
17011787
require.NoError(t, err)
17021788

17031789
workspace, err = db.GetWorkspaceByID(ctx, workspace.ID)
@@ -1712,12 +1798,7 @@ func TestNotifications(t *testing.T) {
17121798
require.Contains(t, notifEnq.sent[0].targets, workspace.ID)
17131799
require.Contains(t, notifEnq.sent[0].targets, workspace.OrganizationID)
17141800
require.Contains(t, notifEnq.sent[0].targets, user.ID)
1715-
if tc.buildReason == database.BuildReasonInitiator {
1716-
require.Equal(t, notifEnq.sent[0].labels["initiator"], initiator.Username)
1717-
} else {
1718-
_, ok := notifEnq.sent[0].labels["initiator"]
1719-
require.False(t, ok, "initiator label not expected")
1720-
}
1801+
require.Equal(t, notifEnq.sent[0].labels["initiator"], "autobuild")
17211802
} else {
17221803
require.Len(t, notifEnq.sent, 0)
17231804
}

0 commit comments

Comments
 (0)