2020-09-02 04:19:57 -04:00
|
|
|
package common
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/google/go-cmp/cmp"
|
2020-12-17 16:29:25 -05:00
|
|
|
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
2020-09-02 04:19:57 -04:00
|
|
|
"github.com/hashicorp/packer/builder/vsphere/driver"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestHardwareConfig_Prepare(t *testing.T) {
|
|
|
|
tc := []struct {
|
|
|
|
name string
|
|
|
|
config *HardwareConfig
|
|
|
|
fail bool
|
|
|
|
expectedErrMsg string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "Validate empty config",
|
|
|
|
config: &HardwareConfig{},
|
|
|
|
fail: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Validate RAMReservation RAMReserveAll cannot be used together",
|
|
|
|
config: &HardwareConfig{
|
|
|
|
RAMReservation: 2,
|
|
|
|
RAMReserveAll: true,
|
|
|
|
},
|
|
|
|
fail: true,
|
|
|
|
expectedErrMsg: "'RAM_reservation' and 'RAM_reserve_all' cannot be used together",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Invalid firmware",
|
|
|
|
config: &HardwareConfig{
|
|
|
|
Firmware: "invalid",
|
|
|
|
},
|
|
|
|
fail: true,
|
|
|
|
expectedErrMsg: "'firmware' must be '', 'bios', 'efi' or 'efi-secure'",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Validate 'bios' firmware",
|
|
|
|
config: &HardwareConfig{
|
|
|
|
Firmware: "bios",
|
|
|
|
},
|
|
|
|
fail: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Validate 'efi' firmware",
|
|
|
|
config: &HardwareConfig{
|
|
|
|
Firmware: "efi",
|
|
|
|
},
|
|
|
|
fail: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Validate 'efi-secure' firmware",
|
|
|
|
config: &HardwareConfig{
|
|
|
|
Firmware: "efi-secure",
|
|
|
|
},
|
|
|
|
fail: false,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, c := range tc {
|
|
|
|
t.Run(c.name, func(t *testing.T) {
|
|
|
|
errs := c.config.Prepare()
|
|
|
|
if c.fail {
|
|
|
|
if len(errs) == 0 {
|
|
|
|
t.Fatalf("Config preprare should fail")
|
|
|
|
}
|
|
|
|
if errs[0].Error() != c.expectedErrMsg {
|
|
|
|
t.Fatalf("Expected error message: %s but was '%s'", c.expectedErrMsg, errs[0].Error())
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if len(errs) != 0 {
|
|
|
|
t.Fatalf("Config preprare should not fail")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestStepConfigureHardware_Run(t *testing.T) {
|
|
|
|
tc := []struct {
|
|
|
|
name string
|
|
|
|
step *StepConfigureHardware
|
|
|
|
action multistep.StepAction
|
|
|
|
configureError error
|
|
|
|
configureCalled bool
|
|
|
|
hardwareConfig *driver.HardwareConfig
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "Configure hardware",
|
|
|
|
step: basicStepConfigureHardware(),
|
|
|
|
action: multistep.ActionContinue,
|
|
|
|
configureError: nil,
|
|
|
|
configureCalled: true,
|
|
|
|
hardwareConfig: driverHardwareConfigFromConfig(basicStepConfigureHardware().Config),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Don't configure hardware when config is empty",
|
|
|
|
step: &StepConfigureHardware{Config: &HardwareConfig{}},
|
|
|
|
action: multistep.ActionContinue,
|
|
|
|
configureError: nil,
|
|
|
|
configureCalled: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Halt when configure return error",
|
|
|
|
step: basicStepConfigureHardware(),
|
|
|
|
action: multistep.ActionHalt,
|
|
|
|
configureError: errors.New("failed to configure"),
|
|
|
|
configureCalled: true,
|
|
|
|
hardwareConfig: driverHardwareConfigFromConfig(basicStepConfigureHardware().Config),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, c := range tc {
|
|
|
|
t.Run(c.name, func(t *testing.T) {
|
|
|
|
state := basicStateBag(nil)
|
|
|
|
vmMock := new(driver.VirtualMachineMock)
|
|
|
|
vmMock.ConfigureError = c.configureError
|
|
|
|
state.Put("vm", vmMock)
|
|
|
|
|
|
|
|
action := c.step.Run(context.TODO(), state)
|
|
|
|
if action != c.action {
|
|
|
|
t.Fatalf("expected action '%v' but actual action was '%v'", c.action, action)
|
|
|
|
}
|
|
|
|
if vmMock.ConfigureCalled != c.configureCalled {
|
|
|
|
t.Fatalf("expecting vm.Configure called to %t but was %t", c.configureCalled, vmMock.ConfigureCalled)
|
|
|
|
}
|
|
|
|
if diff := cmp.Diff(vmMock.ConfigureHardwareConfig, c.hardwareConfig); diff != "" {
|
|
|
|
t.Fatalf("wrong driver.HardwareConfig: %s", diff)
|
|
|
|
}
|
|
|
|
|
|
|
|
err, ok := state.GetOk("error")
|
|
|
|
containsError := c.configureError != nil
|
|
|
|
if containsError != ok {
|
|
|
|
t.Fatalf("Contain error - expecting %t but was %t", containsError, ok)
|
|
|
|
}
|
|
|
|
if containsError {
|
|
|
|
if !strings.Contains(err.(error).Error(), c.configureError.Error()) {
|
|
|
|
t.Fatalf("Destroy should fail with error message '%s' but failed with '%s'", c.configureError.Error(), err.(error).Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func basicStepConfigureHardware() *StepConfigureHardware {
|
|
|
|
return &StepConfigureHardware{
|
|
|
|
Config: &HardwareConfig{
|
|
|
|
CPUs: 1,
|
|
|
|
CpuCores: 1,
|
|
|
|
CPUReservation: 1,
|
|
|
|
CPULimit: 4000,
|
|
|
|
RAM: 1024,
|
|
|
|
RAMReserveAll: true,
|
|
|
|
Firmware: "efi-secure",
|
|
|
|
ForceBIOSSetup: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func driverHardwareConfigFromConfig(config *HardwareConfig) *driver.HardwareConfig {
|
|
|
|
return &driver.HardwareConfig{
|
|
|
|
CPUs: config.CPUs,
|
|
|
|
CpuCores: config.CpuCores,
|
|
|
|
CPUReservation: config.CPUReservation,
|
|
|
|
CPULimit: config.CPULimit,
|
|
|
|
RAM: config.RAM,
|
|
|
|
RAMReservation: config.RAMReservation,
|
|
|
|
RAMReserveAll: config.RAMReserveAll,
|
|
|
|
NestedHV: config.NestedHV,
|
|
|
|
CpuHotAddEnabled: config.CpuHotAddEnabled,
|
|
|
|
MemoryHotAddEnabled: config.MemoryHotAddEnabled,
|
|
|
|
VideoRAM: config.VideoRAM,
|
|
|
|
VGPUProfile: config.VGPUProfile,
|
|
|
|
Firmware: config.Firmware,
|
|
|
|
ForceBIOSSetup: config.ForceBIOSSetup,
|
|
|
|
}
|
|
|
|
}
|