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  }