Example #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))
class LXDTestContainerMigrate(test.NoDBTestCase):
    @mock.patch.object(container_migrate, 'CONF', stubs.MockConf())
    def setUp(self):
        super(LXDTestContainerMigrate, self).setUp()

        self.migrate = container_migrate.LXDContainerMigrate(
            fake.FakeVirtAPI())

    def test_finish_migration(self):
        context = mock.Mock()
        migration = {
            'source_compute': 'fake-source',
            'dest_compute': 'fake-dest'
        }
        instance = stubs._fake_instance()
        bdevice_info = mock.Mock()
        disk_info = mock.Mock()
        network_info = mock.Mock()
        with contextlib.nested(
                mock.patch.object(container_client.LXDContainerClient,
                                  'client'),
                mock.patch.object(container_utils.LXDContainerUtils,
                                  'container_stop'),
                mock.patch.object(container_utils.LXDContainerUtils,
                                  'container_init'),
                mock.patch.object(container_utils.LXDContainerUtils,
                                  'container_destroy'),
        ) as (container_defined, container_stop, container_init,
              container_destroy):
            self.assertEqual(None, (self.migrate.finish_migration(
                context, migration, instance, disk_info, network_info,
                bdevice_info)))
#    License for the specific language governing permissions and limitations
#    under the License.

import ddt
import mock

from nova import exception
from nova import test

from nova_lxd.nova.virt.lxd import container_config
from nova_lxd.nova.virt.lxd import utils as container_dir
from nova_lxd.tests import stubs


