github.com/ByteTerrace/packer@v1.3.2/packer/provisioner_test.go (about)

     1  package packer
     2  
     3  import (
     4  	"sync"
     5  	"testing"
     6  	"time"
     7  )
     8  
     9  func TestProvisionHook_Impl(t *testing.T) {
    10  	var raw interface{}
    11  	raw = &ProvisionHook{}
    12  	if _, ok := raw.(Hook); !ok {
    13  		t.Fatalf("must be a Hook")
    14  	}
    15  }
    16  
    17  func TestProvisionHook(t *testing.T) {
    18  	pA := &MockProvisioner{}
    19  	pB := &MockProvisioner{}
    20  
    21  	ui := testUi()
    22  	var comm Communicator = new(MockCommunicator)
    23  	var data interface{} = nil
    24  
    25  	hook := &ProvisionHook{
    26  		Provisioners: []*HookedProvisioner{
    27  			{pA, nil, ""},
    28  			{pB, nil, ""},
    29  		},
    30  	}
    31  
    32  	hook.Run("foo", ui, comm, data)
    33  
    34  	if !pA.ProvCalled {
    35  		t.Error("provision should be called on pA")
    36  	}
    37  
    38  	if !pB.ProvCalled {
    39  		t.Error("provision should be called on pB")
    40  	}
    41  }
    42  
    43  func TestProvisionHook_nilComm(t *testing.T) {
    44  	pA := &MockProvisioner{}
    45  	pB := &MockProvisioner{}
    46  
    47  	ui := testUi()
    48  	var comm Communicator = nil
    49  	var data interface{} = nil
    50  
    51  	hook := &ProvisionHook{
    52  		Provisioners: []*HookedProvisioner{
    53  			{pA, nil, ""},
    54  			{pB, nil, ""},
    55  		},
    56  	}
    57  
    58  	err := hook.Run("foo", ui, comm, data)
    59  	if err == nil {
    60  		t.Fatal("should error")
    61  	}
    62  }
    63  
    64  func TestProvisionHook_cancel(t *testing.T) {
    65  	var lock sync.Mutex
    66  	order := make([]string, 0, 2)
    67  
    68  	p := &MockProvisioner{
    69  		ProvFunc: func() error {
    70  			time.Sleep(100 * time.Millisecond)
    71  
    72  			lock.Lock()
    73  			defer lock.Unlock()
    74  			order = append(order, "prov")
    75  
    76  			return nil
    77  		},
    78  	}
    79  
    80  	hook := &ProvisionHook{
    81  		Provisioners: []*HookedProvisioner{
    82  			{p, nil, ""},
    83  		},
    84  	}
    85  
    86  	finished := make(chan struct{})
    87  	go func() {
    88  		hook.Run("foo", nil, new(MockCommunicator), nil)
    89  		close(finished)
    90  	}()
    91  
    92  	// Cancel it while it is running
    93  	time.Sleep(10 * time.Millisecond)
    94  	hook.Cancel()
    95  	lock.Lock()
    96  	order = append(order, "cancel")
    97  	lock.Unlock()
    98  
    99  	// Wait
   100  	<-finished
   101  
   102  	// Verify order
   103  	if len(order) != 2 || order[0] != "cancel" || order[1] != "prov" {
   104  		t.Fatalf("bad: %#v", order)
   105  	}
   106  }
   107  
   108  // TODO(mitchellh): Test that they're run in the proper order
   109  
   110  func TestPausedProvisioner_impl(t *testing.T) {
   111  	var _ Provisioner = new(PausedProvisioner)
   112  }
   113  
   114  func TestPausedProvisionerPrepare(t *testing.T) {
   115  	mock := new(MockProvisioner)
   116  	prov := &PausedProvisioner{
   117  		Provisioner: mock,
   118  	}
   119  
   120  	prov.Prepare(42)
   121  	if !mock.PrepCalled {
   122  		t.Fatal("prepare should be called")
   123  	}
   124  	if mock.PrepConfigs[0] != 42 {
   125  		t.Fatal("should have proper configs")
   126  	}
   127  }
   128  
   129  func TestPausedProvisionerProvision(t *testing.T) {
   130  	mock := new(MockProvisioner)
   131  	prov := &PausedProvisioner{
   132  		Provisioner: mock,
   133  	}
   134  
   135  	ui := testUi()
   136  	comm := new(MockCommunicator)
   137  	prov.Provision(ui, comm)
   138  	if !mock.ProvCalled {
   139  		t.Fatal("prov should be called")
   140  	}
   141  	if mock.ProvUi != ui {
   142  		t.Fatal("should have proper ui")
   143  	}
   144  	if mock.ProvCommunicator != comm {
   145  		t.Fatal("should have proper comm")
   146  	}
   147  }
   148  
   149  func TestPausedProvisionerProvision_waits(t *testing.T) {
   150  	mock := new(MockProvisioner)
   151  	prov := &PausedProvisioner{
   152  		PauseBefore: 50 * time.Millisecond,
   153  		Provisioner: mock,
   154  	}
   155  
   156  	dataCh := make(chan struct{})
   157  	mock.ProvFunc = func() error {
   158  		close(dataCh)
   159  		return nil
   160  	}
   161  
   162  	go prov.Provision(testUi(), new(MockCommunicator))
   163  
   164  	select {
   165  	case <-time.After(10 * time.Millisecond):
   166  	case <-dataCh:
   167  		t.Fatal("should not be called")
   168  	}
   169  
   170  	select {
   171  	case <-time.After(100 * time.Millisecond):
   172  		t.Fatal("never called")
   173  	case <-dataCh:
   174  	}
   175  }
   176  
   177  func TestPausedProvisionerCancel(t *testing.T) {
   178  	mock := new(MockProvisioner)
   179  	prov := &PausedProvisioner{
   180  		Provisioner: mock,
   181  	}
   182  
   183  	provCh := make(chan struct{})
   184  	mock.ProvFunc = func() error {
   185  		close(provCh)
   186  		time.Sleep(10 * time.Millisecond)
   187  		return nil
   188  	}
   189  
   190  	// Start provisioning and wait for it to start
   191  	go prov.Provision(testUi(), new(MockCommunicator))
   192  	<-provCh
   193  
   194  	// Cancel it
   195  	prov.Cancel()
   196  	if !mock.CancelCalled {
   197  		t.Fatal("cancel should be called")
   198  	}
   199  }
   200  
   201  func TestDebuggedProvisioner_impl(t *testing.T) {
   202  	var _ Provisioner = new(DebuggedProvisioner)
   203  }
   204  
   205  func TestDebuggedProvisionerPrepare(t *testing.T) {
   206  	mock := new(MockProvisioner)
   207  	prov := &DebuggedProvisioner{
   208  		Provisioner: mock,
   209  	}
   210  
   211  	prov.Prepare(42)
   212  	if !mock.PrepCalled {
   213  		t.Fatal("prepare should be called")
   214  	}
   215  	if mock.PrepConfigs[0] != 42 {
   216  		t.Fatal("should have proper configs")
   217  	}
   218  }
   219  
   220  func TestDebuggedProvisionerProvision(t *testing.T) {
   221  	mock := new(MockProvisioner)
   222  	prov := &DebuggedProvisioner{
   223  		Provisioner: mock,
   224  	}
   225  
   226  	ui := testUi()
   227  	comm := new(MockCommunicator)
   228  	writeReader(ui, "\n")
   229  	prov.Provision(ui, comm)
   230  	if !mock.ProvCalled {
   231  		t.Fatal("prov should be called")
   232  	}
   233  	if mock.ProvUi != ui {
   234  		t.Fatal("should have proper ui")
   235  	}
   236  	if mock.ProvCommunicator != comm {
   237  		t.Fatal("should have proper comm")
   238  	}
   239  }
   240  
   241  func TestDebuggedProvisionerCancel(t *testing.T) {
   242  	mock := new(MockProvisioner)
   243  	prov := &DebuggedProvisioner{
   244  		Provisioner: mock,
   245  	}
   246  
   247  	provCh := make(chan struct{})
   248  	mock.ProvFunc = func() error {
   249  		close(provCh)
   250  		time.Sleep(10 * time.Millisecond)
   251  		return nil
   252  	}
   253  
   254  	// Start provisioning and wait for it to start
   255  	go prov.Provision(testUi(), new(MockCommunicator))
   256  	<-provCh
   257  
   258  	// Cancel it
   259  	prov.Cancel()
   260  	if !mock.CancelCalled {
   261  		t.Fatal("cancel should be called")
   262  	}
   263  }