github.com/chalford/terraform@v0.3.7-0.20150113080010-a78c69a8c81f/helper/resource/testing_test.go (about)

     1  package resource
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/terraform/terraform"
     9  )
    10  
    11  func init() {
    12  	testTesting = true
    13  
    14  	if err := os.Setenv(TestEnvVar, "1"); err != nil {
    15  		panic(err)
    16  	}
    17  }
    18  
    19  func TestTest(t *testing.T) {
    20  	mp := testProvider()
    21  	mp.ApplyReturn = &terraform.InstanceState{
    22  		ID: "foo",
    23  	}
    24  
    25  	checkDestroy := false
    26  	checkStep := false
    27  
    28  	checkDestroyFn := func(*terraform.State) error {
    29  		checkDestroy = true
    30  		return nil
    31  	}
    32  
    33  	checkStepFn := func(s *terraform.State) error {
    34  		checkStep = true
    35  
    36  		rs, ok := s.RootModule().Resources["test_instance.foo"]
    37  		if !ok {
    38  			t.Error("test_instance.foo is not present")
    39  			return nil
    40  		}
    41  		is := rs.Primary
    42  		if is.ID != "foo" {
    43  			t.Errorf("bad check ID: %s", is.ID)
    44  		}
    45  
    46  		return nil
    47  	}
    48  
    49  	mt := new(mockT)
    50  	Test(mt, TestCase{
    51  		Providers: map[string]terraform.ResourceProvider{
    52  			"test": mp,
    53  		},
    54  		CheckDestroy: checkDestroyFn,
    55  		Steps: []TestStep{
    56  			TestStep{
    57  				Config: testConfigStr,
    58  				Check:  checkStepFn,
    59  			},
    60  		},
    61  	})
    62  
    63  	if mt.failed() {
    64  		t.Fatalf("test failed: %s", mt.failMessage())
    65  	}
    66  	if !checkStep {
    67  		t.Fatal("didn't call check for step")
    68  	}
    69  	if !checkDestroy {
    70  		t.Fatal("didn't call check for destroy")
    71  	}
    72  }
    73  
    74  func TestTest_empty(t *testing.T) {
    75  	destroyCalled := false
    76  	checkDestroyFn := func(*terraform.State) error {
    77  		destroyCalled = true
    78  		return nil
    79  	}
    80  
    81  	mt := new(mockT)
    82  	Test(mt, TestCase{
    83  		CheckDestroy: checkDestroyFn,
    84  	})
    85  
    86  	if mt.failed() {
    87  		t.Fatal("test failed")
    88  	}
    89  	if destroyCalled {
    90  		t.Fatal("should not call check destroy if there is no steps")
    91  	}
    92  }
    93  
    94  func TestTest_noEnv(t *testing.T) {
    95  	// Unset the variable
    96  	if err := os.Setenv(TestEnvVar, ""); err != nil {
    97  		t.Fatalf("err: %s", err)
    98  	}
    99  	defer os.Setenv(TestEnvVar, "1")
   100  
   101  	mt := new(mockT)
   102  	Test(mt, TestCase{})
   103  
   104  	if !mt.SkipCalled {
   105  		t.Fatal("skip not called")
   106  	}
   107  }
   108  
   109  func TestTest_preCheck(t *testing.T) {
   110  	called := false
   111  
   112  	mt := new(mockT)
   113  	Test(mt, TestCase{
   114  		PreCheck: func() { called = true },
   115  	})
   116  
   117  	if !called {
   118  		t.Fatal("precheck should be called")
   119  	}
   120  }
   121  
   122  func TestTest_stepError(t *testing.T) {
   123  	mp := testProvider()
   124  	mp.ApplyReturn = &terraform.InstanceState{
   125  		ID: "foo",
   126  	}
   127  
   128  	checkDestroy := false
   129  
   130  	checkDestroyFn := func(*terraform.State) error {
   131  		checkDestroy = true
   132  		return nil
   133  	}
   134  
   135  	checkStepFn := func(*terraform.State) error {
   136  		return fmt.Errorf("error")
   137  	}
   138  
   139  	mt := new(mockT)
   140  	Test(mt, TestCase{
   141  		Providers: map[string]terraform.ResourceProvider{
   142  			"test": mp,
   143  		},
   144  		CheckDestroy: checkDestroyFn,
   145  		Steps: []TestStep{
   146  			TestStep{
   147  				Config: testConfigStr,
   148  				Check:  checkStepFn,
   149  			},
   150  		},
   151  	})
   152  
   153  	if !mt.failed() {
   154  		t.Fatal("test should've failed")
   155  	}
   156  	t.Logf("Fail message: %s", mt.failMessage())
   157  
   158  	if !checkDestroy {
   159  		t.Fatal("didn't call check for destroy")
   160  	}
   161  }
   162  
   163  func TestComposeTestCheckFunc(t *testing.T) {
   164  	cases := []struct {
   165  		F      []TestCheckFunc
   166  		Result string
   167  	}{
   168  		{
   169  			F: []TestCheckFunc{
   170  				func(*terraform.State) error { return nil },
   171  			},
   172  			Result: "",
   173  		},
   174  
   175  		{
   176  			F: []TestCheckFunc{
   177  				func(*terraform.State) error {
   178  					return fmt.Errorf("error")
   179  				},
   180  				func(*terraform.State) error { return nil },
   181  			},
   182  			Result: "error",
   183  		},
   184  
   185  		{
   186  			F: []TestCheckFunc{
   187  				func(*terraform.State) error { return nil },
   188  				func(*terraform.State) error {
   189  					return fmt.Errorf("error")
   190  				},
   191  			},
   192  			Result: "error",
   193  		},
   194  
   195  		{
   196  			F: []TestCheckFunc{
   197  				func(*terraform.State) error { return nil },
   198  				func(*terraform.State) error { return nil },
   199  			},
   200  			Result: "",
   201  		},
   202  	}
   203  
   204  	for i, tc := range cases {
   205  		f := ComposeTestCheckFunc(tc.F...)
   206  		err := f(nil)
   207  		if err == nil {
   208  			err = fmt.Errorf("")
   209  		}
   210  		if tc.Result != err.Error() {
   211  			t.Fatalf("Case %d bad: %s", i, err)
   212  		}
   213  	}
   214  }
   215  
   216  // mockT implements TestT for testing
   217  type mockT struct {
   218  	ErrorCalled bool
   219  	ErrorArgs   []interface{}
   220  	FatalCalled bool
   221  	FatalArgs   []interface{}
   222  	SkipCalled  bool
   223  	SkipArgs    []interface{}
   224  
   225  	f bool
   226  }
   227  
   228  func (t *mockT) Error(args ...interface{}) {
   229  	t.ErrorCalled = true
   230  	t.ErrorArgs = args
   231  	t.f = true
   232  }
   233  
   234  func (t *mockT) Fatal(args ...interface{}) {
   235  	t.FatalCalled = true
   236  	t.FatalArgs = args
   237  	t.f = true
   238  }
   239  
   240  func (t *mockT) Skip(args ...interface{}) {
   241  	t.SkipCalled = true
   242  	t.SkipArgs = args
   243  	t.f = true
   244  }
   245  
   246  func (t *mockT) failed() bool {
   247  	return t.f
   248  }
   249  
   250  func (t *mockT) failMessage() string {
   251  	if t.FatalCalled {
   252  		return t.FatalArgs[0].(string)
   253  	} else if t.ErrorCalled {
   254  		return t.ErrorArgs[0].(string)
   255  	} else if t.SkipCalled {
   256  		return t.SkipArgs[0].(string)
   257  	}
   258  
   259  	return "unknown"
   260  }
   261  
   262  func testProvider() *terraform.MockResourceProvider {
   263  	mp := new(terraform.MockResourceProvider)
   264  	mp.DiffReturn = &terraform.InstanceDiff{
   265  		Attributes: map[string]*terraform.ResourceAttrDiff{
   266  			"foo": &terraform.ResourceAttrDiff{
   267  				New: "bar",
   268  			},
   269  		},
   270  	}
   271  	mp.ResourcesReturn = []terraform.ResourceType{
   272  		terraform.ResourceType{Name: "test_instance"},
   273  	}
   274  
   275  	return mp
   276  }
   277  
   278  const testConfigStr = `
   279  resource "test_instance" "foo" {}
   280  `