mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Run block variable references (#1129)
Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
This commit is contained in:
parent
4961996f51
commit
249ed42fb1
@ -223,7 +223,7 @@ func (m *Meta) addVarsFromFile(filename string, sourceType tofu.ValueSourceType,
|
|||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
// unparsedVariableValueLiteral is a backend.UnparsedVariableValue
|
// unparsedVariableValueExpression is a backend.UnparsedVariableValue
|
||||||
// implementation that was actually already parsed (!). This is
|
// implementation that was actually already parsed (!). This is
|
||||||
// intended to deal with expressions inside "tfvars" files.
|
// intended to deal with expressions inside "tfvars" files.
|
||||||
type unparsedVariableValueExpression struct {
|
type unparsedVariableValueExpression struct {
|
||||||
|
@ -501,7 +501,7 @@ func (runner *TestFileRunner) ExecuteTestRun(run *moduletest.Run, file *modulete
|
|||||||
return state, false
|
return state, false
|
||||||
}
|
}
|
||||||
|
|
||||||
variables, resetVariables, variableDiags := prepareInputVariablesForAssertions(config, run, file, runner.Suite.GlobalVariables)
|
variables, resetVariables, variableDiags := runner.prepareInputVariablesForAssertions(config, run, file, runner.Suite.GlobalVariables)
|
||||||
defer resetVariables()
|
defer resetVariables()
|
||||||
|
|
||||||
run.Diagnostics = run.Diagnostics.Append(variableDiags)
|
run.Diagnostics = run.Diagnostics.Append(variableDiags)
|
||||||
@ -574,7 +574,7 @@ func (runner *TestFileRunner) ExecuteTestRun(run *moduletest.Run, file *modulete
|
|||||||
return updated, true
|
return updated, true
|
||||||
}
|
}
|
||||||
|
|
||||||
variables, resetVariables, variableDiags := prepareInputVariablesForAssertions(config, run, file, runner.Suite.GlobalVariables)
|
variables, resetVariables, variableDiags := runner.prepareInputVariablesForAssertions(config, run, file, runner.Suite.GlobalVariables)
|
||||||
defer resetVariables()
|
defer resetVariables()
|
||||||
|
|
||||||
run.Diagnostics = run.Diagnostics.Append(variableDiags)
|
run.Diagnostics = run.Diagnostics.Append(variableDiags)
|
||||||
@ -1023,6 +1023,26 @@ func buildInputVariablesForTest(run *moduletest.Run, file *moduletest.File, conf
|
|||||||
return backend.ParseVariableValues(variables, config.Module.Variables)
|
return backend.ParseVariableValues(variables, config.Module.Variables)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type testVariableValueExpression struct {
|
||||||
|
expr hcl.Expression
|
||||||
|
sourceType tofu.ValueSourceType
|
||||||
|
ctx *hcl.EvalContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v testVariableValueExpression) ParseVariableValue(mode configs.VariableParsingMode) (*tofu.InputValue, tfdiags.Diagnostics) {
|
||||||
|
var diags tfdiags.Diagnostics
|
||||||
|
val, hclDiags := v.expr.Value(v.ctx)
|
||||||
|
diags = diags.Append(hclDiags)
|
||||||
|
|
||||||
|
rng := tfdiags.SourceRangeFromHCL(v.expr.Range())
|
||||||
|
|
||||||
|
return &tofu.InputValue{
|
||||||
|
Value: val,
|
||||||
|
SourceType: v.sourceType,
|
||||||
|
SourceRange: rng,
|
||||||
|
}, diags
|
||||||
|
}
|
||||||
|
|
||||||
// prepareInputVariablesForAssertions creates a tofu.InputValues mapping
|
// prepareInputVariablesForAssertions creates a tofu.InputValues mapping
|
||||||
// that contains all the variables defined for a given run and file, alongside
|
// that contains all the variables defined for a given run and file, alongside
|
||||||
// any unset variables that have defaults within the provided config.
|
// any unset variables that have defaults within the provided config.
|
||||||
@ -1032,17 +1052,36 @@ func buildInputVariablesForTest(run *moduletest.Run, file *moduletest.File, conf
|
|||||||
// within the config. This allows the assertions to refer to variables defined
|
// within the config. This allows the assertions to refer to variables defined
|
||||||
// solely within the test file, and not only those within the configuration.
|
// solely within the test file, and not only those within the configuration.
|
||||||
//
|
//
|
||||||
|
// It also allows references to previously run test module's outputs as variable
|
||||||
|
// expressions. This relies upon the evaluation order and will not sort the test cases
|
||||||
|
// to run in the dependent order.
|
||||||
|
//
|
||||||
// In addition, it modifies the provided config so that any variables that are
|
// In addition, it modifies the provided config so that any variables that are
|
||||||
// available are also defined in the config. It returns a function that resets
|
// available are also defined in the config. It returns a function that resets
|
||||||
// the config which must be called so the config can be reused going forward.
|
// the config which must be called so the config can be reused going forward.
|
||||||
func prepareInputVariablesForAssertions(config *configs.Config, run *moduletest.Run, file *moduletest.File, globals map[string]backend.UnparsedVariableValue) (tofu.InputValues, func(), tfdiags.Diagnostics) {
|
func (runner *TestFileRunner) prepareInputVariablesForAssertions(config *configs.Config, run *moduletest.Run, file *moduletest.File, globals map[string]backend.UnparsedVariableValue) (tofu.InputValues, func(), tfdiags.Diagnostics) {
|
||||||
|
runCtx := make(map[string]cty.Value)
|
||||||
|
for _, state := range runner.States {
|
||||||
|
if state.Run == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
outputs := make(map[string]cty.Value)
|
||||||
|
mod := state.State.Modules[""] // Empty string is what is used by the module in the test runner
|
||||||
|
for outName, out := range mod.OutputValues {
|
||||||
|
outputs[outName] = out.Value
|
||||||
|
}
|
||||||
|
runCtx[state.Run.Name] = cty.ObjectVal(outputs)
|
||||||
|
}
|
||||||
|
ctx := &hcl.EvalContext{Variables: map[string]cty.Value{"run": cty.ObjectVal(runCtx)}}
|
||||||
|
|
||||||
variables := make(map[string]backend.UnparsedVariableValue)
|
variables := make(map[string]backend.UnparsedVariableValue)
|
||||||
|
|
||||||
if run != nil {
|
if run != nil {
|
||||||
for name, expr := range run.Config.Variables {
|
for name, expr := range run.Config.Variables {
|
||||||
variables[name] = unparsedVariableValueExpression{
|
variables[name] = testVariableValueExpression{
|
||||||
expr: expr,
|
expr: expr,
|
||||||
sourceType: tofu.ValueFromConfig,
|
sourceType: tofu.ValueFromConfig,
|
||||||
|
ctx: ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1054,9 +1093,10 @@ func prepareInputVariablesForAssertions(config *configs.Config, run *moduletest.
|
|||||||
// that value to take precedence.
|
// that value to take precedence.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
variables[name] = unparsedVariableValueExpression{
|
variables[name] = testVariableValueExpression{
|
||||||
expr: expr,
|
expr: expr,
|
||||||
sourceType: tofu.ValueFromConfig,
|
sourceType: tofu.ValueFromConfig,
|
||||||
|
ctx: ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -798,6 +798,10 @@ func TestTest_Modules(t *testing.T) {
|
|||||||
expected: "main.tftest.hcl... pass\n run \"first\"... pass\n run \"second\"... pass\n\nSuccess! 2 passed, 0 failed.\n",
|
expected: "main.tftest.hcl... pass\n run \"first\"... pass\n run \"second\"... pass\n\nSuccess! 2 passed, 0 failed.\n",
|
||||||
code: 0,
|
code: 0,
|
||||||
},
|
},
|
||||||
|
"variables_reference": {
|
||||||
|
expected: "main.tftest.hcl... pass\n run \"setup\"... pass\n run \"test\"... pass\n\nSuccess! 2 passed, 0 failed.\n",
|
||||||
|
code: 0,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, tc := range tcs {
|
for name, tc := range tcs {
|
||||||
|
0
internal/command/testdata/test/variables_reference/main.tf
vendored
Normal file
0
internal/command/testdata/test/variables_reference/main.tf
vendored
Normal file
15
internal/command/testdata/test/variables_reference/main.tftest.hcl
vendored
Normal file
15
internal/command/testdata/test/variables_reference/main.tftest.hcl
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
variables {
|
||||||
|
content = "some value"
|
||||||
|
}
|
||||||
|
|
||||||
|
run "setup" {
|
||||||
|
module {
|
||||||
|
source = "./setup"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run "test" {
|
||||||
|
variables {
|
||||||
|
file_name = run.setup.file_name
|
||||||
|
}
|
||||||
|
}
|
7
internal/command/testdata/test/variables_reference/setup/main.tf
vendored
Normal file
7
internal/command/testdata/test/variables_reference/setup/main.tf
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
variable "content" {
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
output "file_name" {
|
||||||
|
value = "output_value"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user