mirror of
https://github.com/coder/coder.git
synced 2025-07-12 00:14:10 +00:00
feat(cli): add experimental rpty command (#16700)
Relates to https://github.com/coder/coder/issues/16419 Builds upon https://github.com/coder/coder/pull/16638 and adds a command `exp rpty` that allows you to open a ReconnectingPTY session to an agent. This ultimately allows us to add an integration-style CLI test to verify the functionality added in #16638 .
This commit is contained in:
93
cli/exp_errors_test.go
Normal file
93
cli/exp_errors_test.go
Normal file
@ -0,0 +1,93 @@
|
||||
package cli_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/v2/cli"
|
||||
"github.com/coder/coder/v2/cli/clitest"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
type commandErrorCase struct {
|
||||
Name string
|
||||
Cmd []string
|
||||
}
|
||||
|
||||
// TestErrorExamples will test the help output of the
|
||||
// coder exp example-error using golden files.
|
||||
func TestErrorExamples(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
coderRootCmd := getRoot(t)
|
||||
|
||||
var exampleErrorRootCmd *serpent.Command
|
||||
coderRootCmd.Walk(func(command *serpent.Command) {
|
||||
if command.Name() == "example-error" {
|
||||
// cannot abort early, but list is small
|
||||
exampleErrorRootCmd = command
|
||||
}
|
||||
})
|
||||
require.NotNil(t, exampleErrorRootCmd, "example-error command not found")
|
||||
|
||||
var cases []commandErrorCase
|
||||
|
||||
ExtractCommandPathsLoop:
|
||||
for _, cp := range extractCommandPaths(nil, exampleErrorRootCmd.Children) {
|
||||
cmd := append([]string{"exp", "example-error"}, cp...)
|
||||
name := fmt.Sprintf("coder %s", strings.Join(cmd, " "))
|
||||
for _, tt := range cases {
|
||||
if tt.Name == name {
|
||||
continue ExtractCommandPathsLoop
|
||||
}
|
||||
}
|
||||
cases = append(cases, commandErrorCase{Name: name, Cmd: cmd})
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
tt := tt
|
||||
t.Run(tt.Name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var outBuf bytes.Buffer
|
||||
|
||||
coderRootCmd := getRoot(t)
|
||||
|
||||
inv, _ := clitest.NewWithCommand(t, coderRootCmd, tt.Cmd...)
|
||||
inv.Stderr = &outBuf
|
||||
inv.Stdout = &outBuf
|
||||
|
||||
err := inv.Run()
|
||||
|
||||
errFormatter := cli.NewPrettyErrorFormatter(&outBuf, false)
|
||||
errFormatter.Format(err)
|
||||
|
||||
clitest.TestGoldenFile(t, tt.Name, outBuf.Bytes(), nil)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func extractCommandPaths(cmdPath []string, cmds []*serpent.Command) [][]string {
|
||||
var cmdPaths [][]string
|
||||
for _, c := range cmds {
|
||||
cmdPath := append(cmdPath, c.Name())
|
||||
cmdPaths = append(cmdPaths, cmdPath)
|
||||
cmdPaths = append(cmdPaths, extractCommandPaths(cmdPath, c.Children)...)
|
||||
}
|
||||
return cmdPaths
|
||||
}
|
||||
|
||||
// Must return a fresh instance of cmds each time.
|
||||
func getRoot(t *testing.T) *serpent.Command {
|
||||
t.Helper()
|
||||
|
||||
var root cli.RootCmd
|
||||
rootCmd, err := root.Command(root.AGPL())
|
||||
require.NoError(t, err)
|
||||
|
||||
return rootCmd
|
||||
}
|
Reference in New Issue
Block a user