Exemplo n.º 1
0
    def test_workflow_type__diff_with_identical_workflow_type(self):
        with patch.object(
            Layer1, "describe_workflow_type", mock_describe_workflow_type,
        ):
            mocked = mock_describe_workflow_type()
            workflow_type = WorkflowType(
                self.domain,
                name=mocked["typeInfo"]["workflowType"]["name"],
                version=mocked["typeInfo"]["workflowType"]["version"],
                status=mocked["typeInfo"]["status"],
                creation_date=mocked["typeInfo"]["creationDate"],
                deprecation_date=mocked["typeInfo"]["deprecationDate"],
                task_list=mocked["configuration"]["defaultTaskList"]["name"],
                child_policy=mocked["configuration"]["defaultChildPolicy"],
                execution_timeout=mocked["configuration"][
                    "defaultExecutionStartToCloseTimeout"
                ],
                decision_tasks_timeout=mocked["configuration"][
                    "defaultTaskStartToCloseTimeout"
                ],
                description=mocked["typeInfo"]["description"],
            )

            diffs = workflow_type._diff()

            self.assertLength(diffs, 0)
Exemplo n.º 2
0
    def test_workflow_type__diff_with_identical_workflow_type(self):
        with patch.object(
                Layer1,
                'describe_workflow_type',
                mock_describe_workflow_type,
        ):
            mocked = mock_describe_workflow_type()
            workflow_type = WorkflowType(
                self.domain,
                name=mocked['typeInfo']['workflowType']['name'],
                version=mocked['typeInfo']['workflowType']['version'],
                status=mocked['typeInfo']['status'],
                creation_date=mocked['typeInfo']['creationDate'],
                deprecation_date=mocked['typeInfo']['deprecationDate'],
                task_list=mocked['configuration']['defaultTaskList']['name'],
                child_policy=mocked['configuration']['defaultChildPolicy'],
                execution_timeout=mocked['configuration']
                ['defaultExecutionStartToCloseTimeout'],
                decision_tasks_timeout=mocked['configuration']
                ['defaultTaskStartToCloseTimeout'],
                description=mocked['typeInfo']['description'],
            )

            diffs = workflow_type._diff()

            self.assertEqual(len(diffs), 0)
Exemplo n.º 3
0
    def test___diff_with_different_workflow_type(self):
        with patch.object(
            Layer1, "describe_workflow_type", mock_describe_workflow_type,
        ):
            workflow_type = WorkflowType(
                self.domain, "different-workflow-type", version="different-version"
            )
            diffs = workflow_type._diff()

            self.assertIsNotNone(diffs)
            self.assertLength(diffs, 6)

            self.assertTrue(hasattr(diffs[0], "attr"))
            self.assertTrue(hasattr(diffs[0], "local"))
            self.assertTrue(hasattr(diffs[0], "upstream"))
Exemplo n.º 4
0
 def test_is_synced_over_non_existent_workflow_type(self):
     with patch.object(Layer1, 'describe_workflow_type',
                       mock_describe_workflow_type):
         workflow_type = WorkflowType(self.domain,
                                      "non-existent-workflow-type",
                                      version="non-existent-version")
         self.assertFalse(workflow_type.is_synced)
Exemplo n.º 5
0
 def test_is_synced_over_non_existent_workflow_execution(self):
     with patch.object(Layer1, 'describe_workflow_execution',
                       mock_describe_workflow_execution):
         workflow_execution = WorkflowExecution(
             self.domain,
             WorkflowType(self.domain, "NonExistentTestType", "1.0"),
             "non-existent-id")
         self.assertFalse(workflow_execution.is_synced)
Exemplo n.º 6
0
    def test___diff_with_different_workflow_type(self):
        with patch.object(
                Layer1,
                'describe_workflow_type',
                mock_describe_workflow_type,
        ):
            workflow_type = WorkflowType(self.domain,
                                         "different-workflow-type",
                                         version="different-version")
            diffs = workflow_type._diff()

            self.assertIsNotNone(diffs)
            self.assertEqual(len(diffs), 6)

            self.assertTrue(hasattr(diffs[0], 'attr'))
            self.assertTrue(hasattr(diffs[0], 'local'))
            self.assertTrue(hasattr(diffs[0], 'upstream'))
Exemplo n.º 7
0
 def to_WorkflowType(self, domain, workflow_info, **kwargs):
     # Not using get_subkey in order for it to explictly
     # raise when workflowType name doesn't exist for example
     return WorkflowType(domain,
                         workflow_info['workflowType']['name'],
                         workflow_info['workflowType']['version'],
                         status=workflow_info['status'],
                         **kwargs)
Exemplo n.º 8
0
 def test_init_with_invalid_child_policy(self):
     with self.assertRaises(ValueError):
         WorkflowType(
             self.domain,
             "TestType",
             "1.0",
             child_policy="FAILING_POLICY"
         )
