From a05726bbce24ba98ed28b8b2a9b7d0383125ef30 Mon Sep 17 00:00:00 2001 From: Ian Wahbe Date: Fri, 17 Jan 2025 14:29:39 +0100 Subject: [PATCH] Full fidelity SDKv2 `crosstest.Configure` equality Stacked on top of #2840. This switches `crosstest.Configure` over to using a stronger comparison function. Fixes #2521 --- pkg/internal/tests/cross-tests/assert.go | 69 ++++++--------------- pkg/internal/tests/cross-tests/configure.go | 2 +- pkg/internal/tests/cross-tests/create.go | 16 +---- 3 files changed, 21 insertions(+), 66 deletions(-) diff --git a/pkg/internal/tests/cross-tests/assert.go b/pkg/internal/tests/cross-tests/assert.go index 7c71f08fb..95646d89a 100644 --- a/pkg/internal/tests/cross-tests/assert.go +++ b/pkg/internal/tests/cross-tests/assert.go @@ -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() } } diff --git a/pkg/internal/tests/cross-tests/configure.go b/pkg/internal/tests/cross-tests/configure.go index 7e54bf642..efdaf064c 100644 --- a/pkg/internal/tests/cross-tests/configure.go +++ b/pkg/internal/tests/cross-tests/configure.go @@ -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 { diff --git a/pkg/internal/tests/cross-tests/create.go b/pkg/internal/tests/cross-tests/create.go index 0efea6eb7..11d2830c2 100644 --- a/pkg/internal/tests/cross-tests/create.go +++ b/pkg/internal/tests/cross-tests/create.go @@ -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" @@ -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) } }