~rackspace-titan/nova/instance_states

« back to all changes in this revision

Viewing changes to nova/tests/test_virt_drivers.py

  • Committer: Brian Lamar
  • Date: 2011-08-26 18:43:27 UTC
  • mfrom: (1443.2.57 nova)
  • Revision ID: brian.lamar@rackspace.com-20110826184327-isqh61bp35kpzg1b
Merged trunk and fixed conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
2
#
 
3
#    Copyright 2010 OpenStack LLC
 
4
#
 
5
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 
6
#    not use this file except in compliance with the License. You may obtain
 
7
#    a copy of the License at
 
8
#
 
9
#         http://www.apache.org/licenses/LICENSE-2.0
 
10
#
 
11
#    Unless required by applicable law or agreed to in writing, software
 
12
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
13
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
14
#    License for the specific language governing permissions and limitations
 
15
#    under the License.
 
16
 
 
17
import base64
 
18
import netaddr
 
19
import sys
 
20
import traceback
 
21
 
 
22
from nova import exception
 
23
from nova import flags
 
24
from nova import image
 
25
from nova import log as logging
 
26
from nova import test
 
27
from nova.tests import utils as test_utils
 
28
 
 
29
libvirt = None
 
30
FLAGS = flags.FLAGS
 
31
 
 
32
LOG = logging.getLogger('nova.tests.test_virt_drivers')
 
33
 
 
34
 
 
35
def catch_notimplementederror(f):
 
36
    """Decorator to simplify catching drivers raising NotImplementedError
 
37
 
 
38
    If a particular call makes a driver raise NotImplementedError, we
 
39
    log it so that we can extract this information afterwards to
 
40
    automatically generate a hypervisor/feature support matrix."""
 
41
    def wrapped_func(self, *args, **kwargs):
 
42
        try:
 
43
            return f(self, *args, **kwargs)
 
44
        except NotImplementedError:
 
45
            frame = traceback.extract_tb(sys.exc_info()[2])[-1]
 
46
            LOG.error('%(driver)s does not implement %(method)s' % {
 
47
                                               'driver': type(self.connection),
 
48
                                               'method': frame[2]})
 
49
 
 
50
    wrapped_func.__name__ = f.__name__
 
51
    wrapped_func.__doc__ = f.__doc__
 
52
    return wrapped_func
 
53
 
 
54
 
 
55
class _VirtDriverTestCase(test.TestCase):
 
56
    def setUp(self):
 
57
        super(_VirtDriverTestCase, self).setUp()
 
58
        self.connection = self.driver_module.get_connection('')
 
59
        self.ctxt = test_utils.get_test_admin_context()
 
60
        self.image_service = image.get_default_image_service()
 
61
 
 
62
    @catch_notimplementederror
 
63
    def test_init_host(self):
 
64
        self.connection.init_host('myhostname')
 
65
 
 
66
    @catch_notimplementederror
 
67
    def test_list_instances(self):
 
68
        self.connection.list_instances()
 
69
 
 
70
    @catch_notimplementederror
 
71
    def test_list_instances_detail(self):
 
72
        self.connection.list_instances_detail()
 
73
 
 
74
    @catch_notimplementederror
 
75
    def test_spawn(self):
 
76
        instance_ref = test_utils.get_test_instance()
 
77
        network_info = test_utils.get_test_network_info()
 
78
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
79
 
 
80
        domains = self.connection.list_instances()
 
81
        self.assertIn(instance_ref['name'], domains)
 
82
 
 
83
        domains_details = self.connection.list_instances_detail()
 
84
        self.assertIn(instance_ref['name'], [i.name for i in domains_details])
 
85
 
 
86
    @catch_notimplementederror
 
87
    def test_snapshot_not_running(self):
 
88
        instance_ref = test_utils.get_test_instance()
 
89
        img_ref = self.image_service.create(self.ctxt, {'name': 'snap-1'})
 
90
        self.assertRaises(exception.InstanceNotRunning,
 
91
                          self.connection.snapshot,
 
92
                          self.ctxt, instance_ref, img_ref['id'])
 
93
 
 
94
    @catch_notimplementederror
 
95
    def test_snapshot_running(self):
 
96
        instance_ref = test_utils.get_test_instance()
 
97
        network_info = test_utils.get_test_network_info()
 
98
        img_ref = self.image_service.create(self.ctxt, {'name': 'snap-1'})
 