Exemplo n.º 9
0
 def setUp(self):
     self.domain = Domain("TestDomain")
     self.wt = WorkflowType(self.domain, "TestType", "1.0")
     self.we = WorkflowExecution(
         self.domain,
         self.wt,
         "TestType-0.1-TestDomain"
     )
Exemplo n.º 10
0
    def test___diff_with_different_workflow_type(self):
        with patch.object(
            Layer1,
            'describe_workflow_type',
            mock_describe_workflow_type,
        ):
            workflow_type = WorkflowType(
                self.domain,
                "different-workflow-type",
                version="different-version"
            )
            diffs = workflow_type._diff()

            self.assertIsNotNone(diffs)
            self.assertEqual(len(diffs), 6)

            self.assertTrue(hasattr(diffs[0], 'attr'))
            self.assertTrue(hasattr(diffs[0], 'local'))
            self.assertTrue(hasattr(diffs[0], 'upstream'))
Exemplo n.º 11
0
    def test_workflow_type__diff_with_identical_workflow_type(self):
        with patch.object(
            Layer1,
            'describe_workflow_type',
            mock_describe_workflow_type,
        ):
            mocked = mock_describe_workflow_type()
            workflow_type = WorkflowType(
                self.domain,
                name=mocked['typeInfo']['workflowType']['name'],
                version=mocked['typeInfo']['workflowType']['version'],
                status=mocked['typeInfo']['status'],
                creation_date=mocked['typeInfo']['creationDate'],
                deprecation_date=mocked['typeInfo']['deprecationDate'],
                task_list=mocked['configuration']['defaultTaskList']['name'],
                child_policy=mocked['configuration']['defaultChildPolicy'],
                execution_timeout=mocked['configuration']['defaultExecutionStartToCloseTimeout'],
                decision_tasks_timeout=mocked['configuration']['defaultTaskStartToCloseTimeout'],
                description=mocked['typeInfo']['description'],
            )

            diffs = workflow_type._diff()

            self.assertEqual(len(diffs), 0)
Exemplo n.º 12
0
    def test_changes_with_different_workflow_execution(self):
        with patch.object(
            Layer1, "describe_workflow_execution", mock_describe_workflow_execution,
        ):
            workflow_execution = WorkflowExecution(
                self.domain,
                WorkflowType(self.domain, "NonExistentTestType", "1.0"),
                "non-existent-id",
            )
            diffs = workflow_execution.changes

            self.assertIsNotNone(diffs)
            self.assertLength(diffs, 7)

            self.assertTrue(hasattr(diffs[0], "attr"))
            self.assertTrue(hasattr(diffs[0], "local"))
            self.assertTrue(hasattr(diffs[0], "upstream"))
Exemplo n.º 13
0
    def to_WorkflowExecution(self, domain, execution_info, **kwargs):
        workflow_type = WorkflowType(
            self.domain,
            execution_info['workflowType']['name'],
            execution_info['workflowType']['version']
        )

        return WorkflowExecution(
            domain,
            get_subkey(execution_info, ['execution', 'workflowId']),  # workflow_id
            run_id=get_subkey(execution_info, ['execution', 'runId']),
            workflow_type=workflow_type,
            status=execution_info.get('executionStatus'),
            close_status=execution_info.get('closeStatus'),
            tag_list=execution_info.get('tagList'),
            **kwargs
        )
Exemplo n.º 14
0
    def test_changes_with_different_workflow_execution(self):
        with patch.object(
                Layer1,
                'describe_workflow_execution',
                mock_describe_workflow_execution,
        ):
            workflow_execution = WorkflowExecution(
                self.domain,
                WorkflowType(self.domain, "NonExistentTestType", "1.0"),
                "non-existent-id")
            diffs = workflow_execution.changes

            self.assertIsNotNone(diffs)
            self.assertEqual(len(diffs), 7)

            self.assertTrue(hasattr(diffs[0], 'attr'))
            self.assertTrue(hasattr(diffs[0], 'local'))
            self.assertTrue(hasattr(diffs[0], 'upstream'))
Exemplo n.º 15
0
    def to_WorkflowExecution(self, domain, execution_info, **kwargs):
        workflow_type = WorkflowType(self.domain,
                                     execution_info['workflowType']['name'],
                                     execution_info['workflowType']['version'])

        return WorkflowExecution(
            domain,
            get_subkey(execution_info,
                       ['execution', 'workflowId']),  # workflow_id
            run_id=get_subkey(execution_info, ['execution', 'runId']),
            workflow_type=workflow_type,
            status=execution_info.get('executionStatus'),
            close_status=execution_info.get('closeStatus'),
            tag_list=execution_info.get('tagList'),
            start_timestamp=execution_info.get('startTimestamp'),
            close_timestamp=execution_info.get('closeTimestamp'),
            cancel_requested=execution_info.get('cancelRequested'),
            parent=execution_info.get('parent'),
            **kwargs)
