/
context_eval_test.go
130 lines (114 loc) · 3 KB
/
context_eval_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package terraform
import (
"testing"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/providers"
"github.com/hashicorp/terraform/internal/states"
"github.com/zclconf/go-cty/cty"
)
func TestContextEval(t *testing.T) {
// This test doesn't check the "Want" value for impure funcs, so the value
// on those doesn't matter.
tests := []struct {
Input string
Want cty.Value
ImpureFunc bool
}{
{ // An impure function: allowed in the console, but the result is nondeterministic
`bcrypt("example")`,
cty.NilVal,
true,
},
{
`keys(var.map)`,
cty.ListVal([]cty.Value{
cty.StringVal("foo"),
cty.StringVal("baz"),
}),
true,
},
{
`local.result`,
cty.NumberIntVal(6),
false,
},
{
`module.child.result`,
cty.NumberIntVal(6),
false,
},
}
// This module has a little bit of everything (and if it is missing somehitng, add to it):
// resources, variables, locals, modules, output
m := testModule(t, "eval-context-basic")
p := testProvider("test")
ctx := testContext2(t, &ContextOpts{
Providers: map[addrs.Provider]providers.Factory{
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
},
})
scope, diags := ctx.Eval(m, states.NewState(), addrs.RootModuleInstance, &EvalOpts{
SetVariables: testInputValuesUnset(m.Module.Variables),
})
if diags.HasErrors() {
t.Fatalf("Eval errors: %s", diags.Err())
}
// Since we're testing 'eval' (used by terraform console), impure functions
// should be allowed by the scope.
if scope.PureOnly == true {
t.Fatal("wrong result: eval should allow impure funcs")
}
for _, test := range tests {
t.Run(test.Input, func(t *testing.T) {
// Parse the test input as an expression
expr, _ := hclsyntax.ParseExpression([]byte(test.Input), "<test-input>", hcl.Pos{Line: 1, Column: 1})
got, diags := scope.EvalExpr(expr, cty.DynamicPseudoType)
if diags.HasErrors() {
t.Fatalf("unexpected error: %s", diags.Err())
}
if !test.ImpureFunc {
if !got.RawEquals(test.Want) {
t.Fatalf("wrong result: want %#v, got %#v", test.Want, got)
}
}
})
}
}
// ensure that we can execute a console when outputs have preconditions
func TestContextEval_outputsWithPreconditions(t *testing.T) {
m := testModuleInline(t, map[string]string{
"main.tf": `
module "mod" {
source = "./mod"
input = "ok"
}
output "out" {
value = module.mod.out
}
`,
"./mod/main.tf": `
variable "input" {
type = string
}
output "out" {
value = var.input
precondition {
condition = var.input != ""
error_message = "error"
}
}
`,
})
p := simpleMockProvider()
ctx := testContext2(t, &ContextOpts{
Providers: map[addrs.Provider]providers.Factory{
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
},
})
_, diags := ctx.Eval(m, states.NewState(), addrs.RootModuleInstance, &EvalOpts{
SetVariables: testInputValuesUnset(m.Module.Variables),
})
assertNoErrors(t, diags)
}