Merge "Delete instance_group_member records from API DB during archive" into stable/rocky
This commit is contained in:
commit
1f1482eb7d
|
@ -551,12 +551,18 @@ Error: %s""") % six.text_type(e))
|
|||
if deleted_instance_uuids:
|
||||
table_to_rows_archived.setdefault('instance_mappings', 0)
|
||||
table_to_rows_archived.setdefault('request_specs', 0)
|
||||
table_to_rows_archived.setdefault('instance_group_member', 0)
|
||||
deleted_mappings = objects.InstanceMappingList.destroy_bulk(
|
||||
ctxt, deleted_instance_uuids)
|
||||
table_to_rows_archived['instance_mappings'] += deleted_mappings
|
||||
deleted_specs = objects.RequestSpec.destroy_bulk(
|
||||
ctxt, deleted_instance_uuids)
|
||||
table_to_rows_archived['request_specs'] += deleted_specs
|
||||
deleted_group_members = (
|
||||
objects.InstanceGroup.destroy_members_bulk(
|
||||
ctxt, deleted_instance_uuids))
|
||||
table_to_rows_archived['instance_group_member'] += (
|
||||
deleted_group_members)
|
||||
if not until_complete:
|
||||
break
|
||||
elif not run:
|
||||
|
|
|
@ -337,6 +337,17 @@ class InstanceGroup(base.NovaPersistentObject, base.NovaObject,
|
|||
in_(set(instance_uuids))).\
|
||||
delete(synchronize_session=False)
|
||||
|
||||
@staticmethod
|
||||
@db_api.api_context_manager.writer
|
||||
def _destroy_members_bulk_in_db(context, instance_uuids):
|
||||
return context.session.query(api_models.InstanceGroupMember).filter(
|
||||
api_models.InstanceGroupMember.instance_uuid.in_(instance_uuids)).\
|
||||
delete(synchronize_session=False)
|
||||
|
||||
@classmethod
|
||||
def destroy_members_bulk(cls, context, instance_uuids):
|
||||
return cls._destroy_members_bulk_in_db(context, instance_uuids)
|
||||
|
||||
def obj_load_attr(self, attrname):
|
||||
# NOTE(sbauza): Only hosts could be lazy-loaded right now
|
||||
if attrname != 'hosts':
|
||||
|
|
|
@ -738,3 +738,53 @@ class TestNovaManagePlacementSyncAggregates(
|
|||
rp_aggregates = self._get_provider_aggregates(rp_uuid)
|
||||
self.assertEqual(2, len(rp_aggregates),
|
||||
'%s should be in two provider aggregates' % host)
|
||||
|
||||
|
||||
class TestDBArchiveDeletedRows(integrated_helpers._IntegratedTestBase):
|
||||
"""Functional tests for the "nova-manage db archive_deleted_rows" CLI."""
|
||||
USE_NEUTRON = True
|
||||
api_major_version = 'v2.1'
|
||||
_image_ref_parameter = 'imageRef'
|
||||
_flavor_ref_parameter = 'flavorRef'
|
||||
|
||||
def setUp(self):
|
||||
super(TestDBArchiveDeletedRows, self).setUp()
|
||||
self.cli = manage.DbCommands()
|
||||
self.output = StringIO()
|
||||
self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.output))
|
||||
|
||||
def test_archive_instance_group_members(self):
|
||||
"""Tests that instance_group_member records in the API DB are deleted
|
||||
when a server group member instance is archived.
|
||||
"""
|
||||
# Create a server group.
|
||||
group = self.api.post_server_groups(
|
||||
{'name': 'test_archive_instance_group_members',
|
||||
'policies': ['affinity']})
|
||||
# Create two servers in the group.
|
||||
server = self._build_minimal_create_server_request()
|
||||
server['min_count'] = 2
|
||||
server_req = {
|
||||
'server': server, 'os:scheduler_hints': {'group': group['id']}}
|
||||
# Since we don't pass return_reservation_id=True we get the first
|
||||
# server back in the response. We're also using the CastAsCall fixture
|
||||
# (from the base class) fixture so we don't have to worry about the
|
||||
# server being ACTIVE.
|
||||
server = self.api.post_server(server_req)
|
||||
# Assert we have two group members.
|
||||
self.assertEqual(
|
||||
2, len(self.api.get_server_group(group['id'])['members']))
|
||||
# Now delete one server and then we can archive.
|
||||
server = self.api.get_server(server['id'])
|
||||
self.api.delete_server(server['id'])
|
||||
helper = integrated_helpers.InstanceHelperMixin()
|
||||
helper.api = self.api
|
||||
helper._wait_until_deleted(server)
|
||||
# Now archive.
|
||||
self.cli.archive_deleted_rows(verbose=True)
|
||||
# Assert only one instance_group_member record was deleted.
|
||||
self.assertRegexpMatches(self.output.getvalue(),
|
||||
".*instance_group_member.*\| 1.*")
|
||||
# And that we still have one remaining group member.
|
||||
self.assertEqual(
|
||||
1, len(self.api.get_server_group(group['id'])['members']))
|
||||
|
|
|
@ -510,8 +510,10 @@ Rows were archived, running purge...
|
|||
|
||||
@mock.patch.object(db, 'archive_deleted_rows')
|
||||
@mock.patch.object(objects.RequestSpec, 'destroy_bulk')
|
||||
def test_archive_deleted_rows_and_instance_mappings_and_request_specs(self,
|
||||
mock_destroy, mock_db_archive, verbose=True):
|
||||
@mock.patch.object(objects.InstanceGroup, 'destroy_members_bulk')
|
||||
def test_archive_deleted_rows_and_api_db_records(
|
||||
self, mock_members_destroy, mock_reqspec_destroy, mock_db_archive,
|
||||
verbose=True):
|
||||
self.useFixture(nova_fixtures.Database())
|
||||
self.useFixture(nova_fixtures.Database(database='api'))
|
||||
|
||||
|
@ -533,24 +535,27 @@ Rows were archived, running purge...
|
|||
.create()
|
||||
|
||||
mock_db_archive.return_value = (dict(instances=2, consoles=5), uuids)
|
||||
mock_destroy.return_value = 2
|
||||
mock_reqspec_destroy.return_value = 2
|
||||
mock_members_destroy.return_value = 0
|
||||
result = self.commands.archive_deleted_rows(20, verbose=verbose)
|
||||
|
||||
self.assertEqual(1, result)
|
||||
mock_db_archive.assert_called_once_with(20)
|
||||
self.assertEqual(1, mock_destroy.call_count)
|
||||
self.assertEqual(1, mock_reqspec_destroy.call_count)
|
||||
mock_members_destroy.assert_called_once()
|
||||
|
||||
output = self.output.getvalue()
|
||||
if verbose:
|
||||
expected = '''\
|
||||
+-------------------+-------------------------+
|
||||
| Table | Number of Rows Archived |
|
||||
+-------------------+-------------------------+
|
||||
| consoles | 5 |
|
||||
| instance_mappings | 2 |
|
||||
| instances | 2 |
|
||||
| request_specs | 2 |
|
||||
+-------------------+-------------------------+
|
||||
+-----------------------+-------------------------+
|
||||
| Table | Number of Rows Archived |
|
||||
+-----------------------+-------------------------+
|
||||
| consoles | 5 |
|
||||
| instance_group_member | 0 |
|
||||
| instance_mappings | 2 |
|
||||
| instances | 2 |
|
||||
| request_specs | 2 |
|
||||
+-----------------------+-------------------------+
|
||||
'''
|
||||
self.assertEqual(expected, output)
|
||||
else:
|
||||
|
|
Loading…
Reference in New Issue