github.com/ezbercih/terraform@v0.1.1-0.20140729011846-3c33865e0839/command/apply_test.go (about)

     1  package command
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"reflect"
     9  	"sync"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/hashicorp/terraform/config"
    14  	"github.com/hashicorp/terraform/terraform"
    15  	"github.com/mitchellh/cli"
    16  )
    17  
    18  func TestApply(t *testing.T) {
    19  	statePath := testTempFile(t)
    20  
    21  	p := testProvider()
    22  	ui := new(cli.MockUi)
    23  	c := &ApplyCommand{
    24  		Meta: Meta{
    25  			ContextOpts: testCtxConfig(p),
    26  			Ui:          ui,
    27  		},
    28  	}
    29  
    30  	args := []string{
    31  		"-state", statePath,
    32  		testFixturePath("apply"),
    33  	}
    34  	if code := c.Run(args); code != 0 {
    35  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
    36  	}
    37  
    38  	if _, err := os.Stat(statePath); err != nil {
    39  		t.Fatalf("err: %s", err)
    40  	}
    41  
    42  	f, err := os.Open(statePath)
    43  	if err != nil {
    44  		t.Fatalf("err: %s", err)
    45  	}
    46  	defer f.Close()
    47  
    48  	state, err := terraform.ReadState(f)
    49  	if err != nil {
    50  		t.Fatalf("err: %s", err)
    51  	}
    52  	if state == nil {
    53  		t.Fatal("state should not be nil")
    54  	}
    55  }
    56  
    57  func TestApply_configInvalid(t *testing.T) {
    58  	p := testProvider()
    59  	ui := new(cli.MockUi)
    60  	c := &ApplyCommand{
    61  		Meta: Meta{
    62  			ContextOpts: testCtxConfig(p),
    63  			Ui:          ui,
    64  		},
    65  	}
    66  
    67  	args := []string{
    68  		"-state", testTempFile(t),
    69  		testFixturePath("apply-config-invalid"),
    70  	}
    71  	if code := c.Run(args); code != 1 {
    72  		t.Fatalf("bad: \n%s", ui.OutputWriter.String())
    73  	}
    74  }
    75  
    76  func TestApply_defaultState(t *testing.T) {
    77  	td, err := ioutil.TempDir("", "tf")
    78  	if err != nil {
    79  		t.Fatalf("err: %s", err)
    80  	}
    81  	statePath := filepath.Join(td, DefaultStateFilename)
    82  
    83  	// Change to the temporary directory
    84  	cwd, err := os.Getwd()
    85  	if err != nil {
    86  		t.Fatalf("err: %s", err)
    87  	}
    88  	if err := os.Chdir(filepath.Dir(statePath)); err != nil {
    89  		t.Fatalf("err: %s", err)
    90  	}
    91  	defer os.Chdir(cwd)
    92  
    93  	p := testProvider()
    94  	ui := new(cli.MockUi)
    95  	c := &ApplyCommand{
    96  		Meta: Meta{
    97  			ContextOpts: testCtxConfig(p),
    98  			Ui:          ui,
    99  		},
   100  	}
   101  
   102  	args := []string{
   103  		testFixturePath("apply"),
   104  	}
   105  	if code := c.Run(args); code != 0 {
   106  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   107  	}
   108  
   109  	if _, err := os.Stat(statePath); err != nil {
   110  		t.Fatalf("err: %s", err)
   111  	}
   112  
   113  	f, err := os.Open(statePath)
   114  	if err != nil {
   115  		t.Fatalf("err: %s", err)
   116  	}
   117  	defer f.Close()
   118  
   119  	state, err := terraform.ReadState(f)
   120  	if err != nil {
   121  		t.Fatalf("err: %s", err)
   122  	}
   123  	if state == nil {
   124  		t.Fatal("state should not be nil")
   125  	}
   126  }
   127  
   128  func TestApply_error(t *testing.T) {
   129  	statePath := testTempFile(t)
   130  
   131  	p := testProvider()
   132  	ui := new(cli.MockUi)
   133  	c := &ApplyCommand{
   134  		Meta: Meta{
   135  			ContextOpts: testCtxConfig(p),
   136  			Ui:          ui,
   137  		},
   138  	}
   139  
   140  	var lock sync.Mutex
   141  	errored := false
   142  	p.ApplyFn = func(
   143  		s *terraform.ResourceState,
   144  		d *terraform.ResourceDiff) (*terraform.ResourceState, error) {
   145  		lock.Lock()
   146  		defer lock.Unlock()
   147  
   148  		if !errored {
   149  			errored = true
   150  			return nil, fmt.Errorf("error")
   151  		}
   152  
   153  		return &terraform.ResourceState{ID: "foo"}, nil
   154  	}
   155  	p.DiffFn = func(
   156  		*terraform.ResourceState,
   157  		*terraform.ResourceConfig) (*terraform.ResourceDiff, error) {
   158  		return &terraform.ResourceDiff{
   159  			Attributes: map[string]*terraform.ResourceAttrDiff{
   160  				"ami": &terraform.ResourceAttrDiff{
   161  					New: "bar",
   162  				},
   163  			},
   164  		}, nil
   165  	}
   166  
   167  	args := []string{
   168  		"-state", statePath,
   169  		testFixturePath("apply-error"),
   170  	}
   171  	if code := c.Run(args); code != 1 {
   172  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   173  	}
   174  
   175  	if _, err := os.Stat(statePath); err != nil {
   176  		t.Fatalf("err: %s", err)
   177  	}
   178  
   179  	f, err := os.Open(statePath)
   180  	if err != nil {
   181  		t.Fatalf("err: %s", err)
   182  	}
   183  	defer f.Close()
   184  
   185  	state, err := terraform.ReadState(f)
   186  	if err != nil {
   187  		t.Fatalf("err: %s", err)
   188  	}
   189  	if state == nil {
   190  		t.Fatal("state should not be nil")
   191  	}
   192  	if len(state.Resources) == 0 {
   193  		t.Fatal("no resources in state")
   194  	}
   195  }
   196  
   197  func TestApply_noArgs(t *testing.T) {
   198  	cwd, err := os.Getwd()
   199  	if err != nil {
   200  		t.Fatalf("err: %s", err)
   201  	}
   202  	if err := os.Chdir(testFixturePath("plan")); err != nil {
   203  		t.Fatalf("err: %s", err)
   204  	}
   205  	defer os.Chdir(cwd)
   206  
   207  	statePath := testTempFile(t)
   208  
   209  	p := testProvider()
   210  	ui := new(cli.MockUi)
   211  	c := &ApplyCommand{
   212  		Meta: Meta{
   213  			ContextOpts: testCtxConfig(p),
   214  			Ui:          ui,
   215  		},
   216  	}
   217  
   218  	args := []string{
   219  		"-state", statePath,
   220  	}
   221  	if code := c.Run(args); code != 0 {
   222  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   223  	}
   224  
   225  	if _, err := os.Stat(statePath); err != nil {
   226  		t.Fatalf("err: %s", err)
   227  	}
   228  
   229  	f, err := os.Open(statePath)
   230  	if err != nil {
   231  		t.Fatalf("err: %s", err)
   232  	}
   233  	defer f.Close()
   234  
   235  	state, err := terraform.ReadState(f)
   236  	if err != nil {
   237  		t.Fatalf("err: %s", err)
   238  	}
   239  	if state == nil {
   240  		t.Fatal("state should not be nil")
   241  	}
   242  }
   243  
   244  func TestApply_plan(t *testing.T) {
   245  	planPath := testPlanFile(t, &terraform.Plan{
   246  		Config: new(config.Config),
   247  	})
   248  	statePath := testTempFile(t)
   249  
   250  	p := testProvider()
   251  	ui := new(cli.MockUi)
   252  	c := &ApplyCommand{
   253  		Meta: Meta{
   254  			ContextOpts: testCtxConfig(p),
   255  			Ui:          ui,
   256  		},
   257  	}
   258  
   259  	args := []string{
   260  		"-state", statePath,
   261  		planPath,
   262  	}
   263  	if code := c.Run(args); code != 0 {
   264  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   265  	}
   266  
   267  	if _, err := os.Stat(statePath); err != nil {
   268  		t.Fatalf("err: %s", err)
   269  	}
   270  
   271  	f, err := os.Open(statePath)
   272  	if err != nil {
   273  		t.Fatalf("err: %s", err)
   274  	}
   275  	defer f.Close()
   276  
   277  	state, err := terraform.ReadState(f)
   278  	if err != nil {
   279  		t.Fatalf("err: %s", err)
   280  	}
   281  	if state == nil {
   282  		t.Fatal("state should not be nil")
   283  	}
   284  }
   285  
   286  func TestApply_planVars(t *testing.T) {
   287  	planPath := testPlanFile(t, &terraform.Plan{
   288  		Config: new(config.Config),
   289  	})
   290  	statePath := testTempFile(t)
   291  
   292  	p := testProvider()
   293  	ui := new(cli.MockUi)
   294  	c := &ApplyCommand{
   295  		Meta: Meta{
   296  			ContextOpts: testCtxConfig(p),
   297  			Ui:          ui,
   298  		},
   299  	}
   300  
   301  	args := []string{
   302  		"-state", statePath,
   303  		"-var", "foo=bar",
   304  		planPath,
   305  	}
   306  	if code := c.Run(args); code == 0 {
   307  		t.Fatal("should've failed")
   308  	}
   309  }
   310  
   311  func TestApply_refresh(t *testing.T) {
   312  	originalState := &terraform.State{
   313  		Resources: map[string]*terraform.ResourceState{
   314  			"test_instance.foo": &terraform.ResourceState{
   315  				ID:   "bar",
   316  				Type: "test_instance",
   317  			},
   318  		},
   319  	}
   320  
   321  	statePath := testStateFile(t, originalState)
   322  
   323  	p := testProvider()
   324  	ui := new(cli.MockUi)
   325  	c := &ApplyCommand{
   326  		Meta: Meta{
   327  			ContextOpts: testCtxConfig(p),
   328  			Ui:          ui,
   329  		},
   330  	}
   331  
   332  	args := []string{
   333  		"-state", statePath,
   334  		testFixturePath("apply"),
   335  	}
   336  	if code := c.Run(args); code != 0 {
   337  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   338  	}
   339  
   340  	if !p.RefreshCalled {
   341  		t.Fatal("should call refresh")
   342  	}
   343  
   344  	if _, err := os.Stat(statePath); err != nil {
   345  		t.Fatalf("err: %s", err)
   346  	}
   347  
   348  	f, err := os.Open(statePath)
   349  	if err != nil {
   350  		t.Fatalf("err: %s", err)
   351  	}
   352  	defer f.Close()
   353  
   354  	state, err := terraform.ReadState(f)
   355  	if err != nil {
   356  		t.Fatalf("err: %s", err)
   357  	}
   358  	if state == nil {
   359  		t.Fatal("state should not be nil")
   360  	}
   361  
   362  	// Should have a backup file
   363  	f, err = os.Open(statePath + DefaultBackupExtention)
   364  	if err != nil {
   365  		t.Fatalf("err: %s", err)
   366  	}
   367  
   368  	backupState, err := terraform.ReadState(f)
   369  	f.Close()
   370  	if err != nil {
   371  		t.Fatalf("err: %s", err)
   372  	}
   373  
   374  	if !reflect.DeepEqual(backupState, originalState) {
   375  		t.Fatalf("bad: %#v", backupState)
   376  	}
   377  }
   378  
   379  func TestApply_shutdown(t *testing.T) {
   380  	stopped := false
   381  	stopCh := make(chan struct{})
   382  	stopReplyCh := make(chan struct{})
   383  
   384  	statePath := testTempFile(t)
   385  
   386  	p := testProvider()
   387  	shutdownCh := make(chan struct{})
   388  	ui := new(cli.MockUi)
   389  	c := &ApplyCommand{
   390  		Meta: Meta{
   391  			ContextOpts: testCtxConfig(p),
   392  			Ui:          ui,
   393  		},
   394  
   395  		ShutdownCh: shutdownCh,
   396  	}
   397  
   398  	p.DiffFn = func(
   399  		*terraform.ResourceState,
   400  		*terraform.ResourceConfig) (*terraform.ResourceDiff, error) {
   401  		return &terraform.ResourceDiff{
   402  			Attributes: map[string]*terraform.ResourceAttrDiff{
   403  				"ami": &terraform.ResourceAttrDiff{
   404  					New: "bar",
   405  				},
   406  			},
   407  		}, nil
   408  	}
   409  	p.ApplyFn = func(
   410  		*terraform.ResourceState,
   411  		*terraform.ResourceDiff) (*terraform.ResourceState, error) {
   412  		if !stopped {
   413  			stopped = true
   414  			close(stopCh)
   415  			<-stopReplyCh
   416  		}
   417  
   418  		return &terraform.ResourceState{
   419  			ID: "foo",
   420  			Attributes: map[string]string{
   421  				"ami": "2",
   422  			},
   423  		}, nil
   424  	}
   425  
   426  	go func() {
   427  		<-stopCh
   428  		shutdownCh <- struct{}{}
   429  
   430  		// This is really dirty, but we have no other way to assure that
   431  		// tf.Stop() has been called. This doesn't assure it either, but
   432  		// it makes it much more certain.
   433  		time.Sleep(50 * time.Millisecond)
   434  
   435  		close(stopReplyCh)
   436  	}()
   437  
   438  	args := []string{
   439  		"-state", statePath,
   440  		testFixturePath("apply-shutdown"),
   441  	}
   442  	if code := c.Run(args); code != 0 {
   443  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   444  	}
   445  
   446  	if _, err := os.Stat(statePath); err != nil {
   447  		t.Fatalf("err: %s", err)
   448  	}
   449  
   450  	f, err := os.Open(statePath)
   451  	if err != nil {
   452  		t.Fatalf("err: %s", err)
   453  	}
   454  	defer f.Close()
   455  
   456  	state, err := terraform.ReadState(f)
   457  	if err != nil {
   458  		t.Fatalf("err: %s", err)
   459  	}
   460  	if state == nil {
   461  		t.Fatal("state should not be nil")
   462  	}
   463  
   464  	if len(state.Resources) != 1 {
   465  		t.Fatalf("bad: %d", len(state.Resources))
   466  	}
   467  }
   468  
   469  func TestApply_state(t *testing.T) {
   470  	originalState := &terraform.State{
   471  		Resources: map[string]*terraform.ResourceState{
   472  			"test_instance.foo": &terraform.ResourceState{
   473  				ID:       "bar",
   474  				Type:     "test_instance",
   475  				ConnInfo: make(map[string]string),
   476  			},
   477  		},
   478  	}
   479  
   480  	statePath := testStateFile(t, originalState)
   481  
   482  	p := testProvider()
   483  	p.DiffReturn = &terraform.ResourceDiff{
   484  		Attributes: map[string]*terraform.ResourceAttrDiff{
   485  			"ami": &terraform.ResourceAttrDiff{
   486  				New: "bar",
   487  			},
   488  		},
   489  	}
   490  
   491  	ui := new(cli.MockUi)
   492  	c := &ApplyCommand{
   493  		Meta: Meta{
   494  			ContextOpts: testCtxConfig(p),
   495  			Ui:          ui,
   496  		},
   497  	}
   498  
   499  	// Run the apply command pointing to our existing state
   500  	args := []string{
   501  		"-state", statePath,
   502  		testFixturePath("apply"),
   503  	}
   504  	if code := c.Run(args); code != 0 {
   505  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   506  	}
   507  
   508  	// Verify that the provider was called with the existing state
   509  	expectedState := originalState.Resources["test_instance.foo"]
   510  	if !reflect.DeepEqual(p.DiffState, expectedState) {
   511  		t.Fatalf("bad: %#v", p.DiffState)
   512  	}
   513  
   514  	if !reflect.DeepEqual(p.ApplyState, expectedState) {
   515  		t.Fatalf("bad: %#v", p.ApplyState)
   516  	}
   517  
   518  	// Verify a new state exists
   519  	if _, err := os.Stat(statePath); err != nil {
   520  		t.Fatalf("err: %s", err)
   521  	}
   522  
   523  	f, err := os.Open(statePath)
   524  	if err != nil {
   525  		t.Fatalf("err: %s", err)
   526  	}
   527  	defer f.Close()
   528  
   529  	state, err := terraform.ReadState(f)
   530  	if err != nil {
   531  		t.Fatalf("err: %s", err)
   532  	}
   533  	if state == nil {
   534  		t.Fatal("state should not be nil")
   535  	}
   536  
   537  	// Should have a backup file
   538  	f, err = os.Open(statePath + DefaultBackupExtention)
   539  	if err != nil {
   540  		t.Fatalf("err: %s", err)
   541  	}
   542  
   543  	backupState, err := terraform.ReadState(f)
   544  	f.Close()
   545  	if err != nil {
   546  		t.Fatalf("err: %s", err)
   547  	}
   548  
   549  	// nil out the ConnInfo since that should not be restored
   550  	originalState.Resources["test_instance.foo"].ConnInfo = nil
   551  
   552  	if !reflect.DeepEqual(backupState, originalState) {
   553  		t.Fatalf("bad: %#v", backupState)
   554  	}
   555  }
   556  
   557  func TestApply_stateNoExist(t *testing.T) {
   558  	p := testProvider()
   559  	ui := new(cli.MockUi)
   560  	c := &ApplyCommand{
   561  		Meta: Meta{
   562  			ContextOpts: testCtxConfig(p),
   563  			Ui:          ui,
   564  		},
   565  	}
   566  
   567  	args := []string{
   568  		"idontexist.tfstate",
   569  		testFixturePath("apply"),
   570  	}
   571  	if code := c.Run(args); code != 1 {
   572  		t.Fatalf("bad: \n%s", ui.OutputWriter.String())
   573  	}
   574  }
   575  
   576  func TestApply_vars(t *testing.T) {
   577  	statePath := testTempFile(t)
   578  
   579  	p := testProvider()
   580  	ui := new(cli.MockUi)
   581  	c := &ApplyCommand{
   582  		Meta: Meta{
   583  			ContextOpts: testCtxConfig(p),
   584  			Ui:          ui,
   585  		},
   586  	}
   587  
   588  	actual := ""
   589  	p.DiffFn = func(
   590  		s *terraform.ResourceState,
   591  		c *terraform.ResourceConfig) (*terraform.ResourceDiff, error) {
   592  		if v, ok := c.Config["value"]; ok {
   593  			actual = v.(string)
   594  		}
   595  
   596  		return &terraform.ResourceDiff{}, nil
   597  	}
   598  
   599  	args := []string{
   600  		"-var", "foo=bar",
   601  		"-state", statePath,
   602  		testFixturePath("apply-vars"),
   603  	}
   604  	if code := c.Run(args); code != 0 {
   605  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   606  	}
   607  
   608  	if actual != "bar" {
   609  		t.Fatal("didn't work")
   610  	}
   611  }
   612  
   613  func TestApply_varFile(t *testing.T) {
   614  	varFilePath := testTempFile(t)
   615  	if err := ioutil.WriteFile(varFilePath, []byte(applyVarFile), 0644); err != nil {
   616  		t.Fatalf("err: %s", err)
   617  	}
   618  
   619  	statePath := testTempFile(t)
   620  
   621  	p := testProvider()
   622  	ui := new(cli.MockUi)
   623  	c := &ApplyCommand{
   624  		Meta: Meta{
   625  			ContextOpts: testCtxConfig(p),
   626  			Ui:          ui,
   627  		},
   628  	}
   629  
   630  	actual := ""
   631  	p.DiffFn = func(
   632  		s *terraform.ResourceState,
   633  		c *terraform.ResourceConfig) (*terraform.ResourceDiff, error) {
   634  		if v, ok := c.Config["value"]; ok {
   635  			actual = v.(string)
   636  		}
   637  
   638  		return &terraform.ResourceDiff{}, nil
   639  	}
   640  
   641  	args := []string{
   642  		"-var-file", varFilePath,
   643  		"-state", statePath,
   644  		testFixturePath("apply-vars"),
   645  	}
   646  	if code := c.Run(args); code != 0 {
   647  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   648  	}
   649  
   650  	if actual != "bar" {
   651  		t.Fatal("didn't work")
   652  	}
   653  }
   654  
   655  func TestApply_backup(t *testing.T) {
   656  	originalState := &terraform.State{
   657  		Resources: map[string]*terraform.ResourceState{
   658  			"test_instance.foo": &terraform.ResourceState{
   659  				ID:   "bar",
   660  				Type: "test_instance",
   661  			},
   662  		},
   663  	}
   664  
   665  	statePath := testStateFile(t, originalState)
   666  	backupPath := testTempFile(t)
   667  
   668  	p := testProvider()
   669  	p.DiffReturn = &terraform.ResourceDiff{
   670  		Attributes: map[string]*terraform.ResourceAttrDiff{
   671  			"ami": &terraform.ResourceAttrDiff{
   672  				New: "bar",
   673  			},
   674  		},
   675  	}
   676  
   677  	ui := new(cli.MockUi)
   678  	c := &ApplyCommand{
   679  		Meta: Meta{
   680  			ContextOpts: testCtxConfig(p),
   681  			Ui:          ui,
   682  		},
   683  	}
   684  
   685  	// Run the apply command pointing to our existing state
   686  	args := []string{
   687  		"-state", statePath,
   688  		"-backup", backupPath,
   689  		testFixturePath("apply"),
   690  	}
   691  	if code := c.Run(args); code != 0 {
   692  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   693  	}
   694  
   695  	// Verify a new state exists
   696  	if _, err := os.Stat(statePath); err != nil {
   697  		t.Fatalf("err: %s", err)
   698  	}
   699  
   700  	f, err := os.Open(statePath)
   701  	if err != nil {
   702  		t.Fatalf("err: %s", err)
   703  	}
   704  	defer f.Close()
   705  
   706  	state, err := terraform.ReadState(f)
   707  	if err != nil {
   708  		t.Fatalf("err: %s", err)
   709  	}
   710  	if state == nil {
   711  		t.Fatal("state should not be nil")
   712  	}
   713  
   714  	// Should have a backup file
   715  	f, err = os.Open(backupPath)
   716  	if err != nil {
   717  		t.Fatalf("err: %s", err)
   718  	}
   719  
   720  	backupState, err := terraform.ReadState(f)
   721  	f.Close()
   722  	if err != nil {
   723  		t.Fatalf("err: %s", err)
   724  	}
   725  
   726  	actual := backupState.Resources["test_instance.foo"]
   727  	expected := originalState.Resources["test_instance.foo"]
   728  	if !reflect.DeepEqual(actual, expected) {
   729  		t.Fatalf("bad: %#v %#v", actual, expected)
   730  	}
   731  }
   732  
   733  func TestApply_disableBackup(t *testing.T) {
   734  	originalState := &terraform.State{
   735  		Resources: map[string]*terraform.ResourceState{
   736  			"test_instance.foo": &terraform.ResourceState{
   737  				ID:       "bar",
   738  				Type:     "test_instance",
   739  				ConnInfo: make(map[string]string),
   740  			},
   741  		},
   742  	}
   743  
   744  	statePath := testStateFile(t, originalState)
   745  
   746  	p := testProvider()
   747  	p.DiffReturn = &terraform.ResourceDiff{
   748  		Attributes: map[string]*terraform.ResourceAttrDiff{
   749  			"ami": &terraform.ResourceAttrDiff{
   750  				New: "bar",
   751  			},
   752  		},
   753  	}
   754  
   755  	ui := new(cli.MockUi)
   756  	c := &ApplyCommand{
   757  		Meta: Meta{
   758  			ContextOpts: testCtxConfig(p),
   759  			Ui:          ui,
   760  		},
   761  	}
   762  
   763  	// Run the apply command pointing to our existing state
   764  	args := []string{
   765  		"-state", statePath,
   766  		"-backup", "-",
   767  		testFixturePath("apply"),
   768  	}
   769  	if code := c.Run(args); code != 0 {
   770  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   771  	}
   772  
   773  	// Verify that the provider was called with the existing state
   774  	expectedState := originalState.Resources["test_instance.foo"]
   775  	if !reflect.DeepEqual(p.DiffState, expectedState) {
   776  		t.Fatalf("bad: %#v", p.DiffState)
   777  	}
   778  
   779  	if !reflect.DeepEqual(p.ApplyState, expectedState) {
   780  		t.Fatalf("bad: %#v", p.ApplyState)
   781  	}
   782  
   783  	// Verify a new state exists
   784  	if _, err := os.Stat(statePath); err != nil {
   785  		t.Fatalf("err: %s", err)
   786  	}
   787  
   788  	f, err := os.Open(statePath)
   789  	if err != nil {
   790  		t.Fatalf("err: %s", err)
   791  	}
   792  	defer f.Close()
   793  
   794  	state, err := terraform.ReadState(f)
   795  	if err != nil {
   796  		t.Fatalf("err: %s", err)
   797  	}
   798  	if state == nil {
   799  		t.Fatal("state should not be nil")
   800  	}
   801  
   802  	// Ensure there is no backup
   803  	_, err = os.Stat(statePath + DefaultBackupExtention)
   804  	if err == nil || !os.IsNotExist(err) {
   805  		t.Fatalf("backup should not exist")
   806  	}
   807  }
   808  
   809  const applyVarFile = `
   810  foo = "bar"
   811  `