Exemplo n.º 1
0
    def test_execute_rollback(self, prep_resize_mock, sel_dest_mock, sig_mock,
                              az_mock, gmv_mock, cm_mock, sm_mock, cn_mock,
                              rc_mock, mock_ra, mock_gbf):
        sel_dest_mock.return_value = self.host_lists
        az_mock.return_value = 'myaz'
        task = self._generate_task()
        gmv_mock.return_value = 23
        mock_gbf.return_value = objects.MigrationList()
        mock_get_resources = \
            self.mock_network_api.get_requested_resource_for_instance
        mock_get_resources.return_value = []

        # We just need this hook point to set a uuid on the
        # migration before we use it for teardown
        def set_migration_uuid(*a, **k):
            task._migration.uuid = uuids.migration
            return mock.MagicMock()

        # NOTE(danms): It's odd to do this on cn_mock, but it's just because
        # of when we need to have it set in the flow and where we have an easy
        # place to find it via self.migration.
        cn_mock.side_effect = set_migration_uuid

        prep_resize_mock.side_effect = test.TestingException
        task._held_allocations = mock.sentinel.allocs
        self.assertRaises(test.TestingException, task.execute)
        self.assertIsNotNone(task._migration)
        task._migration.create.assert_called_once_with()
        task._migration.save.assert_called_once_with()
        self.assertEqual('error', task._migration.status)
        mock_ra.assert_called_once_with(task.context, task._source_cn,
                                        task.instance, task._migration)
        mock_get_resources.assert_called_once_with(self.context,
                                                   self.instance.uuid)
Exemplo n.º 2
0
    def test_get_migrations(self):
        filters = {'status': 'confirmed'}
        cell1_migrations = objects.MigrationList(
            objects=[objects.Migration(id=123)])
        cell2_migrations = objects.MigrationList(
            objects=[objects.Migration(id=456)])
        fake_responses = [
            self._get_fake_response(cell1_migrations),
            self._get_fake_response(cell2_migrations)
        ]
        self.mox.StubOutWithMock(self.msg_runner, 'get_migrations')
        self.msg_runner.get_migrations(self.ctxt, None, False, filters).\
            AndReturn(fake_responses)
        self.mox.ReplayAll()

        response = self.cells_manager.get_migrations(self.ctxt, filters)

        self.assertEqual(cell1_migrations.objects + cell2_migrations.objects,
                         response.objects)
Exemplo n.º 3
0
    def test_get_migrations_for_a_given_cell(self):
        filters = {'status': 'confirmed', 'cell_name': 'ChildCell1'}
        target_cell = '%s%s%s' % (CONF.cells.name, '!', filters['cell_name'])
        migrations = objects.MigrationList(objects=[objects.Migration(id=123)])
        fake_responses = [self._get_fake_response(migrations)]
        self.mox.StubOutWithMock(self.msg_runner, 'get_migrations')
        self.msg_runner.get_migrations(self.ctxt, target_cell, False,
                                       filters).AndReturn(fake_responses)
        self.mox.ReplayAll()

        response = self.cells_manager.get_migrations(self.ctxt, filters)
        self.assertEqual(migrations.objects, response.objects)
Exemplo n.º 4
0
    def get_migrations(self, ctxt, filters):
        """Fetch migrations applying the filters."""
        target_cell = None
        if "cell_name" in filters:
            _path_cell_sep = cells_utils.PATH_CELL_SEP
            target_cell = '%s%s%s' % (CONF.cells.name, _path_cell_sep,
                                      filters['cell_name'])

        responses = self.msg_runner.get_migrations(ctxt, target_cell, False,
                                                   filters)
        migrations = []
        for response in responses:
            # response.value_or_raise returns MigrationList objects.
            # MigrationList.objects returns the list of Migration objects.
            migrations.extend(response.value_or_raise().objects)
        return objects.MigrationList(objects=migrations)
