Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.ovf_unittest.py @ 72bb6b4e

History | View | Annotate | Download (29.3 kB)

1
#!/usr/bin/python
2
#
3

    
4
# Copyright (C) 2011 Google Inc.
5
#
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.
10
#
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.
15
#
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
19
# 02110-1301, USA.
20

    
21

    
22
"""Script for testing ganeti.ovf.
23

24
"""
25

    
26
import optparse
27
import os
28
import os.path
29
import re
30
import shutil
31
import sys
32
import tempfile
33
import unittest
34

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

    
40
from ganeti import constants
41
from ganeti import errors
42
from ganeti import ovf
43
from ganeti import utils
44

    
45
import testutils
46

    
47
OUTPUT_DIR = "newdir"
48

    
49
GANETI_DISKS = {
50
  "disk_count": "1",
51
  "disk0_dump": "new_disk.raw",
52
  "disk0_size": "0",
53
  "disk0_ivname": "disk/0",
54
}
55
GANETI_NETWORKS = {
56
  "nic_count": "1",
57
  "nic0_mode": "bridged",
58
  "nic0_ip": "none",
59
  "nic0_mac": "aa:00:00:d8:2c:1e",
60
  "nic0_link": "xen-br0",
61
}
62
GANETI_HYPERVISOR = {
63
  "hypervisor_name": "xen-pvm",
64
  "root-path": "/dev/sda",
65
  "kernel_args": "ro",
66
}
67
GANETI_OS = {"os_name": "lenny-image"}
68
GANETI_BACKEND = {
69
  "vcpus": "1",
70
  "memory" : "2048",
71
  "auto_balance": "False",
72
}
73
GANETI_NAME = "ganeti-test-xen"
74
GANETI_TEMPLATE = "plain"
75
GANETI_TAGS = None
76
GANETI_VERSION = "0"
77

    
78
VIRTUALBOX_DISKS = {
79
  "disk_count": "2",
80
  "disk0_ivname": "disk/0",
81
  "disk0_dump": "new_disk.raw",
82
  "disk0_size": "0",
83
  "disk1_ivname": "disk/1",
84
  "disk1_dump": "second_disk.raw",
85
  "disk1_size": "0",
86
}
87
VIRTUALBOX_NETWORKS = {
88
  "nic_count": "1",
89
  "nic0_mode": "bridged",
90
  "nic0_ip": "none",
91
  "nic0_link": "auto",
92
  "nic0_mac": "auto",
93
}
94
VIRTUALBOX_HYPERVISOR = {"hypervisor_name": "auto"}
95
VIRTUALBOX_OS = {"os_name": None}
96
VIRTUALBOX_BACKEND = {
97
 "vcpus": "1",
98
  "memory" : "2048",
99
  "auto_balance": "auto",
100
}
101
VIRTUALBOX_NAME = None
102
VIRTUALBOX_TEMPLATE = None
103
VIRTUALBOX_TAGS = None
104
VIRTUALBOX_VERSION = None
105

    
106
EMPTY_DISKS = {}
107
EMPTY_NETWORKS = {}
108
EMPTY_HYPERVISOR = {"hypervisor_name": "auto"}
109
EMPTY_OS = {}
110
EMPTY_BACKEND = {
111
  "vcpus": "auto",
112
  "memory" : "auto",
113
  "auto_balance": "auto",
114
}
115
EMPTY_NAME = None
116
EMPTY_TEMPLATE = None
117
EMPTY_TAGS = None
118
EMPTY_VERSION = None
119

    
120
CMDARGS_DISKS = {
121
  "disk_count": "1",
122
  "disk0_ivname": "disk/0",
123
  "disk0_dump": "disk0.raw",
124
  "disk0_size": "8",
125
}
126
CMDARGS_NETWORKS = {
127
  "nic0_link": "auto",
128
  "nic0_mode": "bridged",
129
  "nic0_ip": "none",
130
  "nic0_mac": "auto",
131
  "nic_count": "1",
132
}
133
CMDARGS_HYPERVISOR = {
134
  "hypervisor_name": "xen-pvm"
135
}
136
CMDARGS_OS = {"os_name": "lenny-image"}
137
CMDARGS_BACKEND = {
138
  "auto_balance": False,
139
  "vcpus": "1",
140
  "memory": "256",
141
}
142
CMDARGS_NAME = "test-instance"
143
CMDARGS_TEMPLATE = "plain"
144
CMDARGS_TAGS = "test-tag-1,test-tag-2"
145

    
146
ARGS_EMPTY = {
147
  "output_dir": None,
148
  "nics": [],
149
  "disks": [],
150
  "name": "test-instance",
151
  "ova_package": False,
152
  "ext_usage": False,
153
  "disk_format": "cow",
154
  "compression": False,
155
}
156
ARGS_EXPORT_DIR = dict(ARGS_EMPTY, **{
157
  "output_dir": OUTPUT_DIR,
158
  "name": None,
159
  "hypervisor": None,
160
  "os": None,
161
  "beparams": {},
162
  "no_nics": False,
163
  "disk_template": None,
164
  "tags": None,
165
})
166
ARGS_VBOX = dict(ARGS_EXPORT_DIR, **{
167
  "output_dir": OUTPUT_DIR,
168
  "name": "test-instance",
169
  "os": "lenny-image",
170
  "hypervisor": ("xen-pvm", {}),
171
  "osparams":{},
172
  "disks": [],
173
})
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",
180
})
181
ARGS_BROKEN = dict(ARGS_EXPORT_DIR , **{
182
  "no_nics": True,
183
  "disk_template": "diskless",
184
  "name": "test-instance",
185
  "os": "lenny-image",
186
  "osparams": {},
187
})
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

    
314

    
315
def _GetArgs(args, with_name=False):
316
  options = optparse.Values()
