|
1 | 1 | package crosstests |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "github.com/hashicorp/go-cty/cty" |
| 4 | + "reflect" |
| 5 | + |
| 6 | + "github.com/google/go-cmp/cmp" |
5 | 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" |
6 | | - "github.com/stretchr/testify/assert" |
7 | 8 | "github.com/stretchr/testify/require" |
8 | 9 | ) |
9 | 10 |
|
10 | | -func FailNotEqual(t T, name string, tfVal, pulVal any) { |
11 | | - t.Logf(name + " not equal!") |
12 | | - t.Logf("TF value %s", tfVal) |
13 | | - t.Logf("PU value %s", pulVal) |
14 | | - t.Fail() |
15 | | -} |
16 | | - |
17 | | -func assertCtyValEqual(t T, name string, tfVal, pulVal cty.Value) { |
18 | | - if !tfVal.RawEquals(pulVal) { |
19 | | - FailNotEqual(t, name, tfVal.GoString(), pulVal.GoString()) |
20 | | - } |
21 | | -} |
22 | | - |
23 | 11 | func assertValEqual(t T, name string, tfVal, pulVal any) { |
24 | 12 | // usually plugin-sdk schema types |
25 | 13 | if hasEqualTfVal, ok := tfVal.(interface{ Equal(interface{}) bool }); ok { |
26 | 14 | if !hasEqualTfVal.Equal(pulVal) { |
27 | | - FailNotEqual(t, name, tfVal, pulVal) |
| 15 | + t.Logf(name + " not equal!") |
| 16 | + t.Logf("TF value %s", tfVal) |
| 17 | + t.Logf("PU value %s", pulVal) |
| 18 | + t.Fail() |
28 | 19 | } |
29 | 20 | } else { |
30 | 21 | require.Equal(t, tfVal, pulVal, "Values for key %s do not match", name) |
31 | 22 | } |
32 | 23 | } |
33 | 24 |
|
34 | | -func assertResourceDataEqual(t T, resourceSchema map[string]*schema.Schema, tfResult, puResult *schema.ResourceData) { |
35 | | - // TODO[pulumi/pulumi-terraform-bridge#2521]: We are unable to assert that both |
36 | | - // providers were configured with the exact same data. Type information doesn't |
37 | | - // line up in the simple case. This just doesn't work: |
38 | | - // |
39 | | - // assert.Equal(t, tfResult, puResult) |
40 | | - // |
41 | | - // We make do by comparing slices tfResult and puResult. |
42 | | - require.NotNil(t, tfResult) |
43 | | - require.NotNil(t, puResult) |
44 | | - assertCtyValEqual(t, "RawConfig", tfResult.GetRawConfig(), puResult.GetRawConfig()) |
45 | | - assertCtyValEqual(t, "RawPlan", tfResult.GetRawPlan(), puResult.GetRawPlan()) |
46 | | - assertCtyValEqual(t, "RawState", tfResult.GetRawState(), puResult.GetRawState()) |
47 | | - |
48 | | - for _, timeout := range []string{ |
49 | | - schema.TimeoutCreate, |
50 | | - schema.TimeoutRead, |
51 | | - schema.TimeoutUpdate, |
52 | | - schema.TimeoutDelete, |
53 | | - schema.TimeoutDefault, |
54 | | - } { |
55 | | - assert.Equal(t, tfResult.Timeout(timeout), puResult.Timeout(timeout), "timeout %s", timeout) |
| 25 | +func assertResourceDataEqual(t T, tfResult, puResult *schema.ResourceData) { |
| 26 | + // Use cmp to check if data is equal. We need to use cmp instead of |
| 27 | + // `assert`'s default `reflect.DeepEqual` because cmp treats identical |
| 28 | + // function pointers as equal, but `reflect.DeepEqual` does not. |
| 29 | + opts := []cmp.Option{ |
| 30 | + cmp.Exporter(func(reflect.Type) bool { return true }), |
| 31 | + cmp.Comparer(func(x, y schema.SchemaStateFunc) bool { |
| 32 | + return reflect.ValueOf(x).Pointer() == reflect.ValueOf(y).Pointer() |
| 33 | + }), |
56 | 34 | } |
57 | | - |
58 | | - for k := range resourceSchema { |
59 | | - // TODO: make this recursive |
60 | | - tfVal := tfResult.Get(k) |
61 | | - pulVal := puResult.Get(k) |
62 | | - |
63 | | - tfChangeValOld, tfChangeValNew := tfResult.GetChange(k) |
64 | | - pulChangeValOld, pulChangeValNew := puResult.GetChange(k) |
65 | | - |
66 | | - assertValEqual(t, k, tfVal, pulVal) |
67 | | - assertValEqual(t, k+" Change Old", tfChangeValOld, pulChangeValOld) |
68 | | - assertValEqual(t, k+" Change New", tfChangeValNew, pulChangeValNew) |
| 35 | + if !cmp.Equal(tfResult, puResult, opts...) { |
| 36 | + t.Logf("Diff: %s", cmp.Diff(tfResult, puResult, opts...)) |
| 37 | + t.Fail() |
69 | 38 | } |
70 | 39 | } |
0 commit comments