| package cloud |
| |
| import ( |
| "testing" |
| |
| "github.com/google/go-cmp/cmp" |
| "github.com/hashicorp/hcl/v2" |
| "github.com/hashicorp/terraform/internal/backend" |
| "github.com/hashicorp/terraform/internal/configs" |
| "github.com/hashicorp/terraform/internal/terraform" |
| "github.com/hashicorp/terraform/internal/tfdiags" |
| "github.com/zclconf/go-cty/cty" |
| ) |
| |
| func TestParseCloudRunVariables(t *testing.T) { |
| t.Run("populates variables from allowed sources", func(t *testing.T) { |
| vv := map[string]backend.UnparsedVariableValue{ |
| "undeclared": testUnparsedVariableValue{source: terraform.ValueFromCLIArg, value: cty.StringVal("0")}, |
| "declaredFromConfig": testUnparsedVariableValue{source: terraform.ValueFromConfig, value: cty.StringVal("1")}, |
| "declaredFromNamedFileMapString": testUnparsedVariableValue{source: terraform.ValueFromNamedFile, value: cty.MapVal(map[string]cty.Value{"foo": cty.StringVal("bar")})}, |
| "declaredFromNamedFileBool": testUnparsedVariableValue{source: terraform.ValueFromNamedFile, value: cty.BoolVal(true)}, |
| "declaredFromNamedFileNumber": testUnparsedVariableValue{source: terraform.ValueFromNamedFile, value: cty.NumberIntVal(2)}, |
| "declaredFromNamedFileListString": testUnparsedVariableValue{source: terraform.ValueFromNamedFile, value: cty.ListVal([]cty.Value{cty.StringVal("2a"), cty.StringVal("2b")})}, |
| "declaredFromNamedFileNull": testUnparsedVariableValue{source: terraform.ValueFromNamedFile, value: cty.NullVal(cty.String)}, |
| "declaredFromNamedMapComplex": testUnparsedVariableValue{source: terraform.ValueFromNamedFile, value: cty.MapVal(map[string]cty.Value{"foo": cty.ObjectVal(map[string]cty.Value{"qux": cty.ListVal([]cty.Value{cty.BoolVal(true), cty.BoolVal(false)})})})}, |
| "declaredFromCLIArg": testUnparsedVariableValue{source: terraform.ValueFromCLIArg, value: cty.StringVal("3")}, |
| "declaredFromEnvVar": testUnparsedVariableValue{source: terraform.ValueFromEnvVar, value: cty.StringVal("4")}, |
| } |
| |
| decls := map[string]*configs.Variable{ |
| "declaredFromConfig": { |
| Name: "declaredFromConfig", |
| Type: cty.String, |
| ConstraintType: cty.String, |
| ParsingMode: configs.VariableParseLiteral, |
| DeclRange: hcl.Range{ |
| Filename: "fake.tf", |
| Start: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| End: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| }, |
| }, |
| "declaredFromNamedFileMapString": { |
| Name: "declaredFromNamedFileMapString", |
| Type: cty.Map(cty.String), |
| ConstraintType: cty.Map(cty.String), |
| ParsingMode: configs.VariableParseHCL, |
| DeclRange: hcl.Range{ |
| Filename: "fake.tf", |
| Start: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| End: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| }, |
| }, |
| "declaredFromNamedFileBool": { |
| Name: "declaredFromNamedFileBool", |
| Type: cty.Bool, |
| ConstraintType: cty.Bool, |
| ParsingMode: configs.VariableParseLiteral, |
| DeclRange: hcl.Range{ |
| Filename: "fake.tf", |
| Start: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| End: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| }, |
| }, |
| "declaredFromNamedFileNumber": { |
| Name: "declaredFromNamedFileNumber", |
| Type: cty.Number, |
| ConstraintType: cty.Number, |
| ParsingMode: configs.VariableParseLiteral, |
| DeclRange: hcl.Range{ |
| Filename: "fake.tf", |
| Start: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| End: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| }, |
| }, |
| "declaredFromNamedFileListString": { |
| Name: "declaredFromNamedFileListString", |
| Type: cty.List(cty.String), |
| ConstraintType: cty.List(cty.String), |
| ParsingMode: configs.VariableParseHCL, |
| DeclRange: hcl.Range{ |
| Filename: "fake.tf", |
| Start: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| End: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| }, |
| }, |
| "declaredFromNamedFileNull": { |
| Name: "declaredFromNamedFileNull", |
| Type: cty.String, |
| ConstraintType: cty.String, |
| ParsingMode: configs.VariableParseHCL, |
| DeclRange: hcl.Range{ |
| Filename: "fake.tf", |
| Start: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| End: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| }, |
| }, |
| "declaredFromNamedMapComplex": { |
| Name: "declaredFromNamedMapComplex", |
| Type: cty.DynamicPseudoType, |
| ConstraintType: cty.DynamicPseudoType, |
| ParsingMode: configs.VariableParseHCL, |
| DeclRange: hcl.Range{ |
| Filename: "fake.tf", |
| Start: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| End: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| }, |
| }, |
| "declaredFromCLIArg": { |
| Name: "declaredFromCLIArg", |
| Type: cty.String, |
| ConstraintType: cty.String, |
| ParsingMode: configs.VariableParseLiteral, |
| DeclRange: hcl.Range{ |
| Filename: "fake.tf", |
| Start: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| End: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| }, |
| }, |
| "declaredFromEnvVar": { |
| Name: "declaredFromEnvVar", |
| Type: cty.String, |
| ConstraintType: cty.String, |
| ParsingMode: configs.VariableParseLiteral, |
| DeclRange: hcl.Range{ |
| Filename: "fake.tf", |
| Start: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| End: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| }, |
| }, |
| "missing": { |
| Name: "missing", |
| Type: cty.String, |
| ConstraintType: cty.String, |
| Default: cty.StringVal("2"), |
| ParsingMode: configs.VariableParseLiteral, |
| DeclRange: hcl.Range{ |
| Filename: "fake.tf", |
| Start: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| End: hcl.Pos{Line: 2, Column: 1, Byte: 0}, |
| }, |
| }, |
| } |
| wantVals := make(map[string]string) |
| wantVals["declaredFromNamedFileBool"] = "true" |
| wantVals["declaredFromNamedFileNumber"] = "2" |
| wantVals["declaredFromNamedFileListString"] = `["2a", "2b"]` |
| wantVals["declaredFromNamedFileNull"] = "null" |
| wantVals["declaredFromNamedFileMapString"] = "{\n foo = \"bar\"\n}" |
| wantVals["declaredFromNamedMapComplex"] = "{\n foo = {\n qux = [true, false]\n }\n}" |
| wantVals["declaredFromCLIArg"] = `"3"` |
| wantVals["declaredFromEnvVar"] = `"4"` |
| |
| gotVals, diags := ParseCloudRunVariables(vv, decls) |
| if diff := cmp.Diff(wantVals, gotVals, cmp.Comparer(cty.Value.RawEquals)); diff != "" { |
| t.Errorf("wrong result\n%s", diff) |
| } |
| |
| if got, want := len(diags), 1; got != want { |
| t.Fatalf("expected 1 variable error: %v, got %v", diags.Err(), want) |
| } |
| |
| if got, want := diags[0].Description().Summary, "Value for undeclared variable"; got != want { |
| t.Errorf("wrong summary for diagnostic 0\ngot: %s\nwant: %s", got, want) |
| } |
| }) |
| } |
| |
| type testUnparsedVariableValue struct { |
| source terraform.ValueSourceType |
| value cty.Value |
| } |
| |
| func (v testUnparsedVariableValue) ParseVariableValue(mode configs.VariableParsingMode) (*terraform.InputValue, tfdiags.Diagnostics) { |
| return &terraform.InputValue{ |
| Value: v.value, |
| SourceType: v.source, |
| SourceRange: tfdiags.SourceRange{ |
| Filename: "fake.tfvars", |
| Start: tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0}, |
| End: tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0}, |
| }, |
| }, nil |
| } |