Exemplo n.º 5
0
class MigrationTestCaseV266(MigrationsTestCaseV259):
    wsgi_api_version = '2.66'

    def test_index_with_invalid_changes_before(self):
        """Tests detail paging with an invalid changes-before value."""
        req = fakes.HTTPRequest.blank(
            '/os-migrations?changes-before=wrong_time',
            version=self.wsgi_api_version,
            use_admin_context=True)
        self.assertRaises(exception.ValidationError, self.controller.index,
                          req)

    def test_index_with_changes_before_old_microversion_failed(self):
        """Tests that the changes-before query parameter is an error before
        microversion 2.66.
        """
        # Also use a valid filter (instance_uuid) to make sure
        # changes-before is an additional property.
        req = fakes.HTTPRequest.blank(
            '/os-migrations?changes-before=2018-01-10T16:59:24.138939&'
            'instance_uuid=%s' % uuids.instance_uuid,
            version='2.65',
            use_admin_context=True)
        ex = self.assertRaises(exception.ValidationError,
                               self.controller.index, req)
        self.assertIn('Additional properties are not allowed',
                      six.text_type(ex))

    @mock.patch('nova.compute.api.API.get_migrations',
                return_value=objects.MigrationList())
    def test_index_with_changes_before_old_microversion(self, get_migrations):
        """Tests that the changes-before query parameter is ignored before
        microversion 2.59.
        """
        # Also use a valid filter (instance_uuid) to make sure only
        # changes-before is removed.
        req = fakes.HTTPRequest.blank(
            '/os-migrations?changes-before=2018-01-10T16:59:24.138939&'
            'instance_uuid=%s' % uuids.instance_uuid,
            version='2.58',
            use_admin_context=True)
        result = self.controller.index(req)
        self.assertEqual({'migrations': []}, result)
        get_migrations.assert_called_once_with(
            req.environ['nova.context'],
            {'instance_uuid': uuids.instance_uuid})
    'memory_processed': 56789,
    'memory_remaining': 400000,
    'disk_total': 96789,
    'disk_processed': 6789,
    'disk_remaining': 90000,
    'created_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
    'updated_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
    'deleted_at': None,
    'deleted': False,
    'uuid': uuids.migration2,
    'cross_cell_move': False,
    'user_id': None,
    'project_id': None
}]

migrations_obj = base.obj_make_list('fake-context', objects.MigrationList(),
                                    objects.Migration, fake_migrations)


class ServerMigrationsTestsV21(test.NoDBTestCase):
    wsgi_api_version = '2.22'

    def setUp(self):
        super(ServerMigrationsTestsV21, self).setUp()
        self.req = fakes.HTTPRequest.blank('', version=self.wsgi_api_version)
        self.context = self.req.environ['nova.context']
        self.controller = server_migrations.ServerMigrationsController()
        self.compute_api = self.controller.compute_api

    def test_force_complete_succeeded(self):
        @mock.patch.object(self.compute_api, 'live_migrate_force_complete')
Exemplo n.º 7
0
    def _test_execute(self,
                      prep_resize_mock,
                      sel_dest_mock,
                      sig_mock,
                      az_mock,
                      gmv_mock,
                      cm_mock,
                      sm_mock,
                      cn_mock,
                      rc_mock,
                      gbf_mock,
                      requested_destination=False):
        sel_dest_mock.return_value = self.host_lists
        az_mock.return_value = 'myaz'
        gbf_mock.return_value = objects.MigrationList()
        mock_get_resources = \
            self.mock_network_api.get_requested_resource_for_instance
        mock_get_resources.return_value = []

        if requested_destination:
            self.request_spec.requested_destination = objects.Destination(
                host='target_host', node=None)
            self.request_spec.retry = objects.SchedulerRetries.from_dict(
                self.context, self.filter_properties['retry'])
            self.filter_properties.pop('retry')
            self.filter_properties['requested_destination'] = (
                self.request_spec.requested_destination)

        task = self._generate_task()
        gmv_mock.return_value = 23

        # We just need this hook point to set a uuid on the
        # migration before we use it for teardown
        def set_migration_uuid(*a, **k):
            task._migration.uuid = uuids.migration
            return mock.MagicMock()

        # NOTE(danms): It's odd to do this on cn_mock, but it's just because
        # of when we need to have it set in the flow and where we have an easy
        # place to find it via self.migration.
        cn_mock.side_effect = set_migration_uuid

        selection = self.host_lists[0][0]
        with mock.patch.object(scheduler_utils,
                               'fill_provider_mapping') as fill_mock:
            task.execute()
            fill_mock.assert_called_once_with(task.context, task.reportclient,
                                              task.request_spec, selection)

        self.ensure_network_metadata_mock.assert_called_once_with(
            self.instance)
        self.heal_reqspec_is_bfv_mock.assert_called_once_with(
            self.context, self.request_spec, self.instance)
        sig_mock.assert_called_once_with(self.context, self.request_spec)
        task.query_client.select_destinations.assert_called_once_with(
            self.context,
            self.request_spec, [self.instance.uuid],
            return_objects=True,
            return_alternates=True)
        prep_resize_mock.assert_called_once_with(
            self.context,
            self.instance,
            self.request_spec.image,
            self.flavor,
            selection.service_host,
            task._migration,
            request_spec=self.request_spec,
            filter_properties=self.filter_properties,
            node=selection.nodename,
            clean_shutdown=self.clean_shutdown,
            host_list=[])
        az_mock.assert_called_once_with(self.context, 'host1')
        self.assertIsNotNone(task._migration)

        old_flavor = self.instance.flavor
        new_flavor = self.flavor
        self.assertEqual(old_flavor.id, task._migration.old_instance_type_id)
        self.assertEqual(new_flavor.id, task._migration.new_instance_type_id)
        self.assertEqual('pre-migrating', task._migration.status)
        self.assertEqual(self.instance.uuid, task._migration.instance_uuid)
        self.assertEqual(self.instance.host, task._migration.source_compute)
        self.assertEqual(self.instance.node, task._migration.source_node)
        if old_flavor.id != new_flavor.id:
            self.assertEqual('resize', task._migration.migration_type)
        else:
            self.assertEqual('migration', task._migration.migration_type)

        task._migration.create.assert_called_once_with()

        if requested_destination:
            self.assertIsNone(self.request_spec.retry)
            self.assertIn('cell', self.request_spec.requested_destination)
            self.assertIsNotNone(self.request_spec.requested_destination.cell)

        mock_get_resources.assert_called_once_with(self.context,
                                                   self.instance.uuid)
        self.assertEqual([], self.request_spec.requested_resources)
