github.com/kanishk98/terraform@v1.3.0-dev.0.20220917174235-661ca8088a6a/internal/terraform/eval_context_mock.go (about) 1 package terraform 2 3 import ( 4 "github.com/hashicorp/hcl/v2" 5 "github.com/hashicorp/hcl/v2/hcldec" 6 "github.com/hashicorp/terraform/internal/addrs" 7 "github.com/hashicorp/terraform/internal/checks" 8 "github.com/hashicorp/terraform/internal/configs/configschema" 9 "github.com/hashicorp/terraform/internal/instances" 10 "github.com/hashicorp/terraform/internal/lang" 11 "github.com/hashicorp/terraform/internal/plans" 12 "github.com/hashicorp/terraform/internal/providers" 13 "github.com/hashicorp/terraform/internal/provisioners" 14 "github.com/hashicorp/terraform/internal/refactoring" 15 "github.com/hashicorp/terraform/internal/states" 16 "github.com/hashicorp/terraform/internal/tfdiags" 17 "github.com/zclconf/go-cty/cty" 18 "github.com/zclconf/go-cty/cty/convert" 19 ) 20 21 // MockEvalContext is a mock version of EvalContext that can be used 22 // for tests. 23 type MockEvalContext struct { 24 StoppedCalled bool 25 StoppedValue <-chan struct{} 26 27 HookCalled bool 28 HookHook Hook 29 HookError error 30 31 InputCalled bool 32 InputInput UIInput 33 34 InitProviderCalled bool 35 InitProviderType string 36 InitProviderAddr addrs.AbsProviderConfig 37 InitProviderProvider providers.Interface 38 InitProviderError error 39 40 ProviderCalled bool 41 ProviderAddr addrs.AbsProviderConfig 42 ProviderProvider providers.Interface 43 44 ProviderSchemaCalled bool 45 ProviderSchemaAddr addrs.AbsProviderConfig 46 ProviderSchemaSchema *ProviderSchema 47 ProviderSchemaError error 48 49 CloseProviderCalled bool 50 CloseProviderAddr addrs.AbsProviderConfig 51 CloseProviderProvider providers.Interface 52 53 ProviderInputCalled bool 54 ProviderInputAddr addrs.AbsProviderConfig 55 ProviderInputValues map[string]cty.Value 56 57 SetProviderInputCalled bool 58 SetProviderInputAddr addrs.AbsProviderConfig 59 SetProviderInputValues map[string]cty.Value 60 61 ConfigureProviderFn func( 62 addr addrs.AbsProviderConfig, 63 cfg cty.Value) tfdiags.Diagnostics // overrides the other values below, if set 64 ConfigureProviderCalled bool 65 ConfigureProviderAddr addrs.AbsProviderConfig 66 ConfigureProviderConfig cty.Value 67 ConfigureProviderDiags tfdiags.Diagnostics 68 69 ProvisionerCalled bool 70 ProvisionerName string 71 ProvisionerProvisioner provisioners.Interface 72 73 ProvisionerSchemaCalled bool 74 ProvisionerSchemaName string 75 ProvisionerSchemaSchema *configschema.Block 76 ProvisionerSchemaError error 77 78 CloseProvisionersCalled bool 79 80 EvaluateBlockCalled bool 81 EvaluateBlockBody hcl.Body 82 EvaluateBlockSchema *configschema.Block 83 EvaluateBlockSelf addrs.Referenceable 84 EvaluateBlockKeyData InstanceKeyEvalData 85 EvaluateBlockResultFunc func( 86 body hcl.Body, 87 schema *configschema.Block, 88 self addrs.Referenceable, 89 keyData InstanceKeyEvalData, 90 ) (cty.Value, hcl.Body, tfdiags.Diagnostics) // overrides the other values below, if set 91 EvaluateBlockResult cty.Value 92 EvaluateBlockExpandedBody hcl.Body 93 EvaluateBlockDiags tfdiags.Diagnostics 94 95 EvaluateExprCalled bool 96 EvaluateExprExpr hcl.Expression 97 EvaluateExprWantType cty.Type 98 EvaluateExprSelf addrs.Referenceable 99 EvaluateExprResultFunc func( 100 expr hcl.Expression, 101 wantType cty.Type, 102 self addrs.Referenceable, 103 ) (cty.Value, tfdiags.Diagnostics) // overrides the other values below, if set 104 EvaluateExprResult cty.Value 105 EvaluateExprDiags tfdiags.Diagnostics 106 107 EvaluationScopeCalled bool 108 EvaluationScopeSelf addrs.Referenceable 109 EvaluationScopeKeyData InstanceKeyEvalData 110 EvaluationScopeScope *lang.Scope 111 112 PathCalled bool 113 PathPath addrs.ModuleInstance 114 115 SetRootModuleArgumentCalled bool 116 SetRootModuleArgumentAddr addrs.InputVariable 117 SetRootModuleArgumentValue cty.Value 118 SetRootModuleArgumentFunc func(addr addrs.InputVariable, v cty.Value) 119 120 SetModuleCallArgumentCalled bool 121 SetModuleCallArgumentModuleCall addrs.ModuleCallInstance 122 SetModuleCallArgumentVariable addrs.InputVariable 123 SetModuleCallArgumentValue cty.Value 124 SetModuleCallArgumentFunc func(callAddr addrs.ModuleCallInstance, varAddr addrs.InputVariable, v cty.Value) 125 126 GetVariableValueCalled bool 127 GetVariableValueAddr addrs.AbsInputVariableInstance 128 GetVariableValueValue cty.Value 129 GetVariableValueFunc func(addr addrs.AbsInputVariableInstance) cty.Value // supersedes GetVariableValueValue 130 131 ChangesCalled bool 132 ChangesChanges *plans.ChangesSync 133 134 StateCalled bool 135 StateState *states.SyncState 136 137 ChecksCalled bool 138 ChecksState *checks.State 139 140 RefreshStateCalled bool 141 RefreshStateState *states.SyncState 142 143 PrevRunStateCalled bool 144 PrevRunStateState *states.SyncState 145 146 MoveResultsCalled bool 147 MoveResultsResults refactoring.MoveResults 148 149 InstanceExpanderCalled bool 150 InstanceExpanderExpander *instances.Expander 151 } 152 153 // MockEvalContext implements EvalContext 154 var _ EvalContext = (*MockEvalContext)(nil) 155 156 func (c *MockEvalContext) Stopped() <-chan struct{} { 157 c.StoppedCalled = true 158 return c.StoppedValue 159 } 160 161 func (c *MockEvalContext) Hook(fn func(Hook) (HookAction, error)) error { 162 c.HookCalled = true 163 if c.HookHook != nil { 164 if _, err := fn(c.HookHook); err != nil { 165 return err 166 } 167 } 168 169 return c.HookError 170 } 171 172 func (c *MockEvalContext) Input() UIInput { 173 c.InputCalled = true 174 return c.InputInput 175 } 176 177 func (c *MockEvalContext) InitProvider(addr addrs.AbsProviderConfig) (providers.Interface, error) { 178 c.InitProviderCalled = true 179 c.InitProviderType = addr.String() 180 c.InitProviderAddr = addr 181 return c.InitProviderProvider, c.InitProviderError 182 } 183 184 func (c *MockEvalContext) Provider(addr addrs.AbsProviderConfig) providers.Interface { 185 c.ProviderCalled = true 186 c.ProviderAddr = addr 187 return c.ProviderProvider 188 } 189 190 func (c *MockEvalContext) ProviderSchema(addr addrs.AbsProviderConfig) (*ProviderSchema, error) { 191 c.ProviderSchemaCalled = true 192 c.ProviderSchemaAddr = addr 193 return c.ProviderSchemaSchema, c.ProviderSchemaError 194 } 195 196 func (c *MockEvalContext) CloseProvider(addr addrs.AbsProviderConfig) error { 197 c.CloseProviderCalled = true 198 c.CloseProviderAddr = addr 199 return nil 200 } 201 202 func (c *MockEvalContext) ConfigureProvider(addr addrs.AbsProviderConfig, cfg cty.Value) tfdiags.Diagnostics { 203 204 c.ConfigureProviderCalled = true 205 c.ConfigureProviderAddr = addr 206 c.ConfigureProviderConfig = cfg 207 if c.ConfigureProviderFn != nil { 208 return c.ConfigureProviderFn(addr, cfg) 209 } 210 return c.ConfigureProviderDiags 211 } 212 213 func (c *MockEvalContext) ProviderInput(addr addrs.AbsProviderConfig) map[string]cty.Value { 214 c.ProviderInputCalled = true 215 c.ProviderInputAddr = addr 216 return c.ProviderInputValues 217 } 218 219 func (c *MockEvalContext) SetProviderInput(addr addrs.AbsProviderConfig, vals map[string]cty.Value) { 220 c.SetProviderInputCalled = true 221 c.SetProviderInputAddr = addr 222 c.SetProviderInputValues = vals 223 } 224 225 func (c *MockEvalContext) Provisioner(n string) (provisioners.Interface, error) { 226 c.ProvisionerCalled = true 227 c.ProvisionerName = n 228 return c.ProvisionerProvisioner, nil 229 } 230 231 func (c *MockEvalContext) ProvisionerSchema(n string) (*configschema.Block, error) { 232 c.ProvisionerSchemaCalled = true 233 c.ProvisionerSchemaName = n 234 return c.ProvisionerSchemaSchema, c.ProvisionerSchemaError 235 } 236 237 func (c *MockEvalContext) CloseProvisioners() error { 238 c.CloseProvisionersCalled = true 239 return nil 240 } 241 242 func (c *MockEvalContext) EvaluateBlock(body hcl.Body, schema *configschema.Block, self addrs.Referenceable, keyData InstanceKeyEvalData) (cty.Value, hcl.Body, tfdiags.Diagnostics) { 243 c.EvaluateBlockCalled = true 244 c.EvaluateBlockBody = body 245 c.EvaluateBlockSchema = schema 246 c.EvaluateBlockSelf = self 247 c.EvaluateBlockKeyData = keyData 248 if c.EvaluateBlockResultFunc != nil { 249 return c.EvaluateBlockResultFunc(body, schema, self, keyData) 250 } 251 return c.EvaluateBlockResult, c.EvaluateBlockExpandedBody, c.EvaluateBlockDiags 252 } 253 254 func (c *MockEvalContext) EvaluateExpr(expr hcl.Expression, wantType cty.Type, self addrs.Referenceable) (cty.Value, tfdiags.Diagnostics) { 255 c.EvaluateExprCalled = true 256 c.EvaluateExprExpr = expr 257 c.EvaluateExprWantType = wantType 258 c.EvaluateExprSelf = self 259 if c.EvaluateExprResultFunc != nil { 260 return c.EvaluateExprResultFunc(expr, wantType, self) 261 } 262 return c.EvaluateExprResult, c.EvaluateExprDiags 263 } 264 265 func (c *MockEvalContext) EvaluateReplaceTriggeredBy(hcl.Expression, instances.RepetitionData) (*addrs.Reference, bool, tfdiags.Diagnostics) { 266 return nil, false, nil 267 } 268 269 // installSimpleEval is a helper to install a simple mock implementation of 270 // both EvaluateBlock and EvaluateExpr into the receiver. 271 // 272 // These default implementations will either evaluate the given input against 273 // the scope in field EvaluationScopeScope or, if it is nil, with no eval 274 // context at all so that only constant values may be used. 275 // 276 // This function overwrites any existing functions installed in fields 277 // EvaluateBlockResultFunc and EvaluateExprResultFunc. 278 func (c *MockEvalContext) installSimpleEval() { 279 c.EvaluateBlockResultFunc = func(body hcl.Body, schema *configschema.Block, self addrs.Referenceable, keyData InstanceKeyEvalData) (cty.Value, hcl.Body, tfdiags.Diagnostics) { 280 if scope := c.EvaluationScopeScope; scope != nil { 281 // Fully-functional codepath. 282 var diags tfdiags.Diagnostics 283 body, diags = scope.ExpandBlock(body, schema) 284 if diags.HasErrors() { 285 return cty.DynamicVal, body, diags 286 } 287 val, evalDiags := c.EvaluationScopeScope.EvalBlock(body, schema) 288 diags = diags.Append(evalDiags) 289 if evalDiags.HasErrors() { 290 return cty.DynamicVal, body, diags 291 } 292 return val, body, diags 293 } 294 295 // Fallback codepath supporting constant values only. 296 val, hclDiags := hcldec.Decode(body, schema.DecoderSpec(), nil) 297 return val, body, tfdiags.Diagnostics(nil).Append(hclDiags) 298 } 299 c.EvaluateExprResultFunc = func(expr hcl.Expression, wantType cty.Type, self addrs.Referenceable) (cty.Value, tfdiags.Diagnostics) { 300 if scope := c.EvaluationScopeScope; scope != nil { 301 // Fully-functional codepath. 302 return scope.EvalExpr(expr, wantType) 303 } 304 305 // Fallback codepath supporting constant values only. 306 var diags tfdiags.Diagnostics 307 val, hclDiags := expr.Value(nil) 308 diags = diags.Append(hclDiags) 309 if hclDiags.HasErrors() { 310 return cty.DynamicVal, diags 311 } 312 var err error 313 val, err = convert.Convert(val, wantType) 314 if err != nil { 315 diags = diags.Append(err) 316 return cty.DynamicVal, diags 317 } 318 return val, diags 319 } 320 } 321 322 func (c *MockEvalContext) EvaluationScope(self addrs.Referenceable, keyData InstanceKeyEvalData) *lang.Scope { 323 c.EvaluationScopeCalled = true 324 c.EvaluationScopeSelf = self 325 c.EvaluationScopeKeyData = keyData 326 return c.EvaluationScopeScope 327 } 328 329 func (c *MockEvalContext) WithPath(path addrs.ModuleInstance) EvalContext { 330 newC := *c 331 newC.PathPath = path 332 return &newC 333 } 334 335 func (c *MockEvalContext) Path() addrs.ModuleInstance { 336 c.PathCalled = true 337 return c.PathPath 338 } 339 340 func (c *MockEvalContext) SetRootModuleArgument(addr addrs.InputVariable, v cty.Value) { 341 c.SetRootModuleArgumentCalled = true 342 c.SetRootModuleArgumentAddr = addr 343 c.SetRootModuleArgumentValue = v 344 if c.SetRootModuleArgumentFunc != nil { 345 c.SetRootModuleArgumentFunc(addr, v) 346 } 347 } 348 349 func (c *MockEvalContext) SetModuleCallArgument(callAddr addrs.ModuleCallInstance, varAddr addrs.InputVariable, v cty.Value) { 350 c.SetModuleCallArgumentCalled = true 351 c.SetModuleCallArgumentModuleCall = callAddr 352 c.SetModuleCallArgumentVariable = varAddr 353 c.SetModuleCallArgumentValue = v 354 if c.SetModuleCallArgumentFunc != nil { 355 c.SetModuleCallArgumentFunc(callAddr, varAddr, v) 356 } 357 } 358 359 func (c *MockEvalContext) GetVariableValue(addr addrs.AbsInputVariableInstance) cty.Value { 360 c.GetVariableValueCalled = true 361 c.GetVariableValueAddr = addr 362 if c.GetVariableValueFunc != nil { 363 return c.GetVariableValueFunc(addr) 364 } 365 return c.GetVariableValueValue 366 } 367 368 func (c *MockEvalContext) Changes() *plans.ChangesSync { 369 c.ChangesCalled = true 370 return c.ChangesChanges 371 } 372 373 func (c *MockEvalContext) State() *states.SyncState { 374 c.StateCalled = true 375 return c.StateState 376 } 377 378 func (c *MockEvalContext) Checks() *checks.State { 379 c.ChecksCalled = true 380 return c.ChecksState 381 } 382 383 func (c *MockEvalContext) RefreshState() *states.SyncState { 384 c.RefreshStateCalled = true 385 return c.RefreshStateState 386 } 387 388 func (c *MockEvalContext) PrevRunState() *states.SyncState { 389 c.PrevRunStateCalled = true 390 return c.PrevRunStateState 391 } 392 393 func (c *MockEvalContext) MoveResults() refactoring.MoveResults { 394 c.MoveResultsCalled = true 395 return c.MoveResultsResults 396 } 397 398 func (c *MockEvalContext) InstanceExpander() *instances.Expander { 399 c.InstanceExpanderCalled = true 400 return c.InstanceExpanderExpander 401 }