mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
test: batch 02 of refactoring CLI tests not to use PTY (#25931)
Part of [coder/internal#1400](https://github.com/coder/internal/issues/1400) Batch of refactored CLI tests to avoid creating PTYs.
This commit is contained in:
+109
-95
@@ -55,8 +55,8 @@ import (
|
||||
"github.com/coder/coder/v2/provisioner/echo"
|
||||
"github.com/coder/coder/v2/provisionersdk/proto"
|
||||
"github.com/coder/coder/v2/pty"
|
||||
"github.com/coder/coder/v2/pty/ptytest"
|
||||
"github.com/coder/coder/v2/testutil"
|
||||
"github.com/coder/coder/v2/testutil/expecter"
|
||||
)
|
||||
|
||||
func setupWorkspaceForAgent(t *testing.T, mutations ...func([]*proto.Agent) []*proto.Agent) (*codersdk.Client, database.WorkspaceTable, string) {
|
||||
@@ -82,10 +82,12 @@ func TestSSH(t *testing.T) {
|
||||
t.Run("ImmediateExit", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := testutil.Logger(t)
|
||||
client, workspace, agentToken := setupWorkspaceForAgent(t)
|
||||
inv, root := clitest.New(t, "ssh", workspace.Name)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t).Attach(inv)
|
||||
stdout := expecter.NewAttachedToInvocation(t, inv)
|
||||
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
@@ -94,13 +96,13 @@ func TestSSH(t *testing.T) {
|
||||
err := inv.WithContext(ctx).Run()
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
pty.ExpectMatch("Waiting")
|
||||
stdout.ExpectMatchContext(ctx, "Waiting")
|
||||
|
||||
_ = agenttest.New(t, client.URL, agentToken)
|
||||
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
|
||||
|
||||
// Shells on Mac, Windows, and Linux all exit shells with the "exit" command.
|
||||
pty.WriteLine("exit")
|
||||
stdin.WriteLine("exit")
|
||||
<-cmdDone
|
||||
})
|
||||
t.Run("WorkspaceNameInput", func(t *testing.T) {
|
||||
@@ -121,6 +123,7 @@ func TestSSH(t *testing.T) {
|
||||
for _, tc := range cases {
|
||||
t.Run(tc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
logger := testutil.Logger(t)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
@@ -128,19 +131,20 @@ func TestSSH(t *testing.T) {
|
||||
|
||||
inv, root := clitest.New(t, "ssh", tc)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t).Attach(inv)
|
||||
stdout := expecter.NewAttachedToInvocation(t, inv)
|
||||
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
|
||||
|
||||
cmdDone := tGo(t, func() {
|
||||
err := inv.WithContext(ctx).Run()
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
pty.ExpectMatch("Waiting")
|
||||
stdout.ExpectMatchContext(ctx, "Waiting")
|
||||
|
||||
_ = agenttest.New(t, client.URL, agentToken)
|
||||
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
|
||||
|
||||
// Shells on Mac, Windows, and Linux all exit shells with the "exit" command.
|
||||
pty.WriteLine("exit")
|
||||
stdin.WriteLine("exit")
|
||||
<-cmdDone
|
||||
})
|
||||
}
|
||||
@@ -148,6 +152,7 @@ func TestSSH(t *testing.T) {
|
||||
t.Run("StartStoppedWorkspace", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := testutil.Logger(t)
|
||||
authToken := uuid.NewString()
|
||||
ownerClient := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
owner := coderdtest.CreateFirstUser(t, ownerClient)
|
||||
@@ -168,7 +173,7 @@ func TestSSH(t *testing.T) {
|
||||
// SSH to the workspace which should autostart it
|
||||
inv, root := clitest.New(t, "ssh", workspace.Name)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t).Attach(inv)
|
||||
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitSuperLong)
|
||||
defer cancel()
|
||||
@@ -192,7 +197,7 @@ func TestSSH(t *testing.T) {
|
||||
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
|
||||
|
||||
// Shells on Mac, Windows, and Linux all exit shells with the "exit" command.
|
||||
pty.WriteLine("exit")
|
||||
stdin.WriteLine("exit")
|
||||
<-cmdDone
|
||||
})
|
||||
t.Run("StartStoppedWorkspaceConflict", func(t *testing.T) {
|
||||
@@ -253,21 +258,20 @@ func TestSSH(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium)
|
||||
defer cancel()
|
||||
|
||||
var ptys []*ptytest.PTY
|
||||
var stdouts []*expecter.Expecter
|
||||
for i := 0; i < 3; i++ {
|
||||
// SSH to the workspace which should autostart it
|
||||
inv, root := clitest.New(t, "ssh", workspace.Name)
|
||||
|
||||
pty := ptytest.New(t).Attach(inv)
|
||||
ptys = append(ptys, pty)
|
||||
stdouts = append(stdouts, expecter.NewAttachedToInvocation(t, inv))
|
||||
clitest.SetupConfig(t, client, root)
|
||||
testutil.Go(t, func() {
|
||||
_ = inv.WithContext(ctx).Run()
|
||||
})
|
||||
}
|
||||
|
||||
for _, pty := range ptys {
|
||||
pty.ExpectMatchContext(ctx, "Workspace was stopped, starting workspace to allow connecting to")
|
||||
for _, stdout := range stdouts {
|
||||
stdout.ExpectMatchContext(ctx, "Workspace was stopped, starting workspace to allow connecting to")
|
||||
}
|
||||
|
||||
// Allow one build to complete.
|
||||
@@ -275,15 +279,15 @@ func TestSSH(t *testing.T) {
|
||||
testutil.TryReceive(ctx, t, buildDone)
|
||||
|
||||
// Allow the remaining builds to continue.
|
||||
for i := 0; i < len(ptys)-1; i++ {
|
||||
for i := 0; i < len(stdouts)-1; i++ {
|
||||
testutil.RequireSend(ctx, t, buildPause, false)
|
||||
}
|
||||
|
||||
var foundConflict int
|
||||
for _, pty := range ptys {
|
||||
for _, stdout := range stdouts {
|
||||
// Either allow the command to start the workspace or fail
|
||||
// due to conflict (race), in which case it retries.
|
||||
match := pty.ExpectRegexMatchContext(ctx, "Waiting for the workspace agent to connect")
|
||||
match := stdout.ExpectRegexMatchContext(ctx, "Waiting for the workspace agent to connect")
|
||||
if strings.Contains(match, "Unable to start the workspace due to conflict, the workspace may be starting, retrying without autostart...") {
|
||||
foundConflict++
|
||||
}
|
||||
@@ -293,6 +297,7 @@ func TestSSH(t *testing.T) {
|
||||
t.Run("RequireActiveVersion", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := testutil.Logger(t)
|
||||
authToken := uuid.NewString()
|
||||
ownerClient := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
owner := coderdtest.CreateFirstUser(t, ownerClient)
|
||||
@@ -334,7 +339,7 @@ func TestSSH(t *testing.T) {
|
||||
// SSH to the workspace which should auto-update and autostart it
|
||||
inv, root := clitest.New(t, "ssh", workspace.Name)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t).Attach(inv)
|
||||
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
@@ -350,7 +355,7 @@ func TestSSH(t *testing.T) {
|
||||
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
|
||||
|
||||
// Shells on Mac, Windows, and Linux all exit shells with the "exit" command.
|
||||
pty.WriteLine("exit")
|
||||
stdin.WriteLine("exit")
|
||||
<-cmdDone
|
||||
|
||||
// Double-check if workspace's template version is up-to-date
|
||||
@@ -374,10 +379,7 @@ func TestSSH(t *testing.T) {
|
||||
})
|
||||
inv, root := clitest.New(t, "ssh", workspace.Name)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t)
|
||||
inv.Stdin = pty.Input()
|
||||
inv.Stderr = pty.Output()
|
||||
inv.Stdout = pty.Output()
|
||||
stdout := expecter.NewAttachedToInvocation(t, inv)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
@@ -386,7 +388,7 @@ func TestSSH(t *testing.T) {
|
||||
err := inv.WithContext(ctx).Run()
|
||||
assert.ErrorIs(t, err, cliui.ErrCanceled)
|
||||
})
|
||||
pty.ExpectMatch(wantURL)
|
||||
stdout.ExpectMatchContext(ctx, wantURL)
|
||||
cancel()
|
||||
<-cmdDone
|
||||
})
|
||||
@@ -397,6 +399,7 @@ func TestSSH(t *testing.T) {
|
||||
t.Skip("Windows doesn't seem to clean up the process, maybe #7100 will fix it")
|
||||
}
|
||||
|
||||
logger := testutil.Logger(t)
|
||||
store, ps := dbtestutil.NewDB(t)
|
||||
client := coderdtest.New(t, &coderdtest.Options{Pubsub: ps, Database: store})
|
||||
client.SetLogger(testutil.Logger(t).Named("client"))
|
||||
@@ -408,7 +411,8 @@ func TestSSH(t *testing.T) {
|
||||
}).WithAgent().Do()
|
||||
inv, root := clitest.New(t, "ssh", r.Workspace.Name)
|
||||
clitest.SetupConfig(t, userClient, root)
|
||||
pty := ptytest.New(t).Attach(inv)
|
||||
stdout := expecter.NewAttachedToInvocation(t, inv)
|
||||
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
@@ -417,14 +421,14 @@ func TestSSH(t *testing.T) {
|
||||
err := inv.WithContext(ctx).Run()
|
||||
assert.Error(t, err)
|
||||
})
|
||||
pty.ExpectMatch("Waiting")
|
||||
stdout.ExpectMatchContext(ctx, "Waiting")
|
||||
|
||||
_ = agenttest.New(t, client.URL, r.AgentToken)
|
||||
coderdtest.AwaitWorkspaceAgents(t, client, r.Workspace.ID)
|
||||
|
||||
// Ensure the agent is connected.
|
||||
pty.WriteLine("echo hell'o'")
|
||||
pty.ExpectMatchContext(ctx, "hello")
|
||||
stdin.WriteLine("echo hell'o'")
|
||||
stdout.ExpectMatchContext(ctx, "hello")
|
||||
|
||||
_ = dbfake.WorkspaceBuild(t, store, r.Workspace).
|
||||
Seed(database.WorkspaceBuild{
|
||||
@@ -1121,6 +1125,7 @@ func TestSSH(t *testing.T) {
|
||||
|
||||
t.Parallel()
|
||||
|
||||
logger := testutil.Logger(t)
|
||||
client, workspace, agentToken := setupWorkspaceForAgent(t)
|
||||
|
||||
_ = agenttest.New(t, client.URL, agentToken)
|
||||
@@ -1168,8 +1173,8 @@ func TestSSH(t *testing.T) {
|
||||
"--identity-agent", agentSock, // Overrides $SSH_AUTH_SOCK.
|
||||
)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t).Attach(inv)
|
||||
inv.Stderr = pty.Output()
|
||||
stdout := expecter.NewAttachedToInvocation(t, inv)
|
||||
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
|
||||
cmdDone := tGo(t, func() {
|
||||
err := inv.WithContext(ctx).Run()
|
||||
assert.NoError(t, err, "ssh command failed")
|
||||
@@ -1177,21 +1182,21 @@ func TestSSH(t *testing.T) {
|
||||
|
||||
// Wait for the prompt or any output really to indicate the command has
|
||||
// started and accepting input on stdin.
|
||||
_ = pty.Peek(ctx, 1)
|
||||
_ = stdout.Peek(ctx, 1)
|
||||
|
||||
// Ensure that SSH_AUTH_SOCK is set.
|
||||
// Linux: /tmp/auth-agent3167016167/listener.sock
|
||||
// macOS: /var/folders/ng/m1q0wft14hj0t3rtjxrdnzsr0000gn/T/auth-agent3245553419/listener.sock
|
||||
pty.WriteLine(`env | grep SSH_AUTH_SOCK=`)
|
||||
pty.ExpectMatch("SSH_AUTH_SOCK=")
|
||||
stdin.WriteLine(`env | grep SSH_AUTH_SOCK=`)
|
||||
stdout.ExpectMatchContext(ctx, "SSH_AUTH_SOCK=")
|
||||
// Ensure that ssh-add lists our key.
|
||||
pty.WriteLine("ssh-add -L")
|
||||
stdin.WriteLine("ssh-add -L")
|
||||
keys, err := kr.List()
|
||||
require.NoError(t, err, "list keys failed")
|
||||
pty.ExpectMatch(keys[0].String())
|
||||
stdout.ExpectMatchContext(ctx, keys[0].String())
|
||||
|
||||
// And we're done.
|
||||
pty.WriteLine("exit")
|
||||
stdin.WriteLine("exit")
|
||||
<-cmdDone
|
||||
})
|
||||
|
||||
@@ -1259,6 +1264,7 @@ func TestSSH(t *testing.T) {
|
||||
|
||||
t.Parallel()
|
||||
|
||||
logger := testutil.Logger(t)
|
||||
client, workspace, agentToken := setupWorkspaceForAgent(t)
|
||||
_ = agenttest.New(t, client.URL, agentToken)
|
||||
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
|
||||
@@ -1271,8 +1277,8 @@ func TestSSH(t *testing.T) {
|
||||
)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
|
||||
pty := ptytest.New(t).Attach(inv)
|
||||
inv.Stderr = pty.Output()
|
||||
stdout := expecter.NewAttachedToInvocation(t, inv)
|
||||
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
|
||||
|
||||
// Wait super long so this doesn't flake on -race test.
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitSuperLong)
|
||||
@@ -1284,15 +1290,15 @@ func TestSSH(t *testing.T) {
|
||||
// Since something was output, it should be safe to write input.
|
||||
// This could show a prompt or "running startup scripts", so it's
|
||||
// not indicative of the SSH connection being ready.
|
||||
_ = pty.Peek(ctx, 1)
|
||||
_ = stdout.Peek(ctx, 1)
|
||||
|
||||
// Ensure the SSH connection is ready by testing the shell
|
||||
// input/output.
|
||||
pty.WriteLine("echo $foo $baz")
|
||||
pty.ExpectMatchContext(ctx, "bar qux")
|
||||
stdin.WriteLine("echo $foo $baz")
|
||||
stdout.ExpectMatchContext(ctx, "bar qux")
|
||||
|
||||
// And we're done.
|
||||
pty.WriteLine("exit")
|
||||
stdin.WriteLine("exit")
|
||||
})
|
||||
|
||||
t.Run("RemoteForwardUnixSocket", func(t *testing.T) {
|
||||
@@ -1302,6 +1308,7 @@ func TestSSH(t *testing.T) {
|
||||
|
||||
t.Parallel()
|
||||
|
||||
logger := testutil.Logger(t)
|
||||
client, workspace, agentToken := setupWorkspaceForAgent(t)
|
||||
|
||||
_ = agenttest.New(t, client.URL, agentToken)
|
||||
@@ -1321,8 +1328,8 @@ func TestSSH(t *testing.T) {
|
||||
fmt.Sprintf("%s:%s", remoteSock, localSock),
|
||||
)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t).Attach(inv)
|
||||
inv.Stderr = pty.Output()
|
||||
stdout := expecter.NewAttachedToInvocation(t, inv)
|
||||
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
|
||||
|
||||
w := clitest.StartWithWaiter(t, inv.WithContext(ctx))
|
||||
defer w.Wait() // We don't care about any exit error (exit code 255: SSH connection ended unexpectedly).
|
||||
@@ -1330,12 +1337,12 @@ func TestSSH(t *testing.T) {
|
||||
// Since something was output, it should be safe to write input.
|
||||
// This could show a prompt or "running startup scripts", so it's
|
||||
// not indicative of the SSH connection being ready.
|
||||
_ = pty.Peek(ctx, 1)
|
||||
_ = stdout.Peek(ctx, 1)
|
||||
|
||||
// Ensure the SSH connection is ready by testing the shell
|
||||
// input/output.
|
||||
pty.WriteLine("echo ping' 'pong")
|
||||
pty.ExpectMatchContext(ctx, "ping pong")
|
||||
stdin.WriteLine("echo ping' 'pong")
|
||||
stdout.ExpectMatchContext(ctx, "ping pong")
|
||||
|
||||
// Start the listener on the "local machine".
|
||||
l, err := net.Listen("unix", localSock)
|
||||
@@ -1378,7 +1385,7 @@ func TestSSH(t *testing.T) {
|
||||
require.Equal(t, "hello world", string(buf))
|
||||
|
||||
// And we're done.
|
||||
pty.WriteLine("exit")
|
||||
stdin.WriteLine("exit")
|
||||
})
|
||||
|
||||
// Test that we can forward a local unix socket to a remote unix socket and
|
||||
@@ -1391,6 +1398,7 @@ func TestSSH(t *testing.T) {
|
||||
|
||||
t.Parallel()
|
||||
|
||||
logger := testutil.Logger(t)
|
||||
client, workspace, agentToken := setupWorkspaceForAgent(t)
|
||||
|
||||
_ = agenttest.New(t, client.URL, agentToken)
|
||||
@@ -1440,8 +1448,8 @@ func TestSSH(t *testing.T) {
|
||||
)
|
||||
inv.Logger = inv.Logger.Named(id)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t).Attach(inv)
|
||||
inv.Stderr = pty.Output()
|
||||
stdout := expecter.NewAttachedToInvocation(t, inv)
|
||||
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
|
||||
cmdDone := tGo(t, func() {
|
||||
err := inv.WithContext(ctx).Run()
|
||||
assert.NoError(t, err, "ssh command failed: %s", id)
|
||||
@@ -1450,12 +1458,12 @@ func TestSSH(t *testing.T) {
|
||||
// Since something was output, it should be safe to write input.
|
||||
// This could show a prompt or "running startup scripts", so it's
|
||||
// not indicative of the SSH connection being ready.
|
||||
_ = pty.Peek(ctx, 1)
|
||||
_ = stdout.Peek(ctx, 1)
|
||||
|
||||
// Ensure the SSH connection is ready by testing the shell
|
||||
// input/output.
|
||||
pty.WriteLine("echo ping' 'pong")
|
||||
pty.ExpectMatchContext(ctx, "ping pong")
|
||||
stdin.WriteLine("echo ping' 'pong")
|
||||
stdout.ExpectMatchContext(ctx, "ping pong")
|
||||
|
||||
d := &net.Dialer{}
|
||||
fd, err := d.DialContext(ctx, "unix", remoteSock)
|
||||
@@ -1481,7 +1489,7 @@ func TestSSH(t *testing.T) {
|
||||
assert.NoError(t, err, id)
|
||||
assert.Equal(t, "hello world", string(buf), id)
|
||||
|
||||
pty.WriteLine("exit")
|
||||
stdin.WriteLine("exit")
|
||||
<-cmdDone
|
||||
return nil
|
||||
})
|
||||
@@ -1504,6 +1512,7 @@ func TestSSH(t *testing.T) {
|
||||
|
||||
t.Parallel()
|
||||
|
||||
logger := testutil.Logger(t)
|
||||
client, workspace, agentToken := setupWorkspaceForAgent(t)
|
||||
|
||||
_ = agenttest.New(t, client.URL, agentToken)
|
||||
@@ -1534,8 +1543,8 @@ func TestSSH(t *testing.T) {
|
||||
|
||||
inv, root := clitest.New(t, args...)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t).Attach(inv)
|
||||
inv.Stderr = pty.Output()
|
||||
stdout := expecter.NewAttachedToInvocation(t, inv)
|
||||
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
|
||||
|
||||
w := clitest.StartWithWaiter(t, inv.WithContext(ctx))
|
||||
defer w.Wait() // We don't care about any exit error (exit code 255: SSH connection ended unexpectedly).
|
||||
@@ -1543,12 +1552,12 @@ func TestSSH(t *testing.T) {
|
||||
// Since something was output, it should be safe to write input.
|
||||
// This could show a prompt or "running startup scripts", so it's
|
||||
// not indicative of the SSH connection being ready.
|
||||
_ = pty.Peek(ctx, 1)
|
||||
_ = stdout.Peek(ctx, 1)
|
||||
|
||||
// Ensure the SSH connection is ready by testing the shell
|
||||
// input/output.
|
||||
pty.WriteLine("echo ping' 'pong")
|
||||
pty.ExpectMatchContext(ctx, "ping pong")
|
||||
stdin.WriteLine("echo ping' 'pong")
|
||||
stdout.ExpectMatchContext(ctx, "ping pong")
|
||||
|
||||
for i, sock := range sockets {
|
||||
// Start the listener on the "local machine".
|
||||
@@ -1593,27 +1602,30 @@ func TestSSH(t *testing.T) {
|
||||
}
|
||||
|
||||
// And we're done.
|
||||
pty.WriteLine("exit")
|
||||
stdin.WriteLine("exit")
|
||||
})
|
||||
|
||||
t.Run("FileLogging", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := testutil.Logger(t)
|
||||
logDir := t.TempDir()
|
||||
|
||||
client, workspace, agentToken := setupWorkspaceForAgent(t)
|
||||
inv, root := clitest.New(t, "ssh", "-l", logDir, workspace.Name)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t).Attach(inv)
|
||||
ctx := testutil.Context(t, testutil.WaitMedium)
|
||||
stdout := expecter.NewAttachedToInvocation(t, inv)
|
||||
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
|
||||
w := clitest.StartWithWaiter(t, inv)
|
||||
|
||||
pty.ExpectMatch("Waiting")
|
||||
stdout.ExpectMatchContext(ctx, "Waiting")
|
||||
|
||||
agenttest.New(t, client.URL, agentToken)
|
||||
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
|
||||
|
||||
// Shells on Mac, Windows, and Linux all exit shells with the "exit" command.
|
||||
pty.WriteLine("exit")
|
||||
stdin.WriteLine("exit")
|
||||
w.RequireSuccess()
|
||||
|
||||
ents, err := os.ReadDir(logDir)
|
||||
@@ -1681,6 +1693,7 @@ func TestSSH(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := testutil.Logger(t)
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
if tc.experiment {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceUsage)}
|
||||
@@ -1703,7 +1716,8 @@ func TestSSH(t *testing.T) {
|
||||
agentToken := r.AgentToken
|
||||
inv, root := clitest.New(t, "ssh", workspace.Name, fmt.Sprintf("--usage-app=%s", tc.usageAppName))
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t).Attach(inv)
|
||||
stdout := expecter.NewAttachedToInvocation(t, inv)
|
||||
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
@@ -1712,13 +1726,13 @@ func TestSSH(t *testing.T) {
|
||||
err := inv.WithContext(ctx).Run()
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
pty.ExpectMatch("Waiting")
|
||||
stdout.ExpectMatchContext(ctx, "Waiting")
|
||||
|
||||
_ = agenttest.New(t, client.URL, agentToken)
|
||||
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
|
||||
|
||||
// Shells on Mac, Windows, and Linux all exit shells with the "exit" command.
|
||||
pty.WriteLine("exit")
|
||||
stdin.WriteLine("exit")
|
||||
<-cmdDone
|
||||
|
||||
require.EqualValues(t, tc.expectedCalls, batcher.Called)
|
||||
@@ -1974,16 +1988,15 @@ Expire-Date: 0
|
||||
})
|
||||
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
|
||||
|
||||
logger := testutil.Logger(t)
|
||||
inv, root := clitest.New(t,
|
||||
"ssh",
|
||||
workspace.Name,
|
||||
"--forward-gpg",
|
||||
)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
tpty := ptytest.New(t)
|
||||
inv.Stdin = tpty.Input()
|
||||
inv.Stdout = tpty.Output()
|
||||
inv.Stderr = tpty.Output()
|
||||
invOut := expecter.NewAttachedToInvocation(t, inv)
|
||||
invIn := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
|
||||
cmdDone := tGo(t, func() {
|
||||
err := inv.WithContext(ctx).Run()
|
||||
assert.NoError(t, err, "ssh command failed")
|
||||
@@ -1997,24 +2010,24 @@ Expire-Date: 0
|
||||
|
||||
// Wait for the prompt or any output really to indicate the command has
|
||||
// started and accepting input on stdin.
|
||||
_ = tpty.Peek(ctx, 1)
|
||||
_ = invOut.Peek(ctx, 1)
|
||||
|
||||
tpty.WriteLine("echo hello 'world'")
|
||||
tpty.ExpectMatch("hello world")
|
||||
invIn.WriteLine("echo hello 'world'")
|
||||
invOut.ExpectMatchContext(ctx, "hello world")
|
||||
|
||||
// Check the GNUPGHOME was correctly inherited via shell.
|
||||
tpty.WriteLine("env && echo env-''-command-done")
|
||||
match := tpty.ExpectMatch("env--command-done")
|
||||
invIn.WriteLine("env && echo env-''-command-done")
|
||||
match := invOut.ExpectMatchContext(ctx, "env--command-done")
|
||||
require.Contains(t, match, "GNUPGHOME="+gnupgHomeWorkspace, match)
|
||||
|
||||
// Get the agent extra socket path in the "workspace" via shell.
|
||||
tpty.WriteLine("gpgconf --list-dir agent-socket && echo gpgconf-''-agentsocket-command-done")
|
||||
tpty.ExpectMatch(workspaceAgentSocketPath)
|
||||
tpty.ExpectMatch("gpgconf--agentsocket-command-done")
|
||||
invIn.WriteLine("gpgconf --list-dir agent-socket && echo gpgconf-''-agentsocket-command-done")
|
||||
invOut.ExpectMatchContext(ctx, workspaceAgentSocketPath)
|
||||
invOut.ExpectMatchContext(ctx, "gpgconf--agentsocket-command-done")
|
||||
|
||||
// List the keys in the "workspace".
|
||||
tpty.WriteLine("gpg --list-keys && echo gpg-''-listkeys-command-done")
|
||||
listKeysOutput := tpty.ExpectMatch("gpg--listkeys-command-done")
|
||||
invIn.WriteLine("gpg --list-keys && echo gpg-''-listkeys-command-done")
|
||||
listKeysOutput := invOut.ExpectMatchContext(ctx, "gpg--listkeys-command-done")
|
||||
require.Contains(t, listKeysOutput, "[ultimate] Coder Test <test@coder.com>")
|
||||
// It's fine that this key is expired. We're just testing that the key trust
|
||||
// gets synced properly.
|
||||
@@ -2023,14 +2036,14 @@ Expire-Date: 0
|
||||
// Try to sign something. This demonstrates that the forwarding is
|
||||
// working as expected, since the workspace doesn't have access to the
|
||||
// private key directly and must use the forwarded agent.
|
||||
tpty.WriteLine("echo 'hello world' | gpg --clearsign && echo gpg-''-sign-command-done")
|
||||
tpty.ExpectMatch("BEGIN PGP SIGNED MESSAGE")
|
||||
tpty.ExpectMatch("Hash:")
|
||||
tpty.ExpectMatch("hello world")
|
||||
tpty.ExpectMatch("gpg--sign-command-done")
|
||||
invIn.WriteLine("echo 'hello world' | gpg --clearsign && echo gpg-''-sign-command-done")
|
||||
invOut.ExpectMatchContext(ctx, "BEGIN PGP SIGNED MESSAGE")
|
||||
invOut.ExpectMatchContext(ctx, "Hash:")
|
||||
invOut.ExpectMatchContext(ctx, "hello world")
|
||||
invOut.ExpectMatchContext(ctx, "gpg--sign-command-done")
|
||||
|
||||
// And we're done.
|
||||
tpty.WriteLine("exit")
|
||||
invIn.WriteLine("exit")
|
||||
<-cmdDone
|
||||
}
|
||||
|
||||
@@ -2043,6 +2056,7 @@ func TestSSH_Container(t *testing.T) {
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := testutil.Logger(t)
|
||||
client, workspace, agentToken := setupWorkspaceForAgent(t)
|
||||
pool, err := dockertest.NewPool("")
|
||||
require.NoError(t, err, "Could not connect to docker")
|
||||
@@ -2076,7 +2090,8 @@ func TestSSH_Container(t *testing.T) {
|
||||
|
||||
inv, root := clitest.New(t, "ssh", workspace.Name, "-c", ct.Container.ID)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
ptty := ptytest.New(t).Attach(inv)
|
||||
stdout := expecter.NewAttachedToInvocation(t, inv)
|
||||
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
cmdDone := tGo(t, func() {
|
||||
@@ -2084,10 +2099,10 @@ func TestSSH_Container(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
ptty.ExpectMatchContext(ctx, " #")
|
||||
ptty.WriteLine("hostname")
|
||||
ptty.ExpectMatchContext(ctx, ct.Container.Config.Hostname)
|
||||
ptty.WriteLine("exit")
|
||||
stdout.ExpectMatchContext(ctx, " #")
|
||||
stdin.WriteLine("hostname")
|
||||
stdout.ExpectMatchContext(ctx, ct.Container.Config.Hostname)
|
||||
stdin.WriteLine("exit")
|
||||
<-cmdDone
|
||||
})
|
||||
|
||||
@@ -2120,15 +2135,15 @@ func TestSSH_Container(t *testing.T) {
|
||||
cID := uuid.NewString()
|
||||
inv, root := clitest.New(t, "ssh", workspace.Name, "-c", cID)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
ptty := ptytest.New(t).Attach(inv)
|
||||
stdout := expecter.NewAttachedToInvocation(t, inv)
|
||||
|
||||
cmdDone := tGo(t, func() {
|
||||
err := inv.WithContext(ctx).Run()
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
ptty.ExpectMatch(fmt.Sprintf("Container not found: %q", cID))
|
||||
ptty.ExpectMatch("Available containers: [something_completely_different]")
|
||||
stdout.ExpectMatchContext(ctx, fmt.Sprintf("Container not found: %q", cID))
|
||||
stdout.ExpectMatchContext(ctx, "Available containers: [something_completely_different]")
|
||||
<-cmdDone
|
||||
})
|
||||
|
||||
@@ -2163,7 +2178,6 @@ func TestSSH_CoderConnect(t *testing.T) {
|
||||
client, workspace, agentToken := setupWorkspaceForAgent(t)
|
||||
inv, root := clitest.New(t, "ssh", workspace.Name, "--network-info-dir", "/net", "--stdio")
|
||||
clitest.SetupConfig(t, client, root)
|
||||
_ = ptytest.New(t).Attach(inv)
|
||||
|
||||
ctx = cli.WithTestOnlyCoderConnectDialer(ctx, &fakeCoderConnectDialer{})
|
||||
ctx = withCoderConnectRunning(ctx)
|
||||
|
||||
Reference in New Issue
Block a user