317
  needed = args
318
  if with_name:
319
    needed["name"] = "test-instance"
320
  options._update_loose(needed)
321
  return options
322

    
323

    
324
OPTS_EMPTY = _GetArgs(ARGS_EMPTY)
325
OPTS_EXPORT_NO_NAME = _GetArgs(ARGS_EXPORT_DIR)
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

    
331
OPTS_VBOX = _GetArgs(ARGS_VBOX)
332
OPTS_COMPLETE = _GetArgs(ARGS_COMPLETE)
333
OPTS_NONIC_NODISK = _GetArgs(ARGS_BROKEN)
334

    
335

    
336
def _GetFullFilename(file_name):
337
  file_path = "%s/test/data/ovfdata/%s" % (testutils.GetSourceDir(),
338
    file_name)
339
  file_path = os.path.abspath(file_path)
340
  return file_path
341

    
342

    
343
class BetterUnitTest(unittest.TestCase):
344
  def assertRaisesRegexp(self, exception, regexp_val, function, *args):
345
    try:
346
      function(*args)
347
      self.fail("Expected raising %s" % exception)
348
    except exception, err:
349
      regexp = re.compile(regexp_val)
350
      if re.search(regexp, str(err)) == None:
351
        self.fail("Expected matching '%s', got '%s'" %
352
          (regexp_val, str(err)))
353

    
354

    
355
class TestOVFImporter(BetterUnitTest):
356
  def setUp(self):
357
    self.non_existing_file = _GetFullFilename("not_the_file.ovf")
358
    self.ganeti_ovf = _GetFullFilename("ganeti.ovf")
359
    self.virtualbox_ovf = _GetFullFilename("virtualbox.ovf")
360
    self.ova_package = _GetFullFilename("ova.ova")
361
    self.empty_ovf = _GetFullFilename("empty.ovf")
362
    self.wrong_extension = _GetFullFilename("wrong_extension.ovd")
363
    self.wrong_ova_archive = _GetFullFilename("wrong_ova.ova")
364
    self.no_ovf_in_ova = _GetFullFilename("no_ovf.ova")
365
    self.importer = None
366

    
367
  def tearDown(self):
368
    if self.importer:
369
      self.importer.Cleanup()
