core: Update TestContext2Apply_multiVarComprehensive for new assumptions
This comprehensive test was covering a few different behaviors that are intentionally different for v0.12: - Applying the splat operator to a list of resource instances that haven't been created yet produces a list of unknown values rather than a single unknown list as before. This is important because it allows that list to be passed into length(). - Wrapping a splat expression in another round of brackets now produces a list of lists, whereas before we had a special case (for compatibility with prior to v0.10) that would flatten this away in the schema layer.
This commit is contained in:
parent
cdce0d7e27
commit
3e64311dc2
|
@ -14,6 +14,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/go-test/deep"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
|
||||
"github.com/hashicorp/terraform/addrs"
|
||||
|
@ -3514,8 +3515,8 @@ func TestContext2Apply_multiVarComprehensive(t *testing.T) {
|
|||
"source_names": {Type: cty.List(cty.String), Optional: true},
|
||||
"source_ids_from_func": {Type: cty.List(cty.String), Optional: true},
|
||||
"source_names_from_func": {Type: cty.List(cty.String), Optional: true},
|
||||
"source_ids_wrapped": {Type: cty.List(cty.String), Optional: true},
|
||||
"source_names_wrapped": {Type: cty.List(cty.String), Optional: true},
|
||||
"source_ids_wrapped": {Type: cty.List(cty.List(cty.String)), Optional: true},
|
||||
"source_names_wrapped": {Type: cty.List(cty.List(cty.String)), Optional: true},
|
||||
|
||||
"id": {Type: cty.String, Computed: true},
|
||||
"name": {Type: cty.String, Computed: true},
|
||||
|
@ -3546,32 +3547,45 @@ func TestContext2Apply_multiVarComprehensive(t *testing.T) {
|
|||
|
||||
checkConfig := func(name string, want map[string]interface{}) {
|
||||
got := configs[name].Config
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf(
|
||||
"wrong config for %s\ngot: %s\nwant: %s",
|
||||
name, spew.Sdump(got), spew.Sdump(want),
|
||||
)
|
||||
t.Run("config for "+name, func(t *testing.T) {
|
||||
for _, problem := range deep.Equal(got, want) {
|
||||
t.Errorf(problem)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
checkConfig("test_thing.multi_count_var.0", map[string]interface{}{
|
||||
"id": unknownValue(),
|
||||
"name": unknownValue(),
|
||||
"source_id": unknownValue(),
|
||||
"source_name": "test_thing.source.0",
|
||||
})
|
||||
checkConfig("test_thing.multi_count_var.2", map[string]interface{}{
|
||||
"id": unknownValue(),
|
||||
"name": unknownValue(),
|
||||
"source_id": unknownValue(),
|
||||
"source_name": "test_thing.source.2",
|
||||
})
|
||||
checkConfig("test_thing.multi_count_derived.0", map[string]interface{}{
|
||||
"id": unknownValue(),
|
||||
"name": unknownValue(),
|
||||
"source_id": unknownValue(),
|
||||
"source_name": "test_thing.source.0",
|
||||
})
|
||||
checkConfig("test_thing.multi_count_derived.2", map[string]interface{}{
|
||||
"id": unknownValue(),
|
||||
"name": unknownValue(),
|
||||
"source_id": unknownValue(),
|
||||
"source_name": "test_thing.source.2",
|
||||
})
|
||||
checkConfig("test_thing.whole_splat", map[string]interface{}{
|
||||
"source_ids": unknownValue(),
|
||||
"id": unknownValue(),
|
||||
"name": unknownValue(),
|
||||
"source_ids": []interface{}{
|
||||
unknownValue(),
|
||||
unknownValue(),
|
||||
unknownValue(),
|
||||
},
|
||||
"source_names": []interface{}{
|
||||
"test_thing.source.0",
|
||||
"test_thing.source.1",
|
||||
|
@ -3584,47 +3598,60 @@ func TestContext2Apply_multiVarComprehensive(t *testing.T) {
|
|||
"test_thing.source.2",
|
||||
},
|
||||
|
||||
// This one ends up being a list with a single unknown value at this
|
||||
// layer, but is fixed up inside helper/schema. There is a test for
|
||||
// this inside the "test" provider, since core tests can't exercise
|
||||
// helper/schema functionality.
|
||||
"source_ids_wrapped": []interface{}{unknownValue()},
|
||||
|
||||
"source_ids_wrapped": []interface{}{
|
||||
[]interface{}{
|
||||
unknownValue(),
|
||||
unknownValue(),
|
||||
unknownValue(),
|
||||
},
|
||||
},
|
||||
"source_names_wrapped": []interface{}{
|
||||
[]interface{}{
|
||||
"test_thing.source.0",
|
||||
"test_thing.source.1",
|
||||
"test_thing.source.2",
|
||||
},
|
||||
},
|
||||
|
||||
"first_source_id": unknownValue(),
|
||||
"first_source_name": "test_thing.source.0",
|
||||
})
|
||||
checkConfig("module.child.test_thing.whole_splat", map[string]interface{}{
|
||||
"source_ids": unknownValue(),
|
||||
"id": unknownValue(),
|
||||
"name": unknownValue(),
|
||||
"source_ids": []interface{}{
|
||||
unknownValue(),
|
||||
unknownValue(),
|
||||
unknownValue(),
|
||||
},
|
||||
"source_names": []interface{}{
|
||||
"test_thing.source.0",
|
||||
"test_thing.source.1",
|
||||
"test_thing.source.2",
|
||||
},
|
||||
|
||||
// This one ends up being a list with a single unknown value at this
|
||||
// layer, but is fixed up inside helper/schema. There is a test for
|
||||
// this inside the "test" provider, since core tests can't exercise
|
||||
// helper/schema functionality.
|
||||
"source_ids_wrapped": []interface{}{unknownValue()},
|
||||
|
||||
"source_ids_wrapped": []interface{}{
|
||||
[]interface{}{
|
||||
unknownValue(),
|
||||
unknownValue(),
|
||||
unknownValue(),
|
||||
},
|
||||
},
|
||||
"source_names_wrapped": []interface{}{
|
||||
[]interface{}{
|
||||
"test_thing.source.0",
|
||||
"test_thing.source.1",
|
||||
"test_thing.source.2",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
t.Run("apply", func(t *testing.T) {
|
||||
state, diags := ctx.Apply()
|
||||
if diags.HasErrors() {
|
||||
t.Fatalf("error during apply: %s", diags.Err())
|
||||
}
|
||||
|
||||
{
|
||||
want := map[string]interface{}{
|
||||
"source_ids": []interface{}{"foo", "foo", "foo"},
|
||||
"source_names": []interface{}{
|
||||
|
@ -3643,7 +3670,7 @@ func TestContext2Apply_multiVarComprehensive(t *testing.T) {
|
|||
spew.Sdump(got), spew.Sdump(want),
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Test that multi-var (splat) access is ordered by count, not by
|
||||
|
|
|
@ -10,16 +10,16 @@ variable "source_names" {
|
|||
}
|
||||
|
||||
resource "test_thing" "multi_count_var" {
|
||||
count = "${var.num}"
|
||||
count = var.num
|
||||
|
||||
# Can pluck a single item out of a multi-var
|
||||
source_id = "${var.source_ids[count.index]}"
|
||||
source_id = var.source_ids[count.index]
|
||||
}
|
||||
|
||||
resource "test_thing" "whole_splat" {
|
||||
# Can "splat" the ids directly into an attribute of type list.
|
||||
source_ids = "${var.source_ids}"
|
||||
source_names = "${var.source_names}"
|
||||
source_ids = var.source_ids
|
||||
source_names = var.source_names
|
||||
source_ids_wrapped = ["${var.source_ids}"]
|
||||
source_names_wrapped = ["${var.source_names}"]
|
||||
}
|
||||
|
|
|
@ -2,48 +2,48 @@ variable "num" {
|
|||
}
|
||||
|
||||
resource "test_thing" "source" {
|
||||
count = "${var.num}"
|
||||
count = var.num
|
||||
|
||||
# The diffFunc in the test exports "name" here too, which we can use
|
||||
# to test values that are known during plan.
|
||||
}
|
||||
|
||||
resource "test_thing" "multi_count_var" {
|
||||
count = "${var.num}"
|
||||
count = var.num
|
||||
|
||||
# Can pluck a single item out of a multi-var
|
||||
source_id = "${test_thing.source.*.id[count.index]}"
|
||||
source_name = "${test_thing.source.*.name[count.index]}"
|
||||
source_id = test_thing.source.*.id[count.index]
|
||||
source_name = test_thing.source.*.name[count.index]
|
||||
}
|
||||
|
||||
resource "test_thing" "multi_count_derived" {
|
||||
# Can use the source to get the count
|
||||
count = "${length(test_thing.source)}"
|
||||
count = length(test_thing.source)
|
||||
|
||||
source_id = "${test_thing.source.*.id[count.index]}"
|
||||
source_name = "${test_thing.source.*.name[count.index]}"
|
||||
source_id = test_thing.source.*.id[count.index]
|
||||
source_name = test_thing.source.*.name[count.index]
|
||||
}
|
||||
|
||||
resource "test_thing" "whole_splat" {
|
||||
# Can "splat" the ids directly into an attribute of type list.
|
||||
source_ids = "${test_thing.source.*.id}"
|
||||
source_names = "${test_thing.source.*.name}"
|
||||
source_ids = test_thing.source.*.id
|
||||
source_names = test_thing.source.*.name
|
||||
|
||||
# Accessing through a function should work.
|
||||
source_ids_from_func = "${split(" ", join(" ", test_thing.source.*.id))}"
|
||||
source_names_from_func = "${split(" ", join(" ", test_thing.source.*.name))}"
|
||||
source_ids_from_func = split(" ", join(" ", test_thing.source.*.id))
|
||||
source_names_from_func = split(" ", join(" ", test_thing.source.*.name))
|
||||
|
||||
# A common pattern of selecting with a default.
|
||||
first_source_id = "${element(concat(test_thing.source.*.id, list("default")), 0)}"
|
||||
first_source_name = "${element(concat(test_thing.source.*.name, list("default")), 0)}"
|
||||
first_source_id = element(concat(test_thing.source.*.id, ["default"]), 0)
|
||||
first_source_name = element(concat(test_thing.source.*.name, ["default"]), 0)
|
||||
|
||||
# Legacy form: Prior to Terraform having comprehensive list support,
|
||||
# splats were treated as a special case and required to be presented
|
||||
# in a wrapping list. This is no longer the suggested form, but we
|
||||
# need it to keep working for compatibility.
|
||||
#
|
||||
# This should result in exactly the same result as the above, even
|
||||
# though it looks like it would result in a list of lists.
|
||||
# Prior to v0.12 we were handling lists containing list interpolations as
|
||||
# a special case, flattening the result, for compatibility with behavior
|
||||
# prior to v0.10. This deprecated handling is now removed, and so these
|
||||
# each produce a list of lists. We're still using the interpolation syntax
|
||||
# here, rather than the splat expression directly, to properly mimic how
|
||||
# this would've looked prior to v0.12 to be explicit about what the new
|
||||
# behavior is for this old syntax.
|
||||
source_ids_wrapped = ["${test_thing.source.*.id}"]
|
||||
source_names_wrapped = ["${test_thing.source.*.name}"]
|
||||
|
||||
|
@ -52,15 +52,15 @@ resource "test_thing" "whole_splat" {
|
|||
module "child" {
|
||||
source = "./child"
|
||||
|
||||
num = "${var.num}"
|
||||
source_ids = "${test_thing.source.*.id}"
|
||||
source_names = "${test_thing.source.*.name}"
|
||||
num = var.num
|
||||
source_ids = test_thing.source.*.id
|
||||
source_names = test_thing.source.*.name
|
||||
}
|
||||
|
||||
output "source_ids" {
|
||||
value = "${test_thing.source.*.id}"
|
||||
value = test_thing.source.*.id
|
||||
}
|
||||
|
||||
output "source_names" {
|
||||
value = "${test_thing.source.*.name}"
|
||||
value = test_thing.source.*.name
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue