Skip to content

Commit

Permalink
internal/command: Ensure ephemeral variables are validated accordingly
Browse files Browse the repository at this point in the history
  • Loading branch information
radeksimko committed Sep 4, 2024
1 parent cee2a52 commit 0e699a4
Show file tree
Hide file tree
Showing 21 changed files with 207 additions and 1 deletion.
1 change: 1 addition & 0 deletions internal/command/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ func TestApply_parallelism(t *testing.T) {
// called once we reach the desired concurrency, allowing all apply calls
// to proceed in unison.
beginCtx, begin := context.WithCancel(context.Background())
t.Cleanup(begin)

// Since our mock provider has its own mutex preventing concurrent calls
// to ApplyResourceChange, we need to use a number of separate providers
Expand Down
93 changes: 92 additions & 1 deletion internal/command/plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ import (
"github.com/hashicorp/terraform/internal/addrs"
backendinit "github.com/hashicorp/terraform/internal/backend/init"
"github.com/hashicorp/terraform/internal/checks"
"github.com/hashicorp/terraform/internal/command/views"
"github.com/hashicorp/terraform/internal/configs/configschema"
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/providers"
testing_provider "github.com/hashicorp/terraform/internal/providers/testing"
"github.com/hashicorp/terraform/internal/states"
"github.com/hashicorp/terraform/internal/terminal"
"github.com/hashicorp/terraform/internal/tfdiags"
)

Expand Down Expand Up @@ -1428,7 +1430,7 @@ func TestPlan_parallelism(t *testing.T) {
// called once we reach the desired concurrency, allowing all apply calls
// to proceed in unison.
beginCtx, begin := context.WithCancel(context.Background())

t.Cleanup(begin)
// Since our mock provider has its own mutex preventing concurrent calls
// to ApplyResourceChange, we need to use a number of separate providers
// here. They will all have the same mock implementation function assigned
Expand Down Expand Up @@ -1583,6 +1585,95 @@ func TestPlan_jsonGoldenReference(t *testing.T) {
checkGoldenReference(t, output, "plan")
}

func TestPlan_ephemeralValues(t *testing.T) {
testCases := []struct {
fixturePath string
expectedCode int
expectedOutput string
}{
{
"plan-ephemeral-values-invalid-eph-var-in-non-eph-output",
1,
`Error: Ephemeral value not allowed`,
},
{
"plan-ephemeral-values-invalid-module-eph-output",
1,
`Error: Value not allowed in ephemeral output`,
},
{
"plan-ephemeral-values-invalid-module-input",
1,
"Error: Ephemeral value not allowed",
},
{
"plan-ephemeral-values-invalid-module-non-eph-output",
1,
`Error: Ephemeral value not allowed`,
},
{
"plan-ephemeral-values-invalid-noneph-var-in-eph-output",
1,
`Error: Value not allowed in ephemeral output`,
},
{
"plan-ephemeral-values-valid",
0,
"",
},
{
"plan-ephemeral-values-valid-module-input",
0,
"",
},
{
"plan-ephemeral-values-variable-validation",
1,
"Error: Invalid value for variable",
},
}

for i, tc := range testCases {
t.Run(fmt.Sprintf("%2d-%s", i, tc.fixturePath), func(t *testing.T) {
td := t.TempDir()
testCopyDir(t, testFixturePath(tc.fixturePath), td)
defer testChdir(t, td)()

p := planFixtureProvider()
p.GetProviderSchemaResponse.Provider = providers.Schema{
Version: 0,
Block: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"token": {
Type: cty.String,
Optional: true,
Sensitive: true,
},
},
},
}

streams, done := terminal.StreamsForTesting(t)
c := &PlanCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(p),
View: views.NewView(streams),
},
}
code := c.Run([]string{"-json"})
out := done(t)
if code != tc.expectedCode {
t.Fatalf("expected exit code %d, given %d\noutput: %q", tc.expectedCode, code, out.All())
}

stdout := out.Stdout()
if tc.expectedOutput != "" && !strings.Contains(stdout, tc.expectedOutput) {
t.Fatalf("unexpected output: %s", stdout)
}
})
}
}

// planFixtureSchema returns a schema suitable for processing the
// configuration in testdata/plan . This schema should be
// assigned to a mock provider named "test".
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
variable "eph" {
ephemeral = true
default = "foo"
}

output "not-eph" {
value = var.eph
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"test","Source":"./eph-module","Dir":"eph-module"}]}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
output "eph" {
ephemeral = true
value = var.eph
}

output "not-eph" {
value = "foo"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
variable "eph" {
type = string
ephemeral = true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module "test" {
source = "./eph-module"
eph = "foo"
}

output "eph" {
ephemeral = true
value = module.test.not-eph
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"test","Source":"./eph-module","Dir":"eph-module"}]}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
variable "eph" {
type = string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
variable "test-eph" {
type = string
default = "foo"
ephemeral = true
}

module "test" {
source = "./eph-module"
eph = var.test-eph
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"test","Source":"./eph-module","Dir":"eph-module"}]}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
output "eph" {
ephemeral = true
value = var.eph
}

output "not-eph" {
value = "foo"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
variable "eph" {
type = string
ephemeral = true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module "test" {
source = "./eph-module"
eph = "foo"
}

output "eph" {
value = module.test.eph
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
variable "not-eph" {
default = "foo"
}

output "eph" {
ephemeral = true
value = var.not-eph
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"test","Source":"./eph-module","Dir":"eph-module"}]}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
variable "eph" {
ephemeral = true
type = string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
variable "test-eph" {
type = string
default = "foo"
ephemeral = true
}

module "test" {
source = "./eph-module"
eph = var.test-eph
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
variable "valid-eph" {
ephemeral = true
default = "foo"
}

output "valid-eph" {
ephemeral = true
value = var.valid-eph
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
variable "token" {
ephemeral = true
default = "insecure"
}

provider "test" {
token = var.token
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
variable "test" {
ephemeral = true
default = "foo"

validation {
condition = var.test != "foo"
error_message = "value"
}
}

0 comments on commit 0e699a4

Please sign in to comment.