import copy, grpc, logging, pytest
from google.protobuf.json_format import MessageToDict
#from common.database.api.context.Constants import DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID
#from common.tests.Assertions import validate_empty, validate_service, validate_service_id, \
# validate_service_list_is_empty, validate_service_list_is_not_empty
from service.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
from service.client.ServiceClient import ServiceClient
from service.proto.context_pb2 import Service
from service.service.ServiceService import ServiceService
port = 10000 + GRPC_SERVICE_PORT # avoid privileged ports
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.DEBUG)
## use "copy.deepcopy" to prevent propagating forced changes during tests
#CONTEXT_ID = {'contextUuid': {'uuid': DEFAULT_CONTEXT_ID}}
#TOPOLOGY_ID = {'contextId': copy.deepcopy(CONTEXT_ID), 'topoId': {'uuid': DEFAULT_TOPOLOGY_ID}}
#SERVICE_ID = {'contextId': copy.deepcopy(CONTEXT_ID), 'cs_id': {'uuid': 'DEV1'}}
#SERVICE = {
# 'cs_id': copy.deepcopy(SERVICE_ID),
# 'serviceType': ServiceType.L3NM,
# 'serviceConfig': {'serviceConfig': ''},
# 'serviceState': {'serviceState': ServiceStateEnum.PLANNED},
# 'constraint': [
# {'constraint_type': 'latency_ms', 'constraint_value': '100'},
# {'constraint_type': 'hops', 'constraint_value': '5'},
# ],
# 'endpointList' : [
# {'topoId': copy.deepcopy(TOPOLOGY_ID), 'dev_id': {'device_id': {'uuid': 'DEV1'}}, 'port_id': {'uuid' : 'EP5'}},
# {'topoId': copy.deepcopy(TOPOLOGY_ID), 'dev_id': {'device_id': {'uuid': 'DEV2'}}, 'port_id': {'uuid' : 'EP5'}},
# {'topoId': copy.deepcopy(TOPOLOGY_ID), 'dev_id': {'device_id': {'uuid': 'DEV3'}}, 'port_id': {'uuid' : 'EP5'}},
# ]
#}
@pytest.fixture(scope='session')
def service_service():
_service = ServiceService(port=port, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD)
_service.start()
yield _service
_service.stop()
@pytest.fixture(scope='session')
def service_client(service_service):
_client = ServiceClient(address='127.0.0.1', port=port)
yield _client
_client.close()
def test_dummy(service_client : ServiceClient):
reply = service_client.CreateService(Service())
#def test_get_services_empty(service_client : ServiceClient):
# # should work
# validate_service_list_is_empty(MessageToDict(
# service_client.GetServiceList(Empty()),
# including_default_value_fields=True, preserving_proto_field_name=True,
# use_integers_for_enums=False))
#def test_create_service_wrong_service_attributes(service_client : ServiceClient):
# # should fail with wrong service context
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service = copy.deepcopy(SERVICE)
# copy_service['cs_id']['contextId']['contextUuid']['uuid'] = ''
# service_client.CreateService(Service(**copy_service))
# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
# msg = 'service.cs_id.contextId.contextUuid.uuid() is out of range: '\
# 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).'
# assert e.value.details() == msg
#
# # should fail with service context does not exist
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service = copy.deepcopy(SERVICE)
# copy_service['cs_id']['contextId']['contextUuid']['uuid'] = 'wrong-context'
# service_client.CreateService(Service(**copy_service))
# assert e.value.code() == grpc.StatusCode.NOT_FOUND
# msg = 'Context(wrong-context) does not exist in the database.'
# assert e.value.details() == msg
#
# # should fail with wrong service id
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service = copy.deepcopy(SERVICE)
# copy_service['cs_id']['cs_id']['uuid'] = ''
# service_client.CreateService(Service(**copy_service))
# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
# msg = 'service.cs_id.cs_id.uuid() is out of range: '\
# 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).'
# assert e.value.details() == msg
#
# # should fail with wrong service type
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service = copy.deepcopy(SERVICE)
# copy_service['serviceType'] = ServiceType.UNKNOWN
# service_client.CreateService(Service(**copy_service))
# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
# msg = 'Method(CreateService) does not accept ServiceType(UNKNOWN). '\
# 'Permitted values for Method(CreateService) are '\
# 'ServiceType([\'L2NM\', \'L3NM\', \'TAPI_CONNECTIVITY_SERVICE\']).'
# assert e.value.details() == msg
#
# # should fail with wrong service state
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service = copy.deepcopy(SERVICE)
# copy_service['serviceState']['serviceState'] = ServiceStateEnum.PENDING_REMOVAL
# service_client.CreateService(Service(**copy_service))
# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
# msg = 'Method(CreateService) does not accept ServiceState(PENDING_REMOVAL). '\
# 'Permitted values for Method(CreateService) are '\
# 'ServiceState([\'PLANNED\']).'
# assert e.value.details() == msg
#
#def test_create_service_wrong_constraint(service_client : ServiceClient):
# # should fail with wrong constraint type
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service = copy.deepcopy(SERVICE)
# copy_service['constraint'][0]['constraint_type'] = ''
# service_client.CreateService(Service(**copy_service))
# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
# msg = 'constraint[#0].constraint_type() is out of range: '\
# 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).'
# assert e.value.details() == msg
#
# # should fail with wrong constraint value
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service = copy.deepcopy(SERVICE)
# copy_service['constraint'][0]['constraint_value'] = ''
# service_client.CreateService(Service(**copy_service))
# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
# msg = 'constraint[#0].constraint_value() is out of range: '\
# 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).'
# assert e.value.details() == msg
#
# # should fail with dupplicated constraint type
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service = copy.deepcopy(SERVICE)
# copy_service['constraint'][1] = copy_service['constraint'][0]
# service_client.CreateService(Service(**copy_service))
# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
# msg = 'Duplicated ConstraintType(latency_ms) in Constraint(#1) of Context(admin)/Service(DEV1).'
# assert e.value.details() == msg
#
#def test_create_service_wrong_endpoint(service_client : ServiceClient, database : Database):
# # should fail with wrong endpoint context
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service = copy.deepcopy(SERVICE)
# copy_service['endpointList'][0]['topoId']['contextId']['contextUuid']['uuid'] = 'wrong-context'
# print(copy_service)
# service_client.CreateService(Service(**copy_service))
# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
# msg = 'Context(wrong-context) in Endpoint(#0) of '\
# 'Context(admin)/Service(DEV1) mismatches acceptable Contexts({\'admin\'}). '\
# 'Optionally, leave field empty to use predefined Context(admin).'
# assert e.value.details() == msg
#
# # should fail with wrong endpoint topology
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service = copy.deepcopy(SERVICE)
# copy_service['endpointList'][0]['topoId']['topoId']['uuid'] = 'wrong-topo'
# service_client.CreateService(Service(**copy_service))
# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
# msg = 'Context(admin)/Topology(wrong-topo) in Endpoint(#0) of '\
# 'Context(admin)/Service(DEV1) mismatches acceptable Topologies({\'admin\'}). '\
# 'Optionally, leave field empty to use predefined Topology(admin).'
# assert e.value.details() == msg
#
# # should fail with endpoint device is empty
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service = copy.deepcopy(SERVICE)
# copy_service['endpointList'][0]['dev_id']['device_id']['uuid'] = ''
# service_client.CreateService(Service(**copy_service))
# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
# msg = 'endpoint_id[#0].dev_id.device_id.uuid() is out of range: '\
# 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).'
# assert e.value.details() == msg
#
# # should fail with endpoint device not found
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service = copy.deepcopy(SERVICE)
# copy_service['endpointList'][0]['dev_id']['device_id']['uuid'] = 'wrong-device'
# service_client.CreateService(Service(**copy_service))
# assert e.value.code() == grpc.StatusCode.NOT_FOUND
# msg = 'Context(admin)/Topology(admin)/Device(wrong-device) in Endpoint(#0) of '\
# 'Context(admin)/Service(DEV1) does not exist in the database.'
# assert e.value.details() == msg
#
# # should fail with endpoint device duplicated
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service = copy.deepcopy(SERVICE)
# copy_service['endpointList'][1] = copy_service['endpointList'][0]
# service_client.CreateService(Service(**copy_service))
# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
# msg = 'Duplicated Context(admin)/Topology(admin)/Device(DEV1) in Endpoint(#1) of '\
# 'Context(admin)/Service(DEV1).'
# assert e.value.details() == msg
#
# # should fail with endpoint port is empty
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service = copy.deepcopy(SERVICE)
# copy_service['endpointList'][0]['port_id']['uuid'] = ''
# service_client.CreateService(Service(**copy_service))
# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
# msg = 'endpoint_id[#0].port_id.uuid() is out of range: '\
# 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).'
# assert e.value.details() == msg
#
# # should fail with endpoint port not found
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service = copy.deepcopy(SERVICE)
# copy_service['endpointList'][0]['port_id']['uuid'] = 'wrong-port'
# service_client.CreateService(Service(**copy_service))
# assert e.value.code() == grpc.StatusCode.NOT_FOUND
# msg = 'Context(admin)/Topology(admin)/Device(DEV1)/Port(wrong-port) in Endpoint(#0) of '\
# 'Context(admin)/Service(DEV1) does not exist in the database.'
# assert e.value.details() == msg
#
#def test_get_service_does_not_exist(service_client : ServiceClient):
# # should fail with service context does not exist
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service_id = copy.deepcopy(SERVICE_ID)
# copy_service_id['contextId']['contextUuid']['uuid'] = 'wrong-context'
# service_client.GetServiceById(ServiceId(**copy_service_id))
# assert e.value.code() == grpc.StatusCode.NOT_FOUND
# msg = 'Context(wrong-context) does not exist in the database.'
# assert e.value.details() == msg
#
# # should fail with service does not exist
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# service_client.GetServiceById(ServiceId(**SERVICE_ID))
# assert e.value.code() == grpc.StatusCode.NOT_FOUND
# msg = 'Context(admin)/Service(DEV1) does not exist in the database.'
# assert e.value.details() == msg
#
#def test_update_service_does_not_exist(service_client : ServiceClient):
# # should fail with service does not exist
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# service_client.UpdateService(Service(**SERVICE))
# assert e.value.code() == grpc.StatusCode.NOT_FOUND
# msg = 'Context(admin)/Service(DEV1) does not exist in the database.'
# assert e.value.details() == msg
#
#def test_create_service(service_client : ServiceClient):
# # should work
# validate_service_id(MessageToDict(
# service_client.CreateService(Service(**SERVICE)),
# including_default_value_fields=True, preserving_proto_field_name=True,
# use_integers_for_enums=False))
#
#def test_create_service_already_exists(service_client : ServiceClient):
# # should fail with service already exists
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# service_client.CreateService(Service(**SERVICE))
# assert e.value.code() == grpc.StatusCode.ALREADY_EXISTS
# msg = 'Context(admin)/Service(DEV1) already exists in the database.'
# assert e.value.details() == msg
#
#def test_get_service(service_client : ServiceClient):
# # should work
# validate_service(MessageToDict(
# service_client.GetServiceById(ServiceId(**SERVICE_ID)),
# including_default_value_fields=True, preserving_proto_field_name=True,
# use_integers_for_enums=False))
#
#def test_update_service(service_client : ServiceClient):
# # should work
# copy_service = copy.deepcopy(SERVICE)
# copy_service['serviceConfig']['serviceConfig'] = ''
# copy_service['serviceState']['serviceState'] = ServiceStateEnum.ACTIVE
# copy_service['constraint'] = [
# {'constraint_type': 'latency_ms', 'constraint_value': '200'},
# {'constraint_type': 'bandwidth_gbps', 'constraint_value': '100'},
# ]
# copy_service['endpointList'] = [
# {
# 'topoId': {'contextId': {'contextUuid': {'uuid': 'admin'}}, 'topoId': {'uuid': 'admin'}},
# 'dev_id': {'device_id': {'uuid': 'DEV1'}},
# 'port_id': {'uuid' : 'EP5'}
# },
# {
# 'topoId': {'contextId': {'contextUuid': {'uuid': 'admin'}}, 'topoId': {'uuid': 'admin'}},
# 'dev_id': {'device_id': {'uuid': 'DEV2'}},
# 'port_id': {'uuid' : 'EP6'}
# },
# ]
# validate_service_id(MessageToDict(
# service_client.UpdateService(Service(**copy_service)),
# including_default_value_fields=True, preserving_proto_field_name=True,
# use_integers_for_enums=False))
#
#def test_delete_service_wrong_service_id(service_client : ServiceClient):
# # should fail with service context is empty
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service_id = copy.deepcopy(SERVICE_ID)
# copy_service_id['contextId']['contextUuid']['uuid'] = ''
# service_client.DeleteService(ServiceId(**copy_service_id))
# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
# msg = 'service_id.contextId.contextUuid.uuid() is out of range: '\
# 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).'
# assert e.value.details() == msg
#
# # should fail with service context does not exist
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service_id = copy.deepcopy(SERVICE_ID)
# copy_service_id['contextId']['contextUuid']['uuid'] = 'wrong-context'
# service_client.DeleteService(ServiceId(**copy_service_id))
# assert e.value.code() == grpc.StatusCode.NOT_FOUND
# msg = 'Context(wrong-context) does not exist in the database.'
# assert e.value.details() == msg
#
# # should fail with service id is empty
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service_id = copy.deepcopy(SERVICE_ID)
# copy_service_id['cs_id']['uuid'] = ''
# service_client.DeleteService(ServiceId(**copy_service_id))
# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
# msg = 'service_id.cs_id.uuid() is out of range: '\
# 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).'
# assert e.value.details() == msg
#
# # should fail with service id is empty
# with pytest.raises(grpc._channel._InactiveRpcError) as e:
# copy_service_id = copy.deepcopy(SERVICE_ID)
# copy_service_id['cs_id']['uuid'] = 'wrong-service'
# service_client.DeleteService(ServiceId(**copy_service_id))
# assert e.value.code() == grpc.StatusCode.NOT_FOUND
# msg = 'Context(admin)/Service(wrong-service) does not exist in the database.'
# assert e.value.details() == msg
#
#def test_delete_service(service_client : ServiceClient):
# # should work
# validate_empty(MessageToDict(
# service_client.DeleteService(ServiceId(**SERVICE_ID)),
# including_default_value_fields=True, preserving_proto_field_name=True,
# use_integers_for_enums=False))
#
#def test_get_services_empty_2(service_client : ServiceClient):
# # should work
# validate_service_list_is_empty(MessageToDict(
# service_client.GetServiceList(Empty()),
# including_default_value_fields=True, preserving_proto_field_name=True,
# use_integers_for_enums=False))
#
#def test_create_service_empty_endpoints(service_client : ServiceClient):
# # should work
# copy_service = copy.deepcopy(SERVICE)
# copy_service['endpointList'][0]['topoId']['contextId']['contextUuid']['uuid'] = ''
# copy_service['endpointList'][0]['topoId']['topoId']['uuid'] = ''
# validate_service_id(MessageToDict(
# service_client.CreateService(Service(**copy_service)),
# including_default_value_fields=True, preserving_proto_field_name=True,
# use_integers_for_enums=False))
#
#def test_get_services_full(service_client : ServiceClient):
# # should work
# validate_service_list_is_not_empty(MessageToDict(
# service_client.GetServiceList(Empty()),
# including_default_value_fields=True, preserving_proto_field_name=True,
# use_integers_for_enums=False))
#