From 172647f065dbbb819f002d71ce005e838bb971d8 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Thu, 1 Sep 2022 23:54:24 +0000 Subject: [PATCH 1/6] feat(cli): add template create validation test This adds a test to validate that `template create` prints an error message if called with a template name exceeding the 32-char limit. --- cli/templatecreate_test.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/cli/templatecreate_test.go b/cli/templatecreate_test.go index 22a2681b36b9d..c75cc5b29625c 100644 --- a/cli/templatecreate_test.go +++ b/cli/templatecreate_test.go @@ -241,6 +241,25 @@ func TestTemplateCreate(t *testing.T) { err = create() require.NoError(t, err, "Template must be recreated without error") }) + + t.Run("WithParameterExceedingCharLimit", func(t *testing.T) { + t.Parallel() + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) + coderdtest.CreateFirstUser(t, client) + // Template name "1234567890123456789012345678901234567890" exceeds 32 char limit + cmd, root := clitest.New(t, "templates", "create", "1234567890123456789012345678901234567890", "--test.provisioner", string(database.ProvisionerTypeEcho)) + clitest.SetupConfig(t, client, root) + pty := ptytest.New(t) + cmd.SetIn(pty.Input()) + cmd.SetOut(pty.Output()) + + execDone := make(chan error) + go func() { + execDone <- cmd.Execute() + }() + + require.EqualError(t, <-execDone, "template name must be less than 32 characters") + }) } func createTestParseResponse() []*proto.Parse_Response { From 7f8019bccff57fc7e6888b1673497ddfbc49a663 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Fri, 2 Sep 2022 00:04:05 +0000 Subject: [PATCH 2/6] fixup --- cli/templatecreate_test.go | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/cli/templatecreate_test.go b/cli/templatecreate_test.go index c75cc5b29625c..919eb621d9b1d 100644 --- a/cli/templatecreate_test.go +++ b/cli/templatecreate_test.go @@ -246,8 +246,16 @@ func TestTemplateCreate(t *testing.T) { t.Parallel() client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) coderdtest.CreateFirstUser(t, client) - // Template name "1234567890123456789012345678901234567890" exceeds 32 char limit - cmd, root := clitest.New(t, "templates", "create", "1234567890123456789012345678901234567890", "--test.provisioner", string(database.ProvisionerTypeEcho)) + source := clitest.CreateTemplateVersionSource(t, &echo.Responses{ + Parse: createTestParseResponse(), + Provision: echo.ProvisionComplete, + ProvisionDryRun: echo.ProvisionComplete, + }) + tempDir := t.TempDir() + removeTmpDirUntilSuccessAfterTest(t, tempDir) + parameterFile, _ := os.CreateTemp(tempDir, "testParameterFile*.yaml") + _, _ = parameterFile.WriteString("zone: \"bananas\"") + cmd, root := clitest.New(t, "templates", "create", "1234567890123456789012345678901234567890", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--parameter-file", parameterFile.Name()) clitest.SetupConfig(t, client, root) pty := ptytest.New(t) cmd.SetIn(pty.Input()) @@ -258,6 +266,17 @@ func TestTemplateCreate(t *testing.T) { execDone <- cmd.Execute() }() + matches := []struct { + match string + write string + }{ + {match: "Create and upload", write: "yes"}, + } + for _, m := range matches { + pty.ExpectMatch(m.match) + pty.WriteLine(m.write) + } + require.EqualError(t, <-execDone, "template name must be less than 32 characters") }) } From c7e1c4e5b26dbe4f1c8d4baf61e386c4f15c8024 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Fri, 2 Sep 2022 17:33:51 +0000 Subject: [PATCH 3/6] fixup test --- cli/templatecreate_test.go | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/cli/templatecreate_test.go b/cli/templatecreate_test.go index 919eb621d9b1d..6c4296a142c5f 100644 --- a/cli/templatecreate_test.go +++ b/cli/templatecreate_test.go @@ -246,16 +246,7 @@ func TestTemplateCreate(t *testing.T) { t.Parallel() client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) coderdtest.CreateFirstUser(t, client) - source := clitest.CreateTemplateVersionSource(t, &echo.Responses{ - Parse: createTestParseResponse(), - Provision: echo.ProvisionComplete, - ProvisionDryRun: echo.ProvisionComplete, - }) - tempDir := t.TempDir() - removeTmpDirUntilSuccessAfterTest(t, tempDir) - parameterFile, _ := os.CreateTemp(tempDir, "testParameterFile*.yaml") - _, _ = parameterFile.WriteString("zone: \"bananas\"") - cmd, root := clitest.New(t, "templates", "create", "1234567890123456789012345678901234567890", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--parameter-file", parameterFile.Name()) + cmd, root := clitest.New(t, "templates", "create", "1234567890123456789012345678901234567891", "--test.provisioner", string(database.ProvisionerTypeEcho)) clitest.SetupConfig(t, client, root) pty := ptytest.New(t) cmd.SetIn(pty.Input()) @@ -266,18 +257,7 @@ func TestTemplateCreate(t *testing.T) { execDone <- cmd.Execute() }() - matches := []struct { - match string - write string - }{ - {match: "Create and upload", write: "yes"}, - } - for _, m := range matches { - pty.ExpectMatch(m.match) - pty.WriteLine(m.write) - } - - require.EqualError(t, <-execDone, "template name must be less than 32 characters") + require.EqualError(t, <-execDone, "Template name must be less than 32 characters") }) } From cfb2f408c19a56e5c233c825887d08149fc3270c Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Fri, 2 Sep 2022 17:35:22 +0000 Subject: [PATCH 4/6] feat(cli): add name validation to templatecreate This adds a validation step to ensure the template name is less than 32 characters. --- cli/templatecreate.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cli/templatecreate.go b/cli/templatecreate.go index 3f8c7fd2e62e9..d6941b1dcf716 100644 --- a/cli/templatecreate.go +++ b/cli/templatecreate.go @@ -49,6 +49,10 @@ func templateCreate() *cobra.Command { templateName = args[0] } + if len(templateName) > 31 { + return xerrors.Errorf("Template name must be less than 32 characters") + } + _, err = client.TemplateByName(cmd.Context(), organization.ID, templateName) if err == nil { return xerrors.Errorf("A template already exists named %q!", templateName) From 50d71479d3ae1d35af57be9510b4a357ea86d55e Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Fri, 2 Sep 2022 22:30:09 +0000 Subject: [PATCH 5/6] fixup!: use utf8.RuneCountInString --- cli/templatecreate.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cli/templatecreate.go b/cli/templatecreate.go index d6941b1dcf716..9c959f88f7329 100644 --- a/cli/templatecreate.go +++ b/cli/templatecreate.go @@ -6,6 +6,7 @@ import ( "path/filepath" "strings" "time" + "unicode/utf8" "github.com/briandowns/spinner" "github.com/spf13/cobra" @@ -49,7 +50,7 @@ func templateCreate() *cobra.Command { templateName = args[0] } - if len(templateName) > 31 { + if utf8.RuneCountInString(templateName) > 31 { return xerrors.Errorf("Template name must be less than 32 characters") } From dc7ff229f27ca9851864d0e056412b2b992c8140 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Fri, 2 Sep 2022 22:30:53 +0000 Subject: [PATCH 6/6] fixup!: remove pty from test --- cli/templatecreate_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/cli/templatecreate_test.go b/cli/templatecreate_test.go index 6c4296a142c5f..abb0dd1a1b9a6 100644 --- a/cli/templatecreate_test.go +++ b/cli/templatecreate_test.go @@ -248,9 +248,6 @@ func TestTemplateCreate(t *testing.T) { coderdtest.CreateFirstUser(t, client) cmd, root := clitest.New(t, "templates", "create", "1234567890123456789012345678901234567891", "--test.provisioner", string(database.ProvisionerTypeEcho)) clitest.SetupConfig(t, client, root) - pty := ptytest.New(t) - cmd.SetIn(pty.Input()) - cmd.SetOut(pty.Output()) execDone := make(chan error) go func() {