diff options
Diffstat (limited to 'nova/tests/virt/libvirt/test_libvirt.py')
-rw-r--r-- | nova/tests/virt/libvirt/test_libvirt.py | 293 |
1 files changed, 271 insertions, 22 deletions
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): |