github.com/ves/terraform@v0.8.0-beta2/terraform/resource_address_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  
     7  	"github.com/hashicorp/terraform/config"
     8  )
     9  
    10  func TestParseResourceAddressInternal(t *testing.T) {
    11  	cases := map[string]struct {
    12  		Input    string
    13  		Expected *ResourceAddress
    14  		Output   string
    15  	}{
    16  		"basic resource": {
    17  			"aws_instance.foo",
    18  			&ResourceAddress{
    19  				Mode:         config.ManagedResourceMode,
    20  				Type:         "aws_instance",
    21  				Name:         "foo",
    22  				InstanceType: TypePrimary,
    23  				Index:        -1,
    24  			},
    25  			"aws_instance.foo",
    26  		},
    27  
    28  		"basic resource with count": {
    29  			"aws_instance.foo.1",
    30  			&ResourceAddress{
    31  				Mode:         config.ManagedResourceMode,
    32  				Type:         "aws_instance",
    33  				Name:         "foo",
    34  				InstanceType: TypePrimary,
    35  				Index:        1,
    36  			},
    37  			"aws_instance.foo[1]",
    38  		},
    39  
    40  		"data resource": {
    41  			"data.aws_ami.foo",
    42  			&ResourceAddress{
    43  				Mode:         config.DataResourceMode,
    44  				Type:         "aws_ami",
    45  				Name:         "foo",
    46  				InstanceType: TypePrimary,
    47  				Index:        -1,
    48  			},
    49  			"data.aws_ami.foo",
    50  		},
    51  
    52  		"data resource with count": {
    53  			"data.aws_ami.foo.1",
    54  			&ResourceAddress{
    55  				Mode:         config.DataResourceMode,
    56  				Type:         "aws_ami",
    57  				Name:         "foo",
    58  				InstanceType: TypePrimary,
    59  				Index:        1,
    60  			},
    61  			"data.aws_ami.foo[1]",
    62  		},
    63  
    64  		"non-data resource with 4 elements": {
    65  			"aws_instance.foo.bar.1",
    66  			nil,
    67  			"",
    68  		},
    69  	}
    70  
    71  	for tn, tc := range cases {
    72  		t.Run(tc.Input, func(t *testing.T) {
    73  			out, err := parseResourceAddressInternal(tc.Input)
    74  			if (err != nil) != (tc.Expected == nil) {
    75  				t.Fatalf("%s: unexpected err: %#v", tn, err)
    76  			}
    77  			if err != nil {
    78  				return
    79  			}
    80  
    81  			if !reflect.DeepEqual(out, tc.Expected) {
    82  				t.Fatalf("bad: %q\n\nexpected:\n%#v\n\ngot:\n%#v", tn, tc.Expected, out)
    83  			}
    84  
    85  			// Compare outputs if those exist
    86  			expected := tc.Input
    87  			if tc.Output != "" {
    88  				expected = tc.Output
    89  			}
    90  			if out.String() != expected {
    91  				t.Fatalf("bad: %q\n\nexpected: %s\n\ngot: %s", tn, expected, out)
    92  			}
    93  
    94  			// Compare equality because the internal parse is used
    95  			// to compare equality to equal inputs.
    96  			if !out.Equals(tc.Expected) {
    97  				t.Fatalf("expected equality:\n\n%#v\n\n%#v", out, tc.Expected)
    98  			}
    99  		})
   100  	}
   101  }
   102  
   103  func TestParseResourceAddress(t *testing.T) {
   104  	cases := map[string]struct {
   105  		Input    string
   106  		Expected *ResourceAddress
   107  		Output   string
   108  	}{
   109  		"implicit primary managed instance, no specific index": {
   110  			"aws_instance.foo",
   111  			&ResourceAddress{
   112  				Mode:         config.ManagedResourceMode,
   113  				Type:         "aws_instance",
   114  				Name:         "foo",
   115  				InstanceType: TypePrimary,
   116  				Index:        -1,
   117  			},
   118  			"",
   119  		},
   120  		"implicit primary data instance, no specific index": {
   121  			"data.aws_instance.foo",
   122  			&ResourceAddress{
   123  				Mode:         config.DataResourceMode,
   124  				Type:         "aws_instance",
   125  				Name:         "foo",
   126  				InstanceType: TypePrimary,
   127  				Index:        -1,
   128  			},
   129  			"",
   130  		},
   131  		"implicit primary, explicit index": {
   132  			"aws_instance.foo[2]",
   133  			&ResourceAddress{
   134  				Mode:         config.ManagedResourceMode,
   135  				Type:         "aws_instance",
   136  				Name:         "foo",
   137  				InstanceType: TypePrimary,
   138  				Index:        2,
   139  			},
   140  			"",
   141  		},
   142  		"implicit primary, explicit index over ten": {
   143  			"aws_instance.foo[12]",
   144  			&ResourceAddress{
   145  				Mode:         config.ManagedResourceMode,
   146  				Type:         "aws_instance",
   147  				Name:         "foo",
   148  				InstanceType: TypePrimary,
   149  				Index:        12,
   150  			},
   151  			"",
   152  		},
   153  		"explicit primary, explicit index": {
   154  			"aws_instance.foo.primary[2]",
   155  			&ResourceAddress{
   156  				Mode:            config.ManagedResourceMode,
   157  				Type:            "aws_instance",
   158  				Name:            "foo",
   159  				InstanceType:    TypePrimary,
   160  				InstanceTypeSet: true,
   161  				Index:           2,
   162  			},
   163  			"",
   164  		},
   165  		"tainted": {
   166  			"aws_instance.foo.tainted",
   167  			&ResourceAddress{
   168  				Mode:            config.ManagedResourceMode,
   169  				Type:            "aws_instance",
   170  				Name:            "foo",
   171  				InstanceType:    TypeTainted,
   172  				InstanceTypeSet: true,
   173  				Index:           -1,
   174  			},
   175  			"",
   176  		},
   177  		"deposed": {
   178  			"aws_instance.foo.deposed",
   179  			&ResourceAddress{
   180  				Mode:            config.ManagedResourceMode,
   181  				Type:            "aws_instance",
   182  				Name:            "foo",
   183  				InstanceType:    TypeDeposed,
   184  				InstanceTypeSet: true,
   185  				Index:           -1,
   186  			},
   187  			"",
   188  		},
   189  		"with a hyphen": {
   190  			"aws_instance.foo-bar",
   191  			&ResourceAddress{
   192  				Mode:         config.ManagedResourceMode,
   193  				Type:         "aws_instance",
   194  				Name:         "foo-bar",
   195  				InstanceType: TypePrimary,
   196  				Index:        -1,
   197  			},
   198  			"",
   199  		},
   200  		"managed in a module": {
   201  			"module.child.aws_instance.foo",
   202  			&ResourceAddress{
   203  				Path:         []string{"child"},
   204  				Mode:         config.ManagedResourceMode,
   205  				Type:         "aws_instance",
   206  				Name:         "foo",
   207  				InstanceType: TypePrimary,
   208  				Index:        -1,
   209  			},
   210  			"",
   211  		},
   212  		"data in a module": {
   213  			"module.child.data.aws_instance.foo",
   214  			&ResourceAddress{
   215  				Path:         []string{"child"},
   216  				Mode:         config.DataResourceMode,
   217  				Type:         "aws_instance",
   218  				Name:         "foo",
   219  				InstanceType: TypePrimary,
   220  				Index:        -1,
   221  			},
   222  			"",
   223  		},
   224  		"nested modules": {
   225  			"module.a.module.b.module.forever.aws_instance.foo",
   226  			&ResourceAddress{
   227  				Path:         []string{"a", "b", "forever"},
   228  				Mode:         config.ManagedResourceMode,
   229  				Type:         "aws_instance",
   230  				Name:         "foo",
   231  				InstanceType: TypePrimary,
   232  				Index:        -1,
   233  			},
   234  			"",
   235  		},
   236  		"just a module": {
   237  			"module.a",
   238  			&ResourceAddress{
   239  				Path:         []string{"a"},
   240  				Type:         "",
   241  				Name:         "",
   242  				InstanceType: TypePrimary,
   243  				Index:        -1,
   244  			},
   245  			"",
   246  		},
   247  		"just a nested module": {
   248  			"module.a.module.b",
   249  			&ResourceAddress{
   250  				Path:         []string{"a", "b"},
   251  				Type:         "",
   252  				Name:         "",
   253  				InstanceType: TypePrimary,
   254  				Index:        -1,
   255  			},
   256  			"",
   257  		},
   258  	}
   259  
   260  	for tn, tc := range cases {
   261  		out, err := ParseResourceAddress(tc.Input)
   262  		if err != nil {
   263  			t.Fatalf("%s: unexpected err: %#v", tn, err)
   264  		}
   265  
   266  		if !reflect.DeepEqual(out, tc.Expected) {
   267  			t.Fatalf("bad: %q\n\nexpected:\n%#v\n\ngot:\n%#v", tn, tc.Expected, out)
   268  		}
   269  
   270  		expected := tc.Input
   271  		if tc.Output != "" {
   272  			expected = tc.Output
   273  		}
   274  		if out.String() != expected {
   275  			t.Fatalf("bad: %q\n\nexpected: %s\n\ngot: %s", tn, expected, out)
   276  		}
   277  	}
   278  }
   279  
   280  func TestResourceAddressEquals(t *testing.T) {
   281  	cases := map[string]struct {
   282  		Address *ResourceAddress
   283  		Other   interface{}
   284  		Expect  bool
   285  	}{
   286  		"basic match": {
   287  			Address: &ResourceAddress{
   288  				Mode:         config.ManagedResourceMode,
   289  				Type:         "aws_instance",
   290  				Name:         "foo",
   291  				InstanceType: TypePrimary,
   292  				Index:        0,
   293  			},
   294  			Other: &ResourceAddress{
   295  				Mode:         config.ManagedResourceMode,
   296  				Type:         "aws_instance",
   297  				Name:         "foo",
   298  				InstanceType: TypePrimary,
   299  				Index:        0,
   300  			},
   301  			Expect: true,
   302  		},
   303  		"address does not set index": {
   304  			Address: &ResourceAddress{
   305  				Mode:         config.ManagedResourceMode,
   306  				Type:         "aws_instance",
   307  				Name:         "foo",
   308  				InstanceType: TypePrimary,
   309  				Index:        -1,
   310  			},
   311  			Other: &ResourceAddress{
   312  				Mode:         config.ManagedResourceMode,
   313  				Type:         "aws_instance",
   314  				Name:         "foo",
   315  				InstanceType: TypePrimary,
   316  				Index:        3,
   317  			},
   318  			Expect: true,
   319  		},
   320  		"other does not set index": {
   321  			Address: &ResourceAddress{
   322  				Mode:         config.ManagedResourceMode,
   323  				Type:         "aws_instance",
   324  				Name:         "foo",
   325  				InstanceType: TypePrimary,
   326  				Index:        3,
   327  			},
   328  			Other: &ResourceAddress{
   329  				Mode:         config.ManagedResourceMode,
   330  				Type:         "aws_instance",
   331  				Name:         "foo",
   332  				InstanceType: TypePrimary,
   333  				Index:        -1,
   334  			},
   335  			Expect: true,
   336  		},
   337  		"neither sets index": {
   338  			Address: &ResourceAddress{
   339  				Mode:         config.ManagedResourceMode,
   340  				Type:         "aws_instance",
   341  				Name:         "foo",
   342  				InstanceType: TypePrimary,
   343  				Index:        -1,
   344  			},
   345  			Other: &ResourceAddress{
   346  				Mode:         config.ManagedResourceMode,
   347  				Type:         "aws_instance",
   348  				Name:         "foo",
   349  				InstanceType: TypePrimary,
   350  				Index:        -1,
   351  			},
   352  			Expect: true,
   353  		},
   354  		"index over ten": {
   355  			Address: &ResourceAddress{
   356  				Mode:         config.ManagedResourceMode,
   357  				Type:         "aws_instance",
   358  				Name:         "foo",
   359  				InstanceType: TypePrimary,
   360  				Index:        1,
   361  			},
   362  			Other: &ResourceAddress{
   363  				Mode:         config.ManagedResourceMode,
   364  				Type:         "aws_instance",
   365  				Name:         "foo",
   366  				InstanceType: TypePrimary,
   367  				Index:        13,
   368  			},
   369  			Expect: false,
   370  		},
   371  		"different type": {
   372  			Address: &ResourceAddress{
   373  				Mode:         config.ManagedResourceMode,
   374  				Type:         "aws_instance",
   375  				Name:         "foo",
   376  				InstanceType: TypePrimary,
   377  				Index:        0,
   378  			},
   379  			Other: &ResourceAddress{
   380  				Mode:         config.ManagedResourceMode,
   381  				Type:         "aws_vpc",
   382  				Name:         "foo",
   383  				InstanceType: TypePrimary,
   384  				Index:        0,
   385  			},
   386  			Expect: false,
   387  		},
   388  		"different mode": {
   389  			Address: &ResourceAddress{
   390  				Mode:         config.ManagedResourceMode,
   391  				Type:         "aws_instance",
   392  				Name:         "foo",
   393  				InstanceType: TypePrimary,
   394  				Index:        0,
   395  			},
   396  			Other: &ResourceAddress{
   397  				Mode:         config.DataResourceMode,
   398  				Type:         "aws_instance",
   399  				Name:         "foo",
   400  				InstanceType: TypePrimary,
   401  				Index:        0,
   402  			},
   403  			Expect: false,
   404  		},
   405  		"different name": {
   406  			Address: &ResourceAddress{
   407  				Mode:         config.ManagedResourceMode,
   408  				Type:         "aws_instance",
   409  				Name:         "foo",
   410  				InstanceType: TypePrimary,
   411  				Index:        0,
   412  			},
   413  			Other: &ResourceAddress{
   414  				Mode:         config.ManagedResourceMode,
   415  				Type:         "aws_instance",
   416  				Name:         "bar",
   417  				InstanceType: TypePrimary,
   418  				Index:        0,
   419  			},
   420  			Expect: false,
   421  		},
   422  		"different instance type": {
   423  			Address: &ResourceAddress{
   424  				Mode:         config.ManagedResourceMode,
   425  				Type:         "aws_instance",
   426  				Name:         "foo",
   427  				InstanceType: TypePrimary,
   428  				Index:        0,
   429  			},
   430  			Other: &ResourceAddress{
   431  				Mode:         config.ManagedResourceMode,
   432  				Type:         "aws_instance",
   433  				Name:         "foo",
   434  				InstanceType: TypeTainted,
   435  				Index:        0,
   436  			},
   437  			Expect: false,
   438  		},
   439  		"different index": {
   440  			Address: &ResourceAddress{
   441  				Mode:         config.ManagedResourceMode,
   442  				Type:         "aws_instance",
   443  				Name:         "foo",
   444  				InstanceType: TypePrimary,
   445  				Index:        0,
   446  			},
   447  			Other: &ResourceAddress{
   448  				Mode:         config.ManagedResourceMode,
   449  				Type:         "aws_instance",
   450  				Name:         "foo",
   451  				InstanceType: TypePrimary,
   452  				Index:        1,
   453  			},
   454  			Expect: false,
   455  		},
   456  		"module address matches address of managed resource inside module": {
   457  			Address: &ResourceAddress{
   458  				Path:         []string{"a", "b"},
   459  				Type:         "",
   460  				Name:         "",
   461  				InstanceType: TypePrimary,
   462  				Index:        -1,
   463  			},
   464  			Other: &ResourceAddress{
   465  				Path:         []string{"a", "b"},
   466  				Mode:         config.ManagedResourceMode,
   467  				Type:         "aws_instance",
   468  				Name:         "foo",
   469  				InstanceType: TypePrimary,
   470  				Index:        0,
   471  			},
   472  			Expect: true,
   473  		},
   474  		"module address matches address of data resource inside module": {
   475  			Address: &ResourceAddress{
   476  				Path:         []string{"a", "b"},
   477  				Type:         "",
   478  				Name:         "",
   479  				InstanceType: TypePrimary,
   480  				Index:        -1,
   481  			},
   482  			Other: &ResourceAddress{
   483  				Path:         []string{"a", "b"},
   484  				Mode:         config.DataResourceMode,
   485  				Type:         "aws_instance",
   486  				Name:         "foo",
   487  				InstanceType: TypePrimary,
   488  				Index:        0,
   489  			},
   490  			Expect: true,
   491  		},
   492  		"module address doesn't match managed resource outside module": {
   493  			Address: &ResourceAddress{
   494  				Path:         []string{"a", "b"},
   495  				Type:         "",
   496  				Name:         "",
   497  				InstanceType: TypePrimary,
   498  				Index:        -1,
   499  			},
   500  			Other: &ResourceAddress{
   501  				Path:         []string{"a"},
   502  				Mode:         config.ManagedResourceMode,
   503  				Type:         "aws_instance",
   504  				Name:         "foo",
   505  				InstanceType: TypePrimary,
   506  				Index:        0,
   507  			},
   508  			Expect: false,
   509  		},
   510  		"module address doesn't match data resource outside module": {
   511  			Address: &ResourceAddress{
   512  				Path:         []string{"a", "b"},
   513  				Type:         "",
   514  				Name:         "",
   515  				InstanceType: TypePrimary,
   516  				Index:        -1,
   517  			},
   518  			Other: &ResourceAddress{
   519  				Path:         []string{"a"},
   520  				Mode:         config.DataResourceMode,
   521  				Type:         "aws_instance",
   522  				Name:         "foo",
   523  				InstanceType: TypePrimary,
   524  				Index:        0,
   525  			},
   526  			Expect: false,
   527  		},
   528  		"nil path vs empty path should match": {
   529  			Address: &ResourceAddress{
   530  				Path:         []string{},
   531  				Mode:         config.ManagedResourceMode,
   532  				Type:         "aws_instance",
   533  				Name:         "foo",
   534  				InstanceType: TypePrimary,
   535  				Index:        -1,
   536  			},
   537  			Other: &ResourceAddress{
   538  				Path:         nil,
   539  				Mode:         config.ManagedResourceMode,
   540  				Type:         "aws_instance",
   541  				Name:         "foo",
   542  				InstanceType: TypePrimary,
   543  				Index:        0,
   544  			},
   545  			Expect: true,
   546  		},
   547  	}
   548  
   549  	for tn, tc := range cases {
   550  		actual := tc.Address.Equals(tc.Other)
   551  		if actual != tc.Expect {
   552  			t.Fatalf("%q: expected equals: %t, got %t for:\n%#v\n%#v",
   553  				tn, tc.Expect, actual, tc.Address, tc.Other)
   554  		}
   555  	}
   556  }
   557  
   558  func TestResourceAddressStateId(t *testing.T) {
   559  	cases := map[string]struct {
   560  		Input    *ResourceAddress
   561  		Expected string
   562  	}{
   563  		"basic resource": {
   564  			&ResourceAddress{
   565  				Mode:         config.ManagedResourceMode,
   566  				Type:         "aws_instance",
   567  				Name:         "foo",
   568  				InstanceType: TypePrimary,
   569  				Index:        -1,
   570  			},
   571  			"aws_instance.foo",
   572  		},
   573  
   574  		"basic resource ignores count": {
   575  			&ResourceAddress{
   576  				Mode:         config.ManagedResourceMode,
   577  				Type:         "aws_instance",
   578  				Name:         "foo",
   579  				InstanceType: TypePrimary,
   580  				Index:        2,
   581  			},
   582  			"aws_instance.foo",
   583  		},
   584  
   585  		"data resource": {
   586  			&ResourceAddress{
   587  				Mode:         config.DataResourceMode,
   588  				Type:         "aws_instance",
   589  				Name:         "foo",
   590  				InstanceType: TypePrimary,
   591  				Index:        -1,
   592  			},
   593  			"data.aws_instance.foo",
   594  		},
   595  	}
   596  
   597  	for tn, tc := range cases {
   598  		t.Run(tn, func(t *testing.T) {
   599  			actual := tc.Input.stateId()
   600  			if actual != tc.Expected {
   601  				t.Fatalf("bad: %q\n\nexpected: %s\n\ngot: %s", tn, tc.Expected, actual)
   602  			}
   603  		})
   604  	}
   605  }