Exemplo n.º 16
0
    def to_WorkflowExecution(self, domain, execution_info, **kwargs):
        workflow_type = WorkflowType(
            self.domain,
            execution_info["workflowType"]["name"],
            execution_info["workflowType"]["version"],
        )

        return WorkflowExecution(
            domain,
            get_subkey(execution_info, ["execution", "workflowId"]),  # workflow_id
            run_id=get_subkey(execution_info, ["execution", "runId"]),
            workflow_type=workflow_type,
            status=execution_info.get("executionStatus"),
            close_status=execution_info.get("closeStatus"),
            tag_list=execution_info.get("tagList"),
            start_timestamp=execution_info.get("startTimestamp"),
            close_timestamp=execution_info.get("closeTimestamp"),
            cancel_requested=execution_info.get("cancelRequested"),
            parent=execution_info.get("parent"),
            **kwargs
        )
Exemplo n.º 17
0
    def poll(self, task_list=None, identity=None, **kwargs):
        """
        Polls a decision task and returns the token and the full history of the
        workflow's events.

        :param task_list: task list to poll for decision tasks from.
        :type task_list: str

        :param identity: Identity of the decider making the request,
        which is recorded in the DecisionTaskStarted event in the
        workflow history.
        :type identity: str

        :returns: a Response object with history, token, and execution set
        :rtype: swf.responses.Response

        """
        logging_context.reset()
        task_list = task_list or self.task_list

        task = self.connection.poll_for_decision_task(
            self.domain.name,
            task_list=task_list,
            identity=format.identity(identity),
            **kwargs)
        token = task.get("taskToken")
        if not token:
            raise PollTimeout("Decider poll timed out")

        events = task["events"]
        logging_context.set("workflow_id",
                            task["workflowExecution"]["workflowId"])
        logging_context.set("task_type", "decision")
        logging_context.set("event_id", task["startedEventId"])

        next_page = task.get("nextPageToken")
        while next_page:
            try:
                task = self.connection.poll_for_decision_task(
                    self.domain.name,
                    task_list=task_list,
                    identity=format.identity(identity),
                    next_page_token=next_page,
                    **kwargs)
            except boto.exception.SWFResponseError as e:
                message = self.get_error_message(e)
                if e.error_code == "UnknownResourceFault":
                    raise DoesNotExistError(
                        "Unable to poll decision task",
                        message,
                    )

                raise ResponseError(message)

            token = task.get("taskToken")
            if not token:
                raise PollTimeout("Decider poll timed out")

            events.extend(task["events"])
            next_page = task.get("nextPageToken")

        history = History.from_event_list(events)

        workflow_type = WorkflowType(
            domain=self.domain,
            name=task["workflowType"]["name"],
            version=task["workflowType"]["version"],
        )
        execution = WorkflowExecution(
            domain=self.domain,
            workflow_id=task["workflowExecution"]["workflowId"],
            run_id=task["workflowExecution"]["runId"],
            workflow_type=workflow_type,
        )

        # TODO: move history into execution (needs refactoring on WorkflowExecution.history())
        return Response(token=token, history=history, execution=execution)
Exemplo n.º 18
0
 def setUp(self):
     self.domain = Domain("TestDomain")
     self.wt = WorkflowType(self.domain, "TestType", "0.1")
     self.weq = WorkflowExecutionQuerySet(self.domain)
Exemplo n.º 19
0
    def create(
        self,
        name,
        version,
        status=REGISTERED,
        creation_date=0.0,
        deprecation_date=0.0,
        task_list=None,
        child_policy=CHILD_POLICIES.TERMINATE,
        execution_timeout="300",
        decision_tasks_timeout="300",
        description=None,
        *args,
        **kwargs
    ):
        """Creates a new remote workflow type and returns the
        created WorkflowType model instance.

        :param  name: name of the workflow type
        :type   name: String

        :param  version: workflow type version
        :type   version: String

        :param  status: workflow type status
        :type   status: swf.core.ConnectedSWFObject.{REGISTERED, DEPRECATED}

        :param   creation_date: creation date of the current WorkflowType
        :type    creation_date: float (timestamp)

        :param   deprecation_date: deprecation date of WorkflowType
        :type    deprecation_date: float (timestamp)

        :param  task_list: task list to use for scheduling decision tasks for executions
                           of this workflow type
        :type   task_list: String

        :param  child_policy: policy to use for the child workflow executions
                              when a workflow execution of this type is terminated
        :type   child_policy: CHILD_POLICIES.{TERMINATE |
                                              REQUEST_CANCEL |
                                              ABANDON}

        :param  execution_timeout: maximum duration for executions of this workflow type
        :type   execution_timeout: String

        :param  decision_tasks_timeout: maximum duration of decision tasks for this workflow type
        :type   decision_tasks_timeout: String

        :param  description: Textual description of the workflow type
        :type   description: String
        """
        workflow_type = WorkflowType(
            self.domain,
            name,
            version,
            status=status,
            creation_date=creation_date,
            deprecation_date=deprecation_date,
            task_list=task_list,
            child_policy=child_policy,
            execution_timeout=execution_timeout,
            decision_tasks_timeout=decision_tasks_timeout,
            description=description,
        )
        workflow_type.save()

        return workflow_type
