2
# This program is free software; you can redistribute it and/or modify
3
# it under the terms of the GNU General Public License as published by
4
# the Free Software Foundation; either version 2 of the License, or
5
# (at your option) any later version.
7
# This program is distributed in the hope that it will be useful,
8
# but WITHOUT ANY WARRANTY; without even the implied warranty of
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
# GNU General Public License for more details.
12
# You should have received a copy of the GNU General Public License
13
# along with this program; if not, write to the Free Software
14
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25
conn = utils.open_testdriver()
26
kvmconn = utils.open_testkvmdriver()
28
def sanitize_file_xml(xml):
29
# s/"/'/g from generated XML, matches what libxml dumps out
30
# This won't work all the time, but should be good enough for testing
31
return xml.replace("'", "\"")
33
class XMLParseTest(unittest.TestCase):
35
def _roundtrip_compare(self, filename):
36
expectXML = sanitize_file_xml(file(filename).read())
37
guest = virtinst.Guest(connection=conn, parsexml=expectXML)
38
actualXML = guest.get_config_xml()
39
utils.diff_compare(actualXML, expect_out=expectXML)
41
def _alter_compare(self, actualXML, outfile):
42
utils.test_create(conn, actualXML)
43
utils.diff_compare(actualXML, outfile)
45
def testRoundTrip(self):
47
Make sure parsing doesn't output different XML
49
exclude = ["misc-xml-escaping.xml"]
52
for f in glob.glob("tests/xmlconfig-xml/*.xml"):
53
if filter(f.endswith, exclude):
57
self._roundtrip_compare(f)
60
error += "%s:\n%s\n" % (f, "".join(traceback.format_exc()))
63
raise AssertionError("Roundtrip parse tests failed:\n%s" % error)
65
def _set_and_check(self, obj, param, initval, newval="SENTINEL"):
67
Check expected initial value obj.param == initval, then
68
set newval, and make sure it is returned properly
70
curval = getattr(obj, param)
71
self.assertEquals(initval, curval)
73
if newval == "SENTINEL":
75
setattr(obj, param, newval)
76
curval = getattr(obj, param)
77
self.assertEquals(newval, curval)
79
def _make_checker(self, obj):
80
def check(name, initval, newval="SENTINEL"):
81
return self._set_and_check(obj, name, initval, newval)
84
def testAlterGuest(self):
86
Test changing Guest() parameters after parsing
88
infile = "tests/xmlparse-xml/change-guest-in.xml"
89
outfile = "tests/xmlparse-xml/change-guest-out.xml"
90
guest = virtinst.Guest(connection=conn,
91
parsexml=file(infile).read())
93
check = self._make_checker(guest)
95
check("name", "TestGuest", "change_name")
96
check("description", None, "Hey desc changed")
97
check("maxvcpus", 5, 30)
98
check("vcpus", 30, 22)
99
check("cpuset", "1-3", "1-5,15")
100
check("maxmemory", 400, 500)
101
check("memory", 200, 1000)
102
check("maxmemory", 1000, 2000)
103
check("uuid", "12345678-1234-1234-1234-123456789012",
104
"11111111-2222-3333-4444-555555555555")
105
check("emulator", "/usr/lib/xen/bin/qemu-dm", "/usr/binnnn/fooemu")
107
check = self._make_checker(guest.clock)
108
check("offset", "utc", "localtime")
110
check = self._make_checker(guest.seclabel)
111
check("type", "static", "static")
112
check("model", "selinux", "apparmor")
113
check("label", "foolabel", "barlabel")
114
check("imagelabel", "imagelabel", "fooimage")
116
check = self._make_checker(guest.installer)
117
check("type", "kvm", "test")
118
check("os_type", "hvm", "xen")
119
check("arch", "i686", None)
120
check("machine", "foobar", "pc-0.11")
122
check = self._make_checker(guest.installer.bootconfig)
123
check("bootorder", ["hd"], ["fd"])
124
check("enable_bootmenu", None, False)
125
check("kernel", None)
126
check("initrd", None)
127
check("kernel_args", None)
129
check = self._make_checker(guest.features)
130
check("acpi", True, False)
131
check("apic", True, False)
132
check("pae", False, True)
134
check = self._make_checker(guest.cpu)
135
check("match", "exact", "strict")
136
check("model", "footest", "qemu64")
137
check("vendor", "Intel", "qemuvendor")
138
check("threads", 2, 1)
140
check("sockets", 4, 1)
142
check = self._make_checker(guest.cpu.features[0])
143
check("name", "x2apic", "foofeat")
144
check("policy", "force", "disable")
145
guest.cpu.remove_feature(guest.cpu.features[1])
146
guest.cpu.add_feature("addfeature")
148
self._alter_compare(guest.get_config_xml(), outfile)
150
def testAlterMinimalGuest(self):
151
infile = "tests/xmlparse-xml/change-minimal-guest-in.xml"
152
outfile = "tests/xmlparse-xml/change-minimal-guest-out.xml"
153
guest = virtinst.Guest(connection=conn,
154
parsexml=file(infile).read())
156
check = self._make_checker(guest.features)
157
check("acpi", False, True)
160
guest.features.get_xml_config().startswith("<features"))
162
check = self._make_checker(guest.clock)
163
check("offset", None, "utc")
164
self.assertTrue(guest.clock.get_xml_config().startswith("<clock"))
166
check = self._make_checker(guest.seclabel)
167
check("model", None, "default")
168
check("type", None, "static")
169
check("label", None, "frob")
171
guest.seclabel.get_xml_config().startswith("<seclabel"))
173
check = self._make_checker(guest.cpu)
174
check("model", None, "foobar")
175
check("cores", None, 4)
176
guest.cpu.add_feature("x2apic", "forbid")
177
guest.cpu.set_topology_defaults(guest.vcpus)
178
self.assertTrue(guest.cpu.get_xml_config().startswith("<cpu"))
180
self.assertTrue(guest.installer.get_xml_config().startswith("<os"))
182
self._alter_compare(guest.get_config_xml(), outfile)
184
def testAlterBootMulti(self):
185
infile = "tests/xmlparse-xml/change-boot-multi-in.xml"
186
outfile = "tests/xmlparse-xml/change-boot-multi-out.xml"
187
guest = virtinst.Guest(connection=conn,
188
parsexml=file(infile).read())
190
check = self._make_checker(guest.installer.bootconfig)
191
check("bootorder", ['hd', 'fd', 'cdrom', 'network'], ["cdrom"])
192
check("enable_bootmenu", False, True)
193
check("kernel", None, "foo.img")
194
check("initrd", None, "bar.img")
195
check("kernel_args", None, "ks=foo.ks")
197
self._alter_compare(guest.get_config_xml(), outfile)
199
def testAlterBootKernel(self):
200
infile = "tests/xmlparse-xml/change-boot-kernel-in.xml"
201
outfile = "tests/xmlparse-xml/change-boot-kernel-out.xml"
202
guest = virtinst.Guest(connection=conn,
203
parsexml=file(infile).read())
205
check = self._make_checker(guest.installer.bootconfig)
206
check("bootorder", [], ["network", "hd", "fd"])
207
check("enable_bootmenu", None)
208
check("kernel", "/boot/vmlinuz", None)
210
check("initrd", "/boot/initrd", None)
211
check("kernel_args", "location", None)
213
self._alter_compare(guest.get_config_xml(), outfile)
215
def testAlterDisk(self):
217
Test changing VirtualDisk() parameters after parsing
219
infile = "tests/xmlparse-xml/change-disk-in.xml"
220
outfile = "tests/xmlparse-xml/change-disk-out.xml"
221
guest = virtinst.Guest(connection=conn,
222
parsexml=file(infile).read())
224
# XXX: Set size up front. VirtualDisk validation is kind of
225
# convoluted. If trying to change a non-existing one and size wasn't
226
# already specified, we will error out.
227
disk1 = guest.disks[0]
229
disk2 = guest.disks[2]
231
disk3 = guest.disks[5]
234
check = self._make_checker(disk1)
235
check("path", "/tmp/test.img", "/dev/loop0")
236
check("driver_name", None, "test")
237
check("driver_type", None, "foobar")
239
check = self._make_checker(disk2)
240
check("path", "/dev/loop0", None)
241
check("device", "cdrom", "floppy")
242
check("read_only", True, False)
243
check("target", None, "fde")
244
check("bus", None, "fdc")
246
check = self._make_checker(disk3)
247
check("path", None, "/default-pool/default-vol")
248
check("shareable", False, True)
249
check("driver_cache", None, "writeback")
251
self._alter_compare(guest.get_config_xml(), outfile)
253
def testSingleDisk(self):
254
xml = ("""<disk type="file" device="disk"><source file="/a.img"/>"""
255
"""<target dev="hda" bus="ide"/></disk>""")
256
d = virtinst.VirtualDisk(parsexml=xml)
257
self._set_and_check(d, "target", "hda", "hdb")
258
self.assertEquals(xml.replace("hda", "hdb"), d.get_xml_config())
260
def testAlterChars(self):
261
infile = "tests/xmlparse-xml/change-chars-in.xml"
262
outfile = "tests/xmlparse-xml/change-chars-out.xml"
263
guest = virtinst.Guest(connection=conn,
264
parsexml=file(infile).read())
266
serial1 = guest.get_devices("serial")[0]
267
serial2 = guest.get_devices("serial")[1]
268
parallel1 = guest.get_devices("parallel")[0]
269
parallel2 = guest.get_devices("parallel")[1]
270
console1 = guest.get_devices("console")[0]
271
console2 = guest.get_devices("console")[1]
272
channel1 = guest.get_devices("channel")[0]
273
channel2 = guest.get_devices("channel")[1]
275
check = self._make_checker(serial1)
276
check("char_type", "null")
278
check = self._make_checker(serial2)
279
check("char_type", "tcp")
280
check("protocol", "telnet", "raw")
281
check("source_mode", "bind", "connect")
283
check = self._make_checker(parallel1)
284
check("source_mode", "bind")
285
check("source_path", "/tmp/foobar", None)
286
check("char_type", "unix", "pty")
288
check = self._make_checker(parallel2)
289
check("char_type", "udp")
290
check("bind_port", "1111", "1357")
291
check("bind_host", "my.bind.host", "my.foo.host")
292
check("source_mode", "connect")
293
check("source_port", "2222", "7777")
294
check("source_host", "my.source.host", "source.foo.host")
296
check = self._make_checker(console1)
297
check("char_type", "file")
298
check("source_path", "/tmp/foo.img", None)
299
check("source_path", None, "/root/foo")
300
check("target_type", "virtio")
302
check = self._make_checker(console2)
303
check("char_type", "pty")
304
check("target_type", None)
306
check = self._make_checker(channel1)
307
check("char_type", "pty")
308
check("target_type", "virtio")
309
check("target_name", "foo.bar.frob", "test.changed")
311
check = self._make_checker(channel2)
312
check("char_type", "unix")
313
check("target_type", "guestfwd")
314
check("target_address", "1.2.3.4", "5.6.7.8")
315
check("target_port", "4567", "1199")
317
self._alter_compare(guest.get_config_xml(), outfile)
319
def testAlterControllers(self):
320
infile = "tests/xmlparse-xml/change-controllers-in.xml"
321
outfile = "tests/xmlparse-xml/change-controllers-out.xml"
322
guest = virtinst.Guest(connection=conn,
323
parsexml=file(infile).read())
325
dev1 = guest.get_devices("controller")[0]
326
dev2 = guest.get_devices("controller")[1]
327
dev3 = guest.get_devices("controller")[2]
329
check = self._make_checker(dev1)
331
check("index", "3", "1")
333
check = self._make_checker(dev2)
334
check("type", "virtio-serial")
335
check("index", "0", "7")
336
check("ports", "32", "5")
337
check("vectors", "17", None)
339
check = self._make_checker(dev3)
340
check("type", "scsi")
341
check("index", "1", "2")
343
self._alter_compare(guest.get_config_xml(), outfile)
345
def testAlterNics(self):
346
infile = "tests/xmlparse-xml/change-nics-in.xml"
347
outfile = "tests/xmlparse-xml/change-nics-out.xml"
348
guest = virtinst.Guest(connection=conn,
349
parsexml=file(infile).read())
351
dev1 = guest.get_devices("interface")[0]
352
dev2 = guest.get_devices("interface")[1]
353
dev3 = guest.get_devices("interface")[2]
354
dev4 = guest.get_devices("interface")[3]
356
check = self._make_checker(dev1)
357
check("type", "user")
358
check("model", None, "testmodel")
359
check("bridge", None, "br0")
360
check("network", None, "route")
361
check("macaddr", "11:11:11:11:11:11", "AA:AA:AA:AA:AA:AA")
362
self.assertEquals(dev1.get_source(), None)
364
check = self._make_checker(dev2)
365
self.assertEquals(dev2.get_source(), "default")
366
check("type", "network", "bridge")
367
check("network", "default", None)
368
check("bridge", None, "newbr0")
369
check("model", "e1000", "virtio")
371
check = self._make_checker(dev3)
372
check("type", "bridge")
373
check("bridge", "foobr0", "newfoo0")
374
check("network", None, "default")
375
check("macaddr", "22:22:22:22:22:22")
376
check("target_dev", None, "test1")
377
self.assertEquals(dev3.get_source(), "newfoo0")
379
check = self._make_checker(dev4)
380
check("type", "ethernet")
381
check("source_dev", "eth0", "eth1")
382
check("target_dev", "nic02", "nic03")
383
check("target_dev", "nic03", None)
384
self.assertEquals(dev4.get_source(), "eth1")
386
self._alter_compare(guest.get_config_xml(), outfile)
388
def testAlterInputs(self):
389
infile = "tests/xmlparse-xml/change-inputs-in.xml"
390
outfile = "tests/xmlparse-xml/change-inputs-out.xml"
391
guest = virtinst.Guest(connection=conn,
392
parsexml=file(infile).read())
394
dev1 = guest.get_devices("input")[0]
395
dev2 = guest.get_devices("input")[1]
397
check = self._make_checker(dev1)
398
check("type", "mouse", "tablet")
399
check("bus", "ps2", "usb")
401
check = self._make_checker(dev2)
402
check("type", "tablet", "mouse")
403
check("bus", "usb", "xen")
404
check("bus", "xen", "usb")
406
self._alter_compare(guest.get_config_xml(), outfile)
408
def testAlterGraphics(self):
409
infile = "tests/xmlparse-xml/change-graphics-in.xml"
410
outfile = "tests/xmlparse-xml/change-graphics-out.xml"
411
guest = virtinst.Guest(connection=conn,
412
parsexml=file(infile).read())
414
dev1 = guest.get_devices("graphics")[0]
415
dev2 = guest.get_devices("graphics")[1]
416
dev3 = guest.get_devices("graphics")[2]
417
dev4 = guest.get_devices("graphics")[3]
418
dev5 = guest.get_devices("graphics")[4]
420
check = self._make_checker(dev1)
422
check("passwd", "foobar", "newpass")
423
check("port", 100, 6000)
424
check("listen", "0.0.0.0", "1.2.3.4")
426
check = self._make_checker(dev2)
428
check("xauth", "/tmp/.Xauthority", "fooauth")
429
check("display", "1:2", "6:1")
431
check = self._make_checker(dev3)
434
check = self._make_checker(dev4)
437
check("socket", "/tmp/foobar", "/var/lib/libvirt/socket/foo")
439
check = self._make_checker(dev5)
440
check("type", "spice")
441
check("passwd", "foobar", "newpass")
442
check("port", 100, 6000)
443
check("tlsPort", 101, 6001)
444
check("listen", "0.0.0.0", "1.2.3.4")
445
check("channel_inputs_mode", "insecure", "secure")
446
check("channel_main_mode", "secure", "any")
447
check("channel_record_mode", "any", "insecure")
448
check("passwdValidTo", "2010-04-09T15:51:00", "2011-01-07T19:08:00")
450
self._alter_compare(guest.get_config_xml(), outfile)
452
def testAlterVideos(self):
453
infile = "tests/xmlparse-xml/change-videos-in.xml"
454
outfile = "tests/xmlparse-xml/change-videos-out.xml"
455
guest = virtinst.Guest(connection=conn,
456
parsexml=file(infile).read())
458
dev1 = guest.get_devices("video")[0]
459
dev2 = guest.get_devices("video")[1]
460
dev3 = guest.get_devices("video")[2]
462
check = self._make_checker(dev1)
463
check("model_type", "vmvga", "vga")
464
check("vram", None, "1000")
465
check("heads", None, "1")
467
check = self._make_checker(dev2)
468
check("model_type", "cirrus", "vmvga")
469
check("vram", "10240", None)
470
check("heads", "3", "5")
472
check = self._make_checker(dev3)
473
check("model_type", "cirrus", "cirrus")
475
self._alter_compare(guest.get_config_xml(), outfile)
477
def testAlterHostdevs(self):
478
infile = "tests/xmlparse-xml/change-hostdevs-in.xml"
479
outfile = "tests/xmlparse-xml/change-hostdevs-out.xml"
480
guest = virtinst.Guest(connection=conn,
481
parsexml=file(infile).read())
483
dev1 = guest.get_devices("hostdev")[0]
484
dev2 = guest.get_devices("hostdev")[1]
485
dev3 = guest.get_devices("hostdev")[2]
487
check = self._make_checker(dev1)
489
check("managed", True, False)
490
check("mode", "subsystem", None)
491
check("vendor", "0x4321", "0x1111")
492
check("product", "0x1234", "0x2222")
493
check("bus", None, "1")
494
check("device", None, "2")
496
check = self._make_checker(dev2)
498
check("managed", False, True)
499
check("mode", "capabilities", "subsystem")
500
check("bus", "0x12", "0x56")
501
check("device", "0x34", "0x78")
503
check = self._make_checker(dev3)
505
check("managed", True, True)
506
check("mode", "subsystem", "capabilities")
507
check("domain", "0x0", "0x2")
508
check("bus", "0x11", "0x99")
509
check("slot", "0x22", "0x88")
510
check("function", "0x33", "0x77")
512
self._alter_compare(guest.get_config_xml(), outfile)
514
def testAlterWatchdogs(self):
515
infile = "tests/xmlparse-xml/change-watchdogs-in.xml"
516
outfile = "tests/xmlparse-xml/change-watchdogs-out.xml"
517
guest = virtinst.Guest(connection=conn,
518
parsexml=file(infile).read())
520
dev1 = guest.get_devices("watchdog")[0]
521
check = self._make_checker(dev1)
522
check("model", "ib700", "i6300esb")
523
check("action", "none", "poweroff")
525
check = self._make_checker(dev1)
526
self._alter_compare(guest.get_config_xml(), outfile)
528
def testAlterSounds(self):
529
infile = "tests/xmlparse-xml/change-sounds-in.xml"
530
outfile = "tests/xmlparse-xml/change-sounds-out.xml"
531
guest = virtinst.Guest(connection=conn,
532
parsexml=file(infile).read())
534
dev1 = guest.get_devices("sound")[0]
535
dev2 = guest.get_devices("sound")[1]
536
dev3 = guest.get_devices("sound")[2]
538
check = self._make_checker(dev1)
539
check("model", "sb16", "ac97")
541
check = self._make_checker(dev2)
542
check("model", "es1370", "es1370")
544
check = self._make_checker(dev3)
545
check("model", "ac97", "sb16")
547
self._alter_compare(guest.get_config_xml(), outfile)
549
def testConsoleCompat(self):
550
infile = "tests/xmlparse-xml/console-compat-in.xml"
551
outfile = "tests/xmlparse-xml/console-compat-out.xml"
552
guest = virtinst.Guest(connection=conn,
553
parsexml=file(infile).read())
555
dev1 = guest.get_devices("console")[0]
556
check = self._make_checker(dev1)
557
check("source_path", "/dev/pts/4")
559
self._alter_compare(guest.get_config_xml(), outfile)
561
def testAddRemoveDevices(self):
562
infile = "tests/xmlparse-xml/add-devices-in.xml"
563
outfile = "tests/xmlparse-xml/add-devices-out.xml"
564
guest = virtinst.Guest(connection=conn,
565
parsexml=file(infile).read())
567
rmdev = guest.get_devices("disk")[2]
568
guest.remove_device(rmdev)
570
adddev = virtinst.VirtualNetworkInterface(conn=conn, type="network",
572
macaddr="1A:2A:3A:4A:5A:6A")
573
guest.add_device(virtinst.VirtualWatchdog(conn))
574
guest.add_device(adddev)
576
guest.remove_device(adddev)
577
guest.add_device(adddev)
579
self._alter_compare(guest.get_config_xml(), outfile)
581
def testChangeKVMMedia(self):
582
infile = "tests/xmlparse-xml/change-media-in.xml"
583
outfile = "tests/xmlparse-xml/change-media-out.xml"
584
guest = virtinst.Guest(connection=kvmconn,
585
parsexml=file(infile).read())
587
disk = guest.get_devices("disk")[0]
588
check = self._make_checker(disk)
589
check("path", None, "/default-pool/default-vol")
591
disk = guest.get_devices("disk")[1]
592
check = self._make_checker(disk)
593
check("path", None, "/default-pool/default-vol")
594
check("path", "/default-pool/default-vol", "/disk-pool/diskvol1")
596
disk = guest.get_devices("disk")[2]
597
check = self._make_checker(disk)
598
check("path", None, "/disk-pool/diskvol1")
600
disk = guest.get_devices("disk")[3]
601
check = self._make_checker(disk)
602
check("path", None, "/default-pool/default-vol")
604
disk = guest.get_devices("disk")[4]
605
check = self._make_checker(disk)
606
check("path", None, "/disk-pool/diskvol1")
610
self._alter_compare(guest.get_config_xml(), outfile)
612
if __name__ == "__main__":