mirror of https://github.com/pulumi/pulumi.git
253 lines
8.8 KiB
Go
253 lines
8.8 KiB
Go
// Copyright 2016-2017, Pulumi Corporation. All rights reserved.
|
|
|
|
package ints
|
|
|
|
import (
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/pulumi/pulumi/pkg/pack"
|
|
"github.com/pulumi/pulumi/pkg/resource"
|
|
ptesting "github.com/pulumi/pulumi/pkg/testing"
|
|
"github.com/pulumi/pulumi/pkg/testing/integration"
|
|
"github.com/pulumi/pulumi/pkg/tokens"
|
|
)
|
|
|
|
// TestProjectMain tests out the ability to override the main entrypoint.
|
|
func TestProjectMain(t *testing.T) {
|
|
var test integration.ProgramTestOptions
|
|
test = integration.ProgramTestOptions{
|
|
Dir: "project_main",
|
|
Dependencies: []string{"pulumi"},
|
|
ExtraRuntimeValidation: func(t *testing.T, stackInfo integration.RuntimeValidationStackInfo) {
|
|
// Simple runtime validation that just ensures the checkpoint was written and read.
|
|
assert.Equal(t, test.GetStackName(), stackInfo.Checkpoint.Stack)
|
|
},
|
|
}
|
|
integration.ProgramTest(t, &test)
|
|
|
|
t.Run("Error_AbsolutePath", func(t *testing.T) {
|
|
e := ptesting.NewEnvironment(t)
|
|
defer func() {
|
|
if !t.Failed() {
|
|
e.DeleteEnvironment()
|
|
}
|
|
}()
|
|
e.RunCommand("git", "init")
|
|
e.RunCommand("pulumi", "init")
|
|
|
|
e.ImportDirectory("project_main_abs")
|
|
e.RunCommand("pulumi", "stack", "init", "--local", "main-abs")
|
|
stdout, stderr := e.RunCommandExpectError("pulumi", "update")
|
|
assert.Equal(t, "", stdout)
|
|
assert.Contains(t, stderr, "project 'main' must be a relative path")
|
|
})
|
|
|
|
t.Run("Error_ParentFolder", func(t *testing.T) {
|
|
e := ptesting.NewEnvironment(t)
|
|
defer func() {
|
|
if !t.Failed() {
|
|
e.DeleteEnvironment()
|
|
}
|
|
}()
|
|
e.RunCommand("git", "init")
|
|
e.RunCommand("pulumi", "init")
|
|
|
|
e.ImportDirectory("project_main_parent")
|
|
e.RunCommand("pulumi", "stack", "init", "--local", "main-parent")
|
|
stdout, stderr := e.RunCommandExpectError("pulumi", "update")
|
|
assert.Equal(t, "", stdout)
|
|
assert.Contains(t, stderr, "project 'main' must be a subfolder")
|
|
})
|
|
}
|
|
|
|
// TestStackProjectName ensures we can read the Pulumi stack and project name from within the program.
|
|
func TestStackProjectName(t *testing.T) {
|
|
integration.ProgramTest(t, &integration.ProgramTestOptions{
|
|
Dir: "stack_project_name",
|
|
Dependencies: []string{"pulumi"},
|
|
Quick: true,
|
|
})
|
|
}
|
|
|
|
// TestStackOutputs ensures we can export variables from a stack and have them get recorded as outputs.
|
|
func TestStackOutputs(t *testing.T) {
|
|
integration.ProgramTest(t, &integration.ProgramTestOptions{
|
|
Dir: "stack_outputs",
|
|
Dependencies: []string{"pulumi"},
|
|
Quick: true,
|
|
ExtraRuntimeValidation: func(t *testing.T, stackInfo integration.RuntimeValidationStackInfo) {
|
|
// Ensure the checkpoint contains a single resource, the Stack, with two outputs.
|
|
assert.NotNil(t, stackInfo.Checkpoint.Latest)
|
|
if assert.Equal(t, 1, len(stackInfo.Checkpoint.Latest.Resources)) {
|
|
stackRes := stackInfo.Checkpoint.Latest.Resources[0]
|
|
assert.NotNil(t, stackRes)
|
|
assert.Equal(t, resource.RootStackType, stackRes.URN.Type())
|
|
assert.Equal(t, 0, len(stackRes.Inputs))
|
|
assert.Equal(t, 2, len(stackRes.Outputs))
|
|
assert.Equal(t, "ABC", stackRes.Outputs["xyz"])
|
|
assert.Equal(t, float64(42), stackRes.Outputs["foo"])
|
|
}
|
|
},
|
|
})
|
|
}
|
|
|
|
// TestStackParenting tests out that stacks and components are parented correctly.
|
|
func TestStackParenting(t *testing.T) {
|
|
integration.ProgramTest(t, &integration.ProgramTestOptions{
|
|
Dir: "stack_parenting",
|
|
Dependencies: []string{"pulumi"},
|
|
Quick: true,
|
|
ExtraRuntimeValidation: func(t *testing.T, stackInfo integration.RuntimeValidationStackInfo) {
|
|
// Ensure the checkpoint contains resources parented correctly. This should look like this:
|
|
//
|
|
// A F
|
|
// / \ \
|
|
// B C G
|
|
// / \
|
|
// D E
|
|
//
|
|
// with the caveat, of course, that A and F will share a common parent, the implicit stack.
|
|
|
|
assert.NotNil(t, stackInfo.Checkpoint.Latest)
|
|
if assert.Equal(t, 8, len(stackInfo.Checkpoint.Latest.Resources)) {
|
|
stackRes := stackInfo.Checkpoint.Latest.Resources[0]
|
|
assert.NotNil(t, stackRes)
|
|
assert.Equal(t, resource.RootStackType, stackRes.Type)
|
|
assert.Equal(t, "", string(stackRes.Parent))
|
|
a := stackInfo.Checkpoint.Latest.Resources[1]
|
|
assert.NotNil(t, a)
|
|
assert.Equal(t, "a", string(a.URN.Name()))
|
|
assert.NotEqual(t, "", a.Parent)
|
|
assert.Equal(t, stackRes.URN, a.Parent)
|
|
b := stackInfo.Checkpoint.Latest.Resources[2]
|
|
assert.NotNil(t, b)
|
|
assert.Equal(t, "b", string(b.URN.Name()))
|
|
assert.Equal(t, a.URN, b.Parent)
|
|
c := stackInfo.Checkpoint.Latest.Resources[3]
|
|
assert.NotNil(t, c)
|
|
assert.Equal(t, "c", string(c.URN.Name()))
|
|
assert.Equal(t, a.URN, c.Parent)
|
|
d := stackInfo.Checkpoint.Latest.Resources[4]
|
|
assert.NotNil(t, d)
|
|
assert.Equal(t, "d", string(d.URN.Name()))
|
|
assert.Equal(t, c.URN, d.Parent)
|
|
e := stackInfo.Checkpoint.Latest.Resources[5]
|
|
assert.NotNil(t, e)
|
|
assert.Equal(t, "e", string(e.URN.Name()))
|
|
assert.Equal(t, c.URN, e.Parent)
|
|
f := stackInfo.Checkpoint.Latest.Resources[6]
|
|
assert.NotNil(t, f)
|
|
assert.Equal(t, "f", string(f.URN.Name()))
|
|
assert.Equal(t, stackRes.URN, f.Parent)
|
|
g := stackInfo.Checkpoint.Latest.Resources[7]
|
|
assert.NotNil(t, g)
|
|
assert.Equal(t, "g", string(g.URN.Name()))
|
|
assert.Equal(t, f.URN, g.Parent)
|
|
}
|
|
},
|
|
})
|
|
}
|
|
|
|
// TestConfigSave ensures that config commands in the Pulumi CLI work as expected.
|
|
func TestConfigSave(t *testing.T) {
|
|
e := ptesting.NewEnvironment(t)
|
|
defer func() {
|
|
if !t.Failed() {
|
|
e.DeleteEnvironment()
|
|
}
|
|
}()
|
|
|
|
// Initialize an empty stack.
|
|
pkgpath := filepath.Join(e.RootPath, "Pulumi.yaml")
|
|
err := pack.Save(pkgpath, &pack.Package{
|
|
Name: "testing-config",
|
|
Runtime: "nodejs",
|
|
})
|
|
assert.NoError(t, err)
|
|
e.RunCommand("git", "init")
|
|
e.RunCommand("pulumi", "init")
|
|
e.RunCommand("pulumi", "stack", "init", "--local", "testing-2")
|
|
e.RunCommand("pulumi", "stack", "init", "--local", "testing-1")
|
|
|
|
// Now configure and save a few different things:
|
|
// 1) do not save.
|
|
e.RunCommand("pulumi", "config", "set", "configA", "value1", "--save=false")
|
|
// 2) save to the project file, under the current stack.
|
|
e.RunCommand("pulumi", "config", "set", "configB", "value2")
|
|
// 3) save to the project file, underneath an entirely different stack.
|
|
e.RunCommand("pulumi", "config", "set", "configC", "value3", "--stack", "testing-2")
|
|
// 4) save to the project file, across all stacks.
|
|
e.RunCommand("pulumi", "config", "set", "configD", "value4", "--all")
|
|
// 5) save the same config key with a different value in the stack versus all stacks.
|
|
e.RunCommand("pulumi", "config", "set", "configE", "value55")
|
|
e.RunCommand("pulumi", "config", "set", "configE", "value66", "--all")
|
|
|
|
// Now read back the config using the CLI:
|
|
{
|
|
stdout, _ := e.RunCommand("pulumi", "config", "get", "configA")
|
|
assert.Equal(t, "value1\n", stdout)
|
|
}
|
|
{
|
|
stdout, _ := e.RunCommand("pulumi", "config", "get", "configB")
|
|
assert.Equal(t, "value2\n", stdout)
|
|
}
|
|
{
|
|
// config is in a different stack, should yield a stderr:
|
|
stdout, stderr := e.RunCommandExpectError("pulumi", "config", "get", "configC")
|
|
assert.Equal(t, "", stdout)
|
|
assert.NotEqual(t, "", stderr)
|
|
}
|
|
{
|
|
stdout, _ := e.RunCommand("pulumi", "config", "get", "configC", "--stack", "testing-2")
|
|
assert.Equal(t, "value3\n", stdout)
|
|
}
|
|
{
|
|
stdout, _ := e.RunCommand("pulumi", "config", "get", "configD")
|
|
assert.Equal(t, "value4\n", stdout)
|
|
}
|
|
{
|
|
stdout, _ := e.RunCommand("pulumi", "config", "get", "configE")
|
|
assert.Equal(t, "value55\n", stdout)
|
|
}
|
|
|
|
// Finally, check that the project file contains what we expected.
|
|
cfgkey := func(k string) tokens.ModuleMember { return tokens.ModuleMember("testing-config:config:" + k) }
|
|
pkg, err := pack.Load(pkgpath)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 2, len(pkg.Config)) // --all
|
|
d, ok := pkg.Config[cfgkey("configD")]
|
|
assert.True(t, ok)
|
|
dv, err := d.Value(nil)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "value4", dv)
|
|
ee, ok := pkg.Config[cfgkey("configE")]
|
|
assert.True(t, ok)
|
|
ev, err := ee.Value(nil)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "value66", ev)
|
|
assert.Equal(t, 2, len(pkg.Stacks))
|
|
assert.Equal(t, 2, len(pkg.Stacks["testing-1"].Config))
|
|
b, ok := pkg.Stacks["testing-1"].Config[cfgkey("configB")]
|
|
assert.True(t, ok)
|
|
bv, err := b.Value(nil)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "value2", bv)
|
|
e2, ok := pkg.Stacks["testing-1"].Config[cfgkey("configE")]
|
|
assert.True(t, ok)
|
|
e2v, err := e2.Value(nil)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "value55", e2v)
|
|
assert.Equal(t, 1, len(pkg.Stacks["testing-2"].Config))
|
|
c, ok := pkg.Stacks["testing-2"].Config[cfgkey("configC")]
|
|
assert.True(t, ok)
|
|
cv, err := c.Value(nil)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "value3", cv)
|
|
|
|
// We do not allow storing secrets for all stacks, since the encryption key for the secret is tied to the stack
|
|
e.RunCommandExpectError("pulumi", "config", "set", "secretA", "valueA", "--all", "--secret")
|
|
}
|