From d054102d38c54be67edccdd8f191e1beecd68252 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Tue, 21 Sep 2021 11:00:52 -0700 Subject: [PATCH] addrs: AbsResource.UniqueKey distinct from AbsResourceInstance.UniqueKey The whole point of UniqueKey is to deal with the fact that we have some distinct address types which have an identical string representation, but unfortunately that fact caused us to not notice that we'd incorrectly made AbsResource.UniqueKey return a no-key instance UniqueKey instead of its own distinct unique key type. --- internal/addrs/resource.go | 6 ++- internal/addrs/resource_test.go | 71 +++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/internal/addrs/resource.go b/internal/addrs/resource.go index 2c69d2f70..0ebf89d99 100644 --- a/internal/addrs/resource.go +++ b/internal/addrs/resource.go @@ -194,8 +194,12 @@ func (r AbsResource) absMoveableSigil() { // AbsResource is moveable } +type absResourceKey string + +func (r absResourceKey) uniqueKeySigil() {} + func (r AbsResource) UniqueKey() UniqueKey { - return absResourceInstanceKey(r.String()) + return absResourceKey(r.String()) } // AbsResourceInstance is an absolute address for a resource instance under a diff --git a/internal/addrs/resource_test.go b/internal/addrs/resource_test.go index fbaa981f4..d68d2b5d4 100644 --- a/internal/addrs/resource_test.go +++ b/internal/addrs/resource_test.go @@ -215,6 +215,77 @@ func TestAbsResourceInstanceEqual_false(t *testing.T) { } } +func TestAbsResourceUniqueKey(t *testing.T) { + resourceAddr1 := Resource{ + Mode: ManagedResourceMode, + Type: "a", + Name: "b1", + }.Absolute(RootModuleInstance) + resourceAddr2 := Resource{ + Mode: ManagedResourceMode, + Type: "a", + Name: "b2", + }.Absolute(RootModuleInstance) + resourceAddr3 := Resource{ + Mode: ManagedResourceMode, + Type: "a", + Name: "in_module", + }.Absolute(RootModuleInstance.Child("boop", NoKey)) + + tests := []struct { + Reciever AbsResource + Other UniqueKeyer + WantEqual bool + }{ + { + resourceAddr1, + resourceAddr1, + true, + }, + { + resourceAddr1, + resourceAddr2, + false, + }, + { + resourceAddr1, + resourceAddr3, + false, + }, + { + resourceAddr3, + resourceAddr3, + true, + }, + { + resourceAddr1, + resourceAddr1.Instance(NoKey), + false, // no-key instance key is distinct from its resource even though they have the same String result + }, + { + resourceAddr1, + resourceAddr1.Instance(IntKey(1)), + false, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf("%s matches %T %s?", test.Reciever, test.Other, test.Other), func(t *testing.T) { + rKey := test.Reciever.UniqueKey() + oKey := test.Other.UniqueKey() + + gotEqual := rKey == oKey + if gotEqual != test.WantEqual { + t.Errorf( + "wrong result\nreceiver: %s\nother: %s (%T)\ngot: %t\nwant: %t", + test.Reciever, test.Other, test.Other, + gotEqual, test.WantEqual, + ) + } + }) + } +} + func TestConfigResourceEqual_true(t *testing.T) { resources := []ConfigResource{ {