merge trunk, fixed conflicts
This commit is contained in:
2
Authors
2
Authors
@@ -1,4 +1,5 @@
|
||||
Andy Smith <code@term.ie>
|
||||
Andy Southgate <andy.southgate@citrix.com>
|
||||
Anne Gentle <anne@openstack.org>
|
||||
Anthony Young <sleepsonthefloor@gmail.com>
|
||||
Antony Messerli <ant@openstack.org>
|
||||
@@ -21,6 +22,7 @@ Eldar Nugaev <enugaev@griddynamics.com>
|
||||
Eric Day <eday@oddments.org>
|
||||
Eric Windisch <eric@cloudscaling.com>
|
||||
Ewan Mellor <ewan.mellor@citrix.com>
|
||||
Gabe Westmaas <gabe.westmaas@rackspace.com>
|
||||
Hisaharu Ishii <ishii.hisaharu@lab.ntt.co.jp>
|
||||
Hisaki Ohara <hisaki.ohara@intel.com>
|
||||
Ilya Alekseyev <ialekseev@griddynamics.com>
|
||||
|
||||
@@ -19,11 +19,15 @@ Test suite for XenAPI
|
||||
"""
|
||||
|
||||
import functools
|
||||
import os
|
||||
import re
|
||||
import stubout
|
||||
import ast
|
||||
|
||||
from nova import db
|
||||
from nova import context
|
||||
from nova import flags
|
||||
from nova import log as logging
|
||||
from nova import test
|
||||
from nova import utils
|
||||
from nova.auth import manager
|
||||
@@ -38,6 +42,9 @@ from nova.virt.xenapi.vmops import VMOps
|
||||
from nova.tests.db import fakes as db_fakes
|
||||
from nova.tests.xenapi import stubs
|
||||
from nova.tests.glance import stubs as glance_stubs
|
||||
from nova.tests import fake_utils
|
||||
|
||||
LOG = logging.getLogger('nova.tests.test_xenapi')
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
@@ -64,13 +71,14 @@ class XenAPIVolumeTestCase(test.TestCase):
|
||||
def setUp(self):
|
||||
super(XenAPIVolumeTestCase, self).setUp()
|
||||
self.stubs = stubout.StubOutForTesting()
|
||||
self.context = context.RequestContext('fake', 'fake', False)
|
||||
FLAGS.target_host = '127.0.0.1'
|
||||
FLAGS.xenapi_connection_url = 'test_url'
|
||||
FLAGS.xenapi_connection_password = 'test_pass'
|
||||
db_fakes.stub_out_db_instance_api(self.stubs)
|
||||
stubs.stub_out_get_target(self.stubs)
|
||||
xenapi_fake.reset()
|
||||
self.values = {'name': 1, 'id': 1,
|
||||
self.values = {'id': 1,
|
||||
'project_id': 'fake',
|
||||
'user_id': 'fake',
|
||||
'image_id': 1,
|
||||
@@ -90,7 +98,7 @@ class XenAPIVolumeTestCase(test.TestCase):
|
||||
vol['availability_zone'] = FLAGS.storage_availability_zone
|
||||
vol['status'] = "creating"
|
||||
vol['attach_status'] = "detached"
|
||||
return db.volume_create(context.get_admin_context(), vol)
|
||||
return db.volume_create(self.context, vol)
|
||||
|
||||
def test_create_iscsi_storage(self):
|
||||
""" This shows how to test helper classes' methods """
|
||||
@@ -126,7 +134,7 @@ class XenAPIVolumeTestCase(test.TestCase):
|
||||
stubs.stubout_session(self.stubs, stubs.FakeSessionForVolumeTests)
|
||||
conn = xenapi_conn.get_connection(False)
|
||||
volume = self._create_volume()
|
||||
instance = db.instance_create(self.values)
|
||||
instance = db.instance_create(self.context, self.values)
|
||||
vm = xenapi_fake.create_vm(instance.name, 'Running')
|
||||
result = conn.attach_volume(instance.name, volume['id'], '/dev/sdc')
|
||||
|
||||
@@ -146,7 +154,7 @@ class XenAPIVolumeTestCase(test.TestCase):
|
||||
stubs.FakeSessionForVolumeFailedTests)
|
||||
conn = xenapi_conn.get_connection(False)
|
||||
volume = self._create_volume()
|
||||
instance = db.instance_create(self.values)
|
||||
instance = db.instance_create(self.context, self.values)
|
||||
xenapi_fake.create_vm(instance.name, 'Running')
|
||||
self.assertRaises(Exception,
|
||||
conn.attach_volume,
|
||||
@@ -175,8 +183,9 @@ class XenAPIVMTestCase(test.TestCase):
|
||||
self.project = self.manager.create_project('fake', 'fake', 'fake')
|
||||
self.network = utils.import_object(FLAGS.network_manager)
|
||||
self.stubs = stubout.StubOutForTesting()
|
||||
FLAGS.xenapi_connection_url = 'test_url'
|
||||
FLAGS.xenapi_connection_password = 'test_pass'
|
||||
self.flags(xenapi_connection_url='test_url',
|
||||
xenapi_connection_password='test_pass',
|
||||
instance_name_template='%d')
|
||||
xenapi_fake.reset()
|
||||
xenapi_fake.create_local_srs()
|
||||
db_fakes.stub_out_db_instance_api(self.stubs)
|
||||
@@ -189,6 +198,8 @@ class XenAPIVMTestCase(test.TestCase):
|
||||
stubs.stub_out_vm_methods(self.stubs)
|
||||
glance_stubs.stubout_glance_client(self.stubs,
|
||||
glance_stubs.FakeGlance)
|
||||
fake_utils.stub_out_utils_execute(self.stubs)
|
||||
self.context = context.RequestContext('fake', 'fake', False)
|
||||
self.conn = xenapi_conn.get_connection(False)
|
||||
|
||||
def test_list_instances_0(self):
|
||||
@@ -213,7 +224,7 @@ class XenAPIVMTestCase(test.TestCase):
|
||||
if not vm_rec["is_control_domain"]:
|
||||
vm_labels.append(vm_rec["name_label"])
|
||||
|
||||
self.assertEquals(vm_labels, [1])
|
||||
self.assertEquals(vm_labels, ['1'])
|
||||
|
||||
def ensure_vbd_was_torn_down():
|
||||
vbd_labels = []
|
||||
@@ -221,7 +232,7 @@ class XenAPIVMTestCase(test.TestCase):
|
||||
vbd_rec = xenapi_fake.get_record('VBD', vbd_ref)
|
||||
vbd_labels.append(vbd_rec["vm_name_label"])
|
||||
|
||||
self.assertEquals(vbd_labels, [1])
|
||||
self.assertEquals(vbd_labels, ['1'])
|
||||
|
||||
def ensure_vdi_was_torn_down():
|
||||
for vdi_ref in xenapi_fake.get_all('VDI'):
|
||||
@@ -238,11 +249,10 @@ class XenAPIVMTestCase(test.TestCase):
|
||||
|
||||
def create_vm_record(self, conn, os_type):
|
||||
instances = conn.list_instances()
|
||||
self.assertEquals(instances, [1])
|
||||
self.assertEquals(instances, ['1'])
|
||||
|
||||
# Get Nova record for VM
|
||||
vm_info = conn.get_info(1)
|
||||
|
||||
# Get XenAPI record for VM
|
||||
vms = [rec for ref, rec
|
||||
in xenapi_fake.get_all_records('VM').iteritems()
|
||||
@@ -251,7 +261,7 @@ class XenAPIVMTestCase(test.TestCase):
|
||||
self.vm_info = vm_info
|
||||
self.vm = vm
|
||||
|
||||
def check_vm_record(self, conn):
|
||||
def check_vm_record(self, conn, check_injection=False):
|
||||
# Check that m1.large above turned into the right thing.
|
||||
instance_type = db.instance_type_get_by_name(conn, 'm1.large')
|
||||
mem_kib = long(instance_type['memory_mb']) << 10
|
||||
@@ -271,6 +281,25 @@ class XenAPIVMTestCase(test.TestCase):
|
||||
# Check that the VM is running according to XenAPI.
|
||||
self.assertEquals(self.vm['power_state'], 'Running')
|
||||
|
||||
if check_injection:
|
||||
xenstore_data = self.vm['xenstore_data']
|
||||
key = 'vm-data/networking/aabbccddeeff'
|
||||
xenstore_value = xenstore_data[key]
|
||||
tcpip_data = ast.literal_eval(xenstore_value)
|
||||
self.assertEquals(tcpip_data, {
|
||||
'label': 'test_network',
|
||||
'broadcast': '10.0.0.255',
|
||||
'ips': [{'ip': '10.0.0.3',
|
||||
'netmask':'255.255.255.0',
|
||||
'enabled':'1'}],
|
||||
'ip6s': [{'ip': 'fe80::a8bb:ccff:fedd:eeff',
|
||||
'netmask': '120',
|
||||
'enabled': '1',
|
||||
'gateway': 'fe80::a00:1'}],
|
||||
'mac': 'aa:bb:cc:dd:ee:ff',
|
||||
'dns': ['10.0.0.2'],
|
||||
'gateway': '10.0.0.1'})
|
||||
|
||||
def check_vm_params_for_windows(self):
|
||||
self.assertEquals(self.vm['platform']['nx'], 'true')
|
||||
self.assertEquals(self.vm['HVM_boot_params'], {'order': 'dc'})
|
||||
@@ -317,10 +346,10 @@ class XenAPIVMTestCase(test.TestCase):
|
||||
self.fail('Found unexpected unbound VDI:%s' % vdi_rec['uuid'])
|
||||
|
||||
def _test_spawn(self, image_id, kernel_id, ramdisk_id,
|
||||
instance_type="m1.large", os_type="linux"):
|
||||
stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests)
|
||||
values = {'name': 1,
|
||||
'id': 1,
|
||||
instance_type="m1.large", os_type="linux",
|
||||
check_injection=False):
|
||||
stubs.stubout_loopingcall_start(self.stubs)
|
||||
values = {'id': 1,
|
||||
'project_id': self.project.id,
|
||||
'user_id': self.user.id,
|
||||
'image_id': image_id,
|
||||
@@ -329,12 +358,10 @@ class XenAPIVMTestCase(test.TestCase):
|
||||
'instance_type': instance_type,
|
||||
'mac_address': 'aa:bb:cc:dd:ee:ff',
|
||||
'os_type': os_type}
|
||||
|
||||
conn = xenapi_conn.get_connection(False)
|
||||
instance = db.instance_create(values)
|
||||
conn.spawn(instance)
|
||||
self.create_vm_record(conn, os_type)
|
||||
self.check_vm_record(conn)
|
||||
instance = db.instance_create(self.context, values)
|
||||
self.conn.spawn(instance)
|
||||
self.create_vm_record(self.conn, os_type)
|
||||
self.check_vm_record(self.conn, check_injection)
|
||||
|
||||
def test_spawn_not_enough_memory(self):
|
||||
FLAGS.xenapi_image_service = 'glance'
|
||||
@@ -399,6 +426,85 @@ class XenAPIVMTestCase(test.TestCase):
|
||||
glance_stubs.FakeGlance.IMAGE_RAMDISK)
|
||||
self.check_vm_params_for_linux_with_external_kernel()
|
||||
|
||||
def test_spawn_netinject_file(self):
|
||||
FLAGS.xenapi_image_service = 'glance'
|
||||
db_fakes.stub_out_db_instance_api(self.stubs, injected=True)
|
||||
|
||||
self._tee_executed = False
|
||||
|
||||
def _tee_handler(cmd, **kwargs):
|
||||
input = kwargs.get('process_input', None)
|
||||
self.assertNotEqual(input, None)
|
||||
config = [line.strip() for line in input.split("\n")]
|
||||
# Find the start of eth0 configuration and check it
|
||||
index = config.index('auto eth0')
|
||||
self.assertEquals(config[index + 1:index + 8], [
|
||||
'iface eth0 inet static',
|
||||
'address 10.0.0.3',
|
||||
'netmask 255.255.255.0',
|
||||
'broadcast 10.0.0.255',
|
||||
'gateway 10.0.0.1',
|
||||
'dns-nameservers 10.0.0.2',
|
||||
''])
|
||||
self._tee_executed = True
|
||||
return '', ''
|
||||
|
||||
fake_utils.fake_execute_set_repliers([
|
||||
# Capture the sudo tee .../etc/network/interfaces command
|
||||
(r'(sudo\s+)?tee.*interfaces', _tee_handler),
|
||||
])
|
||||
FLAGS.xenapi_image_service = 'glance'
|
||||
self._test_spawn(glance_stubs.FakeGlance.IMAGE_MACHINE,
|
||||
glance_stubs.FakeGlance.IMAGE_KERNEL,
|
||||
glance_stubs.FakeGlance.IMAGE_RAMDISK,
|
||||
check_injection=True)
|
||||
self.assertTrue(self._tee_executed)
|
||||
|
||||
def test_spawn_netinject_xenstore(self):
|
||||
FLAGS.xenapi_image_service = 'glance'
|
||||
db_fakes.stub_out_db_instance_api(self.stubs, injected=True)
|
||||
|
||||
self._tee_executed = False
|
||||
|
||||
def _mount_handler(cmd, *ignore_args, **ignore_kwargs):
|
||||
# When mounting, create real files under the mountpoint to simulate
|
||||
# files in the mounted filesystem
|
||||
|
||||
# mount point will be the last item of the command list
|
||||
self._tmpdir = cmd[len(cmd) - 1]
|
||||
LOG.debug(_('Creating files in %s to simulate guest agent' %
|
||||
self._tmpdir))
|
||||
os.makedirs(os.path.join(self._tmpdir, 'usr', 'sbin'))
|
||||
# Touch the file using open
|
||||
open(os.path.join(self._tmpdir, 'usr', 'sbin',
|
||||
'xe-update-networking'), 'w').close()
|
||||
return '', ''
|
||||
|
||||
def _umount_handler(cmd, *ignore_args, **ignore_kwargs):
|
||||
# Umount would normall make files in the m,ounted filesystem
|
||||
# disappear, so do that here
|
||||
LOG.debug(_('Removing simulated guest agent files in %s' %
|
||||
self._tmpdir))
|
||||
os.remove(os.path.join(self._tmpdir, 'usr', 'sbin',
|
||||
'xe-update-networking'))
|
||||
os.rmdir(os.path.join(self._tmpdir, 'usr', 'sbin'))
|
||||
os.rmdir(os.path.join(self._tmpdir, 'usr'))
|
||||
return '', ''
|
||||
|
||||
def _tee_handler(cmd, *ignore_args, **ignore_kwargs):
|
||||
self._tee_executed = True
|
||||
return '', ''
|
||||
|
||||
fake_utils.fake_execute_set_repliers([
|
||||
(r'(sudo\s+)?mount', _mount_handler),
|
||||
(r'(sudo\s+)?umount', _umount_handler),
|
||||
(r'(sudo\s+)?tee.*interfaces', _tee_handler)])
|
||||
self._test_spawn(1, 2, 3, check_injection=True)
|
||||
|
||||
# tee must not run in this case, where an injection-capable
|
||||
# guest agent is detected
|
||||
self.assertFalse(self._tee_executed)
|
||||
|
||||
def test_spawn_with_network_qos(self):
|
||||
self._create_instance()
|
||||
for vif_ref in xenapi_fake.get_all('VIF'):
|
||||
@@ -408,6 +514,7 @@ class XenAPIVMTestCase(test.TestCase):
|
||||
str(4 * 1024))
|
||||
|
||||
def test_rescue(self):
|
||||
self.flags(xenapi_inject_image=False)
|
||||
instance = self._create_instance()
|
||||
conn = xenapi_conn.get_connection(False)
|
||||
conn.rescue(instance, None)
|
||||
@@ -428,8 +535,8 @@ class XenAPIVMTestCase(test.TestCase):
|
||||
|
||||
def _create_instance(self):
|
||||
"""Creates and spawns a test instance."""
|
||||
values = {'name': 1,
|
||||
'id': 1,
|
||||
stubs.stubout_loopingcall_start(self.stubs)
|
||||
values = {'id': 1,
|
||||
'project_id': self.project.id,
|
||||
'user_id': self.user.id,
|
||||
'image_id': 1,
|
||||
@@ -438,7 +545,7 @@ class XenAPIVMTestCase(test.TestCase):
|
||||
'instance_type': 'm1.large',
|
||||
'mac_address': 'aa:bb:cc:dd:ee:ff',
|
||||
'os_type': 'linux'}
|
||||
instance = db.instance_create(values)
|
||||
instance = db.instance_create(self.context, values)
|
||||
self.conn.spawn(instance)
|
||||
return instance
|
||||
|
||||
@@ -483,21 +590,26 @@ class XenAPIMigrateInstance(test.TestCase):
|
||||
db_fakes.stub_out_db_instance_api(self.stubs)
|
||||
stubs.stub_out_get_target(self.stubs)
|
||||
xenapi_fake.reset()
|
||||
xenapi_fake.create_network('fake', FLAGS.flat_network_bridge)
|
||||
self.manager = manager.AuthManager()
|
||||
self.user = self.manager.create_user('fake', 'fake', 'fake',
|
||||
admin=True)
|
||||
self.project = self.manager.create_project('fake', 'fake', 'fake')
|
||||
self.values = {'name': 1, 'id': 1,
|
||||
self.context = context.RequestContext('fake', 'fake', False)
|
||||
self.values = {'id': 1,
|
||||
'project_id': self.project.id,
|
||||
'user_id': self.user.id,
|
||||
'image_id': 1,
|
||||
'kernel_id': None,
|
||||
'ramdisk_id': None,
|
||||
'local_gb': 5,
|
||||
'instance_type': 'm1.large',
|
||||
'mac_address': 'aa:bb:cc:dd:ee:ff',
|
||||
'os_type': 'linux'}
|
||||
|
||||
fake_utils.stub_out_utils_execute(self.stubs)
|
||||
stubs.stub_out_migration_methods(self.stubs)
|
||||
stubs.stubout_get_this_vm_uuid(self.stubs)
|
||||
glance_stubs.stubout_glance_client(self.stubs,
|
||||
glance_stubs.FakeGlance)
|
||||
|
||||
@@ -508,14 +620,15 @@ class XenAPIMigrateInstance(test.TestCase):
|
||||
self.stubs.UnsetAll()
|
||||
|
||||
def test_migrate_disk_and_power_off(self):
|
||||
instance = db.instance_create(self.values)
|
||||
instance = db.instance_create(self.context, self.values)
|
||||
stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests)
|
||||
conn = xenapi_conn.get_connection(False)
|
||||
conn.migrate_disk_and_power_off(instance, '127.0.0.1')
|
||||
|
||||
def test_finish_resize(self):
|
||||
instance = db.instance_create(self.values)
|
||||
instance = db.instance_create(self.context, self.values)
|
||||
stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests)
|
||||
stubs.stubout_loopingcall_start(self.stubs)
|
||||
conn = xenapi_conn.get_connection(False)
|
||||
conn.finish_resize(instance, dict(base_copy='hurr', cow='durr'))
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ from nova.virt.xenapi import fake
|
||||
from nova.virt.xenapi import volume_utils
|
||||
from nova.virt.xenapi import vm_utils
|
||||
from nova.virt.xenapi import vmops
|
||||
from nova import utils
|
||||
|
||||
|
||||
def stubout_instance_snapshot(stubs):
|
||||
@@ -164,14 +165,17 @@ def stubout_create_vm(stubs):
|
||||
stubs.Set(vm_utils.VMHelper, 'create_vm', f)
|
||||
|
||||
|
||||
def stubout_loopingcall_start(stubs):
|
||||
def fake_start(self, interval, now=True):
|
||||
self.f(*self.args, **self.kw)
|
||||
stubs.Set(utils.LoopingCall, 'start', fake_start)
|
||||
|
||||
|
||||
class FakeSessionForVMTests(fake.SessionBase):
|
||||
""" Stubs out a XenAPISession for VM tests """
|
||||
def __init__(self, uri):
|
||||
super(FakeSessionForVMTests, self).__init__(uri)
|
||||
|
||||
def network_get_all_records_where(self, _1, _2):
|
||||
return self.xenapi.network.get_all_records()
|
||||
|
||||
def host_call_plugin(self, _1, _2, _3, _4, _5):
|
||||
sr_ref = fake.get_all('SR')[0]
|
||||
vdi_ref = fake.create_vdi('', False, sr_ref, False)
|
||||
@@ -223,7 +227,7 @@ def stub_out_vm_methods(stubs):
|
||||
pass
|
||||
|
||||
def fake_spawn_rescue(self, inst):
|
||||
pass
|
||||
inst._rescue = False
|
||||
|
||||
stubs.Set(vmops.VMOps, "_shutdown", fake_shutdown)
|
||||
stubs.Set(vmops.VMOps, "_acquire_bootlock", fake_acquire_bootlock)
|
||||
|
||||
Reference in New Issue
Block a user