Revision d92518d3

b/Makefile.am
82 82
	test \
83 83
	test/data \
84 84
	test/data/ovfdata \
85
	test/data/ovfdata/other \
85 86
	tools
86 87

  
87 88
BUILDTIME_DIR_AUTOCREATE = \
......
642 643
	test/data/proc_drbd83_sync_krnl2.6.39.txt \
643 644
	test/data/sys_drbd_usermode_helper.txt \
644 645
	test/data/ovfdata/compr_disk.vmdk.gz \
646
	test/data/ovfdata/config.ini \
645 647
	test/data/ovfdata/corrupted_resources.ovf \
648
	test/data/ovfdata/empty.ini \
646 649
	test/data/ovfdata/empty.ovf \
647 650
	test/data/ovfdata/ganeti.mf \
648 651
	test/data/ovfdata/ganeti.ovf \
649 652
	test/data/ovfdata/gzip_disk.ovf \
650 653
	test/data/ovfdata/new_disk.vmdk \
654
	test/data/ovfdata/no_disk.ini \
651 655
	test/data/ovfdata/no_disk_in_ref.ovf \
656
	test/data/ovfdata/no_os.ini \
652 657
	test/data/ovfdata/no_ovf.ova \
653 658
	test/data/ovfdata/ova.ova \
654 659
	test/data/ovfdata/second_disk.vmdk \
660
	test/data/ovfdata/rawdisk.raw \
661
	test/data/ovfdata/unsafe_path.ini \
655 662
	test/data/ovfdata/virtualbox.ovf \
656 663
	test/data/ovfdata/wrong_extension.ovd \
664
	test/data/ovfdata/wrong_config.ini \
657 665
	test/data/ovfdata/wrong_manifest.mf \
658 666
	test/data/ovfdata/wrong_manifest.ovf \
659 667
	test/data/ovfdata/wrong_ova.ova \
660 668
	test/data/ovfdata/wrong_xml.ovf \
669
	test/data/ovfdata/other/rawdisk.raw \
661 670
	test/import-export_unittest-helper
662 671

  
663 672
python_tests = \
b/test/data/ovfdata/config.ini
1
[instance]
2
disk0_dump = rawdisk.raw
3
nic0_mode = routed
4
name = ganeti-test-xen
5
hypervisor = xen-pvm
6
disk_count = 1
7
nic0_mac = aa:00:00:d8:2c:1e
8
nic_count = 1
9
nic0_link = br0
10
nic0_ip = None
11
disk0_ivname = disk/0
12
disk0_size = 0
13

  
14
[hypervisor]
15
root-path = /dev/sda
16
kernel_args = ro
17

  
18
[export]
19
version = 0
20
os = lenny-image
21

  
22
[os]
23

  
24
[backend]
25
auto_balance = False
26
vcpus = 1
27
memory = 512
b/test/data/ovfdata/empty.ini
1
[instance]
2
[hypervisor]
3
[export]
4
[os]
5
[backend]
b/test/data/ovfdata/no_disk.ini
1
[instance]
2
disk0_dump = iamnothere.raw
3
nic0_mode = nic
4
name = ganeti-test-xen
5
disk_count = 1
6
nic0_mac = aa:00:00:d8:2c:1e
7
nic_count = 1
8
nic0_link = xen-br0
9
nic0_ip = None
10
disk0_ivname = disk/0
11
disk0_size = 0
12

  
13
[hypervisor]
14
root-path = /dev/sda
15
kernel_args = ro
16

  
17
[export]
18
version = 0
19

  
20
[os]
21

  
22
[backend]
23
auto_balance = False
b/test/data/ovfdata/no_os.ini
1
[instance]
2
disk0_dump = rawdisk.raw
3
nic0_mode = bridged
4
name = ganeti-test-xen
5
hypervisor = xen-pvm
6
disk_count = 1
7
nic0_mac = aa:00:00:d8:2c:1e
8
nic_count = 1
9
nic0_link = xen-br0
10
nic0_ip = None
11
disk0_ivname = disk/0
12
disk0_size = 0
13

  
14
[hypervisor]
15
root-path = /dev/sda
16
kernel_args = ro
17

  
18
[export]
19
version = 0
20

  
21
[os]
22

  
23
[backend]
24
auto_balance = False
25
vcpus = 1
26
memory = 2048
b/test/data/ovfdata/unsafe_path.ini
1
[instance]
2
disk0_dump = other/rawdisk.raw
3
nic0_mode = bridged
4
name = ganeti-test-xen
5
hypervisor = xen-pvm
6
disk_count = 1
7
nic0_mac = aa:00:00:d8:2c:1e
8
nic_count = 1
9
nic0_link = xen-br0
10
nic0_ip = None
11
disk0_ivname = disk/0
12
disk0_size = 0
13

  
14
[hypervisor]
15
root-path = /dev/sda
16
kernel_args = ro
17

  
18
[export]
19
version = 0
20
os = lenny-image
21

  
22
[os]
23

  
24
[backend]
25
auto_balance = False
26
vcpus = 1
27
memory = 2048
b/test/data/ovfdata/wrong_config.ini
1
It's just wrong
b/test/ganeti.ovf_unittest.py
32 32
import tempfile
33 33
import unittest
34 34

  
35
try:
36
  import xml.etree.ElementTree as ET
