add step_add_floppy unit tests

This commit is contained in:
sylviamoss 2020-09-22 16:19:30 +02:00
parent b46f587450
commit 7b1af2c4e8
6 changed files with 502 additions and 12 deletions

View File

@ -13,5 +13,6 @@ coverage:
project: off project: off
patch: off patch: off
ignore: # ignore hcl2spec generated code for coverage ignore: # ignore hcl2spec generated code for coverage and mocks
- "**/*.hcl2spec.go" - "**/*.hcl2spec.go"
- "**/*_mock.go"

View File

@ -37,8 +37,8 @@ type StepAddFloppy struct {
func (s *StepAddFloppy) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { func (s *StepAddFloppy) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
vm := state.Get("vm").(*driver.VirtualMachineDriver) vm := state.Get("vm").(driver.VirtualMachine)
d := state.Get("driver").(*driver.VCenterDriver) d := state.Get("driver").(driver.Driver)
if floppyPath, ok := state.GetOk("floppy_path"); ok { if floppyPath, ok := state.GetOk("floppy_path"); ok {
ui.Say("Uploading created floppy image") ui.Say("Uploading created floppy image")
@ -90,7 +90,7 @@ func (s *StepAddFloppy) Cleanup(state multistep.StateBag) {
} }
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
d := state.Get("driver").(*driver.VCenterDriver) d := state.Get("driver").(driver.Driver)
if UploadedFloppyPath, ok := state.GetOk("uploaded_floppy_path"); ok { if UploadedFloppyPath, ok := state.GetOk("uploaded_floppy_path"); ok {
ui.Say("Deleting Floppy image ...") ui.Say("Deleting Floppy image ...")

View File

@ -0,0 +1,453 @@
package common
import (
"context"
"fmt"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/hashicorp/packer/builder/vsphere/driver"
"github.com/hashicorp/packer/helper/multistep"
)
func TestStepAddFloppy_Run(t *testing.T) {
tc := []struct {
name string
floppyPath string
uploadedPath string
step *StepAddFloppy
expectedAction multistep.StepAction
vmMock *driver.VirtualMachineMock
expectedVmMock *driver.VirtualMachineMock
driverMock *driver.DriverMock
expectedDriverMock *driver.DriverMock
dsMock *driver.DatastoreMock
expectedDsMock *driver.DatastoreMock
fail bool
errMessage string
}{
{
name: "Add floppy from state floppy path",
floppyPath: "floppy/path",
uploadedPath: "vm/dir/packer-tmp-created-floppy.flp",
step: &StepAddFloppy{
Config: new(FloppyConfig),
Datastore: "datastore",
Host: "host",
SetHostForDatastoreUploads: true,
},
expectedAction: multistep.ActionContinue,
vmMock: &driver.VirtualMachineMock{
GetDirResponse: "vm/dir",
},
expectedVmMock: &driver.VirtualMachineMock{
GetDirResponse: "vm/dir",
GetDirCalled: true,
AddFloppyCalled: true,
AddFloppyImagePath: "resolved/path",
},
driverMock: new(driver.DriverMock),
expectedDriverMock: &driver.DriverMock{
FindDatastoreCalled: true,
FindDatastoreName: "datastore",
FindDatastoreHost: "host",
},
dsMock: &driver.DatastoreMock{
ResolvePathReturn: "resolved/path",
},
expectedDsMock: &driver.DatastoreMock{
UploadFileCalled: true,
UploadFileSrc: "floppy/path",
UploadFileDst: "vm/dir/packer-tmp-created-floppy.flp",
UploadFileHost: "host",
UploadFileSetHost: true,
ResolvePathCalled: true,
ResolvePathReturn: "resolved/path",
},
fail: false,
},
{
name: "State floppy path - find datastore fail",
floppyPath: "floppy/path",
step: &StepAddFloppy{
Config: new(FloppyConfig),
Datastore: "datastore",
Host: "host",
SetHostForDatastoreUploads: true,
},
expectedAction: multistep.ActionHalt,
vmMock: new(driver.VirtualMachineMock),
expectedVmMock: new(driver.VirtualMachineMock),
driverMock: &driver.DriverMock{
FindDatastoreErr: fmt.Errorf("error finding datastore"),
},
expectedDriverMock: &driver.DriverMock{
FindDatastoreCalled: true,
FindDatastoreName: "datastore",
FindDatastoreHost: "host",
},
dsMock: new(driver.DatastoreMock),
expectedDsMock: new(driver.DatastoreMock),
fail: true,
errMessage: "error finding datastore",
},
{
name: "State floppy path - vm get dir fail",
floppyPath: "floppy/path",
step: &StepAddFloppy{
Config: new(FloppyConfig),
Datastore: "datastore",
Host: "host",
SetHostForDatastoreUploads: true,
},
expectedAction: multistep.ActionHalt,
vmMock: &driver.VirtualMachineMock{
GetDirErr: fmt.Errorf("fail to get vm dir"),
},
expectedVmMock: &driver.VirtualMachineMock{
GetDirCalled: true,
},
driverMock: new(driver.DriverMock),
expectedDriverMock: &driver.DriverMock{
FindDatastoreCalled: true,
FindDatastoreName: "datastore",
FindDatastoreHost: "host",
},
dsMock: new(driver.DatastoreMock),
expectedDsMock: new(driver.DatastoreMock),
fail: true,
errMessage: "fail to get vm dir",
},
{
name: "State floppy path - datastore upload file fail",
floppyPath: "floppy/path",
step: &StepAddFloppy{
Config: new(FloppyConfig),
Datastore: "datastore",
Host: "host",
SetHostForDatastoreUploads: true,
},
expectedAction: multistep.ActionHalt,
vmMock: &driver.VirtualMachineMock{
GetDirResponse: "vm/dir",
},
expectedVmMock: &driver.VirtualMachineMock{
GetDirResponse: "vm/dir",
GetDirCalled: true,
},
driverMock: new(driver.DriverMock),
expectedDriverMock: &driver.DriverMock{
FindDatastoreCalled: true,
FindDatastoreName: "datastore",
FindDatastoreHost: "host",
},
dsMock: &driver.DatastoreMock{
UploadFileErr: fmt.Errorf("failed to upload file"),
},
expectedDsMock: &driver.DatastoreMock{
UploadFileCalled: true,
UploadFileSrc: "floppy/path",
UploadFileDst: "vm/dir/packer-tmp-created-floppy.flp",
UploadFileHost: "host",
UploadFileSetHost: true,
},
fail: true,
errMessage: "failed to upload file",
},
{
name: "State floppy path - vm fail to add floppy",
floppyPath: "floppy/path",
uploadedPath: "vm/dir/packer-tmp-created-floppy.flp",
step: &StepAddFloppy{
Config: new(FloppyConfig),
Datastore: "datastore",
Host: "host",
SetHostForDatastoreUploads: true,
},
expectedAction: multistep.ActionHalt,
vmMock: &driver.VirtualMachineMock{
GetDirResponse: "vm/dir",
AddFloppyErr: fmt.Errorf("failed to add floppy"),
},
expectedVmMock: &driver.VirtualMachineMock{
GetDirResponse: "vm/dir",
GetDirCalled: true,
AddFloppyCalled: true,
AddFloppyImagePath: "resolved/path",
},
driverMock: new(driver.DriverMock),
expectedDriverMock: &driver.DriverMock{
FindDatastoreCalled: true,
FindDatastoreName: "datastore",
FindDatastoreHost: "host",
},
dsMock: &driver.DatastoreMock{
ResolvePathReturn: "resolved/path",
},
expectedDsMock: &driver.DatastoreMock{
UploadFileCalled: true,
UploadFileSrc: "floppy/path",
UploadFileDst: "vm/dir/packer-tmp-created-floppy.flp",
UploadFileHost: "host",
UploadFileSetHost: true,
ResolvePathCalled: true,
ResolvePathReturn: "resolved/path",
},
fail: true,
errMessage: "failed to add floppy",
},
{
name: "Add floppy from FloppyIMGPath config",
step: &StepAddFloppy{
Config: &FloppyConfig{
FloppyIMGPath: "floppy/image/path",
},
},
expectedAction: multistep.ActionContinue,
vmMock: new(driver.VirtualMachineMock),
expectedVmMock: &driver.VirtualMachineMock{
AddFloppyCalled: true,
AddFloppyImagePath: "floppy/image/path",
},
driverMock: new(driver.DriverMock),
expectedDriverMock: new(driver.DriverMock),
dsMock: new(driver.DatastoreMock),
expectedDsMock: new(driver.DatastoreMock),
fail: false,
},
{
name: "Fail to add floppy from FloppyIMGPath config",
step: &StepAddFloppy{
Config: &FloppyConfig{
FloppyIMGPath: "floppy/image/path",
},
},
expectedAction: multistep.ActionHalt,
vmMock: &driver.VirtualMachineMock{
AddFloppyErr: fmt.Errorf("fail to add floppy"),
},
expectedVmMock: &driver.VirtualMachineMock{
AddFloppyCalled: true,
AddFloppyImagePath: "floppy/image/path",
},
driverMock: new(driver.DriverMock),
expectedDriverMock: new(driver.DriverMock),
dsMock: new(driver.DatastoreMock),
expectedDsMock: new(driver.DatastoreMock),
fail: true,
errMessage: "fail to add floppy",
},
}
for _, c := range tc {
t.Run(c.name, func(t *testing.T) {
state := basicStateBag(nil)
state.Put("vm", c.vmMock)
c.driverMock.DatastoreMock = c.dsMock
state.Put("driver", c.driverMock)
if c.floppyPath != "" {
state.Put("floppy_path", c.floppyPath)
}
if action := c.step.Run(context.TODO(), state); action != c.expectedAction {
t.Fatalf("unexpected action %v", action)
}
err, ok := state.Get("error").(error)
if ok {
if err.Error() != c.errMessage {
t.Fatalf("unexpected error %s", err.Error())
}
} else {
if c.fail {
t.Fatalf("expected to fail but it didn't")
}
}
uploadedPath, _ := state.Get("uploaded_floppy_path").(string)
if uploadedPath != c.uploadedPath {
t.Fatalf("Unexpected uploaded path state %s", uploadedPath)
}
if diff := cmp.Diff(c.vmMock, c.expectedVmMock,
cmpopts.IgnoreInterfaces(struct{ error }{})); diff != "" {
t.Fatalf("unexpected VirtualMachine calls: %s", diff)
}
c.expectedDriverMock.DatastoreMock = c.expectedDsMock
if diff := cmp.Diff(c.driverMock, c.expectedDriverMock,
cmpopts.IgnoreInterfaces(struct{ error }{})); diff != "" {
t.Fatalf("unexpected Driver calls: %s", diff)
}
if diff := cmp.Diff(c.dsMock, c.expectedDsMock,
cmpopts.IgnoreInterfaces(struct{ error }{})); diff != "" {
t.Fatalf("unexpected Datastore calls: %s", diff)
}
})
}
}
func TestStepAddFloppy_Cleanup(t *testing.T) {
tc := []struct {
name string
uploadedPath string
multistepState string
step *StepAddFloppy
driverMock *driver.DriverMock
expectedDriverMock *driver.DriverMock
dsMock *driver.DatastoreMock
expectedDsMock *driver.DatastoreMock
fail bool
errMessage string
}{
{
name: "State cancelled clean up",
uploadedPath: "uploaded/path",
multistepState: multistep.StateCancelled,
step: &StepAddFloppy{
Datastore: "datastore",
Host: "host",
},
driverMock: new(driver.DriverMock),
expectedDriverMock: &driver.DriverMock{
FindDatastoreCalled: true,
FindDatastoreName: "datastore",
FindDatastoreHost: "host",
},
dsMock: &driver.DatastoreMock{
DeleteCalled: true,
},
expectedDsMock: &driver.DatastoreMock{
DeleteCalled: true,
DeletePath: "uploaded/path",
},
fail: false,
},
{
name: "State halted clean up",
uploadedPath: "uploaded/path",
multistepState: multistep.StateHalted,
step: &StepAddFloppy{
Datastore: "datastore",
Host: "host",
},
driverMock: new(driver.DriverMock),
expectedDriverMock: &driver.DriverMock{
FindDatastoreCalled: true,
FindDatastoreName: "datastore",
FindDatastoreHost: "host",
},
dsMock: &driver.DatastoreMock{
DeleteCalled: true,
},
expectedDsMock: &driver.DatastoreMock{
DeleteCalled: true,
DeletePath: "uploaded/path",
},
fail: false,
},
{
name: "Don't clean up without uploaded path",
multistepState: multistep.StateHalted,
step: new(StepAddFloppy),
driverMock: new(driver.DriverMock),
expectedDriverMock: new(driver.DriverMock),
dsMock: new(driver.DatastoreMock),
expectedDsMock: new(driver.DatastoreMock),
fail: false,
},
{
name: "Don't clean up if state is not halted or canceled",
multistepState: "",
step: new(StepAddFloppy),
driverMock: new(driver.DriverMock),
expectedDriverMock: new(driver.DriverMock),
dsMock: new(driver.DatastoreMock),
expectedDsMock: new(driver.DatastoreMock),
fail: false,
},
{
name: "Fail because datastore is not found",
uploadedPath: "uploaded/path",
multistepState: multistep.StateHalted,
step: &StepAddFloppy{
Datastore: "datastore",
Host: "host",
},
driverMock: &driver.DriverMock{
FindDatastoreErr: fmt.Errorf("fail to find datastore"),
},
expectedDriverMock: &driver.DriverMock{
FindDatastoreCalled: true,
FindDatastoreName: "datastore",
FindDatastoreHost: "host",
},
dsMock: new(driver.DatastoreMock),
expectedDsMock: new(driver.DatastoreMock),
fail: true,
errMessage: "fail to find datastore",
},
{
name: "Fail to delete floppy",
uploadedPath: "uploaded/path",
multistepState: multistep.StateHalted,
step: &StepAddFloppy{
Datastore: "datastore",
Host: "host",
},
driverMock: new(driver.DriverMock),
expectedDriverMock: &driver.DriverMock{
FindDatastoreCalled: true,
FindDatastoreName: "datastore",
FindDatastoreHost: "host",
},
dsMock: &driver.DatastoreMock{
DeleteCalled: true,
DeleteErr: fmt.Errorf("failed to delete floppy"),
},
expectedDsMock: &driver.DatastoreMock{
DeleteCalled: true,
DeletePath: "uploaded/path",
},
fail: true,
errMessage: "failed to delete floppy",
},
}
for _, c := range tc {
t.Run(c.name, func(t *testing.T) {
state := basicStateBag(nil)
c.driverMock.DatastoreMock = c.dsMock
state.Put("driver", c.driverMock)
if c.uploadedPath != "" {
state.Put("uploaded_floppy_path", c.uploadedPath)
}
if c.multistepState != "" {
state.Put(c.multistepState, true)
}
c.step.Cleanup(state)
err, ok := state.Get("error").(error)
if ok {
if err.Error() != c.errMessage {
t.Fatalf("unexpected error %s", err.Error())
}
} else {
if c.fail {
t.Fatalf("expected to fail but it didn't")
}
}
c.expectedDriverMock.DatastoreMock = c.expectedDsMock
if diff := cmp.Diff(c.driverMock, c.expectedDriverMock,
cmpopts.IgnoreInterfaces(struct{ error }{})); diff != "" {
t.Fatalf("unexpected Driver calls: %s", diff)
}
if diff := cmp.Diff(c.dsMock, c.expectedDsMock,
cmpopts.IgnoreInterfaces(struct{ error }{})); diff != "" {
t.Fatalf("unexpected Datastore calls: %s", diff)
}
})
}
}

View File

@ -8,7 +8,20 @@ import (
type DatastoreMock struct { type DatastoreMock struct {
FileExistsCalled bool FileExistsCalled bool
MakeDirectoryCalled bool MakeDirectoryCalled bool
ResolvePathCalled bool
ResolvePathReturn string
DeleteCalled bool
DeletePath string
DeleteErr error
UploadFileCalled bool UploadFileCalled bool
UploadFileSrc string
UploadFileDst string
UploadFileHost string
UploadFileSetHost bool
UploadFileErr error
} }
func (ds *DatastoreMock) Info(params ...string) (*mo.Datastore, error) { func (ds *DatastoreMock) Info(params ...string) (*mo.Datastore, error) {
@ -29,16 +42,23 @@ func (ds *DatastoreMock) Reference() types.ManagedObjectReference {
} }
func (ds *DatastoreMock) ResolvePath(path string) string { func (ds *DatastoreMock) ResolvePath(path string) string {
return "" ds.ResolvePathCalled = true
return ds.ResolvePathReturn
} }
func (ds *DatastoreMock) UploadFile(src, dst, host string, setHost bool) error { func (ds *DatastoreMock) UploadFile(src, dst, host string, setHost bool) error {
ds.UploadFileCalled = true ds.UploadFileCalled = true
return nil ds.UploadFileSrc = src
ds.UploadFileDst = dst
ds.UploadFileHost = host
ds.UploadFileSetHost = setHost
return ds.UploadFileErr
} }
func (ds *DatastoreMock) Delete(path string) error { func (ds *DatastoreMock) Delete(path string) error {
return nil ds.DeleteCalled = true
ds.DeletePath = path
return ds.DeleteErr
} }
func (ds *DatastoreMock) MakeDirectory(path string) error { func (ds *DatastoreMock) MakeDirectory(path string) error {

View File

@ -11,6 +11,9 @@ import (
type DriverMock struct { type DriverMock struct {
FindDatastoreCalled bool FindDatastoreCalled bool
DatastoreMock *DatastoreMock DatastoreMock *DatastoreMock
FindDatastoreName string
FindDatastoreHost string
FindDatastoreErr error
PreCleanShouldFail bool PreCleanShouldFail bool
PreCleanVMCalled bool PreCleanVMCalled bool
@ -32,7 +35,9 @@ func (d *DriverMock) FindDatastore(name string, host string) (Datastore, error)
if d.DatastoreMock == nil { if d.DatastoreMock == nil {
d.DatastoreMock = new(DatastoreMock) d.DatastoreMock = new(DatastoreMock)
} }
return d.DatastoreMock, nil d.FindDatastoreName = name
d.FindDatastoreHost = host
return d.DatastoreMock, d.FindDatastoreErr
} }
func (d *DriverMock) NewVM(ref *types.ManagedObjectReference) VirtualMachine { func (d *DriverMock) NewVM(ref *types.ManagedObjectReference) VirtualMachine {

View File

@ -32,6 +32,14 @@ type VirtualMachineMock struct {
AddCdromErr error AddCdromErr error
AddCdromTypes []string AddCdromTypes []string
AddCdromPaths []string AddCdromPaths []string
GetDirCalled bool
GetDirResponse string
GetDirErr error
AddFloppyCalled bool
AddFloppyImagePath string
AddFloppyErr error
} }
func (vm *VirtualMachineMock) Info(params ...string) (*mo.VirtualMachine, error) { func (vm *VirtualMachineMock) Info(params ...string) (*mo.VirtualMachine, error) {
@ -124,7 +132,8 @@ func (vm *VirtualMachineMock) ImportToContentLibrary(template vcenter.Template)
} }
func (vm *VirtualMachineMock) GetDir() (string, error) { func (vm *VirtualMachineMock) GetDir() (string, error) {
return "", nil vm.GetDirCalled = true
return vm.GetDirResponse, vm.GetDirErr
} }
func (vm *VirtualMachineMock) AddCdrom(cdromType string, isoPath string) error { func (vm *VirtualMachineMock) AddCdrom(cdromType string, isoPath string) error {
@ -136,7 +145,9 @@ func (vm *VirtualMachineMock) AddCdrom(cdromType string, isoPath string) error {
} }
func (vm *VirtualMachineMock) AddFloppy(imgPath string) error { func (vm *VirtualMachineMock) AddFloppy(imgPath string) error {
return nil vm.AddFloppyCalled = true
vm.AddFloppyImagePath = imgPath
return vm.AddFloppyErr
} }
func (vm *VirtualMachineMock) SetBootOrder(order []string) error { func (vm *VirtualMachineMock) SetBootOrder(order []string) error {