Skip to content

Commit

Permalink
Full fidelity SDKv2 crosstest.Configure equality
Browse files Browse the repository at this point in the history
Stacked on top of #2840.

This switches `crosstest.Configure` over to using a stronger comparison function.

Fixes #2521
  • Loading branch information
iwahbe committed Jan 17, 2025
1 parent cece87c commit 80add2e
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 66 deletions.
69 changes: 19 additions & 50 deletions pkg/internal/tests/cross-tests/assert.go
Original file line number Diff line number Diff line change
@@ -1,70 +1,39 @@
package crosstests

import (
"github.com/hashicorp/go-cty/cty"
"reflect"

"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func FailNotEqual(t T, name string, tfVal, pulVal any) {
t.Logf(name + " not equal!")
t.Logf("TF value %s", tfVal)
t.Logf("PU value %s", pulVal)
t.Fail()
}

func assertCtyValEqual(t T, name string, tfVal, pulVal cty.Value) {
if !tfVal.RawEquals(pulVal) {
FailNotEqual(t, name, tfVal.GoString(), pulVal.GoString())
}
}

func assertValEqual(t T, name string, tfVal, pulVal any) {
// usually plugin-sdk schema types
if hasEqualTfVal, ok := tfVal.(interface{ Equal(interface{}) bool }); ok {
if !hasEqualTfVal.Equal(pulVal) {
FailNotEqual(t, name, tfVal, pulVal)
t.Logf(name + " not equal!")
t.Logf("TF value %s", tfVal)
t.Logf("PU value %s", pulVal)
t.Fail()
}
} else {
require.Equal(t, tfVal, pulVal, "Values for key %s do not match", name)
}
}

func assertResourceDataEqual(t T, resourceSchema map[string]*schema.Schema, tfResult, puResult *schema.ResourceData) {
// TODO[pulumi/pulumi-terraform-bridge#2521]: We are unable to assert that both
// providers were configured with the exact same data. Type information doesn't
// line up in the simple case. This just doesn't work:
//
// assert.Equal(t, tfResult, puResult)
//
// We make do by comparing slices tfResult and puResult.
require.NotNil(t, tfResult)
require.NotNil(t, puResult)
assertCtyValEqual(t, "RawConfig", tfResult.GetRawConfig(), puResult.GetRawConfig())
assertCtyValEqual(t, "RawPlan", tfResult.GetRawPlan(), puResult.GetRawPlan())
assertCtyValEqual(t, "RawState", tfResult.GetRawState(), puResult.GetRawState())

for _, timeout := range []string{
schema.TimeoutCreate,
schema.TimeoutRead,
schema.TimeoutUpdate,
schema.TimeoutDelete,
schema.TimeoutDefault,
} {
assert.Equal(t, tfResult.Timeout(timeout), puResult.Timeout(timeout), "timeout %s", timeout)
func assertResourceDataEqual(t T, tfResult, puResult *schema.ResourceData) {
// Use cmp to check if data is equal. We need to use cmp instead of
// `assert`'s default `reflect.DeepEqual` because cmp treats identical
// function pointers as equal, but `reflect.DeepEqual` does not.
opts := []cmp.Option{
cmp.Exporter(func(reflect.Type) bool { return true }),
cmp.Comparer(func(x, y schema.SchemaStateFunc) bool {
return reflect.ValueOf(x).Pointer() == reflect.ValueOf(y).Pointer()
}),
}

for k := range resourceSchema {
// TODO: make this recursive
tfVal := tfResult.Get(k)
pulVal := puResult.Get(k)

tfChangeValOld, tfChangeValNew := tfResult.GetChange(k)
pulChangeValOld, pulChangeValNew := puResult.GetChange(k)

assertValEqual(t, k, tfVal, pulVal)
assertValEqual(t, k+" Change Old", tfChangeValOld, pulChangeValOld)
assertValEqual(t, k+" Change New", tfChangeValNew, pulChangeValNew)
if !cmp.Equal(tfResult, puResult, opts...) {
t.Logf("Diff: %s", cmp.Diff(tfResult, puResult, opts...))
t.Fail()
}
}
2 changes: 1 addition & 1 deletion pkg/internal/tests/cross-tests/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func Configure(
}
require.True(t, puResult.resourceCreated, "pulumi resource result was not set")

assertResourceDataEqual(t, provider, tfResult.data, puResult.data)
assertResourceDataEqual(t, tfResult.data, puResult.data)
}

type configureOpts struct {
Expand Down
16 changes: 1 addition & 15 deletions pkg/internal/tests/cross-tests/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@ package crosstests

import (
"context"
"reflect"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
Expand Down Expand Up @@ -122,19 +120,7 @@ func Create(
// Compare the result
if assert.True(t, tfResult.wasSet) && assert.True(t, puResult.wasSet) {
assert.Equal(t, tfResult.meta, puResult.meta, "meta")
// Use cmp to check if data is equal. We need to use cmp instead of
// `assert`'s default `reflect.DeepEqual` because cmp treats identical
// function pointers as equal, but `reflect.DeepEqual` does not.
opts := []cmp.Option{
cmp.Exporter(func(reflect.Type) bool { return true }),
cmp.Comparer(func(x, y schema.SchemaStateFunc) bool {
return reflect.ValueOf(x).Pointer() == reflect.ValueOf(y).Pointer()
}),
}
if !cmp.Equal(tfResult.data, puResult.data, opts...) {
t.Logf("Diff: %s", cmp.Diff(tfResult.data, puResult.data, opts...))
t.Fail()
}
assertResourceDataEqual(t, tfResult.data, puResult.data)
}
}

Expand Down

0 comments on commit 80add2e

Please sign in to comment.