99
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
100
        self.connection.snapshot(self.ctxt, instance_ref, img_ref['id'])
 
101
 
 
102
    @catch_notimplementederror
 
103
    def test_reboot(self):
 
104
        instance_ref = test_utils.get_test_instance()
 
105
        network_info = test_utils.get_test_network_info()
 
106
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
107
        self.connection.reboot(instance_ref, network_info)
 
108
 
 
109
    @catch_notimplementederror
 
110
    def test_get_host_ip_addr(self):
 
111
        host_ip = self.connection.get_host_ip_addr()
 
112
 
 
113
        # Will raise an exception if it's not a valid IP at all
 
114
        ip = netaddr.IPAddress(host_ip)
 
115
 
 
116
        # For now, assume IPv4.
 
117
        self.assertEquals(ip.version, 4)
 
118
 
 
119
    @catch_notimplementederror
 
120
    def test_resize_running(self):
 
121
        instance_ref = test_utils.get_test_instance()
 
122
        network_info = test_utils.get_test_network_info()
 
123
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
124
        self.connection.resize(instance_ref, 7)
 
125
 
 
126
    @catch_notimplementederror
 
127
    def test_set_admin_password(self):
 
128
        instance_ref = test_utils.get_test_instance()
 
129
        network_info = test_utils.get_test_network_info()
 
130
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
131
        self.connection.set_admin_password(instance_ref, 'p4ssw0rd')
 
132
 
 
133
    @catch_notimplementederror
 
134
    def test_inject_file(self):
 
135
        instance_ref = test_utils.get_test_instance()
 
136
        network_info = test_utils.get_test_network_info()
 
137
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
138
        self.connection.inject_file(instance_ref,
 
139
                                    base64.b64encode('/testfile'),
 
140
                                    base64.b64encode('testcontents'))
 
141
 
 
142
    @catch_notimplementederror
 
143
    def test_agent_update(self):
 
144
        instance_ref = test_utils.get_test_instance()
 
145
        network_info = test_utils.get_test_network_info()
 
146
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
147
        self.connection.agent_update(instance_ref, 'http://www.openstack.org/',
 
148
                                     'd41d8cd98f00b204e9800998ecf8427e')
 
149
 
 
150
    @catch_notimplementederror
 
151
    def test_rescue(self):
 
152
        instance_ref = test_utils.get_test_instance()
 
153
        network_info = test_utils.get_test_network_info()
 
154
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
155
        self.connection.rescue(self.ctxt, instance_ref,
 
156
                               lambda x: None, network_info)
 
157
 
 
158
    @catch_notimplementederror
 
159
    def test_unrescue_unrescued_instance(self):
 
160
        instance_ref = test_utils.get_test_instance()
 
161
        network_info = test_utils.get_test_network_info()
 
162
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
163
        self.connection.unrescue(instance_ref, lambda x: None, network_info)
 
164
 
 
165
    @catch_notimplementederror
 
166
    def test_unrescue_rescued_instance(self):
 
167
        instance_ref = test_utils.get_test_instance()
 
168
        network_info = test_utils.get_test_network_info()
 
169
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
170
        self.connection.rescue(self.ctxt, instance_ref,
 
171
                               lambda x: None, network_info)
 
172
        self.connection.unrescue(instance_ref, lambda x: None, network_info)
 
173
 
 
174
    @catch_notimplementederror
 
175
    def test_poll_rescued_instances(self):
 
176
        self.connection.poll_rescued_instances(10)
 
177
 
 
178
    @catch_notimplementederror
 
179
    def test_migrate_disk_and_power_off(self):
 
180
        instance_ref = test_utils.get_test_instance()
 
181
        network_info = test_utils.get_test_network_info()
 
182
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
183
        self.connection.migrate_disk_and_power_off(instance_ref, 'dest_host')
 
184
 
 
185
    @catch_notimplementederror
 
186
    def test_pause(self):
 
187
        instance_ref = test_utils.get_test_instance()
 
188
        network_info = test_utils.get_test_network_info()
 
189
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
190
        self.connection.pause(instance_ref, None)
 
191
 
 
192
    @catch_notimplementederror
 
193
    def test_unpause_unpaused_instance(self):
 
194
        instance_ref = test_utils.get_test_instance()
 
195
        network_info = test_utils.get_test_network_info()
 
