1
0
mirror of https://github.com/kata-containers/kata-containers.git synced 2025-05-02 13:44:33 +00:00
kata-containers/qemu/qemu_test.go
Sebastien Boeuf 7fdfc6a4c9 qemu: Add support for romfile option
Any device inheriting from virtio-pci can specify a ROM file. This
option is provisioned by default with "efi-virtio.rom", but most
of the time, firmwares such as OVMF or seabios will already support
what is provided by this ROM file.

In order to reduce the "forced" dependency on such ROM file, govmm
should provide an empty path if the consumer of the library does not
provide one.

This patch reorganizes the list of devices, so that it gets easier to
list which devices inherit from virtio-pci, and then adds the romfile
option to every single device that support this option.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2018-10-10 17:17:36 -07:00

1096 lines
26 KiB
Go

/*
// Copyright (c) 2016 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/
package qemu
import (
"fmt"
"io/ioutil"
"os"
"strings"
"testing"
)
const agentUUID = "4cb19522-1e18-439a-883a-f9b2a3a95f5e"
const volumeUUID = "67d86208-b46c-4465-9018-e14187d4010"
func testAppend(structure interface{}, expected string, t *testing.T) {
var config Config
testConfigAppend(&config, structure, expected, t)
return
}
func testConfigAppend(config *Config, structure interface{}, expected string, t *testing.T) {
switch s := structure.(type) {
case Machine:
config.Machine = s
config.appendMachine()
case Device:
config.Devices = []Device{s}
config.appendDevices()
case Knobs:
config.Knobs = s
config.appendKnobs()
case Kernel:
config.Kernel = s
config.appendKernel()
case Memory:
config.Memory = s
config.appendMemory()
case SMP:
config.SMP = s
if err := config.appendCPUs(); err != nil {
t.Fatalf("Unexpected error: %v\n", err)
}
case QMPSocket:
config.QMPSockets = []QMPSocket{s}
config.appendQMPSockets()
case []QMPSocket:
config.QMPSockets = s
config.appendQMPSockets()
case RTC:
config.RTC = s
config.appendRTC()
case IOThread:
config.IOThreads = []IOThread{s}
config.appendIOThreads()
case Incoming:
config.Incoming = s
config.appendIncoming()
}
result := strings.Join(config.qemuParams, " ")
if result != expected {
t.Fatalf("Failed to append parameters [%s] != [%s]", result, expected)
}
}
func TestAppendMachine(t *testing.T) {
machineString := "-machine pc-lite,accel=kvm,kernel_irqchip,nvdimm"
machine := Machine{
Type: "pc-lite",
Acceleration: "kvm,kernel_irqchip,nvdimm",
}
testAppend(machine, machineString, t)
machineString = "-machine pc-lite,accel=kvm,kernel_irqchip,nvdimm,gic-version=host,usb=off"
machine = Machine{
Type: "pc-lite",
Acceleration: "kvm,kernel_irqchip,nvdimm",
Options: "gic-version=host,usb=off",
}
testAppend(machine, machineString, t)
}
func TestAppendEmptyMachine(t *testing.T) {
machine := Machine{}
testAppend(machine, "", t)
}
var deviceNVDIMMString = "-device nvdimm,id=nv0,memdev=mem0 -object memory-backend-file,id=mem0,mem-path=/root,size=65536"
func TestAppendDeviceNVDIMM(t *testing.T) {
object := Object{
Driver: NVDIMM,
Type: MemoryBackendFile,
DeviceID: "nv0",
ID: "mem0",
MemPath: "/root",
Size: 1 << 16,
}
testAppend(object, deviceNVDIMMString, t)
}
var deviceFSString = "-device virtio-9p-pci,disable-modern=true,fsdev=workload9p,mount_tag=rootfs,romfile=efi-virtio.rom -fsdev local,id=workload9p,path=/var/lib/docker/devicemapper/mnt/e31ebda2,security_model=none"
func TestAppendDeviceFS(t *testing.T) {
fsdev := FSDevice{
Driver: Virtio9P,
FSDriver: Local,
ID: "workload9p",
Path: "/var/lib/docker/devicemapper/mnt/e31ebda2",
MountTag: "rootfs",
SecurityModel: None,
DisableModern: true,
ROMFile: "efi-virtio.rom",
}
testAppend(fsdev, deviceFSString, t)
}
var deviceNetworkString = "-netdev tap,id=tap0,vhost=on,ifname=ceth0,downscript=no,script=no -device driver=virtio-net-pci,netdev=tap0,mac=01:02:de:ad:be:ef,disable-modern=true,romfile=efi-virtio.rom"
func TestAppendDeviceNetwork(t *testing.T) {
netdev := NetDevice{
Driver: VirtioNet,
Type: TAP,
ID: "tap0",
IFName: "ceth0",
Script: "no",
DownScript: "no",
VHost: true,
MACAddress: "01:02:de:ad:be:ef",
DisableModern: true,
ROMFile: "efi-virtio.rom",
}
testAppend(netdev, deviceNetworkString, t)
}
var deviceNetworkStringMq = "-netdev tap,id=tap0,vhost=on,fds=3:4 -device driver=virtio-net-pci,netdev=tap0,mac=01:02:de:ad:be:ef,disable-modern=true,mq=on,vectors=6,romfile=efi-virtio.rom"
func TestAppendDeviceNetworkMq(t *testing.T) {
foo, _ := ioutil.TempFile(os.TempDir(), "govmm-qemu-test")
bar, _ := ioutil.TempFile(os.TempDir(), "govmm-qemu-test")
defer func() {
_ = foo.Close()
_ = bar.Close()
_ = os.Remove(foo.Name())
_ = os.Remove(bar.Name())
}()
netdev := NetDevice{
Driver: VirtioNet,
Type: TAP,
ID: "tap0",
IFName: "ceth0",
Script: "no",
DownScript: "no",
FDs: []*os.File{foo, bar},
VHost: true,
MACAddress: "01:02:de:ad:be:ef",
DisableModern: true,
ROMFile: "efi-virtio.rom",
}
testAppend(netdev, deviceNetworkStringMq, t)
}
var deviceNetworkPCIString = "-netdev tap,id=tap0,vhost=on,ifname=ceth0,downscript=no,script=no -device driver=virtio-net-pci,netdev=tap0,mac=01:02:de:ad:be:ef,bus=/pci-bus/pcie.0,addr=ff,disable-modern=true,romfile=efi-virtio.rom"
func TestAppendDeviceNetworkPCI(t *testing.T) {
netdev := NetDevice{
Driver: VirtioNetPCI,
Type: TAP,
ID: "tap0",
IFName: "ceth0",
Bus: "/pci-bus/pcie.0",
Addr: "255",
Script: "no",
DownScript: "no",
VHost: true,
MACAddress: "01:02:de:ad:be:ef",
DisableModern: true,
ROMFile: "efi-virtio.rom",
}
testAppend(netdev, deviceNetworkPCIString, t)
}
var deviceNetworkPCIStringMq = "-netdev tap,id=tap0,vhost=on,fds=3:4 -device driver=virtio-net-pci,netdev=tap0,mac=01:02:de:ad:be:ef,bus=/pci-bus/pcie.0,addr=ff,disable-modern=true,mq=on,vectors=6,romfile=efi-virtio.rom"
func TestAppendDeviceNetworkPCIMq(t *testing.T) {
foo, _ := ioutil.TempFile(os.TempDir(), "govmm-qemu-test")
bar, _ := ioutil.TempFile(os.TempDir(), "govmm-qemu-test")
defer func() {
_ = foo.Close()
_ = bar.Close()
_ = os.Remove(foo.Name())
_ = os.Remove(bar.Name())
}()
netdev := NetDevice{
Driver: VirtioNetPCI,
Type: TAP,
ID: "tap0",
IFName: "ceth0",
Bus: "/pci-bus/pcie.0",
Addr: "255",
Script: "no",
DownScript: "no",
FDs: []*os.File{foo, bar},
VHost: true,
MACAddress: "01:02:de:ad:be:ef",
DisableModern: true,
ROMFile: "efi-virtio.rom",
}
testAppend(netdev, deviceNetworkPCIStringMq, t)
}
var deviceSerialString = "-device virtio-serial-pci,disable-modern=true,id=serial0,romfile=efi-virtio.rom"
func TestAppendDeviceSerial(t *testing.T) {
sdev := SerialDevice{
Driver: VirtioSerial,
ID: "serial0",
DisableModern: true,
ROMFile: "efi-virtio.rom",
}
testAppend(sdev, deviceSerialString, t)
}
var deviceSerialPortString = "-device virtserialport,chardev=char0,id=channel0,name=channel.0 -chardev socket,id=char0,path=/tmp/char.sock,server,nowait"
func TestAppendDeviceSerialPort(t *testing.T) {
chardev := CharDevice{
Driver: VirtioSerialPort,
Backend: Socket,
ID: "char0",
DeviceID: "channel0",
Path: "/tmp/char.sock",
Name: "channel.0",
}
testAppend(chardev, deviceSerialPortString, t)
}
var deviceBlockString = "-device virtio-blk,disable-modern=true,drive=hd0,scsi=off,config-wce=off,romfile=efi-virtio.rom -drive id=hd0,file=/var/lib/vm.img,aio=threads,format=qcow2,if=none"
func TestAppendDeviceBlock(t *testing.T) {
blkdev := BlockDevice{
Driver: VirtioBlock,
ID: "hd0",
File: "/var/lib/vm.img",
AIO: Threads,
Format: QCOW2,
Interface: NoInterface,
SCSI: false,
WCE: false,
DisableModern: true,
ROMFile: "efi-virtio.rom",
}
testAppend(blkdev, deviceBlockString, t)
}
var deviceVhostUserNetString = "-chardev socket,id=char1,path=/tmp/nonexistentsocket.socket -netdev type=vhost-user,id=net1,chardev=char1,vhostforce -device virtio-net-pci,netdev=net1,mac=00:11:22:33:44:55,romfile=efi-virtio.rom"
var deviceVhostUserSCSIString = "-chardev socket,id=char1,path=/tmp/nonexistentsocket.socket -device vhost-user-scsi-pci,id=scsi1,chardev=char1,romfile=efi-virtio.rom"
var deviceVhostUserBlkString = "-chardev socket,id=char2,path=/tmp/nonexistentsocket.socket -device vhost-user-blk-pci,logical_block_size=4096,size=512M,chardev=char2,romfile=efi-virtio.rom"
func TestAppendDeviceVhostUser(t *testing.T) {
vhostuserBlkDevice := VhostUserDevice{
SocketPath: "/tmp/nonexistentsocket.socket",
CharDevID: "char2",
TypeDevID: "",
Address: "",
VhostUserType: VhostUserBlk,
ROMFile: "efi-virtio.rom",
}
testAppend(vhostuserBlkDevice, deviceVhostUserBlkString, t)
vhostuserSCSIDevice := VhostUserDevice{
SocketPath: "/tmp/nonexistentsocket.socket",
CharDevID: "char1",
TypeDevID: "scsi1",
Address: "",
VhostUserType: VhostUserSCSI,
ROMFile: "efi-virtio.rom",
}
testAppend(vhostuserSCSIDevice, deviceVhostUserSCSIString, t)
vhostuserNetDevice := VhostUserDevice{
SocketPath: "/tmp/nonexistentsocket.socket",
CharDevID: "char1",
TypeDevID: "net1",
Address: "00:11:22:33:44:55",
VhostUserType: VhostUserNet,
ROMFile: "efi-virtio.rom",
}
testAppend(vhostuserNetDevice, deviceVhostUserNetString, t)
}
var deviceVFIOString = "-device vfio-pci,host=02:10.0,romfile=efi-virtio.rom"
func TestAppendDeviceVFIO(t *testing.T) {
vfioDevice := VFIODevice{
BDF: "02:10.0",
ROMFile: "efi-virtio.rom",
}
testAppend(vfioDevice, deviceVFIOString, t)
}
var deviceVSOCKString = "-device vhost-vsock-pci,disable-modern=true,id=vhost-vsock-pci0,guest-cid=4,romfile=efi-virtio.rom"
func TestAppendVSOCK(t *testing.T) {
vsockDevice := VSOCKDevice{
ID: "vhost-vsock-pci0",
ContextID: 4,
VHostFD: nil,
DisableModern: true,
ROMFile: "efi-virtio.rom",
}
testAppend(vsockDevice, deviceVSOCKString, t)
}
func TestVSOCKValid(t *testing.T) {
vsockDevice := VSOCKDevice{
ID: "vhost-vsock-pci0",
ContextID: MinimalGuestCID - 1,
VHostFD: nil,
DisableModern: true,
}
if vsockDevice.Valid() {
t.Fatalf("VSOCK Context ID is not valid")
}
vsockDevice.ID = ""
if vsockDevice.Valid() {
t.Fatalf("VSOCK ID is not valid")
}
}
func TestAppendVirtioRng(t *testing.T) {
var objectString = "-object rng-random,id=rng0"
var deviceString = "-device " + string(VirtioRng) + ",rng=rng0,romfile=efi-virtio.rom"
rngDevice := RngDevice{
ID: "rng0",
ROMFile: "efi-virtio.rom",
}
testAppend(rngDevice, objectString+" "+deviceString, t)
rngDevice.Filename = "/dev/urandom"
objectString += ",filename=" + rngDevice.Filename
testAppend(rngDevice, objectString+" "+deviceString, t)
rngDevice.MaxBytes = 20
deviceString += fmt.Sprintf(",max-bytes=%d", rngDevice.MaxBytes)
testAppend(rngDevice, objectString+" "+deviceString, t)
rngDevice.Period = 500
deviceString += fmt.Sprintf(",period=%d", rngDevice.Period)
testAppend(rngDevice, objectString+" "+deviceString, t)
}
func TestVirtioRngValid(t *testing.T) {
rng := RngDevice{
ID: "",
}
if rng.Valid() {
t.Fatalf("rng should be not valid when ID is empty")
}
rng.ID = "rng0"
if !rng.Valid() {
t.Fatalf("rng should be valid")
}
}
func TestAppendVirtioBalloon(t *testing.T) {
balloonDevice := BalloonDevice{
ID: "balloon",
ROMFile: "efi-virtio.rom",
}
var deviceString = "-device " + string(VirtioBalloon)
deviceString += ",id=" + balloonDevice.ID + ",romfile=" + balloonDevice.ROMFile
var OnDeflateOnOMM = ",deflate-on-oom=on"
var OffDeflateOnOMM = ",deflate-on-oom=off"
var OnDisableModern = ",disable-modern=on"
var OffDisableModern = ",disable-modern=off"
testAppend(balloonDevice, deviceString+OffDeflateOnOMM+OffDisableModern, t)
balloonDevice.DeflateOnOOM = true
testAppend(balloonDevice, deviceString+OnDeflateOnOMM+OffDisableModern, t)
balloonDevice.DisableModern = true
testAppend(balloonDevice, deviceString+OnDeflateOnOMM+OnDisableModern, t)
}
func TestVirtioBalloonValid(t *testing.T) {
balloon := BalloonDevice{
ID: "",
}
if balloon.Valid() {
t.Fatalf("balloon should be not valid when ID is empty")
}
balloon.ID = "balloon0"
if !balloon.Valid() {
t.Fatalf("balloon should be valid")
}
}
var deviceSCSIControllerStr = "-device virtio-scsi-pci,id=foo,romfile=efi-virtio.rom"
var deviceSCSIControllerBusAddrStr = "-device virtio-scsi-pci,id=foo,bus=pci.0,addr=00:04.0,disable-modern=true,iothread=iothread1,romfile=efi-virtio.rom"
func TestAppendDeviceSCSIController(t *testing.T) {
scsiCon := SCSIController{
ID: "foo",
ROMFile: "efi-virtio.rom",
}
testAppend(scsiCon, deviceSCSIControllerStr, t)
scsiCon.Bus = "pci.0"
scsiCon.Addr = "00:04.0"
scsiCon.DisableModern = true
scsiCon.IOThread = "iothread1"
testAppend(scsiCon, deviceSCSIControllerBusAddrStr, t)
}
var devicePCIBridgeString = "-device pci-bridge,bus=/pci-bus/pcie.0,id=mybridge,chassis_nr=5,shpc=on,addr=ff,romfile=efi-virtio.rom"
func TestAppendPCIBridgeDevice(t *testing.T) {
bridge := BridgeDevice{
Type: PCIBridge,
ID: "mybridge",
Bus: "/pci-bus/pcie.0",
Addr: "255",
Chassis: 5,
SHPC: true,
ROMFile: "efi-virtio.rom",
}
testAppend(bridge, devicePCIBridgeString, t)
}
var devicePCIEBridgeString = "-device pcie-pci-bridge,bus=/pci-bus/pcie.0,id=mybridge,addr=ff,romfile=efi-virtio.rom"
func TestAppendPCIEBridgeDevice(t *testing.T) {
bridge := BridgeDevice{
Type: PCIEBridge,
ID: "mybridge",
Bus: "/pci-bus/pcie.0",
Addr: "255",
ROMFile: "efi-virtio.rom",
}
testAppend(bridge, devicePCIEBridgeString, t)
}
func TestAppendEmptyDevice(t *testing.T) {
device := SerialDevice{}
testAppend(device, "", t)
}
func TestAppendKnobsAllTrue(t *testing.T) {
var knobsString = "-no-user-config -nodefaults -nographic -daemonize -realtime mlock=on -S"
knobs := Knobs{
NoUserConfig: true,
NoDefaults: true,
NoGraphic: true,
Daemonize: true,
MemPrealloc: true,
FileBackedMem: true,
FileBackedMemShared: true,
Realtime: true,
Mlock: true,
Stopped: true,
}
testAppend(knobs, knobsString, t)
}
func TestAppendKnobsAllFalse(t *testing.T) {
var knobsString = "-realtime mlock=off"
knobs := Knobs{
NoUserConfig: false,
NoDefaults: false,
NoGraphic: false,
MemPrealloc: false,
FileBackedMem: false,
FileBackedMemShared: false,
Realtime: false,
Mlock: false,
Stopped: false,
}
testAppend(knobs, knobsString, t)
}
func TestAppendMemoryHugePages(t *testing.T) {
conf := &Config{
Memory: Memory{
Size: "1G",
Slots: 8,
MaxMem: "3G",
Path: "foobar",
},
}
memString := "-m 1G,slots=8,maxmem=3G"
testConfigAppend(conf, conf.Memory, memString, t)
knobs := Knobs{
HugePages: true,
MemPrealloc: true,
FileBackedMem: true,
FileBackedMemShared: true,
}
knobsString := "-object memory-backend-file,id=dimm1,size=1G,mem-path=/dev/hugepages,share=on,prealloc=on -numa node,memdev=dimm1"
mlockFalseString := "-realtime mlock=off"
testConfigAppend(conf, knobs, memString+" "+knobsString+" "+mlockFalseString, t)
}
func TestAppendMemoryMemPrealloc(t *testing.T) {
conf := &Config{
Memory: Memory{
Size: "1G",
Slots: 8,
MaxMem: "3G",
Path: "foobar",
},
}
memString := "-m 1G,slots=8,maxmem=3G"
testConfigAppend(conf, conf.Memory, memString, t)
knobs := Knobs{
MemPrealloc: true,
FileBackedMem: true,
FileBackedMemShared: true,
}
knobsString := "-object memory-backend-ram,id=dimm1,size=1G,prealloc=on -numa node,memdev=dimm1"
mlockFalseString := "-realtime mlock=off"
testConfigAppend(conf, knobs, memString+" "+knobsString+" "+mlockFalseString, t)
}
func TestAppendMemoryFileBackedMemShared(t *testing.T) {
conf := &Config{
Memory: Memory{
Size: "1G",
Slots: 8,
MaxMem: "3G",
Path: "foobar",
},
}
memString := "-m 1G,slots=8,maxmem=3G"
testConfigAppend(conf, conf.Memory, memString, t)
knobs := Knobs{
FileBackedMem: true,
FileBackedMemShared: true,
}
knobsString := "-object memory-backend-file,id=dimm1,size=1G,mem-path=foobar,share=on -numa node,memdev=dimm1"
mlockFalseString := "-realtime mlock=off"
testConfigAppend(conf, knobs, memString+" "+knobsString+" "+mlockFalseString, t)
}
func TestAppendMemoryFileBackedMem(t *testing.T) {
conf := &Config{
Memory: Memory{
Size: "1G",
Slots: 8,
MaxMem: "3G",
Path: "foobar",
},
}
memString := "-m 1G,slots=8,maxmem=3G"
testConfigAppend(conf, conf.Memory, memString, t)
knobs := Knobs{
FileBackedMem: true,
FileBackedMemShared: false,
}
knobsString := "-object memory-backend-file,id=dimm1,size=1G,mem-path=foobar -numa node,memdev=dimm1"
mlockFalseString := "-realtime mlock=off"
testConfigAppend(conf, knobs, memString+" "+knobsString+" "+mlockFalseString, t)
}
var kernelString = "-kernel /opt/vmlinux.container -initrd /opt/initrd.container -append root=/dev/pmem0p1 rootflags=dax,data=ordered,errors=remount-ro rw rootfstype=ext4 tsc=reliable"
func TestAppendKernel(t *testing.T) {
kernel := Kernel{
Path: "/opt/vmlinux.container",
InitrdPath: "/opt/initrd.container",
Params: "root=/dev/pmem0p1 rootflags=dax,data=ordered,errors=remount-ro rw rootfstype=ext4 tsc=reliable",
}
testAppend(kernel, kernelString, t)
}
var memoryString = "-m 2G,slots=2,maxmem=3G"
func TestAppendMemory(t *testing.T) {
memory := Memory{
Size: "2G",
Slots: 2,
MaxMem: "3G",
Path: "",
}
testAppend(memory, memoryString, t)
}
var cpusString = "-smp 2,cores=1,threads=2,sockets=2,maxcpus=6"
func TestAppendCPUs(t *testing.T) {
smp := SMP{
CPUs: 2,
Sockets: 2,
Cores: 1,
Threads: 2,
MaxCPUs: 6,
}
testAppend(smp, cpusString, t)
}
func TestFailToAppendCPUs(t *testing.T) {
config := Config{
SMP: SMP{
CPUs: 2,
Sockets: 2,
Cores: 1,
Threads: 2,
MaxCPUs: 1,
},
}
if err := config.appendCPUs(); err == nil {
t.Fatalf("Expected appendCPUs to fail")
}
}
var qmpSingleSocketServerString = "-qmp unix:cc-qmp,server,nowait"
var qmpSingleSocketString = "-qmp unix:cc-qmp"
func TestAppendSingleQMPSocketServer(t *testing.T) {
qmp := QMPSocket{
Type: "unix",
Name: "cc-qmp",
Server: true,
NoWait: true,
}
testAppend(qmp, qmpSingleSocketServerString, t)
}
func TestAppendSingleQMPSocket(t *testing.T) {
qmp := QMPSocket{
Type: Unix,
Name: "cc-qmp",
Server: false,
}
testAppend(qmp, qmpSingleSocketString, t)
}
var qmpSocketServerString = "-qmp unix:cc-qmp-1,server,nowait -qmp unix:cc-qmp-2,server,nowait"
func TestAppendQMPSocketServer(t *testing.T) {
qmp := []QMPSocket{
{
Type: "unix",
Name: "cc-qmp-1",
Server: true,
NoWait: true,
},
{
Type: "unix",
Name: "cc-qmp-2",
Server: true,
NoWait: true,
},
}
testAppend(qmp, qmpSocketServerString, t)
}
var qemuString = "-name cc-qemu -cpu host -uuid " + agentUUID
func TestAppendStrings(t *testing.T) {
config := Config{
Path: "qemu",
Name: "cc-qemu",
UUID: agentUUID,
CPUModel: "host",
}
config.appendName()
config.appendCPUModel()
config.appendUUID()
result := strings.Join(config.qemuParams, " ")
if result != qemuString {
t.Fatalf("Failed to append parameters [%s] != [%s]", result, qemuString)
}
}
var rtcString = "-rtc base=utc,driftfix=slew,clock=host"
func TestAppendRTC(t *testing.T) {
rtc := RTC{
Base: UTC,
Clock: Host,
DriftFix: Slew,
}
testAppend(rtc, rtcString, t)
}
var ioThreadString = "-object iothread,id=iothread1"
func TestAppendIOThread(t *testing.T) {
ioThread := IOThread{
ID: "iothread1",
}
testAppend(ioThread, ioThreadString, t)
}
var incomingStringFD = "-S -incoming fd:3"
func TestAppendIncomingFD(t *testing.T) {
source := Incoming{
MigrationType: MigrationFD,
FD: os.Stdout,
}
testAppend(source, incomingStringFD, t)
}
var incomingStringExec = "-S -incoming exec:test migration cmd"
func TestAppendIncomingExec(t *testing.T) {
source := Incoming{
MigrationType: MigrationExec,
Exec: "test migration cmd",
}
testAppend(source, incomingStringExec, t)
}
func TestBadName(t *testing.T) {
c := &Config{}
c.appendName()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
}
func TestBadMachine(t *testing.T) {
c := &Config{}
c.appendMachine()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
}
func TestBadCPUModel(t *testing.T) {
c := &Config{}
c.appendCPUModel()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
}
func TestBadQMPSockets(t *testing.T) {
c := &Config{}
c.appendQMPSockets()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
c = &Config{
QMPSockets: []QMPSocket{{}},
}
c.appendQMPSockets()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
c = &Config{
QMPSockets: []QMPSocket{{Name: "test"}},
}
c.appendQMPSockets()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
c = &Config{
QMPSockets: []QMPSocket{
{
Name: "test",
Type: QMPSocketType("ip"),
},
},
}
c.appendQMPSockets()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
}
func TestBadDevices(t *testing.T) {
c := &Config{}
c.appendDevices()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
c = &Config{
Devices: []Device{
FSDevice{},
FSDevice{
ID: "id0",
MountTag: "tag",
},
CharDevice{},
CharDevice{
ID: "id1",
},
NetDevice{},
NetDevice{
ID: "id1",
IFName: "if",
Type: IPVTAP,
},
SerialDevice{},
SerialDevice{
ID: "id0",
},
BlockDevice{},
BlockDevice{
Driver: "drv",
ID: "id1",
},
VhostUserDevice{},
VhostUserDevice{
CharDevID: "devid",
},
VhostUserDevice{
CharDevID: "devid",
SocketPath: "/var/run/sock",
},
VhostUserDevice{
CharDevID: "devid",
SocketPath: "/var/run/sock",
VhostUserType: VhostUserNet,
},
VhostUserDevice{
CharDevID: "devid",
SocketPath: "/var/run/sock",
VhostUserType: VhostUserSCSI,
},
},
}
c.appendDevices()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
}
func TestBadRTC(t *testing.T) {
c := &Config{}
c.appendRTC()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
c = &Config{
RTC: RTC{
Clock: RTCClock("invalid"),
},
}
c.appendRTC()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
c = &Config{
RTC: RTC{
Clock: Host,
DriftFix: RTCDriftFix("invalid"),
},
}
c.appendRTC()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
}
func TestBadGlobalParam(t *testing.T) {
c := &Config{}
c.appendGlobalParam()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
}
func TestBadVGA(t *testing.T) {
c := &Config{}
c.appendVGA()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
}
func TestBadKernel(t *testing.T) {
c := &Config{}
c.appendKernel()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
}
func TestBadMemoryKnobs(t *testing.T) {
c := &Config{}
c.appendMemoryKnobs()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
c = &Config{
Knobs: Knobs{
HugePages: true,
},
}
c.appendMemoryKnobs()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
c = &Config{
Knobs: Knobs{
HugePages: true,
},
}
c.appendMemoryKnobs()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
c = &Config{
Knobs: Knobs{
MemPrealloc: true,
},
}
c.appendMemoryKnobs()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
c = &Config{
Knobs: Knobs{
FileBackedMem: true,
},
Memory: Memory{
Size: "1024",
},
}
c.appendMemoryKnobs()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
}
func TestBadKnobs(t *testing.T) {
c := &Config{
Knobs: Knobs{
Mlock: true,
},
}
c.appendKnobs()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
}
func TestBadBios(t *testing.T) {
c := &Config{}
c.appendBios()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
}
func TestBadIOThreads(t *testing.T) {
c := &Config{}
c.appendIOThreads()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
c = &Config{
IOThreads: []IOThread{{ID: ""}},
}
c.appendIOThreads()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
}
func TestBadIncoming(t *testing.T) {
c := &Config{}
c.appendIncoming()
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
}
func TestBadCPUs(t *testing.T) {
c := &Config{}
if err := c.appendCPUs(); err != nil {
t.Fatalf("No error expected got %v", err)
}
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
c = &Config{
SMP: SMP{
MaxCPUs: 1,
CPUs: 2,
},
}
if c.appendCPUs() == nil {
t.Errorf("Error expected")
}
}