Newer
Older
import copy, grpc, logging, pytest, threading
from queue import Queue
from typing import Tuple
from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID
from common.orm.Database import Database
from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBackendEnum
from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum
from common.message_broker.MessageBroker import MessageBroker
from context.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
from context.client.ContextClient import ContextClient
Context, ContextEvent, ContextId, Device, DeviceEvent, DeviceId, DeviceOperationalStatusEnum, Empty,
EventTypeEnum, Link, LinkEvent, LinkId, Service, ServiceEvent, ServiceId, ServiceStatusEnum, ServiceTypeEnum,
Topology, TopologyEvent, TopologyId)
from context.service.grpc_server.ContextService import ContextService
CONTEXT, CONTEXT_ID, DEVICE1, DEVICE1_ID, DEVICE1_UUID, DEVICE2, DEVICE2_ID, DEVICE2_UUID, LINK_DEV1_DEV2,
LINK_DEV1_DEV2_ID, LINK_DEV1_DEV2_UUID, SERVICE_DEV1_DEV2, SERVICE_DEV1_DEV2_ID, SERVICE_DEV1_DEV2_UUID, TOPOLOGY,
TOPOLOGY_ID)
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.DEBUG)
GRPC_PORT = 10000 + GRPC_SERVICE_PORT # avoid privileged ports
REDIS_CONFIG = {
'REDIS_SERVICE_HOST': '10.1.7.194',
'REDIS_SERVICE_PORT': 30283,
'REDIS_DATABASE_ID': 0,
}
('all_inmemory', DatabaseBackendEnum.INMEMORY, {}, MessageBrokerBackendEnum.INMEMORY, {} ),
('all_redis', DatabaseBackendEnum.REDIS, REDIS_CONFIG, MessageBrokerBackendEnum.REDIS, REDIS_CONFIG),
@pytest.fixture(scope='session', ids=[str(scenario[0]) for scenario in SCENARIOS], params=SCENARIOS)
def context_db_mb(request) -> Tuple[Database, MessageBroker]:
name,db_backend,db_settings,mb_backend,mb_settings = request.param
msg = 'Running scenario {:s} db_backend={:s}, db_settings={:s}, mb_backend={:s}, mb_settings={:s}...'
LOGGER.info(msg.format(str(name), str(db_backend.value), str(db_settings), str(mb_backend.value), str(mb_settings)))
_database = Database(get_database_backend(backend=db_backend, **db_settings))
_message_broker = MessageBroker(get_messagebroker_backend(backend=mb_backend, **mb_settings))
yield _database, _message_broker
_message_broker.terminate()
def context_service(context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name
context_db_mb[0], context_db_mb[1], port=GRPC_PORT, max_workers=GRPC_MAX_WORKERS,
grace_period=GRPC_GRACE_PERIOD)
_service.start()
yield _service
_service.stop()
@pytest.fixture(scope='session')
def context_client(context_service : ContextService): # pylint: disable=redefined-outer-name
_client = ContextClient(address='127.0.0.1', port=GRPC_PORT)
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
class EventsCollector:
def __init__(self, context_client : ContextClient) -> None: # pylint: disable=redefined-outer-name
self._events_queue = Queue()
self._context_stream = context_client.GetContextEvents(Empty())
self._topology_stream = context_client.GetTopologyEvents(Empty())
self._device_stream = context_client.GetDeviceEvents(Empty())
self._link_stream = context_client.GetLinkEvents(Empty())
self._service_stream = context_client.GetServiceEvents(Empty())
self._context_thread = threading.Thread(target=self._collect, args=(self._context_stream ,), daemon=False)
self._topology_thread = threading.Thread(target=self._collect, args=(self._topology_stream,), daemon=False)
self._device_thread = threading.Thread(target=self._collect, args=(self._device_stream ,), daemon=False)
self._link_thread = threading.Thread(target=self._collect, args=(self._link_stream ,), daemon=False)
self._service_thread = threading.Thread(target=self._collect, args=(self._service_stream ,), daemon=False)
def _collect(self, events_stream) -> None:
try:
for event in events_stream:
self._events_queue.put_nowait(event)
except grpc.RpcError as e:
if e.code() != grpc.StatusCode.CANCELLED: # pylint: disable=no-member
raise # pragma: no cover
def start(self):
self._context_thread.start()
self._topology_thread.start()
self._device_thread.start()
self._link_thread.start()
self._service_thread.start()
def get_event(self, block : bool = True, timeout : float = 0.1):
return self._events_queue.get(block=block, timeout=timeout)
def stop(self):
self._context_stream.cancel()
self._topology_stream.cancel()
self._device_stream.cancel()
self._link_stream.cancel()
self._service_stream.cancel()
self._context_thread.join()
self._topology_thread.join()
self._device_thread.join()
self._link_thread.join()
self._service_thread.join()
def test_context(
context_client : ContextClient, # pylint: disable=redefined-outer-name
context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name
context_database = context_db_mb[0]
# ----- Clean the database -----------------------------------------------------------------------------------------
# ----- Initialize the EventsCollector -----------------------------------------------------------------------------
events_collector = EventsCollector(context_client)
events_collector.start()
# ----- Get when the object does not exist -------------------------------------------------------------------------
with pytest.raises(grpc.RpcError) as e:
context_client.GetContext(ContextId(**CONTEXT_ID))
assert e.value.code() == grpc.StatusCode.NOT_FOUND
assert e.value.details() == 'Context({:s}) not found'.format(DEFAULT_CONTEXT_UUID)
# ----- List when the object does not exist ------------------------------------------------------------------------
response = context_client.ListContextIds(Empty())
assert len(response.context_ids) == 0
response = context_client.ListContexts(Empty())
assert len(response.contexts) == 0
# ----- Dump state of database before create the object ------------------------------------------------------------
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
assert len(db_entries) == 0
# ----- Create the object ------------------------------------------------------------------------------------------
response = context_client.SetContext(Context(**CONTEXT))
assert response.context_uuid.uuid == DEFAULT_CONTEXT_UUID
# ----- Check create event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, ContextEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
assert event.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
# ----- Update the object ------------------------------------------------------------------------------------------
response = context_client.SetContext(Context(**CONTEXT))
assert response.context_uuid.uuid == DEFAULT_CONTEXT_UUID
# ----- Check update event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, ContextEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_UPDATE
assert event.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
# ----- Dump state of database after create/update the object ------------------------------------------------------
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
assert len(db_entries) == 2
# ----- Get when the object exists ---------------------------------------------------------------------------------
response = context_client.GetContext(ContextId(**CONTEXT_ID))
assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert len(response.topology_ids) == 0
assert len(response.service_ids) == 0
# ----- List when the object exists --------------------------------------------------------------------------------
response = context_client.ListContextIds(Empty())
assert len(response.context_ids) == 1
assert response.context_ids[0].context_uuid.uuid == DEFAULT_CONTEXT_UUID
response = context_client.ListContexts(Empty())
assert len(response.contexts) == 1
assert response.contexts[0].context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert len(response.contexts[0].topology_ids) == 0
assert len(response.contexts[0].service_ids) == 0
# ----- Remove the object ------------------------------------------------------------------------------------------
context_client.RemoveContext(ContextId(**CONTEXT_ID))
# ----- Check remove event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, ContextEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
assert event.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
# ----- Stop the EventsCollector -----------------------------------------------------------------------------------
events_collector.stop()
# ----- Dump state of database after remove the object -------------------------------------------------------------
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
assert len(db_entries) == 0
def test_topology(
context_client : ContextClient, # pylint: disable=redefined-outer-name
context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name
context_database = context_db_mb[0]
# ----- Clean the database -----------------------------------------------------------------------------------------
# ----- Initialize the EventsCollector -----------------------------------------------------------------------------
events_collector = EventsCollector(context_client)
events_collector.start()
# ----- Prepare dependencies for the test and capture related events -----------------------------------------------
response = context_client.SetContext(Context(**CONTEXT))
assert response.context_uuid.uuid == DEFAULT_CONTEXT_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, ContextEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
assert event.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
# ----- Get when the object does not exist -------------------------------------------------------------------------
with pytest.raises(grpc.RpcError) as e:
context_client.GetTopology(TopologyId(**TOPOLOGY_ID))
assert e.value.code() == grpc.StatusCode.NOT_FOUND
assert e.value.details() == 'Topology({:s}/{:s}) not found'.format(DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID)
# ----- List when the object does not exist ------------------------------------------------------------------------
response = context_client.ListTopologyIds(ContextId(**CONTEXT_ID))
assert len(response.topology_ids) == 0
response = context_client.ListTopologies(ContextId(**CONTEXT_ID))
assert len(response.topologies) == 0
# ----- Dump state of database before create the object ------------------------------------------------------------
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
# ----- Create the object ------------------------------------------------------------------------------------------
response = context_client.SetTopology(Topology(**TOPOLOGY))
assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
# ----- Check create event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, TopologyEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
assert event.topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert event.topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
# ----- Update the object ------------------------------------------------------------------------------------------
response = context_client.SetTopology(Topology(**TOPOLOGY))
assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
# ----- Check update event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, TopologyEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_UPDATE
assert event.topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert event.topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
# ----- Dump state of database after create/update the object ------------------------------------------------------
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
assert len(db_entries) == 5
# ----- Get when the object exists ---------------------------------------------------------------------------------
response = context_client.GetTopology(TopologyId(**TOPOLOGY_ID))
assert response.topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
assert len(response.device_ids) == 0
assert len(response.link_ids) == 0
# ----- List when the object exists --------------------------------------------------------------------------------
response = context_client.ListTopologyIds(ContextId(**CONTEXT_ID))
assert len(response.topology_ids) == 1
assert response.topology_ids[0].context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.topology_ids[0].topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
response = context_client.ListTopologies(ContextId(**CONTEXT_ID))
assert len(response.topologies) == 1
assert response.topologies[0].topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.topologies[0].topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
assert len(response.topologies[0].device_ids) == 0
assert len(response.topologies[0].link_ids) == 0
# ----- Remove the object ------------------------------------------------------------------------------------------
context_client.RemoveTopology(TopologyId(**TOPOLOGY_ID))
context_client.RemoveContext(ContextId(**CONTEXT_ID))
# ----- Check remove event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, TopologyEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
assert event.topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert event.topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, ContextEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
assert event.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
# ----- Stop the EventsCollector -----------------------------------------------------------------------------------
events_collector.stop()
# ----- Dump state of database after remove the object -------------------------------------------------------------
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
assert len(db_entries) == 0
def test_device(
context_client : ContextClient, # pylint: disable=redefined-outer-name
context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name
context_database = context_db_mb[0]
# ----- Clean the database -----------------------------------------------------------------------------------------
# ----- Initialize the EventsCollector -----------------------------------------------------------------------------
events_collector = EventsCollector(context_client)
events_collector.start()
# ----- Prepare dependencies for the test and capture related events -----------------------------------------------
response = context_client.SetContext(Context(**CONTEXT))
assert response.context_uuid.uuid == DEFAULT_CONTEXT_UUID
response = context_client.SetTopology(Topology(**TOPOLOGY))
assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, ContextEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
assert event.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, TopologyEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
assert event.topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert event.topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
# ----- Get when the object does not exist -------------------------------------------------------------------------
with pytest.raises(grpc.RpcError) as e:
context_client.GetDevice(DeviceId(**DEVICE1_ID))
assert e.value.code() == grpc.StatusCode.NOT_FOUND
assert e.value.details() == 'Device({:s}) not found'.format(DEVICE1_UUID)
# ----- List when the object does not exist ------------------------------------------------------------------------
response = context_client.ListDeviceIds(Empty())
assert len(response.device_ids) == 0
response = context_client.ListDevices(Empty())
assert len(response.devices) == 0
# ----- Dump state of database before create the object ------------------------------------------------------------
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
assert len(db_entries) == 5
# ----- Create the object ------------------------------------------------------------------------------------------
response = context_client.SetDevice(Device(**DEVICE1))
assert response.device_uuid.uuid == DEVICE1_UUID
# ----- Check create event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, DeviceEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
assert event.device_id.device_uuid.uuid == DEVICE1_UUID
# ----- Update the object ------------------------------------------------------------------------------------------
response = context_client.SetDevice(Device(**DEVICE1))
assert response.device_uuid.uuid == DEVICE1_UUID
# ----- Check update event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, DeviceEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_UPDATE
assert event.device_id.device_uuid.uuid == DEVICE1_UUID
# ----- Dump state of database after create/update the object ------------------------------------------------------
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
assert len(db_entries) == 25
# ----- Get when the object exists ---------------------------------------------------------------------------------
response = context_client.GetDevice(DeviceId(**DEVICE1_ID))
assert response.device_id.device_uuid.uuid == DEVICE1_UUID
assert response.device_type == 'packet-router'
assert len(response.device_config.config_rules) == 3
assert response.device_operational_status == DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
assert len(response.device_drivers) == 2
assert len(response.device_endpoints) == 3
# ----- List when the object exists --------------------------------------------------------------------------------
response = context_client.ListDeviceIds(Empty())
assert len(response.device_ids) == 1
assert response.device_ids[0].device_uuid.uuid == DEVICE1_UUID
response = context_client.ListDevices(Empty())
assert len(response.devices) == 1
assert response.devices[0].device_id.device_uuid.uuid == DEVICE1_UUID
assert response.devices[0].device_type == 'packet-router'
assert len(response.devices[0].device_config.config_rules) == 3
assert response.devices[0].device_operational_status == DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
assert len(response.devices[0].device_drivers) == 2
assert len(response.devices[0].device_endpoints) == 3
# ----- Create object relation -------------------------------------------------------------------------------------
TOPOLOGY_WITH_DEVICE = copy.deepcopy(TOPOLOGY)
TOPOLOGY_WITH_DEVICE['device_ids'].append(DEVICE1_ID)
response = context_client.SetTopology(Topology(**TOPOLOGY_WITH_DEVICE))
assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
# ----- Check update event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, TopologyEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_UPDATE
assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
# ----- Check relation was created ---------------------------------------------------------------------------------
response = context_client.GetTopology(TopologyId(**TOPOLOGY_ID))
assert response.topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
assert len(response.device_ids) == 1
assert response.device_ids[0].device_uuid.uuid == DEVICE1_UUID
assert len(response.link_ids) == 0
# ----- Dump state of database after creating the object relation --------------------------------------------------
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
assert len(db_entries) == 25
# ----- Remove the object ------------------------------------------------------------------------------------------
context_client.RemoveDevice(DeviceId(**DEVICE1_ID))
context_client.RemoveTopology(TopologyId(**TOPOLOGY_ID))
context_client.RemoveContext(ContextId(**CONTEXT_ID))
# ----- Check remove event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, DeviceEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
assert event.device_id.device_uuid.uuid == DEVICE1_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, TopologyEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
assert event.topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert event.topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, ContextEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
assert event.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
# ----- Stop the EventsCollector -----------------------------------------------------------------------------------
events_collector.stop()
# ----- Dump state of database after remove the object -------------------------------------------------------------
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
assert len(db_entries) == 0
def test_link(
context_client : ContextClient, # pylint: disable=redefined-outer-name
context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name
context_database = context_db_mb[0]
# ----- Clean the database -----------------------------------------------------------------------------------------
# ----- Initialize the EventsCollector -----------------------------------------------------------------------------
events_collector = EventsCollector(context_client)
events_collector.start()
# ----- Prepare dependencies for the test and capture related events -----------------------------------------------
response = context_client.SetContext(Context(**CONTEXT))
assert response.context_uuid.uuid == DEFAULT_CONTEXT_UUID
response = context_client.SetTopology(Topology(**TOPOLOGY))
assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
response = context_client.SetDevice(Device(**DEVICE1))
assert response.device_uuid.uuid == DEVICE1_UUID
response = context_client.SetDevice(Device(**DEVICE2))
assert response.device_uuid.uuid == DEVICE2_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, ContextEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
assert event.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, TopologyEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
assert event.topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert event.topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, DeviceEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
assert event.device_id.device_uuid.uuid == DEVICE1_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, DeviceEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
assert event.device_id.device_uuid.uuid == DEVICE2_UUID
# ----- Get when the object does not exist -------------------------------------------------------------------------
with pytest.raises(grpc.RpcError) as e:
context_client.GetLink(LinkId(**LINK_DEV1_DEV2_ID))
assert e.value.code() == grpc.StatusCode.NOT_FOUND
assert e.value.details() == 'Link({:s}) not found'.format(LINK_DEV1_DEV2_UUID)
# ----- List when the object does not exist ------------------------------------------------------------------------
response = context_client.ListLinkIds(Empty())
assert len(response.link_ids) == 0
response = context_client.ListLinks(Empty())
assert len(response.links) == 0
# ----- Dump state of database before create the object ------------------------------------------------------------
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
# ----- Create the object ------------------------------------------------------------------------------------------
response = context_client.SetLink(Link(**LINK_DEV1_DEV2))
assert response.link_uuid.uuid == LINK_DEV1_DEV2_UUID
# ----- Check create event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, LinkEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
assert event.link_id.link_uuid.uuid == LINK_DEV1_DEV2_UUID
# ----- Update the object ------------------------------------------------------------------------------------------
response = context_client.SetLink(Link(**LINK_DEV1_DEV2))
assert response.link_uuid.uuid == LINK_DEV1_DEV2_UUID
# ----- Check update event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, LinkEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_UPDATE
assert event.link_id.link_uuid.uuid == LINK_DEV1_DEV2_UUID
# ----- Dump state of database after create/update the object ------------------------------------------------------
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
# ----- Get when the object exists ---------------------------------------------------------------------------------
response = context_client.GetLink(LinkId(**LINK_DEV1_DEV2_ID))
assert response.link_id.link_uuid.uuid == LINK_DEV1_DEV2_UUID
# ----- List when the object exists --------------------------------------------------------------------------------
response = context_client.ListLinkIds(Empty())
assert len(response.link_ids) == 1
assert response.link_ids[0].link_uuid.uuid == LINK_DEV1_DEV2_UUID
response = context_client.ListLinks(Empty())
assert len(response.links) == 1
assert response.links[0].link_id.link_uuid.uuid == LINK_DEV1_DEV2_UUID
assert len(response.links[0].link_endpoint_ids) == 2
# ----- Create object relation -------------------------------------------------------------------------------------
TOPOLOGY_WITH_LINK['link_ids'].append(LINK_DEV1_DEV2_ID)
response = context_client.SetTopology(Topology(**TOPOLOGY_WITH_LINK))
assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
# ----- Check update event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, TopologyEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_UPDATE
assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
# ----- Check relation was created ---------------------------------------------------------------------------------
response = context_client.GetTopology(TopologyId(**TOPOLOGY_ID))
assert response.topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
assert len(response.device_ids) == 2
assert response.device_ids[0].device_uuid.uuid == DEVICE1_UUID
assert response.device_ids[1].device_uuid.uuid == DEVICE2_UUID
assert len(response.link_ids) == 1
assert response.link_ids[0].link_uuid.uuid == LINK_DEV1_DEV2_UUID
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
# ----- Remove the object ------------------------------------------------------------------------------------------
context_client.RemoveLink(LinkId(**LINK_DEV1_DEV2_ID))
context_client.RemoveDevice(DeviceId(**DEVICE1_ID))
context_client.RemoveDevice(DeviceId(**DEVICE2_ID))
context_client.RemoveTopology(TopologyId(**TOPOLOGY_ID))
context_client.RemoveContext(ContextId(**CONTEXT_ID))
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
# ----- Check remove event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, LinkEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
assert event.link_id.link_uuid.uuid == LINK_DEV1_DEV2_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, DeviceEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
assert event.device_id.device_uuid.uuid == DEVICE1_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, DeviceEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
assert event.device_id.device_uuid.uuid == DEVICE2_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, TopologyEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
assert event.topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert event.topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, ContextEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
assert event.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
# ----- Stop the EventsCollector -----------------------------------------------------------------------------------
events_collector.stop()
# ----- Dump state of database after remove the object -------------------------------------------------------------
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
assert len(db_entries) == 0
def test_service(
context_client : ContextClient, # pylint: disable=redefined-outer-name
context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name
context_database = context_db_mb[0]
# ----- Clean the database -----------------------------------------------------------------------------------------
# ----- Initialize the EventsCollector -----------------------------------------------------------------------------
events_collector = EventsCollector(context_client)
events_collector.start()
# ----- Prepare dependencies for the test and capture related events -----------------------------------------------
response = context_client.SetContext(Context(**CONTEXT))
assert response.context_uuid.uuid == DEFAULT_CONTEXT_UUID
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
response = context_client.SetTopology(Topology(**TOPOLOGY))
assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
response = context_client.SetDevice(Device(**DEVICE1))
assert response.device_uuid.uuid == DEVICE1_UUID
response = context_client.SetDevice(Device(**DEVICE2))
assert response.device_uuid.uuid == DEVICE2_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, ContextEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
assert event.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, TopologyEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
assert event.topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert event.topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, DeviceEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
assert event.device_id.device_uuid.uuid == DEVICE1_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, DeviceEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
assert event.device_id.device_uuid.uuid == DEVICE2_UUID
# ----- Get when the object does not exist -------------------------------------------------------------------------
with pytest.raises(grpc.RpcError) as e:
context_client.GetService(ServiceId(**SERVICE_DEV1_DEV2_ID))
assert e.value.code() == grpc.StatusCode.NOT_FOUND
assert e.value.details() == 'Service({:s}/{:s}) not found'.format(DEFAULT_CONTEXT_UUID, SERVICE_DEV1_DEV2_UUID)
# ----- List when the object does not exist ------------------------------------------------------------------------
response = context_client.ListServiceIds(ContextId(**CONTEXT_ID))
assert len(response.service_ids) == 0
response = context_client.ListServices(ContextId(**CONTEXT_ID))
assert len(response.services) == 0
# ----- Dump state of database before create the object ------------------------------------------------------------
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
# ----- Create the object ------------------------------------------------------------------------------------------
response = context_client.SetService(Service(**SERVICE_DEV1_DEV2))
assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.service_uuid.uuid == SERVICE_DEV1_DEV2_UUID
# ----- Check create event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, ServiceEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
assert event.service_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert event.service_id.service_uuid.uuid == SERVICE_DEV1_DEV2_UUID
# ----- Update the object ------------------------------------------------------------------------------------------
response = context_client.SetService(Service(**SERVICE_DEV1_DEV2))
assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.service_uuid.uuid == SERVICE_DEV1_DEV2_UUID
# ----- Check update event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, ServiceEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_UPDATE
assert event.service_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert event.service_id.service_uuid.uuid == SERVICE_DEV1_DEV2_UUID
# ----- Dump state of database after create/update the object ------------------------------------------------------
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
# ----- Get when the object exists ---------------------------------------------------------------------------------
response = context_client.GetService(ServiceId(**SERVICE_DEV1_DEV2_ID))
assert response.service_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.service_id.service_uuid.uuid == SERVICE_DEV1_DEV2_UUID
assert response.service_type == ServiceTypeEnum.SERVICETYPE_L3NM
assert len(response.service_endpoint_ids) == 2
assert len(response.service_constraints) == 2
assert response.service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE
assert len(response.service_config.config_rules) == 3
# ----- List when the object exists --------------------------------------------------------------------------------
response = context_client.ListServiceIds(ContextId(**CONTEXT_ID))
assert len(response.service_ids) == 1
assert response.service_ids[0].context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.service_ids[0].service_uuid.uuid == SERVICE_DEV1_DEV2_UUID
response = context_client.ListServices(ContextId(**CONTEXT_ID))
assert len(response.services) == 1
assert response.services[0].service_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert response.services[0].service_id.service_uuid.uuid == SERVICE_DEV1_DEV2_UUID
assert response.services[0].service_type == ServiceTypeEnum.SERVICETYPE_L3NM
assert len(response.services[0].service_endpoint_ids) == 2
assert len(response.services[0].service_constraints) == 2
assert response.services[0].service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE
assert len(response.services[0].service_config.config_rules) == 3
# ----- Remove the object ------------------------------------------------------------------------------------------
context_client.RemoveService(ServiceId(**SERVICE_DEV1_DEV2_ID))
context_client.RemoveDevice(DeviceId(**DEVICE1_ID))
context_client.RemoveDevice(DeviceId(**DEVICE2_ID))
context_client.RemoveTopology(TopologyId(**TOPOLOGY_ID))
context_client.RemoveContext(ContextId(**CONTEXT_ID))
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
# ----- Check remove event -----------------------------------------------------------------------------------------
event = events_collector.get_event(block=True)
assert isinstance(event, ServiceEvent)
assert event.service_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert event.service_id.service_uuid.uuid == SERVICE_DEV1_DEV2_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, DeviceEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
assert event.device_id.device_uuid.uuid == DEVICE1_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, DeviceEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
assert event.device_id.device_uuid.uuid == DEVICE2_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, TopologyEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
assert event.topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
assert event.topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
event = events_collector.get_event(block=True)
assert isinstance(event, ContextEvent)
assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
assert event.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
# ----- Stop the EventsCollector -----------------------------------------------------------------------------------
events_collector.stop()
# ----- Dump state of database after remove the object -------------------------------------------------------------
db_entries = context_database.dump()
LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
for db_entry in db_entries:
LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
LOGGER.info('-----------------------------------------------------------')
assert len(db_entries) == 0