370
    del_dir = os.path.abspath(OUTPUT_DIR)
371
    try:
372
      shutil.rmtree(del_dir)
373
    except OSError:
374
      pass
375

    
376
  def testFileDoesNotExistError(self):
377
    self.assertRaisesRegexp(errors.OpPrereqError, "does not exist",
378
      ovf.OVFImporter, self.non_existing_file, None)
379

    
380
  def testWrongInputFileExtensionError(self):
381
    self.assertRaisesRegexp(errors.OpPrereqError,
382
      "Unknown file extension", ovf.OVFImporter,
383
      self.wrong_extension, None)
384

    
385
  def testOVAUnpackingDirectories(self):
386
    self.importer = ovf.OVFImporter(self.ova_package, OPTS_EMPTY)
387
    self.assertTrue(self.importer.input_dir != None)
388
    self.assertEquals(self.importer.output_dir , constants.EXPORT_DIR)
389
    self.assertTrue(self.importer.temp_dir != None)
390

    
391
  def testOVFUnpackingDirectories(self):
392
    self.importer = ovf.OVFImporter(self.virtualbox_ovf,
393
      OPTS_EMPTY)
394
    self.assertEquals(self.importer.input_dir , _GetFullFilename(""))
395
    self.assertEquals(self.importer.output_dir , constants.EXPORT_DIR)
396
    self.assertEquals(self.importer.temp_dir , None)
397

    
398
  def testOVFSetOutputDirDirectories(self):
399
    self.importer = ovf.OVFImporter(self.ganeti_ovf, OPTS_EXPORT)
400
    self.assertEquals(self.importer.input_dir , _GetFullFilename(""))
401
    self.assertTrue(OUTPUT_DIR in self.importer.output_dir)
402
    self.assertEquals(self.importer.temp_dir , None)
403

    
404
  def testWrongOVAArchiveError(self):
405
    self.assertRaisesRegexp(errors.OpPrereqError, "not a proper tar",
406
      ovf.OVFImporter, self.wrong_ova_archive, None)
407

    
408
  def testNoOVFFileInOVAPackageError(self):
409
    self.assertRaisesRegexp(errors.OpPrereqError, "No .ovf file",
410
      ovf.OVFImporter, self.no_ovf_in_ova, None)
411

    
412
  def testParseGanetiOvf(self):
413
    self.importer = ovf.OVFImporter(self.ganeti_ovf, OPTS_EXPORT_NO_NAME)
414
    self.importer.Parse()
415
    self.assertTrue("%s/ganeti-test-xen" % OUTPUT_DIR in
416
      self.importer.output_dir)
417
    self.assertEqual(self.importer.results_disk, GANETI_DISKS)
418
    self.assertEqual(self.importer.results_network, GANETI_NETWORKS)
419
    self.assertEqual(self.importer.results_hypervisor, GANETI_HYPERVISOR)
420
    self.assertEqual(self.importer.results_os, GANETI_OS)
421
    self.assertEqual(self.importer.results_backend, GANETI_BACKEND)
422
    self.assertEqual(self.importer.results_name, GANETI_NAME)
423
    self.assertEqual(self.importer.results_template, GANETI_TEMPLATE)
424
    self.assertEqual(self.importer.results_tags, GANETI_TAGS)
425
    self.assertEqual(self.importer.results_version, GANETI_VERSION)
426

    
427
  def testParseVirtualboxOvf(self):
428
    self.importer = ovf.OVFImporter(self.virtualbox_ovf, OPTS_VBOX)
429
    self.importer.Parse()
430
    self.assertTrue("%s/test-instance" % OUTPUT_DIR in self.importer.output_dir)
431
    self.assertEquals(self.importer.results_disk, VIRTUALBOX_DISKS)
432
    self.assertEquals(self.importer.results_network, VIRTUALBOX_NETWORKS)
433
    self.assertEquals(self.importer.results_hypervisor, CMDARGS_HYPERVISOR)
434
    self.assertEquals(self.importer.results_os, CMDARGS_OS)
