Skip to content

Commit be3e6ac

Browse files
committed
Improve test coverage for workspace history
1 parent 9cd8b43 commit be3e6ac

14 files changed

+322
-277
lines changed

coderd/coderdtest/coderdtest.go

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package coderdtest
33
import (
44
"context"
55
"database/sql"
6+
"fmt"
67
"io"
78
"net/http/httptest"
89
"net/url"
@@ -67,37 +68,6 @@ func New(t *testing.T) *codersdk.Client {
6768
return codersdk.New(serverURL)
6869
}
6970

70-
// Server represents a test instance of coderd.
71-
// The database is intentionally omitted from
72-
// this struct to promote data being exposed via
73-
// the API.
74-
type Server struct {
75-
Client *codersdk.Client
76-
URL *url.URL
77-
}
78-
79-
// NewInitialUser creates a user with preset credentials and authenticates
80-
// with the passed in codersdk client.
81-
func NewInitialUser(t *testing.T, client *codersdk.Client) coderd.CreateInitialUserRequest {
82-
req := coderd.CreateInitialUserRequest{
83-
Email: "testuser@coder.com",
84-
Username: "testuser",
85-
Password: "testpass",
86-
Organization: "testorg",
87-
}
88-
_, err := client.CreateInitialUser(context.Background(), req)
89-
require.NoError(t, err)
90-
91-
login, err := client.LoginWithPassword(context.Background(), coderd.LoginWithPasswordRequest{
92-
Email: req.Email,
93-
Password: req.Password,
94-
})
95-
require.NoError(t, err)
96-
err = client.SetSessionToken(login.SessionToken)
97-
require.NoError(t, err)
98-
return req
99-
}
100-
10171
// NewProvisionerDaemon launches a provisionerd instance configured to work
10272
// well with coderd testing. It registers the "echo" provisioner for
10373
// quick testing.
@@ -131,9 +101,31 @@ func NewProvisionerDaemon(t *testing.T, client *codersdk.Client) io.Closer {
131101
return closer
132102
}
133103

134-
// NewProject creates a project with the "echo" provisioner for
104+
// CreateInitialUser creates a user with preset credentials and authenticates
105+
// with the passed in codersdk client.
106+
func CreateInitialUser(t *testing.T, client *codersdk.Client) coderd.CreateInitialUserRequest {
107+
req := coderd.CreateInitialUserRequest{
108+
Email: "testuser@coder.com",
109+
Username: "testuser",
110+
Password: "testpass",
111+
Organization: "testorg",
112+
}
113+
_, err := client.CreateInitialUser(context.Background(), req)
114+
require.NoError(t, err)
115+
116+
login, err := client.LoginWithPassword(context.Background(), coderd.LoginWithPasswordRequest{
117+
Email: req.Email,
118+
Password: req.Password,
119+
})
120+
require.NoError(t, err)
121+
err = client.SetSessionToken(login.SessionToken)
122+
require.NoError(t, err)
123+
return req
124+
}
125+
126+
// CreateProject creates a project with the "echo" provisioner for
135127
// compatibility with testing. The name assigned is randomly generated.
136-
func NewProject(t *testing.T, client *codersdk.Client, organization string) coderd.Project {
128+
func CreateProject(t *testing.T, client *codersdk.Client, organization string) coderd.Project {
137129
project, err := client.CreateProject(context.Background(), organization, coderd.CreateProjectRequest{
138130
Name: randomUsername(),
139131
Provisioner: database.ProvisionerTypeEcho,
@@ -142,9 +134,9 @@ func NewProject(t *testing.T, client *codersdk.Client, organization string) code
142134
return project
143135
}
144136

145-
// NewProjectVersion creates a project version for the "echo" provisioner
137+
// CreateProjectVersion creates a project version for the "echo" provisioner
146138
// for compatibility with testing.
147-
func NewProjectVersion(t *testing.T, client *codersdk.Client, organization, project string, responses *echo.Responses) coderd.ProjectVersion {
139+
func CreateProjectVersion(t *testing.T, client *codersdk.Client, organization, project string, responses *echo.Responses) coderd.ProjectVersion {
148140
data, err := echo.Tar(responses)
149141
require.NoError(t, err)
150142
version, err := client.CreateProjectVersion(context.Background(), organization, project, coderd.CreateProjectVersionRequest{
@@ -162,14 +154,15 @@ func AwaitProjectVersionImported(t *testing.T, client *codersdk.Client, organiza
162154
var err error
163155
projectVersion, err = client.ProjectVersion(context.Background(), organization, project, version)
164156
require.NoError(t, err)
157+
fmt.Printf("GOT: %s\n", projectVersion.Import.Status)
165158
return projectVersion.Import.Status.Completed()
166-
}, 3*time.Second, 50*time.Millisecond)
159+
}, 3*time.Second, 25*time.Millisecond)
167160
return projectVersion
168161
}
169162

170-
// NewWorkspace creates a workspace for the user and project provided.
163+
// CreateWorkspace creates a workspace for the user and project provided.
171164
// A random name is generated for it.
172-
func NewWorkspace(t *testing.T, client *codersdk.Client, user string, projectID uuid.UUID) coderd.Workspace {
165+
func CreateWorkspace(t *testing.T, client *codersdk.Client, user string, projectID uuid.UUID) coderd.Workspace {
173166
workspace, err := client.CreateWorkspace(context.Background(), user, coderd.CreateWorkspaceRequest{
174167
ProjectID: projectID,
175168
Name: randomUsername(),
@@ -178,6 +171,18 @@ func NewWorkspace(t *testing.T, client *codersdk.Client, user string, projectID
178171
return workspace
179172
}
180173

174+
// AwaitWorkspaceHistoryProvisioned awaits for the workspace provision job to reach completed status.
175+
func AwaitWorkspaceHistoryProvisioned(t *testing.T, client *codersdk.Client, user, workspace, history string) coderd.WorkspaceHistory {
176+
var workspaceHistory coderd.WorkspaceHistory
177+
require.Eventually(t, func() bool {
178+
var err error
179+
workspaceHistory, err = client.WorkspaceHistory(context.Background(), user, workspace, history)
180+
require.NoError(t, err)
181+
return workspaceHistory.Provision.Status.Completed()
182+
}, 3*time.Second, 25*time.Millisecond)
183+
return workspaceHistory
184+
}
185+
181186
func randomUsername() string {
182187
return strings.ReplaceAll(namesgenerator.GetRandomName(0), "_", "-")
183188
}

coderd/coderdtest/coderdtest_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ func TestMain(m *testing.M) {
1515
func TestNew(t *testing.T) {
1616
t.Parallel()
1717
client := coderdtest.New(t)
18-
_ = coderdtest.NewInitialUser(t, client)
18+
_ = coderdtest.CreateInitialUser(t, client)
1919
_ = coderdtest.NewProvisionerDaemon(t, client)
2020
}

coderd/projects_test.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func TestProjects(t *testing.T) {
1919
t.Run("ListEmpty", func(t *testing.T) {
2020
t.Parallel()
2121
client := coderdtest.New(t)
22-
_ = coderdtest.NewInitialUser(t, client)
22+
_ = coderdtest.CreateInitialUser(t, client)
2323
projects, err := client.Projects(context.Background(), "")
2424
require.NoError(t, err)
2525
require.NotNil(t, projects)
@@ -29,8 +29,8 @@ func TestProjects(t *testing.T) {
2929
t.Run("List", func(t *testing.T) {
3030
t.Parallel()
3131
client := coderdtest.New(t)
32-
user := coderdtest.NewInitialUser(t, client)
33-
_ = coderdtest.NewProject(t, client, user.Organization)
32+
user := coderdtest.CreateInitialUser(t, client)
33+
_ = coderdtest.CreateProject(t, client, user.Organization)
3434
projects, err := client.Projects(context.Background(), "")
3535
require.NoError(t, err)
3636
require.Len(t, projects, 1)
@@ -42,7 +42,7 @@ func TestProjectsByOrganization(t *testing.T) {
4242
t.Run("ListEmpty", func(t *testing.T) {
4343
t.Parallel()
4444
client := coderdtest.New(t)
45-
user := coderdtest.NewInitialUser(t, client)
45+
user := coderdtest.CreateInitialUser(t, client)
4646
projects, err := client.Projects(context.Background(), user.Organization)
4747
require.NoError(t, err)
4848
require.NotNil(t, projects)
@@ -52,8 +52,8 @@ func TestProjectsByOrganization(t *testing.T) {
5252
t.Run("List", func(t *testing.T) {
5353
t.Parallel()
5454
client := coderdtest.New(t)
55-
user := coderdtest.NewInitialUser(t, client)
56-
_ = coderdtest.NewProject(t, client, user.Organization)
55+
user := coderdtest.CreateInitialUser(t, client)
56+
_ = coderdtest.CreateProject(t, client, user.Organization)
5757
projects, err := client.Projects(context.Background(), "")
5858
require.NoError(t, err)
5959
require.Len(t, projects, 1)
@@ -65,15 +65,15 @@ func TestPostProjectsByOrganization(t *testing.T) {
6565
t.Run("Create", func(t *testing.T) {
6666
t.Parallel()
6767
client := coderdtest.New(t)
68-
user := coderdtest.NewInitialUser(t, client)
69-
_ = coderdtest.NewProject(t, client, user.Organization)
68+
user := coderdtest.CreateInitialUser(t, client)
69+
_ = coderdtest.CreateProject(t, client, user.Organization)
7070
})
7171

7272
t.Run("AlreadyExists", func(t *testing.T) {
7373
t.Parallel()
7474
client := coderdtest.New(t)
75-
user := coderdtest.NewInitialUser(t, client)
76-
project := coderdtest.NewProject(t, client, user.Organization)
75+
user := coderdtest.CreateInitialUser(t, client)
76+
project := coderdtest.CreateProject(t, client, user.Organization)
7777
_, err := client.CreateProject(context.Background(), user.Organization, coderd.CreateProjectRequest{
7878
Name: project.Name,
7979
Provisioner: database.ProvisionerTypeEcho,
@@ -89,8 +89,8 @@ func TestProjectByOrganization(t *testing.T) {
8989
t.Run("Get", func(t *testing.T) {
9090
t.Parallel()
9191
client := coderdtest.New(t)
92-
user := coderdtest.NewInitialUser(t, client)
93-
project := coderdtest.NewProject(t, client, user.Organization)
92+
user := coderdtest.CreateInitialUser(t, client)
93+
project := coderdtest.CreateProject(t, client, user.Organization)
9494
_, err := client.Project(context.Background(), user.Organization, project.Name)
9595
require.NoError(t, err)
9696
})
@@ -101,8 +101,8 @@ func TestPostParametersByProject(t *testing.T) {
101101
t.Run("Create", func(t *testing.T) {
102102
t.Parallel()
103103
client := coderdtest.New(t)
104-
user := coderdtest.NewInitialUser(t, client)
105-
project := coderdtest.NewProject(t, client, user.Organization)
104+
user := coderdtest.CreateInitialUser(t, client)
105+
project := coderdtest.CreateProject(t, client, user.Organization)
106106
_, err := client.CreateProjectParameter(context.Background(), user.Organization, project.Name, coderd.CreateParameterValueRequest{
107107
Name: "somename",
108108
SourceValue: "tomato",
@@ -119,8 +119,8 @@ func TestParametersByProject(t *testing.T) {
119119
t.Run("List", func(t *testing.T) {
120120
t.Parallel()
121121
client := coderdtest.New(t)
122-
user := coderdtest.NewInitialUser(t, client)
123-
project := coderdtest.NewProject(t, client, user.Organization)
122+
user := coderdtest.CreateInitialUser(t, client)
123+
project := coderdtest.CreateProject(t, client, user.Organization)
124124
params, err := client.ProjectParameters(context.Background(), user.Organization, project.Name)
125125
require.NoError(t, err)
126126
require.NotNil(t, params)

coderd/projectversion_test.go

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ func TestProjectVersionsByOrganization(t *testing.T) {
2020
t.Run("ListEmpty", func(t *testing.T) {
2121
t.Parallel()
2222
client := coderdtest.New(t)
23-
user := coderdtest.NewInitialUser(t, client)
24-
project := coderdtest.NewProject(t, client, user.Organization)
23+
user := coderdtest.CreateInitialUser(t, client)
24+
project := coderdtest.CreateProject(t, client, user.Organization)
2525
versions, err := client.ProjectVersions(context.Background(), user.Organization, project.Name)
2626
require.NoError(t, err)
2727
require.NotNil(t, versions)
@@ -31,9 +31,9 @@ func TestProjectVersionsByOrganization(t *testing.T) {
3131
t.Run("List", func(t *testing.T) {
3232
t.Parallel()
3333
client := coderdtest.New(t)
34-
user := coderdtest.NewInitialUser(t, client)
35-
project := coderdtest.NewProject(t, client, user.Organization)
36-
_ = coderdtest.NewProjectVersion(t, client, user.Organization, project.Name, nil)
34+
user := coderdtest.CreateInitialUser(t, client)
35+
project := coderdtest.CreateProject(t, client, user.Organization)
36+
_ = coderdtest.CreateProjectVersion(t, client, user.Organization, project.Name, nil)
3737
versions, err := client.ProjectVersions(context.Background(), user.Organization, project.Name)
3838
require.NoError(t, err)
3939
require.Len(t, versions, 1)
@@ -45,9 +45,9 @@ func TestProjectVersionByOrganizationAndName(t *testing.T) {
4545
t.Run("Get", func(t *testing.T) {
4646
t.Parallel()
4747
client := coderdtest.New(t)
48-
user := coderdtest.NewInitialUser(t, client)
49-
project := coderdtest.NewProject(t, client, user.Organization)
50-
version := coderdtest.NewProjectVersion(t, client, user.Organization, project.Name, nil)
48+
user := coderdtest.CreateInitialUser(t, client)
49+
project := coderdtest.CreateProject(t, client, user.Organization)
50+
version := coderdtest.CreateProjectVersion(t, client, user.Organization, project.Name, nil)
5151
require.Equal(t, version.Import.Status, coderd.ProvisionerJobStatusPending)
5252
})
5353
}
@@ -57,16 +57,16 @@ func TestPostProjectVersionByOrganization(t *testing.T) {
5757
t.Run("Create", func(t *testing.T) {
5858
t.Parallel()
5959
client := coderdtest.New(t)
60-
user := coderdtest.NewInitialUser(t, client)
61-
project := coderdtest.NewProject(t, client, user.Organization)
62-
_ = coderdtest.NewProjectVersion(t, client, user.Organization, project.Name, nil)
60+
user := coderdtest.CreateInitialUser(t, client)
61+
project := coderdtest.CreateProject(t, client, user.Organization)
62+
_ = coderdtest.CreateProjectVersion(t, client, user.Organization, project.Name, nil)
6363
})
6464

6565
t.Run("InvalidStorage", func(t *testing.T) {
6666
t.Parallel()
6767
client := coderdtest.New(t)
68-
user := coderdtest.NewInitialUser(t, client)
69-
project := coderdtest.NewProject(t, client, user.Organization)
68+
user := coderdtest.CreateInitialUser(t, client)
69+
project := coderdtest.CreateProject(t, client, user.Organization)
7070
_, err := client.CreateProjectVersion(context.Background(), user.Organization, project.Name, coderd.CreateProjectVersionRequest{
7171
StorageMethod: database.ProjectStorageMethod("invalid"),
7272
StorageSource: []byte{},
@@ -80,9 +80,9 @@ func TestProjectVersionParametersByOrganizationAndName(t *testing.T) {
8080
t.Run("NotImported", func(t *testing.T) {
8181
t.Parallel()
8282
client := coderdtest.New(t)
83-
user := coderdtest.NewInitialUser(t, client)
84-
project := coderdtest.NewProject(t, client, user.Organization)
85-
version := coderdtest.NewProjectVersion(t, client, user.Organization, project.Name, nil)
83+
user := coderdtest.CreateInitialUser(t, client)
84+
project := coderdtest.CreateProject(t, client, user.Organization)
85+
version := coderdtest.CreateProjectVersion(t, client, user.Organization, project.Name, nil)
8686
_, err := client.ProjectVersionParameters(context.Background(), user.Organization, project.Name, version.Name)
8787
var apiErr *codersdk.Error
8888
require.ErrorAs(t, err, &apiErr)
@@ -92,10 +92,10 @@ func TestProjectVersionParametersByOrganizationAndName(t *testing.T) {
9292
t.Run("FailedImport", func(t *testing.T) {
9393
t.Parallel()
9494
client := coderdtest.New(t)
95-
user := coderdtest.NewInitialUser(t, client)
95+
user := coderdtest.CreateInitialUser(t, client)
9696
_ = coderdtest.NewProvisionerDaemon(t, client)
97-
project := coderdtest.NewProject(t, client, user.Organization)
98-
version := coderdtest.NewProjectVersion(t, client, user.Organization, project.Name, &echo.Responses{
97+
project := coderdtest.CreateProject(t, client, user.Organization)
98+
version := coderdtest.CreateProjectVersion(t, client, user.Organization, project.Name, &echo.Responses{
9999
Provision: []*proto.Provision_Response{{}},
100100
})
101101
coderdtest.AwaitProjectVersionImported(t, client, user.Organization, project.Name, version.Name)
@@ -107,10 +107,10 @@ func TestProjectVersionParametersByOrganizationAndName(t *testing.T) {
107107
t.Run("List", func(t *testing.T) {
108108
t.Parallel()
109109
client := coderdtest.New(t)
110-
user := coderdtest.NewInitialUser(t, client)
110+
user := coderdtest.CreateInitialUser(t, client)
111111
_ = coderdtest.NewProvisionerDaemon(t, client)
112-
project := coderdtest.NewProject(t, client, user.Organization)
113-
version := coderdtest.NewProjectVersion(t, client, user.Organization, project.Name, &echo.Responses{
112+
project := coderdtest.CreateProject(t, client, user.Organization)
113+
version := coderdtest.CreateProjectVersion(t, client, user.Organization, project.Name, &echo.Responses{
114114
Parse: []*proto.Parse_Response{{
115115
Type: &proto.Parse_Response_Complete{
116116
Complete: &proto.Parse_Complete{

coderd/provisioners.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func convertProvisionerJob(provisionerJob database.ProvisionerJob) ProvisionerJo
7070
job.Status = ProvisionerJobStatusRunning
7171
}
7272

73-
if job.Error != "" {
73+
if !provisionerJob.CancelledAt.Valid && job.Error != "" {
7474
job.Status = ProvisionerJobStatusFailed
7575
}
7676

coderd/users.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@ func (api *api) organizationsByUser(rw http.ResponseWriter, r *http.Request) {
195195
user := httpmw.UserParam(r)
196196

197197
organizations, err := api.Database.GetOrganizationsByUserID(r.Context(), user.ID)
198+
if errors.Is(err, sql.ErrNoRows) {
199+
err = nil
200+
organizations = []database.Organization{}
201+
}
198202
if err != nil {
199203
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
200204
Message: fmt.Sprintf("get organizations: %s", err.Error()),

0 commit comments

Comments
 (0)