mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-23 15:40:07 -06:00
OpenTofu Specific Code Override: Add support to .tofu files (#1738)
Signed-off-by: Ronny Orot <ronny.orot@gmail.com>
This commit is contained in:
parent
1ecb2dcae3
commit
ab289fc07c
@ -32,6 +32,9 @@ linters-settings:
|
||||
cyclop:
|
||||
max-complexity: 15
|
||||
|
||||
gocognit:
|
||||
min-complexity: 50
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
- path: (.+)_test.go
|
||||
|
@ -7,9 +7,11 @@ package configs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
@ -19,6 +21,17 @@ const (
|
||||
DefaultTestDirectory = "tests"
|
||||
)
|
||||
|
||||
const (
|
||||
tfExt = ".tf"
|
||||
tofuExt = ".tofu"
|
||||
tfJSONExt = ".tf.json"
|
||||
tofuJSONExt = ".tofu.json"
|
||||
tfTestExt = ".tftest.hcl"
|
||||
tofuTestExt = ".tofutest.hcl"
|
||||
tfTestJSONExt = ".tftest.json"
|
||||
tofuTestJSONExt = ".tofutest.json"
|
||||
)
|
||||
|
||||
// LoadConfigDir reads the .tf and .tf.json files in the given directory
|
||||
// as config files (using LoadConfigFile) and then combines these files into
|
||||
// a single Module.
|
||||
@ -178,7 +191,8 @@ func (p *Parser) dirFiles(dir string, testsDir string) (primary, override, tests
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasSuffix(testInfo.Name(), ".tftest.hcl") || strings.HasSuffix(testInfo.Name(), ".tftest.json") {
|
||||
ext := fileExt(testInfo.Name())
|
||||
if isTestFileExt(ext) {
|
||||
tests = append(tests, filepath.Join(testPath, testInfo.Name()))
|
||||
}
|
||||
}
|
||||
@ -208,7 +222,7 @@ func (p *Parser) dirFiles(dir string, testsDir string) (primary, override, tests
|
||||
continue
|
||||
}
|
||||
|
||||
if ext == ".tftest.hcl" || ext == ".tftest.json" {
|
||||
if isTestFileExt(ext) {
|
||||
if includeTests {
|
||||
tests = append(tests, filepath.Join(dir, name))
|
||||
}
|
||||
@ -226,7 +240,44 @@ func (p *Parser) dirFiles(dir string, testsDir string) (primary, override, tests
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
return filterTfPathsWithTofuAlternatives(primary), filterTfPathsWithTofuAlternatives(override), filterTfPathsWithTofuAlternatives(tests), diags
|
||||
}
|
||||
|
||||
// filterTfPathsWithTofuAlternatives filters out .tf files if they have an
|
||||
// alternative .tofu file with the same name.
|
||||
// For example, if there are both 'resources.tf.json' and
|
||||
// 'resources.tofu.json' files, the 'resources.tf.json' file will be ignored,
|
||||
// and only the 'resources.tofu.json' file will be returned as a relevant path.
|
||||
func filterTfPathsWithTofuAlternatives(paths []string) []string {
|
||||
var ignoredPaths []string
|
||||
var relevantPaths []string
|
||||
|
||||
for _, p := range paths {
|
||||
ext := tfFileExt(p)
|
||||
|
||||
if ext == "" {
|
||||
relevantPaths = append(relevantPaths, p)
|
||||
continue
|
||||
}
|
||||
|
||||
parallelTofuExt := strings.ReplaceAll(ext, ".tf", ".tofu")
|
||||
pathWithoutExt, _ := strings.CutSuffix(p, ext)
|
||||
parallelTofuPath := pathWithoutExt + parallelTofuExt
|
||||
|
||||
// If the .tf file has a parallel .tofu file in the directory,
|
||||
// we'll ignore the .tf file and only use the .tofu file
|
||||
if slices.Contains(paths, parallelTofuPath) {
|
||||
ignoredPaths = append(ignoredPaths, p)
|
||||
} else {
|
||||
relevantPaths = append(relevantPaths, p)
|
||||
}
|
||||
}
|
||||
|
||||
if len(ignoredPaths) > 0 {
|
||||
log.Printf("[INFO] filterTfPathsWithTofuAlternatives: Ignored the following .tf files because a .tofu file alternative exists: %q", ignoredPaths)
|
||||
}
|
||||
|
||||
return relevantPaths
|
||||
}
|
||||
|
||||
func (p *Parser) loadTestFiles(basePath string, paths []string) (map[string]*TestFile, hcl.Diagnostics) {
|
||||
@ -258,19 +309,53 @@ func (p *Parser) loadTestFiles(basePath string, paths []string) (map[string]*Tes
|
||||
// fileExt returns the OpenTofu configuration extension of the given
|
||||
// path, or a blank string if it is not a recognized extension.
|
||||
func fileExt(path string) string {
|
||||
if strings.HasSuffix(path, ".tf") {
|
||||
return ".tf"
|
||||
} else if strings.HasSuffix(path, ".tf.json") {
|
||||
return ".tf.json"
|
||||
} else if strings.HasSuffix(path, ".tftest.hcl") {
|
||||
return ".tftest.hcl"
|
||||
} else if strings.HasSuffix(path, ".tftest.json") {
|
||||
return ".tftest.json"
|
||||
} else {
|
||||
extension := tfFileExt(path)
|
||||
|
||||
if extension == "" {
|
||||
extension = tofuFileExt(path)
|
||||
}
|
||||
|
||||
return extension
|
||||
}
|
||||
|
||||
// tfFileExt returns the OpenTofu .tf configuration extension of the given
|
||||
// path, or a blank string if it is not a recognized .tf extension.
|
||||
func tfFileExt(path string) string {
|
||||
switch {
|
||||
case strings.HasSuffix(path, tfExt):
|
||||
return tfExt
|
||||
case strings.HasSuffix(path, tfJSONExt):
|
||||
return tfJSONExt
|
||||
case strings.HasSuffix(path, tfTestExt):
|
||||
return tfTestExt
|
||||
case strings.HasSuffix(path, tfTestJSONExt):
|
||||
return tfTestJSONExt
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// tofuFileExt returns the OpenTofu .tofu configuration extension of the given
|
||||
// path, or a blank string if it is not a recognized .tofu extension.
|
||||
func tofuFileExt(path string) string {
|
||||
switch {
|
||||
case strings.HasSuffix(path, tofuExt):
|
||||
return tofuExt
|
||||
case strings.HasSuffix(path, tofuJSONExt):
|
||||
return tofuJSONExt
|
||||
case strings.HasSuffix(path, tofuTestExt):
|
||||
return tofuTestExt
|
||||
case strings.HasSuffix(path, tofuTestJSONExt):
|
||||
return tofuTestJSONExt
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func isTestFileExt(ext string) bool {
|
||||
return ext == tfTestExt || ext == tfTestJSONExt || ext == tofuTestExt || ext == tofuTestJSONExt
|
||||
}
|
||||
|
||||
// IsIgnoredFile returns true if the given filename (which must not have a
|
||||
// directory path ahead of it) should be ignored as e.g. an editor swap file.
|
||||
func IsIgnoredFile(name string) bool {
|
||||
|
@ -238,6 +238,79 @@ func TestParserLoadConfigDirFailure(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestParserLoadConfigDirWithTests_TofuFiles(t *testing.T) {
|
||||
expectedVariablesToOverride := []string{"should_override", "should_override_json"}
|
||||
expectedLoadedTestFiles := []string{"test/resources_test.tofutest.hcl", "test/resources_test_json.tofutest.json"}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
expectedResources []string
|
||||
}{
|
||||
{
|
||||
name: "only .tofu files",
|
||||
path: "testdata/tofu-only-files",
|
||||
expectedResources: []string{"aws_security_group.firewall_tofu", "aws_instance.web_tofu", "test_object.a_tofu", "test_object.b_tofu"},
|
||||
},
|
||||
{
|
||||
name: ".tofu and .tf files",
|
||||
path: "testdata/tofu-and-tf-files",
|
||||
expectedResources: []string{"aws_security_group.firewall_tofu", "aws_instance.web_tofu", "test_object.a_tofu", "test_object.b_tofu", "tf_resource.first", "tf_json_resource.a"},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
parser := NewParser(nil)
|
||||
path := tt.path
|
||||
|
||||
mod, diags := parser.LoadConfigDirWithTests(path, "test")
|
||||
if len(diags) != 0 {
|
||||
t.Errorf("unexpected diagnostics")
|
||||
for _, diag := range diags {
|
||||
t.Logf("- %s", diag)
|
||||
}
|
||||
}
|
||||
|
||||
if mod.SourceDir != path {
|
||||
t.Errorf("wrong SourceDir value %q; want %s", mod.SourceDir, path)
|
||||
}
|
||||
|
||||
if len(tt.expectedResources) != len(mod.ManagedResources) {
|
||||
t.Errorf("expected to find %d resources but instead got %d resources", len(tt.expectedResources), len(mod.ManagedResources))
|
||||
}
|
||||
|
||||
for _, expectedResource := range tt.expectedResources {
|
||||
if mod.ManagedResources[expectedResource] == nil {
|
||||
t.Errorf("expected to load %s resource as part of configuration but it is missing", expectedResource)
|
||||
}
|
||||
}
|
||||
|
||||
if len(expectedVariablesToOverride) != len(mod.Variables) {
|
||||
t.Errorf("expected to find %d variables but instead got %d resources", len(expectedVariablesToOverride), len(mod.Variables))
|
||||
}
|
||||
|
||||
for _, expectedVariable := range expectedVariablesToOverride {
|
||||
variableInConfiguration := mod.Variables[expectedVariable]
|
||||
if variableInConfiguration == nil {
|
||||
t.Errorf("expected to load %s variable as part of configuration but it is missing", expectedVariable)
|
||||
} else if variableInConfiguration.Default.AsString() != "overridden by tofu file" {
|
||||
t.Errorf("expected variable default value %s to be overridden", expectedVariable)
|
||||
}
|
||||
}
|
||||
|
||||
if len(mod.Tests) != 2 {
|
||||
t.Errorf("incorrect number of test files found: %d", len(mod.Tests))
|
||||
}
|
||||
|
||||
for _, expectedTest := range expectedLoadedTestFiles {
|
||||
if mod.Tests[expectedTest] == nil {
|
||||
t.Errorf("expected to load %s test as part of configuration but it is missing", expectedTest)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsEmptyDir(t *testing.T) {
|
||||
val, err := IsEmptyDir(filepath.Join("testdata", "valid-files"))
|
||||
if err != nil {
|
||||
|
3
internal/configs/testdata/tofu-and-tf-files/more-resources.tf
vendored
Normal file
3
internal/configs/testdata/tofu-and-tf-files/more-resources.tf
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
resource "tf_resource" "first" {
|
||||
test_string = "hello"
|
||||
}
|
10
internal/configs/testdata/tofu-and-tf-files/more-resources.tf.json
vendored
Normal file
10
internal/configs/testdata/tofu-and-tf-files/more-resources.tf.json
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"resource": {
|
||||
"tf_json_resource": {
|
||||
"a": {
|
||||
"count": 1,
|
||||
"test_string": "first"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
43
internal/configs/testdata/tofu-and-tf-files/resources.tf
vendored
Normal file
43
internal/configs/testdata/tofu-and-tf-files/resources.tf
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
resource "aws_security_group" "firewall" {
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
prevent_destroy = true
|
||||
ignore_changes = [
|
||||
description,
|
||||
]
|
||||
}
|
||||
|
||||
connection {
|
||||
host = "127.0.0.1"
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "echo hello"
|
||||
|
||||
connection {
|
||||
host = "10.1.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "echo hello"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_instance" "web" {
|
||||
count = 2
|
||||
ami = "ami-1234"
|
||||
security_groups = [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
|
||||
network_interface {
|
||||
device_index = 0
|
||||
description = "Main network interface"
|
||||
}
|
||||
|
||||
depends_on = [
|
||||
aws_security_group.firewall,
|
||||
]
|
||||
}
|
14
internal/configs/testdata/tofu-and-tf-files/resources.tf.json
vendored
Normal file
14
internal/configs/testdata/tofu-and-tf-files/resources.tf.json
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"resource": {
|
||||
"test_object": {
|
||||
"a": {
|
||||
"count": 1,
|
||||
"test_string": "hello"
|
||||
},
|
||||
"b": {
|
||||
"count": 1,
|
||||
"test_string": "world"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
43
internal/configs/testdata/tofu-and-tf-files/resources.tofu
vendored
Normal file
43
internal/configs/testdata/tofu-and-tf-files/resources.tofu
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
resource "aws_security_group" "firewall_tofu" {
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
prevent_destroy = true
|
||||
ignore_changes = [
|
||||
description,
|
||||
]
|
||||
}
|
||||
|
||||
connection {
|
||||
host = "127.0.0.1"
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "echo hello"
|
||||
|
||||
connection {
|
||||
host = "10.1.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "echo hello"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_instance" "web_tofu" {
|
||||
count = 2
|
||||
ami = "ami-1234"
|
||||
security_groups = [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
|
||||
network_interface {
|
||||
device_index = 0
|
||||
description = "Main network interface"
|
||||
}
|
||||
|
||||
depends_on = [
|
||||
aws_security_group.firewall,
|
||||
]
|
||||
}
|
14
internal/configs/testdata/tofu-and-tf-files/resources.tofu.json
vendored
Normal file
14
internal/configs/testdata/tofu-and-tf-files/resources.tofu.json
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"resource": {
|
||||
"test_object": {
|
||||
"a_tofu": {
|
||||
"count": 1,
|
||||
"test_string": "hello"
|
||||
},
|
||||
"b_tofu": {
|
||||
"count": 1,
|
||||
"test_string": "world"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
internal/configs/testdata/tofu-and-tf-files/test/resources_test.tftest.hcl
vendored
Normal file
27
internal/configs/testdata/tofu-and-tf-files/test/resources_test.tftest.hcl
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
# test_run_one runs a partial plan
|
||||
run "test_run_one" {
|
||||
command = plan
|
||||
|
||||
plan_options {
|
||||
target = [
|
||||
test_object.b
|
||||
]
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = test_object.b.test_string == "world"
|
||||
error_message = "invalid value"
|
||||
}
|
||||
}
|
||||
|
||||
# test_run_two does a complete apply operation
|
||||
run "test_run_two" {
|
||||
variables {
|
||||
input = "custom"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = test_object.a.test_string == "hello"
|
||||
error_message = "invalid value"
|
||||
}
|
||||
}
|
27
internal/configs/testdata/tofu-and-tf-files/test/resources_test.tofutest.hcl
vendored
Normal file
27
internal/configs/testdata/tofu-and-tf-files/test/resources_test.tofutest.hcl
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
# test_run_one runs a partial plan
|
||||
run "test_run_one" {
|
||||
command = plan
|
||||
|
||||
plan_options {
|
||||
target = [
|
||||
test_object.b
|
||||
]
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = test_object.b.test_string == "world"
|
||||
error_message = "invalid value"
|
||||
}
|
||||
}
|
||||
|
||||
# test_run_two does a complete apply operation
|
||||
run "test_run_two" {
|
||||
variables {
|
||||
input = "custom"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = test_object.a.test_string == "hello"
|
||||
error_message = "invalid value"
|
||||
}
|
||||
}
|
29
internal/configs/testdata/tofu-and-tf-files/test/resources_test_json.tftest.json
vendored
Normal file
29
internal/configs/testdata/tofu-and-tf-files/test/resources_test_json.tftest.json
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"variables": {
|
||||
"input": "default"
|
||||
},
|
||||
"run": {
|
||||
"test_run_one": {
|
||||
"command": "plan",
|
||||
"plan_options": {
|
||||
"target": [
|
||||
"test_object.a"
|
||||
]
|
||||
},
|
||||
"assert": [
|
||||
{
|
||||
"condition": "${test_object.a.test_string} == hello",
|
||||
"error_message": "invalid value"
|
||||
}
|
||||
]
|
||||
},
|
||||
"test_run_two": {
|
||||
"assert": [
|
||||
{
|
||||
"condition": "${test_object.b.test_string} == world",
|
||||
"error_message": "invalid value"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
29
internal/configs/testdata/tofu-and-tf-files/test/resources_test_json.tofutest.json
vendored
Normal file
29
internal/configs/testdata/tofu-and-tf-files/test/resources_test_json.tofutest.json
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"variables": {
|
||||
"input": "default"
|
||||
},
|
||||
"run": {
|
||||
"test_run_one": {
|
||||
"command": "plan",
|
||||
"plan_options": {
|
||||
"target": [
|
||||
"test_object.a"
|
||||
]
|
||||
},
|
||||
"assert": [
|
||||
{
|
||||
"condition": "${test_object.a.test_string} == hello",
|
||||
"error_message": "invalid value"
|
||||
}
|
||||
]
|
||||
},
|
||||
"test_run_two": {
|
||||
"assert": [
|
||||
{
|
||||
"condition": "${test_object.b.test_string} == world",
|
||||
"error_message": "invalid value"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
3
internal/configs/testdata/tofu-and-tf-files/variables.tf
vendored
Normal file
3
internal/configs/testdata/tofu-and-tf-files/variables.tf
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
variable "should_override" {
|
||||
default = "not overridden"
|
||||
}
|
7
internal/configs/testdata/tofu-and-tf-files/variables.tf.json
vendored
Normal file
7
internal/configs/testdata/tofu-and-tf-files/variables.tf.json
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"variable": {
|
||||
"should_override_json": {
|
||||
"default": "not overridden"
|
||||
}
|
||||
}
|
||||
}
|
3
internal/configs/testdata/tofu-and-tf-files/variables_override.tf
vendored
Normal file
3
internal/configs/testdata/tofu-and-tf-files/variables_override.tf
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
variable "should_override" {
|
||||
default = "overridden by tf file"
|
||||
}
|
7
internal/configs/testdata/tofu-and-tf-files/variables_override.tf.json
vendored
Normal file
7
internal/configs/testdata/tofu-and-tf-files/variables_override.tf.json
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"variable": {
|
||||
"should_override_json": {
|
||||
"default": "overridden by tf file"
|
||||
}
|
||||
}
|
||||
}
|
3
internal/configs/testdata/tofu-and-tf-files/variables_override.tofu
vendored
Normal file
3
internal/configs/testdata/tofu-and-tf-files/variables_override.tofu
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
variable "should_override" {
|
||||
default = "overridden by tofu file"
|
||||
}
|
7
internal/configs/testdata/tofu-and-tf-files/variables_override.tofu.json
vendored
Normal file
7
internal/configs/testdata/tofu-and-tf-files/variables_override.tofu.json
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"variable": {
|
||||
"should_override_json": {
|
||||
"default": "overridden by tofu file"
|
||||
}
|
||||
}
|
||||
}
|
43
internal/configs/testdata/tofu-only-files/resources.tofu
vendored
Normal file
43
internal/configs/testdata/tofu-only-files/resources.tofu
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
resource "aws_security_group" "firewall_tofu" {
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
prevent_destroy = true
|
||||
ignore_changes = [
|
||||
description,
|
||||
]
|
||||
}
|
||||
|
||||
connection {
|
||||
host = "127.0.0.1"
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "echo hello"
|
||||
|
||||
connection {
|
||||
host = "10.1.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "echo hello"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_instance" "web_tofu" {
|
||||
count = 2
|
||||
ami = "ami-1234"
|
||||
security_groups = [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
|
||||
network_interface {
|
||||
device_index = 0
|
||||
description = "Main network interface"
|
||||
}
|
||||
|
||||
depends_on = [
|
||||
aws_security_group.firewall,
|
||||
]
|
||||
}
|
14
internal/configs/testdata/tofu-only-files/resources.tofu.json
vendored
Normal file
14
internal/configs/testdata/tofu-only-files/resources.tofu.json
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"resource": {
|
||||
"test_object": {
|
||||
"a_tofu": {
|
||||
"count": 1,
|
||||
"test_string": "hello"
|
||||
},
|
||||
"b_tofu": {
|
||||
"count": 1,
|
||||
"test_string": "world"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
internal/configs/testdata/tofu-only-files/test/resources_test.tofutest.hcl
vendored
Normal file
27
internal/configs/testdata/tofu-only-files/test/resources_test.tofutest.hcl
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
# test_run_one runs a partial plan
|
||||
run "test_run_one" {
|
||||
command = plan
|
||||
|
||||
plan_options {
|
||||
target = [
|
||||
test_object.b
|
||||
]
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = test_object.b.test_string == "world"
|
||||
error_message = "invalid value"
|
||||
}
|
||||
}
|
||||
|
||||
# test_run_two does a complete apply operation
|
||||
run "test_run_two" {
|
||||
variables {
|
||||
input = "custom"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = test_object.a.test_string == "hello"
|
||||
error_message = "invalid value"
|
||||
}
|
||||
}
|
29
internal/configs/testdata/tofu-only-files/test/resources_test_json.tofutest.json
vendored
Normal file
29
internal/configs/testdata/tofu-only-files/test/resources_test_json.tofutest.json
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"variables": {
|
||||
"input": "default"
|
||||
},
|
||||
"run": {
|
||||
"test_run_one": {
|
||||
"command": "plan",
|
||||
"plan_options": {
|
||||
"target": [
|
||||
"test_object.a"
|
||||
]
|
||||
},
|
||||
"assert": [
|
||||
{
|
||||
"condition": "${test_object.a.test_string} == hello",
|
||||
"error_message": "invalid value"
|
||||
}
|
||||
]
|
||||
},
|
||||
"test_run_two": {
|
||||
"assert": [
|
||||
{
|
||||
"condition": "${test_object.b.test_string} == world",
|
||||
"error_message": "invalid value"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
3
internal/configs/testdata/tofu-only-files/variables.tofu
vendored
Normal file
3
internal/configs/testdata/tofu-only-files/variables.tofu
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
variable "should_override" {
|
||||
default = "not overridden"
|
||||
}
|
7
internal/configs/testdata/tofu-only-files/variables.tofu.json
vendored
Normal file
7
internal/configs/testdata/tofu-only-files/variables.tofu.json
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"variable": {
|
||||
"should_override_json": {
|
||||
"default": "not overridden"
|
||||
}
|
||||
}
|
||||
}
|
3
internal/configs/testdata/tofu-only-files/variables_override.tofu
vendored
Normal file
3
internal/configs/testdata/tofu-only-files/variables_override.tofu
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
variable "should_override" {
|
||||
default = "overridden by tofu file"
|
||||
}
|
7
internal/configs/testdata/tofu-only-files/variables_override.tofu.json
vendored
Normal file
7
internal/configs/testdata/tofu-only-files/variables_override.tofu.json
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"variable": {
|
||||
"should_override_json": {
|
||||
"default": "overridden by tofu file"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user