Commit f48b98b5 authored by lopezaguilar's avatar lopezaguilar
Browse files

Adding logic to manage 044_01 and added tests

parent 6d3f28c3
Loading
Loading
Loading
Loading
+50 −17
Original line number Diff line number Diff line
from os import getcwd
from os.path import dirname
from robot.api import TestSuiteBuilder
from doc.analysis.parserobotfile import ParseRobotFile
from doc.analysis.parseapiutilsfile import ParseApiUtilsFile
@@ -53,12 +53,12 @@ class GenerateRobotData:
        _ = [self.get_step_data(test=x.name) for x in self.suite.tests]
        self.test_suite['test_cases'] = self.test_cases

        # Generate the permutation key to provide the keys in test_cases list that are different
        # Generate the permutation keys to provide the keys in test_cases list that are different
        self.test_suite['permutations'] = self.get_permutation_keys(data=self.test_suite['test_cases'])

    def get_permutation_keys(self, data):
        all_keys = set().union(*data)
        excluded_keys = ['doc', 'permutation_tp_id', 'setup', 'teardown', 'name', 'params', 'tags']
        excluded_keys = ['doc', 'permutation_tp_id', 'setup', 'teardown', 'name', 'tags']
        all_keys = [x for x in all_keys if x not in excluded_keys]
        keys_with_different_values = [
            key for key in all_keys if any(d.get(key) != data[0].get(key) for d in data[1:])
@@ -67,14 +67,30 @@ class GenerateRobotData:
        return keys_with_different_values

    def get_params(self, string: str):
        # New content
        test_case = self.robot.test_cases[string]

        lines_starting_response = re.findall(r'^\s*\$\{response\}.*', test_case, re.MULTILINE)

        # If there is more than one line, it means that the test case has several operations, all of them to
        # create the environment content to execute the last one, which is the correct one to test the Test Case
        if len(lines_starting_response) > 1:
            response_to_check = lines_starting_response[-1]
        else:
            response_to_check = lines_starting_response[0]

        index = test_case.find(response_to_check)
        aux = test_case[index:].split('\n')

        # Previuos content
        params = list()
        request = str()
        index_start = string.find('${response}')
        aux = string[index_start:].split('\n')

        #index_start = string.find('${response}')
        #aux = string[index_start:].split('\n')
        # End previous content
        # Get the list of params of the function, they are the keys
        if '    ...    ' in aux[1]:
            request = aux[0].split('    ')[1]
            request = aux[0].split('    ')[2]
            # We are in the case that the attributes are in following lines
            for i in range(1, len(aux)):
                if '    ...    ' in aux[i]:
@@ -88,7 +104,7 @@ class GenerateRobotData:
            # the attributes are in the same line
            regex = r"\s*\$\{response\}=\s{4}(.*)\n"
            matches = re.finditer(regex, string, re.MULTILINE)
            request = aux[0].split('    ')[1]
            request = aux[0].split('    ')[2]

            # We have two options from here, or the parameters are defined in the same line or the parameters are defined in
            # following lines, next lines
@@ -107,9 +123,10 @@ class GenerateRobotData:
    def get_step_data(self, test: str):
        string = self.robot.get_substring(initial_string=test, final_string=self.suite.name, include=False)

        request, params = self.get_params(string=string)
        # request, params = self.get_params(string=string)
        request, params = self.get_params(string=test)

        self.check_header_parameters(params=params, test=test)
        #self.check_header_parameters(params=params, test=test)

        verb, url = self.apiutil.get_response(keyword=request)

@@ -120,7 +137,7 @@ class GenerateRobotData:
                break

        self.test_cases[index]['http_verb'] = verb
        self.test_cases[index]['endpoint'] = self.get_header_value(key=url)
        self.test_cases[index]['endpoint'] = self.get_values_url(keys=url)
        self.test_cases[index]['when'] = self.robot.generate_when_content(http_verb=self.test_cases[index]['http_verb'],
                                                                          endpoint=self.test_cases[index]['endpoint'],
                                                                          when=self.test_cases[index]['when'])
@@ -156,9 +173,28 @@ class GenerateRobotData:
                    index = i
                    break

            self.test_cases[index]['params'] = params
            # self.test_cases[index]['params'] = params
            self.test_cases[index][self.headers[key]] = value

    def get_values_url(self, keys: list) -> str:
        data = [self.get_value_url(key=x) for x in keys]
        data = '/'.join(data).replace('//', '/')
        return data

    def get_value_url(self, key: str) -> str:
        key_to_search = f'${key}'
        try:
            value = self.apiutil.variables[key_to_search]
        except KeyError:
            # It is not defined in ApiUtils, maybe in Robot File?
            try:
                value = self.robot.variables[key_to_search]
            except KeyError:
                # The variable is not defined, so it is keep as it is in the url
                value = key

        return value

    def get_header_value(self, key: str):
        value = str()
        # We can have a simple variable or a compound of two variables
@@ -285,11 +321,8 @@ class GenerateRobotData:
        return aux

    def generate_name(self):
        current_path = getcwd()
        tp_id = str(self.suite.source.parent)[len(current_path):]

        if tp_id[0:4] == '/../':
            tp_id = tp_id[4:]
        base_dir = dirname(dirname(dirname(__file__)))
        tp_id = str(self.suite.source.parent).replace(f'{base_dir}/', "")

        for key, value in self.identifier.items():
            tp_id = tp_id.replace(key, value)
+17 −1
Original line number Diff line number Diff line
@@ -12,6 +12,9 @@ class ParseApiUtilsFile:
        self.get_variables_data()

    def get_response(self, keyword):
        verb = str()
        url = list()

        string = self.get_substring(initial_string=keyword, final_string='RETURN', include=True)
        index = string.find('    ${response}')
        string = string[index:]
@@ -26,10 +29,23 @@ class ParseApiUtilsFile:
                if match:
                    verb = match.groups()[0]
            elif 'url' in item:
                url = item.split('/')[1]
                #url = item.split('/')[1]
                url = self.get_url_request(url=item)

        return verb, url

    @staticmethod
    def get_url_request(url: str) -> list:
        regex = r"\s*\.{3}\s*url=\$\{url\}\/(.*)"

        match = re.match(pattern=regex, string=url)
        if match:
            aux = match.groups()[0]
            keys = re.split(r'\$|/', aux)
            keys = [k for k in keys if k != '']

        return keys

    def get_variables_data(self):
        string = self.get_substring(initial_string='*** Variables ***\n', final_string='*** ', include=False)

doc/files/043_01.json

0 → 100644
+98 −0
Original line number Diff line number Diff line
{
  "tp_id": "TP/NGSI-LD/CB/043",
  "test_objective": "Verify receiving 503 \u2013 LdContextNotAvailable error if remote JSON-LD @context cannot be retrieved",
  "reference": "ETSI GS CIM 009 V1.3.1 [], clause 5.2.2",
  "config_id": "",
  "parent_release": "v1.3.1",
  "pics_selection": "PICS_5_2_2",
  "keywords": [],
  "teardown": "None",
  "initial_condition": "with {\n    the SUT in the \"initial state\"\n}",
  "test_cases": [
    {
      "name": "043_01 Create entity",
      "permutation_tp_id": "TP/NGSI-LD/CB/043_01",
      "doc": "Verify receiving 503 \u2013 LdContextNotAvailable error if remote JSON-LD @context cannot be retrieved (Create entity)",
      "tags": [
        "5_2_2",
        "e-create"
      ],
      "setup": null,
      "teardown": "Delete Entity by Id",
      "template": null,
      "then": "then {\n    the SUT sends a valid Response containing:\n        Response Body containing the type 'https://uri.etsi.org/ngsi-ld/errors/LdContextNotAvailable' and\n        Response body containing 'title' element and\n        Response Status Code set to 503\n}",
      "when": "when {\n    the SUT receives a Request from the client containing:\n        URL set to '/ngsi-ld/v1/entities/'\n        method set to 'POST'\n        Request Header['Content-Type'] set to 'application/ld+json' and\n payload defined in file: 'building-unretrievable-context-sample.jsonld'",
      "http_verb": "POST",
      "endpoint": "entities/"
    },
    {
      "name": "043_02 Create subscription",
      "permutation_tp_id": "TP/NGSI-LD/CB/043_02",
      "doc": "Verify receiving 503 \u2013 LdContextNotAvailable error if remote JSON-LD @context cannot be retrieved (Create subscription)",
      "tags": [
        "5_2_2",
        "sub-create"
      ],
      "setup": null,
      "teardown": "Delete Subscription",
      "template": null,
      "then": "then {\n    the SUT sends a valid Response containing:\n        Response Body containing the type 'https://uri.etsi.org/ngsi-ld/errors/LdContextNotAvailable' and\n        Response body containing 'title' element and\n        Response Status Code set to 503\n}",
      "when": "when {\n    the SUT receives a Request from the client containing:\n        URL set to '/ngsi-ld/v1/subscriptions/'\n        method set to 'POST'\n        Request Header['Content-Type'] set to 'application/ld+json' and\n payload defined in file: 'subscriptions/subscription-unretrievable-context-sample.jsonld'",
      "http_verb": "POST",
      "endpoint": "subscriptions/"
    },
    {
      "name": "043_03 Create Temporal Representation of Entities",
      "permutation_tp_id": "TP/NGSI-LD/CB/043_03",
      "doc": "Verify receiving 503 \u2013 LdContextNotAvailable error if remote JSON-LD @context cannot be retrieved (Create Temporal Representation of Entities)",
      "tags": [
        "5_2_2",
        "te-create"
      ],
      "setup": null,
      "teardown": "Delete Temporal Representation Of Entity",
      "template": null,
      "then": "then {\n    the SUT sends a valid Response containing:\n        Response Body containing the type 'https://uri.etsi.org/ngsi-ld/errors/LdContextNotAvailable' and\n        Response body containing 'title' element and\n        Response Status Code set to 503\n}",
      "when": "when {\n    the SUT receives a Request from the client containing:\n        URL set to '/ngsi-ld/v1/temporal/entities'\n        method set to 'POST'\n        Request Header['Content-Type'] set to 'application/ld+json' and\n payload defined in file: 'bus-temporal-representation-unretrievable-context-sample.jsonld'",
      "http_verb": "POST",
      "endpoint": "temporal/entities"
    },
    {
      "name": "043_04 Batch entity create",
      "permutation_tp_id": "TP/NGSI-LD/CB/043_04",
      "doc": "Verify receiving 503 \u2013 LdContextNotAvailable error if remote JSON-LD @context cannot be retrieved (Batch entity create)",
      "tags": [
        "5_2_2",
        "be-create"
      ],
      "setup": null,
      "teardown": "Batch Delete Entities",
      "template": null,
      "then": "then {\n    the SUT sends a valid Response containing:\n        Response Body containing the type 'https://uri.etsi.org/ngsi-ld/errors/LdContextNotAvailable' and\n        Response body containing 'title' element and\n        Response Status Code set to 503\n}",
      "when": "when {\n    the SUT receives a Request from the client containing:\n        URL set to '/ngsi-ld/v1/entityOperations/create'\n        method set to 'POST'\n        Request Header['Content-Type'] set to 'content_type=${CONTENT_TYPE_LD_JSON}' and\n payload set to a list of entities to be created",
      "http_verb": "POST",
      "endpoint": "entityOperations/create"
    },
    {
      "name": "043_05 Create context source registration",
      "permutation_tp_id": "TP/NGSI-LD/CB/043_05",
      "doc": "Verify receiving 503 \u2013 LdContextNotAvailable error if remote JSON-LD @context cannot be retrieved (Create context source registration)",
      "tags": [
        "5_2_2",
        "csr-create"
      ],
      "setup": null,
      "teardown": "Delete Context Source Registration",
      "template": null,
      "then": "then {\n    the SUT sends a valid Response containing:\n        Response Status Code set to 503\n}",
      "when": "when {\n    the SUT receives a Request from the client containing:\n        URL set to '/ngsi-ld/v1/csourceRegistrations'\n        method set to 'POST'\n        Request Header['Content-Type'] set to 'application/ld+json' and\n payload defined in file: '${updated_payload}'",
      "http_verb": "POST",
      "endpoint": "csourceRegistrations"
    }
  ],
  "permutations": [
    "when",
    "endpoint",
    "then"
  ]
}
 No newline at end of file

doc/files/044_01.json

0 → 100644
+49 −0
Original line number Diff line number Diff line
{
    "tp_id": "TP/NGSI-LD/CB/044_01",
    "test_objective": "Verify that PATCH HTTP requests can be done with \"application/merge-patch+json\" as Content-Type",
    "reference": "ETSI GS CIM 009 V1.3.1 [], clause 6.3.4",
    "config_id": "",
    "parent_release": "v1.3.1",
    "pics_selection": "PICS_6_3_4",
    "keywords": [],
    "teardown": "None",
    "initial_condition": "with {\n    the SUT in the \"initial state\"\n}",
    "test_cases": [
        {
            "name": "044_01_01 endpoint /entities/{entityId}/attrs/{attrId}",
            "permutation_tp_id": "TP/NGSI-LD/CB/044_01_01",
            "doc": "Verify that PATCH HTTP requests can be done with \"application/merge-patch+json\" as Content-Type",
            "tags": [
                "6_3_4",
                "ea-partial-update"
            ],
            "setup": null,
            "teardown": "Delete Entity by Id",
            "template": null,
            "then": "then {\n    the SUT sends a valid Response containing:\n        Response Status Code set to 204\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        Request Header['Content-Type'] set to 'application/ld+json' and\n payload defined in file: 'vehicle-simple-attributes-sample.jsonld'",
            "http_verb": "PATCH",
            "endpoint": "entities/{entityId}/attrs/{attributeId}"
        },
        {
            "name": "044_01_02 endpoint /subscriptions/{subscriptionId}",
            "permutation_tp_id": "TP/NGSI-LD/CB/044_01_02",
            "doc": "Verify that PATCH HTTP requests can be done with \"application/merge-patch+json\" as Content-Type",
            "tags": [
                "6_3_4",
                "sub-update"
            ],
            "setup": null,
            "teardown": "Delete Subscription",
            "template": null,
            "then": "then {\n    the SUT sends a valid Response containing:\n        Response Status Code set to 204\n}",
            "when": "when {\n    the SUT receives a Request from the client containing:\n        URL set to '/ngsi-ld/v1/subscriptions/{subscription_id}'\n        method set to 'PATCH'\n        Request Header['Content-Type'] set to 'application/ld+json' and\n payload defined in file: 'subscriptions/subscription-sample.jsonld'",
            "http_verb": "PATCH",
            "endpoint": "subscriptions/{subscription_id}"
        }
    ],
    "permutations": [
        "endpoint",
        "when"
    ]
}
 No newline at end of file
+14 −3
Original line number Diff line number Diff line
from pprint import pprint
from doc.analysis.generaterobotdata import GenerateRobotData
import json
from os.path import dirname, exists
from os import makedirs

if __name__ == "__main__":
    data = GenerateRobotData(robot_file='../TP/NGSI-LD/CommonBehaviours/044_01.robot',
                             execdir='/home/fla/Documents/workspace/bdd/ngsi-ld-test-suite')
    folder_test_suites = dirname(dirname(__file__))
    folder_result_path = f'{folder_test_suites}/doc/results'
    result_file = f'{folder_result_path}/result.json'
    robot_file = f'{folder_test_suites}/TP/NGSI-LD/CommonBehaviours/044_01.robot'

    # Check that the folder '/results' exists and if not, create it
    if not exists(folder_result_path):
        makedirs(folder_result_path)

    data = GenerateRobotData(robot_file=robot_file,
                             execdir=folder_test_suites)
    data.parse_robot()
    info = data.get_info()

    with open('result.json', 'w') as fp:
    with open(result_file, 'w') as fp:
        json.dump(obj=info, indent=4, fp=fp)

    # data = GenerateRobotData(robot_file='../TP/NGSI-LD/ContextInformation/Provision/Entities/CreateEntity/001_01.robot',
Loading