From 4d81b4698c44e9a6fd210e93fe494629ee1d88d6 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Mon, 1 Aug 2022 20:28:58 +0000 Subject: [PATCH] fix: NPE when no arg provided to 'coder update' - Add test suite for 'coder update'. --- cli/update.go | 3 +- cli/update_test.go | 141 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 cli/update_test.go diff --git a/cli/update.go b/cli/update.go index 52aee949cb013..53d73800255c9 100644 --- a/cli/update.go +++ b/cli/update.go @@ -18,7 +18,8 @@ func update() *cobra.Command { cmd := &cobra.Command{ Annotations: workspaceCommand, - Use: "update", + Use: "update ", + Args: cobra.ExactArgs(1), Short: "Update a workspace to the latest template version", RunE: func(cmd *cobra.Command, args []string) error { client, err := createClient(cmd) diff --git a/cli/update_test.go b/cli/update_test.go new file mode 100644 index 0000000000000..3b448e3eec281 --- /dev/null +++ b/cli/update_test.go @@ -0,0 +1,141 @@ +package cli_test + +import ( + "context" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/coder/coder/cli/clitest" + "github.com/coder/coder/coderd/coderdtest" + "github.com/coder/coder/codersdk" + "github.com/coder/coder/provisioner/echo" + "github.com/coder/coder/pty/ptytest" +) + +func TestUpdate(t *testing.T) { + t.Parallel() + + // Test that the function does not panic on missing arg. + t.Run("NoArgs", func(t *testing.T) { + t.Parallel() + + cmd, _ := clitest.New(t, "update") + err := cmd.Execute() + require.Error(t, err) + }) + + t.Run("OK", func(t *testing.T) { + t.Parallel() + + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) + user := coderdtest.CreateFirstUser(t, client) + version1 := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) + + coderdtest.AwaitTemplateVersionJob(t, client, version1.ID) + template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version1.ID) + + cmd, root := clitest.New(t, "create", + "my-workspace", + "--template", template.Name, + "-y", + ) + clitest.SetupConfig(t, client, root) + + err := cmd.Execute() + require.NoError(t, err) + + ws, err := client.WorkspaceByOwnerAndName(context.Background(), "testuser", "my-workspace", codersdk.WorkspaceOptions{}) + require.NoError(t, err) + require.Equal(t, version1.ID.String(), ws.LatestBuild.TemplateVersionID.String()) + + version2 := coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ + Parse: echo.ParseComplete, + Provision: echo.ProvisionComplete, + ProvisionDryRun: echo.ProvisionComplete, + }, template.ID) + _ = coderdtest.AwaitTemplateVersionJob(t, client, version2.ID) + + err = client.UpdateActiveTemplateVersion(context.Background(), template.ID, codersdk.UpdateActiveTemplateVersion{ + ID: version2.ID, + }) + require.NoError(t, err) + + cmd, root = clitest.New(t, "update", ws.Name) + clitest.SetupConfig(t, client, root) + + err = cmd.Execute() + require.NoError(t, err) + + ws, err = client.WorkspaceByOwnerAndName(context.Background(), "testuser", "my-workspace", codersdk.WorkspaceOptions{}) + require.NoError(t, err) + require.Equal(t, version2.ID.String(), ws.LatestBuild.TemplateVersionID.String()) + }) + + t.Run("WithParameter", func(t *testing.T) { + t.Parallel() + + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) + user := coderdtest.CreateFirstUser(t, client) + version1 := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) + + coderdtest.AwaitTemplateVersionJob(t, client, version1.ID) + template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version1.ID) + + cmd, root := clitest.New(t, "create", + "my-workspace", + "--template", template.Name, + "-y", + ) + clitest.SetupConfig(t, client, root) + + err := cmd.Execute() + require.NoError(t, err) + + ws, err := client.WorkspaceByOwnerAndName(context.Background(), "testuser", "my-workspace", codersdk.WorkspaceOptions{}) + require.NoError(t, err) + require.Equal(t, version1.ID.String(), ws.LatestBuild.TemplateVersionID.String()) + + defaultValue := "something" + version2 := coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ + Parse: createTestParseResponseWithDefault(defaultValue), + Provision: echo.ProvisionComplete, + ProvisionDryRun: echo.ProvisionComplete, + }, template.ID) + coderdtest.AwaitTemplateVersionJob(t, client, version2.ID) + + err = client.UpdateActiveTemplateVersion(context.Background(), template.ID, codersdk.UpdateActiveTemplateVersion{ + ID: version2.ID, + }) + require.NoError(t, err) + + cmd, root = clitest.New(t, "update", ws.Name) + clitest.SetupConfig(t, client, root) + + pty := ptytest.New(t) + cmd.SetIn(pty.Input()) + cmd.SetOut(pty.Output()) + + doneChan := make(chan struct{}) + go func() { + defer close(doneChan) + err := cmd.Execute() + assert.NoError(t, err) + }() + + matches := []string{ + fmt.Sprintf("Enter a value (default: %q):", defaultValue), "bingo", + "Enter a value:", "boingo", + } + for i := 0; i < len(matches); i += 2 { + match := matches[i] + value := matches[i+1] + pty.ExpectMatch(match) + pty.WriteLine(value) + } + + <-doneChan + }) +}