Exemplo n.º 20
0
class TestWorkflowType(unittest2.TestCase):
    def setUp(self):
        self.domain = Domain("test-domain")
        self.wt = WorkflowType(self.domain, "TestType", "1.0")

    def tearDown(self):
        pass

    def test_init_with_invalid_child_policy(self):
        with self.assertRaises(ValueError):
            WorkflowType(
                self.domain,
                "TestType",
                "1.0",
                child_policy="FAILING_POLICY"
            )

    def test___diff_with_different_workflow_type(self):
        with patch.object(
            Layer1,
            'describe_workflow_type',
            mock_describe_workflow_type,
        ):
            workflow_type = WorkflowType(
                self.domain,
                "different-workflow-type",
                version="different-version"
            )
            diffs = workflow_type._diff()

            self.assertIsNotNone(diffs)
            self.assertEqual(len(diffs), 6)

            self.assertTrue(hasattr(diffs[0], 'attr'))
            self.assertTrue(hasattr(diffs[0], 'local'))
            self.assertTrue(hasattr(diffs[0], 'upstream'))

    def test_workflow_type__diff_with_identical_workflow_type(self):
        with patch.object(
            Layer1,
            'describe_workflow_type',
            mock_describe_workflow_type,
        ):
            mocked = mock_describe_workflow_type()
            workflow_type = WorkflowType(
                self.domain,
                name=mocked['typeInfo']['workflowType']['name'],
                version=mocked['typeInfo']['workflowType']['version'],
                status=mocked['typeInfo']['status'],
                creation_date=mocked['typeInfo']['creationDate'],
                deprecation_date=mocked['typeInfo']['deprecationDate'],
                task_list=mocked['configuration']['defaultTaskList']['name'],
                child_policy=mocked['configuration']['defaultChildPolicy'],
                execution_timeout=mocked['configuration']['defaultExecutionStartToCloseTimeout'],
                decision_tasks_timeout=mocked['configuration']['defaultTaskStartToCloseTimeout'],
                description=mocked['typeInfo']['description'],
            )

            diffs = workflow_type._diff()

            self.assertEqual(len(diffs), 0)

    def test_exists_with_existing_workflow_type(self):
        with patch.object(Layer1, 'describe_workflow_type'):
            self.assertTrue(self.wt.exists)

    def test_exists_with_non_existent_workflow_type(self):
        with patch.object(self.wt.connection, 'describe_workflow_type') as mock:
            mock.side_effect = SWFResponseError(
                    400,
                    "Bad Request:",
                    {'__type': 'com.amazonaws.swf.base.model#UnknownResourceFault',
                     'message': 'Unknown type: WorkflowType=[workflowId=blah, runId=test]'},
                    'UnknownResourceFault',
                )

            self.assertFalse(self.wt.exists)

    def test_workflow_type_exists_with_whatever_error(self):
        with patch.object(self.wt.connection, 'describe_workflow_type') as mock:
            with self.assertRaises(ResponseError):
                mock.side_effect = SWFResponseError(
                        400,
                        "mocking exception",
                        {
                            '__type': 'WhateverError',
                            'message': 'Whatever'
                        }
                )
                self.domain.exists

    def test_is_synced_with_unsynced_workflow_type(self):
        pass

    def test_is_synced_with_synced_workflow_type(self):
        pass

    def test_is_synced_over_non_existent_workflow_type(self):
        with patch.object(
            Layer1,
            'describe_workflow_type',
            mock_describe_workflow_type
        ):
            workflow_type = WorkflowType(
                self.domain,
                "non-existent-workflow-type",
                version="non-existent-version"
            )
            self.assertFalse(workflow_type.is_synced)

    def test_changes_with_different_workflow_type(self):
        with patch.object(
            Layer1,
            'describe_workflow_type',
            mock_describe_workflow_type,
        ):
            workflow_type = WorkflowType(
                self.domain,
                "different-workflow-type-type",
                version="different-workflow-type-type-version"
            )
            diffs = workflow_type.changes

            self.assertIsNotNone(diffs)
            self.assertEqual(len(diffs), 6)

            self.assertTrue(hasattr(diffs[0], 'attr'))
            self.assertTrue(hasattr(diffs[0], 'local'))
            self.assertTrue(hasattr(diffs[0], 'upstream'))

    def test_workflow_type_changes_with_identical_workflow_type(self):
        with patch.object(
            Layer1,
            'describe_workflow_type',
            mock_describe_workflow_type,
        ):
            mocked = mock_describe_workflow_type()
            workflow_type = WorkflowType(
               self.domain,
                name=mocked['typeInfo']['workflowType']['name'],
                version=mocked['typeInfo']['workflowType']['version'],
                status=mocked['typeInfo']['status'],
                creation_date=mocked['typeInfo']['creationDate'],
                deprecation_date=mocked['typeInfo']['deprecationDate'],
                task_list=mocked['configuration']['defaultTaskList']['name'],
                child_policy=mocked['configuration']['defaultChildPolicy'],
                execution_timeout=mocked['configuration']['defaultExecutionStartToCloseTimeout'],
                decision_tasks_timeout=mocked['configuration']['defaultTaskStartToCloseTimeout'],
                description=mocked['typeInfo']['description'],
            )

            diffs = workflow_type.changes

            self.assertEqual(len(diffs), 0)


    def test_save_already_existing_type(self):
        with patch.object(self.wt.connection, 'register_workflow_type') as mock:
            with self.assertRaises(AlreadyExistsError):
                mock.side_effect = SWFTypeAlreadyExistsError(400, "mocked exception")
                self.wt.save()

    def test_save_with_response_error(self):
        with patch.object(self.wt.connection, 'register_workflow_type') as mock:
            with self.assertRaises(DoesNotExistError):
                mock.side_effect = SWFResponseError(
                    400,
                    "mocked exception",
                    {
                        "__type": "UnknownResourceFault",
                        "message": "Whatever"
                    }
                )
                self.wt.save()

    def test_delete_non_existent_type(self):
        with patch.object(self.wt.connection, 'deprecate_workflow_type') as mock:
            with self.assertRaises(DoesNotExistError):
                mock.side_effect = SWFResponseError(
                    400,
                    "mocked exception",
                    {
                        "__type": "UnknownResourceFault",
                        "message": "Whatever"
                    }
                )
                self.wt.delete()

    def test_delete_deprecated_type(self):
        with patch.object(self.wt.connection, 'deprecate_workflow_type') as mock:
            with self.assertRaises(DoesNotExistError):
                mock.side_effect = SWFResponseError(
                    400,
                    "mocked exception",
                    {
                        "__type": "TypeDeprecatedFault",
                        "message": "Whatever"
                    }
                )
                self.wt.delete()
