package clitest import ( "archive/tar" "bytes" "errors" "io" "os" "path/filepath" "testing" "github.com/spf13/cobra" "github.com/stretchr/testify/require" "github.com/coder/coder/cli" "github.com/coder/coder/cli/config" "github.com/coder/coder/codersdk" "github.com/coder/coder/provisioner/echo" ) // New creates a CLI instance with a configuration pointed to a // temporary testing directory. func New(t *testing.T, args ...string) (*cobra.Command, config.Root) { cmd := cli.Root() dir := t.TempDir() root := config.Root(dir) cmd.SetArgs(append([]string{"--global-config", dir}, args...)) return cmd, root } // 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) require.NoError(t, err) err = root.URL().Write(client.URL.String()) require.NoError(t, err) } // CreateTemplateVersionSource writes the echo provisioner responses into a // new temporary testing directory. func CreateTemplateVersionSource(t *testing.T, responses *echo.Responses) string { directory := t.TempDir() data, err := echo.Tar(responses) require.NoError(t, err) extractTar(t, data, directory) return directory } func extractTar(t *testing.T, data []byte, directory string) { reader := tar.NewReader(bytes.NewBuffer(data)) for { header, err := reader.Next() if errors.Is(err, io.EOF) { break } require.NoError(t, err) // #nosec path := filepath.Join(directory, header.Name) mode := header.FileInfo().Mode() if mode == 0 { mode = 0600 } switch header.Typeflag { case tar.TypeDir: err = os.MkdirAll(path, mode) require.NoError(t, err) case tar.TypeReg: file, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, mode) require.NoError(t, err) // Max file size of 10MB. _, err = io.CopyN(file, reader, (1<<20)*10) if errors.Is(err, io.EOF) { err = nil } require.NoError(t, err) err = file.Close() require.NoError(t, err) } } }