Skip to content

Commit

Permalink
Prevent directly nested output failure for TestRapidDeepEqual (#275)
Browse files Browse the repository at this point in the history
Fixes #274

Issue #274 revealed a bug in the test, but not in the actual
`DeepEquals` implementation.
  • Loading branch information
iwahbe authored Sep 19, 2024
1 parent dd0bf94 commit c63d6b6
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 54 deletions.
7 changes: 6 additions & 1 deletion internal/putil/putil.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
// Package putil contains utility functions for working with [resource.PropertyValue]s.
package putil

import "github.com/pulumi/pulumi/sdk/v3/go/common/resource"
import (
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
)

// IsComputed checks if v is some form of a computed/unknown value.
func IsComputed(v resource.PropertyValue) bool {
Expand Down Expand Up @@ -106,6 +109,8 @@ func MakeKnown(v resource.PropertyValue) resource.PropertyValue {
// 2. It doesn't panic when computed values are present.
func DeepEquals(a, b resource.PropertyValue) bool {
a, b = foldOutputValue(a), foldOutputValue(b)
contract.Assertf(!a.IsSecret() && !b.IsSecret(), "Secrets should be Outputs at this point")
contract.Assertf(!a.IsComputed() && !b.IsComputed(), "Computed should be Outputs at this point")
switch {
case a.IsOutput() && b.IsOutput():
a, b := a.OutputValue(), b.OutputValue()
Expand Down
103 changes: 103 additions & 0 deletions internal/putil/putil_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright 2024, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package putil_test

import (
"testing"

"github.com/pulumi/pulumi-go-provider/internal/putil"
rresource "github.com/pulumi/pulumi-go-provider/internal/rapid/resource"
r "github.com/pulumi/pulumi/sdk/v3/go/common/resource"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource/urn"
"github.com/stretchr/testify/assert"
"pgregory.net/rapid"
)

func TestRapidDeepEqual(t *testing.T) {
t.Parallel()

t.Run("reflexivity", rapid.MakeCheck(func(t *rapid.T) { //nolint:paralleltest
value := rresource.PropertyValue(5).Draw(t, "value")
assert.True(t, putil.DeepEquals(value, value))
}))

// Check that "distinct" values never equal themselves.
t.Run("distinct-values", rapid.MakeCheck(func(t *rapid.T) { //nolint:paralleltest
// keyFn is how [rapid] determines that values are distinct.
//
// We do this by calling [fmt.Stringer.String] on the normalized form of v.
keyFn := func(v r.PropertyValue) string { return normalize(v).String() }
values := rapid.SliceOfNDistinct(
rresource.PropertyValue(5), 2, 2, keyFn,
).Draw(t, "distinct")
assert.False(t, putil.DeepEquals(values[0], values[1]))
}))

t.Run("nested-outputs", func(t *testing.T) {
t.Parallel()

v1 := r.NewProperty(r.Output{
Element: r.NewProperty(r.Output{
Element: r.PropertyValue{V: interface{}(nil)},
Known: false,
Secret: false,
Dependencies: []urn.URN{
"",
"&\n[?", "\x7f=&\u202c\x7fᾩ:AȺ~",
"!aAὂ̥\ue007~a\x01?۵%",
"*\"\u2005\ue005-a=\v\u2008䍨~ᶞ٣_",
},
}),
Known: true,
Secret: true,
Dependencies: []urn.URN{
"",
"A#@\u008b%\x00$\u202e\U000e006a|ᛮ<:ፘ.᭴ो〦\U000fd7da!𞥋\v%\x7fڌ֝[A{ॊⅣ\nA1|_\u3000%a",
"%",
},
})
v2 := r.NewProperty(r.Output{
Element: r.PropertyValue{V: interface{}(nil)},
Known: false,
Secret: true,
Dependencies: []urn.URN{
"",
"̿A#꙲ .\u2029\u1680~;,*\ue000֍\ue001º`a貦",
"_¦?!",
"\u2007�",
";\U000e003e\r𞥋\\𞓶\x02٦Lj$=1𝛜ᾫ?",
"{Aັ\\Dž",
"̆aLjⅺ*~",
},
})

assert.True(t, putil.DeepEquals(v1, v2))
})

t.Run("folding-secret-computed", func(t *testing.T) {
t.Parallel()

assert.True(t, putil.DeepEquals(
r.MakeComputed(r.MakeSecret(r.NewStringProperty("hi"))),
r.MakeSecret(r.MakeComputed(r.NewStringProperty("hi")))))
assert.False(t, putil.DeepEquals(
r.MakeSecret(r.NewStringProperty("hi")),
r.MakeComputed(r.NewStringProperty("hi"))))
})
}

func normalize(p r.PropertyValue) r.PropertyValue {
return r.ToResourcePropertyValue(r.FromResourcePropertyValue(p))
}
53 changes: 0 additions & 53 deletions putil/putil_test.go

This file was deleted.

0 comments on commit c63d6b6

Please sign in to comment.