This commit is contained in:
Ilia Gogotchuri 2025-02-25 12:28:11 +00:00 committed by GitHub
commit 3816695d37
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 80 additions and 5 deletions

View File

@ -535,7 +535,10 @@ func (runner *TestFileRunner) ExecuteTestRun(ctx context.Context, run *moduletes
return state, false
}
resetConfig, configDiags := config.TransformForTest(run.Config, file.Config)
evalCtx, ctxDiags := getEvalContextForTest(runner.States, config, runner.Suite.GlobalVariables)
run.Diagnostics = run.Diagnostics.Append(ctxDiags)
resetConfig, configDiags := config.TransformForTest(run.Config, file.Config, evalCtx)
defer resetConfig()
run.Diagnostics = run.Diagnostics.Append(configDiags)
@ -1034,7 +1037,10 @@ func (runner *TestFileRunner) Cleanup(ctx context.Context, file *moduletest.File
runConfig = state.Run.Config.ConfigUnderTest
}
reset, configDiags := runConfig.TransformForTest(state.Run.Config, file.Config)
evalCtx, ctxDiags := getEvalContextForTest(runner.States, runConfig, runner.Suite.GlobalVariables)
diags = diags.Append(ctxDiags)
reset, configDiags := runConfig.TransformForTest(state.Run.Config, file.Config, evalCtx)
diags = diags.Append(configDiags)
updated := state.State

View File

@ -170,6 +170,10 @@ func TestTest(t *testing.T) {
expected: "1 passed, 0 failed.",
code: 0,
},
"local_variables_in_provider_block": {
expected: "1 passed, 0 failed.",
code: 0,
},
}
for name, tc := range tcs {
t.Run(name, func(t *testing.T) {

View File

@ -0,0 +1,8 @@
variable "input" {
type = string
default = "bar"
}
resource "test_resource" "foo" {
value = var.input
}

View File

@ -0,0 +1,13 @@
variables {
username = "u"
password = "p"
}
provider "test" {
username = var.username
password = var.password
}
run "validate" {}

View File

@ -28,6 +28,8 @@ var (
Attributes: map[string]*configschema.Attribute{
"data_prefix": {Type: cty.String, Optional: true},
"resource_prefix": {Type: cty.String, Optional: true},
"username": {Type: cty.String, Optional: true},
"password": {Type: cty.String, Optional: true},
},
},
},

View File

@ -884,6 +884,8 @@ func (c *Config) CheckCoreVersionRequirements() hcl.Diagnostics {
return diags
}
type configTransform func(*TestRun, *TestFile) (func(), hcl.Diagnostics)
// TransformForTest prepares the config to execute the given test.
//
// This function directly edits the config that is to be tested, and returns a
@ -891,15 +893,16 @@ func (c *Config) CheckCoreVersionRequirements() hcl.Diagnostics {
//
// Tests will call this before they execute, and then call the deferred function
// to reset the config before the next test.
func (c *Config) TransformForTest(run *TestRun, file *TestFile) (func(), hcl.Diagnostics) {
func (c *Config) TransformForTest(run *TestRun, file *TestFile, evalCtx *hcl.EvalContext) (func(), hcl.Diagnostics) {
var diags hcl.Diagnostics
// These transformation functions must be in sync of what is being transformed,
// currently all the functions operate on different fields of configuration.
transformFuncs := []func(*TestRun, *TestFile) (func(), hcl.Diagnostics){
transformFuncs := []configTransform{
c.transformProviderConfigsForTest,
c.transformOverriddenResourcesForTest,
c.transformOverriddenModulesForTest,
c.getTransformAddVariablesForTest(evalCtx),
}
var resetFuncs []func()
@ -1086,6 +1089,44 @@ func (c *Config) transformOverriddenResourcesForTest(run *TestRun, file *TestFil
}, diags
}
// getTransformAddVariablesForTest takes in evalCtx and gets a transformer function back.
// The transformer adds variables from test file to the config. Needed to allow provider block to access variables defined in the test file.
func (c *Config) getTransformAddVariablesForTest(evalCtx *hcl.EvalContext) configTransform {
return func(run *TestRun, file *TestFile) (func(), hcl.Diagnostics) {
var diags hcl.Diagnostics
oldVars := make(map[string]*Variable, len(c.Module.Variables))
newVars := make(map[string]*Variable, len(c.Module.Variables)+len(file.Variables))
for k, v := range c.Module.Variables {
oldVars[k] = v
newVars[k] = v
}
for variableName, variableExpr := range file.Variables {
// Skip if variable already exists in the config.
if v, ok := newVars[variableName]; ok {
newVars[variableName] = v
continue
}
value, diag := variableExpr.Value(evalCtx)
diags = append(diags, diag...)
if diags.HasErrors() {
return nil, diags
}
newVars[variableName] = &Variable{
Name: variableName,
Type: value.Type(),
ConstraintType: value.Type(),
DeclRange: variableExpr.Range(),
}
}
c.Module.Variables = newVars
return func() {
c.Module.Variables = oldVars
}, nil
}
}
func (c *Config) transformOverriddenModulesForTest(run *TestRun, file *TestFile) (func(), hcl.Diagnostics) {
modules, diags := mergeOverriddenModules(run.OverrideModules, file.OverrideModules)

View File

@ -916,7 +916,8 @@ func TestTransformForTest(t *testing.T) {
Providers: tc.runProviders,
}
reset, diags := config.TransformForTest(run, file)
evalCtx := &hcl.EvalContext{}
reset, diags := config.TransformForTest(run, file, evalCtx)
var actualErrs []string
for _, err := range diags.Errs() {