196
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
197
        self.connection.unpause(instance_ref, None)
 
198
 
 
199
    @catch_notimplementederror
 
200
    def test_unpause_paused_instance(self):
 
201
        instance_ref = test_utils.get_test_instance()
 
202
        network_info = test_utils.get_test_network_info()
 
203
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
204
        self.connection.pause(instance_ref, None)
 
205
        self.connection.unpause(instance_ref, None)
 
206
 
 
207
    @catch_notimplementederror
 
208
    def test_suspend(self):
 
209
        instance_ref = test_utils.get_test_instance()
 
210
        network_info = test_utils.get_test_network_info()
 
211
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
212
        self.connection.suspend(instance_ref, None)
 
213
 
 
214
    @catch_notimplementederror
 
215
    def test_resume_unsuspended_instance(self):
 
216
        instance_ref = test_utils.get_test_instance()
 
217
        network_info = test_utils.get_test_network_info()
 
218
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
219
        self.connection.resume(instance_ref, None)
 
220
 
 
221
    @catch_notimplementederror
 
222
    def test_resume_suspended_instance(self):
 
223
        instance_ref = test_utils.get_test_instance()
 
224
        network_info = test_utils.get_test_network_info()
 
225
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
226
        self.connection.suspend(instance_ref, None)
 
227
        self.connection.resume(instance_ref, None)
 
228
 
 
229
    @catch_notimplementederror
 
230
    def test_destroy_instance_nonexistant(self):
 
231
        fake_instance = {'id': 42, 'name': 'I just made this up!'}
 
232
        network_info = test_utils.get_test_network_info()
 
233
        self.connection.destroy(fake_instance, network_info)
 
234
 
 
235
    @catch_notimplementederror
 
236
    def test_destroy_instance(self):
 
237
        instance_ref = test_utils.get_test_instance()
 
238
        network_info = test_utils.get_test_network_info()
 
239
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
240
        self.assertIn(instance_ref['name'],
 
241
                      self.connection.list_instances())
 
242
        self.connection.destroy(instance_ref, network_info)
 
243
        self.assertNotIn(instance_ref['name'],
 
244
                         self.connection.list_instances())
 
245
 
 
246
    @catch_notimplementederror
 
247
    def test_attach_detach_volume(self):
 
248
        network_info = test_utils.get_test_network_info()
 
249
        instance_ref = test_utils.get_test_instance()
 
250
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
251
        self.connection.attach_volume(instance_ref['name'],
 
252
                                      '/dev/null', '/mnt/nova/something')
 
253
        self.connection.detach_volume(instance_ref['name'],
 
254
                                      '/mnt/nova/something')
 
255
 
 
256
    @catch_notimplementederror
 
257
    def test_get_info(self):
 
258
        network_info = test_utils.get_test_network_info()
 
259
        instance_ref = test_utils.get_test_instance()
 
260
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
261
        info = self.connection.get_info(instance_ref['name'])
 
262
        self.assertIn('state', info)
 
263
        self.assertIn('max_mem', info)
 
264
        self.assertIn('mem', info)
 
265
        self.assertIn('num_cpu', info)
 
266
        self.assertIn('cpu_time', info)
 
267
 
 
268
    @catch_notimplementederror
 
269
    def test_get_info_for_unknown_instance(self):
 
270
        self.assertRaises(exception.NotFound,
 
271
                          self.connection.get_info, 'I just made this name up')
 
272
 
 
273
    @catch_notimplementederror
 
274
    def test_get_diagnostics(self):
 
275
        network_info = test_utils.get_test_network_info()
 
276
        instance_ref = test_utils.get_test_instance()
 
277
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
278
        self.connection.get_diagnostics(instance_ref['name'])
 
279
 
 
280
    @catch_notimplementederror
 
281
    def test_list_disks(self):
 
282
        network_info = test_utils.get_test_network_info()
 
283
        instance_ref = test_utils.get_test_instance()
 
284
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
285
        self.connection.list_disks(instance_ref['name'])
 
286
 
 
287
    @catch_notimplementederror
 
288
    def test_list_interfaces(self):
 
289
        network_info = test_utils.get_test_network_info()
 
290
        instance_ref = test_utils.get_test_instance()
 
291
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
292
        self.connection.list_interfaces(instance_ref['name'])
 
293
 
 
294
    @catch_notimplementederror
 
295
    def test_block_stats(self):
 
