Skip to content

Commit 0317665

Browse files
rowansmithauclaude
andcommitted
test: Add tests for workspace builds and logs CLI commands
Added tests for CLI commands: - 'builds list' command for listing workspace builds - 'logs' command for retrieving workspace build logs Added golden files for help output: - coder_builds_--help.golden - coder_builds_list_--help.golden - coder_logs_--help.golden 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 3d3dc08 commit 0317665

File tree

5 files changed

+229
-0
lines changed

5 files changed

+229
-0
lines changed

cli/builds_test.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package cli_test
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"encoding/json"
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
11+
12+
"github.com/coder/coder/v2/cli/clitest"
13+
"github.com/coder/coder/v2/coderd/coderdtest"
14+
"github.com/coder/coder/v2/coderd/database"
15+
"github.com/coder/coder/v2/coderd/database/dbfake"
16+
"github.com/coder/coder/v2/codersdk"
17+
"github.com/coder/coder/v2/pty/ptytest"
18+
"github.com/coder/coder/v2/testutil"
19+
)
20+
21+
func TestBuildsList(t *testing.T) {
22+
t.Parallel()
23+
24+
t.Run("Table", func(t *testing.T) {
25+
t.Parallel()
26+
client, db := coderdtest.NewWithDatabase(t, nil)
27+
owner := coderdtest.CreateFirstUser(t, client)
28+
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
29+
30+
// Create a workspace with a build
31+
r := dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
32+
OrganizationID: owner.OrganizationID,
33+
OwnerID: memberUser.ID,
34+
}).WithAgent().Do()
35+
36+
inv, root := clitest.New(t, "builds", "list", r.Workspace.Name)
37+
clitest.SetupConfig(t, member, root)
38+
pty := ptytest.New(t).Attach(inv)
39+
40+
ctx, cancelFunc := context.WithTimeout(context.Background(), testutil.WaitLong)
41+
defer cancelFunc()
42+
43+
done := make(chan any)
44+
go func() {
45+
errC := inv.WithContext(ctx).Run()
46+
assert.NoError(t, errC)
47+
close(done)
48+
}()
49+
50+
pty.ExpectMatch("1") // Build number
51+
pty.ExpectMatch(r.Build.ID.String()) // Build ID
52+
cancelFunc()
53+
<-done
54+
})
55+
56+
t.Run("JSON", func(t *testing.T) {
57+
t.Parallel()
58+
client, db := coderdtest.NewWithDatabase(t, nil)
59+
owner := coderdtest.CreateFirstUser(t, client)
60+
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
61+
62+
// Create a workspace with a build
63+
r := dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
64+
OrganizationID: owner.OrganizationID,
65+
OwnerID: memberUser.ID,
66+
}).WithAgent().Do()
67+
68+
inv, root := clitest.New(t, "builds", "list", r.Workspace.Name, "--output=json")
69+
clitest.SetupConfig(t, member, root)
70+
71+
ctx, cancelFunc := context.WithTimeout(context.Background(), testutil.WaitLong)
72+
defer cancelFunc()
73+
74+
out := bytes.NewBuffer(nil)
75+
inv.Stdout = out
76+
err := inv.WithContext(ctx).Run()
77+
require.NoError(t, err)
78+
79+
var builds []codersdk.WorkspaceBuild
80+
require.NoError(t, json.Unmarshal(out.Bytes(), &builds))
81+
require.Len(t, builds, 1)
82+
assert.Equal(t, r.Build.ID, builds[0].ID)
83+
})
84+
85+
t.Run("WorkspaceNotFound", func(t *testing.T) {
86+
t.Parallel()
87+
client := coderdtest.New(t, nil)
88+
owner := coderdtest.CreateFirstUser(t, client)
89+
member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
90+
91+
inv, root := clitest.New(t, "builds", "list", "non-existent-workspace")
92+
clitest.SetupConfig(t, member, root)
93+
94+
ctx, cancelFunc := context.WithTimeout(context.Background(), testutil.WaitLong)
95+
defer cancelFunc()
96+
97+
err := inv.WithContext(ctx).Run()
98+
require.Error(t, err)
99+
assert.Contains(t, err.Error(), "get workspace")
100+
})
101+
}

