packer-cn/packer/provisioner_test.go

270 lines
5.2 KiB
Go
Raw Normal View History

2013-05-22 18:39:30 -04:00
package packer
import (
"context"
"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) {
pA := &MockProvisioner{}
pB := &MockProvisioner{}
2013-05-24 00:13:18 -04:00
ui := testUi()
var comm Communicator = new(MockCommunicator)
2013-05-24 00:13:18 -04:00
var data interface{} = nil
hook := &ProvisionHook{
Provisioners: []*HookedProvisioner{
{pA, nil, ""},
{pB, nil, ""},
2017-11-03 02:31:32 -04:00
},
}
hook.Run(context.Background(), "foo", ui, comm, data)
2013-05-24 00:13:18 -04:00
if !pA.ProvCalled {
2013-05-24 00:13:18 -04:00
t.Error("provision should be called on pA")
}
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
func TestProvisionHook_nilComm(t *testing.T) {
pA := &MockProvisioner{}
pB := &MockProvisioner{}
ui := testUi()
var comm Communicator = nil
var data interface{} = nil
hook := &ProvisionHook{
Provisioners: []*HookedProvisioner{
{pA, nil, ""},
{pB, nil, ""},
2017-11-03 02:31:32 -04:00
},
}
err := hook.Run(context.Background(), "foo", ui, comm, data)
if err == nil {
t.Fatal("should error")
}
}
func TestProvisionHook_cancel(t *testing.T) {
var lock sync.Mutex
order := make([]string, 0, 2)
p := &MockProvisioner{
ProvFunc: func() error {
2017-11-30 19:30:28 -05:00
time.Sleep(100 * time.Millisecond)
lock.Lock()
defer lock.Unlock()
order = append(order, "prov")
return nil
},
}
hook := &ProvisionHook{
Provisioners: []*HookedProvisioner{
{p, nil, ""},
2017-11-03 02:31:32 -04:00
},
}
ctx, cancel := context.WithCancel(context.Background())
finished := make(chan struct{})
go func() {
hook.Run(ctx, "foo", nil, new(MockCommunicator), nil)
close(finished)
}()
// Cancel it while it is running
time.Sleep(10 * time.Millisecond)
cancel()
lock.Lock()
order = append(order, "cancel")
lock.Unlock()
// Wait
<-finished
// Verify order
if len(order) != 2 || order[0] != "cancel" || order[1] != "prov" {
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(context.Background(), ui, comm)
2013-12-21 00:36:41 -05:00
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(context.Background(), testUi(), new(MockCommunicator))
2013-12-21 00:36:41 -05:00
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
}
ctx, cancel := context.WithCancel(context.Background())
2013-12-21 00:36:41 -05:00
// Start provisioning and wait for it to start
go func() {
<-provCh
cancel()
}()
2013-12-21 00:36:41 -05:00
prov.Provision(ctx, testUi(), new(MockCommunicator))
2013-12-21 00:36:41 -05:00
if !mock.CancelCalled {
t.Fatal("cancel should be called")
}
}
func TestDebuggedProvisioner_impl(t *testing.T) {
var _ Provisioner = new(DebuggedProvisioner)
}
func TestDebuggedProvisionerPrepare(t *testing.T) {
mock := new(MockProvisioner)
prov := &DebuggedProvisioner{
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 TestDebuggedProvisionerProvision(t *testing.T) {
mock := new(MockProvisioner)
prov := &DebuggedProvisioner{
Provisioner: mock,
}
ui := testUi()
comm := new(MockCommunicator)
writeReader(ui, "\n")
prov.Provision(context.Background(), 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 TestDebuggedProvisionerCancel(t *testing.T) {
mock := new(MockProvisioner)
prov := &DebuggedProvisioner{
Provisioner: mock,
}
provCh := make(chan struct{})
mock.ProvFunc = func() error {
close(provCh)
time.Sleep(10 * time.Millisecond)
return nil
}
ctx, cancel := context.WithCancel(context.Background())
// Start provisioning and wait for it to start
go func() {
<-provCh
cancel()
}()
prov.Provision(ctx, testUi(), new(MockCommunicator))
if !mock.CancelCalled {
t.Fatal("cancel should be called")
}
}