Improve unit test coverage for dcmanager/manager/system_peer__manager.py (2/2)

This commit includes new unit tests for system_peer_manager.py,
covering new test cases in sync subclouds, delete, update
operations.

Test plan:
1) PASS: Run tox py39, pylint and pep8 envs and
         verify that they are all passing.
2) PASS: Check 'tox -e cover' command output.
         Coverage increased from 69% to 91%

Depends-On: https://review.opendev.org/c/starlingx/distcloud/+/915055

Story: 2007082
Task: 49713

Change-Id: I0b5a7d024f7b3a5c5ef4adb4aa29dc9d0e7f9de4
Signed-off-by: Swapna Gorre <swapna.gorre@windriver.com>
This commit is contained in:
Swapna Gorre 2024-03-15 06:56:21 -04:00
parent c585a4a21d
commit 94ea41fa25
1 changed files with 345 additions and 1 deletions

View File

@ -11,6 +11,7 @@ import mock
from dccommon import exceptions as dccommon_exceptions
from dcmanager.common import consts
from dcmanager.common import exceptions
from dcmanager.db.sqlalchemy import api as db_api
from dcmanager.manager import system_peer_manager
from dcmanager.tests import base
@ -88,6 +89,7 @@ class TestSystemPeerManager(base.DCManagerTestCase):
self._mock_get_local_system()
self._mock_system_peer_manager_dcmanagerclient()
self._mock_system_peer_manager_peersitedriver()
self._mock_log(system_peer_manager)
self.spm = system_peer_manager.SystemPeerManager(mock.MagicMock())
@ -129,7 +131,8 @@ class TestSystemPeerManager(base.DCManagerTestCase):
else FAKE_SITE1_SUBCLOUD2_REGION_NAME if SUBCLOUD_ID == 2
else 'subcloud3',
'deploy-status': 'secondary' if SUBCLOUD_ID in [1, 3]
else 'secondary-failed'
else 'secondary-failed' if SUBCLOUD_ID == 2
else consts.DEPLOY_STATE_REHOMING
}
def _mock_system_peer_manager_dcmanagerclient(self):
@ -447,3 +450,344 @@ class TestSystemPeerManager(base.DCManagerTestCase):
}
self.mock_dc_client().update_subcloud_peer_group.assert_called_once_with(
FAKE_SITE0_PEER_GROUP_NAME, **peer_group_kwargs)
def test_handle_association_operations_in_progress(self):
db_api.peer_group_association_update(
self.ctx,
self.peer.id,
sync_status=consts.ASSOCIATION_SYNC_STATUS_SYNCING)
self.spm.handle_association_operations_in_progress()
associations = db_api.peer_group_association_get(self.ctx,
self.association.id)
self.assertEqual(consts.ASSOCIATION_SYNC_STATUS_FAILED,
associations.sync_status)
Calls = [mock.call('Identifying associations in transitory stages.'),
mock.call('Changing association 1 '
'sync status from syncing to failed')]
self.mock_log.info.assert_has_calls(Calls)
def test_delete_peer_group_association_failed(self):
self.mock_dc_client().delete_subcloud_peer_group.side_effect = \
dccommon_exceptions.SubcloudPeerGroupDeleteFailedAssociated
self.assertRaises(dccommon_exceptions.
SubcloudPeerGroupDeleteFailedAssociated,
self.spm.delete_peer_group_association,
self.ctx, self.association.id)
self.mock_log.error.assert_called_once_with(
f'Subcloud Peer Group {self.peer_group.peer_group_name} '
'delete failed as it is associated with system peer on peer site.')
def test_delete_peer_group_association_subcloud_pg_notfound(self):
self.mock_dc_client().get_subcloud_peer_group.side_effect = \
dccommon_exceptions.SubcloudPeerGroupNotFound
self.spm.delete_peer_group_association(self.ctx, self.association.id)
self.mock_log.warning.assert_called_once_with(
f'Subcloud Peer Group {self.peer_group.peer_group_name} '
'does not exist on peer site.')
def test_sync_subclouds_delete_subcloud_exception(self):
peer_subcloud1 = self._fake_site_data(1)
self.mock_dc_client().get_subcloud.side_effect = [peer_subcloud1]
self.mock_dc_client().get_subcloud_list_by_peer_group.return_value = [
peer_subcloud1]
self.mock_dc_client().delete_subcloud.side_effect = Exception('boom')
self.spm._sync_subclouds(self.ctx, self.peer, self.peer_group.id,
FAKE_SITE1_PEER_GROUP_ID)
self.mock_log.error.assert_called_once_with(
'Subcloud delete failed: boom')
def test_get_peer_ks_client(self):
self.mock_keystone_client.side_effect = Exception('BOOM')
self.assertRaises(Exception, self.spm.get_peer_ks_client, self.peer)
self.mock_log.warn.assert_called_once_with(
'Failure initializing KeystoneClient for system peer '
f'{self.peer.peer_name}')
def test_valid_for_subcloud_sync_deploy_status_secondary(self):
data_install = json.dumps(fake_subcloud.FAKE_SUBCLOUD_INSTALL_VALUES)
subcloud1 = self.create_subcloud_with_pg_static(
self.ctx,
peer_group_id=self.peer_group.id,
deploy_status=consts.DEPLOY_STATE_SECONDARY_FAILED,
name='subcloud1',
region_name='subcloud1',
data_install=data_install)
ret = self.spm._is_valid_for_subcloud_sync(subcloud1)
self.mock_log.info.assert_called_once_with(
'Ignoring the Subcloud subcloud1 (region_name: subcloud1)'
' in secondary status to sync with peer site.')
self.assertEqual(system_peer_manager.VERIFY_SUBCLOUD_SYNC_IGNORE, ret)
def test_is_valid_for_subcloud_sync_missing_rehome_data(self):
# Create local dc subcloud1 mock data in database
data_install = json.dumps(fake_subcloud.FAKE_SUBCLOUD_INSTALL_VALUES)
subcloud1 = self.create_subcloud_with_pg_static(
self.ctx,
peer_group_id=self.peer_group.id,
rehome_data=None,
name='subcloud1',
region_name='subcloud1',
data_install=data_install)
ret_msg = self.spm._is_valid_for_subcloud_sync(subcloud1)
msg = 'Subcloud subcloud1 (region_name: subcloud1)'\
' does not have rehome_data.'
self.assertEqual(msg, ret_msg)
def test_is_valid_for_subcloud_sync_missing_saved_payload_empty(self):
# Create local dc subcloud1 mock data in database
rehome_data = {
"saved_payload": {}
}
# Create local dc subcloud1 mock data in database
data_install = json.dumps(fake_subcloud.FAKE_SUBCLOUD_INSTALL_VALUES)
subcloud1 = self.create_subcloud_with_pg_static(
self.ctx,
peer_group_id=self.peer_group.id,
rehome_data=json.dumps(rehome_data),
name='subcloud1',
region_name='subcloud1',
data_install=data_install)
ret_msg = self.spm._is_valid_for_subcloud_sync(subcloud1)
msg = 'Subcloud subcloud1 (region_name: subcloud1) saved_payload is empty.'
self.assertEqual(msg, ret_msg)
def test_is_valid_for_subcloud_sync_missing_bootstrap_address(self):
# Create local dc subcloud1 mock data in database
rehome_data = {
"saved_payload": {
"systemcontroller_gateway_address": "192.168.204.101"
}
}
# Create local dc subcloud1 mock data in database
data_install = json.dumps(fake_subcloud.FAKE_SUBCLOUD_INSTALL_VALUES)
subcloud1 = self.create_subcloud_with_pg_static(
self.ctx,
peer_group_id=self.peer_group.id,
rehome_data=json.dumps(rehome_data),
name='subcloud1',
region_name='subcloud1',
data_install=data_install)
ret_msg = self.spm._is_valid_for_subcloud_sync(subcloud1)
msg = 'Subcloud subcloud1 (region_name: subcloud1)'\
' does not have bootstrap-address in saved_payload.'
self.assertEqual(msg, ret_msg)
def test_is_valid_for_subcloud_sync_missing_saved_payload(self):
# Create local dc subcloud1 mock data in database
rehome_data = {
}
# Create local dc subcloud1 mock data in database
data_install = json.dumps(fake_subcloud.FAKE_SUBCLOUD_INSTALL_VALUES)
subcloud1 = self.create_subcloud_with_pg_static(
self.ctx,
peer_group_id=self.peer_group.id,
rehome_data=json.dumps(rehome_data),
name='subcloud1',
region_name='subcloud1',
data_install=data_install)
ret_msg = self.spm._is_valid_for_subcloud_sync(subcloud1)
msg = 'Subcloud subcloud1 (region_name: subcloud1) '\
'does not have saved_payload.'
self.assertEqual(msg, ret_msg)
def test_valid_for_subcloud_sync_missing_systemcontroller_gateway_addr(self):
# Create local dc subcloud1 mock data in database
rehome_data = {
"saved_payload": {
"bootstrap-address": "192.168.10.10"
}
}
# Create local dc subcloud1 mock data in database
data_install = json.dumps(fake_subcloud.FAKE_SUBCLOUD_INSTALL_VALUES)
subcloud1 = self.create_subcloud_with_pg_static(
self.ctx,
peer_group_id=self.peer_group.id,
rehome_data=json.dumps(rehome_data),
name='subcloud1',
region_name='subcloud1',
data_install=data_install)
spm = system_peer_manager.SystemPeerManager(mock.MagicMock())
spm._is_valid_for_subcloud_sync(subcloud1)
def test_sync_subcloud_peer_group_uuid_does_not_match(self):
self.mock_dc_client().get_peer_group_association_with_peer_id_and_pg_id.\
side_effect = dccommon_exceptions.PeerGroupAssociationNotFound
self.mock_dc_client().add_peer_group_association.side_effect = \
Exception('boom')
self.assertRaises(Exception,
self.spm.sync_subcloud_peer_group,
self.ctx, self.association.id, True)
def test_sync_subcloud_peer_group_exception(self):
self.spm.sync_subcloud_peer_group(self.ctx, self.association.id, False)
self.mock_dc_client().get_subcloud_peer_group.assert_called_once_with(
self.peer_group.peer_group_name)
self.mock_dc_client().update_subcloud_peer_group.assert_called_once()
@mock.patch('dcmanager.manager.system_peer_manager.'
'SystemPeerManager.get_peer_dc_client')
def test_update_sync_status_exception(self, mock_client):
mock_client.return_value = Exception('boom')
self.spm.update_sync_status(
self.ctx, self.peer, consts.ASSOCIATION_SYNC_STATUS_IN_SYNC)
association_new = db_api.peer_group_association_get(
self.ctx, self.association.id)
self.assertEqual(consts.ASSOCIATION_SYNC_STATUS_FAILED,
association_new.sync_status)
def test_update_subcloud_peer_group_exception(self):
self.mock_dc_client().update_subcloud_peer_group = Exception('boom')
self.spm.update_subcloud_peer_group(
self.ctx, self.peer_group.id,
FAKE_SITE1_PEER_GROUP_STATE,
FAKE_SITE1_PEER_GROUP_MAX_SUBCLOUDS_REHOMING,
FAKE_SITE0_PEER_GROUP_NAME,
FAKE_SITE1_PEER_GROUP_NAME)
def test_sync_subclouds_update_subcloud_exception(self):
self.mock_dc_client().add_subcloud_with_secondary_status = mock.MagicMock()
self.mock_dc_client().add_subcloud_with_secondary_status.return_value = {
"region-name": FAKE_SITE1_SUBCLOUD2_REGION_NAME}
rehome_data = {
"saved_payload": {
"bootstrap-address": "192.168.10.10",
"systemcontroller_gateway_address": "192.168.204.101"
}
}
# Create local dc subcloud1 mock data in database
data_install = json.dumps(fake_subcloud.FAKE_SUBCLOUD_INSTALL_VALUES)
self.create_subcloud_with_pg_static(
self.ctx,
peer_group_id=self.peer_group.id,
rehome_data=json.dumps(rehome_data),
name='subcloud1',
region_name='subcloud1',
data_install=data_install)
peer_subcloud1 = self._fake_site_data(1)
self.mock_dc_client().get_subcloud.side_effect = [
peer_subcloud1, dccommon_exceptions.SubcloudNotFound]
self.mock_dc_client().update_subcloud.side_effect = Exception('boom')
self.spm._sync_subclouds(self.ctx, self.peer, self.peer_group.id,
FAKE_SITE1_PEER_GROUP_ID)
self.mock_log.error.assert_called_once_with(
'Failed to add/update Subcloud subcloud1 '
'(region_name: subcloud1) on peer site: boom'
)
def test_sync_subcloud_peer_group_fail(self):
# system_uuid of the peer site not matches with the peer_uuid
peer = self.create_system_peer_static(
self.ctx,
peer_uuid=111,
peer_name='SystemPeer')
peer_group = self.create_subcloud_peer_group_static(
self.ctx,
peer_group_name='SubcloudPeerGroup3')
association = self.create_peer_group_association_static(
self.ctx,
system_peer_id=peer.id,
peer_group_id=peer_group.id)
spm = system_peer_manager.SystemPeerManager(mock.MagicMock())
self.assertRaises(exceptions.PeerGroupAssociationTargetNotMatch,
spm.sync_subcloud_peer_group, self.ctx,
association.id, False)
def test_delete_peer_group_association_secondary(self):
# Create local dc subcloud1 mock data in database
subcloud4 = self.create_subcloud_with_pg_static(
self.ctx,
peer_group_id=self.peer_group.id,
name='subcloud4')
peer_subcloud4 = self._fake_site_data(4)
self.mock_dc_client().get_subcloud = mock.MagicMock()
self.mock_dc_client().get_subcloud.side_effect = [
peer_subcloud4]
self.mock_dc_client().get_peer_group_association_with_peer_id_and_pg_id.\
return_value = {'id': FAKE_SITE1_ASSOCIATION_ID}
self.spm.delete_peer_group_association(self.ctx, self.association.id)
Calls = [mock.call('Deleting association peer group 1.'),
mock.call('Ignoring delete Peer Site Subcloud subcloud4 as '
'is not in secondary or rehome failed state.'),
mock.call('Processed subcloud subcloud4 for peer subcloud clean '
'(operation 100% complete, 0 subcloud(s) remaining)'),
mock.call('Deleted Subcloud Peer Group '
'SubcloudPeerGroup1 on peer site.')]
self.mock_log.info.assert_has_calls(Calls)
def test_sync_subcloud_peer_group_systempeer_notfound(self):
self.mock_dc_client().get_system_peer.side_effect = \
dccommon_exceptions.SystemPeerNotFound
spm = system_peer_manager.SystemPeerManager(mock.MagicMock())
spm.sync_subcloud_peer_group(self.ctx, self.association.id, False)
self.mock_log.error.assert_called_once_with(
f'Peer Site System Peer {self.mock_get_local_system().uuid}'
' does not exist.'
)
def test_delete_peer_group_association_uuid_does_not_match(self):
peer = self.create_system_peer_static(
self.ctx,
peer_uuid=111,
peer_name='SystemPeer')
peer_group = self.create_subcloud_peer_group_static(
self.ctx,
peer_group_name='SubcloudPeerGroup3')
association = self.create_peer_group_association_static(
self.ctx,
system_peer_id=peer.id,
peer_group_id=peer_group.id)
self.spm.delete_peer_group_association(self.ctx, association.id)
associations = db_api.peer_group_association_get_all(self.ctx)
self.assertEqual(1, len(associations))
self.mock_log.warning.assert_called_once_with(
f'Peer site system uuid {FAKE_SITE1_SYSTEM_UUID} '
f'does not match with the peer_uuid {peer.peer_uuid}'
)
def test_delete_peer_group_association_failed_sp_notfound(self):
self.mock_dc_client().get_system_peer.side_effect = \
dccommon_exceptions.SystemPeerNotFound
self.spm.delete_peer_group_association(self.ctx, self.association.id)
self.mock_log.error.assert_called_once_with(
f'Peer Site System Peer {self.mock_get_local_system().uuid}'
' does not exist.')
def test_sync_subcloud_peer_group_failed_sp_notfound(self):
self.mock_dc_client().get_system_peer.side_effect = \
dccommon_exceptions.SystemPeerNotFound
self.spm.sync_subcloud_peer_group(self.ctx, self.association.id)
self.mock_log.error.assert_called_once_with(
'Peer Site System Peer '
f'{self.mock_get_local_system().uuid} does not exist.')
def test_update_subcloud_peer_group_offline(self):
db_api.system_peer_update(
self.ctx, self.peer.id,
availability_state=consts.SYSTEM_PEER_AVAILABILITY_STATE_UNAVAILABLE
)
self.spm.update_subcloud_peer_group(
self.ctx, self.peer_group.id,
FAKE_SITE1_PEER_GROUP_STATE,
FAKE_SITE1_PEER_GROUP_MAX_SUBCLOUDS_REHOMING,
FAKE_SITE0_PEER_GROUP_NAME)
self.mock_log.warning.assert_called_once_with('Peer system 1 offline')
def test_update_subcloud_peer_group_associations_notfound(self):
peer_group = self.create_subcloud_peer_group_static(
self.ctx, peer_group_name='SubcloudPeerGroup2'
)
self.spm.update_subcloud_peer_group(
self.ctx, peer_group.id,
FAKE_SITE1_PEER_GROUP_STATE,
FAKE_SITE1_PEER_GROUP_MAX_SUBCLOUDS_REHOMING,
FAKE_SITE0_PEER_GROUP_NAME)
self.mock_log.info.assert_called_once_with(
'No association found for peer group 2'
)