@ddt.ddt
@mock.patch.object(container_config, 'CONF', stubs.MockConf())
@mock.patch.object(container_dir, 'CONF', stubs.MockConf())
class LXDTestContainerConfig(test.NoDBTestCase):
    def setUp(self):
        super(LXDTestContainerConfig, self).setUp()
        self.container_config = container_config.LXDContainerConfig()

    def test_init_config(self):
        self.assertEqual({
            'config': {},
            'devices': {}
        }, self.container_config._init_container_config())

    @stubs.annotated_data(
        ('mem_limit', {
            'memory_mb': 2048
#    under the License.

import contextlib

import mock

from nova import test
from nova.virt import fake

from nova_lxd.nova.virt.lxd import container_client
from nova_lxd.nova.virt.lxd import container_migrate
from nova_lxd.nova.virt.lxd import container_utils
from nova_lxd.tests import stubs


@mock.patch.object(container_migrate, 'CONF', stubs.MockConf())
class LXDTestContainerMigrate(test.NoDBTestCase):
    @mock.patch.object(container_migrate, 'CONF', stubs.MockConf())
    def setUp(self):
        super(LXDTestContainerMigrate, self).setUp()

        self.migrate = container_migrate.LXDContainerMigrate(
            fake.FakeVirtAPI())

    def test_finish_migration(self):
        context = mock.Mock()
        migration = {
            'source_compute': 'fake-source',
            'dest_compute': 'fake-dest'
        }
        instance = stubs._fake_instance()
Example #5
0
class LXDTestContainerOps(test.NoDBTestCase):
    @mock.patch.object(container_utils, 'CONF', stubs.MockConf())
    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.container_ops = (container_ops.LXDContainerOperations(
            fake.FakeVirtAPI()))
        self.mc = mock.MagicMock()
        config_patcher = mock.patch.object(self.container_ops,
                                           'container_config', self.mc)
        config_patcher.start()
        self.addCleanup(config_patcher.stop)
        self.mv = mock.MagicMock()
        vif_patcher = mock.patch.object(self.container_ops, 'vif_driver',
                                        self.mv)
        vif_patcher.start()
        self.addCleanup(vif_patcher.stop)

    def test_rescue_defined(self):
        instance = stubs.MockInstance()
        self.ml.container_defined.return_value = True
        self.assertRaises(exception.InstanceExists,
                          self.container_ops.spawn, {},
                          instance, {}, [],
                          'secret',
                          rescue=True)
        self.ml.container_defined.called_once_with('fake-instance')

    def test_create_instance_initfail(self):
        instance = stubs._fake_instance()
        self.ml.container_init.side_effect = (lxd_exception.APIError(
            'Fake', 500))
        self.assertEqual(
            None,
            self.container_ops.create_container(instance, [], [], {}, None,
                                                True))

    @stubs.annotated_data(('network_info', False, mock.Mock()),
                          ('rescue', False, mock.Mock()),
                          ('network-rescue', True, mock.Mock()))
    def test_create_container(self, tag, rescue, network_info):
        instance = stubs._fake_instance()
        injected_files = mock.Mock()
        block_device_info = mock.Mock()
        need_vif_plugged = mock.Mock()
        self.ml.container_defined.return_value = True

        with contextlib.nested(
                mock.patch.object(container_config.LXDContainerConfig,
                                  'create_container'),
                mock.patch.object(container_utils.LXDContainerUtils,
                                  'container_init'),
                mock.patch.object(self.container_ops,
                                  'start_container')) as (create_container,
                                                          container_init,
                                                          start_container):
            self.assertEqual(
                None,
                self.container_ops.create_container(instance, injected_files,
                                                    network_info,
                                                    block_device_info, rescue,
                                                    need_vif_plugged))
            create_container.called_assert_called_once_with(
                instance, injected_files, block_device_info, rescue)
            print(container_init.method_calls)
            container_init.called_assert_called_once_with(
                container_config, instance.host)

    @mock.patch.object(container_ops, 'utils')
    @stubs.annotated_data(
        {
            'tag': 'rescue',
            'rescue': True,
            'is_neutron': False,
            'timeout': 0
        },
        {
            'tag': 'neutron',
            'timeout': 0
        },
        {'tag': 'neutron_timeout'},
        {
            'tag': 'neutron_unknown',
            'network_info': [{
                'id': '0123456789abcdef',
            }]
        },
        {
            'tag': 'neutron_active',
            'network_info': [{
                'id': '0123456789abcdef',
                'active': True
            }]
        },
        {
            'tag': 'neutron_inactive',
            'network_info': [{
                'id': '0123456789abcdef',
                'active': False
            }],
            'vifs': ('0123456789abcdef', )
        },
        {
            'tag':
            'neutron_multi',
            'network_info': [{
                'id': '0123456789abcdef',
            }, {
                'id': '123456789abcdef0',
                'active': True
            }, {
                'id': '23456789abcdef01',
                'active': False
            }],
            'vifs': ('23456789abcdef01', )
        },
        {
            'tag': 'neutron_failed',
            'network_info': [{
                'id': '0123456789abcdef',
                'active': False
            }],
            'vifs': ('0123456789abcdef', ),
            'plug_side_effect': exception.VirtualInterfaceCreateException
        },
    )
    def test_start_instance(self,
                            mu,
                            tag='',
                            rescue=False,
                            running=False,
                            is_neutron=True,
                            timeout=10,
                            network_info=[],
                            vifs=(),
                            plug_side_effect=None):
        instance = stubs.MockInstance()
        container_config = mock.Mock()
        need_vif_plugged = True
        self.ml.container_running.return_value = running
        self.ml.container_start.return_value = (200, {
            'operation':
            '/1.0/operations/0123456789'
        })
        container_ops.CONF.vif_plugging_timeout = timeout
        mu.is_neutron.return_value = is_neutron
        self.mv.plug.side_effect = plug_side_effect
        with mock.patch.object(self.container_ops.virtapi,
                               'wait_for_instance_event') as mw:
            self.assertEqual(
                None,
                self.container_ops.start_container(container_config, instance,
                                                   network_info,
                                                   need_vif_plugged))
            mw.assert_called_once_with(
                instance, [('network-vif-plugged', vif) for vif in vifs],
                deadline=timeout,
                error_callback=self.container_ops._neutron_failed_callback)
        self.assertEqual(
            [mock.call(instance, viface) for viface in network_info],
            self.mv.plug.call_args_list)
        calls = [
            mock.call.container_start('fake-uuid', 5),
            mock.call.wait_container_operation('/1.0/operations/0123456789',
                                               200, -1)
        ]
        self.assertEqual(calls, self.ml.method_calls[-2:])
Example #6
0
import mock

import contextlib
from nova import exception
from nova import test
from nova.virt import fake
from pylxd import exceptions as lxd_exception

from nova_lxd.nova.virt.lxd import container_config
from nova_lxd.nova.virt.lxd import container_ops
from nova_lxd.nova.virt.lxd import container_utils
from nova_lxd.tests import stubs


@ddt.ddt
@mock.patch.object(container_ops, 'CONF', stubs.MockConf())
@mock.patch.object(container_utils, 'CONF', stubs.MockConf())
class LXDTestContainerOps(test.NoDBTestCase):
    @mock.patch.object(container_utils, 'CONF', stubs.MockConf())
    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.container_ops = (container_ops.LXDContainerOperations(
            fake.FakeVirtAPI()))
        self.mc = mock.MagicMock()
        config_patcher = mock.patch.object(self.container_ops,
class LXDTestContainerUtils(test.NoDBTestCase):

    @mock.patch.object(container_utils, 'CONF', stubs.MockConf())
    def setUp(self):
        super(LXDTestContainerUtils, self).setUp()

        self.container_utils = container_utils.LXDContainerUtils()

    def test_container_start(self):
        instance = stubs._fake_instance()
        instance_name = 'fake-uuid'
        with contextlib.nested(
            mock.patch.object(container_client.LXDContainerClient,
                              'container_start'),
            mock.patch.object(container_client.LXDContainerClient,
                              'container_wait'),
        ) as (
            container_start,
            container_wait
        ):
            container_start.return_value = (200, fake_api.fake_operation())
            self.assertEqual(None,
                             (self.container_utils.container_start(
                                 instance_name, instance)))
            self.assertTrue(container_start)
            self.assertTrue(container_wait)

    def test_container_stop(self):
        instance = stubs._fake_instance()
        instance_name = 'fake-uuid'
        with contextlib.nested(
            mock.patch.object(container_client.LXDContainerClient,
                              'container_stop'),
            mock.patch.object(container_client.LXDContainerClient,
                              'container_wait'),
        ) as (
            container_stop,
            container_wait
        ):
            container_stop.return_value = (200, fake_api.fake_operation())
            self.assertEqual(None,
                             (self.container_utils.container_stop(
                                 instance_name, instance)))
            self.assertTrue(container_stop)
            self.assertTrue(container_wait)

    def test_container_reboot(self):
        instance = stubs._fake_instance()
        with contextlib.nested(
            mock.patch.object(container_client.LXDContainerClient,
                              'container_reboot'),
            mock.patch.object(container_client.LXDContainerClient,
                              'container_wait'),
        ) as (
            container_reboot,
            container_wait
        ):
            container_reboot.return_value = (200, fake_api.fake_operation())
            self.assertEqual(None,
                             self.container_utils.container_reboot(instance))
            self.assertTrue(container_reboot)
            self.assertTrue(container_wait)

    def test_container_destroy(self):
        instance_name = mock.Mock()
        host = mock.Mock()
        with contextlib.nested(
            mock.patch.object(container_client.LXDContainerClient,
                              'container_defined'),
            mock.patch.object(container_utils.LXDContainerUtils,
                              'container_stop'),
            mock.patch.object(container_client.LXDContainerClient,
                              'container_destroy'),
            mock.patch.object(container_client.LXDContainerClient,
                              'container_wait')
        ) as (
            container_defined,
            container_stop,
            container_destroy,
            container_wait
        ):
            container_defined.retrun_value = True
            container_destroy.return_value = (200, fake_api.fake_operation())
            self.assertEqual(None,
                             (self.container_utils.container_destroy(
                                 instance_name, host)))
            self.assertTrue(container_defined)
            self.assertTrue(container_stop)
            self.assertTrue(container_destroy)
            self.assertTrue(container_wait)

    def test_container_pause(self):
        instance = stubs._fake_instance()
        instance_name = 'fake-uuid'
        with contextlib.nested(
            mock.patch.object(container_client.LXDContainerClient,
                              'container_pause'),
            mock.patch.object(container_client.LXDContainerClient,
                              'container_wait'),
        ) as (
            container_pause,
            container_wait
        ):
            container_pause.return_value = (200, fake_api.fake_operation())
            self.assertEqual(None,
                             (self.container_utils.container_pause(
                                 instance_name, instance)))
            self.assertTrue(container_pause)
            self.assertTrue(container_wait)

    def test_container_unpause(self):
        instance = stubs._fake_instance()
        instance_name = 'fake-uuid'
        with contextlib.nested(
            mock.patch.object(container_client.LXDContainerClient,
                              'container_pause'),
            mock.patch.object(container_client.LXDContainerClient,
                              'container_wait'),
        ) as (
            container_pause,
            container_wait
        ):
            container_pause.return_value = (200, fake_api.fake_operation())
            self.assertEqual(None,
                             self.container_utils.container_pause(
                                 instance_name, instance))
            self.assertTrue(container_pause)
            self.assertTrue(container_wait)

    def test_container_suspend(self):
        instance = stubs._fake_instance()
        snapshot = mock.Mock()
        with contextlib.nested(
            mock.patch.object(container_client.LXDContainerClient,
                              'container_snapshot_create'),
            mock.patch.object(container_client.LXDContainerClient,
                              'container_wait'),
        ) as (
            snapshot_create,
            container_wait
        ):
            snapshot_create.return_value = (200, fake_api.fake_operation())
            self.assertEqual(None,
                             (self.container_utils.container_snapshot(
                                 snapshot, instance)))
            self.assertTrue(snapshot_create)
            self.assertTrue(container_wait)

    def test_container_copy(self):
        instance = stubs._fake_instance()
        config = mock.Mock()

        with contextlib.nested(
            mock.patch.object(container_client.LXDContainerClient,
                              'container_local_copy'),
            mock.patch.object(container_client.LXDContainerClient,
                              'container_wait'),
        ) as (
            container_copy,
            container_wait
        ):
            container_copy.return_value = (200, fake_api.fake_operation())
            self.assertEqual(None,
                             (self.container_utils.container_copy(config,
                                                                  instance)))
            self.assertTrue(container_copy)
            self.assertTrue(container_wait)

    def test_container_move(self):
        instance = stubs._fake_instance()
        config = mock.Mock()
        old_name = mock.Mock()

        with contextlib.nested(
            mock.patch.object(container_client.LXDContainerClient,
                              'container_local_move'),
            mock.patch.object(container_client.LXDContainerClient,
                              'container_wait'),
        ) as (
            container_move,
            container_wait
        ):
            container_move.return_value = (200, fake_api.fake_operation())
            self.assertEqual(None,
                             (self.container_utils.container_move(old_name,
                                                                  config,
                                                                  instance)))
            self.assertTrue(container_move)
            self.assertTrue(container_wait)

    def test_container_init(self):
        config = mock.Mock()
        instance = stubs._fake_instance()
        host = mock.Mock()
        with contextlib.nested(
            mock.patch.object(container_client.LXDContainerClient,
                              'container_init'),
            mock.patch.object(container_client.LXDContainerClient,
                              'container_wait'),
            mock.patch.object(container_client.LXDContainerClient,
                              'container_operation_info'),
        ) as (
            container_init,
            container_wait,
            container_operation_info,
        ):
            container_init.return_value = (200, fake_api.fake_operation())
            container_operation_info.return_value = (
                200,
                fake_api.fake_operation_info_ok())
            self.assertEqual(None,
                             (self.container_utils.container_init(config,
                                                                  instance,
                                                                  host)))
            self.assertTrue(container_init)
            self.assertTrue(container_wait)
            self.assertTrue(container_operation_info)

    def test_container_init_failure(self):
        config = mock.Mock()
        instance = stubs._fake_instance()
        host = mock.Mock()
        with contextlib.nested(
            mock.patch.object(container_client.LXDContainerClient,
                              'container_init'),
            mock.patch.object(container_client.LXDContainerClient,
                              'container_wait'),
            mock.patch.object(container_client.LXDContainerClient,
                              'container_operation_info'),
        ) as (
            container_init,
            container_wait,
            container_operation_info,
        ):
            container_init.return_value = (200, fake_api.fake_operation())
            container_operation_info.return_value = (
                200,
                fake_api.fake_operation_info_failed())
            self.assertRaises(exception.NovaException,
                              self.container_utils.container_init,
                              config, instance, host)
            self.assertTrue(container_init)
            self.assertTrue(container_wait)
            self.assertTrue(container_operation_info)
Example #8
0
class LXDTestContainerImage(test.NoDBTestCase):
    @mock.patch.object(container_utils, '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.container_image = container_image.LXDContainerImage()

    @mock.patch('os.path.exists', mock.Mock(return_value=False))
    @mock.patch('oslo_utils.fileutils.ensure_tree', mock.Mock())
    @mock.patch('nova.utils.execute')
    def test_fetch_image(self, mock_execute):
        context = mock.Mock()
        instance = stubs._fake_instance()
        image_meta = {'name': 'new_image', 'id': 'fake_image'}
        with contextlib.nested(
                mock.patch.object(container_image.LXDContainerImage,
                                  '_image_defined'),
                mock.patch.object(container_image.IMAGE_API, 'download'),
                mock.patch.object(container_image.LXDContainerImage,
                                  '_get_lxd_manifest'),
                mock.patch.object(container_image.LXDContainerImage,
                                  '_image_upload'),
                mock.patch.object(container_image.LXDContainerImage,
                                  '_setup_alias'),
                mock.patch.object(
                    os, 'unlink')) as (mock_image_defined, mock_image_download,
                                       mock_image_manifest, image_upload,
                                       setup_alias, os_unlink):
            mock_image_defined.return_value = False
            mock_image_manifest.return_value = \
                '/fake/image/cache/fake_image-manifest.tar'
            self.assertEqual(
                None,
                self.container_image.setup_image(context, instance,
                                                 image_meta))
            mock_execute.assert_called_once_with(
                'xz', '-9', '/fake/image/cache/'
                'fake_image-manifest.tar')

    @mock.patch('os.path.exists', mock.Mock(return_value=False))
    @mock.patch('oslo_utils.fileutils.ensure_tree', mock.Mock())
    @mock.patch('nova.utils.execute')
    def test_fetch_imagei_fail(self, mock_execute):
        context = mock.Mock()
        instance = stubs._fake_instance()
        image_meta = {'name': 'new_image', 'id': 'fake_image'}
        with contextlib.nested(
                mock.patch.object(container_image.LXDContainerImage,
                                  '_image_defined'),
                mock.patch.object(container_image.IMAGE_API, 'download'),
                mock.patch.object(container_image.LXDContainerImage,
                                  '_get_lxd_manifest'),
                mock.patch.object(container_image.LXDContainerImage,
                                  '_image_upload'),
                mock.patch.object(container_image.LXDContainerImage,
                                  '_setup_alias'),
                mock.patch.object(
                    os, 'unlink')) as (mock_image_defined, mock_image_download,
                                       mock_image_manifest, image_upload,
                                       setup_alias, os_unlink):
            mock_image_defined.return_value = True
            self.assertEqual(
                None,
                self.container_image.setup_image(context, instance,
                                                 image_meta))
            self.assertFalse(mock_image_manifest.called)
Example #9
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'])

    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')
    def test_cleanup(self, mr):
        instance = stubs.MockInstance()
        self.assertEqual(
            None,
            self.connection.cleanup({}, instance, [], [], None, None, None))
        mr.assert_called_once_with(
            '/fake/instances/path/fake-uuid')

    @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))
Example #10
0
from nova_lxd.nova.virt.lxd import session
from nova_lxd.nova.virt.lxd import utils as container_dir
from nova_lxd.tests 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())