Skip to content

Commit 143e56a

Browse files
committed
Merge branch 'main' into no-sx
2 parents 8aba5e2 + 1c2f9e3 commit 143e56a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+451
-226
lines changed

cli/ping_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func TestPing(t *testing.T) {
1919
t.Run("OK", func(t *testing.T) {
2020
t.Parallel()
2121

22-
client, workspace, agentToken := setupWorkspaceForAgent(t, nil)
22+
client, workspace, agentToken := setupWorkspaceForAgent(t)
2323
inv, root := clitest.New(t, "ping", workspace.Name)
2424
clitest.SetupConfig(t, client, root)
2525
pty := ptytest.New(t)

cli/server_internal_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ func TestIsDERPPath(t *testing.T) {
254254
//{
255255
// path: "/derp",
256256
// expected: true,
257-
//},
257+
// },
258258
{
259259
path: "/derp/",
260260
expected: true,

cli/speedtest_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func TestSpeedtest(t *testing.T) {
2323
if testing.Short() {
2424
t.Skip("This test takes a minimum of 5ms per a hardcoded value in Tailscale!")
2525
}
26-
client, workspace, agentToken := setupWorkspaceForAgent(t, nil)
26+
client, workspace, agentToken := setupWorkspaceForAgent(t)
2727
_ = agenttest.New(t, client.URL, agentToken)
2828
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
2929

cli/ssh_test.go

Lines changed: 61 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,11 @@ import (
2121
"testing"
2222
"time"
2323

24-
"golang.org/x/xerrors"
25-
26-
"github.com/google/uuid"
2724
"github.com/stretchr/testify/assert"
2825
"github.com/stretchr/testify/require"
2926
"golang.org/x/crypto/ssh"
3027
gosshagent "golang.org/x/crypto/ssh/agent"
28+
"golang.org/x/xerrors"
3129

3230
"cdr.dev/slog"
3331
"cdr.dev/slog/sloggers/slogtest"
@@ -38,71 +36,36 @@ import (
3836
"github.com/coder/coder/v2/cli/cliui"
3937
"github.com/coder/coder/v2/coderd/coderdtest"
4038
"github.com/coder/coder/v2/coderd/database"
39+
"github.com/coder/coder/v2/coderd/database/dbfake"
40+
"github.com/coder/coder/v2/coderd/database/dbtestutil"
4141
"github.com/coder/coder/v2/codersdk"
42-
"github.com/coder/coder/v2/provisioner/echo"
4342
"github.com/coder/coder/v2/provisionersdk/proto"
4443
"github.com/coder/coder/v2/pty"
4544
"github.com/coder/coder/v2/pty/ptytest"
4645
"github.com/coder/coder/v2/testutil"
4746
)
4847

49-
const (
50-
startupScriptPattern = "i-am-ready"
51-
)
52-
53-
func setupWorkspaceForAgent(t *testing.T, mutate func([]*proto.Agent) []*proto.Agent) (*codersdk.Client, codersdk.Workspace, string) {
48+
func setupWorkspaceForAgent(t *testing.T, mutations ...func([]*proto.Agent) []*proto.Agent) (*codersdk.Client, database.Workspace, string) {
5449
t.Helper()
55-
if mutate == nil {
56-
mutate = func(a []*proto.Agent) []*proto.Agent {
57-
return a
58-
}
59-
}
60-
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
50+
51+
client, store := coderdtest.NewWithDatabase(t, nil)
6152
client.SetLogger(slogtest.Make(t, nil).Named("client").Leveled(slog.LevelDebug))
62-
user := coderdtest.CreateFirstUser(t, client)
63-
agentToken := uuid.NewString()
64-
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
65-
Parse: echo.ParseComplete,
66-
ProvisionPlan: echo.PlanComplete,
67-
ProvisionApply: []*proto.Response{{
68-
Type: &proto.Response_Apply{
69-
Apply: &proto.ApplyComplete{
70-
Resources: []*proto.Resource{{
71-
Name: "dev",
72-
Type: "google_compute_instance",
73-
Agents: mutate([]*proto.Agent{{
74-
Id: uuid.NewString(),
75-
Auth: &proto.Agent_Token{
76-
Token: agentToken,
77-
},
78-
Scripts: []*proto.Script{
79-
{
80-
Script: fmt.Sprintf("echo '%s'", startupScriptPattern),
81-
RunOnStart: true,
82-
},
83-
},
84-
}}),
85-
}},
86-
},
87-
},
88-
}},
89-
})
90-
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
91-
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
92-
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
93-
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
94-
workspace, err := client.Workspace(context.Background(), workspace.ID)
95-
require.NoError(t, err)
96-
97-
return client, workspace, agentToken
53+
first := coderdtest.CreateFirstUser(t, client)
54+
userClient, user := coderdtest.CreateAnotherUser(t, client, first.OrganizationID)
55+
workspace, agentToken := dbfake.WorkspaceWithAgent(t, store, database.Workspace{
56+
OrganizationID: first.OrganizationID,
57+
OwnerID: user.ID,
58+
}, mutations...)
59+
60+
return userClient, workspace, agentToken
9861
}
9962

10063
func TestSSH(t *testing.T) {
10164
t.Parallel()
10265
t.Run("ImmediateExit", func(t *testing.T) {
10366
t.Parallel()
10467

105-
client, workspace, agentToken := setupWorkspaceForAgent(t, nil)
68+
client, workspace, agentToken := setupWorkspaceForAgent(t)
10669
inv, root := clitest.New(t, "ssh", workspace.Name)
10770
clitest.SetupConfig(t, client, root)
10871
pty := ptytest.New(t).Attach(inv)
@@ -159,9 +122,17 @@ func TestSSH(t *testing.T) {
159122
t.Skip("Windows doesn't seem to clean up the process, maybe #7100 will fix it")
160123
}
161124

162-
client, workspace, agentToken := setupWorkspaceForAgent(t, nil)
125+
store, ps := dbtestutil.NewDB(t)
126+
client := coderdtest.New(t, &coderdtest.Options{Pubsub: ps, Database: store})
127+
client.SetLogger(slogtest.Make(t, nil).Named("client").Leveled(slog.LevelDebug))
128+
first := coderdtest.CreateFirstUser(t, client)
129+
userClient, user := coderdtest.CreateAnotherUser(t, client, first.OrganizationID)
130+
workspace, agentToken := dbfake.WorkspaceWithAgent(t, store, database.Workspace{
131+
OrganizationID: first.OrganizationID,
132+
OwnerID: user.ID,
133+
})
163134
inv, root := clitest.New(t, "ssh", workspace.Name)
164-
clitest.SetupConfig(t, client, root)
135+
clitest.SetupConfig(t, userClient, root)
165136
pty := ptytest.New(t).Attach(inv)
166137

167138
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
@@ -180,7 +151,13 @@ func TestSSH(t *testing.T) {
180151
pty.WriteLine("echo hell'o'")
181152
pty.ExpectMatchContext(ctx, "hello")
182153

183-
workspace = coderdtest.MustTransitionWorkspace(t, client, workspace.ID, database.WorkspaceTransitionStart, database.WorkspaceTransitionStop)
154+
_ = dbfake.WorkspaceBuildBuilder(t, store, workspace).
155+
Seed(database.WorkspaceBuild{
156+
Transition: database.WorkspaceTransitionStop,
157+
BuildNumber: 2,
158+
}).
159+
Pubsub(ps).Do()
160+
t.Log("stopped workspace")
184161

185162
select {
186163
case <-cmdDone:
@@ -191,7 +168,7 @@ func TestSSH(t *testing.T) {
191168

192169
t.Run("Stdio", func(t *testing.T) {
193170
t.Parallel()
194-
client, workspace, agentToken := setupWorkspaceForAgent(t, nil)
171+
client, workspace, agentToken := setupWorkspaceForAgent(t)
195172
_, _ = tGoContext(t, func(ctx context.Context) {
196173
// Run this async so the SSH command has to wait for
197174
// the build and agent to connect!
@@ -251,7 +228,7 @@ func TestSSH(t *testing.T) {
251228

252229
t.Run("Stdio_RemoteForward_Signal", func(t *testing.T) {
253230
t.Parallel()
254-
client, workspace, agentToken := setupWorkspaceForAgent(t, nil)
231+
client, workspace, agentToken := setupWorkspaceForAgent(t)
255232
_, _ = tGoContext(t, func(ctx context.Context) {
256233
// Run this async so the SSH command has to wait for
257234
// the build and agent to connect!
@@ -312,7 +289,7 @@ func TestSSH(t *testing.T) {
312289

313290
t.Run("Stdio_BrokenConn", func(t *testing.T) {
314291
t.Parallel()
315-
client, workspace, agentToken := setupWorkspaceForAgent(t, nil)
292+
client, workspace, agentToken := setupWorkspaceForAgent(t)
316293
_, _ = tGoContext(t, func(ctx context.Context) {
317294
// Run this async so the SSH command has to wait for
318295
// the build and agent to connect!
@@ -373,7 +350,7 @@ func TestSSH(t *testing.T) {
373350
}
374351
t.Parallel()
375352
ctx := testutil.Context(t, testutil.WaitSuperLong)
376-
client, workspace, agentToken := setupWorkspaceForAgent(t, nil)
353+
client, workspace, agentToken := setupWorkspaceForAgent(t)
377354
_, _ = tGoContext(t, func(ctx context.Context) {
378355
// Run this async so the SSH command has to wait for
379356
// the build and agent to connect!
@@ -483,7 +460,17 @@ func TestSSH(t *testing.T) {
483460
if runtime.GOOS == "windows" {
484461
t.Skip("Windows doesn't seem to clean up the process, maybe #7100 will fix it")
485462
}
486-
client, workspace, agentToken := setupWorkspaceForAgent(t, nil)
463+
464+
store, ps := dbtestutil.NewDB(t)
465+
client := coderdtest.New(t, &coderdtest.Options{Pubsub: ps, Database: store})
466+
client.SetLogger(slogtest.Make(t, nil).Named("client").Leveled(slog.LevelDebug))
467+
first := coderdtest.CreateFirstUser(t, client)
468+
userClient, user := coderdtest.CreateAnotherUser(t, client, first.OrganizationID)
469+
workspace, agentToken := dbfake.WorkspaceWithAgent(t, store, database.Workspace{
470+
OrganizationID: first.OrganizationID,
471+
OwnerID: user.ID,
472+
})
473+
487474
_, _ = tGoContext(t, func(ctx context.Context) {
488475
// Run this async so the SSH command has to wait for
489476
// the build and agent to connect.
@@ -503,7 +490,7 @@ func TestSSH(t *testing.T) {
503490
defer cancel()
504491

505492
inv, root := clitest.New(t, "ssh", "--stdio", workspace.Name)
506-
clitest.SetupConfig(t, client, root)
493+
clitest.SetupConfig(t, userClient, root)
507494
inv.Stdin = clientOutput
508495
inv.Stdout = serverInput
509496
inv.Stderr = io.Discard
@@ -533,7 +520,14 @@ func TestSSH(t *testing.T) {
533520
err = session.Shell()
534521
require.NoError(t, err)
535522

536-
workspace = coderdtest.MustTransitionWorkspace(t, client, workspace.ID, database.WorkspaceTransitionStart, database.WorkspaceTransitionStop)
523+
_ = dbfake.WorkspaceBuildBuilder(t, store, workspace).
524+
Seed(database.WorkspaceBuild{
525+
Transition: database.WorkspaceTransitionStop,
526+
BuildNumber: 2,
527+
}).
528+
Pubsub(ps).
529+
Do()
530+
t.Log("stopped workspace")
537531

538532
select {
539533
case <-cmdDone:
@@ -549,7 +543,7 @@ func TestSSH(t *testing.T) {
549543

550544
t.Parallel()
551545

552-
client, workspace, agentToken := setupWorkspaceForAgent(t, nil)
546+
client, workspace, agentToken := setupWorkspaceForAgent(t)
553547

554548
_ = agenttest.New(t, client.URL, agentToken)
555549
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
@@ -635,7 +629,7 @@ func TestSSH(t *testing.T) {
635629
}))
636630
defer httpServer.Close()
637631

638-
client, workspace, agentToken := setupWorkspaceForAgent(t, nil)
632+
client, workspace, agentToken := setupWorkspaceForAgent(t)
639633
_ = agenttest.New(t, client.URL, agentToken)
640634
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
641635

@@ -686,7 +680,7 @@ func TestSSH(t *testing.T) {
686680

687681
t.Parallel()
688682

689-
client, workspace, agentToken := setupWorkspaceForAgent(t, nil)
683+
client, workspace, agentToken := setupWorkspaceForAgent(t)
690684

691685
_ = agenttest.New(t, client.URL, agentToken)
692686
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
@@ -733,7 +727,7 @@ func TestSSH(t *testing.T) {
733727

734728
logDir := t.TempDir()
735729

736-
client, workspace, agentToken := setupWorkspaceForAgent(t, nil)
730+
client, workspace, agentToken := setupWorkspaceForAgent(t)
737731
inv, root := clitest.New(t, "ssh", "-l", logDir, workspace.Name)
738732
clitest.SetupConfig(t, client, root)
739733
pty := ptytest.New(t).Attach(inv)
@@ -908,7 +902,7 @@ Expire-Date: 0
908902
workspaceAgentSocketPath := strings.TrimSpace(stdout.String())
909903
require.NotEqual(t, extraSocketPath, workspaceAgentSocketPath, "socket path should be different")
910904

911-
client, workspace, agentToken := setupWorkspaceForAgent(t, nil)
905+
client, workspace, agentToken := setupWorkspaceForAgent(t)
912906

913907
_ = agenttest.New(t, client.URL, agentToken, func(o *agent.Options) {
914908
o.EnvironmentVariables = map[string]string{

cli/templateedit.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,16 +120,24 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
120120
autostopRequirementDaysOfWeek = []string{}
121121
}
122122

123-
// Only pass explicitly set deprecated values since the empty string
124-
// removes the deprecated message. By default if we pass a nil,
125-
// there is no change to this field.
123+
// Default values
124+
if !userSetOption(inv, "description") {
125+
description = template.Description
126+
}
127+
128+
if !userSetOption(inv, "icon") {
129+
icon = template.Icon
130+
}
131+
132+
if !userSetOption(inv, "display-name") {
133+
displayName = template.DisplayName
134+
}
135+
126136
var deprecated *string
127-
opt := inv.Command.Options.ByName(deprecatedFlagName)
128-
if !(opt.ValueSource == "" || opt.ValueSource == clibase.ValueSourceDefault) {
137+
if !userSetOption(inv, "deprecated") {
129138
deprecated = &deprecationMessage
130139
}
131140

132-
// NOTE: coderd will ignore empty fields.
133141
req := codersdk.UpdateTemplateMeta{
134142
Name: name,
135143
DisplayName: displayName,

cli/templateedit_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,9 @@ func TestTemplateEdit(t *testing.T) {
228228
"templates",
229229
"edit",
230230
template.Name,
231+
"--description", "",
232+
"--display-name", "",
233+
"--icon", "",
231234
}
232235
inv, root := clitest.New(t, cmdArgs...)
233236
clitest.SetupConfig(t, templateAdmin, root)
@@ -1047,4 +1050,41 @@ func TestTemplateEdit(t *testing.T) {
10471050
require.Error(t, err)
10481051
require.ErrorContains(t, err, "appears to be an AGPL deployment")
10491052
})
1053+
t.Run("DefaultValues", func(t *testing.T) {
1054+
t.Parallel()
1055+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
1056+
owner := coderdtest.CreateFirstUser(t, client)
1057+
1058+
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil)
1059+
_ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
1060+
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID, func(ctr *codersdk.CreateTemplateRequest) {
1061+
ctr.Name = "random"
1062+
ctr.Icon = "/icon/foobar.png"
1063+
ctr.DisplayName = "Foobar"
1064+
ctr.Description = "Some description"
1065+
})
1066+
1067+
// We need to change some field to get a db write.
1068+
cmdArgs := []string{
1069+
"templates",
1070+
"edit",
1071+
template.Name,
1072+
"--name", "something-new",
1073+
}
1074+
inv, root := clitest.New(t, cmdArgs...)
1075+
//nolint
1076+
clitest.SetupConfig(t, client, root)
1077+
1078+
ctx := testutil.Context(t, testutil.WaitLong)
1079+
err := inv.WithContext(ctx).Run()
1080+
require.NoError(t, err)
1081+
1082+
updated, err := client.Template(context.Background(), template.ID)
1083+
require.NoError(t, err)
1084+
assert.Equal(t, "something-new", updated.Name)
1085+
assert.Equal(t, template.Icon, updated.Icon)
1086+
assert.Equal(t, template.DisplayName, updated.DisplayName)
1087+
assert.Equal(t, template.Description, updated.Description)
1088+
assert.Equal(t, template.DeprecationMessage, updated.DeprecationMessage)
1089+
})
10501090
}

cli/util.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"golang.org/x/xerrors"
1010

11+
"github.com/coder/coder/v2/cli/clibase"
1112
"github.com/coder/coder/v2/coderd/schedule/cron"
1213
"github.com/coder/coder/v2/coderd/util/tz"
1314
)
@@ -18,6 +19,19 @@ var (
1819
errUnsupportedTimezone = xerrors.New("The location you provided looks like a timezone. Check https://ipinfo.io for your location.")
1920
)
2021

22+
// userSetOption returns true if the option was set by the user.
23+
// This is helpful if the zero value of a flag is meaningful, and you need
24+
// to distinguish between the user setting the flag to the zero value and
25+
// the user not setting the flag at all.
26+
func userSetOption(inv *clibase.Invocation, flagName string) bool {
27+
for _, opt := range inv.Command.Options {
28+
if opt.Name == flagName {
29+
return !(opt.ValueSource == clibase.ValueSourceNone || opt.ValueSource == clibase.ValueSourceDefault)
30+
}
31+
}
32+
return false
33+
}
34+
2135
// durationDisplay formats a duration for easier display:
2236
// - Durations of 24 hours or greater are displays as Xd
2337
// - Durations less than 1 minute are displayed as <1m

0 commit comments

Comments
 (0)