Exemplo n.º 8
0
class MigrationTestCaseV266(MigrationsTestCaseV259):
    wsgi_api_version = '2.66'

    def test_index_with_invalid_changes_before(self):
        """Tests detail paging with an invalid changes-before value."""
        req = fakes.HTTPRequest.blank(
            '/os-migrations?changes-before=wrong_time',
            version=self.wsgi_api_version,
            use_admin_context=True)
        self.assertRaises(exception.ValidationError, self.controller.index,
                          req)

    @mock.patch('nova.compute.api.API.get_migrations_sorted',
                return_value=objects.MigrationList())
    def test_index_with_changes_since_and_changes_before(
            self, get_migrations_sorted):
        changes_since = '2013-10-22T13:42:02Z'
        changes_before = '2013-10-22T13:42:03Z'
        req = fakes.HTTPRequest.blank(
            '/os-migrations?changes-since=%s&changes-before=%s&'
            'instance_uuid=%s' %
            (changes_since, changes_before, uuids.instance_uuid),
            version=self.wsgi_api_version,
            use_admin_context=True)

        self.controller.index(req)
        search_opts = {
            'instance_uuid':
            uuids.instance_uuid,
            'changes-before':
            datetime.datetime(2013,
                              10,
                              22,
                              13,
                              42,
                              3,
                              tzinfo=iso8601.iso8601.UTC),
            'changes-since':
            datetime.datetime(2013,
                              10,
                              22,
                              13,
                              42,
                              2,
                              tzinfo=iso8601.iso8601.UTC)
        }
        get_migrations_sorted.assert_called_once_with(
            req.environ['nova.context'],
            search_opts,
            sort_dirs=mock.ANY,
            sort_keys=mock.ANY,
            limit=1000,
            marker=None)

    def test_get_migrations_filters_with_distinct_changes_time_bad_request(
            self):
        changes_since = '2018-09-04T05:45:27Z'
        changes_before = '2018-09-03T05:45:27Z'
        req = fakes.HTTPRequest.blank('/os-migrations?'
                                      'changes-since=%s&changes-before=%s' %
                                      (changes_since, changes_before),
                                      version=self.wsgi_api_version,
                                      use_admin_context=True)
        ex = self.assertRaises(exc.HTTPBadRequest, self.controller.index, req)
        self.assertIn(
            'The value of changes-since must be less than '
            'or equal to changes-before', six.text_type(ex))

    def test_index_with_changes_before_old_microversion_failed(self):
        """Tests that the changes-before query parameter is an error before
        microversion 2.66.
        """
        # Also use a valid filter (instance_uuid) to make sure
        # changes-before is an additional property.
        req = fakes.HTTPRequest.blank(
            '/os-migrations?changes-before=2018-01-10T16:59:24.138939&'
            'instance_uuid=%s' % uuids.instance_uuid,
            version='2.65',
            use_admin_context=True)
        ex = self.assertRaises(exception.ValidationError,
                               self.controller.index, req)
        self.assertIn('Additional properties are not allowed',
                      six.text_type(ex))

    @mock.patch('nova.compute.api.API.get_migrations',
                return_value=objects.MigrationList())
    def test_index_with_changes_before_old_microversion(self, get_migrations):
        """Tests that the changes-before query parameter is ignored before
        microversion 2.59.
        """
        # Also use a valid filter (instance_uuid) to make sure only
        # changes-before is removed.
        req = fakes.HTTPRequest.blank(
            '/os-migrations?changes-before=2018-01-10T16:59:24.138939&'
            'instance_uuid=%s' % uuids.instance_uuid,
            version='2.58',
            use_admin_context=True)
        result = self.controller.index(req)
        self.assertEqual({'migrations': []}, result)
        get_migrations.assert_called_once_with(
            req.environ['nova.context'],
            {'instance_uuid': uuids.instance_uuid})
