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 `