2024-10-28 11:58:59 +00:00
|
|
|
// Copyright 2016-2024, Pulumi Corporation.
|
2022-10-11 15:30:58 +00:00
|
|
|
//
|
|
|
|
// 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 lifecycletest
|
|
|
|
|
|
|
|
import (
|
2024-07-26 12:14:45 +00:00
|
|
|
"context"
|
2022-10-11 15:30:58 +00:00
|
|
|
"regexp"
|
2022-10-10 10:18:57 +00:00
|
|
|
"strings"
|
2022-10-11 15:30:58 +00:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/blang/semver"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
2023-09-18 11:01:28 +00:00
|
|
|
"github.com/pulumi/pulumi/pkg/v3/display"
|
2023-11-21 15:16:13 +00:00
|
|
|
. "github.com/pulumi/pulumi/pkg/v3/engine" //nolint:revive
|
2024-10-28 11:58:59 +00:00
|
|
|
lt "github.com/pulumi/pulumi/pkg/v3/engine/lifecycletest/framework"
|
2022-10-11 15:30:58 +00:00
|
|
|
"github.com/pulumi/pulumi/pkg/v3/resource/deploy"
|
|
|
|
"github.com/pulumi/pulumi/pkg/v3/resource/deploy/deploytest"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/resource/plugin"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/workspace"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestPlannedUpdate(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: "created-id",
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
var ins resource.PropertyMap
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Generate a plan.
|
|
|
|
computed := interface{}(resource.Computed{Element: resource.NewStringProperty("")})
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"baz": map[string]interface{}{
|
|
|
|
"a": 42,
|
|
|
|
"b": computed,
|
|
|
|
},
|
|
|
|
"qux": []interface{}{
|
|
|
|
computed,
|
|
|
|
24,
|
|
|
|
},
|
|
|
|
"zed": computed,
|
|
|
|
})
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, nil)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Attempt to run an update using the plan.
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"qux": []interface{}{
|
|
|
|
"alpha",
|
|
|
|
24,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
p.Options.Plan = plan.Clone()
|
|
|
|
validate := ExpectDiagMessage(t, regexp.QuoteMeta(
|
|
|
|
"<{%reset%}>resource urn:pulumi:test::test::pkgA:m:typA::resA violates plan: "+
|
|
|
|
"properties changed: +-baz[{map[a:{42} b:output<string>{}]}], +-foo[{bar}]<{%reset%}>\n"))
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).RunStep(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, validate, "0")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check the resource's state.
|
|
|
|
if !assert.Len(t, snap.Resources, 1) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change the provider's planned operation to a same step.
|
|
|
|
// Remove the provider from the plan.
|
|
|
|
plan.ResourcePlans["urn:pulumi:test::test::pulumi:providers:pkgA::default"].Ops = []display.StepOp{deploy.OpSame}
|
|
|
|
|
|
|
|
// Attempt to run an update using the plan.
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"baz": map[string]interface{}{
|
|
|
|
"a": 42,
|
|
|
|
"b": "alpha",
|
|
|
|
},
|
|
|
|
"qux": []interface{}{
|
|
|
|
"beta",
|
|
|
|
24,
|
|
|
|
},
|
|
|
|
"zed": "grr",
|
|
|
|
})
|
|
|
|
p.Options.Plan = plan.Clone()
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, nil, "1")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check the resource's state.
|
|
|
|
if !assert.Len(t, snap.Resources, 2) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
expected := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"baz": map[string]interface{}{
|
|
|
|
"a": 42,
|
|
|
|
"b": "alpha",
|
|
|
|
},
|
|
|
|
"qux": []interface{}{
|
|
|
|
"beta",
|
|
|
|
24,
|
|
|
|
},
|
|
|
|
"zed": "grr",
|
|
|
|
})
|
|
|
|
assert.Equal(t, expected, snap.Resources[1].Outputs)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestUnplannedCreate(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: "created-id",
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
ins := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
})
|
|
|
|
createResource := false
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2022-10-11 15:30:58 +00:00
|
|
|
if createResource {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
|
|
|
HostF: hostF,
|
|
|
|
SkipDisplayTests: true,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
2023-09-28 21:50:18 +00:00
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Create a plan to do nothing
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, nil)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Now set the flag for the language runtime to create a resource, and run update with the plan
|
|
|
|
createResource = true
|
|
|
|
p.Options.Plan = plan.Clone()
|
|
|
|
validate := ExpectDiagMessage(t, regexp.QuoteMeta(
|
|
|
|
"<{%reset%}>create is not allowed by the plan: no steps were expected for this resource<{%reset%}>\n"))
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).Run(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, validate)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check nothing was was created
|
|
|
|
assert.NotNil(t, snap)
|
|
|
|
if !assert.Len(t, snap.Resources, 0) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestUnplannedDelete(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: resource.ID("created-id-" + req.URN.Name()),
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
2024-07-26 12:14:45 +00:00
|
|
|
DeleteF: func(context.Context, plugin.DeleteRequest) (plugin.DeleteResponse, error) {
|
|
|
|
return plugin.DeleteResponse{}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
ins := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
})
|
|
|
|
createAllResources := true
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
if createAllResources {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err = monitor.RegisterResource("pkgA:m:typA", "resB", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Create an initial snapshot that resA and resB exist
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).RunStep(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, nil, "0")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Create a plan that resA and resB won't change
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, snap), p.Options, p.BackendClient, nil)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Now set the flag for the language runtime to not create resB and run an update with
|
|
|
|
// the no-op plan, this should block the delete
|
|
|
|
createAllResources = false
|
|
|
|
p.Options.Plan = plan.Clone()
|
|
|
|
validate := ExpectDiagMessage(t, regexp.QuoteMeta(
|
|
|
|
"<{%reset%}>delete is not allowed by the plan: this resource is constrained to same<{%reset%}>\n"))
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, validate, "1")
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check both resources and the provider are still listed in the snapshot
|
|
|
|
if !assert.Len(t, snap.Resources, 3) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestExpectedDelete(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: resource.ID("created-id-" + req.URN.Name()),
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
2024-07-26 12:14:45 +00:00
|
|
|
DeleteF: func(context.Context, plugin.DeleteRequest) (plugin.DeleteResponse, error) {
|
|
|
|
return plugin.DeleteResponse{}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
ins := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
})
|
|
|
|
createAllResources := true
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
if createAllResources {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err = monitor.RegisterResource("pkgA:m:typA", "resB", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Create an initial snapshot that resA and resB exist
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).RunStep(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, nil, "0")
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Create a plan that resA is same and resB is deleted
|
|
|
|
createAllResources = false
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, snap), p.Options, p.BackendClient, nil)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, plan)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Now run but set the runtime to return resA and resB, given we expected resB to be deleted
|
|
|
|
// this should be an error
|
|
|
|
createAllResources = true
|
|
|
|
p.Options.Plan = plan.Clone()
|
|
|
|
validate := ExpectDiagMessage(t, regexp.QuoteMeta(
|
|
|
|
"<{%reset%}>resource urn:pulumi:test::test::pkgA:m:typA::resB violates plan: "+
|
|
|
|
"resource unexpectedly not deleted<{%reset%}>\n"))
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, validate, "1")
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check both resources and the provider are still listed in the snapshot
|
|
|
|
if !assert.Len(t, snap.Resources, 3) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestExpectedCreate(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: resource.ID("created-id-" + req.URN.Name()),
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
ins := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
})
|
|
|
|
createAllResources := false
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
if createAllResources {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err = monitor.RegisterResource("pkgA:m:typA", "resB", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Create an initial snapshot that resA exists
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).RunStep(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, nil, "0")
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Create a plan that resA is same and resB is created
|
|
|
|
createAllResources = true
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, snap), p.Options, p.BackendClient, nil)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, plan)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Now run but set the runtime to return resA, given we expected resB to be created
|
|
|
|
// this should be an error
|
|
|
|
createAllResources = false
|
|
|
|
p.Options.Plan = plan.Clone()
|
|
|
|
validate := ExpectDiagMessage(t, regexp.QuoteMeta(
|
|
|
|
"<{%reset%}>expected resource operations for "+
|
|
|
|
"urn:pulumi:test::test::pkgA:m:typA::resB but none were seen<{%reset%}>\n"))
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, validate, "1")
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check resA and the provider are still listed in the snapshot
|
|
|
|
if !assert.Len(t, snap.Resources, 2) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPropertySetChange(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: resource.ID("created-id-" + req.URN.Name()),
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
ins := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"frob": "baz",
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Create an initial plan to create resA
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, nil)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, plan)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Now change the runtime to not return property "frob", this should error
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
})
|
|
|
|
p.Options.Plan = plan.Clone()
|
|
|
|
validate := ExpectDiagMessage(t, regexp.QuoteMeta(
|
|
|
|
"<{%reset%}>resource urn:pulumi:test::test::pkgA:m:typA::resA violates plan: "+
|
|
|
|
"properties changed: +-frob[{baz}]<{%reset%}>\n"))
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).Run(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, validate)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestExpectedUnneededCreate(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: resource.ID("created-id-" + req.URN.Name()),
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
ins := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Create a plan that resA needs creating
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, nil)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, plan)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Create an a snapshot that resA exists
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).RunStep(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, nil, "0")
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Now run again with the plan set but the snapshot that resA already exists
|
|
|
|
p.Options.Plan = plan.Clone()
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, nil, "1")
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check resA and the provider are still listed in the snapshot
|
|
|
|
if !assert.Len(t, snap.Resources, 2) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestExpectedUnneededDelete(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: resource.ID("created-id-" + req.URN.Name()),
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
2024-07-26 12:14:45 +00:00
|
|
|
DeleteF: func(context.Context, plugin.DeleteRequest) (plugin.DeleteResponse, error) {
|
|
|
|
return plugin.DeleteResponse{}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
ins := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
})
|
|
|
|
createResource := true
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2022-10-11 15:30:58 +00:00
|
|
|
if createResource {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Create an initial snapshot that resA exists
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).RunStep(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, nil, "0")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Create a plan that resA is deleted
|
|
|
|
createResource = false
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, snap), p.Options, p.BackendClient, nil)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Now run to delete resA
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, nil, "1")
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Now run again with the plan set but the snapshot that resA is already deleted
|
|
|
|
p.Options.Plan = plan.Clone()
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, nil, "2")
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check the resources are still gone
|
|
|
|
if !assert.Len(t, snap.Resources, 0) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestResoucesWithSames(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
// This test checks that if between generating a constraint and running the update that if new resources have been
|
|
|
|
// added to the stack that the update doesn't change those resources in any way that they don't cause constraint
|
|
|
|
// errors.
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: "created-id",
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
var ins resource.PropertyMap
|
|
|
|
createA := false
|
|
|
|
createB := false
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2022-10-11 15:30:58 +00:00
|
|
|
if createA {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if createB {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resB", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"X": "Y",
|
|
|
|
}),
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Generate a plan to create A
|
|
|
|
createA = true
|
|
|
|
createB = false
|
|
|
|
computed := interface{}(resource.Computed{Element: resource.NewStringProperty("")})
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"zed": computed,
|
|
|
|
})
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, nil)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Run an update that creates B
|
|
|
|
createA = false
|
|
|
|
createB = true
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).RunStep(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, nil, "0")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check the resource's state.
|
|
|
|
if !assert.Len(t, snap.Resources, 2) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
expected := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"X": "Y",
|
|
|
|
})
|
|
|
|
assert.Equal(t, expected, snap.Resources[1].Outputs)
|
|
|
|
|
|
|
|
// Attempt to run an update with the plan on the stack that creates A and sames B
|
|
|
|
createA = true
|
|
|
|
createB = true
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"zed": 24,
|
|
|
|
})
|
|
|
|
p.Options.Plan = plan.Clone()
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, nil, "1")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check the resource's state.
|
|
|
|
if !assert.Len(t, snap.Resources, 3) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
expected = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"X": "Y",
|
|
|
|
})
|
|
|
|
assert.Equal(t, expected, snap.Resources[2].Outputs)
|
|
|
|
|
|
|
|
expected = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"zed": 24,
|
|
|
|
})
|
|
|
|
assert.Equal(t, expected, snap.Resources[1].Outputs)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPlannedPreviews(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
// This checks that plans work in previews, this is very similar to TestPlannedUpdate except we only do previews
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: "created-id",
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
var ins resource.PropertyMap
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Generate a plan.
|
|
|
|
computed := interface{}(resource.Computed{Element: resource.NewStringProperty("")})
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"baz": map[string]interface{}{
|
|
|
|
"a": 42,
|
|
|
|
"b": computed,
|
|
|
|
},
|
|
|
|
"qux": []interface{}{
|
|
|
|
computed,
|
|
|
|
24,
|
|
|
|
},
|
|
|
|
"zed": computed,
|
|
|
|
})
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, nil)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Attempt to run a new preview using the plan, given we've changed the property set this should fail
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"qux": []interface{}{
|
|
|
|
"alpha",
|
|
|
|
24,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
p.Options.Plan = plan.Clone()
|
|
|
|
validate := ExpectDiagMessage(t, regexp.QuoteMeta(
|
|
|
|
"<{%reset%}>resource urn:pulumi:test::test::pkgA:m:typA::resA violates plan: properties changed: "+
|
|
|
|
"+-baz[{map[a:{42} b:output<string>{}]}], +-foo[{bar}]<{%reset%}>\n"))
|
2024-10-28 11:58:59 +00:00
|
|
|
_, err = lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, validate)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Attempt to run an preview using the plan, such that the property set is now valid
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"baz": map[string]interface{}{
|
|
|
|
"a": 42,
|
|
|
|
"b": computed,
|
|
|
|
},
|
|
|
|
"qux": []interface{}{
|
|
|
|
"beta",
|
|
|
|
24,
|
|
|
|
},
|
|
|
|
"zed": "grr",
|
|
|
|
})
|
|
|
|
p.Options.Plan = plan.Clone()
|
2024-10-28 11:58:59 +00:00
|
|
|
_, err = lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, nil)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestPlannedUpdateChangedStack(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
// This tests the case that we run a planned update against a stack that has changed between preview and update
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: "created-id",
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
var ins resource.PropertyMap
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Set initial data for foo and zed
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"zed": 24,
|
|
|
|
})
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).RunStep(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, nil, "0")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Generate a plan that we want to change foo
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "baz",
|
|
|
|
"zed": 24,
|
|
|
|
})
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, snap), p.Options, p.BackendClient, nil)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Change zed in the stack
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"zed": 26,
|
|
|
|
})
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, nil, "1")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Attempt to run an update using the plan but where we haven't updated our program for the change of zed
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "baz",
|
|
|
|
"zed": 24,
|
|
|
|
})
|
|
|
|
p.Options.Plan = plan.Clone()
|
|
|
|
validate := ExpectDiagMessage(t, regexp.QuoteMeta(
|
|
|
|
"<{%reset%}>resource urn:pulumi:test::test::pkgA:m:typA::resA violates plan: "+
|
|
|
|
"properties changed: =~zed[{24}]<{%reset%}>\n"))
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, validate, "2")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check the resource's state we shouldn't of changed anything because the update failed
|
|
|
|
if !assert.Len(t, snap.Resources, 2) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
expected := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"zed": 26,
|
|
|
|
})
|
|
|
|
assert.Equal(t, expected, snap.Resources[1].Outputs)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPlannedOutputChanges(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: resource.ID("created-id-" + req.URN.Name()),
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
outs := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"frob": "baz",
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
resp, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{})
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2024-04-19 11:08:56 +00:00
|
|
|
err = monitor.RegisterResourceOutputs(resp.URN, outs)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Create an initial plan to create resA and the outputs
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, nil)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, plan)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Now change the runtime to not return property "frob", this should error
|
|
|
|
outs = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
})
|
|
|
|
p.Options.Plan = plan.Clone()
|
|
|
|
validate := ExpectDiagMessage(t, regexp.QuoteMeta(
|
|
|
|
"<{%reset%}>resource violates plan: properties changed: +-frob[{baz}]<{%reset%}>\n"))
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).Run(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, validate)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestPlannedInputOutputDifferences(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
// This tests that plans are working on the program inputs, not the provider outputs
|
|
|
|
|
|
|
|
createOutputs := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"frob": "baz",
|
|
|
|
"baz": 24,
|
|
|
|
})
|
|
|
|
updateOutputs := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"frob": "newBazzer",
|
|
|
|
"baz": 24,
|
|
|
|
})
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: resource.ID("created-id-" + req.URN.Name()),
|
|
|
|
Properties: createOutputs,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
2024-07-26 12:14:45 +00:00
|
|
|
UpdateF: func(_ context.Context, req plugin.UpdateRequest) (plugin.UpdateResponse, error) {
|
|
|
|
return plugin.UpdateResponse{
|
|
|
|
Properties: updateOutputs,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
inputs := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"frob": "baz",
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2023-03-03 16:36:39 +00:00
|
|
|
Inputs: inputs,
|
|
|
|
})
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Create an initial plan to create resA
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, nil)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, plan)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check we can create resA even though its outputs are different to the planned inputs
|
|
|
|
p.Options.Plan = plan.Clone()
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).RunStep(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, nil, "0")
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Make a plan to change resA
|
|
|
|
inputs = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"frob": "newBazzer",
|
|
|
|
})
|
|
|
|
p.Options.Plan = nil
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err = lt.TestOp(Update).Plan(project, p.GetTarget(t, snap), p.Options, p.BackendClient, nil)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, plan)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Test the plan fails if we don't pass newBazzer
|
|
|
|
inputs = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"frob": "differentBazzer",
|
|
|
|
})
|
|
|
|
p.Options.Plan = plan.Clone()
|
|
|
|
validate := ExpectDiagMessage(t, regexp.QuoteMeta(
|
|
|
|
"<{%reset%}>resource urn:pulumi:test::test::pkgA:m:typA::resA violates plan: "+
|
|
|
|
"properties changed: ~~frob[{newBazzer}!={differentBazzer}]<{%reset%}>\n"))
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, validate, "1")
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check the plan succeeds if we do pass newBazzer
|
|
|
|
inputs = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"frob": "newBazzer",
|
|
|
|
})
|
|
|
|
p.Options.Plan = plan.Clone()
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, nil, "2")
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestAliasWithPlans(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
// This tests that if a resource has an alias the plan for it is still used
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: resource.ID("created-id-" + req.URN.Name()),
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
resourceName := "resA"
|
|
|
|
var aliases []resource.URN
|
|
|
|
ins := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"frob": "baz",
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", resourceName, true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
AliasURNs: aliases,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Create an initial ResA
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).RunStep(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, nil, "0")
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Update the name and alias and make a plan for resA
|
|
|
|
resourceName = "newResA"
|
|
|
|
aliases = make([]resource.URN, 1)
|
|
|
|
aliases[0] = resource.URN("urn:pulumi:test::test::pkgA:m:typA::resA")
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, nil)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, plan)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Now try and run with the plan
|
|
|
|
p.Options.Plan = plan.Clone()
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, nil, "1")
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestComputedCanBeDropped(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
// This tests that values that show as <computed> in the plan can be dropped in the update (because they may of
|
|
|
|
// resolved to undefined). We're testing both RegisterResource and RegisterResourceOutputs here.
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: resource.ID("created-id-" + req.URN.Name()),
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
var resourceInputs resource.PropertyMap
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
resp, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{})
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err = monitor.RegisterResource("pkgA:m:typA", "resB", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: resourceInputs,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
// We're using the same property set on purpose, this is not a test bug
|
2024-04-19 11:08:56 +00:00
|
|
|
err = monitor.RegisterResourceOutputs(resp.URN, resourceInputs)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// The three property sets we'll use in this test
|
|
|
|
computed := interface{}(resource.Computed{Element: resource.NewStringProperty("")})
|
|
|
|
computedPropertySet := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"baz": map[string]interface{}{
|
|
|
|
"a": 42,
|
|
|
|
"b": computed,
|
|
|
|
},
|
|
|
|
"qux": []interface{}{
|
|
|
|
computed,
|
|
|
|
24,
|
|
|
|
},
|
|
|
|
"zed": computed,
|
|
|
|
})
|
|
|
|
fullPropertySet := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"baz": map[string]interface{}{
|
|
|
|
"a": 42,
|
|
|
|
"b": "alpha",
|
|
|
|
},
|
|
|
|
"qux": []interface{}{
|
|
|
|
"beta",
|
|
|
|
24,
|
|
|
|
},
|
|
|
|
"zed": "grr",
|
|
|
|
})
|
|
|
|
partialPropertySet := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"baz": map[string]interface{}{
|
|
|
|
"a": 42,
|
|
|
|
},
|
|
|
|
"qux": []interface{}{
|
|
|
|
nil, // computed values that resolve to undef don't get dropped from arrays, they just become null
|
|
|
|
24,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
// Generate a plan.
|
|
|
|
resourceInputs = computedPropertySet
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, nil)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Attempt to run an update using the plan with all computed values removed
|
|
|
|
resourceInputs = partialPropertySet
|
|
|
|
p.Options.Plan = plan.Clone()
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).RunStep(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, nil, "0")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check the resource's state.
|
|
|
|
if !assert.Len(t, snap.Resources, 3) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Equal(t, partialPropertySet, snap.Resources[1].Outputs)
|
|
|
|
assert.Equal(t, partialPropertySet, snap.Resources[2].Outputs)
|
|
|
|
|
|
|
|
// Now run an update to set the values of the computed properties...
|
|
|
|
resourceInputs = fullPropertySet
|
|
|
|
p.Options.Plan = nil
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, nil, "1")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check the resource's state.
|
|
|
|
if !assert.Len(t, snap.Resources, 3) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Equal(t, fullPropertySet, snap.Resources[1].Outputs)
|
|
|
|
assert.Equal(t, fullPropertySet, snap.Resources[2].Outputs)
|
|
|
|
|
|
|
|
// ...and then build a new plan where they're computed updates (vs above where its computed creates)
|
|
|
|
resourceInputs = computedPropertySet
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err = lt.TestOp(Update).Plan(project, p.GetTarget(t, snap), p.Options, p.BackendClient, nil)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Now run the an update with the plan and check the update is allowed to remove these properties
|
|
|
|
resourceInputs = partialPropertySet
|
|
|
|
p.Options.Plan = plan.Clone()
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, nil, "2")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check the resource's state.
|
|
|
|
if !assert.Len(t, snap.Resources, 3) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Equal(t, partialPropertySet, snap.Resources[1].Outputs)
|
|
|
|
assert.Equal(t, partialPropertySet, snap.Resources[2].Outputs)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPlannedUpdateWithNondeterministicCheck(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: resource.ID("created-id-" + req.URN.Name()),
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
2024-07-26 12:14:45 +00:00
|
|
|
CheckF: func(
|
|
|
|
_ context.Context,
|
|
|
|
req plugin.CheckRequest,
|
|
|
|
) (plugin.CheckResponse, error) {
|
2022-10-11 15:30:58 +00:00
|
|
|
// If we have name use it, else use olds name, else make one up
|
2024-07-26 12:14:45 +00:00
|
|
|
if _, has := req.News["name"]; has {
|
|
|
|
return plugin.CheckResponse{Properties: req.News}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
2024-07-26 12:14:45 +00:00
|
|
|
if _, has := req.Olds["name"]; has {
|
|
|
|
result := req.News.Copy()
|
|
|
|
result["name"] = req.Olds["name"]
|
|
|
|
return plugin.CheckResponse{Properties: result}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
2024-07-26 12:14:45 +00:00
|
|
|
name, err := resource.NewUniqueHex(req.URN.Name(), 8, 512)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-07-26 12:14:45 +00:00
|
|
|
result := req.News.Copy()
|
2022-10-11 15:30:58 +00:00
|
|
|
result["name"] = resource.NewStringProperty(name)
|
2024-07-26 12:14:45 +00:00
|
|
|
return plugin.CheckResponse{Properties: result}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
var ins resource.PropertyMap
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
resp, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err = monitor.RegisterResource("pkgA:m:typA", "resB", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: resource.NewPropertyMapFromMap(map[string]interface{}{
|
2024-04-19 11:08:56 +00:00
|
|
|
"other": resp.Outputs["name"].StringValue(),
|
2022-10-11 15:30:58 +00:00
|
|
|
}),
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
|
|
|
HostF: hostF,
|
|
|
|
SkipDisplayTests: true,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
2023-09-28 21:50:18 +00:00
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Generate a plan.
|
|
|
|
computed := interface{}(resource.Computed{Element: resource.NewStringProperty("")})
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"zed": computed,
|
|
|
|
})
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, nil)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Attempt to run an update using the plan.
|
|
|
|
// This should fail because of the non-determinism
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"zed": "baz",
|
|
|
|
})
|
|
|
|
p.Options.Plan = plan.Clone()
|
|
|
|
|
|
|
|
validate := ExpectDiagMessage(t,
|
|
|
|
"<{%reset%}>resource urn:pulumi:test::test::pkgA:m:typA::resA violates plan: "+
|
|
|
|
"properties changed: \\+\\+name\\[{res[\\d\\w]{9}}!={res[\\d\\w]{9}}\\]<{%reset%}>\\n")
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).RunStep(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, validate, "4")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Check the resource's state.
|
|
|
|
if !assert.Len(t, snap.Resources, 1) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPlannedUpdateWithCheckFailure(t *testing.T) {
|
|
|
|
// Regression test for https://github.com/pulumi/pulumi/issues/9247
|
|
|
|
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: "created-id",
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
2024-07-26 12:14:45 +00:00
|
|
|
CheckF: func(
|
|
|
|
_ context.Context,
|
|
|
|
req plugin.CheckRequest,
|
|
|
|
) (plugin.CheckResponse, error) {
|
|
|
|
if req.News["foo"].StringValue() == "bad" {
|
|
|
|
return plugin.CheckResponse{
|
|
|
|
Failures: []plugin.CheckFailure{{
|
|
|
|
Property: resource.PropertyKey("foo"),
|
|
|
|
Reason: "Bad foo",
|
|
|
|
}},
|
2022-10-11 15:30:58 +00:00
|
|
|
}, nil
|
|
|
|
}
|
2024-07-26 12:14:45 +00:00
|
|
|
return plugin.CheckResponse{Properties: req.News}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
var ins resource.PropertyMap
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Generate a plan with bad inputs
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bad",
|
|
|
|
})
|
|
|
|
validate := ExpectDiagMessage(t, regexp.QuoteMeta(
|
|
|
|
"<{%reset%}>pkgA:m:typA resource 'resA': property foo value {bad} has a problem: Bad foo<{%reset%}>\n"))
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, validate)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.Nil(t, plan)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Generate a plan with good inputs
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "good",
|
|
|
|
})
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err = lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, nil)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, plan)
|
|
|
|
assert.Contains(t, plan.ResourcePlans, resource.URN("urn:pulumi:test::test::pkgA:m:typA::resA"))
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
|
|
|
// Try and run against the plan with inputs that will fail Check
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bad",
|
|
|
|
})
|
|
|
|
p.Options.Plan = plan.Clone()
|
|
|
|
validate = ExpectDiagMessage(t, regexp.QuoteMeta(
|
|
|
|
"<{%reset%}>pkgA:m:typA resource 'resA': property foo value {bad} has a problem: Bad foo<{%reset%}>\n"))
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).Run(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, validate)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
|
|
|
|
|
|
|
// Check the resource's state.
|
|
|
|
if !assert.Len(t, snap.Resources, 1) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPluginsAreDownloaded(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
semver10 := semver.MustParse("1.0.0")
|
|
|
|
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{})
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
return nil
|
2024-12-02 20:24:23 +00:00
|
|
|
},
|
|
|
|
workspace.PackageDescriptor{PluginSpec: workspace.PluginSpec{Name: "pkgA"}},
|
|
|
|
workspace.PackageDescriptor{PluginSpec: workspace.PluginSpec{Name: "pkgB", Version: &semver10}})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, nil)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, plan)
|
|
|
|
assert.Contains(t, plan.ResourcePlans, resource.URN("urn:pulumi:test::test::pkgA:m:typA::resA"))
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestProviderDeterministicPreview(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
var generatedName resource.PropertyValue
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
|
|
|
CheckF: func(
|
2024-07-26 12:14:45 +00:00
|
|
|
_ context.Context,
|
|
|
|
req plugin.CheckRequest,
|
|
|
|
) (plugin.CheckResponse, error) {
|
2022-10-11 15:30:58 +00:00
|
|
|
// make a deterministic autoname
|
2024-07-26 12:14:45 +00:00
|
|
|
if _, has := req.News["name"]; !has {
|
|
|
|
if name, has := req.Olds["name"]; has {
|
|
|
|
req.News["name"] = name
|
2022-10-11 15:30:58 +00:00
|
|
|
} else {
|
2024-07-26 12:14:45 +00:00
|
|
|
name, err := resource.NewUniqueName(req.RandomSeed, req.URN.Name(), -1, -1, nil)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
generatedName = resource.NewStringProperty(name)
|
2024-07-26 12:14:45 +00:00
|
|
|
req.News["name"] = generatedName
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-26 12:14:45 +00:00
|
|
|
return plugin.CheckResponse{Properties: req.News}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
2024-07-26 12:14:45 +00:00
|
|
|
DiffF: func(_ context.Context, req plugin.DiffRequest) (plugin.DiffResult, error) {
|
|
|
|
if !req.OldOutputs["foo"].DeepEquals(req.NewInputs["foo"]) {
|
2022-10-11 15:30:58 +00:00
|
|
|
// If foo changes do a replace, we use this to check we get a new name
|
|
|
|
return plugin.DiffResult{
|
|
|
|
Changes: plugin.DiffSome,
|
|
|
|
ReplaceKeys: []resource.PropertyKey{"foo"},
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
return plugin.DiffResult{}, nil
|
|
|
|
},
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: "created-id",
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-11 15:30:58 +00:00
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}, deploytest.WithoutGrpc),
|
|
|
|
}
|
|
|
|
|
|
|
|
ins := resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
})
|
|
|
|
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2022-10-11 15:30:58 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-11 15:30:58 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
|
|
|
HostF: hostF,
|
|
|
|
SkipDisplayTests: true,
|
|
|
|
UpdateOptions: UpdateOptions{GeneratePlan: true, Experimental: true},
|
2023-09-28 21:50:18 +00:00
|
|
|
},
|
2022-10-11 15:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Run a preview, this should want to create resA with a given name
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), p.Options, p.BackendClient, nil)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.True(t, generatedName.IsString())
|
|
|
|
assert.NotEqual(t, "", generatedName.StringValue())
|
|
|
|
expectedName := generatedName
|
|
|
|
|
|
|
|
// Run an update, we should get the same name as we saw in preview
|
|
|
|
p.Options.Plan = plan
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).RunStep(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, nil, "0")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
|
|
|
assert.Len(t, snap.Resources, 2)
|
|
|
|
assert.Equal(t, expectedName, snap.Resources[1].Inputs["name"])
|
|
|
|
assert.Equal(t, expectedName, snap.Resources[1].Outputs["name"])
|
|
|
|
|
|
|
|
// Run a new update which will cause a replace and check we get a new name
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "baz",
|
|
|
|
})
|
|
|
|
p.Options.Plan = nil
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, nil, "1")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-11 15:30:58 +00:00
|
|
|
assert.NotNil(t, snap)
|
|
|
|
assert.Len(t, snap.Resources, 2)
|
|
|
|
assert.NotEqual(t, expectedName, snap.Resources[1].Inputs["name"])
|
|
|
|
assert.NotEqual(t, expectedName, snap.Resources[1].Outputs["name"])
|
|
|
|
}
|
2022-10-10 10:18:57 +00:00
|
|
|
|
|
|
|
func TestPlannedUpdateWithDependentDelete(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
var diffResult *plugin.DiffResult
|
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{
|
2024-07-26 12:14:45 +00:00
|
|
|
CreateF: func(_ context.Context, req plugin.CreateRequest) (plugin.CreateResponse, error) {
|
|
|
|
return plugin.CreateResponse{
|
|
|
|
ID: resource.ID("created-id-" + req.URN.Name()),
|
|
|
|
Properties: req.Properties,
|
|
|
|
Status: resource.StatusOK,
|
|
|
|
}, nil
|
2022-10-10 10:18:57 +00:00
|
|
|
},
|
2024-07-26 12:14:45 +00:00
|
|
|
CheckF: func(
|
|
|
|
_ context.Context,
|
|
|
|
req plugin.CheckRequest,
|
|
|
|
) (plugin.CheckResponse, error) {
|
|
|
|
return plugin.CheckResponse{Properties: req.News}, nil
|
2022-10-10 10:18:57 +00:00
|
|
|
},
|
2024-07-26 12:14:45 +00:00
|
|
|
DiffF: func(_ context.Context, req plugin.DiffRequest) (plugin.DiffResult, error) {
|
|
|
|
if strings.Contains(string(req.URN), "resA") || strings.Contains(string(req.URN), "resB") {
|
2022-10-10 10:18:57 +00:00
|
|
|
assert.NotNil(t, diffResult, "Diff was called but diffResult wasn't set")
|
|
|
|
return *diffResult, nil
|
|
|
|
}
|
|
|
|
return plugin.DiffResult{}, nil
|
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
var ins resource.PropertyMap
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
respA, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2022-10-10 10:18:57 +00:00
|
|
|
Inputs: ins,
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err = monitor.RegisterResource("pkgA:m:typB", "resB", true, deploytest.ResourceOptions{
|
|
|
|
Inputs: respA.Outputs,
|
|
|
|
Dependencies: []resource.URN{respA.URN},
|
2022-10-10 10:18:57 +00:00
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2022-10-10 10:18:57 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{
|
|
|
|
Options: lt.TestUpdateOptions{T: t, HostF: hostF, UpdateOptions: UpdateOptions{GeneratePlan: true}},
|
2022-10-10 10:18:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Create an initial ResA and resB
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
"zed": "baz",
|
|
|
|
})
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err := lt.TestOp(Update).RunStep(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, nil, "0")
|
2022-10-10 10:18:57 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-10 10:18:57 +00:00
|
|
|
|
|
|
|
// Update the input and mark it as a replace, check that both A and B are marked as replacements
|
|
|
|
ins = resource.NewPropertyMapFromMap(map[string]interface{}{
|
|
|
|
"foo": "frob",
|
|
|
|
"zed": "baz",
|
|
|
|
})
|
|
|
|
diffResult = &plugin.DiffResult{
|
|
|
|
Changes: plugin.DiffSome,
|
|
|
|
ReplaceKeys: []resource.PropertyKey{"foo"},
|
|
|
|
StableKeys: []resource.PropertyKey{"zed"},
|
|
|
|
DetailedDiff: map[string]plugin.PropertyDiff{
|
|
|
|
"foo": {
|
|
|
|
Kind: plugin.DiffUpdateReplace,
|
|
|
|
InputDiff: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
DeleteBeforeReplace: true,
|
|
|
|
}
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, snap), p.Options, p.BackendClient, nil)
|
2022-10-10 10:18:57 +00:00
|
|
|
assert.NotNil(t, plan)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-10 10:18:57 +00:00
|
|
|
|
|
|
|
assert.Equal(t, 3, len(plan.ResourcePlans["urn:pulumi:test::test::pkgA:m:typA::resA"].Ops))
|
|
|
|
assert.Equal(t, 3, len(plan.ResourcePlans["urn:pulumi:test::test::pkgA:m:typB::resB"].Ops))
|
|
|
|
|
|
|
|
// Now try and run with the plan
|
|
|
|
p.Options.Plan = plan.Clone()
|
2024-10-28 11:58:59 +00:00
|
|
|
snap, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, nil, "1")
|
2022-10-10 10:18:57 +00:00
|
|
|
assert.NotNil(t, snap)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2022-10-10 10:18:57 +00:00
|
|
|
}
|
2023-04-07 22:40:41 +00:00
|
|
|
|
2023-05-02 16:42:58 +00:00
|
|
|
// TestResourcesTargeted checks that a plan created with targets specified captures only those targets and
|
|
|
|
// default providers. It checks that trying to construct a new resource that was not targeted in the plan
|
|
|
|
// fails and that the update with the same --targets specified is compatible with the plan (roundtripped).
|
2024-09-03 08:57:30 +00:00
|
|
|
func TestResourcesTargeted(t *testing.T) {
|
2023-04-07 22:40:41 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2023-09-28 21:50:18 +00:00
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{}, nil
|
|
|
|
}),
|
|
|
|
}
|
2023-04-07 22:40:41 +00:00
|
|
|
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{
|
2023-09-28 21:50:18 +00:00
|
|
|
Inputs: resource.PropertyMap{
|
|
|
|
"foo": resource.NewStringProperty("bar"),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
2023-04-07 22:40:41 +00:00
|
|
|
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err = monitor.RegisterResource("pkgA:m:typA", "resB", true, deploytest.ResourceOptions{
|
2023-09-28 21:50:18 +00:00
|
|
|
Inputs: resource.PropertyMap{
|
|
|
|
"foo": resource.NewStringProperty("bar"),
|
|
|
|
},
|
2023-04-07 22:40:41 +00:00
|
|
|
})
|
2023-09-28 21:50:18 +00:00
|
|
|
assert.NoError(t, err)
|
2023-04-07 22:40:41 +00:00
|
|
|
|
2023-09-28 21:50:18 +00:00
|
|
|
return nil
|
|
|
|
})
|
|
|
|
|
|
|
|
hostF := deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2023-04-07 22:40:41 +00:00
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{}
|
2023-04-07 22:40:41 +00:00
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Create the update plan with only targeted resources.
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{
|
|
|
|
Experimental: true,
|
|
|
|
GeneratePlan: true,
|
|
|
|
Targets: deploy.NewUrnTargets([]string{
|
|
|
|
"urn:pulumi:test::test::pkgA:m:typA::resB",
|
|
|
|
}),
|
|
|
|
},
|
2023-04-07 22:40:41 +00:00
|
|
|
}, p.BackendClient, nil)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2023-04-07 22:40:41 +00:00
|
|
|
assert.NotNil(t, plan)
|
|
|
|
|
|
|
|
// Check that running an update with everything targeted fails due to our plan being constrained
|
2023-05-02 16:42:58 +00:00
|
|
|
// to the resource.
|
2024-10-28 11:58:59 +00:00
|
|
|
_, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, nil), lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{
|
|
|
|
// Clone the plan as the plan will be mutated by the engine and useless in future runs.
|
|
|
|
Plan: plan.Clone(),
|
|
|
|
Experimental: true,
|
|
|
|
},
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
}, false, p.BackendClient, nil, "0")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.Error(t, err)
|
2023-04-07 22:40:41 +00:00
|
|
|
|
2023-05-23 20:17:59 +00:00
|
|
|
// Check that running an update with the same Targets as the Plan succeeds.
|
2024-10-28 11:58:59 +00:00
|
|
|
_, err = lt.TestOp(Update).RunStep(project, p.GetTarget(t, nil), lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: hostF,
|
|
|
|
UpdateOptions: UpdateOptions{
|
|
|
|
// Clone the plan as the plan will be mutated by the engine and useless in future runs.
|
|
|
|
Plan: plan.Clone(),
|
|
|
|
Experimental: true,
|
|
|
|
Targets: deploy.NewUrnTargets([]string{
|
|
|
|
"urn:pulumi:test::test::pkgA:m:typA::resB",
|
|
|
|
}),
|
|
|
|
},
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
}, false, p.BackendClient, nil, "1")
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2023-04-07 22:40:41 +00:00
|
|
|
}
|
2023-05-04 21:38:25 +00:00
|
|
|
|
|
|
|
// This test checks that registering resource outputs does not fail for the root stack resource when it
|
|
|
|
// is not specified by the update targets.
|
|
|
|
func TestStackOutputsWithTargetedPlan(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2024-10-28 11:58:59 +00:00
|
|
|
p := <.TestPlan{}
|
2023-05-04 21:38:25 +00:00
|
|
|
|
|
|
|
loaders := []*deploytest.ProviderLoader{
|
|
|
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
|
|
|
return &deploytest.Provider{}, nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
2023-09-28 21:50:18 +00:00
|
|
|
programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
2024-04-19 11:08:56 +00:00
|
|
|
resp, err := monitor.RegisterResource("pulumi:pulumi:Stack", "test-test", false)
|
2023-05-04 21:38:25 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2024-04-19 11:08:56 +00:00
|
|
|
_, err = monitor.RegisterResource("pkgA:m:typA", "resA", true)
|
2023-05-04 21:38:25 +00:00
|
|
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2024-04-19 11:08:56 +00:00
|
|
|
err = monitor.RegisterResourceOutputs(resp.URN, resource.PropertyMap{
|
2023-05-04 21:38:25 +00:00
|
|
|
"foo": resource.NewStringProperty("bar"),
|
|
|
|
})
|
|
|
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
|
2023-09-28 21:50:18 +00:00
|
|
|
p.Options.HostF = deploytest.NewPluginHostF(nil, nil, programF, loaders...)
|
2023-05-04 21:38:25 +00:00
|
|
|
|
|
|
|
project := p.GetProject()
|
|
|
|
|
|
|
|
// Create the update plan without targeting the root stack.
|
2024-10-28 11:58:59 +00:00
|
|
|
plan, err := lt.TestOp(Update).Plan(project, p.GetTarget(t, nil), lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: p.Options.HostF,
|
|
|
|
UpdateOptions: UpdateOptions{
|
|
|
|
Experimental: true,
|
|
|
|
GeneratePlan: true,
|
|
|
|
Targets: deploy.NewUrnTargetsFromUrns([]resource.URN{
|
|
|
|
resource.URN("urn:pulumi:test::test::pkgA:m:typA::resA"),
|
|
|
|
}),
|
|
|
|
},
|
2023-05-04 21:38:25 +00:00
|
|
|
}, p.BackendClient, nil)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2023-05-04 21:38:25 +00:00
|
|
|
assert.NotNil(t, plan)
|
|
|
|
|
|
|
|
// Check that update succeeds despite the root stack not being targeted.
|
2024-10-28 11:58:59 +00:00
|
|
|
_, err = lt.TestOp(Update).Run(project, p.GetTarget(t, nil), lt.TestUpdateOptions{
|
Add display to the engine tests (#16050)
We want to add more test coverage to the display code. The best way to
do that is to add it to the engine tests, that already cover most of the
pulumi functionality.
It's probably not really possible to review all of the output, but at
least it gives us a baseline, which we can work with.
There's a couple of tests that are flaky for reasons I don't quite
understand yet. I marked them as to skip and we can look at them later.
I'd rather get in the baseline tests sooner, rather than spending a
bunch of time looking at that. The output differences also seem very
minor, so not super concerning.
The biggest remaining issue is that this doesn't interact well with the
Chdir we're doing in the engine. We could either pass the CWD through,
or just try to get rid of that Chdir. So this should only be merged
after https://github.com/pulumi/pulumi/pull/15607.
I've tried to split this into a few commits, separating out adding the
testdata, so it's hopefully a little easier to review, even though the
PR is still quite large.
One other thing to note is that we're comparing that the output has all
the same lines, and not that it is exactly the same. Because of how the
engine is implemented, there's a bunch of race conditions otherwise,
that would make us have to skip a bunch of tests, just because e.g.
resource A is sometimes deleted before resource B and sometimes it's the
other way around.
The biggest downside of that is that running with `PULUMI_ACCEPT` will
produce a diff even when there are no changes. Hopefully we won't have
to run that way too often though, so it might not be a huge issue?
---------
Co-authored-by: Fraser Waters <fraser@pulumi.com>
2024-05-13 07:18:25 +00:00
|
|
|
T: t,
|
2023-09-28 21:50:18 +00:00
|
|
|
HostF: p.Options.HostF,
|
|
|
|
UpdateOptions: UpdateOptions{
|
|
|
|
GeneratePlan: true,
|
|
|
|
Experimental: true,
|
|
|
|
Targets: deploy.NewUrnTargetsFromUrns([]resource.URN{
|
|
|
|
resource.URN("urn:pulumi:test::test::pkgA:m:typA::resA"),
|
|
|
|
}),
|
|
|
|
},
|
2023-05-04 21:38:25 +00:00
|
|
|
}, false, p.BackendClient, nil)
|
2023-10-13 09:46:07 +00:00
|
|
|
assert.NoError(t, err)
|
2023-05-04 21:38:25 +00:00
|
|
|
}
|