Skip to content

Commit df3ee21

Browse files
extract global and suite-level variables before configuring providers
1 parent 697e0d1 commit df3ee21

File tree

4 files changed

+65
-47
lines changed

4 files changed

+65
-47
lines changed

internal/backend/local/test.go

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -382,9 +382,11 @@ func (runner *TestFileRunner) run(run *moduletest.Run, file *moduletest.File, st
382382
}
383383
runner.gatherProviders(key, config)
384384

385+
vars, diag := runner.GetGlobalAndSuiteVariables(runner.Suite.Config)
386+
run.Diagnostics = run.Diagnostics.Append(diag)
385387
// TODO: Merge local variables and suite-level variables
386388
// It might be necessary to change the format or add an extra parameter, not sure yet
387-
resetConfig, configDiags := configtest.TransformConfigForTest(config, run, file, runner.globalVariables, runner.PriorOutputs, runner.Suite.configProviders[key])
389+
resetConfig, configDiags := configtest.TransformConfigForTest(config, run, file, vars, runner.PriorOutputs, runner.Suite.configProviders[key])
388390
defer resetConfig()
389391

390392
run.Diagnostics = run.Diagnostics.Append(configDiags)
@@ -949,7 +951,10 @@ func (runner *TestFileRunner) cleanup(file *moduletest.File) {
949951
key = state.Run.Config.Module.Source.String()
950952
}
951953

952-
reset, configDiags := configtest.TransformConfigForTest(config, state.Run, file, runner.globalVariables, runner.PriorOutputs, runner.Suite.configProviders[key])
954+
vars, varsDiags := runner.GetGlobalAndSuiteVariables(config)
955+
diags = diags.Append(varsDiags)
956+
957+
reset, configDiags := configtest.TransformConfigForTest(config, state.Run, file, vars, runner.PriorOutputs, runner.Suite.configProviders[key])
953958
diags = diags.Append(configDiags)
954959

955960
updated := state.State
@@ -1044,33 +1049,7 @@ func (runner *TestFileRunner) GetVariables(config *configs.Config, run *modulete
10441049
continue
10451050
}
10461051

1047-
// By default, we parse global variables as HCL inputs.
1048-
parsingMode := configs.VariableParseHCL
1049-
1050-
cfg, exists := config.Module.Variables[name]
1051-
1052-
if exists {
1053-
// Unless we have some configuration that can actually tell us
1054-
// what parsing mode to use.
1055-
parsingMode = cfg.ParsingMode
1056-
}
1057-
1058-
value, valueDiags := variable.ParseVariableValue(parsingMode)
1059-
diags = diags.Append(valueDiags)
1060-
if diags.HasErrors() {
1061-
// We still add a value for this variable even though we couldn't
1062-
// parse it as we don't want to compound errors later. For example,
1063-
// the system would report this variable didn't have a value which
1064-
// would confuse the user because it does have a value, it's just
1065-
// not a valid value. We have added the diagnostics so the user
1066-
// will be informed about the error, and the test won't run. We'll
1067-
// just report only the relevant errors.
1068-
values[name] = &terraform.InputValue{
1069-
Value: cty.NilVal,
1070-
}
1071-
continue
1072-
}
1073-
values[name] = value
1052+
values[name] = runner.getGlobalVariable(name, variable, config)
10741053
}
10751054

10761055
// Second, we'll check the file level variables
@@ -1130,6 +1109,34 @@ func (runner *TestFileRunner) GetVariables(config *configs.Config, run *modulete
11301109
return values, diags
11311110
}
11321111

