github.com/lamielle/terraform@v0.3.2-0.20141121070651-81f008ba53d5/helper/schema/resource_test.go (about) 1 package schema 2 3 import ( 4 "fmt" 5 "reflect" 6 "testing" 7 8 "github.com/hashicorp/terraform/terraform" 9 ) 10 11 func TestResourceApply_create(t *testing.T) { 12 r := &Resource{ 13 Schema: map[string]*Schema{ 14 "foo": &Schema{ 15 Type: TypeInt, 16 Optional: true, 17 }, 18 }, 19 } 20 21 called := false 22 r.Create = func(d *ResourceData, m interface{}) error { 23 called = true 24 d.SetId("foo") 25 return nil 26 } 27 28 var s *terraform.InstanceState = nil 29 30 d := &terraform.InstanceDiff{ 31 Attributes: map[string]*terraform.ResourceAttrDiff{ 32 "foo": &terraform.ResourceAttrDiff{ 33 New: "42", 34 }, 35 }, 36 } 37 38 actual, err := r.Apply(s, d, nil) 39 if err != nil { 40 t.Fatalf("err: %s", err) 41 } 42 43 if !called { 44 t.Fatal("not called") 45 } 46 47 expected := &terraform.InstanceState{ 48 ID: "foo", 49 Attributes: map[string]string{ 50 "id": "foo", 51 "foo": "42", 52 }, 53 } 54 55 if !reflect.DeepEqual(actual, expected) { 56 t.Fatalf("bad: %#v", actual) 57 } 58 } 59 60 func TestResourceApply_destroy(t *testing.T) { 61 r := &Resource{ 62 Schema: map[string]*Schema{ 63 "foo": &Schema{ 64 Type: TypeInt, 65 Optional: true, 66 }, 67 }, 68 } 69 70 called := false 71 r.Delete = func(d *ResourceData, m interface{}) error { 72 called = true 73 return nil 74 } 75 76 s := &terraform.InstanceState{ 77 ID: "bar", 78 } 79 80 d := &terraform.InstanceDiff{ 81 Destroy: true, 82 } 83 84 actual, err := r.Apply(s, d, nil) 85 if err != nil { 86 t.Fatalf("err: %s", err) 87 } 88 89 if !called { 90 t.Fatal("delete not called") 91 } 92 93 if actual != nil { 94 t.Fatalf("bad: %#v", actual) 95 } 96 } 97 98 func TestResourceApply_destroyCreate(t *testing.T) { 99 r := &Resource{ 100 Schema: map[string]*Schema{ 101 "foo": &Schema{ 102 Type: TypeInt, 103 Optional: true, 104 }, 105 106 "tags": &Schema{ 107 Type: TypeMap, 108 Optional: true, 109 Computed: true, 110 }, 111 }, 112 } 113 114 change := false 115 r.Create = func(d *ResourceData, m interface{}) error { 116 change = d.HasChange("tags") 117 d.SetId("foo") 118 return nil 119 } 120 r.Delete = func(d *ResourceData, m interface{}) error { 121 return nil 122 } 123 124 var s *terraform.InstanceState = &terraform.InstanceState{ 125 ID: "bar", 126 Attributes: map[string]string{ 127 "foo": "bar", 128 "tags.Name": "foo", 129 }, 130 } 131 132 d := &terraform.InstanceDiff{ 133 Attributes: map[string]*terraform.ResourceAttrDiff{ 134 "foo": &terraform.ResourceAttrDiff{ 135 New: "42", 136 RequiresNew: true, 137 }, 138 "tags.Name": &terraform.ResourceAttrDiff{ 139 Old: "foo", 140 New: "foo", 141 RequiresNew: true, 142 }, 143 }, 144 } 145 146 actual, err := r.Apply(s, d, nil) 147 if err != nil { 148 t.Fatalf("err: %s", err) 149 } 150 151 if !change { 152 t.Fatal("should have change") 153 } 154 155 expected := &terraform.InstanceState{ 156 ID: "foo", 157 Attributes: map[string]string{ 158 "id": "foo", 159 "foo": "42", 160 "tags.Name": "foo", 161 }, 162 } 163 164 if !reflect.DeepEqual(actual, expected) { 165 t.Fatalf("bad: %#v", actual) 166 } 167 } 168 169 func TestResourceApply_destroyPartial(t *testing.T) { 170 r := &Resource{ 171 Schema: map[string]*Schema{ 172 "foo": &Schema{ 173 Type: TypeInt, 174 Optional: true, 175 }, 176 }, 177 } 178 179 r.Delete = func(d *ResourceData, m interface{}) error { 180 d.Set("foo", 42) 181 return fmt.Errorf("some error") 182 } 183 184 s := &terraform.InstanceState{ 185 ID: "bar", 186 Attributes: map[string]string{ 187 "foo": "12", 188 }, 189 } 190 191 d := &terraform.InstanceDiff{ 192 Destroy: true, 193 } 194 195 actual, err := r.Apply(s, d, nil) 196 if err == nil { 197 t.Fatal("should error") 198 } 199 200 expected := &terraform.InstanceState{ 201 ID: "bar", 202 Attributes: map[string]string{ 203 "id": "bar", 204 "foo": "42", 205 }, 206 } 207 208 if !reflect.DeepEqual(actual, expected) { 209 t.Fatalf("bad: %#v", actual) 210 } 211 } 212 213 func TestResourceApply_update(t *testing.T) { 214 r := &Resource{ 215 Schema: map[string]*Schema{ 216 "foo": &Schema{ 217 Type: TypeInt, 218 Optional: true, 219 }, 220 }, 221 } 222 223 r.Update = func(d *ResourceData, m interface{}) error { 224 d.Set("foo", 42) 225 return nil 226 } 227 228 s := &terraform.InstanceState{ 229 ID: "foo", 230 Attributes: map[string]string{ 231 "foo": "12", 232 }, 233 } 234 235 d := &terraform.InstanceDiff{ 236 Attributes: map[string]*terraform.ResourceAttrDiff{ 237 "foo": &terraform.ResourceAttrDiff{ 238 New: "13", 239 }, 240 }, 241 } 242 243 actual, err := r.Apply(s, d, nil) 244 if err != nil { 245 t.Fatalf("err: %s", err) 246 } 247 248 expected := &terraform.InstanceState{ 249 ID: "foo", 250 Attributes: map[string]string{ 251 "id": "foo", 252 "foo": "42", 253 }, 254 } 255 256 if !reflect.DeepEqual(actual, expected) { 257 t.Fatalf("bad: %#v", actual) 258 } 259 } 260 261 func TestResourceApply_updateNoCallback(t *testing.T) { 262 r := &Resource{ 263 Schema: map[string]*Schema{ 264 "foo": &Schema{ 265 Type: TypeInt, 266 Optional: true, 267 }, 268 }, 269 } 270 271 r.Update = nil 272 273 s := &terraform.InstanceState{ 274 ID: "foo", 275 Attributes: map[string]string{ 276 "foo": "12", 277 }, 278 } 279 280 d := &terraform.InstanceDiff{ 281 Attributes: map[string]*terraform.ResourceAttrDiff{ 282 "foo": &terraform.ResourceAttrDiff{ 283 New: "13", 284 }, 285 }, 286 } 287 288 actual, err := r.Apply(s, d, nil) 289 if err == nil { 290 t.Fatal("should error") 291 } 292 293 expected := &terraform.InstanceState{ 294 ID: "foo", 295 Attributes: map[string]string{ 296 "foo": "12", 297 }, 298 } 299 300 if !reflect.DeepEqual(actual, expected) { 301 t.Fatalf("bad: %#v", actual) 302 } 303 } 304 305 func TestResourceInternalValidate(t *testing.T) { 306 cases := []struct { 307 In *Resource 308 Err bool 309 }{ 310 { 311 nil, 312 true, 313 }, 314 315 // No optional and no required 316 { 317 &Resource{ 318 Schema: map[string]*Schema{ 319 "foo": &Schema{ 320 Type: TypeInt, 321 Optional: true, 322 Required: true, 323 }, 324 }, 325 }, 326 true, 327 }, 328 } 329 330 for i, tc := range cases { 331 err := tc.In.InternalValidate() 332 if (err != nil) != tc.Err { 333 t.Fatalf("%d: bad: %s", i, err) 334 } 335 } 336 } 337 338 func TestResourceRefresh(t *testing.T) { 339 r := &Resource{ 340 Schema: map[string]*Schema{ 341 "foo": &Schema{ 342 Type: TypeInt, 343 Optional: true, 344 }, 345 }, 346 } 347 348 r.Read = func(d *ResourceData, m interface{}) error { 349 if m != 42 { 350 return fmt.Errorf("meta not passed") 351 } 352 353 return d.Set("foo", d.Get("foo").(int)+1) 354 } 355 356 s := &terraform.InstanceState{ 357 ID: "bar", 358 Attributes: map[string]string{ 359 "foo": "12", 360 }, 361 } 362 363 expected := &terraform.InstanceState{ 364 ID: "bar", 365 Attributes: map[string]string{ 366 "id": "bar", 367 "foo": "13", 368 }, 369 } 370 371 actual, err := r.Refresh(s, 42) 372 if err != nil { 373 t.Fatalf("err: %s", err) 374 } 375 376 if !reflect.DeepEqual(actual, expected) { 377 t.Fatalf("bad: %#v", actual) 378 } 379 } 380 381 func TestResourceRefresh_delete(t *testing.T) { 382 r := &Resource{ 383 Schema: map[string]*Schema{ 384 "foo": &Schema{ 385 Type: TypeInt, 386 Optional: true, 387 }, 388 }, 389 } 390 391 r.Read = func(d *ResourceData, m interface{}) error { 392 d.SetId("") 393 return nil 394 } 395 396 s := &terraform.InstanceState{ 397 ID: "bar", 398 Attributes: map[string]string{ 399 "foo": "12", 400 }, 401 } 402 403 actual, err := r.Refresh(s, 42) 404 if err != nil { 405 t.Fatalf("err: %s", err) 406 } 407 408 if actual != nil { 409 t.Fatalf("bad: %#v", actual) 410 } 411 }