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 `