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