pulumi/pkg/backend/display/detailedDiff_test.go
CyrusNajmabadi 66bd3f4aa8
Breaking changes due to Feature 2.0 work
* Make `async:true` the default for `invoke` calls (#3750)

* Switch away from native grpc impl. (#3728)

* Remove usage of the 'deasync' library from @pulumi/pulumi. (#3752)

* Only retry as long as we get unavailable back.  Anything else continues. (#3769)

* Handle all errors for now. (#3781)


* Do not assume --yes was present when using pulumi in non-interactive mode (#3793)

* Upgrade all paths for sdk and pkg to v2

* Backport C# invoke classes and other recent gen changes (#4288)

Adjust C# generation

* Replace IDeployment with a sealed class (#4318)

Replace IDeployment with a sealed class

* .NET: default to args subtype rather than Args.Empty (#4320)

* Adding system namespace for Dotnet code gen

This is required for using Obsolute attributes for deprecations

```
Iam/InstanceProfile.cs(142,10): error CS0246: The type or namespace name 'ObsoleteAttribute' could not be found (are you missing a using directive or an assembly reference?) [/Users/stack72/code/go/src/github.com/pulumi/pulumi-aws/sdk/dotnet/Pulumi.Aws.csproj]
Iam/InstanceProfile.cs(142,10): error CS0246: The type or namespace name 'Obsolete' could not be found (are you missing a using directive or an assembly reference?) [/Users/stack72/code/go/src/github.com/pulumi/pulumi-aws/sdk/dotnet/Pulumi.Aws.csproj]
```

* Fix the nullability of config type properties in C# codegen (#4379)
2020-04-14 09:30:25 +01:00

725 lines
18 KiB
Go

package display
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/pulumi/pulumi/pkg/v2/engine"
"github.com/pulumi/pulumi/sdk/v2/go/common/resource"
"github.com/pulumi/pulumi/sdk/v2/go/common/resource/plugin"
)
func TestTranslateDetailedDiff(t *testing.T) {
var (
A = plugin.PropertyDiff{Kind: plugin.DiffAdd}
D = plugin.PropertyDiff{Kind: plugin.DiffDelete}
U = plugin.PropertyDiff{Kind: plugin.DiffUpdate}
)
cases := []struct {
state map[string]interface{}
oldInputs map[string]interface{}
inputs map[string]interface{}
detailedDiff map[string]plugin.PropertyDiff
expected *resource.ObjectDiff
}{
{
state: map[string]interface{}{
"foo": 42,
},
inputs: map[string]interface{}{
"foo": 24,
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo": U,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Old: resource.NewNumberProperty(42),
New: resource.NewNumberProperty(24),
},
},
},
},
{
state: map[string]interface{}{
"foo": 42,
},
inputs: map[string]interface{}{
"foo": 42,
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo": U,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Old: resource.NewNumberProperty(42),
New: resource.NewNumberProperty(42),
},
},
},
},
{
state: map[string]interface{}{
"foo": 42,
"bar": "hello",
},
inputs: map[string]interface{}{
"foo": 24,
"bar": "hello",
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo": U,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Old: resource.NewNumberProperty(42),
New: resource.NewNumberProperty(24),
},
},
},
},
{
state: map[string]interface{}{
"foo": 42,
"bar": "hello",
},
inputs: map[string]interface{}{
"foo": 24,
"bar": "world",
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo": U,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Old: resource.NewNumberProperty(42),
New: resource.NewNumberProperty(24),
},
},
},
},
{
state: map[string]interface{}{},
inputs: map[string]interface{}{
"foo": 24,
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo": A,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{
"foo": resource.NewNumberProperty(24),
},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{},
},
},
{
state: map[string]interface{}{
"foo": 24,
},
inputs: map[string]interface{}{},
detailedDiff: map[string]plugin.PropertyDiff{
"foo": D,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{
"foo": resource.NewNumberProperty(24),
},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{},
},
},
{
state: map[string]interface{}{
"foo": 24,
},
oldInputs: map[string]interface{}{
"foo": 42,
},
inputs: map[string]interface{}{},
detailedDiff: map[string]plugin.PropertyDiff{
"foo": {
Kind: plugin.DiffDelete,
InputDiff: true,
},
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{
"foo": resource.NewNumberProperty(42),
},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{},
},
},
{
state: map[string]interface{}{
"foo": []interface{}{
"bar",
"baz",
},
},
inputs: map[string]interface{}{
"foo": []interface{}{
"bar",
"qux",
},
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo[1]": U,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Array: &resource.ArrayDiff{
Adds: map[int]resource.PropertyValue{},
Deletes: map[int]resource.PropertyValue{},
Sames: map[int]resource.PropertyValue{},
Updates: map[int]resource.ValueDiff{
1: {
Old: resource.NewStringProperty("baz"),
New: resource.NewStringProperty("qux"),
},
},
},
},
},
},
},
{
state: map[string]interface{}{
"foo": []interface{}{
"bar",
"baz",
},
},
inputs: map[string]interface{}{
"foo": []interface{}{
"bar",
"qux",
},
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo": U,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Old: resource.NewPropertyValue([]interface{}{
"bar",
"baz",
}),
New: resource.NewPropertyValue([]interface{}{
"bar",
"qux",
}),
Array: &resource.ArrayDiff{
Adds: map[int]resource.PropertyValue{},
Deletes: map[int]resource.PropertyValue{},
Sames: map[int]resource.PropertyValue{
0: resource.NewPropertyValue("bar"),
},
Updates: map[int]resource.ValueDiff{
1: {
Old: resource.NewStringProperty("baz"),
New: resource.NewStringProperty("qux"),
},
},
},
},
},
},
},
{
state: map[string]interface{}{
"foo": []interface{}{
"bar",
},
},
inputs: map[string]interface{}{
"foo": []interface{}{
"bar",
"baz",
},
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo[1]": A,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Array: &resource.ArrayDiff{
Adds: map[int]resource.PropertyValue{
1: resource.NewStringProperty("baz"),
},
Deletes: map[int]resource.PropertyValue{},
Sames: map[int]resource.PropertyValue{},
Updates: map[int]resource.ValueDiff{},
},
},
},
},
},
{
state: map[string]interface{}{
"foo": []interface{}{
"bar",
"baz",
},
},
inputs: map[string]interface{}{
"foo": []interface{}{
"bar",
},
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo[1]": D,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Array: &resource.ArrayDiff{
Adds: map[int]resource.PropertyValue{},
Deletes: map[int]resource.PropertyValue{
1: resource.NewStringProperty("baz"),
},
Sames: map[int]resource.PropertyValue{},
Updates: map[int]resource.ValueDiff{},
},
},
},
},
},
{
state: map[string]interface{}{
"foo": []interface{}{
"bar",
"baz",
},
},
inputs: map[string]interface{}{
"foo": []interface{}{
"bar",
"qux",
},
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo[100]": U,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Array: &resource.ArrayDiff{
Adds: map[int]resource.PropertyValue{},
Deletes: map[int]resource.PropertyValue{},
Sames: map[int]resource.PropertyValue{},
Updates: map[int]resource.ValueDiff{
100: {
Old: resource.PropertyValue{},
New: resource.PropertyValue{},
},
},
},
},
},
},
},
{
state: map[string]interface{}{
"foo": []interface{}{
"bar",
"baz",
},
},
inputs: map[string]interface{}{
"foo": []interface{}{
"bar",
"qux",
},
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo[100][200]": U,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Array: &resource.ArrayDiff{
Adds: map[int]resource.PropertyValue{},
Deletes: map[int]resource.PropertyValue{},
Sames: map[int]resource.PropertyValue{},
Updates: map[int]resource.ValueDiff{
100: {
Array: &resource.ArrayDiff{
Adds: map[int]resource.PropertyValue{},
Deletes: map[int]resource.PropertyValue{},
Sames: map[int]resource.PropertyValue{},
Updates: map[int]resource.ValueDiff{
200: {
Old: resource.PropertyValue{},
New: resource.PropertyValue{},
},
},
},
},
},
},
},
},
},
},
{
state: map[string]interface{}{
"foo": []interface{}{
map[string]interface{}{
"baz": 42,
},
},
},
inputs: map[string]interface{}{
"foo": []interface{}{},
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo[0].baz": D,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Array: &resource.ArrayDiff{
Adds: map[int]resource.PropertyValue{},
Deletes: map[int]resource.PropertyValue{
0: resource.NewObjectProperty(resource.PropertyMap{
"baz": resource.NewNumberProperty(42),
}),
},
Sames: map[int]resource.PropertyValue{},
Updates: map[int]resource.ValueDiff{},
},
},
},
},
},
{
state: map[string]interface{}{
"foo": map[string]interface{}{
"bar": "baz",
"qux": "zed",
},
},
inputs: map[string]interface{}{
"foo": map[string]interface{}{
"bar": "baz",
"qux": "alpha",
},
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo.qux": U,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Object: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"qux": {
Old: resource.NewStringProperty("zed"),
New: resource.NewStringProperty("alpha"),
},
},
},
},
},
},
},
{
state: map[string]interface{}{
"foo": map[string]interface{}{
"bar": "baz",
"qux": "zed",
},
},
inputs: map[string]interface{}{
"foo": map[string]interface{}{
"bar": "baz",
"qux": "alpha",
},
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo": U,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Old: resource.NewPropertyValue(map[string]interface{}{
"bar": "baz",
"qux": "zed",
}),
New: resource.NewPropertyValue(map[string]interface{}{
"bar": "baz",
"qux": "alpha",
}),
Object: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{
"bar": resource.NewPropertyValue("baz"),
},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"qux": {
Old: resource.NewStringProperty("zed"),
New: resource.NewStringProperty("alpha"),
},
},
},
},
},
},
},
{
state: map[string]interface{}{
"foo": map[string]interface{}{
"bar": "baz",
},
},
inputs: map[string]interface{}{
"foo": map[string]interface{}{
"bar": "baz",
"qux": "alpha",
},
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo.qux": A,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Object: &resource.ObjectDiff{
Adds: resource.PropertyMap{
"qux": resource.NewStringProperty("alpha"),
},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{},
},
},
},
},
},
{
state: map[string]interface{}{
"foo": map[string]interface{}{
"bar": "baz",
"qux": "zed",
},
},
inputs: map[string]interface{}{
"foo": map[string]interface{}{
"bar": "baz",
},
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo.qux": D,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Object: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{
"qux": resource.NewStringProperty("zed"),
},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{},
},
},
},
},
},
{
state: map[string]interface{}{
"foo": map[string]interface{}{
"bar": "baz",
"qux": "zed",
},
},
inputs: map[string]interface{}{
"foo": map[string]interface{}{
"bar": "baz",
"qux": "alpha",
},
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo.missing": U,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Object: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"missing": {
Old: resource.PropertyValue{},
New: resource.PropertyValue{},
},
},
},
},
},
},
},
{
state: map[string]interface{}{
"foo": map[string]interface{}{
"bar": "baz",
"qux": "zed",
},
},
inputs: map[string]interface{}{
"foo": map[string]interface{}{
"bar": "baz",
"qux": "alpha",
},
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo.nested.missing": U,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Object: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"nested": {
Object: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"missing": {
Old: resource.PropertyValue{},
New: resource.PropertyValue{},
},
},
},
},
},
},
},
},
},
},
{
state: map[string]interface{}{
"foo": []interface{}{
map[string]interface{}{
"baz": 42,
},
},
},
inputs: map[string]interface{}{
"foo": []interface{}{},
},
detailedDiff: map[string]plugin.PropertyDiff{
"foo[0].baz": D,
},
expected: &resource.ObjectDiff{
Adds: resource.PropertyMap{},
Deletes: resource.PropertyMap{},
Sames: resource.PropertyMap{},
Updates: map[resource.PropertyKey]resource.ValueDiff{
"foo": {
Array: &resource.ArrayDiff{
Adds: map[int]resource.PropertyValue{},
Deletes: map[int]resource.PropertyValue{
0: resource.NewObjectProperty(resource.PropertyMap{
"baz": resource.NewNumberProperty(42),
}),
},
Sames: map[int]resource.PropertyValue{},
Updates: map[int]resource.ValueDiff{},
},
},
},
},
},
}
for _, c := range cases {
oldInputs := resource.NewPropertyMapFromMap(c.oldInputs)
state := resource.NewPropertyMapFromMap(c.state)
inputs := resource.NewPropertyMapFromMap(c.inputs)
diff := translateDetailedDiff(engine.StepEventMetadata{
Old: &engine.StepEventStateMetadata{Inputs: oldInputs, Outputs: state},
New: &engine.StepEventStateMetadata{Inputs: inputs},
DetailedDiff: c.detailedDiff,
})
assert.Equal(t, c.expected, diff)
}
}