Commit 1837f418 authored by Marco Cavalli's avatar Marco Cavalli
Browse files

feat: parser is capable to understand if a user context is used and this is reflected in the jsons

parent d74ed701
Loading
Loading
Loading
Loading
+107 −15
Original line number Diff line number Diff line
@@ -682,7 +682,12 @@ class GenerateRobotData:

        return setup

    def _resolve_iop_value(self, value: str, field: str) -> str:
    def _resolve_iop_value(
        self,
        value: str,
        field: str,
        setup_variables: dict | None = None,
    ) -> str:
        original = str(value)
        result = original
        visited = set()
@@ -692,6 +697,10 @@ class GenerateRobotData:
                raise ValueError(f"{field} variable '{original}' contains a circular reference")
            visited.add(result)

            if setup_variables is not None and result in setup_variables:
                result = str(setup_variables[result])
                continue

            if result in self.robot.variables:
                result = str(self.robot.variables[result])
                continue
@@ -749,12 +758,65 @@ class GenerateRobotData:

        return values

    @staticmethod
    def _compose_iop_configuration_context(args) -> str:
        for argument in (str(item) for item in args):
            key, separator, value = argument.partition('=')
            if separator and key == 'ld_context':
                return value

        if len(args) > 1:
            return str(args[1])
        return '${ngsild_test_suite_context}'

    def _iop_context_kind(
        self,
        value: str,
        field: str,
        setup_variables: dict,
    ) -> tuple[str, bool]:
        resolved = self._resolve_iop_value(
            value=value,
            field=field,
            setup_variables=setup_variables,
        )
        core_context = self._resolve_iop_value(
            value='${core_context}',
            field='Core context',
        )
        test_suite_context = self._resolve_iop_value(
            value='${ngsild_test_suite_context}',
            field='Test suite context',
        )
        return (
            'Default context' if resolved == core_context else 'User context',
            resolved == test_suite_context,
        )

    def generate_iop_preconditions(self, test_name: str) -> list:
        setup = self._get_iop_setup(test_name=test_name)
        contexts = []
        data = []
        context_operations = []
        setup_variables = {}

        for keyword in setup.body:
            if keyword.name == 'Set Test Variable' and len(keyword.args) >= 2:
                setup_variables[str(keyword.args[0])] = str(keyword.args[1])
                continue

            if keyword.name == 'Compose IOP Configuration':
                context_kind, is_test_suite_context = self._iop_context_kind(
                    value=self._compose_iop_configuration_context(keyword.args),
                    field='Compose IOP Configuration context',
                    setup_variables=setup_variables,
                )
                context_operations.append((
                    'registrations',
                    context_kind,
                    is_test_suite_context,
                ))
                continue

            if keyword.name != 'Create Entity':
                continue

