github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/container/kvm/libvirt/domainxml_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package libvirt_test 5 6 import ( 7 "encoding/xml" 8 9 "github.com/juju/errors" 10 "github.com/juju/testing" 11 jc "github.com/juju/testing/checkers" 12 gc "gopkg.in/check.v1" 13 14 . "github.com/juju/juju/container/kvm/libvirt" 15 ) 16 17 // gocheck boilerplate. 18 type domainXMLSuite struct { 19 testing.IsolationSuite 20 } 21 22 var _ = gc.Suite(&domainXMLSuite{}) 23 24 var amd64DomainStr = ` 25 <domain type="kvm"> 26 <name>juju-someid</name> 27 <vcpu>2</vcpu> 28 <currentMemory unit="MiB">1024</currentMemory> 29 <memory unit="MiB">1024</memory> 30 <os> 31 <type>hvm</type> 32 </os> 33 <features> 34 <acpi></acpi> 35 </features> 36 <cpu mode="host-passthrough" check="none"></cpu> 37 <devices> 38 <disk device="disk" type="file"> 39 <driver type="qcow2" name="qemu"></driver> 40 <source file="/some/path"></source> 41 <target dev="vda"></target> 42 </disk> 43 <disk device="disk" type="file"> 44 <driver type="raw" name="qemu"></driver> 45 <source file="/another/path"></source> 46 <target dev="vdb"></target> 47 </disk> 48 <interface type="bridge"> 49 <mac address="00:00:00:00:00:00"></mac> 50 <model type="virtio"></model> 51 <source bridge="parent-dev"></source> 52 <guest dev="device-name"></guest> 53 </interface> 54 <serial type="pty"> 55 <source path="/dev/pts/2"></source> 56 <target port="0"></target> 57 </serial> 58 <console type="pty" tty="/dev/pts/2"> 59 <source path="/dev/pts/2"></source> 60 <target port="0"></target> 61 </console> 62 </devices> 63 </domain>`[1:] 64 65 var arm64DomainStr = ` 66 <domain type="kvm"> 67 <name>juju-someid</name> 68 <vcpu>2</vcpu> 69 <currentMemory unit="MiB">1024</currentMemory> 70 <memory unit="MiB">1024</memory> 71 <os> 72 <type arch="aarch64" machine="virt">hvm</type> 73 <loader readonly="yes" type="pflash">/shared/readonly.fd</loader> 74 </os> 75 <features> 76 <gic version="host"></gic> 77 <acpi></acpi> 78 </features> 79 <cpu mode="host-passthrough" check="none"></cpu> 80 <devices> 81 <disk device="disk" type="file"> 82 <driver type="qcow2" name="qemu"></driver> 83 <source file="/some/path"></source> 84 <target dev="vda"></target> 85 </disk> 86 <disk device="disk" type="file"> 87 <driver type="raw" name="qemu"></driver> 88 <source file="/another/path"></source> 89 <target dev="vdb"></target> 90 </disk> 91 <interface type="bridge"> 92 <mac address="00:00:00:00:00:00"></mac> 93 <model type="virtio"></model> 94 <source bridge="parent-dev"></source> 95 <guest dev="device-name"></guest> 96 </interface> 97 <serial type="pty"> 98 <source path="/dev/pts/2"></source> 99 <target port="0"></target> 100 </serial> 101 <console type="pty" tty="/dev/pts/2"> 102 <source path="/dev/pts/2"></source> 103 <target port="0"></target> 104 </console> 105 </devices> 106 </domain>`[1:] 107 108 var amd64WithOvsBridgeDomainStr = ` 109 <domain type="kvm"> 110 <name>juju-someid</name> 111 <vcpu>2</vcpu> 112 <currentMemory unit="MiB">1024</currentMemory> 113 <memory unit="MiB">1024</memory> 114 <os> 115 <type>hvm</type> 116 </os> 117 <features> 118 <acpi></acpi> 119 </features> 120 <cpu mode="host-passthrough" check="none"></cpu> 121 <devices> 122 <disk device="disk" type="file"> 123 <driver type="qcow2" name="qemu"></driver> 124 <source file="/some/path"></source> 125 <target dev="vda"></target> 126 </disk> 127 <disk device="disk" type="file"> 128 <driver type="raw" name="qemu"></driver> 129 <source file="/another/path"></source> 130 <target dev="vdb"></target> 131 </disk> 132 <interface type="bridge"> 133 <mac address="00:00:00:00:00:00"></mac> 134 <model type="virtio"></model> 135 <source bridge="parent-dev"></source> 136 <guest dev="device-name"></guest> 137 <virtualport type="openvswitch"></virtualport> 138 </interface> 139 <serial type="pty"> 140 <source path="/dev/pts/2"></source> 141 <target port="0"></target> 142 </serial> 143 <console type="pty" tty="/dev/pts/2"> 144 <source path="/dev/pts/2"></source> 145 <target port="0"></target> 146 </console> 147 </devices> 148 </domain>`[1:] 149 150 func (domainXMLSuite) TestNewDomain(c *gc.C) { 151 table := []struct { 152 arch, want string 153 }{ 154 {"amd64", amd64DomainStr}, 155 {"arm64", arm64DomainStr}, 156 } 157 for i, test := range table { 158 c.Logf("TestNewDomain: test #%d for %s", i+1, test.arch) 159 ifaces := []InterfaceInfo{ 160 dummyInterface{ 161 mac: "00:00:00:00:00:00", 162 parent: "parent-dev", 163 name: "device-name"}} 164 disks := []DiskInfo{ 165 dummyDisk{driver: "qcow2", source: "/some/path"}, 166 dummyDisk{driver: "raw", source: "/another/path"}, 167 } 168 params := dummyParams{ifaceInfo: ifaces, diskInfo: disks, memory: 1024, cpuCores: 2, hostname: "juju-someid", arch: test.arch} 169 170 if test.arch == "arm64" { 171 params.loader = "/shared/readonly.fd" 172 } 173 174 d, err := NewDomain(params) 175 c.Check(err, jc.ErrorIsNil) 176 ml, err := xml.MarshalIndent(&d, "", " ") 177 c.Check(err, jc.ErrorIsNil) 178 c.Assert(string(ml), jc.DeepEquals, test.want) 179 } 180 } 181 182 func (domainXMLSuite) TestNewDomainWithOvsBridge(c *gc.C) { 183 ifaces := []InterfaceInfo{ 184 dummyInterface{ 185 mac: "00:00:00:00:00:00", 186 parent: "parent-dev", 187 name: "device-name", 188 parentVirtualPortType: "openvswitch", 189 }, 190 } 191 disks := []DiskInfo{ 192 dummyDisk{driver: "qcow2", source: "/some/path"}, 193 dummyDisk{driver: "raw", source: "/another/path"}, 194 } 195 params := dummyParams{ifaceInfo: ifaces, diskInfo: disks, memory: 1024, cpuCores: 2, hostname: "juju-someid", arch: "amd64"} 196 197 d, err := NewDomain(params) 198 c.Check(err, jc.ErrorIsNil) 199 ml, err := xml.MarshalIndent(&d, "", " ") 200 c.Check(err, jc.ErrorIsNil) 201 c.Assert(string(ml), jc.DeepEquals, amd64WithOvsBridgeDomainStr) 202 } 203 204 func (domainXMLSuite) TestNewDomainError(c *gc.C) { 205 d, err := NewDomain(dummyParams{err: errors.Errorf("boom")}) 206 c.Check(d, jc.DeepEquals, Domain{}) 207 c.Check(err, gc.ErrorMatches, "boom") 208 } 209 210 type dummyParams struct { 211 err error 212 arch string 213 cpuCores uint64 214 diskInfo []DiskInfo 215 hostname string 216 ifaceInfo []InterfaceInfo 217 loader string 218 memory uint64 219 nvram string 220 } 221 222 func (p dummyParams) Arch() string { return p.arch } 223 func (p dummyParams) CPUs() uint64 { return p.cpuCores } 224 func (p dummyParams) DiskInfo() []DiskInfo { return p.diskInfo } 225 func (p dummyParams) Host() string { return p.hostname } 226 func (p dummyParams) Loader() string { return p.loader } 227 func (p dummyParams) NVRAM() string { return p.nvram } 228 func (p dummyParams) NetworkInfo() []InterfaceInfo { return p.ifaceInfo } 229 func (p dummyParams) RAM() uint64 { return p.memory } 230 func (p dummyParams) ValidateDomainParams() error { return p.err } 231 232 type dummyDisk struct { 233 source string 234 driver string 235 } 236 237 func (d dummyDisk) Driver() string { return d.driver } 238 func (d dummyDisk) Source() string { return d.source } 239 240 type dummyInterface struct { 241 mac, parent, parentVirtualPortType, name string 242 } 243 244 func (i dummyInterface) InterfaceName() string { return i.name } 245 func (i dummyInterface) MACAddress() string { return i.mac } 246 func (i dummyInterface) ParentInterfaceName() string { return i.parent } 247 func (i dummyInterface) ParentVirtualPortType() string { return i.parentVirtualPortType }