github.com/anuaimi/terraform@v0.6.4-0.20150904235404-2bf9aec61da8/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 TestLoadFileBasic(t *testing.T) {
    49  	c, err := LoadFile(filepath.Join(fixtureDir, "basic.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  	expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"}
    63  	if !reflect.DeepEqual(c.Atlas, expectedAtlas) {
    64  		t.Fatalf("bad: %#v", c.Atlas)
    65  	}
    66  
    67  	actual := variablesStr(c.Variables)
    68  	if actual != strings.TrimSpace(basicVariablesStr) {
    69  		t.Fatalf("bad:\n%s", actual)
    70  	}
    71  
    72  	actual = providerConfigsStr(c.ProviderConfigs)
    73  	if actual != strings.TrimSpace(basicProvidersStr) {
    74  		t.Fatalf("bad:\n%s", actual)
    75  	}
    76  
    77  	actual = resourcesStr(c.Resources)
    78  	if actual != strings.TrimSpace(basicResourcesStr) {
    79  		t.Fatalf("bad:\n%s", actual)
    80  	}
    81  
    82  	actual = outputsStr(c.Outputs)
    83  	if actual != strings.TrimSpace(basicOutputsStr) {
    84  		t.Fatalf("bad:\n%s", actual)
    85  	}
    86  }
    87  
    88  func TestLoadFileBasic_empty(t *testing.T) {
    89  	c, err := LoadFile(filepath.Join(fixtureDir, "empty.tf"))
    90  	if err != nil {
    91  		t.Fatalf("err: %s", err)
    92  	}
    93  
    94  	if c == nil {
    95  		t.Fatal("config should not be nil")
    96  	}
    97  }
    98  
    99  func TestLoadFileBasic_import(t *testing.T) {
   100  	// Skip because we disabled importing
   101  	t.Skip()
   102  
   103  	c, err := LoadFile(filepath.Join(fixtureDir, "import.tf"))
   104  	if err != nil {
   105  		t.Fatalf("err: %s", err)
   106  	}
   107  
   108  	if c == nil {
   109  		t.Fatal("config should not be nil")
   110  	}
   111  
   112  	actual := variablesStr(c.Variables)
   113  	if actual != strings.TrimSpace(importVariablesStr) {
   114  		t.Fatalf("bad:\n%s", actual)
   115  	}
   116  
   117  	actual = providerConfigsStr(c.ProviderConfigs)
   118  	if actual != strings.TrimSpace(importProvidersStr) {
   119  		t.Fatalf("bad:\n%s", actual)
   120  	}
   121  
   122  	actual = resourcesStr(c.Resources)
   123  	if actual != strings.TrimSpace(importResourcesStr) {
   124  		t.Fatalf("bad:\n%s", actual)
   125  	}
   126  }
   127  
   128  func TestLoadFileBasic_json(t *testing.T) {
   129  	c, err := LoadFile(filepath.Join(fixtureDir, "basic.tf.json"))
   130  	if err != nil {
   131  		t.Fatalf("err: %s", err)
   132  	}
   133  
   134  	if c == nil {
   135  		t.Fatal("config should not be nil")
   136  	}
   137  
   138  	if c.Dir != "" {
   139  		t.Fatalf("bad: %#v", c.Dir)
   140  	}
   141  
   142  	expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"}
   143  	if !reflect.DeepEqual(c.Atlas, expectedAtlas) {
   144  		t.Fatalf("bad: %#v", c.Atlas)
   145  	}
   146  
   147  	actual := variablesStr(c.Variables)
   148  	if actual != strings.TrimSpace(basicVariablesStr) {
   149  		t.Fatalf("bad:\n%s", actual)
   150  	}
   151  
   152  	actual = providerConfigsStr(c.ProviderConfigs)
   153  	if actual != strings.TrimSpace(basicProvidersStr) {
   154  		t.Fatalf("bad:\n%s", actual)
   155  	}
   156  
   157  	actual = resourcesStr(c.Resources)
   158  	if actual != strings.TrimSpace(basicResourcesStr) {
   159  		t.Fatalf("bad:\n%s", actual)
   160  	}
   161  
   162  	actual = outputsStr(c.Outputs)
   163  	if actual != strings.TrimSpace(basicOutputsStr) {
   164  		t.Fatalf("bad:\n%s", actual)
   165  	}
   166  }
   167  
   168  func TestLoadFileBasic_modules(t *testing.T) {
   169  	c, err := LoadFile(filepath.Join(fixtureDir, "modules.tf"))
   170  	if err != nil {
   171  		t.Fatalf("err: %s", err)
   172  	}
   173  
   174  	if c == nil {
   175  		t.Fatal("config should not be nil")
   176  	}
   177  
   178  	if c.Dir != "" {
   179  		t.Fatalf("bad: %#v", c.Dir)
   180  	}
   181  
   182  	actual := modulesStr(c.Modules)
   183  	if actual != strings.TrimSpace(modulesModulesStr) {
   184  		t.Fatalf("bad:\n%s", actual)
   185  	}
   186  }
   187  
   188  func TestLoadJSONBasic(t *testing.T) {
   189  	raw, err := ioutil.ReadFile(filepath.Join(fixtureDir, "basic.tf.json"))
   190  	if err != nil {
   191  		t.Fatalf("err: %s", err)
   192  	}
   193  
   194  	c, err := LoadJSON(raw)
   195  	if err != nil {
   196  		t.Fatalf("err: %s", err)
   197  	}
   198  
   199  	if c == nil {
   200  		t.Fatal("config should not be nil")
   201  	}
   202  
   203  	if c.Dir != "" {
   204  		t.Fatalf("bad: %#v", c.Dir)
   205  	}
   206  
   207  	expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"}
   208  	if !reflect.DeepEqual(c.Atlas, expectedAtlas) {
   209  		t.Fatalf("bad: %#v", c.Atlas)
   210  	}
   211  
   212  	actual := variablesStr(c.Variables)
   213  	if actual != strings.TrimSpace(basicVariablesStr) {
   214  		t.Fatalf("bad:\n%s", actual)
   215  	}
   216  
   217  	actual = providerConfigsStr(c.ProviderConfigs)
   218  	if actual != strings.TrimSpace(basicProvidersStr) {
   219  		t.Fatalf("bad:\n%s", actual)
   220  	}
   221  
   222  	actual = resourcesStr(c.Resources)
   223  	if actual != strings.TrimSpace(basicResourcesStr) {
   224  		t.Fatalf("bad:\n%s", actual)
   225  	}
   226  
   227  	actual = outputsStr(c.Outputs)
   228  	if actual != strings.TrimSpace(basicOutputsStr) {
   229  		t.Fatalf("bad:\n%s", actual)
   230  	}
   231  }
   232  
   233  func TestLoadFile_variables(t *testing.T) {
   234  	c, err := LoadFile(filepath.Join(fixtureDir, "variables.tf"))
   235  	if err != nil {
   236  		t.Fatalf("err: %s", err)
   237  	}
   238  	if c == nil {
   239  		t.Fatal("config should not be nil")
   240  	}
   241  
   242  	if c.Dir != "" {
   243  		t.Fatalf("bad: %#v", c.Dir)
   244  	}
   245  
   246  	actual := variablesStr(c.Variables)
   247  	if actual != strings.TrimSpace(variablesVariablesStr) {
   248  		t.Fatalf("bad:\n%s", actual)
   249  	}
   250  }
   251  
   252  func TestLoadDir_basic(t *testing.T) {
   253  	dir := filepath.Join(fixtureDir, "dir-basic")
   254  	c, err := LoadDir(dir)
   255  	if err != nil {
   256  		t.Fatalf("err: %s", err)
   257  	}
   258  
   259  	if c == nil {
   260  		t.Fatal("config should not be nil")
   261  	}
   262  
   263  	dirAbs, err := filepath.Abs(dir)
   264  	if err != nil {
   265  		t.Fatalf("err: %s", err)
   266  	}
   267  	if c.Dir != dirAbs {
   268  		t.Fatalf("bad: %#v", c.Dir)
   269  	}
   270  
   271  	actual := variablesStr(c.Variables)
   272  	if actual != strings.TrimSpace(dirBasicVariablesStr) {
   273  		t.Fatalf("bad:\n%s", actual)
   274  	}
   275  
   276  	actual = providerConfigsStr(c.ProviderConfigs)
   277  	if actual != strings.TrimSpace(dirBasicProvidersStr) {
   278  		t.Fatalf("bad:\n%s", actual)
   279  	}
   280  
   281  	actual = resourcesStr(c.Resources)
   282  	if actual != strings.TrimSpace(dirBasicResourcesStr) {
   283  		t.Fatalf("bad:\n%s", actual)
   284  	}
   285  
   286  	actual = outputsStr(c.Outputs)
   287  	if actual != strings.TrimSpace(dirBasicOutputsStr) {
   288  		t.Fatalf("bad:\n%s", actual)
   289  	}
   290  }
   291  
   292  func TestLoadDir_file(t *testing.T) {
   293  	_, err := LoadDir(filepath.Join(fixtureDir, "variables.tf"))
   294  	if err == nil {
   295  		t.Fatal("should error")
   296  	}
   297  }
   298  
   299  func TestLoadDir_noConfigs(t *testing.T) {
   300  	_, err := LoadDir(filepath.Join(fixtureDir, "dir-empty"))
   301  	if err == nil {
   302  		t.Fatal("should error")
   303  	}
   304  }
   305  
   306  func TestLoadDir_noMerge(t *testing.T) {
   307  	c, err := LoadDir(filepath.Join(fixtureDir, "dir-merge"))
   308  	if err != nil {
   309  		t.Fatalf("err: %s", err)
   310  	}
   311  
   312  	if c == nil {
   313  		t.Fatal("config should not be nil")
   314  	}
   315  
   316  	if err := c.Validate(); err == nil {
   317  		t.Fatal("should not be valid")
   318  	}
   319  }
   320  
   321  func TestLoadDir_override(t *testing.T) {
   322  	c, err := LoadDir(filepath.Join(fixtureDir, "dir-override"))
   323  	if err != nil {
   324  		t.Fatalf("err: %s", err)
   325  	}
   326  
   327  	if c == nil {
   328  		t.Fatal("config should not be nil")
   329  	}
   330  
   331  	actual := variablesStr(c.Variables)
   332  	if actual != strings.TrimSpace(dirOverrideVariablesStr) {
   333  		t.Fatalf("bad:\n%s", actual)
   334  	}
   335  
   336  	actual = providerConfigsStr(c.ProviderConfigs)
   337  	if actual != strings.TrimSpace(dirOverrideProvidersStr) {
   338  		t.Fatalf("bad:\n%s", actual)
   339  	}
   340  
   341  	actual = resourcesStr(c.Resources)
   342  	if actual != strings.TrimSpace(dirOverrideResourcesStr) {
   343  		t.Fatalf("bad:\n%s", actual)
   344  	}
   345  
   346  	actual = outputsStr(c.Outputs)
   347  	if actual != strings.TrimSpace(dirOverrideOutputsStr) {
   348  		t.Fatalf("bad:\n%s", actual)
   349  	}
   350  }
   351  
   352  func TestLoadFile_provisioners(t *testing.T) {
   353  	c, err := LoadFile(filepath.Join(fixtureDir, "provisioners.tf"))
   354  	if err != nil {
   355  		t.Fatalf("err: %s", err)
   356  	}
   357  
   358  	if c == nil {
   359  		t.Fatal("config should not be nil")
   360  	}
   361  
   362  	actual := resourcesStr(c.Resources)
   363  	if actual != strings.TrimSpace(provisionerResourcesStr) {
   364  		t.Fatalf("bad:\n%s", actual)
   365  	}
   366  }
   367  
   368  func TestLoadFile_connections(t *testing.T) {
   369  	c, err := LoadFile(filepath.Join(fixtureDir, "connection.tf"))
   370  	if err != nil {
   371  		t.Fatalf("err: %s", err)
   372  	}
   373  
   374  	if c == nil {
   375  		t.Fatal("config should not be nil")
   376  	}
   377  
   378  	actual := resourcesStr(c.Resources)
   379  	if actual != strings.TrimSpace(connectionResourcesStr) {
   380  		t.Fatalf("bad:\n%s", actual)
   381  	}
   382  
   383  	// Check for the connection info
   384  	r := c.Resources[0]
   385  	if r.Name != "web" && r.Type != "aws_instance" {
   386  		t.Fatalf("Bad: %#v", r)
   387  	}
   388  
   389  	p1 := r.Provisioners[0]
   390  	if p1.ConnInfo == nil || len(p1.ConnInfo.Raw) != 2 {
   391  		t.Fatalf("Bad: %#v", p1.ConnInfo)
   392  	}
   393  	if p1.ConnInfo.Raw["user"] != "nobody" {
   394  		t.Fatalf("Bad: %#v", p1.ConnInfo)
   395  	}
   396  
   397  	p2 := r.Provisioners[1]
   398  	if p2.ConnInfo == nil || len(p2.ConnInfo.Raw) != 2 {
   399  		t.Fatalf("Bad: %#v", p2.ConnInfo)
   400  	}
   401  	if p2.ConnInfo.Raw["user"] != "root" {
   402  		t.Fatalf("Bad: %#v", p2.ConnInfo)
   403  	}
   404  }
   405  
   406  func TestLoadFile_createBeforeDestroy(t *testing.T) {
   407  	c, err := LoadFile(filepath.Join(fixtureDir, "create-before-destroy.tf"))
   408  	if err != nil {
   409  		t.Fatalf("err: %s", err)
   410  	}
   411  
   412  	if c == nil {
   413  		t.Fatal("config should not be nil")
   414  	}
   415  
   416  	actual := resourcesStr(c.Resources)
   417  	if actual != strings.TrimSpace(createBeforeDestroyResourcesStr) {
   418  		t.Fatalf("bad:\n%s", actual)
   419  	}
   420  
   421  	// Check for the flag value
   422  	r := c.Resources[0]
   423  	if r.Name != "web" && r.Type != "aws_instance" {
   424  		t.Fatalf("Bad: %#v", r)
   425  	}
   426  
   427  	// Should enable create before destroy
   428  	if !r.Lifecycle.CreateBeforeDestroy {
   429  		t.Fatalf("Bad: %#v", r)
   430  	}
   431  
   432  	r = c.Resources[1]
   433  	if r.Name != "bar" && r.Type != "aws_instance" {
   434  		t.Fatalf("Bad: %#v", r)
   435  	}
   436  
   437  	// Should not enable create before destroy
   438  	if r.Lifecycle.CreateBeforeDestroy {
   439  		t.Fatalf("Bad: %#v", r)
   440  	}
   441  }
   442  
   443  func TestLoad_preventDestroyString(t *testing.T) {
   444  	c, err := LoadFile(filepath.Join(fixtureDir, "prevent-destroy-string.tf"))
   445  	if err != nil {
   446  		t.Fatalf("err: %s", err)
   447  	}
   448  
   449  	if c == nil {
   450  		t.Fatal("config should not be nil")
   451  	}
   452  
   453  	actual := resourcesStr(c.Resources)
   454  	if actual != strings.TrimSpace(createBeforeDestroyResourcesStr) {
   455  		t.Fatalf("bad:\n%s", actual)
   456  	}
   457  
   458  	// Check for the flag value
   459  	r := c.Resources[0]
   460  	if r.Name != "web" && r.Type != "aws_instance" {
   461  		t.Fatalf("Bad: %#v", r)
   462  	}
   463  
   464  	// Should enable create before destroy
   465  	if !r.Lifecycle.PreventDestroy {
   466  		t.Fatalf("Bad: %#v", r)
   467  	}
   468  
   469  	r = c.Resources[1]
   470  	if r.Name != "bar" && r.Type != "aws_instance" {
   471  		t.Fatalf("Bad: %#v", r)
   472  	}
   473  
   474  	// Should not enable create before destroy
   475  	if r.Lifecycle.PreventDestroy {
   476  		t.Fatalf("Bad: %#v", r)
   477  	}
   478  }
   479  
   480  func TestLoad_temporary_files(t *testing.T) {
   481  	_, err := LoadDir(filepath.Join(fixtureDir, "dir-temporary-files"))
   482  	if err == nil {
   483  		t.Fatalf("Expected to see an error stating no config files found")
   484  	}
   485  }
   486  
   487  const basicOutputsStr = `
   488  web_ip
   489    vars
   490      resource: aws_instance.web.private_ip
   491  `
   492  
   493  const basicProvidersStr = `
   494  aws
   495    access_key
   496    secret_key
   497  do
   498    api_key
   499    vars
   500      user: var.foo
   501  `
   502  
   503  const basicResourcesStr = `
   504  aws_instance[db] (x1)
   505    VPC
   506    security_groups
   507    provisioners
   508      file
   509        destination
   510        source
   511    dependsOn
   512      aws_instance.web
   513    vars
   514      resource: aws_security_group.firewall.*.id
   515  aws_instance[web] (x1)
   516    ami
   517    network_interface
   518    security_groups
   519    provisioners
   520      file
   521        destination
   522        source
   523    vars
   524      resource: aws_security_group.firewall.foo
   525      user: var.foo
   526  aws_security_group[firewall] (x5)
   527  `
   528  
   529  const basicVariablesStr = `
   530  foo
   531    bar
   532    bar
   533  `
   534  
   535  const dirBasicOutputsStr = `
   536  web_ip
   537    vars
   538      resource: aws_instance.web.private_ip
   539  `
   540  
   541  const dirBasicProvidersStr = `
   542  aws
   543    access_key
   544    secret_key
   545  do
   546    api_key
   547    vars
   548      user: var.foo
   549  `
   550  
   551  const dirBasicResourcesStr = `
   552  aws_instance[db] (x1)
   553    security_groups
   554    vars
   555      resource: aws_security_group.firewall.*.id
   556  aws_instance[web] (x1)
   557    ami
   558    network_interface
   559    security_groups
   560    vars
   561      resource: aws_security_group.firewall.foo
   562      user: var.foo
   563  aws_security_group[firewall] (x5)
   564  `
   565  
   566  const dirBasicVariablesStr = `
   567  foo
   568    bar
   569    bar
   570  `
   571  
   572  const dirOverrideOutputsStr = `
   573  web_ip
   574    vars
   575      resource: aws_instance.web.private_ip
   576  `
   577  
   578  const dirOverrideProvidersStr = `
   579  aws
   580    access_key
   581    secret_key
   582  do
   583    api_key
   584    vars
   585      user: var.foo
   586  `
   587  
   588  const dirOverrideResourcesStr = `
   589  aws_instance[db] (x1)
   590    ami
   591    security_groups
   592  aws_instance[web] (x1)
   593    ami
   594    foo
   595    network_interface
   596    security_groups
   597    vars
   598      resource: aws_security_group.firewall.foo
   599      user: var.foo
   600  aws_security_group[firewall] (x5)
   601  `
   602  
   603  const dirOverrideVariablesStr = `
   604  foo
   605    bar
   606    bar
   607  `
   608  
   609  const importProvidersStr = `
   610  aws
   611    bar
   612    foo
   613  `
   614  
   615  const importResourcesStr = `
   616  aws_security_group[db] (x1)
   617  aws_security_group[web] (x1)
   618  `
   619  
   620  const importVariablesStr = `
   621  bar (required)
   622    <>
   623    <>
   624  foo
   625    bar
   626    bar
   627  `
   628  
   629  const modulesModulesStr = `
   630  bar
   631    source = baz
   632    memory
   633  `
   634  
   635  const provisionerResourcesStr = `
   636  aws_instance[web] (x1)
   637    ami
   638    security_groups
   639    provisioners
   640      shell
   641        path
   642    vars
   643      resource: aws_security_group.firewall.foo
   644      user: var.foo
   645  `
   646  
   647  const connectionResourcesStr = `
   648  aws_instance[web] (x1)
   649    ami
   650    security_groups
   651    provisioners
   652      shell
   653        path
   654      shell
   655        path
   656    vars
   657      resource: aws_security_group.firewall.foo
   658      user: var.foo
   659  `
   660  
   661  const variablesVariablesStr = `
   662  bar
   663    <>
   664    <>
   665  baz
   666    foo
   667    <>
   668  foo (required)
   669    <>
   670    <>
   671  `
   672  
   673  const createBeforeDestroyResourcesStr = `
   674  aws_instance[bar] (x1)
   675    ami
   676  aws_instance[web] (x1)
   677    ami
   678  `