4 "github.com/hashicorp/hcl2/hcl"
5 "github.com/hashicorp/hcl2/hcldec"
6 "github.com/zclconf/go-cty/cty"
7 "github.com/zclconf/go-cty/cty/convert"
9 "github.com/hashicorp/terraform/addrs"
10 "github.com/hashicorp/terraform/config"
11 "github.com/hashicorp/terraform/configs/configschema"
12 "github.com/hashicorp/terraform/lang"
13 "github.com/hashicorp/terraform/plans"
14 "github.com/hashicorp/terraform/providers"
15 "github.com/hashicorp/terraform/provisioners"
16 "github.com/hashicorp/terraform/states"
17 "github.com/hashicorp/terraform/tfdiags"
20 // MockEvalContext is a mock version of EvalContext that can be used
22 type MockEvalContext struct {
24 StoppedValue <-chan struct{}
33 InitProviderCalled bool
34 InitProviderType string
35 InitProviderAddr addrs.ProviderConfig
36 InitProviderProvider providers.Interface
37 InitProviderError error
40 ProviderAddr addrs.AbsProviderConfig
41 ProviderProvider providers.Interface
43 ProviderSchemaCalled bool
44 ProviderSchemaAddr addrs.AbsProviderConfig
45 ProviderSchemaSchema *ProviderSchema
47 CloseProviderCalled bool
48 CloseProviderAddr addrs.ProviderConfig
49 CloseProviderProvider providers.Interface
51 ProviderInputCalled bool
52 ProviderInputAddr addrs.ProviderConfig
53 ProviderInputValues map[string]cty.Value
55 SetProviderInputCalled bool
56 SetProviderInputAddr addrs.ProviderConfig
57 SetProviderInputValues map[string]cty.Value
59 ConfigureProviderCalled bool
60 ConfigureProviderAddr addrs.ProviderConfig
61 ConfigureProviderConfig cty.Value
62 ConfigureProviderDiags tfdiags.Diagnostics
64 InitProvisionerCalled bool
65 InitProvisionerName string
66 InitProvisionerProvisioner provisioners.Interface
67 InitProvisionerError error
69 ProvisionerCalled bool
70 ProvisionerName string
71 ProvisionerProvisioner provisioners.Interface
73 ProvisionerSchemaCalled bool
74 ProvisionerSchemaName string
75 ProvisionerSchemaSchema *configschema.Block
77 CloseProvisionerCalled bool
78 CloseProvisionerName string
79 CloseProvisionerProvisioner provisioners.Interface
81 EvaluateBlockCalled bool
82 EvaluateBlockBody hcl.Body
83 EvaluateBlockSchema *configschema.Block
84 EvaluateBlockSelf addrs.Referenceable
85 EvaluateBlockKeyData InstanceKeyEvalData
86 EvaluateBlockResultFunc func(
88 schema *configschema.Block,
89 self addrs.Referenceable,
90 keyData InstanceKeyEvalData,
91 ) (cty.Value, hcl.Body, tfdiags.Diagnostics) // overrides the other values below, if set
92 EvaluateBlockResult cty.Value
93 EvaluateBlockExpandedBody hcl.Body
94 EvaluateBlockDiags tfdiags.Diagnostics
96 EvaluateExprCalled bool
97 EvaluateExprExpr hcl.Expression
98 EvaluateExprWantType cty.Type
99 EvaluateExprSelf addrs.Referenceable
100 EvaluateExprResultFunc func(
103 self addrs.Referenceable,
104 ) (cty.Value, tfdiags.Diagnostics) // overrides the other values below, if set
105 EvaluateExprResult cty.Value
106 EvaluateExprDiags tfdiags.Diagnostics
108 EvaluationScopeCalled bool
109 EvaluationScopeSelf addrs.Referenceable
110 EvaluationScopeKeyData InstanceKeyEvalData
111 EvaluationScopeScope *lang.Scope
113 InterpolateCalled bool
114 InterpolateConfig *config.RawConfig
115 InterpolateResource *Resource
116 InterpolateConfigResult *ResourceConfig
117 InterpolateError error
119 InterpolateProviderCalled bool
120 InterpolateProviderConfig *config.ProviderConfig
121 InterpolateProviderResource *Resource
122 InterpolateProviderConfigResult *ResourceConfig
123 InterpolateProviderError error
126 PathPath addrs.ModuleInstance
128 SetModuleCallArgumentsCalled bool
129 SetModuleCallArgumentsModule addrs.ModuleCallInstance
130 SetModuleCallArgumentsValues map[string]cty.Value
133 ChangesChanges *plans.ChangesSync
136 StateState *states.SyncState
139 // MockEvalContext implements EvalContext
140 var _ EvalContext = (*MockEvalContext)(nil)
142 func (c *MockEvalContext) Stopped() <-chan struct{} {
143 c.StoppedCalled = true
144 return c.StoppedValue
147 func (c *MockEvalContext) Hook(fn func(Hook) (HookAction, error)) error {
149 if c.HookHook != nil {
150 if _, err := fn(c.HookHook); err != nil {
158 func (c *MockEvalContext) Input() UIInput {
163 func (c *MockEvalContext) InitProvider(t string, addr addrs.ProviderConfig) (providers.Interface, error) {
164 c.InitProviderCalled = true
165 c.InitProviderType = t
166 c.InitProviderAddr = addr
167 return c.InitProviderProvider, c.InitProviderError
170 func (c *MockEvalContext) Provider(addr addrs.AbsProviderConfig) providers.Interface {
171 c.ProviderCalled = true
172 c.ProviderAddr = addr
173 return c.ProviderProvider
176 func (c *MockEvalContext) ProviderSchema(addr addrs.AbsProviderConfig) *ProviderSchema {
177 c.ProviderSchemaCalled = true
178 c.ProviderSchemaAddr = addr
179 return c.ProviderSchemaSchema
182 func (c *MockEvalContext) CloseProvider(addr addrs.ProviderConfig) error {
183 c.CloseProviderCalled = true
184 c.CloseProviderAddr = addr
188 func (c *MockEvalContext) ConfigureProvider(addr addrs.ProviderConfig, cfg cty.Value) tfdiags.Diagnostics {
189 c.ConfigureProviderCalled = true
190 c.ConfigureProviderAddr = addr
191 c.ConfigureProviderConfig = cfg
192 return c.ConfigureProviderDiags
195 func (c *MockEvalContext) ProviderInput(addr addrs.ProviderConfig) map[string]cty.Value {
196 c.ProviderInputCalled = true
197 c.ProviderInputAddr = addr
198 return c.ProviderInputValues
201 func (c *MockEvalContext) SetProviderInput(addr addrs.ProviderConfig, vals map[string]cty.Value) {
202 c.SetProviderInputCalled = true
203 c.SetProviderInputAddr = addr
204 c.SetProviderInputValues = vals
207 func (c *MockEvalContext) InitProvisioner(n string) (provisioners.Interface, error) {
208 c.InitProvisionerCalled = true
209 c.InitProvisionerName = n
210 return c.InitProvisionerProvisioner, c.InitProvisionerError
213 func (c *MockEvalContext) Provisioner(n string) provisioners.Interface {
214 c.ProvisionerCalled = true
215 c.ProvisionerName = n
216 return c.ProvisionerProvisioner
219 func (c *MockEvalContext) ProvisionerSchema(n string) *configschema.Block {
220 c.ProvisionerSchemaCalled = true
221 c.ProvisionerSchemaName = n
222 return c.ProvisionerSchemaSchema
225 func (c *MockEvalContext) CloseProvisioner(n string) error {
226 c.CloseProvisionerCalled = true
227 c.CloseProvisionerName = n
231 func (c *MockEvalContext) EvaluateBlock(body hcl.Body, schema *configschema.Block, self addrs.Referenceable, keyData InstanceKeyEvalData) (cty.Value, hcl.Body, tfdiags.Diagnostics) {
232 c.EvaluateBlockCalled = true
233 c.EvaluateBlockBody = body
234 c.EvaluateBlockSchema = schema
235 c.EvaluateBlockSelf = self
236 c.EvaluateBlockKeyData = keyData
237 if c.EvaluateBlockResultFunc != nil {
238 return c.EvaluateBlockResultFunc(body, schema, self, keyData)
240 return c.EvaluateBlockResult, c.EvaluateBlockExpandedBody, c.EvaluateBlockDiags
243 func (c *MockEvalContext) EvaluateExpr(expr hcl.Expression, wantType cty.Type, self addrs.Referenceable) (cty.Value, tfdiags.Diagnostics) {
244 c.EvaluateExprCalled = true
245 c.EvaluateExprExpr = expr
246 c.EvaluateExprWantType = wantType
247 c.EvaluateExprSelf = self
248 if c.EvaluateExprResultFunc != nil {
249 return c.EvaluateExprResultFunc(expr, wantType, self)
251 return c.EvaluateExprResult, c.EvaluateExprDiags
254 // installSimpleEval is a helper to install a simple mock implementation of
255 // both EvaluateBlock and EvaluateExpr into the receiver.
257 // These default implementations will either evaluate the given input against
258 // the scope in field EvaluationScopeScope or, if it is nil, with no eval
259 // context at all so that only constant values may be used.
261 // This function overwrites any existing functions installed in fields
262 // EvaluateBlockResultFunc and EvaluateExprResultFunc.
263 func (c *MockEvalContext) installSimpleEval() {
264 c.EvaluateBlockResultFunc = func(body hcl.Body, schema *configschema.Block, self addrs.Referenceable, keyData InstanceKeyEvalData) (cty.Value, hcl.Body, tfdiags.Diagnostics) {
265 if scope := c.EvaluationScopeScope; scope != nil {
266 // Fully-functional codepath.
267 var diags tfdiags.Diagnostics
268 body, diags = scope.ExpandBlock(body, schema)
269 if diags.HasErrors() {
270 return cty.DynamicVal, body, diags
272 val, evalDiags := c.EvaluationScopeScope.EvalBlock(body, schema)
273 diags = diags.Append(evalDiags)
274 if evalDiags.HasErrors() {
275 return cty.DynamicVal, body, diags
277 return val, body, diags
280 // Fallback codepath supporting constant values only.
281 val, hclDiags := hcldec.Decode(body, schema.DecoderSpec(), nil)
282 return val, body, tfdiags.Diagnostics(nil).Append(hclDiags)
284 c.EvaluateExprResultFunc = func(expr hcl.Expression, wantType cty.Type, self addrs.Referenceable) (cty.Value, tfdiags.Diagnostics) {
285 if scope := c.EvaluationScopeScope; scope != nil {
286 // Fully-functional codepath.
287 return scope.EvalExpr(expr, wantType)
290 // Fallback codepath supporting constant values only.
291 var diags tfdiags.Diagnostics
292 val, hclDiags := expr.Value(nil)
293 diags = diags.Append(hclDiags)
294 if hclDiags.HasErrors() {
295 return cty.DynamicVal, diags
298 val, err = convert.Convert(val, wantType)
300 diags = diags.Append(err)
301 return cty.DynamicVal, diags
307 func (c *MockEvalContext) EvaluationScope(self addrs.Referenceable, keyData InstanceKeyEvalData) *lang.Scope {
308 c.EvaluationScopeCalled = true
309 c.EvaluationScopeSelf = self
310 c.EvaluationScopeKeyData = keyData
311 return c.EvaluationScopeScope
314 func (c *MockEvalContext) Interpolate(
315 config *config.RawConfig, resource *Resource) (*ResourceConfig, error) {
316 c.InterpolateCalled = true
317 c.InterpolateConfig = config
318 c.InterpolateResource = resource
319 return c.InterpolateConfigResult, c.InterpolateError
322 func (c *MockEvalContext) InterpolateProvider(
323 config *config.ProviderConfig, resource *Resource) (*ResourceConfig, error) {
324 c.InterpolateProviderCalled = true
325 c.InterpolateProviderConfig = config
326 c.InterpolateProviderResource = resource
327 return c.InterpolateProviderConfigResult, c.InterpolateError
330 func (c *MockEvalContext) Path() addrs.ModuleInstance {
335 func (c *MockEvalContext) SetModuleCallArguments(n addrs.ModuleCallInstance, values map[string]cty.Value) {
336 c.SetModuleCallArgumentsCalled = true
337 c.SetModuleCallArgumentsModule = n
338 c.SetModuleCallArgumentsValues = values
341 func (c *MockEvalContext) Changes() *plans.ChangesSync {
342 c.ChangesCalled = true
343 return c.ChangesChanges
346 func (c *MockEvalContext) State() *states.SyncState {