github.com/jmbataller/terraform@v0.6.8-0.20151125192640-b7a12e3a580c/config/loader_test.go (about)

     1  package config
     2  
     3  import (
     4  	"io/ioutil"
     5  	"path/filepath"
     6  	"reflect"
     7  	"strings"
     8  	"testing"
     9  )
    10  
    11  func TestIsEmptyDir(t *testing.T) {
    12  	val, err := IsEmptyDir(fixtureDir)
    13  	if err != nil {
    14  		t.Fatalf("err: %s", err)
    15  	}
    16  	if val {
    17  		t.Fatal("should not be empty")
    18  	}
    19  }
    20  
    21  func TestIsEmptyDir_noExist(t *testing.T) {
    22  	val, err := IsEmptyDir(filepath.Join(fixtureDir, "nopenopenope"))
    23  	if err != nil {
    24  		t.Fatalf("err: %s", err)
    25  	}
    26  	if !val {
    27  		t.Fatal("should be empty")
    28  	}
    29  }
    30  
    31  func TestIsEmptyDir_noConfigs(t *testing.T) {
    32  	val, err := IsEmptyDir(filepath.Join(fixtureDir, "dir-empty"))
    33  	if err != nil {
    34  		t.Fatalf("err: %s", err)
    35  	}
    36  	if !val {
    37  		t.Fatal("should be empty")
    38  	}
    39  }
    40  
    41  func TestLoadFile_badType(t *testing.T) {
    42  	_, err := LoadFile(filepath.Join(fixtureDir, "bad_type.tf.nope"))
    43  	if err == nil {
    44  		t.Fatal("should have error")
    45  	}
    46  }
    47  
    48  func TestLoadFileHeredoc(t *testing.T) {
    49  	c, err := LoadFile(filepath.Join(fixtureDir, "heredoc.tf"))
    50  	if err != nil {
    51  		t.Fatalf("err: %s", err)
    52  	}
    53  
    54  	if c == nil {
    55  		t.Fatal("config should not be nil")
    56  	}
    57  
    58  	if c.Dir != "" {
    59  		t.Fatalf("bad: %#v", c.Dir)
    60  	}
    61  
    62  	actual := providerConfigsStr(c.ProviderConfigs)
    63  	if actual != strings.TrimSpace(heredocProvidersStr) {
    64  		t.Fatalf("bad:\n%s", actual)
    65  	}
    66  
    67  	actual = resourcesStr(c.Resources)
    68  	if actual != strings.TrimSpace(heredocResourcesStr) {
    69  		t.Fatalf("bad:\n%s", actual)
    70  	}
    71  }
    72  
    73  func TestLoadFileEscapedQuotes(t *testing.T) {
    74  	c, err := LoadFile(filepath.Join(fixtureDir, "escapedquotes.tf"))
    75  	if err != nil {
    76  		t.Fatalf("err: %s", err)
    77  	}
    78  
    79  	if c == nil {
    80  		t.Fatal("config should not be nil")
    81  	}
    82  
    83  	if c.Dir != "" {
    84  		t.Fatalf("bad: %#v", c.Dir)
    85  	}
    86  
    87  	actual := resourcesStr(c.Resources)
    88  	if actual != strings.TrimSpace(escapedquotesResourcesStr) {
    89  		t.Fatalf("bad:\n%s", actual)
    90  	}
    91  }
    92  
    93  func TestLoadFileBasic(t *testing.T) {
    94  	c, err := LoadFile(filepath.Join(fixtureDir, "basic.tf"))
    95  	if err != nil {
    96  		t.Fatalf("err: %s", err)
    97  	}
    98  
    99  	if c == nil {
   100  		t.Fatal("config should not be nil")
   101  	}
   102  
   103  	if c.Dir != "" {
   104  		t.Fatalf("bad: %#v", c.Dir)
   105  	}
   106  
   107  	expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"}
   108  	if !reflect.DeepEqual(c.Atlas, expectedAtlas) {
   109  		t.Fatalf("bad: %#v", c.Atlas)
   110  	}
   111  
   112  	actual := variablesStr(c.Variables)
   113  	if actual != strings.TrimSpace(basicVariablesStr) {
   114  		t.Fatalf("bad:\n%s", actual)
   115  	}
   116  
   117  	actual = providerConfigsStr(c.ProviderConfigs)
   118  	if actual != strings.TrimSpace(basicProvidersStr) {
   119  		t.Fatalf("bad:\n%s", actual)
   120  	}
   121  
   122  	actual = resourcesStr(c.Resources)
   123  	if actual != strings.TrimSpace(basicResourcesStr) {
   124  		t.Fatalf("bad:\n%s", actual)
   125  	}
   126  
   127  	actual = outputsStr(c.Outputs)
   128  	if actual != strings.TrimSpace(basicOutputsStr) {
   129  		t.Fatalf("bad:\n%s", actual)
   130  	}
   131  }
   132  
   133  func TestLoadFileBasic_empty(t *testing.T) {
   134  	c, err := LoadFile(filepath.Join(fixtureDir, "empty.tf"))
   135  	if err != nil {
   136  		t.Fatalf("err: %s", err)
   137  	}
   138  
   139  	if c == nil {
   140  		t.Fatal("config should not be nil")
   141  	}
   142  }
   143  
   144  func TestLoadFileBasic_import(t *testing.T) {
   145  	// Skip because we disabled importing
   146  	t.Skip()
   147  
   148  	c, err := LoadFile(filepath.Join(fixtureDir, "import.tf"))
   149  	if err != nil {
   150  		t.Fatalf("err: %s", err)
   151  	}
   152  
   153  	if c == nil {
   154  		t.Fatal("config should not be nil")
   155  	}
   156  
   157  	actual := variablesStr(c.Variables)
   158  	if actual != strings.TrimSpace(importVariablesStr) {
   159  		t.Fatalf("bad:\n%s", actual)
   160  	}
   161  
   162  	actual = providerConfigsStr(c.ProviderConfigs)
   163  	if actual != strings.TrimSpace(importProvidersStr) {
   164  		t.Fatalf("bad:\n%s", actual)
   165  	}
   166  
   167  	actual = resourcesStr(c.Resources)
   168  	if actual != strings.TrimSpace(importResourcesStr) {
   169  		t.Fatalf("bad:\n%s", actual)
   170  	}
   171  }
   172  
   173  func TestLoadFileBasic_json(t *testing.T) {
   174  	c, err := LoadFile(filepath.Join(fixtureDir, "basic.tf.json"))
   175  	if err != nil {
   176  		t.Fatalf("err: %s", err)
   177  	}
   178  
   179  	if c == nil {
   180  		t.Fatal("config should not be nil")
   181  	}
   182  
   183  	if c.Dir != "" {
   184  		t.Fatalf("bad: %#v", c.Dir)
   185  	}
   186  
   187  	expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"}
   188  	if !reflect.DeepEqual(c.Atlas, expectedAtlas) {
   189  		t.Fatalf("bad: %#v", c.Atlas)
   190  	}
   191  
   192  	actual := variablesStr(c.Variables)
   193  	if actual != strings.TrimSpace(basicVariablesStr) {
   194  		t.Fatalf("bad:\n%s", actual)
   195  	}
   196  
   197  	actual = providerConfigsStr(c.ProviderConfigs)
   198  	if actual != strings.TrimSpace(basicProvidersStr) {
   199  		t.Fatalf("bad:\n%s", actual)
   200  	}
   201  
   202  	actual = resourcesStr(c.Resources)
   203  	if actual != strings.TrimSpace(basicResourcesStr) {
   204  		t.Fatalf("bad:\n%s", actual)
   205  	}
   206  
   207  	actual = outputsStr(c.Outputs)
   208  	if actual != strings.TrimSpace(basicOutputsStr) {
   209  		t.Fatalf("bad:\n%s", actual)
   210  	}
   211  }
   212  
   213  func TestLoadFileBasic_modules(t *testing.T) {
   214  	c, err := LoadFile(filepath.Join(fixtureDir, "modules.tf"))
   215  	if err != nil {
   216  		t.Fatalf("err: %s", err)
   217  	}
   218  
   219  	if c == nil {
   220  		t.Fatal("config should not be nil")
   221  	}
   222  
   223  	if c.Dir != "" {
   224  		t.Fatalf("bad: %#v", c.Dir)
   225  	}
   226  
   227  	actual := modulesStr(c.Modules)
   228  	if actual != strings.TrimSpace(modulesModulesStr) {
   229  		t.Fatalf("bad:\n%s", actual)
   230  	}
   231  }
   232  
   233  func TestLoadJSONBasic(t *testing.T) {
   234  	raw, err := ioutil.ReadFile(filepath.Join(fixtureDir, "basic.tf.json"))
   235  	if err != nil {
   236  		t.Fatalf("err: %s", err)
   237  	}
   238  
   239  	c, err := LoadJSON(raw)
   240  	if err != nil {
   241  		t.Fatalf("err: %s", err)
   242  	}
   243  
   244  	if c == nil {
   245  		t.Fatal("config should not be nil")
   246  	}
   247  
   248  	if c.Dir != "" {
   249  		t.Fatalf("bad: %#v", c.Dir)
   250  	}
   251  
   252  	expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"}
   253  	if !reflect.DeepEqual(c.Atlas, expectedAtlas) {
   254  		t.Fatalf("bad: %#v", c.Atlas)
   255  	}
   256  
   257  	actual := variablesStr(c.Variables)
   258  	if actual != strings.TrimSpace(basicVariablesStr) {
   259  		t.Fatalf("bad:\n%s", actual)
   260  	}
   261  
   262  	actual = providerConfigsStr(c.ProviderConfigs)
   263  	if actual != strings.TrimSpace(basicProvidersStr) {
   264  		t.Fatalf("bad:\n%s", actual)
   265  	}
   266  
   267  	actual = resourcesStr(c.Resources)
   268  	if actual != strings.TrimSpace(basicResourcesStr) {
   269  		t.Fatalf("bad:\n%s", actual)
   270  	}
   271  
   272  	actual = outputsStr(c.Outputs)
   273  	if actual != strings.TrimSpace(basicOutputsStr) {
   274  		t.Fatalf("bad:\n%s", actual)
   275  	}
   276  }
   277  
   278  func TestLoadFile_variables(t *testing.T) {
   279  	c, err := LoadFile(filepath.Join(fixtureDir, "variables.tf"))
   280  	if err != nil {
   281  		t.Fatalf("err: %s", err)
   282  	}
   283  	if c == nil {
   284  		t.Fatal("config should not be nil")
   285  	}
   286  
   287  	if c.Dir != "" {
   288  		t.Fatalf("bad: %#v", c.Dir)
   289  	}
   290  
   291  	actual := variablesStr(c.Variables)
   292  	if actual != strings.TrimSpace(variablesVariablesStr) {
   293  		t.Fatalf("bad:\n%s", actual)
   294  	}
   295  }
   296  
   297  func TestLoadDir_basic(t *testing.T) {
   298  	dir := filepath.Join(fixtureDir, "dir-basic")
   299  	c, err := LoadDir(dir)
   300  	if err != nil {
   301  		t.Fatalf("err: %s", err)
   302  	}
   303  
   304  	if c == nil {
   305  		t.Fatal("config should not be nil")
   306  	}
   307  
   308  	dirAbs, err := filepath.Abs(dir)
   309  	if err != nil {
   310  		t.Fatalf("err: %s", err)
   311  	}
   312  	if c.Dir != dirAbs {
   313  		t.Fatalf("bad: %#v", c.Dir)
   314  	}
   315  
   316  	actual := variablesStr(c.Variables)
   317  	if actual != strings.TrimSpace(dirBasicVariablesStr) {
   318  		t.Fatalf("bad:\n%s", actual)
   319  	}
   320  
   321  	actual = providerConfigsStr(c.ProviderConfigs)
   322  	if actual != strings.TrimSpace(dirBasicProvidersStr) {
   323  		t.Fatalf("bad:\n%s", actual)
   324  	}
   325  
   326  	actual = resourcesStr(c.Resources)
   327  	if actual != strings.TrimSpace(dirBasicResourcesStr) {
   328  		t.Fatalf("bad:\n%s", actual)
   329  	}
   330  
   331  	actual = outputsStr(c.Outputs)
   332  	if actual != strings.TrimSpace(dirBasicOutputsStr) {
   333  		t.Fatalf("bad:\n%s", actual)
   334  	}
   335  }
   336  
   337  func TestLoadDir_file(t *testing.T) {
   338  	_, err := LoadDir(filepath.Join(fixtureDir, "variables.tf"))
   339  	if err == nil {
   340  		t.Fatal("should error")
   341  	}
   342  }
   343  
   344  func TestLoadDir_noConfigs(t *testing.T) {
   345  	_, err := LoadDir(filepath.Join(fixtureDir, "dir-empty"))
   346  	if err == nil {
   347  		t.Fatal("should error")
   348  	}
   349  }
   350  
   351  func TestLoadDir_noMerge(t *testing.T) {
   352  	c, err := LoadDir(filepath.Join(fixtureDir, "dir-merge"))
   353  	if err != nil {
   354  		t.Fatalf("err: %s", err)
   355  	}
   356  
   357  	if c == nil {
   358  		t.Fatal("config should not be nil")
   359  	}
   360  
   361  	if err := c.Validate(); err == nil {
   362  		t.Fatal("should not be valid")
   363  	}
   364  }
   365  
   366  func TestLoadDir_override(t *testing.T) {
   367  	c, err := LoadDir(filepath.Join(fixtureDir, "dir-override"))
   368  	if err != nil {
   369  		t.Fatalf("err: %s", err)
   370  	}
   371  
   372  	if c == nil {
   373  		t.Fatal("config should not be nil")
   374  	}
   375  
   376  	actual := variablesStr(c.Variables)
   377  	if actual != strings.TrimSpace(dirOverrideVariablesStr) {
   378  		t.Fatalf("bad:\n%s", actual)
   379  	}
   380  
   381  	actual = providerConfigsStr(c.ProviderConfigs)
   382  	if actual != strings.TrimSpace(dirOverrideProvidersStr) {
   383  		t.Fatalf("bad:\n%s", actual)
   384  	}
   385  
   386  	actual = resourcesStr(c.Resources)
   387  	if actual != strings.TrimSpace(dirOverrideResourcesStr) {
   388  		t.Fatalf("bad:\n%s", actual)
   389  	}
   390  
   391  	actual = outputsStr(c.Outputs)
   392  	if actual != strings.TrimSpace(dirOverrideOutputsStr) {
   393  		t.Fatalf("bad:\n%s", actual)
   394  	}
   395  }
   396  
   397  func TestLoadFile_provisioners(t *testing.T) {
   398  	c, err := LoadFile(filepath.Join(fixtureDir, "provisioners.tf"))
   399  	if err != nil {
   400  		t.Fatalf("err: %s", err)
   401  	}
   402  
   403  	if c == nil {
   404  		t.Fatal("config should not be nil")
   405  	}
   406  
   407  	actual := resourcesStr(c.Resources)
   408  	if actual != strings.TrimSpace(provisionerResourcesStr) {
   409  		t.Fatalf("bad:\n%s", actual)
   410  	}
   411  }
   412  
   413  func TestLoadFile_connections(t *testing.T) {
   414  	c, err := LoadFile(filepath.Join(fixtureDir, "connection.tf"))
   415  	if err != nil {
   416  		t.Fatalf("err: %s", err)
   417  	}
   418  
   419  	if c == nil {
   420  		t.Fatal("config should not be nil")
   421  	}
   422  
   423  	actual := resourcesStr(c.Resources)
   424  	if actual != strings.TrimSpace(connectionResourcesStr) {
   425  		t.Fatalf("bad:\n%s", actual)
   426  	}
   427  
   428  	// Check for the connection info
   429  	r := c.Resources[0]
   430  	if r.Name != "web" && r.Type != "aws_instance" {
   431  		t.Fatalf("Bad: %#v", r)
   432  	}
   433  
   434  	p1 := r.Provisioners[0]
   435  	if p1.ConnInfo == nil || len(p1.ConnInfo.Raw) != 2 {
   436  		t.Fatalf("Bad: %#v", p1.ConnInfo)
   437  	}
   438  	if p1.ConnInfo.Raw["user"] != "nobody" {
   439  		t.Fatalf("Bad: %#v", p1.ConnInfo)
   440  	}
   441  
   442  	p2 := r.Provisioners[1]
   443  	if p2.ConnInfo == nil || len(p2.ConnInfo.Raw) != 2 {
   444  		t.Fatalf("Bad: %#v", p2.ConnInfo)
   445  	}
   446  	if p2.ConnInfo.Raw["user"] != "root" {
   447  		t.Fatalf("Bad: %#v", p2.ConnInfo)
   448  	}
   449  }
   450  
   451  func TestLoadFile_createBeforeDestroy(t *testing.T) {
   452  	c, err := LoadFile(filepath.Join(fixtureDir, "create-before-destroy.tf"))
   453  	if err != nil {
   454  		t.Fatalf("err: %s", err)
   455  	}
   456  
   457  	if c == nil {
   458  		t.Fatal("config should not be nil")
   459  	}
   460  
   461  	actual := resourcesStr(c.Resources)
   462  	if actual != strings.TrimSpace(createBeforeDestroyResourcesStr) {
   463  		t.Fatalf("bad:\n%s", actual)
   464  	}
   465  
   466  	// Check for the flag value
   467  	r := c.Resources[0]
   468  	if r.Name != "web" && r.Type != "aws_instance" {
   469  		t.Fatalf("Bad: %#v", r)
   470  	}
   471  
   472  	// Should enable create before destroy
   473  	if !r.Lifecycle.CreateBeforeDestroy {
   474  		t.Fatalf("Bad: %#v", r)
   475  	}
   476  
   477  	r = c.Resources[1]
   478  	if r.Name != "bar" && r.Type != "aws_instance" {
   479  		t.Fatalf("Bad: %#v", r)
   480  	}
   481  
   482  	// Should not enable create before destroy
   483  	if r.Lifecycle.CreateBeforeDestroy {
   484  		t.Fatalf("Bad: %#v", r)
   485  	}
   486  }
   487  
   488  func TestLoadFile_ignoreChanges(t *testing.T) {
   489  	c, err := LoadFile(filepath.Join(fixtureDir, "ignore-changes.tf"))
   490  	if err != nil {
   491  		t.Fatalf("err: %s", err)
   492  	}
   493  
   494  	if c == nil {
   495  		t.Fatal("config should not be nil")
   496  	}
   497  
   498  	actual := resourcesStr(c.Resources)
   499  	print(actual)
   500  	if actual != strings.TrimSpace(ignoreChangesResourcesStr) {
   501  		t.Fatalf("bad:\n%s", actual)
   502  	}
   503  
   504  	// Check for the flag value
   505  	r := c.Resources[0]
   506  	if r.Name != "web" && r.Type != "aws_instance" {
   507  		t.Fatalf("Bad: %#v", r)
   508  	}
   509  
   510  	// Should populate ignore changes
   511  	if len(r.Lifecycle.IgnoreChanges) == 0 {
   512  		t.Fatalf("Bad: %#v", r)
   513  	}
   514  
   515  	r = c.Resources[1]
   516  	if r.Name != "bar" && r.Type != "aws_instance" {
   517  		t.Fatalf("Bad: %#v", r)
   518  	}
   519  
   520  	// Should not populate ignore changes
   521  	if len(r.Lifecycle.IgnoreChanges) > 0 {
   522  		t.Fatalf("Bad: %#v", r)
   523  	}
   524  
   525  	r = c.Resources[2]
   526  	if r.Name != "baz" && r.Type != "aws_instance" {
   527  		t.Fatalf("Bad: %#v", r)
   528  	}
   529  
   530  	// Should not populate ignore changes
   531  	if len(r.Lifecycle.IgnoreChanges) > 0 {
   532  		t.Fatalf("Bad: %#v", r)
   533  	}
   534  }
   535  
   536  func TestLoad_preventDestroyString(t *testing.T) {
   537  	c, err := LoadFile(filepath.Join(fixtureDir, "prevent-destroy-string.tf"))
   538  	if err != nil {
   539  		t.Fatalf("err: %s", err)
   540  	}
   541  
   542  	if c == nil {
   543  		t.Fatal("config should not be nil")
   544  	}
   545  
   546  	actual := resourcesStr(c.Resources)
   547  	if actual != strings.TrimSpace(createBeforeDestroyResourcesStr) {
   548  		t.Fatalf("bad:\n%s", actual)
   549  	}
   550  
   551  	// Check for the flag value
   552  	r := c.Resources[0]
   553  	if r.Name != "web" && r.Type != "aws_instance" {
   554  		t.Fatalf("Bad: %#v", r)
   555  	}
   556  
   557  	// Should enable create before destroy
   558  	if !r.Lifecycle.PreventDestroy {
   559  		t.Fatalf("Bad: %#v", r)
   560  	}
   561  
   562  	r = c.Resources[1]
   563  	if r.Name != "bar" && r.Type != "aws_instance" {
   564  		t.Fatalf("Bad: %#v", r)
   565  	}
   566  
   567  	// Should not enable create before destroy
   568  	if r.Lifecycle.PreventDestroy {
   569  		t.Fatalf("Bad: %#v", r)
   570  	}
   571  }
   572  
   573  func TestLoad_temporary_files(t *testing.T) {
   574  	_, err := LoadDir(filepath.Join(fixtureDir, "dir-temporary-files"))
   575  	if err == nil {
   576  		t.Fatalf("Expected to see an error stating no config files found")
   577  	}
   578  }
   579  
   580  func TestLoad_hclAttributes(t *testing.T) {
   581  	c, err := LoadFile(filepath.Join(fixtureDir, "attributes.tf"))
   582  	if err != nil {
   583  		t.Fatalf("Bad: %s", err)
   584  	}
   585  
   586  	if c == nil {
   587  		t.Fatal("config should not be nil")
   588  	}
   589  
   590  	actual := resourcesStr(c.Resources)
   591  	print(actual)
   592  	if actual != strings.TrimSpace(jsonAttributeStr) {
   593  		t.Fatalf("bad:\n%s", actual)
   594  	}
   595  
   596  	r := c.Resources[0]
   597  	if r.Name != "test" && r.Type != "cloudstack_firewall" {
   598  		t.Fatalf("Bad: %#v", r)
   599  	}
   600  
   601  	raw := r.RawConfig
   602  	if raw.Raw["ipaddress"] != "192.168.0.1" {
   603  		t.Fatalf("Bad: %s", raw.Raw["ipAddress"])
   604  	}
   605  
   606  	rule := raw.Raw["rule"].([]map[string]interface{})[0]
   607  	if rule["protocol"] != "tcp" {
   608  		t.Fatalf("Bad: %s", rule["protocol"])
   609  	}
   610  
   611  	if rule["source_cidr"] != "10.0.0.0/8" {
   612  		t.Fatalf("Bad: %s", rule["source_cidr"])
   613  	}
   614  
   615  	ports := rule["ports"].([]interface{})
   616  
   617  	if ports[0] != "80" {
   618  		t.Fatalf("Bad ports: %s", ports[0])
   619  	}
   620  	if ports[1] != "1000-2000" {
   621  		t.Fatalf("Bad ports: %s", ports[1])
   622  	}
   623  }
   624  
   625  func TestLoad_jsonAttributes(t *testing.T) {
   626  	c, err := LoadFile(filepath.Join(fixtureDir, "attributes.tf.json"))
   627  	if err != nil {
   628  		t.Fatalf("Bad: %s", err)
   629  	}
   630  
   631  	if c == nil {
   632  		t.Fatal("config should not be nil")
   633  	}
   634  
   635  	actual := resourcesStr(c.Resources)
   636  	print(actual)
   637  	if actual != strings.TrimSpace(jsonAttributeStr) {
   638  		t.Fatalf("bad:\n%s", actual)
   639  	}
   640  
   641  	r := c.Resources[0]
   642  	if r.Name != "test" && r.Type != "cloudstack_firewall" {
   643  		t.Fatalf("Bad: %#v", r)
   644  	}
   645  
   646  	raw := r.RawConfig
   647  	if raw.Raw["ipaddress"] != "192.168.0.1" {
   648  		t.Fatalf("Bad: %s", raw.Raw["ipAddress"])
   649  	}
   650  
   651  	rule := raw.Raw["rule"].([]map[string]interface{})[0]
   652  	if rule["protocol"] != "tcp" {
   653  		t.Fatalf("Bad: %s", rule["protocol"])
   654  	}
   655  
   656  	if rule["source_cidr"] != "10.0.0.0/8" {
   657  		t.Fatalf("Bad: %s", rule["source_cidr"])
   658  	}
   659  
   660  	ports := rule["ports"].([]interface{})
   661  
   662  	if ports[0] != "80" {
   663  		t.Fatalf("Bad ports: %s", ports[0])
   664  	}
   665  	if ports[1] != "1000-2000" {
   666  		t.Fatalf("Bad ports: %s", ports[1])
   667  	}
   668  }
   669  
   670  const jsonAttributeStr = `
   671  cloudstack_firewall[test] (x1)
   672    ipaddress
   673    rule
   674  `
   675  
   676  const heredocProvidersStr = `
   677  aws
   678    access_key
   679    secret_key
   680  `
   681  
   682  const heredocResourcesStr = `
   683  aws_iam_policy[policy] (x1)
   684    description
   685    name
   686    path
   687    policy
   688  `
   689  
   690  const escapedquotesResourcesStr = `
   691  aws_instance[quotes] (x1)
   692    ami
   693    vars
   694      user: var.ami
   695  `
   696  
   697  const basicOutputsStr = `
   698  web_ip
   699    vars
   700      resource: aws_instance.web.private_ip
   701  `
   702  
   703  const basicProvidersStr = `
   704  aws
   705    access_key
   706    secret_key
   707  do
   708    api_key
   709    vars
   710      user: var.foo
   711  `
   712  
   713  const basicResourcesStr = `
   714  aws_instance[db] (x1)
   715    VPC
   716    security_groups
   717    provisioners
   718      file
   719        destination
   720        source
   721    dependsOn
   722      aws_instance.web
   723    vars
   724      resource: aws_security_group.firewall.*.id
   725  aws_instance[web] (x1)
   726    ami
   727    network_interface
   728    security_groups
   729    provisioners
   730      file
   731        destination
   732        source
   733    vars
   734      resource: aws_security_group.firewall.foo
   735      user: var.foo
   736  aws_security_group[firewall] (x5)
   737  `
   738  
   739  const basicVariablesStr = `
   740  foo
   741    bar
   742    bar
   743  `
   744  
   745  const dirBasicOutputsStr = `
   746  web_ip
   747    vars
   748      resource: aws_instance.web.private_ip
   749  `
   750  
   751  const dirBasicProvidersStr = `
   752  aws
   753    access_key
   754    secret_key
   755  do
   756    api_key
   757    vars
   758      user: var.foo
   759  `
   760  
   761  const dirBasicResourcesStr = `
   762  aws_instance[db] (x1)
   763    security_groups
   764    vars
   765      resource: aws_security_group.firewall.*.id
   766  aws_instance[web] (x1)
   767    ami
   768    network_interface
   769    security_groups
   770    vars
   771      resource: aws_security_group.firewall.foo
   772      user: var.foo
   773  aws_security_group[firewall] (x5)
   774  `
   775  
   776  const dirBasicVariablesStr = `
   777  foo
   778    bar
   779    bar
   780  `
   781  
   782  const dirOverrideOutputsStr = `
   783  web_ip
   784    vars
   785      resource: aws_instance.web.private_ip
   786  `
   787  
   788  const dirOverrideProvidersStr = `
   789  aws
   790    access_key
   791    secret_key
   792  do
   793    api_key
   794    vars
   795      user: var.foo
   796  `
   797  
   798  const dirOverrideResourcesStr = `
   799  aws_instance[db] (x1)
   800    ami
   801    security_groups
   802  aws_instance[web] (x1)
   803    ami
   804    foo
   805    network_interface
   806    security_groups
   807    vars
   808      resource: aws_security_group.firewall.foo
   809      user: var.foo
   810  aws_security_group[firewall] (x5)
   811  `
   812  
   813  const dirOverrideVariablesStr = `
   814  foo
   815    bar
   816    bar
   817  `
   818  
   819  const importProvidersStr = `
   820  aws
   821    bar
   822    foo
   823  `
   824  
   825  const importResourcesStr = `
   826  aws_security_group[db] (x1)
   827  aws_security_group[web] (x1)
   828  `
   829  
   830  const importVariablesStr = `
   831  bar (required)
   832    <>
   833    <>
   834  foo
   835    bar
   836    bar
   837  `
   838  
   839  const modulesModulesStr = `
   840  bar
   841    source = baz
   842    memory
   843  `
   844  
   845  const provisionerResourcesStr = `
   846  aws_instance[web] (x1)
   847    ami
   848    security_groups
   849    provisioners
   850      shell
   851        path
   852    vars
   853      resource: aws_security_group.firewall.foo
   854      user: var.foo
   855  `
   856  
   857  const connectionResourcesStr = `
   858  aws_instance[web] (x1)
   859    ami
   860    security_groups
   861    provisioners
   862      shell
   863        path
   864      shell
   865        path
   866    vars
   867      resource: aws_security_group.firewall.foo
   868      user: var.foo
   869  `
   870  
   871  const variablesVariablesStr = `
   872  bar
   873    <>
   874    <>
   875  baz
   876    foo
   877    <>
   878  foo (required)
   879    <>
   880    <>
   881  `
   882  
   883  const createBeforeDestroyResourcesStr = `
   884  aws_instance[bar] (x1)
   885    ami
   886  aws_instance[web] (x1)
   887    ami
   888  `
   889  
   890  const ignoreChangesResourcesStr = `
   891  aws_instance[bar] (x1)
   892    ami
   893  aws_instance[baz] (x1)
   894    ami
   895  aws_instance[web] (x1)
   896    ami
   897  `