class LXDTestContainerImage(test.NoDBTestCase): @mock.patch.object(session, 'CONF', stubs.MockConf()) def setUp(self): super(LXDTestContainerImage, self).setUp() self.tempdir = self.useFixture(fixtures.TempDir()).path self.fixture = self.useFixture(config_fixture.Config(lockutils.CONF)) self.fixture.config(lock_path=self.tempdir, group='oslo_concurrency') self.fixture.config(disable_process_locking=True, group='oslo_concurrency') self.image = image.LXDContainerImage() @stubs.annotated_data( ('valid_image_raw', True, { 'disk_format': 'raw' }, None), ('valid_image_root-tar', True, { 'disk_format': 'root-tar' }, None), ('qcow2_image', False, { 'disk_format': 'qcow2' }, exception.ImageUnacceptable), ('iso_image', False, { 'disk_format': 'iso' }, exception.ImageUnacceptable), ('image_unacceptable', False, { 'disk_format': '' }, exception.ImageUnacceptable), ('bad_meta', False, {}, exception.ImageUnacceptable), ) def test_image(self, tag, sucess, image_data, expected): context = mock.Mock instance = stubs._fake_instance() with mock.patch.object(image.IMAGE_API, 'get', return_value=image_data): if sucess: self.assertEqual(expected, self.image._verify_image(context, instance)) else: self.assertRaises(expected, self.image._verify_image, context, instance) @mock.patch.object(image.IMAGE_API, 'download') def test_fetch_image(self, mock_download): context = mock.Mock() instance = stubs._fake_instance() self.assertEqual(None, self.image._fetch_image(context, instance)) @mock.patch.object(os, 'stat') @mock.patch.object(json, 'dumps') @mock.patch.object(tarfile, 'open') @mock.patch.object(io, 'BytesIO') @mock.patch.object(image.IMAGE_API, 'get') def test_get_lxd_manifest(self, mock_stat, mock_json, mock_tarfile, mock_io, mock_image): instance = stubs._fake_instance() image_meta = mock.Mock() self.assertEqual(None, self.image._get_lxd_manifest(instance, image_meta))
import ddt import mock from nova import test from nova.tests.unit import fake_network from nova.virt.lxd import config from nova.virt.lxd import session from nova.virt.lxd import utils as container_dir from oslo_utils import units import stubs @ddt.ddt @mock.patch.object(config, 'CONF', stubs.MockConf()) @mock.patch.object(container_dir, 'CONF', stubs.MockConf()) class LXDTestContainerConfig(test.NoDBTestCase): """LXD Container configuration unit tests.""" def setUp(self): super(LXDTestContainerConfig, self).setUp() self.config = config.LXDContainerConfig() @stubs.annotated_data( ('test_name', 'name', 'instance-00000001'), ('test_source', 'source', {'type': 'image', 'alias': 'fake_image'}), ('test_devices', 'devices', {}) ) def test_create_container(self, tag, key, expected):
class LXDTestDriver(test.NoDBTestCase): @mock.patch.object(driver, 'CONF', stubs.MockConf()) def setUp(self): super(LXDTestDriver, self).setUp() self.ml = stubs.lxd_mock() lxd_patcher = mock.patch('pylxd.api.API', mock.Mock(return_value=self.ml)) lxd_patcher.start() self.addCleanup(lxd_patcher.stop) self.connection = driver.LXDDriver(fake.FakeVirtAPI()) def test_capabilities(self): self.assertFalse(self.connection.capabilities['has_imagecache']) self.assertFalse(self.connection.capabilities['supports_recreate']) self.assertFalse( self.connection.capabilities['supports_migrate_to_same_host']) self.assertTrue( self.connection.capabilities['supports_attach_interface']) def test_init_host(self): self.assertEqual(True, self.connection.init_host(None)) def test_init_host_new_profile(self): self.ml.profile_list.return_value = [] self.assertEqual(True, self.connection.init_host(None)) @stubs.annotated_data( ('no_ping', { 'host_ping.return_value': False }), ('ping_fail', { 'host_ping.side_effect': (lxd_exceptions.APIError('Fake', 500)) }), ) def test_init_host_fail(self, tag, config): self.ml.configure_mock(**config) self.assertRaises(exception.HostNotFound, self.connection.init_host, None) @stubs.annotated_data( ('running', { 'state': 200, 'mem': 0, 'max_mem': 0 }, power_state.RUNNING), ('shutdown', { 'state': 102, 'mem': 0, 'max_mem': 0 }, power_state.SHUTDOWN), ('crashed', { 'state': 108, 'mem': 0, 'max_mem': 0 }, power_state.CRASHED), ('suspend', { 'state': 109, 'mem': 0, 'max_mem': 0 }, power_state.SUSPENDED), ('no_state', { 'state': 401, 'mem': 0, 'max_mem': 0 }, power_state.NOSTATE), ) def test_get_info(self, tag, side_effect, expected): instance = stubs._fake_instance() with mock.patch.object( session.LXDAPISession, "container_state", ) as state: state.return_value = side_effect info = self.connection.get_info(instance) self.assertEqual( dir(hardware.InstanceInfo(state=expected, num_cpu=2)), dir(info)) @stubs.annotated_data( (True, 'mock-instance-1'), (False, 'fake-instance'), ) def test_instance_exists(self, expected, name): self.assertEqual( expected, self.connection.instance_exists(stubs.MockInstance(name=name))) def test_estimate_instance_overhead(self): self.assertEqual({'memory_mb': 0}, self.connection.estimate_instance_overhead( mock.Mock())) def test_list_instances(self): self.assertEqual(['mock-instance-1', 'mock-instance-2'], self.connection.list_instances()) def test_list_instances_fail(self): self.ml.container_list.side_effect = (lxd_exceptions.APIError( 'Fake', 500)) self.assertRaises(exception.NovaException, self.connection.list_instances) @stubs.annotated_data( ('exists', [True], exception.InstanceExists), ('fail', lxd_exceptions.APIError('Fake', 500), exception.NovaException) ) def test_spawn_defined(self, tag, side_effect, expected): instance = stubs.MockInstance() self.ml.container_defined.side_effect = side_effect self.assertRaises(expected, self.connection.spawn, {}, instance, {}, [], 'secret') self.ml.container_defined.called_once_with('mock_instance') @stubs.annotated_data( ('undefined', False), ('404', lxd_exceptions.APIError('Not found', 404)), ) @mock.patch('oslo_concurrency.lockutils.lock') def test_spawn_new(self, tag, side_effect, mc): context = mock.Mock() instance = stubs.MockInstance() image_meta = mock.Mock() injected_files = mock.Mock() network_info = mock.Mock() block_device_info = mock.Mock() self.ml.container_defined.side_effect = [side_effect] with test.nested( mock.patch.object(self.connection.container_ops, 'spawn'), ) as (create_container): self.connection.spawn(context, instance, image_meta, injected_files, None, network_info, block_device_info) self.assertTrue(create_container) def test_destroy_fail(self): instance = stubs._fake_instance() context = mock.Mock() network_info = mock.Mock() self.ml.container_destroy.side_effect = (lxd_exceptions.APIError( 'Fake', 500)) with test.nested( mock.patch.object(session.LXDAPISession, 'container_destroy'), mock.patch.object(session.LXDAPISession, 'container_stop'), mock.patch.object(self.connection, 'cleanup'), mock.patch.object(container_ops.LXDContainerOperations, 'unplug_vifs'), ) as (container_destroy, container_stop, cleanup, unplug_vifs): self.connection.destroy(context, instance, network_info) def test_destroy(self): instance = stubs._fake_instance() context = mock.Mock() network_info = mock.Mock() with test.nested( mock.patch.object(session.LXDAPISession, 'container_stop'), mock.patch.object(session.LXDAPISession, 'container_destroy'), mock.patch.object(self.connection, 'cleanup'), mock.patch.object(container_ops.LXDContainerOperations, 'unplug_vifs'), ) as (container_stop, container_destroy, cleanup, unplug_vifs): self.connection.destroy(context, instance, network_info) self.assertTrue(container_stop) self.assertTrue(container_destroy) self.assertTrue(cleanup) unplug_vifs.assert_called_with(instance, network_info) @mock.patch('os.path.exists', mock.Mock(return_value=True)) @mock.patch('shutil.rmtree') @mock.patch('pwd.getpwuid', mock.Mock(return_value=mock.Mock(pw_uid=1234))) @mock.patch.object(container_ops.utils, 'execute') def test_cleanup(self, mr, mu): instance = stubs.MockInstance() self.assertEqual( None, self.connection.cleanup({}, instance, [], [], None, None, None)) @mock.patch('six.moves.builtins.open') @mock.patch.object(container_ops.utils, 'execute') @mock.patch('pwd.getpwuid', mock.Mock(return_value=mock.Mock(pw_uid=1234))) @mock.patch('os.getuid', mock.Mock()) @mock.patch('os.path.exists', mock.Mock(return_value=True)) def test_get_console_output(self, me, mo): instance = stubs.MockInstance() mo.return_value.__enter__.return_value = six.BytesIO(b'fake contents') self.assertEqual(b'fake contents', self.connection.get_console_output({}, instance)) calls = [ mock.call('chown', '1234:1234', '/var/log/lxd/fake-uuid/console.log', run_as_root=True), mock.call('chmod', '755', '/fake/lxd/root/containers/fake-uuid', run_as_root=True) ] self.assertEqual(calls, me.call_args_list) @mock.patch.object(host.compute_utils, 'get_machine_ips') @stubs.annotated_data( ('found', ['1.2.3.4']), ('not-found', ['4.3.2.1']), ) def test_get_host_ip_addr(self, tag, return_value, mi): mi.return_value = return_value self.assertEqual('1.2.3.4', self.connection.get_host_ip_addr()) @mock.patch('socket.gethostname', mock.Mock(return_value='fake_hostname')) @mock.patch('os.statvfs', return_value=mock.Mock(f_blocks=131072000, f_bsize=8192, f_bavail=65536000)) @mock.patch('six.moves.builtins.open') @mock.patch.object(container_ops.utils, 'execute') def test_get_available_resource(self, me, mo, ms): me.return_value = ('Model name: Fake CPU\n' 'Vendor ID: FakeVendor\n' 'Socket(s): 10\n' 'Core(s) per socket: 5\n' 'Thread(s) per core: 4\n' '\n', None) meminfo = mock.MagicMock() meminfo.__enter__.return_value = six.moves.cStringIO( 'MemTotal: 10240000 kB\n' 'MemFree: 2000000 kB\n' 'Buffers: 24000 kB\n' 'Cached: 24000 kB\n') mo.side_effect = [ six.moves.cStringIO('flags: fake flag goes here\n' 'processor: 2\n' '\n'), meminfo, ] value = self.connection.get_available_resource(None) value['cpu_info'] = json.loads(value['cpu_info']) value['supported_instances'] = [ [arch.I686, hv_type.LXD, vm_mode.EXE], [arch.X86_64, hv_type.LXD, vm_mode.EXE], [arch.I686, hv_type.LXC, vm_mode.EXE], [arch.X86_64, hv_type.LXC, vm_mode.EXE] ] expected = { 'cpu_info': { u'arch': platform.uname()[5], u'features': u'fake flag goes here', u'model': u'Fake CPU', u'topology': { u'cores': u'5', u'sockets': u'10', u'threads': u'4' }, u'vendor': u'FakeVendor' }, 'hypervisor_hostname': 'fake_hostname', 'hypervisor_type': 'lxd', 'hypervisor_version': '011', 'local_gb': 1000, 'local_gb_used': 500, 'memory_mb': 10000, 'memory_mb_used': 8000, 'numa_topology': None, 'supported_instances': [[arch.I686, hv_type.LXD, vm_mode.EXE], [arch.X86_64, hv_type.LXD, vm_mode.EXE], [arch.I686, hv_type.LXC, vm_mode.EXE], [arch.X86_64, hv_type.LXC, vm_mode.EXE]], 'vcpus': 200, 'vcpus_used': 0 } self.assertEqual(expected, value) me.assert_called_once_with('lscpu') self.assertEqual( [mock.call('/proc/cpuinfo', 'r'), mock.call('/proc/meminfo')], mo.call_args_list) ms.assert_called_once_with('/fake/lxd/root') def test_container_reboot(self): instance = stubs._fake_instance() context = mock.Mock() network_info = mock.Mock() reboot_type = 'SOFT' with test.nested( mock.patch.object(self.connection.container_ops, 'reboot')) as (reboot): self.connection.reboot(context, instance, network_info, reboot_type) self.assertTrue(reboot) def test_container_power_off(self): instance = stubs._fake_instance() with test.nested( mock.patch.object(self.connection.container_ops, 'power_off')) as (power_off): self.connection.power_off(instance) self.assertTrue(power_off) def test_container_power_on(self): context = mock.Mock() instance = stubs._fake_instance() network_info = mock.Mock() with test.nested( mock.patch.object(self.connection.container_ops, 'power_on')) as (power_on): self.connection.power_on(context, instance, network_info) self.assertTrue(power_on) @stubs.annotated_data( ('refresh_security_group_rules', (mock.Mock(), )), ('refresh_security_group_members', (mock.Mock(), )), ('refresh_provider_fw_rules', ), ('refresh_instance_security_rules', (mock.Mock(), )), ('ensure_filtering_rules_for_instance', (mock.Mock(), mock.Mock())), ('filter_defer_apply_on', ), ('filter_defer_apply_off', ), ('unfilter_instance', (mock.Mock(), mock.Mock())), ) def test_firewall_calls(self, name, args=()): with mock.patch.object(self.connection.container_firewall, 'firewall_driver') as mf: driver_method = getattr(self.connection, name) firewall_method = getattr(mf, name) self.assertEqual(firewall_method.return_value, driver_method(*args)) firewall_method.assert_called_once_with(*args) @mock.patch.object(host.utils, 'execute') def test_get_host_uptime(self, me): me.return_value = ('out', 'err') self.assertEqual('out', self.connection.get_host_uptime()) @mock.patch('socket.gethostname', mock.Mock(return_value='mock_hostname')) def test_get_available_nodes(self): self.assertEqual(['mock_hostname'], self.connection.get_available_nodes()) @mock.patch('socket.gethostname', mock.Mock(return_value='mock_hostname')) @stubs.annotated_data( ('mock_hostname', True), ('wrong_hostname', False), ) def test_node_is_available(self, nodename, available): self.assertEqual(available, self.connection.node_is_available(nodename))
from nova.virt.lxd import operations as container_ops from nova.virt.lxd import session from nova.virt.lxd import utils as container_dir import stubs class LXDTestConfig(test.NoDBTestCase): def test_config(self): self.assertIsInstance(driver.CONF.lxd, cfg.ConfigOpts.GroupAttr) self.assertEqual(os.path.abspath('/var/lib/lxd'), os.path.abspath(driver.CONF.lxd.root_dir)) self.assertEqual(-1, driver.CONF.lxd.timeout) @ddt.ddt @mock.patch.object(container_ops, 'CONF', stubs.MockConf()) @mock.patch.object(container_dir, 'CONF', stubs.MockConf()) @mock.patch.object(driver, 'CONF', stubs.MockConf()) @mock.patch.object(host, 'CONF', stubs.MockConf()) class LXDTestDriver(test.NoDBTestCase): @mock.patch.object(driver, 'CONF', stubs.MockConf()) def setUp(self): super(LXDTestDriver, self).setUp() self.ml = stubs.lxd_mock() lxd_patcher = mock.patch('pylxd.api.API', mock.Mock(return_value=self.ml)) lxd_patcher.start() self.addCleanup(lxd_patcher.stop) self.connection = driver.LXDDriver(fake.FakeVirtAPI())
import ddt import mock from nova import test from nova.virt import fake from nova.virt.lxd import config from nova.virt.lxd import image from nova.virt.lxd import operations as container_ops from nova.virt.lxd import session import stubs @ddt.ddt @mock.patch.object(container_ops, 'CONF', stubs.MockConf()) class LXDTestContainerOps(test.NoDBTestCase): """LXD Container operations unit tests.""" def setUp(self): super(LXDTestContainerOps, self).setUp() self.ml = stubs.lxd_mock() lxd_patcher = mock.patch('pylxd.api.API', mock.Mock(return_value=self.ml)) lxd_patcher.start() self.addCleanup(lxd_patcher.stop) self.operations = ( container_ops.LXDContainerOperations(fake.FakeVirtAPI())) self.mv = mock.MagicMock() vif_patcher = mock.patch.object(self.operations,