github.com/ggiamarchi/terraform@v0.3.7-0.20150607194748-ed2a66a46a71/config/loader_test.go (about)

     1  package config
     2  
     3  import (
     4  	"path/filepath"
     5  	"reflect"
     6  	"strings"
     7  	"testing"
     8  )
     9  
    10  func TestIsEmptyDir(t *testing.T) {
    11  	val, err := IsEmptyDir(fixtureDir)
    12  	if err != nil {
    13  		t.Fatalf("err: %s", err)
    14  	}
    15  	if val {
    16  		t.Fatal("should not be empty")
    17  	}
    18  }
    19  
    20  func TestIsEmptyDir_noExist(t *testing.T) {
    21  	val, err := IsEmptyDir(filepath.Join(fixtureDir, "nopenopenope"))
    22  	if err != nil {
    23  		t.Fatalf("err: %s", err)
    24  	}
    25  	if !val {
    26  		t.Fatal("should be empty")
    27  	}
    28  }
    29  
    30  func TestIsEmptyDir_noConfigs(t *testing.T) {
    31  	val, err := IsEmptyDir(filepath.Join(fixtureDir, "dir-empty"))
    32  	if err != nil {
    33  		t.Fatalf("err: %s", err)
    34  	}
    35  	if !val {
    36  		t.Fatal("should be empty")
    37  	}
    38  }
    39  
    40  func TestLoad_badType(t *testing.T) {
    41  	_, err := Load(filepath.Join(fixtureDir, "bad_type.tf.nope"))
    42  	if err == nil {
    43  		t.Fatal("should have error")
    44  	}
    45  }
    46  
    47  func TestLoadBasic(t *testing.T) {
    48  	c, err := Load(filepath.Join(fixtureDir, "basic.tf"))
    49  	if err != nil {
    50  		t.Fatalf("err: %s", err)
    51  	}
    52  
    53  	if c == nil {
    54  		t.Fatal("config should not be nil")
    55  	}
    56  
    57  	if c.Dir != "" {
    58  		t.Fatalf("bad: %#v", c.Dir)
    59  	}
    60  
    61  	expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"}
    62  	if !reflect.DeepEqual(c.Atlas, expectedAtlas) {
    63  		t.Fatalf("bad: %#v", c.Atlas)
    64  	}
    65  
    66  	actual := variablesStr(c.Variables)
    67  	if actual != strings.TrimSpace(basicVariablesStr) {
    68  		t.Fatalf("bad:\n%s", actual)
    69  	}
    70  
    71  	actual = providerConfigsStr(c.ProviderConfigs)
    72  	if actual != strings.TrimSpace(basicProvidersStr) {
    73  		t.Fatalf("bad:\n%s", actual)
    74  	}
    75  
    76  	actual = resourcesStr(c.Resources)
    77  	if actual != strings.TrimSpace(basicResourcesStr) {
    78  		t.Fatalf("bad:\n%s", actual)
    79  	}
    80  
    81  	actual = outputsStr(c.Outputs)
    82  	if actual != strings.TrimSpace(basicOutputsStr) {
    83  		t.Fatalf("bad:\n%s", actual)
    84  	}
    85  }
    86  
    87  func TestLoadBasic_empty(t *testing.T) {
    88  	c, err := Load(filepath.Join(fixtureDir, "empty.tf"))
    89  	if err != nil {
    90  		t.Fatalf("err: %s", err)
    91  	}
    92  
    93  	if c == nil {
    94  		t.Fatal("config should not be nil")
    95  	}
    96  }
    97  
    98  func TestLoadBasic_import(t *testing.T) {
    99  	// Skip because we disabled importing
   100  	t.Skip()
   101  
   102  	c, err := Load(filepath.Join(fixtureDir, "import.tf"))
   103  	if err != nil {
   104  		t.Fatalf("err: %s", err)
   105  	}
   106  
   107  	if c == nil {
   108  		t.Fatal("config should not be nil")
   109  	}
   110  
   111  	actual := variablesStr(c.Variables)
   112  	if actual != strings.TrimSpace(importVariablesStr) {
   113  		t.Fatalf("bad:\n%s", actual)
   114  	}
   115  
   116  	actual = providerConfigsStr(c.ProviderConfigs)
   117  	if actual != strings.TrimSpace(importProvidersStr) {
   118  		t.Fatalf("bad:\n%s", actual)
   119  	}
   120  
   121  	actual = resourcesStr(c.Resources)
   122  	if actual != strings.TrimSpace(importResourcesStr) {
   123  		t.Fatalf("bad:\n%s", actual)
   124  	}
   125  }
   126  
   127  func TestLoadBasic_json(t *testing.T) {
   128  	c, err := Load(filepath.Join(fixtureDir, "basic.tf.json"))
   129  	if err != nil {
   130  		t.Fatalf("err: %s", err)
   131  	}
   132  
   133  	if c == nil {
   134  		t.Fatal("config should not be nil")
   135  	}
   136  
   137  	if c.Dir != "" {
   138  		t.Fatalf("bad: %#v", c.Dir)
   139  	}
   140  
   141  	expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"}
   142  	if !reflect.DeepEqual(c.Atlas, expectedAtlas) {
   143  		t.Fatalf("bad: %#v", c.Atlas)
   144  	}
   145  
   146  	actual := variablesStr(c.Variables)
   147  	if actual != strings.TrimSpace(basicVariablesStr) {
   148  		t.Fatalf("bad:\n%s", actual)
   149  	}
   150  
   151  	actual = providerConfigsStr(c.ProviderConfigs)
   152  	if actual != strings.TrimSpace(basicProvidersStr) {
   153  		t.Fatalf("bad:\n%s", actual)
   154  	}
   155  
   156  	actual = resourcesStr(c.Resources)
   157  	if actual != strings.TrimSpace(basicResourcesStr) {
   158  		t.Fatalf("bad:\n%s", actual)
   159  	}
   160  
   161  	actual = outputsStr(c.Outputs)
   162  	if actual != strings.TrimSpace(basicOutputsStr) {
   163  		t.Fatalf("bad:\n%s", actual)
   164  	}
   165  }
   166  
   167  func TestLoadBasic_modules(t *testing.T) {
   168  	c, err := Load(filepath.Join(fixtureDir, "modules.tf"))
   169  	if err != nil {
   170  		t.Fatalf("err: %s", err)
   171  	}
   172  
   173  	if c == nil {
   174  		t.Fatal("config should not be nil")
   175  	}
   176  
   177  	if c.Dir != "" {
   178  		t.Fatalf("bad: %#v", c.Dir)
   179  	}
   180  
   181  	actual := modulesStr(c.Modules)
   182  	if actual != strings.TrimSpace(modulesModulesStr) {
   183  		t.Fatalf("bad:\n%s", actual)
   184  	}
   185  }
   186  
   187  func TestLoad_variables(t *testing.T) {
   188  	c, err := Load(filepath.Join(fixtureDir, "variables.tf"))
   189  	if err != nil {
   190  		t.Fatalf("err: %s", err)
   191  	}
   192  	if c == nil {
   193  		t.Fatal("config should not be nil")
   194  	}
   195  
   196  	if c.Dir != "" {
   197  		t.Fatalf("bad: %#v", c.Dir)
   198  	}
   199  
   200  	actual := variablesStr(c.Variables)
   201  	if actual != strings.TrimSpace(variablesVariablesStr) {
   202  		t.Fatalf("bad:\n%s", actual)
   203  	}
   204  }
   205  
   206  func TestLoadDir_basic(t *testing.T) {
   207  	dir := filepath.Join(fixtureDir, "dir-basic")
   208  	c, err := LoadDir(dir)
   209  	if err != nil {
   210  		t.Fatalf("err: %s", err)
   211  	}
   212  
   213  	if c == nil {
   214  		t.Fatal("config should not be nil")
   215  	}
   216  
   217  	dirAbs, err := filepath.Abs(dir)
   218  	if err != nil {
   219  		t.Fatalf("err: %s", err)
   220  	}
   221  	if c.Dir != dirAbs {
   222  		t.Fatalf("bad: %#v", c.Dir)
   223  	}
   224  
   225  	actual := variablesStr(c.Variables)
   226  	if actual != strings.TrimSpace(dirBasicVariablesStr) {
   227  		t.Fatalf("bad:\n%s", actual)
   228  	}
   229  
   230  	actual = providerConfigsStr(c.ProviderConfigs)
   231  	if actual != strings.TrimSpace(dirBasicProvidersStr) {
   232  		t.Fatalf("bad:\n%s", actual)
   233  	}
   234  
   235  	actual = resourcesStr(c.Resources)
   236  	if actual != strings.TrimSpace(dirBasicResourcesStr) {
   237  		t.Fatalf("bad:\n%s", actual)
   238  	}
   239  
   240  	actual = outputsStr(c.Outputs)
   241  	if actual != strings.TrimSpace(dirBasicOutputsStr) {
   242  		t.Fatalf("bad:\n%s", actual)
   243  	}
   244  }
   245  
   246  func TestLoadDir_file(t *testing.T) {
   247  	_, err := LoadDir(filepath.Join(fixtureDir, "variables.tf"))
   248  	if err == nil {
   249  		t.Fatal("should error")
   250  	}
   251  }
   252  
   253  func TestLoadDir_noConfigs(t *testing.T) {
   254  	_, err := LoadDir(filepath.Join(fixtureDir, "dir-empty"))
   255  	if err == nil {
   256  		t.Fatal("should error")
   257  	}
   258  }
   259  
   260  func TestLoadDir_noMerge(t *testing.T) {
   261  	c, err := LoadDir(filepath.Join(fixtureDir, "dir-merge"))
   262  	if err != nil {
   263  		t.Fatalf("err: %s", err)
   264  	}
   265  
   266  	if c == nil {
   267  		t.Fatal("config should not be nil")
   268  	}
   269  
   270  	if err := c.Validate(); err == nil {
   271  		t.Fatal("should not be valid")
   272  	}
   273  }
   274  
   275  func TestLoadDir_override(t *testing.T) {
   276  	c, err := LoadDir(filepath.Join(fixtureDir, "dir-override"))
   277  	if err != nil {
   278  		t.Fatalf("err: %s", err)
   279  	}
   280  
   281  	if c == nil {
   282  		t.Fatal("config should not be nil")
   283  	}
   284  
   285  	actual := variablesStr(c.Variables)
   286  	if actual != strings.TrimSpace(dirOverrideVariablesStr) {
   287  		t.Fatalf("bad:\n%s", actual)
   288  	}
   289  
   290  	actual = providerConfigsStr(c.ProviderConfigs)
   291  	if actual != strings.TrimSpace(dirOverrideProvidersStr) {
   292  		t.Fatalf("bad:\n%s", actual)
   293  	}
   294  
   295  	actual = resourcesStr(c.Resources)
   296  	if actual != strings.TrimSpace(dirOverrideResourcesStr) {
   297  		t.Fatalf("bad:\n%s", actual)
   298  	}
   299  
   300  	actual = outputsStr(c.Outputs)
   301  	if actual != strings.TrimSpace(dirOverrideOutputsStr) {
   302  		t.Fatalf("bad:\n%s", actual)
   303  	}
   304  }
   305  
   306  func TestLoad_provisioners(t *testing.T) {
   307  	c, err := Load(filepath.Join(fixtureDir, "provisioners.tf"))
   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  	actual := resourcesStr(c.Resources)
   317  	if actual != strings.TrimSpace(provisionerResourcesStr) {
   318  		t.Fatalf("bad:\n%s", actual)
   319  	}
   320  }
   321  
   322  func TestLoad_connections(t *testing.T) {
   323  	c, err := Load(filepath.Join(fixtureDir, "connection.tf"))
   324  	if err != nil {
   325  		t.Fatalf("err: %s", err)
   326  	}
   327  
   328  	if c == nil {
   329  		t.Fatal("config should not be nil")
   330  	}
   331  
   332  	actual := resourcesStr(c.Resources)
   333  	if actual != strings.TrimSpace(connectionResourcesStr) {
   334  		t.Fatalf("bad:\n%s", actual)
   335  	}
   336  
   337  	// Check for the connection info
   338  	r := c.Resources[0]
   339  	if r.Name != "web" && r.Type != "aws_instance" {
   340  		t.Fatalf("Bad: %#v", r)
   341  	}
   342  
   343  	p1 := r.Provisioners[0]
   344  	if p1.ConnInfo == nil || len(p1.ConnInfo.Raw) != 2 {
   345  		t.Fatalf("Bad: %#v", p1.ConnInfo)
   346  	}
   347  	if p1.ConnInfo.Raw["user"] != "nobody" {
   348  		t.Fatalf("Bad: %#v", p1.ConnInfo)
   349  	}
   350  
   351  	p2 := r.Provisioners[1]
   352  	if p2.ConnInfo == nil || len(p2.ConnInfo.Raw) != 2 {
   353  		t.Fatalf("Bad: %#v", p2.ConnInfo)
   354  	}
   355  	if p2.ConnInfo.Raw["user"] != "root" {
   356  		t.Fatalf("Bad: %#v", p2.ConnInfo)
   357  	}
   358  }
   359  
   360  func TestLoad_createBeforeDestroy(t *testing.T) {
   361  	c, err := Load(filepath.Join(fixtureDir, "create-before-destroy.tf"))
   362  	if err != nil {
   363  		t.Fatalf("err: %s", err)
   364  	}
   365  
   366  	if c == nil {
   367  		t.Fatal("config should not be nil")
   368  	}
   369  
   370  	actual := resourcesStr(c.Resources)
   371  	if actual != strings.TrimSpace(createBeforeDestroyResourcesStr) {
   372  		t.Fatalf("bad:\n%s", actual)
   373  	}
   374  
   375  	// Check for the flag value
   376  	r := c.Resources[0]
   377  	if r.Name != "web" && r.Type != "aws_instance" {
   378  		t.Fatalf("Bad: %#v", r)
   379  	}
   380  
   381  	// Should enable create before destroy
   382  	if !r.Lifecycle.CreateBeforeDestroy {
   383  		t.Fatalf("Bad: %#v", r)
   384  	}
   385  
   386  	r = c.Resources[1]
   387  	if r.Name != "bar" && r.Type != "aws_instance" {
   388  		t.Fatalf("Bad: %#v", r)
   389  	}
   390  
   391  	// Should not enable create before destroy
   392  	if r.Lifecycle.CreateBeforeDestroy {
   393  		t.Fatalf("Bad: %#v", r)
   394  	}
   395  }
   396  
   397  func TestLoad_temporary_files(t *testing.T) {
   398  	_, err := LoadDir(filepath.Join(fixtureDir, "dir-temporary-files"))
   399  	if err == nil {
   400  		t.Fatalf("Expected to see an error stating no config files found")
   401  	}
   402  }
   403  
   404  const basicOutputsStr = `
   405  web_ip
   406    vars
   407      resource: aws_instance.web.private_ip
   408  `
   409  
   410  const basicProvidersStr = `
   411  aws
   412    access_key
   413    secret_key
   414  do
   415    api_key
   416    vars
   417      user: var.foo
   418  `
   419  
   420  const basicResourcesStr = `
   421  aws_instance[db] (x1)
   422    VPC
   423    security_groups
   424    provisioners
   425      file
   426        destination
   427        source
   428    dependsOn
   429      aws_instance.web
   430    vars
   431      resource: aws_security_group.firewall.*.id
   432  aws_instance[web] (x1)
   433    ami
   434    network_interface
   435    security_groups
   436    provisioners
   437      file
   438        destination
   439        source
   440    vars
   441      resource: aws_security_group.firewall.foo
   442      user: var.foo
   443  aws_security_group[firewall] (x5)
   444  `
   445  
   446  const basicVariablesStr = `
   447  foo
   448    bar
   449    bar
   450  `
   451  
   452  const dirBasicOutputsStr = `
   453  web_ip
   454    vars
   455      resource: aws_instance.web.private_ip
   456  `
   457  
   458  const dirBasicProvidersStr = `
   459  aws
   460    access_key
   461    secret_key
   462  do
   463    api_key
   464    vars
   465      user: var.foo
   466  `
   467  
   468  const dirBasicResourcesStr = `
   469  aws_instance[db] (x1)
   470    security_groups
   471    vars
   472      resource: aws_security_group.firewall.*.id
   473  aws_instance[web] (x1)
   474    ami
   475    network_interface
   476    security_groups
   477    vars
   478      resource: aws_security_group.firewall.foo
   479      user: var.foo
   480  aws_security_group[firewall] (x5)
   481  `
   482  
   483  const dirBasicVariablesStr = `
   484  foo
   485    bar
   486    bar
   487  `
   488  
   489  const dirOverrideOutputsStr = `
   490  web_ip
   491    vars
   492      resource: aws_instance.web.private_ip
   493  `
   494  
   495  const dirOverrideProvidersStr = `
   496  aws
   497    access_key
   498    secret_key
   499  do
   500    api_key
   501    vars
   502      user: var.foo
   503  `
   504  
   505  const dirOverrideResourcesStr = `
   506  aws_instance[db] (x1)
   507    ami
   508    security_groups
   509  aws_instance[web] (x1)
   510    ami
   511    foo
   512    network_interface
   513    security_groups
   514    vars
   515      resource: aws_security_group.firewall.foo
   516      user: var.foo
   517  aws_security_group[firewall] (x5)
   518  `
   519  
   520  const dirOverrideVariablesStr = `
   521  foo
   522    bar
   523    bar
   524  `
   525  
   526  const importProvidersStr = `
   527  aws
   528    bar
   529    foo
   530  `
   531  
   532  const importResourcesStr = `
   533  aws_security_group[db] (x1)
   534  aws_security_group[web] (x1)
   535  `
   536  
   537  const importVariablesStr = `
   538  bar (required)
   539    <>
   540    <>
   541  foo
   542    bar
   543    bar
   544  `
   545  
   546  const modulesModulesStr = `
   547  bar
   548    source = baz
   549    memory
   550  `
   551  
   552  const provisionerResourcesStr = `
   553  aws_instance[web] (x1)
   554    ami
   555    security_groups
   556    provisioners
   557      shell
   558        path
   559    vars
   560      resource: aws_security_group.firewall.foo
   561      user: var.foo
   562  `
   563  
   564  const connectionResourcesStr = `
   565  aws_instance[web] (x1)
   566    ami
   567    security_groups
   568    provisioners
   569      shell
   570        path
   571      shell
   572        path
   573    vars
   574      resource: aws_security_group.firewall.foo
   575      user: var.foo
   576  `
   577  
   578  const variablesVariablesStr = `
   579  bar
   580    <>
   581    <>
   582  baz
   583    foo
   584    <>
   585  foo (required)
   586    <>
   587    <>
   588  `
   589  
   590  const createBeforeDestroyResourcesStr = `
   591  aws_instance[bar] (x1)
   592    ami
   593  aws_instance[web] (x1)
   594    ami
   595  `