2014-10-01 06:49:24 +02:00
|
|
|
package command
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
2018-05-23 04:33:45 +02:00
|
|
|
"github.com/hashicorp/terraform/config/configschema"
|
2014-10-01 06:49:24 +02:00
|
|
|
"github.com/hashicorp/terraform/terraform"
|
|
|
|
"github.com/mitchellh/cli"
|
2018-05-23 04:33:45 +02:00
|
|
|
"github.com/zclconf/go-cty/cty"
|
2014-10-01 06:49:24 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestApply_destroy(t *testing.T) {
|
|
|
|
originalState := &terraform.State{
|
|
|
|
Modules: []*terraform.ModuleState{
|
|
|
|
&terraform.ModuleState{
|
|
|
|
Path: []string{"root"},
|
|
|
|
Resources: map[string]*terraform.ResourceState{
|
|
|
|
"test_instance.foo": &terraform.ResourceState{
|
|
|
|
Type: "test_instance",
|
|
|
|
Primary: &terraform.InstanceState{
|
|
|
|
ID: "bar",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
statePath := testStateFile(t, originalState)
|
|
|
|
|
|
|
|
p := testProvider()
|
2018-05-23 04:33:45 +02:00
|
|
|
p.GetSchemaReturn = applyFixtureSchema()
|
|
|
|
|
2014-10-01 06:49:24 +02:00
|
|
|
ui := new(cli.MockUi)
|
|
|
|
c := &ApplyCommand{
|
|
|
|
Destroy: true,
|
|
|
|
Meta: Meta{
|
2017-04-14 03:05:58 +02:00
|
|
|
testingOverrides: metaOverridesForProvider(p),
|
|
|
|
Ui: ui,
|
2014-10-01 06:49:24 +02:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
// Run the apply command pointing to our existing state
|
|
|
|
args := []string{
|
2018-02-01 01:14:42 +01:00
|
|
|
"-auto-approve",
|
2014-10-01 06:49:24 +02:00
|
|
|
"-state", statePath,
|
|
|
|
testFixturePath("apply"),
|
|
|
|
}
|
|
|
|
if code := c.Run(args); code != 0 {
|
2017-02-15 17:53:19 +01:00
|
|
|
t.Log(ui.OutputWriter.String())
|
2014-10-01 06:49:24 +02:00
|
|
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify a new state exists
|
|
|
|
if _, err := os.Stat(statePath); err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
f, err := os.Open(statePath)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
state, err := terraform.ReadState(f)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
if state == nil {
|
|
|
|
t.Fatal("state should not be nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
actualStr := strings.TrimSpace(state.String())
|
|
|
|
expectedStr := strings.TrimSpace(testApplyDestroyStr)
|
|
|
|
if actualStr != expectedStr {
|
|
|
|
t.Fatalf("bad:\n\n%s\n\n%s", actualStr, expectedStr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Should have a backup file
|
2015-09-11 20:56:20 +02:00
|
|
|
f, err = os.Open(statePath + DefaultBackupExtension)
|
2014-10-01 06:49:24 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
backupState, err := terraform.ReadState(f)
|
|
|
|
f.Close()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
actualStr = strings.TrimSpace(backupState.String())
|
|
|
|
expectedStr = strings.TrimSpace(originalState.String())
|
|
|
|
if actualStr != expectedStr {
|
|
|
|
t.Fatalf("bad:\n\n%s\n\n%s", actualStr, expectedStr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-03 22:06:01 +01:00
|
|
|
func TestApply_destroyLockedState(t *testing.T) {
|
|
|
|
originalState := &terraform.State{
|
|
|
|
Modules: []*terraform.ModuleState{
|
|
|
|
&terraform.ModuleState{
|
|
|
|
Path: []string{"root"},
|
|
|
|
Resources: map[string]*terraform.ResourceState{
|
|
|
|
"test_instance.foo": &terraform.ResourceState{
|
|
|
|
Type: "test_instance",
|
|
|
|
Primary: &terraform.InstanceState{
|
|
|
|
ID: "bar",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
statePath := testStateFile(t, originalState)
|
|
|
|
|
2017-02-06 19:26:03 +01:00
|
|
|
unlock, err := testLockState("./testdata", statePath)
|
2017-02-03 22:06:01 +01:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer unlock()
|
|
|
|
|
|
|
|
p := testProvider()
|
|
|
|
ui := new(cli.MockUi)
|
|
|
|
c := &ApplyCommand{
|
|
|
|
Destroy: true,
|
|
|
|
Meta: Meta{
|
2017-04-14 03:05:58 +02:00
|
|
|
testingOverrides: metaOverridesForProvider(p),
|
|
|
|
Ui: ui,
|
2017-02-03 22:06:01 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
// Run the apply command pointing to our existing state
|
|
|
|
args := []string{
|
2018-02-01 01:14:42 +01:00
|
|
|
"-auto-approve",
|
2017-02-03 22:06:01 +01:00
|
|
|
"-state", statePath,
|
|
|
|
testFixturePath("apply"),
|
|
|
|
}
|
|
|
|
|
|
|
|
if code := c.Run(args); code == 0 {
|
|
|
|
t.Fatal("expected error")
|
|
|
|
}
|
|
|
|
|
|
|
|
output := ui.ErrorWriter.String()
|
2017-02-15 20:01:18 +01:00
|
|
|
if !strings.Contains(output, "lock") {
|
2017-02-03 22:06:01 +01:00
|
|
|
t.Fatal("command output does not look like a lock error:", output)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-01 06:49:24 +02:00
|
|
|
func TestApply_destroyPlan(t *testing.T) {
|
|
|
|
planPath := testPlanFile(t, &terraform.Plan{
|
2018-05-23 04:33:45 +02:00
|
|
|
Config: testModule(t, "apply"),
|
2014-10-01 06:49:24 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
p := testProvider()
|
|
|
|
ui := new(cli.MockUi)
|
|
|
|
c := &ApplyCommand{
|
|
|
|
Destroy: true,
|
|
|
|
Meta: Meta{
|
2017-04-14 03:05:58 +02:00
|
|
|
testingOverrides: metaOverridesForProvider(p),
|
|
|
|
Ui: ui,
|
2014-10-01 06:49:24 +02:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
// Run the apply command pointing to our existing state
|
|
|
|
args := []string{
|
|
|
|
planPath,
|
|
|
|
}
|
|
|
|
if code := c.Run(args); code != 1 {
|
|
|
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-24 17:18:15 +01:00
|
|
|
func TestApply_destroyTargeted(t *testing.T) {
|
|
|
|
originalState := &terraform.State{
|
|
|
|
Modules: []*terraform.ModuleState{
|
|
|
|
&terraform.ModuleState{
|
|
|
|
Path: []string{"root"},
|
|
|
|
Resources: map[string]*terraform.ResourceState{
|
|
|
|
"test_instance.foo": &terraform.ResourceState{
|
|
|
|
Type: "test_instance",
|
|
|
|
Primary: &terraform.InstanceState{
|
|
|
|
ID: "i-ab123",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"test_load_balancer.foo": &terraform.ResourceState{
|
|
|
|
Type: "test_load_balancer",
|
|
|
|
Primary: &terraform.InstanceState{
|
|
|
|
ID: "lb-abc123",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
statePath := testStateFile(t, originalState)
|
|
|
|
|
|
|
|
p := testProvider()
|
2018-05-23 04:33:45 +02:00
|
|
|
p.GetSchemaReturn = &terraform.ProviderSchema{
|
|
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
|
|
"test_instance": {
|
|
|
|
Attributes: map[string]*configschema.Attribute{
|
|
|
|
"id": {Type: cty.String, Computed: true},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"test_load_balancer": {
|
|
|
|
Attributes: map[string]*configschema.Attribute{
|
|
|
|
"instances": {Type: cty.List(cty.String), Optional: true},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2015-03-24 17:18:15 +01:00
|
|
|
ui := new(cli.MockUi)
|
|
|
|
c := &ApplyCommand{
|
|
|
|
Destroy: true,
|
|
|
|
Meta: Meta{
|
2017-04-14 03:05:58 +02:00
|
|
|
testingOverrides: metaOverridesForProvider(p),
|
|
|
|
Ui: ui,
|
2015-03-24 17:18:15 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
// Run the apply command pointing to our existing state
|
|
|
|
args := []string{
|
2018-02-01 01:14:42 +01:00
|
|
|
"-auto-approve",
|
2015-03-24 17:18:15 +01:00
|
|
|
"-target", "test_instance.foo",
|
|
|
|
"-state", statePath,
|
|
|
|
testFixturePath("apply-destroy-targeted"),
|
|
|
|
}
|
|
|
|
if code := c.Run(args); code != 0 {
|
|
|
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify a new state exists
|
|
|
|
if _, err := os.Stat(statePath); err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
f, err := os.Open(statePath)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
state, err := terraform.ReadState(f)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
if state == nil {
|
|
|
|
t.Fatal("state should not be nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
actualStr := strings.TrimSpace(state.String())
|
|
|
|
expectedStr := strings.TrimSpace(testApplyDestroyStr)
|
|
|
|
if actualStr != expectedStr {
|
2016-11-10 16:54:39 +01:00
|
|
|
t.Fatalf("bad:\n\n%s\n\nexpected:\n\n%s", actualStr, expectedStr)
|
2015-03-24 17:18:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Should have a backup file
|
2015-09-11 20:56:20 +02:00
|
|
|
f, err = os.Open(statePath + DefaultBackupExtension)
|
2015-03-24 17:18:15 +01:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
backupState, err := terraform.ReadState(f)
|
|
|
|
f.Close()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
actualStr = strings.TrimSpace(backupState.String())
|
|
|
|
expectedStr = strings.TrimSpace(originalState.String())
|
|
|
|
if actualStr != expectedStr {
|
|
|
|
t.Fatalf("bad:\n\nactual:\n%s\n\nexpected:\nb%s", actualStr, expectedStr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-01 06:49:24 +02:00
|
|
|
const testApplyDestroyStr = `
|
|
|
|
<no state>
|
|
|
|
`
|