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
51 "disk0_dump": "new_disk.raw",
53 "disk0_ivname": "disk/0",
57 "nic0_mode": "bridged",
59 "nic0_mac": "aa:00:00:d8:2c:1e",
60 "nic0_link": "xen-br0",
63 "hypervisor_name": "xen-pvm",
64 "root-path": "/dev/sda",
67 GANETI_OS = {"os_name": "lenny-image"}
71 "auto_balance": "False",
73 GANETI_NAME = "ganeti-test-xen"
74 GANETI_TEMPLATE = "plain"
80 "disk0_ivname": "disk/0",
81 "disk0_dump": "new_disk.raw",
83 "disk1_ivname": "disk/1",
84 "disk1_dump": "second_disk.raw",
87 VIRTUALBOX_NETWORKS = {
89 "nic0_mode": "bridged",
94 VIRTUALBOX_HYPERVISOR = {"hypervisor_name": "auto"}
95 VIRTUALBOX_OS = {"os_name": None}
96 VIRTUALBOX_BACKEND = {
99 "auto_balance": "auto",
101 VIRTUALBOX_NAME = None
102 VIRTUALBOX_TEMPLATE = None
103 VIRTUALBOX_TAGS = None
104 VIRTUALBOX_VERSION = None
108 EMPTY_HYPERVISOR = {"hypervisor_name": "auto"}
113 "auto_balance": "auto",
116 EMPTY_TEMPLATE = None
122 "disk0_ivname": "disk/0",
123 "disk0_dump": "disk0.raw",
128 "nic0_mode": "bridged",
133 CMDARGS_HYPERVISOR = {
134 "hypervisor_name": "xen-pvm"
136 CMDARGS_OS = {"os_name": "lenny-image"}
138 "auto_balance": False,
142 CMDARGS_NAME = "test-instance"
143 CMDARGS_TEMPLATE = "plain"
144 CMDARGS_TAGS = "test-tag-1,test-tag-2"
150 "name": "test-instance",
151 "ova_package": False,
153 "disk_format": "cow",
154 "compression": False,
156 ARGS_EXPORT_DIR = dict(ARGS_EMPTY, **{
157 "output_dir": OUTPUT_DIR,
163 "disk_template": None,
166 ARGS_VBOX = dict(ARGS_EXPORT_DIR, **{
167 "output_dir": OUTPUT_DIR,
168 "name": "test-instance",
170 "hypervisor": ("xen-pvm", {}),
174 ARGS_COMPLETE = dict(ARGS_VBOX, **{
175 "beparams": {"vcpus":"1", "memory":"256", "auto_balance": False},
176 "disks": [(0,{"size":"5mb"})],
177 "nics": [("0",{"mode":"bridged"})],
178 "disk_template": "plain",
179 "tags": "test-tag-1,test-tag-2",
181 ARGS_BROKEN = dict(ARGS_EXPORT_DIR , **{
183 "disk_template": "diskless",
184 "name": "test-instance",
189 EXP_ARGS_COMPRESSED = dict(ARGS_EXPORT_DIR, **{
196 "compression": "gzip",
199 "path": "new_disk.cow.gz",
205 "path": "new_disk.cow",
208 EXP_NETWORKS_LIST = [
209 {"mac": "aa:00:00:d8:2c:1e", "ip":"None", "link":"br0","mode":"routed"},
211 EXP_PARTIAL_GANETI_DICT = {
212 "hypervisor": {"name": "xen-kvm"},
213 "os": {"name": "lenny-image"},
214 "auto_balance": "True",
219 'auto_balance': 'False',
221 'root-path': '/dev/sda',
226 'disk_template': None,
227 'os': {'name': 'lenny-image'}
229 EXP_NAME ="xen-dev-i1"
233 EXPORT_EMPTY = ("<Envelope xml:lang=\"en-US\" xmlns=\"http://schemas.dmtf.org/"
234 "ovf/envelope/1\" xmlns:gnt=\"http://ganeti\" xmlns:ovf=\""
235 "http://schemas.dmtf.org/ovf/envelope/1\" xmlns:rasd=\""
236 "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_Resource"
237 "AllocationSettingData\" xmlns:vssd=\"http://schemas.dmtf.org"
238 "/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData\""
239 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" />")
240 EXPORT_DISKS_EMPTY = ("<References /><DiskSection><Info>Virtual disk"
241 " information</Info></DiskSection>")
242 EXPORT_DISKS = ("<References><File ovf:compression=\"gzip\" ovf:href=\"new_disk"
243 ".cow.gz\" ovf:id=\"file0\" ovf:size=\"203\" /><File ovf:href="
244 "\"new_disk.cow\" ovf:id=\"file1\" ovf:size=\"15\" />"
245 "</References><DiskSection><Info>Virtual disk information"
246 "</Info><Disk ovf:capacity=\"90000\" ovf:diskId=\"disk0\" ovf"
247 ":fileRef=\"file0\" ovf:format=\"http://www.vmware.com/"
248 "interfaces/specifications/vmdk.html#monolithicSparse\" /><Disk"
249 " ovf:capacity=\"15\" ovf:diskId=\"disk1\" ovf:fileRef"
250 "=\"file1\" ovf:format=\"http://www.gnome.org/~markmc/qcow"
251 "-image-format.html\" /></DiskSection>")
252 EXPORT_NETWORKS_EMPTY = ("<NetworkSection><Info>List of logical networks</Info>"
254 EXPORT_NETWORKS = ("<NetworkSection><Info>List of logical networks</Info>"
255 "<Network ovf:name=\"routed0\" /></NetworkSection>")
256 EXPORT_GANETI_INCOMPLETE = ("<gnt:GanetiSection><gnt:Version>0</gnt:Version>"
257 "<gnt:AutoBalance>True</gnt:AutoBalance><gnt:"
258 "OperatingSystem><gnt:Name>lenny-image</gnt:Name>"
259 "<gnt:Parameters /></gnt:OperatingSystem><gnt:"
260 "Hypervisor><gnt:Name>xen-kvm</gnt:Name><gnt:"
261 "Parameters /></gnt:Hypervisor><gnt:Network><gnt:"
262 "Nic ovf:name=\"routed0\"><gnt:Mode>routed</gnt:"
263 "Mode><gnt:MACAddress>aa:00:00:d8:2c:1e</gnt:"
264 "MACAddress><gnt:IPAddress>None</gnt:IPAddress>"
265 "<gnt:Link>br0</gnt:Link></gnt:Nic></gnt:Network>"
266 "</gnt:GanetiSection>")
267 EXPORT_GANETI = ("<gnt:GanetiSection><gnt:Version>0</gnt:Version><gnt:"
268 "AutoBalance>False</gnt:AutoBalance><gnt:OperatingSystem>"
269 "<gnt:Name>lenny-image</gnt:Name><gnt:Parameters /></gnt:"
270 "OperatingSystem><gnt:Hypervisor><gnt:Name>xen-pvm</gnt:Name>"
271 "<gnt:Parameters><gnt:root-path>/dev/sda</gnt:root-path><gnt:"
272 "kernel_args>ro</gnt:kernel_args></gnt:Parameters></gnt:"
273 "Hypervisor><gnt:Network><gnt:Nic ovf:name=\"routed0\"><gnt:"
274 "Mode>routed</gnt:Mode><gnt:MACAddress>aa:00:00:d8:2c:1e</gnt:"
275 "MACAddress><gnt:IPAddress>None</gnt:IPAddress><gnt:Link>br0"
276 "</gnt:Link></gnt:Nic></gnt:Network></gnt:GanetiSection>")
277 EXPORT_SYSTEM = ("<References><File ovf:compression=\"gzip\" ovf:href=\"new_"
278 "disk.cow.gz\" ovf:id=\"file0\" ovf:size=\"203\" /><File ovf:"
279 "href=\"new_disk.cow\" ovf:id=\"file1\" ovf:size=\"15\" />"
280 "</References><DiskSection><Info>Virtual disk information"
281 "</Info><Disk ovf:capacity=\"90000\" ovf:diskId=\"disk0\""
282 " ovf:fileRef=\"file0\" ovf:format=\"http://www.vmware.com"
283 "/interfaces/specifications/vmdk.html#monolithicSparse\" />"
284 "<Disk ovf:capacity=\"15\" ovf:diskId=\"disk1\" ovf:fileRef"
285 "=\"file1\" ovf:format=\"http://www.gnome.org/~markmc/qcow"
286 "-image-format.html\" /></DiskSection><NetworkSection><Info>"
287 "List of logical networks</Info><Network ovf:name=\"routed0\""
288 " /></NetworkSection><VirtualSystem ovf:id=\"xen-dev-i1\">"
289 "<Info>A virtual machine</Info><Name>xen-dev-i1</Name>"
290 "<OperatingSystemSection ovf:id=\"0\"><Info>Installed guest"
291 " operating system</Info></OperatingSystemSection><Virtual"
292 "HardwareSection><Info>Virtual hardware requirements</Info>"
293 "<System><vssd:ElementName>Virtual Hardware Family"
294 "</vssd:ElementName><vssd:InstanceID>0</vssd:InstanceID><vssd:"
295 "VirtualSystemIdentifier>xen-dev-i1</vssd:VirtualSystem"
296 "Identifier><vssd:VirtualSystemType>ganeti-ovf</vssd:Virtual"
297 "SystemType></System><Item><rasd:ElementName>1 virtual CPU(s)"
298 "</rasd:ElementName><rasd:InstanceID>1</rasd:InstanceID><rasd:"
299 "ResourceType>3</rasd:ResourceType><rasd:VirtualQuantity>1"
300 "</rasd:VirtualQuantity></Item><Item><rasd:AllocationUnits>"
301 "byte * 2^20</rasd:AllocationUnits><rasd:ElementName>512MB of"
302 " memory</rasd:ElementName><rasd:InstanceID>2</rasd:"
303 "InstanceID><rasd:ResourceType>4</rasd:ResourceType><rasd:"
304 "VirtualQuantity>512</rasd:VirtualQuantity></Item><Item>"
305 "<rasd:Address>0</rasd:Address><rasd:ElementName>scsi"
306 "_controller0</rasd:ElementName><rasd:InstanceID>3"
307 "</rasd:InstanceID><rasd:ResourceSubType>lsilogic</rasd"
308 ":ResourceSubType><rasd:ResourceType>6</rasd:ResourceType>"
309 "</Item><Item><rasd:ElementName>disk0</rasd:ElementName><rasd"
310 ":HostResource>ovf:/disk/disk0</rasd:HostResource><rasd"
311 ":InstanceID>4</rasd:InstanceID><rasd:Parent>3</rasd:Parent>"
312 "<rasd:ResourceType>17</rasd:ResourceType></Item><Item><rasd:"
313 "ElementName>disk1</rasd:ElementName><rasd:HostResource>ovf:/"
314 "disk/disk1</rasd:HostResource><rasd:InstanceID>5</rasd"
315 ":InstanceID><rasd:Parent>3</rasd:Parent><rasd:ResourceType>17"
316 "</rasd:ResourceType></Item><Item><rasd:Address>aa:00"
317 ":00:d8:2c:1e</rasd:Address><rasd:Connection>routed0</rasd"
318 ":Connection><rasd:ElementName>routed0</rasd:ElementName><rasd"
319 ":InstanceID>6</rasd:InstanceID><rasd:ResourceType>10</rasd"
320 ":ResourceType></Item></VirtualHardwareSection>"
324 def _GetArgs(args, with_name=False):
325 options = optparse.Values()
328 needed["name"] = "test-instance"
329 options._update_loose(needed)
333 OPTS_EMPTY = _GetArgs(ARGS_EMPTY)
334 OPTS_EXPORT_NO_NAME = _GetArgs(ARGS_EXPORT_DIR)
335 OPTS_EXPORT = _GetArgs(ARGS_EXPORT_DIR, with_name=True)
337 EXP_OPTS = OPTS_EXPORT_NO_NAME
338 EXP_OPTS_COMPRESSED = _GetArgs(EXP_ARGS_COMPRESSED)
340 OPTS_VBOX = _GetArgs(ARGS_VBOX)
341 OPTS_COMPLETE = _GetArgs(ARGS_COMPLETE)
342 OPTS_NONIC_NODISK = _GetArgs(ARGS_BROKEN)
345 def _GetFullFilename(file_name):
346 file_path = "%s/test/data/ovfdata/%s" % (testutils.GetSourceDir(),
348 file_path = os.path.abspath(file_path)
352 class BetterUnitTest(unittest.TestCase):
353 def assertRaisesRegexp(self, exception, regexp_val, function, *args):
356 self.fail("Expected raising %s" % exception)
357 except exception, err:
358 regexp = re.compile(regexp_val)
359 if re.search(regexp, str(err)) == None:
360 self.fail("Expected matching '%s', got '%s'" %
361 (regexp_val, str(err)))
364 class TestOVFImporter(BetterUnitTest):
366 self.non_existing_file = _GetFullFilename("not_the_file.ovf")
367 self.ganeti_ovf = _GetFullFilename("ganeti.ovf")
368 self.virtualbox_ovf = _GetFullFilename("virtualbox.ovf")
369 self.ova_package = _GetFullFilename("ova.ova")
370 self.empty_ovf = _GetFullFilename("empty.ovf")
371 self.wrong_extension = _GetFullFilename("wrong_extension.ovd")
372 self.wrong_ova_archive = _GetFullFilename("wrong_ova.ova")
373 self.no_ovf_in_ova = _GetFullFilename("no_ovf.ova")
378 self.importer.Cleanup()
379 del_dir = os.path.abspath(OUTPUT_DIR)
381 shutil.rmtree(del_dir)
385 def testFileDoesNotExistError(self):
386 self.assertRaisesRegexp(errors.OpPrereqError, "does not exist",
387 ovf.OVFImporter, self.non_existing_file, None)
389 def testWrongInputFileExtensionError(self):
390 self.assertRaisesRegexp(errors.OpPrereqError,
391 "Unknown file extension", ovf.OVFImporter,
392 self.wrong_extension, None)
394 def testOVAUnpackingDirectories(self):
395 self.importer = ovf.OVFImporter(self.ova_package, OPTS_EMPTY)
396 self.assertTrue(self.importer.input_dir != None)
397 self.assertEquals(self.importer.output_dir , constants.EXPORT_DIR)
398 self.assertTrue(self.importer.temp_dir != None)
400 def testOVFUnpackingDirectories(self):
401 self.importer = ovf.OVFImporter(self.virtualbox_ovf,
403 self.assertEquals(self.importer.input_dir , _GetFullFilename(""))
404 self.assertEquals(self.importer.output_dir , constants.EXPORT_DIR)
405 self.assertEquals(self.importer.temp_dir , None)
407 def testOVFSetOutputDirDirectories(self):
408 self.importer = ovf.OVFImporter(self.ganeti_ovf, OPTS_EXPORT)
409 self.assertEquals(self.importer.input_dir , _GetFullFilename(""))
410 self.assertTrue(OUTPUT_DIR in self.importer.output_dir)
411 self.assertEquals(self.importer.temp_dir , None)
413 def testWrongOVAArchiveError(self):
414 self.assertRaisesRegexp(errors.OpPrereqError, "not a proper tar",
415 ovf.OVFImporter, self.wrong_ova_archive, None)
417 def testNoOVFFileInOVAPackageError(self):
418 self.assertRaisesRegexp(errors.OpPrereqError, "No .ovf file",
419 ovf.OVFImporter, self.no_ovf_in_ova, None)
421 def testParseGanetiOvf(self):
422 self.importer = ovf.OVFImporter(self.ganeti_ovf, OPTS_EXPORT_NO_NAME)
423 self.importer.Parse()
424 self.assertTrue("%s/ganeti-test-xen" % OUTPUT_DIR in
425 self.importer.output_dir)
426 self.assertEqual(self.importer.results_disk, GANETI_DISKS)
427 self.assertEqual(self.importer.results_network, GANETI_NETWORKS)
428 self.assertEqual(self.importer.results_hypervisor, GANETI_HYPERVISOR)
429 self.assertEqual(self.importer.results_os, GANETI_OS)
430 self.assertEqual(self.importer.results_backend, GANETI_BACKEND)
431 self.assertEqual(self.importer.results_name, GANETI_NAME)
432 self.assertEqual(self.importer.results_template, GANETI_TEMPLATE)
433 self.assertEqual(self.importer.results_tags, GANETI_TAGS)
434 self.assertEqual(self.importer.results_version, GANETI_VERSION)
436 def testParseVirtualboxOvf(self):
437 self.importer = ovf.OVFImporter(self.virtualbox_ovf, OPTS_VBOX)
438 self.importer.Parse()
439 self.assertTrue("%s/test-instance" % OUTPUT_DIR in self.importer.output_dir)
440 self.assertEquals(self.importer.results_disk, VIRTUALBOX_DISKS)
441 self.assertEquals(self.importer.results_network, VIRTUALBOX_NETWORKS)
442 self.assertEquals(self.importer.results_hypervisor, CMDARGS_HYPERVISOR)
443 self.assertEquals(self.importer.results_os, CMDARGS_OS)
444 self.assertEquals(self.importer.results_backend, VIRTUALBOX_BACKEND)
445 self.assertEquals(self.importer.results_name, CMDARGS_NAME)
446 self.assertEquals(self.importer.results_template, VIRTUALBOX_TEMPLATE)
447 self.assertEqual(self.importer.results_tags, VIRTUALBOX_TAGS)
448 self.assertEqual(self.importer.results_version, constants.EXPORT_VERSION)
450 def testParseEmptyOvf(self):
451 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
452 self.importer.Parse()
453 self.assertTrue("%s/test-instance" % OUTPUT_DIR in self.importer.output_dir)
454 self.assertEquals(self.importer.results_disk, CMDARGS_DISKS)
455 self.assertEquals(self.importer.results_network, CMDARGS_NETWORKS)
456 self.assertEquals(self.importer.results_hypervisor, CMDARGS_HYPERVISOR)
457 self.assertEquals(self.importer.results_os, CMDARGS_OS)
458 self.assertEquals(self.importer.results_backend, CMDARGS_BACKEND)
459 self.assertEquals(self.importer.results_name, CMDARGS_NAME)
460 self.assertEquals(self.importer.results_template, CMDARGS_TEMPLATE)
461 self.assertEqual(self.importer.results_tags, CMDARGS_TAGS)
462 self.assertEqual(self.importer.results_version, constants.EXPORT_VERSION)
464 def testParseNameOptions(self):
465 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
466 results = self.importer._ParseNameOptions()
467 self.assertEquals(results, CMDARGS_NAME)
469 def testParseHypervisorOptions(self):
470 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
471 results = self.importer._ParseHypervisorOptions()
472 self.assertEquals(results, CMDARGS_HYPERVISOR)
474 def testParseOSOptions(self):
475 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
476 results = self.importer._ParseOSOptions()
477 self.assertEquals(results, CMDARGS_OS)
479 def testParseBackendOptions(self):
480 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
481 results = self.importer._ParseBackendOptions()
482 self.assertEquals(results, CMDARGS_BACKEND)
484 def testParseTags(self):
485 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
486 results = self.importer._ParseTags()
487 self.assertEquals(results, CMDARGS_TAGS)
489 def testParseNicOptions(self):
490 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
491 results = self.importer._ParseNicOptions()
492 self.assertEquals(results, CMDARGS_NETWORKS)
494 def testParseDiskOptionsFromGanetiOVF(self):
495 self.importer = ovf.OVFImporter(self.ganeti_ovf, OPTS_EXPORT)
497 results = self.importer._GetDiskInfo()
498 self.assertEquals(results, GANETI_DISKS)
500 def testParseTemplateOptions(self):
501 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
502 results = self.importer._ParseTemplateOptions()
503 self.assertEquals(results, GANETI_TEMPLATE)
505 def testParseDiskOptionsFromCmdLine(self):
506 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
508 results = self.importer._ParseDiskOptions()
509 self.assertEquals(results, CMDARGS_DISKS)
511 def testGetDiskFormat(self):
512 self.importer = ovf.OVFImporter(self.ganeti_ovf, OPTS_EXPORT)
513 disks_list = self.importer.ovf_reader.GetDisksNames()
514 results = [self.importer._GetDiskQemuInfo("%s/%s" %
515 (self.importer.input_dir, path), "file format: (\S+)")
516 for (path, _) in disks_list]
517 self.assertEqual(results, ["vmdk"])
519 def testNoInstanceNameOVF(self):
520 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_EXPORT_NO_NAME)
521 self.assertRaisesRegexp(errors.OpPrereqError, "Name of instance",
524 def testErrorNoOSNameOVF(self):
525 self.importer = ovf.OVFImporter(self.virtualbox_ovf, OPTS_EXPORT)
526 self.assertRaisesRegexp(errors.OpPrereqError, "OS name",
529 def testErrorNoDiskAndNoNetwork(self):
530 self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_NONIC_NODISK)
531 self.assertRaisesRegexp(errors.OpPrereqError,
532 "Either disk specification or network"
533 " description", self.importer.Parse)
536 class TestOVFExporter(BetterUnitTest):
539 self.wrong_config_file = _GetFullFilename("wrong_config.ini")
540 self.unsafe_path_to_disk = _GetFullFilename("unsafe_path.ini")
541 self.disk_image_not_exist = _GetFullFilename("no_disk.ini")
542 self.empty_config = _GetFullFilename("empty.ini")
543 self.standard_export = _GetFullFilename("config.ini")
544 self.wrong_network_mode = self.disk_image_not_exist
545 self.no_memory = self.disk_image_not_exist
546 self.no_vcpus = self.disk_image_not_exist
547 self.no_os = _GetFullFilename("no_os.ini")
548 self.no_hypervisor = self.disk_image_not_exist
552 self.exporter.Cleanup()
553 del_dir = os.path.abspath(OUTPUT_DIR)
555 shutil.rmtree(del_dir)
559 def testErrorWrongConfigFile(self):
560 self.assertRaisesRegexp(errors.OpPrereqError,
561 "Error when trying to read", ovf.OVFExporter,
562 self.wrong_config_file, EXP_OPTS)
564 def testErrorPathToTheDiskIncorrect(self):
565 self.exporter = ovf.OVFExporter(self.unsafe_path_to_disk, EXP_OPTS)
566 self.assertRaisesRegexp(errors.OpPrereqError, "contains a directory name",
567 self.exporter._ParseDisks)
569 def testErrorDiskImageNotExist(self):
570 self.exporter = ovf.OVFExporter(self.disk_image_not_exist, EXP_OPTS)
571 self.assertRaisesRegexp(errors.OpPrereqError, "Disk image does not exist",
572 self.exporter._ParseDisks)
574 def testParseNetworks(self):
575 self.exporter = ovf.OVFExporter(self.standard_export, EXP_OPTS)
576 results = self.exporter._ParseNetworks()
577 self.assertEqual(results, EXP_NETWORKS_LIST)
579 def testErrorWrongNetworkMode(self):
580 self.exporter = ovf.OVFExporter(self.wrong_network_mode, EXP_OPTS)
581 self.assertRaisesRegexp(errors.OpPrereqError,
582 "Network mode nic not recognized", self.exporter._ParseNetworks)
584 def testParseVCPusMem(self):
585 self.exporter = ovf.OVFExporter(self.standard_export, EXP_OPTS)
586 vcpus = self.exporter._ParseVCPUs()
587 memory = self.exporter._ParseMemory()
588 self.assertEqual(vcpus, EXP_VCPUS)
589 self.assertEqual(memory, EXP_MEMORY)
591 def testErrorNoVCPUs(self):
592 self.exporter = ovf.OVFExporter(self.no_vcpus, EXP_OPTS)
593 self.assertRaisesRegexp(errors.OpPrereqError, "No CPU information found",
594 self.exporter._ParseVCPUs)
596 def testErrorNoMemory(self):
597 self.exporter = ovf.OVFExporter(self.no_memory, EXP_OPTS)
598 self.assertRaisesRegexp(errors.OpPrereqError, "No memory information found",
599 self.exporter._ParseMemory)
601 def testParseGaneti(self):
602 self.exporter = ovf.OVFExporter(self.standard_export, EXP_OPTS)
603 results = self.exporter._ParseGaneti()
604 self.assertEqual(results, EXP_GANETI_DICT)
606 def testErrorNoHypervisor(self):
607 self.exporter = ovf.OVFExporter(self.no_hypervisor, EXP_OPTS)
608 self.assertRaisesRegexp(errors.OpPrereqError,
609 "No hypervisor information found", self.exporter._ParseGaneti)
611 def testErrorNoOS(self):
612 self.exporter = ovf.OVFExporter(self.no_os, EXP_OPTS)
613 self.assertRaisesRegexp(errors.OpPrereqError,
614 "No operating system information found", self.exporter._ParseGaneti)
616 def testErrorParseNoInstanceName(self):
617 self.exporter = ovf.OVFExporter(self.empty_config, EXP_OPTS)
618 self.assertRaisesRegexp(errors.OpPrereqError, "No instance name found",
622 class TestOVFReader(BetterUnitTest):
624 self.wrong_xml_file = _GetFullFilename("wrong_xml.ovf")
625 self.ganeti_ovf = _GetFullFilename("ganeti.ovf")
626 self.virtualbox_ovf = _GetFullFilename("virtualbox.ovf")
627 self.corrupted_ovf = _GetFullFilename("corrupted_resources.ovf")
628 self.wrong_manifest_ovf = _GetFullFilename("wrong_manifest.ovf")
629 self.no_disk_in_ref_ovf = _GetFullFilename("no_disk_in_ref.ovf")
630 self.empty_ovf = _GetFullFilename("empty.ovf")
631 self.compressed_disk = _GetFullFilename("gzip_disk.ovf")
636 def testXMLParsingError(self):
637 self.assertRaisesRegexp(errors.OpPrereqError,
638 "Error while reading .ovf", ovf.OVFReader, self.wrong_xml_file)
640 def testFileInResourcesDoesNotExistError(self):
641 self.assertRaisesRegexp(errors.OpPrereqError, "does not exist",
642 ovf.OVFReader, self.corrupted_ovf)
644 def testWrongManifestChecksumError(self):
645 reader = ovf.OVFReader(self.wrong_manifest_ovf)
646 self.assertRaisesRegexp(errors.OpPrereqError,
647 "does not match the value in manifest file", reader.VerifyManifest)
649 def testGoodManifestChecksum(self):
650 reader = ovf.OVFReader(self.ganeti_ovf)
651 self.assertEqual(reader.VerifyManifest(), None)
653 def testGetDisksNamesOVFCorruptedError(self):
654 reader = ovf.OVFReader(self.no_disk_in_ref_ovf)
655 self.assertRaisesRegexp(errors.OpPrereqError,
656 "not found in references", reader.GetDisksNames)
658 def testGetDisksNamesVirtualbox(self):
659 reader = ovf.OVFReader(self.virtualbox_ovf)
660 disk_names = reader.GetDisksNames()
662 ("new_disk.vmdk", None) ,
663 ("second_disk.vmdk", None),
665 self.assertEqual(sorted(disk_names), sorted(expected_names))
667 def testGetDisksNamesEmpty(self):
668 reader = ovf.OVFReader(self.empty_ovf)
669 disk_names = reader.GetDisksNames()
670 self.assertEqual(disk_names, [])
672 def testGetDisksNamesCompressed(self):
673 reader = ovf.OVFReader(self.compressed_disk)
674 disk_names = reader.GetDisksNames()
675 self.assertEqual(disk_names, [("compr_disk.vmdk.gz", "gzip")])
677 def testGetNetworkDataGaneti(self):
678 reader = ovf.OVFReader(self.ganeti_ovf)
679 networks = reader.GetNetworkData()
680 self.assertEqual(networks, GANETI_NETWORKS)
682 def testGetNetworkDataVirtualbox(self):
683 reader = ovf.OVFReader(self.virtualbox_ovf)
684 networks = reader.GetNetworkData()
685 self.assertEqual(networks, VIRTUALBOX_NETWORKS)
687 def testGetNetworkDataEmpty(self):
688 reader = ovf.OVFReader(self.empty_ovf)
689 networks = reader.GetNetworkData()
690 self.assertEqual(networks, EMPTY_NETWORKS)
692 def testGetHypervisorDataGaneti(self):
693 reader = ovf.OVFReader(self.ganeti_ovf)
694 hypervisor = reader.GetHypervisorData()
695 self.assertEqual(hypervisor, GANETI_HYPERVISOR)
697 def testGetHypervisorDataEmptyOvf(self):
698 reader = ovf.OVFReader(self.empty_ovf)
699 hypervisor = reader.GetHypervisorData()
700 self.assertEqual(hypervisor, EMPTY_HYPERVISOR)
702 def testGetOSDataGaneti(self):
703 reader = ovf.OVFReader(self.ganeti_ovf)
704 osys = reader.GetOSData()
705 self.assertEqual(osys, GANETI_OS)
707 def testGetOSDataEmptyOvf(self):
708 reader = ovf.OVFReader(self.empty_ovf)
709 osys = reader.GetOSData()
710 self.assertEqual(osys, EMPTY_OS)
712 def testGetBackendDataGaneti(self):
713 reader = ovf.OVFReader(self.ganeti_ovf)
714 backend = reader.GetBackendData()
715 self.assertEqual(backend, GANETI_BACKEND)
717 def testGetBackendDataVirtualbox(self):
718 reader = ovf.OVFReader(self.virtualbox_ovf)
719 backend = reader.GetBackendData()
720 self.assertEqual(backend, VIRTUALBOX_BACKEND)
722 def testGetBackendDataEmptyOvf(self):
723 reader = ovf.OVFReader(self.empty_ovf)
724 backend = reader.GetBackendData()
725 self.assertEqual(backend, EMPTY_BACKEND)
727 def testGetInstanceNameGaneti(self):
728 reader = ovf.OVFReader(self.ganeti_ovf)
729 name = reader.GetInstanceName()
730 self.assertEqual(name, GANETI_NAME)
732 def testGetInstanceNameDataEmptyOvf(self):
733 reader = ovf.OVFReader(self.empty_ovf)
734 name = reader.GetInstanceName()
735 self.assertEqual(name, EMPTY_NAME)
737 def testGetDiskTemplateGaneti(self):
738 reader = ovf.OVFReader(self.ganeti_ovf)
739 name = reader.GetDiskTemplate()
740 self.assertEqual(name, GANETI_TEMPLATE)
742 def testGetDiskTemplateEmpty(self):
743 reader = ovf.OVFReader(self.empty_ovf)
744 name = reader.GetDiskTemplate()
745 self.assertEqual(name, EMPTY_TEMPLATE)
747 def testGetTagsGaneti(self):
748 reader = ovf.OVFReader(self.ganeti_ovf)
749 tags = reader.GetTagsData()
750 self.assertEqual(tags, GANETI_TAGS)
752 def testGetTagsEmpty(self):
753 reader = ovf.OVFReader(self.empty_ovf)
754 tags = reader.GetTagsData()
755 self.assertEqual(tags, EMPTY_TAGS)
757 def testGetVersionGaneti(self):
758 reader = ovf.OVFReader(self.ganeti_ovf)
759 version = reader.GetVersionData()
760 self.assertEqual(version, GANETI_VERSION)
762 def testGetVersionEmpty(self):
763 reader = ovf.OVFReader(self.empty_ovf)
764 version = reader.GetVersionData()
765 self.assertEqual(version, EMPTY_VERSION)
768 class TestOVFWriter(BetterUnitTest):
770 self.writer = ovf.OVFWriter(True)
775 def testOVFWriterInit(self):
776 result = ET.tostring(self.writer.tree)
777 self.assertTrue(EXPORT_EMPTY in result)
779 def testSaveDisksDataEmpty(self):
780 self.writer.SaveDisksData([])
781 result = ET.tostring(self.writer.tree)
782 self.assertTrue(EXPORT_DISKS_EMPTY in result)
784 def testSaveDisksData(self):
785 self.writer.SaveDisksData(EXP_DISKS_LIST)
786 result = ET.tostring(self.writer.tree)
787 self.assertTrue(EXPORT_DISKS in result)
789 def testSaveNetworkDataEmpty(self):
790 self.writer.SaveNetworksData([])
791 result = ET.tostring(self.writer.tree)
792 self.assertTrue(EXPORT_NETWORKS_EMPTY in result)
794 def testSaveNetworksData(self):
795 self.writer.SaveNetworksData(EXP_NETWORKS_LIST)
796 result = ET.tostring(self.writer.tree)
797 self.assertTrue(EXPORT_NETWORKS in result)
799 def testSaveGanetiDataIncomplete(self):
800 self.writer.SaveGanetiData(EXP_PARTIAL_GANETI_DICT, EXP_NETWORKS_LIST)
801 result = ET.tostring(self.writer.tree)
802 self.assertTrue(EXPORT_GANETI_INCOMPLETE in result)
804 def testSaveGanetiDataComplete(self):
805 self.writer.SaveGanetiData(EXP_GANETI_DICT, EXP_NETWORKS_LIST)
806 result = ET.tostring(self.writer.tree)
807 self.assertTrue(EXPORT_GANETI in result)
809 def testSaveVirtualSystem(self):
810 self.writer.SaveDisksData(EXP_DISKS_LIST)
811 self.writer.SaveNetworksData(EXP_NETWORKS_LIST)
812 self.writer.SaveVirtualSystemData(EXP_NAME, EXP_VCPUS, EXP_MEMORY)
813 result = ET.tostring(self.writer.tree)
814 self.assertTrue(EXPORT_SYSTEM in result)
817 if __name__ == "__main__":
818 testutils.GanetiTestProgram()