From 052345abfe2f59b7ce724818cd205e56fd009ea7 Mon Sep 17 00:00:00 2001 From: James Nugent Date: Sun, 12 Jun 2016 12:33:05 +0200 Subject: [PATCH] core: Fix empty multi-variable type Previously, interpolation of multi-variables was returning an empty variable if the resource count was 0. The empty variable was defined as TypeString, Value "". This means that empty resource counts fail type checking for interpolation functions which operate on lists. Instead, return an empty list if the count is 0. A context test tests this against further regression. Also add a regression test covering the case of a single count multi-variable. In order to make the context testing framework deal with this change it was necessary to special case empty lists in the test diff function. Fixes #7002 --- terraform/context_apply_test.go | 63 +++++++++++++++++++ terraform/context_test.go | 8 ++- terraform/interpolate.go | 2 +- .../apply-resource-count-one-list/main.tf | 7 +++ .../apply-resource-count-zero-list/main.tf | 7 +++ 5 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 terraform/test-fixtures/apply-resource-count-one-list/main.tf create mode 100644 terraform/test-fixtures/apply-resource-count-zero-list/main.tf diff --git a/terraform/context_apply_test.go b/terraform/context_apply_test.go index d643991590..a287abdd80 100644 --- a/terraform/context_apply_test.go +++ b/terraform/context_apply_test.go @@ -48,6 +48,69 @@ func TestContext2Apply(t *testing.T) { } } +func TestContext2Apply_resourceCountOneList(t *testing.T) { + m := testModule(t, "apply-resource-count-one-list") + p := testProvider("null") + p.ApplyFn = testApplyFn + p.DiffFn = testDiffFn + ctx := testContext2(t, &ContextOpts{ + Module: m, + Providers: map[string]ResourceProviderFactory{ + "null": testProviderFuncFixed(p), + }, + }) + + if _, err := ctx.Plan(); err != nil { + t.Fatalf("err: %s", err) + } + + state, err := ctx.Apply() + if err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(state.String()) + expected := strings.TrimSpace(`null_resource.foo: + ID = foo + +Outputs: + +test = [foo]`) + if actual != expected { + t.Fatalf("expected: \n%s\n\ngot: \n%s\n", expected, actual) + } +} +func TestContext2Apply_resourceCountZeroList(t *testing.T) { + m := testModule(t, "apply-resource-count-zero-list") + p := testProvider("null") + p.ApplyFn = testApplyFn + p.DiffFn = testDiffFn + ctx := testContext2(t, &ContextOpts{ + Module: m, + Providers: map[string]ResourceProviderFactory{ + "null": testProviderFuncFixed(p), + }, + }) + + if _, err := ctx.Plan(); err != nil { + t.Fatalf("err: %s", err) + } + + state, err := ctx.Apply() + if err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(state.String()) + expected := strings.TrimSpace(` +Outputs: + +test = []`) + if actual != expected { + t.Fatalf("expected: \n%s\n\ngot: \n%s\n", expected, actual) + } +} + func TestContext2Apply_mapVarBetweenModules(t *testing.T) { m := testModule(t, "apply-map-var-through-module") p := testProvider("null") diff --git a/terraform/context_test.go b/terraform/context_test.go index 897539f6dc..6d3f1e57f8 100644 --- a/terraform/context_test.go +++ b/terraform/context_test.go @@ -2,6 +2,7 @@ package terraform import ( "fmt" + "reflect" "strings" "testing" "time" @@ -166,7 +167,12 @@ func testDiffFn( attrDiff := &ResourceAttrDiff{ Old: "", - New: v.(string), + } + + if reflect.DeepEqual(v, []interface{}{}) { + attrDiff.New = "" + } else { + attrDiff.New = v.(string) } if k == "require_new" { diff --git a/terraform/interpolate.go b/terraform/interpolate.go index bb0d22144d..f03154141c 100644 --- a/terraform/interpolate.go +++ b/terraform/interpolate.go @@ -487,7 +487,7 @@ func (i *Interpolater) computeResourceMultiVariable( // If we have no module in the state yet or count, return empty if module == nil || len(module.Resources) == 0 || count == 0 { - return &ast.Variable{Type: ast.TypeString, Value: ""}, nil + return &ast.Variable{Type: ast.TypeList, Value: []ast.Variable{}}, nil } var values []string diff --git a/terraform/test-fixtures/apply-resource-count-one-list/main.tf b/terraform/test-fixtures/apply-resource-count-one-list/main.tf new file mode 100644 index 0000000000..0aeb75b1af --- /dev/null +++ b/terraform/test-fixtures/apply-resource-count-one-list/main.tf @@ -0,0 +1,7 @@ +resource "null_resource" "foo" { + count = 1 +} + +output "test" { + value = "${sort(null_resource.foo.*.id)}" +} diff --git a/terraform/test-fixtures/apply-resource-count-zero-list/main.tf b/terraform/test-fixtures/apply-resource-count-zero-list/main.tf new file mode 100644 index 0000000000..6d9b4d55d2 --- /dev/null +++ b/terraform/test-fixtures/apply-resource-count-zero-list/main.tf @@ -0,0 +1,7 @@ +resource "null_resource" "foo" { + count = 0 +} + +output "test" { + value = "${sort(null_resource.foo.*.id)}" +}