github.com/articulate/terraform@v0.6.13-0.20160303003731-8d31c93862de/builtin/providers/aws/resource_aws_security_group_rules_matching_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"log"
     5  	"testing"
     6  
     7  	"github.com/hashicorp/terraform/helper/schema"
     8  )
     9  
    10  // testing rulesForGroupPermissions
    11  func TestRulesMixedMatching(t *testing.T) {
    12  	cases := []struct {
    13  		groupId string
    14  		local   []interface{}
    15  		remote  []map[string]interface{}
    16  		saves   []map[string]interface{}
    17  	}{
    18  		{
    19  			local: []interface{}{
    20  				map[string]interface{}{
    21  					"from_port":       80,
    22  					"to_port":         8000,
    23  					"protocol":        "tcp",
    24  					"cidr_blocks":     []interface{}{"172.8.0.0/16", "10.0.0.0/16"},
    25  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
    26  				},
    27  			},
    28  			remote: []map[string]interface{}{
    29  				map[string]interface{}{
    30  					"from_port":       int64(80),
    31  					"to_port":         int64(8000),
    32  					"protocol":        "tcp",
    33  					"cidr_blocks":     []string{"172.8.0.0/16", "10.0.0.0/16"},
    34  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
    35  				},
    36  			},
    37  			saves: []map[string]interface{}{
    38  				map[string]interface{}{
    39  					"from_port":       80,
    40  					"to_port":         8000,
    41  					"protocol":        "tcp",
    42  					"cidr_blocks":     []string{"172.8.0.0/16", "10.0.0.0/16"},
    43  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
    44  				},
    45  			},
    46  		},
    47  		{
    48  			local: []interface{}{
    49  				map[string]interface{}{
    50  					"from_port":       80,
    51  					"to_port":         8000,
    52  					"protocol":        "tcp",
    53  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
    54  				},
    55  			},
    56  			remote: []map[string]interface{}{
    57  				map[string]interface{}{
    58  					"from_port":       int64(80),
    59  					"to_port":         int64(8000),
    60  					"protocol":        "tcp",
    61  					"cidr_blocks":     []string{"172.8.0.0/16", "10.0.0.0/16"},
    62  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
    63  				},
    64  			},
    65  			saves: []map[string]interface{}{
    66  				map[string]interface{}{
    67  					"from_port":       80,
    68  					"to_port":         8000,
    69  					"protocol":        "tcp",
    70  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
    71  				},
    72  				map[string]interface{}{
    73  					"from_port":   int64(80),
    74  					"to_port":     int64(8000),
    75  					"protocol":    "tcp",
    76  					"cidr_blocks": []string{"172.8.0.0/16", "10.0.0.0/16"},
    77  				},
    78  			},
    79  		},
    80  		{
    81  			local: []interface{}{
    82  				map[string]interface{}{
    83  					"from_port":   80,
    84  					"to_port":     8000,
    85  					"protocol":    "tcp",
    86  					"cidr_blocks": []interface{}{"172.8.0.0/16", "10.0.0.0/16"},
    87  				},
    88  			},
    89  			remote: []map[string]interface{}{
    90  				map[string]interface{}{
    91  					"from_port":   int64(80),
    92  					"to_port":     int64(8000),
    93  					"protocol":    "tcp",
    94  					"cidr_blocks": []string{"172.8.0.0/16", "10.0.0.0/16"},
    95  				},
    96  			},
    97  			saves: []map[string]interface{}{
    98  				map[string]interface{}{
    99  					"from_port":   80,
   100  					"to_port":     8000,
   101  					"protocol":    "tcp",
   102  					"cidr_blocks": []string{"172.8.0.0/16", "10.0.0.0/16"},
   103  				},
   104  			},
   105  		},
   106  		{
   107  			local: []interface{}{
   108  				map[string]interface{}{
   109  					"from_port":       80,
   110  					"to_port":         8000,
   111  					"protocol":        "tcp",
   112  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   113  				},
   114  			},
   115  			remote: []map[string]interface{}{
   116  				map[string]interface{}{
   117  					"from_port":       int64(80),
   118  					"to_port":         int64(8000),
   119  					"protocol":        "tcp",
   120  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   121  				},
   122  			},
   123  			saves: []map[string]interface{}{
   124  				map[string]interface{}{
   125  					"from_port":       80,
   126  					"to_port":         8000,
   127  					"protocol":        "tcp",
   128  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   129  				},
   130  			},
   131  		},
   132  		{
   133  			local: []interface{}{
   134  				map[string]interface{}{
   135  					"from_port":   80,
   136  					"to_port":     8000,
   137  					"protocol":    "tcp",
   138  					"cidr_blocks": []interface{}{"172.8.0.0/16"},
   139  				},
   140  				map[string]interface{}{
   141  					"from_port":   80,
   142  					"to_port":     8000,
   143  					"protocol":    "tcp",
   144  					"cidr_blocks": []interface{}{"192.168.0.0/16"},
   145  				},
   146  			},
   147  			remote: []map[string]interface{}{
   148  				map[string]interface{}{
   149  					"from_port":   int64(80),
   150  					"to_port":     int64(8000),
   151  					"protocol":    "tcp",
   152  					"cidr_blocks": []string{"172.8.0.0/16", "192.168.0.0/16"},
   153  				},
   154  			},
   155  			saves: []map[string]interface{}{
   156  				map[string]interface{}{
   157  					"from_port":   80,
   158  					"to_port":     8000,
   159  					"protocol":    "tcp",
   160  					"cidr_blocks": []string{"172.8.0.0/16"},
   161  				},
   162  				map[string]interface{}{
   163  					"from_port":   80,
   164  					"to_port":     8000,
   165  					"protocol":    "tcp",
   166  					"cidr_blocks": []string{"192.168.0.0/16"},
   167  				},
   168  			},
   169  		},
   170  		{
   171  			local: []interface{}{},
   172  			remote: []map[string]interface{}{
   173  				map[string]interface{}{
   174  					"from_port":   int64(80),
   175  					"to_port":     int64(8000),
   176  					"protocol":    "tcp",
   177  					"cidr_blocks": []string{"172.8.0.0/16", "10.0.0.0/16"},
   178  				},
   179  			},
   180  			saves: []map[string]interface{}{
   181  				map[string]interface{}{
   182  					"from_port":   int64(80),
   183  					"to_port":     int64(8000),
   184  					"protocol":    "tcp",
   185  					"cidr_blocks": []string{"172.8.0.0/16", "10.0.0.0/16"},
   186  				},
   187  			},
   188  		},
   189  		// local and remote differ
   190  		{
   191  			local: []interface{}{
   192  				map[string]interface{}{
   193  					"from_port":   80,
   194  					"to_port":     8000,
   195  					"protocol":    "tcp",
   196  					"cidr_blocks": []interface{}{"172.8.0.0/16"},
   197  				},
   198  			},
   199  			remote: []map[string]interface{}{
   200  				map[string]interface{}{
   201  					"from_port":   int64(80),
   202  					"to_port":     int64(8000),
   203  					"protocol":    "tcp",
   204  					"cidr_blocks": []string{"10.0.0.0/16"},
   205  				},
   206  			},
   207  			// Because this is the remote rule being saved, we need to check for int64
   208  			// encoding. We could convert this code, but ultimately Terraform doesn't
   209  			// care it's for the reflect.DeepEqual in this test
   210  			saves: []map[string]interface{}{
   211  				map[string]interface{}{
   212  					"from_port":   int64(80),
   213  					"to_port":     int64(8000),
   214  					"protocol":    "tcp",
   215  					"cidr_blocks": []string{"10.0.0.0/16"},
   216  				},
   217  			},
   218  		},
   219  		// local with more rules and the remote (the remote should then be saved)
   220  		{
   221  			local: []interface{}{
   222  				map[string]interface{}{
   223  					"from_port":   80,
   224  					"to_port":     8000,
   225  					"protocol":    "tcp",
   226  					"cidr_blocks": []interface{}{"172.8.0.0/16", "10.8.0.0/16", "192.168.0.0/16"},
   227  				},
   228  			},
   229  			remote: []map[string]interface{}{
   230  				map[string]interface{}{
   231  					"from_port":   int64(80),
   232  					"to_port":     int64(8000),
   233  					"protocol":    "tcp",
   234  					"cidr_blocks": []string{"172.8.0.0/16", "192.168.0.0/16"},
   235  				},
   236  			},
   237  			saves: []map[string]interface{}{
   238  				map[string]interface{}{
   239  					"from_port":   int64(80),
   240  					"to_port":     int64(8000),
   241  					"protocol":    "tcp",
   242  					"cidr_blocks": []string{"172.8.0.0/16", "192.168.0.0/16"},
   243  				},
   244  			},
   245  		},
   246  		// 3 local rules
   247  		// this should trigger a diff (not shown)
   248  		{
   249  			local: []interface{}{
   250  				map[string]interface{}{
   251  					"from_port":   80,
   252  					"to_port":     8000,
   253  					"protocol":    "tcp",
   254  					"cidr_blocks": []interface{}{"172.8.0.0/16"},
   255  				},
   256  				map[string]interface{}{
   257  					"from_port":   80,
   258  					"to_port":     8000,
   259  					"protocol":    "tcp",
   260  					"cidr_blocks": []interface{}{"10.8.0.0/16"},
   261  				},
   262  				map[string]interface{}{
   263  					"from_port":   80,
   264  					"to_port":     8000,
   265  					"protocol":    "tcp",
   266  					"cidr_blocks": []interface{}{"192.168.0.0/16"},
   267  				},
   268  			},
   269  			remote: []map[string]interface{}{
   270  				map[string]interface{}{
   271  					"from_port":   int64(80),
   272  					"to_port":     int64(8000),
   273  					"protocol":    "tcp",
   274  					"cidr_blocks": []string{"172.8.0.0/16", "192.168.0.0/16"},
   275  				},
   276  			},
   277  			saves: []map[string]interface{}{
   278  				map[string]interface{}{
   279  					"from_port":   80,
   280  					"to_port":     8000,
   281  					"protocol":    "tcp",
   282  					"cidr_blocks": []string{"172.8.0.0/16"},
   283  				},
   284  				map[string]interface{}{
   285  					"from_port":   80,
   286  					"to_port":     8000,
   287  					"protocol":    "tcp",
   288  					"cidr_blocks": []string{"192.168.0.0/16"},
   289  				},
   290  			},
   291  		},
   292  		// a local rule with 2 cidrs, remote has 4 cidrs, shoudl be saved to match
   293  		// the local but also an extra rule found
   294  		{
   295  			local: []interface{}{
   296  				map[string]interface{}{
   297  					"from_port":   80,
   298  					"to_port":     8000,
   299  					"protocol":    "tcp",
   300  					"cidr_blocks": []interface{}{"172.8.0.0/16", "10.8.0.0/16"},
   301  				},
   302  			},
   303  			remote: []map[string]interface{}{
   304  				map[string]interface{}{
   305  					"from_port":   int64(80),
   306  					"to_port":     int64(8000),
   307  					"protocol":    "tcp",
   308  					"cidr_blocks": []string{"172.8.0.0/16", "192.168.0.0/16", "10.8.0.0/16", "206.8.0.0/16"},
   309  				},
   310  			},
   311  			saves: []map[string]interface{}{
   312  				map[string]interface{}{
   313  					"from_port":   80,
   314  					"to_port":     8000,
   315  					"protocol":    "tcp",
   316  					"cidr_blocks": []string{"172.8.0.0/16", "10.8.0.0/16"},
   317  				},
   318  				map[string]interface{}{
   319  					"from_port":   int64(80),
   320  					"to_port":     int64(8000),
   321  					"protocol":    "tcp",
   322  					"cidr_blocks": []string{"192.168.0.0/16", "206.8.0.0/16"},
   323  				},
   324  			},
   325  		},
   326  		// testing some SGS
   327  		{
   328  			local: []interface{}{},
   329  			remote: []map[string]interface{}{
   330  				map[string]interface{}{
   331  					"from_port":       int64(22),
   332  					"to_port":         int64(22),
   333  					"protocol":        "tcp",
   334  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876"}),
   335  				},
   336  			},
   337  			saves: []map[string]interface{}{
   338  				map[string]interface{}{
   339  					// we're saving the remote, so it will be int64 encoded
   340  					"from_port":       int64(22),
   341  					"to_port":         int64(22),
   342  					"protocol":        "tcp",
   343  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876"}),
   344  				},
   345  			},
   346  		},
   347  		// two local blocks that match a single remote group, but are saved as two
   348  		{
   349  			local: []interface{}{
   350  				map[string]interface{}{
   351  					"from_port":       22,
   352  					"to_port":         22,
   353  					"protocol":        "tcp",
   354  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876"}),
   355  				},
   356  				map[string]interface{}{
   357  					"from_port":       22,
   358  					"to_port":         22,
   359  					"protocol":        "tcp",
   360  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-4444"}),
   361  				},
   362  			},
   363  			remote: []map[string]interface{}{
   364  				map[string]interface{}{
   365  					"from_port": int64(22),
   366  					"to_port":   int64(22),
   367  					"protocol":  "tcp",
   368  					"security_groups": schema.NewSet(
   369  						schema.HashString,
   370  						[]interface{}{
   371  							"sg-9876",
   372  							"sg-4444",
   373  						},
   374  					),
   375  				},
   376  			},
   377  			saves: []map[string]interface{}{
   378  				map[string]interface{}{
   379  					"from_port": 22,
   380  					"to_port":   22,
   381  					"protocol":  "tcp",
   382  					"security_groups": schema.NewSet(
   383  						schema.HashString,
   384  						[]interface{}{
   385  							"sg-9876",
   386  						},
   387  					),
   388  				},
   389  				map[string]interface{}{
   390  					"from_port": 22,
   391  					"to_port":   22,
   392  					"protocol":  "tcp",
   393  					"security_groups": schema.NewSet(
   394  						schema.HashString,
   395  						[]interface{}{
   396  							"sg-4444",
   397  						},
   398  					),
   399  				},
   400  			},
   401  		},
   402  		// test self with other rules
   403  		{
   404  			local: []interface{}{
   405  				map[string]interface{}{
   406  					"from_port":       22,
   407  					"to_port":         22,
   408  					"protocol":        "tcp",
   409  					"self":            true,
   410  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   411  				},
   412  			},
   413  			remote: []map[string]interface{}{
   414  				map[string]interface{}{
   415  					"from_port": int64(22),
   416  					"to_port":   int64(22),
   417  					"protocol":  "tcp",
   418  					"self":      true,
   419  				},
   420  			},
   421  			saves: []map[string]interface{}{
   422  				map[string]interface{}{
   423  					"from_port": int64(22),
   424  					"to_port":   int64(22),
   425  					"protocol":  "tcp",
   426  					"self":      true,
   427  				},
   428  			},
   429  		},
   430  		// test self
   431  		{
   432  			local: []interface{}{
   433  				map[string]interface{}{
   434  					"from_port": 22,
   435  					"to_port":   22,
   436  					"protocol":  "tcp",
   437  					"self":      true,
   438  				},
   439  			},
   440  			remote: []map[string]interface{}{
   441  				map[string]interface{}{
   442  					"from_port": int64(22),
   443  					"to_port":   int64(22),
   444  					"protocol":  "tcp",
   445  					"self":      true,
   446  				},
   447  			},
   448  			saves: []map[string]interface{}{
   449  				map[string]interface{}{
   450  					"from_port": int64(22),
   451  					"to_port":   int64(22),
   452  					"protocol":  "tcp",
   453  					"self":      true,
   454  				},
   455  			},
   456  		},
   457  		{
   458  			local: []interface{}{
   459  				map[string]interface{}{
   460  					"from_port":       22,
   461  					"to_port":         22,
   462  					"protocol":        "tcp",
   463  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   464  				},
   465  			},
   466  			remote: []map[string]interface{}{
   467  				map[string]interface{}{
   468  					"from_port": int64(22),
   469  					"to_port":   int64(22),
   470  					"protocol":  "tcp",
   471  					"self":      true,
   472  				},
   473  			},
   474  			saves: []map[string]interface{}{
   475  				map[string]interface{}{
   476  					"from_port": int64(22),
   477  					"to_port":   int64(22),
   478  					"protocol":  "tcp",
   479  					"self":      true,
   480  				},
   481  			},
   482  		},
   483  		// mix of sgs and cidrs
   484  		{
   485  			local: []interface{}{
   486  				map[string]interface{}{
   487  					"from_port":   80,
   488  					"to_port":     8000,
   489  					"protocol":    "tcp",
   490  					"cidr_blocks": []interface{}{"172.8.0.0/16", "10.8.0.0/16", "192.168.0.0/16"},
   491  				},
   492  				map[string]interface{}{
   493  					"from_port":       80,
   494  					"to_port":         8000,
   495  					"protocol":        "tcp",
   496  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   497  				},
   498  			},
   499  			remote: []map[string]interface{}{
   500  				map[string]interface{}{
   501  					"from_port":       int64(80),
   502  					"to_port":         int64(8000),
   503  					"protocol":        "tcp",
   504  					"cidr_blocks":     []string{"172.8.0.0/16", "192.168.0.0/16"},
   505  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   506  				},
   507  			},
   508  			saves: []map[string]interface{}{
   509  				map[string]interface{}{
   510  					"from_port":   int64(80),
   511  					"to_port":     int64(8000),
   512  					"protocol":    "tcp",
   513  					"cidr_blocks": []string{"172.8.0.0/16", "192.168.0.0/16"},
   514  				},
   515  				map[string]interface{}{
   516  					"from_port":       int64(80),
   517  					"to_port":         int64(8000),
   518  					"protocol":        "tcp",
   519  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   520  				},
   521  			},
   522  		},
   523  		{
   524  			local: []interface{}{
   525  				map[string]interface{}{
   526  					"from_port":   80,
   527  					"to_port":     8000,
   528  					"protocol":    "tcp",
   529  					"cidr_blocks": []interface{}{"172.8.0.0/16", "10.8.0.0/16", "192.168.0.0/16"},
   530  				},
   531  				map[string]interface{}{
   532  					"from_port": 80,
   533  					"to_port":   8000,
   534  					"protocol":  "tcp",
   535  					"self":      true,
   536  				},
   537  			},
   538  			remote: []map[string]interface{}{
   539  				map[string]interface{}{
   540  					"from_port":       int64(80),
   541  					"to_port":         int64(8000),
   542  					"protocol":        "tcp",
   543  					"cidr_blocks":     []string{"172.8.0.0/16", "192.168.0.0/16"},
   544  					"self":            true,
   545  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   546  				},
   547  			},
   548  			saves: []map[string]interface{}{
   549  				map[string]interface{}{
   550  					"from_port": 80,
   551  					"to_port":   8000,
   552  					"protocol":  "tcp",
   553  					"self":      true,
   554  				},
   555  				map[string]interface{}{
   556  					"from_port":       int64(80),
   557  					"to_port":         int64(8000),
   558  					"protocol":        "tcp",
   559  					"cidr_blocks":     []string{"172.8.0.0/16", "192.168.0.0/16"},
   560  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   561  				},
   562  			},
   563  		},
   564  	}
   565  	for i, c := range cases {
   566  		saves := matchRules("ingress", c.local, c.remote)
   567  		log.Printf("\n======\n\nSaves:\n%#v\n\nCS Saves:\n%#v\n\n======\n", saves, c.saves)
   568  		log.Printf("\n\tTest %d:\n", i)
   569  
   570  		if len(saves) != len(c.saves) {
   571  			t.Fatalf("Expected %d saves, got %d", len(c.saves), len(saves))
   572  		}
   573  
   574  		shouldFind := len(c.saves)
   575  		var found int
   576  		for _, s := range saves {
   577  			for _, cs := range c.saves {
   578  				// deep equal cannot compare schema.Set's directly
   579  				// make sure we're not failing the reflect b/c of ports/type
   580  				for _, attr := range []string{"to_port", "from_port", "type"} {
   581  					if s[attr] != cs[attr] {
   582  						continue
   583  					}
   584  				}
   585  
   586  				var numExpectedCidrs, numExpectedSGs, numRemoteCidrs, numRemoteSGs int
   587  				// var matchingCidrs []string
   588  				// var matchingSGs []string
   589  
   590  				var cidrsMatch, sGsMatch bool
   591  
   592  				if _, ok := s["cidr_blocks"]; ok {
   593  					switch s["cidr_blocks"].(type) {
   594  					case []string:
   595  						numExpectedCidrs = len(s["cidr_blocks"].([]string))
   596  					default:
   597  						numExpectedCidrs = len(s["cidr_blocks"].([]interface{}))
   598  					}
   599  
   600  				}
   601  				if _, ok := s["security_groups"]; ok {
   602  					numExpectedSGs = len(s["security_groups"].(*schema.Set).List())
   603  				}
   604  
   605  				if _, ok := cs["cidr_blocks"]; ok {
   606  					numRemoteCidrs = len(cs["cidr_blocks"].([]string))
   607  				}
   608  
   609  				if _, ok := cs["security_groups"]; ok {
   610  					numRemoteSGs = len(cs["security_groups"].(*schema.Set).List())
   611  				}
   612  
   613  				// skip early
   614  				if numExpectedSGs != numRemoteSGs {
   615  					log.Printf("\n\ncontinuning on numRemoteSGs \n\n")
   616  					continue
   617  				}
   618  				if numExpectedCidrs != numRemoteCidrs {
   619  					log.Printf("\n\ncontinuning numRemoteCidrs\n\n")
   620  					continue
   621  				}
   622  
   623  				if numExpectedCidrs == 0 {
   624  					cidrsMatch = true
   625  				}
   626  				if numExpectedSGs == 0 {
   627  					sGsMatch = true
   628  				}
   629  
   630  				// convert save cidrs to set
   631  				var lcs []interface{}
   632  				if _, ok := s["cidr_blocks"]; ok {
   633  					switch s["cidr_blocks"].(type) {
   634  					case []string:
   635  						for _, c := range s["cidr_blocks"].([]string) {
   636  							lcs = append(lcs, c)
   637  						}
   638  					default:
   639  						for _, c := range s["cidr_blocks"].([]interface{}) {
   640  							lcs = append(lcs, c)
   641  						}
   642  					}
   643  				}
   644  				savesCidrs := schema.NewSet(schema.HashString, lcs)
   645  
   646  				// convert cs cidrs to set
   647  				var cslcs []interface{}
   648  				if _, ok := cs["cidr_blocks"]; ok {
   649  					for _, c := range cs["cidr_blocks"].([]string) {
   650  						cslcs = append(cslcs, c)
   651  					}
   652  				}
   653  				csCidrs := schema.NewSet(schema.HashString, cslcs)
   654  
   655  				if csCidrs.Equal(savesCidrs) {
   656  					log.Printf("\nmatched cidrs")
   657  					cidrsMatch = true
   658  				}
   659  
   660  				if rawS, ok := s["security_groups"]; ok {
   661  					outSet := rawS.(*schema.Set)
   662  					if rawL, ok := cs["security_groups"]; ok {
   663  						localSet := rawL.(*schema.Set)
   664  						if outSet.Equal(localSet) {
   665  							log.Printf("\nmatched sgs")
   666  							sGsMatch = true
   667  						}
   668  					}
   669  				}
   670  
   671  				var lSelf bool
   672  				var rSelf bool
   673  				if _, ok := s["self"]; ok {
   674  					lSelf = s["self"].(bool)
   675  				}
   676  				if _, ok := cs["self"]; ok {
   677  					rSelf = cs["self"].(bool)
   678  				}
   679  
   680  				if (sGsMatch && cidrsMatch) && (lSelf == rSelf) {
   681  					found++
   682  				}
   683  			}
   684  		}
   685  
   686  		if found != shouldFind {
   687  			t.Fatalf("Bad sg rule matches (%d / %d)", found, shouldFind)
   688  		}
   689  	}
   690  }