7 "github.com/zclconf/go-cty/cty"
8 "github.com/zclconf/go-cty/cty/convert"
10 "github.com/hashicorp/terraform/provisioners"
13 var _ provisioners.Interface = (*MockProvisioner)(nil)
15 // MockProvisioner implements provisioners.Interface but mocks out all the
16 // calls for testing purposes.
17 type MockProvisioner struct {
19 // Anything you want, in case you need to store extra data with the mock.
23 GetSchemaResponse provisioners.GetSchemaResponse
25 ValidateProvisionerConfigCalled bool
26 ValidateProvisionerConfigRequest provisioners.ValidateProvisionerConfigRequest
27 ValidateProvisionerConfigResponse provisioners.ValidateProvisionerConfigResponse
28 ValidateProvisionerConfigFn func(provisioners.ValidateProvisionerConfigRequest) provisioners.ValidateProvisionerConfigResponse
30 ProvisionResourceCalled bool
31 ProvisionResourceRequest provisioners.ProvisionResourceRequest
32 ProvisionResourceResponse provisioners.ProvisionResourceResponse
33 ProvisionResourceFn func(provisioners.ProvisionResourceRequest) provisioners.ProvisionResourceResponse
43 // Legacy callbacks: if these are set, we will shim incoming calls for
44 // new-style methods to these old-fashioned terraform.ResourceProvider
45 // mock callbacks, for the benefit of older tests that were written against
47 ApplyFn func(rs *InstanceState, c *ResourceConfig) error
50 func (p *MockProvisioner) GetSchema() provisioners.GetSchemaResponse {
54 p.GetSchemaCalled = true
58 // getSchema is the implementation of GetSchema, which can be called from other
59 // methods on MockProvisioner that may already be holding the lock.
60 func (p *MockProvisioner) getSchema() provisioners.GetSchemaResponse {
61 return p.GetSchemaResponse
64 func (p *MockProvisioner) ValidateProvisionerConfig(r provisioners.ValidateProvisionerConfigRequest) provisioners.ValidateProvisionerConfigResponse {
68 p.ValidateProvisionerConfigCalled = true
69 p.ValidateProvisionerConfigRequest = r
70 if p.ValidateProvisionerConfigFn != nil {
71 return p.ValidateProvisionerConfigFn(r)
73 return p.ValidateProvisionerConfigResponse
76 func (p *MockProvisioner) ProvisionResource(r provisioners.ProvisionResourceRequest) provisioners.ProvisionResourceResponse {
80 p.ProvisionResourceCalled = true
81 p.ProvisionResourceRequest = r
83 if !r.Config.IsKnown() {
84 panic(fmt.Sprintf("cannot provision with unknown value: %#v", r.Config))
87 schema := p.getSchema()
88 rc := NewResourceConfigShimmed(r.Config, schema.Provisioner)
89 connVal := r.Connection
90 connMap := map[string]string{}
92 if !connVal.IsNull() && connVal.IsKnown() {
93 for it := connVal.ElementIterator(); it.Next(); {
94 ak, av := it.Element()
97 if !av.IsKnown() || av.IsNull() {
101 av, _ = convert.Convert(av, cty.String)
102 connMap[name] = av.AsString()
106 // We no longer pass the full instance state to a provisioner, so we'll
107 // construct a partial one that should be good enough for what existing
109 is := &InstanceState{
110 Ephemeral: EphemeralState{
114 var resp provisioners.ProvisionResourceResponse
115 err := p.ApplyFn(is, rc)
117 resp.Diagnostics = resp.Diagnostics.Append(err)
121 if p.ProvisionResourceFn != nil {
122 fn := p.ProvisionResourceFn
127 return p.ProvisionResourceResponse
130 func (p *MockProvisioner) Stop() error {
131 // We intentionally don't lock in this one because the whole point of this
132 // method is to be called concurrently with another operation that can
133 // be cancelled. The provisioner itself is responsible for handling
134 // any concurrency concerns in this case.
141 return p.StopResponse
144 func (p *MockProvisioner) Close() error {
149 if p.CloseFn != nil {
153 return p.CloseResponse