4 # Copyright (C) 2011, 2012 Google Inc.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 """Script for testing ganeti.ovf.
36 import xml.etree.ElementTree as ET
38 import elementtree.ElementTree as ET
40 from ganeti import constants
41 from ganeti import errors
42 from ganeti import ovf
43 from ganeti import utils
44 from ganeti import pathutils
52 "disk0_dump": "new_disk.raw",
54 "disk0_ivname": "disk/0",
58 "nic0_mode": "bridged",
60 "nic0_mac": "aa:00:00:d8:2c:1e",
61 "nic0_link": "xen-br0",
62 "nic0_network": "auto",
65 "hypervisor_name": "xen-pvm",
66 "root-path": "/dev/sda",
69 GANETI_OS = {"os_name": "lenny-image"}
73 "auto_balance": "False",
75 GANETI_NAME = "ganeti-test-xen"
76 GANETI_TEMPLATE = "plain"
82 "disk0_ivname": "disk/0",
83 "disk0_dump": "new_disk.raw",
85 "disk1_ivname": "disk/1",
86 "disk1_dump": "second_disk.raw",
89 VIRTUALBOX_NETWORKS = {
91 "nic0_mode": "bridged",
95 "nic0_network": "auto",
97 VIRTUALBOX_HYPERVISOR = {"hypervisor_name": "auto"}
98 VIRTUALBOX_OS = {"os_name": None}
99 VIRTUALBOX_BACKEND = {
102 "auto_balance": "auto",
104 VIRTUALBOX_NAME = None
105 VIRTUALBOX_TEMPLATE = None
106 VIRTUALBOX_TAGS = None
107 VIRTUALBOX_VERSION = None
111 EMPTY_HYPERVISOR = {"hypervisor_name": "auto"}
116 "auto_balance": "auto",
119 EMPTY_TEMPLATE = None
125 "disk0_ivname": "disk/0",
126 "disk0_dump": "disk0.raw",
131 "nic0_mode": "bridged",
135 "nic0_network": "auto",
137 CMDARGS_HYPERVISOR = {
138 "hypervisor_name": "xen-pvm"
140 CMDARGS_OS = {"os_name": "lenny-image"}
142 "auto_balance": False,
146 CMDARGS_NAME = "test-instance"
147 CMDARGS_TEMPLATE = "plain"
148 CMDARGS_TAGS = "test-tag-1,test-tag-2"
154 "name": "test-instance",
155 "ova_package": False,
157 "disk_format": "cow",
158 "compression": False,
160 ARGS_EXPORT_DIR = dict(ARGS_EMPTY, **{
161 "output_dir": OUTPUT_DIR,
167 "disk_template": None,
170 ARGS_VBOX = dict(ARGS_EXPORT_DIR, **{
171 "output_dir": OUTPUT_DIR,
172 "name": "test-instance",
174 "hypervisor": ("xen-pvm", {}),
178 ARGS_COMPLETE = dict(ARGS_VBOX, **{
179 "beparams": {"vcpus":"1", "memory":"256", "auto_balance": False},
180 "disks": [(0,{"size":"5mb"})],
181 "nics": [("0",{"mode":"bridged"})],
182 "disk_template": "plain",
183 "tags": "test-tag-1,test-tag-2",
185 ARGS_BROKEN = dict(ARGS_EXPORT_DIR , **{
187 "disk_template": "diskless",
188 "name": "test-instance",
193 EXP_ARGS_COMPRESSED = dict(ARGS_EXPORT_DIR, **{
200 "compression": "gzip",
203 "path": "new_disk.cow.gz",
209 "path": "new_disk.cow",
212 EXP_NETWORKS_LIST = [
213 {"mac": "aa:00:00:d8:2c:1e", "ip":"None", "link":"br0",
214 "mode":"routed", "network": "test"},
216 EXP_PARTIAL_GANETI_DICT = {
217 "hypervisor": {"name": "xen-kvm"},
218 "os": {"name": "lenny-image"},
219 "auto_balance": "True",
224 "auto_balance": "False",
226 "root-path": "/dev/sda",
231 "disk_template": None,
232 "os": {"name": "lenny-image"}
234 EXP_NAME ="xen-dev-i1"
238 EXPORT_EMPTY = ("<Envelope xml:lang=\"en-US\" xmlns=\"http://schemas.dmtf.org/"
239 "ovf/envelope/1\" xmlns:gnt=\"http://ganeti\" xmlns:ovf=\""
240 "http://schemas.dmtf.org/ovf/envelope/1\" xmlns:rasd=\""
241 "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_Resource"
242 "AllocationSettingData\" xmlns:vssd=\"http://schemas.dmtf.org"
243 "/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData\""
244 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" />")
245 EXPORT_DISKS_EMPTY = ("<References /><DiskSection><Info>Virtual disk"
246 " information</Info></DiskSection>")
247 EXPORT_DISKS = ("<References><File ovf:compression=\"gzip\" ovf:href=\"new_disk"
248 ".cow.gz\" ovf:id=\"file0\" ovf:size=\"203\" /><File ovf:href="
249 "\"new_disk.cow\" ovf:id=\"file1\" ovf:size=\"15\" />"
250 "</References><DiskSection><Info>Virtual disk information"
251 "</Info><Disk ovf:capacity=\"90000\" ovf:diskId=\"disk0\" ovf"
252 ":fileRef=\"file0\" ovf:format=\"http://www.vmware.com/"
253 "interfaces/specifications/vmdk.html#monolithicSparse\" /><Disk"
254 " ovf:capacity=\"15\" ovf:diskId=\"disk1\" ovf:fileRef"
255 "=\"file1\" ovf:format=\"http://www.gnome.org/~markmc/qcow"
256 "-image-format.html\" /></DiskSection>")
257 EXPORT_NETWORKS_EMPTY = ("<NetworkSection><Info>List of logical networks</Info>"
259 EXPORT_NETWORKS = ("<NetworkSection><Info>List of logical networks</Info>"
260 "<Network ovf:name=\"routed0\" /></NetworkSection>")
261 EXPORT_GANETI_INCOMPLETE = ("<gnt:GanetiSection><gnt:Version>0</gnt:Version>"
262 "<gnt:AutoBalance>True</gnt:AutoBalance><gnt:"
263 "OperatingSystem><gnt:Name>lenny-image</gnt:Name>"
264 "<gnt:Parameters /></gnt:OperatingSystem><gnt:"
265 "Hypervisor><gnt:Name>xen-kvm</gnt:Name><gnt:"
266 "Parameters /></gnt:Hypervisor><gnt:Network><gnt:"
267 "Nic ovf:name=\"routed0\"><gnt:Mode>routed</gnt:"
268 "Mode><gnt:MACAddress>aa:00:00:d8:2c:1e</gnt:"
269 "MACAddress><gnt:IPAddress>None</gnt:IPAddress>"
270 "<gnt:Link>br0</gnt:Link><gnt:Net>test</gnt:Net>"
271 "</gnt:Nic></gnt:Network></gnt:GanetiSection>")
272 EXPORT_GANETI = ("<gnt:GanetiSection><gnt:Version>0</gnt:Version><gnt:"
273 "AutoBalance>False</gnt:AutoBalance><gnt:OperatingSystem>"
274 "<gnt:Name>lenny-image</gnt:Name><gnt:Parameters /></gnt:"
275 "OperatingSystem><gnt:Hypervisor><gnt:Name>xen-pvm</gnt:Name>"
276 "<gnt:Parameters><gnt:root-path>/dev/sda</gnt:root-path><gnt:"
277 "kernel_args>ro</gnt:kernel_args></gnt:Parameters></gnt:"
278 "Hypervisor><gnt:Network><gnt:Nic ovf:name=\"routed0\"><gnt:"
279 "Mode>routed</gnt:Mode><gnt:MACAddress>aa:00:00:d8:2c:1e</gnt:"
280 "MACAddress><gnt:IPAddress>None</gnt:IPAddress><gnt:Link>br0"
281 "</gnt:Link><gnt:Net>test</gnt:Net></gnt:Nic></gnt:Network>"
282 "</gnt:GanetiSection>")
283 EXPORT_SYSTEM = ("<References><File ovf:compression=\"gzip\" ovf:href=\"new_"
284 "disk.cow.gz\" ovf:id=\"file0\" ovf:size=\"203\" /><File ovf:"
285 "href=\"new_disk.cow\" ovf:id=\"file1\" ovf:size=\"15\" />"
286 "</References><DiskSection><Info>Virtual disk information"
287 "</Info><Disk ovf:capacity=\"90000\" ovf:diskId=\"disk0\""
288 " ovf:fileRef=\"file0\" ovf:format=\"http://www.vmware.com"
289 "/interfaces/specifications/vmdk.html#monolithicSparse\" />"
290 "<Disk ovf:capacity=\"15\" ovf:diskId=\"disk1\" ovf:fileRef"
291 "=\"file1\" ovf:format=\"http://www.gnome.org/~markmc/qcow"
292 "-image-format.html\" /></DiskSection><NetworkSection><Info>"
293 "List of logical networks</Info><Network ovf:name=\"routed0\""
294 " /></NetworkSection><VirtualSystem ovf:id=\"xen-dev-i1\">"
295 "<Info>A virtual machine</Info><Name>xen-dev-i1</Name>"
296 "<OperatingSystemSection ovf:id=\"0\"><Info>Installed guest"
297 " operating system</Info></OperatingSystemSection><Virtual"
298 "HardwareSection><Info>Virtual hardware requirements</Info>"
299 "<System><vssd:ElementName>Virtual Hardware Family"
300 "</vssd:ElementName><vssd:InstanceID>0</vssd:InstanceID><vssd:"
301 "VirtualSystemIdentifier>xen-dev-i1</vssd:VirtualSystem"
302 "Identifier><vssd:VirtualSystemType>ganeti-ovf</vssd:Virtual"
303 "SystemType></System><Item><rasd:ElementName>1 virtual CPU(s)"
304 "</rasd:ElementName><rasd:InstanceID>1</rasd:InstanceID><rasd:"
305 "ResourceType>3</rasd:ResourceType><rasd:VirtualQuantity>1"
306 "</rasd:VirtualQuantity></Item><Item><rasd:AllocationUnits>"
307 "byte * 2^20</rasd:AllocationUnits><rasd:ElementName>512MB of"
308 " memory</rasd:ElementName><rasd:InstanceID>2</rasd:"
309 "InstanceID><rasd:ResourceType>4</rasd:ResourceType><rasd:"
310 "VirtualQuantity>512</rasd:VirtualQuantity></Item><Item>"
311 "<rasd:Address>0</rasd:Address><rasd:ElementName>scsi"
312 "_controller0</rasd:ElementName><rasd:InstanceID>3"
313 "</rasd:InstanceID><rasd:ResourceSubType>lsilogic</rasd"
314 ":ResourceSubType><rasd:ResourceType>6</rasd:ResourceType>"
315 "</Item><Item><rasd:ElementName>disk0</rasd:ElementName><rasd"
316 ":HostResource>ovf:/disk/disk0</rasd:HostResource><rasd"
317 ":InstanceID>4</rasd:InstanceID><rasd:Parent>3</rasd:Parent>"
318 "<rasd:ResourceType>17</rasd:ResourceType></Item><Item><rasd:"
319 "ElementName>disk1</rasd:ElementName><rasd:HostResource>ovf:/"
320 "disk/disk1</rasd:HostResource><rasd:InstanceID>5</rasd"
321 ":InstanceID><rasd:Parent>3</rasd:Parent><rasd:ResourceType>17"
322 "</rasd:ResourceType></Item><Item><rasd:Address>aa:00"
323 ":00:d8:2c:1e</rasd:Address><rasd:Connection>routed0</rasd"
324 ":Connection><rasd:ElementName>routed0</rasd:ElementName><rasd"
325 ":InstanceID>6</rasd:InstanceID><rasd:ResourceType>10</rasd"
326 ":ResourceType></Item></VirtualHardwareSection>"
330 def _GetArgs(args, with_name=False):
331 options = optparse.Values()
334 needed["name"] = "test-instance"
335 options._update_loose(needed)
339 OPTS_EMPTY = _GetArgs(ARGS_EMPTY)
340 OPTS_EXPORT_NO_NAME = _GetArgs(ARGS_EXPORT_DIR)
341 OPTS_EXPORT = _GetArgs(ARGS_EXPORT_DIR, with_name=True)
343 EXP_OPTS = OPTS_EXPORT_NO_NAME
344 EXP_OPTS_COMPRESSED = _GetArgs(EXP_ARGS_COMPRESSED)
346 OPTS_VBOX = _GetArgs(ARGS_VBOX)
347 OPTS_COMPLETE = _GetArgs(ARGS_COMPLETE)
348 OPTS_NONIC_NODISK = _GetArgs(ARGS_BROKEN)
351 def _GetFullFilename(file_name):
352 file_path = "%s/test/data/ovfdata/%s" % (testutils.GetSourceDir(),
354 file_path = os.path.abspath(file_path)
358 class BetterUnitTest(unittest.TestCase):
359 def assertRaisesRegexp(self, exception, regexp_val, function, *args):
362 self.fail("Expected raising %s" % exception)
363 except exception, err:
364 regexp = re.compile(regexp_val)
365 if re.search(regexp, str(err)) == None:
366 self.fail("Expected matching '%s', got '%s'" %
367 (regexp_val, str(err)))
370 class TestOVFImporter(BetterUnitTest):
372 self.non_existing_file = _GetFullFilename("not_the_file.ovf")
373 self.ganeti_ovf = _GetFullFilename("ganeti.ovf")
374 self.virtualbox_ovf = _GetFullFilename("virtualbox.ovf")
375 self.ova_package = _GetFullFilename("ova.ova")
376 self.empty_ovf = _GetFullFilename("empty.ovf")
377 self.wrong_extension = _GetFullFilename("wrong_extension.ovd")
378 self.wrong_ova_archive = _GetFullFilename("wrong_ova.ova")
379 self.no_ovf_in_ova = _GetFullFilename("no_ovf.ova")
384 self.importer.Cleanup()
385 del_dir = os.path.abspath(OUTPUT_DIR)
387 shutil.rmtree(del_dir)
391 def testFileDoesNotExistError(self):
392 self.assertRaisesRegexp(errors.OpPrereqError, "does not exist",
393 ovf.OVFImporter, self.non_existing_file, None)
395 def testWrongInputFileExtensionError(self):
396 self.assertRaisesRegexp(errors.OpPrereqError,
397 "Unknown file extension", ovf.OVFImporter,
398 self.wrong_extension, None)
400 def testOVAUnpackingDirectories(self):
401 self.importer = ovf.OVFImporter(self.ova_package, OPTS_EMPTY)
402 self.assertTrue(self.importer.input_dir != None)
403 self.assertEquals(self.importer.output_dir , pathutils.EXPORT_DIR)
404 self.assertTrue(self.importer.temp_dir != None)
406 def testOVFUnpackingDirectories(self):
407 self.importer = ovf.OVFImporter(self.virtualbox_ovf,
409 self.assertEquals(self.importer.input_dir , _GetFullFilename(""))
410 self.assertEquals(self.importer.output_dir , pathutils.EXPORT_DIR)
411 self.assertEquals(self.importer.temp_dir , None)
413 def testOVFSetOutputDirDirectories(self):
414 self.importer = ovf.OVFImporter(self.ganeti_ovf, OPTS_EXPORT)
415 self.assertEquals(self.importer.input_dir , _GetFullFilename(""))
416 self.assertTrue(OUTPUT_DIR in self.importer.output_dir)
417 self.assertEquals(self.importer.temp_dir , None)
419 def testWrongOVAArchiveError(self):
420 self.assertRaisesRegexp(errors.OpPrereqError, "not a proper tar",
421 ovf.OVFImporter, self.wrong_ova_archive, None)
423 def testNoOVFFileInOVAPackageError(self):
424 self.assertRaisesRegexp(errors.OpPrereqError, "No .ovf file",
425 ovf.OVFImporter, self.no_ovf_in_ova, None)
427 def testParseGanetiOvf(self):
428 self.importer = ovf.OVFImporter(self.ganeti_ovf, OPTS_EXPORT_NO_NAME)
429 self.importer.Parse()
430 self.assertTrue("%s/ganeti-test-xen" % OUTPUT_DIR in
431 self.importer.output_dir)
432 self.assertEqual(self.importer.results_disk, GANETI_DISKS)
433 self.assertEqual(self.importer.results_network, GANETI_NETWORKS)
434 self.assertEqual(self.importer.results_hypervisor, GANETI_HYPERVISOR)
435 self.assertEqual(self.importer.results_os, GANETI_OS)
436 self.assertEqual(self.importer.results_backend, GANETI_BACKEND)
437 self.assertEqual(self.importer.results_name, GANETI_NAME)
438 self.assertEqual(self.importer.results_template, GANETI_TEMPLATE)
439 self.assertEqual(self.importer.results_tags, GANETI_TAGS)
440 self.assertEqual(self.importer.results_version, GANETI_VERSION)
442 def testParseVirtualboxOvf(self):
443 self.importer = ovf.OVFImporter(self.virtualbox_ovf, OPTS_VBOX)
444 self.importer.Parse()
445 self.assertTrue("%s/test-instance" % OUTPUT_DIR in self.importer.output_dir)
446 self.assertEquals(self.importer.results_disk, VIRTUALBOX_DISKS)
447 self.assertEquals(self.importer.results_network, VIRTUALBOX_NETWORKS)
448 self.assertEquals(self.importer.results_hypervisor, CMDARGS_HYPERVISOR)
449 self.assertEquals(self.importer.results_os, CMDARGS_OS)
450 self.assertEquals(self.importer.results_backend, VIRTUALBOX_BACKEND)
451 self.assertEquals(self.importer.results_name, CMDARGS_NAME)
452 self.assertEquals(self.importer.results_template, VIRTUALBOX_TEMPLATE)
453 self.assertEqual(self.importer.results_tags, VIRTUALBOX_TAGS)
454 self.assertEqual(self.importer.results_version, constants.EXPORT_VERSION)
456 def testParseEmptyOvf(self):
457 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
458 self.importer.Parse()
459 self.assertTrue("%s/test-instance" % OUTPUT_DIR in self.importer.output_dir)
460 self.assertEquals(self.importer.results_disk, CMDARGS_DISKS)
461 self.assertEquals(self.importer.results_network, CMDARGS_NETWORKS)
462 self.assertEquals(self.importer.results_hypervisor, CMDARGS_HYPERVISOR)
463 self.assertEquals(self.importer.results_os, CMDARGS_OS)
464 self.assertEquals(self.importer.results_backend, CMDARGS_BACKEND)
465 self.assertEquals(self.importer.results_name, CMDARGS_NAME)
466 self.assertEquals(self.importer.results_template, CMDARGS_TEMPLATE)
467 self.assertEqual(self.importer.results_tags, CMDARGS_TAGS)
468 self.assertEqual(self.importer.results_version, constants.EXPORT_VERSION)
470 def testParseNameOptions(self):
471 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
472 results = self.importer._ParseNameOptions()
473 self.assertEquals(results, CMDARGS_NAME)
475 def testParseHypervisorOptions(self):
476 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
477 results = self.importer._ParseHypervisorOptions()
478 self.assertEquals(results, CMDARGS_HYPERVISOR)
480 def testParseOSOptions(self):
481 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
482 results = self.importer._ParseOSOptions()
483 self.assertEquals(results, CMDARGS_OS)
485 def testParseBackendOptions(self):
486 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
487 results = self.importer._ParseBackendOptions()
488 self.assertEquals(results, CMDARGS_BACKEND)
490 def testParseTags(self):
491 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
492 results = self.importer._ParseTags()
493 self.assertEquals(results, CMDARGS_TAGS)
495 def testParseNicOptions(self):
496 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
497 results = self.importer._ParseNicOptions()
498 self.assertEquals(results, CMDARGS_NETWORKS)
500 def testParseDiskOptionsFromGanetiOVF(self):
501 self.importer = ovf.OVFImporter(self.ganeti_ovf, OPTS_EXPORT)
503 results = self.importer._GetDiskInfo()
504 self.assertEquals(results, GANETI_DISKS)
506 def testParseTemplateOptions(self):
507 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
508 results = self.importer._ParseTemplateOptions()
509 self.assertEquals(results, GANETI_TEMPLATE)
511 def testParseDiskOptionsFromCmdLine(self):
512 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
514 results = self.importer._ParseDiskOptions()
515 self.assertEquals(results, CMDARGS_DISKS)
517 def testGetDiskFormat(self):
518 self.importer = ovf.OVFImporter(self.ganeti_ovf, OPTS_EXPORT)
519 disks_list = self.importer.ovf_reader.GetDisksNames()
520 results = [self.importer._GetDiskQemuInfo("%s/%s" %
521 (self.importer.input_dir, path), "file format: (\S+)")
522 for (path, _) in disks_list]
523 self.assertEqual(results, ["vmdk"])
525 def testNoInstanceNameOVF(self):
526 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_EXPORT_NO_NAME)
527 self.assertRaisesRegexp(errors.OpPrereqError, "Name of instance",
530 def testErrorNoOSNameOVF(self):
531 self.importer = ovf.OVFImporter(self.virtualbox_ovf, OPTS_EXPORT)
532 self.assertRaisesRegexp(errors.OpPrereqError, "OS name",
535 def testErrorNoDiskAndNoNetwork(self):
536 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_NONIC_NODISK)
537 self.assertRaisesRegexp(errors.OpPrereqError,
538 "Either disk specification or network"
539 " description", self.importer.Parse)
542 class TestOVFExporter(BetterUnitTest):
545 self.wrong_config_file = _GetFullFilename("wrong_config.ini")
546 self.unsafe_path_to_disk = _GetFullFilename("unsafe_path.ini")
547 self.disk_image_not_exist = _GetFullFilename("no_disk.ini")
548 self.empty_config = _GetFullFilename("empty.ini")
549 self.standard_export = _GetFullFilename("config.ini")
550 self.wrong_network_mode = self.disk_image_not_exist
551 self.no_memory = self.disk_image_not_exist
552 self.no_vcpus = self.disk_image_not_exist
553 self.no_os = _GetFullFilename("no_os.ini")
554 self.no_hypervisor = self.disk_image_not_exist
558 self.exporter.Cleanup()
559 del_dir = os.path.abspath(OUTPUT_DIR)
561 shutil.rmtree(del_dir)
565 def testErrorWrongConfigFile(self):
566 self.assertRaisesRegexp(errors.OpPrereqError,
567 "Error when trying to read", ovf.OVFExporter,
568 self.wrong_config_file, EXP_OPTS)
570 def testErrorPathToTheDiskIncorrect(self):
571 self.exporter = ovf.OVFExporter(self.unsafe_path_to_disk, EXP_OPTS)
572 self.assertRaisesRegexp(errors.OpPrereqError, "contains a directory name",
573 self.exporter._ParseDisks)
575 def testErrorDiskImageNotExist(self):
576 self.exporter = ovf.OVFExporter(self.disk_image_not_exist, EXP_OPTS)
577 self.assertRaisesRegexp(errors.OpPrereqError, "Disk image does not exist",
578 self.exporter._ParseDisks)
580 def testParseNetworks(self):
581 self.exporter = ovf.OVFExporter(self.standard_export, EXP_OPTS)
582 results = self.exporter._ParseNetworks()
583 self.assertEqual(results, EXP_NETWORKS_LIST)
585 def testErrorWrongNetworkMode(self):
586 self.exporter = ovf.OVFExporter(self.wrong_network_mode, EXP_OPTS)
587 self.assertRaisesRegexp(errors.OpPrereqError,
588 "Network mode nic not recognized", self.exporter._ParseNetworks)
590 def testParseVCPusMem(self):
591 self.exporter = ovf.OVFExporter(self.standard_export, EXP_OPTS)
592 vcpus = self.exporter._ParseVCPUs()
593 memory = self.exporter._ParseMemory()
594 self.assertEqual(vcpus, EXP_VCPUS)
595 self.assertEqual(memory, EXP_MEMORY)
597 def testErrorNoVCPUs(self):
598 self.exporter = ovf.OVFExporter(self.no_vcpus, EXP_OPTS)
599 self.assertRaisesRegexp(errors.OpPrereqError, "No CPU information found",
600 self.exporter._ParseVCPUs)
602 def testErrorNoMemory(self):
603 self.exporter = ovf.OVFExporter(self.no_memory, EXP_OPTS)
604 self.assertRaisesRegexp(errors.OpPrereqError, "No memory information found",
605 self.exporter._ParseMemory)
607 def testParseGaneti(self):
608 self.exporter = ovf.OVFExporter(self.standard_export, EXP_OPTS)
609 results = self.exporter._ParseGaneti()
610 self.assertEqual(results, EXP_GANETI_DICT)
612 def testErrorNoHypervisor(self):
613 self.exporter = ovf.OVFExporter(self.no_hypervisor, EXP_OPTS)
614 self.assertRaisesRegexp(errors.OpPrereqError,
615 "No hypervisor information found", self.exporter._ParseGaneti)
617 def testErrorNoOS(self):
618 self.exporter = ovf.OVFExporter(self.no_os, EXP_OPTS)
619 self.assertRaisesRegexp(errors.OpPrereqError,
620 "No operating system information found", self.exporter._ParseGaneti)
622 def testErrorParseNoInstanceName(self):
623 self.exporter = ovf.OVFExporter(self.empty_config, EXP_OPTS)
624 self.assertRaisesRegexp(errors.OpPrereqError, "No instance name found",
628 class TestOVFReader(BetterUnitTest):
630 self.wrong_xml_file = _GetFullFilename("wrong_xml.ovf")
631 self.ganeti_ovf = _GetFullFilename("ganeti.ovf")
632 self.virtualbox_ovf = _GetFullFilename("virtualbox.ovf")
633 self.corrupted_ovf = _GetFullFilename("corrupted_resources.ovf")
634 self.wrong_manifest_ovf = _GetFullFilename("wrong_manifest.ovf")
635 self.no_disk_in_ref_ovf = _GetFullFilename("no_disk_in_ref.ovf")
636 self.empty_ovf = _GetFullFilename("empty.ovf")
637 self.compressed_disk = _GetFullFilename("gzip_disk.ovf")
642 def testXMLParsingError(self):
643 self.assertRaisesRegexp(errors.OpPrereqError,
644 "Error while reading .ovf", ovf.OVFReader, self.wrong_xml_file)
646 def testFileInResourcesDoesNotExistError(self):
647 self.assertRaisesRegexp(errors.OpPrereqError, "does not exist",
648 ovf.OVFReader, self.corrupted_ovf)
650 def testWrongManifestChecksumError(self):
651 reader = ovf.OVFReader(self.wrong_manifest_ovf)
652 self.assertRaisesRegexp(errors.OpPrereqError,
653 "does not match the value in manifest file", reader.VerifyManifest)
655 def testGoodManifestChecksum(self):
656 reader = ovf.OVFReader(self.ganeti_ovf)
657 self.assertEqual(reader.VerifyManifest(), None)
659 def testGetDisksNamesOVFCorruptedError(self):
660 reader = ovf.OVFReader(self.no_disk_in_ref_ovf)
661 self.assertRaisesRegexp(errors.OpPrereqError,
662 "not found in references", reader.GetDisksNames)
664 def testGetDisksNamesVirtualbox(self):
665 reader = ovf.OVFReader(self.virtualbox_ovf)
666 disk_names = reader.GetDisksNames()
668 ("new_disk.vmdk", None) ,
669 ("second_disk.vmdk", None),
671 self.assertEqual(sorted(disk_names), sorted(expected_names))
673 def testGetDisksNamesEmpty(self):
674 reader = ovf.OVFReader(self.empty_ovf)
675 disk_names = reader.GetDisksNames()
676 self.assertEqual(disk_names, [])
678 def testGetDisksNamesCompressed(self):
679 reader = ovf.OVFReader(self.compressed_disk)
680 disk_names = reader.GetDisksNames()
681 self.assertEqual(disk_names, [("compr_disk.vmdk.gz", "gzip")])
683 def testGetNetworkDataGaneti(self):
684 reader = ovf.OVFReader(self.ganeti_ovf)
685 networks = reader.GetNetworkData()
686 self.assertEqual(networks, GANETI_NETWORKS)
688 def testGetNetworkDataVirtualbox(self):
689 reader = ovf.OVFReader(self.virtualbox_ovf)
690 networks = reader.GetNetworkData()
691 self.assertEqual(networks, VIRTUALBOX_NETWORKS)
693 def testGetNetworkDataEmpty(self):
694 reader = ovf.OVFReader(self.empty_ovf)
695 networks = reader.GetNetworkData()
696 self.assertEqual(networks, EMPTY_NETWORKS)
698 def testGetHypervisorDataGaneti(self):
699 reader = ovf.OVFReader(self.ganeti_ovf)
700 hypervisor = reader.GetHypervisorData()
701 self.assertEqual(hypervisor, GANETI_HYPERVISOR)
703 def testGetHypervisorDataEmptyOvf(self):
704 reader = ovf.OVFReader(self.empty_ovf)
705 hypervisor = reader.GetHypervisorData()
706 self.assertEqual(hypervisor, EMPTY_HYPERVISOR)
708 def testGetOSDataGaneti(self):
709 reader = ovf.OVFReader(self.ganeti_ovf)
710 osys = reader.GetOSData()
711 self.assertEqual(osys, GANETI_OS)
713 def testGetOSDataEmptyOvf(self):
714 reader = ovf.OVFReader(self.empty_ovf)
715 osys = reader.GetOSData()
716 self.assertEqual(osys, EMPTY_OS)
718 def testGetBackendDataGaneti(self):
719 reader = ovf.OVFReader(self.ganeti_ovf)
720 backend = reader.GetBackendData()
721 self.assertEqual(backend, GANETI_BACKEND)
723 def testGetBackendDataVirtualbox(self):
724 reader = ovf.OVFReader(self.virtualbox_ovf)
725 backend = reader.GetBackendData()
726 self.assertEqual(backend, VIRTUALBOX_BACKEND)
728 def testGetBackendDataEmptyOvf(self):
729 reader = ovf.OVFReader(self.empty_ovf)
730 backend = reader.GetBackendData()
731 self.assertEqual(backend, EMPTY_BACKEND)
733 def testGetInstanceNameGaneti(self):
734 reader = ovf.OVFReader(self.ganeti_ovf)
735 name = reader.GetInstanceName()
736 self.assertEqual(name, GANETI_NAME)
738 def testGetInstanceNameDataEmptyOvf(self):
739 reader = ovf.OVFReader(self.empty_ovf)
740 name = reader.GetInstanceName()
741 self.assertEqual(name, EMPTY_NAME)
743 def testGetDiskTemplateGaneti(self):
744 reader = ovf.OVFReader(self.ganeti_ovf)
745 name = reader.GetDiskTemplate()
746 self.assertEqual(name, GANETI_TEMPLATE)
748 def testGetDiskTemplateEmpty(self):
749 reader = ovf.OVFReader(self.empty_ovf)
750 name = reader.GetDiskTemplate()
751 self.assertEqual(name, EMPTY_TEMPLATE)
753 def testGetTagsGaneti(self):
754 reader = ovf.OVFReader(self.ganeti_ovf)
755 tags = reader.GetTagsData()
756 self.assertEqual(tags, GANETI_TAGS)
758 def testGetTagsEmpty(self):
759 reader = ovf.OVFReader(self.empty_ovf)
760 tags = reader.GetTagsData()
761 self.assertEqual(tags, EMPTY_TAGS)
763 def testGetVersionGaneti(self):
764 reader = ovf.OVFReader(self.ganeti_ovf)
765 version = reader.GetVersionData()
766 self.assertEqual(version, GANETI_VERSION)
768 def testGetVersionEmpty(self):
769 reader = ovf.OVFReader(self.empty_ovf)
770 version = reader.GetVersionData()
771 self.assertEqual(version, EMPTY_VERSION)
774 class TestOVFWriter(BetterUnitTest):
776 self.writer = ovf.OVFWriter(True)
781 def testOVFWriterInit(self):
782 result = ET.tostring(self.writer.tree)
783 self.assertTrue(EXPORT_EMPTY in result)
785 def testSaveDisksDataEmpty(self):
786 self.writer.SaveDisksData([])
787 result = ET.tostring(self.writer.tree)
788 self.assertTrue(EXPORT_DISKS_EMPTY in result)
790 def testSaveDisksData(self):
791 self.writer.SaveDisksData(EXP_DISKS_LIST)
792 result = ET.tostring(self.writer.tree)
793 self.assertTrue(EXPORT_DISKS in result)
795 def testSaveNetworkDataEmpty(self):
796 self.writer.SaveNetworksData([])
797 result = ET.tostring(self.writer.tree)
798 self.assertTrue(EXPORT_NETWORKS_EMPTY in result)
800 def testSaveNetworksData(self):
801 self.writer.SaveNetworksData(EXP_NETWORKS_LIST)
802 result = ET.tostring(self.writer.tree)
803 self.assertTrue(EXPORT_NETWORKS in result)
805 def testSaveGanetiDataIncomplete(self):
806 self.writer.SaveGanetiData(EXP_PARTIAL_GANETI_DICT, EXP_NETWORKS_LIST)
807 result = ET.tostring(self.writer.tree)
808 self.assertTrue(EXPORT_GANETI_INCOMPLETE in result)
810 def testSaveGanetiDataComplete(self):
811 self.writer.SaveGanetiData(EXP_GANETI_DICT, EXP_NETWORKS_LIST)
812 result = ET.tostring(self.writer.tree)
813 self.assertTrue(EXPORT_GANETI in result)
815 def testSaveVirtualSystem(self):
816 self.writer.SaveDisksData(EXP_DISKS_LIST)
817 self.writer.SaveNetworksData(EXP_NETWORKS_LIST)
818 self.writer.SaveVirtualSystemData(EXP_NAME, EXP_VCPUS, EXP_MEMORY)
819 result = ET.tostring(self.writer.tree)
820 self.assertTrue(EXPORT_SYSTEM in result)
823 if __name__ == "__main__":
824 testutils.GanetiTestProgram()