pulumi/cmd/new_test.go

315 lines
8.4 KiB
Go
Raw Normal View History

// Copyright 2016-2018, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"context"
2019-08-20 15:20:27 +02:00
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/pulumi/pulumi/pkg/backend"
"github.com/pulumi/pulumi/pkg/backend/display"
"github.com/pulumi/pulumi/pkg/workspace"
"github.com/stretchr/testify/assert"
)
2019-08-20 15:20:27 +02:00
func TestCreatingProjectWithArgsSpecifiedName(t *testing.T) {
tempdir, _ := ioutil.TempDir("", "test-env")
defer os.RemoveAll(tempdir)
assert.NoError(t, os.Chdir(tempdir))
uniqueProjectName := filepath.Base(tempdir)
var args = newArgs{
interactive: false,
2019-08-20 15:20:27 +02:00
name: uniqueProjectName,
prompt: promptForValue,
2019-08-20 15:20:27 +02:00
secretsProvider: "default",
templateNameOrURL: "typescript",
}
err := runNew(args)
assert.NoError(t, err)
2019-08-20 15:20:27 +02:00
removeStack(t)
proj := loadProject(t, tempdir)
assert.Equal(t, uniqueProjectName, proj.Name.String())
}
func TestCreatingProjectWithPromptedName(t *testing.T) {
tempdir, _ := ioutil.TempDir("", "test-env")
defer os.RemoveAll(tempdir)
assert.NoError(t, os.Chdir(tempdir))
uniqueProjectName := filepath.Base(tempdir)
var args = newArgs{
interactive: true,
prompt: promptMock(uniqueProjectName),
secretsProvider: "default",
templateNameOrURL: "typescript",
}
err := runNew(args)
assert.NoError(t, err)
2019-08-20 15:20:27 +02:00
removeStack(t)
proj := loadProject(t, tempdir)
assert.Equal(t, uniqueProjectName, proj.Name.String())
}
2019-08-20 15:20:27 +02:00
func TestCreatingProjectWithExistingArgsSpecifiedNameFails(t *testing.T) {
tempdir, _ := ioutil.TempDir("", "test-env")
defer os.RemoveAll(tempdir)
assert.NoError(t, os.Chdir(tempdir))
2019-08-20 15:20:27 +02:00
backendInstance = &backend.MockBackend{
DoesProjectExistF: func(ctx context.Context, name string) (bool, error) {
return name == projectName, nil
},
}
var args = newArgs{
interactive: false,
name: projectName,
2019-08-20 15:20:27 +02:00
prompt: promptForValue,
secretsProvider: "default",
templateNameOrURL: "typescript",
2019-08-20 15:20:27 +02:00
}
err := runNew(args)
assert.Error(t, err)
assert.Contains(t, err.Error(), "project with this name already exists")
}
func TestCreatingProjectWithExistingPromptedNameFails(t *testing.T) {
tempdir, _ := ioutil.TempDir("", "test-env")
defer os.RemoveAll(tempdir)
assert.NoError(t, os.Chdir(tempdir))
backendInstance = &backend.MockBackend{
DoesProjectExistF: func(ctx context.Context, name string) (bool, error) {
return name == projectName, nil
},
}
var args = newArgs{
interactive: true,
prompt: promptMock(projectName),
secretsProvider: "default",
2019-08-20 15:20:27 +02:00
templateNameOrURL: "typescript",
}
err := runNew(args)
2019-08-20 15:20:27 +02:00
assert.Error(t, err)
assert.Contains(t, err.Error(), "project with this name already exists")
}
func TestGeneratingProjectWithExistingArgsSpecifiedNameSucceeds(t *testing.T) {
tempdir, _ := ioutil.TempDir("", "test-env")
defer os.RemoveAll(tempdir)
assert.NoError(t, os.Chdir(tempdir))
backendInstance = &backend.MockBackend{
DoesProjectExistF: func(ctx context.Context, name string) (bool, error) {
return true, nil
},
}
// Generate-only command is not creating any stacks, so don't bother with with the name uniqueness check.
var args = newArgs{
generateOnly: true,
interactive: false,
name: projectName,
prompt: promptForValue,
secretsProvider: "default",
templateNameOrURL: "typescript",
}
2019-08-20 15:20:27 +02:00
err := runNew(args)
assert.NoError(t, err)
2019-08-20 15:20:27 +02:00
proj := loadProject(t, tempdir)
assert.Equal(t, projectName, proj.Name.String())
}
func TestGeneratingProjectWithExistingPromptedNameSucceeds(t *testing.T) {
tempdir, _ := ioutil.TempDir("", "test-env")
defer os.RemoveAll(tempdir)
assert.NoError(t, os.Chdir(tempdir))
backendInstance = &backend.MockBackend{
DoesProjectExistF: func(ctx context.Context, name string) (bool, error) {
return true, nil
},
}
// Generate-only command is not creating any stacks, so don't bother with with the name uniqueness check.
var args = newArgs{
generateOnly: true,
interactive: true,
prompt: promptMock(projectName),
secretsProvider: "default",
templateNameOrURL: "typescript",
}
err := runNew(args)
assert.NoError(t, err)
2019-08-20 15:20:27 +02:00
proj := loadProject(t, tempdir)
assert.Equal(t, projectName, proj.Name.String())
}
2019-08-20 15:20:27 +02:00
func TestGeneratingProjectWithInvalidArgsSpecifiedNameFails(t *testing.T) {
tempdir, _ := ioutil.TempDir("", "test-env")
defer os.RemoveAll(tempdir)
assert.NoError(t, os.Chdir(tempdir))
2019-08-20 15:20:27 +02:00
backendInstance = &backend.MockBackend{
DoesProjectExistF: func(ctx context.Context, name string) (bool, error) {
return true, nil
},
}
2019-08-20 15:20:27 +02:00
// Generate-only command is not creating any stacks, so don't bother with with the name uniqueness check.
var args = newArgs{
generateOnly: true,
interactive: false,
name: "not#valid",
prompt: promptForValue,
secretsProvider: "default",
templateNameOrURL: "typescript",
}
err := runNew(args)
assert.Error(t, err)
assert.Contains(t, err.Error(), "project name may only contain")
}
func TestGeneratingProjectWithInvalidPromptedNameFails(t *testing.T) {
tempdir, _ := ioutil.TempDir("", "test-env")
defer os.RemoveAll(tempdir)
assert.NoError(t, os.Chdir(tempdir))
backendInstance = &backend.MockBackend{
DoesProjectExistF: func(ctx context.Context, name string) (bool, error) {
2019-08-20 15:20:27 +02:00
return true, nil
},
}
2019-08-20 15:20:27 +02:00
// Generate-only command is not creating any stacks, so don't bother with with the name uniqueness check.
var args = newArgs{
2019-08-20 15:20:27 +02:00
generateOnly: true,
interactive: true,
2019-08-20 15:20:27 +02:00
prompt: promptMock("not#valid"),
secretsProvider: "default",
templateNameOrURL: "typescript",
}
err := runNew(args)
assert.Error(t, err)
2019-08-20 15:20:27 +02:00
assert.Contains(t, err.Error(), "project name may only contain")
}
2019-08-23 15:35:19 +02:00
func TestInvalidTemplateName(t *testing.T) {
t.Run("NoTemplateSpecified", func(t *testing.T) {
tempdir, _ := ioutil.TempDir("", "test-env")
defer os.RemoveAll(tempdir)
assert.NoError(t, os.Chdir(tempdir))
var args = newArgs{
secretsProvider: "default",
templateNameOrURL: "",
}
err := runNew(args)
assert.Error(t, err)
assert.Contains(t, err.Error(), "no template selected")
})
2019-08-23 18:05:19 +02:00
t.Run("RemoteTemplateNotFound", func(t *testing.T) {
2019-08-23 15:35:19 +02:00
tempdir, _ := ioutil.TempDir("", "test-env")
defer os.RemoveAll(tempdir)
assert.NoError(t, os.Chdir(tempdir))
// A template that will never exist.
template := "this-is-not-the-template-youre-looking-for"
var args = newArgs{
secretsProvider: "default",
templateNameOrURL: template,
}
err := runNew(args)
assert.Error(t, err)
assert.Contains(t, err.Error(), "not found")
})
2019-08-23 18:05:19 +02:00
t.Run("LocalTemplateNotFound", func(t *testing.T) {
2019-08-23 15:35:19 +02:00
tempdir, _ := ioutil.TempDir("", "test-env")
defer os.RemoveAll(tempdir)
assert.NoError(t, os.Chdir(tempdir))
// A template that will never exist remotely.
template := "this-is-not-the-template-youre-looking-for"
var args = newArgs{
generateOnly: true,
offline: true,
secretsProvider: "default",
templateNameOrURL: template,
yes: true,
}
err := runNew(args)
assert.Error(t, err)
assert.Contains(t, err.Error(), "not found")
})
}
2019-08-20 15:20:27 +02:00
const projectName = "test_project"
func promptMock(name string) promptForValueFunc {
return func(yes bool, valueType string, defaultValue string, secret bool,
isValidFn func(value string) error, opts display.Options) (string, error) {
if valueType == "project name" {
err := isValidFn(name)
return name, err
}
return defaultValue, nil
}
}
func loadProject(t *testing.T, dir string) *workspace.Project {
path, err := workspace.DetectProjectPathFrom(dir)
assert.NoError(t, err)
proj, err := workspace.LoadProject(path)
assert.NoError(t, err)
return proj
}
func removeStack(t *testing.T) {
b, err := currentBackend(display.Options{})
assert.NoError(t, err)
ref, err := b.ParseStackReference("dev")
assert.NoError(t, err)
_, err = b.RemoveStack(context.Background(), ref, false)
assert.NoError(t, err)
}