diff options
Diffstat (limited to 'nova/tests/virt')
-rw-r--r-- | nova/tests/virt/baremetal/db/test_bm_pxe_ip.py | 94 | ||||
-rw-r--r-- | nova/tests/virt/baremetal/db/utils.py | 12 | ||||
-rw-r--r-- | nova/tests/virt/baremetal/test_pxe.py | 26 | ||||
-rwxr-xr-x | nova/tests/virt/baremetal/test_tilera.py | 7 | ||||
-rw-r--r-- | nova/tests/virt/hyperv/test_hypervapi.py | 21 | ||||
-rw-r--r-- | nova/tests/virt/libvirt/test_libvirt.py | 293 | ||||
-rw-r--r-- | nova/tests/virt/libvirt/test_libvirt_vif.py | 80 | ||||
-rw-r--r-- | nova/tests/virt/powervm/test_powervm.py | 35 | ||||
-rw-r--r-- | nova/tests/virt/test_virt_drivers.py | 29 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/db_fakes.py | 2 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/test_vmwareapi.py | 113 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py | 96 | ||||
-rw-r--r-- | nova/tests/virt/xenapi/test_agent.py | 10 | ||||
-rw-r--r-- | nova/tests/virt/xenapi/test_vm_utils.py | 4 | ||||
-rw-r--r-- | nova/tests/virt/xenapi/test_xenapi.py | 99 |
15 files changed, 757 insertions, 164 deletions
diff --git a/nova/tests/virt/baremetal/db/test_bm_pxe_ip.py b/nova/tests/virt/baremetal/db/test_bm_pxe_ip.py deleted file mode 100644 index 85f3e2f4b..000000000 --- a/nova/tests/virt/baremetal/db/test_bm_pxe_ip.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright (c) 2012 NTT DOCOMO, INC. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Bare-metal DB testcase for BareMetalPxeIp -""" - -from nova import exception -from nova.openstack.common.db import exception as db_exc -from nova.tests.virt.baremetal.db import base -from nova.tests.virt.baremetal.db import utils -from nova.virt.baremetal import db - - -class BareMetalPxeIpTestCase(base.BMDBTestCase): - - def _create_pxe_ip(self): - i1 = utils.new_bm_pxe_ip(address='10.1.1.1', - server_address='10.1.1.101') - i2 = utils.new_bm_pxe_ip(address='10.1.1.2', - server_address='10.1.1.102') - - i1_ref = db.bm_pxe_ip_create_direct(self.context, i1) - self.assertTrue(i1_ref['id'] is not None) - self.assertEqual(i1_ref['address'], '10.1.1.1') - self.assertEqual(i1_ref['server_address'], '10.1.1.101') - - i2_ref = db.bm_pxe_ip_create_direct(self.context, i2) - self.assertTrue(i2_ref['id'] is not None) - self.assertEqual(i2_ref['address'], '10.1.1.2') - self.assertEqual(i2_ref['server_address'], '10.1.1.102') - - self.i1 = i1_ref - self.i2 = i2_ref - - def test_unuque_address(self): - self._create_pxe_ip() - - # address duplicates - i = utils.new_bm_pxe_ip(address='10.1.1.1', - server_address='10.1.1.201') - self.assertRaises(db_exc.DBError, - db.bm_pxe_ip_create_direct, - self.context, i) - - # server_address duplicates - i = utils.new_bm_pxe_ip(address='10.1.1.3', - server_address='10.1.1.101') - self.assertRaises(db_exc.DBError, - db.bm_pxe_ip_create_direct, - self.context, i) - - db.bm_pxe_ip_destroy(self.context, self.i1['id']) - i = utils.new_bm_pxe_ip(address='10.1.1.1', - server_address='10.1.1.101') - ref = db.bm_pxe_ip_create_direct(self.context, i) - self.assertTrue(ref is not None) - - def test_bm_pxe_ip_associate(self): - self._create_pxe_ip() - node = db.bm_node_create(self.context, utils.new_bm_node()) - ip_id = db.bm_pxe_ip_associate(self.context, node['id']) - ref = db.bm_pxe_ip_get(self.context, ip_id) - self.assertEqual(ref['bm_node_id'], node['id']) - - def test_bm_pxe_ip_associate_raise(self): - self._create_pxe_ip() - node_id = 123 - self.assertRaises(exception.NovaException, - db.bm_pxe_ip_associate, - self.context, node_id) - - def test_delete_by_address(self): - self._create_pxe_ip() - db.bm_pxe_ip_destroy_by_address(self.context, '10.1.1.1') - del_ref = db.bm_pxe_ip_get(self.context, self.i1['id']) - self.assertTrue(del_ref is None) - - def test_delete_by_address_not_exist(self): - self._create_pxe_ip() - del_ref = db.bm_pxe_ip_destroy_by_address(self.context, '10.11.12.13') - self.assertTrue(del_ref is None) diff --git a/nova/tests/virt/baremetal/db/utils.py b/nova/tests/virt/baremetal/db/utils.py index c3b3cff5f..6faeb13d8 100644 --- a/nova/tests/virt/baremetal/db/utils.py +++ b/nova/tests/virt/baremetal/db/utils.py @@ -39,18 +39,6 @@ def new_bm_node(**kwargs): return h -def new_bm_pxe_ip(**kwargs): - x = bm_models.BareMetalPxeIp() - x.id = kwargs.pop('id', None) - x.address = kwargs.pop('address', None) - x.server_address = kwargs.pop('server_address', None) - x.bm_node_id = kwargs.pop('bm_node_id', None) - if len(kwargs) > 0: - raise test.TestingException("unknown field: %s" - % ','.join(kwargs.keys())) - return x - - def new_bm_interface(**kwargs): x = bm_models.BareMetalInterface() x.id = kwargs.pop('id', None) diff --git a/nova/tests/virt/baremetal/test_pxe.py b/nova/tests/virt/baremetal/test_pxe.py index 022f9c692..cd4e5c143 100644 --- a/nova/tests/virt/baremetal/test_pxe.py +++ b/nova/tests/virt/baremetal/test_pxe.py @@ -116,6 +116,7 @@ class PXEClassMethodsTestCase(BareMetalPXETestCase): 'deployment_ari_path': 'eee', 'aki_path': 'fff', 'ari_path': 'ggg', + 'network_info': self.test_network_info, } config = pxe.build_pxe_config(**args) self.assertThat(config, matchers.StartsWith('default deploy')) @@ -140,6 +141,21 @@ class PXEClassMethodsTestCase(BareMetalPXETestCase): matchers.Not(matchers.Contains('kernel ddd')), )) + def test_build_pxe_network_config(self): + self.flags( + pxe_network_config=True, + group='baremetal', + ) + net = utils.get_test_network_info(1) + config = pxe.build_pxe_network_config(net) + self.assertIn('eth0:off', config) + self.assertNotIn('eth1', config) + + net = utils.get_test_network_info(2) + config = pxe.build_pxe_network_config(net) + self.assertIn('eth0:off', config) + self.assertIn('eth1:off', config) + def test_build_network_config(self): net = utils.get_test_network_info(1) config = pxe.build_network_config(net) @@ -458,7 +474,8 @@ class PXEPublicMethodsTestCase(BareMetalPXETestCase): bm_utils.random_alnum(32).AndReturn('alnum') pxe.build_pxe_config( self.node['id'], 'alnum', iqn, - 'aaaa', 'bbbb', 'cccc', 'dddd').AndReturn(pxe_config) + 'aaaa', 'bbbb', 'cccc', 'dddd', + self.test_network_info).AndReturn(pxe_config) bm_utils.write_to_file(pxe_path, pxe_config) for mac in macs: bm_utils.create_link_without_raise( @@ -466,7 +483,8 @@ class PXEPublicMethodsTestCase(BareMetalPXETestCase): self.mox.ReplayAll() - self.driver.activate_bootloader(self.context, self.node, self.instance) + self.driver.activate_bootloader(self.context, self.node, self.instance, + network_info=self.test_network_info) self.mox.VerifyAll() @@ -515,8 +533,8 @@ class PXEPublicMethodsTestCase(BareMetalPXETestCase): row = db.bm_node_get(self.context, 1) self.assertTrue(row['deploy_key'] is None) - self.driver.activate_bootloader(self.context, self.node, - self.instance) + self.driver.activate_bootloader(self.context, self.node, self.instance, + network_info=self.test_network_info) row = db.bm_node_get(self.context, 1) self.assertTrue(row['deploy_key'] is not None) diff --git a/nova/tests/virt/baremetal/test_tilera.py b/nova/tests/virt/baremetal/test_tilera.py index 488cba4df..7ad5c4b6a 100755 --- a/nova/tests/virt/baremetal/test_tilera.py +++ b/nova/tests/virt/baremetal/test_tilera.py @@ -317,7 +317,8 @@ class TileraPublicMethodsTestCase(BareMetalTileraTestCase): self.mox.ReplayAll() - self.driver.activate_bootloader(self.context, self.node, self.instance) + self.driver.activate_bootloader(self.context, self.node, self.instance, + network_info=self.test_network_info) self.mox.VerifyAll() @@ -334,8 +335,8 @@ class TileraPublicMethodsTestCase(BareMetalTileraTestCase): row = db.bm_node_get(self.context, 1) self.assertTrue(row['deploy_key'] is None) - self.driver.activate_bootloader(self.context, self.node, - self.instance) + self.driver.activate_bootloader(self.context, self.node, self.instance, + network_info=self.test_network_info) row = db.bm_node_get(self.context, 1) self.assertTrue(row['deploy_key'] is not None) diff --git a/nova/tests/virt/hyperv/test_hypervapi.py b/nova/tests/virt/hyperv/test_hypervapi.py index cfc79c388..9f2d745ff 100644 --- a/nova/tests/virt/hyperv/test_hypervapi.py +++ b/nova/tests/virt/hyperv/test_hypervapi.py @@ -495,13 +495,24 @@ class HyperVAPITestCase(test.TestCase): constants.HYPERV_VM_STATE_DISABLED) def test_power_on(self): - self._test_vm_state_change(self._conn.power_on, - constants.HYPERV_VM_STATE_DISABLED, - constants.HYPERV_VM_STATE_ENABLED) + self._instance_data = self._get_instance_data() + network_info = fake_network.fake_get_instance_nw_info(self.stubs, + spectacular=True) + vmutils.VMUtils.set_vm_state(mox.Func(self._check_instance_name), + constants.HYPERV_VM_STATE_ENABLED) + self._mox.ReplayAll() + self._conn.power_on(self._context, self._instance_data, network_info) + self._mox.VerifyAll() def test_power_on_already_running(self): - self._test_vm_state_change(self._conn.power_on, None, - constants.HYPERV_VM_STATE_ENABLED) + self._instance_data = self._get_instance_data() + network_info = fake_network.fake_get_instance_nw_info(self.stubs, + spectacular=True) + vmutils.VMUtils.set_vm_state(mox.Func(self._check_instance_name), + constants.HYPERV_VM_STATE_ENABLED) + self._mox.ReplayAll() + self._conn.power_on(self._context, self._instance_data, network_info) + self._mox.VerifyAll() def test_reboot(self): diff --git a/nova/tests/virt/libvirt/test_libvirt.py b/nova/tests/virt/libvirt/test_libvirt.py index 3c658a7f5..5636e1706 100644 --- a/nova/tests/virt/libvirt/test_libvirt.py +++ b/nova/tests/virt/libvirt/test_libvirt.py @@ -26,6 +26,7 @@ import re import shutil import tempfile +from eventlet import greenthread from lxml import etree from oslo.config import cfg from xml.dom import minidom @@ -43,6 +44,7 @@ from nova.openstack.common import fileutils from nova.openstack.common import importutils from nova.openstack.common import jsonutils from nova.openstack.common import loopingcall +from nova.openstack.common import processutils from nova.openstack.common import uuidutils from nova import test from nova.tests import fake_network @@ -77,6 +79,7 @@ CONF.import_opt('compute_manager', 'nova.service') CONF.import_opt('host', 'nova.netconf') CONF.import_opt('my_ip', 'nova.netconf') CONF.import_opt('base_dir_name', 'nova.virt.libvirt.imagecache') +CONF.import_opt('instances_path', 'nova.compute.manager') _fake_network_info = fake_network.fake_get_instance_nw_info _fake_stub_out_get_nw_info = fake_network.stub_out_nw_api_get_instance_nw_info @@ -286,8 +289,9 @@ class LibvirtConnTestCase(test.TestCase): self.user_id = 'fake' self.project_id = 'fake' self.context = context.get_admin_context() - self.flags(instances_path='') - self.flags(libvirt_snapshots_directory='') + temp_dir = self.useFixture(fixtures.TempDir()).path + self.flags(instances_path=temp_dir) + self.flags(libvirt_snapshots_directory=temp_dir) self.useFixture(fixtures.MonkeyPatch( 'nova.virt.libvirt.driver.libvirt_utils', fake_libvirt_utils)) @@ -343,6 +347,9 @@ class LibvirtConnTestCase(test.TestCase): 'extra_specs': {}, 'system_metadata': sys_meta} + def relpath(self, path): + return os.path.relpath(path, CONF.instances_path) + def tearDown(self): nova.tests.image.fake.FakeImageService_reset() super(LibvirtConnTestCase, self).tearDown() @@ -589,8 +596,8 @@ class LibvirtConnTestCase(test.TestCase): conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) instance_ref = db.instance_create(self.context, self.test_instance) - # make configdrive.enabled_for() return True - instance_ref['config_drive'] = 'ANY_ID' + # make configdrive.required_by() return True + instance_ref['config_drive'] = True disk_info = blockinfo.get_disk_info(CONF.libvirt_type, instance_ref) @@ -2078,8 +2085,8 @@ class LibvirtConnTestCase(test.TestCase): else: suffix = '' if expect_kernel: - check = (lambda t: t.find('./os/kernel').text.split( - '/')[1], 'kernel' + suffix) + check = (lambda t: self.relpath(t.find('./os/kernel').text). + split('/')[1], 'kernel' + suffix) else: check = (lambda t: t.find('./os/kernel'), None) check_list.append(check) @@ -2094,8 +2101,8 @@ class LibvirtConnTestCase(test.TestCase): check_list.append(check) if expect_ramdisk: - check = (lambda t: t.find('./os/initrd').text.split( - '/')[1], 'ramdisk' + suffix) + check = (lambda t: self.relpath(t.find('./os/initrd').text). + split('/')[1], 'ramdisk' + suffix) else: check = (lambda t: t.find('./os/initrd'), None) check_list.append(check) @@ -2146,8 +2153,9 @@ class LibvirtConnTestCase(test.TestCase): check = (lambda t: t.findall('./devices/serial')[1].get( 'type'), 'pty') check_list.append(check) - check = (lambda t: t.findall('./devices/serial/source')[0].get( - 'path').split('/')[1], 'console.log') + check = (lambda t: self.relpath(t.findall( + './devices/serial/source')[0].get('path')). + split('/')[1], 'console.log') check_list.append(check) else: check = (lambda t: t.find('./devices/console').get( @@ -2159,16 +2167,16 @@ class LibvirtConnTestCase(test.TestCase): (lambda t: t.find('./memory').text, '2097152')] if rescue: common_checks += [ - (lambda t: t.findall('./devices/disk/source')[0].get( - 'file').split('/')[1], 'disk.rescue'), - (lambda t: t.findall('./devices/disk/source')[1].get( - 'file').split('/')[1], 'disk')] + (lambda t: self.relpath(t.findall('./devices/disk/source')[0]. + get('file')).split('/')[1], 'disk.rescue'), + (lambda t: self.relpath(t.findall('./devices/disk/source')[1]. + get('file')).split('/')[1], 'disk')] else: - common_checks += [(lambda t: t.findall( - './devices/disk/source')[0].get('file').split('/')[1], + common_checks += [(lambda t: self.relpath(t.findall( + './devices/disk/source')[0].get('file')).split('/')[1], 'disk')] - common_checks += [(lambda t: t.findall( - './devices/disk/source')[1].get('file').split('/')[1], + common_checks += [(lambda t: self.relpath(t.findall( + './devices/disk/source')[1].get('file')).split('/')[1], 'disk.local')] for (libvirt_type, (expected_uri, checks)) in type_uri_map.iteritems(): @@ -2683,6 +2691,80 @@ class LibvirtConnTestCase(test.TestCase): db.instance_destroy(self.context, instance_ref['uuid']) + def test_get_instance_disk_info_excludes_volumes(self): + # Test data + instance_ref = db.instance_create(self.context, self.test_instance) + dummyxml = ("<domain type='kvm'><name>instance-0000000a</name>" + "<devices>" + "<disk type='file'><driver name='qemu' type='raw'/>" + "<source file='/test/disk'/>" + "<target dev='vda' bus='virtio'/></disk>" + "<disk type='file'><driver name='qemu' type='qcow2'/>" + "<source file='/test/disk.local'/>" + "<target dev='vdb' bus='virtio'/></disk>" + "<disk type='file'><driver name='qemu' type='qcow2'/>" + "<source file='/fake/path/to/volume1'/>" + "<target dev='vdc' bus='virtio'/></disk>" + "<disk type='file'><driver name='qemu' type='qcow2'/>" + "<source file='/fake/path/to/volume2'/>" + "<target dev='vdd' bus='virtio'/></disk>" + "</devices></domain>") + + # Preparing mocks + vdmock = self.mox.CreateMock(libvirt.virDomain) + self.mox.StubOutWithMock(vdmock, "XMLDesc") + vdmock.XMLDesc(0).AndReturn(dummyxml) + + def fake_lookup(instance_name): + if instance_name == instance_ref['name']: + return vdmock + self.create_fake_libvirt_mock(lookupByName=fake_lookup) + + GB = 1024 * 1024 * 1024 + fake_libvirt_utils.disk_sizes['/test/disk'] = 10 * GB + fake_libvirt_utils.disk_sizes['/test/disk.local'] = 20 * GB + fake_libvirt_utils.disk_backing_files['/test/disk.local'] = 'file' + + self.mox.StubOutWithMock(os.path, "getsize") + os.path.getsize('/test/disk').AndReturn((10737418240)) + os.path.getsize('/test/disk.local').AndReturn((3328599655)) + + ret = ("image: /test/disk\n" + "file format: raw\n" + "virtual size: 20G (21474836480 bytes)\n" + "disk size: 3.1G\n" + "cluster_size: 2097152\n" + "backing file: /test/dummy (actual path: /backing/file)\n") + + self.mox.StubOutWithMock(os.path, "exists") + os.path.exists('/test/disk.local').AndReturn(True) + + self.mox.StubOutWithMock(utils, "execute") + utils.execute('env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', + '/test/disk.local').AndReturn((ret, '')) + + self.mox.ReplayAll() + conn_info = {'driver_volume_type': 'fake'} + info = {'block_device_mapping': [ + {'connection_info': conn_info, 'mount_device': '/dev/vdc'}, + {'connection_info': conn_info, 'mount_device': '/dev/vdd'}]} + conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + info = conn.get_instance_disk_info(instance_ref['name'], + block_device_info=info) + info = jsonutils.loads(info) + self.assertEquals(info[0]['type'], 'raw') + self.assertEquals(info[0]['path'], '/test/disk') + self.assertEquals(info[0]['disk_size'], 10737418240) + self.assertEquals(info[0]['backing_file'], "") + self.assertEquals(info[0]['over_committed_disk_size'], 0) + self.assertEquals(info[1]['type'], 'qcow2') + self.assertEquals(info[1]['path'], '/test/disk.local') + self.assertEquals(info[1]['virt_disk_size'], 21474836480) + self.assertEquals(info[1]['backing_file'], "file") + self.assertEquals(info[1]['over_committed_disk_size'], 18146236825) + + db.instance_destroy(self.context, instance_ref['uuid']) + def test_spawn_with_network_info(self): # Preparing mocks def fake_none(*args, **kwargs): @@ -3165,6 +3247,90 @@ class LibvirtConnTestCase(test.TestCase): self.stubs.Set(os.path, 'exists', fake_os_path_exists) conn.destroy(instance, [], None, False) + def test_reboot_different_ids(self): + class FakeLoopingCall: + def start(self, *a, **k): + return self + + def wait(self): + return None + + self.flags(libvirt_wait_soft_reboot_seconds=1) + info_tuple = ('fake', 'fake', 'fake', 'also_fake') + self.reboot_create_called = False + + # Mock domain + mock_domain = self.mox.CreateMock(libvirt.virDomain) + mock_domain.info().AndReturn( + (libvirt_driver.VIR_DOMAIN_RUNNING,) + info_tuple) + mock_domain.ID().AndReturn('some_fake_id') + mock_domain.shutdown() + mock_domain.info().AndReturn( + (libvirt_driver.VIR_DOMAIN_CRASHED,) + info_tuple) + mock_domain.ID().AndReturn('some_other_fake_id') + + self.mox.ReplayAll() + + def fake_lookup_by_name(instance_name): + return mock_domain + + def fake_create_domain(**kwargs): + self.reboot_create_called = True + + conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + instance = {"name": "instancename", "id": "instanceid", + "uuid": "875a8070-d0b9-4949-8b31-104d125c9a64"} + self.stubs.Set(conn, '_lookup_by_name', fake_lookup_by_name) + self.stubs.Set(conn, '_create_domain', fake_create_domain) + self.stubs.Set(loopingcall, 'FixedIntervalLoopingCall', + lambda *a, **k: FakeLoopingCall()) + conn.reboot(None, instance, []) + self.assertTrue(self.reboot_create_called) + + def test_reboot_same_ids(self): + class FakeLoopingCall: + def start(self, *a, **k): + return self + + def wait(self): + return None + + self.flags(libvirt_wait_soft_reboot_seconds=1) + info_tuple = ('fake', 'fake', 'fake', 'also_fake') + self.reboot_hard_reboot_called = False + + # Mock domain + mock_domain = self.mox.CreateMock(libvirt.virDomain) + mock_domain.info().AndReturn( + (libvirt_driver.VIR_DOMAIN_RUNNING,) + info_tuple) + mock_domain.ID().AndReturn('some_fake_id') + mock_domain.shutdown() + mock_domain.info().AndReturn( + (libvirt_driver.VIR_DOMAIN_CRASHED,) + info_tuple) + mock_domain.ID().AndReturn('some_fake_id') + + self.mox.ReplayAll() + + def fake_lookup_by_name(instance_name): + return mock_domain + + def fake_hard_reboot(*args, **kwargs): + self.reboot_hard_reboot_called = True + + def fake_sleep(interval): + pass + + conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + instance = {"name": "instancename", "id": "instanceid", + "uuid": "875a8070-d0b9-4949-8b31-104d125c9a64"} + self.stubs.Set(conn, '_lookup_by_name', fake_lookup_by_name) + self.stubs.Set(greenthread, 'sleep', fake_sleep) + self.stubs.Set(conn, '_hard_reboot', fake_hard_reboot) + self.stubs.Set(loopingcall, 'FixedIntervalLoopingCall', + lambda *a, **k: FakeLoopingCall()) + conn.reboot(None, instance, []) + self.assertTrue(self.reboot_hard_reboot_called) + def test_destroy_undefines(self): mock = self.mox.CreateMock(libvirt.virDomain) mock.ID() @@ -3931,6 +4097,88 @@ class LibvirtConnTestCase(test.TestCase): self.mox.ReplayAll() self.assertTrue(conn._is_storage_shared_with('foo', '/path')) + def test_create_domain_define_xml_fails(self): + """ + Tests that the xml is logged when defining the domain fails. + """ + fake_xml = "<test>this is a test</test>" + + def fake_defineXML(xml): + self.assertEquals(fake_xml, xml) + raise libvirt.libvirtError('virDomainDefineXML() failed') + + self.log_error_called = False + + def fake_error(msg): + self.log_error_called = True + self.assertTrue(fake_xml in msg) + + self.stubs.Set(nova.virt.libvirt.driver.LOG, 'error', fake_error) + + self.create_fake_libvirt_mock(defineXML=fake_defineXML) + self.mox.ReplayAll() + conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) + + self.assertRaises(libvirt.libvirtError, conn._create_domain, fake_xml) + self.assertTrue(self.log_error_called) + + def test_create_domain_with_flags_fails(self): + """ + Tests that the xml is logged when creating the domain with flags fails. + """ + fake_xml = "<test>this is a test</test>" + fake_domain = FakeVirtDomain(fake_xml) + + def fake_createWithFlags(launch_flags): + raise libvirt.libvirtError('virDomainCreateWithFlags() failed') + + self.log_error_called = False + + def fake_error(msg): + self.log_error_called = True + self.assertTrue(fake_xml in msg) + + self.stubs.Set(fake_domain, 'createWithFlags', fake_createWithFlags) + self.stubs.Set(nova.virt.libvirt.driver.LOG, 'error', fake_error) + + self.create_fake_libvirt_mock() + self.mox.ReplayAll() + conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) + + self.assertRaises(libvirt.libvirtError, conn._create_domain, + domain=fake_domain) + self.assertTrue(self.log_error_called) + + def test_create_domain_enable_hairpin_fails(self): + """ + Tests that the xml is logged when enabling hairpin mode for the domain + fails. + """ + fake_xml = "<test>this is a test</test>" + fake_domain = FakeVirtDomain(fake_xml) + + def fake_enable_hairpin(launch_flags): + raise processutils.ProcessExecutionError('error') + + self.log_error_called = False + + def fake_error(msg): + self.log_error_called = True + self.assertTrue(fake_xml in msg) + + self.stubs.Set(nova.virt.libvirt.driver.LOG, 'error', fake_error) + + self.create_fake_libvirt_mock() + self.mox.ReplayAll() + conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) + self.stubs.Set(conn, '_enable_hairpin', fake_enable_hairpin) + + self.assertRaises(processutils.ProcessExecutionError, + conn._create_domain, + domain=fake_domain, + power_on=False) + self.assertTrue(self.log_error_called) + class HostStateTestCase(test.TestCase): @@ -4945,10 +5193,9 @@ class LibvirtDriverTestCase(test.TestCase): inst['host'] = 'host1' inst['root_gb'] = 10 inst['ephemeral_gb'] = 20 - inst['config_drive'] = 1 + inst['config_drive'] = True inst['kernel_id'] = 2 inst['ramdisk_id'] = 3 - inst['config_drive_id'] = 1 inst['key_data'] = 'ABCDEFG' inst['system_metadata'] = sys_meta @@ -4963,7 +5210,8 @@ class LibvirtDriverTestCase(test.TestCase): self.counter = 0 self.checked_shared_storage = False - def fake_get_instance_disk_info(instance, xml=None): + def fake_get_instance_disk_info(instance, xml=None, + block_device_info=None): return '[]' def fake_destroy(instance): @@ -5015,7 +5263,8 @@ class LibvirtDriverTestCase(test.TestCase): 'disk_size': '83886080'}] disk_info_text = jsonutils.dumps(disk_info) - def fake_get_instance_disk_info(instance, xml=None): + def fake_get_instance_disk_info(instance, xml=None, + block_device_info=None): return disk_info_text def fake_destroy(instance): diff --git a/nova/tests/virt/libvirt/test_libvirt_vif.py b/nova/tests/virt/libvirt/test_libvirt_vif.py index c9c6aef12..7cbf67b07 100644 --- a/nova/tests/virt/libvirt/test_libvirt_vif.py +++ b/nova/tests/virt/libvirt/test_libvirt_vif.py @@ -103,6 +103,17 @@ class LibvirtVifTestCase(test.TestCase): 'ovs_interfaceid': 'aaa-bbb-ccc', } + mapping_ivs = { + 'mac': 'ca:fe:de:ad:be:ef', + 'gateway_v6': net_ovs['gateway_v6'], + 'ips': [{'ip': '101.168.1.9'}], + 'dhcp_server': '191.168.1.1', + 'vif_uuid': 'vif-xxx-yyy-zzz', + 'vif_devname': 'tap-xxx-yyy-zzz', + 'vif_type': network_model.VIF_TYPE_IVS, + 'ivs_interfaceid': 'aaa-bbb-ccc', + } + mapping_ovs_legacy = { 'mac': 'ca:fe:de:ad:be:ef', 'gateway_v6': net_ovs['gateway_v6'], @@ -411,6 +422,24 @@ class LibvirtVifTestCase(test.TestCase): self.mapping_bridge_quantum, br_want) + def _check_ivs_ethernet_driver(self, d, net, mapping, dev_prefix): + self.flags(firewall_driver="nova.virt.firewall.NoopFirewallDriver") + xml = self._get_instance_xml(d, net, mapping) + + doc = etree.fromstring(xml) + ret = doc.findall('./devices/interface') + self.assertEqual(len(ret), 1) + node = ret[0] + ret = node.findall("filterref") + self.assertEqual(len(ret), 0) + self.assertEqual(node.get("type"), "ethernet") + dev_name = node.find("target").get("dev") + self.assertTrue(dev_name.startswith(dev_prefix)) + mac = node.find("mac").get("address") + self.assertEqual(mac, self.mapping_ivs['mac']) + script = node.find("script").get("path") + self.assertEquals(script, "") + def _check_ovs_ethernet_driver(self, d, net, mapping, dev_prefix): self.flags(firewall_driver="nova.virt.firewall.NoopFirewallDriver") xml = self._get_instance_xml(d, net, mapping) @@ -451,6 +480,33 @@ class LibvirtVifTestCase(test.TestCase): self.mapping_ovs, "tap") + def test_ivs_ethernet_driver(self): + def get_connection(): + return fakelibvirt.Connection("qemu:///session", + False, + 9010) + d = vif.LibvirtGenericVIFDriver(get_connection) + self._check_ivs_ethernet_driver(d, + self.net_ovs, + self.mapping_ivs, + "tap") + + def _check_ivs_virtualport_driver(self, d, net, mapping, want_iface_id): + self.flags(firewall_driver="nova.virt.firewall.NoopFirewallDriver") + xml = self._get_instance_xml(d, net, mapping) + doc = etree.fromstring(xml) + ret = doc.findall('./devices/interface') + self.assertEqual(len(ret), 1) + node = ret[0] + ret = node.findall("filterref") + self.assertEqual(len(ret), 0) + self.assertEqual(node.get("type"), "ethernet") + + tap_name = node.find("target").get("dev") + self.assertEqual(tap_name, mapping['vif_devname']) + mac = node.find("mac").get("address") + self.assertEqual(mac, mapping['mac']) + def _check_ovs_virtualport_driver(self, d, net, mapping, want_iface_id): self.flags(firewall_driver="nova.virt.firewall.NoopFirewallDriver") xml = self._get_instance_xml(d, net, mapping) @@ -502,6 +558,18 @@ class LibvirtVifTestCase(test.TestCase): self.mapping_ovs, want_iface_id) + def test_generic_ivs_virtualport_driver(self): + def get_connection(): + return fakelibvirt.Connection("qemu:///session", + False, + 9011) + d = vif.LibvirtGenericVIFDriver(get_connection) + want_iface_id = self.mapping_ivs['ivs_interfaceid'] + self._check_ivs_virtualport_driver(d, + self.net_ovs, + self.mapping_ivs, + want_iface_id) + def _check_quantum_hybrid_driver(self, d, net, mapping, br_want): self.flags(firewall_driver="nova.virt.firewall.IptablesFirewallDriver") xml = self._get_instance_xml(d, net, mapping) @@ -542,6 +610,18 @@ class LibvirtVifTestCase(test.TestCase): self.mapping_ovs, br_want) + def test_ivs_hybrid_driver(self): + def get_connection(): + return fakelibvirt.Connection("qemu:///session", + False) + d = vif.LibvirtGenericVIFDriver(get_connection) + br_want = "qbr" + self.mapping_ivs['vif_uuid'] + br_want = br_want[:network_model.NIC_NAME_LEN] + self._check_quantum_hybrid_driver(d, + self.net_ovs, + self.mapping_ivs, + br_want) + def test_generic_8021qbh_driver(self): def get_connection(): return fakelibvirt.Connection("qemu:///session", diff --git a/nova/tests/virt/powervm/test_powervm.py b/nova/tests/virt/powervm/test_powervm.py index 8fe08bdb8..fddd97a9d 100644 --- a/nova/tests/virt/powervm/test_powervm.py +++ b/nova/tests/virt/powervm/test_powervm.py @@ -173,7 +173,8 @@ class FakeBlockAdapter(powervm_blockdev.PowerVMLocalVolumeAdapter): def fake_get_powervm_operator(): - return FakeIVMOperator(None) + return FakeIVMOperator(common.Connection('fake_host', 'fake_user', + 'fake_password')) def create_instance(testcase): @@ -269,9 +270,12 @@ class PowerVMDriverTestCase(test.TestCase): self._loc_expected_task_state = expected_state loc_context = context.get_admin_context() + arch = 'fake_arch' properties = {'instance_id': self.instance['id'], - 'user_id': str(loc_context.user_id)} - sent_meta = {'name': 'fake_snap', 'is_public': False, + 'user_id': str(loc_context.user_id), + 'architecture': arch} + snapshot_name = 'fake_snap' + sent_meta = {'name': snapshot_name, 'is_public': False, 'status': 'creating', 'properties': properties} image_service = fake.FakeImageService() recv_meta = image_service.create(loc_context, sent_meta) @@ -283,6 +287,12 @@ class PowerVMDriverTestCase(test.TestCase): self.assertTrue(self._loc_task_state == task_states.IMAGE_UPLOADING and self._loc_expected_task_state == task_states.IMAGE_PENDING_UPLOAD) + snapshot = image_service.show(context, recv_meta['id']) + self.assertEquals(snapshot['properties']['image_state'], 'available') + self.assertEquals(snapshot['properties']['architecture'], arch) + self.assertEquals(snapshot['status'], 'active') + self.assertEquals(snapshot['name'], snapshot_name) + def _set_get_info_stub(self, state): def fake_get_instance(instance_name): return {'state': state, @@ -609,6 +619,25 @@ class PowerVMDriverTestCase(test.TestCase): self.assertEquals(host_stats['supported_instances'][0][1], "powervm") self.assertEquals(host_stats['supported_instances'][0][2], "hvm") + def test_get_host_uptime(self): + """ + Tests that the get_host_uptime method issues the proper sysstat command + and parses the output correctly. + """ + exp_cmd = "ioscli sysstat -short fake_user" + output = [("02:54PM up 24 days, 5:41, 1 user, " + "load average: 0.06, 0.03, 0.02")] + + fake_op = self.powervm_connection._powervm + self.mox.StubOutWithMock(fake_op._operator, 'run_vios_command') + fake_op._operator.run_vios_command(exp_cmd).AndReturn(output) + + self.mox.ReplayAll() + + # the host parameter isn't used so we just pass None + uptime = self.powervm_connection.get_host_uptime(None) + self.assertEquals("02:54PM up 24 days 5:41", uptime) + class PowerVMDriverLparTestCase(test.TestCase): """Unit tests for PowerVM connection calls.""" diff --git a/nova/tests/virt/test_virt_drivers.py b/nova/tests/virt/test_virt_drivers.py index 47f983258..6cc9bef43 100644 --- a/nova/tests/virt/test_virt_drivers.py +++ b/nova/tests/virt/test_virt_drivers.py @@ -60,7 +60,7 @@ class _FakeDriverBackendTestCase(object): # So that the _supports_direct_io does the test based # on the current working directory, instead of the # default instances_path which doesn't exist - self.flags(instances_path='') + self.flags(instances_path=self.useFixture(fixtures.TempDir()).path) # Put fakelibvirt in place if 'libvirt' in sys.modules: @@ -106,7 +106,8 @@ class _FakeDriverBackendTestCase(object): def fake_make_drive(_self, _path): pass - def fake_get_instance_disk_info(_self, instance, xml=None): + def fake_get_instance_disk_info(_self, instance, xml=None, + block_device_info=None): return '[]' self.stubs.Set(nova.virt.libvirt.driver.LibvirtDriver, @@ -311,13 +312,14 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase): @catch_notimplementederror def test_power_on_running(self): instance_ref, network_info = self._get_running_instance() - self.connection.power_on(instance_ref) + self.connection.power_on(self.ctxt, instance_ref, + network_info, None) @catch_notimplementederror def test_power_on_powered_off(self): instance_ref, network_info = self._get_running_instance() self.connection.power_off(instance_ref) - self.connection.power_on(instance_ref) + self.connection.power_on(self.ctxt, instance_ref, network_info, None) @catch_notimplementederror def test_soft_delete(self): @@ -407,7 +409,24 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase): self.connection.attach_volume({'driver_volume_type': 'fake'}, instance_ref, '/dev/sda') - self.connection.power_on(instance_ref) + + bdm = { + 'root_device_name': None, + 'swap': None, + 'ephemerals': [], + 'block_device_mapping': [{ + 'instance_uuid': instance_ref['uuid'], + 'connection_info': {'driver_volume_type': 'fake'}, + 'mount_device': '/dev/sda', + 'delete_on_termination': False, + 'virtual_name': None, + 'snapshot_id': None, + 'volume_id': 'abcdedf', + 'volume_size': None, + 'no_device': None + }] + } + self.connection.power_on(self.ctxt, instance_ref, network_info, bdm) self.connection.detach_volume({'driver_volume_type': 'fake'}, instance_ref, '/dev/sda') diff --git a/nova/tests/virt/vmwareapi/db_fakes.py b/nova/tests/virt/vmwareapi/db_fakes.py index 93fcf6e13..87c3dde67 100644 --- a/nova/tests/virt/vmwareapi/db_fakes.py +++ b/nova/tests/virt/vmwareapi/db_fakes.py @@ -1,5 +1,6 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # Copyright (c) 2011 Citrix Systems, Inc. # Copyright 2011 OpenStack Foundation # @@ -74,6 +75,7 @@ def stub_out_db_instance_api(stubs): 'vcpus': type_data['vcpus'], 'mac_addresses': [{'address': values['mac_address']}], 'root_gb': type_data['root_gb'], + 'node': values['node'], } return FakeModel(base_options) diff --git a/nova/tests/virt/vmwareapi/test_vmwareapi.py b/nova/tests/virt/vmwareapi/test_vmwareapi.py index 69a9ffab8..7b1829b84 100644 --- a/nova/tests/virt/vmwareapi/test_vmwareapi.py +++ b/nova/tests/virt/vmwareapi/test_vmwareapi.py @@ -1,5 +1,6 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # Copyright (c) 2012 VMware, Inc. # Copyright (c) 2011 Citrix Systems, Inc. # Copyright 2011 OpenStack Foundation @@ -111,6 +112,7 @@ class VMwareAPIVMTestCase(test.TestCase): use_linked_clone=False) self.user_id = 'fake' self.project_id = 'fake' + self.node_name = 'test_url' self.context = context.RequestContext(self.user_id, self.project_id) vmwareapi_fake.reset() db_fakes.stub_out_db_instance_api(self.stubs) @@ -143,6 +145,7 @@ class VMwareAPIVMTestCase(test.TestCase): 'ramdisk_id': "1", 'mac_address': "de:ad:be:ef:be:ef", 'instance_type': 'm1.large', + 'node': self.node_name, } self.instance = db.instance_create(None, values) @@ -332,14 +335,14 @@ class VMwareAPIVMTestCase(test.TestCase): self.conn.power_off(self.instance) info = self.conn.get_info({'uuid': 'fake-uuid'}) self._check_vm_info(info, power_state.SHUTDOWN) - self.conn.power_on(self.instance) + self.conn.power_on(self.context, self.instance, self.network_info) info = self.conn.get_info({'uuid': 'fake-uuid'}) self._check_vm_info(info, power_state.RUNNING) def test_power_on_non_existent(self): self._create_instance_in_the_db() self.assertRaises(exception.InstanceNotFound, self.conn.power_on, - self.instance) + self.context, self.instance, self.network_info) def test_power_off(self): self._create_vm() @@ -362,6 +365,40 @@ class VMwareAPIVMTestCase(test.TestCase): self.assertRaises(exception.InstancePowerOffFailure, self.conn.power_off, self.instance) + def test_resume_state_on_host_boot(self): + self._create_vm() + self.mox.StubOutWithMock(vm_util, 'get_vm_state_from_name') + self.mox.StubOutWithMock(self.conn, "reboot") + vm_util.get_vm_state_from_name(mox.IgnoreArg(), + self.instance['uuid']).AndReturn("poweredOff") + self.conn.reboot(self.context, self.instance, 'network_info', + 'hard', None) + self.mox.ReplayAll() + self.conn.resume_state_on_host_boot(self.context, self.instance, + 'network_info') + + def test_resume_state_on_host_boot_no_reboot_1(self): + """Don't call reboot on instance which is poweredon.""" + self._create_vm() + self.mox.StubOutWithMock(vm_util, 'get_vm_state_from_name') + self.mox.StubOutWithMock(self.conn, 'reboot') + vm_util.get_vm_state_from_name(mox.IgnoreArg(), + self.instance['uuid']).AndReturn("poweredOn") + self.mox.ReplayAll() + self.conn.resume_state_on_host_boot(self.context, self.instance, + 'network_info') + + def test_resume_state_on_host_boot_no_reboot_2(self): + """Don't call reboot on instance which is suspended.""" + self._create_vm() + self.mox.StubOutWithMock(vm_util, 'get_vm_state_from_name') + self.mox.StubOutWithMock(self.conn, 'reboot') + vm_util.get_vm_state_from_name(mox.IgnoreArg(), + self.instance['uuid']).AndReturn("suspended") + self.mox.ReplayAll() + self.conn.resume_state_on_host_boot(self.context, self.instance, + 'network_info') + def test_get_info(self): self._create_vm() info = self.conn.get_info({'uuid': 'fake-uuid'}) @@ -424,7 +461,7 @@ class VMwareAPIVMTestCase(test.TestCase): self.assertEquals(4, step) self.assertEqual(vmops.RESIZE_TOTAL_STEPS, total_steps) - self.stubs.Set(self.conn._vmops, "power_on", fake_power_on) + self.stubs.Set(self.conn._vmops, "_power_on", fake_power_on) self.stubs.Set(self.conn._vmops, "_update_instance_progress", fake_vmops_update_instance_progress) @@ -436,6 +473,7 @@ class VMwareAPIVMTestCase(test.TestCase): instance=self.instance, disk_info=None, network_info=None, + block_device_info=None, image_meta=None, power_on=power_on) # verify the results @@ -472,15 +510,20 @@ class VMwareAPIVMTestCase(test.TestCase): self.assertEquals(self.vm_name, vm_name) return vmwareapi_fake._get_objects("VirtualMachine")[0] + def fake_get_vm_ref_from_uuid(session, vm_uuid): + return vmwareapi_fake._get_objects("VirtualMachine")[0] + def fake_call_method(*args, **kwargs): pass def fake_wait_for_task(*args, **kwargs): pass - self.stubs.Set(self.conn._vmops, "power_on", fake_power_on) + self.stubs.Set(self.conn._vmops, "_power_on", fake_power_on) self.stubs.Set(self.conn._vmops, "_get_orig_vm_name_label", fake_get_orig_vm_name_label) + self.stubs.Set(vm_util, "get_vm_ref_from_uuid", + fake_get_vm_ref_from_uuid) self.stubs.Set(vm_util, "get_vm_ref_from_name", fake_get_vm_ref_from_name) self.stubs.Set(self.conn._session, "_call_method", fake_call_method) @@ -500,6 +543,41 @@ class VMwareAPIVMTestCase(test.TestCase): def test_finish_revert_migration_power_off(self): self._test_finish_revert_migration(power_on=False) + def test_diagnostics_non_existent_vm(self): + self._create_instance_in_the_db() + self.assertRaises(exception.InstanceNotFound, + self.conn.get_diagnostics, + self.instance) + + def test_get_console_pool_info(self): + info = self.conn.get_console_pool_info("console_type") + self.assertEquals(info['address'], 'test_url') + self.assertEquals(info['username'], 'test_username') + self.assertEquals(info['password'], 'test_pass') + + def test_get_vnc_console_non_existent(self): + self._create_instance_in_the_db() + self.assertRaises(exception.InstanceNotFound, + self.conn.get_vnc_console, + self.instance) + + def test_get_vnc_console(self): + self._create_instance_in_the_db() + self._create_vm() + vnc_dict = self.conn.get_vnc_console(self.instance) + self.assertEquals(vnc_dict['host'], "ha-host") + self.assertEquals(vnc_dict['port'], 5910) + + def test_host_ip_addr(self): + self.assertEquals(self.conn.get_host_ip_addr(), "test_url") + + def test_get_volume_connector(self): + self._create_instance_in_the_db() + connector_dict = self.conn.get_volume_connector(self.instance) + self.assertEquals(connector_dict['ip'], "test_url") + self.assertEquals(connector_dict['initiator'], "iscsi-name") + self.assertEquals(connector_dict['host'], "test_url") + class VMwareAPIHostTestCase(test.TestCase): """Unit tests for Vmware API host calls.""" @@ -547,3 +625,30 @@ class VMwareAPIHostTestCase(test.TestCase): def test_host_maintenance_off(self): self._test_host_action(self.conn.host_maintenance_mode, False) + + +class VMwareAPIVCDriverTestCase(VMwareAPIVMTestCase): + + def setUp(self): + super(VMwareAPIVCDriverTestCase, self).setUp() + self.flags( + vmwareapi_cluster_name='test_cluster', + vmwareapi_task_poll_interval=10, + vnc_enabled=False + ) + self.conn = driver.VMwareVCDriver(None, False) + + def tearDown(self): + super(VMwareAPIVCDriverTestCase, self).tearDown() + vmwareapi_fake.cleanup() + + def test_get_available_resource(self): + stats = self.conn.get_available_resource(self.node_name) + self.assertEquals(stats['vcpus'], 16) + self.assertEquals(stats['local_gb'], 1024) + self.assertEquals(stats['local_gb_used'], 1024 - 500) + self.assertEquals(stats['memory_mb'], 1024) + self.assertEquals(stats['memory_mb_used'], 1024 - 524) + self.assertEquals(stats['hypervisor_type'], 'VMware ESXi') + self.assertEquals(stats['hypervisor_version'], '5.0.0') + self.assertEquals(stats['hypervisor_hostname'], 'test_url') diff --git a/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py b/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py index 123a314c1..0456dfece 100644 --- a/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py +++ b/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py @@ -16,6 +16,8 @@ # License for the specific language governing permissions and limitations # under the License. +from collections import namedtuple + from nova import exception from nova import test from nova.virt.vmwareapi import fake @@ -33,9 +35,11 @@ class fake_session(object): class VMwareVMUtilTestCase(test.TestCase): def setUp(self): super(VMwareVMUtilTestCase, self).setUp() + fake.reset() def tearDown(self): super(VMwareVMUtilTestCase, self).tearDown() + fake.reset() def test_get_datastore_ref_and_name(self): result = vm_util.get_datastore_ref_and_name( @@ -54,3 +58,95 @@ class VMwareVMUtilTestCase(test.TestCase): self.assertRaises(exception.DatastoreNotFound, vm_util.get_datastore_ref_and_name, fake_session(), cluster="fake-cluster") + + def test_get_host_ref_from_id(self): + + fake_host_sys = fake.HostSystem( + fake.ManagedObjectReference("HostSystem", "host-123")) + + fake_host_id = fake_host_sys.obj.value + fake_host_name = "ha-host" + + ref = vm_util.get_host_ref_from_id( + fake_session([fake_host_sys]), fake_host_id, ['name']) + + self.assertIsInstance(ref, fake.HostSystem) + self.assertEqual(fake_host_id, ref.obj.value) + + host_name = vm_util.get_host_name_from_host_ref(ref) + + self.assertEquals(fake_host_name, host_name) + + def test_get_host_name_for_vm(self): + + fake_vm = fake.ManagedObject( + "VirtualMachine", fake.ManagedObjectReference( + "vm-123", "VirtualMachine")) + fake_vm.propSet.append( + fake.Property('name', 'vm-123')) + + vm_ref = vm_util.get_vm_ref_from_name( + fake_session([fake_vm]), 'vm-123') + + self.assertIsNotNone(vm_ref) + + fake_results = [ + fake.ObjectContent( + None, [ + fake.Property('runtime.host', + fake.ManagedObjectReference( + 'host-123', 'HostSystem')) + ])] + + host_id = vm_util.get_host_id_from_vm_ref( + fake_session(fake_results), vm_ref) + + self.assertEqual('host-123', host_id) + + def test_property_from_property_set(self): + + ObjectContent = namedtuple('ObjectContent', ['propSet']) + DynamicProperty = namedtuple('Property', ['name', 'val']) + MoRef = namedtuple('Val', ['value']) + + results_good = [ + ObjectContent(propSet=[ + DynamicProperty(name='name', val=MoRef(value='vm-123'))]), + ObjectContent(propSet=[ + DynamicProperty(name='foo', val=MoRef(value='bar1')), + DynamicProperty( + name='runtime.host', val=MoRef(value='host-123')), + DynamicProperty(name='foo', val=MoRef(value='bar2')), + ]), + ObjectContent(propSet=[ + DynamicProperty( + name='something', val=MoRef(value='thing'))]), ] + + results_bad = [ + ObjectContent(propSet=[ + DynamicProperty(name='name', val=MoRef(value='vm-123'))]), + ObjectContent(propSet=[ + DynamicProperty(name='foo', val='bar1'), + DynamicProperty(name='foo', val='bar2'), ]), + ObjectContent(propSet=[ + DynamicProperty( + name='something', val=MoRef(value='thing'))]), ] + + prop = vm_util.property_from_property_set( + 'runtime.host', results_good) + self.assertIsNotNone(prop) + value = prop.val.value + self.assertEqual('host-123', value) + + prop2 = vm_util.property_from_property_set( + 'runtime.host', results_bad) + self.assertIsNone(prop2) + + prop3 = vm_util.property_from_property_set('foo', results_good) + self.assertIsNotNone(prop3) + val3 = prop3.val.value + self.assertEqual('bar1', val3) + + prop4 = vm_util.property_from_property_set('foo', results_bad) + self.assertIsNotNone(prop4) + self.assertEqual('bar1', prop4.val) diff --git a/nova/tests/virt/xenapi/test_agent.py b/nova/tests/virt/xenapi/test_agent.py index 9a4d7c345..c81c9ec79 100644 --- a/nova/tests/virt/xenapi/test_agent.py +++ b/nova/tests/virt/xenapi/test_agent.py @@ -24,28 +24,28 @@ class AgentEnabledCase(test.TestCase): def test_agent_is_present(self): self.flags(xenapi_use_agent_default=False) instance = {"system_metadata": - {"image_xenapi_use_agent": "true"}} + [{"key": "image_xenapi_use_agent", "value": "true"}]} self.assertTrue(agent.should_use_agent(instance)) def test_agent_is_disabled(self): self.flags(xenapi_use_agent_default=True) instance = {"system_metadata": - {"image_xenapi_use_agent": "false"}} + [{"key": "image_xenapi_use_agent", "value": "false"}]} self.assertFalse(agent.should_use_agent(instance)) def test_agent_uses_deafault_when_prop_invalid(self): self.flags(xenapi_use_agent_default=True) instance = {"system_metadata": - {"image_xenapi_use_agent": "bob"}, + [{"key": "image_xenapi_use_agent", "value": "bob"}], "uuid": "uuid"} self.assertTrue(agent.should_use_agent(instance)) def test_agent_default_not_present(self): self.flags(xenapi_use_agent_default=False) - instance = {"system_metadata": {}} + instance = {"system_metadata": []} self.assertFalse(agent.should_use_agent(instance)) def test_agent_default_present(self): self.flags(xenapi_use_agent_default=True) - instance = {"system_metadata": {}} + instance = {"system_metadata": []} self.assertTrue(agent.should_use_agent(instance)) diff --git a/nova/tests/virt/xenapi/test_vm_utils.py b/nova/tests/virt/xenapi/test_vm_utils.py index 68caab651..6884ab5a8 100644 --- a/nova/tests/virt/xenapi/test_vm_utils.py +++ b/nova/tests/virt/xenapi/test_vm_utils.py @@ -266,7 +266,7 @@ class FetchVhdImageTestCase(test.TestCase): self._apply_stubouts() self._common_params_setup(True) - vm_utils._add_bittorrent_params(self.params) + vm_utils._add_bittorrent_params(self.image_id, self.params) vm_utils._fetch_using_dom0_plugin_with_retry(self.context, self.session, self.image_id, "bittorrent", self.params, @@ -289,7 +289,7 @@ class FetchVhdImageTestCase(test.TestCase): self._common_params_setup(True) self.mox.StubOutWithMock(self.session, 'call_xenapi') - vm_utils._add_bittorrent_params(self.params) + vm_utils._add_bittorrent_params(self.image_id, self.params) vm_utils._fetch_using_dom0_plugin_with_retry(self.context, self.session, self.image_id, "bittorrent", self.params, diff --git a/nova/tests/virt/xenapi/test_xenapi.py b/nova/tests/virt/xenapi/test_xenapi.py index 91d4f0770..f6ff23aba 100644 --- a/nova/tests/virt/xenapi/test_xenapi.py +++ b/nova/tests/virt/xenapi/test_xenapi.py @@ -31,6 +31,7 @@ from nova.compute import power_state from nova.compute import task_states from nova.compute import vm_states from nova import context +from nova import crypto from nova import db from nova import exception from nova.openstack.common import importutils @@ -983,13 +984,14 @@ class XenAPIVMTestCase(stubs.XenAPITestBase): actual_injected_files.append((path, contents)) return jsonutils.dumps({'returncode': '0', 'message': 'success'}) - def noop(*args, **kwargs): - pass - self.stubs.Set(stubs.FakeSessionForVMTests, '_plugin_agent_inject_file', fake_inject_file) - self.stubs.Set(agent.XenAPIBasedAgent, - 'set_admin_password', noop) + + def fake_encrypt_text(sshkey, new_pass): + self.assertEqual("fake_keydata", sshkey) + return "fake" + + self.stubs.Set(crypto, 'ssh_encrypt_text', fake_encrypt_text) expected_data = ('\n# The following ssh key was injected by ' 'Nova\nfake_keydata\n') @@ -1020,6 +1022,93 @@ class XenAPIVMTestCase(stubs.XenAPITestBase): self.check_vm_params_for_linux() self.assertEquals(actual_injected_files, injected_files) + def test_spawn_agent_upgrade(self): + self.flags(xenapi_use_agent_default=True) + actual_injected_files = [] + + def fake_agent_build(_self, *args): + return {"version": "1.1.0", "architecture": "x86-64", + "hypervisor": "xen", "os": "windows", + "url": "url", "md5hash": "asdf"} + + self.stubs.Set(self.conn.virtapi, 'agent_build_get_by_triple', + fake_agent_build) + + self._test_spawn(IMAGE_VHD, None, None, + os_type="linux", architecture="x86-64") + + def test_spawn_agent_upgrade_fails_silently(self): + self.flags(xenapi_use_agent_default=True) + actual_injected_files = [] + + def fake_agent_build(_self, *args): + return {"version": "1.1.0", "architecture": "x86-64", + "hypervisor": "xen", "os": "windows", + "url": "url", "md5hash": "asdf"} + + self.stubs.Set(self.conn.virtapi, 'agent_build_get_by_triple', + fake_agent_build) + + def fake_agent_update(self, method, args): + raise xenapi_fake.Failure(["fake_error"]) + + self.stubs.Set(stubs.FakeSessionForVMTests, + '_plugin_agent_agentupdate', fake_agent_update) + + self._test_spawn(IMAGE_VHD, None, None, + os_type="linux", architecture="x86-64") + + def _test_spawn_fails_with(self, trigger, expected_exception): + self.flags(xenapi_use_agent_default=True) + self.flags(agent_version_timeout=0) + actual_injected_files = [] + + def fake_agent_version(self, method, args): + raise xenapi_fake.Failure([trigger]) + + self.stubs.Set(stubs.FakeSessionForVMTests, + '_plugin_agent_version', fake_agent_version) + + self.assertRaises(expected_exception, self._test_spawn, + IMAGE_VHD, None, None, os_type="linux", architecture="x86-64") + + def test_spawn_fails_with_agent_timeout(self): + self._test_spawn_fails_with("TIMEOUT:fake", exception.AgentTimeout) + + def test_spawn_fails_with_agent_not_implemented(self): + self._test_spawn_fails_with("NOT IMPLEMENTED:fake", + exception.AgentNotImplemented) + + def test_spawn_fails_with_agent_error(self): + self._test_spawn_fails_with("fake_error", exception.AgentError) + + def test_spawn_fails_with_agent_bad_return(self): + self.flags(xenapi_use_agent_default=True) + self.flags(agent_version_timeout=0) + actual_injected_files = [] + + def fake_agent_version(self, method, args): + return xenapi_fake.as_json(returncode='-1', message='fake') + self.stubs.Set(stubs.FakeSessionForVMTests, + '_plugin_agent_version', fake_agent_version) + + self.assertRaises(exception.AgentError, self._test_spawn, + IMAGE_VHD, None, None, os_type="linux", architecture="x86-64") + + def test_spawn_fails_agent_not_implemented(self): + # Test spawning with injected_files. + self.flags(xenapi_use_agent_default=True) + self.flags(agent_version_timeout=0) + actual_injected_files = [] + + def fake_agent_version(self, method, args): + raise xenapi_fake.Failure(["NOT IMPLEMENTED:fake"]) + self.stubs.Set(stubs.FakeSessionForVMTests, + '_plugin_agent_version', fake_agent_version) + + self.assertRaises(exception.AgentNotImplemented, self._test_spawn, + IMAGE_VHD, None, None, os_type="linux", architecture="x86-64") + def test_rescue(self): instance = self._create_instance() session = xenapi_conn.XenAPISession('test_url', 'root', 'test_pass', |