2013-05-22 18:39:30 -04:00
|
|
|
package packer
|
|
|
|
|
2013-08-31 02:39:29 -04:00
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
)
|
2013-05-24 00:13:18 -04:00
|
|
|
|
|
|
|
func TestProvisionHook_Impl(t *testing.T) {
|
|
|
|
var raw interface{}
|
|
|
|
raw = &ProvisionHook{}
|
|
|
|
if _, ok := raw.(Hook); !ok {
|
|
|
|
t.Fatalf("must be a Hook")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestProvisionHook(t *testing.T) {
|
2013-08-31 02:21:15 -04:00
|
|
|
pA := &MockProvisioner{}
|
|
|
|
pB := &MockProvisioner{}
|
2013-05-24 00:13:18 -04:00
|
|
|
|
|
|
|
ui := testUi()
|
2015-06-15 13:26:46 -04:00
|
|
|
var comm Communicator = new(MockCommunicator)
|
2013-05-24 00:13:18 -04:00
|
|
|
var data interface{} = nil
|
|
|
|
|
2013-08-31 02:39:29 -04:00
|
|
|
hook := &ProvisionHook{
|
2017-11-04 16:06:36 -04:00
|
|
|
Provisioners: []*HookedProvisioner{
|
|
|
|
{pA, nil, ""},
|
|
|
|
{pB, nil, ""},
|
2017-11-03 02:31:32 -04:00
|
|
|
},
|
2013-08-31 02:39:29 -04:00
|
|
|
}
|
|
|
|
|
2013-05-24 00:13:18 -04:00
|
|
|
hook.Run("foo", ui, comm, data)
|
|
|
|
|
2013-08-31 02:21:15 -04:00
|
|
|
if !pA.ProvCalled {
|
2013-05-24 00:13:18 -04:00
|
|
|
t.Error("provision should be called on pA")
|
|
|
|
}
|
|
|
|
|
2013-08-31 02:21:15 -04:00
|
|
|
if !pB.ProvCalled {
|
2013-05-24 00:13:18 -04:00
|
|
|
t.Error("provision should be called on pB")
|
|
|
|
}
|
|
|
|
}
|
2013-05-24 00:13:40 -04:00
|
|
|
|
2015-06-15 13:26:46 -04:00
|
|
|
func TestProvisionHook_nilComm(t *testing.T) {
|
|
|
|
pA := &MockProvisioner{}
|
|
|
|
pB := &MockProvisioner{}
|
|
|
|
|
|
|
|
ui := testUi()
|
|
|
|
var comm Communicator = nil
|
|
|
|
var data interface{} = nil
|
|
|
|
|
|
|
|
hook := &ProvisionHook{
|
2017-11-04 16:06:36 -04:00
|
|
|
Provisioners: []*HookedProvisioner{
|
|
|
|
{pA, nil, ""},
|
|
|
|
{pB, nil, ""},
|
2017-11-03 02:31:32 -04:00
|
|
|
},
|
2015-06-15 13:26:46 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
err := hook.Run("foo", ui, comm, data)
|
|
|
|
if err == nil {
|
|
|
|
t.Fatal("should error")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-31 02:39:29 -04:00
|
|
|
func TestProvisionHook_cancel(t *testing.T) {
|
|
|
|
var lock sync.Mutex
|
|
|
|
order := make([]string, 0, 2)
|
|
|
|
|
|
|
|
p := &MockProvisioner{
|
|
|
|
ProvFunc: func() error {
|
|
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
|
|
|
|
lock.Lock()
|
|
|
|
defer lock.Unlock()
|
|
|
|
order = append(order, "prov")
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
hook := &ProvisionHook{
|
2017-11-04 16:06:36 -04:00
|
|
|
Provisioners: []*HookedProvisioner{
|
|
|
|
{p, nil, ""},
|
2017-11-03 02:31:32 -04:00
|
|
|
},
|
2013-08-31 02:39:29 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
finished := make(chan struct{})
|
|
|
|
go func() {
|
2015-06-15 13:26:46 -04:00
|
|
|
hook.Run("foo", nil, new(MockCommunicator), nil)
|
2013-08-31 02:39:29 -04:00
|
|
|
close(finished)
|
|
|
|
}()
|
|
|
|
|
|
|
|
// Cancel it while it is running
|
|
|
|
time.Sleep(10 * time.Millisecond)
|
|
|
|
hook.Cancel()
|
|
|
|
lock.Lock()
|
|
|
|
order = append(order, "cancel")
|
|
|
|
lock.Unlock()
|
|
|
|
|
|
|
|
// Wait
|
|
|
|
<-finished
|
|
|
|
|
|
|
|
// Verify order
|
2015-06-15 13:26:46 -04:00
|
|
|
if len(order) != 2 || order[0] != "cancel" || order[1] != "prov" {
|
2013-08-31 02:39:29 -04:00
|
|
|
t.Fatalf("bad: %#v", order)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-24 00:13:40 -04:00
|
|
|
// TODO(mitchellh): Test that they're run in the proper order
|
2013-12-21 00:36:41 -05:00
|
|
|
|
|
|
|
func TestPausedProvisioner_impl(t *testing.T) {
|
|
|
|
var _ Provisioner = new(PausedProvisioner)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPausedProvisionerPrepare(t *testing.T) {
|
|
|
|
mock := new(MockProvisioner)
|
|
|
|
prov := &PausedProvisioner{
|
|
|
|
Provisioner: mock,
|
|
|
|
}
|
|
|
|
|
|
|
|
prov.Prepare(42)
|
|
|
|
if !mock.PrepCalled {
|
|
|
|
t.Fatal("prepare should be called")
|
|
|
|
}
|
|
|
|
if mock.PrepConfigs[0] != 42 {
|
|
|
|
t.Fatal("should have proper configs")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPausedProvisionerProvision(t *testing.T) {
|
|
|
|
mock := new(MockProvisioner)
|
|
|
|
prov := &PausedProvisioner{
|
|
|
|
Provisioner: mock,
|
|
|
|
}
|
|
|
|
|
|
|
|
ui := testUi()
|
|
|
|
comm := new(MockCommunicator)
|
|
|
|
prov.Provision(ui, comm)
|
|
|
|
if !mock.ProvCalled {
|
|
|
|
t.Fatal("prov should be called")
|
|
|
|
}
|
|
|
|
if mock.ProvUi != ui {
|
|
|
|
t.Fatal("should have proper ui")
|
|
|
|
}
|
|
|
|
if mock.ProvCommunicator != comm {
|
|
|
|
t.Fatal("should have proper comm")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPausedProvisionerProvision_waits(t *testing.T) {
|
|
|
|
mock := new(MockProvisioner)
|
|
|
|
prov := &PausedProvisioner{
|
|
|
|
PauseBefore: 50 * time.Millisecond,
|
|
|
|
Provisioner: mock,
|
|
|
|
}
|
|
|
|
|
|
|
|
dataCh := make(chan struct{})
|
|
|
|
mock.ProvFunc = func() error {
|
|
|
|
close(dataCh)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
go prov.Provision(testUi(), new(MockCommunicator))
|
|
|
|
|
|
|
|
select {
|
|
|
|
case <-time.After(10 * time.Millisecond):
|
|
|
|
case <-dataCh:
|
|
|
|
t.Fatal("should not be called")
|
|
|
|
}
|
|
|
|
|
|
|
|
select {
|
|
|
|
case <-time.After(100 * time.Millisecond):
|
|
|
|
t.Fatal("never called")
|
|
|
|
case <-dataCh:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPausedProvisionerCancel(t *testing.T) {
|
|
|
|
mock := new(MockProvisioner)
|
|
|
|
prov := &PausedProvisioner{
|
|
|
|
Provisioner: mock,
|
|
|
|
}
|
|
|
|
|
|
|
|
provCh := make(chan struct{})
|
|
|
|
mock.ProvFunc = func() error {
|
|
|
|
close(provCh)
|
|
|
|
time.Sleep(10 * time.Millisecond)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start provisioning and wait for it to start
|
|
|
|
go prov.Provision(testUi(), new(MockCommunicator))
|
|
|
|
<-provCh
|
|
|
|
|
|
|
|
// Cancel it
|
|
|
|
prov.Cancel()
|
|
|
|
if !mock.CancelCalled {
|
|
|
|
t.Fatal("cancel should be called")
|
|
|
|
}
|
|
|
|
}
|