github.com/pbthorste/terraform@v0.8.6-0.20170127005045-deb56bd93da2/backend/local/backend_plan_test.go (about)

     1  package local
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	"github.com/hashicorp/terraform/backend"
    10  	"github.com/hashicorp/terraform/config/module"
    11  	"github.com/hashicorp/terraform/terraform"
    12  )
    13  
    14  func TestLocal_planBasic(t *testing.T) {
    15  	b := TestLocal(t)
    16  	p := TestLocalProvider(t, b, "test")
    17  
    18  	mod, modCleanup := module.TestTree(t, "./test-fixtures/plan")
    19  	defer modCleanup()
    20  
    21  	op := testOperationPlan()
    22  	op.Module = mod
    23  	op.PlanRefresh = true
    24  
    25  	run, err := b.Operation(context.Background(), op)
    26  	if err != nil {
    27  		t.Fatalf("bad: %s", err)
    28  	}
    29  	<-run.Done()
    30  	if run.Err != nil {
    31  		t.Fatalf("err: %s", err)
    32  	}
    33  
    34  	if !p.DiffCalled {
    35  		t.Fatal("diff should be called")
    36  	}
    37  }
    38  
    39  func TestLocal_planRefreshFalse(t *testing.T) {
    40  	b := TestLocal(t)
    41  	p := TestLocalProvider(t, b, "test")
    42  	terraform.TestStateFile(t, b.StatePath, testPlanState())
    43  
    44  	mod, modCleanup := module.TestTree(t, "./test-fixtures/plan")
    45  	defer modCleanup()
    46  
    47  	op := testOperationPlan()
    48  	op.Module = mod
    49  
    50  	run, err := b.Operation(context.Background(), op)
    51  	if err != nil {
    52  		t.Fatalf("bad: %s", err)
    53  	}
    54  	<-run.Done()
    55  	if run.Err != nil {
    56  		t.Fatalf("err: %s", err)
    57  	}
    58  
    59  	if p.RefreshCalled {
    60  		t.Fatal("refresh should not be called")
    61  	}
    62  
    63  	if !run.PlanEmpty {
    64  		t.Fatal("plan should be empty")
    65  	}
    66  }
    67  
    68  func TestLocal_planDestroy(t *testing.T) {
    69  	b := TestLocal(t)
    70  	p := TestLocalProvider(t, b, "test")
    71  	terraform.TestStateFile(t, b.StatePath, testPlanState())
    72  
    73  	mod, modCleanup := module.TestTree(t, "./test-fixtures/plan")
    74  	defer modCleanup()
    75  
    76  	outDir := testTempDir(t)
    77  	defer os.RemoveAll(outDir)
    78  	planPath := filepath.Join(outDir, "plan.tfplan")
    79  
    80  	op := testOperationPlan()
    81  	op.Destroy = true
    82  	op.PlanRefresh = true
    83  	op.Module = mod
    84  	op.PlanOutPath = planPath
    85  
    86  	run, err := b.Operation(context.Background(), op)
    87  	if err != nil {
    88  		t.Fatalf("bad: %s", err)
    89  	}
    90  	<-run.Done()
    91  	if run.Err != nil {
    92  		t.Fatalf("err: %s", err)
    93  	}
    94  
    95  	if !p.RefreshCalled {
    96  		t.Fatal("refresh should be called")
    97  	}
    98  
    99  	if run.PlanEmpty {
   100  		t.Fatal("plan should not be empty")
   101  	}
   102  
   103  	plan := testReadPlan(t, planPath)
   104  	for _, m := range plan.Diff.Modules {
   105  		for _, r := range m.Resources {
   106  			if !r.Destroy {
   107  				t.Fatalf("bad: %#v", r)
   108  			}
   109  		}
   110  	}
   111  }
   112  
   113  func TestLocal_planOutPathNoChange(t *testing.T) {
   114  	b := TestLocal(t)
   115  	TestLocalProvider(t, b, "test")
   116  	terraform.TestStateFile(t, b.StatePath, testPlanState())
   117  
   118  	mod, modCleanup := module.TestTree(t, "./test-fixtures/plan")
   119  	defer modCleanup()
   120  
   121  	outDir := testTempDir(t)
   122  	defer os.RemoveAll(outDir)
   123  	planPath := filepath.Join(outDir, "plan.tfplan")
   124  
   125  	op := testOperationPlan()
   126  	op.Module = mod
   127  	op.PlanOutPath = planPath
   128  
   129  	run, err := b.Operation(context.Background(), op)
   130  	if err != nil {
   131  		t.Fatalf("bad: %s", err)
   132  	}
   133  	<-run.Done()
   134  	if run.Err != nil {
   135  		t.Fatalf("err: %s", err)
   136  	}
   137  
   138  	plan := testReadPlan(t, planPath)
   139  	if !plan.Diff.Empty() {
   140  		t.Fatalf("expected empty plan to be written")
   141  	}
   142  }
   143  
   144  func testOperationPlan() *backend.Operation {
   145  	return &backend.Operation{
   146  		Type: backend.OperationTypePlan,
   147  	}
   148  }
   149  
   150  // testPlanState is just a common state that we use for testing refresh.
   151  func testPlanState() *terraform.State {
   152  	return &terraform.State{
   153  		Version: 2,
   154  		Modules: []*terraform.ModuleState{
   155  			&terraform.ModuleState{
   156  				Path: []string{"root"},
   157  				Resources: map[string]*terraform.ResourceState{
   158  					"test_instance.foo": &terraform.ResourceState{
   159  						Type: "test_instance",
   160  						Primary: &terraform.InstanceState{
   161  							ID: "bar",
   162  						},
   163  					},
   164  				},
   165  			},
   166  		},
   167  	}
   168  }
   169  
   170  func testReadPlan(t *testing.T, path string) *terraform.Plan {
   171  	f, err := os.Open(path)
   172  	if err != nil {
   173  		t.Fatalf("err: %s", err)
   174  	}
   175  	defer f.Close()
   176  
   177  	p, err := terraform.ReadPlan(f)
   178  	if err != nil {
   179  		t.Fatalf("err: %s", err)
   180  	}
   181  
   182  	return p
   183  }