cli/templatecreate_test.go
Rama main · réplica de lectura del repositorio original.
package cli_test
import (
"bytes"
"context"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/cli/clitest"
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/provisioner/echo"
"github.com/coder/coder/v2/provisionersdk/proto"
"github.com/coder/coder/v2/testutil"
"github.com/coder/coder/v2/testutil/expecter"
)
func TestCliTemplateCreate(t *testing.T) {
t.Parallel()
t.Run("Create", func(t *testing.T) {
t.Parallel()
logger := testutil.Logger(t)
ctx := testutil.Context(t, testutil.WaitMedium)
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
coderdtest.CreateFirstUser(t, client)
source := clitest.CreateTemplateVersionSource(t, completeWithAgent())
args := []string{
"templates",
"create",
"my-template",
"--directory", source,
"--test.provisioner", string(database.ProvisionerTypeEcho),
"--default-ttl", "24h",
}
inv, root := clitest.New(t, args...)
clitest.SetupConfig(t, client, root)
stdout := expecter.NewAttachedToInvocation(t, inv)
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
clitest.Start(t, inv)
matches := []struct {
match string
write string
}{
{match: "Upload", write: "yes"},
{match: "compute.main"},
{match: "smith (linux, i386)"},
{match: "Confirm create?", write: "yes"},
}
for _, m := range matches {
stdout.ExpectMatch(ctx, m.match)
if len(m.write) > 0 {
stdin.WriteLine(m.write)
}
}
})
t.Run("AgentsAllowed", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
owner := coderdtest.CreateFirstUser(t, client)
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
for _, tt := range []struct {
name string
flag string
agentsAllowed bool
}{
{
name: "DefaultTrue",
agentsAllowed: true,
},
{
name: "False",
flag: "--agents-allowed=false",
agentsAllowed: false,
},
} {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
templateName := coderdtest.RandomUsername(t)
source := clitest.CreateTemplateVersionSource(t, completeWithAgent())
args := []string{
"templates",
"create",
templateName,
"--yes",
"--directory", source,
"--test.provisioner", string(database.ProvisionerTypeEcho),
}
if tt.flag != "" {
args = append(args, tt.flag)
}
inv, root := clitest.New(t, args...)
clitest.SetupConfig(t, templateAdmin, root)
require.NoError(t, inv.Run())
template, err := client.TemplateByName(t.Context(), owner.OrganizationID, templateName)
require.NoError(t, err)
require.Equal(t, tt.agentsAllowed, template.AgentsAllowed)
})
}
})
t.Run("CreateNoLockfile", func(t *testing.T) {
t.Parallel()
logger := testutil.Logger(t)
ctx := testutil.Context(t, testutil.WaitMedium)
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
coderdtest.CreateFirstUser(t, client)
source := clitest.CreateTemplateVersionSource(t, completeWithAgent())
require.NoError(t, os.Remove(filepath.Join(source, ".terraform.lock.hcl")))
args := []string{
"templates",
"create",
"my-template",
"--directory", source,
"--test.provisioner", string(database.ProvisionerTypeEcho),
"--default-ttl", "24h",
}
inv, root := clitest.New(t, args...)
clitest.SetupConfig(t, client, root)
stdout := expecter.NewAttachedToInvocation(t, inv)
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
execDone := make(chan error)
go func() {
execDone <- inv.Run()
}()
matches := []struct {
match string
write string
}{
{match: "No .terraform.lock.hcl file found"},
{match: "Upload", write: "no"},
}
for _, m := range matches {
stdout.ExpectMatch(ctx, m.match)
if len(m.write) > 0 {
stdin.WriteLine(m.write)
}
}
// cmd should error once we say no.
require.Error(t, <-execDone)
})
t.Run("CreateNoLockfileIgnored", func(t *testing.T) {
t.Parallel()
logger := testutil.Logger(t)
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
coderdtest.CreateFirstUser(t, client)
source := clitest.CreateTemplateVersionSource(t, completeWithAgent())
require.NoError(t, os.Remove(filepath.Join(source, ".terraform.lock.hcl")))
args := []string{
"templates",
"create",
"my-template",
"--directory", source,
"--test.provisioner", string(database.ProvisionerTypeEcho),
"--default-ttl", "24h",
"--ignore-lockfile",
}
inv, root := clitest.New(t, args...)
clitest.SetupConfig(t, client, root)
stdout := expecter.NewAttachedToInvocation(t, inv)
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
execDone := make(chan error)
go func() {
execDone <- inv.Run()
}()
{
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium)
defer cancel()
stdout.ExpectNoMatchBefore(ctx, "No .terraform.lock.hcl file found", "Upload")
stdin.WriteLine("no")
}
// cmd should error once we say no.
require.Error(t, <-execDone)
})
t.Run("CreateStdin", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
coderdtest.CreateFirstUser(t, client)
source, err := echo.Tar(completeWithAgent())
require.NoError(t, err)
args := []string{
"templates",
"create",
"my-template",
"--directory", "-",
"--test.provisioner", string(database.ProvisionerTypeEcho),
"--default-ttl", "24h",
}
inv, root := clitest.New(t, args...)
clitest.SetupConfig(t, client, root)
inv.Stdin = bytes.NewReader(source)
require.NoError(t, inv.Run())
})
t.Run("Recreate template with same name (create, delete, create)", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
coderdtest.CreateFirstUser(t, client)
create := func() error {
source := clitest.CreateTemplateVersionSource(t, completeWithAgent())
args := []string{
"templates",
"create",
"my-template",
"--yes",
"--directory", source,
"--test.provisioner", string(database.ProvisionerTypeEcho),
}
inv, root := clitest.New(t, args...)
clitest.SetupConfig(t, client, root)
return inv.Run()
}
del := func() error {
args := []string{
"templates",
"delete",
"my-template",
"--yes",
}
inv, root := clitest.New(t, args...)
clitest.SetupConfig(t, client, root)
return inv.Run()
}
err := create()
require.NoError(t, err, "Template must be created without error")
err = del()
require.NoError(t, err, "Template must be deleted without error")
err = create()
require.NoError(t, err, "Template must be recreated without error")
})
t.Run("WithVariablesFileWithTheRequiredValue", func(t *testing.T) {
t.Parallel()
logger := testutil.Logger(t)
ctx := testutil.Context(t, testutil.WaitMedium)
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
coderdtest.CreateFirstUser(t, client)
templateVariables := []*proto.TemplateVariable{
{
Name: "first_variable",
Description: "This is the first variable.",
Type: "string",
Required: true,
Sensitive: true,
},
{
Name: "second_variable",
Description: "This is the second variable",
Type: "string",
DefaultValue: "abc",
Required: false,
Sensitive: true,
},
}
source := clitest.CreateTemplateVersionSource(t,
createEchoResponsesWithTemplateVariables(templateVariables))
tempDir := t.TempDir()
removeTmpDirUntilSuccessAfterTest(t, tempDir)
variablesFile, _ := os.CreateTemp(tempDir, "variables*.yaml")
_, _ = variablesFile.WriteString(`first_variable: foobar`)
inv, root := clitest.New(t, "templates", "create", "my-template", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--variables-file", variablesFile.Name())
clitest.SetupConfig(t, client, root)
stdout := expecter.NewAttachedToInvocation(t, inv)
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
clitest.Start(t, inv)
matches := []struct {
match string
write string
}{
{match: "Upload", write: "yes"},
{match: "Confirm create?", write: "yes"},
}
for _, m := range matches {
stdout.ExpectMatch(ctx, m.match)
if len(m.write) > 0 {
stdin.WriteLine(m.write)
}
}
})
t.Run("WithVariableOption", func(t *testing.T) {
t.Parallel()
logger := testutil.Logger(t)
ctx := testutil.Context(t, testutil.WaitMedium)
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
coderdtest.CreateFirstUser(t, client)
templateVariables := []*proto.TemplateVariable{
{
Name: "first_variable",
Description: "This is the first variable.",
Type: "string",
Required: true,
Sensitive: true,
},
}
source := clitest.CreateTemplateVersionSource(t,
createEchoResponsesWithTemplateVariables(templateVariables))
inv, root := clitest.New(t, "templates", "create", "my-template", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--variable", "first_variable=foobar")
clitest.SetupConfig(t, client, root)
stdout := expecter.NewAttachedToInvocation(t, inv)
stdin := testutil.NewWriterAttachedToInvocation(t, logger.Named("stdin"), inv)
clitest.Start(t, inv)
matches := []struct {
match string
write string
}{
{match: "Upload", write: "yes"},
{match: "Confirm create?", write: "yes"},
}
for _, m := range matches {
stdout.ExpectMatch(ctx, m.match)
if len(m.write) > 0 {
stdin.WriteLine(m.write)
}
}
})
t.Run("RequireActiveVersionInvalid", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{
IncludeProvisionerDaemon: true,
})
coderdtest.CreateFirstUser(t, client)
source := clitest.CreateTemplateVersionSource(t, completeWithAgent())
args := []string{
"templates",
"create",
"my-template",
"--directory", source,
"--test.provisioner", string(database.ProvisionerTypeEcho),
"--require-active-version",
}
inv, root := clitest.New(t, args...)
clitest.SetupConfig(t, client, root)
err := inv.Run()
require.Error(t, err)
require.Contains(t, err.Error(), "your deployment appears to be an AGPL deployment, so you cannot set flags that require a license")
})
}