@@ -771,23 +833,53 @@ class GenerateRobotData:
            )
            data.append(f"{broker} contains {payload_filename}.")

            if 'context' in arguments:
                context_filename = self._iop_filename(
                    value=arguments['context'],
                    field='Create Entity context'
            context_kind, is_test_suite_context = self._iop_context_kind(
                value=arguments.get('context', '${ngsild_test_suite_context}'),
                field='Create Entity context',
                setup_variables=setup_variables,
            )
            entity_id = self._resolve_iop_value(
                value=arguments['entity_id'],
                field='Create Entity entity ID',
                setup_variables=setup_variables,
            )
            context_operations.append((
                'entity',
                context_kind,
                is_test_suite_context,
                entity_id,
                broker,
            ))

        if not context_operations or all(
            operation[1] == 'Default context'
            for operation in context_operations
        ):
            context_top_level = 'No user context used.'
            contexts = []
        elif all(operation[2] for operation in context_operations):
            context_top_level = 'User context used in every operation.'
            contexts = []
        else:
            context_top_level = 'The following user contexts are used:'
            contexts = []
            for operation in context_operations:
                if operation[0] == 'entity':
                    _, context_kind, _, entity_id, broker = operation
                    contexts.append(
                    f"The {context_filename} user context is used when creating on {broker}."
                        f"{context_kind} when creating the entity with id {entity_id} "
                        f"in broker {broker}."
                    )
                else:
                    _, context_kind, _ = operation
                    contexts.append(
                        f"{context_kind} when creating the registrations in all brokers."
                    )

        return [
            {
                'type': 'context',
                'top-level': (
                    'Context used for creation in following brokers:'
                    if contexts else
                    'No user context used.'
                ),
                'top-level': context_top_level,
                'nested-object': contexts
            },
            {
+52 −7
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ Prepare Preconditions
            ['since_v1.6.1', 'iop', '4_3_3']
        )

    def test_generates_context_and_data_objects(self):
    def test_generates_mixed_context_and_data_objects(self):
        result = self.generate(
            variables='''${first_payload}     fixtures/first-entity.jsonld
${context_path}      https://example.test/contexts/example-context.jsonld?version=1
@@ -95,12 +95,15 @@ ${b3_url} ${EMPTY}''',
            [
                {
                    'type': 'context',
                    'top-level': 'Context used for creation in following brokers:',
                    'top-level': 'The following user contexts are used:',
                    'nested-object': [
                        'The example-context.jsonld user context is used when creating on b2.',
                        (
                            'The ngsi-ld-test-suite-compound.jsonld user context '
                            'is used when creating on b3.'
                            'User context when creating the entity with id '
                            'urn:ngsi-ld:Example:1 in broker b2.'
                        ),
                        (
                            'User context when creating the entity with id '
                            'urn:ngsi-ld:Example:2 in broker b3.'
                        )
                    ]
                },
@@ -115,7 +118,7 @@ ${b3_url} ${EMPTY}''',
            ]
        )

    def test_uses_empty_context_object_when_context_is_omitted(self):
    def test_uses_test_suite_context_when_context_is_omitted(self):
        result = self.generate(
            variables='${b2_url}    ${EMPTY}',
            setup=(
@@ -131,7 +134,7 @@ ${b3_url} ${EMPTY}''',
            [
                {
                    'type': 'context',
                    'top-level': 'No user context used.',
                    'top-level': 'User context used in every operation.',
                    'nested-object': []
                },
                {
@@ -145,6 +148,48 @@ ${b3_url} ${EMPTY}''',
            ]
        )

    def test_uses_no_user_context_when_all_operations_use_core_context(self):
        result = self.generate(
            variables='${b1_url}    ${EMPTY}',
            setup='''    Set Test Variable    ${entity_id}    urn:ngsi-ld:Example:1
    Create Entity    entity.jsonld    ${entity_id}    broker_url=${b1_url}    context=${core_context}
    @{configuration}=    Create List
    Compose IOP Configuration    ${configuration}    ld_context=${core_context}'''
        )

        self.assertEqual(
            result['pre_conditions'][0],
            {
                'type': 'context',
                'top-level': 'No user context used.',
                'nested-object': []
            }
        )

    def test_generates_mixed_entity_and_registration_contexts(self):
        result = self.generate(
            variables='${b1_url}    ${EMPTY}',
            setup='''    Set Test Variable    ${entity_id}    urn:ngsi-ld:Example:1
    Create Entity    entity.jsonld    ${entity_id}    broker_url=${b1_url}    context=${core_context}
    @{configuration}=    Create List
    Compose IOP Configuration    ${configuration}    ld_context=${ngsild_test_suite_context}'''
        )

        self.assertEqual(
            result['pre_conditions'][0],
            {
                'type': 'context',
                'top-level': 'The following user contexts are used:',
                'nested-object': [
                    (
                        'Default context when creating the entity with id '
                        'urn:ngsi-ld:Example:1 in broker b1.'
                    ),
                    'User context when creating the registrations in all brokers.'
                ]
            }
        )

    def test_uses_empty_objects_without_create_entity(self):
        result = self.generate(
            variables='${b1_url}    ${EMPTY}',