Exemplo n.º 21
0
    def create(self, name, version,
               status=REGISTERED,
               creation_date=0.0,
               deprecation_date=0.0,
               task_list=None,
               child_policy=CHILD_POLICIES.TERMINATE,
               execution_timeout='300',
               decision_tasks_timeout='300',
               description=None,
               *args, **kwargs):
        """Creates a new remote workflow type and returns the
        created WorkflowType model instance.

        :param  name: name of the workflow type
        :type   name: String

        :param  version: workflow type version
        :type   version: String

        :param  status: workflow type status
        :type   status: swf.core.ConnectedSWFObject.{REGISTERED, DEPRECATED}

        :param   creation_date: creation date of the current WorkflowType
        :type    creation_date: float (timestamp)

        :param   deprecation_date: deprecation date of WorkflowType
        :type    deprecation_date: float (timestamp)

        :param  task_list: task list to use for scheduling decision tasks for executions
                           of this workflow type
        :type   task_list: String

        :param  child_policy: policy to use for the child workflow executions
                              when a workflow execution of this type is terminated
        :type   child_policy: CHILD_POLICIES.{TERMINATE |
                                              REQUEST_CANCEL |
                                              ABANDON}

        :param  execution_timeout: maximum duration for executions of this workflow type
        :type   execution_timeout: String

        :param  decision_tasks_timeout: maximum duration of decision tasks for this workflow type
        :type   decision_tasks_timeout: String

        :param  description: Textual description of the workflow type
        :type   description: String
        """
        workflow_type = WorkflowType(
            self.domain,
            name,
            version,
            status=status,
            creation_date=creation_date,
            deprecation_date=deprecation_date,
            task_list=task_list,
            child_policy=child_policy,
            execution_timeout=execution_timeout,
            decision_tasks_timeout=decision_tasks_timeout,
            description=description
        )
        workflow_type.save()

        return workflow_type
Exemplo n.º 22
0
 def setUp(self):
     self.domain = Domain("test-domain")
     self.wt = WorkflowType(self.domain, "TestType", "1.0")
Exemplo n.º 23
0
 def setUp(self):
     self.domain = Domain("test-domain")
     self.wt = WorkflowType(self.domain, "TestType", "1.0")
