@@ -997,34 +997,30 @@ func (runner *TestFileRunner) GetVariables(config *configs.Config, run *modulete
997997 }
998998 }
999999
1000- // Second, we'll check to see which variables the suites global variables
1001- // themselves reference.
1002- for _ , expr := range runner .fileVariables {
1003- for _ , variable := range expr .Variables () {
1004- reference , referenceDiags := addrs .ParseRefFromTestingScope (variable )
1005- diags = diags .Append (referenceDiags )
1006- if reference != nil {
1007- if addr , ok := reference .Subject .(addrs.InputVariable ); ok {
1008- relevantVariables [addr .Name ] = true
1000+ getRelevantVariables := func (src map [string ]hcl.Expression ) tfdiags.Diagnostics {
1001+ var getVarsDiags tfdiags.Diagnostics
1002+ for _ , expr := range runner .fileVariables {
1003+ for _ , variable := range expr .Variables () {
1004+ reference , referenceDiags := addrs .ParseRefFromTestingScope (variable )
1005+ getVarsDiags = getVarsDiags .Append (referenceDiags )
1006+ if reference != nil {
1007+ if addr , ok := reference .Subject .(addrs.InputVariable ); ok {
1008+ relevantVariables [addr .Name ] = true
1009+ }
10091010 }
10101011 }
10111012 }
1013+ return getVarsDiags
10121014 }
10131015
1016+ // Second, we'll check to see which variables the suites global variables
1017+ // themselves reference.
1018+ diags = diags .Append (getRelevantVariables (runner .fileVariables ))
1019+
10141020 // Third, we'll check to see which variables the run block variables
10151021 // themselves reference. We might be processing variables just for the file
10161022 // so the run block itself could be nil.
1017- for _ , expr := range run .Config .Variables {
1018- for _ , variable := range expr .Variables () {
1019- reference , referenceDiags := addrs .ParseRefFromTestingScope (variable )
1020- diags = diags .Append (referenceDiags )
1021- if reference != nil {
1022- if addr , ok := reference .Subject .(addrs.InputVariable ); ok {
1023- relevantVariables [addr .Name ] = true
1024- }
1025- }
1026- }
1027- }
1023+ diags = diags .Append (getRelevantVariables (run .Config .Variables ))
10281024
10291025 // Finally, we'll check to see which variables are actually defined within
10301026 // the configuration.
@@ -1080,96 +1076,101 @@ func (runner *TestFileRunner) GetVariables(config *configs.Config, run *modulete
10801076 }
10811077
10821078 // Second, we'll check the file level variables
1083- var exprs []hcl.Expression
1084- for _ , expr := range runner .fileVariables {
1085- exprs = append (exprs , expr )
1079+ // This is a bit more complicated, as the file and run level variables can reference
1080+ // previously defined variables.
1081+ fileValues , fileDiags := runner .getVariablesFromConfiguration (values , relevantVariables , run .Name , runner .fileVariables )
1082+ diags = diags .Append (fileDiags )
1083+ for name , value := range fileValues {
1084+ values [name ] = value
10861085 }
10871086
1088- // Preformat the variables we've processed already - these will be made
1089- // available to the eval context.
1090- variables := make ( map [ string ]cty. Value )
1091- for name , value := range values {
1092- variables [name ] = value . Value
1087+ // Third, we'll check the run level variables.
1088+ runValues , runDiags := runner . getVariablesFromConfiguration ( values , relevantVariables , run . Name , run . Config . Variables )
1089+ diags = diags . Append ( runDiags )
1090+ for name , value := range runValues {
1091+ values [name ] = value
10931092 }
10941093
1095- fmt .Printf ("\n variables: \n \t %#v \n " , variables )
1094+ // Finally, we check the configuration again. This is where we'll discover
1095+ // if there's any missing variables and fill in any optional variables that
1096+ // don't have a value already.
10961097
1097- ctx , ctxDiags := hcltest .EvalContext (hcltest .TargetRunBlock , exprs , variables , runner .PriorOutputs )
1098- diags = diags .Append (ctxDiags )
1098+ for name , variable := range config .Module .Variables {
1099+ if _ , exists := values [name ]; exists {
1100+ // Then we've provided a variable for this. It's all good.
1101+ continue
1102+ }
10991103
1100- var failedContext bool
1101- if ctxDiags .HasErrors () {
1102- // If we couldn't build the context, we won't actually process these
1103- // variables. Instead, we'll fill them with an empty value but still
1104- // make a note that the user did provide them.
1105- failedContext = true
1106- }
1104+ // Otherwise, we're going to give these variables a value. They'll be
1105+ // processed by the Terraform graph and provided a default value later
1106+ // if they have one.
11071107
1108- for name , expr := range runner .fileVariables {
1109- if ! relevantVariables [name ] {
1110- // We'll add a warning for this. Since we're right in the run block
1111- // users shouldn't be defining variables that are not relevant.
1108+ if variable .Required () {
11121109 diags = diags .Append (& hcl.Diagnostic {
1113- Severity : hcl .DiagWarning ,
1114- Summary : "Value for undeclared variable" ,
1115- Detail : fmt .Sprintf ("The module under test does not declare a variable named %q, but it is declared in run block %q." , name , run .Name ),
1116- Subject : expr .Range ().Ptr (),
1110+ Severity : hcl .DiagError ,
1111+ Summary : "No value for required variable" ,
1112+ Detail : fmt .Sprintf ("The module under test for run block %q has a required variable %q with no set value. Use a -var or -var-file command line argument or add this variable into a \" variables\" block within the test file or run block." ,
1113+ run .Name , variable .Name ),
1114+ Subject : variable .DeclRange .Ptr (),
11171115 })
1118- continue
1119- }
11201116
1121- value := cty .NilVal
1122- if ! failedContext {
1123- var valueDiags hcl.Diagnostics
1124- value , valueDiags = expr .Value (ctx )
1125- diags = diags .Append (valueDiags )
1117+ values [name ] = & terraform.InputValue {
1118+ Value : cty .DynamicVal ,
1119+ SourceType : terraform .ValueFromConfig ,
1120+ SourceRange : tfdiags .SourceRangeFromHCL (variable .DeclRange ),
1121+ }
1122+ } else {
1123+ values [name ] = & terraform.InputValue {
1124+ Value : cty .NilVal ,
1125+ SourceType : terraform .ValueFromConfig ,
1126+ SourceRange : tfdiags .SourceRangeFromHCL (variable .DeclRange ),
1127+ }
11261128 }
11271129
1128- values [name ] = & terraform.InputValue {
1129- Value : value ,
1130- SourceType : terraform .ValueFromConfig ,
1131- SourceRange : tfdiags .SourceRangeFromHCL (expr .Range ()),
1132- }
11331130 }
11341131
1135- // Third, we'll check the run level variables.
1132+ return values , diags
1133+ }
11361134
1137- // This is a bit more complicated, as the run level variables can reference
1138- // previously defined variables.
1135+ // getVariablesFromConfiguration will process the variables from the configuration
1136+ // and return a map of the variables and their values.
1137+ func (runner * TestFileRunner ) getVariablesFromConfiguration (knownVariables terraform.InputValues , relevantVariables map [string ]bool , runName string , variableConfig map [string ]hcl.Expression ) (terraform.InputValues , tfdiags.Diagnostics ) {
1138+ var exprs []hcl.Expression
1139+ var diags tfdiags.Diagnostics
1140+ variableValues := make (terraform.InputValues )
11391141
11401142 // Preload the available expressions, we're going to validate them when we
11411143 // build the context.
1142- exprs = []hcl.Expression {}
1143- for _ , expr := range run .Config .Variables {
1144+ for _ , expr := range runner .fileVariables {
11441145 exprs = append (exprs , expr )
11451146 }
11461147
11471148 // Preformat the variables we've processed already - these will be made
11481149 // available to the eval context.
1149- variables = make (map [string ]cty.Value )
1150- for name , value := range values {
1150+ variables : = make (map [string ]cty.Value )
1151+ for name , value := range knownVariables {
11511152 variables [name ] = value .Value
11521153 }
11531154
1154- ctx , ctxDiags = hcltest .EvalContext (hcltest .TargetRunBlock , exprs , variables , runner .PriorOutputs )
1155+ ctx , ctxDiags : = hcltest .EvalContext (hcltest .TargetRunBlock , exprs , variables , runner .PriorOutputs )
11551156 diags = diags .Append (ctxDiags )
11561157
1157- failedContext = false
1158+ var failedContext bool
11581159 if ctxDiags .HasErrors () {
11591160 // If we couldn't build the context, we won't actually process these
11601161 // variables. Instead, we'll fill them with an empty value but still
11611162 // make a note that the user did provide them.
11621163 failedContext = true
11631164 }
11641165
1165- for name , expr := range run . Config . Variables {
1166+ for name , expr := range runner . fileVariables {
11661167 if ! relevantVariables [name ] {
11671168 // We'll add a warning for this. Since we're right in the run block
11681169 // users shouldn't be defining variables that are not relevant.
11691170 diags = diags .Append (& hcl.Diagnostic {
11701171 Severity : hcl .DiagWarning ,
11711172 Summary : "Value for undeclared variable" ,
1172- Detail : fmt .Sprintf ("The module under test does not declare a variable named %q, but it is declared in run block %q." , name , run . Name ),
1173+ Detail : fmt .Sprintf ("The module under test does not declare a variable named %q, but it is declared in run block %q." , name , runName ),
11731174 Subject : expr .Range ().Ptr (),
11741175 })
11751176 continue
@@ -1182,52 +1183,14 @@ func (runner *TestFileRunner) GetVariables(config *configs.Config, run *modulete
11821183 diags = diags .Append (valueDiags )
11831184 }
11841185
1185- values [name ] = & terraform.InputValue {
1186+ variableValues [name ] = & terraform.InputValue {
11861187 Value : value ,
11871188 SourceType : terraform .ValueFromConfig ,
11881189 SourceRange : tfdiags .SourceRangeFromHCL (expr .Range ()),
11891190 }
11901191 }
11911192
1192- // Finally, we check the configuration again. This is where we'll discover
1193- // if there's any missing variables and fill in any optional variables that
1194- // don't have a value already.
1195-
1196- for name , variable := range config .Module .Variables {
1197- if _ , exists := values [name ]; exists {
1198- // Then we've provided a variable for this. It's all good.
1199- continue
1200- }
1201-
1202- // Otherwise, we're going to give these variables a value. They'll be
1203- // processed by the Terraform graph and provided a default value later
1204- // if they have one.
1205-
1206- if variable .Required () {
1207- diags = diags .Append (& hcl.Diagnostic {
1208- Severity : hcl .DiagError ,
1209- Summary : "No value for required variable" ,
1210- Detail : fmt .Sprintf ("The module under test for run block %q has a required variable %q with no set value. Use a -var or -var-file command line argument or add this variable into a \" variables\" block within the test file or run block." ,
1211- run .Name , variable .Name ),
1212- Subject : variable .DeclRange .Ptr (),
1213- })
1214-
1215- values [name ] = & terraform.InputValue {
1216- Value : cty .DynamicVal ,
1217- SourceType : terraform .ValueFromConfig ,
1218- SourceRange : tfdiags .SourceRangeFromHCL (variable .DeclRange ),
1219- }
1220- } else {
1221- values [name ] = & terraform.InputValue {
1222- Value : cty .NilVal ,
1223- SourceType : terraform .ValueFromConfig ,
1224- SourceRange : tfdiags .SourceRangeFromHCL (variable .DeclRange ),
1225- }
1226- }
1227-
1228- }
1229-
1230- return values , diags
1193+ return variableValues , diags
12311194}
12321195
12331196// FilterVariablesToModule splits the provided values into two disjoint maps:
@@ -1324,17 +1287,20 @@ func (runner *TestFileRunner) AddVariablesToConfig(config *configs.Config, varia
13241287// the file.
13251288func (runner * TestFileRunner ) initVariables (file * moduletest.File ) {
13261289 runner .globalVariables = make (map [string ]backend.UnparsedVariableValue )
1290+ fmt .Printf ("\n runner.Suite.GlobalVariables: \n \t %#v \n " , runner .Suite .GlobalVariables )
13271291 for name , value := range runner .Suite .GlobalVariables {
13281292 runner .globalVariables [name ] = value
13291293 }
13301294 if filepath .Dir (file .Name ) == runner .Suite .TestingDirectory {
13311295 // If the file is in the testing directory, then also include any
13321296 // variables that are defined within the default variable file also in
13331297 // the test directory.
1298+ fmt .Printf ("\n runner.Suite.GlobalTestVariables: \n \t %#v \n " , runner .Suite .GlobalTestVariables )
13341299 for name , value := range runner .Suite .GlobalTestVariables {
13351300 runner .globalVariables [name ] = value
13361301 }
13371302 }
1303+ fmt .Printf ("\n file.Config.Variables: \n \t %#v \n " , file .Config .Variables )
13381304 runner .fileVariables = make (map [string ]hcl.Expression )
13391305 for name , expr := range file .Config .Variables {
13401306 runner .fileVariables [name ] = expr
0 commit comments