Exemplo n.º 1
0
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))
Exemplo n.º 2
0
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):
Exemplo n.º 3
0
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))
Exemplo n.º 4
0
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())
Exemplo n.º 5
0
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,