Skip to content

Commit

Permalink
chore: applied the same fix in the 'internal/cloud' package
Browse files Browse the repository at this point in the history
  • Loading branch information
tchupp committed Jan 21, 2022
1 parent cc5ef7a commit da153fb
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 3 deletions.
2 changes: 1 addition & 1 deletion internal/backend/remote/backend_context_test.go
Expand Up @@ -351,7 +351,7 @@ func TestRemoteVariablesDoNotOverride(t *testing.T) {
},
},
},
"no-conflicting local variable": {
"no conflicting local variable": {
map[string]backend.UnparsedVariableValue{
varName3: testUnparsedVariableValue(varValue3),
},
Expand Down
6 changes: 4 additions & 2 deletions internal/cloud/backend_context.go
Expand Up @@ -110,8 +110,10 @@ func (b *Cloud) LocalRun(op *backend.Operation) (*backend.LocalRun, statemgr.Ful
}
for _, v := range tfeVariables.Items {
if v.Category == tfe.CategoryTerraform {
op.Variables[v.Key] = &remoteStoredVariableValue{
definition: v,
if _, ok := op.Variables[v.Key]; !ok {
op.Variables[v.Key] = &remoteStoredVariableValue{
definition: v,
}
}
}
}
Expand Down
220 changes: 220 additions & 0 deletions internal/cloud/backend_context_test.go
Expand Up @@ -2,6 +2,7 @@ package cloud

import (
"context"
"reflect"
"testing"

tfe "github.com/hashicorp/go-tfe"
Expand All @@ -13,6 +14,8 @@ import (
"github.com/hashicorp/terraform/internal/initwd"
"github.com/hashicorp/terraform/internal/states/statemgr"
"github.com/hashicorp/terraform/internal/terminal"
"github.com/hashicorp/terraform/internal/terraform"
"github.com/hashicorp/terraform/internal/tfdiags"
"github.com/zclconf/go-cty/cty"
)

Expand Down Expand Up @@ -233,3 +236,220 @@ func TestRemoteContextWithVars(t *testing.T) {
})
}
}

func TestRemoteVariablesDoNotOverride(t *testing.T) {
catTerraform := tfe.CategoryTerraform

varName1 := "key1"
varName2 := "key2"
varName3 := "key3"

varValue1 := "value1"
varValue2 := "value2"
varValue3 := "value3"

tests := map[string]struct {
localVariables map[string]backend.UnparsedVariableValue
remoteVariables []*tfe.VariableCreateOptions
expectedVariables terraform.InputValues
}{
"no local variables": {
map[string]backend.UnparsedVariableValue{},
[]*tfe.VariableCreateOptions{
{
Key: &varName1,
Value: &varValue1,
Category: &catTerraform,
},
{
Key: &varName2,
Value: &varValue2,
Category: &catTerraform,
},
{
Key: &varName3,
Value: &varValue3,
Category: &catTerraform,
},
},
terraform.InputValues{
varName1: &terraform.InputValue{
Value: cty.StringVal(varValue1),
SourceType: terraform.ValueFromInput,
SourceRange: tfdiags.SourceRange{
Filename: "",
Start: tfdiags.SourcePos{Line: 0, Column: 0, Byte: 0},
End: tfdiags.SourcePos{Line: 0, Column: 0, Byte: 0},
},
},
varName2: &terraform.InputValue{
Value: cty.StringVal(varValue2),
SourceType: terraform.ValueFromInput,
SourceRange: tfdiags.SourceRange{
Filename: "",
Start: tfdiags.SourcePos{Line: 0, Column: 0, Byte: 0},
End: tfdiags.SourcePos{Line: 0, Column: 0, Byte: 0},
},
},
varName3: &terraform.InputValue{
Value: cty.StringVal(varValue3),
SourceType: terraform.ValueFromInput,
SourceRange: tfdiags.SourceRange{
Filename: "",
Start: tfdiags.SourcePos{Line: 0, Column: 0, Byte: 0},
End: tfdiags.SourcePos{Line: 0, Column: 0, Byte: 0},
},
},
},
},
"single conflicting local variable": {
map[string]backend.UnparsedVariableValue{
varName3: testUnparsedVariableValue{source: terraform.ValueFromNamedFile, value: cty.StringVal(varValue3)},
},
[]*tfe.VariableCreateOptions{
{
Key: &varName1,
Value: &varValue1,
Category: &catTerraform,
}, {
Key: &varName2,
Value: &varValue2,
Category: &catTerraform,
}, {
Key: &varName3,
Value: &varValue3,
Category: &catTerraform,
},
},
terraform.InputValues{
varName1: &terraform.InputValue{
Value: cty.StringVal(varValue1),
SourceType: terraform.ValueFromInput,
SourceRange: tfdiags.SourceRange{
Filename: "",
Start: tfdiags.SourcePos{Line: 0, Column: 0, Byte: 0},
End: tfdiags.SourcePos{Line: 0, Column: 0, Byte: 0},
},
},
varName2: &terraform.InputValue{
Value: cty.StringVal(varValue2),
SourceType: terraform.ValueFromInput,
SourceRange: tfdiags.SourceRange{
Filename: "",
Start: tfdiags.SourcePos{Line: 0, Column: 0, Byte: 0},
End: tfdiags.SourcePos{Line: 0, Column: 0, Byte: 0},
},
},
varName3: &terraform.InputValue{
Value: cty.StringVal(varValue3),
SourceType: terraform.ValueFromNamedFile,
SourceRange: tfdiags.SourceRange{
Filename: "fake.tfvars",
Start: tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
End: tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
},
},
},
},
"no conflicting local variable": {
map[string]backend.UnparsedVariableValue{
varName3: testUnparsedVariableValue{source: terraform.ValueFromNamedFile, value: cty.StringVal(varValue3)},
},
[]*tfe.VariableCreateOptions{
{
Key: &varName1,
Value: &varValue1,
Category: &catTerraform,
}, {
Key: &varName2,
Value: &varValue2,
Category: &catTerraform,
},
},
terraform.InputValues{
varName1: &terraform.InputValue{
Value: cty.StringVal(varValue1),
SourceType: terraform.ValueFromInput,
SourceRange: tfdiags.SourceRange{
Filename: "",
Start: tfdiags.SourcePos{Line: 0, Column: 0, Byte: 0},
End: tfdiags.SourcePos{Line: 0, Column: 0, Byte: 0},
},
},
varName2: &terraform.InputValue{
Value: cty.StringVal(varValue2),
SourceType: terraform.ValueFromInput,
SourceRange: tfdiags.SourceRange{
Filename: "",
Start: tfdiags.SourcePos{Line: 0, Column: 0, Byte: 0},
End: tfdiags.SourcePos{Line: 0, Column: 0, Byte: 0},
},
},
varName3: &terraform.InputValue{
Value: cty.StringVal(varValue3),
SourceType: terraform.ValueFromNamedFile,
SourceRange: tfdiags.SourceRange{
Filename: "fake.tfvars",
Start: tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
End: tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
},
},
},
},
}

for name, test := range tests {
t.Run(name, func(t *testing.T) {
configDir := "./testdata/variables"

b, bCleanup := testBackendWithName(t)
defer bCleanup()

_, configLoader, configCleanup := initwd.MustLoadConfigForTests(t, configDir)
defer configCleanup()

workspaceID, err := b.getRemoteWorkspaceID(context.Background(), testBackendSingleWorkspaceName)
if err != nil {
t.Fatal(err)
}

streams, _ := terminal.StreamsForTesting(t)
view := views.NewStateLocker(arguments.ViewHuman, views.NewView(streams))

op := &backend.Operation{
ConfigDir: configDir,
ConfigLoader: configLoader,
StateLocker: clistate.NewLocker(0, view),
Workspace: testBackendSingleWorkspaceName,
Variables: test.localVariables,
}

for _, v := range test.remoteVariables {
b.client.Variables.Create(context.TODO(), workspaceID, *v)
}

lr, _, diags := b.LocalRun(op)

if diags.HasErrors() {
t.Fatalf("unexpected error\ngot: %s\nwant: <no error>", diags.Err().Error())
}
// When Context() succeeds, this should fail w/ "workspace already locked"
stateMgr, _ := b.StateMgr(testBackendSingleWorkspaceName)
if _, err := stateMgr.Lock(statemgr.NewLockInfo()); err == nil {
t.Fatal("unexpected success locking state after Context")
}

actual := lr.PlanOpts.SetVariables
expected := test.expectedVariables

for expectedKey := range expected {
actualValue := actual[expectedKey]
expectedValue := expected[expectedKey]

if !reflect.DeepEqual(*actualValue, *expectedValue) {
t.Fatalf("unexpected variable '%s'\ngot: %v\nwant: %v", expectedKey, actualValue, expectedValue)
}
}
})
}
}
8 changes: 8 additions & 0 deletions internal/cloud/testdata/variables/main.tf
@@ -0,0 +1,8 @@
variable "key1" {
}

variable "key2" {
}

variable "key3" {
}

0 comments on commit da153fb

Please sign in to comment.