github.com/magodo/terraform@v0.11.12-beta1/builtin/provisioners/local-exec/resource_provisioner_test.go (about) 1 package localexec 2 3 import ( 4 "io/ioutil" 5 "os" 6 "strings" 7 "testing" 8 "time" 9 10 "github.com/hashicorp/terraform/config" 11 "github.com/hashicorp/terraform/helper/schema" 12 "github.com/hashicorp/terraform/terraform" 13 ) 14 15 func TestResourceProvisioner_impl(t *testing.T) { 16 var _ terraform.ResourceProvisioner = Provisioner() 17 } 18 19 func TestProvisioner(t *testing.T) { 20 if err := Provisioner().(*schema.Provisioner).InternalValidate(); err != nil { 21 t.Fatalf("err: %s", err) 22 } 23 } 24 25 func TestResourceProvider_Apply(t *testing.T) { 26 defer os.Remove("test_out") 27 c := testConfig(t, map[string]interface{}{ 28 "command": "echo foo > test_out", 29 }) 30 31 output := new(terraform.MockUIOutput) 32 p := Provisioner() 33 34 if err := p.Apply(output, nil, c); err != nil { 35 t.Fatalf("err: %v", err) 36 } 37 38 // Check the file 39 raw, err := ioutil.ReadFile("test_out") 40 if err != nil { 41 t.Fatalf("err: %v", err) 42 } 43 44 actual := strings.TrimSpace(string(raw)) 45 expected := "foo" 46 if actual != expected { 47 t.Fatalf("bad: %#v", actual) 48 } 49 } 50 51 func TestResourceProvider_stop(t *testing.T) { 52 c := testConfig(t, map[string]interface{}{ 53 // bash/zsh/ksh will exec a single command in the same process. This 54 // makes certain there's a subprocess in the shell. 55 "command": "sleep 30; sleep 30", 56 }) 57 58 output := new(terraform.MockUIOutput) 59 p := Provisioner() 60 61 doneCh := make(chan struct{}) 62 startTime := time.Now() 63 go func() { 64 defer close(doneCh) 65 // The functionality of p.Apply is tested in TestResourceProvider_Apply. 66 // Because p.Apply is called in a goroutine, trying to t.Fatal() on its 67 // result would be ignored or would cause a panic if the parent goroutine 68 // has already completed. 69 _ = p.Apply(output, nil, c) 70 }() 71 72 mustExceed := (50 * time.Millisecond) 73 select { 74 case <-doneCh: 75 t.Fatalf("expected to finish sometime after %s finished in %s", mustExceed, time.Since(startTime)) 76 case <-time.After(mustExceed): 77 t.Logf("correctly took longer than %s", mustExceed) 78 } 79 80 // Stop it 81 stopTime := time.Now() 82 p.Stop() 83 84 maxTempl := "expected to finish under %s, finished in %s" 85 finishWithin := (2 * time.Second) 86 select { 87 case <-doneCh: 88 t.Logf(maxTempl, finishWithin, time.Since(stopTime)) 89 case <-time.After(finishWithin): 90 t.Fatalf(maxTempl, finishWithin, time.Since(stopTime)) 91 } 92 } 93 94 func TestResourceProvider_Validate_good(t *testing.T) { 95 c := testConfig(t, map[string]interface{}{ 96 "command": "echo foo", 97 }) 98 99 warn, errs := Provisioner().Validate(c) 100 if len(warn) > 0 { 101 t.Fatalf("Warnings: %v", warn) 102 } 103 if len(errs) > 0 { 104 t.Fatalf("Errors: %v", errs) 105 } 106 } 107 108 func TestResourceProvider_Validate_missing(t *testing.T) { 109 c := testConfig(t, map[string]interface{}{}) 110 111 warn, errs := Provisioner().Validate(c) 112 if len(warn) > 0 { 113 t.Fatalf("Warnings: %v", warn) 114 } 115 if len(errs) == 0 { 116 t.Fatalf("Should have errors") 117 } 118 } 119 120 func testConfig(t *testing.T, c map[string]interface{}) *terraform.ResourceConfig { 121 r, err := config.NewRawConfig(c) 122 if err != nil { 123 t.Fatalf("bad: %s", err) 124 } 125 126 return terraform.NewResourceConfig(r) 127 } 128 129 func TestResourceProvider_ApplyCustomInterpreter(t *testing.T) { 130 c := testConfig(t, map[string]interface{}{ 131 "interpreter": []interface{}{"echo", "is"}, 132 "command": "not really an interpreter", 133 }) 134 135 output := new(terraform.MockUIOutput) 136 p := Provisioner() 137 138 if err := p.Apply(output, nil, c); err != nil { 139 t.Fatalf("err: %v", err) 140 } 141 142 got := strings.TrimSpace(output.OutputMessage) 143 want := "is not really an interpreter" 144 if got != want { 145 t.Errorf("wrong output\ngot: %s\nwant: %s", got, want) 146 } 147 } 148 149 func TestResourceProvider_ApplyCustomWorkingDirectory(t *testing.T) { 150 testdir := "working_dir_test" 151 os.Mkdir(testdir, 0755) 152 defer os.Remove(testdir) 153 154 c := testConfig(t, map[string]interface{}{ 155 "working_dir": testdir, 156 "command": "echo `pwd`", 157 }) 158 159 output := new(terraform.MockUIOutput) 160 p := Provisioner() 161 162 if err := p.Apply(output, nil, c); err != nil { 163 t.Fatalf("err: %v", err) 164 } 165 166 dir, err := os.Getwd() 167 if err != nil { 168 t.Fatalf("err: %v", err) 169 } 170 171 got := strings.TrimSpace(output.OutputMessage) 172 want := dir + "/" + testdir 173 if got != want { 174 t.Errorf("wrong output\ngot: %s\nwant: %s", got, want) 175 } 176 } 177 178 func TestResourceProvider_ApplyCustomEnv(t *testing.T) { 179 c := testConfig(t, map[string]interface{}{ 180 "command": "echo $FOO $BAR $BAZ", 181 "environment": map[string]interface{}{ 182 "FOO": "BAR", 183 "BAR": 1, 184 "BAZ": "true", 185 }, 186 }) 187 188 output := new(terraform.MockUIOutput) 189 p := Provisioner() 190 191 if err := p.Apply(output, nil, c); err != nil { 192 t.Fatalf("err: %v", err) 193 } 194 195 got := strings.TrimSpace(output.OutputMessage) 196 want := "BAR 1 true" 197 if got != want { 198 t.Errorf("wrong output\ngot: %s\nwant: %s", got, want) 199 } 200 }