Skip to content

Commit b5a774a

Browse files
committed
Add create workspace CLI
1 parent 485c07b commit b5a774a

File tree

11 files changed

+108
-69
lines changed

11 files changed

+108
-69
lines changed

cli/clitest/clitest.go

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,20 @@ import (
44
"archive/tar"
55
"bufio"
66
"bytes"
7-
"context"
87
"errors"
98
"io"
109
"os"
1110
"path/filepath"
1211
"regexp"
1312
"testing"
1413

14+
"github.com/Netflix/go-expect"
1515
"github.com/spf13/cobra"
1616
"github.com/stretchr/testify/require"
1717
"golang.org/x/xerrors"
1818

1919
"github.com/coder/coder/cli"
2020
"github.com/coder/coder/cli/config"
21-
"github.com/coder/coder/coderd"
22-
"github.com/coder/coder/coderd/coderdtest"
2321
"github.com/coder/coder/codersdk"
2422
"github.com/coder/coder/provisioner/echo"
2523
)
@@ -39,20 +37,12 @@ func New(t *testing.T, args ...string) (*cobra.Command, config.Root) {
3937
return cmd, root
4038
}
4139

42-
// CreateInitialUser creates the initial user and write's the session
43-
// token to the config root provided.
44-
func CreateInitialUser(t *testing.T, client *codersdk.Client, root config.Root) coderd.CreateInitialUserRequest {
45-
user := coderdtest.CreateInitialUser(t, client)
46-
resp, err := client.LoginWithPassword(context.Background(), coderd.LoginWithPasswordRequest{
47-
Email: user.Email,
48-
Password: user.Password,
49-
})
50-
require.NoError(t, err)
51-
err = root.Session().Write(resp.SessionToken)
40+
// SetupConfig applies the URL and SessionToken of the client to the config.
41+
func SetupConfig(t *testing.T, client *codersdk.Client, root config.Root) {
42+
err := root.Session().Write(client.SessionToken)
5243
require.NoError(t, err)
5344
err = root.URL().Write(client.URL.String())
5445
require.NoError(t, err)
55-
return user
5646
}
5747

5848
// CreateProjectVersionSource writes the echo provisioner responses into a
@@ -66,9 +56,9 @@ func CreateProjectVersionSource(t *testing.T, responses *echo.Responses) string
6656
return directory
6757
}
6858