435
    self.assertEquals(self.importer.results_backend, VIRTUALBOX_BACKEND)
436
    self.assertEquals(self.importer.results_name, CMDARGS_NAME)
437
    self.assertEquals(self.importer.results_template, VIRTUALBOX_TEMPLATE)
438
    self.assertEqual(self.importer.results_tags, VIRTUALBOX_TAGS)
439
    self.assertEqual(self.importer.results_version, constants.EXPORT_VERSION)
440

    
441
  def testParseEmptyOvf(self):
442
    self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
443
    self.importer.Parse()
444
    self.assertTrue("%s/test-instance" % OUTPUT_DIR in self.importer.output_dir)
445
    self.assertEquals(self.importer.results_disk, CMDARGS_DISKS)
446
    self.assertEquals(self.importer.results_network, CMDARGS_NETWORKS)
447
    self.assertEquals(self.importer.results_hypervisor, CMDARGS_HYPERVISOR)
448
    self.assertEquals(self.importer.results_os, CMDARGS_OS)
449
    self.assertEquals(self.importer.results_backend, CMDARGS_BACKEND)
450
    self.assertEquals(self.importer.results_name, CMDARGS_NAME)
451
    self.assertEquals(self.importer.results_template, CMDARGS_TEMPLATE)
452
    self.assertEqual(self.importer.results_tags, CMDARGS_TAGS)
453
    self.assertEqual(self.importer.results_version, constants.EXPORT_VERSION)
454

    
455
  def testParseNameOptions(self):
456
    self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
457
    results = self.importer._ParseNameOptions()
458
    self.assertEquals(results, CMDARGS_NAME)
459

    
460
  def testParseHypervisorOptions(self):
461
    self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
462
    results = self.importer._ParseHypervisorOptions()
463
    self.assertEquals(results, CMDARGS_HYPERVISOR)
464

    
465
  def testParseOSOptions(self):
466
    self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
467
    results = self.importer._ParseOSOptions()
468
    self.assertEquals(results, CMDARGS_OS)
469

    
470
  def testParseBackendOptions(self):
471
    self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
472
    results = self.importer._ParseBackendOptions()
473
    self.assertEquals(results, CMDARGS_BACKEND)
474

    
475
  def testParseTags(self):
476
    self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
477
    results = self.importer._ParseTags()
478
    self.assertEquals(results, CMDARGS_TAGS)
479

    
480
  def testParseNicOptions(self):
481
    self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
482
    results = self.importer._ParseNicOptions()
483
    self.assertEquals(results, CMDARGS_NETWORKS)
484

    
485
  def testParseDiskOptionsFromGanetiOVF(self):
486
    self.importer = ovf.OVFImporter(self.ganeti_ovf, OPTS_EXPORT)
487
    os.mkdir(OUTPUT_DIR)
488
    results = self.importer._GetDiskInfo()
489
    self.assertEquals(results, GANETI_DISKS)
490

    
491
  def testParseTemplateOptions(self):
492
    self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
493
    results = self.importer._ParseTemplateOptions()
494
    self.assertEquals(results, GANETI_TEMPLATE)
495

    
496
  def testParseDiskOptionsFromCmdLine(self):
497
    self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_COMPLETE)
498
    os.mkdir(OUTPUT_DIR)
499
    results = self.importer._ParseDiskOptions()
500
    self.assertEquals(results, CMDARGS_DISKS)
501

    
502
  def testGetDiskFormat(self):
503
    self.importer = ovf.OVFImporter(self.ganeti_ovf, OPTS_EXPORT)
504
    disks_list = self.importer.ovf_reader.GetDisksNames()
505
    results = [self.importer._GetDiskQemuInfo("%s/%s" %
506
      (self.importer.input_dir, path), "file format: (\S+)")
507
      for (path, _) in disks_list]
508
    self.assertEqual(results, ["vmdk"])
509

    
510
  def testNoInstanceNameOVF(self):
511
    self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_EXPORT_NO_NAME)
512
    self.assertRaisesRegexp(errors.OpPrereqError, "Name of instance",
513
      self.importer.Parse)