Exemplo n.º 9
0
class MigrationsTestCaseV259(MigrationsTestCaseV223):
    wsgi_api_version = '2.59'

    def test_index(self):
        migrations = {
            'migrations':
            self.controller._output(self.req, migrations_obj, True, True)
        }

        for i, mig in enumerate(migrations['migrations']):
            # first item is in-progress live migration
            if i == 0:
                self.assertIn('links', mig)
            else:
                self.assertNotIn('links', mig)

            self.assertIn('migration_type', mig)
            self.assertIn('id', mig)
            self.assertIn('uuid', mig)
            self.assertNotIn('deleted', mig)
            self.assertNotIn('deleted_at', mig)

        with mock.patch.object(self.controller.compute_api,
                               'get_migrations_sorted') as m_get:
            m_get.return_value = migrations_obj
            response = self.controller.index(self.req)
            self.assertEqual(migrations, response)
            self.assertIn('links', response['migrations'][0])
            self.assertIn('migration_type', response['migrations'][0])

    @mock.patch('nova.compute.api.API.get_migrations_sorted')
    def test_index_with_invalid_marker(self, mock_migrations_get):
        """Tests detail paging with an invalid marker (not found)."""
        mock_migrations_get.side_effect = exception.MarkerNotFound(
            marker=uuids.invalid_marker)
        req = fakes.HTTPRequest.blank('/os-migrations?marker=%s' %
                                      uuids.invalid_marker,
                                      version=self.wsgi_api_version,
                                      use_admin_context=True)
        e = self.assertRaises(exc.HTTPBadRequest, self.controller.index, req)
        self.assertEqual(
            "Marker %s could not be found." % uuids.invalid_marker,
            six.text_type(e))

    def test_index_with_invalid_limit(self):
        """Tests detail paging with an invalid limit."""
        req = fakes.HTTPRequest.blank('/os-migrations?limit=x',
                                      version=self.wsgi_api_version,
                                      use_admin_context=True)
        self.assertRaises(exception.ValidationError, self.controller.index,
                          req)
        req = fakes.HTTPRequest.blank('/os-migrations?limit=-1',
                                      version=self.wsgi_api_version,
                                      use_admin_context=True)
        self.assertRaises(exception.ValidationError, self.controller.index,
                          req)

    def test_index_with_invalid_changes_since(self):
        """Tests detail paging with an invalid changes-since value."""
        req = fakes.HTTPRequest.blank(
            '/os-migrations?changes-since=wrong_time',
            version=self.wsgi_api_version,
            use_admin_context=True)
        self.assertRaises(exception.ValidationError, self.controller.index,
                          req)

    def test_index_with_unknown_query_param(self):
        """Tests detail paging with an unknown query parameter."""
        req = fakes.HTTPRequest.blank('/os-migrations?foo=bar',
                                      version=self.wsgi_api_version,
                                      use_admin_context=True)
        ex = self.assertRaises(exception.ValidationError,
                               self.controller.index, req)
        self.assertIn('Additional properties are not allowed',
                      six.text_type(ex))

    @mock.patch('nova.compute.api.API.get_migrations',
                return_value=objects.MigrationList())
    def test_index_with_changes_since_old_microversion(self, get_migrations):
        """Tests that the changes-since query parameter is ignored before
        microversion 2.59.
        """
        # Also use a valid filter (instance_uuid) to make sure only
        # changes-since is removed.
        req = fakes.HTTPRequest.blank(
            '/os-migrations?changes-since=2018-01-10T16:59:24.138939&'
            'instance_uuid=%s' % uuids.instance_uuid,
            version='2.58',
            use_admin_context=True)
        result = self.controller.index(req)
        self.assertEqual({'migrations': []}, result)
        get_migrations.assert_called_once_with(
            req.environ['nova.context'],
            {'instance_uuid': uuids.instance_uuid})