37
except ImportError:
38
  import elementtree.ElementTree as ET
39

  
35 40
from ganeti import constants
36 41
from ganeti import errors
37 42
from ganeti import ovf
......
143 148
  "nics": [],
144 149
  "disks": [],
145 150
  "name": "test-instance",
151
  "ova_package": False,
152
  "ext_usage": False,
153
  "disk_format": "cow",
154
  "compression": False,
146 155
}
147 156
ARGS_EXPORT_DIR = dict(ARGS_EMPTY, **{
148 157
  "output_dir": OUTPUT_DIR,
......
177 186
  "osparams": {},
178 187
})
179 188

  
189
EXP_ARGS_COMPRESSED = dict(ARGS_EXPORT_DIR, **{
190
  "compression": True,
191
})
192

  
193
EXP_DISKS_LIST = [
194
  {
195
    "format": "vmdk",
196
    "compression": "gzip",
197
    "virt-size": 90000,
198
    "real-size": 203,
199
    "path": "new_disk.cow.gz",
200
  },
201
  {
202
    "format": "cow",
203
    "virt-size": 15,
204
    "real-size": 15,
205
    "path": "new_disk.cow",
206
  },
207
]
208
EXP_NETWORKS_LIST = [
209
  {"mac": "aa:00:00:d8:2c:1e", "ip":"None", "link":"br0","mode":"routed"},
210
]
211
EXP_PARTIAL_GANETI_DICT = {
212
  "hypervisor": {"name": "xen-kvm"},
213
  "os": {"name": "lenny-image"},
214
  "auto_balance": "True",
215
  "version": "0",
216
}
217
EXP_GANETI_DICT = {
218
  'tags': None,
219
  'auto_balance': 'False',
220
  'hypervisor': {
221
     'root-path': '/dev/sda',
222
     'name': 'xen-pvm',
223
     'kernel_args': 'ro'
224
   },
225
  'version': '0',
226
  'disk_template': None,
227
  'os': {'name': 'lenny-image'}
228
}
229
EXP_NAME ="xen-dev-i1"
230
EXP_VCPUS = 1
231
EXP_MEMORY = 512
232

  
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 />"
241
EXPORT_DISKS = ("<References><File ovf:compression=\"gzip\" ovf:href=\"new_disk"
242
                ".cow.gz\" ovf:id=\"file0\" ovf:size=\"203\" /><File ovf:href="
243
                "\"new_disk.cow\" ovf:id=\"file1\" ovf:size=\"15\" />"
244
                "</References><DiskSection><Disk ovf:capacity=\"90000\""
245
                " ovf:diskId=\"disk0\" ovf:fileRef=\"file0\" ovf:format=\"http"
246
                "://www.vmware.com/interfaces/specifications/vmdk.html"
247
                "#monolithicSparse\" /><Disk ovf:capacity=\"15\" ovf:diskId="
248
                "\"disk1\" ovf:fileRef=\"file1\" ovf:format=\"http://www.gnome"
249
                ".org/~markmc/qcow-image-format.html\" /></DiskSection>")
250
EXPORT_NETWORKS_EMPTY = "<NetworkSection />"
251
EXPORT_NETWORKS = ("<NetworkSection><Network ovf:name=\"routed0\" />"
252
                   "</NetworkSection>")
253
EXPORT_GANETI_INCOMPLETE = ("<gnt:GanetiSection><gnt:Version>0</gnt:Version>"
254
                            "<gnt:AutoBalance>True</gnt:AutoBalance><gnt:"
255
                            "OperatingSystem><gnt:Name>lenny-image</gnt:Name>"
256
                            "<gnt:Parameters /></gnt:OperatingSystem><gnt:"
257
                            "Hypervisor><gnt:Name>xen-kvm</gnt:Name><gnt:"
258
                            "Parameters /></gnt:Hypervisor><gnt:Network><gnt:"
259
                            "Nic ovf:name=\"routed0\"><gnt:Mode>routed</gnt:"
260
                            "Mode><gnt:MACAddress>aa:00:00:d8:2c:1e</gnt:"
261
                            "MACAddress><gnt:IPAddress>None</gnt:IPAddress>"
262
                            "<gnt:Link>br0</gnt:Link></gnt:Nic></gnt:Network>"
263
                            "</gnt:GanetiSection>")
