github.com/paybyphone/terraform@v0.9.5-0.20170613192930-9706042ddd51/config/config_test.go (about)

     1  package config
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"log"
     8  	"os"
     9  	"path/filepath"
    10  	"reflect"
    11  	"strings"
    12  	"testing"
    13  
    14  	"github.com/hashicorp/hil/ast"
    15  	"github.com/hashicorp/terraform/helper/logging"
    16  )
    17  
    18  // This is the directory where our test fixtures are.
    19  const fixtureDir = "./test-fixtures"
    20  
    21  func TestMain(m *testing.M) {
    22  	flag.Parse()
    23  	if testing.Verbose() {
    24  		// if we're verbose, use the logging requested by TF_LOG
    25  		logging.SetOutput()
    26  	} else {
    27  		// otherwise silence all logs
    28  		log.SetOutput(ioutil.Discard)
    29  	}
    30  
    31  	os.Exit(m.Run())
    32  }
    33  
    34  func TestConfigCopy(t *testing.T) {
    35  	c := testConfig(t, "copy-basic")
    36  	rOrig := c.Resources[0]
    37  	rCopy := rOrig.Copy()
    38  
    39  	if rCopy.Name != rOrig.Name {
    40  		t.Fatalf("Expected names to equal: %q <=> %q", rCopy.Name, rOrig.Name)
    41  	}
    42  
    43  	if rCopy.Type != rOrig.Type {
    44  		t.Fatalf("Expected types to equal: %q <=> %q", rCopy.Type, rOrig.Type)
    45  	}
    46  
    47  	origCount := rOrig.RawCount.Config()["count"]
    48  	rCopy.RawCount.Config()["count"] = "5"
    49  	if rOrig.RawCount.Config()["count"] != origCount {
    50  		t.Fatalf("Expected RawCount to be copied, but it behaves like a ref!")
    51  	}
    52  
    53  	rCopy.RawConfig.Config()["newfield"] = "hello"
    54  	if rOrig.RawConfig.Config()["newfield"] == "hello" {
    55  		t.Fatalf("Expected RawConfig to be copied, but it behaves like a ref!")
    56  	}
    57  
    58  	rCopy.Provisioners = append(rCopy.Provisioners, &Provisioner{})
    59  	if len(rOrig.Provisioners) == len(rCopy.Provisioners) {
    60  		t.Fatalf("Expected Provisioners to be copied, but it behaves like a ref!")
    61  	}
    62  
    63  	if rCopy.Provider != rOrig.Provider {
    64  		t.Fatalf("Expected providers to equal: %q <=> %q",
    65  			rCopy.Provider, rOrig.Provider)
    66  	}
    67  
    68  	rCopy.DependsOn[0] = "gotchya"
    69  	if rOrig.DependsOn[0] == rCopy.DependsOn[0] {
    70  		t.Fatalf("Expected DependsOn to be copied, but it behaves like a ref!")
    71  	}
    72  
    73  	rCopy.Lifecycle.IgnoreChanges[0] = "gotchya"
    74  	if rOrig.Lifecycle.IgnoreChanges[0] == rCopy.Lifecycle.IgnoreChanges[0] {
    75  		t.Fatalf("Expected Lifecycle to be copied, but it behaves like a ref!")
    76  	}
    77  
    78  }
    79  
    80  func TestConfigCount(t *testing.T) {
    81  	c := testConfig(t, "count-int")
    82  	actual, err := c.Resources[0].Count()
    83  	if err != nil {
    84  		t.Fatalf("err: %s", err)
    85  	}
    86  	if actual != 5 {
    87  		t.Fatalf("bad: %#v", actual)
    88  	}
    89  }
    90  
    91  func TestConfigCount_string(t *testing.T) {
    92  	c := testConfig(t, "count-string")
    93  	actual, err := c.Resources[0].Count()
    94  	if err != nil {
    95  		t.Fatalf("err: %s", err)
    96  	}
    97  	if actual != 5 {
    98  		t.Fatalf("bad: %#v", actual)
    99  	}
   100  }
   101  
   102  // Terraform GH-11800
   103  func TestConfigCount_list(t *testing.T) {
   104  	c := testConfig(t, "count-list")
   105  
   106  	// The key is to interpolate so it doesn't fail parsing
   107  	c.Resources[0].RawCount.Interpolate(map[string]ast.Variable{
   108  		"var.list": ast.Variable{
   109  			Value: []ast.Variable{},
   110  			Type:  ast.TypeList,
   111  		},
   112  	})
   113  
   114  	_, err := c.Resources[0].Count()
   115  	if err == nil {
   116  		t.Fatal("should error")
   117  	}
   118  }
   119  
   120  func TestConfigCount_var(t *testing.T) {
   121  	c := testConfig(t, "count-var")
   122  	_, err := c.Resources[0].Count()
   123  	if err == nil {
   124  		t.Fatalf("should error")
   125  	}
   126  }
   127  
   128  func TestConfig_emptyCollections(t *testing.T) {
   129  	c := testConfig(t, "empty-collections")
   130  	if len(c.Variables) != 3 {
   131  		t.Fatalf("bad: expected 3 variables, got %d", len(c.Variables))
   132  	}
   133  	for _, variable := range c.Variables {
   134  		switch variable.Name {
   135  		case "empty_string":
   136  			if variable.Default != "" {
   137  				t.Fatalf("bad: wrong default %q for variable empty_string", variable.Default)
   138  			}
   139  		case "empty_map":
   140  			if !reflect.DeepEqual(variable.Default, map[string]interface{}{}) {
   141  				t.Fatalf("bad: wrong default %#v for variable empty_map", variable.Default)
   142  			}
   143  		case "empty_list":
   144  			if !reflect.DeepEqual(variable.Default, []interface{}{}) {
   145  				t.Fatalf("bad: wrong default %#v for variable empty_list", variable.Default)
   146  			}
   147  		default:
   148  			t.Fatalf("Unexpected variable: %s", variable.Name)
   149  		}
   150  	}
   151  }
   152  
   153  // This table test is the preferred way to test validation of configuration.
   154  // There are dozens of functions below which do not follow this that are
   155  // there mostly historically. They should be converted at some point.
   156  func TestConfigValidate_table(t *testing.T) {
   157  	cases := []struct {
   158  		Name      string
   159  		Fixture   string
   160  		Err       bool
   161  		ErrString string
   162  	}{
   163  		{
   164  			"basic good",
   165  			"validate-good",
   166  			false,
   167  			"",
   168  		},
   169  
   170  		{
   171  			"depends on module",
   172  			"validate-depends-on-module",
   173  			false,
   174  			"",
   175  		},
   176  
   177  		{
   178  			"depends on non-existent module",
   179  			"validate-depends-on-bad-module",
   180  			true,
   181  			"non-existent module 'foo'",
   182  		},
   183  
   184  		{
   185  			"data source with provisioners",
   186  			"validate-data-provisioner",
   187  			true,
   188  			"data sources cannot have",
   189  		},
   190  
   191  		{
   192  			"basic provisioners",
   193  			"validate-basic-provisioners",
   194  			false,
   195  			"",
   196  		},
   197  
   198  		{
   199  			"backend config with interpolations",
   200  			"validate-backend-interpolate",
   201  			true,
   202  			"cannot contain interp",
   203  		},
   204  		{
   205  			"nested types in variable default",
   206  			"validate-var-nested",
   207  			false,
   208  			"",
   209  		},
   210  		{
   211  			"provider with valid version constraint",
   212  			"provider-version",
   213  			false,
   214  			"",
   215  		},
   216  		{
   217  			"provider with invalid version constraint",
   218  			"provider-version-invalid",
   219  			true,
   220  			"invalid version constraint",
   221  		},
   222  	}
   223  
   224  	for i, tc := range cases {
   225  		t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) {
   226  			c := testConfig(t, tc.Fixture)
   227  			err := c.Validate()
   228  			if (err != nil) != tc.Err {
   229  				t.Fatalf("err: %s", err)
   230  			}
   231  			if err != nil {
   232  				if tc.ErrString != "" && !strings.Contains(err.Error(), tc.ErrString) {
   233  					t.Fatalf("expected err to contain: %s\n\ngot: %s", tc.ErrString, err)
   234  				}
   235  
   236  				return
   237  			}
   238  		})
   239  	}
   240  
   241  }
   242  
   243  func TestConfigValidate_tfVersion(t *testing.T) {
   244  	c := testConfig(t, "validate-tf-version")
   245  	if err := c.Validate(); err != nil {
   246  		t.Fatalf("err: %s", err)
   247  	}
   248  }
   249  
   250  func TestConfigValidate_tfVersionBad(t *testing.T) {
   251  	c := testConfig(t, "validate-bad-tf-version")
   252  	if err := c.Validate(); err == nil {
   253  		t.Fatal("should not be valid")
   254  	}
   255  }
   256  
   257  func TestConfigValidate_tfVersionInterpolations(t *testing.T) {
   258  	c := testConfig(t, "validate-tf-version-interp")
   259  	if err := c.Validate(); err == nil {
   260  		t.Fatal("should not be valid")
   261  	}
   262  }
   263  
   264  func TestConfigValidate_badDependsOn(t *testing.T) {
   265  	c := testConfig(t, "validate-bad-depends-on")
   266  	if err := c.Validate(); err == nil {
   267  		t.Fatal("should not be valid")
   268  	}
   269  }
   270  
   271  func TestConfigValidate_countInt(t *testing.T) {
   272  	c := testConfig(t, "validate-count-int")
   273  	if err := c.Validate(); err != nil {
   274  		t.Fatalf("err: %s", err)
   275  	}
   276  }
   277  
   278  func TestConfigValidate_countBadContext(t *testing.T) {
   279  	c := testConfig(t, "validate-count-bad-context")
   280  
   281  	err := c.Validate()
   282  
   283  	expected := []string{
   284  		"no_count_in_output: count variables are only valid within resources",
   285  		"no_count_in_module: count variables are only valid within resources",
   286  	}
   287  	for _, exp := range expected {
   288  		if !strings.Contains(err.Error(), exp) {
   289  			t.Fatalf("expected: %q,\nto contain: %q", err, exp)
   290  		}
   291  	}
   292  }
   293  
   294  func TestConfigValidate_countCountVar(t *testing.T) {
   295  	c := testConfig(t, "validate-count-count-var")
   296  	if err := c.Validate(); err == nil {
   297  		t.Fatal("should not be valid")
   298  	}
   299  }
   300  
   301  func TestConfigValidate_countNotInt(t *testing.T) {
   302  	c := testConfig(t, "validate-count-not-int")
   303  	if err := c.Validate(); err == nil {
   304  		t.Fatal("should not be valid")
   305  	}
   306  }
   307  
   308  func TestConfigValidate_countUserVar(t *testing.T) {
   309  	c := testConfig(t, "validate-count-user-var")
   310  	if err := c.Validate(); err != nil {
   311  		t.Fatalf("err: %s", err)
   312  	}
   313  }
   314  
   315  func TestConfigValidate_countVar(t *testing.T) {
   316  	c := testConfig(t, "validate-count-var")
   317  	if err := c.Validate(); err != nil {
   318  		t.Fatalf("err: %s", err)
   319  	}
   320  }
   321  
   322  func TestConfigValidate_countVarInvalid(t *testing.T) {
   323  	c := testConfig(t, "validate-count-var-invalid")
   324  	if err := c.Validate(); err == nil {
   325  		t.Fatal("should not be valid")
   326  	}
   327  }
   328  
   329  func TestConfigValidate_countVarUnknown(t *testing.T) {
   330  	c := testConfig(t, "validate-count-var-unknown")
   331  	if err := c.Validate(); err == nil {
   332  		t.Fatal("should not be valid")
   333  	}
   334  }
   335  
   336  func TestConfigValidate_dependsOnVar(t *testing.T) {
   337  	c := testConfig(t, "validate-depends-on-var")
   338  	if err := c.Validate(); err == nil {
   339  		t.Fatal("should not be valid")
   340  	}
   341  }
   342  
   343  func TestConfigValidate_dupModule(t *testing.T) {
   344  	c := testConfig(t, "validate-dup-module")
   345  	if err := c.Validate(); err == nil {
   346  		t.Fatal("should not be valid")
   347  	}
   348  }
   349  
   350  func TestConfigValidate_dupResource(t *testing.T) {
   351  	c := testConfig(t, "validate-dup-resource")
   352  	if err := c.Validate(); err == nil {
   353  		t.Fatal("should not be valid")
   354  	}
   355  }
   356  
   357  func TestConfigValidate_ignoreChanges(t *testing.T) {
   358  	c := testConfig(t, "validate-ignore-changes")
   359  	if err := c.Validate(); err != nil {
   360  		t.Fatalf("err: %s", err)
   361  	}
   362  }
   363  
   364  func TestConfigValidate_ignoreChangesBad(t *testing.T) {
   365  	c := testConfig(t, "validate-ignore-changes-bad")
   366  	if err := c.Validate(); err == nil {
   367  		t.Fatal("should not be valid")
   368  	}
   369  }
   370  
   371  func TestConfigValidate_ignoreChangesInterpolate(t *testing.T) {
   372  	c := testConfig(t, "validate-ignore-changes-interpolate")
   373  	if err := c.Validate(); err == nil {
   374  		t.Fatal("should not be valid")
   375  	}
   376  }
   377  
   378  func TestConfigValidate_moduleNameBad(t *testing.T) {
   379  	c := testConfig(t, "validate-module-name-bad")
   380  	if err := c.Validate(); err == nil {
   381  		t.Fatal("should not be valid")
   382  	}
   383  }
   384  
   385  func TestConfigValidate_moduleSourceVar(t *testing.T) {
   386  	c := testConfig(t, "validate-module-source-var")
   387  	if err := c.Validate(); err == nil {
   388  		t.Fatal("should not be valid")
   389  	}
   390  }
   391  
   392  func TestConfigValidate_moduleVarInt(t *testing.T) {
   393  	c := testConfig(t, "validate-module-var-int")
   394  	if err := c.Validate(); err != nil {
   395  		t.Fatalf("should be valid: %s", err)
   396  	}
   397  }
   398  
   399  func TestConfigValidate_moduleVarMap(t *testing.T) {
   400  	c := testConfig(t, "validate-module-var-map")
   401  	if err := c.Validate(); err != nil {
   402  		t.Fatalf("should be valid: %s", err)
   403  	}
   404  }
   405  
   406  func TestConfigValidate_moduleVarList(t *testing.T) {
   407  	c := testConfig(t, "validate-module-var-list")
   408  	if err := c.Validate(); err != nil {
   409  		t.Fatalf("should be valid: %s", err)
   410  	}
   411  }
   412  
   413  func TestConfigValidate_moduleVarSelf(t *testing.T) {
   414  	c := testConfig(t, "validate-module-var-self")
   415  	if err := c.Validate(); err == nil {
   416  		t.Fatal("should be invalid")
   417  	}
   418  }
   419  
   420  func TestConfigValidate_nil(t *testing.T) {
   421  	var c Config
   422  	if err := c.Validate(); err != nil {
   423  		t.Fatalf("err: %s", err)
   424  	}
   425  }
   426  
   427  func TestConfigValidate_outputBadField(t *testing.T) {
   428  	c := testConfig(t, "validate-output-bad-field")
   429  	if err := c.Validate(); err == nil {
   430  		t.Fatal("should not be valid")
   431  	}
   432  }
   433  
   434  func TestConfigValidate_outputDescription(t *testing.T) {
   435  	c := testConfig(t, "validate-output-description")
   436  	if err := c.Validate(); err != nil {
   437  		t.Fatalf("err: %s", err)
   438  	}
   439  	if len(c.Outputs) != 1 {
   440  		t.Fatalf("got %d outputs; want 1", len(c.Outputs))
   441  	}
   442  	if got, want := "Number 5", c.Outputs[0].Description; got != want {
   443  		t.Fatalf("got description %q; want %q", got, want)
   444  	}
   445  }
   446  
   447  func TestConfigValidate_outputDuplicate(t *testing.T) {
   448  	c := testConfig(t, "validate-output-dup")
   449  	if err := c.Validate(); err == nil {
   450  		t.Fatal("should not be valid")
   451  	}
   452  }
   453  
   454  func TestConfigValidate_pathVar(t *testing.T) {
   455  	c := testConfig(t, "validate-path-var")
   456  	if err := c.Validate(); err != nil {
   457  		t.Fatalf("err: %s", err)
   458  	}
   459  }
   460  
   461  func TestConfigValidate_pathVarInvalid(t *testing.T) {
   462  	c := testConfig(t, "validate-path-var-invalid")
   463  	if err := c.Validate(); err == nil {
   464  		t.Fatal("should not be valid")
   465  	}
   466  }
   467  
   468  func TestConfigValidate_providerMulti(t *testing.T) {
   469  	c := testConfig(t, "validate-provider-multi")
   470  	if err := c.Validate(); err == nil {
   471  		t.Fatal("should not be valid")
   472  	}
   473  }
   474  
   475  func TestConfigValidate_providerMultiGood(t *testing.T) {
   476  	c := testConfig(t, "validate-provider-multi-good")
   477  	if err := c.Validate(); err != nil {
   478  		t.Fatalf("should be valid: %s", err)
   479  	}
   480  }
   481  
   482  func TestConfigValidate_providerMultiRefGood(t *testing.T) {
   483  	c := testConfig(t, "validate-provider-multi-ref-good")
   484  	if err := c.Validate(); err != nil {
   485  		t.Fatalf("should be valid: %s", err)
   486  	}
   487  }
   488  
   489  func TestConfigValidate_provConnSplatOther(t *testing.T) {
   490  	c := testConfig(t, "validate-prov-conn-splat-other")
   491  	if err := c.Validate(); err != nil {
   492  		t.Fatalf("should be valid: %s", err)
   493  	}
   494  }
   495  
   496  func TestConfigValidate_provConnSplatSelf(t *testing.T) {
   497  	c := testConfig(t, "validate-prov-conn-splat-self")
   498  	if err := c.Validate(); err == nil {
   499  		t.Fatal("should not be valid")
   500  	}
   501  }
   502  
   503  func TestConfigValidate_provSplatOther(t *testing.T) {
   504  	c := testConfig(t, "validate-prov-splat-other")
   505  	if err := c.Validate(); err != nil {
   506  		t.Fatalf("should be valid: %s", err)
   507  	}
   508  }
   509  
   510  func TestConfigValidate_provSplatSelf(t *testing.T) {
   511  	c := testConfig(t, "validate-prov-splat-self")
   512  	if err := c.Validate(); err == nil {
   513  		t.Fatal("should not be valid")
   514  	}
   515  }
   516  
   517  func TestConfigValidate_resourceProvVarSelf(t *testing.T) {
   518  	c := testConfig(t, "validate-resource-prov-self")
   519  	if err := c.Validate(); err != nil {
   520  		t.Fatalf("should be valid: %s", err)
   521  	}
   522  }
   523  
   524  func TestConfigValidate_resourceVarSelf(t *testing.T) {
   525  	c := testConfig(t, "validate-resource-self")
   526  	if err := c.Validate(); err == nil {
   527  		t.Fatal("should not be valid")
   528  	}
   529  }
   530  
   531  func TestConfigValidate_unknownThing(t *testing.T) {
   532  	c := testConfig(t, "validate-unknownthing")
   533  	if err := c.Validate(); err == nil {
   534  		t.Fatal("should not be valid")
   535  	}
   536  }
   537  
   538  func TestConfigValidate_unknownResourceVar(t *testing.T) {
   539  	c := testConfig(t, "validate-unknown-resource-var")
   540  	if err := c.Validate(); err == nil {
   541  		t.Fatal("should not be valid")
   542  	}
   543  }
   544  
   545  func TestConfigValidate_unknownResourceVar_output(t *testing.T) {
   546  	c := testConfig(t, "validate-unknown-resource-var-output")
   547  	if err := c.Validate(); err == nil {
   548  		t.Fatal("should not be valid")
   549  	}
   550  }
   551  
   552  func TestConfigValidate_unknownVar(t *testing.T) {
   553  	c := testConfig(t, "validate-unknownvar")
   554  	if err := c.Validate(); err == nil {
   555  		t.Fatal("should not be valid")
   556  	}
   557  }
   558  
   559  func TestConfigValidate_unknownVarCount(t *testing.T) {
   560  	c := testConfig(t, "validate-unknownvar-count")
   561  	if err := c.Validate(); err == nil {
   562  		t.Fatal("should not be valid")
   563  	}
   564  }
   565  
   566  func TestConfigValidate_varDefault(t *testing.T) {
   567  	c := testConfig(t, "validate-var-default")
   568  	if err := c.Validate(); err != nil {
   569  		t.Fatalf("should be valid: %s", err)
   570  	}
   571  }
   572  
   573  func TestConfigValidate_varDefaultListType(t *testing.T) {
   574  	c := testConfig(t, "validate-var-default-list-type")
   575  	if err := c.Validate(); err != nil {
   576  		t.Fatalf("should be valid: %s", err)
   577  	}
   578  }
   579  
   580  func TestConfigValidate_varDefaultInterpolate(t *testing.T) {
   581  	c := testConfig(t, "validate-var-default-interpolate")
   582  	if err := c.Validate(); err == nil {
   583  		t.Fatal("should not be valid")
   584  	}
   585  }
   586  
   587  func TestConfigValidate_varDefaultInterpolateEscaped(t *testing.T) {
   588  	c := testConfig(t, "validate-var-default-interpolate-escaped")
   589  	if err := c.Validate(); err != nil {
   590  		t.Fatalf("should be valid, but got err: %s", err)
   591  	}
   592  }
   593  
   594  func TestConfigValidate_varDup(t *testing.T) {
   595  	c := testConfig(t, "validate-var-dup")
   596  	if err := c.Validate(); err == nil {
   597  		t.Fatal("should not be valid")
   598  	}
   599  }
   600  
   601  func TestConfigValidate_varMultiExactNonSlice(t *testing.T) {
   602  	c := testConfig(t, "validate-var-multi-exact-non-slice")
   603  	if err := c.Validate(); err != nil {
   604  		t.Fatalf("should be valid: %s", err)
   605  	}
   606  }
   607  
   608  func TestConfigValidate_varMultiFunctionCall(t *testing.T) {
   609  	c := testConfig(t, "validate-var-multi-func")
   610  	if err := c.Validate(); err != nil {
   611  		t.Fatalf("should be valid: %s", err)
   612  	}
   613  }
   614  
   615  func TestConfigValidate_varModule(t *testing.T) {
   616  	c := testConfig(t, "validate-var-module")
   617  	if err := c.Validate(); err != nil {
   618  		t.Fatalf("err: %s", err)
   619  	}
   620  }
   621  
   622  func TestConfigValidate_varModuleInvalid(t *testing.T) {
   623  	c := testConfig(t, "validate-var-module-invalid")
   624  	if err := c.Validate(); err == nil {
   625  		t.Fatal("should not be valid")
   626  	}
   627  }
   628  
   629  func TestConfigValidate_varProviderVersionInvalid(t *testing.T) {
   630  	c := testConfig(t, "validate-provider-version-invalid")
   631  	if err := c.Validate(); err == nil {
   632  		t.Fatal("should not be valid")
   633  	}
   634  }
   635  
   636  func TestNameRegexp(t *testing.T) {
   637  	cases := []struct {
   638  		Input string
   639  		Match bool
   640  	}{
   641  		{"hello", true},
   642  		{"foo-bar", true},
   643  		{"foo_bar", true},
   644  		{"_hello", true},
   645  		{"foo bar", false},
   646  		{"foo.bar", false},
   647  	}
   648  
   649  	for _, tc := range cases {
   650  		if NameRegexp.Match([]byte(tc.Input)) != tc.Match {
   651  			t.Fatalf("Input: %s\n\nExpected: %#v", tc.Input, tc.Match)
   652  		}
   653  	}
   654  }
   655  
   656  func TestProviderConfigName(t *testing.T) {
   657  	pcs := []*ProviderConfig{
   658  		&ProviderConfig{Name: "aw"},
   659  		&ProviderConfig{Name: "aws"},
   660  		&ProviderConfig{Name: "a"},
   661  		&ProviderConfig{Name: "gce_"},
   662  	}
   663  
   664  	n := ProviderConfigName("aws_instance", pcs)
   665  	if n != "aws" {
   666  		t.Fatalf("bad: %s", n)
   667  	}
   668  }
   669  
   670  func testConfig(t *testing.T, name string) *Config {
   671  	c, err := LoadFile(filepath.Join(fixtureDir, name, "main.tf"))
   672  	if err != nil {
   673  		t.Fatalf("file: %s\n\nerr: %s", name, err)
   674  	}
   675  
   676  	return c
   677  }
   678  
   679  func TestConfigDataCount(t *testing.T) {
   680  	c := testConfig(t, "data-count")
   681  	actual, err := c.Resources[0].Count()
   682  	if err != nil {
   683  		t.Fatalf("err: %s", err)
   684  	}
   685  	if actual != 5 {
   686  		t.Fatalf("bad: %#v", actual)
   687  	}
   688  
   689  	// we need to make sure "count" has been removed from the RawConfig, since
   690  	// it's not a real key and won't validate.
   691  	if _, ok := c.Resources[0].RawConfig.Raw["count"]; ok {
   692  		t.Fatal("count key still exists in RawConfig")
   693  	}
   694  }
   695  
   696  func TestConfigProviderVersion(t *testing.T) {
   697  	c := testConfig(t, "provider-version")
   698  
   699  	if len(c.ProviderConfigs) != 1 {
   700  		t.Fatal("expected 1 provider")
   701  	}
   702  
   703  	p := c.ProviderConfigs[0]
   704  	if p.Name != "aws" {
   705  		t.Fatalf("expected provider name 'aws', got %q", p.Name)
   706  	}
   707  
   708  	if p.Version != "0.0.1" {
   709  		t.Fatalf("expected providers version '0.0.1', got %q", p.Version)
   710  	}
   711  
   712  	if _, ok := p.RawConfig.Raw["version"]; ok {
   713  		t.Fatal("'version' should not exist in raw config")
   714  	}
   715  }
   716  
   717  func TestResourceProviderFullName(t *testing.T) {
   718  	type testCase struct {
   719  		ResourceName string
   720  		Alias        string
   721  		Expected     string
   722  	}
   723  
   724  	tests := []testCase{
   725  		{
   726  			// If no alias is provided, the first underscore-separated segment
   727  			// is assumed to be the provider name.
   728  			ResourceName: "aws_thing",
   729  			Alias:        "",
   730  			Expected:     "aws",
   731  		},
   732  		{
   733  			// If we have more than one underscore then it's the first one that we'll use.
   734  			ResourceName: "aws_thingy_thing",
   735  			Alias:        "",
   736  			Expected:     "aws",
   737  		},
   738  		{
   739  			// A provider can export a resource whose name is just the bare provider name,
   740  			// e.g. because the provider only has one resource and so any additional
   741  			// parts would be redundant.
   742  			ResourceName: "external",
   743  			Alias:        "",
   744  			Expected:     "external",
   745  		},
   746  		{
   747  			// Alias always overrides the default extraction of the name
   748  			ResourceName: "aws_thing",
   749  			Alias:        "tls.baz",
   750  			Expected:     "tls.baz",
   751  		},
   752  	}
   753  
   754  	for _, test := range tests {
   755  		got := ResourceProviderFullName(test.ResourceName, test.Alias)
   756  		if got != test.Expected {
   757  			t.Errorf(
   758  				"(%q, %q) produced %q; want %q",
   759  				test.ResourceName, test.Alias,
   760  				got,
   761  				test.Expected,
   762  			)
   763  		}
   764  	}
   765  }