Exemplo n.º 24
0
class TestWorkflowType(unittest.TestCase, CustomAssertions):
    def setUp(self):
        self.domain = Domain("test-domain")
        self.wt = WorkflowType(self.domain, "TestType", "1.0")

    def tearDown(self):
        pass

    def test_init_with_invalid_child_policy(self):
        with self.assertRaises(ValueError):
            WorkflowType(self.domain, "TestType", "1.0", child_policy="FAILING_POLICY")

    def test___diff_with_different_workflow_type(self):
        with patch.object(
            Layer1, "describe_workflow_type", mock_describe_workflow_type,
        ):
            workflow_type = WorkflowType(
                self.domain, "different-workflow-type", version="different-version"
            )
            diffs = workflow_type._diff()

            self.assertIsNotNone(diffs)
            self.assertLength(diffs, 6)

            self.assertTrue(hasattr(diffs[0], "attr"))
            self.assertTrue(hasattr(diffs[0], "local"))
            self.assertTrue(hasattr(diffs[0], "upstream"))

    def test_workflow_type__diff_with_identical_workflow_type(self):
        with patch.object(
            Layer1, "describe_workflow_type", mock_describe_workflow_type,
        ):
            mocked = mock_describe_workflow_type()
            workflow_type = WorkflowType(
                self.domain,
                name=mocked["typeInfo"]["workflowType"]["name"],
                version=mocked["typeInfo"]["workflowType"]["version"],
                status=mocked["typeInfo"]["status"],
                creation_date=mocked["typeInfo"]["creationDate"],
                deprecation_date=mocked["typeInfo"]["deprecationDate"],
                task_list=mocked["configuration"]["defaultTaskList"]["name"],
                child_policy=mocked["configuration"]["defaultChildPolicy"],
                execution_timeout=mocked["configuration"][
                    "defaultExecutionStartToCloseTimeout"
                ],
                decision_tasks_timeout=mocked["configuration"][
                    "defaultTaskStartToCloseTimeout"
                ],
                description=mocked["typeInfo"]["description"],
            )

            diffs = workflow_type._diff()

            self.assertLength(diffs, 0)

    def test_exists_with_existing_workflow_type(self):
        with patch.object(Layer1, "describe_workflow_type"):
            self.assertTrue(self.wt.exists)

    def test_exists_with_non_existent_workflow_type(self):
        with patch.object(self.wt.connection, "describe_workflow_type") as mock:
            mock.side_effect = SWFResponseError(
                400,
                "Bad Request:",
                {
                    "__type": "com.amazonaws.swf.base.model#UnknownResourceFault",
                    "message": "Unknown type: WorkflowType=[workflowId=blah, runId=test]",
                },
                "UnknownResourceFault",
            )

            self.assertFalse(self.wt.exists)

    # TODO: fix test when no network (probably hits real SWF endpoints)
    @unittest.skip("Skip it in case there's no network connection.")
    def test_workflow_type_exists_with_whatever_error(self):
        with patch.object(self.wt.connection, "describe_workflow_type") as mock:
            with self.assertRaises(ResponseError):
                mock.side_effect = SWFResponseError(
                    400,
                    "mocking exception",
                    {"__type": "WhateverError", "message": "Whatever"},
                )
                dummy = self.domain.exists

    def test_is_synced_with_unsynced_workflow_type(self):
        pass

    def test_is_synced_with_synced_workflow_type(self):
        pass

    def test_is_synced_over_non_existent_workflow_type(self):
        with patch.object(
            Layer1, "describe_workflow_type", mock_describe_workflow_type
        ):
            workflow_type = WorkflowType(
                self.domain,
                "non-existent-workflow-type",
                version="non-existent-version",
            )
            self.assertFalse(workflow_type.is_synced)

    def test_changes_with_different_workflow_type(self):
        with patch.object(
            Layer1, "describe_workflow_type", mock_describe_workflow_type,
        ):
            workflow_type = WorkflowType(
                self.domain,
                "different-workflow-type-type",
                version="different-workflow-type-type-version",
            )
            diffs = workflow_type.changes

            self.assertIsNotNone(diffs)
            self.assertLength(diffs, 6)

            self.assertTrue(hasattr(diffs[0], "attr"))
            self.assertTrue(hasattr(diffs[0], "local"))
            self.assertTrue(hasattr(diffs[0], "upstream"))

    def test_workflow_type_changes_with_identical_workflow_type(self):
        with patch.object(
            Layer1, "describe_workflow_type", mock_describe_workflow_type,
        ):
            mocked = mock_describe_workflow_type()
            workflow_type = WorkflowType(
                self.domain,
                name=mocked["typeInfo"]["workflowType"]["name"],
                version=mocked["typeInfo"]["workflowType"]["version"],
                status=mocked["typeInfo"]["status"],
                creation_date=mocked["typeInfo"]["creationDate"],
                deprecation_date=mocked["typeInfo"]["deprecationDate"],
                task_list=mocked["configuration"]["defaultTaskList"]["name"],
                child_policy=mocked["configuration"]["defaultChildPolicy"],
                execution_timeout=mocked["configuration"][
                    "defaultExecutionStartToCloseTimeout"
                ],
                decision_tasks_timeout=mocked["configuration"][
                    "defaultTaskStartToCloseTimeout"
                ],
                description=mocked["typeInfo"]["description"],
            )

            diffs = workflow_type.changes

            self.assertLength(diffs, 0)

    def test_save_already_existing_type(self):
        with patch.object(self.wt.connection, "register_workflow_type") as mock:
            with self.assertRaises(AlreadyExistsError):
                mock.side_effect = SWFTypeAlreadyExistsError(400, "mocked exception")
                self.wt.save()

    def test_save_with_response_error(self):
        with patch.object(self.wt.connection, "register_workflow_type") as mock:
            with self.assertRaises(DoesNotExistError):
                mock.side_effect = SWFResponseError(
                    400,
                    "mocked exception",
                    {"__type": "UnknownResourceFault", "message": "Whatever"},
                )
                self.wt.save()

    def test_delete_non_existent_type(self):
        with patch.object(self.wt.connection, "deprecate_workflow_type") as mock:
            with self.assertRaises(DoesNotExistError):
                mock.side_effect = SWFResponseError(
                    400,
                    "mocked exception",
                    {"__type": "UnknownResourceFault", "message": "Whatever"},
                )
                self.wt.delete()

    def test_delete_deprecated_type(self):
        with patch.object(self.wt.connection, "deprecate_workflow_type") as mock:
            with self.assertRaises(DoesNotExistError):
                mock.side_effect = SWFResponseError(
                    400,
                    "mocked exception",
                    {"__type": "TypeDeprecatedFault", "message": "Whatever"},
                )
                self.wt.delete()