264
EXPORT_GANETI = ("<gnt:GanetiSection><gnt:Version>0</gnt:Version><gnt:"
265
                 "AutoBalance>False</gnt:AutoBalance><gnt:OperatingSystem>"
266
                 "<gnt:Name>lenny-image</gnt:Name><gnt:Parameters /></gnt:"
267
                 "OperatingSystem><gnt:Hypervisor><gnt:Name>xen-pvm</gnt:Name>"
268
                 "<gnt:Parameters><gnt:root-path>/dev/sda</gnt:root-path><gnt:"
269
                 "kernel_args>ro</gnt:kernel_args></gnt:Parameters></gnt:"
270
                 "Hypervisor><gnt:Network><gnt:Nic ovf:name=\"routed0\"><gnt:"
271
                 "Mode>routed</gnt:Mode><gnt:MACAddress>aa:00:00:d8:2c:1e</gnt:"
272
                 "MACAddress><gnt:IPAddress>None</gnt:IPAddress><gnt:Link>br0"
273
                 "</gnt:Link></gnt:Nic></gnt:Network></gnt:GanetiSection>")
274
EXPORT_SYSTEM = ("<References><File ovf:compression=\"gzip\" ovf:href=\"new_"
275
                 "disk.cow.gz\" ovf:id=\"file0\" ovf:size=\"203\" /><File ovf:"
276
                 "href=\"new_disk.cow\" ovf:id=\"file1\" ovf:size=\"15\" />"
277
                 "</References><DiskSection><Disk ovf:capacity=\"90000\" ovf:"
278
                 "diskId=\"disk0\" ovf:fileRef=\"file0\" ovf:format=\"http://"
279
                 "www.vmware.com/interfaces/specifications/vmdk.html#monolithic"
280
                 "Sparse\" /><Disk ovf:capacity=\"15\" ovf:diskId=\"disk1\""
281
                 " ovf:fileRef=\"file1\" ovf:format=\"http://www.gnome.org/"
282
                 "~markmc/qcow-image-format.html\" /></DiskSection><Network"
283
                 "Section><Network ovf:name=\"routed0\" /></NetworkSection>"
284
                 "<VirtualSystem ovf:id=\"xen-dev-i1\"><Name>xen-dev-i1</Name>"
285
                 "<OperatingSystemSection ovf:id=\"0\" /><VirtualHardware"
286
                 "Section><System><vssd:ElementName>Virtual Hardware Family"
287
                 "</vssd:ElementName><vssd:InstanceId>0</vssd:InstanceId><vssd:"
288
                 "VirtualSystemIdentifier>xen-dev-i1</vssd:VirtualSystem"
289
                 "Identifier><vssd:VirtualSystemType>ganeti-ovf</vssd:Virtual"
290
                 "SystemType></System><Item><rasd:ElementName>1 virtual CPU(s)"
291
                 "</rasd:ElementName><rasd:InstanceID>1</rasd:InstanceID><rasd:"
292
                 "ResourceType>3</rasd:ResourceType><rasd:VirtualQuantity>1"
293
                 "</rasd:VirtualQuantity></Item><Item><rasd:AllocationUnits>"
294
                 "byte * 2^20</rasd:AllocationUnits><rasd:ElementName>512MB of"
295
                 " memory</rasd:ElementName><rasd:InstanceID>2</rasd:"
296
                 "InstanceID><rasd:ResourceType>4</rasd:ResourceType><rasd:"
297
                 "VirtualQuantity>512</rasd:VirtualQuantity></Item><Item>"
298
                 "<rasd:Address>0</rasd:Address><rasd:ElementName>scsi"
299
                 "_controller0</rasd:ElementName><rasd:ResourceType>6</rasd"
300
                 ":ResourceType><rasd:InstanceId>3</rasd:InstanceId></Item>"
301
                 "<Item><rasd:ElementName>disk0</rasd:ElementName><rasd:"
302
                 "ResourceType>17</rasd:ResourceType><rasd:HostResource>ovf:/"
303
                 "disk/disk0</rasd:HostResource><rasd:Parent>3</rasd:Parent>"
304
                 "<rasd:InstanceID>4</rasd:InstanceID></Item><Item><rasd:"
305
                 "ElementName>disk1</rasd:ElementName><rasd:ResourceType>17"
306
                 "</rasd:ResourceType><rasd:HostResource>ovf:/disk/disk1</rasd:"
307
                 "HostResource><rasd:Parent>3</rasd:Parent><rasd:InstanceID>5"
308
                 "</rasd:InstanceID></Item><Item><rasd:ElementName>routed0"
309
                 "</rasd:ElementName><rasd:ResourceType>10</rasd:ResourceType>"
310
                 "<rasd:Connection>routed0</rasd:Connection><rasd:Address>aa:00"
311
                 ":00:d8:2c:1e</rasd:Address><rasd:InstanceID>6</rasd:Instance"
312
                 "ID></Item></VirtualHardwareSection></VirtualSystem>")
