4 # Copyright (C) 2011 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",
64 "hypervisor_name": "xen-pvm",
65 "root-path": "/dev/sda",
68 GANETI_OS = {"os_name": "lenny-image"}
72 "auto_balance": "False",
74 GANETI_NAME = "ganeti-test-xen"
75 GANETI_TEMPLATE = "plain"
81 "disk0_ivname": "disk/0",
82 "disk0_dump": "new_disk.raw",
84 "disk1_ivname": "disk/1",
85 "disk1_dump": "second_disk.raw",
88 VIRTUALBOX_NETWORKS = {
90 "nic0_mode": "bridged",
95 VIRTUALBOX_HYPERVISOR = {"hypervisor_name": "auto"}
96 VIRTUALBOX_OS = {"os_name": None}
97 VIRTUALBOX_BACKEND = {
100 "auto_balance": "auto",
102 VIRTUALBOX_NAME = None
103 VIRTUALBOX_TEMPLATE = None
104 VIRTUALBOX_TAGS = None
105 VIRTUALBOX_VERSION = None
109 EMPTY_HYPERVISOR = {"hypervisor_name": "auto"}
114 "auto_balance": "auto",
117 EMPTY_TEMPLATE = None
123 "disk0_ivname": "disk/0",
124 "disk0_dump": "disk0.raw",
129 "nic0_mode": "bridged",
134 CMDARGS_HYPERVISOR = {
135 "hypervisor_name": "xen-pvm"
137 CMDARGS_OS = {"os_name": "lenny-image"}
139 "auto_balance": False,
143 CMDARGS_NAME = "test-instance"
144 CMDARGS_TEMPLATE = "plain"
145 CMDARGS_TAGS = "test-tag-1,test-tag-2"
151 "name": "test-instance",
152 "ova_package": False,
154 "disk_format": "cow",
155 "compression": False,
157 ARGS_EXPORT_DIR = dict(ARGS_EMPTY, **{
158 "output_dir": OUTPUT_DIR,
164 "disk_template": None,
167 ARGS_VBOX = dict(ARGS_EXPORT_DIR, **{
168 "output_dir": OUTPUT_DIR,
169 "name": "test-instance",
171 "hypervisor": ("xen-pvm", {}),
175 ARGS_COMPLETE = dict(ARGS_VBOX, **{
176 "beparams": {"vcpus":"1", "memory":"256", "auto_balance": False},
177 "disks": [(0,{"size":"5mb"})],
178 "nics": [("0",{"mode":"bridged"})],
179 "disk_template": "plain",
180 "tags": "test-tag-1,test-tag-2",
182 ARGS_BROKEN = dict(ARGS_EXPORT_DIR , **{
184 "disk_template": "diskless",
185 "name": "test-instance",
190 EXP_ARGS_COMPRESSED = dict(ARGS_EXPORT_DIR, **{
197 "compression": "gzip",
200 "path": "new_disk.cow.gz",
206 "path": "new_disk.cow",
209 EXP_NETWORKS_LIST = [
210 {"mac": "aa:00:00:d8:2c:1e", "ip":"None", "link":"br0","mode":"routed"},
212 EXP_PARTIAL_GANETI_DICT = {
213 "hypervisor": {"name": "xen-kvm"},
214 "os": {"name": "lenny-image"},
215 "auto_balance": "True",
220 'auto_balance': 'False',
222 'root-path': '/dev/sda',
227 'disk_template': None,
228 'os': {'name': 'lenny-image'}
230 EXP_NAME ="xen-dev-i1"
234 EXPORT_EMPTY = ("<Envelope xml:lang=\"en-US\" xmlns=\"http://schemas.dmtf.org/"
235 "ovf/envelope/1\" xmlns:gnt=\"http://ganeti\" xmlns:ovf=\""
236 "http://schemas.dmtf.org/ovf/envelope/1\" xmlns:rasd=\""
237 "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_Resource"
238 "AllocationSettingData\" xmlns:vssd=\"http://schemas.dmtf.org"
239 "/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData\""
240 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" />")
241 EXPORT_DISKS_EMPTY = ("<References /><DiskSection><Info>Virtual disk"
242 " information</Info></DiskSection>")
243 EXPORT_DISKS = ("<References><File ovf:compression=\"gzip\" ovf:href=\"new_disk"
244 ".cow.gz\" ovf:id=\"file0\" ovf:size=\"203\" /><File ovf:href="
245 "\"new_disk.cow\" ovf:id=\"file1\" ovf:size=\"15\" />"
246 "</References><DiskSection><Info>Virtual disk information"
247 "</Info><Disk ovf:capacity=\"90000\" ovf:diskId=\"disk0\" ovf"
248 ":fileRef=\"file0\" ovf:format=\"http://www.vmware.com/"
249 "interfaces/specifications/vmdk.html#monolithicSparse\" /><Disk"
250 " ovf:capacity=\"15\" ovf:diskId=\"disk1\" ovf:fileRef"
251 "=\"file1\" ovf:format=\"http://www.gnome.org/~markmc/qcow"
252 "-image-format.html\" /></DiskSection>")
253 EXPORT_NETWORKS_EMPTY = ("<NetworkSection><Info>List of logical networks</Info>"
255 EXPORT_NETWORKS = ("<NetworkSection><Info>List of logical networks</Info>"
256 "<Network ovf:name=\"routed0\" /></NetworkSection>")
257 EXPORT_GANETI_INCOMPLETE = ("<gnt:GanetiSection><gnt:Version>0</gnt:Version>"
258 "<gnt:AutoBalance>True</gnt:AutoBalance><gnt:"
259 "OperatingSystem><gnt:Name>lenny-image</gnt:Name>"
260 "<gnt:Parameters /></gnt:OperatingSystem><gnt:"
261 "Hypervisor><gnt:Name>xen-kvm</gnt:Name><gnt:"
262 "Parameters /></gnt:Hypervisor><gnt:Network><gnt:"
263 "Nic ovf:name=\"routed0\"><gnt:Mode>routed</gnt:"
264 "Mode><gnt:MACAddress>aa:00:00:d8:2c:1e</gnt:"
265 "MACAddress><gnt:IPAddress>None</gnt:IPAddress>"
266 "<gnt:Link>br0</gnt:Link></gnt:Nic></gnt:Network>"
267 "</gnt:GanetiSection>")
268 EXPORT_GANETI = ("<gnt:GanetiSection><gnt:Version>0</gnt:Version><gnt:"
269 "AutoBalance>False</gnt:AutoBalance><gnt:OperatingSystem>"
270 "<gnt:Name>lenny-image</gnt:Name><gnt:Parameters /></gnt:"
271 "OperatingSystem><gnt:Hypervisor><gnt:Name>xen-pvm</gnt:Name>"
272 "<gnt:Parameters><gnt:root-path>/dev/sda</gnt:root-path><gnt:"
273 "kernel_args>ro</gnt:kernel_args></gnt:Parameters></gnt:"
274 "Hypervisor><gnt:Network><gnt:Nic ovf:name=\"routed0\"><gnt:"
275 "Mode>routed</gnt:Mode><gnt:MACAddress>aa:00:00:d8:2c:1e</gnt:"
276 "MACAddress><gnt:IPAddress>None</gnt:IPAddress><gnt:Link>br0"
277 "</gnt:Link></gnt:Nic></gnt:Network></gnt:GanetiSection>")
278 EXPORT_SYSTEM = ("<References><File ovf:compression=\"gzip\" ovf:href=\"new_"
279 "disk.cow.gz\" ovf:id=\"file0\" ovf:size=\"203\" /><File ovf:"
280 "href=\"new_disk.cow\" ovf:id=\"file1\" ovf:size=\"15\" />"
281 "</References><DiskSection><Info>Virtual disk information"
282 "</Info><Disk ovf:capacity=\"90000\" ovf:diskId=\"disk0\""
283 " ovf:fileRef=\"file0\" ovf:format=\"http://www.vmware.com"
284 "/interfaces/specifications/vmdk.html#monolithicSparse\" />"
285 "<Disk ovf:capacity=\"15\" ovf:diskId=\"disk1\" ovf:fileRef"
286 "=\"file1\" ovf:format=\"http://www.gnome.org/~markmc/qcow"
287 "-image-format.html\" /></DiskSection><NetworkSection><Info>"
288 "List of logical networks</Info><Network ovf:name=\"routed0\""
289 " /></NetworkSection><VirtualSystem ovf:id=\"xen-dev-i1\">"
290 "<Info>A virtual machine</Info><Name>xen-dev-i1</Name>"
291 "<OperatingSystemSection ovf:id=\"0\"><Info>Installed guest"
292 " operating system</Info></OperatingSystemSection><Virtual"
293 "HardwareSection><Info>Virtual hardware requirements</Info>"
294 "<System><vssd:ElementName>Virtual Hardware Family"
295 "</vssd:ElementName><vssd:InstanceID>0</vssd:InstanceID><vssd:"
296 "VirtualSystemIdentifier>xen-dev-i1</vssd:VirtualSystem"
297 "Identifier><vssd:VirtualSystemType>ganeti-ovf</vssd:Virtual"
298 "SystemType></System><Item><rasd:ElementName>1 virtual CPU(s)"
299 "</rasd:ElementName><rasd:InstanceID>1</rasd:InstanceID><rasd:"
300 "ResourceType>3</rasd:ResourceType><rasd:VirtualQuantity>1"
301 "</rasd:VirtualQuantity></Item><Item><rasd:AllocationUnits>"
302 "byte * 2^20</rasd:AllocationUnits><rasd:ElementName>512MB of"
303 " memory</rasd:ElementName><rasd:InstanceID>2</rasd:"
304 "InstanceID><rasd:ResourceType>4</rasd:ResourceType><rasd:"
305 "VirtualQuantity>512</rasd:VirtualQuantity></Item><Item>"
306 "<rasd:Address>0</rasd:Address><rasd:ElementName>scsi"
307 "_controller0</rasd:ElementName><rasd:InstanceID>3"
308 "</rasd:InstanceID><rasd:ResourceSubType>lsilogic</rasd"
309 ":ResourceSubType><rasd:ResourceType>6</rasd:ResourceType>"
310 "</Item><Item><rasd:ElementName>disk0</rasd:ElementName><rasd"
311 ":HostResource>ovf:/disk/disk0</rasd:HostResource><rasd"
312 ":InstanceID>4</rasd:InstanceID><rasd:Parent>3</rasd:Parent>"
313 "<rasd:ResourceType>17</rasd:ResourceType></Item><Item><rasd:"
314 "ElementName>disk1</rasd:ElementName><rasd:HostResource>ovf:/"
315 "disk/disk1</rasd:HostResource><rasd:InstanceID>5</rasd"
316 ":InstanceID><rasd:Parent>3</rasd:Parent><rasd:ResourceType>17"
317 "</rasd:ResourceType></Item><Item><rasd:Address>aa:00"
318 ":00:d8:2c:1e</rasd:Address><rasd:Connection>routed0</rasd"
319 ":Connection><rasd:ElementName>routed0</rasd:ElementName><rasd"
320 ":InstanceID>6</rasd:InstanceID><rasd:ResourceType>10</rasd"
321 ":ResourceType></Item></VirtualHardwareSection>"
325 def _GetArgs(args, with_name=False):
326 options = optparse.Values()
329 needed["name"] = "test-instance"
330 options._update_loose(needed)
334 OPTS_EMPTY = _GetArgs(ARGS_EMPTY)
335 OPTS_EXPORT_NO_NAME = _GetArgs(ARGS_EXPORT_DIR)
336 OPTS_EXPORT = _GetArgs(ARGS_EXPORT_DIR, with_name=True)
338 EXP_OPTS = OPTS_EXPORT_NO_NAME
339 EXP_OPTS_COMPRESSED = _GetArgs(EXP_ARGS_COMPRESSED)
341 OPTS_VBOX = _GetArgs(ARGS_VBOX)
342 OPTS_COMPLETE = _GetArgs(ARGS_COMPLETE)
343 OPTS_NONIC_NODISK = _GetArgs(ARGS_BROKEN)
346 def _GetFullFilename(file_name):
347 file_path = "%s/test/data/ovfdata/%s" % (testutils.GetSourceDir(),
349 file_path = os.path.abspath(file_path)
353 class BetterUnitTest(unittest.TestCase):
354 def assertRaisesRegexp(self, exception, regexp_val, function, *args):
357 self.fail("Expected raising %s" % exception)
358 except exception, err:
359 regexp = re.compile(regexp_val)
360 if re.search(regexp, str(err)) == None:
361 self.fail("Expected matching '%s', got '%s'" %
362 (regexp_val, str(err)))
365 class TestOVFImporter(BetterUnitTest):
367 self.non_existing_file = _GetFullFilename("not_the_file.ovf")
368 self.ganeti_ovf = _GetFullFilename("ganeti.ovf")
369 self.virtualbox_ovf = _GetFullFilename("virtualbox.ovf")
370 self.ova_package = _GetFullFilename("ova.ova")
371 self.empty_ovf = _GetFullFilename("empty.ovf")
372 self.wrong_extension = _GetFullFilename("wrong_extension.ovd")
373 self.wrong_ova_archive = _GetFullFilename("wrong_ova.ova")
374 self.no_ovf_in_ova = _GetFullFilename("no_ovf.ova")
379 self.importer.Cleanup()
380 del_dir = os.path.abspath(OUTPUT_DIR)
382 shutil.rmtree(del_dir)
386 def testFileDoesNotExistError(self):
387 self.assertRaisesRegexp(errors.OpPrereqError, "does not exist",
388 ovf.OVFImporter, self.non_existing_file, None)
390 def testWrongInputFileExtensionError(self):
391 self.assertRaisesRegexp(errors.OpPrereqError,
392 "Unknown file extension", ovf.OVFImporter,
393 self.wrong_extension, None)
395 def testOVAUnpackingDirectories(self):
396 self.importer = ovf.OVFImporter(self.ova_package, OPTS_EMPTY)
397 self.assertTrue(self.importer.input_dir != None)
398 self.assertEquals(self.importer.output_dir , pathutils.EXPORT_DIR)
399 self.assertTrue(self.importer.temp_dir != None)
401 def testOVFUnpackingDirectories(self):
402 self.importer = ovf.OVFImporter(self.virtualbox_ovf,
404 self.assertEquals(self.importer.input_dir , _GetFullFilename(""))
405 self.assertEquals(self.importer.output_dir , pathutils.EXPORT_DIR)
406 self.assertEquals(self.importer.temp_dir , None)
408 def testOVFSetOutputDirDirectories(self):
409 self.importer = ovf.OVFImporter(self.ganeti_ovf, OPTS_EXPORT)
410 self.assertEquals(self.importer.input_dir , _GetFullFilename(""))
411 self.assertTrue(OUTPUT_DIR in self.importer.output_dir)
412 self.assertEquals(self.importer.temp_dir , None)
414 def testWrongOVAArchiveError(self):
415 self.assertRaisesRegexp(errors.OpPrereqError, "not a proper tar",
416 ovf.OVFImporter, self.wrong_ova_archive, None)
418 def testNoOVFFileInOVAPackageError(self):
419 self.assertRaisesRegexp(errors.OpPrereqError, "No .ovf file",
420 ovf.OVFImporter, self.no_ovf_in_ova, None)
422 def testParseGanetiOvf(self):
423 self.importer = ovf.OVFImporter(self.ganeti_ovf, OPTS_EXPORT_NO_NAME)
424 self.importer.Parse()
425 self.assertTrue("%s/ganeti-test-xen" % OUTPUT_DIR in
426 self.importer.output_dir)
427 self.assertEqual(self.importer.results_disk, GANETI_DISKS)
428 self.assertEqual(self.importer.results_network, GANETI_NETWORKS)
429 self.assertEqual(self.importer.results_hypervisor, GANETI_HYPERVISOR)
430 self.assertEqual(self.importer.results_os, GANETI_OS)
431 self.assertEqual(self.importer.results_backend, GANETI_BACKEND)
432 self.assertEqual(self.importer.results_name, GANETI_NAME)
433 self.assertEqual(self.importer.results_template, GANETI_TEMPLATE)
434 self.assertEqual(self.importer.results_tags, GANETI_TAGS)
435 self.assertEqual(self.importer.results_version, GANETI_VERSION)
437 def testParseVirtualboxOvf(self):
438 self.importer = ovf.OVFImporter(self.virtualbox_ovf, OPTS_VBOX)
439 self.importer.Parse()
440 self.assertTrue("%s/test-instance" % OUTPUT_DIR in self.importer.output_dir)
441 self.assertEquals(self.importer.results_disk, VIRTUALBOX_DISKS)
442 self.assertEquals(self.importer.results_network, VIRTUALBOX_NETWORKS)
443 self.assertEquals(self.importer.results_hypervisor, CMDARGS_HYPERVISOR)
444 self.assertEquals(self.importer.results_os, CMDARGS_OS)
445 self.assertEquals(self.importer.results_backend, VIRTUALBOX_BACKEND)
446 self.assertEquals(self.importer.results_name, CMDARGS_NAME)
447 self.assertEquals(self.importer.results_template, VIRTUALBOX_TEMPLATE)
448 self.assertEqual(self.importer.results_tags, VIRTUALBOX_TAGS)
449 self.assertEqual(self.importer.results_version, constants.EXPORT_VERSION)
451 def testParseEmptyOvf(self):
452 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
453 self.importer.Parse()
454 self.assertTrue("%s/test-instance" % OUTPUT_DIR in self.importer.output_dir)
455 self.assertEquals(self.importer.results_disk, CMDARGS_DISKS)
456 self.assertEquals(self.importer.results_network, CMDARGS_NETWORKS)
457 self.assertEquals(self.importer.results_hypervisor, CMDARGS_HYPERVISOR)
458 self.assertEquals(self.importer.results_os, CMDARGS_OS)
459 self.assertEquals(self.importer.results_backend, CMDARGS_BACKEND)
460 self.assertEquals(self.importer.results_name, CMDARGS_NAME)
461 self.assertEquals(self.importer.results_template, CMDARGS_TEMPLATE)
462 self.assertEqual(self.importer.results_tags, CMDARGS_TAGS)
463 self.assertEqual(self.importer.results_version, constants.EXPORT_VERSION)
465 def testParseNameOptions(self):
466 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
467 results = self.importer._ParseNameOptions()
468 self.assertEquals(results, CMDARGS_NAME)
470 def testParseHypervisorOptions(self):
471 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
472 results = self.importer._ParseHypervisorOptions()
473 self.assertEquals(results, CMDARGS_HYPERVISOR)
475 def testParseOSOptions(self):
476 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
477 results = self.importer._ParseOSOptions()
478 self.assertEquals(results, CMDARGS_OS)
480 def testParseBackendOptions(self):
481 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
482 results = self.importer._ParseBackendOptions()
483 self.assertEquals(results, CMDARGS_BACKEND)
485 def testParseTags(self):
486 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
487 results = self.importer._ParseTags()
488 self.assertEquals(results, CMDARGS_TAGS)
490 def testParseNicOptions(self):
491 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
492 results = self.importer._ParseNicOptions()
493 self.assertEquals(results, CMDARGS_NETWORKS)
495 def testParseDiskOptionsFromGanetiOVF(self):
496 self.importer = ovf.OVFImporter(self.ganeti_ovf, OPTS_EXPORT)
498 results = self.importer._GetDiskInfo()
499 self.assertEquals(results, GANETI_DISKS)
501 def testParseTemplateOptions(self):
502 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
503 results = self.importer._ParseTemplateOptions()
504 self.assertEquals(results, GANETI_TEMPLATE)
506 def testParseDiskOptionsFromCmdLine(self):
507 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
509 results = self.importer._ParseDiskOptions()
510 self.assertEquals(results, CMDARGS_DISKS)
512 def testGetDiskFormat(self):
513 self.importer = ovf.OVFImporter(self.ganeti_ovf, OPTS_EXPORT)
514 disks_list = self.importer.ovf_reader.GetDisksNames()
515 results = [self.importer._GetDiskQemuInfo("%s/%s" %
516 (self.importer.input_dir, path), "file format: (\S+)")
517 for (path, _) in disks_list]
518 self.assertEqual(results, ["vmdk"])
520 def testNoInstanceNameOVF(self):
521 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_EXPORT_NO_NAME)
522 self.assertRaisesRegexp(errors.OpPrereqError, "Name of instance",
525 def testErrorNoOSNameOVF(self):
526 self.importer = ovf.OVFImporter(self.virtualbox_ovf, OPTS_EXPORT)
527 self.assertRaisesRegexp(errors.OpPrereqError, "OS name",
530 def testErrorNoDiskAndNoNetwork(self):
531 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_NONIC_NODISK)
532 self.assertRaisesRegexp(errors.OpPrereqError,
533 "Either disk specification or network"
534 " description", self.importer.Parse)
537 class TestOVFExporter(BetterUnitTest):
540 self.wrong_config_file = _GetFullFilename("wrong_config.ini")
541 self.unsafe_path_to_disk = _GetFullFilename("unsafe_path.ini")
542 self.disk_image_not_exist = _GetFullFilename("no_disk.ini")
543 self.empty_config = _GetFullFilename("empty.ini")
544 self.standard_export = _GetFullFilename("config.ini")
545 self.wrong_network_mode = self.disk_image_not_exist
546 self.no_memory = self.disk_image_not_exist
547 self.no_vcpus = self.disk_image_not_exist
548 self.no_os = _GetFullFilename("no_os.ini")
549 self.no_hypervisor = self.disk_image_not_exist
553 self.exporter.Cleanup()
554 del_dir = os.path.abspath(OUTPUT_DIR)
556 shutil.rmtree(del_dir)
560 def testErrorWrongConfigFile(self):
561 self.assertRaisesRegexp(errors.OpPrereqError,
562 "Error when trying to read", ovf.OVFExporter,
563 self.wrong_config_file, EXP_OPTS)
565 def testErrorPathToTheDiskIncorrect(self):
566 self.exporter = ovf.OVFExporter(self.unsafe_path_to_disk, EXP_OPTS)
567 self.assertRaisesRegexp(errors.OpPrereqError, "contains a directory name",
568 self.exporter._ParseDisks)
570 def testErrorDiskImageNotExist(self):
571 self.exporter = ovf.OVFExporter(self.disk_image_not_exist, EXP_OPTS)
572 self.assertRaisesRegexp(errors.OpPrereqError, "Disk image does not exist",
573 self.exporter._ParseDisks)
575 def testParseNetworks(self):
576 self.exporter = ovf.OVFExporter(self.standard_export, EXP_OPTS)
577 results = self.exporter._ParseNetworks()
578 self.assertEqual(results, EXP_NETWORKS_LIST)
580 def testErrorWrongNetworkMode(self):
581 self.exporter = ovf.OVFExporter(self.wrong_network_mode, EXP_OPTS)
582 self.assertRaisesRegexp(errors.OpPrereqError,
583 "Network mode nic not recognized", self.exporter._ParseNetworks)
585 def testParseVCPusMem(self):
586 self.exporter = ovf.OVFExporter(self.standard_export, EXP_OPTS)
587 vcpus = self.exporter._ParseVCPUs()
588 memory = self.exporter._ParseMemory()
589 self.assertEqual(vcpus, EXP_VCPUS)
590 self.assertEqual(memory, EXP_MEMORY)
592 def testErrorNoVCPUs(self):
593 self.exporter = ovf.OVFExporter(self.no_vcpus, EXP_OPTS)
594 self.assertRaisesRegexp(errors.OpPrereqError, "No CPU information found",
595 self.exporter._ParseVCPUs)
597 def testErrorNoMemory(self):
598 self.exporter = ovf.OVFExporter(self.no_memory, EXP_OPTS)
599 self.assertRaisesRegexp(errors.OpPrereqError, "No memory information found",
600 self.exporter._ParseMemory)
602 def testParseGaneti(self):
603 self.exporter = ovf.OVFExporter(self.standard_export, EXP_OPTS)
604 results = self.exporter._ParseGaneti()
605 self.assertEqual(results, EXP_GANETI_DICT)
607 def testErrorNoHypervisor(self):
608 self.exporter = ovf.OVFExporter(self.no_hypervisor, EXP_OPTS)
609 self.assertRaisesRegexp(errors.OpPrereqError,
610 "No hypervisor information found", self.exporter._ParseGaneti)
612 def testErrorNoOS(self):
613 self.exporter = ovf.OVFExporter(self.no_os, EXP_OPTS)
614 self.assertRaisesRegexp(errors.OpPrereqError,
615 "No operating system information found", self.exporter._ParseGaneti)
617 def testErrorParseNoInstanceName(self):
618 self.exporter = ovf.OVFExporter(self.empty_config, EXP_OPTS)
619 self.assertRaisesRegexp(errors.OpPrereqError, "No instance name found",
623 class TestOVFReader(BetterUnitTest):
625 self.wrong_xml_file = _GetFullFilename("wrong_xml.ovf")
626 self.ganeti_ovf = _GetFullFilename("ganeti.ovf")
627 self.virtualbox_ovf = _GetFullFilename("virtualbox.ovf")
628 self.corrupted_ovf = _GetFullFilename("corrupted_resources.ovf")
629 self.wrong_manifest_ovf = _GetFullFilename("wrong_manifest.ovf")
630 self.no_disk_in_ref_ovf = _GetFullFilename("no_disk_in_ref.ovf")
631 self.empty_ovf = _GetFullFilename("empty.ovf")
632 self.compressed_disk = _GetFullFilename("gzip_disk.ovf")
637 def testXMLParsingError(self):
638 self.assertRaisesRegexp(errors.OpPrereqError,
639 "Error while reading .ovf", ovf.OVFReader, self.wrong_xml_file)
641 def testFileInResourcesDoesNotExistError(self):
642 self.assertRaisesRegexp(errors.OpPrereqError, "does not exist",
643 ovf.OVFReader, self.corrupted_ovf)
645 def testWrongManifestChecksumError(self):
646 reader = ovf.OVFReader(self.wrong_manifest_ovf)
647 self.assertRaisesRegexp(errors.OpPrereqError,
648 "does not match the value in manifest file", reader.VerifyManifest)
650 def testGoodManifestChecksum(self):
651 reader = ovf.OVFReader(self.ganeti_ovf)
652 self.assertEqual(reader.VerifyManifest(), None)
654 def testGetDisksNamesOVFCorruptedError(self):
655 reader = ovf.OVFReader(self.no_disk_in_ref_ovf)
656 self.assertRaisesRegexp(errors.OpPrereqError,
657 "not found in references", reader.GetDisksNames)
659 def testGetDisksNamesVirtualbox(self):
660 reader = ovf.OVFReader(self.virtualbox_ovf)
661 disk_names = reader.GetDisksNames()
663 ("new_disk.vmdk", None) ,
664 ("second_disk.vmdk", None),
666 self.assertEqual(sorted(disk_names), sorted(expected_names))
668 def testGetDisksNamesEmpty(self):
669 reader = ovf.OVFReader(self.empty_ovf)
670 disk_names = reader.GetDisksNames()
671 self.assertEqual(disk_names, [])
673 def testGetDisksNamesCompressed(self):
674 reader = ovf.OVFReader(self.compressed_disk)
675 disk_names = reader.GetDisksNames()
676 self.assertEqual(disk_names, [("compr_disk.vmdk.gz", "gzip")])
678 def testGetNetworkDataGaneti(self):
679 reader = ovf.OVFReader(self.ganeti_ovf)
680 networks = reader.GetNetworkData()
681 self.assertEqual(networks, GANETI_NETWORKS)
683 def testGetNetworkDataVirtualbox(self):
684 reader = ovf.OVFReader(self.virtualbox_ovf)
685 networks = reader.GetNetworkData()
686 self.assertEqual(networks, VIRTUALBOX_NETWORKS)
688 def testGetNetworkDataEmpty(self):
689 reader = ovf.OVFReader(self.empty_ovf)
690 networks = reader.GetNetworkData()
691 self.assertEqual(networks, EMPTY_NETWORKS)
693 def testGetHypervisorDataGaneti(self):
694 reader = ovf.OVFReader(self.ganeti_ovf)
695 hypervisor = reader.GetHypervisorData()
696 self.assertEqual(hypervisor, GANETI_HYPERVISOR)
698 def testGetHypervisorDataEmptyOvf(self):
699 reader = ovf.OVFReader(self.empty_ovf)
700 hypervisor = reader.GetHypervisorData()
701 self.assertEqual(hypervisor, EMPTY_HYPERVISOR)
703 def testGetOSDataGaneti(self):
704 reader = ovf.OVFReader(self.ganeti_ovf)
705 osys = reader.GetOSData()
706 self.assertEqual(osys, GANETI_OS)
708 def testGetOSDataEmptyOvf(self):
709 reader = ovf.OVFReader(self.empty_ovf)
710 osys = reader.GetOSData()
711 self.assertEqual(osys, EMPTY_OS)
713 def testGetBackendDataGaneti(self):
714 reader = ovf.OVFReader(self.ganeti_ovf)
715 backend = reader.GetBackendData()
716 self.assertEqual(backend, GANETI_BACKEND)
718 def testGetBackendDataVirtualbox(self):
719 reader = ovf.OVFReader(self.virtualbox_ovf)
720 backend = reader.GetBackendData()
721 self.assertEqual(backend, VIRTUALBOX_BACKEND)
723 def testGetBackendDataEmptyOvf(self):
724 reader = ovf.OVFReader(self.empty_ovf)
725 backend = reader.GetBackendData()
726 self.assertEqual(backend, EMPTY_BACKEND)
728 def testGetInstanceNameGaneti(self):
729 reader = ovf.OVFReader(self.ganeti_ovf)
730 name = reader.GetInstanceName()
731 self.assertEqual(name, GANETI_NAME)
733 def testGetInstanceNameDataEmptyOvf(self):
734 reader = ovf.OVFReader(self.empty_ovf)
735 name = reader.GetInstanceName()
736 self.assertEqual(name, EMPTY_NAME)
738 def testGetDiskTemplateGaneti(self):
739 reader = ovf.OVFReader(self.ganeti_ovf)
740 name = reader.GetDiskTemplate()
741 self.assertEqual(name, GANETI_TEMPLATE)
743 def testGetDiskTemplateEmpty(self):
744 reader = ovf.OVFReader(self.empty_ovf)
745 name = reader.GetDiskTemplate()
746 self.assertEqual(name, EMPTY_TEMPLATE)
748 def testGetTagsGaneti(self):
749 reader = ovf.OVFReader(self.ganeti_ovf)
750 tags = reader.GetTagsData()
751 self.assertEqual(tags, GANETI_TAGS)
753 def testGetTagsEmpty(self):
754 reader = ovf.OVFReader(self.empty_ovf)
755 tags = reader.GetTagsData()
756 self.assertEqual(tags, EMPTY_TAGS)
758 def testGetVersionGaneti(self):
759 reader = ovf.OVFReader(self.ganeti_ovf)
760 version = reader.GetVersionData()
761 self.assertEqual(version, GANETI_VERSION)
763 def testGetVersionEmpty(self):
764 reader = ovf.OVFReader(self.empty_ovf)
765 version = reader.GetVersionData()
766 self.assertEqual(version, EMPTY_VERSION)
769 class TestOVFWriter(BetterUnitTest):
771 self.writer = ovf.OVFWriter(True)
776 def testOVFWriterInit(self):
777 result = ET.tostring(self.writer.tree)
778 self.assertTrue(EXPORT_EMPTY in result)
780 def testSaveDisksDataEmpty(self):
781 self.writer.SaveDisksData([])
782 result = ET.tostring(self.writer.tree)
783 self.assertTrue(EXPORT_DISKS_EMPTY in result)
785 def testSaveDisksData(self):
786 self.writer.SaveDisksData(EXP_DISKS_LIST)
787 result = ET.tostring(self.writer.tree)
788 self.assertTrue(EXPORT_DISKS in result)
790 def testSaveNetworkDataEmpty(self):
791 self.writer.SaveNetworksData([])
792 result = ET.tostring(self.writer.tree)
793 self.assertTrue(EXPORT_NETWORKS_EMPTY in result)
795 def testSaveNetworksData(self):
796 self.writer.SaveNetworksData(EXP_NETWORKS_LIST)
797 result = ET.tostring(self.writer.tree)
798 self.assertTrue(EXPORT_NETWORKS in result)
800 def testSaveGanetiDataIncomplete(self):
801 self.writer.SaveGanetiData(EXP_PARTIAL_GANETI_DICT, EXP_NETWORKS_LIST)
802 result = ET.tostring(self.writer.tree)
803 self.assertTrue(EXPORT_GANETI_INCOMPLETE in result)
805 def testSaveGanetiDataComplete(self):
806 self.writer.SaveGanetiData(EXP_GANETI_DICT, EXP_NETWORKS_LIST)
807 result = ET.tostring(self.writer.tree)
808 self.assertTrue(EXPORT_GANETI in result)
810 def testSaveVirtualSystem(self):
811 self.writer.SaveDisksData(EXP_DISKS_LIST)
812 self.writer.SaveNetworksData(EXP_NETWORKS_LIST)
813 self.writer.SaveVirtualSystemData(EXP_NAME, EXP_VCPUS, EXP_MEMORY)
814 result = ET.tostring(self.writer.tree)
815 self.assertTrue(EXPORT_SYSTEM in result)
818 if __name__ == "__main__":
819 testutils.GanetiTestProgram()