Exemplo n.º 25
0
    def poll(self, task_list=None, identity=None, **kwargs):
        """
        Polls a decision task and returns the token and the full history of the
        workflow's events.

        :param task_list: task list to poll for decision tasks from.
        :type task_list: str

        :param identity: Identity of the decider making the request,
        which is recorded in the DecisionTaskStarted event in the
        workflow history.
        :type identity: str

        :returns: a Response object with history, token, and execution set
        :rtype: swf.responses.Response

        """
        task_list = task_list or self.task_list

        task = self.connection.poll_for_decision_task(self.domain.name,
                                                      task_list=task_list,
                                                      identity=identity,
                                                      **kwargs)
        token = task.get('taskToken')
        if token is None:
            raise PollTimeout("Decider poll timed out")

        events = task['events']

        next_page = task.get('nextPageToken')
        while next_page:
            try:
                task = self.connection.poll_for_decision_task(
                    self.domain.name,
                    task_list=task_list,
                    identity=identity,
                    next_page_token=next_page,
                    **kwargs)
            except boto.exception.SWFResponseError as e:
                if e.error_code == 'UnknownResourceFault':
                    raise DoesNotExistError(
                        "Unable to poll decision task",
                        e.body['message'],
                    )

                raise ResponseError(e.body['message'])

            token = task.get('taskToken')
            if token is None:
                raise PollTimeout("Decider poll timed out")

            events.extend(task['events'])
            next_page = task.get('nextPageToken')

        history = History.from_event_list(events)

        workflow_type = WorkflowType(
            domain=self.domain,
            name=task['workflowType']['name'],
            version=task['workflowType']['version'],
        )
        execution = WorkflowExecution(
            domain=self.domain,
            workflow_id=task['workflowExecution']['workflowId'],
            run_id=task['workflowExecution']['runId'],
            workflow_type=workflow_type,
        )

        # TODO: move history into execution (needs refactoring on WorkflowExecution.history())
        return Response(token=token, history=history, execution=execution)