296
        network_info = test_utils.get_test_network_info()
 
297
        instance_ref = test_utils.get_test_instance()
 
298
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
299
        stats = self.connection.block_stats(instance_ref['name'], 'someid')
 
300
        self.assertEquals(len(stats), 5)
 
301
 
 
302
    @catch_notimplementederror
 
303
    def test_interface_stats(self):
 
304
        network_info = test_utils.get_test_network_info()
 
305
        instance_ref = test_utils.get_test_instance()
 
306
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
307
        stats = self.connection.interface_stats(instance_ref['name'], 'someid')
 
308
        self.assertEquals(len(stats), 8)
 
309
 
 
310
    @catch_notimplementederror
 
311
    def test_get_console_output(self):
 
312
        network_info = test_utils.get_test_network_info()
 
313
        instance_ref = test_utils.get_test_instance()
 
314
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
315
        console_output = self.connection.get_console_output(instance_ref)
 
316
        self.assertTrue(isinstance(console_output, basestring))
 
317
 
 
318
    @catch_notimplementederror
 
319
    def test_get_ajax_console(self):
 
320
        network_info = test_utils.get_test_network_info()
 
321
        instance_ref = test_utils.get_test_instance()
 
322
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
323
        ajax_console = self.connection.get_ajax_console(instance_ref)
 
324
        self.assertIn('token', ajax_console)
 
325
        self.assertIn('host', ajax_console)
 
326
        self.assertIn('port', ajax_console)
 
327
 
 
328
    @catch_notimplementederror
 
329
    def test_get_vnc_console(self):
 
330
        network_info = test_utils.get_test_network_info()
 
331
        instance_ref = test_utils.get_test_instance()
 
332
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
333
        vnc_console = self.connection.get_vnc_console(instance_ref)
 
334
        self.assertIn('token', vnc_console)
 
335
        self.assertIn('host', vnc_console)
 
336
        self.assertIn('port', vnc_console)
 
337
 
 
338
    @catch_notimplementederror
 
339
    def test_get_console_pool_info(self):
 
340
        network_info = test_utils.get_test_network_info()
 
341
        instance_ref = test_utils.get_test_instance()
 
342
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
343
        console_pool = self.connection.get_console_pool_info(instance_ref)
 
344
        self.assertIn('address', console_pool)
 
345
        self.assertIn('username', console_pool)
 
346
        self.assertIn('password', console_pool)
 
347
 
 
348
    @catch_notimplementederror
 
349
    def test_refresh_security_group_rules(self):
 
350
        network_info = test_utils.get_test_network_info()
 
351
        instance_ref = test_utils.get_test_instance()
 
352
        # FIXME: Create security group and add the instance to it
 
353
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
354
        self.connection.refresh_security_group_rules(1)
 
355
 
 
356
    @catch_notimplementederror
 
357
    def test_refresh_security_group_members(self):
 
358
        network_info = test_utils.get_test_network_info()
 
359
        instance_ref = test_utils.get_test_instance()
 
360
        # FIXME: Create security group and add the instance to it
 
361
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
362
        self.connection.refresh_security_group_members(1)
 
363
 
 
364
    @catch_notimplementederror
 
365
    def test_refresh_provider_fw_rules(self):
 
366
        network_info = test_utils.get_test_network_info()
 
367
        instance_ref = test_utils.get_test_instance()
 
368
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
369
        self.connection.refresh_provider_fw_rules()
 
370
 
 
371
    @catch_notimplementederror
 
372
    def test_update_available_resource(self):
 
373
        self.compute = self.start_service('compute', host='dummy')
 
374
        self.connection.update_available_resource(self.ctxt, 'dummy')
 
375
 
 
376
    @catch_notimplementederror
 
377
    def test_compare_cpu(self):
 
378
        cpu_info = '''{ "topology": {
 
379
                               "sockets": 1,
 
380
                               "cores": 2,
 
381
                               "threads": 1 },
 
382
                        "features": [
 
383
                            "xtpr",
 
384
                            "tm2",
 
385
                            "est",
 
386
                            "vmx",
 
387
                            "ds_cpl",
 
388
                            "monitor",
 
389
                            "pbe",
 
390
                            "tm",
 
391
                            "ht",
 
392
                            "ss",
 
393
                            "acpi",
 
394
                            "ds",
 
395
                            "vme"],
 
396
                        "arch": "x86_64",
 
397
                        "model": "Penryn",
 
398
                        "vendor": "Intel" }'''
 