Exemplo n.º 10
0
        'dest_compute': 'compute20',
        'dest_host': '5.6.7.8',
        'status': 'Done',
        'instance_uuid': 'instance_id_456',
        'old_instance_type_id': 5,
        'new_instance_type_id': 6,
        'created_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
        'updated_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
        'deleted_at': None,
        'deleted': False
    }
]

migrations_obj = base.obj_make_list(
    'fake-context',
    objects.MigrationList(),
    objects.Migration,
    fake_migrations)


class FakeRequest(object):
    environ = {"nova.context": context.RequestContext('fake_user', 'fake',
                                                      is_admin=True)}
    GET = {}


class MigrationsTestCaseV21(test.NoDBTestCase):
    migrations = migrations_v21

    def setUp(self):
        """Run before each test."""
Exemplo n.º 11
0
def get_migration_objects_sorted(ctx, filters, limit, marker, sort_keys,
                                 sort_dirs):
    mig_generator = MigrationLister(sort_keys, sort_dirs).get_records_sorted(
        ctx, filters, limit, marker)
    return base.obj_make_list(ctx, objects.MigrationList(), objects.Migration,
                              mig_generator)
Exemplo n.º 12
0
    def test_find_destination_works_with_instance_group(self):
        self.instance.numa_topology = None
        self.fake_spec.instance_group = objects.InstanceGroup(members=["uuid"])
        self.instance_uuid = self.instance.uuid = "uuid-2"
        updated_instance_group = objects.InstanceGroup(
            members=["uuid", "uuid-2"],
            hosts=['host1', 'host2'],
            policies=['anti-affinity'],
            metadetails={'wrs-sg:best_effort': 'false'})
        expected_instance_group = copy.deepcopy(updated_instance_group)
        expected_instance_group.hosts = ['host1', 'host2', 'host3']
        migration = objects.Migration(source_compute='host1',
                                      dest_compute='host3')
        migrations = objects.MigrationList(objects=[migration])

        self.mox.StubOutWithMock(utils, 'get_image_from_system_metadata')
        self.mox.StubOutWithMock(scheduler_utils, 'setup_instance_group')
        self.mox.StubOutWithMock(objects.RequestSpec,
                                 'reset_forced_destinations')
        self.mox.StubOutWithMock(objects.InstanceGroup, 'get_by_instance_uuid')
        self.mox.StubOutWithMock(objects.MigrationList, 'get_by_filters')
        filters = {
            'migration_type':
            'live-migration',
            'instance_uuid':
            'uuid',
            'status':
            ['queued', 'accepted', 'pre-migrating', 'preparing', 'running']
        }

        self.mox.StubOutWithMock(self.task,
                                 '_check_compatible_with_source_hypervisor')
        self.mox.StubOutWithMock(self.task, '_call_livem_checks_on_host')
        self.mox.StubOutWithMock(self.instance, 'is_volume_backed')

        def fake_select_destinations(context, request_spec, instance_uuids):
            self.assertEqual(expected_instance_group.members,
                             request_spec.instance_group.members)
            self.assertEqual(expected_instance_group.hosts,
                             request_spec.instance_group.hosts)
            return [{
                'host': 'host1',
                'nodename': 'node1',
                'limits': 'fake-limits'
            }]

        self.instance.is_volume_backed().AndReturn(False)
        self.task.scheduler_client.select_destinations = \
                                                      fake_select_destinations
        utils.get_image_from_system_metadata(
            self.instance.system_metadata).AndReturn("image")
        scheduler_utils.setup_instance_group(self.context, self.fake_spec)
        self.fake_spec.reset_forced_destinations()
        objects.InstanceGroup.get_by_instance_uuid(
            self.context, self.instance_uuid).AndReturn(updated_instance_group)
        objects.MigrationList.get_by_filters(self.context,
                                             filters).AndReturn(migrations)

        self.task._check_compatible_with_source_hypervisor("host1")
        self.task._call_livem_checks_on_host("host1", limits='fake-limits')

        self.mox.ReplayAll()
        self.assertEqual(("host1", 'fake-limits'),
                         self.task._find_destination())
        self.mox.VerifyAll()