1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3
# Copyright 2010 OpenStack LLC
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
9
# http://www.apache.org/licenses/LICENSE-2.0
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
22
from nova import exception
23
from nova import flags
24
from nova import image
25
from nova import log as logging
27
from nova.tests import utils as test_utils
32
LOG = logging.getLogger('nova.tests.test_virt_drivers')
35
def catch_notimplementederror(f):
36
"""Decorator to simplify catching drivers raising NotImplementedError
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):
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),
50
wrapped_func.__name__ = f.__name__
51
wrapped_func.__doc__ = f.__doc__
55
class _VirtDriverTestCase(test.TestCase):
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()
62
@catch_notimplementederror
63
def test_init_host(self):
64
self.connection.init_host('myhostname')
66
@catch_notimplementederror
67
def test_list_instances(self):
68
self.connection.list_instances()
70
@catch_notimplementederror
71
def test_list_instances_detail(self):
72
self.connection.list_instances_detail()
74
@catch_notimplementederror
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)
80
domains = self.connection.list_instances()
81
self.assertIn(instance_ref['name'], domains)
83
domains_details = self.connection.list_instances_detail()
84
self.assertIn(instance_ref['name'], [i.name for i in domains_details])
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'])
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'])
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)
109
@catch_notimplementederror
110
def test_get_host_ip_addr(self):
111
host_ip = self.connection.get_host_ip_addr()
113
# Will raise an exception if it's not a valid IP at all
114
ip = netaddr.IPAddress(host_ip)
116
# For now, assume IPv4.
117
self.assertEquals(ip.version, 4)
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)
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')
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'))
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')
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)
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)
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)
174
@catch_notimplementederror
175
def test_poll_rescued_instances(self):
176
self.connection.poll_rescued_instances(10)
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')
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)
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)
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)
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)
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)
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)
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)
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())
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')
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)
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')
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'])
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'])
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'])
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)
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)
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))
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)
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)
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)
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)
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)
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()
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')
376
@catch_notimplementederror
377
def test_compare_cpu(self):
378
cpu_info = '''{ "topology": {
398
"vendor": "Intel" }'''
400
self.connection.compare_cpu(cpu_info)
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,
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)
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',
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)
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)
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)
450
@catch_notimplementederror
451
def test_set_host_enabled(self):
452
self.connection.set_host_enabled('a useless argument?', True)
454
@catch_notimplementederror
455
def test_host_power_action_reboot(self):
456
self.connection.host_power_action('a useless argument?', 'reboot')
458
@catch_notimplementederror
459
def test_host_power_action_shutdown(self):
460
self.connection.host_power_action('a useless argument?', 'shutdown')
462
@catch_notimplementederror
463
def test_host_power_action_startup(self):
464
self.connection.host_power_action('a useless argument?', 'startup')
467
class AbstractDriverTestCase(_VirtDriverTestCase):
469
import nova.virt.driver
471
self.driver_module = nova.virt.driver
473
def get_driver_connection(_):
474
return nova.virt.driver.ComputeDriver()
476
self.driver_module.get_connection = get_driver_connection
477
super(AbstractDriverTestCase, self).setUp()
480
class FakeConnectionTestCase(_VirtDriverTestCase):
482
import nova.virt.fake
483
self.driver_module = nova.virt.fake
484
super(FakeConnectionTestCase, self).setUp()
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