Exemplo n.º 26
0
class TestWorkflowType(unittest.TestCase):
    def setUp(self):
        self.domain = Domain("test-domain")
        self.wt = WorkflowType(self.domain, "TestType", "1.0")

    def tearDown(self):
        pass

    def test_init_with_invalid_child_policy(self):
        with self.assertRaises(ValueError):
            WorkflowType(self.domain,
                         "TestType",
                         "1.0",
                         child_policy="FAILING_POLICY")

    def test___diff_with_different_workflow_type(self):
        with patch.object(
                Layer1,
                'describe_workflow_type',
                mock_describe_workflow_type,
        ):
            workflow_type = WorkflowType(self.domain,
                                         "different-workflow-type",
                                         version="different-version")
            diffs = workflow_type._diff()

            self.assertIsNotNone(diffs)
            self.assertEqual(len(diffs), 6)

            self.assertTrue(hasattr(diffs[0], 'attr'))
            self.assertTrue(hasattr(diffs[0], 'local'))
            self.assertTrue(hasattr(diffs[0], 'upstream'))

    def test_workflow_type__diff_with_identical_workflow_type(self):
        with patch.object(
                Layer1,
                'describe_workflow_type',
                mock_describe_workflow_type,
        ):
            mocked = mock_describe_workflow_type()
            workflow_type = WorkflowType(
                self.domain,
                name=mocked['typeInfo']['workflowType']['name'],
                version=mocked['typeInfo']['workflowType']['version'],
                status=mocked['typeInfo']['status'],
                creation_date=mocked['typeInfo']['creationDate'],
                deprecation_date=mocked['typeInfo']['deprecationDate'],
                task_list=mocked['configuration']['defaultTaskList']['name'],
                child_policy=mocked['configuration']['defaultChildPolicy'],
                execution_timeout=mocked['configuration']
                ['defaultExecutionStartToCloseTimeout'],
                decision_tasks_timeout=mocked['configuration']
                ['defaultTaskStartToCloseTimeout'],
                description=mocked['typeInfo']['description'],
            )

            diffs = workflow_type._diff()

            self.assertEqual(len(diffs), 0)

    def test_exists_with_existing_workflow_type(self):
        with patch.object(Layer1, 'describe_workflow_type'):
            self.assertTrue(self.wt.exists)

    def test_exists_with_non_existent_workflow_type(self):
        with patch.object(self.wt.connection,
                          'describe_workflow_type') as mock:
            mock.side_effect = SWFResponseError(
                400,
                "Bad Request:",
                {
                    '__type':
                    'com.amazonaws.swf.base.model#UnknownResourceFault',
                    'message':
                    'Unknown type: WorkflowType=[workflowId=blah, runId=test]'
                },
                'UnknownResourceFault',
            )

            self.assertFalse(self.wt.exists)

    def test_workflow_type_exists_with_whatever_error(self):
        with patch.object(self.wt.connection,
                          'describe_workflow_type') as mock:
            with self.assertRaises(ResponseError):
                mock.side_effect = SWFResponseError(400, "mocking exception", {
                    '__type': 'WhateverError',
                    'message': 'Whatever'
                })
                self.domain.exists

    def test_is_synced_with_unsynced_workflow_type(self):
        pass

    def test_is_synced_with_synced_workflow_type(self):
        pass

    def test_is_synced_over_non_existent_workflow_type(self):
        with patch.object(Layer1, 'describe_workflow_type',
                          mock_describe_workflow_type):
            workflow_type = WorkflowType(self.domain,
                                         "non-existent-workflow-type",
                                         version="non-existent-version")
            self.assertFalse(workflow_type.is_synced)

    def test_changes_with_different_workflow_type(self):
        with patch.object(
                Layer1,
                'describe_workflow_type',
                mock_describe_workflow_type,
        ):
            workflow_type = WorkflowType(
                self.domain,
                "different-workflow-type-type",
                version="different-workflow-type-type-version")
            diffs = workflow_type.changes

            self.assertIsNotNone(diffs)
            self.assertEqual(len(diffs), 6)

            self.assertTrue(hasattr(diffs[0], 'attr'))
            self.assertTrue(hasattr(diffs[0], 'local'))
            self.assertTrue(hasattr(diffs[0], 'upstream'))

    def test_workflow_type_changes_with_identical_workflow_type(self):
        with patch.object(
                Layer1,
                'describe_workflow_type',
                mock_describe_workflow_type,
        ):
            mocked = mock_describe_workflow_type()
            workflow_type = WorkflowType(
                self.domain,
                name=mocked['typeInfo']['workflowType']['name'],
                version=mocked['typeInfo']['workflowType']['version'],
                status=mocked['typeInfo']['status'],
                creation_date=mocked['typeInfo']['creationDate'],
                deprecation_date=mocked['typeInfo']['deprecationDate'],
                task_list=mocked['configuration']['defaultTaskList']['name'],
                child_policy=mocked['configuration']['defaultChildPolicy'],
                execution_timeout=mocked['configuration']
                ['defaultExecutionStartToCloseTimeout'],
                decision_tasks_timeout=mocked['configuration']
                ['defaultTaskStartToCloseTimeout'],
                description=mocked['typeInfo']['description'],
            )

            diffs = workflow_type.changes

            self.assertEqual(len(diffs), 0)

    def test_save_already_existing_type(self):
        with patch.object(self.wt.connection,
                          'register_workflow_type') as mock:
            with self.assertRaises(AlreadyExistsError):
                mock.side_effect = SWFTypeAlreadyExistsError(
                    400, "mocked exception")
                self.wt.save()

    def test_save_with_response_error(self):
        with patch.object(self.wt.connection,
                          'register_workflow_type') as mock:
            with self.assertRaises(DoesNotExistError):
                mock.side_effect = SWFResponseError(400, "mocked exception", {
                    "__type": "UnknownResourceFault",
                    "message": "Whatever"
                })
                self.wt.save()

    def test_delete_non_existent_type(self):
        with patch.object(self.wt.connection,
                          'deprecate_workflow_type') as mock:
            with self.assertRaises(DoesNotExistError):
                mock.side_effect = SWFResponseError(400, "mocked exception", {
                    "__type": "UnknownResourceFault",
                    "message": "Whatever"
                })
                self.wt.delete()

    def test_delete_deprecated_type(self):
        with patch.object(self.wt.connection,
                          'deprecate_workflow_type') as mock:
            with self.assertRaises(DoesNotExistError):
                mock.side_effect = SWFResponseError(400, "mocked exception", {
                    "__type": "TypeDeprecatedFault",
                    "message": "Whatever"
                })
                self.wt.delete()