From 804da4be576976398123b8a27f5c4b1062d15f9a Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Wed, 26 Sep 2018 12:01:15 -0700 Subject: [PATCH] core: Fix TestContext2Apply_multiDepose_createBeforeDestroy Since this one has a situation where there are two deposed objects for the same instance at once, we can't rely on comparing state strings: they are not deterministic when multiple deposed objects are present. Instead, we do more surgical comparisons directly on the state model objects, which is not quite as robust but still gets us the main stuff we care about here, to be followed up by another checkStateString further down for the final state. --- terraform/context_apply_test.go | 49 ++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/terraform/context_apply_test.go b/terraform/context_apply_test.go index ec82eee45..4f22026e2 100644 --- a/terraform/context_apply_test.go +++ b/terraform/context_apply_test.go @@ -1,6 +1,7 @@ package terraform import ( + "bytes" "encoding/json" "errors" "fmt" @@ -4762,6 +4763,16 @@ func TestContext2Apply_multiDepose_createBeforeDestroy(t *testing.T) { m := testModule(t, "apply-multi-depose-create-before-destroy") p := testProvider("aws") p.DiffFn = testDiffFn + p.GetSchemaReturn = &ProviderSchema{ + ResourceTypes: map[string]*configschema.Block{ + "aws_instance": { + Attributes: map[string]*configschema.Attribute{ + "require_new": {Type: cty.String, Optional: true}, + "id": {Type: cty.String, Computed: true}, + }, + }, + }, + } ps := map[string]providers.Factory{"aws": testProviderFuncFixed(p)} state := mustShimLegacyState(&State{ Modules: []*ModuleState{ @@ -4835,13 +4846,37 @@ aws_instance.web: (1 deposed) t.Fatal("should have error") } - checkStateString(t, state, ` -aws_instance.web: (2 deposed) - ID = baz - provider = provider.aws - Deposed ID 1 = foo - Deposed ID 2 = bar - `) + // For this one we can't rely on checkStateString because its result is + // not deterministic when multiple deposed objects are present. Instead, + // we will probe the state object directly. + { + is := state.RootModule().Resources["aws_instance.web"].Instances[addrs.NoKey] + t.Logf("aws_instance.web is %s", spew.Sdump(is)) + if is.Current == nil { + t.Fatalf("no current object for aws_instance web; should have one") + } + if !bytes.Contains(is.Current.AttrsJSON, []byte("baz")) { + t.Fatalf("incorrect current object attrs %s; want id=baz", is.Current.AttrsJSON) + } + if got, want := len(is.Deposed), 2; got != want { + t.Fatalf("wrong number of deposed instances %d; want %d", got, want) + } + var foos, bars int + for _, obj := range is.Deposed { + if bytes.Contains(obj.AttrsJSON, []byte("foo")) { + foos++ + } + if bytes.Contains(obj.AttrsJSON, []byte("bar")) { + bars++ + } + } + if got, want := foos, 1; got != want { + t.Fatalf("wrong number of deposed instances with id=foo %d; want %d", got, want) + } + if got, want := bars, 1; got != want { + t.Fatalf("wrong number of deposed instances with id=bar %d; want %d", got, want) + } + } // Destroy partially fixed! destroyFunc = func(is *InstanceState) (*InstanceState, error) {