69-
// StdoutLogs provides a writer to t.Log that strips
70-
// all ANSI escape codes.
71-
func StdoutLogs(t *testing.T) io.Writer {
59+
// NewConsole creates a new TTY bound to the command provided.
60+
// All ANSI escape codes are stripped to provide clean output.
61+
func NewConsole(t *testing.T, cmd *cobra.Command) *expect.Console {
7262
reader, writer := io.Pipe()
7363
scanner := bufio.NewScanner(reader)
7464
t.Cleanup(func() {
@@ -83,7 +73,12 @@ func StdoutLogs(t *testing.T) io.Writer {
8373
t.Log(stripAnsi.ReplaceAllString(scanner.Text(), ""))
8474
}
8575
}()
86-
return writer
76+
77+
console, err := expect.NewConsole(expect.WithStdout(writer))
78+
require.NoError(t, err)
79+
cmd.SetIn(console.Tty())
80+
cmd.SetOut(console.Tty())
81+
return console
8782
}
8883

8984
func extractTar(data []byte, directory string) error {

cli/login_test.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,9 @@ package cli_test
33
import (
44
"testing"
55

6-
"github.com/stretchr/testify/require"
7-
86
"github.com/coder/coder/cli/clitest"
97
"github.com/coder/coder/coderd/coderdtest"
10-
11-
"github.com/ActiveState/termtest/expect"
8+
"github.com/stretchr/testify/require"
129
)
1310

1411
func TestLogin(t *testing.T) {
@@ -23,12 +20,9 @@ func TestLogin(t *testing.T) {
2320

2421
t.Run("InitialUserTTY", func(t *testing.T) {
2522
t.Parallel()
26-
console, err := expect.NewConsole(expect.WithStdout(clitest.StdoutLogs(t)))
27-
require.NoError(t, err)
2823
client := coderdtest.New(t)
2924
root, _ := clitest.New(t, "login", client.URL.String())
30-
root.SetIn(console.Tty())
31-
root.SetOut(console.Tty())
25+
console := clitest.NewConsole(t, root)
3226
go func() {
3327
err := root.Execute()
3428
require.NoError(t, err)
@@ -44,12 +38,12 @@ func TestLogin(t *testing.T) {
4438
for i := 0; i < len(matches); i += 2 {
4539
match := matches[i]
4640
value := matches[i+1]
47-
_, err = console.ExpectString(match)
41+
_, err := console.ExpectString(match)
4842
require.NoError(t, err)
4943
_, err = console.SendLine(value)
5044
require.NoError(t, err)
5145
}
52-
_, err = console.ExpectString("Welcome to Coder")
46+
_, err := console.ExpectString("Welcome to Coder")
5347
require.NoError(t, err)
5448
})
5549
}

cli/projectcreate_test.go

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package cli_test
33
import (
44
"testing"
55

6-
"github.com/ActiveState/termtest/expect"
76
"github.com/stretchr/testify/require"
87

98
"github.com/coder/coder/cli/clitest"
@@ -17,18 +16,16 @@ func TestProjectCreate(t *testing.T) {
1716
t.Parallel()
1817
t.Run("NoParameters", func(t *testing.T) {
1918
t.Parallel()
20-
console, err := expect.NewConsole(expect.WithStdout(clitest.StdoutLogs(t)))
21-
require.NoError(t, err)
2219
client := coderdtest.New(t)
20+
coderdtest.CreateInitialUser(t, client)
2321
source := clitest.CreateProjectVersionSource(t, &echo.Responses{
2422
Parse: echo.ParseComplete,
2523
Provision: echo.ProvisionComplete,
2624
})
2725
cmd, root := clitest.New(t, "projects", "create", "--directory", source, "--provisioner", string(database.ProvisionerTypeEcho))
28-
_ = clitest.CreateInitialUser(t, client, root)
26+
clitest.SetupConfig(t, client, root)
2927
_ = coderdtest.NewProvisionerDaemon(t, client)
30-
cmd.SetIn(console.Tty())
31-
cmd.SetOut(console.Tty())
28+
console := clitest.NewConsole(t, cmd)
3229
closeChan := make(chan struct{})
3330
go func() {
3431
err := cmd.Execute()
@@ -45,7 +42,7 @@ func TestProjectCreate(t *testing.T) {
4542
for i := 0; i < len(matches); i += 2 {
4643
match := matches[i]
4744
value := matches[i+1]
48-
_, err = console.ExpectString(match)
45+
_, err := console.ExpectString(match)
4946
require.NoError(t, err)
5047
_, err = console.SendLine(value)
5148
require.NoError(t, err)
@@ -55,9 +52,8 @@ func TestProjectCreate(t *testing.T) {
5552

5653
t.Run("Parameter", func(t *testing.T) {
5754
t.Parallel()
58-
console, err := expect.NewConsole(expect.WithStdout(clitest.StdoutLogs(t)))
59-
require.NoError(t, err)
6055
client := coderdtest.New(t)
56+
coderdtest.CreateInitialUser(t, client)
6157
source := clitest.CreateProjectVersionSource(t, &echo.Responses{
6258
Parse: []*proto.Parse_Response{{
6359
Type: &proto.Parse_Response_Complete{
@@ -74,10 +70,9 @@ func TestProjectCreate(t *testing.T) {
7470
Provision: echo.ProvisionComplete,
7571
})
7672
cmd, root := clitest.New(t, "projects", "create", "--directory", source, "--provisioner", string(database.ProvisionerTypeEcho))
77-
_ = clitest.CreateInitialUser(t, client, root)
78-
_ = coderdtest.NewProvisionerDaemon(t, client)
79-
cmd.SetIn(console.Tty())
80-
cmd.SetOut(console.Tty())
73+
clitest.SetupConfig(t, client, root)
74+
coderdtest.NewProvisionerDaemon(t, client)
75+
console := clitest.NewConsole(t, cmd)
8176
closeChan := make(chan struct{})
8277
go func() {
8378
err := cmd.Execute()
@@ -95,7 +90,7 @@ func TestProjectCreate(t *testing.T) {
9590
for i := 0; i < len(matches); i += 2 {
9691
match := matches[i]
9792
value := matches[i+1]
98-
_, err = console.ExpectString(match)
93+
_, err := console.ExpectString(match)
9994
require.NoError(t, err)
10095
_, err = console.SendLine(value)
10196
require.NoError(t, err)

cli/root.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ func createClient(cmd *cobra.Command) (*codersdk.Client, error) {
8686
return nil, err
8787
}
8888
client := codersdk.New(serverURL)
89-
return client, client.SetSessionToken(token)
89+
client.SessionToken = token
90+
return client, nil
9091
}
9192

9293
// currentOrganization returns the currently active organization for the authenticated user.

cli/workspacecreate.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ func workspaceCreate() *cobra.Command {
3636
name, err = prompt(cmd, &promptui.Prompt{
3737
Label: "What's your workspace's name?",
3838
Validate: func(s string) error {
39+
if s == "" {
40+
return xerrors.Errorf("You must provide a name!")
41+
}
3942
workspace, _ := client.Workspace(cmd.Context(), "", s)
4043
if workspace.ID.String() != uuid.Nil.String() {
4144
return xerrors.New("A workspace already exists with that name!")

cli/workspacecreate_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package cli_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/coder/coder/cli/clitest"
7+
"github.com/coder/coder/coderd/coderdtest"
8+
"github.com/coder/coder/provisioner/echo"
9+
"github.com/coder/coder/provisionersdk/proto"
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
func TestWorkspaceCreate(t *testing.T) {
14+
t.Parallel()
15+
t.Run("Create", func(t *testing.T) {
16+
t.Parallel()
17+
client := coderdtest.New(t)
18+
user := coderdtest.CreateInitialUser(t, client)
19+
_ = coderdtest.NewProvisionerDaemon(t, client)
20+
job := coderdtest.CreateProjectImportProvisionerJob(t, client, user.Organization, &echo.Responses{
21+
Parse: echo.ParseComplete,
22+
Provision: []*proto.Provision_Response{{
23+
Type: &proto.Provision_Response_Complete{
24+
Complete: &proto.Provision_Complete{
25+
Resources: []*proto.Resource{{
26+
Name: "example",
27+
Type: "aws_instance",
28+
}},
29+
},
30+
},
31+
}},
32+
})
33+
coderdtest.AwaitProvisionerJob(t, client, user.Organization, job.ID)
34+
project := coderdtest.CreateProject(t, client, user.Organization, job.ID)
35+
cmd, root := clitest.New(t, "workspaces", "create", project.Name)
36+
clitest.SetupConfig(t, client, root)
37+
38+
console := clitest.NewConsole(t, cmd)
39+
closeChan := make(chan struct{})
40+
go func() {
41+
err := cmd.Execute()
42+
require.NoError(t, err)
43+
close(closeChan)
44+
}()
45+
46+
matches := []string{
47+
"name?", "workspace-name",
48+
"Create workspace", "y",
49+
}
50+
for i := 0; i < len(matches); i += 2 {
51+
match := matches[i]
52+
value := matches[i+1]
53+
_, err := console.ExpectString(match)
54+
require.NoError(t, err)
55+
_, err = console.SendLine(value)
56+
require.NoError(t, err)
57+
}
58+
_, err := console.ExpectString("Create")
59+
require.NoError(t, err)
60+
<-closeChan
61+
})
62+
}

coderd/coderdtest/coderdtest.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,7 @@ func CreateInitialUser(t *testing.T, client *codersdk.Client) coderd.CreateIniti
117117
Password: req.Password,
118118
})
119119
require.NoError(t, err)
120-
err = client.SetSessionToken(login.SessionToken)
121-
require.NoError(t, err)
120+
client.SessionToken = login.SessionToken
122121
return req
123122
}
124123

coderd/provisionerdaemons.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,15 +195,11 @@ func (server *provisionerdServer) AcquireJob(ctx context.Context, _ *proto.Empty
195195
if err != nil {
196196
return nil, failJob(fmt.Sprintf("get project: %s", err))
197197
}
198-
organization, err := server.Database.GetOrganizationByID(ctx, project.OrganizationID)
199-
if err != nil {
200-
return nil, failJob(fmt.Sprintf("get organization: %s", err))
201-
}
202198

203199
// Compute parameters for the workspace to consume.
204200
parameters, err := parameter.Compute(ctx, server.Database, parameter.ComputeScope{
205201
ProjectImportJobID: projectVersion.ImportJobID,
206-
OrganizationID: organization.ID,
202+
OrganizationID: job.OrganizationID,
207203
ProjectID: uuid.NullUUID{
208204
UUID: project.ID,
209205
Valid: true,
@@ -226,6 +222,11 @@ func (server *provisionerdServer) AcquireJob(ctx context.Context, _ *proto.Empty
226222
}
227223
protoParameters = append(protoParameters, converted)
228224
}
225+
protoParameters = append(protoParameters, &sdkproto.ParameterValue{
226+
DestinationScheme: sdkproto.ParameterDestination_PROVISIONER_VARIABLE,
227+
Name: parameter.CoderWorkspaceTransition,
228+
Value: string(workspaceHistory.Transition),
229+
})
229230

230231
protoJob.Type = &proto.AcquiredJob_WorkspaceProvision_{
231232
WorkspaceProvision: &proto.AcquiredJob_WorkspaceProvision{

coderd/provisionerjobs.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ func (api *api) postProvisionerImportJobByOrganization(rw http.ResponseWriter, r
112112
StorageMethod: database.ProvisionerStorageMethodFile,
113113
StorageSource: file.Hash,
114114
Type: database.ProvisionerJobTypeProjectVersionImport,
115+
Input: []byte{'{', '}'},
115116
})
116117
if err != nil {
117118
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{

coderd/workspaces_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func TestPostWorkspaceByUser(t *testing.T) {
7373
Password: anotherUser.Password,
7474
})
7575
require.NoError(t, err)
76-
err = client.SetSessionToken(token.SessionToken)
76+
client.SessionToken = token.SessionToken
7777
require.NoError(t, err)
7878

7979
_, err = client.CreateWorkspace(context.Background(), "", coderd.CreateWorkspaceRequest{

0 commit comments

Comments
 (0)
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