* .NET & python SDKs parity for bad pulumi versions They handle invalid Pulumi CLI version gracefully. * Make python version property lazy * Clarify .NET logic * Add python test for validate_pulumi_version * Add tests for invalid versions * Fix python test * Fix typo * Fix tests * Have _validate_pulumi_version handle parsing * Modify python and .NET to parseAndValidate * Modify typescript and go to parseAndValidate * fix name
2359 lines
70 KiB
Go
2359 lines
70 KiB
Go
// Copyright 2016-2021, 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 auto
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"math/rand"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/blang/semver"
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/auto/events"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/auto/optdestroy"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/auto/optpreview"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/auto/optrefresh"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/auto/optremove"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/auto/optup"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/apitype"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/tokens"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/workspace"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
|
|
)
|
|
|
|
var pulumiOrg = getTestOrg()
|
|
|
|
const pName = "testproj"
|
|
const agent = "pulumi/pulumi/test"
|
|
|
|
func TestWorkspaceSecretsProvider(t *testing.T) {
|
|
ctx := context.Background()
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
|
|
opts := []LocalWorkspaceOption{
|
|
SecretsProvider("passphrase"),
|
|
EnvVars(map[string]string{
|
|
"PULUMI_CONFIG_PASSPHRASE": "password",
|
|
}),
|
|
}
|
|
|
|
// initialize
|
|
s, err := NewStackInlineSource(ctx, stackName, pName, func(ctx *pulumi.Context) error {
|
|
c := config.New(ctx, "")
|
|
ctx.Export("exp_static", pulumi.String("foo"))
|
|
ctx.Export("exp_cfg", pulumi.String(c.Get("bar")))
|
|
ctx.Export("exp_secret", c.GetSecret("buzz"))
|
|
return nil
|
|
}, opts...)
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
err := os.Unsetenv("PULUMI_CONFIG_PASSPHRASE")
|
|
assert.Nil(t, err, "failed to unset EnvVar.")
|
|
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
passwordVal := "Password1234!"
|
|
err = s.SetConfig(ctx, "MySecretDatabasePassword", ConfigValue{Value: passwordVal, Secret: true})
|
|
if err != nil {
|
|
t.Errorf("setConfig failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// -- pulumi up --
|
|
res, err := s.Up(ctx)
|
|
if err != nil {
|
|
t.Errorf("up failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, "update", res.Summary.Kind)
|
|
assert.Equal(t, "succeeded", res.Summary.Result)
|
|
|
|
// -- get config --
|
|
conf, err := s.GetConfig(ctx, "MySecretDatabasePassword")
|
|
if err != nil {
|
|
t.Errorf("GetConfig failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, passwordVal, conf.Value)
|
|
assert.Equal(t, true, conf.Secret)
|
|
|
|
// -- pulumi destroy --
|
|
|
|
dRes, err := s.Destroy(ctx)
|
|
if err != nil {
|
|
t.Errorf("destroy failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, "destroy", dRes.Summary.Kind)
|
|
assert.Equal(t, "succeeded", dRes.Summary.Result)
|
|
}
|
|
|
|
func TestRemoveWithForce(t *testing.T) {
|
|
ctx := context.Background()
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
cfg := ConfigMap{
|
|
"bar": ConfigValue{
|
|
Value: "abc",
|
|
},
|
|
"buzz": ConfigValue{
|
|
Value: "secret",
|
|
Secret: true,
|
|
},
|
|
}
|
|
|
|
// initialize
|
|
pDir := filepath.Join(".", "test", "testproj")
|
|
s, err := NewStackLocalSource(ctx, stackName, pDir)
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
t.Errorf("failed to set config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// Set environment variables scoped to the workspace.
|
|
envvars := map[string]string{
|
|
"foo": "bar",
|
|
"barfoo": "foobar",
|
|
}
|
|
err = s.Workspace().SetEnvVars(envvars)
|
|
assert.Nil(t, err, "failed to set environment values")
|
|
envvars = s.Workspace().GetEnvVars()
|
|
assert.NotNil(t, envvars, "failed to get environment values after setting many")
|
|
|
|
s.Workspace().SetEnvVar("bar", "buzz")
|
|
envvars = s.Workspace().GetEnvVars()
|
|
assert.NotNil(t, envvars, "failed to get environment value after setting")
|
|
|
|
s.Workspace().UnsetEnvVar("bar")
|
|
envvars = s.Workspace().GetEnvVars()
|
|
assert.NotNil(t, envvars, "failed to get environment values after unsetting.")
|
|
|
|
// -- pulumi up --
|
|
res, err := s.Up(ctx)
|
|
if err != nil {
|
|
t.Errorf("up failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, 3, len(res.Outputs), "expected two plain outputs")
|
|
assert.Equal(t, "foo", res.Outputs["exp_static"].Value)
|
|
assert.False(t, res.Outputs["exp_static"].Secret)
|
|
assert.Equal(t, "abc", res.Outputs["exp_cfg"].Value)
|
|
assert.False(t, res.Outputs["exp_cfg"].Secret)
|
|
assert.Equal(t, "secret", res.Outputs["exp_secret"].Value)
|
|
assert.True(t, res.Outputs["exp_secret"].Secret)
|
|
assert.Equal(t, "update", res.Summary.Kind)
|
|
assert.Equal(t, "succeeded", res.Summary.Result)
|
|
|
|
const permalinkSearchStr = "https://app.pulumi.com"
|
|
var startRegex = regexp.MustCompile(permalinkSearchStr)
|
|
permalink, err := GetPermalink(res.StdOut)
|
|
assert.Nil(t, err, "failed to get permalink.")
|
|
assert.True(t, startRegex.MatchString(permalink))
|
|
|
|
if err = s.Workspace().RemoveStack(ctx, stackName, optremove.Force()); err != nil {
|
|
t.Errorf("remove stack with force failed")
|
|
t.FailNow()
|
|
}
|
|
|
|
// to make sure stack was removed
|
|
err = s.Workspace().SelectStack(ctx, s.Name())
|
|
assert.Error(t, err)
|
|
assert.True(t, strings.Contains(err.Error(), "no stack named"))
|
|
}
|
|
|
|
func TestNewStackLocalSource(t *testing.T) {
|
|
ctx := context.Background()
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
cfg := ConfigMap{
|
|
"bar": ConfigValue{
|
|
Value: "abc",
|
|
},
|
|
"buzz": ConfigValue{
|
|
Value: "secret",
|
|
Secret: true,
|
|
},
|
|
}
|
|
|
|
// initialize
|
|
pDir := filepath.Join(".", "test", "testproj")
|
|
s, err := NewStackLocalSource(ctx, stackName, pDir)
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
t.Errorf("failed to set config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// Set environment variables scoped to the workspace.
|
|
envvars := map[string]string{
|
|
"foo": "bar",
|
|
"barfoo": "foobar",
|
|
}
|
|
err = s.Workspace().SetEnvVars(envvars)
|
|
assert.Nil(t, err, "failed to set environment values")
|
|
envvars = s.Workspace().GetEnvVars()
|
|
assert.NotNil(t, envvars, "failed to get environment values after setting many")
|
|
|
|
s.Workspace().SetEnvVar("bar", "buzz")
|
|
envvars = s.Workspace().GetEnvVars()
|
|
assert.NotNil(t, envvars, "failed to get environment value after setting")
|
|
|
|
s.Workspace().UnsetEnvVar("bar")
|
|
envvars = s.Workspace().GetEnvVars()
|
|
assert.NotNil(t, envvars, "failed to get environment values after unsetting.")
|
|
|
|
// -- pulumi up --
|
|
res, err := s.Up(ctx, optup.UserAgent(agent))
|
|
if err != nil {
|
|
t.Errorf("up failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, 3, len(res.Outputs), "expected two plain outputs")
|
|
assert.Equal(t, "foo", res.Outputs["exp_static"].Value)
|
|
assert.False(t, res.Outputs["exp_static"].Secret)
|
|
assert.Equal(t, "abc", res.Outputs["exp_cfg"].Value)
|
|
assert.False(t, res.Outputs["exp_cfg"].Secret)
|
|
assert.Equal(t, "secret", res.Outputs["exp_secret"].Value)
|
|
assert.True(t, res.Outputs["exp_secret"].Secret)
|
|
assert.Equal(t, "update", res.Summary.Kind)
|
|
assert.Equal(t, "succeeded", res.Summary.Result)
|
|
|
|
const permalinkSearchStr = "https://app.pulumi.com"
|
|
var startRegex = regexp.MustCompile(permalinkSearchStr)
|
|
permalink, err := GetPermalink(res.StdOut)
|
|
assert.Nil(t, err, "failed to get permalink.")
|
|
assert.True(t, startRegex.MatchString(permalink))
|
|
|
|
// -- pulumi preview --
|
|
|
|
var previewEvents []events.EngineEvent
|
|
prevCh := make(chan events.EngineEvent)
|
|
go collectEvents(prevCh, &previewEvents)
|
|
prev, err := s.Preview(ctx, optpreview.EventStreams(prevCh), optpreview.UserAgent(agent))
|
|
if err != nil {
|
|
t.Errorf("preview failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, 1, prev.ChangeSummary[apitype.OpSame])
|
|
steps := countSteps(previewEvents)
|
|
assert.Equal(t, 1, steps)
|
|
|
|
// -- pulumi refresh --
|
|
|
|
ref, err := s.Refresh(ctx, optrefresh.UserAgent(agent))
|
|
|
|
if err != nil {
|
|
t.Errorf("refresh failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, "refresh", ref.Summary.Kind)
|
|
assert.Equal(t, "succeeded", ref.Summary.Result)
|
|
|
|
// -- pulumi destroy --
|
|
|
|
dRes, err := s.Destroy(ctx, optdestroy.UserAgent(agent))
|
|
if err != nil {
|
|
t.Errorf("destroy failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, "destroy", dRes.Summary.Kind)
|
|
assert.Equal(t, "succeeded", dRes.Summary.Result)
|
|
}
|
|
|
|
func TestUpsertStackLocalSource(t *testing.T) {
|
|
ctx := context.Background()
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
cfg := ConfigMap{
|
|
"bar": ConfigValue{
|
|
Value: "abc",
|
|
},
|
|
"buzz": ConfigValue{
|
|
Value: "secret",
|
|
Secret: true,
|
|
},
|
|
}
|
|
|
|
// initialize
|
|
pDir := filepath.Join(".", "test", "testproj")
|
|
s, err := UpsertStackLocalSource(ctx, stackName, pDir)
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
t.Errorf("failed to set config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// Set environment variables scoped to the workspace.
|
|
envvars := map[string]string{
|
|
"foo": "bar",
|
|
"barfoo": "foobar",
|
|
}
|
|
err = s.Workspace().SetEnvVars(envvars)
|
|
assert.Nil(t, err, "failed to set environment values")
|
|
envvars = s.Workspace().GetEnvVars()
|
|
assert.NotNil(t, envvars, "failed to get environment values after setting many")
|
|
|
|
s.Workspace().SetEnvVar("bar", "buzz")
|
|
envvars = s.Workspace().GetEnvVars()
|
|
assert.NotNil(t, envvars, "failed to get environment value after setting")
|
|
|
|
s.Workspace().UnsetEnvVar("bar")
|
|
envvars = s.Workspace().GetEnvVars()
|
|
assert.NotNil(t, envvars, "failed to get environment values after unsetting.")
|
|
|
|
// -- pulumi up --
|
|
res, err := s.Up(ctx)
|
|
if err != nil {
|
|
t.Errorf("up failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, 3, len(res.Outputs), "expected two plain outputs")
|
|
assert.Equal(t, "foo", res.Outputs["exp_static"].Value)
|
|
assert.False(t, res.Outputs["exp_static"].Secret)
|
|
assert.Equal(t, "abc", res.Outputs["exp_cfg"].Value)
|
|
assert.False(t, res.Outputs["exp_cfg"].Secret)
|
|
assert.Equal(t, "secret", res.Outputs["exp_secret"].Value)
|
|
assert.True(t, res.Outputs["exp_secret"].Secret)
|
|
assert.Equal(t, "update", res.Summary.Kind)
|
|
assert.Equal(t, "succeeded", res.Summary.Result)
|
|
|
|
// -- pulumi preview --
|
|
|
|
var previewEvents []events.EngineEvent
|
|
prevCh := make(chan events.EngineEvent)
|
|
go collectEvents(prevCh, &previewEvents)
|
|
prev, err := s.Preview(ctx, optpreview.EventStreams(prevCh))
|
|
if err != nil {
|
|
t.Errorf("preview failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, 1, prev.ChangeSummary[apitype.OpSame])
|
|
steps := countSteps(previewEvents)
|
|
assert.Equal(t, 1, steps)
|
|
|
|
// -- pulumi refresh --
|
|
ref, err := s.Refresh(ctx)
|
|
if err != nil {
|
|
t.Errorf("refresh failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, "refresh", ref.Summary.Kind)
|
|
assert.Equal(t, "succeeded", ref.Summary.Result)
|
|
|
|
// -- pulumi destroy --
|
|
dRes, err := s.Destroy(ctx)
|
|
if err != nil {
|
|
t.Errorf("destroy failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, "destroy", dRes.Summary.Kind)
|
|
assert.Equal(t, "succeeded", dRes.Summary.Result)
|
|
}
|
|
|
|
func rangeIn(low, hi int) int {
|
|
rand.Seed(time.Now().UnixNano())
|
|
return low + rand.Intn(hi-low) //nolint:gosec
|
|
}
|
|
|
|
func TestNewStackRemoteSource(t *testing.T) {
|
|
ctx := context.Background()
|
|
pName := "go_remote_proj"
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
cfg := ConfigMap{
|
|
"bar": ConfigValue{
|
|
Value: "abc",
|
|
},
|
|
"buzz": ConfigValue{
|
|
Value: "secret",
|
|
Secret: true,
|
|
},
|
|
}
|
|
repo := GitRepo{
|
|
URL: "https://github.com/pulumi/test-repo.git",
|
|
ProjectPath: "goproj",
|
|
}
|
|
|
|
// initialize
|
|
s, err := NewStackRemoteSource(ctx, stackName, repo)
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
t.Errorf("failed to set config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// -- pulumi up --
|
|
res, err := s.Up(ctx)
|
|
if err != nil {
|
|
t.Errorf("up failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, 3, len(res.Outputs), "expected two plain outputs")
|
|
assert.Equal(t, "foo", res.Outputs["exp_static"].Value)
|
|
assert.False(t, res.Outputs["exp_static"].Secret)
|
|
assert.Equal(t, "abc", res.Outputs["exp_cfg"].Value)
|
|
assert.False(t, res.Outputs["exp_cfg"].Secret)
|
|
assert.Equal(t, "secret", res.Outputs["exp_secret"].Value)
|
|
assert.True(t, res.Outputs["exp_secret"].Secret)
|
|
assert.Equal(t, "update", res.Summary.Kind)
|
|
assert.Equal(t, "succeeded", res.Summary.Result)
|
|
|
|
// -- pulumi preview --
|
|
|
|
var previewEvents []events.EngineEvent
|
|
prevCh := make(chan events.EngineEvent)
|
|
go collectEvents(prevCh, &previewEvents)
|
|
prev, err := s.Preview(ctx, optpreview.EventStreams(prevCh))
|
|
if err != nil {
|
|
t.Errorf("preview failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, 1, prev.ChangeSummary[apitype.OpSame])
|
|
steps := countSteps(previewEvents)
|
|
assert.Equal(t, 1, steps)
|
|
|
|
// -- pulumi refresh --
|
|
|
|
ref, err := s.Refresh(ctx)
|
|
|
|
if err != nil {
|
|
t.Errorf("refresh failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, "refresh", ref.Summary.Kind)
|
|
assert.Equal(t, "succeeded", ref.Summary.Result)
|
|
|
|
// -- pulumi destroy --
|
|
|
|
dRes, err := s.Destroy(ctx)
|
|
if err != nil {
|
|
t.Errorf("destroy failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, "destroy", dRes.Summary.Kind)
|
|
assert.Equal(t, "succeeded", dRes.Summary.Result)
|
|
}
|
|
|
|
func TestUpsertStackRemoteSource(t *testing.T) {
|
|
ctx := context.Background()
|
|
pName := "go_remote_proj"
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
cfg := ConfigMap{
|
|
"bar": ConfigValue{
|
|
Value: "abc",
|
|
},
|
|
"buzz": ConfigValue{
|
|
Value: "secret",
|
|
Secret: true,
|
|
},
|
|
}
|
|
repo := GitRepo{
|
|
URL: "https://github.com/pulumi/test-repo.git",
|
|
ProjectPath: "goproj",
|
|
}
|
|
|
|
// initialize
|
|
s, err := UpsertStackRemoteSource(ctx, stackName, repo)
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
t.Errorf("failed to set config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// -- pulumi up --
|
|
res, err := s.Up(ctx)
|
|
if err != nil {
|
|
t.Errorf("up failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, 3, len(res.Outputs), "expected two plain outputs")
|
|
assert.Equal(t, "foo", res.Outputs["exp_static"].Value)
|
|
assert.False(t, res.Outputs["exp_static"].Secret)
|
|
assert.Equal(t, "abc", res.Outputs["exp_cfg"].Value)
|
|
assert.False(t, res.Outputs["exp_cfg"].Secret)
|
|
assert.Equal(t, "secret", res.Outputs["exp_secret"].Value)
|
|
assert.True(t, res.Outputs["exp_secret"].Secret)
|
|
assert.Equal(t, "update", res.Summary.Kind)
|
|
assert.Equal(t, "succeeded", res.Summary.Result)
|
|
|
|
// -- pulumi preview --
|
|
|
|
var previewEvents []events.EngineEvent
|
|
prevCh := make(chan events.EngineEvent)
|
|
go collectEvents(prevCh, &previewEvents)
|
|
prev, err := s.Preview(ctx, optpreview.EventStreams(prevCh))
|
|
if err != nil {
|
|
t.Errorf("preview failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, 1, prev.ChangeSummary[apitype.OpSame])
|
|
steps := countSteps(previewEvents)
|
|
assert.Equal(t, 1, steps)
|
|
|
|
// -- pulumi refresh --
|
|
|
|
ref, err := s.Refresh(ctx)
|
|
|
|
if err != nil {
|
|
t.Errorf("refresh failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, "refresh", ref.Summary.Kind)
|
|
assert.Equal(t, "succeeded", ref.Summary.Result)
|
|
|
|
// -- pulumi destroy --
|
|
|
|
dRes, err := s.Destroy(ctx)
|
|
if err != nil {
|
|
t.Errorf("destroy failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, "destroy", dRes.Summary.Kind)
|
|
assert.Equal(t, "succeeded", dRes.Summary.Result)
|
|
}
|
|
|
|
func TestNewStackRemoteSourceWithSetup(t *testing.T) {
|
|
ctx := context.Background()
|
|
pName := "go_remote_proj"
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
cfg := ConfigMap{
|
|
"bar": ConfigValue{
|
|
Value: "abc",
|
|
},
|
|
"buzz": ConfigValue{
|
|
Value: "secret",
|
|
Secret: true,
|
|
},
|
|
}
|
|
binName := "examplesBinary"
|
|
repo := GitRepo{
|
|
URL: "https://github.com/pulumi/test-repo.git",
|
|
ProjectPath: "goproj",
|
|
Setup: func(ctx context.Context, workspace Workspace) error {
|
|
cmd := exec.Command("go", "build", "-o", binName, "main.go")
|
|
cmd.Dir = workspace.WorkDir()
|
|
return cmd.Run()
|
|
},
|
|
}
|
|
project := workspace.Project{
|
|
Name: tokens.PackageName(pName),
|
|
Runtime: workspace.NewProjectRuntimeInfo("go", map[string]interface{}{
|
|
"binary": binName,
|
|
}),
|
|
}
|
|
|
|
// initialize
|
|
s, err := NewStackRemoteSource(ctx, stackName, repo, Project(project))
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
t.Errorf("failed to set config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// -- pulumi up --
|
|
res, err := s.Up(ctx)
|
|
if err != nil {
|
|
t.Errorf("up failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, 3, len(res.Outputs), "expected two plain outputs")
|
|
assert.Equal(t, "foo", res.Outputs["exp_static"].Value)
|
|
assert.False(t, res.Outputs["exp_static"].Secret)
|
|
assert.Equal(t, "abc", res.Outputs["exp_cfg"].Value)
|
|
assert.False(t, res.Outputs["exp_cfg"].Secret)
|
|
assert.Equal(t, "secret", res.Outputs["exp_secret"].Value)
|
|
assert.True(t, res.Outputs["exp_secret"].Secret)
|
|
assert.Equal(t, "update", res.Summary.Kind)
|
|
assert.Equal(t, "succeeded", res.Summary.Result)
|
|
|
|
// -- pulumi preview --
|
|
|
|
var previewEvents []events.EngineEvent
|
|
prevCh := make(chan events.EngineEvent)
|
|
go collectEvents(prevCh, &previewEvents)
|
|
prev, err := s.Preview(ctx, optpreview.EventStreams(prevCh))
|
|
if err != nil {
|
|
t.Errorf("preview failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, 1, prev.ChangeSummary[apitype.OpSame])
|
|
steps := countSteps(previewEvents)
|
|
assert.Equal(t, 1, steps)
|
|
|
|
// -- pulumi refresh --
|
|
|
|
ref, err := s.Refresh(ctx)
|
|
|
|
if err != nil {
|
|
t.Errorf("refresh failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, "refresh", ref.Summary.Kind)
|
|
assert.Equal(t, "succeeded", ref.Summary.Result)
|
|
|
|
// -- pulumi destroy --
|
|
|
|
dRes, err := s.Destroy(ctx)
|
|
if err != nil {
|
|
t.Errorf("destroy failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, "destroy", dRes.Summary.Kind)
|
|
assert.Equal(t, "succeeded", dRes.Summary.Result)
|
|
}
|
|
|
|
func TestUpsertStackRemoteSourceWithSetup(t *testing.T) {
|
|
ctx := context.Background()
|
|
pName := "go_remote_proj"
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
cfg := ConfigMap{
|
|
"bar": ConfigValue{
|
|
Value: "abc",
|
|
},
|
|
"buzz": ConfigValue{
|
|
Value: "secret",
|
|
Secret: true,
|
|
},
|
|
}
|
|
binName := "examplesBinary"
|
|
repo := GitRepo{
|
|
URL: "https://github.com/pulumi/test-repo.git",
|
|
ProjectPath: "goproj",
|
|
Setup: func(ctx context.Context, workspace Workspace) error {
|
|
cmd := exec.Command("go", "build", "-o", binName, "main.go")
|
|
cmd.Dir = workspace.WorkDir()
|
|
return cmd.Run()
|
|
},
|
|
}
|
|
project := workspace.Project{
|
|
Name: tokens.PackageName(pName),
|
|
Runtime: workspace.NewProjectRuntimeInfo("go", map[string]interface{}{
|
|
"binary": binName,
|
|
}),
|
|
}
|
|
|
|
// initialize or select
|
|
s, err := UpsertStackRemoteSource(ctx, stackName, repo, Project(project))
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
t.Errorf("failed to set config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// -- pulumi up --
|
|
res, err := s.Up(ctx)
|
|
if err != nil {
|
|
t.Errorf("up failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, 3, len(res.Outputs), "expected two plain outputs")
|
|
assert.Equal(t, "foo", res.Outputs["exp_static"].Value)
|
|
assert.False(t, res.Outputs["exp_static"].Secret)
|
|
assert.Equal(t, "abc", res.Outputs["exp_cfg"].Value)
|
|
assert.False(t, res.Outputs["exp_cfg"].Secret)
|
|
assert.Equal(t, "secret", res.Outputs["exp_secret"].Value)
|
|
assert.True(t, res.Outputs["exp_secret"].Secret)
|
|
assert.Equal(t, "update", res.Summary.Kind)
|
|
assert.Equal(t, "succeeded", res.Summary.Result)
|
|
|
|
// -- pulumi preview --
|
|
|
|
var previewEvents []events.EngineEvent
|
|
prevCh := make(chan events.EngineEvent)
|
|
go collectEvents(prevCh, &previewEvents)
|
|
prev, err := s.Preview(ctx, optpreview.EventStreams(prevCh))
|
|
if err != nil {
|
|
t.Errorf("preview failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, 1, prev.ChangeSummary[apitype.OpSame])
|
|
steps := countSteps(previewEvents)
|
|
assert.Equal(t, 1, steps)
|
|
|
|
// -- pulumi refresh --
|
|
|
|
ref, err := s.Refresh(ctx)
|
|
|
|
if err != nil {
|
|
t.Errorf("refresh failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, "refresh", ref.Summary.Kind)
|
|
assert.Equal(t, "succeeded", ref.Summary.Result)
|
|
|
|
// -- pulumi destroy --
|
|
|
|
dRes, err := s.Destroy(ctx)
|
|
if err != nil {
|
|
t.Errorf("destroy failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, "destroy", dRes.Summary.Kind)
|
|
assert.Equal(t, "succeeded", dRes.Summary.Result)
|
|
}
|
|
|
|
func TestNewStackInlineSource(t *testing.T) {
|
|
ctx := context.Background()
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
cfg := ConfigMap{
|
|
"bar": ConfigValue{
|
|
Value: "abc",
|
|
},
|
|
"buzz": ConfigValue{
|
|
Value: "secret",
|
|
Secret: true,
|
|
},
|
|
}
|
|
|
|
// initialize
|
|
s, err := NewStackInlineSource(ctx, stackName, pName, func(ctx *pulumi.Context) error {
|
|
c := config.New(ctx, "")
|
|
ctx.Export("exp_static", pulumi.String("foo"))
|
|
ctx.Export("exp_cfg", pulumi.String(c.Get("bar")))
|
|
ctx.Export("exp_secret", c.GetSecret("buzz"))
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
t.Errorf("failed to set config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// -- pulumi up --
|
|
res, err := s.Up(ctx, optup.UserAgent(agent))
|
|
if err != nil {
|
|
t.Errorf("up failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, 3, len(res.Outputs), "expected two plain outputs")
|
|
assert.Equal(t, "foo", res.Outputs["exp_static"].Value)
|
|
assert.False(t, res.Outputs["exp_static"].Secret)
|
|
assert.Equal(t, "abc", res.Outputs["exp_cfg"].Value)
|
|
assert.False(t, res.Outputs["exp_cfg"].Secret)
|
|
assert.Equal(t, "secret", res.Outputs["exp_secret"].Value)
|
|
assert.True(t, res.Outputs["exp_secret"].Secret)
|
|
assert.Equal(t, "update", res.Summary.Kind)
|
|
assert.Equal(t, "succeeded", res.Summary.Result)
|
|
assert.Greater(t, res.Summary.Version, 0)
|
|
|
|
// -- pulumi preview --
|
|
|
|
var previewEvents []events.EngineEvent
|
|
prevCh := make(chan events.EngineEvent)
|
|
go collectEvents(prevCh, &previewEvents)
|
|
prev, err := s.Preview(ctx, optpreview.EventStreams(prevCh), optpreview.UserAgent(agent))
|
|
if err != nil {
|
|
t.Errorf("preview failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, 1, prev.ChangeSummary[apitype.OpSame])
|
|
steps := countSteps(previewEvents)
|
|
assert.Equal(t, 1, steps)
|
|
|
|
// -- pulumi refresh --
|
|
|
|
ref, err := s.Refresh(ctx, optrefresh.UserAgent(agent))
|
|
|
|
if err != nil {
|
|
t.Errorf("refresh failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, "refresh", ref.Summary.Kind)
|
|
assert.Equal(t, "succeeded", ref.Summary.Result)
|
|
|
|
// -- pulumi destroy --
|
|
|
|
dRes, err := s.Destroy(ctx, optdestroy.UserAgent(agent))
|
|
if err != nil {
|
|
t.Errorf("destroy failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, "destroy", dRes.Summary.Kind)
|
|
assert.Equal(t, "succeeded", dRes.Summary.Result)
|
|
}
|
|
|
|
func TestUpsertStackInlineSource(t *testing.T) {
|
|
ctx := context.Background()
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
cfg := ConfigMap{
|
|
"bar": ConfigValue{
|
|
Value: "abc",
|
|
},
|
|
"buzz": ConfigValue{
|
|
Value: "secret",
|
|
Secret: true,
|
|
},
|
|
}
|
|
|
|
// initialize or select
|
|
s, err := UpsertStackInlineSource(ctx, stackName, pName, func(ctx *pulumi.Context) error {
|
|
c := config.New(ctx, "")
|
|
ctx.Export("exp_static", pulumi.String("foo"))
|
|
ctx.Export("exp_cfg", pulumi.String(c.Get("bar")))
|
|
ctx.Export("exp_secret", c.GetSecret("buzz"))
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
t.Errorf("failed to set config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// -- pulumi up --
|
|
res, err := s.Up(ctx)
|
|
if err != nil {
|
|
t.Errorf("up failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, 3, len(res.Outputs), "expected two plain outputs")
|
|
assert.Equal(t, "foo", res.Outputs["exp_static"].Value)
|
|
assert.False(t, res.Outputs["exp_static"].Secret)
|
|
assert.Equal(t, "abc", res.Outputs["exp_cfg"].Value)
|
|
assert.False(t, res.Outputs["exp_cfg"].Secret)
|
|
assert.Equal(t, "secret", res.Outputs["exp_secret"].Value)
|
|
assert.True(t, res.Outputs["exp_secret"].Secret)
|
|
assert.Equal(t, "update", res.Summary.Kind)
|
|
assert.Equal(t, "succeeded", res.Summary.Result)
|
|
|
|
// -- pulumi preview --
|
|
|
|
var previewEvents []events.EngineEvent
|
|
prevCh := make(chan events.EngineEvent)
|
|
go collectEvents(prevCh, &previewEvents)
|
|
prev, err := s.Preview(ctx, optpreview.EventStreams(prevCh))
|
|
if err != nil {
|
|
t.Errorf("preview failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, 1, prev.ChangeSummary[apitype.OpSame])
|
|
steps := countSteps(previewEvents)
|
|
assert.Equal(t, 1, steps)
|
|
|
|
// -- pulumi refresh --
|
|
|
|
ref, err := s.Refresh(ctx)
|
|
|
|
if err != nil {
|
|
t.Errorf("refresh failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, "refresh", ref.Summary.Kind)
|
|
assert.Equal(t, "succeeded", ref.Summary.Result)
|
|
|
|
// -- pulumi destroy --
|
|
|
|
dRes, err := s.Destroy(ctx)
|
|
if err != nil {
|
|
t.Errorf("destroy failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, "destroy", dRes.Summary.Kind)
|
|
assert.Equal(t, "succeeded", dRes.Summary.Result)
|
|
}
|
|
|
|
func TestNestedStackFails(t *testing.T) {
|
|
// FIXME: see https://github.com/pulumi/pulumi/issues/5301
|
|
t.Skip("skipping test, see pulumi/pulumi#5301")
|
|
testCtx := context.Background()
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
parentstackName := FullyQualifiedStackName(pulumiOrg, "parent", sName)
|
|
nestedstackName := FullyQualifiedStackName(pulumiOrg, "nested", sName)
|
|
|
|
nestedStack, err := NewStackInlineSource(testCtx, nestedstackName, "nested", func(ctx *pulumi.Context) error {
|
|
ctx.Export("exp_static", pulumi.String("foo"))
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// initialize
|
|
s, err := NewStackInlineSource(testCtx, parentstackName, "parent", func(ctx *pulumi.Context) error {
|
|
_, err := nestedStack.Up(testCtx)
|
|
return err
|
|
})
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(testCtx, s.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
|
|
err = nestedStack.Workspace().RemoveStack(testCtx, nestedStack.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
result, err := s.Up(testCtx)
|
|
|
|
t.Log(result)
|
|
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "nested stack operations are not supported")
|
|
|
|
// -- pulumi destroy --
|
|
|
|
dRes, err := s.Destroy(testCtx)
|
|
if err != nil {
|
|
t.Errorf("destroy failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, "destroy", dRes.Summary.Kind)
|
|
assert.Equal(t, "succeeded", dRes.Summary.Result)
|
|
|
|
dRes, err = nestedStack.Destroy(testCtx)
|
|
if err != nil {
|
|
t.Errorf("destroy failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, "destroy", dRes.Summary.Kind)
|
|
assert.Equal(t, "succeeded", dRes.Summary.Result)
|
|
}
|
|
|
|
func TestProgressStreams(t *testing.T) {
|
|
ctx := context.Background()
|
|
pName := "inline_progress_streams"
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
cfg := ConfigMap{
|
|
"bar": ConfigValue{
|
|
Value: "abc",
|
|
},
|
|
"buzz": ConfigValue{
|
|
Value: "secret",
|
|
Secret: true,
|
|
},
|
|
}
|
|
|
|
// initialize
|
|
s, err := NewStackInlineSource(ctx, stackName, pName, func(ctx *pulumi.Context) error {
|
|
c := config.New(ctx, "")
|
|
ctx.Export("exp_static", pulumi.String("foo"))
|
|
ctx.Export("exp_cfg", pulumi.String(c.Get("bar")))
|
|
ctx.Export("exp_secret", c.GetSecret("buzz"))
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
t.Errorf("failed to set config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// -- pulumi up --
|
|
var upOut bytes.Buffer
|
|
res, err := s.Up(ctx, optup.ProgressStreams(&upOut))
|
|
if err != nil {
|
|
t.Errorf("up failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, upOut.String(), res.StdOut, "expected stdout writers to contain same contents")
|
|
|
|
// -- pulumi refresh --
|
|
var refOut bytes.Buffer
|
|
ref, err := s.Refresh(ctx, optrefresh.ProgressStreams(&refOut))
|
|
|
|
if err != nil {
|
|
t.Errorf("refresh failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, refOut.String(), ref.StdOut, "expected stdout writers to contain same contents")
|
|
|
|
// -- pulumi destroy --
|
|
var desOut bytes.Buffer
|
|
dRes, err := s.Destroy(ctx, optdestroy.ProgressStreams(&desOut))
|
|
if err != nil {
|
|
t.Errorf("destroy failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, desOut.String(), dRes.StdOut, "expected stdout writers to contain same contents")
|
|
}
|
|
|
|
func TestImportExportStack(t *testing.T) {
|
|
ctx := context.Background()
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
cfg := ConfigMap{
|
|
"bar": ConfigValue{
|
|
Value: "abc",
|
|
},
|
|
"buzz": ConfigValue{
|
|
Value: "secret",
|
|
Secret: true,
|
|
},
|
|
}
|
|
|
|
// initialize
|
|
s, err := NewStackInlineSource(ctx, stackName, pName, func(ctx *pulumi.Context) error {
|
|
c := config.New(ctx, "")
|
|
ctx.Export("exp_static", pulumi.String("foo"))
|
|
ctx.Export("exp_cfg", pulumi.String(c.Get("bar")))
|
|
ctx.Export("exp_secret", c.GetSecret("buzz"))
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
t.Errorf("failed to set config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// -- pulumi up --
|
|
_, err = s.Up(ctx)
|
|
if err != nil {
|
|
t.Errorf("up failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// -- pulumi stack export --
|
|
state, err := s.Export(ctx)
|
|
if err != nil {
|
|
t.Errorf("export failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// -- pulumi stack import --
|
|
err = s.Import(ctx, state)
|
|
if err != nil {
|
|
t.Errorf("import failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// -- pulumi destroy --
|
|
|
|
dRes, err := s.Destroy(ctx)
|
|
if err != nil {
|
|
t.Errorf("destroy failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, "destroy", dRes.Summary.Kind)
|
|
assert.Equal(t, "succeeded", dRes.Summary.Result)
|
|
}
|
|
|
|
func TestNestedConfig(t *testing.T) {
|
|
if getTestOrg() != "pulumi-test" {
|
|
return
|
|
}
|
|
ctx := context.Background()
|
|
stackName := FullyQualifiedStackName(pulumiOrg, "nested_config", "dev")
|
|
|
|
// initialize
|
|
pDir := filepath.Join(".", "test", "nested_config")
|
|
s, err := UpsertStackLocalSource(ctx, stackName, pDir)
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// Also retrieve the stack settings directly from the yaml file and
|
|
// make sure the config agrees with the config loaded by Pulumi.
|
|
stackSettings, err := s.Workspace().StackSettings(ctx, stackName)
|
|
require.NoError(t, err)
|
|
confKeys := map[string]bool{}
|
|
for k := range stackSettings.Config {
|
|
confKeys[k.String()] = true
|
|
}
|
|
|
|
allConfig, err := s.GetAllConfig(ctx)
|
|
if err != nil {
|
|
t.Errorf("failed to get config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
allConfKeys := map[string]bool{}
|
|
for k := range allConfig {
|
|
allConfKeys[k] = true
|
|
}
|
|
assert.Equal(t, confKeys, allConfKeys)
|
|
assert.NotEmpty(t, confKeys)
|
|
|
|
outerVal, ok := allConfig["nested_config:outer"]
|
|
assert.True(t, ok)
|
|
assert.True(t, outerVal.Secret)
|
|
assert.JSONEq(t, "{\"inner\":\"my_secret\", \"other\": \"something_else\"}", outerVal.Value)
|
|
|
|
listVal, ok := allConfig["nested_config:myList"]
|
|
assert.True(t, ok)
|
|
assert.False(t, listVal.Secret)
|
|
assert.JSONEq(t, "[\"one\",\"two\",\"three\"]", listVal.Value)
|
|
|
|
outer, err := s.GetConfig(ctx, "outer")
|
|
if err != nil {
|
|
t.Errorf("failed to get config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.True(t, outer.Secret)
|
|
assert.JSONEq(t, "{\"inner\":\"my_secret\", \"other\": \"something_else\"}", outer.Value)
|
|
|
|
list, err := s.GetConfig(ctx, "myList")
|
|
if err != nil {
|
|
t.Errorf("failed to get config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.False(t, list.Secret)
|
|
assert.JSONEq(t, "[\"one\",\"two\",\"three\"]", list.Value)
|
|
}
|
|
|
|
func TestStructuredOutput(t *testing.T) {
|
|
ctx := context.Background()
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
cfg := ConfigMap{
|
|
"bar": ConfigValue{
|
|
Value: "abc",
|
|
},
|
|
"buzz": ConfigValue{
|
|
Value: "secret",
|
|
Secret: true,
|
|
},
|
|
}
|
|
|
|
// initialize
|
|
pDir := filepath.Join(".", "test", "testproj")
|
|
s, err := UpsertStackLocalSource(ctx, stackName, pDir)
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
t.Errorf("failed to set config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// Set environment variables scoped to the workspace.
|
|
envvars := map[string]string{
|
|
"foo": "bar",
|
|
"barfoo": "foobar",
|
|
}
|
|
err = s.Workspace().SetEnvVars(envvars)
|
|
assert.Nil(t, err, "failed to set environment values")
|
|
envvars = s.Workspace().GetEnvVars()
|
|
assert.NotNil(t, envvars, "failed to get environment values after setting many")
|
|
|
|
s.Workspace().SetEnvVar("bar", "buzz")
|
|
envvars = s.Workspace().GetEnvVars()
|
|
assert.NotNil(t, envvars, "failed to get environment value after setting")
|
|
|
|
s.Workspace().UnsetEnvVar("bar")
|
|
envvars = s.Workspace().GetEnvVars()
|
|
assert.NotNil(t, envvars, "failed to get environment values after unsetting.")
|
|
|
|
// -- pulumi up --
|
|
var upEvents []events.EngineEvent
|
|
upCh := make(chan events.EngineEvent)
|
|
go collectEvents(upCh, &upEvents)
|
|
res, err := s.Up(ctx, optup.EventStreams(upCh))
|
|
if err != nil {
|
|
t.Errorf("up failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, 3, len(res.Outputs), "expected two plain outputs")
|
|
assert.Equal(t, "foo", res.Outputs["exp_static"].Value)
|
|
assert.False(t, res.Outputs["exp_static"].Secret)
|
|
assert.Equal(t, "abc", res.Outputs["exp_cfg"].Value)
|
|
assert.False(t, res.Outputs["exp_cfg"].Secret)
|
|
assert.Equal(t, "secret", res.Outputs["exp_secret"].Value)
|
|
assert.True(t, res.Outputs["exp_secret"].Secret)
|
|
assert.Equal(t, "update", res.Summary.Kind)
|
|
assert.Equal(t, "succeeded", res.Summary.Result)
|
|
assert.True(t, containsSummary(upEvents))
|
|
|
|
// -- pulumi preview --
|
|
var previewEvents []events.EngineEvent
|
|
prevCh := make(chan events.EngineEvent)
|
|
go collectEvents(prevCh, &previewEvents)
|
|
prev, err := s.Preview(ctx, optpreview.EventStreams(prevCh))
|
|
if err != nil {
|
|
t.Errorf("preview failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, 1, prev.ChangeSummary[apitype.OpSame])
|
|
steps := countSteps(previewEvents)
|
|
assert.Equal(t, 1, steps)
|
|
assert.True(t, containsSummary(previewEvents))
|
|
|
|
// -- pulumi refresh --
|
|
var refreshEvents []events.EngineEvent
|
|
refCh := make(chan events.EngineEvent)
|
|
go collectEvents(refCh, &refreshEvents)
|
|
ref, err := s.Refresh(ctx, optrefresh.EventStreams(refCh))
|
|
if err != nil {
|
|
t.Errorf("refresh failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, "refresh", ref.Summary.Kind)
|
|
assert.Equal(t, "succeeded", ref.Summary.Result)
|
|
assert.True(t, containsSummary(refreshEvents))
|
|
|
|
// -- pulumi destroy --
|
|
var destroyEvents []events.EngineEvent
|
|
desCh := make(chan events.EngineEvent)
|
|
go collectEvents(desCh, &destroyEvents)
|
|
dRes, err := s.Destroy(ctx, optdestroy.EventStreams(desCh))
|
|
if err != nil {
|
|
t.Errorf("destroy failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, "destroy", dRes.Summary.Kind)
|
|
assert.Equal(t, "succeeded", dRes.Summary.Result)
|
|
assert.True(t, containsSummary(destroyEvents))
|
|
}
|
|
|
|
func TestSupportsStackOutputs(t *testing.T) {
|
|
ctx := context.Background()
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
cfg := ConfigMap{
|
|
"bar": ConfigValue{
|
|
Value: "abc",
|
|
},
|
|
"buzz": ConfigValue{
|
|
Value: "secret",
|
|
Secret: true,
|
|
},
|
|
}
|
|
|
|
// initialize
|
|
s, err := NewStackInlineSource(ctx, stackName, pName, func(ctx *pulumi.Context) error {
|
|
c := config.New(ctx, "")
|
|
|
|
nestedObj := pulumi.Map{
|
|
"not_a_secret": pulumi.String("foo"),
|
|
"is_a_secret": pulumi.ToSecret("iamsecret"),
|
|
}
|
|
ctx.Export("exp_static", pulumi.String("foo"))
|
|
ctx.Export("exp_cfg", pulumi.String(c.Get("bar")))
|
|
ctx.Export("exp_secret", c.GetSecret("buzz"))
|
|
ctx.Export("nested_obj", nestedObj)
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
t.Errorf("failed to set config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assertOutputs := func(t *testing.T, outputs OutputMap) {
|
|
assert.Equal(t, 4, len(outputs), "expected four outputs")
|
|
assert.Equal(t, "foo", outputs["exp_static"].Value)
|
|
assert.False(t, outputs["exp_static"].Secret)
|
|
assert.Equal(t, "abc", outputs["exp_cfg"].Value)
|
|
assert.False(t, outputs["exp_cfg"].Secret)
|
|
assert.Equal(t, "secret", outputs["exp_secret"].Value)
|
|
assert.True(t, outputs["exp_secret"].Secret)
|
|
assert.Equal(t, map[string]interface{}{
|
|
"is_a_secret": "iamsecret",
|
|
"not_a_secret": "foo",
|
|
}, outputs["nested_obj"].Value)
|
|
assert.True(t, outputs["nested_obj"].Secret)
|
|
}
|
|
|
|
initialOutputs, err := s.Outputs(ctx)
|
|
if err != nil {
|
|
t.Errorf("failed to get initial outputs, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, 0, len(initialOutputs))
|
|
|
|
// -- pulumi up --
|
|
res, err := s.Up(ctx)
|
|
if err != nil {
|
|
t.Errorf("up failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, "update", res.Summary.Kind)
|
|
assert.Equal(t, "succeeded", res.Summary.Result)
|
|
assert.Greater(t, res.Summary.Version, 0)
|
|
assertOutputs(t, res.Outputs)
|
|
|
|
outputsAfterUp, err := s.Outputs(ctx)
|
|
if err != nil {
|
|
t.Errorf("failed to get outputs after up, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assertOutputs(t, outputsAfterUp)
|
|
|
|
// -- pulumi destroy --
|
|
dRes, err := s.Destroy(ctx)
|
|
if err != nil {
|
|
t.Errorf("destroy failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, "destroy", dRes.Summary.Kind)
|
|
assert.Equal(t, "succeeded", dRes.Summary.Result)
|
|
|
|
outputsAfterDestroy, err := s.Outputs(ctx)
|
|
if err != nil {
|
|
t.Errorf("failed to get outputs after destroy, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.Equal(t, 0, len(outputsAfterDestroy))
|
|
}
|
|
|
|
func TestPulumiVersion(t *testing.T) {
|
|
ctx := context.Background()
|
|
ws, err := NewLocalWorkspace(ctx)
|
|
if err != nil {
|
|
t.Errorf("failed to create workspace, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
version := ws.PulumiVersion()
|
|
assert.NotEqual(t, "v0.0.0", version)
|
|
assert.Regexp(t, `(\d+\.)(\d+\.)(\d+)(-.*)?`, version)
|
|
}
|
|
|
|
const PARSE = `Unable to parse`
|
|
const MAJOR = `Major version mismatch.`
|
|
const MINIMUM = `Minimum version requirement failed.`
|
|
|
|
var minVersionTests = []struct {
|
|
name string
|
|
currentVersion string
|
|
expectedError string
|
|
optOut bool
|
|
}{
|
|
{
|
|
"higher_major",
|
|
"100.0.0",
|
|
MAJOR,
|
|
false,
|
|
},
|
|
{
|
|
"lower_major",
|
|
"1.0.0",
|
|
MINIMUM,
|
|
false,
|
|
},
|
|
{
|
|
"higher_minor",
|
|
"2.2.0",
|
|
MINIMUM,
|
|
false,
|
|
},
|
|
{
|
|
"lower_minor",
|
|
"2.1.0",
|
|
MINIMUM,
|
|
false,
|
|
},
|
|
{
|
|
"equal_minor_higher_patch",
|
|
"2.2.2",
|
|
MINIMUM,
|
|
false,
|
|
},
|
|
{
|
|
"equal_minor_equal_patch",
|
|
"2.2.1",
|
|
MINIMUM,
|
|
false,
|
|
},
|
|
{
|
|
"equal_minor_lower_patch",
|
|
"2.2.0",
|
|
MINIMUM,
|
|
false,
|
|
},
|
|
{
|
|
"equal_minor_equal_patch_prerelease",
|
|
// Note that prerelease < release so this case will error
|
|
"2.21.1-alpha.1234",
|
|
MINIMUM,
|
|
false,
|
|
},
|
|
{
|
|
"opt_out_of_check_would_fail_otherwise",
|
|
"2.2.0",
|
|
"",
|
|
true,
|
|
},
|
|
{
|
|
"opt_out_of_check_would_succeed_otherwise",
|
|
"2.2.0",
|
|
"",
|
|
true,
|
|
},
|
|
{
|
|
"unparsable_version",
|
|
"invalid",
|
|
PARSE,
|
|
false,
|
|
},
|
|
{
|
|
"opt_out_unparsable_version",
|
|
"invalid",
|
|
"",
|
|
true,
|
|
},
|
|
}
|
|
|
|
func TestMinimumVersion(t *testing.T) {
|
|
for _, tt := range minVersionTests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
minVersion := semver.Version{Major: 2, Minor: 21, Patch: 1}
|
|
|
|
_, err := parseAndValidatePulumiVersion(minVersion, tt.currentVersion, tt.optOut)
|
|
|
|
if tt.expectedError != "" {
|
|
assert.Error(t, err)
|
|
assert.Regexp(t, tt.expectedError, err.Error())
|
|
} else {
|
|
assert.Nil(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestProjectSettingsRespected(t *testing.T) {
|
|
ctx := context.Background()
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
pName := "correct_project"
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
badProjectName := "project_was_overwritten"
|
|
stack, err := NewStackInlineSource(ctx, stackName, badProjectName, func(ctx *pulumi.Context) error {
|
|
return nil
|
|
}, WorkDir(filepath.Join(".", "test", pName)))
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = stack.Workspace().RemoveStack(ctx, stack.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
assert.Nil(t, err)
|
|
projectSettings, err := stack.workspace.ProjectSettings(ctx)
|
|
assert.Nil(t, err)
|
|
assert.Equal(t, projectSettings.Name, tokens.PackageName("correct_project"))
|
|
assert.Equal(t, *projectSettings.Description, "This is a description")
|
|
}
|
|
|
|
func TestSaveStackSettings(t *testing.T) {
|
|
ctx := context.Background()
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
|
|
opts := []LocalWorkspaceOption{
|
|
SecretsProvider("passphrase"),
|
|
EnvVars(map[string]string{
|
|
"PULUMI_CONFIG_PASSPHRASE": "password",
|
|
}),
|
|
}
|
|
|
|
// initialize
|
|
s, err := NewStackInlineSource(ctx, stackName, pName, func(ctx *pulumi.Context) error {
|
|
c := config.New(ctx, "")
|
|
ctx.Export("exp_static", pulumi.String("foo"))
|
|
ctx.Export("exp_cfg", pulumi.String(c.Get("bar")))
|
|
ctx.Export("exp_secret", c.GetSecret("buzz"))
|
|
return nil
|
|
}, opts...)
|
|
require.NoError(t, err, "failed to initialize stack, err: %v", err)
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
// first load settings for created stack
|
|
stackConfig, err := s.Workspace().StackSettings(ctx, stackName)
|
|
require.NoError(t, err)
|
|
stackConfig.SecretsProvider = "passphrase"
|
|
assert.NoError(t, s.Workspace().SaveStackSettings(ctx, stackName, stackConfig))
|
|
|
|
// -- pulumi up --
|
|
|
|
res, err := s.Up(ctx)
|
|
if err != nil {
|
|
t.Errorf("up failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, "update", res.Summary.Kind)
|
|
assert.Equal(t, "succeeded", res.Summary.Result)
|
|
|
|
reloaded, err := s.workspace.StackSettings(ctx, stackName)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, stackConfig, reloaded)
|
|
|
|
// -- pulumi destroy --
|
|
|
|
dRes, err := s.Destroy(ctx)
|
|
if err != nil {
|
|
t.Errorf("destroy failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
assert.Equal(t, "destroy", dRes.Summary.Kind)
|
|
assert.Equal(t, "succeeded", dRes.Summary.Result)
|
|
}
|
|
|
|
func TestConfigSecretWarnings(t *testing.T) {
|
|
// TODO[pulumi/pulumi#7127]: Re-enabled the warning.
|
|
t.Skip("Temporarily skipping test until we've re-enabled the warning - pulumi/pulumi#7127")
|
|
ctx := context.Background()
|
|
sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999))
|
|
stackName := FullyQualifiedStackName(pulumiOrg, pName, sName)
|
|
cfg := ConfigMap{
|
|
"plainstr1": ConfigValue{Value: "1"},
|
|
"plainstr2": ConfigValue{Value: "2"},
|
|
"plainstr3": ConfigValue{Value: "3"},
|
|
"plainstr4": ConfigValue{Value: "4"},
|
|
"plainstr5": ConfigValue{Value: "5"},
|
|
"plainstr6": ConfigValue{Value: "6"},
|
|
"plainstr7": ConfigValue{Value: "7"},
|
|
"plainstr8": ConfigValue{Value: "8"},
|
|
"plainstr9": ConfigValue{Value: "9"},
|
|
"plainstr10": ConfigValue{Value: "10"},
|
|
"plainstr11": ConfigValue{Value: "11"},
|
|
"plainstr12": ConfigValue{Value: "12"},
|
|
"plainbool1": ConfigValue{Value: "true"},
|
|
"plainbool2": ConfigValue{Value: "true"},
|
|
"plainbool3": ConfigValue{Value: "true"},
|
|
"plainbool4": ConfigValue{Value: "true"},
|
|
"plainbool5": ConfigValue{Value: "true"},
|
|
"plainbool6": ConfigValue{Value: "true"},
|
|
"plainbool7": ConfigValue{Value: "true"},
|
|
"plainbool8": ConfigValue{Value: "true"},
|
|
"plainbool9": ConfigValue{Value: "true"},
|
|
"plainbool10": ConfigValue{Value: "true"},
|
|
"plainbool11": ConfigValue{Value: "true"},
|
|
"plainbool12": ConfigValue{Value: "true"},
|
|
"plainint1": ConfigValue{Value: "1"},
|
|
"plainint2": ConfigValue{Value: "2"},
|
|
"plainint3": ConfigValue{Value: "3"},
|
|
"plainint4": ConfigValue{Value: "4"},
|
|
"plainint5": ConfigValue{Value: "5"},
|
|
"plainint6": ConfigValue{Value: "6"},
|
|
"plainint7": ConfigValue{Value: "7"},
|
|
"plainint8": ConfigValue{Value: "8"},
|
|
"plainint9": ConfigValue{Value: "9"},
|
|
"plainint10": ConfigValue{Value: "10"},
|
|
"plainint11": ConfigValue{Value: "11"},
|
|
"plainint12": ConfigValue{Value: "12"},
|
|
"plainfloat1": ConfigValue{Value: "1.1"},
|
|
"plainfloat2": ConfigValue{Value: "2.2"},
|
|
"plainfloat3": ConfigValue{Value: "3.3"},
|
|
"plainfloat4": ConfigValue{Value: "4.4"},
|
|
"plainfloat5": ConfigValue{Value: "5.5"},
|
|
"plainfloat6": ConfigValue{Value: "6.6"},
|
|
"plainfloat7": ConfigValue{Value: "7.7"},
|
|
"plainfloat8": ConfigValue{Value: "8.8"},
|
|
"plainfloat9": ConfigValue{Value: "9.9"},
|
|
"plainfloat10": ConfigValue{Value: "10.1"},
|
|
"plainfloat11": ConfigValue{Value: "11.11"},
|
|
"plainfloat12": ConfigValue{Value: "12.12"},
|
|
"plainobj1": ConfigValue{Value: "{}"},
|
|
"plainobj2": ConfigValue{Value: "{}"},
|
|
"plainobj3": ConfigValue{Value: "{}"},
|
|
"plainobj4": ConfigValue{Value: "{}"},
|
|
"plainobj5": ConfigValue{Value: "{}"},
|
|
"plainobj6": ConfigValue{Value: "{}"},
|
|
"plainobj7": ConfigValue{Value: "{}"},
|
|
"plainobj8": ConfigValue{Value: "{}"},
|
|
"plainobj9": ConfigValue{Value: "{}"},
|
|
"plainobj10": ConfigValue{Value: "{}"},
|
|
"plainobj11": ConfigValue{Value: "{}"},
|
|
"plainobj12": ConfigValue{Value: "{}"},
|
|
"str1": ConfigValue{Value: "1", Secret: true},
|
|
"str2": ConfigValue{Value: "2", Secret: true},
|
|
"str3": ConfigValue{Value: "3", Secret: true},
|
|
"str4": ConfigValue{Value: "4", Secret: true},
|
|
"str5": ConfigValue{Value: "5", Secret: true},
|
|
"str6": ConfigValue{Value: "6", Secret: true},
|
|
"str7": ConfigValue{Value: "7", Secret: true},
|
|
"str8": ConfigValue{Value: "8", Secret: true},
|
|
"str9": ConfigValue{Value: "9", Secret: true},
|
|
"str10": ConfigValue{Value: "10", Secret: true},
|
|
"str11": ConfigValue{Value: "11", Secret: true},
|
|
"str12": ConfigValue{Value: "12", Secret: true},
|
|
"bool1": ConfigValue{Value: "true", Secret: true},
|
|
"bool2": ConfigValue{Value: "true", Secret: true},
|
|
"bool3": ConfigValue{Value: "true", Secret: true},
|
|
"bool4": ConfigValue{Value: "true", Secret: true},
|
|
"bool5": ConfigValue{Value: "true", Secret: true},
|
|
"bool6": ConfigValue{Value: "true", Secret: true},
|
|
"bool7": ConfigValue{Value: "true", Secret: true},
|
|
"bool8": ConfigValue{Value: "true", Secret: true},
|
|
"bool9": ConfigValue{Value: "true", Secret: true},
|
|
"bool10": ConfigValue{Value: "true", Secret: true},
|
|
"bool11": ConfigValue{Value: "true", Secret: true},
|
|
"bool12": ConfigValue{Value: "true", Secret: true},
|
|
"int1": ConfigValue{Value: "1", Secret: true},
|
|
"int2": ConfigValue{Value: "2", Secret: true},
|
|
"int3": ConfigValue{Value: "3", Secret: true},
|
|
"int4": ConfigValue{Value: "4", Secret: true},
|
|
"int5": ConfigValue{Value: "5", Secret: true},
|
|
"int6": ConfigValue{Value: "6", Secret: true},
|
|
"int7": ConfigValue{Value: "7", Secret: true},
|
|
"int8": ConfigValue{Value: "8", Secret: true},
|
|
"int9": ConfigValue{Value: "9", Secret: true},
|
|
"int10": ConfigValue{Value: "10", Secret: true},
|
|
"int11": ConfigValue{Value: "11", Secret: true},
|
|
"int12": ConfigValue{Value: "12", Secret: true},
|
|
"float1": ConfigValue{Value: "1.1", Secret: true},
|
|
"float2": ConfigValue{Value: "2.2", Secret: true},
|
|
"float3": ConfigValue{Value: "3.3", Secret: true},
|
|
"float4": ConfigValue{Value: "4.4", Secret: true},
|
|
"float5": ConfigValue{Value: "5.5", Secret: true},
|
|
"float6": ConfigValue{Value: "6.6", Secret: true},
|
|
"float7": ConfigValue{Value: "7.7", Secret: true},
|
|
"float8": ConfigValue{Value: "8.8", Secret: true},
|
|
"float9": ConfigValue{Value: "9.9", Secret: true},
|
|
"float10": ConfigValue{Value: "10.1", Secret: true},
|
|
"float11": ConfigValue{Value: "11.11", Secret: true},
|
|
"float12": ConfigValue{Value: "12.12", Secret: true},
|
|
"obj1": ConfigValue{Value: "{}", Secret: true},
|
|
"obj2": ConfigValue{Value: "{}", Secret: true},
|
|
"obj3": ConfigValue{Value: "{}", Secret: true},
|
|
"obj4": ConfigValue{Value: "{}", Secret: true},
|
|
"obj5": ConfigValue{Value: "{}", Secret: true},
|
|
"obj6": ConfigValue{Value: "{}", Secret: true},
|
|
"obj7": ConfigValue{Value: "{}", Secret: true},
|
|
"obj8": ConfigValue{Value: "{}", Secret: true},
|
|
"obj9": ConfigValue{Value: "{}", Secret: true},
|
|
"obj10": ConfigValue{Value: "{}", Secret: true},
|
|
"obj11": ConfigValue{Value: "{}", Secret: true},
|
|
"obj12": ConfigValue{Value: "{}", Secret: true},
|
|
}
|
|
|
|
// initialize
|
|
//nolint:errcheck
|
|
s, err := NewStackInlineSource(ctx, stackName, pName, func(ctx *pulumi.Context) error {
|
|
c := config.New(ctx, "")
|
|
|
|
config.Get(ctx, "plainstr1")
|
|
config.Require(ctx, "plainstr2")
|
|
config.Try(ctx, "plainstr3")
|
|
config.GetSecret(ctx, "plainstr4")
|
|
config.RequireSecret(ctx, "plainstr5")
|
|
config.TrySecret(ctx, "plainstr6")
|
|
c.Get("plainstr7")
|
|
c.Require("plainstr8")
|
|
c.Try("plainstr9")
|
|
c.GetSecret("plainstr10")
|
|
c.RequireSecret("plainstr11")
|
|
c.TrySecret("plainstr12")
|
|
|
|
config.GetBool(ctx, "plainbool1")
|
|
config.RequireBool(ctx, "plainbool2")
|
|
config.TryBool(ctx, "plainbool3")
|
|
config.GetSecretBool(ctx, "plainbool4")
|
|
config.RequireSecretBool(ctx, "plainbool5")
|
|
config.TrySecretBool(ctx, "plainbool6")
|
|
c.GetBool("plainbool7")
|
|
c.RequireBool("plainbool8")
|
|
c.TryBool("plainbool9")
|
|
c.GetSecretBool("plainbool10")
|
|
c.RequireSecretBool("plainbool11")
|
|
c.TrySecretBool("plainbool12")
|
|
|
|
config.GetInt(ctx, "plainint1")
|
|
config.RequireInt(ctx, "plainint2")
|
|
config.TryInt(ctx, "plainint3")
|
|
config.GetSecretInt(ctx, "plainint4")
|
|
config.RequireSecretInt(ctx, "plainint5")
|
|
config.TrySecretInt(ctx, "plainint6")
|
|
c.GetInt("plainint7")
|
|
c.RequireInt("plainint8")
|
|
c.TryInt("plainint9")
|
|
c.GetSecretInt("plainint10")
|
|
c.RequireSecretInt("plainint11")
|
|
c.TrySecretInt("plainint12")
|
|
|
|
config.GetFloat64(ctx, "plainfloat1")
|
|
config.RequireFloat64(ctx, "plainfloat2")
|
|
config.TryFloat64(ctx, "plainfloat3")
|
|
config.GetSecretFloat64(ctx, "plainfloat4")
|
|
config.RequireSecretFloat64(ctx, "plainfloat5")
|
|
config.TrySecretFloat64(ctx, "plainfloat6")
|
|
c.GetFloat64("plainfloat7")
|
|
c.RequireFloat64("plainfloat8")
|
|
c.TryFloat64("plainfloat9")
|
|
c.GetSecretFloat64("plainfloat10")
|
|
c.RequireSecretFloat64("plainfloat11")
|
|
c.TrySecretFloat64("plainfloat12")
|
|
|
|
var obj interface{}
|
|
config.GetObject(ctx, "plainobjj1", &obj)
|
|
config.RequireObject(ctx, "plainobj2", &obj)
|
|
config.TryObject(ctx, "plainobj3", &obj)
|
|
config.GetSecretObject(ctx, "plainobj4", &obj)
|
|
config.RequireSecretObject(ctx, "plainobj5", &obj)
|
|
config.TrySecretObject(ctx, "plainobj6", &obj)
|
|
c.GetObject("plainobjj7", &obj)
|
|
c.RequireObject("plainobj8", &obj)
|
|
c.TryObject("plainobj9", &obj)
|
|
c.GetSecretObject("plainobj10", &obj)
|
|
c.RequireSecretObject("plainobj11", &obj)
|
|
c.TrySecretObject("plainobj12", &obj)
|
|
|
|
config.Get(ctx, "str1")
|
|
config.Require(ctx, "str2")
|
|
config.Try(ctx, "str3")
|
|
config.GetSecret(ctx, "str4")
|
|
config.RequireSecret(ctx, "str5")
|
|
config.TrySecret(ctx, "str6")
|
|
c.Get("str7")
|
|
c.Require("str8")
|
|
c.Try("str9")
|
|
c.GetSecret("str10")
|
|
c.RequireSecret("str11")
|
|
c.TrySecret("str12")
|
|
|
|
config.GetBool(ctx, "bool1")
|
|
config.RequireBool(ctx, "bool2")
|
|
config.TryBool(ctx, "bool3")
|
|
config.GetSecretBool(ctx, "bool4")
|
|
config.RequireSecretBool(ctx, "bool5")
|
|
config.TrySecretBool(ctx, "bool6")
|
|
c.GetBool("bool7")
|
|
c.RequireBool("bool8")
|
|
c.TryBool("bool9")
|
|
c.GetSecretBool("bool10")
|
|
c.RequireSecretBool("bool11")
|
|
c.TrySecretBool("bool12")
|
|
|
|
config.GetInt(ctx, "int1")
|
|
config.RequireInt(ctx, "int2")
|
|
config.TryInt(ctx, "int3")
|
|
config.GetSecretInt(ctx, "int4")
|
|
config.RequireSecretInt(ctx, "int5")
|
|
config.TrySecretInt(ctx, "int6")
|
|
c.GetInt("int7")
|
|
c.RequireInt("int8")
|
|
c.TryInt("int9")
|
|
c.GetSecretInt("int10")
|
|
c.RequireSecretInt("int11")
|
|
c.TrySecretInt("int12")
|
|
|
|
config.GetFloat64(ctx, "float1")
|
|
config.RequireFloat64(ctx, "float2")
|
|
config.TryFloat64(ctx, "float3")
|
|
config.GetSecretFloat64(ctx, "float4")
|
|
config.RequireSecretFloat64(ctx, "float5")
|
|
config.TrySecretFloat64(ctx, "float6")
|
|
c.GetFloat64("float7")
|
|
c.RequireFloat64("float8")
|
|
c.TryFloat64("float9")
|
|
c.GetSecretFloat64("float10")
|
|
c.RequireSecretFloat64("float11")
|
|
c.TrySecretFloat64("float12")
|
|
|
|
config.GetObject(ctx, "obj1", &obj)
|
|
config.RequireObject(ctx, "obj2", &obj)
|
|
config.TryObject(ctx, "obj3", &obj)
|
|
config.GetSecretObject(ctx, "obj4", &obj)
|
|
config.RequireSecretObject(ctx, "obj5", &obj)
|
|
config.TrySecretObject(ctx, "obj6", &obj)
|
|
c.GetObject("obj7", &obj)
|
|
c.RequireObject("obj8", &obj)
|
|
c.TryObject("obj9", &obj)
|
|
c.GetSecretObject("obj10", &obj)
|
|
c.RequireSecretObject("obj11", &obj)
|
|
c.TrySecretObject("obj12", &obj)
|
|
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
t.Errorf("failed to initialize stack, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(t, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
t.Errorf("failed to set config, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
validate := func(engineEvents []events.EngineEvent) {
|
|
expectedWarnings := []string{
|
|
"Configuration 'testproj:str1' value is a secret; use `GetSecret` instead of `Get`",
|
|
"Configuration 'testproj:str2' value is a secret; use `RequireSecret` instead of `Require`",
|
|
"Configuration 'testproj:str3' value is a secret; use `TrySecret` instead of `Try`",
|
|
"Configuration 'testproj:str7' value is a secret; use `GetSecret` instead of `Get`",
|
|
"Configuration 'testproj:str8' value is a secret; use `RequireSecret` instead of `Require`",
|
|
"Configuration 'testproj:str9' value is a secret; use `TrySecret` instead of `Try`",
|
|
|
|
"Configuration 'testproj:bool1' value is a secret; use `GetSecretBool` instead of `GetBool`",
|
|
"Configuration 'testproj:bool2' value is a secret; use `RequireSecretBool` instead of `RequireBool`",
|
|
"Configuration 'testproj:bool3' value is a secret; use `TrySecretBool` instead of `TryBool`",
|
|
"Configuration 'testproj:bool7' value is a secret; use `GetSecretBool` instead of `GetBool`",
|
|
"Configuration 'testproj:bool8' value is a secret; use `RequireSecretBool` instead of `RequireBool`",
|
|
"Configuration 'testproj:bool9' value is a secret; use `TrySecretBool` instead of `TryBool`",
|
|
|
|
"Configuration 'testproj:int1' value is a secret; use `GetSecretInt` instead of `GetInt`",
|
|
"Configuration 'testproj:int2' value is a secret; use `RequireSecretInt` instead of `RequireInt`",
|
|
"Configuration 'testproj:int3' value is a secret; use `TrySecretInt` instead of `TryInt`",
|
|
"Configuration 'testproj:int7' value is a secret; use `GetSecretInt` instead of `GetInt`",
|
|
"Configuration 'testproj:int8' value is a secret; use `RequireSecretInt` instead of `RequireInt`",
|
|
"Configuration 'testproj:int9' value is a secret; use `TrySecretInt` instead of `TryInt`",
|
|
|
|
"Configuration 'testproj:float1' value is a secret; use `GetSecretFloat64` instead of `GetFloat64`",
|
|
"Configuration 'testproj:float2' value is a secret; use `RequireSecretFloat64` instead of `RequireFloat64`",
|
|
"Configuration 'testproj:float3' value is a secret; use `TrySecretFloat64` instead of `TryFloat64`",
|
|
"Configuration 'testproj:float7' value is a secret; use `GetSecretFloat64` instead of `GetFloat64`",
|
|
"Configuration 'testproj:float8' value is a secret; use `RequireSecretFloat64` instead of `RequireFloat64`",
|
|
"Configuration 'testproj:float9' value is a secret; use `TrySecretFloat64` instead of `TryFloat64`",
|
|
|
|
"Configuration 'testproj:obj1' value is a secret; use `GetSecretObject` instead of `GetObject`",
|
|
"Configuration 'testproj:obj2' value is a secret; use `RequireSecretObject` instead of `RequireObject`",
|
|
"Configuration 'testproj:obj3' value is a secret; use `TrySecretObject` instead of `TryObject`",
|
|
"Configuration 'testproj:obj7' value is a secret; use `GetSecretObject` instead of `GetObject`",
|
|
"Configuration 'testproj:obj8' value is a secret; use `RequireSecretObject` instead of `RequireObject`",
|
|
"Configuration 'testproj:obj9' value is a secret; use `TrySecretObject` instead of `TryObject`",
|
|
}
|
|
for _, warning := range expectedWarnings {
|
|
var found bool
|
|
for _, event := range engineEvents {
|
|
if event.DiagnosticEvent != nil && event.DiagnosticEvent.Severity == "warning" &&
|
|
strings.Contains(event.DiagnosticEvent.Message, warning) {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
assert.True(t, found, "expected warning %q", warning)
|
|
}
|
|
|
|
// These keys should not be in any warning messages.
|
|
unexpectedWarnings := []string{
|
|
"plainstr1",
|
|
"plainstr2",
|
|
"plainstr3",
|
|
"plainstr4",
|
|
"plainstr5",
|
|
"plainstr6",
|
|
"plainstr7",
|
|
"plainstr8",
|
|
"plainstr9",
|
|
"plainstr10",
|
|
"plainstr11",
|
|
"plainstr12",
|
|
"plainbool1",
|
|
"plainbool2",
|
|
"plainbool3",
|
|
"plainbool4",
|
|
"plainbool5",
|
|
"plainbool6",
|
|
"plainbool7",
|
|
"plainbool8",
|
|
"plainbool9",
|
|
"plainbool10",
|
|
"plainbool11",
|
|
"plainbool12",
|
|
"plainint1",
|
|
"plainint2",
|
|
"plainint3",
|
|
"plainint4",
|
|
"plainint5",
|
|
"plainint6",
|
|
"plainint7",
|
|
"plainint8",
|
|
"plainint9",
|
|
"plainint10",
|
|
"plainint11",
|
|
"plainint12",
|
|
"plainfloat1",
|
|
"plainfloat2",
|
|
"plainfloat3",
|
|
"plainfloat4",
|
|
"plainfloat5",
|
|
"plainfloat6",
|
|
"plainfloat7",
|
|
"plainfloat8",
|
|
"plainfloat9",
|
|
"plainfloat10",
|
|
"plainfloat11",
|
|
"plainfloat12",
|
|
"plainobj1",
|
|
"plainobj2",
|
|
"plainobj3",
|
|
"plainobj4",
|
|
"plainobj5",
|
|
"plainobj6",
|
|
"plainobj7",
|
|
"plainobj8",
|
|
"plainobj9",
|
|
"plainobj10",
|
|
"plainobj11",
|
|
"plainobj12",
|
|
}
|
|
for _, warning := range unexpectedWarnings {
|
|
for _, event := range engineEvents {
|
|
if event.DiagnosticEvent != nil {
|
|
assert.NotContains(t, event.DiagnosticEvent.Message, warning)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// -- pulumi up --
|
|
var upEvents []events.EngineEvent
|
|
upCh := make(chan events.EngineEvent)
|
|
go collectEvents(upCh, &upEvents)
|
|
_, err = s.Up(ctx, optup.EventStreams(upCh))
|
|
if err != nil {
|
|
t.Errorf("up failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
validate(upEvents)
|
|
|
|
// -- pulumi preview --
|
|
var previewEvents []events.EngineEvent
|
|
prevCh := make(chan events.EngineEvent)
|
|
go collectEvents(prevCh, &previewEvents)
|
|
_, err = s.Preview(ctx, optpreview.EventStreams(prevCh))
|
|
if err != nil {
|
|
t.Errorf("preview failed, err: %v", err)
|
|
t.FailNow()
|
|
}
|
|
validate(previewEvents)
|
|
}
|
|
|
|
func BenchmarkBulkSetConfigMixed(b *testing.B) {
|
|
ctx := context.Background()
|
|
stackName := FullyQualifiedStackName(pulumiOrg, "set_config_mixed", "dev")
|
|
|
|
// initialize
|
|
s, err := NewStackInlineSource(ctx, stackName, "set_config_mixed", func(ctx *pulumi.Context) error { return nil })
|
|
if err != nil {
|
|
b.Errorf("failed to initialize stack, err: %v", err)
|
|
b.FailNow()
|
|
}
|
|
|
|
cfg := ConfigMap{
|
|
"one": ConfigValue{Value: "one", Secret: true},
|
|
"two": ConfigValue{Value: "two"},
|
|
"three": ConfigValue{Value: "three", Secret: true},
|
|
"four": ConfigValue{Value: "four"},
|
|
"five": ConfigValue{Value: "five", Secret: true},
|
|
"six": ConfigValue{Value: "six"},
|
|
"seven": ConfigValue{Value: "seven", Secret: true},
|
|
"eight": ConfigValue{Value: "eight"},
|
|
"nine": ConfigValue{Value: "nine", Secret: true},
|
|
"ten": ConfigValue{Value: "ten"},
|
|
"eleven": ConfigValue{Value: "one", Secret: true},
|
|
"twelve": ConfigValue{Value: "two"},
|
|
"thirteen": ConfigValue{Value: "three", Secret: true},
|
|
"fourteen": ConfigValue{Value: "four"},
|
|
"fifteen": ConfigValue{Value: "five", Secret: true},
|
|
"sixteen": ConfigValue{Value: "six"},
|
|
"seventeen": ConfigValue{Value: "seven", Secret: true},
|
|
"eighteen": ConfigValue{Value: "eight"},
|
|
"nineteen": ConfigValue{Value: "nine", Secret: true},
|
|
"twenty": ConfigValue{Value: "ten"},
|
|
"one1": ConfigValue{Value: "one", Secret: true},
|
|
"two1": ConfigValue{Value: "two"},
|
|
"three1": ConfigValue{Value: "three", Secret: true},
|
|
"four1": ConfigValue{Value: "four"},
|
|
"five1": ConfigValue{Value: "five", Secret: true},
|
|
"six1": ConfigValue{Value: "six"},
|
|
"seven1": ConfigValue{Value: "seven", Secret: true},
|
|
"eight1": ConfigValue{Value: "eight"},
|
|
"nine1": ConfigValue{Value: "nine", Secret: true},
|
|
"ten1": ConfigValue{Value: "ten"},
|
|
"eleven1": ConfigValue{Value: "one", Secret: true},
|
|
"twelve1": ConfigValue{Value: "two"},
|
|
"thirteen1": ConfigValue{Value: "three", Secret: true},
|
|
"fourteen1": ConfigValue{Value: "four"},
|
|
"fifteen1": ConfigValue{Value: "five", Secret: true},
|
|
"sixteen1": ConfigValue{Value: "six"},
|
|
"seventeen1": ConfigValue{Value: "seven", Secret: true},
|
|
"eighteen1": ConfigValue{Value: "eight"},
|
|
"nineteen1": ConfigValue{Value: "nine", Secret: true},
|
|
"twenty1": ConfigValue{Value: "ten"},
|
|
}
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
b.Errorf("failed to set config, err: %v", err)
|
|
b.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(b, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
}
|
|
|
|
func BenchmarkBulkSetConfigPlain(b *testing.B) {
|
|
ctx := context.Background()
|
|
stackName := FullyQualifiedStackName(pulumiOrg, "set_config_plain", "dev")
|
|
|
|
// initialize
|
|
s, err := NewStackInlineSource(ctx, stackName, "set_config_plain", func(ctx *pulumi.Context) error { return nil })
|
|
if err != nil {
|
|
b.Errorf("failed to initialize stack, err: %v", err)
|
|
b.FailNow()
|
|
}
|
|
|
|
cfg := ConfigMap{
|
|
"one": ConfigValue{Value: "one"},
|
|
"two": ConfigValue{Value: "two"},
|
|
"three": ConfigValue{Value: "three"},
|
|
"four": ConfigValue{Value: "four"},
|
|
"five": ConfigValue{Value: "five"},
|
|
"six": ConfigValue{Value: "six"},
|
|
"seven": ConfigValue{Value: "seven"},
|
|
"eight": ConfigValue{Value: "eight"},
|
|
"nine": ConfigValue{Value: "nine"},
|
|
"ten": ConfigValue{Value: "ten"},
|
|
"eleven": ConfigValue{Value: "one"},
|
|
"twelve": ConfigValue{Value: "two"},
|
|
"thirteen": ConfigValue{Value: "three"},
|
|
"fourteen": ConfigValue{Value: "four"},
|
|
"fifteen": ConfigValue{Value: "five"},
|
|
"sixteen": ConfigValue{Value: "six"},
|
|
"seventeen": ConfigValue{Value: "seven"},
|
|
"eighteen": ConfigValue{Value: "eight"},
|
|
"nineteen": ConfigValue{Value: "nine"},
|
|
"twenty": ConfigValue{Value: "ten"},
|
|
"one1": ConfigValue{Value: "one"},
|
|
"two1": ConfigValue{Value: "two"},
|
|
"three1": ConfigValue{Value: "three"},
|
|
"four1": ConfigValue{Value: "four"},
|
|
"five1": ConfigValue{Value: "five"},
|
|
"six1": ConfigValue{Value: "six"},
|
|
"seven1": ConfigValue{Value: "seven"},
|
|
"eight1": ConfigValue{Value: "eight"},
|
|
"nine1": ConfigValue{Value: "nine"},
|
|
"ten1": ConfigValue{Value: "ten"},
|
|
"eleven1": ConfigValue{Value: "one"},
|
|
"twelve1": ConfigValue{Value: "two"},
|
|
"thirteen1": ConfigValue{Value: "three"},
|
|
"fourteen1": ConfigValue{Value: "four"},
|
|
"fifteen1": ConfigValue{Value: "five"},
|
|
"sixteen1": ConfigValue{Value: "six"},
|
|
"seventeen1": ConfigValue{Value: "seven"},
|
|
"eighteen1": ConfigValue{Value: "eight"},
|
|
"nineteen1": ConfigValue{Value: "nine"},
|
|
"twenty1": ConfigValue{Value: "ten"},
|
|
}
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
b.Errorf("failed to set config, err: %v", err)
|
|
b.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(b, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
}
|
|
|
|
func BenchmarkBulkSetConfigSecret(b *testing.B) {
|
|
ctx := context.Background()
|
|
stackName := FullyQualifiedStackName(pulumiOrg, "set_config_plain", "dev")
|
|
|
|
// initialize
|
|
s, err := NewStackInlineSource(ctx, stackName, "set_config_plain", func(ctx *pulumi.Context) error { return nil })
|
|
if err != nil {
|
|
b.Errorf("failed to initialize stack, err: %v", err)
|
|
b.FailNow()
|
|
}
|
|
|
|
cfg := ConfigMap{
|
|
"one": ConfigValue{Value: "one", Secret: true},
|
|
"two": ConfigValue{Value: "two", Secret: true},
|
|
"three": ConfigValue{Value: "three", Secret: true},
|
|
"four": ConfigValue{Value: "four", Secret: true},
|
|
"five": ConfigValue{Value: "five", Secret: true},
|
|
"six": ConfigValue{Value: "six", Secret: true},
|
|
"seven": ConfigValue{Value: "seven", Secret: true},
|
|
"eight": ConfigValue{Value: "eight", Secret: true},
|
|
"nine": ConfigValue{Value: "nine", Secret: true},
|
|
"ten": ConfigValue{Value: "ten", Secret: true},
|
|
"eleven": ConfigValue{Value: "one", Secret: true},
|
|
"twelve": ConfigValue{Value: "two", Secret: true},
|
|
"thirteen": ConfigValue{Value: "three", Secret: true},
|
|
"fourteen": ConfigValue{Value: "four", Secret: true},
|
|
"fifteen": ConfigValue{Value: "five", Secret: true},
|
|
"sixteen": ConfigValue{Value: "six", Secret: true},
|
|
"seventeen": ConfigValue{Value: "seven", Secret: true},
|
|
"eighteen": ConfigValue{Value: "eight", Secret: true},
|
|
"nineteen": ConfigValue{Value: "nine", Secret: true},
|
|
"1twenty": ConfigValue{Value: "ten", Secret: true},
|
|
"one1": ConfigValue{Value: "one", Secret: true},
|
|
"two1": ConfigValue{Value: "two", Secret: true},
|
|
"three1": ConfigValue{Value: "three", Secret: true},
|
|
"four1": ConfigValue{Value: "four", Secret: true},
|
|
"five1": ConfigValue{Value: "five", Secret: true},
|
|
"six1": ConfigValue{Value: "six", Secret: true},
|
|
"seven1": ConfigValue{Value: "seven", Secret: true},
|
|
"eight1": ConfigValue{Value: "eight", Secret: true},
|
|
"nine1": ConfigValue{Value: "nine", Secret: true},
|
|
"ten1": ConfigValue{Value: "ten", Secret: true},
|
|
"eleven1": ConfigValue{Value: "one", Secret: true},
|
|
"twelve1": ConfigValue{Value: "two", Secret: true},
|
|
"thirteen1": ConfigValue{Value: "three", Secret: true},
|
|
"fourteen1": ConfigValue{Value: "four", Secret: true},
|
|
"fifteen1": ConfigValue{Value: "five", Secret: true},
|
|
"sixteen1": ConfigValue{Value: "six", Secret: true},
|
|
"seventeen1": ConfigValue{Value: "seven", Secret: true},
|
|
"eighteen1": ConfigValue{Value: "eight", Secret: true},
|
|
"nineteen1": ConfigValue{Value: "nine", Secret: true},
|
|
"twenty1": ConfigValue{Value: "ten", Secret: true},
|
|
}
|
|
|
|
err = s.SetAllConfig(ctx, cfg)
|
|
if err != nil {
|
|
b.Errorf("failed to set config, err: %v", err)
|
|
b.FailNow()
|
|
}
|
|
|
|
defer func() {
|
|
// -- pulumi stack rm --
|
|
err = s.Workspace().RemoveStack(ctx, s.Name())
|
|
assert.Nil(b, err, "failed to remove stack. Resources have leaked.")
|
|
}()
|
|
}
|
|
|
|
func getTestOrg() string {
|
|
testOrg := "pulumi-test"
|
|
if _, set := os.LookupEnv("PULUMI_TEST_ORG"); set {
|
|
testOrg = os.Getenv("PULUMI_TEST_ORG")
|
|
}
|
|
return testOrg
|
|
}
|
|
|
|
func countSteps(log []events.EngineEvent) int {
|
|
steps := 0
|
|
for _, e := range log {
|
|
if e.ResourcePreEvent != nil {
|
|
steps++
|
|
}
|
|
}
|
|
return steps
|
|
}
|
|
|
|
func containsSummary(log []events.EngineEvent) bool {
|
|
hasSummary := false
|
|
for _, e := range log {
|
|
if e.SummaryEvent != nil {
|
|
hasSummary = true
|
|
}
|
|
}
|
|
return hasSummary
|
|
}
|
|
|
|
func collectEvents(eventChannel <-chan events.EngineEvent, events *[]events.EngineEvent) {
|
|
for {
|
|
event, ok := <-eventChannel
|
|
if !ok {
|
|
return
|
|
}
|
|
*events = append(*events, event)
|
|
}
|
|
}
|