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  }