From 2de3f2755a78fec8cb755b9e39849ad40df87864 Mon Sep 17 00:00:00 2001 From: sylviamoss Date: Wed, 23 Sep 2020 12:00:28 +0200 Subject: [PATCH] add step_remove_floppy tests --- builder/vsphere/common/step_remove_cdrom.go | 2 +- builder/vsphere/common/step_remove_floppy.go | 8 +- .../vsphere/common/step_remove_floppy_test.go | 213 ++++++++++++++++++ builder/vsphere/driver/vm.go | 10 + builder/vsphere/driver/vm_mock.go | 19 +- 5 files changed, 245 insertions(+), 7 deletions(-) create mode 100644 builder/vsphere/common/step_remove_floppy_test.go diff --git a/builder/vsphere/common/step_remove_cdrom.go b/builder/vsphere/common/step_remove_cdrom.go index fc48bf2fc..00bd6dc94 100644 --- a/builder/vsphere/common/step_remove_cdrom.go +++ b/builder/vsphere/common/step_remove_cdrom.go @@ -22,7 +22,7 @@ type StepRemoveCDRom struct { func (s *StepRemoveCDRom) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) - vm := state.Get("vm").(*driver.VirtualMachineDriver) + vm := state.Get("vm").(driver.VirtualMachine) ui.Say("Eject CD-ROM drives...") err := vm.EjectCdroms() diff --git a/builder/vsphere/common/step_remove_floppy.go b/builder/vsphere/common/step_remove_floppy.go index 265e3067f..7141e04b9 100644 --- a/builder/vsphere/common/step_remove_floppy.go +++ b/builder/vsphere/common/step_remove_floppy.go @@ -6,7 +6,6 @@ import ( "github.com/hashicorp/packer/builder/vsphere/driver" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/vmware/govmomi/vim25/types" ) type StepRemoveFloppy struct { @@ -16,16 +15,15 @@ type StepRemoveFloppy struct { func (s *StepRemoveFloppy) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) - vm := state.Get("vm").(*driver.VirtualMachineDriver) - d := state.Get("driver").(*driver.VCenterDriver) + vm := state.Get("vm").(driver.VirtualMachine) + d := state.Get("driver").(driver.Driver) ui.Say("Deleting Floppy drives...") - devices, err := vm.Devices() + floppies, err := vm.FloppyDevices() if err != nil { state.Put("error", err) return multistep.ActionHalt } - floppies := devices.SelectByType((*types.VirtualFloppy)(nil)) if err = vm.RemoveDevice(true, floppies...); err != nil { state.Put("error", err) return multistep.ActionHalt diff --git a/builder/vsphere/common/step_remove_floppy_test.go b/builder/vsphere/common/step_remove_floppy_test.go new file mode 100644 index 000000000..1b76bb0fa --- /dev/null +++ b/builder/vsphere/common/step_remove_floppy_test.go @@ -0,0 +1,213 @@ +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 TestStepRemoveFloppy_Run(t *testing.T) { + tc := []struct { + name string + uploadedPath string + step *StepRemoveFloppy + 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: "Remove floppy drives and images", + uploadedPath: "vm/dir/packer-tmp-created-floppy.flp", + step: &StepRemoveFloppy{ + Datastore: "datastore", + Host: "host", + }, + expectedAction: multistep.ActionContinue, + vmMock: new(driver.VirtualMachineMock), + expectedVmMock: &driver.VirtualMachineMock{ + FloppyDevicesCalled: true, + RemoveDeviceCalled: true, + RemoveDeviceKeepFiles: true, + }, + driverMock: new(driver.DriverMock), + expectedDriverMock: &driver.DriverMock{ + FindDatastoreCalled: true, + FindDatastoreName: "datastore", + FindDatastoreHost: "host", + }, + dsMock: new(driver.DatastoreMock), + expectedDsMock: &driver.DatastoreMock{ + DeleteCalled: true, + DeletePath: "vm/dir/packer-tmp-created-floppy.flp", + }, + fail: false, + }, + { + name: "No floppy image to remove", + step: &StepRemoveFloppy{}, + expectedAction: multistep.ActionContinue, + vmMock: new(driver.VirtualMachineMock), + expectedVmMock: &driver.VirtualMachineMock{ + FloppyDevicesCalled: true, + RemoveDeviceCalled: true, + RemoveDeviceKeepFiles: true, + }, + driverMock: new(driver.DriverMock), + expectedDriverMock: new(driver.DriverMock), + dsMock: new(driver.DatastoreMock), + expectedDsMock: new(driver.DatastoreMock), + fail: false, + }, + { + name: "Fail to find floppy devices", + step: &StepRemoveFloppy{}, + expectedAction: multistep.ActionHalt, + vmMock: &driver.VirtualMachineMock{ + FloppyDevicesErr: fmt.Errorf("failed to find floppy devices"), + }, + expectedVmMock: &driver.VirtualMachineMock{ + FloppyDevicesCalled: true, + }, + driverMock: new(driver.DriverMock), + expectedDriverMock: new(driver.DriverMock), + dsMock: new(driver.DatastoreMock), + expectedDsMock: new(driver.DatastoreMock), + fail: true, + errMessage: "failed to find floppy devices", + }, + { + name: "Fail to remove floppy devices", + step: &StepRemoveFloppy{}, + expectedAction: multistep.ActionHalt, + vmMock: &driver.VirtualMachineMock{ + RemoveDeviceErr: fmt.Errorf("failed to remove device"), + }, + expectedVmMock: &driver.VirtualMachineMock{ + FloppyDevicesCalled: true, + RemoveDeviceCalled: true, + RemoveDeviceKeepFiles: true, + }, + driverMock: new(driver.DriverMock), + expectedDriverMock: new(driver.DriverMock), + dsMock: new(driver.DatastoreMock), + expectedDsMock: new(driver.DatastoreMock), + fail: true, + errMessage: "failed to remove device", + }, + { + name: "Fail to find datastore", + uploadedPath: "vm/dir/packer-tmp-created-floppy.flp", + step: &StepRemoveFloppy{ + Datastore: "datastore", + Host: "host", + }, + expectedAction: multistep.ActionHalt, + vmMock: new(driver.VirtualMachineMock), + expectedVmMock: &driver.VirtualMachineMock{ + FloppyDevicesCalled: true, + RemoveDeviceCalled: true, + RemoveDeviceKeepFiles: true, + }, + driverMock: &driver.DriverMock{ + FindDatastoreErr: fmt.Errorf("failed to find datastore"), + }, + expectedDriverMock: &driver.DriverMock{ + FindDatastoreCalled: true, + FindDatastoreName: "datastore", + FindDatastoreHost: "host", + }, + dsMock: new(driver.DatastoreMock), + expectedDsMock: new(driver.DatastoreMock), + fail: true, + errMessage: "failed to find datastore", + }, + { + name: "Fail to delete floppy image", + uploadedPath: "vm/dir/packer-tmp-created-floppy.flp", + step: &StepRemoveFloppy{ + Datastore: "datastore", + Host: "host", + }, + expectedAction: multistep.ActionHalt, + vmMock: new(driver.VirtualMachineMock), + expectedVmMock: &driver.VirtualMachineMock{ + FloppyDevicesCalled: true, + RemoveDeviceCalled: true, + RemoveDeviceKeepFiles: true, + }, + driverMock: new(driver.DriverMock), + expectedDriverMock: &driver.DriverMock{ + FindDatastoreCalled: true, + FindDatastoreName: "datastore", + FindDatastoreHost: "host", + }, + dsMock: &driver.DatastoreMock{ + DeleteErr: fmt.Errorf("failed to delete floppy"), + }, + expectedDsMock: &driver.DatastoreMock{ + DeleteCalled: true, + DeletePath: "vm/dir/packer-tmp-created-floppy.flp", + }, + fail: true, + errMessage: "failed to delete 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.uploadedPath != "" { + state.Put("uploaded_floppy_path", c.uploadedPath) + } + + 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") + } + } + + if !c.fail { + if _, ok := state.GetOk("uploaded_floppy_path"); ok { + t.Fatalf("uploaded_floppy_path should not be in state") + } + } + + 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) + } + }) + } +} diff --git a/builder/vsphere/driver/vm.go b/builder/vsphere/driver/vm.go index fbcc9e2d5..f0bbf6f6d 100644 --- a/builder/vsphere/driver/vm.go +++ b/builder/vsphere/driver/vm.go @@ -24,6 +24,7 @@ import ( type VirtualMachine interface { Info(params ...string) (*mo.VirtualMachine, error) Devices() (object.VirtualDeviceList, error) + FloppyDevices() (object.VirtualDeviceList, error) Clone(ctx context.Context, config *CloneConfig) (VirtualMachine, error) updateVAppConfig(ctx context.Context, newProps map[string]string) (*types.VmConfigSpec, error) AddPublicKeys(ctx context.Context, publicKeys string) error @@ -284,6 +285,15 @@ func (vm *VirtualMachineDriver) Devices() (object.VirtualDeviceList, error) { return vmInfo.Config.Hardware.Device, nil } +func (vm *VirtualMachineDriver) FloppyDevices() (object.VirtualDeviceList, error) { + device, err := vm.Devices() + if err != nil { + return device, err + } + floppies := device.SelectByType((*types.VirtualFloppy)(nil)) + return floppies, nil +} + func (vm *VirtualMachineDriver) Clone(ctx context.Context, config *CloneConfig) (VirtualMachine, error) { folder, err := vm.driver.FindFolder(config.Folder) if err != nil { diff --git a/builder/vsphere/driver/vm_mock.go b/builder/vsphere/driver/vm_mock.go index a60a9b705..ea16f8e57 100644 --- a/builder/vsphere/driver/vm_mock.go +++ b/builder/vsphere/driver/vm_mock.go @@ -40,6 +40,15 @@ type VirtualMachineMock struct { AddFloppyCalled bool AddFloppyImagePath string AddFloppyErr error + + FloppyDevicesErr error + FloppyDevicesReturn object.VirtualDeviceList + FloppyDevicesCalled bool + + RemoveDeviceErr error + RemoveDeviceCalled bool + RemoveDeviceKeepFiles bool + RemoveDeviceDevices []types.BaseVirtualDevice } func (vm *VirtualMachineMock) Info(params ...string) (*mo.VirtualMachine, error) { @@ -50,6 +59,11 @@ func (vm *VirtualMachineMock) Devices() (object.VirtualDeviceList, error) { return object.VirtualDeviceList{}, nil } +func (vm *VirtualMachineMock) FloppyDevices() (object.VirtualDeviceList, error) { + vm.FloppyDevicesCalled = true + return vm.FloppyDevicesReturn, vm.FloppyDevicesErr +} + func (vm *VirtualMachineMock) Clone(ctx context.Context, config *CloneConfig) (VirtualMachine, error) { return nil, nil } @@ -155,7 +169,10 @@ func (vm *VirtualMachineMock) SetBootOrder(order []string) error { } func (vm *VirtualMachineMock) RemoveDevice(keepFiles bool, device ...types.BaseVirtualDevice) error { - return nil + vm.RemoveDeviceCalled = true + vm.RemoveDeviceKeepFiles = keepFiles + vm.RemoveDeviceDevices = device + return vm.RemoveDeviceErr } func (vm *VirtualMachineMock) addDevice(device types.BaseVirtualDevice) error {