514

    
515
  def testErrorNoOSNameOVF(self):
516
    self.importer = ovf.OVFImporter(self.virtualbox_ovf, OPTS_EXPORT)
517
    self.assertRaisesRegexp(errors.OpPrereqError, "OS name",
518
      self.importer.Parse)
519

    
520
  def testErrorNoDiskAndNoNetwork(self):
521
    self.importer = ovf.OVFImporter(self.empty_ovf, OPTS_NONIC_NODISK)
522
    self.assertRaisesRegexp(errors.OpPrereqError,
523
      "Either disk specification or network"
524
      " description", self.importer.Parse)
525

    
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

    
613
class TestOVFReader(BetterUnitTest):
614
  def setUp(self):
615
    self.wrong_xml_file = _GetFullFilename("wrong_xml.ovf")
616
    self.ganeti_ovf = _GetFullFilename("ganeti.ovf")
617
    self.virtualbox_ovf = _GetFullFilename("virtualbox.ovf")
618
    self.corrupted_ovf = _GetFullFilename("corrupted_resources.ovf")
619
    self.wrong_manifest_ovf = _GetFullFilename("wrong_manifest.ovf")
620
    self.no_disk_in_ref_ovf = _GetFullFilename("no_disk_in_ref.ovf")
621
    self.empty_ovf = _GetFullFilename("empty.ovf")
622
    self.compressed_disk = _GetFullFilename("gzip_disk.ovf")
623

    
624
  def tearDown(self):
625
    pass
626

    
627
  def testXMLParsingError(self):
628
    self.assertRaisesRegexp(errors.OpPrereqError,
629
      "Error while reading .ovf", ovf.OVFReader, self.wrong_xml_file)
630

    
631
  def testFileInResourcesDoesNotExistError(self):
632
    self.assertRaisesRegexp(errors.OpPrereqError, "does not exist",
633
      ovf.OVFReader, self.corrupted_ovf)
634

    
635
  def testWrongManifestChecksumError(self):
636
    reader = ovf.OVFReader(self.wrong_manifest_ovf)
637
    self.assertRaisesRegexp(errors.OpPrereqError,
638
      "does not match the value in manifest file", reader.VerifyManifest)
639

    
640
  def testGoodManifestChecksum(self):
641
    reader = ovf.OVFReader(self.ganeti_ovf)
642
    self.assertEqual(reader.VerifyManifest(), None)
643

    
644
  def testGetDisksNamesOVFCorruptedError(self):
645
    reader = ovf.OVFReader(self.no_disk_in_ref_ovf)
646
    self.assertRaisesRegexp(errors.OpPrereqError,
647
      "not found in references", reader.GetDisksNames)
648

    
649
  def testGetDisksNamesVirtualbox(self):
650
    reader = ovf.OVFReader(self.virtualbox_ovf)
651
    disk_names = reader.GetDisksNames()
652
    expected_names = [
653
      ("new_disk.vmdk", None) ,
654
      ("second_disk.vmdk", None),
655
    ]
656
    self.assertEqual(sorted(disk_names), sorted(expected_names))
657

    
658
  def testGetDisksNamesEmpty(self):
659
    reader = ovf.OVFReader(self.empty_ovf)
660
    disk_names = reader.GetDisksNames()
661
    self.assertEqual(disk_names, [])
662

    
663
  def testGetDisksNamesCompressed(self):
664
    reader = ovf.OVFReader(self.compressed_disk)
665
    disk_names = reader.GetDisksNames()
666
    self.assertEqual(disk_names, [("compr_disk.vmdk.gz", "gzip")])
667

    
668
  def testGetNetworkDataGaneti(self):
669
    reader = ovf.OVFReader(self.ganeti_ovf)
670
    networks = reader.GetNetworkData()
671
    self.assertEqual(networks, GANETI_NETWORKS)
672

    
673
  def testGetNetworkDataVirtualbox(self):
674
    reader = ovf.OVFReader(self.virtualbox_ovf)
