Files
Packer-Cn/packer/provisioner_test.go
hashicorp-copywrite[bot] 19055df3ec [COMPLIANCE] License changes (#12568)
* Updating the license from MPL to Business Source License

Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at https://hashi.co/bsl-blog, FAQ at https://hashi.co/license-faq, and details of the license at www.hashicorp.com/bsl.

* Update copyright file headers to BUSL-1.1

---------

Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
2023-08-10 15:53:29 -07:00

349 lines
7.6 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package packer
import (
"context"
"errors"
"fmt"
"testing"
"time"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
func TestProvisionHook_Impl(t *testing.T) {
var raw interface{}
raw = &ProvisionHook{}
if _, ok := raw.(packersdk.Hook); !ok {
t.Fatalf("must be a Hook")
}
}
func TestProvisionHook(t *testing.T) {
pA := &packersdk.MockProvisioner{}
pB := &packersdk.MockProvisioner{}
ui := testUi()
var comm packersdk.Communicator = new(packersdk.MockCommunicator)
var data interface{} = nil
hook := &ProvisionHook{
Provisioners: []*HookedProvisioner{
{pA, nil, ""},
{pB, nil, ""},
},
}
hook.Run(context.Background(), "foo", ui, comm, data)
if !pA.ProvCalled {
t.Error("provision should be called on pA")
}
if !pB.ProvCalled {
t.Error("provision should be called on pB")
}
}
func TestProvisionHook_nilComm(t *testing.T) {
pA := &packersdk.MockProvisioner{}
pB := &packersdk.MockProvisioner{}
ui := testUi()
var comm packersdk.Communicator = nil
var data interface{} = nil
hook := &ProvisionHook{
Provisioners: []*HookedProvisioner{
{pA, nil, ""},
{pB, nil, ""},
},
}
err := hook.Run(context.Background(), "foo", ui, comm, data)
if err == nil {
t.Fatal("should error")
}
}
func TestProvisionHook_cancel(t *testing.T) {
topCtx, topCtxCancel := context.WithCancel(context.Background())
p := &packersdk.MockProvisioner{
ProvFunc: func(ctx context.Context) error {
topCtxCancel()
<-ctx.Done()
return ctx.Err()
},
}
hook := &ProvisionHook{
Provisioners: []*HookedProvisioner{
{p, nil, ""},
},
}
err := hook.Run(topCtx, "foo", nil, new(packersdk.MockCommunicator), nil)
if err == nil {
t.Fatal("should have err")
}
}
// TODO(mitchellh): Test that they're run in the proper order
func TestPausedProvisioner_impl(t *testing.T) {
var _ packersdk.Provisioner = new(PausedProvisioner)
}
func TestPausedProvisionerPrepare(t *testing.T) {
mock := new(packersdk.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(packersdk.MockProvisioner)
prov := &PausedProvisioner{
Provisioner: mock,
}
ui := testUi()
comm := new(packersdk.MockCommunicator)
prov.Provision(context.Background(), ui, comm, make(map[string]interface{}))
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) {
startTime := time.Now()
waitTime := 50 * time.Millisecond
prov := &PausedProvisioner{
PauseBefore: waitTime,
Provisioner: &packersdk.MockProvisioner{
ProvFunc: func(context.Context) error {
timeSinceStartTime := time.Since(startTime)
if timeSinceStartTime < waitTime {
return fmt.Errorf("Spent not enough time waiting: %s", timeSinceStartTime)
}
return nil
},
},
}
err := prov.Provision(context.Background(), testUi(), new(packersdk.MockCommunicator), make(map[string]interface{}))
if err != nil {
t.Fatalf("prov failed: %v", err)
}
}
func TestPausedProvisionerCancel(t *testing.T) {
topCtx, cancelTopCtx := context.WithCancel(context.Background())
mock := new(packersdk.MockProvisioner)
prov := &PausedProvisioner{
Provisioner: mock,
}
mock.ProvFunc = func(ctx context.Context) error {
cancelTopCtx()
<-ctx.Done()
return ctx.Err()
}
err := prov.Provision(topCtx, testUi(), new(packersdk.MockCommunicator), make(map[string]interface{}))
if err == nil {
t.Fatal("should have err")
}
}
func TestDebuggedProvisioner_impl(t *testing.T) {
var _ packersdk.Provisioner = new(DebuggedProvisioner)
}
func TestDebuggedProvisionerPrepare(t *testing.T) {
mock := new(packersdk.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(packersdk.MockProvisioner)
prov := &DebuggedProvisioner{
Provisioner: mock,
}
ui := testUi()
comm := new(packersdk.MockCommunicator)
writeReader(ui, "\n")
prov.Provision(context.Background(), ui, comm, make(map[string]interface{}))
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) {
topCtx, topCtxCancel := context.WithCancel(context.Background())
mock := new(packersdk.MockProvisioner)
prov := &DebuggedProvisioner{
Provisioner: mock,
}
mock.ProvFunc = func(ctx context.Context) error {
topCtxCancel()
<-ctx.Done()
return ctx.Err()
}
err := prov.Provision(topCtx, testUi(), new(packersdk.MockCommunicator), make(map[string]interface{}))
if err == nil {
t.Fatal("should have error")
}
}
func TestRetriedProvisioner_impl(t *testing.T) {
var _ packersdk.Provisioner = new(RetriedProvisioner)
}
func TestRetriedProvisionerPrepare(t *testing.T) {
mock := new(packersdk.MockProvisioner)
prov := &RetriedProvisioner{
Provisioner: mock,
}
err := prov.Prepare(42)
if err != nil {
t.Fatal("should not have errored")
}
if !mock.PrepCalled {
t.Fatal("prepare should be called")
}
if mock.PrepConfigs[0] != 42 {
t.Fatal("should have proper configs")
}
}
func TestRetriedProvisionerProvision(t *testing.T) {
mock := &packersdk.MockProvisioner{
ProvFunc: func(ctx context.Context) error {
return errors.New("failed")
},
}
prov := &RetriedProvisioner{
MaxRetries: 2,
Provisioner: mock,
}
ui := testUi()
comm := new(packersdk.MockCommunicator)
err := prov.Provision(context.Background(), ui, comm, make(map[string]interface{}))
if err != nil {
t.Fatal("should not have errored")
}
if !mock.ProvCalled {
t.Fatal("prov should be called")
}
if !mock.ProvRetried {
t.Fatal("prov should be retried")
}
if mock.ProvUi != ui {
t.Fatal("should have proper ui")
}
if mock.ProvCommunicator != comm {
t.Fatal("should have proper comm")
}
}
func TestRetriedProvisionerCancelledProvision(t *testing.T) {
// Don't retry if context is cancelled
ctx, topCtxCancel := context.WithCancel(context.Background())
mock := &packersdk.MockProvisioner{
ProvFunc: func(ctx context.Context) error {
topCtxCancel()
<-ctx.Done()
return ctx.Err()
},
}
prov := &RetriedProvisioner{
MaxRetries: 2,
Provisioner: mock,
}
ui := testUi()
comm := new(packersdk.MockCommunicator)
err := prov.Provision(ctx, ui, comm, make(map[string]interface{}))
if err == nil {
t.Fatal("should have errored")
}
if !mock.ProvCalled {
t.Fatal("prov should be called")
}
if mock.ProvRetried {
t.Fatal("prov should NOT be retried")
}
if mock.ProvUi != ui {
t.Fatal("should have proper ui")
}
if mock.ProvCommunicator != comm {
t.Fatal("should have proper comm")
}
}
func TestRetriedProvisionerCancel(t *testing.T) {
topCtx, cancelTopCtx := context.WithCancel(context.Background())
mock := new(packersdk.MockProvisioner)
prov := &RetriedProvisioner{
Provisioner: mock,
}
mock.ProvFunc = func(ctx context.Context) error {
cancelTopCtx()
<-ctx.Done()
return ctx.Err()
}
err := prov.Provision(topCtx, testUi(), new(packersdk.MockCommunicator), make(map[string]interface{}))
if err == nil {
t.Fatal("should have err")
}
}