github.com/subuk/terraform@v0.6.14-0.20160317140351-de1567c2e732/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/autoscaling"
    10  	"github.com/aws/aws-sdk-go/service/ec2"
    11  	"github.com/aws/aws-sdk-go/service/elasticache"
    12  	"github.com/aws/aws-sdk-go/service/elb"
    13  	"github.com/aws/aws-sdk-go/service/rds"
    14  	"github.com/aws/aws-sdk-go/service/redshift"
    15  	"github.com/aws/aws-sdk-go/service/route53"
    16  	"github.com/hashicorp/terraform/flatmap"
    17  	"github.com/hashicorp/terraform/helper/schema"
    18  )
    19  
    20  // Returns test configuration
    21  func testConf() map[string]string {
    22  	return map[string]string{
    23  		"listener.#":                   "1",
    24  		"listener.0.lb_port":           "80",
    25  		"listener.0.lb_protocol":       "http",
    26  		"listener.0.instance_port":     "8000",
    27  		"listener.0.instance_protocol": "http",
    28  		"availability_zones.#":         "2",
    29  		"availability_zones.0":         "us-east-1a",
    30  		"availability_zones.1":         "us-east-1b",
    31  		"ingress.#":                    "1",
    32  		"ingress.0.protocol":           "icmp",
    33  		"ingress.0.from_port":          "1",
    34  		"ingress.0.to_port":            "-1",
    35  		"ingress.0.cidr_blocks.#":      "1",
    36  		"ingress.0.cidr_blocks.0":      "0.0.0.0/0",
    37  		"ingress.0.security_groups.#":  "2",
    38  		"ingress.0.security_groups.0":  "sg-11111",
    39  		"ingress.0.security_groups.1":  "foo/sg-22222",
    40  	}
    41  }
    42  
    43  func TestExpandIPPerms(t *testing.T) {
    44  	hash := schema.HashString
    45  
    46  	expanded := []interface{}{
    47  		map[string]interface{}{
    48  			"protocol":    "icmp",
    49  			"from_port":   1,
    50  			"to_port":     -1,
    51  			"cidr_blocks": []interface{}{"0.0.0.0/0"},
    52  			"security_groups": schema.NewSet(hash, []interface{}{
    53  				"sg-11111",
    54  				"foo/sg-22222",
    55  			}),
    56  		},
    57  		map[string]interface{}{
    58  			"protocol":  "icmp",
    59  			"from_port": 1,
    60  			"to_port":   -1,
    61  			"self":      true,
    62  		},
    63  	}
    64  	group := &ec2.SecurityGroup{
    65  		GroupId: aws.String("foo"),
    66  		VpcId:   aws.String("bar"),
    67  	}
    68  	perms, err := expandIPPerms(group, expanded)
    69  	if err != nil {
    70  		t.Fatalf("error expanding perms: %v", err)
    71  	}
    72  
    73  	expected := []ec2.IpPermission{
    74  		ec2.IpPermission{
    75  			IpProtocol: aws.String("icmp"),
    76  			FromPort:   aws.Int64(int64(1)),
    77  			ToPort:     aws.Int64(int64(-1)),
    78  			IpRanges:   []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("0.0.0.0/0")}},
    79  			UserIdGroupPairs: []*ec2.UserIdGroupPair{
    80  				&ec2.UserIdGroupPair{
    81  					UserId:  aws.String("foo"),
    82  					GroupId: aws.String("sg-22222"),
    83  				},
    84  				&ec2.UserIdGroupPair{
    85  					GroupId: aws.String("sg-11111"),
    86  				},
    87  			},
    88  		},
    89  		ec2.IpPermission{
    90  			IpProtocol: aws.String("icmp"),
    91  			FromPort:   aws.Int64(int64(1)),
    92  			ToPort:     aws.Int64(int64(-1)),
    93  			UserIdGroupPairs: []*ec2.UserIdGroupPair{
    94  				&ec2.UserIdGroupPair{
    95  					GroupId: aws.String("foo"),
    96  				},
    97  			},
    98  		},
    99  	}
   100  
   101  	exp := expected[0]
   102  	perm := perms[0]
   103  
   104  	if *exp.FromPort != *perm.FromPort {
   105  		t.Fatalf(
   106  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   107  			*perm.FromPort,
   108  			*exp.FromPort)
   109  	}
   110  
   111  	if *exp.IpRanges[0].CidrIp != *perm.IpRanges[0].CidrIp {
   112  		t.Fatalf(
   113  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   114  			*perm.IpRanges[0].CidrIp,
   115  			*exp.IpRanges[0].CidrIp)
   116  	}
   117  
   118  	if *exp.UserIdGroupPairs[0].UserId != *perm.UserIdGroupPairs[0].UserId {
   119  		t.Fatalf(
   120  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   121  			*perm.UserIdGroupPairs[0].UserId,
   122  			*exp.UserIdGroupPairs[0].UserId)
   123  	}
   124  
   125  	if *exp.UserIdGroupPairs[0].GroupId != *perm.UserIdGroupPairs[0].GroupId {
   126  		t.Fatalf(
   127  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   128  			*perm.UserIdGroupPairs[0].GroupId,
   129  			*exp.UserIdGroupPairs[0].GroupId)
   130  	}
   131  
   132  	if *exp.UserIdGroupPairs[1].GroupId != *perm.UserIdGroupPairs[1].GroupId {
   133  		t.Fatalf(
   134  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   135  			*perm.UserIdGroupPairs[1].GroupId,
   136  			*exp.UserIdGroupPairs[1].GroupId)
   137  	}
   138  
   139  	exp = expected[1]
   140  	perm = perms[1]
   141  
   142  	if *exp.UserIdGroupPairs[0].GroupId != *perm.UserIdGroupPairs[0].GroupId {
   143  		t.Fatalf(
   144  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   145  			*perm.UserIdGroupPairs[0].GroupId,
   146  			*exp.UserIdGroupPairs[0].GroupId)
   147  	}
   148  }
   149  
   150  func TestExpandIPPerms_NegOneProtocol(t *testing.T) {
   151  	hash := schema.HashString
   152  
   153  	expanded := []interface{}{
   154  		map[string]interface{}{
   155  			"protocol":    "-1",
   156  			"from_port":   0,
   157  			"to_port":     0,
   158  			"cidr_blocks": []interface{}{"0.0.0.0/0"},
   159  			"security_groups": schema.NewSet(hash, []interface{}{
   160  				"sg-11111",
   161  				"foo/sg-22222",
   162  			}),
   163  		},
   164  	}
   165  	group := &ec2.SecurityGroup{
   166  		GroupId: aws.String("foo"),
   167  		VpcId:   aws.String("bar"),
   168  	}
   169  
   170  	perms, err := expandIPPerms(group, expanded)
   171  	if err != nil {
   172  		t.Fatalf("error expanding perms: %v", err)
   173  	}
   174  
   175  	expected := []ec2.IpPermission{
   176  		ec2.IpPermission{
   177  			IpProtocol: aws.String("-1"),
   178  			FromPort:   aws.Int64(int64(0)),
   179  			ToPort:     aws.Int64(int64(0)),
   180  			IpRanges:   []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("0.0.0.0/0")}},
   181  			UserIdGroupPairs: []*ec2.UserIdGroupPair{
   182  				&ec2.UserIdGroupPair{
   183  					UserId:  aws.String("foo"),
   184  					GroupId: aws.String("sg-22222"),
   185  				},
   186  				&ec2.UserIdGroupPair{
   187  					GroupId: aws.String("sg-11111"),
   188  				},
   189  			},
   190  		},
   191  	}
   192  
   193  	exp := expected[0]
   194  	perm := perms[0]
   195  
   196  	if *exp.FromPort != *perm.FromPort {
   197  		t.Fatalf(
   198  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   199  			*perm.FromPort,
   200  			*exp.FromPort)
   201  	}
   202  
   203  	if *exp.IpRanges[0].CidrIp != *perm.IpRanges[0].CidrIp {
   204  		t.Fatalf(
   205  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   206  			*perm.IpRanges[0].CidrIp,
   207  			*exp.IpRanges[0].CidrIp)
   208  	}
   209  
   210  	if *exp.UserIdGroupPairs[0].UserId != *perm.UserIdGroupPairs[0].UserId {
   211  		t.Fatalf(
   212  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   213  			*perm.UserIdGroupPairs[0].UserId,
   214  			*exp.UserIdGroupPairs[0].UserId)
   215  	}
   216  
   217  	// Now test the error case. This *should* error when either from_port
   218  	// or to_port is not zero, but protocol is "-1".
   219  	errorCase := []interface{}{
   220  		map[string]interface{}{
   221  			"protocol":    "-1",
   222  			"from_port":   0,
   223  			"to_port":     65535,
   224  			"cidr_blocks": []interface{}{"0.0.0.0/0"},
   225  			"security_groups": schema.NewSet(hash, []interface{}{
   226  				"sg-11111",
   227  				"foo/sg-22222",
   228  			}),
   229  		},
   230  	}
   231  	securityGroups := &ec2.SecurityGroup{
   232  		GroupId: aws.String("foo"),
   233  		VpcId:   aws.String("bar"),
   234  	}
   235  
   236  	_, expandErr := expandIPPerms(securityGroups, errorCase)
   237  	if expandErr == nil {
   238  		t.Fatal("expandIPPerms should have errored!")
   239  	}
   240  }
   241  
   242  func TestExpandIPPerms_nonVPC(t *testing.T) {
   243  	hash := schema.HashString
   244  
   245  	expanded := []interface{}{
   246  		map[string]interface{}{
   247  			"protocol":    "icmp",
   248  			"from_port":   1,
   249  			"to_port":     -1,
   250  			"cidr_blocks": []interface{}{"0.0.0.0/0"},
   251  			"security_groups": schema.NewSet(hash, []interface{}{
   252  				"sg-11111",
   253  				"foo/sg-22222",
   254  			}),
   255  		},
   256  		map[string]interface{}{
   257  			"protocol":  "icmp",
   258  			"from_port": 1,
   259  			"to_port":   -1,
   260  			"self":      true,
   261  		},
   262  	}
   263  	group := &ec2.SecurityGroup{
   264  		GroupName: aws.String("foo"),
   265  	}
   266  	perms, err := expandIPPerms(group, expanded)
   267  	if err != nil {
   268  		t.Fatalf("error expanding perms: %v", err)
   269  	}
   270  
   271  	expected := []ec2.IpPermission{
   272  		ec2.IpPermission{
   273  			IpProtocol: aws.String("icmp"),
   274  			FromPort:   aws.Int64(int64(1)),
   275  			ToPort:     aws.Int64(int64(-1)),
   276  			IpRanges:   []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("0.0.0.0/0")}},
   277  			UserIdGroupPairs: []*ec2.UserIdGroupPair{
   278  				&ec2.UserIdGroupPair{
   279  					GroupName: aws.String("sg-22222"),
   280  				},
   281  				&ec2.UserIdGroupPair{
   282  					GroupName: aws.String("sg-11111"),
   283  				},
   284  			},
   285  		},
   286  		ec2.IpPermission{
   287  			IpProtocol: aws.String("icmp"),
   288  			FromPort:   aws.Int64(int64(1)),
   289  			ToPort:     aws.Int64(int64(-1)),
   290  			UserIdGroupPairs: []*ec2.UserIdGroupPair{
   291  				&ec2.UserIdGroupPair{
   292  					GroupName: aws.String("foo"),
   293  				},
   294  			},
   295  		},
   296  	}
   297  
   298  	exp := expected[0]
   299  	perm := perms[0]
   300  
   301  	if *exp.FromPort != *perm.FromPort {
   302  		t.Fatalf(
   303  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   304  			*perm.FromPort,
   305  			*exp.FromPort)
   306  	}
   307  
   308  	if *exp.IpRanges[0].CidrIp != *perm.IpRanges[0].CidrIp {
   309  		t.Fatalf(
   310  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   311  			*perm.IpRanges[0].CidrIp,
   312  			*exp.IpRanges[0].CidrIp)
   313  	}
   314  
   315  	if *exp.UserIdGroupPairs[0].GroupName != *perm.UserIdGroupPairs[0].GroupName {
   316  		t.Fatalf(
   317  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   318  			*perm.UserIdGroupPairs[0].GroupName,
   319  			*exp.UserIdGroupPairs[0].GroupName)
   320  	}
   321  
   322  	if *exp.UserIdGroupPairs[1].GroupName != *perm.UserIdGroupPairs[1].GroupName {
   323  		t.Fatalf(
   324  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   325  			*perm.UserIdGroupPairs[1].GroupName,
   326  			*exp.UserIdGroupPairs[1].GroupName)
   327  	}
   328  
   329  	exp = expected[1]
   330  	perm = perms[1]
   331  
   332  	if *exp.UserIdGroupPairs[0].GroupName != *perm.UserIdGroupPairs[0].GroupName {
   333  		t.Fatalf(
   334  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   335  			*perm.UserIdGroupPairs[0].GroupName,
   336  			*exp.UserIdGroupPairs[0].GroupName)
   337  	}
   338  }
   339  
   340  func TestExpandListeners(t *testing.T) {
   341  	expanded := []interface{}{
   342  		map[string]interface{}{
   343  			"instance_port":     8000,
   344  			"lb_port":           80,
   345  			"instance_protocol": "http",
   346  			"lb_protocol":       "http",
   347  		},
   348  		map[string]interface{}{
   349  			"instance_port":      8000,
   350  			"lb_port":            80,
   351  			"instance_protocol":  "https",
   352  			"lb_protocol":        "https",
   353  			"ssl_certificate_id": "something",
   354  		},
   355  	}
   356  	listeners, err := expandListeners(expanded)
   357  	if err != nil {
   358  		t.Fatalf("bad: %#v", err)
   359  	}
   360  
   361  	expected := &elb.Listener{
   362  		InstancePort:     aws.Int64(int64(8000)),
   363  		LoadBalancerPort: aws.Int64(int64(80)),
   364  		InstanceProtocol: aws.String("http"),
   365  		Protocol:         aws.String("http"),
   366  	}
   367  
   368  	if !reflect.DeepEqual(listeners[0], expected) {
   369  		t.Fatalf(
   370  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   371  			listeners[0],
   372  			expected)
   373  	}
   374  }
   375  
   376  // this test should produce an error from expandlisteners on an invalid
   377  // combination
   378  func TestExpandListeners_invalid(t *testing.T) {
   379  	expanded := []interface{}{
   380  		map[string]interface{}{
   381  			"instance_port":      8000,
   382  			"lb_port":            80,
   383  			"instance_protocol":  "http",
   384  			"lb_protocol":        "http",
   385  			"ssl_certificate_id": "something",
   386  		},
   387  	}
   388  	_, err := expandListeners(expanded)
   389  	if err != nil {
   390  		// Check the error we got
   391  		if !strings.Contains(err.Error(), "ssl_certificate_id may be set only when protocol") {
   392  			t.Fatalf("Got error in TestExpandListeners_invalid, but not what we expected: %s", err)
   393  		}
   394  	}
   395  
   396  	if err == nil {
   397  		t.Fatalf("Expected TestExpandListeners_invalid to fail, but passed")
   398  	}
   399  }
   400  
   401  func TestFlattenHealthCheck(t *testing.T) {
   402  	cases := []struct {
   403  		Input  *elb.HealthCheck
   404  		Output []map[string]interface{}
   405  	}{
   406  		{
   407  			Input: &elb.HealthCheck{
   408  				UnhealthyThreshold: aws.Int64(int64(10)),
   409  				HealthyThreshold:   aws.Int64(int64(10)),
   410  				Target:             aws.String("HTTP:80/"),
   411  				Timeout:            aws.Int64(int64(30)),
   412  				Interval:           aws.Int64(int64(30)),
   413  			},
   414  			Output: []map[string]interface{}{
   415  				map[string]interface{}{
   416  					"unhealthy_threshold": int64(10),
   417  					"healthy_threshold":   int64(10),
   418  					"target":              "HTTP:80/",
   419  					"timeout":             int64(30),
   420  					"interval":            int64(30),
   421  				},
   422  			},
   423  		},
   424  	}
   425  
   426  	for _, tc := range cases {
   427  		output := flattenHealthCheck(tc.Input)
   428  		if !reflect.DeepEqual(output, tc.Output) {
   429  			t.Fatalf("Got:\n\n%#v\n\nExpected:\n\n%#v", output, tc.Output)
   430  		}
   431  	}
   432  }
   433  
   434  func TestExpandStringList(t *testing.T) {
   435  	expanded := flatmap.Expand(testConf(), "availability_zones").([]interface{})
   436  	stringList := expandStringList(expanded)
   437  	expected := []*string{
   438  		aws.String("us-east-1a"),
   439  		aws.String("us-east-1b"),
   440  	}
   441  
   442  	if !reflect.DeepEqual(stringList, expected) {
   443  		t.Fatalf(
   444  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   445  			stringList,
   446  			expected)
   447  	}
   448  
   449  }
   450  
   451  func TestExpandParameters(t *testing.T) {
   452  	expanded := []interface{}{
   453  		map[string]interface{}{
   454  			"name":         "character_set_client",
   455  			"value":        "utf8",
   456  			"apply_method": "immediate",
   457  		},
   458  	}
   459  	parameters, err := expandParameters(expanded)
   460  	if err != nil {
   461  		t.Fatalf("bad: %#v", err)
   462  	}
   463  
   464  	expected := &rds.Parameter{
   465  		ParameterName:  aws.String("character_set_client"),
   466  		ParameterValue: aws.String("utf8"),
   467  		ApplyMethod:    aws.String("immediate"),
   468  	}
   469  
   470  	if !reflect.DeepEqual(parameters[0], expected) {
   471  		t.Fatalf(
   472  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   473  			parameters[0],
   474  			expected)
   475  	}
   476  }
   477  
   478  func TestexpandRedshiftParameters(t *testing.T) {
   479  	expanded := []interface{}{
   480  		map[string]interface{}{
   481  			"name":  "character_set_client",
   482  			"value": "utf8",
   483  		},
   484  	}
   485  	parameters, err := expandRedshiftParameters(expanded)
   486  	if err != nil {
   487  		t.Fatalf("bad: %#v", err)
   488  	}
   489  
   490  	expected := &redshift.Parameter{
   491  		ParameterName:  aws.String("character_set_client"),
   492  		ParameterValue: aws.String("utf8"),
   493  	}
   494  
   495  	if !reflect.DeepEqual(parameters[0], expected) {
   496  		t.Fatalf(
   497  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   498  			parameters[0],
   499  			expected)
   500  	}
   501  }
   502  
   503  func TestexpandElasticacheParameters(t *testing.T) {
   504  	expanded := []interface{}{
   505  		map[string]interface{}{
   506  			"name":         "activerehashing",
   507  			"value":        "yes",
   508  			"apply_method": "immediate",
   509  		},
   510  	}
   511  	parameters, err := expandElastiCacheParameters(expanded)
   512  	if err != nil {
   513  		t.Fatalf("bad: %#v", err)
   514  	}
   515  
   516  	expected := &elasticache.ParameterNameValue{
   517  		ParameterName:  aws.String("activerehashing"),
   518  		ParameterValue: aws.String("yes"),
   519  	}
   520  
   521  	if !reflect.DeepEqual(parameters[0], expected) {
   522  		t.Fatalf(
   523  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   524  			parameters[0],
   525  			expected)
   526  	}
   527  }
   528  
   529  func TestFlattenParameters(t *testing.T) {
   530  	cases := []struct {
   531  		Input  []*rds.Parameter
   532  		Output []map[string]interface{}
   533  	}{
   534  		{
   535  			Input: []*rds.Parameter{
   536  				&rds.Parameter{
   537  					ParameterName:  aws.String("character_set_client"),
   538  					ParameterValue: aws.String("utf8"),
   539  				},
   540  			},
   541  			Output: []map[string]interface{}{
   542  				map[string]interface{}{
   543  					"name":  "character_set_client",
   544  					"value": "utf8",
   545  				},
   546  			},
   547  		},
   548  	}
   549  
   550  	for _, tc := range cases {
   551  		output := flattenParameters(tc.Input)
   552  		if !reflect.DeepEqual(output, tc.Output) {
   553  			t.Fatalf("Got:\n\n%#v\n\nExpected:\n\n%#v", output, tc.Output)
   554  		}
   555  	}
   556  }
   557  
   558  func TestflattenRedshiftParameters(t *testing.T) {
   559  	cases := []struct {
   560  		Input  []*redshift.Parameter
   561  		Output []map[string]interface{}
   562  	}{
   563  		{
   564  			Input: []*redshift.Parameter{
   565  				&redshift.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 := flattenRedshiftParameters(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 TestflattenElasticacheParameters(t *testing.T) {
   588  	cases := []struct {
   589  		Input  []*elasticache.Parameter
   590  		Output []map[string]interface{}
   591  	}{
   592  		{
   593  			Input: []*elasticache.Parameter{
   594  				&elasticache.Parameter{
   595  					ParameterName:  aws.String("activerehashing"),
   596  					ParameterValue: aws.String("yes"),
   597  				},
   598  			},
   599  			Output: []map[string]interface{}{
   600  				map[string]interface{}{
   601  					"name":  "activerehashing",
   602  					"value": "yes",
   603  				},
   604  			},
   605  		},
   606  	}
   607  
   608  	for _, tc := range cases {
   609  		output := flattenElastiCacheParameters(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 TestExpandInstanceString(t *testing.T) {
   617  
   618  	expected := []*elb.Instance{
   619  		&elb.Instance{InstanceId: aws.String("test-one")},
   620  		&elb.Instance{InstanceId: aws.String("test-two")},
   621  	}
   622  
   623  	ids := []interface{}{
   624  		"test-one",
   625  		"test-two",
   626  	}
   627  
   628  	expanded := expandInstanceString(ids)
   629  
   630  	if !reflect.DeepEqual(expanded, expected) {
   631  		t.Fatalf("Expand Instance String output did not match.\nGot:\n%#v\n\nexpected:\n%#v", expanded, expected)
   632  	}
   633  }
   634  
   635  func TestFlattenNetworkInterfacesPrivateIPAddresses(t *testing.T) {
   636  	expanded := []*ec2.NetworkInterfacePrivateIpAddress{
   637  		&ec2.NetworkInterfacePrivateIpAddress{PrivateIpAddress: aws.String("192.168.0.1")},
   638  		&ec2.NetworkInterfacePrivateIpAddress{PrivateIpAddress: aws.String("192.168.0.2")},
   639  	}
   640  
   641  	result := flattenNetworkInterfacesPrivateIPAddresses(expanded)
   642  
   643  	if result == nil {
   644  		t.Fatal("result was nil")
   645  	}
   646  
   647  	if len(result) != 2 {
   648  		t.Fatalf("expected result had %d elements, but got %d", 2, len(result))
   649  	}
   650  
   651  	if result[0] != "192.168.0.1" {
   652  		t.Fatalf("expected ip to be 192.168.0.1, but was %s", result[0])
   653  	}
   654  
   655  	if result[1] != "192.168.0.2" {
   656  		t.Fatalf("expected ip to be 192.168.0.2, but was %s", result[1])
   657  	}
   658  }
   659  
   660  func TestFlattenGroupIdentifiers(t *testing.T) {
   661  	expanded := []*ec2.GroupIdentifier{
   662  		&ec2.GroupIdentifier{GroupId: aws.String("sg-001")},
   663  		&ec2.GroupIdentifier{GroupId: aws.String("sg-002")},
   664  	}
   665  
   666  	result := flattenGroupIdentifiers(expanded)
   667  
   668  	if len(result) != 2 {
   669  		t.Fatalf("expected result had %d elements, but got %d", 2, len(result))
   670  	}
   671  
   672  	if result[0] != "sg-001" {
   673  		t.Fatalf("expected id to be sg-001, but was %s", result[0])
   674  	}
   675  
   676  	if result[1] != "sg-002" {
   677  		t.Fatalf("expected id to be sg-002, but was %s", result[1])
   678  	}
   679  }
   680  
   681  func TestExpandPrivateIPAddresses(t *testing.T) {
   682  
   683  	ip1 := "192.168.0.1"
   684  	ip2 := "192.168.0.2"
   685  	flattened := []interface{}{
   686  		ip1,
   687  		ip2,
   688  	}
   689  
   690  	result := expandPrivateIPAddresses(flattened)
   691  
   692  	if len(result) != 2 {
   693  		t.Fatalf("expected result had %d elements, but got %d", 2, len(result))
   694  	}
   695  
   696  	if *result[0].PrivateIpAddress != "192.168.0.1" || !*result[0].Primary {
   697  		t.Fatalf("expected ip to be 192.168.0.1 and Primary, but got %v, %t", *result[0].PrivateIpAddress, *result[0].Primary)
   698  	}
   699  
   700  	if *result[1].PrivateIpAddress != "192.168.0.2" || *result[1].Primary {
   701  		t.Fatalf("expected ip to be 192.168.0.2 and not Primary, but got %v, %t", *result[1].PrivateIpAddress, *result[1].Primary)
   702  	}
   703  }
   704  
   705  func TestFlattenAttachment(t *testing.T) {
   706  	expanded := &ec2.NetworkInterfaceAttachment{
   707  		InstanceId:   aws.String("i-00001"),
   708  		DeviceIndex:  aws.Int64(int64(1)),
   709  		AttachmentId: aws.String("at-002"),
   710  	}
   711  
   712  	result := flattenAttachment(expanded)
   713  
   714  	if result == nil {
   715  		t.Fatal("expected result to have value, but got nil")
   716  	}
   717  
   718  	if result["instance"] != "i-00001" {
   719  		t.Fatalf("expected instance to be i-00001, but got %s", result["instance"])
   720  	}
   721  
   722  	if result["device_index"] != int64(1) {
   723  		t.Fatalf("expected device_index to be 1, but got %d", result["device_index"])
   724  	}
   725  
   726  	if result["attachment_id"] != "at-002" {
   727  		t.Fatalf("expected attachment_id to be at-002, but got %s", result["attachment_id"])
   728  	}
   729  }
   730  
   731  func TestFlattenResourceRecords(t *testing.T) {
   732  	expanded := []*route53.ResourceRecord{
   733  		&route53.ResourceRecord{
   734  			Value: aws.String("127.0.0.1"),
   735  		},
   736  		&route53.ResourceRecord{
   737  			Value: aws.String("127.0.0.3"),
   738  		},
   739  	}
   740  
   741  	result := flattenResourceRecords(expanded)
   742  
   743  	if result == nil {
   744  		t.Fatal("expected result to have value, but got nil")
   745  	}
   746  
   747  	if len(result) != 2 {
   748  		t.Fatal("expected result to have value, but got nil")
   749  	}
   750  }
   751  
   752  func TestFlattenAsgEnabledMetrics(t *testing.T) {
   753  	expanded := []*autoscaling.EnabledMetric{
   754  		&autoscaling.EnabledMetric{Granularity: aws.String("1Minute"), Metric: aws.String("GroupTotalInstances")},
   755  		&autoscaling.EnabledMetric{Granularity: aws.String("1Minute"), Metric: aws.String("GroupMaxSize")},
   756  	}
   757  
   758  	result := flattenAsgEnabledMetrics(expanded)
   759  
   760  	if len(result) != 2 {
   761  		t.Fatalf("expected result had %d elements, but got %d", 2, len(result))
   762  	}
   763  
   764  	if result[0] != "GroupTotalInstances" {
   765  		t.Fatalf("expected id to be GroupTotalInstances, but was %s", result[0])
   766  	}
   767  
   768  	if result[1] != "GroupMaxSize" {
   769  		t.Fatalf("expected id to be GroupMaxSize, but was %s", result[1])
   770  	}
   771  }
   772  
   773  func TestFlattenSecurityGroups(t *testing.T) {
   774  	cases := []struct {
   775  		ownerId  *string
   776  		pairs    []*ec2.UserIdGroupPair
   777  		expected []*ec2.GroupIdentifier
   778  	}{
   779  		// simple, no user id included (we ignore it mostly)
   780  		{
   781  			ownerId: aws.String("user1234"),
   782  			pairs: []*ec2.UserIdGroupPair{
   783  				&ec2.UserIdGroupPair{
   784  					GroupId: aws.String("sg-12345"),
   785  				},
   786  			},
   787  			expected: []*ec2.GroupIdentifier{
   788  				&ec2.GroupIdentifier{
   789  					GroupId: aws.String("sg-12345"),
   790  				},
   791  			},
   792  		},
   793  		// include the owner id, but keep it consitent with the same account. Tests
   794  		// EC2 classic situation
   795  		{
   796  			ownerId: aws.String("user1234"),
   797  			pairs: []*ec2.UserIdGroupPair{
   798  				&ec2.UserIdGroupPair{
   799  					GroupId: aws.String("sg-12345"),
   800  					UserId:  aws.String("user1234"),
   801  				},
   802  			},
   803  			expected: []*ec2.GroupIdentifier{
   804  				&ec2.GroupIdentifier{
   805  					GroupId: aws.String("sg-12345"),
   806  				},
   807  			},
   808  		},
   809  
   810  		// include the owner id, but from a different account. This is reflects
   811  		// EC2 Classic when refering to groups by name
   812  		{
   813  			ownerId: aws.String("user1234"),
   814  			pairs: []*ec2.UserIdGroupPair{
   815  				&ec2.UserIdGroupPair{
   816  					GroupId:   aws.String("sg-12345"),
   817  					GroupName: aws.String("somegroup"), // GroupName is only included in Classic
   818  					UserId:    aws.String("user4321"),
   819  				},
   820  			},
   821  			expected: []*ec2.GroupIdentifier{
   822  				&ec2.GroupIdentifier{
   823  					GroupId:   aws.String("sg-12345"),
   824  					GroupName: aws.String("user4321/somegroup"),
   825  				},
   826  			},
   827  		},
   828  
   829  		// include the owner id, but from a different account. This reflects in
   830  		// EC2 VPC when refering to groups by id
   831  		{
   832  			ownerId: aws.String("user1234"),
   833  			pairs: []*ec2.UserIdGroupPair{
   834  				&ec2.UserIdGroupPair{
   835  					GroupId: aws.String("sg-12345"),
   836  					UserId:  aws.String("user4321"),
   837  				},
   838  			},
   839  			expected: []*ec2.GroupIdentifier{
   840  				&ec2.GroupIdentifier{
   841  					GroupId: aws.String("user4321/sg-12345"),
   842  				},
   843  			},
   844  		},
   845  	}
   846  
   847  	for _, c := range cases {
   848  		out := flattenSecurityGroups(c.pairs, c.ownerId)
   849  		if !reflect.DeepEqual(out, c.expected) {
   850  			t.Fatalf("Error matching output and expected: %#v vs %#v", out, c.expected)
   851  		}
   852  	}
   853  }