313

  
180 314

  
181 315
def _GetArgs(args, with_name=False):
182 316
  options = optparse.Values()
......
190 324
OPTS_EMPTY = _GetArgs(ARGS_EMPTY)
191 325
OPTS_EXPORT_NO_NAME = _GetArgs(ARGS_EXPORT_DIR)
192 326
OPTS_EXPORT = _GetArgs(ARGS_EXPORT_DIR, with_name=True)
327

  
328
EXP_OPTS = OPTS_EXPORT_NO_NAME
329
EXP_OPTS_COMPRESSED = _GetArgs(EXP_ARGS_COMPRESSED)
330

  
193 331
OPTS_VBOX = _GetArgs(ARGS_VBOX)
194 332
OPTS_COMPLETE = _GetArgs(ARGS_COMPLETE)
195 333
OPTS_NONIC_NODISK = _GetArgs(ARGS_BROKEN)
......
386 524
      " description", self.importer.Parse)
387 525

  
388 526

  
527
class TestOVFExporter(BetterUnitTest):
528
  def setUp(self):
529
    self.exporter = None
530
    self.wrong_config_file = _GetFullFilename("wrong_config.ini")
531
    self.unsafe_path_to_disk = _GetFullFilename("unsafe_path.ini")
532
    self.disk_image_not_exist = _GetFullFilename("no_disk.ini")
533
    self.empty_config = _GetFullFilename("empty.ini")
534
    self.standard_export = _GetFullFilename("config.ini")
535
    self.wrong_network_mode = self.disk_image_not_exist
536
    self.no_memory = self.disk_image_not_exist
537
    self.no_vcpus = self.disk_image_not_exist
538
    self.no_os = _GetFullFilename("no_os.ini")
539
    self.no_hypervisor = self.disk_image_not_exist
540

  
541
  def tearDown(self):
542
    if self.exporter:
543
      self.exporter.Cleanup()
544
    del_dir = os.path.abspath(OUTPUT_DIR)
545
    try:
546
      shutil.rmtree(del_dir)
547
    except OSError:
548
      pass
549

  
550
  def testErrorWrongConfigFile(self):
551
    self.assertRaisesRegexp(errors.OpPrereqError,
552
      "Error when trying to read", ovf.OVFExporter,
553
      self.wrong_config_file, EXP_OPTS)
554

  
555
  def testErrorPathToTheDiskIncorrect(self):
556
    self.exporter = ovf.OVFExporter(self.unsafe_path_to_disk, EXP_OPTS)
557
    self.assertRaisesRegexp(errors.OpPrereqError, "contains a directory name",
558
      self.exporter._ParseDisks)
559

  
560
  def testErrorDiskImageNotExist(self):
561
    self.exporter = ovf.OVFExporter(self.disk_image_not_exist, EXP_OPTS)
562
    self.assertRaisesRegexp(errors.OpPrereqError, "Disk image does not exist",
563
      self.exporter._ParseDisks)
564

  
565
  def testParseNetworks(self):
566
    self.exporter = ovf.OVFExporter(self.standard_export, EXP_OPTS)
567
    results = self.exporter._ParseNetworks()
568
    self.assertEqual(results, EXP_NETWORKS_LIST)
569

  
570
  def testErrorWrongNetworkMode(self):
571
    self.exporter = ovf.OVFExporter(self.wrong_network_mode, EXP_OPTS)
572
    self.assertRaisesRegexp(errors.OpPrereqError,
573
      "Network mode nic not recognized", self.exporter._ParseNetworks)
574

  
575
  def testParseVCPusMem(self):
576
    self.exporter = ovf.OVFExporter(self.standard_export, EXP_OPTS)
577
    vcpus = self.exporter._ParseVCPUs()
578
    memory = self.exporter._ParseMemory()
579
    self.assertEqual(vcpus, EXP_VCPUS)