399
 
 
400
        self.connection.compare_cpu(cpu_info)
 
401
 
 
402
    @catch_notimplementederror
 
403
    def test_ensure_filtering_for_instance(self):
 
404
        instance_ref = test_utils.get_test_instance()
 
405
        network_info = test_utils.get_test_network_info()
 
406
        self.connection.ensure_filtering_rules_for_instance(instance_ref,
 
407
                                                            network_info)
 
408
 
 
409
    @catch_notimplementederror
 
410
    def test_unfilter_instance(self):
 
411
        instance_ref = test_utils.get_test_instance()
 
412
        network_info = test_utils.get_test_network_info()
 
413
        self.connection.unfilter_instance(instance_ref, network_info)
 
414
 
 
415
    @catch_notimplementederror
 
416
    def test_live_migration(self):
 
417
        network_info = test_utils.get_test_network_info()
 
418
        instance_ref = test_utils.get_test_instance()
 
419
        self.connection.spawn(self.ctxt, instance_ref, network_info)
 
420
        self.connection.live_migration(self.ctxt, instance_ref, 'otherhost',
 
421
                                       None, None)
 
422
 
 
423
    @catch_notimplementederror
 
424
    def _check_host_status_fields(self, host_status):
 
425
        self.assertIn('host_name-description', host_status)
 
426
        self.assertIn('host_hostname', host_status)
 
427
        self.assertIn('host_memory_total', host_status)
 
428
        self.assertIn('host_memory_overhead', host_status)
 
429
        self.assertIn('host_memory_free', host_status)
 
430
        self.assertIn('host_memory_free_computed', host_status)
 
431
        self.assertIn('host_other_config', host_status)
 
432
        self.assertIn('host_ip_address', host_status)
 
433
        self.assertIn('host_cpu_info', host_status)
 
434
        self.assertIn('disk_available', host_status)
 
435
        self.assertIn('disk_total', host_status)
 
436
        self.assertIn('disk_used', host_status)
 
437
        self.assertIn('host_uuid', host_status)
 
438
        self.assertIn('host_name_label', host_status)
 
439
 
 
440
    @catch_notimplementederror
 
441
    def test_update_host_status(self):
 
442
        host_status = self.connection.update_host_status()
 
443
        self._check_host_status_fields(host_status)
 
444
 
 
445
    @catch_notimplementederror
 
446
    def test_get_host_stats(self):
 
447
        host_status = self.connection.get_host_stats()
 
448
        self._check_host_status_fields(host_status)
 
449
 
 
450
    @catch_notimplementederror
 
451
    def test_set_host_enabled(self):
 
452
        self.connection.set_host_enabled('a useless argument?', True)
 
453
 
 
454
    @catch_notimplementederror
 
455
    def test_host_power_action_reboot(self):
 
456
        self.connection.host_power_action('a useless argument?', 'reboot')
 
457
 
 
458
    @catch_notimplementederror
 
459
    def test_host_power_action_shutdown(self):
 
460
        self.connection.host_power_action('a useless argument?', 'shutdown')
 
461
 
 
462
    @catch_notimplementederror
 
463
    def test_host_power_action_startup(self):
 
464
        self.connection.host_power_action('a useless argument?', 'startup')
 
465
 
 
466
 
 
467
class AbstractDriverTestCase(_VirtDriverTestCase):
 
468
    def setUp(self):
 
469
        import nova.virt.driver
 
470
 
 
471
        self.driver_module = nova.virt.driver
 
472
 
 
473
        def get_driver_connection(_):
 
474
            return nova.virt.driver.ComputeDriver()
 
475
 
 
476
        self.driver_module.get_connection = get_driver_connection
 
477
        super(AbstractDriverTestCase, self).setUp()
 
478
 
 
479
 
 
480
class FakeConnectionTestCase(_VirtDriverTestCase):
 
481
    def setUp(self):
 
482
        import nova.virt.fake
 
483
        self.driver_module = nova.virt.fake
 
484
        super(FakeConnectionTestCase, self).setUp()
 
485
 
 
486
# Before long, we'll add the real hypervisor drivers here as well
 
487
# with whatever instrumentation they need to work independently of
 
488
# their hypervisor. This way, we can verify that they all act the
 
489
# same.