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)) #