2020-11-17 17:00:52 -06:00
package terraform
import (
"encoding/json"
"sync"
"github.com/zclconf/go-cty/cty"
ctyjson "github.com/zclconf/go-cty/cty/json"
"github.com/hashicorp/terraform/configs/hcl2shim"
"github.com/hashicorp/terraform/providers"
)
var _ providers . Interface = ( * MockProvider ) ( nil )
// MockProvider implements providers.Interface but mocks out all the
// calls for testing purposes.
type MockProvider struct {
sync . Mutex
// Anything you want, in case you need to store extra data with the mock.
Meta interface { }
GetSchemaCalled bool
2021-02-18 09:13:43 -06:00
GetSchemaReturn * ProviderSchema // This is using ProviderSchema directly rather than providers.GetProviderSchemaResponse for compatibility with old tests
2020-11-17 17:00:52 -06:00
2021-02-18 09:13:43 -06:00
ValidateProviderConfigCalled bool
ValidateProviderConfigResponse providers . ValidateProviderConfigResponse
ValidateProviderConfigRequest providers . ValidateProviderConfigRequest
ValidateProviderConfigFn func ( providers . ValidateProviderConfigRequest ) providers . ValidateProviderConfigResponse
2020-11-17 17:00:52 -06:00
2021-02-18 09:13:43 -06:00
ValidateResourceConfigCalled bool
ValidateResourceConfigTypeName string
ValidateResourceConfigResponse providers . ValidateResourceConfigResponse
ValidateResourceConfigRequest providers . ValidateResourceConfigRequest
ValidateResourceConfigFn func ( providers . ValidateResourceConfigRequest ) providers . ValidateResourceConfigResponse
2020-11-17 17:00:52 -06:00
2021-02-24 11:04:28 -06:00
ValidateDataResourceConfigCalled bool
ValidateDataResourceConfigTypeName string
ValidateDataResourceConfigResponse providers . ValidateDataResourceConfigResponse
ValidateDataResourceConfigRequest providers . ValidateDataResourceConfigRequest
ValidateDataResourceConfigFn func ( providers . ValidateDataResourceConfigRequest ) providers . ValidateDataResourceConfigResponse
2020-11-17 17:00:52 -06:00
UpgradeResourceStateCalled bool
UpgradeResourceStateTypeName string
UpgradeResourceStateResponse providers . UpgradeResourceStateResponse
UpgradeResourceStateRequest providers . UpgradeResourceStateRequest
UpgradeResourceStateFn func ( providers . UpgradeResourceStateRequest ) providers . UpgradeResourceStateResponse
2021-02-18 09:13:43 -06:00
ConfigureProviderCalled bool
ConfigureProviderResponse providers . ConfigureProviderResponse
ConfigureProviderRequest providers . ConfigureProviderRequest
ConfigureProviderFn func ( providers . ConfigureProviderRequest ) providers . ConfigureProviderResponse
2020-11-17 17:00:52 -06:00
StopCalled bool
StopFn func ( ) error
StopResponse error
ReadResourceCalled bool
ReadResourceResponse providers . ReadResourceResponse
ReadResourceRequest providers . ReadResourceRequest
ReadResourceFn func ( providers . ReadResourceRequest ) providers . ReadResourceResponse
PlanResourceChangeCalled bool
PlanResourceChangeResponse providers . PlanResourceChangeResponse
PlanResourceChangeRequest providers . PlanResourceChangeRequest
PlanResourceChangeFn func ( providers . PlanResourceChangeRequest ) providers . PlanResourceChangeResponse
ApplyResourceChangeCalled bool
ApplyResourceChangeResponse providers . ApplyResourceChangeResponse
ApplyResourceChangeRequest providers . ApplyResourceChangeRequest
ApplyResourceChangeFn func ( providers . ApplyResourceChangeRequest ) providers . ApplyResourceChangeResponse
ImportResourceStateCalled bool
ImportResourceStateResponse providers . ImportResourceStateResponse
ImportResourceStateRequest providers . ImportResourceStateRequest
ImportResourceStateFn func ( providers . ImportResourceStateRequest ) providers . ImportResourceStateResponse
// Legacy return type for existing tests, which will be shimmed into an
// ImportResourceStateResponse if set
ImportStateReturn [ ] * InstanceState
ReadDataSourceCalled bool
ReadDataSourceResponse providers . ReadDataSourceResponse
ReadDataSourceRequest providers . ReadDataSourceRequest
ReadDataSourceFn func ( providers . ReadDataSourceRequest ) providers . ReadDataSourceResponse
CloseCalled bool
CloseError error
}
2021-02-18 09:13:43 -06:00
func ( p * MockProvider ) GetProviderSchema ( ) providers . GetProviderSchemaResponse {
2020-11-17 17:00:52 -06:00
p . Lock ( )
defer p . Unlock ( )
p . GetSchemaCalled = true
return p . getSchema ( )
}
2021-02-18 09:13:43 -06:00
func ( p * MockProvider ) getSchema ( ) providers . GetProviderSchemaResponse {
2020-11-17 17:00:52 -06:00
// This version of getSchema doesn't do any locking, so it's suitable to
// call from other methods of this mock as long as they are already
// holding the lock.
2021-02-18 09:13:43 -06:00
ret := providers . GetProviderSchemaResponse {
2020-11-17 17:00:52 -06:00
Provider : providers . Schema { } ,
DataSources : map [ string ] providers . Schema { } ,
ResourceTypes : map [ string ] providers . Schema { } ,
}
if p . GetSchemaReturn != nil {
ret . Provider . Block = p . GetSchemaReturn . Provider
ret . ProviderMeta . Block = p . GetSchemaReturn . ProviderMeta
for n , s := range p . GetSchemaReturn . DataSources {
ret . DataSources [ n ] = providers . Schema {
Block : s ,
}
}
for n , s := range p . GetSchemaReturn . ResourceTypes {
ret . ResourceTypes [ n ] = providers . Schema {
Version : int64 ( p . GetSchemaReturn . ResourceTypeSchemaVersions [ n ] ) ,
Block : s ,
}
}
}
return ret
}
2021-02-18 09:13:43 -06:00
func ( p * MockProvider ) ValidateProviderConfig ( r providers . ValidateProviderConfigRequest ) providers . ValidateProviderConfigResponse {
2020-11-17 17:00:52 -06:00
p . Lock ( )
defer p . Unlock ( )
2021-02-18 09:13:43 -06:00
p . ValidateProviderConfigCalled = true
p . ValidateProviderConfigRequest = r
if p . ValidateProviderConfigFn != nil {
return p . ValidateProviderConfigFn ( r )
2020-11-17 17:00:52 -06:00
}
2021-02-18 09:13:43 -06:00
return p . ValidateProviderConfigResponse
2020-11-17 17:00:52 -06:00
}
2021-02-18 09:13:43 -06:00
func ( p * MockProvider ) ValidateResourceConfig ( r providers . ValidateResourceConfigRequest ) providers . ValidateResourceConfigResponse {
2020-11-17 17:00:52 -06:00
p . Lock ( )
defer p . Unlock ( )
2021-02-18 09:13:43 -06:00
p . ValidateResourceConfigCalled = true
p . ValidateResourceConfigRequest = r
2020-11-17 17:00:52 -06:00
2021-02-18 09:13:43 -06:00
if p . ValidateResourceConfigFn != nil {
return p . ValidateResourceConfigFn ( r )
2020-11-17 17:00:52 -06:00
}
2021-02-18 09:13:43 -06:00
return p . ValidateResourceConfigResponse
2020-11-17 17:00:52 -06:00
}
2021-02-24 11:04:28 -06:00
func ( p * MockProvider ) ValidateDataResourceConfig ( r providers . ValidateDataResourceConfigRequest ) providers . ValidateDataResourceConfigResponse {
2020-11-17 17:00:52 -06:00
p . Lock ( )
defer p . Unlock ( )
2021-02-24 11:04:28 -06:00
p . ValidateDataResourceConfigCalled = true
p . ValidateDataResourceConfigRequest = r
2020-11-17 17:00:52 -06:00
2021-02-24 11:04:28 -06:00
if p . ValidateDataResourceConfigFn != nil {
return p . ValidateDataResourceConfigFn ( r )
2020-11-17 17:00:52 -06:00
}
2021-02-24 11:04:28 -06:00
return p . ValidateDataResourceConfigResponse
2020-11-17 17:00:52 -06:00
}
func ( p * MockProvider ) UpgradeResourceState ( r providers . UpgradeResourceStateRequest ) providers . UpgradeResourceStateResponse {
p . Lock ( )
defer p . Unlock ( )
schemas := p . getSchema ( )
schema := schemas . ResourceTypes [ r . TypeName ]
schemaType := schema . Block . ImpliedType ( )
p . UpgradeResourceStateCalled = true
p . UpgradeResourceStateRequest = r
if p . UpgradeResourceStateFn != nil {
return p . UpgradeResourceStateFn ( r )
}
resp := p . UpgradeResourceStateResponse
if resp . UpgradedState == cty . NilVal {
switch {
case r . RawStateFlatmap != nil :
v , err := hcl2shim . HCL2ValueFromFlatmap ( r . RawStateFlatmap , schemaType )
if err != nil {
resp . Diagnostics = resp . Diagnostics . Append ( err )
return resp
}
resp . UpgradedState = v
case len ( r . RawStateJSON ) > 0 :
v , err := ctyjson . Unmarshal ( r . RawStateJSON , schemaType )
if err != nil {
resp . Diagnostics = resp . Diagnostics . Append ( err )
return resp
}
resp . UpgradedState = v
}
}
return resp
}
2021-02-18 09:13:43 -06:00
func ( p * MockProvider ) ConfigureProvider ( r providers . ConfigureProviderRequest ) providers . ConfigureProviderResponse {
2020-11-17 17:00:52 -06:00
p . Lock ( )
defer p . Unlock ( )
2021-02-18 09:13:43 -06:00
p . ConfigureProviderCalled = true
p . ConfigureProviderRequest = r
2020-11-17 17:00:52 -06:00
2021-02-18 09:13:43 -06:00
if p . ConfigureProviderFn != nil {
return p . ConfigureProviderFn ( r )
2020-11-17 17:00:52 -06:00
}
2021-02-18 09:13:43 -06:00
return p . ConfigureProviderResponse
2020-11-17 17:00:52 -06:00
}
func ( p * MockProvider ) Stop ( ) error {
// We intentionally don't lock in this one because the whole point of this
// method is to be called concurrently with another operation that can
// be cancelled. The provider itself is responsible for handling
// any concurrency concerns in this case.
p . StopCalled = true
if p . StopFn != nil {
return p . StopFn ( )
}
return p . StopResponse
}
func ( p * MockProvider ) ReadResource ( r providers . ReadResourceRequest ) providers . ReadResourceResponse {
p . Lock ( )
defer p . Unlock ( )
p . ReadResourceCalled = true
p . ReadResourceRequest = r
if p . ReadResourceFn != nil {
return p . ReadResourceFn ( r )
}
resp := p . ReadResourceResponse
if resp . NewState != cty . NilVal {
// make sure the NewState fits the schema
// This isn't always the case for the existing tests
newState , err := p . GetSchemaReturn . ResourceTypes [ r . TypeName ] . CoerceValue ( resp . NewState )
if err != nil {
panic ( err )
}
resp . NewState = newState
return resp
}
// just return the same state we received
resp . NewState = r . PriorState
return resp
}
func ( p * MockProvider ) PlanResourceChange ( r providers . PlanResourceChangeRequest ) providers . PlanResourceChangeResponse {
p . Lock ( )
defer p . Unlock ( )
p . PlanResourceChangeCalled = true
p . PlanResourceChangeRequest = r
if p . PlanResourceChangeFn != nil {
return p . PlanResourceChangeFn ( r )
}
return p . PlanResourceChangeResponse
}
func ( p * MockProvider ) ApplyResourceChange ( r providers . ApplyResourceChangeRequest ) providers . ApplyResourceChangeResponse {
p . Lock ( )
p . ApplyResourceChangeCalled = true
p . ApplyResourceChangeRequest = r
p . Unlock ( )
if p . ApplyResourceChangeFn != nil {
return p . ApplyResourceChangeFn ( r )
}
return p . ApplyResourceChangeResponse
}
func ( p * MockProvider ) ImportResourceState ( r providers . ImportResourceStateRequest ) providers . ImportResourceStateResponse {
p . Lock ( )
defer p . Unlock ( )
if p . ImportStateReturn != nil {
for _ , is := range p . ImportStateReturn {
if is . Attributes == nil {
is . Attributes = make ( map [ string ] string )
}
is . Attributes [ "id" ] = is . ID
typeName := is . Ephemeral . Type
// Use the requested type if the resource has no type of it's own.
// We still return the empty type, which will error, but this prevents a panic.
if typeName == "" {
typeName = r . TypeName
}
schema := p . GetSchemaReturn . ResourceTypes [ typeName ]
if schema == nil {
panic ( "no schema found for " + typeName )
}
private , err := json . Marshal ( is . Meta )
if err != nil {
panic ( err )
}
state , err := hcl2shim . HCL2ValueFromFlatmap ( is . Attributes , schema . ImpliedType ( ) )
if err != nil {
panic ( err )
}
state , err = schema . CoerceValue ( state )
if err != nil {
panic ( err )
}
p . ImportResourceStateResponse . ImportedResources = append (
p . ImportResourceStateResponse . ImportedResources ,
providers . ImportedResource {
TypeName : is . Ephemeral . Type ,
State : state ,
Private : private ,
} )
}
}
p . ImportResourceStateCalled = true
p . ImportResourceStateRequest = r
if p . ImportResourceStateFn != nil {
return p . ImportResourceStateFn ( r )
}
return p . ImportResourceStateResponse
}
func ( p * MockProvider ) ReadDataSource ( r providers . ReadDataSourceRequest ) providers . ReadDataSourceResponse {
p . Lock ( )
defer p . Unlock ( )
p . ReadDataSourceCalled = true
p . ReadDataSourceRequest = r
if p . ReadDataSourceFn != nil {
return p . ReadDataSourceFn ( r )
}
return p . ReadDataSourceResponse
}
func ( p * MockProvider ) Close ( ) error {
p . CloseCalled = true
return p . CloseError
}