cli/logs_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package cli_test
2+
3+
import (
4+
"context"
5+
"strings"
6+
"testing"
7+
8+
"github.com/google/uuid"
9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
11+
12+
"github.com/coder/coder/v2/cli/clitest"
13+
"github.com/coder/coder/v2/coderd/coderdtest"
14+
"github.com/coder/coder/v2/testutil"
15+
)
16+
17+
func TestLogs(t *testing.T) {
18+
t.Parallel()
19+
20+
t.Run("LogsInvalidBuildID", func(t *testing.T) {
21+
t.Parallel()
22+
23+
client := coderdtest.New(t, nil)
24+
_ = coderdtest.CreateFirstUser(t, client)
25+
26+
inv, root := clitest.New(t, "logs", "invalid-uuid")
27+
clitest.SetupConfig(t, client, root)
28+
29+
ctx, cancelFunc := context.WithTimeout(context.Background(), testutil.WaitMedium)
30+
defer cancelFunc()
31+
32+
err := inv.WithContext(ctx).Run()
33+
require.Error(t, err)
34+
assert.True(t, strings.Contains(err.Error(), "invalid build ID"))
35+
})
36+
37+
t.Run("LogsNonexistentBuild", func(t *testing.T) {
38+
t.Parallel()
39+
40+
client := coderdtest.New(t, nil)
41+
_ = coderdtest.CreateFirstUser(t, client)
42+
43+
inv, root := clitest.New(t, "logs", uuid.New().String())
44+
clitest.SetupConfig(t, client, root)
45+
46+
ctx, cancelFunc := context.WithTimeout(context.Background(), testutil.WaitMedium)
47+
defer cancelFunc()
48+
49+
err := inv.WithContext(ctx).Run()
50+
require.Error(t, err)
51+
assert.True(t, strings.Contains(err.Error(), "get build logs"))
52+
})
53+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Manage workspace builds
2+
3+
Usage:
4+
coder builds [flags] <subcommand>
5+
6+
Available Commands:
7+
list List builds for a workspace
8+
9+
Flags:
10+
--debug-options Print all options, how they're set, then exit.
11+
-h, --help Help for "builds"
12+
13+
Global Flags:
14+
--header=key=value Additional HTTP headers added to all requests. Provide as key=value. Can be specified multiple times.
15+
--header-command=string An external command that outputs additional HTTP headers added to all requests. The command must output each header as key=value on its own line.
16+
-v, --verbose Enable verbose output.
17+
--no-version-warning Suppress warning when client and server versions do not match.
18+
--no-feature-warning Suppress warnings about unlicensed features.
19+
--url=string URL to a deployment.
20+
--token=string Specify an authentication token. For security reasons setting CODER_SESSION_TOKEN is preferred.
21+
--config-dir=/home/coder/.config/coderv2 Path to the global coder config directory.
22+
--disable-direct-connections Disable direct (P2P) connections to workspaces.
23+
--disable-network-telemetry Disable network telemetry. Network telemetry is collected when connecting to workspaces using the CLI, and is forwarded to the server. If telemetry is also enabled on the server, it may be sent to Coder. Network telemetry is used to measure network quality and detect regressions.
24+
--force-tty Force the use of a TTY.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
List builds for a workspace
2+
3+
Usage:
4+
coder builds list [flags] <workspace>
5+
6+
Aliases:
7+
list, ls
8+
9+
Flags:
10+
--column=string Specify a column to sort by.
11+
-h, --help Help for "list"
12+
--output=table Output format. Available formats are: table, json.
13+
--search=string Filter data by search query.
14+
--sort-by=default_sort Sort builds by the specified column (default "build").
15+
--sort-desc Sort by descending order.
16+
17+
Global Flags:
18+
--debug-options Print all options, how they're set, then exit.
19+
--header=key=value Additional HTTP headers added to all requests. Provide as key=value. Can be specified multiple times.
20+
--header-command=string An external command that outputs additional HTTP headers added to all requests. The command must output each header as key=value on its own line.
21+
-v, --verbose Enable verbose output.
22+
--no-version-warning Suppress warning when client and server versions do not match.
23+
--no-feature-warning Suppress warnings about unlicensed features.
24+
--url=string URL to a deployment.
25+
--token=string Specify an authentication token. For security reasons setting CODER_SESSION_TOKEN is preferred.
26+
--config-dir=/home/coder/.config/coderv2 Path to the global coder config directory.
27+
--disable-direct-connections Disable direct (P2P) connections to workspaces.
28+
--disable-network-telemetry Disable network telemetry. Network telemetry is collected when connecting to workspaces using the CLI, and is forwarded to the server. If telemetry is also enabled on the server, it may be sent to Coder. Network telemetry is used to measure network quality and detect regressions.
29+
--force-tty Force the use of a TTY.

cli/testdata/coder_logs_--help.golden

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Show logs for a workspace build
2+
3+
Usage:
4+
coder logs [flags] <build-id>
5+
6+
Flags:
7+
-f, --follow Follow log output (stream real-time logs).
8+
-h, --help Help for "logs"
9+
10+
Global Flags:
11+
--debug-options Print all options, how they're set, then exit.
12+
--header=key=value Additional HTTP headers added to all requests. Provide as key=value. Can be specified multiple times.
13+
--header-command=string An external command that outputs additional HTTP headers added to all requests. The command must output each header as key=value on its own line.
14+
-v, --verbose Enable verbose output.
15+
--no-version-warning Suppress warning when client and server versions do not match.
16+
--no-feature-warning Suppress warnings about unlicensed features.
17+
--url=string URL to a deployment.
18+
--token=string Specify an authentication token. For security reasons setting CODER_SESSION_TOKEN is preferred.
19+
--config-dir=/home/coder/.config/coderv2 Path to the global coder config directory.
20+
--disable-direct-connections Disable direct (P2P) connections to workspaces.
21+
--disable-network-telemetry Disable network telemetry. Network telemetry is collected when connecting to workspaces using the CLI, and is forwarded to the server. If telemetry is also enabled on the server, it may be sent to Coder. Network telemetry is used to measure network quality and detect regressions.
22+
--force-tty Force the use of a TTY.

0 commit comments

Comments
 (0)