| # Licensed to the Apache Software Foundation (ASF) under one or more |
| # contributor license agreements. See the NOTICE file distributed with |
| # this work for additional information regarding copyright ownership. |
| # The ASF licenses this file to You under the Apache License, Version 2.0 |
| # (the "License"); you may not use this file except in compliance with |
| # the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| from datetime import datetime |
| from contextlib import contextmanager |
| |
| import pytest |
| |
| from aria import application_model_storage |
| from aria.storage import ( |
| sql_mapi, |
| ) |
| from aria.storage.exceptions import StorageError |
| from aria.modeling.exceptions import ValueFormatException |
| from aria.modeling.models import ( |
| ServiceTemplate, |
| Service, |
| ServiceUpdate, |
| ServiceUpdateStep, |
| ServiceModification, |
| Execution, |
| Task, |
| Plugin, |
| Relationship, |
| NodeTemplate, |
| Node, |
| Input, |
| Output, |
| Property, |
| Attribute, |
| Configuration, |
| Argument, |
| Type |
| ) |
| |
| from tests import mock |
| from tests.storage import release_sqlite_storage, init_inmemory_model_storage |
| |
| |
| @contextmanager |
| def sql_storage(storage_func): |
| storage = None |
| try: |
| storage = storage_func() |
| yield storage |
| finally: |
| if storage: |
| release_sqlite_storage(storage) |
| |
| |
| def _empty_storage(): |
| return application_model_storage(sql_mapi.SQLAlchemyModelAPI, |
| initiator=init_inmemory_model_storage) |
| |
| |
| def _service_template_storage(): |
| storage = _empty_storage() |
| service_template = mock.models.create_service_template() |
| storage.service_template.put(service_template) |
| return storage |
| |
| |
| def _service_storage(): |
| storage = _service_template_storage() |
| service = mock.models.create_service( |
| storage.service_template.get_by_name(mock.models.SERVICE_TEMPLATE_NAME)) |
| storage.service.put(service) |
| return storage |
| |
| |
| def _service_update_storage(): |
| storage = _service_storage() |
| service_update = ServiceUpdate( |
| service=storage.service.list()[0], |
| created_at=now, |
| service_plan={}, |
| ) |
| storage.service_update.put(service_update) |
| return storage |
| |
| |
| def _node_template_storage(): |
| storage = _service_storage() |
| service_template = storage.service_template.list()[0] |
| dependency_node_template = mock.models.create_dependency_node_template(service_template) |
| mock.models.create_dependent_node_template(service_template, dependency_node_template) |
| storage.service_template.update(service_template) |
| return storage |
| |
| |
| def _nodes_storage(): |
| storage = _node_template_storage() |
| service = storage.service.get_by_name(mock.models.SERVICE_NAME) |
| dependency_node_template = storage.node_template.get_by_name( |
| mock.models.DEPENDENCY_NODE_TEMPLATE_NAME) |
| mock.models.create_node(dependency_node_template, service, |
| name=mock.models.DEPENDENCY_NODE_NAME) |
| |
| dependent_node_template = mock.models.create_dependent_node_template(service.service_template, |
| dependency_node_template) |
| |
| mock.models.create_node(dependent_node_template, service, name=mock.models.DEPENDENT_NODE_NAME) |
| storage.service.update(service) |
| return storage |
| |
| |
| def _execution_storage(): |
| storage = _service_storage() |
| execution = mock.models.create_execution(storage.service.list()[0]) |
| plugin = mock.models.create_plugin() |
| storage.execution.put(execution) |
| storage.plugin.put(plugin) |
| return storage |
| |
| |
| @pytest.fixture |
| def empty_storage(): |
| with sql_storage(_empty_storage) as storage: |
| yield storage |
| |
| |
| @pytest.fixture |
| def service_template_storage(): |
| with sql_storage(_service_template_storage) as storage: |
| yield storage |
| |
| |
| @pytest.fixture |
| def service_storage(): |
| with sql_storage(_service_storage) as storage: |
| yield storage |
| |
| |
| @pytest.fixture |
| def service_update_storage(): |
| with sql_storage(_service_update_storage) as storage: |
| yield storage |
| |
| |
| @pytest.fixture |
| def node_template_storage(): |
| with sql_storage(_node_template_storage) as storage: |
| yield storage |
| |
| |
| @pytest.fixture |
| def nodes_storage(): |
| with sql_storage(_nodes_storage) as storage: |
| yield storage |
| |
| |
| @pytest.fixture |
| def execution_storage(): |
| with sql_storage(_execution_storage) as storage: |
| yield storage |
| |
| |
| m_cls = type('MockClass') |
| now = datetime.utcnow() |
| |
| |
| def _test_model(is_valid, storage, model_cls, model_kwargs): |
| if is_valid: |
| model = model_cls(**model_kwargs) |
| getattr(storage, model_cls.__modelname__).put(model) |
| return model |
| else: |
| with pytest.raises((ValueFormatException, StorageError, TypeError),): |
| getattr(storage, model_cls.__modelname__).put(model_cls(**model_kwargs)) |
| |
| |
| class TestServiceTemplate(object): |
| |
| @pytest.mark.parametrize( |
| 'is_valid, description, created_at, updated_at, main_file_name', |
| [ |
| (False, [], now, now, '/path'), |
| (False, 'description', 'error', now, '/path'), |
| (False, 'description', now, 'error', '/path'), |
| (False, 'description', now, now, {}), |
| |
| (True, 'description', now, now, '/path'), |
| ] |
| ) |
| |
| def test_service_template_model_creation(self, empty_storage, is_valid, description, created_at, |
| updated_at, main_file_name): |
| _test_model(is_valid=is_valid, |
| storage=empty_storage, |
| model_cls=ServiceTemplate, |
| model_kwargs=dict( |
| description=description, |
| created_at=created_at, |
| updated_at=updated_at, |
| main_file_name=main_file_name) |
| ) |
| |
| |
| class TestService(object): |
| |
| @pytest.mark.parametrize( |
| 'is_valid, name, created_at, description, inputs, ' |
| 'outputs, updated_at', |
| [ |
| (False, m_cls, now, 'desc', {}, {}, now), |
| (False, 'name', m_cls, 'desc', {}, {}, now), |
| (False, 'name', now, m_cls, {}, {}, now), |
| (False, 'name', now, 'desc', m_cls, {}, now), |
| (False, 'name', now, 'desc', {}, m_cls, now), |
| (False, 'name', now, 'desc', {}, {}, m_cls), |
| |
| (True, 'name', now, 'desc', {}, {}, now), |
| (True, None, now, 'desc', {}, {}, now), |
| (True, 'name', now, None, {}, {}, now), |
| (True, 'name', now, 'desc', {}, {}, None), |
| (True, 'name', now, 'desc', {}, {}, now), |
| ] |
| ) |
| def test_service_model_creation(self, service_storage, is_valid, name, created_at, description, |
| inputs, outputs, updated_at): |
| service = _test_model( |
| is_valid=is_valid, |
| storage=service_storage, |
| model_cls=Service, |
| model_kwargs=dict( |
| name=name, |
| service_template=service_storage.service_template.list()[0], |
| created_at=created_at, |
| description=description, |
| inputs=inputs, |
| outputs=outputs, |
| updated_at=updated_at |
| )) |
| if is_valid: |
| assert service.service_template == \ |
| service_storage.service_template.list()[0] |
| |
| |
| class TestExecution(object): |
| |
| @pytest.mark.parametrize( |
| 'is_valid, created_at, started_at, ended_at, error, inputs, ' |
| 'status, workflow_name', |
| [ |
| (False, m_cls, now, now, 'error', {}, Execution.STARTED, 'wf_name'), |
| (False, now, m_cls, now, 'error', {}, Execution.STARTED, 'wf_name'), |
| (False, now, now, m_cls, 'error', {}, Execution.STARTED, 'wf_name'), |
| (False, now, now, now, m_cls, {}, Execution.STARTED, 'wf_name'), |
| (False, now, now, now, 'error', m_cls, Execution.STARTED, 'wf_name'), |
| (False, now, now, now, 'error', {}, m_cls, 'wf_name'), |
| (False, now, now, now, 'error', {}, Execution.STARTED, m_cls), |
| |
| (True, now, now, now, 'error', {}, Execution.STARTED, 'wf_name'), |
| (True, now, None, now, 'error', {}, Execution.STARTED, 'wf_name'), |
| (True, now, now, None, 'error', {}, Execution.STARTED, 'wf_name'), |
| (True, now, now, now, None, {}, Execution.STARTED, 'wf_name'), |
| ] |
| ) |
| def test_execution_model_creation(self, service_storage, is_valid, created_at, started_at, |
| ended_at, error, inputs, status, workflow_name): |
| execution = _test_model( |
| is_valid=is_valid, |
| storage=service_storage, |
| model_cls=Execution, |
| model_kwargs=dict( |
| service=service_storage.service.list()[0], |
| created_at=created_at, |
| started_at=started_at, |
| ended_at=ended_at, |
| error=error, |
| inputs=inputs, |
| status=status, |
| workflow_name=workflow_name, |
| )) |
| if is_valid: |
| assert execution.service == service_storage.service.list()[0] |
| assert execution.service_template == service_storage.service_template.list()[0] |
| |
| def test_execution_status_transition(self): |
| def create_execution(status): |
| execution = Execution( |
| id='e_id', |
| workflow_name='w_name', |
| status=status, |
| inputs={}, |
| created_at=now, |
| ) |
| return execution |
| |
| valid_transitions = { |
| Execution.PENDING: [Execution.STARTED, |
| Execution.CANCELLED, |
| Execution.PENDING], |
| Execution.STARTED: [Execution.FAILED, |
| Execution.SUCCEEDED, |
| Execution.CANCELLED, |
| Execution.CANCELLING, |
| Execution.STARTED], |
| Execution.CANCELLING: [Execution.FAILED, |
| Execution.SUCCEEDED, |
| Execution.CANCELLED, |
| Execution.CANCELLING], |
| Execution.FAILED: [Execution.FAILED], |
| Execution.SUCCEEDED: [Execution.SUCCEEDED], |
| Execution.CANCELLED: [Execution.CANCELLED, Execution.PENDING] |
| } |
| |
| invalid_transitions = { |
| Execution.PENDING: [Execution.FAILED, |
| Execution.SUCCEEDED, |
| Execution.CANCELLING], |
| Execution.STARTED: [Execution.PENDING], |
| Execution.CANCELLING: [Execution.PENDING, |
| Execution.STARTED], |
| Execution.FAILED: [Execution.STARTED, |
| Execution.SUCCEEDED, |
| Execution.CANCELLED, |
| Execution.CANCELLING], |
| Execution.SUCCEEDED: [Execution.PENDING, |
| Execution.STARTED, |
| Execution.FAILED, |
| Execution.CANCELLED, |
| Execution.CANCELLING], |
| Execution.CANCELLED: [Execution.STARTED, |
| Execution.FAILED, |
| Execution.SUCCEEDED, |
| Execution.CANCELLING], |
| } |
| |
| for current_status, valid_transitioned_statues in valid_transitions.items(): |
| for transitioned_status in valid_transitioned_statues: |
| execution = create_execution(current_status) |
| execution.status = transitioned_status |
| |
| for current_status, invalid_transitioned_statues in invalid_transitions.items(): |
| for transitioned_status in invalid_transitioned_statues: |
| execution = create_execution(current_status) |
| with pytest.raises(ValueError): |
| execution.status = transitioned_status |
| |
| |
| class TestServiceUpdate(object): |
| @pytest.mark.parametrize( |
| 'is_valid, created_at, service_plan, service_update_nodes, ' |
| 'service_update_service, service_update_node_templates, ' |
| 'modified_entity_ids, state', |
| [ |
| (False, m_cls, {}, {}, {}, [], {}, 'state'), |
| (False, now, m_cls, {}, {}, [], {}, 'state'), |
| (False, now, {}, m_cls, {}, [], {}, 'state'), |
| (False, now, {}, {}, m_cls, [], {}, 'state'), |
| (False, now, {}, {}, {}, m_cls, {}, 'state'), |
| (False, now, {}, {}, {}, [], m_cls, 'state'), |
| (False, now, {}, {}, {}, [], {}, m_cls), |
| |
| (True, now, {}, {}, {}, [], {}, 'state'), |
| (True, now, {}, None, {}, [], {}, 'state'), |
| (True, now, {}, {}, None, [], {}, 'state'), |
| (True, now, {}, {}, {}, None, {}, 'state'), |
| (True, now, {}, {}, {}, [], None, 'state'), |
| (True, now, {}, {}, {}, [], {}, None), |
| ] |
| ) |
| def test_service_update_model_creation(self, service_storage, is_valid, created_at, |
| service_plan, service_update_nodes, |
| service_update_service, service_update_node_templates, |
| modified_entity_ids, state): |
| service_update = _test_model( |
| is_valid=is_valid, |
| storage=service_storage, |
| model_cls=ServiceUpdate, |
| model_kwargs=dict( |
| service=service_storage.service.list()[0], |
| created_at=created_at, |
| service_plan=service_plan, |
| service_update_nodes=service_update_nodes, |
| service_update_service=service_update_service, |
| service_update_node_templates=service_update_node_templates, |
| modified_entity_ids=modified_entity_ids, |
| state=state |
| )) |
| if is_valid: |
| assert service_update.service == \ |
| service_storage.service.list()[0] |
| |
| |
| class TestServiceUpdateStep(object): |
| |
| @pytest.mark.parametrize( |
| 'is_valid, action, entity_id, entity_type', |
| [ |
| (False, m_cls, 'id', ServiceUpdateStep.ENTITY_TYPES.NODE), |
| (False, ServiceUpdateStep.ACTION_TYPES.ADD, m_cls, |
| ServiceUpdateStep.ENTITY_TYPES.NODE), |
| (False, ServiceUpdateStep.ACTION_TYPES.ADD, 'id', m_cls), |
| |
| (True, ServiceUpdateStep.ACTION_TYPES.ADD, 'id', |
| ServiceUpdateStep.ENTITY_TYPES.NODE) |
| ] |
| ) |
| def test_service_update_step_model_creation(self, service_update_storage, is_valid, action, |
| entity_id, entity_type): |
| service_update_step = _test_model( |
| is_valid=is_valid, |
| storage=service_update_storage, |
| model_cls=ServiceUpdateStep, |
| model_kwargs=dict( |
| service_update= |
| service_update_storage.service_update.list()[0], |
| action=action, |
| entity_id=entity_id, |
| entity_type=entity_type |
| )) |
| if is_valid: |
| assert service_update_step.service_update == \ |
| service_update_storage.service_update.list()[0] |
| |
| def test_service_update_step_order(self): |
| add_node = ServiceUpdateStep( |
| id='add_step', |
| action='add', |
| entity_type='node', |
| entity_id='node_id') |
| |
| modify_node = ServiceUpdateStep( |
| id='modify_step', |
| action='modify', |
| entity_type='node', |
| entity_id='node_id') |
| |
| remove_node = ServiceUpdateStep( |
| id='remove_step', |
| action='remove', |
| entity_type='node', |
| entity_id='node_id') |
| |
| for step in (add_node, modify_node, remove_node): |
| assert hash((step.id, step.entity_id)) == hash(step) |
| |
| assert remove_node < modify_node < add_node |
| assert not remove_node > modify_node > add_node |
| |
| add_rel = ServiceUpdateStep( |
| id='add_step', |
| action='add', |
| entity_type='relationship', |
| entity_id='relationship_id') |
| |
| remove_rel = ServiceUpdateStep( |
| id='remove_step', |
| action='remove', |
| entity_type='relationship', |
| entity_id='relationship_id') |
| |
| assert remove_rel < remove_node < add_node < add_rel |
| assert not add_node < None |
| |
| |
| class TestServiceModification(object): |
| @pytest.mark.parametrize( |
| 'is_valid, context, created_at, ended_at, modified_node_templates, nodes, status', |
| [ |
| (False, m_cls, now, now, {}, {}, ServiceModification.STARTED), |
| (False, {}, m_cls, now, {}, {}, ServiceModification.STARTED), |
| (False, {}, now, m_cls, {}, {}, ServiceModification.STARTED), |
| (False, {}, now, now, m_cls, {}, ServiceModification.STARTED), |
| (False, {}, now, now, {}, m_cls, ServiceModification.STARTED), |
| (False, {}, now, now, {}, {}, m_cls), |
| |
| (True, {}, now, now, {}, {}, ServiceModification.STARTED), |
| (True, {}, now, None, {}, {}, ServiceModification.STARTED), |
| (True, {}, now, now, None, {}, ServiceModification.STARTED), |
| (True, {}, now, now, {}, None, ServiceModification.STARTED), |
| ] |
| ) |
| def test_service_modification_model_creation(self, service_storage, is_valid, context, |
| created_at, ended_at, modified_node_templates, |
| nodes, status): |
| service_modification = _test_model( |
| is_valid=is_valid, |
| storage=service_storage, |
| model_cls=ServiceModification, |
| model_kwargs=dict( |
| service=service_storage.service.list()[0], |
| context=context, |
| created_at=created_at, |
| ended_at=ended_at, |
| modified_node_templates=modified_node_templates, |
| nodes=nodes, |
| status=status, |
| )) |
| if is_valid: |
| assert service_modification.service == \ |
| service_storage.service.list()[0] |
| |
| |
| class TestNodeTemplate(object): |
| @pytest.mark.parametrize( |
| 'is_valid, name, properties', |
| [ |
| (False, m_cls, {}), |
| (False, 'name', m_cls), |
| |
| (True, 'name', {}), |
| ] |
| ) |
| def test_node_template_model_creation(self, service_storage, is_valid, name, properties): |
| node_template = _test_model( |
| is_valid=is_valid, |
| storage=service_storage, |
| model_cls=NodeTemplate, |
| model_kwargs=dict( |
| name=name, |
| type=service_storage.type.list()[0], |
| properties=properties, |
| service_template=service_storage.service_template.list()[0] |
| )) |
| if is_valid: |
| assert node_template.service_template == \ |
| service_storage.service_template.list()[0] |
| |
| |
| class TestNode(object): |
| @pytest.mark.parametrize( |
| 'is_valid, name, state, version', |
| [ |
| (False, m_cls, 'state', 1), |
| (False, 'name', 'state', 1), |
| (False, 'name', m_cls, 1), |
| (False, m_cls, 'state', m_cls), |
| |
| (True, 'name', 'initial', 1), |
| (True, None, 'initial', 1), |
| (True, 'name', 'initial', 1), |
| (True, 'name', 'initial', None), |
| ] |
| ) |
| def test_node_model_creation(self, node_template_storage, is_valid, name, state, version): |
| node = _test_model( |
| is_valid=is_valid, |
| storage=node_template_storage, |
| model_cls=Node, |
| model_kwargs=dict( |
| node_template=node_template_storage.node_template.list()[0], |
| type=node_template_storage.type.list()[0], |
| name=name, |
| state=state, |
| version=version, |
| service=node_template_storage.service.list()[0] |
| )) |
| if is_valid: |
| assert node.node_template == node_template_storage.node_template.list()[0] |
| assert node.service == \ |
| node_template_storage.service.list()[0] |
| |
| |
| class TestNodeHostAddress(object): |
| |
| host_address = '1.1.1.1' |
| |
| def test_host_address_on_none_hosted_node(self, service_storage): |
| node_template = self._node_template(service_storage, host_address='not considered') |
| node = self._node(service_storage, |
| node_template, |
| is_host=False, |
| host_address='not considered') |
| assert node.host_address is None |
| |
| def test_property_host_address_on_host_node(self, service_storage): |
| node_template = self._node_template(service_storage, host_address=self.host_address) |
| node = self._node(service_storage, node_template, is_host=True, host_address=None) |
| assert node.host_address == self.host_address |
| |
| def test_runtime_property_host_address_on_host_node(self, service_storage): |
| node_template = self._node_template(service_storage, host_address='not considered') |
| node = self._node(service_storage, node_template, is_host=True, |
| host_address=self.host_address) |
| assert node.host_address == self.host_address |
| |
| def test_no_host_address_configured_on_host_node(self, service_storage): |
| node_template = self._node_template(service_storage, host_address=None) |
| node = self._node(service_storage, node_template, is_host=True, host_address=None) |
| assert node.host_address is None |
| |
| def test_runtime_property_on_hosted_node(self, service_storage): |
| host_node_template = self._node_template(service_storage, host_address=None) |
| host_node = self._node(service_storage, |
| host_node_template, |
| is_host=True, |
| host_address=self.host_address) |
| node_template = self._node_template(service_storage, host_address=None) |
| node = self._node(service_storage, |
| node_template, |
| is_host=False, |
| host_address=None, |
| host_fk=host_node.id) |
| assert node.host_address == self.host_address |
| |
| def _node_template(self, storage, host_address): |
| kwargs = dict( |
| name='node_template', |
| type=storage.type.list()[0], |
| service_template=storage.service_template.list()[0] |
| ) |
| if host_address: |
| kwargs['properties'] = {'host_address': Property.wrap('host_address', host_address)} |
| node = NodeTemplate(**kwargs) |
| storage.node_template.put(node) |
| return node |
| |
| def _node(self, storage, node_template, is_host, host_address, host_fk=None): |
| kwargs = dict( |
| name='node', |
| node_template=node_template, |
| type=storage.type.list()[0], |
| state='initial', |
| service=storage.service.list()[0] |
| ) |
| if is_host and (host_address is None): |
| host_address = node_template.properties.get('host_address') |
| if host_address is not None: |
| host_address = host_address.value |
| if host_address: |
| kwargs.setdefault('attributes', {})['ip'] = Attribute.wrap('ip', host_address) |
| if is_host: |
| kwargs['host_fk'] = 1 |
| elif host_fk: |
| kwargs['host_fk'] = host_fk |
| node = Node(**kwargs) |
| storage.node.put(node) |
| return node |
| |
| |
| class TestRelationship(object): |
| @pytest.mark.parametrize( |
| 'is_valid, source_position, target_position', |
| [ |
| (False, m_cls, 0), |
| (False, 0, m_cls), |
| |
| (True, 0, 0), |
| (True, None, 0), |
| (True, 0, None), |
| ] |
| ) |
| def test_relationship_model_creation(self, nodes_storage, is_valid, source_position, |
| target_position): |
| nodes = nodes_storage.node |
| source_node = nodes.get_by_name(mock.models.DEPENDENT_NODE_NAME) |
| target_node = nodes.get_by_name(mock.models.DEPENDENCY_NODE_NAME) |
| _test_model(is_valid=is_valid, |
| storage=nodes_storage, |
| model_cls=Relationship, |
| model_kwargs=dict( |
| source_node=source_node, |
| target_node=target_node, |
| source_position=source_position, |
| target_position=target_position |
| )) |
| |
| |
| class TestPlugin(object): |
| @pytest.mark.parametrize( |
| 'is_valid, archive_name, distribution, distribution_release, ' |
| 'distribution_version, package_name, package_source, ' |
| 'package_version, supported_platform, supported_py_versions, uploaded_at, wheels', |
| [ |
| (False, m_cls, 'dis_name', 'dis_rel', 'dis_ver', 'pak_name', 'pak_src', 'pak_ver', |
| 'sup_plat', [], now, []), |
| (False, 'arc_name', m_cls, 'dis_rel', 'dis_ver', 'pak_name', 'pak_src', 'pak_ver', |
| 'sup_plat', [], now, []), |
| (False, 'arc_name', 'dis_name', m_cls, 'dis_ver', 'pak_name', 'pak_src', 'pak_ver', |
| 'sup_plat', [], now, []), |
| (False, 'arc_name', 'dis_name', 'dis_rel', m_cls, 'pak_name', 'pak_src', 'pak_ver', |
| 'sup_plat', [], now, []), |
| (False, 'arc_name', 'dis_name', 'dis_rel', 'dis_ver', m_cls, 'pak_src', 'pak_ver', |
| 'sup_plat', [], now, []), |
| (False, 'arc_name', 'dis_name', 'dis_rel', 'dis_ver', 'pak_name', m_cls, 'pak_ver', |
| 'sup_plat', [], now, []), |
| (False, 'arc_name', 'dis_name', 'dis_rel', 'dis_ver', 'pak_name', 'pak_src', m_cls, |
| 'sup_plat', [], now, []), |
| (False, 'arc_name', 'dis_name', 'dis_rel', 'dis_ver', 'pak_name', 'pak_src', |
| 'pak_ver', m_cls, [], now, []), |
| (False, 'arc_name', 'dis_name', 'dis_rel', 'dis_ver', 'pak_name', 'pak_src', |
| 'pak_ver', 'sup_plat', m_cls, now, []), |
| (False, 'arc_name', 'dis_name', 'dis_rel', 'dis_ver', 'pak_name', 'pak_src', |
| 'pak_ver', 'sup_plat', [], m_cls, []), |
| (False, 'arc_name', 'dis_name', 'dis_rel', 'dis_ver', 'pak_name', 'pak_src', |
| 'pak_ver', 'sup_plat', [], now, m_cls), |
| |
| (True, 'arc_name', 'dis_name', 'dis_rel', 'dis_ver', 'pak_name', 'pak_src', 'pak_ver', |
| 'sup_plat', [], now, []), |
| (True, 'arc_name', None, 'dis_rel', 'dis_ver', 'pak_name', 'pak_src', 'pak_ver', |
| 'sup_plat', [], now, []), |
| (True, 'arc_name', 'dis_name', None, 'dis_ver', 'pak_name', 'pak_src', 'pak_ver', |
| 'sup_plat', [], now, []), |
| (True, 'arc_name', 'dis_name', 'dis_rel', None, 'pak_name', 'pak_src', 'pak_ver', |
| 'sup_plat', [], now, []), |
| (True, 'arc_name', 'dis_name', 'dis_rel', 'dis_ver', 'pak_name', 'pak_src', |
| 'pak_ver', 'sup_plat', [], now, []), |
| (True, 'arc_name', 'dis_name', 'dis_rel', 'dis_ver', 'pak_name', None, 'pak_ver', |
| 'sup_plat', [], now, []), |
| (True, 'arc_name', 'dis_name', 'dis_rel', 'dis_ver', 'pak_name', 'pak_src', None, |
| 'sup_plat', [], now, []), |
| (True, 'arc_name', 'dis_name', 'dis_rel', 'dis_ver', 'pak_name', 'pak_src', |
| 'pak_ver', None, [], now, []), |
| (True, 'arc_name', 'dis_name', 'dis_rel', 'dis_ver', 'pak_name', 'pak_src', |
| 'pak_ver', 'sup_plat', None, now, []), |
| (True, 'arc_name', 'dis_name', 'dis_rel', 'dis_ver', 'pak_name', 'pak_src', |
| 'pak_ver', 'sup_plat', [], now, []), |
| ] |
| ) |
| def test_plugin_model_creation(self, empty_storage, is_valid, archive_name, distribution, |
| distribution_release, distribution_version, package_name, |
| package_source, package_version, supported_platform, |
| supported_py_versions, uploaded_at, wheels): |
| _test_model(is_valid=is_valid, |
| storage=empty_storage, |
| model_cls=Plugin, |
| model_kwargs=dict( |
| archive_name=archive_name, |
| distribution=distribution, |
| distribution_release=distribution_release, |
| distribution_version=distribution_version, |
| package_name=package_name, |
| package_source=package_source, |
| package_version=package_version, |
| supported_platform=supported_platform, |
| supported_py_versions=supported_py_versions, |
| uploaded_at=uploaded_at, |
| wheels=wheels, |
| )) |
| |
| |
| class TestTask(object): |
| |
| @pytest.mark.parametrize( |
| 'is_valid, status, due_at, started_at, ended_at, max_attempts, attempts_count, ' |
| 'retry_interval, ignore_failure, name, operation_mapping, arguments, plugin_id', |
| [ |
| (False, m_cls, now, now, now, 1, 1, 1, True, 'name', 'map', {}, '1'), |
| (False, Task.STARTED, m_cls, now, now, 1, 1, 1, True, 'name', 'map', {}, '1'), |
| (False, Task.STARTED, now, m_cls, now, 1, 1, 1, True, 'name', 'map', {}, '1'), |
| (False, Task.STARTED, now, now, m_cls, 1, 1, 1, True, 'name', 'map', {}, '1'), |
| (False, Task.STARTED, now, now, now, m_cls, 1, 1, True, 'name', 'map', {}, '1'), |
| (False, Task.STARTED, now, now, now, 1, m_cls, 1, True, 'name', 'map', {}, '1'), |
| (False, Task.STARTED, now, now, now, 1, 1, m_cls, True, 'name', 'map', {}, '1'), |
| (False, Task.STARTED, now, now, now, 1, 1, 1, True, m_cls, 'map', {}, '1'), |
| (False, Task.STARTED, now, now, now, 1, 1, 1, True, 'name', m_cls, {}, '1'), |
| (False, Task.STARTED, now, now, now, 1, 1, 1, True, 'name', 'map', m_cls, '1'), |
| (False, Task.STARTED, now, now, now, 1, 1, 1, True, 'name', 'map', {}, m_cls), |
| (False, Task.STARTED, now, now, now, 1, 1, 1, True, 'name', 'map', None, '1'), |
| |
| (True, Task.STARTED, now, now, now, 1, 1, 1, True, 'name', 'map', {}, '1'), |
| (True, Task.STARTED, None, now, now, 1, 1, 1, True, 'name', 'map', {}, '1'), |
| (True, Task.STARTED, now, None, now, 1, 1, 1, True, 'name', 'map', {}, '1'), |
| (True, Task.STARTED, now, now, None, 1, 1, 1, True, 'name', 'map', {}, '1'), |
| (True, Task.STARTED, now, now, now, 1, None, 1, True, 'name', 'map', {}, '1'), |
| (True, Task.STARTED, now, now, now, 1, 1, None, True, 'name', 'map', {}, '1'), |
| (True, Task.STARTED, now, now, now, 1, 1, 1, None, 'name', 'map', {}, '1'), |
| (True, Task.STARTED, now, now, now, 1, 1, 1, True, None, 'map', {}, '1'), |
| (True, Task.STARTED, now, now, now, 1, 1, 1, True, 'name', None, {}, '1'), |
| (True, Task.STARTED, now, now, now, 1, 1, 1, True, 'name', 'map', {}, None), |
| ] |
| ) |
| def test_task_model_creation(self, execution_storage, is_valid, status, due_at, started_at, |
| ended_at, max_attempts, attempts_count, retry_interval, |
| ignore_failure, name, operation_mapping, arguments, plugin_id): |
| task = _test_model( |
| is_valid=is_valid, |
| storage=execution_storage, |
| model_cls=Task, |
| model_kwargs=dict( |
| status=status, |
| execution=execution_storage.execution.list()[0], |
| due_at=due_at, |
| started_at=started_at, |
| ended_at=ended_at, |
| max_attempts=max_attempts, |
| attempts_count=attempts_count, |
| retry_interval=retry_interval, |
| ignore_failure=ignore_failure, |
| name=name, |
| function=operation_mapping, |
| arguments=arguments, |
| plugin_fk=plugin_id, |
| )) |
| if is_valid: |
| assert task.execution == execution_storage.execution.list()[0] |
| if task.plugin: |
| assert task.plugin == execution_storage.plugin.list()[0] |
| |
| def test_task_max_attempts_validation(self): |
| def create_task(max_attempts): |
| Task(execution_fk='eid', |
| name='name', |
| function='', |
| arguments={}, |
| max_attempts=max_attempts) |
| create_task(max_attempts=1) |
| create_task(max_attempts=2) |
| create_task(max_attempts=Task.INFINITE_RETRIES) |
| with pytest.raises(ValueError): |
| create_task(max_attempts=0) |
| with pytest.raises(ValueError): |
| create_task(max_attempts=-2) |
| |
| |
| class TestType(object): |
| def test_type_hierarchy(self): |
| super_type = Type(variant='variant', name='super') |
| sub_type = Type(variant='variant', parent=super_type, name='sub') |
| additional_type = Type(variant='variant', name='non_related') |
| |
| assert super_type.hierarchy == [super_type] |
| assert sub_type.hierarchy == [sub_type, super_type] |
| assert additional_type.hierarchy == [additional_type] |
| |
| super_type.parent = additional_type |
| |
| assert super_type.hierarchy == [super_type, additional_type] |
| assert sub_type.hierarchy == [sub_type, super_type, additional_type] |
| |
| |
| class TestParameter(object): |
| |
| MODELS_DERIVED_FROM_PARAMETER = (Input, Output, Property, Attribute, Configuration, Argument) |
| |
| @pytest.mark.parametrize( |
| 'is_valid, name, type_name, description', |
| [ |
| (False, 'name', 'int', []), |
| (False, 'name', [], 'desc'), |
| (False, [], 'type_name', 'desc'), |
| (True, 'name', 'type_name', 'desc'), |
| ] |
| ) |
| def test_derived_from_parameter_model_creation(self, empty_storage, is_valid, name, type_name, |
| description): |
| |
| for model_cls in self.MODELS_DERIVED_FROM_PARAMETER: |
| _test_model(is_valid=is_valid, |
| storage=empty_storage, |
| model_cls=model_cls, |
| model_kwargs=dict( |
| name=name, |
| type_name=type_name, |
| description=description, |
| _value={}) |
| ) |
| |
| def test_as_argument(self): |
| |
| for model_cls in self.MODELS_DERIVED_FROM_PARAMETER: |
| model = model_cls(name='name', |
| type_name='type_name', |
| description='description', |
| _value={}) |
| argument = model.as_argument() |
| assert isinstance(argument, Argument) |