Merge pull request #19674 from hashicorp/jbardin/count-refs

failing count refs
This commit is contained in:
James Bardin 2018-12-17 12:49:54 -05:00 committed by GitHub
commit 82f5f50fe7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 103 additions and 0 deletions

View File

@ -31,6 +31,17 @@ func testDataSource() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"input_map": {
Type: schema.TypeMap,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
},
"output_map": {
Type: schema.TypeMap,
Elem: &schema.Schema{Type: schema.TypeString},
Computed: true,
},
},
}
}
@ -45,5 +56,8 @@ func testDataSourceRead(d *schema.ResourceData, meta interface{}) error {
d.Set("output", "some output")
}
if inputMap, hasInput := d.GetOk("input_map"); hasInput {
d.Set("output_map", inputMap)
}
return nil
}

View File

@ -3,6 +3,7 @@ package test
import (
"errors"
"fmt"
"regexp"
"strings"
"testing"
@ -189,3 +190,52 @@ data "test_data_source" "y" {
},
})
}
// referencing test_data_source.one.output_map["a"] should produce an error when
// there's a count, but instead we end up with an unknown value after apply.
func TestDataSource_indexedCountOfOne(t *testing.T) {
resource.UnitTest(t, resource.TestCase{
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: strings.TrimSpace(`
data "test_data_source" "one" {
count = 1
input_map = {
"a" = "b"
}
}
data "test_data_source" "two" {
input_map = {
"x" = data.test_data_source.one.output_map["a"]
}
}
`),
ExpectError: regexp.MustCompile("value does not have any attributes"),
},
},
})
}
// Verify that we can destroy when a data source references something with a
// count of 1.
func TestDataSource_countRefDestroyError(t *testing.T) {
resource.UnitTest(t, resource.TestCase{
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: strings.TrimSpace(`
data "test_data_source" "one" {
count = 1
input = "a"
}
data "test_data_source" "two" {
input = data.test_data_source.one[0].output
}
`),
},
},
})
}

View File

@ -493,3 +493,31 @@ resource "test_resource" "foo" {
},
})
}
// Verify that we can destroy when a managed resource references something with
// a count of 1.
func TestResource_countRefDestroyError(t *testing.T) {
resource.UnitTest(t, resource.TestCase{
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: strings.TrimSpace(`
resource "test_resource" "one" {
count = 1
required = "ok"
required_map = {
key = "val"
}
}
resource "test_resource" "two" {
required = test_resource.one[0].id
required_map = {
key = "val"
}
}
`),
},
},
})
}

View File

@ -289,6 +289,7 @@ func (ctx *BuiltinEvalContext) EvaluationScope(self addrs.Referenceable, keyData
Evaluator: ctx.Evaluator,
ModulePath: ctx.PathValue,
InstanceKeyData: keyData,
Operation: ctx.Evaluator.Operation,
}
return ctx.Evaluator.Scope(data, self)
}

View File

@ -91,6 +91,10 @@ type evaluationStateData struct {
// since the user specifies in that case which variable name to locally
// shadow.)
InstanceKeyData InstanceKeyEvalData
// Operation records the type of walk the evaluationStateData is being used
// for.
Operation walkOperation
}
// InstanceKeyEvalData is used during evaluation to specify which values,
@ -506,6 +510,12 @@ func (d *evaluationStateData) GetResourceInstance(addr addrs.ResourceInstance, r
return cty.DynamicVal, diags
}
// Break out early during validation, because resource may not be expanded
// yet and indexed references may show up as invalid.
if d.Operation == walkValidate {
return cty.DynamicVal, diags
}
schema := d.getResourceSchema(addr.ContainingResource(), rs.ProviderConfig)
// If we are able to automatically convert to the "right" type of instance