github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/template/datasource_template_file_test.go (about) 1 package template 2 3 import ( 4 "fmt" 5 "strings" 6 "sync" 7 "testing" 8 9 r "github.com/hashicorp/terraform/helper/resource" 10 "github.com/hashicorp/terraform/terraform" 11 ) 12 13 var testProviders = map[string]terraform.ResourceProvider{ 14 "template": Provider(), 15 } 16 17 func TestTemplateRendering(t *testing.T) { 18 var cases = []struct { 19 vars string 20 template string 21 want string 22 }{ 23 {`{}`, `ABC`, `ABC`}, 24 {`{a="foo"}`, `$${a}`, `foo`}, 25 {`{a="hello"}`, `$${replace(a, "ello", "i")}`, `hi`}, 26 {`{}`, `${1+2+3}`, `6`}, 27 {`{}`, `/`, `/`}, 28 } 29 30 for _, tt := range cases { 31 r.UnitTest(t, r.TestCase{ 32 Providers: testProviders, 33 Steps: []r.TestStep{ 34 r.TestStep{ 35 Config: testTemplateConfig(tt.template, tt.vars), 36 Check: func(s *terraform.State) error { 37 got := s.RootModule().Outputs["rendered"] 38 if tt.want != got.Value { 39 return fmt.Errorf("template:\n%s\nvars:\n%s\ngot:\n%s\nwant:\n%s\n", tt.template, tt.vars, got, tt.want) 40 } 41 return nil 42 }, 43 }, 44 }, 45 }) 46 } 47 } 48 49 func TestValidateVarsAttribute(t *testing.T) { 50 cases := map[string]struct { 51 Vars map[string]interface{} 52 ExpectErr string 53 }{ 54 "lists are invalid": { 55 map[string]interface{}{ 56 "list": []interface{}{}, 57 }, 58 `vars: cannot contain non-primitives`, 59 }, 60 "maps are invalid": { 61 map[string]interface{}{ 62 "map": map[string]interface{}{}, 63 }, 64 `vars: cannot contain non-primitives`, 65 }, 66 "strings, integers, floats, and bools are AOK": { 67 map[string]interface{}{ 68 "string": "foo", 69 "int": 1, 70 "bool": true, 71 "float": float64(1.0), 72 }, 73 ``, 74 }, 75 } 76 77 for tn, tc := range cases { 78 _, es := validateVarsAttribute(tc.Vars, "vars") 79 if len(es) > 0 { 80 if tc.ExpectErr == "" { 81 t.Fatalf("%s: expected no err, got: %#v", tn, es) 82 } 83 if !strings.Contains(es[0].Error(), tc.ExpectErr) { 84 t.Fatalf("%s: expected\n%s\nto contain\n%s", tn, es[0], tc.ExpectErr) 85 } 86 } else if tc.ExpectErr != "" { 87 t.Fatalf("%s: expected err containing %q, got none!", tn, tc.ExpectErr) 88 } 89 } 90 } 91 92 // This test covers a panic due to config.Func formerly being a 93 // shared map, causing multiple template_file resources to try and 94 // accessing it parallel during their lang.Eval() runs. 95 // 96 // Before fix, test fails under `go test -race` 97 func TestTemplateSharedMemoryRace(t *testing.T) { 98 var wg sync.WaitGroup 99 for i := 0; i < 100; i++ { 100 wg.Add(1) 101 go func(t *testing.T, i int) { 102 out, err := execute("don't panic!", map[string]interface{}{}) 103 if err != nil { 104 t.Fatalf("err: %s", err) 105 } 106 if out != "don't panic!" { 107 t.Fatalf("bad output: %s", out) 108 } 109 wg.Done() 110 }(t, i) 111 } 112 wg.Wait() 113 } 114 115 func testTemplateConfig(template, vars string) string { 116 return fmt.Sprintf(` 117 data "template_file" "t0" { 118 template = "%s" 119 vars = %s 120 } 121 output "rendered" { 122 value = "${data.template_file.t0.rendered}" 123 }`, template, vars) 124 }