From fc7453c07327e7647b18d75d07f13fbc3f901cfb Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Fri, 11 May 2018 14:40:40 -0700 Subject: [PATCH] core: Update tests that use the apply-vars fixture These now need to include a suitable schema in order to properly process the configuration. --- terraform/context_apply_test.go | 138 +++++++++--------- terraform/context_fixtures_test.go | 84 +++++++++++ terraform/context_validate_test.go | 69 ++++----- terraform/terraform_test.go | 22 ++- .../test-fixtures/apply-vars-env/main.tf | 14 +- terraform/test-fixtures/apply-vars/main.tf | 18 +-- 6 files changed, 211 insertions(+), 134 deletions(-) create mode 100644 terraform/context_fixtures_test.go diff --git a/terraform/context_apply_test.go b/terraform/context_apply_test.go index 99bd9dc66e..ee588b996e 100644 --- a/terraform/context_apply_test.go +++ b/terraform/context_apply_test.go @@ -8336,106 +8336,102 @@ func TestContext2Apply_unknownAttributeInterpolate(t *testing.T) { } func TestContext2Apply_vars(t *testing.T) { - m := testModule(t, "apply-vars") - p := testProvider("aws") - p.ApplyFn = testApplyFn - p.DiffFn = testDiffFn - ctx := testContext2(t, &ContextOpts{ - Config: m, - ProviderResolver: ResourceProviderResolverFixed( - map[string]ResourceProviderFactory{ - "aws": testProviderFuncFixed(p), - }, - ), - Variables: InputValues{ - "foo": &InputValue{ - Value: cty.StringVal("us-west-2"), - SourceType: ValueFromCaller, - }, - "test_list": &InputValue{ - Value: cty.ListVal([]cty.Value{ - cty.StringVal("Hello"), - cty.StringVal("World"), - }), - SourceType: ValueFromCaller, - }, - "test_map": &InputValue{ - Value: cty.MapVal(map[string]cty.Value{ - "Hello": cty.StringVal("World"), - "Foo": cty.StringVal("Bar"), - "Baz": cty.StringVal("Foo"), - }), - SourceType: ValueFromCaller, - }, - "amis": &InputValue{ - Value: cty.ListVal([]cty.Value{ - cty.MapVal(map[string]cty.Value{ - "us-west-1": cty.StringVal("override"), - }), - }), - SourceType: ValueFromCaller, - }, + fixture := contextFixtureApplyVars(t) + opts := fixture.ContextOpts() + opts.Variables = InputValues{ + "foo": &InputValue{ + Value: cty.StringVal("us-east-1"), + SourceType: ValueFromCaller, }, - }) + "test_list": &InputValue{ + Value: cty.ListVal([]cty.Value{ + cty.StringVal("Hello"), + cty.StringVal("World"), + }), + SourceType: ValueFromCaller, + }, + "test_map": &InputValue{ + Value: cty.MapVal(map[string]cty.Value{ + "Hello": cty.StringVal("World"), + "Foo": cty.StringVal("Bar"), + "Baz": cty.StringVal("Foo"), + }), + SourceType: ValueFromCaller, + }, + "amis": &InputValue{ + Value: cty.MapVal(map[string]cty.Value{ + "us-east-1": cty.StringVal("override"), + }), + SourceType: ValueFromCaller, + }, + } + ctx := testContext2(t, opts) diags := ctx.Validate() if len(diags) != 0 { - t.Fatalf("bad: %#v", diags) + t.Fatalf("bad: %s", diags.ErrWithWarnings()) } - if _, err := ctx.Plan(); err != nil { - t.Fatalf("err: %s", err) + if _, diags := ctx.Plan(); diags.HasErrors() { + t.Fatalf("err: %s", diags.Err()) } - state, err := ctx.Apply() - if err != nil { - t.Fatalf("err: %s", err) + state, diags := ctx.Apply() + if diags.HasErrors() { + t.Fatalf("err: %s", diags.Err()) } actual := strings.TrimSpace(state.String()) expected := strings.TrimSpace(testTerraformApplyVarsStr) if actual != expected { - t.Fatalf("expected: %s\n got:\n%s", expected, actual) + t.Errorf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) } } func TestContext2Apply_varsEnv(t *testing.T) { - // Set the env var - defer tempEnv(t, "TF_VAR_ami", "baz")() - defer tempEnv(t, "TF_VAR_list", `["Hello", "World"]`)() - defer tempEnv(t, "TF_VAR_map", `{"Hello" = "World", "Foo" = "Bar", "Baz" = "Foo"}`)() - - m := testModule(t, "apply-vars-env") - p := testProvider("aws") - p.ApplyFn = testApplyFn - p.DiffFn = testDiffFn - ctx := testContext2(t, &ContextOpts{ - Config: m, - ProviderResolver: ResourceProviderResolverFixed( - map[string]ResourceProviderFactory{ - "aws": testProviderFuncFixed(p), - }, - ), - }) + fixture := contextFixtureApplyVarsEnv(t) + opts := fixture.ContextOpts() + opts.Variables = InputValues{ + "string": &InputValue{ + Value: cty.StringVal("baz"), + SourceType: ValueFromEnvVar, + }, + "list": &InputValue{ + Value: cty.ListVal([]cty.Value{ + cty.StringVal("Hello"), + cty.StringVal("World"), + }), + SourceType: ValueFromEnvVar, + }, + "map": &InputValue{ + Value: cty.MapVal(map[string]cty.Value{ + "Hello": cty.StringVal("World"), + "Foo": cty.StringVal("Bar"), + "Baz": cty.StringVal("Foo"), + }), + SourceType: ValueFromEnvVar, + }, + } + ctx := testContext2(t, opts) diags := ctx.Validate() if len(diags) != 0 { - t.Fatalf("bad: %#v", diags) + t.Fatalf("bad: %s", diags.ErrWithWarnings()) } - if _, err := ctx.Plan(); err != nil { - t.Fatalf("err: %s", err) + if _, diags := ctx.Plan(); diags.HasErrors() { + t.Fatalf("err: %s", diags.Err()) } - state, err := ctx.Apply() - if err != nil { - t.Fatalf("err: %s", err) + state, diags := ctx.Apply() + if diags.HasErrors() { + t.Fatalf("err: %s", diags.Err()) } actual := strings.TrimSpace(state.String()) expected := strings.TrimSpace(testTerraformApplyVarsEnvStr) if actual != expected { - t.Fatalf("bad: \n%s", actual) + t.Errorf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) } } diff --git a/terraform/context_fixtures_test.go b/terraform/context_fixtures_test.go new file mode 100644 index 0000000000..61536c249a --- /dev/null +++ b/terraform/context_fixtures_test.go @@ -0,0 +1,84 @@ +package terraform + +import ( + "testing" + + "github.com/hashicorp/terraform/config/configschema" + "github.com/hashicorp/terraform/configs" + "github.com/zclconf/go-cty/cty" +) + +// contextTestFixture is a container for a set of objects that work together +// to create a base testing scenario. This is used to represent some common +// situations used as the basis for multiple tests. +type contextTestFixture struct { + Config *configs.Config + ProviderResolver ResourceProviderResolver + Provisioners map[string]ResourceProvisionerFactory +} + +// ContextOpts returns a ContextOps pre-populated with the elements of this +// fixture. Each call returns a distinct object, so callers can apply further +// _shallow_ modifications to the options as needed. +func (f *contextTestFixture) ContextOpts() *ContextOpts { + return &ContextOpts{ + Config: f.Config, + ProviderResolver: f.ProviderResolver, + Provisioners: f.Provisioners, + } +} + +// contextFixtureApplyVars builds and returns a test fixture for testing +// input variables, primarily during the apply phase. The configuration is +// loaded from test-fixtures/apply-vars, and the provider resolver is +// configured with a resource type schema for aws_instance that matches +// what's used in that configuration. +func contextFixtureApplyVars(t *testing.T) *contextTestFixture { + c := testModule(t, "apply-vars") + p := mockProviderWithResourceTypeSchema("aws_instance", &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "foo": {Type: cty.String, Optional: true}, + "bar": {Type: cty.String, Optional: true}, + "baz": {Type: cty.String, Optional: true}, + "num": {Type: cty.Number, Optional: true}, + "list": {Type: cty.List(cty.String), Optional: true}, + "map": {Type: cty.Map(cty.String), Optional: true}, + }, + }) + p.ApplyFn = testApplyFn + p.DiffFn = testDiffFn + return &contextTestFixture{ + Config: c, + ProviderResolver: ResourceProviderResolverFixed( + map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + }, + ), + } +} + +// contextFixtureApplyVarsEnv builds and returns a test fixture for testing +// input variables set from the environment. The configuration is +// loaded from test-fixtures/apply-vars-env, and the provider resolver is +// configured with a resource type schema for aws_instance that matches +// what's used in that configuration. +func contextFixtureApplyVarsEnv(t *testing.T) *contextTestFixture { + c := testModule(t, "apply-vars-env") + p := mockProviderWithResourceTypeSchema("aws_instance", &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "string": {Type: cty.String, Optional: true}, + "list": {Type: cty.List(cty.String), Optional: true}, + "map": {Type: cty.Map(cty.String), Optional: true}, + }, + }) + p.ApplyFn = testApplyFn + p.DiffFn = testDiffFn + return &contextTestFixture{ + Config: c, + ProviderResolver: ResourceProviderResolverFixed( + map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + }, + ), + } +} diff --git a/terraform/context_validate_test.go b/terraform/context_validate_test.go index 40dfcdab41..8cc07c81e3 100644 --- a/terraform/context_validate_test.go +++ b/terraform/context_validate_test.go @@ -847,47 +847,36 @@ func TestContext2Validate_interpolateMap(t *testing.T) { // Manually validate using the new PlanGraphBuilder func TestContext2Validate_PlanGraphBuilder(t *testing.T) { - m := testModule(t, "apply-vars") - p := testProvider("aws") - p.ApplyFn = testApplyFn - p.DiffFn = testDiffFn - c := testContext2(t, &ContextOpts{ - Config: m, - ProviderResolver: ResourceProviderResolverFixed( - map[string]ResourceProviderFactory{ - "aws": testProviderFuncFixed(p), - }, - ), - Variables: InputValues{ - "foo": &InputValue{ - Value: cty.StringVal("us-west-2"), - SourceType: ValueFromCaller, - }, - "test_list": &InputValue{ - Value: cty.ListVal([]cty.Value{ - cty.StringVal("Hello"), - cty.StringVal("World"), - }), - SourceType: ValueFromCaller, - }, - "test_map": &InputValue{ - Value: cty.MapVal(map[string]cty.Value{ - "Hello": cty.StringVal("World"), - "Foo": cty.StringVal("Bar"), - "Baz": cty.StringVal("Foo"), - }), - SourceType: ValueFromCaller, - }, - "amis": &InputValue{ - Value: cty.ListVal([]cty.Value{ - cty.MapVal(map[string]cty.Value{ - "us-east-1": cty.StringVal("override"), - }), - }), - SourceType: ValueFromCaller, - }, + fixture := contextFixtureApplyVars(t) + opts := fixture.ContextOpts() + opts.Variables = InputValues{ + "foo": &InputValue{ + Value: cty.StringVal("us-east-1"), + SourceType: ValueFromCaller, }, - }) + "test_list": &InputValue{ + Value: cty.ListVal([]cty.Value{ + cty.StringVal("Hello"), + cty.StringVal("World"), + }), + SourceType: ValueFromCaller, + }, + "test_map": &InputValue{ + Value: cty.MapVal(map[string]cty.Value{ + "Hello": cty.StringVal("World"), + "Foo": cty.StringVal("Bar"), + "Baz": cty.StringVal("Foo"), + }), + SourceType: ValueFromCaller, + }, + "amis": &InputValue{ + Value: cty.MapVal(map[string]cty.Value{ + "us-east-1": cty.StringVal("override"), + }), + SourceType: ValueFromCaller, + }, + } + c := testContext2(t, opts) graph, diags := (&PlanGraphBuilder{ Config: c.config, diff --git a/terraform/terraform_test.go b/terraform/terraform_test.go index ea647121aa..6df72ea0c5 100644 --- a/terraform/terraform_test.go +++ b/terraform/terraform_test.go @@ -965,16 +965,20 @@ const testTerraformApplyVarsStr = ` aws_instance.bar: ID = foo provider = provider.aws - bar = foo + bar = override baz = override - foo = us-west-2 + foo = us-east-1 type = aws_instance aws_instance.foo: ID = foo provider = provider.aws bar = baz - list = Hello,World - map = Baz,Foo,Hello + list.# = 2 + list.0 = Hello + list.1 = World + map.Baz = Foo + map.Foo = Bar + map.Hello = World num = 2 type = aws_instance ` @@ -983,9 +987,13 @@ const testTerraformApplyVarsEnvStr = ` aws_instance.bar: ID = foo provider = provider.aws - bar = Hello,World - baz = Baz,Foo,Hello - foo = baz + list.# = 2 + list.0 = Hello + list.1 = World + map.Baz = Foo + map.Foo = Bar + map.Hello = World + string = baz type = aws_instance ` diff --git a/terraform/test-fixtures/apply-vars-env/main.tf b/terraform/test-fixtures/apply-vars-env/main.tf index 2455643232..1b62ad6338 100644 --- a/terraform/test-fixtures/apply-vars-env/main.tf +++ b/terraform/test-fixtures/apply-vars-env/main.tf @@ -1,20 +1,20 @@ -variable "ami" { +variable "string" { default = "foo" - type = "string" + type = string } variable "list" { default = [] - type = "list" + type = list(string) } variable "map" { default = {} - type = "map" + type = map(string) } resource "aws_instance" "bar" { - foo = "${var.ami}" - bar = "${join(",", var.list)}" - baz = "${join(",", keys(var.map))}" + string = var.string + list = var.list + map = var.map } diff --git a/terraform/test-fixtures/apply-vars/main.tf b/terraform/test-fixtures/apply-vars/main.tf index 7c426b2278..dc413c0be4 100644 --- a/terraform/test-fixtures/apply-vars/main.tf +++ b/terraform/test-fixtures/apply-vars/main.tf @@ -6,11 +6,11 @@ variable "amis" { } variable "test_list" { - type = "list" + type = list(string) } variable "test_map" { - type = "map" + type = map(string) } variable "bar" { @@ -20,14 +20,14 @@ variable "bar" { variable "foo" {} resource "aws_instance" "foo" { - num = "2" - bar = "${var.bar}" - list = "${join(",", var.test_list)}" - map = "${join(",", keys(var.test_map))}" + num = "2" + bar = var.bar + list = var.test_list + map = var.test_map } resource "aws_instance" "bar" { - foo = "${var.foo}" - bar = "${lookup(var.amis, var.foo)}" - baz = "${var.amis["us-east-1"]}" + foo = var.foo + bar = var.amis[var.foo] + baz = var.amis["us-east-1"] }