580
    self.assertEqual(memory, EXP_MEMORY)
581

  
582
  def testErrorNoVCPUs(self):
583
    self.exporter = ovf.OVFExporter(self.no_vcpus, EXP_OPTS)
584
    self.assertRaisesRegexp(errors.OpPrereqError, "No CPU information found",
585
      self.exporter._ParseVCPUs)
586

  
587
  def testErrorNoMemory(self):
588
    self.exporter = ovf.OVFExporter(self.no_memory, EXP_OPTS)
589
    self.assertRaisesRegexp(errors.OpPrereqError, "No memory information found",
590
      self.exporter._ParseMemory)
591

  
592
  def testParseGaneti(self):
593
    self.exporter = ovf.OVFExporter(self.standard_export, EXP_OPTS)
594
    results = self.exporter._ParseGaneti()
595
    self.assertEqual(results, EXP_GANETI_DICT)
596

  
597
  def testErrorNoHypervisor(self):
598
    self.exporter = ovf.OVFExporter(self.no_hypervisor, EXP_OPTS)
599
    self.assertRaisesRegexp(errors.OpPrereqError,
600
      "No hypervisor information found", self.exporter._ParseGaneti)
601

  
602
  def testErrorNoOS(self):
603
    self.exporter = ovf.OVFExporter(self.no_os, EXP_OPTS)
604
    self.assertRaisesRegexp(errors.OpPrereqError,
605
      "No operating system information found", self.exporter._ParseGaneti)
606

  
607
  def testErrorParseNoInstanceName(self):
608
    self.exporter = ovf.OVFExporter(self.empty_config, EXP_OPTS)
609
    self.assertRaisesRegexp(errors.OpPrereqError, "No instance name found",
610
      self.exporter.Parse)
611

  
612

  
389 613
class TestOVFReader(BetterUnitTest):
390 614
  def setUp(self):
391 615
    self.wrong_xml_file = _GetFullFilename("wrong_xml.ovf")
......
532 756
    self.assertEqual(version, EMPTY_VERSION)
533 757

  
534 758

  
759
class TestOVFWriter(BetterUnitTest):
760
  def setUp(self):
761
    self.writer = ovf.OVFWriter(True)
762

  
763
  def tearDown(self):
764
    pass
765

  
766
  def testOVFWriterInit(self):
767
    result = ET.tostring(self.writer.tree)
768
    self.assertTrue(EXPORT_EMPTY in result)
769

  
770
  def testSaveDisksDataEmpty(self):
771
    self.writer.SaveDisksData([])
772
    result = ET.tostring(self.writer.tree)
773
    self.assertTrue(EXPORT_DISKS_EMPTY in result)
774

  
775
  def testSaveDisksData(self):
776
    self.writer.SaveDisksData(EXP_DISKS_LIST)
777
    result = ET.tostring(self.writer.tree)
778
    self.assertTrue(EXPORT_DISKS in result)
779

  
780
  def testSaveNetworkDataEmpty(self):
781
    self.writer.SaveNetworksData([])
782
    result = ET.tostring(self.writer.tree)
783
    self.assertTrue(EXPORT_NETWORKS_EMPTY in result)
784

  
785
  def testSaveNetworksData(self):
786
    self.writer.SaveNetworksData(EXP_NETWORKS_LIST)
787
    result = ET.tostring(self.writer.tree)
788
    self.assertTrue(EXPORT_NETWORKS in result)
789

  
790
  def testSaveGanetiDataIncomplete(self):
791
    self.writer.SaveGanetiData(EXP_PARTIAL_GANETI_DICT, EXP_NETWORKS_LIST)
792
    result = ET.tostring(self.writer.tree)
793
    self.assertTrue(EXPORT_GANETI_INCOMPLETE in result)
794

  
795
  def testSaveGanetiDataComplete(self):
796
    self.writer.SaveGanetiData(EXP_GANETI_DICT, EXP_NETWORKS_LIST)
797
    result = ET.tostring(self.writer.tree)
798
    self.assertTrue(EXPORT_GANETI in result)
799

  
800
  def testSaveVirtualSystem(self):
801
    self.writer.SaveDisksData(EXP_DISKS_LIST)
802
    self.writer.SaveNetworksData(EXP_NETWORKS_LIST)
803
    self.writer.SaveVirtualSystemData(EXP_NAME, EXP_VCPUS, EXP_MEMORY)
804
    result = ET.tostring(self.writer.tree)
805
    self.assertTrue(EXPORT_SYSTEM in result)
806

  
807

  
535 808
if __name__ == "__main__":
536 809
  testutils.GanetiTestProgram()

Also available in: Unified diff