-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Testing Framework] Add test file HCL configuration and parser functi…
…onality (#33325) * Add test structure to views package for rendering test output * Add test file HCL configuration and parser functionality * address comments
- v1.12.0-alpha20250213
- v1.11.0-rc1
- v1.11.0-beta2
- v1.11.0-beta1
- v1.11.0-alpha20250107
- v1.11.0-alpha20241218
- v1.11.0-alpha20241211
- v1.11.0-alpha20241106
- v1.10.5
- v1.10.4
- v1.10.3
- v1.10.2
- v1.10.1
- v1.10.0
- v1.10.0-rc3
- v1.10.0-rc2
- v1.10.0-rc1
- v1.10.0-beta1
- v1.10.0-alpha20241023
- v1.10.0-alpha20241009
- v1.10.0-alpha20240926
- v1.10.0-alpha20240918
- v1.10.0-alpha20240911
- v1.10.0-alpha20240828
- v1.10.0-alpha20240814
- v1.10.0-alpha20240807
- v1.10.0-alpha20240730
- v1.10.0-alpha20240717
- v1.10.0-alpha20240619
- v1.10.0-alpha20240606
- v1.9.8
- v1.9.7
- v1.9.6
- v1.9.5
- v1.9.4
- v1.9.3
- v1.9.2
- v1.9.1
- v1.9.0
- v1.9.0-rc3
- v1.9.0-rc2
- v1.9.0-rc1
- v1.9.0-beta1
- v1.9.0-alpha20240516
- v1.9.0-alpha20240501
- v1.9.0-alpha20240404
- v1.8.5
- v1.8.4
- v1.8.3
- v1.8.2
- v1.8.1
- v1.8.0
- v1.8.0-rc2
- v1.8.0-rc1
- v1.8.0-beta1
- v1.8.0-alpha20240228
- v1.8.0-alpha20240216
- v1.8.0-alpha20240214
- v1.8.0-alpha20240131
- v1.7.5
- v1.7.4
- v1.7.3
- v1.7.2
- v1.7.1
- v1.7.0
- v1.7.0-rc2
- v1.7.0-rc1
- v1.7.0-beta2
- v1.7.0-beta1
- v1.7.0-alpha20231130
- v1.7.0-alpha20231108
- v1.7.0-alpha20231025
- v1.6.6
- v1.6.5
- v1.6.4
- v1.6.3
- v1.6.2
- v1.6.1
- v1.6.0
- v1.6.0-rc1
- v1.6.0-beta3
- v1.6.0-beta2
- v1.6.0-beta1
- v1.6.0-alpha20230816
- v1.6.0-alpha20230802
- v1.6.0-alpha20230719
1 parent
cf3a72a
commit cad9aa9
Showing
17 changed files
with
790 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,335 @@ | ||
package configs | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/hashicorp/hcl/v2" | ||
"github.com/hashicorp/hcl/v2/gohcl" | ||
) | ||
|
||
// TestCommand represents the Terraform a given run block will execute, plan | ||
// or apply. Defaults to apply. | ||
type TestCommand rune | ||
|
||
// TestMode represents the plan mode that Terraform will use for a given run | ||
// block, normal or refresh-only. Defaults to normal. | ||
type TestMode rune | ||
|
||
const ( | ||
// ApplyTestCommand causes the run block to execute a Terraform apply | ||
// operation. | ||
ApplyTestCommand TestCommand = 0 | ||
|
||
// PlanTestCommand causes the run block to execute a Terraform plan | ||
// operation. | ||
PlanTestCommand TestCommand = 'P' | ||
|
||
// NormalTestMode causes the run block to execute in plans.NormalMode. | ||
NormalTestMode TestMode = 0 | ||
|
||
// RefreshOnlyTestMode causes the run block to execute in | ||
// plans.RefreshOnlyMode. | ||
RefreshOnlyTestMode TestMode = 'R' | ||
) | ||
|
||
// TestFile represents a single test file within a `terraform test` execution. | ||
// | ||
// A test file is made up of a sequential list of run blocks, each designating | ||
// a command to execute and a series of validations to check after the command. | ||
type TestFile struct { | ||
// Variables defines a set of global variable definitions that should be set | ||
// for every run block within the test file. | ||
Variables map[string]hcl.Expression | ||
|
||
// Runs defines the sequential list of run blocks that should be executed in | ||
// order. | ||
Runs []*TestRun | ||
|
||
VariablesDeclRange hcl.Range | ||
} | ||
|
||
// TestRun represents a single run block within a test file. | ||
// | ||
// Each run block represents a single Terraform command to be executed and a set | ||
// of validations to run after the command. | ||
type TestRun struct { | ||
Name string | ||
|
||
// Command is the Terraform command to execute. | ||
// | ||
// One of ['apply', 'plan']. | ||
Command TestCommand | ||
|
||
// Options contains the embedded plan options that will affect the given | ||
// Command. These should map to the options documented here: | ||
// - https://developer.hashicorp.com/terraform/cli/commands/plan#planning-options | ||
// | ||
// Note, that the Variables are a top level concept and not embedded within | ||
// the options despite being listed as plan options in the documentation. | ||
Options *TestRunOptions | ||
|
||
// Variables defines a set of variable definitions for this command. | ||
// | ||
// Any variables specified locally that clash with the global variables will | ||
// take precedence over the global definition. | ||
Variables map[string]hcl.Expression | ||
|
||
// CheckRules defines the list of assertions/validations that should be | ||
// checked by this run block. | ||
CheckRules []*CheckRule | ||
|
||
NameDeclRange hcl.Range | ||
VariablesDeclRange hcl.Range | ||
DeclRange hcl.Range | ||
} | ||
|
||
// TestRunOptions contains the plan options for a given run block. | ||
type TestRunOptions struct { | ||
// Mode is the planning mode to run in. One of ['normal', 'refresh-only']. | ||
Mode TestMode | ||
|
||
// Refresh is analogous to the -refresh=false Terraform plan option. | ||
Refresh bool | ||
|
||
// Replace is analogous to the -refresh=ADDRESS Terraform plan option. | ||
Replace []hcl.Traversal | ||
|
||
// Target is analogous to the -target=ADDRESS Terraform plan option. | ||
Target []hcl.Traversal | ||
|
||
DeclRange hcl.Range | ||
} | ||
|
||
func loadTestFile(body hcl.Body) (*TestFile, hcl.Diagnostics) { | ||
var diags hcl.Diagnostics | ||
|
||
content, contentDiags := body.Content(testFileSchema) | ||
diags = append(diags, contentDiags...) | ||
|
||
tf := TestFile{} | ||
|
||
for _, block := range content.Blocks { | ||
switch block.Type { | ||
case "run": | ||
run, runDiags := decodeTestRunBlock(block) | ||
diags = append(diags, runDiags...) | ||
if !runDiags.HasErrors() { | ||
tf.Runs = append(tf.Runs, run) | ||
} | ||
case "variables": | ||
if tf.Variables != nil { | ||
diags = append(diags, &hcl.Diagnostic{ | ||
Severity: hcl.DiagError, | ||
Summary: "Multiple \"variables\" blocks", | ||
Detail: fmt.Sprintf("This test file already has a variables block defined at %s.", tf.VariablesDeclRange), | ||
Subject: block.DefRange.Ptr(), | ||
}) | ||
continue | ||
} | ||
|
||
tf.Variables = make(map[string]hcl.Expression) | ||
tf.VariablesDeclRange = block.DefRange | ||
|
||
vars, varsDiags := block.Body.JustAttributes() | ||
diags = append(diags, varsDiags...) | ||
for _, v := range vars { | ||
tf.Variables[v.Name] = v.Expr | ||
} | ||
} | ||
} | ||
|
||
return &tf, diags | ||
} | ||
|
||
func decodeTestRunBlock(block *hcl.Block) (*TestRun, hcl.Diagnostics) { | ||
var diags hcl.Diagnostics | ||
|
||
content, contentDiags := block.Body.Content(testRunBlockSchema) | ||
diags = append(diags, contentDiags...) | ||
|
||
r := TestRun{ | ||
Name: block.Labels[0], | ||
NameDeclRange: block.LabelRanges[0], | ||
DeclRange: block.DefRange, | ||
} | ||
for _, block := range content.Blocks { | ||
switch block.Type { | ||
case "assert": | ||
cr, crDiags := decodeCheckRuleBlock(block, false) | ||
diags = append(diags, crDiags...) | ||
if !crDiags.HasErrors() { | ||
r.CheckRules = append(r.CheckRules, cr) | ||
} | ||
case "plan_options": | ||
if r.Options != nil { | ||
diags = append(diags, &hcl.Diagnostic{ | ||
Severity: hcl.DiagError, | ||
Summary: "Multiple \"plan_options\" blocks", | ||
Detail: fmt.Sprintf("This run block already has a plan_options block defined at %s.", r.Options.DeclRange), | ||
Subject: block.DefRange.Ptr(), | ||
}) | ||
continue | ||
} | ||
|
||
opts, optsDiags := decodeTestRunOptionsBlock(block) | ||
diags = append(diags, optsDiags...) | ||
if !optsDiags.HasErrors() { | ||
r.Options = opts | ||
} | ||
case "variables": | ||
if r.Variables != nil { | ||
diags = append(diags, &hcl.Diagnostic{ | ||
Severity: hcl.DiagError, | ||
Summary: "Multiple \"variables\" blocks", | ||
Detail: fmt.Sprintf("This run block already has a variables block defined at %s.", r.VariablesDeclRange), | ||
Subject: block.DefRange.Ptr(), | ||
}) | ||
continue | ||
} | ||
|
||
r.Variables = make(map[string]hcl.Expression) | ||
r.VariablesDeclRange = block.DefRange | ||
|
||
vars, varsDiags := block.Body.JustAttributes() | ||
diags = append(diags, varsDiags...) | ||
for _, v := range vars { | ||
r.Variables[v.Name] = v.Expr | ||
} | ||
|
||
} | ||
} | ||
|
||
if r.Variables == nil { | ||
// There is no distinction between a nil map of variables or an empty | ||
// map, but we can avoid any potential nil pointer exceptions by just | ||
// creating an empty map. | ||
r.Variables = make(map[string]hcl.Expression) | ||
} | ||
|
||
if r.Options == nil { | ||
// Create an options with default values if the user didn't specify | ||
// anything. | ||
r.Options = &TestRunOptions{ | ||
Mode: NormalTestMode, | ||
Refresh: true, | ||
} | ||
} | ||
|
||
if attr, exists := content.Attributes["command"]; exists { | ||
switch hcl.ExprAsKeyword(attr.Expr) { | ||
case "apply": | ||
r.Command = ApplyTestCommand | ||
case "plan": | ||
r.Command = PlanTestCommand | ||
default: | ||
diags = append(diags, &hcl.Diagnostic{ | ||
Severity: hcl.DiagError, | ||
Summary: "Invalid \"command\" keyword", | ||
Detail: "The \"command\" argument requires one of the following keywords without quotes: apply or plan.", | ||
Subject: attr.Expr.Range().Ptr(), | ||
}) | ||
} | ||
} else { | ||
r.Command = ApplyTestCommand // Default to apply | ||
} | ||
|
||
return &r, diags | ||
} | ||
|
||
func decodeTestRunOptionsBlock(block *hcl.Block) (*TestRunOptions, hcl.Diagnostics) { | ||
var diags hcl.Diagnostics | ||
|
||
content, contentDiags := block.Body.Content(testRunOptionsBlockSchema) | ||
diags = append(diags, contentDiags...) | ||
|
||
opts := TestRunOptions{ | ||
DeclRange: block.DefRange, | ||
} | ||
|
||
if attr, exists := content.Attributes["mode"]; exists { | ||
switch hcl.ExprAsKeyword(attr.Expr) { | ||
case "refresh-only": | ||
opts.Mode = RefreshOnlyTestMode | ||
case "normal": | ||
opts.Mode = NormalTestMode | ||
default: | ||
diags = append(diags, &hcl.Diagnostic{ | ||
Severity: hcl.DiagError, | ||
Summary: "Invalid \"mode\" keyword", | ||
Detail: "The \"mode\" argument requires one of the following keywords without quotes: normal or refresh-only", | ||
Subject: attr.Expr.Range().Ptr(), | ||
}) | ||
} | ||
} else { | ||
opts.Mode = NormalTestMode // Default to normal | ||
} | ||
|
||
if attr, exists := content.Attributes["refresh"]; exists { | ||
diags = append(diags, gohcl.DecodeExpression(attr.Expr, nil, &opts.Refresh)...) | ||
} else { | ||
// Defaults to true. | ||
opts.Refresh = true | ||
} | ||
|
||
if attr, exists := content.Attributes["replace"]; exists { | ||
reps, repsDiags := decodeDependsOn(attr) | ||
diags = append(diags, repsDiags...) | ||
opts.Replace = reps | ||
} | ||
|
||
if attr, exists := content.Attributes["target"]; exists { | ||
tars, tarsDiags := decodeDependsOn(attr) | ||
diags = append(diags, tarsDiags...) | ||
opts.Target = tars | ||
} | ||
|
||
if !opts.Refresh && opts.Mode == RefreshOnlyTestMode { | ||
// These options are incompatible. | ||
diags = append(diags, &hcl.Diagnostic{ | ||
Severity: hcl.DiagError, | ||
Summary: "Incompatible plan options", | ||
Detail: "The \"refresh\" option cannot be set to false when running a test in \"refresh-only\" mode.", | ||
Subject: content.Attributes["refresh"].Range.Ptr(), | ||
}) | ||
} | ||
|
||
return &opts, diags | ||
} | ||
|
||
var testFileSchema = &hcl.BodySchema{ | ||
Blocks: []hcl.BlockHeaderSchema{ | ||
{ | ||
Type: "run", | ||
LabelNames: []string{"name"}, | ||
}, | ||
{ | ||
Type: "variables", | ||
}, | ||
}, | ||
} | ||
|
||
var testRunBlockSchema = &hcl.BodySchema{ | ||
Attributes: []hcl.AttributeSchema{ | ||
{Name: "command"}, | ||
}, | ||
Blocks: []hcl.BlockHeaderSchema{ | ||
{ | ||
Type: "plan_options", | ||
}, | ||
{ | ||
Type: "assert", | ||
}, | ||
{ | ||
Type: "variables", | ||
}, | ||
}, | ||
} | ||
|
||
var testRunOptionsBlockSchema = &hcl.BodySchema{ | ||
Attributes: []hcl.AttributeSchema{ | ||
{Name: "mode"}, | ||
{Name: "refresh"}, | ||
{Name: "replace"}, | ||
{Name: "target"}, | ||
}, | ||
} |
17 changes: 17 additions & 0 deletions
17
internal/configs/testdata/valid-modules/with-tests-json/main.tf.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"variable": { | ||
"input": { | ||
"type": "string" | ||
} | ||
}, | ||
"resource": { | ||
"foo_resource": { | ||
"a": { | ||
"value": "${var.input}" | ||
} | ||
}, | ||
"bar_resource": { | ||
"c": {} | ||
} | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
internal/configs/testdata/valid-modules/with-tests-json/test_case_two.tftest.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
{ | ||
"run": { | ||
"test_run_one": { | ||
"variables": { | ||
"input": "test_run_one" | ||
}, | ||
"assert": [ | ||
{ | ||
"condition": "${foo_resource.a.value} == test_run_one", | ||
"error_message": "invalid value" | ||
} | ||
] | ||
}, | ||
"test_run_two": { | ||
"plan_options": { | ||
"mode": "refresh-only" | ||
}, | ||
"variables": { | ||
"input": "test_run_two" | ||
}, | ||
"assert": [ | ||
{ | ||
"condition": "${foo_resource.a.value} == test_run_one", | ||
"error_message": "invalid value" | ||
} | ||
] | ||
}, | ||
"test_run_three": { | ||
"variables": { | ||
"input": "test_run_three" | ||
}, | ||
"plan_options": { | ||
"replace": [ | ||
"bar_resource.c" | ||
] | ||
}, | ||
"assert": [ | ||
{ | ||
"condition": "${foo_resource.a.value} == test_run_three", | ||
"error_message": "invalid value" | ||
} | ||
] | ||
} | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
internal/configs/testdata/valid-modules/with-tests-json/tests/test_case_one.tftest.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"variables": { | ||
"input": "default" | ||
}, | ||
"run": { | ||
"test_run_one": { | ||
"command": "plan", | ||
"plan_options": { | ||
"target": [ | ||
"foo_resource.a" | ||
] | ||
}, | ||
"assert": [ | ||
{ | ||
"condition": "${foo_resource.a.value} == default", | ||
"error_message": "invalid value" | ||
} | ||
] | ||
}, | ||
"test_run_two": { | ||
"variables": { | ||
"input": "custom" | ||
}, | ||
"assert": [ | ||
{ | ||
"condition": "${foo_resource.a.value} == custom", | ||
"error_message": "invalid value" | ||
} | ||
] | ||
} | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
internal/configs/testdata/valid-modules/with-tests-nested/main.tf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
|
||
variable "input" { | ||
type = string | ||
} | ||
|
||
|
||
resource "foo_resource" "a" { | ||
value = var.input | ||
} | ||
|
||
resource "bar_resource" "c" {} |
31 changes: 31 additions & 0 deletions
31
internal/configs/testdata/valid-modules/with-tests-nested/tests/test_case_one.tftest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
variables { | ||
input = "default" | ||
} | ||
|
||
# test_run_one runs a partial plan | ||
run "test_run_one" { | ||
command = plan | ||
|
||
plan_options { | ||
target = [ | ||
foo_resource.a | ||
] | ||
} | ||
|
||
assert { | ||
condition = foo_resource.a.value == "default" | ||
error_message = "invalid value" | ||
} | ||
} | ||
|
||
# test_run_two does a complete apply operation | ||
run "test_run_two" { | ||
variables { | ||
input = "custom" | ||
} | ||
|
||
assert { | ||
condition = foo_resource.a.value == "custom" | ||
error_message = "invalid value" | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
internal/configs/testdata/valid-modules/with-tests-nested/tests/test_case_two.tftest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# test_run_one does a complete apply | ||
run "test_run_one" { | ||
variables { | ||
input = "test_run_one" | ||
} | ||
|
||
assert { | ||
condition = foo_resource.a.value == "test_run_one" | ||
error_message = "invalid value" | ||
} | ||
} | ||
|
||
# test_run_two does a refresh only apply | ||
run "test_run_two" { | ||
plan_options { | ||
mode = refresh-only | ||
} | ||
|
||
variables { | ||
input = "test_run_two" | ||
} | ||
|
||
assert { | ||
# value shouldn't change, as we're doing a refresh-only apply. | ||
condition = foo_resource.a.value == "test_run_one" | ||
error_message = "invalid value" | ||
} | ||
} | ||
|
||
# test_run_three does an apply with a replace operation | ||
run "test_run_three" { | ||
variables { | ||
input = "test_run_three" | ||
} | ||
|
||
plan_options { | ||
replace = [ | ||
bar_resource.c | ||
] | ||
} | ||
|
||
assert { | ||
condition = foo_resource.a.value == "test_run_three" | ||
error_message = "invalid value" | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
internal/configs/testdata/valid-modules/with-tests/main.tf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
|
||
variable "input" { | ||
type = string | ||
} | ||
|
||
|
||
resource "foo_resource" "a" { | ||
value = var.input | ||
} | ||
|
||
resource "bar_resource" "c" {} |
31 changes: 31 additions & 0 deletions
31
internal/configs/testdata/valid-modules/with-tests/test_case_one.tftest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
variables { | ||
input = "default" | ||
} | ||
|
||
# test_run_one runs a partial plan | ||
run "test_run_one" { | ||
command = plan | ||
|
||
plan_options { | ||
target = [ | ||
foo_resource.a | ||
] | ||
} | ||
|
||
assert { | ||
condition = foo_resource.a.value == "default" | ||
error_message = "invalid value" | ||
} | ||
} | ||
|
||
# test_run_two does a complete apply operation | ||
run "test_run_two" { | ||
variables { | ||
input = "custom" | ||
} | ||
|
||
assert { | ||
condition = foo_resource.a.value == "custom" | ||
error_message = "invalid value" | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
internal/configs/testdata/valid-modules/with-tests/test_case_two.tftest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# test_run_one does a complete apply | ||
run "test_run_one" { | ||
variables { | ||
input = "test_run_one" | ||
} | ||
|
||
assert { | ||
condition = foo_resource.a.value == "test_run_one" | ||
error_message = "invalid value" | ||
} | ||
} | ||
|
||
# test_run_two does a refresh only apply | ||
run "test_run_two" { | ||
plan_options { | ||
mode = refresh-only | ||
} | ||
|
||
variables { | ||
input = "test_run_two" | ||
} | ||
|
||
assert { | ||
# value shouldn't change, as we're doing a refresh-only apply. | ||
condition = foo_resource.a.value == "test_run_one" | ||
error_message = "invalid value" | ||
} | ||
} | ||
|
||
# test_run_three does an apply with a replace operation | ||
run "test_run_three" { | ||
variables { | ||
input = "test_run_three" | ||
} | ||
|
||
plan_options { | ||
replace = [ | ||
bar_resource.c | ||
] | ||
} | ||
|
||
assert { | ||
condition = foo_resource.a.value == "test_run_three" | ||
error_message = "invalid value" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters