test destroy with provider depending on a resource
This commit is contained in:
parent
79d74c9ba0
commit
c0dbc95236
|
@ -11372,8 +11372,12 @@ output "myoutput" {
|
||||||
func TestContext2Apply_scaleInCBD(t *testing.T) {
|
func TestContext2Apply_scaleInCBD(t *testing.T) {
|
||||||
m := testModuleInline(t, map[string]string{
|
m := testModuleInline(t, map[string]string{
|
||||||
"main.tf": `
|
"main.tf": `
|
||||||
|
variable "ct" {
|
||||||
|
type = number
|
||||||
|
}
|
||||||
|
|
||||||
resource "test_instance" "a" {
|
resource "test_instance" "a" {
|
||||||
count = 1
|
count = var.ct
|
||||||
lifecycle {
|
lifecycle {
|
||||||
create_before_destroy = true
|
create_before_destroy = true
|
||||||
}
|
}
|
||||||
|
@ -11425,6 +11429,12 @@ output "out" {
|
||||||
|
|
||||||
p.DiffFn = testDiffFn
|
p.DiffFn = testDiffFn
|
||||||
ctx := testContext2(t, &ContextOpts{
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Variables: InputValues{
|
||||||
|
"ct": &InputValue{
|
||||||
|
Value: cty.NumberIntVal(1),
|
||||||
|
SourceType: ValueFromCaller,
|
||||||
|
},
|
||||||
|
},
|
||||||
Config: m,
|
Config: m,
|
||||||
Providers: map[addrs.Provider]providers.Factory{
|
Providers: map[addrs.Provider]providers.Factory{
|
||||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||||
|
@ -11447,6 +11457,188 @@ output "out" {
|
||||||
// check the output, as those can't cause an error planning the value
|
// check the output, as those can't cause an error planning the value
|
||||||
out := state.RootModule().OutputValues["out"].Value.AsString()
|
out := state.RootModule().OutputValues["out"].Value.AsString()
|
||||||
if out != "a0" {
|
if out != "a0" {
|
||||||
t.Fatalf(`expected output "new", got: %q`, out)
|
t.Fatalf(`expected output "a0", got: %q`, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
// reduce the count to 0
|
||||||
|
ctx = testContext2(t, &ContextOpts{
|
||||||
|
Variables: InputValues{
|
||||||
|
"ct": &InputValue{
|
||||||
|
Value: cty.NumberIntVal(0),
|
||||||
|
SourceType: ValueFromCaller,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Config: m,
|
||||||
|
Providers: map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
State: state,
|
||||||
|
})
|
||||||
|
|
||||||
|
_, diags = ctx.Plan()
|
||||||
|
if diags.HasErrors() {
|
||||||
|
t.Fatal(diags.ErrWithWarnings())
|
||||||
|
}
|
||||||
|
|
||||||
|
// if resource b isn't going to apply correctly, we will get an error about
|
||||||
|
// an invalid plan value
|
||||||
|
state, diags = ctx.Apply()
|
||||||
|
if diags.HasErrors() {
|
||||||
|
t.Fatal(diags.ErrWithWarnings())
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the output, as those can't cause an error planning the value
|
||||||
|
out = state.RootModule().OutputValues["out"].Value.AsString()
|
||||||
|
if out != "" {
|
||||||
|
t.Fatalf(`expected output "", got: %q`, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that we can destroy when a provider references a resource that will
|
||||||
|
// also be destroyed
|
||||||
|
func TestContext2Apply_destroyProviderReference(t *testing.T) {
|
||||||
|
m := testModuleInline(t, map[string]string{
|
||||||
|
"main.tf": `
|
||||||
|
provider "null" {
|
||||||
|
value = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
module "mod" {
|
||||||
|
source = "./mod"
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "test" {
|
||||||
|
value = module.mod.output
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "test_instance" "bar" {
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
"mod/main.tf": `
|
||||||
|
data "null_data_source" "foo" {
|
||||||
|
count = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
output "output" {
|
||||||
|
value = data.null_data_source.foo[0].output
|
||||||
|
}
|
||||||
|
`})
|
||||||
|
|
||||||
|
schemaFn := func(name string) *ProviderSchema {
|
||||||
|
return &ProviderSchema{
|
||||||
|
Provider: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"value": {
|
||||||
|
Type: cty.String,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ResourceTypes: map[string]*configschema.Block{
|
||||||
|
name + "_instance": {
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {
|
||||||
|
Type: cty.String,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"foo": {
|
||||||
|
Type: cty.String,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DataSources: map[string]*configschema.Block{
|
||||||
|
name + "_data_source": {
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {
|
||||||
|
Type: cty.String,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
Type: cty.String,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testP := new(MockProvider)
|
||||||
|
testP.ReadResourceFn = func(req providers.ReadResourceRequest) providers.ReadResourceResponse {
|
||||||
|
return providers.ReadResourceResponse{NewState: req.PriorState}
|
||||||
|
}
|
||||||
|
testP.GetSchemaReturn = schemaFn("test")
|
||||||
|
|
||||||
|
providerConfig := ""
|
||||||
|
testP.ConfigureNewFn = func(req providers.ConfigureRequest) (resp providers.ConfigureResponse) {
|
||||||
|
value := req.Config.GetAttr("value")
|
||||||
|
if value.IsKnown() && !value.IsNull() {
|
||||||
|
providerConfig = value.AsString()
|
||||||
|
} else {
|
||||||
|
providerConfig = ""
|
||||||
|
}
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
testP.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
|
||||||
|
if providerConfig != "valid" {
|
||||||
|
return nil, fmt.Errorf("provider config is %q", providerConfig)
|
||||||
|
}
|
||||||
|
return testApplyFn(info, s, d)
|
||||||
|
}
|
||||||
|
testP.DiffFn = testDiffFn
|
||||||
|
|
||||||
|
nullP := new(MockProvider)
|
||||||
|
nullP.ReadResourceFn = func(req providers.ReadResourceRequest) providers.ReadResourceResponse {
|
||||||
|
return providers.ReadResourceResponse{NewState: req.PriorState}
|
||||||
|
}
|
||||||
|
nullP.GetSchemaReturn = schemaFn("null")
|
||||||
|
|
||||||
|
nullP.ApplyFn = testApplyFn
|
||||||
|
nullP.DiffFn = testDiffFn
|
||||||
|
|
||||||
|
nullP.ReadDataSourceResponse = providers.ReadDataSourceResponse{
|
||||||
|
State: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("ID"),
|
||||||
|
"output": cty.StringVal("valid"),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
Providers: map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewDefaultProvider("test"): testProviderFuncFixed(testP),
|
||||||
|
addrs.NewDefaultProvider("null"): testProviderFuncFixed(nullP),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if _, diags := ctx.Plan(); diags.HasErrors() {
|
||||||
|
t.Fatalf("plan errors: %s", diags.Err())
|
||||||
|
}
|
||||||
|
|
||||||
|
state, diags := ctx.Apply()
|
||||||
|
if diags.HasErrors() {
|
||||||
|
t.Fatalf("apply errors: %s", diags.Err())
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
Providers: map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewDefaultProvider("test"): testProviderFuncFixed(testP),
|
||||||
|
addrs.NewDefaultProvider("null"): testProviderFuncFixed(nullP),
|
||||||
|
},
|
||||||
|
|
||||||
|
State: state,
|
||||||
|
Destroy: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
if _, diags := ctx.Plan(); diags.HasErrors() {
|
||||||
|
t.Fatalf("destroy plan errors: %s", diags.Err())
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, diags := ctx.Apply(); diags.HasErrors() {
|
||||||
|
t.Fatalf("destroy apply errors: %s", diags.Err())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue