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