diff --git a/README.md b/README.md index e14b5ae8ff7e65b81f35ea471e26a15481fefcdf..e471a85673d3a8b7ec45ab3da263ee8267d1edf7 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,9 @@ test launch command followed by the file name. > > .venv\scripts\deactivate.bat > ``` +### Specific test requirements +- Mqtt tests (058) launch a mosquitto container with docker, thus it requires docker to be installed and running + ## Test Suite Management (tsm) The `tsm` script is designed to facilitate the selection and execution of the Test Suite, especially if not all the @@ -352,7 +355,7 @@ In these cases, it is needed to provide the corresponding information in the Pyt in `self.description` to reference the method that pretty print the operation, and add the method that pretty prints the operation) - When a new permutation is added in an existing Test Case, run the documentation generation script - (`python doc/generateDocumentationData.py {tc_id}`) for the Test Case and copy the generated JSON file in the + (`python doc/analysis/generateDocumentationData.py {tc_id}`) for the Test Case and copy the generated JSON file in the folder containing all files for the given group and subgroup (`cp doc/results/{tc_id}.json doc/files/{group}/{subgroup}`) - When a new directory containing Test Cases is created, it has to be declared in `doc/generaterobotdata.py` along with its acronym diff --git a/TP/NGSI-LD/ContextInformation/Subscription/SubscriptionNotificationBehaviour/MQTT/058_01.robot b/TP/NGSI-LD/ContextInformation/Subscription/SubscriptionNotificationBehaviour/MQTT/058_01.robot new file mode 100644 index 0000000000000000000000000000000000000000..93b3d1825a0d469a69066d711b4ab8288bfe6526 --- /dev/null +++ b/TP/NGSI-LD/ContextInformation/Subscription/SubscriptionNotificationBehaviour/MQTT/058_01.robot @@ -0,0 +1,89 @@ +*** Settings *** +Documentation Check that the Mqtt Notification is received with different userInfo and port + +Resource ${EXECDIR}/resources/ApiUtils/ContextInformationSubscription.resource +Resource ${EXECDIR}/resources/ApiUtils/ContextInformationProvision.resource +Resource ${EXECDIR}/resources/AssertionUtils.resource +Resource ${EXECDIR}/resources/JsonUtils.resource +Resource ${EXECDIR}/resources/NotificationUtils.resource +Resource ${EXECDIR}/resources/mqttUtils/MqttUtils.resource + +Test Teardown After Test +Test Template Receive MQTT Notification + + +*** Variables *** +${subscription_id_prefix} urn:ngsi-ld:Subscription: +${subscription_payload_file_path} subscriptions/subscription-building-entities-default.jsonld +${building_id_prefix} urn:ngsi-ld:Building: +${entity_building_filepath} building-simple-attributes-sample.jsonld +${fragment_filename} airQualityLevel-fragment.jsonld +${topic} ngsild-test-suite/topic + + +*** Test Cases *** +058_01_01 Without User And Port + [Tags] sub-mqtt-notification 5_8_6 + mosquitto.conf mqtt://127.0.0.1/${topic} +058_01_02 With Non Default Port + [Tags] sub-mqtt-notification 5_8_6 + mosquitto.conf mqtt://127.0.0.1:2883/${topic} port=2883 +058_01_03 With User + [Tags] sub-mqtt-notification 5_8_6 + mosquitto.conf mqtt://user@127.0.0.1/${topic} +058_01_04 With User And Password + [Tags] sub-mqtt-notification 5_8_6 + mosquitto_with_user.conf mqtt://user_with_password:password@127.0.0.1/${topic} username=user_with_password password=password +058_01_05 With User Password And Non Default Port + [Tags] sub-mqtt-notification 5_8_6 + mosquitto_with_user.conf mqtt://user_with_password:password@127.0.0.1:2883/${topic} username=user_with_password password=password port=2883 + + +*** Keywords *** +Receive MQTT Notification + [Documentation] Check that the broker uses the authentication information from the endpoint url + [Arguments] ${config_filename} ${endpoint_uri} ${port}=1883 ${username}=${None} ${password}=${None} + + Start Mqtt Server ${config_filename} ${port} + Setup Mqtt Subscription ${endpoint_uri} + + Set Username And Password ${username} ${password} + Connect 127.0.0.1 ${port} + Subscribe topic=${topic} qos=1 + + ${response}= Update Entity Attributes ${entity_id} ${fragment_filename} ${CONTENT_TYPE_LD_JSON} + ${listenMessages}= Listen ${topic} + Check Messages Contain One Instance ${listenMessages} + +After Test + Delete Initial Subscriptions + Delete Initial Entity + Stop Mqtt Server + Disconnect + +Setup Mqtt Subscription + [Arguments] ${endpoint_uri} + ${subscription_id}= Generate Random Entity Id ${subscription_id_prefix} + ${entity_id}= Generate Random Entity Id ${building_id_prefix} + + ${subscription_payload}= Load Subscription Sample With Reachable Endpoint + ... ${subscription_payload_file_path} + ... ${subscription_id} + ... ${endpoint_uri} + ${subscription_payload}= Set Entity Id In Subscription ${subscription_payload} ${entity_id} + + Set Suite Variable ${subscription_id} + Set Suite Variable ${entity_id} + + ${response}= Create Entity ${entity_building_filepath} ${entity_id} + Check Response Status Code 201 ${response.status_code} + Sleep 1s + ${response}= Create Subscription From Subscription Payload ${subscription_payload} ${CONTENT_TYPE_LD_JSON} + Check Response Status Code 201 ${response.status_code} + Sleep 1s + +Delete Initial Subscriptions + Delete Subscription ${subscription_id} + +Delete Initial Entity + Delete Entity by Id ${entity_id} diff --git a/TP/NGSI-LD/ContextInformation/Subscription/SubscriptionNotificationBehaviour/MQTT/058_02.robot b/TP/NGSI-LD/ContextInformation/Subscription/SubscriptionNotificationBehaviour/MQTT/058_02.robot new file mode 100644 index 0000000000000000000000000000000000000000..3f985a6930537b0a3d8032378b01813fd241535a --- /dev/null +++ b/TP/NGSI-LD/ContextInformation/Subscription/SubscriptionNotificationBehaviour/MQTT/058_02.robot @@ -0,0 +1,98 @@ +*** Settings *** +Documentation Check that the mqtt notification is received with different qos + +Resource ${EXECDIR}/resources/ApiUtils/ContextInformationSubscription.resource +Resource ${EXECDIR}/resources/ApiUtils/ContextInformationProvision.resource +Resource ${EXECDIR}/resources/AssertionUtils.resource +Resource ${EXECDIR}/resources/JsonUtils.resource +Resource ${EXECDIR}/resources/NotificationUtils.resource +Resource ${EXECDIR}/resources/mqttUtils/MqttUtils.resource + +Test Setup Start Mqtt Server And Connect +Test Teardown After Test +Test Template Receive MQTT Notification + + +*** Variables *** +${subscription_id_prefix} urn:ngsi-ld:Subscription: +${subscription_payload_file_path} subscriptions/subscription-building-entities-default.jsonld +${building_id_prefix} urn:ngsi-ld:Building: +${entity_building_filepath} building-simple-attributes-sample.jsonld +${fragment_filename} airQualityLevel-fragment.jsonld +${topic} ngsild-test-suite/topic +${endpoint} mqtt://127.0.0.1/${topic} +${config_filename} mosquitto.conf + + +*** Test Cases *** +058_02_01 With Default QoS + [Tags] sub-mqtt-notification 5_8_6 + qos=${None} +058_02_02 With QoS 1 + [Tags] sub-mqtt-notification 5_8_6 + qos=1 +058_02_03 With QoS 2 + [Tags] sub-mqtt-notification 5_8_6 + qos=2 + + +*** Keywords *** +Receive MQTT Notification + [Documentation] Check that the broker supports different quality of service (qos) + [Arguments] ${qos} + + Setup Mqtt Subscription ${endpoint} qos=${qos} + ${response}= Update Entity Attributes ${entity_id} ${fragment_filename} ${CONTENT_TYPE_LD_JSON} + + ${listenMessages}= Listen ${topic} + Check Messages Contain One Instance ${listenMessages} + +Start Mqtt Server And Connect + Start Mqtt Server ${config_filename} 1883 + Connect 127.0.0.1 1883 + Subscribe topic=${topic} qos=1 + +After Test + Delete Initial Subscriptions + Delete Initial Entity + Stop Mqtt Server + Disconnect + +Setup Mqtt Subscription + [Arguments] ${endpoint_uri} ${qos}=${None} + ${subscription_id}= Generate Random Entity Id ${subscription_id_prefix} + ${entity_id}= Generate Random Entity Id ${building_id_prefix} + + ${subscription_payload}= Load Subscription Sample With Reachable Endpoint + ... ${subscription_payload_file_path} + ... ${subscription_id} + ... ${endpoint_uri} + ${subscription_payload}= Set Entity Id In Subscription ${subscription_payload} ${entity_id} + IF ${qos} != ${None} + ${notifierInfo}= Create Dictionary + Set To Dictionary ${notifierInfo} key MQTT-QoS + Set To Dictionary ${notifierInfo} value ${qos} + ${notifierInfo}= Create List ${notifierInfo} + ${subscription_payload}= Add Object To Json + ... ${subscription_payload} + ... $.notification.endpoint.notifierInfo + ... ${notifierInfo} + END + + Set Suite Variable ${subscription_id} + Set Suite Variable ${entity_id} + + ${response}= Create Entity ${entity_building_filepath} ${entity_id} + Check Response Status Code 201 ${response.status_code} + + Sleep 1s + ${response}= Create Subscription From Subscription Payload ${subscription_payload} ${CONTENT_TYPE_LD_JSON} + Check Response Status Code 201 ${response.status_code} + + Sleep 1s + +Delete Initial Subscriptions + Delete Subscription ${subscription_id} + +Delete Initial Entity + Delete Entity by Id ${entity_id} diff --git a/TP/NGSI-LD/ContextInformation/Subscription/SubscriptionNotificationBehaviour/MQTT/058_03.robot b/TP/NGSI-LD/ContextInformation/Subscription/SubscriptionNotificationBehaviour/MQTT/058_03.robot new file mode 100644 index 0000000000000000000000000000000000000000..863e95341626179ab26fb8bb22ea493360bd65f1 --- /dev/null +++ b/TP/NGSI-LD/ContextInformation/Subscription/SubscriptionNotificationBehaviour/MQTT/058_03.robot @@ -0,0 +1,98 @@ +*** Settings *** +Documentation Check that mqtt notification is received with different mqtt version + +Resource ${EXECDIR}/resources/ApiUtils/ContextInformationSubscription.resource +Resource ${EXECDIR}/resources/ApiUtils/ContextInformationProvision.resource +Resource ${EXECDIR}/resources/AssertionUtils.resource +Resource ${EXECDIR}/resources/JsonUtils.resource +Resource ${EXECDIR}/resources/NotificationUtils.resource +Resource ${EXECDIR}/resources/mqttUtils/MqttUtils.resource + +Test Setup Start Mqtt Server And Connect +Test Teardown After Test +Test Template Receive Mqtt Notification + + +*** Variables *** +${subscription_id_prefix} urn:ngsi-ld:Subscription: +${subscription_payload_file_path} subscriptions/subscription-building-entities-default.jsonld +${building_id_prefix} urn:ngsi-ld:Building: +${entity_building_filepath} building-simple-attributes-sample.jsonld +${fragment_filename} airQualityLevel-fragment.jsonld +${topic} ngsild-test-suite/topic +${endpoint} mqtt://127.0.0.1/${topic} +${config_filename} mosquitto.conf + + +*** Test Cases *** +058_03_01 With Default Protocol + [Tags] sub-mqtt-notification 5_8_6 + version=${None} +058_03_02 With MQTT 3.1.1 Protocol + [Tags] sub-mqtt-notification 5_8_6 + version=mqtt3.1.1 +058_03_03 With MQTT 5.0 Protocol + [Tags] sub-mqtt-notification 5_8_6 + version=mqtt5.0 + + +*** Keywords *** +Receive Mqtt Notification + [Documentation] Check that the broker support different mqtt version + [Arguments] ${version} + + Setup Mqtt Subscription ${endpoint} ${version} + Subscribe topic=${topic} qos=1 + + ${response}= Update Entity Attributes ${entity_id} ${fragment_filename} ${CONTENT_TYPE_LD_JSON} + + ${listenMessages}= Listen ${topic} + Check Messages Contain One Instance ${listenMessages} + +Start Mqtt Server And Connect + Start Mqtt Server ${config_filename} 1883 + Connect 127.0.0.1 1883 + Subscribe topic=${topic} qos=1 + +After Test + Delete Initial Subscriptions + Delete Initial Entity + Stop Mqtt Server + Disconnect + +Setup Mqtt Subscription + [Arguments] ${endpoint_uri} ${version}=${None} + ${subscription_id}= Generate Random Entity Id ${subscription_id_prefix} + ${entity_id}= Generate Random Entity Id ${building_id_prefix} + + ${subscription_payload}= Load Subscription Sample With Reachable Endpoint + ... ${subscription_payload_file_path} + ... ${subscription_id} + ... ${endpoint_uri} + ${subscription_payload}= Set Entity Id In Subscription ${subscription_payload} ${entity_id} + ${notifierInfo}= Create Dictionary + IF $version != $None + Set To Dictionary ${notifierInfo} key MQTT-Version + Set To Dictionary ${notifierInfo} value ${version} + ${notifierInfo}= Create List ${notifierInfo} + ${subscription_payload}= Add Object To Json + ... ${subscription_payload} + ... $.notification.endpoint.notifierInfo + ... ${notifierInfo} + END + Set Suite Variable ${subscription_id} + Set Suite Variable ${entity_id} + + ${response}= Create Entity ${entity_building_filepath} ${entity_id} + Check Response Status Code 201 ${response.status_code} + Sleep 1s + + ${response}= Create Subscription From Subscription Payload ${subscription_payload} ${CONTENT_TYPE_LD_JSON} + Check Response Status Code 201 ${response.status_code} + Sleep 1s + +Delete Initial Subscriptions + Delete Subscription ${subscription_id} + +Delete Initial Entity + Delete Entity by Id ${entity_id} diff --git a/TP/NGSI-LD/ContextInformation/Subscription/SubscriptionNotificationBehaviour/MQTT/058_04.robot b/TP/NGSI-LD/ContextInformation/Subscription/SubscriptionNotificationBehaviour/MQTT/058_04.robot new file mode 100644 index 0000000000000000000000000000000000000000..e45aca73109a54c6d6ec1aa3eded1be4efaf2eca --- /dev/null +++ b/TP/NGSI-LD/ContextInformation/Subscription/SubscriptionNotificationBehaviour/MQTT/058_04.robot @@ -0,0 +1,101 @@ +*** Settings *** +Documentation Check that the mqtt notification payload is well formed + +Resource ${EXECDIR}/resources/ApiUtils/ContextInformationSubscription.resource +Resource ${EXECDIR}/resources/ApiUtils/ContextInformationProvision.resource +Resource ${EXECDIR}/resources/AssertionUtils.resource +Resource ${EXECDIR}/resources/JsonUtils.resource +Resource ${EXECDIR}/resources/NotificationUtils.resource +Resource ${EXECDIR}/resources/mqttUtils/MqttUtils.resource + +Test Setup Start Mqtt Server And Connect +Test Teardown After Test +Test Template Receive Mqtt Notification + + +*** Variables *** +${subscription_id_prefix} urn:ngsi-ld:Subscription: +${subscription_payload_file_path} subscriptions/subscription-building-entities-default.jsonld +${building_id_prefix} urn:ngsi-ld:Building: +${entity_building_filepath} building-simple-attributes-sample.jsonld +${fragment_filename} airQualityLevel-fragment.jsonld +${topic} ngsild-test-suite/topic +${endpoint} mqtt://127.0.0.1/${topic} +${config_filename} mosquitto.conf + + +*** Test Cases *** +058_04_01 Basic Subscription + [Tags] sub-mqtt-notification 5_8_6 + ${EMPTY} + + +*** Keywords *** +Receive Mqtt Notification + [Documentation] Check that the broker send well formed data + [Arguments] ${arg} + + ${response}= Update Entity Attributes ${entity_id} ${fragment_filename} ${CONTENT_TYPE_LD_JSON} + ${listenMessages}= Listen ${topic} + ${firstmessage}= Set Variable ${listenMessages}[0] + ${message}= Convert String To Json ${firstmessage} + + Check Message Contain Key ${message} metadata + Check Message Contain Key ${message} body + Check Message Contain Key ${message}[metadata] Content-Type + Check Message Contain Key ${message}[metadata] Link + Check Message Field Equal ${message}[metadata][test-receiver-key] test-receiver-info + Check Message Field Equal ${message}[body][type] Notification + Check Message Contain Key ${message}[body] data + Check Message Contain Key ${message}[body][data][0] id + Check Message Contain Key ${message}[body][data][0] type + +Start Mqtt Server And Connect + Start Mqtt Server ${config_filename} 1883 + Setup Mqtt Subscription ${endpoint} + + Connect 127.0.0.1 1883 + Subscribe topic=${topic} qos=1 + +After Test + Delete Initial Subscriptions + Delete Initial Entity + Stop Mqtt Server + Disconnect + +Setup Mqtt Subscription + [Arguments] ${endpoint_uri} + ${subscription_id}= Generate Random Entity Id ${subscription_id_prefix} + ${entity_id}= Generate Random Entity Id ${building_id_prefix} + + ${subscription_payload}= Load Subscription Sample With Reachable Endpoint + ... ${subscription_payload_file_path} + ... ${subscription_id} + ... ${endpoint_uri} + ${subscription_payload}= Set Entity Id In Subscription ${subscription_payload} ${entity_id} + + Set Suite Variable ${subscription_id} + + Set Suite Variable ${entity_id} + ${receiverInfo}= Create Dictionary + Set To Dictionary ${receiverInfo} key test-receiver-key + Set To Dictionary ${receiverInfo} value test-receiver-info + ${receiverInfo}= Create List ${receiverInfo} + ${subscription_payload}= Add Object To Json + ... ${subscription_payload} + ... $.notification.endpoint.receiverInfo + ... ${receiverInfo} + + ${response}= Create Entity ${entity_building_filepath} ${entity_id} + Check Response Status Code 201 ${response.status_code} + Sleep 1s + + ${response}= Create Subscription From Subscription Payload ${subscription_payload} ${CONTENT_TYPE_LD_JSON} + Check Response Status Code 201 ${response.status_code} + Sleep 1s + +Delete Initial Subscriptions + Delete Subscription ${subscription_id} + +Delete Initial Entity + Delete Entity by Id ${entity_id} diff --git a/doc/analysis/checks.py b/doc/analysis/checks.py index ec9a873d5bbe93dfcb4852d6ab9c0830a447bf0b..d0b4f7ce4e96dead300c995f3027e74ec316a7e2 100644 --- a/doc/analysis/checks.py +++ b/doc/analysis/checks.py @@ -138,7 +138,13 @@ class Checks: Checks.check_response_headers_link_set_to, 'Check Response Headers Containing NGSILD-Results-Count Equals To' : Checks.check_response_header_contains_ngsild_results_count_equals_to, - } + 'Check Messages Contain One Instance' : + Checks.check_messages_contain_one_instance, + 'Check Message Contain Key': + Checks.check_message_contain_key, + 'Check Message Field Equal': + Checks.check_message_field_equal + } self.args = { 'Check Response Status Code': { @@ -399,6 +405,18 @@ class Checks: 'Check Response Headers Containing NGSILD-Results-Count Equals To': { 'params': ['expected_result_count' , 'response_headers'], 'position': [0, 1] + }, + 'Check Messages Contain One Instance': { + 'params': ['messages'], + 'position': [0] + }, + 'Check Message Contain Key': { + 'params': ['message', 'key'], + 'position': [0,1] + }, + 'Check Message Field Equal': { + 'params': ['expected_field', 'field'], + 'position': [0,1] } } @@ -1106,6 +1124,32 @@ class Checks: else: raise Exception(f"ERROR, Expected 'expected_result_count' but received: '{kwargs}'") + @staticmethod + def check_messages_contain_one_instance(kwargs: list) -> str: + if 'messages' in kwargs: + messages = kwargs['messages'] + return f'Received messages {messages}' + else: + raise Exception(f"ERROR, Expected 1 message but received: '{kwargs}'") + + @staticmethod + def check_message_contain_key(kwargs: list) -> str: + if 'message' in kwargs and 'key' in kwargs: + message = kwargs['message'] + key = kwargs['key'] + return f'Received message {message} with key {key}' + else: + raise Exception(f"ERROR, Expected a message containing the key but received: '{kwargs}'") + + @staticmethod + def check_message_field_equal(kwargs: list) -> str: + if 'expected_field' in kwargs and 'field' in kwargs: + field = kwargs['field'] + expected_field = kwargs['expected_field'] + return f'expected field {expected_field} equals field {field}' + else: + raise Exception(f"ERROR, Expected the field to be equal 'expected_field' but received: '{kwargs}'") + def get_checks(self, **kwargs) -> str: checking = None diff --git a/doc/analysis/generaterobotdata.py b/doc/analysis/generaterobotdata.py index 0c6c7b391435acfe653b92279d36702b13e7cfb2..9b2b7a918134f220671843d57823e097ff44c432 100644 --- a/doc/analysis/generaterobotdata.py +++ b/doc/analysis/generaterobotdata.py @@ -68,6 +68,7 @@ class GenerateRobotData: 'Subscription/RetrieveSubscription': 'SUB', 'Subscription/UpdateSubscription': 'SUB', 'Subscription/SubscriptionNotificationBehaviour': 'SUB', + 'Subscription/SubscriptionNotificationBehaviour/MQTT': 'SUBMQTT', 'Registration/CreateContextSourceRegistration': 'REG', 'Registration/CreateCSRegistration': 'REG', 'Registration/UpdateCSRegistration': 'REG', diff --git a/doc/analysis/initial_setup.py b/doc/analysis/initial_setup.py index 3dd79db0500434ee8b582e9b9fd5ed06bd5c7429..d249a4fdc07de7cc02ddc64cca69debd6929d949 100644 --- a/doc/analysis/initial_setup.py +++ b/doc/analysis/initial_setup.py @@ -21,6 +21,7 @@ class InitialSetup: 'Create Id': InitialSetup.init_temporal_entity2(), 'Create Initial Subscription': InitialSetup.init_subscription(), 'Setup Initial Subscriptions': InitialSetup.init_subscription(), + 'Start Mqtt Server And Connect': InitialSetup.init_mqtt_subscription(), 'Setup Initial Entities': InitialSetup.init_entities(), 'Setup Initial Temporal Entities': InitialSetup.init_temporal_entities(), 'Create Initial Context Source Registration and Context Source Registration Subscription': @@ -108,6 +109,17 @@ class InitialSetup: }''' return data + @staticmethod + def init_mqtt_subscription() -> str: + data = '''with + the SUT being in the "initial state" and + the SUT containing an initial Subscription ${subscription} + with an id set to ${subscription_id} + and an notification endpoint set to a mqtt broker +}''' + return data + + @staticmethod def init_entities() -> str: data = '''with { diff --git a/doc/files/ContextInformation/Subscription/058_01.json b/doc/files/ContextInformation/Subscription/058_01.json new file mode 100644 index 0000000000000000000000000000000000000000..2eee94633ea94fd0a60eed7c39437169e022592a --- /dev/null +++ b/doc/files/ContextInformation/Subscription/058_01.json @@ -0,0 +1,105 @@ +{ + "tp_id": "TP/NGSI-LD/CI/SUB/MQTT/058_01", + "test_objective": "Check that the Mqtt Notification is received with different userInfo and port", + "reference": "ETSI GS CIM 009 V1.3.1 [], clause 5.8.6", + "config_id": "", + "parent_release": "v1.3.1", + "clauses": [ + "5.8.6" + ], + "pics_selection": "", + "keywords": [ + "Receive MQTT Notification", + "After Test", + "Setup Mqtt Subscription", + "Delete Initial Subscriptions", + "Delete Initial Entity" + ], + "teardown": "None", + "initial_condition": "with {\n the SUT containing an initial state\n}", + "test_cases": [ + { + "name": "058_01_01 Without User And Port", + "permutation_tp_id": "TP/NGSI-LD/CI/SUB/MQTT/058_01_01", + "doc": "Check that the broker uses the authentication information from the endpoint url", + "tags": [ + "5_8_6", + "sub-mqtt-notification" + ], + "setup": null, + "teardown": "After Test", + "template": "Receive MQTT Notification", + "then": "then {\n the SUT sends a valid Response for the operation:\n Notification with Received messages ${listenMessages}\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entities/{entityId}/attrs/{attributeId}'\n method set to 'PATCH'\n Update Entity Attributes and\n Query Parameter: id set to '${entity_id}' and\n Query Parameter: fragment_filename set to '${fragment_filename}' and\n Query Parameter: content_type set to 'application/ld+json'\n}", + "http_verb": "PATCH", + "endpoint": "entities/{entityId}/attrs/{attributeId}" + }, + { + "name": "058_01_02 With Non Default Port", + "permutation_tp_id": "TP/NGSI-LD/CI/SUB/MQTT/058_01_02", + "doc": "Check that the broker uses the authentication information from the endpoint url", + "tags": [ + "5_8_6", + "sub-mqtt-notification" + ], + "setup": null, + "teardown": "After Test", + "template": "Receive MQTT Notification", + "then": "then {\n the SUT sends a valid Response for the operation:\n Notification with Received messages ${listenMessages}\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entities/{entityId}/attrs/{attributeId}'\n method set to 'PATCH'\n Update Entity Attributes and\n Query Parameter: id set to '${entity_id}' and\n Query Parameter: fragment_filename set to '${fragment_filename}' and\n Query Parameter: content_type set to 'application/ld+json'\n}", + "http_verb": "PATCH", + "endpoint": "entities/{entityId}/attrs/{attributeId}" + }, + { + "name": "058_01_03 With User", + "permutation_tp_id": "TP/NGSI-LD/CI/SUB/MQTT/058_01_03", + "doc": "Check that the broker uses the authentication information from the endpoint url", + "tags": [ + "5_8_6", + "sub-mqtt-notification" + ], + "setup": null, + "teardown": "After Test", + "template": "Receive MQTT Notification", + "then": "then {\n the SUT sends a valid Response for the operation:\n Notification with Received messages ${listenMessages}\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entities/{entityId}/attrs/{attributeId}'\n method set to 'PATCH'\n Update Entity Attributes and\n Query Parameter: id set to '${entity_id}' and\n Query Parameter: fragment_filename set to '${fragment_filename}' and\n Query Parameter: content_type set to 'application/ld+json'\n}", + "http_verb": "PATCH", + "endpoint": "entities/{entityId}/attrs/{attributeId}" + }, + { + "name": "058_01_04 With User And Password", + "permutation_tp_id": "TP/NGSI-LD/CI/SUB/MQTT/058_01_04", + "doc": "Check that the broker uses the authentication information from the endpoint url", + "tags": [ + "5_8_6", + "sub-mqtt-notification" + ], + "setup": null, + "teardown": "After Test", + "template": "Receive MQTT Notification", + "then": "then {\n the SUT sends a valid Response for the operation:\n Notification with Received messages ${listenMessages}\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entities/{entityId}/attrs/{attributeId}'\n method set to 'PATCH'\n Update Entity Attributes and\n Query Parameter: id set to '${entity_id}' and\n Query Parameter: fragment_filename set to '${fragment_filename}' and\n Query Parameter: content_type set to 'application/ld+json'\n}", + "http_verb": "PATCH", + "endpoint": "entities/{entityId}/attrs/{attributeId}" + }, + { + "name": "058_01_05 With User Password And Non Default Port", + "permutation_tp_id": "TP/NGSI-LD/CI/SUB/MQTT/058_01_05", + "doc": "Check that the broker uses the authentication information from the endpoint url", + "tags": [ + "5_8_6", + "sub-mqtt-notification" + ], + "setup": null, + "teardown": "After Test", + "template": "Receive MQTT Notification", + "then": "then {\n the SUT sends a valid Response for the operation:\n Notification with Received messages ${listenMessages}\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entities/{entityId}/attrs/{attributeId}'\n method set to 'PATCH'\n Update Entity Attributes and\n Query Parameter: id set to '${entity_id}' and\n Query Parameter: fragment_filename set to '${fragment_filename}' and\n Query Parameter: content_type set to 'application/ld+json'\n}", + "http_verb": "PATCH", + "endpoint": "entities/{entityId}/attrs/{attributeId}" + } + ], + "permutations": [], + "robotpath": "ContextInformation/Subscription/SubscriptionNotificationBehaviour/MQTT", + "robotfile": "058_01" +} \ No newline at end of file diff --git a/doc/files/ContextInformation/Subscription/058_02.json b/doc/files/ContextInformation/Subscription/058_02.json new file mode 100644 index 0000000000000000000000000000000000000000..87e91aa1b61739c0db66d8f0c34e332f94a7691d --- /dev/null +++ b/doc/files/ContextInformation/Subscription/058_02.json @@ -0,0 +1,74 @@ +{ + "tp_id": "TP/NGSI-LD/CI/SUB/MQTT/058_02", + "test_objective": "Check that the mqtt notification is received with different qos", + "reference": "ETSI GS CIM 009 V1.3.1 [], clause 5.8.6", + "config_id": "", + "parent_release": "v1.3.1", + "clauses": [ + "5.8.6" + ], + "pics_selection": "", + "keywords": [ + "Receive MQTT Notification", + "Start Mqtt Server And Connect", + "After Test", + "Setup Mqtt Subscription", + "Delete Initial Subscriptions", + "Delete Initial Entity" + ], + "teardown": "None", + "initial_condition": "with \n the SUT being in the \"initial state\" and\n the SUT containing an initial Subscription ${subscription} \n with an id set to ${subscription_id}\n and an notification endpoint set to a mqtt broker\n}", + "test_cases": [ + { + "name": "058_02_01 With Default QoS", + "permutation_tp_id": "TP/NGSI-LD/CI/SUB/MQTT/058_02_01", + "doc": "Check that the broker supports different quality of service (qos)", + "tags": [ + "5_8_6", + "sub-mqtt-notification" + ], + "setup": "Start Mqtt Server And Connect", + "teardown": "After Test", + "template": "Receive MQTT Notification", + "then": "then {\n the SUT sends a valid Response for the operation:\n Notification with Received messages ${listenMessages}\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entities/{entityId}/attrs/{attributeId}'\n method set to 'PATCH'\n Update Entity Attributes and\n Query Parameter: id set to '${entity_id}' and\n Query Parameter: fragment_filename set to '${fragment_filename}' and\n Query Parameter: content_type set to 'application/ld+json'\n}", + "http_verb": "PATCH", + "endpoint": "entities/{entityId}/attrs/{attributeId}" + }, + { + "name": "058_02_02 With QoS 1", + "permutation_tp_id": "TP/NGSI-LD/CI/SUB/MQTT/058_02_02", + "doc": "Check that the broker supports different quality of service (qos)", + "tags": [ + "5_8_6", + "sub-mqtt-notification" + ], + "setup": "Start Mqtt Server And Connect", + "teardown": "After Test", + "template": "Receive MQTT Notification", + "then": "then {\n the SUT sends a valid Response for the operation:\n Notification with Received messages ${listenMessages}\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entities/{entityId}/attrs/{attributeId}'\n method set to 'PATCH'\n Update Entity Attributes and\n Query Parameter: id set to '${entity_id}' and\n Query Parameter: fragment_filename set to '${fragment_filename}' and\n Query Parameter: content_type set to 'application/ld+json'\n}", + "http_verb": "PATCH", + "endpoint": "entities/{entityId}/attrs/{attributeId}" + }, + { + "name": "058_02_03 With QoS 2", + "permutation_tp_id": "TP/NGSI-LD/CI/SUB/MQTT/058_02_03", + "doc": "Check that the broker supports different quality of service (qos)", + "tags": [ + "5_8_6", + "sub-mqtt-notification" + ], + "setup": "Start Mqtt Server And Connect", + "teardown": "After Test", + "template": "Receive MQTT Notification", + "then": "then {\n the SUT sends a valid Response for the operation:\n Notification with Received messages ${listenMessages}\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entities/{entityId}/attrs/{attributeId}'\n method set to 'PATCH'\n Update Entity Attributes and\n Query Parameter: id set to '${entity_id}' and\n Query Parameter: fragment_filename set to '${fragment_filename}' and\n Query Parameter: content_type set to 'application/ld+json'\n}", + "http_verb": "PATCH", + "endpoint": "entities/{entityId}/attrs/{attributeId}" + } + ], + "permutations": [], + "robotpath": "ContextInformation/Subscription/SubscriptionNotificationBehaviour/MQTT", + "robotfile": "058_02" +} \ No newline at end of file diff --git a/doc/files/ContextInformation/Subscription/058_03.json b/doc/files/ContextInformation/Subscription/058_03.json new file mode 100644 index 0000000000000000000000000000000000000000..64a223fac7825564a66a89ac65191e9fd8776515 --- /dev/null +++ b/doc/files/ContextInformation/Subscription/058_03.json @@ -0,0 +1,74 @@ +{ + "tp_id": "TP/NGSI-LD/CI/SUB/MQTT/058_03", + "test_objective": "Check that mqtt notification is received with different mqtt version", + "reference": "ETSI GS CIM 009 V1.3.1 [], clause 5.8.6", + "config_id": "", + "parent_release": "v1.3.1", + "clauses": [ + "5.8.6" + ], + "pics_selection": "", + "keywords": [ + "Receive Mqtt Notification", + "Start Mqtt Server And Connect", + "After Test", + "Setup Mqtt Subscription", + "Delete Initial Subscriptions", + "Delete Initial Entity" + ], + "teardown": "None", + "initial_condition": "with \n the SUT being in the \"initial state\" and\n the SUT containing an initial Subscription ${subscription} \n with an id set to ${subscription_id}\n and an notification endpoint set to a mqtt broker\n}", + "test_cases": [ + { + "name": "058_03_01 With Default Protocol", + "permutation_tp_id": "TP/NGSI-LD/CI/SUB/MQTT/058_03_01", + "doc": "Check that the broker support different mqtt version", + "tags": [ + "5_8_6", + "sub-mqtt-notification" + ], + "setup": "Start Mqtt Server And Connect", + "teardown": "After Test", + "template": "Receive Mqtt Notification", + "then": "then {\n the SUT sends a valid Response for the operation:\n Notification with Received messages ${listenMessages}\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entities/{entityId}/attrs/{attributeId}'\n method set to 'PATCH'\n Update Entity Attributes and\n Query Parameter: id set to '${entity_id}' and\n Query Parameter: fragment_filename set to '${fragment_filename}' and\n Query Parameter: content_type set to 'application/ld+json'\n}", + "http_verb": "PATCH", + "endpoint": "entities/{entityId}/attrs/{attributeId}" + }, + { + "name": "058_03_02 With MQTT 3.1.1 Protocol", + "permutation_tp_id": "TP/NGSI-LD/CI/SUB/MQTT/058_03_02", + "doc": "Check that the broker support different mqtt version", + "tags": [ + "5_8_6", + "sub-mqtt-notification" + ], + "setup": "Start Mqtt Server And Connect", + "teardown": "After Test", + "template": "Receive Mqtt Notification", + "then": "then {\n the SUT sends a valid Response for the operation:\n Notification with Received messages ${listenMessages}\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entities/{entityId}/attrs/{attributeId}'\n method set to 'PATCH'\n Update Entity Attributes and\n Query Parameter: id set to '${entity_id}' and\n Query Parameter: fragment_filename set to '${fragment_filename}' and\n Query Parameter: content_type set to 'application/ld+json'\n}", + "http_verb": "PATCH", + "endpoint": "entities/{entityId}/attrs/{attributeId}" + }, + { + "name": "058_03_03 With MQTT 5.0 Protocol", + "permutation_tp_id": "TP/NGSI-LD/CI/SUB/MQTT/058_03_03", + "doc": "Check that the broker support different mqtt version", + "tags": [ + "5_8_6", + "sub-mqtt-notification" + ], + "setup": "Start Mqtt Server And Connect", + "teardown": "After Test", + "template": "Receive Mqtt Notification", + "then": "then {\n the SUT sends a valid Response for the operation:\n Notification with Received messages ${listenMessages}\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entities/{entityId}/attrs/{attributeId}'\n method set to 'PATCH'\n Update Entity Attributes and\n Query Parameter: id set to '${entity_id}' and\n Query Parameter: fragment_filename set to '${fragment_filename}' and\n Query Parameter: content_type set to 'application/ld+json'\n}", + "http_verb": "PATCH", + "endpoint": "entities/{entityId}/attrs/{attributeId}" + } + ], + "permutations": [], + "robotpath": "ContextInformation/Subscription/SubscriptionNotificationBehaviour/MQTT", + "robotfile": "058_03" +} \ No newline at end of file diff --git a/doc/files/ContextInformation/Subscription/058_04.json b/doc/files/ContextInformation/Subscription/058_04.json new file mode 100644 index 0000000000000000000000000000000000000000..c55aa3cce08c022d5e41cb38550c70c61a42102b --- /dev/null +++ b/doc/files/ContextInformation/Subscription/058_04.json @@ -0,0 +1,42 @@ +{ + "tp_id": "TP/NGSI-LD/CI/SUB/MQTT/058_04", + "test_objective": "Check that the mqtt notification payload is well formed", + "reference": "ETSI GS CIM 009 V1.3.1 [], clause 5.8.6", + "config_id": "", + "parent_release": "v1.3.1", + "clauses": [ + "5.8.6" + ], + "pics_selection": "", + "keywords": [ + "Receive Mqtt Notification", + "Start Mqtt Server And Connect", + "After Test", + "Setup Mqtt Subscription", + "Delete Initial Subscriptions", + "Delete Initial Entity" + ], + "teardown": "None", + "initial_condition": "with \n the SUT being in the \"initial state\" and\n the SUT containing an initial Subscription ${subscription} \n with an id set to ${subscription_id}\n and an notification endpoint set to a mqtt broker\n}", + "test_cases": [ + { + "name": "058_04_01 Basic Subscription", + "permutation_tp_id": "TP/NGSI-LD/CI/SUB/MQTT/058_04_01", + "doc": "Check that the broker send well formed data", + "tags": [ + "5_8_6", + "sub-mqtt-notification" + ], + "setup": "Start Mqtt Server And Connect", + "teardown": "After Test", + "template": "Receive Mqtt Notification", + "then": "then {\n the SUT sends a valid Response for the operations:\n Notification with Received message ${message} with key metadata and\n Notification with Received message ${message} with key body and\n Notification with Received message ${message}[metadata] with key Content-Type and\n Notification with Received message ${message}[metadata] with key Link and\n Notification with expected field ${message}[metadata][test-receiver-key] equals field test-receiver-info and\n Notification with expected field ${message}[body][type] equals field Notification and\n Notification with Received message ${message}[body] with key data and\n Notification with Received message ${message}[body][data][0] with key id and\n Notification with Received message ${message}[body][data][0] with key type\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entities/{entityId}/attrs/{attributeId}'\n method set to 'PATCH'\n Update Entity Attributes and\n Query Parameter: id set to '${entity_id}' and\n Query Parameter: fragment_filename set to '${fragment_filename}' and\n Query Parameter: content_type set to 'application/ld+json'\n}", + "http_verb": "PATCH", + "endpoint": "entities/{entityId}/attrs/{attributeId}" + } + ], + "permutations": [], + "robotpath": "ContextInformation/Subscription/SubscriptionNotificationBehaviour/MQTT", + "robotfile": "058_04" +} \ No newline at end of file diff --git a/doc/tests/test_ContextInformation_Subscription.py b/doc/tests/test_ContextInformation_Subscription.py index 265e10d4c5eb3c5fadcd4b10ac55d9b0cd5e5951..8a550fbdb639c78db149417e492a1e8d1c6b5dbc 100644 --- a/doc/tests/test_ContextInformation_Subscription.py +++ b/doc/tests/test_ContextInformation_Subscription.py @@ -328,3 +328,32 @@ class TestCISubscription(TestCase): difference_file = f'{self.folder_test_suites}/doc/results/out_029_11.json' self.common_function(robot_file=robot_file, expected_value=expected_value, difference_file=difference_file) + + def test_058_01(self): + robot_file = f'{self.folder_test_suites}/TP/NGSI-LD/ContextInformation/Subscription/UpdateSubscription/058_01.robot' + expected_value = f'{self.folder_test_suites}/doc/files/ContextInformation/Subscription/058_01.json' + difference_file = f'{self.folder_test_suites}/doc/results/out_058_01.json' + + self.common_function(robot_file=robot_file, expected_value=expected_value, difference_file=difference_file) + + def test_058_02(self): + robot_file = f'{self.folder_test_suites}/TP/NGSI-LD/ContextInformation/Subscription/UpdateSubscription/058_02.robot' + expected_value = f'{self.folder_test_suites}/doc/files/ContextInformation/Subscription/058_02.json' + difference_file = f'{self.folder_test_suites}/doc/results/out_058_02.json' + + self.common_function(robot_file=robot_file, expected_value=expected_value, difference_file=difference_file) + + def test_058_03(self): + robot_file = f'{self.folder_test_suites}/TP/NGSI-LD/ContextInformation/Subscription/UpdateSubscription/058_03.robot' + expected_value = f'{self.folder_test_suites}/doc/files/ContextInformation/Subscription/058_03.json' + difference_file = f'{self.folder_test_suites}/doc/results/out_058_03.json' + + self.common_function(robot_file=robot_file, expected_value=expected_value, difference_file=difference_file) + + def test_058_04(self): + robot_file = f'{self.folder_test_suites}/TP/NGSI-LD/ContextInformation/Subscription/UpdateSubscription/058_04.robot' + expected_value = f'{self.folder_test_suites}/doc/files/ContextInformation/Subscription/058_04.json' + difference_file = f'{self.folder_test_suites}/doc/results/out_058_04.json' + + self.common_function(robot_file=robot_file, expected_value=expected_value, difference_file=difference_file) + diff --git a/requirements.txt b/requirements.txt index 5104bc18cdd29cb983042dcfb57e420afcf13800..e26df1ea32e903b469640de42e1c63a488d57eaa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,5 @@ deepdiff==6.7.1 prettydiff==0.1.0 robotframework-httpctrl==0.3.1 robotframework-tidy==4.11.0 +paho-mqtt==1.6.1 +robotframework-mqttlibrary==0.7.1.post3 diff --git a/resources/AssertionUtils.resource b/resources/AssertionUtils.resource index 432e6ce779d2223304c39322e6b1b22a21d4723b..63181b6d7c2c79815c96d62db3f3c5407ee43e73 100755 --- a/resources/AssertionUtils.resource +++ b/resources/AssertionUtils.resource @@ -43,7 +43,7 @@ Check Response Body Containing Entities URIS set to Append To List ${response_entities_ids} ${entity['id']} END - Lists Should Be Equal ${expected_entities_ids} ${response_entities_ids} ignore_order=True + Lists Should Be Equal ${expected_entities_ids} ${response_entities_ids} ignore_order=True Check Response Body Content [Arguments] ${expectation_filename} ${response_body} ${additional_ignored_path}=${EMPTY} @@ -759,3 +759,15 @@ Check Context Response Body Containing a JSONObject with details of a Implicitly # Check that there is no other keys Check Context Detailed Information Keys ${response}[0] + +Check Messages Contain One Instance + [Arguments] ${messages} + Length Should Be ${messages} 1 + +Check Message Contain Key + [Arguments] ${message} ${key} + Dictionary Should Contain Key ${message} ${key} + +Check Message Field Equal + [Arguments] ${expected_field} ${field} + Should Be Equal As Strings ${expected_field} ${field} diff --git a/resources/mqttUtils/MqttUtils.resource b/resources/mqttUtils/MqttUtils.resource new file mode 100644 index 0000000000000000000000000000000000000000..8ee17e867c2835d289e8be3f602bbf2a80fa8490 --- /dev/null +++ b/resources/mqttUtils/MqttUtils.resource @@ -0,0 +1,30 @@ +*** Settings *** +Documentation manage a mqtt server + +Library Process +Library MQTTLibrary + + +*** Variables *** +${container_name}= ngsi-ld-test-suite-mosquitto-container + + +*** Keywords *** +Start Mqtt Server + [Arguments] ${conf_file_name} ${port} + ${request} = Set Variable + ... docker run -d -p ${port}:1883 -v "${CURDIR}/mosquitto/${conf_file_name}:/mosquitto/config/mosquitto.conf" -v "${CURDIR}/mosquitto/mosquitto_pwd:/mosquitto/config/mosquitto_pwd" --name "${container_name}" eclipse-mosquitto:2.0.18-openssl + + ${result} = Run Process ${request} shell=yes + IF ${result.rc} > 0 + Log The launch of mosquitto encount an error + Log Check that docker is installed + Log that the port ${port} is available + Log and that no other container named ${container_name} is running + Log ${result.stdout} + Log ${result.stderr} + END + +Stop Mqtt Server + ${request} = Set Variable docker container rm -f "${container_name}" + Run Process ${request} shell=yes diff --git a/resources/mqttUtils/mosquitto/mosquitto.conf b/resources/mqttUtils/mosquitto/mosquitto.conf new file mode 100644 index 0000000000000000000000000000000000000000..5c56c8ed2d15657c30d06c01fd705fee59cdba31 --- /dev/null +++ b/resources/mqttUtils/mosquitto/mosquitto.conf @@ -0,0 +1,3 @@ +# see possible config : https://mosquitto.org/man/mosquitto-conf-5.html +allow_anonymous true +listener 1883 \ No newline at end of file diff --git a/resources/mqttUtils/mosquitto/mosquitto_pwd b/resources/mqttUtils/mosquitto/mosquitto_pwd new file mode 100644 index 0000000000000000000000000000000000000000..b0f87528263ba90a888c8539396e6e1bcb1df700 --- /dev/null +++ b/resources/mqttUtils/mosquitto/mosquitto_pwd @@ -0,0 +1 @@ +user_with_password:$7$101$DJEdWpis1ub7wd3W$2wJOFueA24YFV/q35IJT3MI6cOXkHX75PZXGcxMPeuMuc//YqFDyk6Nz5MKcrJtvkKXXmJItkorF7qZEoCb/9g== \ No newline at end of file diff --git a/resources/mqttUtils/mosquitto/mosquitto_with_user.conf b/resources/mqttUtils/mosquitto/mosquitto_with_user.conf new file mode 100644 index 0000000000000000000000000000000000000000..bf300cb8880ffb9015e0b17a4b58a87015710d5d --- /dev/null +++ b/resources/mqttUtils/mosquitto/mosquitto_with_user.conf @@ -0,0 +1,5 @@ +# see possible config : https://mosquitto.org/man/mosquitto-conf-5.html +allow_anonymous false +listener 1883 +# file with username user:user_with_password and password:password +password_file /mosquitto/config/mosquitto_pwd \ No newline at end of file