github.com/minamijoyo/terraform@v0.7.8-0.20161029001309-18b3736ba44b/builtin/providers/aws/structure_test.go (about) 1 package aws 2 3 import ( 4 "reflect" 5 "strings" 6 "testing" 7 8 "github.com/aws/aws-sdk-go/aws" 9 "github.com/aws/aws-sdk-go/service/apigateway" 10 "github.com/aws/aws-sdk-go/service/autoscaling" 11 "github.com/aws/aws-sdk-go/service/ec2" 12 "github.com/aws/aws-sdk-go/service/elasticache" 13 "github.com/aws/aws-sdk-go/service/elb" 14 "github.com/aws/aws-sdk-go/service/kinesis" 15 "github.com/aws/aws-sdk-go/service/rds" 16 "github.com/aws/aws-sdk-go/service/redshift" 17 "github.com/aws/aws-sdk-go/service/route53" 18 "github.com/hashicorp/terraform/flatmap" 19 "github.com/hashicorp/terraform/helper/schema" 20 ) 21 22 // Returns test configuration 23 func testConf() map[string]string { 24 return map[string]string{ 25 "listener.#": "1", 26 "listener.0.lb_port": "80", 27 "listener.0.lb_protocol": "http", 28 "listener.0.instance_port": "8000", 29 "listener.0.instance_protocol": "http", 30 "availability_zones.#": "2", 31 "availability_zones.0": "us-east-1a", 32 "availability_zones.1": "us-east-1b", 33 "ingress.#": "1", 34 "ingress.0.protocol": "icmp", 35 "ingress.0.from_port": "1", 36 "ingress.0.to_port": "-1", 37 "ingress.0.cidr_blocks.#": "1", 38 "ingress.0.cidr_blocks.0": "0.0.0.0/0", 39 "ingress.0.security_groups.#": "2", 40 "ingress.0.security_groups.0": "sg-11111", 41 "ingress.0.security_groups.1": "foo/sg-22222", 42 } 43 } 44 45 func TestExpandIPPerms(t *testing.T) { 46 hash := schema.HashString 47 48 expanded := []interface{}{ 49 map[string]interface{}{ 50 "protocol": "icmp", 51 "from_port": 1, 52 "to_port": -1, 53 "cidr_blocks": []interface{}{"0.0.0.0/0"}, 54 "security_groups": schema.NewSet(hash, []interface{}{ 55 "sg-11111", 56 "foo/sg-22222", 57 }), 58 }, 59 map[string]interface{}{ 60 "protocol": "icmp", 61 "from_port": 1, 62 "to_port": -1, 63 "self": true, 64 }, 65 } 66 group := &ec2.SecurityGroup{ 67 GroupId: aws.String("foo"), 68 VpcId: aws.String("bar"), 69 } 70 perms, err := expandIPPerms(group, expanded) 71 if err != nil { 72 t.Fatalf("error expanding perms: %v", err) 73 } 74 75 expected := []ec2.IpPermission{ 76 ec2.IpPermission{ 77 IpProtocol: aws.String("icmp"), 78 FromPort: aws.Int64(int64(1)), 79 ToPort: aws.Int64(int64(-1)), 80 IpRanges: []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("0.0.0.0/0")}}, 81 UserIdGroupPairs: []*ec2.UserIdGroupPair{ 82 &ec2.UserIdGroupPair{ 83 UserId: aws.String("foo"), 84 GroupId: aws.String("sg-22222"), 85 }, 86 &ec2.UserIdGroupPair{ 87 GroupId: aws.String("sg-11111"), 88 }, 89 }, 90 }, 91 ec2.IpPermission{ 92 IpProtocol: aws.String("icmp"), 93 FromPort: aws.Int64(int64(1)), 94 ToPort: aws.Int64(int64(-1)), 95 UserIdGroupPairs: []*ec2.UserIdGroupPair{ 96 &ec2.UserIdGroupPair{ 97 GroupId: aws.String("foo"), 98 }, 99 }, 100 }, 101 } 102 103 exp := expected[0] 104 perm := perms[0] 105 106 if *exp.FromPort != *perm.FromPort { 107 t.Fatalf( 108 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 109 *perm.FromPort, 110 *exp.FromPort) 111 } 112 113 if *exp.IpRanges[0].CidrIp != *perm.IpRanges[0].CidrIp { 114 t.Fatalf( 115 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 116 *perm.IpRanges[0].CidrIp, 117 *exp.IpRanges[0].CidrIp) 118 } 119 120 if *exp.UserIdGroupPairs[0].UserId != *perm.UserIdGroupPairs[0].UserId { 121 t.Fatalf( 122 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 123 *perm.UserIdGroupPairs[0].UserId, 124 *exp.UserIdGroupPairs[0].UserId) 125 } 126 127 if *exp.UserIdGroupPairs[0].GroupId != *perm.UserIdGroupPairs[0].GroupId { 128 t.Fatalf( 129 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 130 *perm.UserIdGroupPairs[0].GroupId, 131 *exp.UserIdGroupPairs[0].GroupId) 132 } 133 134 if *exp.UserIdGroupPairs[1].GroupId != *perm.UserIdGroupPairs[1].GroupId { 135 t.Fatalf( 136 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 137 *perm.UserIdGroupPairs[1].GroupId, 138 *exp.UserIdGroupPairs[1].GroupId) 139 } 140 141 exp = expected[1] 142 perm = perms[1] 143 144 if *exp.UserIdGroupPairs[0].GroupId != *perm.UserIdGroupPairs[0].GroupId { 145 t.Fatalf( 146 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 147 *perm.UserIdGroupPairs[0].GroupId, 148 *exp.UserIdGroupPairs[0].GroupId) 149 } 150 } 151 152 func TestExpandIPPerms_NegOneProtocol(t *testing.T) { 153 hash := schema.HashString 154 155 expanded := []interface{}{ 156 map[string]interface{}{ 157 "protocol": "-1", 158 "from_port": 0, 159 "to_port": 0, 160 "cidr_blocks": []interface{}{"0.0.0.0/0"}, 161 "security_groups": schema.NewSet(hash, []interface{}{ 162 "sg-11111", 163 "foo/sg-22222", 164 }), 165 }, 166 } 167 group := &ec2.SecurityGroup{ 168 GroupId: aws.String("foo"), 169 VpcId: aws.String("bar"), 170 } 171 172 perms, err := expandIPPerms(group, expanded) 173 if err != nil { 174 t.Fatalf("error expanding perms: %v", err) 175 } 176 177 expected := []ec2.IpPermission{ 178 ec2.IpPermission{ 179 IpProtocol: aws.String("-1"), 180 FromPort: aws.Int64(int64(0)), 181 ToPort: aws.Int64(int64(0)), 182 IpRanges: []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("0.0.0.0/0")}}, 183 UserIdGroupPairs: []*ec2.UserIdGroupPair{ 184 &ec2.UserIdGroupPair{ 185 UserId: aws.String("foo"), 186 GroupId: aws.String("sg-22222"), 187 }, 188 &ec2.UserIdGroupPair{ 189 GroupId: aws.String("sg-11111"), 190 }, 191 }, 192 }, 193 } 194 195 exp := expected[0] 196 perm := perms[0] 197 198 if *exp.FromPort != *perm.FromPort { 199 t.Fatalf( 200 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 201 *perm.FromPort, 202 *exp.FromPort) 203 } 204 205 if *exp.IpRanges[0].CidrIp != *perm.IpRanges[0].CidrIp { 206 t.Fatalf( 207 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 208 *perm.IpRanges[0].CidrIp, 209 *exp.IpRanges[0].CidrIp) 210 } 211 212 if *exp.UserIdGroupPairs[0].UserId != *perm.UserIdGroupPairs[0].UserId { 213 t.Fatalf( 214 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 215 *perm.UserIdGroupPairs[0].UserId, 216 *exp.UserIdGroupPairs[0].UserId) 217 } 218 219 // Now test the error case. This *should* error when either from_port 220 // or to_port is not zero, but protocol is "-1". 221 errorCase := []interface{}{ 222 map[string]interface{}{ 223 "protocol": "-1", 224 "from_port": 0, 225 "to_port": 65535, 226 "cidr_blocks": []interface{}{"0.0.0.0/0"}, 227 "security_groups": schema.NewSet(hash, []interface{}{ 228 "sg-11111", 229 "foo/sg-22222", 230 }), 231 }, 232 } 233 securityGroups := &ec2.SecurityGroup{ 234 GroupId: aws.String("foo"), 235 VpcId: aws.String("bar"), 236 } 237 238 _, expandErr := expandIPPerms(securityGroups, errorCase) 239 if expandErr == nil { 240 t.Fatal("expandIPPerms should have errored!") 241 } 242 } 243 244 func TestExpandIPPerms_nonVPC(t *testing.T) { 245 hash := schema.HashString 246 247 expanded := []interface{}{ 248 map[string]interface{}{ 249 "protocol": "icmp", 250 "from_port": 1, 251 "to_port": -1, 252 "cidr_blocks": []interface{}{"0.0.0.0/0"}, 253 "security_groups": schema.NewSet(hash, []interface{}{ 254 "sg-11111", 255 "foo/sg-22222", 256 }), 257 }, 258 map[string]interface{}{ 259 "protocol": "icmp", 260 "from_port": 1, 261 "to_port": -1, 262 "self": true, 263 }, 264 } 265 group := &ec2.SecurityGroup{ 266 GroupName: aws.String("foo"), 267 } 268 perms, err := expandIPPerms(group, expanded) 269 if err != nil { 270 t.Fatalf("error expanding perms: %v", err) 271 } 272 273 expected := []ec2.IpPermission{ 274 ec2.IpPermission{ 275 IpProtocol: aws.String("icmp"), 276 FromPort: aws.Int64(int64(1)), 277 ToPort: aws.Int64(int64(-1)), 278 IpRanges: []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("0.0.0.0/0")}}, 279 UserIdGroupPairs: []*ec2.UserIdGroupPair{ 280 &ec2.UserIdGroupPair{ 281 GroupName: aws.String("sg-22222"), 282 }, 283 &ec2.UserIdGroupPair{ 284 GroupName: aws.String("sg-11111"), 285 }, 286 }, 287 }, 288 ec2.IpPermission{ 289 IpProtocol: aws.String("icmp"), 290 FromPort: aws.Int64(int64(1)), 291 ToPort: aws.Int64(int64(-1)), 292 UserIdGroupPairs: []*ec2.UserIdGroupPair{ 293 &ec2.UserIdGroupPair{ 294 GroupName: aws.String("foo"), 295 }, 296 }, 297 }, 298 } 299 300 exp := expected[0] 301 perm := perms[0] 302 303 if *exp.FromPort != *perm.FromPort { 304 t.Fatalf( 305 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 306 *perm.FromPort, 307 *exp.FromPort) 308 } 309 310 if *exp.IpRanges[0].CidrIp != *perm.IpRanges[0].CidrIp { 311 t.Fatalf( 312 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 313 *perm.IpRanges[0].CidrIp, 314 *exp.IpRanges[0].CidrIp) 315 } 316 317 if *exp.UserIdGroupPairs[0].GroupName != *perm.UserIdGroupPairs[0].GroupName { 318 t.Fatalf( 319 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 320 *perm.UserIdGroupPairs[0].GroupName, 321 *exp.UserIdGroupPairs[0].GroupName) 322 } 323 324 if *exp.UserIdGroupPairs[1].GroupName != *perm.UserIdGroupPairs[1].GroupName { 325 t.Fatalf( 326 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 327 *perm.UserIdGroupPairs[1].GroupName, 328 *exp.UserIdGroupPairs[1].GroupName) 329 } 330 331 exp = expected[1] 332 perm = perms[1] 333 334 if *exp.UserIdGroupPairs[0].GroupName != *perm.UserIdGroupPairs[0].GroupName { 335 t.Fatalf( 336 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 337 *perm.UserIdGroupPairs[0].GroupName, 338 *exp.UserIdGroupPairs[0].GroupName) 339 } 340 } 341 342 func TestExpandListeners(t *testing.T) { 343 expanded := []interface{}{ 344 map[string]interface{}{ 345 "instance_port": 8000, 346 "lb_port": 80, 347 "instance_protocol": "http", 348 "lb_protocol": "http", 349 }, 350 map[string]interface{}{ 351 "instance_port": 8000, 352 "lb_port": 80, 353 "instance_protocol": "https", 354 "lb_protocol": "https", 355 "ssl_certificate_id": "something", 356 }, 357 } 358 listeners, err := expandListeners(expanded) 359 if err != nil { 360 t.Fatalf("bad: %#v", err) 361 } 362 363 expected := &elb.Listener{ 364 InstancePort: aws.Int64(int64(8000)), 365 LoadBalancerPort: aws.Int64(int64(80)), 366 InstanceProtocol: aws.String("http"), 367 Protocol: aws.String("http"), 368 } 369 370 if !reflect.DeepEqual(listeners[0], expected) { 371 t.Fatalf( 372 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 373 listeners[0], 374 expected) 375 } 376 } 377 378 // this test should produce an error from expandlisteners on an invalid 379 // combination 380 func TestExpandListeners_invalid(t *testing.T) { 381 expanded := []interface{}{ 382 map[string]interface{}{ 383 "instance_port": 8000, 384 "lb_port": 80, 385 "instance_protocol": "http", 386 "lb_protocol": "http", 387 "ssl_certificate_id": "something", 388 }, 389 } 390 _, err := expandListeners(expanded) 391 if err != nil { 392 // Check the error we got 393 if !strings.Contains(err.Error(), "ssl_certificate_id may be set only when protocol") { 394 t.Fatalf("Got error in TestExpandListeners_invalid, but not what we expected: %s", err) 395 } 396 } 397 398 if err == nil { 399 t.Fatalf("Expected TestExpandListeners_invalid to fail, but passed") 400 } 401 } 402 403 func TestFlattenHealthCheck(t *testing.T) { 404 cases := []struct { 405 Input *elb.HealthCheck 406 Output []map[string]interface{} 407 }{ 408 { 409 Input: &elb.HealthCheck{ 410 UnhealthyThreshold: aws.Int64(int64(10)), 411 HealthyThreshold: aws.Int64(int64(10)), 412 Target: aws.String("HTTP:80/"), 413 Timeout: aws.Int64(int64(30)), 414 Interval: aws.Int64(int64(30)), 415 }, 416 Output: []map[string]interface{}{ 417 map[string]interface{}{ 418 "unhealthy_threshold": int64(10), 419 "healthy_threshold": int64(10), 420 "target": "HTTP:80/", 421 "timeout": int64(30), 422 "interval": int64(30), 423 }, 424 }, 425 }, 426 } 427 428 for _, tc := range cases { 429 output := flattenHealthCheck(tc.Input) 430 if !reflect.DeepEqual(output, tc.Output) { 431 t.Fatalf("Got:\n\n%#v\n\nExpected:\n\n%#v", output, tc.Output) 432 } 433 } 434 } 435 436 func TestExpandStringList(t *testing.T) { 437 expanded := flatmap.Expand(testConf(), "availability_zones").([]interface{}) 438 stringList := expandStringList(expanded) 439 expected := []*string{ 440 aws.String("us-east-1a"), 441 aws.String("us-east-1b"), 442 } 443 444 if !reflect.DeepEqual(stringList, expected) { 445 t.Fatalf( 446 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 447 stringList, 448 expected) 449 } 450 451 } 452 453 func TestExpandParameters(t *testing.T) { 454 expanded := []interface{}{ 455 map[string]interface{}{ 456 "name": "character_set_client", 457 "value": "utf8", 458 "apply_method": "immediate", 459 }, 460 } 461 parameters, err := expandParameters(expanded) 462 if err != nil { 463 t.Fatalf("bad: %#v", err) 464 } 465 466 expected := &rds.Parameter{ 467 ParameterName: aws.String("character_set_client"), 468 ParameterValue: aws.String("utf8"), 469 ApplyMethod: aws.String("immediate"), 470 } 471 472 if !reflect.DeepEqual(parameters[0], expected) { 473 t.Fatalf( 474 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 475 parameters[0], 476 expected) 477 } 478 } 479 480 func TestExpandRedshiftParameters(t *testing.T) { 481 expanded := []interface{}{ 482 map[string]interface{}{ 483 "name": "character_set_client", 484 "value": "utf8", 485 }, 486 } 487 parameters, err := expandRedshiftParameters(expanded) 488 if err != nil { 489 t.Fatalf("bad: %#v", err) 490 } 491 492 expected := &redshift.Parameter{ 493 ParameterName: aws.String("character_set_client"), 494 ParameterValue: aws.String("utf8"), 495 } 496 497 if !reflect.DeepEqual(parameters[0], expected) { 498 t.Fatalf( 499 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 500 parameters[0], 501 expected) 502 } 503 } 504 505 func TestExpandElasticacheParameters(t *testing.T) { 506 expanded := []interface{}{ 507 map[string]interface{}{ 508 "name": "activerehashing", 509 "value": "yes", 510 "apply_method": "immediate", 511 }, 512 } 513 parameters, err := expandElastiCacheParameters(expanded) 514 if err != nil { 515 t.Fatalf("bad: %#v", err) 516 } 517 518 expected := &elasticache.ParameterNameValue{ 519 ParameterName: aws.String("activerehashing"), 520 ParameterValue: aws.String("yes"), 521 } 522 523 if !reflect.DeepEqual(parameters[0], expected) { 524 t.Fatalf( 525 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 526 parameters[0], 527 expected) 528 } 529 } 530 531 func TestExpandStepAdjustments(t *testing.T) { 532 expanded := []interface{}{ 533 map[string]interface{}{ 534 "metric_interval_lower_bound": "1.0", 535 "metric_interval_upper_bound": "2.0", 536 "scaling_adjustment": 1, 537 }, 538 } 539 parameters, err := expandStepAdjustments(expanded) 540 if err != nil { 541 t.Fatalf("bad: %#v", err) 542 } 543 544 expected := &autoscaling.StepAdjustment{ 545 MetricIntervalLowerBound: aws.Float64(1.0), 546 MetricIntervalUpperBound: aws.Float64(2.0), 547 ScalingAdjustment: aws.Int64(int64(1)), 548 } 549 550 if !reflect.DeepEqual(parameters[0], expected) { 551 t.Fatalf( 552 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 553 parameters[0], 554 expected) 555 } 556 } 557 558 func TestFlattenParameters(t *testing.T) { 559 cases := []struct { 560 Input []*rds.Parameter 561 Output []map[string]interface{} 562 }{ 563 { 564 Input: []*rds.Parameter{ 565 &rds.Parameter{ 566 ParameterName: aws.String("character_set_client"), 567 ParameterValue: aws.String("utf8"), 568 }, 569 }, 570 Output: []map[string]interface{}{ 571 map[string]interface{}{ 572 "name": "character_set_client", 573 "value": "utf8", 574 }, 575 }, 576 }, 577 } 578 579 for _, tc := range cases { 580 output := flattenParameters(tc.Input) 581 if !reflect.DeepEqual(output, tc.Output) { 582 t.Fatalf("Got:\n\n%#v\n\nExpected:\n\n%#v", output, tc.Output) 583 } 584 } 585 } 586 587 func TestFlattenRedshiftParameters(t *testing.T) { 588 cases := []struct { 589 Input []*redshift.Parameter 590 Output []map[string]interface{} 591 }{ 592 { 593 Input: []*redshift.Parameter{ 594 &redshift.Parameter{ 595 ParameterName: aws.String("character_set_client"), 596 ParameterValue: aws.String("utf8"), 597 }, 598 }, 599 Output: []map[string]interface{}{ 600 map[string]interface{}{ 601 "name": "character_set_client", 602 "value": "utf8", 603 }, 604 }, 605 }, 606 } 607 608 for _, tc := range cases { 609 output := flattenRedshiftParameters(tc.Input) 610 if !reflect.DeepEqual(output, tc.Output) { 611 t.Fatalf("Got:\n\n%#v\n\nExpected:\n\n%#v", output, tc.Output) 612 } 613 } 614 } 615 616 func TestFlattenElasticacheParameters(t *testing.T) { 617 cases := []struct { 618 Input []*elasticache.Parameter 619 Output []map[string]interface{} 620 }{ 621 { 622 Input: []*elasticache.Parameter{ 623 &elasticache.Parameter{ 624 ParameterName: aws.String("activerehashing"), 625 ParameterValue: aws.String("yes"), 626 }, 627 }, 628 Output: []map[string]interface{}{ 629 map[string]interface{}{ 630 "name": "activerehashing", 631 "value": "yes", 632 }, 633 }, 634 }, 635 } 636 637 for _, tc := range cases { 638 output := flattenElastiCacheParameters(tc.Input) 639 if !reflect.DeepEqual(output, tc.Output) { 640 t.Fatalf("Got:\n\n%#v\n\nExpected:\n\n%#v", output, tc.Output) 641 } 642 } 643 } 644 645 func TestExpandInstanceString(t *testing.T) { 646 647 expected := []*elb.Instance{ 648 &elb.Instance{InstanceId: aws.String("test-one")}, 649 &elb.Instance{InstanceId: aws.String("test-two")}, 650 } 651 652 ids := []interface{}{ 653 "test-one", 654 "test-two", 655 } 656 657 expanded := expandInstanceString(ids) 658 659 if !reflect.DeepEqual(expanded, expected) { 660 t.Fatalf("Expand Instance String output did not match.\nGot:\n%#v\n\nexpected:\n%#v", expanded, expected) 661 } 662 } 663 664 func TestFlattenNetworkInterfacesPrivateIPAddresses(t *testing.T) { 665 expanded := []*ec2.NetworkInterfacePrivateIpAddress{ 666 &ec2.NetworkInterfacePrivateIpAddress{PrivateIpAddress: aws.String("192.168.0.1")}, 667 &ec2.NetworkInterfacePrivateIpAddress{PrivateIpAddress: aws.String("192.168.0.2")}, 668 } 669 670 result := flattenNetworkInterfacesPrivateIPAddresses(expanded) 671 672 if result == nil { 673 t.Fatal("result was nil") 674 } 675 676 if len(result) != 2 { 677 t.Fatalf("expected result had %d elements, but got %d", 2, len(result)) 678 } 679 680 if result[0] != "192.168.0.1" { 681 t.Fatalf("expected ip to be 192.168.0.1, but was %s", result[0]) 682 } 683 684 if result[1] != "192.168.0.2" { 685 t.Fatalf("expected ip to be 192.168.0.2, but was %s", result[1]) 686 } 687 } 688 689 func TestFlattenGroupIdentifiers(t *testing.T) { 690 expanded := []*ec2.GroupIdentifier{ 691 &ec2.GroupIdentifier{GroupId: aws.String("sg-001")}, 692 &ec2.GroupIdentifier{GroupId: aws.String("sg-002")}, 693 } 694 695 result := flattenGroupIdentifiers(expanded) 696 697 if len(result) != 2 { 698 t.Fatalf("expected result had %d elements, but got %d", 2, len(result)) 699 } 700 701 if result[0] != "sg-001" { 702 t.Fatalf("expected id to be sg-001, but was %s", result[0]) 703 } 704 705 if result[1] != "sg-002" { 706 t.Fatalf("expected id to be sg-002, but was %s", result[1]) 707 } 708 } 709 710 func TestExpandPrivateIPAddresses(t *testing.T) { 711 712 ip1 := "192.168.0.1" 713 ip2 := "192.168.0.2" 714 flattened := []interface{}{ 715 ip1, 716 ip2, 717 } 718 719 result := expandPrivateIPAddresses(flattened) 720 721 if len(result) != 2 { 722 t.Fatalf("expected result had %d elements, but got %d", 2, len(result)) 723 } 724 725 if *result[0].PrivateIpAddress != "192.168.0.1" || !*result[0].Primary { 726 t.Fatalf("expected ip to be 192.168.0.1 and Primary, but got %v, %t", *result[0].PrivateIpAddress, *result[0].Primary) 727 } 728 729 if *result[1].PrivateIpAddress != "192.168.0.2" || *result[1].Primary { 730 t.Fatalf("expected ip to be 192.168.0.2 and not Primary, but got %v, %t", *result[1].PrivateIpAddress, *result[1].Primary) 731 } 732 } 733 734 func TestFlattenAttachment(t *testing.T) { 735 expanded := &ec2.NetworkInterfaceAttachment{ 736 InstanceId: aws.String("i-00001"), 737 DeviceIndex: aws.Int64(int64(1)), 738 AttachmentId: aws.String("at-002"), 739 } 740 741 result := flattenAttachment(expanded) 742 743 if result == nil { 744 t.Fatal("expected result to have value, but got nil") 745 } 746 747 if result["instance"] != "i-00001" { 748 t.Fatalf("expected instance to be i-00001, but got %s", result["instance"]) 749 } 750 751 if result["device_index"] != int64(1) { 752 t.Fatalf("expected device_index to be 1, but got %d", result["device_index"]) 753 } 754 755 if result["attachment_id"] != "at-002" { 756 t.Fatalf("expected attachment_id to be at-002, but got %s", result["attachment_id"]) 757 } 758 } 759 760 func TestFlattenAttachmentWhenNoInstanceId(t *testing.T) { 761 expanded := &ec2.NetworkInterfaceAttachment{ 762 DeviceIndex: aws.Int64(int64(1)), 763 AttachmentId: aws.String("at-002"), 764 } 765 766 result := flattenAttachment(expanded) 767 768 if result == nil { 769 t.Fatal("expected result to have value, but got nil") 770 } 771 772 if result["instance"] != nil { 773 t.Fatalf("expected instance to be nil, but got %s", result["instance"]) 774 } 775 } 776 777 func TestFlattenStepAdjustments(t *testing.T) { 778 expanded := []*autoscaling.StepAdjustment{ 779 &autoscaling.StepAdjustment{ 780 MetricIntervalLowerBound: aws.Float64(1.0), 781 MetricIntervalUpperBound: aws.Float64(2.0), 782 ScalingAdjustment: aws.Int64(int64(1)), 783 }, 784 } 785 786 result := flattenStepAdjustments(expanded)[0] 787 if result == nil { 788 t.Fatal("expected result to have value, but got nil") 789 } 790 if result["metric_interval_lower_bound"] != float64(1.0) { 791 t.Fatalf("expected metric_interval_lower_bound to be 1.0, but got %d", result["metric_interval_lower_bound"]) 792 } 793 if result["metric_interval_upper_bound"] != float64(2.0) { 794 t.Fatalf("expected metric_interval_upper_bound to be 1.0, but got %d", result["metric_interval_upper_bound"]) 795 } 796 if result["scaling_adjustment"] != int64(1) { 797 t.Fatalf("expected scaling_adjustment to be 1, but got %d", result["scaling_adjustment"]) 798 } 799 } 800 801 func TestFlattenResourceRecords(t *testing.T) { 802 expanded := []*route53.ResourceRecord{ 803 &route53.ResourceRecord{ 804 Value: aws.String("127.0.0.1"), 805 }, 806 &route53.ResourceRecord{ 807 Value: aws.String("127.0.0.3"), 808 }, 809 } 810 811 result := flattenResourceRecords(expanded) 812 813 if result == nil { 814 t.Fatal("expected result to have value, but got nil") 815 } 816 817 if len(result) != 2 { 818 t.Fatal("expected result to have value, but got nil") 819 } 820 } 821 822 func TestFlattenAsgEnabledMetrics(t *testing.T) { 823 expanded := []*autoscaling.EnabledMetric{ 824 &autoscaling.EnabledMetric{Granularity: aws.String("1Minute"), Metric: aws.String("GroupTotalInstances")}, 825 &autoscaling.EnabledMetric{Granularity: aws.String("1Minute"), Metric: aws.String("GroupMaxSize")}, 826 } 827 828 result := flattenAsgEnabledMetrics(expanded) 829 830 if len(result) != 2 { 831 t.Fatalf("expected result had %d elements, but got %d", 2, len(result)) 832 } 833 834 if result[0] != "GroupTotalInstances" { 835 t.Fatalf("expected id to be GroupTotalInstances, but was %s", result[0]) 836 } 837 838 if result[1] != "GroupMaxSize" { 839 t.Fatalf("expected id to be GroupMaxSize, but was %s", result[1]) 840 } 841 } 842 843 func TestFlattenKinesisShardLevelMetrics(t *testing.T) { 844 expanded := []*kinesis.EnhancedMetrics{ 845 &kinesis.EnhancedMetrics{ 846 ShardLevelMetrics: []*string{ 847 aws.String("IncomingBytes"), 848 aws.String("IncomingRecords"), 849 }, 850 }, 851 } 852 result := flattenKinesisShardLevelMetrics(expanded) 853 if len(result) != 2 { 854 t.Fatalf("expected result had %d elements, but got %d", 2, len(result)) 855 } 856 if result[0] != "IncomingBytes" { 857 t.Fatalf("expected element 0 to be IncomingBytes, but was %s", result[0]) 858 } 859 if result[1] != "IncomingRecords" { 860 t.Fatalf("expected element 0 to be IncomingRecords, but was %s", result[1]) 861 } 862 } 863 864 func TestFlattenSecurityGroups(t *testing.T) { 865 cases := []struct { 866 ownerId *string 867 pairs []*ec2.UserIdGroupPair 868 expected []*ec2.GroupIdentifier 869 }{ 870 // simple, no user id included (we ignore it mostly) 871 { 872 ownerId: aws.String("user1234"), 873 pairs: []*ec2.UserIdGroupPair{ 874 &ec2.UserIdGroupPair{ 875 GroupId: aws.String("sg-12345"), 876 }, 877 }, 878 expected: []*ec2.GroupIdentifier{ 879 &ec2.GroupIdentifier{ 880 GroupId: aws.String("sg-12345"), 881 }, 882 }, 883 }, 884 // include the owner id, but keep it consitent with the same account. Tests 885 // EC2 classic situation 886 { 887 ownerId: aws.String("user1234"), 888 pairs: []*ec2.UserIdGroupPair{ 889 &ec2.UserIdGroupPair{ 890 GroupId: aws.String("sg-12345"), 891 UserId: aws.String("user1234"), 892 }, 893 }, 894 expected: []*ec2.GroupIdentifier{ 895 &ec2.GroupIdentifier{ 896 GroupId: aws.String("sg-12345"), 897 }, 898 }, 899 }, 900 901 // include the owner id, but from a different account. This is reflects 902 // EC2 Classic when referring to groups by name 903 { 904 ownerId: aws.String("user1234"), 905 pairs: []*ec2.UserIdGroupPair{ 906 &ec2.UserIdGroupPair{ 907 GroupId: aws.String("sg-12345"), 908 GroupName: aws.String("somegroup"), // GroupName is only included in Classic 909 UserId: aws.String("user4321"), 910 }, 911 }, 912 expected: []*ec2.GroupIdentifier{ 913 &ec2.GroupIdentifier{ 914 GroupId: aws.String("sg-12345"), 915 GroupName: aws.String("user4321/somegroup"), 916 }, 917 }, 918 }, 919 920 // include the owner id, but from a different account. This reflects in 921 // EC2 VPC when referring to groups by id 922 { 923 ownerId: aws.String("user1234"), 924 pairs: []*ec2.UserIdGroupPair{ 925 &ec2.UserIdGroupPair{ 926 GroupId: aws.String("sg-12345"), 927 UserId: aws.String("user4321"), 928 }, 929 }, 930 expected: []*ec2.GroupIdentifier{ 931 &ec2.GroupIdentifier{ 932 GroupId: aws.String("user4321/sg-12345"), 933 }, 934 }, 935 }, 936 } 937 938 for _, c := range cases { 939 out := flattenSecurityGroups(c.pairs, c.ownerId) 940 if !reflect.DeepEqual(out, c.expected) { 941 t.Fatalf("Error matching output and expected: %#v vs %#v", out, c.expected) 942 } 943 } 944 } 945 946 func TestFlattenApiGatewayThrottleSettings(t *testing.T) { 947 expectedBurstLimit := int64(140) 948 expectedRateLimit := 120.0 949 950 ts := &apigateway.ThrottleSettings{ 951 BurstLimit: aws.Int64(expectedBurstLimit), 952 RateLimit: aws.Float64(expectedRateLimit), 953 } 954 result := flattenApiGatewayThrottleSettings(ts) 955 956 if len(result) != 1 { 957 t.Fatalf("Expected map to have exactly 1 element, got %d", len(result)) 958 } 959 960 burstLimit, ok := result[0]["burst_limit"] 961 if !ok { 962 t.Fatal("Expected 'burst_limit' key in the map") 963 } 964 burstLimitInt, ok := burstLimit.(int64) 965 if !ok { 966 t.Fatal("Expected 'burst_limit' to be int") 967 } 968 if burstLimitInt != expectedBurstLimit { 969 t.Fatalf("Expected 'burst_limit' to equal %d, got %d", expectedBurstLimit, burstLimitInt) 970 } 971 972 rateLimit, ok := result[0]["rate_limit"] 973 if !ok { 974 t.Fatal("Expected 'rate_limit' key in the map") 975 } 976 rateLimitFloat, ok := rateLimit.(float64) 977 if !ok { 978 t.Fatal("Expected 'rate_limit' to be float64") 979 } 980 if rateLimitFloat != expectedRateLimit { 981 t.Fatalf("Expected 'rate_limit' to equal %f, got %f", expectedRateLimit, rateLimitFloat) 982 } 983 } 984 985 func TestFlattenApiGatewayStageKeys(t *testing.T) { 986 cases := []struct { 987 Input []*string 988 Output []map[string]interface{} 989 }{ 990 { 991 Input: []*string{ 992 aws.String("a1b2c3d4e5/dev"), 993 aws.String("e5d4c3b2a1/test"), 994 }, 995 Output: []map[string]interface{}{ 996 map[string]interface{}{ 997 "stage_name": "dev", 998 "rest_api_id": "a1b2c3d4e5", 999 }, 1000 map[string]interface{}{ 1001 "stage_name": "test", 1002 "rest_api_id": "e5d4c3b2a1", 1003 }, 1004 }, 1005 }, 1006 } 1007 1008 for _, tc := range cases { 1009 output := flattenApiGatewayStageKeys(tc.Input) 1010 if !reflect.DeepEqual(output, tc.Output) { 1011 t.Fatalf("Got:\n\n%#v\n\nExpected:\n\n%#v", output, tc.Output) 1012 } 1013 } 1014 } 1015 1016 func TestExpandPolicyAttributes(t *testing.T) { 1017 expanded := []interface{}{ 1018 map[string]interface{}{ 1019 "name": "Protocol-TLSv1", 1020 "value": "false", 1021 }, 1022 map[string]interface{}{ 1023 "name": "Protocol-TLSv1.1", 1024 "value": "false", 1025 }, 1026 map[string]interface{}{ 1027 "name": "Protocol-TLSv1.2", 1028 "value": "true", 1029 }, 1030 } 1031 attributes, err := expandPolicyAttributes(expanded) 1032 if err != nil { 1033 t.Fatalf("bad: %#v", err) 1034 } 1035 1036 if len(attributes) != 3 { 1037 t.Fatalf("expected number of attributes to be 3, but got %d", len(attributes)) 1038 } 1039 1040 expected := &elb.PolicyAttribute{ 1041 AttributeName: aws.String("Protocol-TLSv1.2"), 1042 AttributeValue: aws.String("true"), 1043 } 1044 1045 if !reflect.DeepEqual(attributes[2], expected) { 1046 t.Fatalf( 1047 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 1048 attributes[2], 1049 expected) 1050 } 1051 } 1052 1053 func TestExpandPolicyAttributes_invalid(t *testing.T) { 1054 expanded := []interface{}{ 1055 map[string]interface{}{ 1056 "name": "Protocol-TLSv1.2", 1057 "value": "true", 1058 }, 1059 } 1060 attributes, err := expandPolicyAttributes(expanded) 1061 if err != nil { 1062 t.Fatalf("bad: %#v", err) 1063 } 1064 1065 expected := &elb.PolicyAttribute{ 1066 AttributeName: aws.String("Protocol-TLSv1.2"), 1067 AttributeValue: aws.String("false"), 1068 } 1069 1070 if reflect.DeepEqual(attributes[0], expected) { 1071 t.Fatalf( 1072 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 1073 attributes[0], 1074 expected) 1075 } 1076 } 1077 1078 func TestExpandPolicyAttributes_empty(t *testing.T) { 1079 var expanded []interface{} 1080 1081 attributes, err := expandPolicyAttributes(expanded) 1082 if err != nil { 1083 t.Fatalf("bad: %#v", err) 1084 } 1085 1086 if len(attributes) != 0 { 1087 t.Fatalf("expected number of attributes to be 0, but got %d", len(attributes)) 1088 } 1089 } 1090 1091 func TestFlattenPolicyAttributes(t *testing.T) { 1092 cases := []struct { 1093 Input []*elb.PolicyAttributeDescription 1094 Output []interface{} 1095 }{ 1096 { 1097 Input: []*elb.PolicyAttributeDescription{ 1098 &elb.PolicyAttributeDescription{ 1099 AttributeName: aws.String("Protocol-TLSv1.2"), 1100 AttributeValue: aws.String("true"), 1101 }, 1102 }, 1103 Output: []interface{}{ 1104 map[string]string{ 1105 "name": "Protocol-TLSv1.2", 1106 "value": "true", 1107 }, 1108 }, 1109 }, 1110 } 1111 1112 for _, tc := range cases { 1113 output := flattenPolicyAttributes(tc.Input) 1114 if !reflect.DeepEqual(output, tc.Output) { 1115 t.Fatalf("Got:\n\n%#v\n\nExpected:\n\n%#v", output, tc.Output) 1116 } 1117 } 1118 } 1119 1120 func TestNormalizeJsonString(t *testing.T) { 1121 var err error 1122 var actual string 1123 1124 // Well formatted and valid. 1125 validJson := `{ 1126 "abc": { 1127 "def": 123, 1128 "xyz": [ 1129 { 1130 "a": "ホリネズミ" 1131 }, 1132 { 1133 "b": "1\\n2" 1134 } 1135 ] 1136 } 1137 }` 1138 expected := `{"abc":{"def":123,"xyz":[{"a":"ホリネズミ"},{"b":"1\\n2"}]}}` 1139 1140 actual, err = normalizeJsonString(validJson) 1141 if err != nil { 1142 t.Fatalf("Expected not to throw an error while parsing JSON, but got: %s", err) 1143 } 1144 1145 if actual != expected { 1146 t.Fatalf("Got:\n\n%s\n\nExpected:\n\n%s\n", actual, expected) 1147 } 1148 1149 // Well formatted but not valid, 1150 // missing closing squre bracket. 1151 invalidJson := `{ 1152 "abc": { 1153 "def": 123, 1154 "xyz": [ 1155 { 1156 "a": "1" 1157 } 1158 } 1159 } 1160 }` 1161 actual, err = normalizeJsonString(invalidJson) 1162 if err == nil { 1163 t.Fatalf("Expected to throw an error while parsing JSON, but got: %s", err) 1164 } 1165 1166 // We expect the invalid JSON to be shown back to us again. 1167 if actual != invalidJson { 1168 t.Fatalf("Got:\n\n%s\n\nExpected:\n\n%s\n", expected, invalidJson) 1169 } 1170 }