213 lines
8.5 KiB
Python
213 lines
8.5 KiB
Python
#
|
|
# Copyright (c) 2024 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
|
|
import uuid
|
|
|
|
import mock
|
|
|
|
from dcmanager.common import consts
|
|
from dcmanager.db.sqlalchemy import api as db_api
|
|
from dcmanager.manager import peer_monitor_manager
|
|
from dcmanager.tests import base
|
|
|
|
# FAKE SYSINV DATA
|
|
FAKE_SITE0_SYSTEM_UUID = str(uuid.uuid4())
|
|
FAKE_SITE1_SYSTEM_UUID = str(uuid.uuid4())
|
|
|
|
# FAKE SYSTEM PEER DATA
|
|
FAKE_SYSTEM_PEER_ID = 1
|
|
FAKE_SYSTEM_PEER_UUID = FAKE_SITE1_SYSTEM_UUID
|
|
FAKE_SYSTEM_PEER_NAME = 'PeerSite1'
|
|
FAKE_MANAGER_ENDPOINT = 'http://128.128.128.128:5000/v3'
|
|
FAKE_MANAGER_USERNAME = 'admin'
|
|
FAKE_MANAGER_PASSWORD = 'cGFzc3dvcmQ='
|
|
FAKE_PEER_CONTROLLER_GATEWAY_IP = '128.128.1.1'
|
|
|
|
# FAKE SUBCLOUD PEER GROUP DATA (SITE0)
|
|
FAKE_SITE0_PEER_GROUP_ID = 1
|
|
FAKE_SITE0_PEER_GROUP_NAME = 'PeerGroup1'
|
|
FAKE_SITE0_PEER_GROUP_SYSTEM_LEADER_ID = FAKE_SITE0_SYSTEM_UUID
|
|
FAKE_SITE0_PEER_GROUP_SYSTEM_LEADER_NAME = 'site0'
|
|
FAKE_SITE0_PEER_GROUP_MAX_SUBCLOUDS_REHOMING = 50
|
|
FAKE_SITE0_PEER_GROUP_PRIORITY = 0
|
|
FAKE_SITE0_PEER_GROUP_STATE = 'enabled'
|
|
|
|
# FAKE SYSTEM PEER DATA (SITE1)
|
|
FAKE_SITE1_SYSTEM_PEER_ID = 10
|
|
|
|
# FAKE SUBCLOUD PEER GROUP DATA (SITE1)
|
|
FAKE_SITE1_PEER_GROUP_ID = 9
|
|
|
|
# FAKE PEER GROUP ASSOCIATION DATA (SITE0)
|
|
FAKE_ASSOCIATION_PEER_GROUP_ID = \
|
|
FAKE_SITE0_PEER_GROUP_ID
|
|
FAKE_ASSOCIATION_SYSTEM_PEER_ID = \
|
|
FAKE_SYSTEM_PEER_ID
|
|
FAKE_ASSOCIATION_PEER_GROUP_PRIORITY = 1
|
|
FAKE_ASSOCIATION_SYNC_STATUS = 'in-sync'
|
|
FAKE_ASSOCIATION_SYNC_MESSAGE = 'None'
|
|
FAKE_ASSOCIATION_TYPE = 'primary'
|
|
|
|
# FAKE PEER GROUP ASSOCIATION DATA (SITE1)
|
|
FAKE_SITE1_ASSOCIATION_ID = 10
|
|
|
|
|
|
class FakeLocalSystem(object):
|
|
def __init__(self):
|
|
self.uuid = FAKE_SITE0_SYSTEM_UUID
|
|
|
|
|
|
class TestPeerMonitor(base.DCManagerTestCase):
|
|
def setUp(self):
|
|
super(TestPeerMonitor, self).setUp()
|
|
|
|
@staticmethod
|
|
def create_system_peer_static(ctxt, **kwargs):
|
|
values = {
|
|
'peer_uuid': FAKE_SYSTEM_PEER_UUID,
|
|
'peer_name': FAKE_SYSTEM_PEER_NAME,
|
|
'endpoint': FAKE_MANAGER_ENDPOINT,
|
|
'username': FAKE_MANAGER_USERNAME,
|
|
'password': FAKE_MANAGER_PASSWORD,
|
|
'gateway_ip': FAKE_PEER_CONTROLLER_GATEWAY_IP
|
|
}
|
|
values.update(kwargs)
|
|
return db_api.system_peer_create(ctxt, **values)
|
|
|
|
@staticmethod
|
|
def create_subcloud_peer_group_static(ctxt, **kwargs):
|
|
values = {
|
|
"peer_group_name": FAKE_SITE0_PEER_GROUP_NAME,
|
|
"system_leader_id": FAKE_SITE0_PEER_GROUP_SYSTEM_LEADER_ID,
|
|
"system_leader_name": FAKE_SITE0_PEER_GROUP_SYSTEM_LEADER_NAME,
|
|
"group_priority": FAKE_SITE0_PEER_GROUP_PRIORITY,
|
|
"group_state": FAKE_SITE0_PEER_GROUP_STATE,
|
|
"max_subcloud_rehoming":
|
|
FAKE_SITE0_PEER_GROUP_MAX_SUBCLOUDS_REHOMING,
|
|
"migration_status": None
|
|
}
|
|
values.update(kwargs)
|
|
return db_api.subcloud_peer_group_create(ctxt, **values)
|
|
|
|
@staticmethod
|
|
def create_peer_group_association_static(ctxt, **kwargs):
|
|
values = {
|
|
"system_peer_id": FAKE_ASSOCIATION_SYSTEM_PEER_ID,
|
|
"peer_group_id": FAKE_ASSOCIATION_PEER_GROUP_ID,
|
|
"peer_group_priority": FAKE_ASSOCIATION_PEER_GROUP_PRIORITY,
|
|
"sync_status": FAKE_ASSOCIATION_SYNC_STATUS,
|
|
"sync_message": FAKE_ASSOCIATION_SYNC_MESSAGE,
|
|
"association_type": FAKE_ASSOCIATION_TYPE
|
|
}
|
|
values.update(kwargs)
|
|
return db_api.peer_group_association_create(ctxt, **values)
|
|
|
|
def test_initialize_peer_monitor_manager(self):
|
|
peer = self.create_system_peer_static(self.ctx)
|
|
pm = peer_monitor_manager.PeerMonitor(peer, self.ctx, mock.MagicMock())
|
|
self.assertIsNotNone(pm)
|
|
self.assertEqual(FAKE_SYSTEM_PEER_NAME, pm.peer.peer_name)
|
|
|
|
def test_update_sync_status_when_secondary_site_becomes_unreachable(self):
|
|
peer = self.create_system_peer_static(
|
|
self.ctx,
|
|
peer_name='SystemPeer1')
|
|
peer_group = self.create_subcloud_peer_group_static(
|
|
self.ctx,
|
|
peer_group_name='SubcloudPeerGroup1')
|
|
association = self.create_peer_group_association_static(
|
|
self.ctx,
|
|
system_peer_id=peer.id,
|
|
peer_group_id=peer_group.id)
|
|
|
|
pm = peer_monitor_manager.PeerMonitor(peer, self.ctx, mock.MagicMock())
|
|
pm._update_sync_status_when_secondary_site_becomes_unreachable()
|
|
|
|
association_new = db_api.peer_group_association_get(
|
|
self.ctx, association.id)
|
|
self.assertEqual(consts.ASSOCIATION_SYNC_STATUS_UNKNOWN,
|
|
association_new.sync_status)
|
|
|
|
@mock.patch('dcmanager.manager.peer_monitor_manager.'
|
|
'SystemPeerManager.get_peer_dc_client')
|
|
def test_update_sync_status_and_association_is_non_primary(self, mock_client):
|
|
mock_dc_client = mock.MagicMock()
|
|
mock_dc_client().get_subcloud_peer_group = mock.MagicMock()
|
|
mock_client.return_value = mock_dc_client()
|
|
|
|
peer = self.create_system_peer_static(
|
|
self.ctx, peer_name='SystemPeer1')
|
|
peer_group = self.create_subcloud_peer_group_static(
|
|
self.ctx, peer_group_name='SubcloudPeerGroup1')
|
|
association = self.create_peer_group_association_static(
|
|
self.ctx, system_peer_id=peer.id,
|
|
peer_group_id=peer_group.id,
|
|
association_type=consts.ASSOCIATION_TYPE_NON_PRIMARY)
|
|
|
|
mock_dc_client().get_subcloud_peer_group.return_value = \
|
|
{'id': FAKE_SITE1_PEER_GROUP_ID}
|
|
|
|
# Test the case where the association is non-primary
|
|
pm = peer_monitor_manager.PeerMonitor(peer, self.ctx, mock.MagicMock())
|
|
pm._update_sync_status_when_secondary_site_becomes_reachable()
|
|
mock_dc_client().get_subcloud_peer_group.assert_not_called()
|
|
|
|
association_new = db_api.peer_group_association_get(
|
|
self.ctx, association.id)
|
|
self.assertEqual(consts.ASSOCIATION_SYNC_STATUS_IN_SYNC,
|
|
association_new.sync_status)
|
|
|
|
@mock.patch('dcmanager.manager.system_peer_manager.'
|
|
'utils.get_local_system')
|
|
@mock.patch('dcmanager.manager.peer_monitor_manager.'
|
|
'SystemPeerManager.get_peer_dc_client')
|
|
def test_update_sync_status_when_secondary_site_becomes_reachable(
|
|
self, mock_client, mock_utils):
|
|
mock_dc_client = mock.MagicMock()
|
|
mock_dc_client().get_subcloud_peer_group = mock.MagicMock()
|
|
mock_dc_client().get_system_peer = mock.MagicMock()
|
|
mock_dc_client().get_peer_group_association_with_peer_id_and_pg_id = \
|
|
mock.MagicMock()
|
|
mock_dc_client().update_peer_group_association_sync_status = \
|
|
mock.MagicMock()
|
|
mock_client.return_value = mock_dc_client()
|
|
mock_utils.return_value = FakeLocalSystem()
|
|
|
|
peer = self.create_system_peer_static(
|
|
self.ctx, peer_name='SystemPeer1')
|
|
peer_group = self.create_subcloud_peer_group_static(
|
|
self.ctx, peer_group_name='SubcloudPeerGroup1')
|
|
association = self.create_peer_group_association_static(
|
|
self.ctx, system_peer_id=peer.id,
|
|
peer_group_id=peer_group.id,
|
|
sync_status=consts.ASSOCIATION_SYNC_STATUS_UNKNOWN)
|
|
|
|
mock_dc_client().get_subcloud_peer_group.return_value = \
|
|
{'id': FAKE_SITE1_PEER_GROUP_ID}
|
|
mock_dc_client().get_system_peer.return_value = \
|
|
{'id': FAKE_SITE1_SYSTEM_PEER_ID}
|
|
mock_dc_client().get_peer_group_association_with_peer_id_and_pg_id.\
|
|
return_value = {'id': FAKE_SITE1_ASSOCIATION_ID}
|
|
|
|
# Test the case where the association sync_status is unknown
|
|
pm = peer_monitor_manager.PeerMonitor(peer, self.ctx, mock.MagicMock())
|
|
pm._update_sync_status_when_secondary_site_becomes_reachable()
|
|
mock_dc_client().get_subcloud_peer_group.assert_called_once_with(
|
|
peer_group.peer_group_name)
|
|
mock_dc_client().get_system_peer.assert_called_once_with(
|
|
FAKE_SITE0_SYSTEM_UUID)
|
|
mock_dc_client().get_peer_group_association_with_peer_id_and_pg_id.\
|
|
assert_called_once_with(FAKE_SITE1_SYSTEM_PEER_ID,
|
|
FAKE_SITE1_PEER_GROUP_ID)
|
|
mock_dc_client().update_peer_group_association_sync_status.\
|
|
assert_called_once_with(FAKE_SITE1_ASSOCIATION_ID,
|
|
consts.ASSOCIATION_SYNC_STATUS_IN_SYNC)
|
|
|
|
association_new = db_api.peer_group_association_get(
|
|
self.ctx, association.id)
|
|
self.assertEqual(consts.ASSOCIATION_SYNC_STATUS_IN_SYNC,
|
|
association_new.sync_status)
|