github.com/hooklift/terraform@v0.11.0-beta1.0.20171117000744-6786c1361ffe/builtin/provisioners/remote-exec/resource_provisioner_test.go (about) 1 package remoteexec 2 3 import ( 4 "bytes" 5 "context" 6 "errors" 7 "io" 8 "net" 9 "testing" 10 "time" 11 12 "strings" 13 14 "github.com/hashicorp/terraform/config" 15 "github.com/hashicorp/terraform/helper/schema" 16 "github.com/hashicorp/terraform/terraform" 17 ) 18 19 func TestResourceProvisioner_impl(t *testing.T) { 20 var _ terraform.ResourceProvisioner = Provisioner() 21 } 22 23 func TestProvisioner(t *testing.T) { 24 if err := Provisioner().(*schema.Provisioner).InternalValidate(); err != nil { 25 t.Fatalf("err: %s", err) 26 } 27 } 28 29 func TestResourceProvider_Validate_good(t *testing.T) { 30 c := testConfig(t, map[string]interface{}{ 31 "inline": "echo foo", 32 }) 33 34 warn, errs := Provisioner().Validate(c) 35 if len(warn) > 0 { 36 t.Fatalf("Warnings: %v", warn) 37 } 38 if len(errs) > 0 { 39 t.Fatalf("Errors: %v", errs) 40 } 41 } 42 43 func TestResourceProvider_Validate_bad(t *testing.T) { 44 c := testConfig(t, map[string]interface{}{ 45 "invalid": "nope", 46 }) 47 48 warn, errs := Provisioner().Validate(c) 49 if len(warn) > 0 { 50 t.Fatalf("Warnings: %v", warn) 51 } 52 if len(errs) == 0 { 53 t.Fatalf("Should have errors") 54 } 55 } 56 57 var expectedScriptOut = `cd /tmp 58 wget http://foobar 59 exit 0 60 ` 61 62 func TestResourceProvider_generateScript(t *testing.T) { 63 conf := map[string]interface{}{ 64 "inline": []interface{}{ 65 "cd /tmp", 66 "wget http://foobar", 67 "exit 0", 68 }, 69 } 70 71 out, err := generateScripts( 72 schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, conf), 73 ) 74 if err != nil { 75 t.Fatalf("err: %v", err) 76 } 77 78 if len(out) != 1 { 79 t.Fatal("expected 1 out") 80 } 81 82 if out[0] != expectedScriptOut { 83 t.Fatalf("bad: %v", out) 84 } 85 } 86 87 func TestResourceProvider_generateScriptEmptyInline(t *testing.T) { 88 p := Provisioner().(*schema.Provisioner) 89 conf := map[string]interface{}{ 90 "inline": []interface{}{""}, 91 } 92 93 _, err := generateScripts(schema.TestResourceDataRaw( 94 t, p.Schema, conf)) 95 if err == nil { 96 t.Fatal("expected error, got none") 97 } 98 99 if !strings.Contains(err.Error(), "Error parsing") { 100 t.Fatalf("expected parsing error, got: %s", err) 101 } 102 } 103 104 func TestResourceProvider_CollectScripts_inline(t *testing.T) { 105 conf := map[string]interface{}{ 106 "inline": []interface{}{ 107 "cd /tmp", 108 "wget http://foobar", 109 "exit 0", 110 }, 111 } 112 113 scripts, err := collectScripts( 114 schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, conf), 115 ) 116 if err != nil { 117 t.Fatalf("err: %v", err) 118 } 119 120 if len(scripts) != 1 { 121 t.Fatalf("bad: %v", scripts) 122 } 123 124 var out bytes.Buffer 125 _, err = io.Copy(&out, scripts[0]) 126 if err != nil { 127 t.Fatalf("err: %v", err) 128 } 129 130 if out.String() != expectedScriptOut { 131 t.Fatalf("bad: %v", out.String()) 132 } 133 } 134 135 func TestResourceProvider_CollectScripts_script(t *testing.T) { 136 conf := map[string]interface{}{ 137 "script": "test-fixtures/script1.sh", 138 } 139 140 scripts, err := collectScripts( 141 schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, conf), 142 ) 143 if err != nil { 144 t.Fatalf("err: %v", err) 145 } 146 147 if len(scripts) != 1 { 148 t.Fatalf("bad: %v", scripts) 149 } 150 151 var out bytes.Buffer 152 _, err = io.Copy(&out, scripts[0]) 153 if err != nil { 154 t.Fatalf("err: %v", err) 155 } 156 157 if out.String() != expectedScriptOut { 158 t.Fatalf("bad: %v", out.String()) 159 } 160 } 161 162 func TestResourceProvider_CollectScripts_scripts(t *testing.T) { 163 conf := map[string]interface{}{ 164 "scripts": []interface{}{ 165 "test-fixtures/script1.sh", 166 "test-fixtures/script1.sh", 167 "test-fixtures/script1.sh", 168 }, 169 } 170 171 scripts, err := collectScripts( 172 schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, conf), 173 ) 174 if err != nil { 175 t.Fatalf("err: %v", err) 176 } 177 178 if len(scripts) != 3 { 179 t.Fatalf("bad: %v", scripts) 180 } 181 182 for idx := range scripts { 183 var out bytes.Buffer 184 _, err = io.Copy(&out, scripts[idx]) 185 if err != nil { 186 t.Fatalf("err: %v", err) 187 } 188 189 if out.String() != expectedScriptOut { 190 t.Fatalf("bad: %v", out.String()) 191 } 192 } 193 } 194 195 func TestResourceProvider_CollectScripts_scriptsEmpty(t *testing.T) { 196 p := Provisioner().(*schema.Provisioner) 197 conf := map[string]interface{}{ 198 "scripts": []interface{}{""}, 199 } 200 201 _, err := collectScripts(schema.TestResourceDataRaw( 202 t, p.Schema, conf)) 203 204 if err == nil { 205 t.Fatal("expected error") 206 } 207 208 if !strings.Contains(err.Error(), "Error parsing") { 209 t.Fatalf("Expected parsing error, got: %s", err) 210 } 211 } 212 213 func TestRetryFunc(t *testing.T) { 214 origMax := maxBackoffDelay 215 maxBackoffDelay = time.Second 216 origStart := initialBackoffDelay 217 initialBackoffDelay = 10 * time.Millisecond 218 219 defer func() { 220 maxBackoffDelay = origMax 221 initialBackoffDelay = origStart 222 }() 223 224 // succeed on the third try 225 errs := []error{io.EOF, &net.OpError{Err: errors.New("ERROR")}, nil} 226 count := 0 227 228 err := retryFunc(context.Background(), time.Second, func() error { 229 if count >= len(errs) { 230 return errors.New("failed to stop after nil error") 231 } 232 233 err := errs[count] 234 count++ 235 236 return err 237 }) 238 239 if count != 3 { 240 t.Fatal("retry func should have been called 3 times") 241 } 242 243 if err != nil { 244 t.Fatal(err) 245 } 246 } 247 248 func TestRetryFuncBackoff(t *testing.T) { 249 origMax := maxBackoffDelay 250 maxBackoffDelay = time.Second 251 origStart := initialBackoffDelay 252 initialBackoffDelay = 100 * time.Millisecond 253 254 defer func() { 255 maxBackoffDelay = origMax 256 initialBackoffDelay = origStart 257 }() 258 259 count := 0 260 261 retryFunc(context.Background(), time.Second, func() error { 262 count++ 263 return io.EOF 264 }) 265 266 if count > 4 { 267 t.Fatalf("retry func failed to backoff. called %d times", count) 268 } 269 } 270 271 func testConfig(t *testing.T, c map[string]interface{}) *terraform.ResourceConfig { 272 r, err := config.NewRawConfig(c) 273 if err != nil { 274 t.Fatalf("bad: %s", err) 275 } 276 277 return terraform.NewResourceConfig(r) 278 }