675
    networks = reader.GetNetworkData()
676
    self.assertEqual(networks, VIRTUALBOX_NETWORKS)
677

    
678
  def testGetNetworkDataEmpty(self):
679
    reader = ovf.OVFReader(self.empty_ovf)
680
    networks = reader.GetNetworkData()
681
    self.assertEqual(networks, EMPTY_NETWORKS)
682

    
683
  def testGetHypervisorDataGaneti(self):
684
    reader = ovf.OVFReader(self.ganeti_ovf)
685
    hypervisor = reader.GetHypervisorData()
686
    self.assertEqual(hypervisor, GANETI_HYPERVISOR)
687

    
688
  def testGetHypervisorDataEmptyOvf(self):
689
    reader = ovf.OVFReader(self.empty_ovf)
690
    hypervisor = reader.GetHypervisorData()
691
    self.assertEqual(hypervisor, EMPTY_HYPERVISOR)
692

    
693
  def testGetOSDataGaneti(self):
694
    reader = ovf.OVFReader(self.ganeti_ovf)
695
    osys = reader.GetOSData()
696
    self.assertEqual(osys, GANETI_OS)
697

    
698
  def testGetOSDataEmptyOvf(self):
699
    reader = ovf.OVFReader(self.empty_ovf)
700
    osys = reader.GetOSData()
701
    self.assertEqual(osys, EMPTY_OS)
702

    
703
  def testGetBackendDataGaneti(self):
704
    reader = ovf.OVFReader(self.ganeti_ovf)
705
    backend = reader.GetBackendData()
706
    self.assertEqual(backend, GANETI_BACKEND)
707

    
708
  def testGetBackendDataVirtualbox(self):
709
    reader = ovf.OVFReader(self.virtualbox_ovf)
710
    backend = reader.GetBackendData()
711
    self.assertEqual(backend, VIRTUALBOX_BACKEND)
712

    
713
  def testGetBackendDataEmptyOvf(self):
714
    reader = ovf.OVFReader(self.empty_ovf)
715
    backend = reader.GetBackendData()
716
    self.assertEqual(backend, EMPTY_BACKEND)
717

    
718
  def testGetInstanceNameGaneti(self):
719
    reader = ovf.OVFReader(self.ganeti_ovf)
720
    name = reader.GetInstanceName()
721
    self.assertEqual(name, GANETI_NAME)
722

    
723
  def testGetInstanceNameDataEmptyOvf(self):
724
    reader = ovf.OVFReader(self.empty_ovf)
725
    name = reader.GetInstanceName()
726
    self.assertEqual(name, EMPTY_NAME)
727

    
728
  def testGetDiskTemplateGaneti(self):
729
    reader = ovf.OVFReader(self.ganeti_ovf)
730
    name = reader.GetDiskTemplate()
731
    self.assertEqual(name, GANETI_TEMPLATE)
732

    
733
  def testGetDiskTemplateEmpty(self):
734
    reader = ovf.OVFReader(self.empty_ovf)
735
    name = reader.GetDiskTemplate()
736
    self.assertEqual(name, EMPTY_TEMPLATE)
737

    
738
  def testGetTagsGaneti(self):
739
    reader = ovf.OVFReader(self.ganeti_ovf)
740
    tags = reader.GetTagsData()
741
    self.assertEqual(tags, GANETI_TAGS)
742

    
743
  def testGetTagsEmpty(self):
744
    reader = ovf.OVFReader(self.empty_ovf)
745
    tags = reader.GetTagsData()
746
    self.assertEqual(tags, EMPTY_TAGS)
747

    
748
  def testGetVersionGaneti(self):
749
    reader = ovf.OVFReader(self.ganeti_ovf)
750
    version = reader.GetVersionData()
751
    self.assertEqual(version, GANETI_VERSION)
752

    
753
  def testGetVersionEmpty(self):
754
    reader = ovf.OVFReader(self.empty_ovf)
755
    version = reader.GetVersionData()
756
    self.assertEqual(version, EMPTY_VERSION)
757

    
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

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