Add tests for step_type_boot_command, fix found bug (shifted chars were not lower cased)
This commit is contained in:
parent
28ca0f71b5
commit
0765bc2283
|
@ -11,14 +11,14 @@ import (
|
|||
)
|
||||
|
||||
type proxmoxDriver struct {
|
||||
client *proxmox.Client
|
||||
client commandTyper
|
||||
vmRef *proxmox.VmRef
|
||||
specialMap map[string]string
|
||||
runeMap map[rune]string
|
||||
interval time.Duration
|
||||
}
|
||||
|
||||
func NewProxmoxDriver(c *proxmox.Client, vmRef *proxmox.VmRef, interval time.Duration) *proxmoxDriver {
|
||||
func NewProxmoxDriver(c commandTyper, vmRef *proxmox.VmRef, interval time.Duration) *proxmoxDriver {
|
||||
// Mappings for packer shorthand to qemu qkeycodes
|
||||
sMap := map[string]string{
|
||||
"spacebar": "spc",
|
||||
|
@ -90,7 +90,7 @@ func (p *proxmoxDriver) SendKey(key rune, action bootcommand.KeyAction) error {
|
|||
|
||||
var keys string
|
||||
if keyShift {
|
||||
keys = fmt.Sprintf(shiftFormat, key)
|
||||
keys = fmt.Sprintf(shiftFormat, unicode.ToLower(key))
|
||||
} else {
|
||||
keys = fmt.Sprintf("%c", key)
|
||||
}
|
||||
|
|
|
@ -28,10 +28,14 @@ type bootCommandTemplateData struct {
|
|||
HTTPPort uint
|
||||
}
|
||||
|
||||
type commandTyper interface {
|
||||
MonitorCmd(*proxmox.VmRef, string) (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
func (s *stepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
c := state.Get("config").(*Config)
|
||||
client := state.Get("proxmoxClient").(*proxmox.Client)
|
||||
client := state.Get("proxmoxClient").(commandTyper)
|
||||
vmRef := state.Get("vmRef").(*proxmox.VmRef)
|
||||
|
||||
if len(s.BootCommand) == 0 {
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
package proxmox
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/Telmate/proxmox-api-go/proxmox"
|
||||
"github.com/hashicorp/packer/common/bootcommand"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
type commandTyperMock struct {
|
||||
monitorCmd func(*proxmox.VmRef, string) (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
func (m commandTyperMock) MonitorCmd(ref *proxmox.VmRef, cmd string) (map[string]interface{}, error) {
|
||||
return m.monitorCmd(ref, cmd)
|
||||
}
|
||||
|
||||
func TestTypeBootCommand(t *testing.T) {
|
||||
cs := []struct {
|
||||
name string
|
||||
builderConfig *Config
|
||||
expectCallMonitorCmd bool
|
||||
monitorCmdErr error
|
||||
monitorCmdRet map[string]interface{}
|
||||
expectedKeysSent string
|
||||
expectedAction multistep.StepAction
|
||||
}{
|
||||
{
|
||||
name: "simple boot command is typed",
|
||||
builderConfig: &Config{BootConfig: bootcommand.BootConfig{BootCommand: []string{"hello"}}},
|
||||
expectCallMonitorCmd: true,
|
||||
expectedKeysSent: "hello",
|
||||
expectedAction: multistep.ActionContinue,
|
||||
},
|
||||
{
|
||||
name: "interpolated boot command",
|
||||
builderConfig: &Config{BootConfig: bootcommand.BootConfig{BootCommand: []string{"hello<enter>world"}}},
|
||||
expectCallMonitorCmd: true,
|
||||
expectedKeysSent: "helloretworld",
|
||||
expectedAction: multistep.ActionContinue,
|
||||
},
|
||||
{
|
||||
name: "merge multiple interpolated boot command",
|
||||
builderConfig: &Config{BootConfig: bootcommand.BootConfig{BootCommand: []string{"Hello World 2.0", "foo!bar@baz"}}},
|
||||
expectCallMonitorCmd: true,
|
||||
expectedKeysSent: "shift-hellospcshift-worldspc2dot0fooshift-1barshift-2baz",
|
||||
expectedAction: multistep.ActionContinue,
|
||||
},
|
||||
{
|
||||
name: "without boot command monitorcmd should not be called",
|
||||
builderConfig: &Config{BootConfig: bootcommand.BootConfig{BootCommand: []string{}}},
|
||||
expectCallMonitorCmd: false,
|
||||
expectedAction: multistep.ActionContinue,
|
||||
},
|
||||
{
|
||||
name: "invalid boot command template function",
|
||||
builderConfig: &Config{BootConfig: bootcommand.BootConfig{BootCommand: []string{"{{ foo }}"}}},
|
||||
expectCallMonitorCmd: false,
|
||||
expectedAction: multistep.ActionHalt,
|
||||
},
|
||||
{
|
||||
// When proxmox (or Qemu, really) doesn't recognize the keycode we send, we get no error back, but
|
||||
// a map {"data": "invalid parameter: X"}, where X is the keycode.
|
||||
name: "invalid keys sent to proxmox",
|
||||
builderConfig: &Config{BootConfig: bootcommand.BootConfig{BootCommand: []string{"x"}}},
|
||||
expectCallMonitorCmd: true,
|
||||
monitorCmdRet: map[string]interface{}{"data": "invalid parameter: x"},
|
||||
expectedKeysSent: "x",
|
||||
expectedAction: multistep.ActionHalt,
|
||||
},
|
||||
{
|
||||
name: "error in typing should return halt",
|
||||
builderConfig: &Config{BootConfig: bootcommand.BootConfig{BootCommand: []string{"hello"}}},
|
||||
expectCallMonitorCmd: true,
|
||||
monitorCmdErr: fmt.Errorf("some error"),
|
||||
expectedKeysSent: "h",
|
||||
expectedAction: multistep.ActionHalt,
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cs {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
accumulator := strings.Builder{}
|
||||
typer := commandTyperMock{
|
||||
monitorCmd: func(ref *proxmox.VmRef, cmd string) (map[string]interface{}, error) {
|
||||
if !c.expectCallMonitorCmd {
|
||||
t.Error("Did not expect MonitorCmd to be called")
|
||||
}
|
||||
if !strings.HasPrefix(cmd, "sendkey ") {
|
||||
t.Errorf("Expected all commands to be sendkey, got %s", cmd)
|
||||
}
|
||||
|
||||
accumulator.WriteString(strings.TrimPrefix(cmd, "sendkey "))
|
||||
|
||||
return c.monitorCmdRet, c.monitorCmdErr
|
||||
},
|
||||
}
|
||||
|
||||
state := new(multistep.BasicStateBag)
|
||||
state.Put("ui", packer.TestUi(t))
|
||||
state.Put("config", c.builderConfig)
|
||||
state.Put("http_port", uint(0))
|
||||
state.Put("vmRef", proxmox.NewVmRef(1))
|
||||
state.Put("proxmoxClient", typer)
|
||||
|
||||
step := stepTypeBootCommand{
|
||||
c.builderConfig.BootConfig,
|
||||
c.builderConfig.ctx,
|
||||
}
|
||||
action := step.Run(context.TODO(), state)
|
||||
if action != c.expectedAction {
|
||||
t.Errorf("Expected action to be %v, got %v", c.expectedAction, action)
|
||||
}
|
||||
if c.expectedKeysSent != accumulator.String() {
|
||||
t.Errorf("Expected keystrokes to be %q, got %q", c.expectedKeysSent, accumulator.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue