Skip to content

Commit 839a16e

Browse files
authored
feat: add dbfake for workspace builds and resources (#10426)
* feat: add dbfakedata for workspace builds and resources This creates `coderdtest.NewWithDatabase` and adds a series of helper functions to `dbfake` that insert structured fake data for resources into the database. It allows us to remove provisionerd from a significant amount of tests which should speed them up and reduce flakes. * Rename dbfakedata to dbfake * Migrate workspaceagents_test.go to use the new dbfake * Migrate agent_test.go to use the new fakes * Fix comments
1 parent ac9c168 commit 839a16e

File tree

5 files changed

+413
-530
lines changed

5 files changed

+413
-530
lines changed

cli/agent_test.go

+55-101
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ import (
1616
"github.com/coder/coder/v2/agent"
1717
"github.com/coder/coder/v2/cli/clitest"
1818
"github.com/coder/coder/v2/coderd/coderdtest"
19+
"github.com/coder/coder/v2/coderd/database"
20+
"github.com/coder/coder/v2/coderd/database/dbfake"
1921
"github.com/coder/coder/v2/codersdk"
20-
"github.com/coder/coder/v2/provisioner/echo"
2122
"github.com/coder/coder/v2/provisionersdk/proto"
2223
"github.com/coder/coder/v2/pty/ptytest"
2324
)
@@ -28,20 +29,12 @@ func TestWorkspaceAgent(t *testing.T) {
2829
t.Run("LogDirectory", func(t *testing.T) {
2930
t.Parallel()
3031

31-
authToken := uuid.NewString()
32-
client := coderdtest.New(t, &coderdtest.Options{
33-
IncludeProvisionerDaemon: true,
34-
})
32+
client, db := coderdtest.NewWithDatabase(t, nil)
3533
user := coderdtest.CreateFirstUser(t, client)
36-
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
37-
Parse: echo.ParseComplete,
38-
ProvisionApply: echo.ProvisionApplyWithAgent(authToken),
34+
ws, authToken := dbfake.WorkspaceWithAgent(t, db, database.Workspace{
35+
OrganizationID: user.OrganizationID,
36+
OwnerID: user.UserID,
3937
})
40-
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
41-
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
42-
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
43-
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
44-
4538
logDir := t.TempDir()
4639
inv, _ := clitest.New(t,
4740
"agent",
@@ -57,7 +50,7 @@ func TestWorkspaceAgent(t *testing.T) {
5750
ctx := inv.Context()
5851
pty.ExpectMatchContext(ctx, "agent is starting now")
5952

60-
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
53+
coderdtest.AwaitWorkspaceAgents(t, client, ws.ID)
6154

6255
info, err := os.Stat(filepath.Join(logDir, "coder-agent.log"))
6356
require.NoError(t, err)
@@ -68,33 +61,23 @@ func TestWorkspaceAgent(t *testing.T) {
6861
t.Parallel()
6962
instanceID := "instanceidentifier"
7063
certificates, metadataClient := coderdtest.NewAzureInstanceIdentity(t, instanceID)
71-
client := coderdtest.New(t, &coderdtest.Options{
72-
AzureCertificates: certificates,
73-
IncludeProvisionerDaemon: true,
64+
client, db := coderdtest.NewWithDatabase(t, &coderdtest.Options{
65+
AzureCertificates: certificates,
7466
})
7567
user := coderdtest.CreateFirstUser(t, client)
76-
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
77-
Parse: echo.ParseComplete,
78-
ProvisionApply: []*proto.Response{{
79-
Type: &proto.Response_Apply{
80-
Apply: &proto.ApplyComplete{
81-
Resources: []*proto.Resource{{
82-
Name: "somename",
83-
Type: "someinstance",
84-
Agents: []*proto.Agent{{
85-
Auth: &proto.Agent_InstanceId{
86-
InstanceId: instanceID,
87-
},
88-
}},
89-
}},
90-
},
68+
ws := dbfake.Workspace(t, db, database.Workspace{
69+
OrganizationID: user.OrganizationID,
70+
OwnerID: user.UserID,
71+
})
72+
dbfake.WorkspaceBuild(t, db, ws, database.WorkspaceBuild{}, &proto.Resource{
73+
Name: "somename",
74+
Type: "someinstance",
75+
Agents: []*proto.Agent{{
76+
Auth: &proto.Agent_InstanceId{
77+
InstanceId: instanceID,
9178
},
9279
}},
9380
})
94-
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
95-
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
96-
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
97-
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
9881

9982
inv, _ := clitest.New(t, "agent", "--auth", "azure-instance-identity", "--agent-url", client.URL.String())
10083
inv = inv.WithContext(
@@ -103,8 +86,8 @@ func TestWorkspaceAgent(t *testing.T) {
10386
)
10487
ctx := inv.Context()
10588
clitest.Start(t, inv)
106-
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
107-
workspace, err := client.Workspace(ctx, workspace.ID)
89+
coderdtest.AwaitWorkspaceAgents(t, client, ws.ID)
90+
workspace, err := client.Workspace(ctx, ws.ID)
10891
require.NoError(t, err)
10992
resources := workspace.LatestBuild.Resources
11093
if assert.NotEmpty(t, workspace.LatestBuild.Resources) && assert.NotEmpty(t, resources[0].Agents) {
@@ -120,33 +103,23 @@ func TestWorkspaceAgent(t *testing.T) {
120103
t.Parallel()
121104
instanceID := "instanceidentifier"
122105
certificates, metadataClient := coderdtest.NewAWSInstanceIdentity(t, instanceID)
123-
client := coderdtest.New(t, &coderdtest.Options{
124-
AWSCertificates: certificates,
125-
IncludeProvisionerDaemon: true,
106+
client, db := coderdtest.NewWithDatabase(t, &coderdtest.Options{
107+
AWSCertificates: certificates,
126108
})
127109
user := coderdtest.CreateFirstUser(t, client)
128-
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
129-
Parse: echo.ParseComplete,
130-
ProvisionApply: []*proto.Response{{
131-
Type: &proto.Response_Apply{
132-
Apply: &proto.ApplyComplete{
133-
Resources: []*proto.Resource{{
134-
Name: "somename",
135-
Type: "someinstance",
136-
Agents: []*proto.Agent{{
137-
Auth: &proto.Agent_InstanceId{
138-
InstanceId: instanceID,
139-
},
140-
}},
141-
}},
142-
},
110+
ws := dbfake.Workspace(t, db, database.Workspace{
111+
OrganizationID: user.OrganizationID,
112+
OwnerID: user.UserID,
113+
})
114+
dbfake.WorkspaceBuild(t, db, ws, database.WorkspaceBuild{}, &proto.Resource{
115+
Name: "somename",
116+
Type: "someinstance",
117+
Agents: []*proto.Agent{{
118+
Auth: &proto.Agent_InstanceId{
119+
InstanceId: instanceID,
143120
},
144121
}},
145122
})
146-
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
147-
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
148-
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
149-
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
150123

151124
inv, _ := clitest.New(t, "agent", "--auth", "aws-instance-identity", "--agent-url", client.URL.String())
152125
inv = inv.WithContext(
@@ -155,8 +128,8 @@ func TestWorkspaceAgent(t *testing.T) {
155128
)
156129
clitest.Start(t, inv)
157130
ctx := inv.Context()
158-
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
159-
workspace, err := client.Workspace(ctx, workspace.ID)
131+
coderdtest.AwaitWorkspaceAgents(t, client, ws.ID)
132+
workspace, err := client.Workspace(ctx, ws.ID)
160133
require.NoError(t, err)
161134
resources := workspace.LatestBuild.Resources
162135
if assert.NotEmpty(t, resources) && assert.NotEmpty(t, resources[0].Agents) {
@@ -172,35 +145,24 @@ func TestWorkspaceAgent(t *testing.T) {
172145
t.Parallel()
173146
instanceID := "instanceidentifier"
174147
validator, metadataClient := coderdtest.NewGoogleInstanceIdentity(t, instanceID, false)
175-
client := coderdtest.New(t, &coderdtest.Options{
176-
GoogleTokenValidator: validator,
177-
IncludeProvisionerDaemon: true,
148+
client, db := coderdtest.NewWithDatabase(t, &coderdtest.Options{
149+
GoogleTokenValidator: validator,
178150
})
179151
owner := coderdtest.CreateFirstUser(t, client)
180-
member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
181-
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, &echo.Responses{
182-
Parse: echo.ParseComplete,
183-
ProvisionApply: []*proto.Response{{
184-
Type: &proto.Response_Apply{
185-
Apply: &proto.ApplyComplete{
186-
Resources: []*proto.Resource{{
187-
Name: "somename",
188-
Type: "someinstance",
189-
Agents: []*proto.Agent{{
190-
Auth: &proto.Agent_InstanceId{
191-
InstanceId: instanceID,
192-
},
193-
}},
194-
}},
195-
},
152+
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
153+
ws := dbfake.Workspace(t, db, database.Workspace{
154+
OrganizationID: owner.OrganizationID,
155+
OwnerID: memberUser.ID,
156+
})
157+
dbfake.WorkspaceBuild(t, db, ws, database.WorkspaceBuild{}, &proto.Resource{
158+
Name: "somename",
159+
Type: "someinstance",
160+
Agents: []*proto.Agent{{
161+
Auth: &proto.Agent_InstanceId{
162+
InstanceId: instanceID,
196163
},
197164
}},
198165
})
199-
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
200-
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
201-
workspace := coderdtest.CreateWorkspace(t, member, owner.OrganizationID, template.ID)
202-
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
203-
204166
inv, cfg := clitest.New(t, "agent", "--auth", "google-instance-identity", "--agent-url", client.URL.String())
205167
ptytest.New(t).Attach(inv)
206168
clitest.SetupConfig(t, member, cfg)
@@ -212,9 +174,8 @@ func TestWorkspaceAgent(t *testing.T) {
212174
)
213175

214176
ctx := inv.Context()
215-
216-
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
217-
workspace, err := client.Workspace(ctx, workspace.ID)
177+
coderdtest.AwaitWorkspaceAgents(t, client, ws.ID)
178+
workspace, err := client.Workspace(ctx, ws.ID)
218179
require.NoError(t, err)
219180
resources := workspace.LatestBuild.Resources
220181
if assert.NotEmpty(t, resources) && assert.NotEmpty(t, resources[0].Agents) {
@@ -244,19 +205,12 @@ func TestWorkspaceAgent(t *testing.T) {
244205
t.Run("PostStartup", func(t *testing.T) {
245206
t.Parallel()
246207

247-
authToken := uuid.NewString()
248-
client := coderdtest.New(t, &coderdtest.Options{
249-
IncludeProvisionerDaemon: true,
250-
})
208+
client, db := coderdtest.NewWithDatabase(t, nil)
251209
user := coderdtest.CreateFirstUser(t, client)
252-
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
253-
Parse: echo.ParseComplete,
254-
ProvisionApply: echo.ProvisionApplyWithAgent(authToken),
210+
ws, authToken := dbfake.WorkspaceWithAgent(t, db, database.Workspace{
211+
OrganizationID: user.OrganizationID,
212+
OwnerID: user.UserID,
255213
})
256-
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
257-
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
258-
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
259-
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
260214

261215
logDir := t.TempDir()
262216
inv, _ := clitest.New(t,
@@ -274,7 +228,7 @@ func TestWorkspaceAgent(t *testing.T) {
274228
clitest.Start(t, inv)
275229
pty.ExpectMatchContext(inv.Context(), "agent is starting now")
276230

277-
resources := coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
231+
resources := coderdtest.AwaitWorkspaceAgents(t, client, ws.ID)
278232
require.Len(t, resources, 1)
279233
require.Len(t, resources[0].Agents, 1)
280234
require.Len(t, resources[0].Agents[0].Subsystems, 2)

coderd/coderdtest/coderdtest.go

+7
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ func New(t testing.TB, options *Options) *codersdk.Client {
151151
return client
152152
}
153153

154+
// NewWithDatabase constructs a codersdk client connected to an in-memory API instance.
155+
// The database is returned to provide direct data manipulation for tests.
156+
func NewWithDatabase(t testing.TB, options *Options) (*codersdk.Client, database.Store) {
157+
client, _, api := NewWithAPI(t, options)
158+
return client, api.Database
159+
}
160+
154161
// NewWithProvisionerCloser returns a client as well as a handle to close
155162
// the provisioner. This is a temporary function while work is done to
156163
// standardize how provisioners are registered with coderd. The option

0 commit comments

Comments
 (0)