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