Compare commits
1 Commits
wsproxy
...
spike/cli-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fb08b94694 |
@@ -78,6 +78,14 @@ func NewWithCommand(
|
||||
return i, configDir
|
||||
}
|
||||
|
||||
func NewWithSDKOverride(t testing.TB, override any, args ...string) (*serpent.Invocation, config.Root) {
|
||||
var root cli.RootCmd
|
||||
cmd, err := root.Command(root.AGPL())
|
||||
root.TestOverrideSDKClient = override
|
||||
require.NoError(t, err)
|
||||
return NewWithCommand(t, cmd, args...)
|
||||
}
|
||||
|
||||
// SetupConfig applies the URL and SessionToken of the client to the config.
|
||||
func SetupConfig(t *testing.T, client *codersdk.Client, root config.Root) {
|
||||
err := root.Session().Write(client.SessionToken())
|
||||
|
||||
23
cli/root.go
23
cli/root.go
@@ -538,6 +538,23 @@ type RootCmd struct {
|
||||
noVersionCheck bool
|
||||
noFeatureWarning bool
|
||||
useKeyring bool
|
||||
|
||||
// TestOverrideSDKClient is returned by GetClient if set. This is used in unit testing to mock or fake the
|
||||
// *codersdk.Client
|
||||
TestOverrideSDKClient any
|
||||
}
|
||||
|
||||
// GetClient gets the SDK client of the given type. In tests, this can be used with TestOverrideSDKClient to mock or
|
||||
// fake the client. In production, this returns a *codersdk.Client.
|
||||
func GetClient[T any](r *RootCmd, inv *serpent.Invocation) (T, error) {
|
||||
if r.TestOverrideSDKClient != nil {
|
||||
// nolint: forcetypeassert
|
||||
return r.TestOverrideSDKClient.(T), nil
|
||||
}
|
||||
var a any
|
||||
a, err := r.InitClient(inv)
|
||||
// nolint: forcetypeassert
|
||||
return a.(T), err
|
||||
}
|
||||
|
||||
// InitClient creates and configures a new client with authentication, telemetry,
|
||||
@@ -893,10 +910,14 @@ func splitNamedWorkspace(identifier string) (owner string, workspaceName string,
|
||||
return owner, workspaceName, nil
|
||||
}
|
||||
|
||||
type workspaceGetterByName interface {
|
||||
WorkspaceByOwnerAndName(context.Context, string, string, codersdk.WorkspaceOptions) (codersdk.Workspace, error)
|
||||
}
|
||||
|
||||
// namedWorkspace fetches and returns a workspace by an identifier, which may be either
|
||||
// a bare name (for a workspace owned by the current user) or a "user/workspace" combination,
|
||||
// where user is either a username or UUID.
|
||||
func namedWorkspace(ctx context.Context, client *codersdk.Client, identifier string) (codersdk.Workspace, error) {
|
||||
func namedWorkspace(ctx context.Context, client workspaceGetterByName, identifier string) (codersdk.Workspace, error) {
|
||||
owner, name, err := splitNamedWorkspace(identifier)
|
||||
if err != nil {
|
||||
return codersdk.Workspace{}, err
|
||||
|
||||
16
cli/show.go
16
cli/show.go
@@ -1,6 +1,7 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
@@ -14,6 +15,17 @@ import (
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
// showSDKClient is the subset of codersdk.Client that the show command uses.
|
||||
type showSDKClient interface {
|
||||
workspaceGetterByName
|
||||
BuildInfo(context.Context) (codersdk.BuildInfoResponse, error)
|
||||
WorkspaceAgentListeningPorts(context.Context, uuid.UUID) (codersdk.WorkspaceAgentListeningPortsResponse, error)
|
||||
WorkspaceAgentListContainers(context.Context, uuid.UUID, map[string]string) (codersdk.WorkspaceAgentListContainersResponse, error)
|
||||
}
|
||||
|
||||
// ensure methods track the SDK
|
||||
var _ showSDKClient = &codersdk.Client{}
|
||||
|
||||
func (r *RootCmd) show() *serpent.Command {
|
||||
var details bool
|
||||
return &serpent.Command{
|
||||
@@ -31,7 +43,7 @@ func (r *RootCmd) show() *serpent.Command {
|
||||
serpent.RequireNArgs(1),
|
||||
),
|
||||
Handler: func(inv *serpent.Invocation) error {
|
||||
client, err := r.InitClient(inv)
|
||||
client, err := GetClient[showSDKClient](r, inv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -62,7 +74,7 @@ func (r *RootCmd) show() *serpent.Command {
|
||||
}
|
||||
}
|
||||
|
||||
func fetchRuntimeResources(inv *serpent.Invocation, client *codersdk.Client, resources ...codersdk.WorkspaceResource) (map[uuid.UUID]codersdk.WorkspaceAgentListeningPortsResponse, map[uuid.UUID]codersdk.WorkspaceAgentListContainersResponse) {
|
||||
func fetchRuntimeResources(inv *serpent.Invocation, client showSDKClient, resources ...codersdk.WorkspaceResource) (map[uuid.UUID]codersdk.WorkspaceAgentListeningPortsResponse, map[uuid.UUID]codersdk.WorkspaceAgentListContainersResponse) {
|
||||
ports := make(map[uuid.UUID]codersdk.WorkspaceAgentListeningPortsResponse)
|
||||
devcontainers := make(map[uuid.UUID]codersdk.WorkspaceAgentListContainersResponse)
|
||||
var wg sync.WaitGroup
|
||||
|
||||
@@ -2,6 +2,7 @@ package cli_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -12,7 +13,6 @@ import (
|
||||
"github.com/coder/coder/v2/agent/agentcontainers"
|
||||
"github.com/coder/coder/v2/cli/clitest"
|
||||
"github.com/coder/coder/v2/cli/cliui"
|
||||
"github.com/coder/coder/v2/coderd/coderdtest"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/coder/v2/pty/ptytest"
|
||||
)
|
||||
@@ -21,21 +21,36 @@ func TestShow(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("Exists", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
owner := coderdtest.CreateFirstUser(t, client)
|
||||
member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, completeWithAgent())
|
||||
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, member, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
|
||||
|
||||
args := []string{
|
||||
"show",
|
||||
workspace.Name,
|
||||
agentID := uuid.UUID{1}
|
||||
workspaceID := uuid.UUID{2}
|
||||
workspace := codersdk.Workspace{
|
||||
Name: "test",
|
||||
ID: workspaceID,
|
||||
LatestBuild: codersdk.WorkspaceBuild{
|
||||
Status: codersdk.WorkspaceStatusRunning,
|
||||
Resources: []codersdk.WorkspaceResource{
|
||||
{
|
||||
Name: "main",
|
||||
Type: "compute",
|
||||
Agents: []codersdk.WorkspaceAgent{
|
||||
{Name: "smith", ID: agentID, Architecture: "i386", OperatingSystem: "linux"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
inv, root := clitest.New(t, args...)
|
||||
clitest.SetupConfig(t, member, root)
|
||||
fSDK := &fakeShowSDK{
|
||||
t: t,
|
||||
expectedOwner: codersdk.Me,
|
||||
returnedWorkspace: workspace,
|
||||
expectedAgentID: agentID,
|
||||
expectedContainerLabels: map[string]string{
|
||||
agentcontainers.DevcontainerConfigFileLabel: "",
|
||||
agentcontainers.DevcontainerLocalFolderLabel: "",
|
||||
},
|
||||
}
|
||||
|
||||
inv, _ := clitest.NewWithSDKOverride(t, fSDK, "show", workspace.Name)
|
||||
doneChan := make(chan struct{})
|
||||
pty := ptytest.New(t).Attach(inv)
|
||||
go func() {
|
||||
@@ -61,6 +76,45 @@ func TestShow(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
type fakeShowSDK struct {
|
||||
t *testing.T
|
||||
expectedOwner string
|
||||
returnedWorkspace codersdk.Workspace
|
||||
expectedAgentID uuid.UUID
|
||||
expectedContainerLabels map[string]string
|
||||
}
|
||||
|
||||
func (f *fakeShowSDK) WorkspaceByOwnerAndName(_ context.Context, owner string, name string, _ codersdk.WorkspaceOptions) (codersdk.Workspace, error) {
|
||||
assert.Equal(f.t, f.expectedOwner, owner)
|
||||
assert.Equal(f.t, f.returnedWorkspace.Name, name)
|
||||
return f.returnedWorkspace, nil
|
||||
}
|
||||
|
||||
func (*fakeShowSDK) BuildInfo(_ context.Context) (codersdk.BuildInfoResponse, error) {
|
||||
return codersdk.BuildInfoResponse{
|
||||
Version: "test-version",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (f *fakeShowSDK) WorkspaceAgentListeningPorts(_ context.Context, u uuid.UUID) (codersdk.WorkspaceAgentListeningPortsResponse, error) {
|
||||
assert.Equal(f.t, f.expectedAgentID, u)
|
||||
return codersdk.WorkspaceAgentListeningPortsResponse{
|
||||
Ports: []codersdk.WorkspaceAgentListeningPort{
|
||||
{
|
||||
ProcessName: "postgres",
|
||||
Port: 5432,
|
||||
Network: "tcp",
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (f *fakeShowSDK) WorkspaceAgentListContainers(_ context.Context, u uuid.UUID, m map[string]string) (codersdk.WorkspaceAgentListContainersResponse, error) {
|
||||
assert.Equal(f.t, f.expectedAgentID, u)
|
||||
assert.Equal(f.t, f.expectedContainerLabels, m)
|
||||
return codersdk.WorkspaceAgentListContainersResponse{}, nil
|
||||
}
|
||||
|
||||
func TestShowDevcontainers_Golden(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user