diff --git a/tests/features/Vendor Extensibility/__init__.robot b/tests/features/Vendor Extensibility/__init__.robot new file mode 100644 index 0000000000000000000000000000000000000000..cdcb8538db7a9a7f41f8d6021cbd1d6b0198a222 --- /dev/null +++ b/tests/features/Vendor Extensibility/__init__.robot @@ -0,0 +1,2 @@ +*** Settings *** +Force Tags vendor_extensibility \ No newline at end of file diff --git a/tests/features/Vendor Extensibility/vendor_extensibility.robot b/tests/features/Vendor Extensibility/vendor_extensibility.robot new file mode 100644 index 0000000000000000000000000000000000000000..b14dc71996b805d55ec5ae038ed1613f12bd50f4 --- /dev/null +++ b/tests/features/Vendor Extensibility/vendor_extensibility.robot @@ -0,0 +1,335 @@ +*** Settings *** +Resource /opt/robot-tests/tests/resources/common.resource +Resource /opt/robot-tests/tests/resources/api_invoker_management_requests/apiInvokerManagementRequests.robot +Resource ../../resources/common.resource +Library /opt/robot-tests/tests/libraries/bodyRequests.py + +Suite Teardown Reset Testing Environment +Test Setup Reset Testing Environment +Test Teardown Reset Testing Environment + + +*** Variables *** +${API_INVOKER_NOT_REGISTERED} not-valid + + +*** Test Cases *** +Published API with vendor extensibility + [Tags] vendor_extensibility-1 + ${vendor_specific_service_api_key}= Set Variable vendorSpecific-urn:etsi:mec:capifext:service-info + ${vendor_specific_aef_profile_key}= Set Variable vendorSpecific-urn:etsi:mec:capifext:transport-info + # Register APF + ${register_user_info}= Provider Default Registration + + # Create Vendor Specific information + ${vendor_specific_service_api_description}= Create Vendor Specific Service Api Description + ... ${vendor_specific_service_api_key} + ${vendor_specific_aef_profile}= Create Vendor Specific Aef Profile + ... ${vendor_specific_aef_profile_key} + + # Publish one api + ${service_api_description_published} ${resource_url} ${request_body}= Publish Service Api + ... ${register_user_info} + ... supported_features=100 + ... vendor_specific_service_api_description=${vendor_specific_service_api_description} + ... vendor_specific_aef_profile=${vendor_specific_aef_profile} + + Dictionary Should Contain Key ${service_api_description_published} ${vendor_specific_service_api_key} + Dictionary Should Contain Key + ... ${service_api_description_published['aefProfiles'][0]} + ... ${vendor_specific_aef_profile_key} + + # Default Invoker Registration and Onboarding + ${register_user_info_invoker} ${url} ${request_body}= Invoker Default Onboarding + + # Test + ${resp}= Get Request Capif + ... ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}&aef-id=${register_user_info['aef_id']}&supported_features=2 + ... server=${CAPIF_HTTPS_URL} + ... verify=ca.crt + ... username=${INVOKER_USERNAME} + + Check Response Variable Type And Values ${resp} 200 DiscoveredAPIs + + # Check Results + Dictionary Should Contain Key ${resp.json()} serviceAPIDescriptions + Should Not Be Empty ${resp.json()['serviceAPIDescriptions']} + Length Should Be ${resp.json()['serviceAPIDescriptions']} 1 + List Should Contain Value ${resp.json()['serviceAPIDescriptions']} ${service_api_description_published} + +Published API with vendor extensibility and discover with VendSpecQueryParams disabled + [Tags] vendor_extensibility-2 + ${vendor_specific_service_api_key}= Set Variable vendorSpecific-urn:etsi:mec:capifext:service-info + ${vendor_specific_aef_profile_key}= Set Variable vendorSpecific-urn:etsi:mec:capifext:transport-info + # Register APF + ${register_user_info}= Provider Default Registration + + # Create Vendor Specific information + ${vendor_specific_service_api_description}= Create Vendor Specific Service Api Description + ... ${vendor_specific_service_api_key} + ${vendor_specific_aef_profile}= Create Vendor Specific Aef Profile + ... ${vendor_specific_aef_profile_key} + + # Publish one api + ${service_api_description_published} ${resource_url} ${request_body}= Publish Service Api + ... ${register_user_info} + ... supported_features=100 + ... vendor_specific_service_api_description=${vendor_specific_service_api_description} + ... vendor_specific_aef_profile=${vendor_specific_aef_profile} + + Dictionary Should Contain Key ${service_api_description_published} ${vendor_specific_service_api_key} + Dictionary Should Contain Key + ... ${service_api_description_published['aefProfiles'][0]} + ... ${vendor_specific_aef_profile_key} + + # Default Invoker Registration and Onboarding + ${register_user_info_invoker} ${url} ${request_body}= Invoker Default Onboarding + + # Test + ${resp}= Get Request Capif + ... ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}&aef-id=${register_user_info['aef_id']}&supported_features=0 + ... server=${CAPIF_HTTPS_URL} + ... verify=ca.crt + ... username=${INVOKER_USERNAME} + + Check Response Variable Type And Values + ... ${resp} + ... 404 + ... ProblemDetails + ... title=Not Found + ... status=404 + ... detail=API Invoker ${register_user_info_invoker['api_invoker_id']} has no API Published that accomplish filter conditions + ... cause=No API Published accomplish filter conditions + +Publish API with vendorExt active and discover without supported features filter + [Tags] vendor_extensibility-3 + ${vendor_specific_service_api_key}= Set Variable vendorSpecific-urn:etsi:mec:capifext:service-info + ${vendor_specific_aef_profile_key}= Set Variable vendorSpecific-urn:etsi:mec:capifext:transport-info + # Register APF + ${register_user_info}= Provider Default Registration + + # Create Vendor Specific information + ${vendor_specific_service_api_description}= Create Vendor Specific Service Api Description + ... ${vendor_specific_service_api_key} + ${vendor_specific_aef_profile}= Create Vendor Specific Aef Profile + ... ${vendor_specific_aef_profile_key} + + # Publish one api + ${service_api_description_published} ${resource_url} ${request_body}= Publish Service Api + ... ${register_user_info} + ... supported_features=100 + ... vendor_specific_service_api_description=${vendor_specific_service_api_description} + ... vendor_specific_aef_profile=${vendor_specific_aef_profile} + + Dictionary Should Contain Key ${service_api_description_published} ${vendor_specific_service_api_key} + Dictionary Should Contain Key + ... ${service_api_description_published['aefProfiles'][0]} + ... ${vendor_specific_aef_profile_key} + + # Default Invoker Registration and Onboarding + ${register_user_info_invoker} ${url} ${request_body}= Invoker Default Onboarding + + # Test + ${resp}= Get Request Capif + ... ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}&aef-id=${register_user_info['aef_id']} + ... server=${CAPIF_HTTPS_URL} + ... verify=ca.crt + ... username=${INVOKER_USERNAME} + + Check Response Variable Type And Values ${resp} 200 DiscoveredAPIs + + # Check Results + Dictionary Should Contain Key ${resp.json()} serviceAPIDescriptions + Should Not Be Empty ${resp.json()['serviceAPIDescriptions']} + Length Should Be ${resp.json()['serviceAPIDescriptions']} 1 + Dictionary Should Not Contain Key + ... ${resp.json()['serviceAPIDescriptions'][0]} + ... ${vendor_specific_service_api_key} + Dictionary Should Not Contain Key + ... ${resp.json()['serviceAPIDescriptions'][0]['aefProfiles'][0]} + ... ${vendor_specific_aef_profile_key} + + ${service_api_description_published_to_check}= Copy Dictionary + ... ${service_api_description_published} + ... deepcopy=True + Remove From Dictionary ${service_api_description_published_to_check} ${vendor_specific_service_api_key} + Remove From Dictionary + ... ${service_api_description_published_to_check['aefProfiles'][0]} + ... ${vendor_specific_aef_profile_key} + + List Should Contain Value + ... ${resp.json()['serviceAPIDescriptions']} + ... ${service_api_description_published_to_check} + +Publish API with vendorExt active but without vendorSpecifics + [Tags] vendor_extensibility-4 + # Register APF + ${register_user_info}= Provider Default Registration + + # Publish API with supported features + ${request_body}= Create Service Api Description + ... api_name=service_1 + ... aef_id=${register_user_info['aef_id']} + ... supported_features=100 + ${resp}= Post Request Capif + ... /published-apis/v1/${register_user_info['apf_id']}/service-apis + ... json=${request_body} + ... server=${CAPIF_HTTPS_URL} + ... verify=ca.crt + ... username=${register_user_info['apf_username']} + + Check Response Variable Type And Values + ... ${resp} + ... 400 + ... ProblemDetails + ... title=Bad Request + ... status=400 + ... detail=VendorExt feature active at Supported Features but VendorSpecifics parameters not published + ... cause=VendorExt feature active but vendorSpecifics not present + +Publish API with vendorExt inactive but with vendorSpecifics + [Tags] vendor_extensibility-5 + ${vendor_specific_service_api_key}= Set Variable vendorSpecific-urn:etsi:mec:capifext:service-info + ${vendor_specific_aef_profile_key}= Set Variable vendorSpecific-urn:etsi:mec:capifext:transport-info + # Register APF + ${register_user_info}= Provider Default Registration + + # Create Vendor Specific information + ${vendor_specific_service_api_description}= Create Vendor Specific Service Api Description + ... ${vendor_specific_service_api_key} + ${vendor_specific_aef_profile}= Create Vendor Specific Aef Profile + ... ${vendor_specific_aef_profile_key} + + # Publish API with supported features + ${request_body}= Create Service Api Description + ... api_name=service_1 + ... aef_id=${register_user_info['aef_id']} + ... supported_features=0 + ... vendor_specific_service_api_description=${vendor_specific_service_api_description} + ... vendor_specific_aef_profile=${vendor_specific_aef_profile} + ${resp}= Post Request Capif + ... /published-apis/v1/${register_user_info['apf_id']}/service-apis + ... json=${request_body} + ... server=${CAPIF_HTTPS_URL} + ... verify=ca.crt + ... username=${register_user_info['apf_username']} + + Check Response Variable Type And Values + ... ${resp} + ... 400 + ... ProblemDetails + ... title=Bad Request + ... status=400 + ... detail=VendorExt feature inactive at Supported Features but VendorSpecifics are present parameters published + ... cause=VendorExt feature inactive but vendorSpecifics present + +Published API without vendor extensibility discover with VendSpecQueryParams enabled + [Tags] vendor_extensibility-6 + # Register APF + ${register_user_info}= Provider Default Registration + + # Publish one api + ${service_api_description_published} ${resource_url} ${request_body}= Publish Service Api + ... ${register_user_info} + ... supported_features=000 + + # Default Invoker Registration and Onboarding + ${register_user_info_invoker} ${url} ${request_body}= Invoker Default Onboarding + + # Test + ${resp}= Get Request Capif + ... ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}&aef-id=${register_user_info['aef_id']}&supported_features=2 + ... server=${CAPIF_HTTPS_URL} + ... verify=ca.crt + ... username=${INVOKER_USERNAME} + + Check Response Variable Type And Values + ... ${resp} + ... 404 + ... ProblemDetails + ... title=Not Found + ... status=404 + ... detail=API Invoker ${register_user_info_invoker['api_invoker_id']} has no API Published that accomplish filter conditions + ... cause=No API Published accomplish filter conditions + +Published API without vendor extensibility and discover with vendSpecQueryParams disabled + [Tags] vendor_extensibility-7 + # Register APF + ${register_user_info}= Provider Default Registration + + # Publish one api + ${service_api_description_published} ${resource_url} ${request_body}= Publish Service Api + ... ${register_user_info} + ... supported_features=00 + + # Default Invoker Registration and Onboarding + ${register_user_info_invoker} ${url} ${request_body}= Invoker Default Onboarding + + # Test + ${resp}= Get Request Capif + ... ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}&aef-id=${register_user_info['aef_id']}&supported_features=0 + ... server=${CAPIF_HTTPS_URL} + ... verify=ca.crt + ... username=${INVOKER_USERNAME} + + Check Response Variable Type And Values ${resp} 200 DiscoveredAPIs + + # Check Results + Dictionary Should Contain Key ${resp.json()} serviceAPIDescriptions + Should Not Be Empty ${resp.json()['serviceAPIDescriptions']} + Length Should Be ${resp.json()['serviceAPIDescriptions']} 1 + List Should Contain Value ${resp.json()['serviceAPIDescriptions']} ${service_api_description_published} + +Published API without vendor extensibility and discover without supported-features query parameter + [Tags] vendor_extensibility-8 + # Register APF + ${register_user_info}= Provider Default Registration + + # Publish one api + ${service_api_description_published} ${resource_url} ${request_body}= Publish Service Api + ... ${register_user_info} + ... supported_features=00 + + # Default Invoker Registration and Onboarding + ${register_user_info_invoker} ${url} ${request_body}= Invoker Default Onboarding + + # Test + ${resp}= Get Request Capif + ... ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}&aef-id=${register_user_info['aef_id']} + ... server=${CAPIF_HTTPS_URL} + ... verify=ca.crt + ... username=${INVOKER_USERNAME} + + Check Response Variable Type And Values ${resp} 200 DiscoveredAPIs + + # Check Results + Dictionary Should Contain Key ${resp.json()} serviceAPIDescriptions + Should Not Be Empty ${resp.json()['serviceAPIDescriptions']} + Length Should Be ${resp.json()['serviceAPIDescriptions']} 1 + List Should Contain Value ${resp.json()['serviceAPIDescriptions']} ${service_api_description_published} + +Publish API without supportedFeatures + [Tags] vendor_extensibility-9 + # Register APF + ${register_user_info}= Provider Default Registration + + # Publish API without supported features + ${request_body}= Create Service Api Description + ... api_name=service_1 + ... aef_id=${register_user_info['aef_id']} + ... supported_features=${NONE} + ${resp}= Post Request Capif + ... /published-apis/v1/${register_user_info['apf_id']}/service-apis + ... json=${request_body} + ... server=${CAPIF_HTTPS_URL} + ... verify=ca.crt + ... username=${register_user_info['apf_username']} + + Check Response Variable Type And Values + ... ${resp} + ... 400 + ... ProblemDetails + ... title=Bad Request + ... status=400 + ... detail=supportedFeatures must be present in this request + ... cause=supportedFeatures missed diff --git a/tests/libraries/api_publish_service/bodyRequests.py b/tests/libraries/api_publish_service/bodyRequests.py index 69e7bb117f01b4c53ee7d1db74b7da09e20bf3a1..ddf25ff42bf96dbb5a3ddbfea827d2d731b1c32f 100644 --- a/tests/libraries/api_publish_service/bodyRequests.py +++ b/tests/libraries/api_publish_service/bodyRequests.py @@ -1,5 +1,5 @@ -def create_service_api_description(api_name="service_1",aef_id="aef_id"): - return { +def create_service_api_description(api_name="service_1", aef_id="aef_id", supported_features="0", vendor_specific_service_api_description=None, vendor_specific_aef_profile=None): + body = { "apiName": api_name, "aefProfiles": [ { @@ -35,7 +35,6 @@ def create_service_api_description(api_name="service_1",aef_id="aef_id"): } ], "description": "ROBOT_TESTING", - "supportedFeatures": "fffff", "shareableInfo": { "isShareable": True, "capifProvDoms": [ @@ -51,3 +50,16 @@ def create_service_api_description(api_name="service_1",aef_id="aef_id"): }, "ccfId": "string" } + + if vendor_specific_service_api_description is not None: + if isinstance(vendor_specific_service_api_description, dict): + for key, value in vendor_specific_service_api_description.items(): + body[key] = value + if vendor_specific_aef_profile is not None: + if isinstance(vendor_specific_aef_profile, dict): + for key, value in vendor_specific_aef_profile.items(): + body["aefProfiles"][0][key] = value + if supported_features is not None: + body['supportedFeatures'] = supported_features + + return body diff --git a/tests/libraries/bodyRequests.py b/tests/libraries/bodyRequests.py index b458689720ee3fa5a1d981a9bd9cd7dca445774b..450ca5ae2a24503e07a8fe436bf79c46e2796be5 100644 --- a/tests/libraries/bodyRequests.py +++ b/tests/libraries/bodyRequests.py @@ -5,4 +5,5 @@ from api_publish_service.bodyRequests import * from api_events.bodyRequests import * from security_api.bodyRequests import * from api_provider_management.bodyRequests import * +from vendor_extensibility.bodyRequests import * from vault_requests.bodyRequests import * diff --git a/tests/libraries/common/bodyRequests.py b/tests/libraries/common/bodyRequests.py index c1c3061ab7b9455bbb3d99fb6a403996206b9026..e87f3492a711b922d776459f10667ea27d91c80b 100644 --- a/tests/libraries/common/bodyRequests.py +++ b/tests/libraries/common/bodyRequests.py @@ -31,7 +31,7 @@ def check_variable(input, data_type): else: raise Exception("variable is not integer type") elif data_type == "URI": - check_uri(input,data_type) + check_uri(input, data_type) return True elif data_type == "URI_reference": check_uri(input, data_type) @@ -69,13 +69,29 @@ def check_variable(input, data_type): def check_attributes_dict(body, data_type): mandatory_attributes = capif_types[data_type]["mandatory_attributes"] optional_parameters = capif_types[data_type]["optional_attributes"] + regex_attributes = capif_types[data_type].get("regex_attributes",{}) + all_attributes = mandatory_attributes | optional_parameters # Check if body has not allowed attributes for body_key in body.keys(): + print(body_key) if body_key not in all_attributes.keys(): - raise Exception('Attribute "' + body_key + - '" is not present as a mandatory or optional key (' + ','.join(all_attributes.keys()) + ')') + print(body_key + " NOT IN ALL ATTRIBUTES") + present = False + if regex_attributes is not None: + print("REGEX ATTRIBUTES PRESENT") + print(regex_attributes) + for regex_key, regex_data_type in regex_attributes.items(): + print(regex_key + ":" + regex_data_type) + if check_regex(body_key, regex_key): + print("MATCH with " + body_key) + present = True + all_attributes[body_key] = regex_data_type + break + if not present: + raise Exception('Attribute "' + body_key + + '" is not present as a mandatory or optional key (' + ','.join(all_attributes.keys()) + ')') if mandatory_attributes: for mandatory_key in mandatory_attributes.keys(): @@ -109,7 +125,7 @@ def sign_csr_body(username, public_key): return data -def check_uri(input,rule): +def check_uri(input, rule): if rfc3987.match(input, rule=rule) is not None: return input else: @@ -121,6 +137,7 @@ def check_regex(input, regex): is_match = bool(matched) if is_match: print("Regex match") + return True else: raise Exception("Input(" + input + ") not match regex (" + regex + ")") diff --git a/tests/libraries/common/types.json b/tests/libraries/common/types.json index 220dd0f5710796fd875ddda8d05dfb3e39a272cd..f2f0ff8a3bd857048cab718aa63531a6e07c7d76 100644 --- a/tests/libraries/common/types.json +++ b/tests/libraries/common/types.json @@ -83,8 +83,14 @@ "apiSuppFeats": "SupportedFeatures", "pubApiPath": "PublishedApiPath", "ccfId": "string" + }, + "regex_attributes": { + "^vendorSpecific-(.*)": "VendorSpecificObject" } }, + "VendorSpecificObject": { + "Check": false + }, "AefProfile": { "mandatory_attributes": { "aefId": "string", @@ -98,6 +104,9 @@ "interfaceDescriptions": "InterfaceDescription", "aefLocation": "AefLocation" }, + "regex_attributes": { + "^vendorSpecific-(.*)": "VendorSpecificObject" + }, "oneOf": ["interfaceDescriptions", "domainName"] }, "Version": { diff --git a/tests/libraries/vault_requests/bodyRequests.py b/tests/libraries/vault_requests/bodyRequests.py new file mode 100644 index 0000000000000000000000000000000000000000..3bade1ab11ba20d3faa4b30bcc4600814dd8fb90 --- /dev/null +++ b/tests/libraries/vault_requests/bodyRequests.py @@ -0,0 +1,17 @@ +def sign_csr_body(username, public_key): + data = { + "csr": public_key.decode("utf-8"), + "mode": "client", + "filename": username + } + return data + + +def vault_sign_superadmin_certificate_body(csr_request): + data = { + "format": "pem_bundle", + "ttl": "43000h", + "csr": csr_request.decode("utf-8"), + "common_name": "superadmin" + } + return data diff --git a/tests/libraries/vendor_extensibility/bodyRequests.py b/tests/libraries/vendor_extensibility/bodyRequests.py new file mode 100644 index 0000000000000000000000000000000000000000..0e4e5bc6983e8b6c5dbf9968559d135f13ec3a3a --- /dev/null +++ b/tests/libraries/vendor_extensibility/bodyRequests.py @@ -0,0 +1,34 @@ +def create_vendor_specific_service_api_description(vendor_specific_key): + vendor_dict = { + vendor_specific_key: { + "serializer": "JSON", + "state": "ACTIVE", + "scopeOfLocality": "MEC_SYSTEM", + "consumedLocalOnly": "True", + "isLocal": "True", + "category": { + "href": "https://www.location.com", + "id": "location_1", + "name": "Location", + "version": "1.0" + } + } + } + return vendor_dict + + +def create_vendor_specific_aef_profile(vendor_specific_key): + vendor_dict = { + vendor_specific_key: { + "name": "trasport1", + "description": "Transport Info 1", + "type": "REST_HTTP", + "protocol": "HTTP", + "version": "2", + "security": { + "grantTypes": "OAUTH2_CLIENT_CREDENTIALS", + "tokenEndpoint": "https://token-endpoint/" + } + } + } + return vendor_dict diff --git a/tests/resources/common/basicRequests.robot b/tests/resources/common/basicRequests.robot index f9c1139dfe3dbf9e27c3023dafe810ad70a33a8e..1f69f48fdb91d2c1668024cddb7564a936c2d3aa 100644 --- a/tests/resources/common/basicRequests.robot +++ b/tests/resources/common/basicRequests.robot @@ -533,8 +533,7 @@ Delete User At Register Should Be Equal As Strings ${resp.status_code} 204 -q - IF ${environment_users} + IF ${environment_users} Call Method ${CAPIF_USERS} remove_register_users_entry ${user_uuid} END @@ -793,6 +792,9 @@ Publish Service Api ... ${service_name}=service_1 ... ${apf_id}=${NONE} ... ${apf_username}=${NONE} + ... ${supported_features}=0 + ... ${vendor_specific_service_api_description}=${None} + ... ${vendor_specific_aef_profile}=${None} ${apf_id_to_use}= Set Variable ${register_user_info_provider['apf_id']} ${apf_username_to_use}= Set Variable ${register_user_info_provider['apf_username']} @@ -809,7 +811,7 @@ Publish Service Api ${apf_username_to_use}= Set Variable ${apf_username} END - ${request_body}= Create Service Api Description ${service_name} ${register_user_info_provider['aef_id']} + ${request_body}= Create Service Api Description ${service_name} ${register_user_info_provider['aef_id']} ${supported_features} ${vendor_specific_service_api_description} ${vendor_specific_aef_profile} ${resp}= Post Request Capif ... /published-apis/v1/${apf_id_to_use}/service-apis ... json=${request_body}