1112+
func (runner *TestFileRunner) getGlobalVariable(name string, variable backend.UnparsedVariableValue, config *configs.Config) *terraform.InputValue {
1113+
// By default, we parse global variables as HCL inputs.
1114+
parsingMode := configs.VariableParseHCL
1115+
1116+
cfg, exists := config.Module.Variables[name]
1117+
1118+
if exists {
1119+
// Unless we have some configuration that can actually tell us
1120+
// what parsing mode to use.
1121+
parsingMode = cfg.ParsingMode
1122+
}
1123+
1124+
value, diags := variable.ParseVariableValue(parsingMode)
1125+
if diags.HasErrors() {
1126+
// We still add a value for this variable even though we couldn't
1127+
// parse it as we don't want to compound errors later. For example,
1128+
// the system would report this variable didn't have a value which
1129+
// would confuse the user because it does have a value, it's just
1130+
// not a valid value. We have added the diagnostics so the user
1131+
// will be informed about the error, and the test won't run. We'll
1132+
// just report only the relevant errors.
1133+
return &terraform.InputValue{
1134+
Value: cty.NilVal,
1135+
}
1136+
}
1137+
return value
1138+
}
1139+
11331140
// getVariablesFromConfiguration will process the variables from the configuration
11341141
// and return a map of the variables and their values.
11351142
func (runner *TestFileRunner) getVariablesFromConfiguration(knownVariables terraform.InputValues, relevantVariables map[string]bool, runName string, variableConfig map[string]hcl.Expression) (terraform.InputValues, tfdiags.Diagnostics) {
@@ -1191,6 +1198,25 @@ func (runner *TestFileRunner) getVariablesFromConfiguration(knownVariables terra
11911198
return variableValues, diags
11921199
}
11931200

1201+
// GetGlobalAndSuiteVariables returns the global and suite level variables
1202+
func (runner *TestFileRunner) GetGlobalAndSuiteVariables(config *configs.Config) (terraform.InputValues, tfdiags.Diagnostics) {
1203+
var diags tfdiags.Diagnostics
1204+
values := make(terraform.InputValues)
1205+
// TODO: Verify it's not problematic that we don't care about the variables being used
1206+
// First, let's look at the global variables.
1207+
for name, variable := range runner.globalVariables {
1208+
values[name] = runner.getGlobalVariable(name, variable, config)
1209+
}
1210+
1211+
fileValues, fileDiags := runner.getVariablesFromConfiguration(values, nil, "TODO: Rewrite error to either not mention run block or wrap the error", runner.fileVariables)
1212+
diags = diags.Append(fileDiags)
1213+
for name, value := range fileValues {
1214+
values[name] = value
1215+
}
1216+
1217+
return values, diags
1218+
}
1219+
11941220
// FilterVariablesToModule splits the provided values into two disjoint maps:
11951221
// moduleVars contains the ones that correspond with declarations in the root
11961222
// module of the given configuration, while testOnlyVars contains any others

internal/moduletest/config/config.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ import (
1010
"github.com/zclconf/go-cty/cty"
1111

1212
"github.com/hashicorp/terraform/internal/addrs"
13-
"github.com/hashicorp/terraform/internal/backend"
1413
"github.com/hashicorp/terraform/internal/configs"
1514
"github.com/hashicorp/terraform/internal/moduletest"
1615
hcltest "github.com/hashicorp/terraform/internal/moduletest/hcl"
16+
"github.com/hashicorp/terraform/internal/terraform"
1717
)
1818

1919
// TransformConfigForTest transforms the provided configuration ready for the
@@ -27,7 +27,7 @@ import (
2727
// We also return a reset function that should be called to return the
2828
// configuration to it's original state before the next run block or test file
2929
// needs to use it.
30-
func TransformConfigForTest(config *configs.Config, run *moduletest.Run, file *moduletest.File, availableVariables map[string]backend.UnparsedVariableValue, availableRunOutputs map[addrs.Run]cty.Value, requiredProviders map[string]bool) (func(), hcl.Diagnostics) {
30+
func TransformConfigForTest(config *configs.Config, run *moduletest.Run, file *moduletest.File, availableVariables terraform.InputValues, availableRunOutputs map[addrs.Run]cty.Value, requiredProviders map[string]bool) (func(), hcl.Diagnostics) {
3131
var diags hcl.Diagnostics
3232

3333
// Currently, we only need to override the provider settings.

internal/moduletest/hcl/provider.go

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import (
88
"github.com/zclconf/go-cty/cty"
99

1010
"github.com/hashicorp/terraform/internal/addrs"
11-
"github.com/hashicorp/terraform/internal/backend"
1211
"github.com/hashicorp/terraform/internal/configs"
1312
"github.com/hashicorp/terraform/internal/lang"
13+
"github.com/hashicorp/terraform/internal/terraform"
1414
)
1515

1616
var _ hcl.Body = (*ProviderConfig)(nil)
@@ -27,7 +27,7 @@ type ProviderConfig struct {
2727
Original hcl.Body
2828

2929
ConfigVariables map[string]*configs.Variable
30-
AvailableVariables map[string]backend.UnparsedVariableValue
30+
AvailableVariables terraform.InputValues
3131
AvailableRunOutputs map[addrs.Run]cty.Value
3232
}
3333

@@ -88,17 +88,7 @@ func (p *ProviderConfig) transformAttributes(originals hcl.Attributes) (hcl.Attr
8888
continue
8989
}
9090

91-
if variable, exists := p.AvailableVariables[addr.Name]; exists {
92-
// Then we have a value for this variable! So we think we'll
93-
// be able to process it - let's parse it now.
94-
95-
parsingMode := configs.VariableParseHCL
96-
if config, exists := p.ConfigVariables[addr.Name]; exists {
97-
parsingMode = config.ParsingMode
98-
}
99-
100-
value, valueDiags := variable.ParseVariableValue(parsingMode)
101-
diags = append(diags, valueDiags.ToHCL()...)
91+
if value, exists := p.AvailableVariables[addr.Name]; exists {
10292
if value != nil {
10393
availableVariables[addr.Name] = value.Value
10494
}

internal/moduletest/hcl/provider_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,12 @@ func TestProviderConfig(t *testing.T) {
183183
}
184184
return variables
185185
}(),
186-
AvailableVariables: func() map[string]backend.UnparsedVariableValue {
187-
variables := make(map[string]backend.UnparsedVariableValue)
186+
AvailableVariables: func() terraform.InputValues {
187+
variables := make(terraform.InputValues)
188188
for name, value := range tc.variables {
189-
variables[name] = &variable{value}
189+
variables[name] = &terraform.InputValue{
190+
Value: value,
191+
}
190192
}
191193
return variables
192194
}(),

0 commit comments

Comments
 (0)