From 369285b7ca1de06aaa296ea5d51482dad2492d83 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Wed, 26 Feb 2020 01:06:58 +1000 Subject: [PATCH 1/2] Don't 0-default previous started event ID Signed-off-by: Laurie O --- moto/swf/models/decision_task.py | 5 +++-- tests/test_swf/models/test_decision_task.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/moto/swf/models/decision_task.py b/moto/swf/models/decision_task.py index c8c9824a2..d7236a0ad 100644 --- a/moto/swf/models/decision_task.py +++ b/moto/swf/models/decision_task.py @@ -15,7 +15,7 @@ class DecisionTask(BaseModel): self.workflow_type = workflow_execution.workflow_type self.task_token = str(uuid.uuid4()) self.scheduled_event_id = scheduled_event_id - self.previous_started_event_id = 0 + self.previous_started_event_id = None self.started_event_id = None self.started_timestamp = None self.start_to_close_timeout = ( @@ -40,10 +40,11 @@ class DecisionTask(BaseModel): hsh = { "events": [evt.to_dict() for evt in events], "taskToken": self.task_token, - "previousStartedEventId": self.previous_started_event_id, "workflowExecution": self.workflow_execution.to_short_dict(), "workflowType": self.workflow_type.to_short_dict(), } + if self.previous_started_event_id is not None: + hsh["previousStartedEventId"] = self.previous_started_event_id if self.started_event_id: hsh["startedEventId"] = self.started_event_id return hsh diff --git a/tests/test_swf/models/test_decision_task.py b/tests/test_swf/models/test_decision_task.py index 0661adffb..8296f0472 100644 --- a/tests/test_swf/models/test_decision_task.py +++ b/tests/test_swf/models/test_decision_task.py @@ -24,7 +24,7 @@ def test_decision_task_full_dict_representation(): fd = dt.to_full_dict() fd["events"].should.be.a("list") - fd["previousStartedEventId"].should.equal(0) + fd.should_not.contain("previousStartedEventId") fd.should_not.contain("startedEventId") fd.should.contain("taskToken") fd["workflowExecution"].should.equal(wfe.to_short_dict()) From 209c9997061b88d11ba62e700d5df05b706345ef Mon Sep 17 00:00:00 2001 From: Laurie O Date: Wed, 26 Feb 2020 01:08:03 +1000 Subject: [PATCH 2/2] Keep track of previous started event ID Closes #2107 Signed-off-by: Laurie O --- moto/swf/models/decision_task.py | 3 ++- moto/swf/models/workflow_execution.py | 4 +++- tests/test_swf/models/test_decision_task.py | 3 ++- .../test_swf/responses/test_decision_tasks.py | 24 +++++++++++++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/moto/swf/models/decision_task.py b/moto/swf/models/decision_task.py index d7236a0ad..aaf810f08 100644 --- a/moto/swf/models/decision_task.py +++ b/moto/swf/models/decision_task.py @@ -49,10 +49,11 @@ class DecisionTask(BaseModel): hsh["startedEventId"] = self.started_event_id return hsh - def start(self, started_event_id): + def start(self, started_event_id, previous_started_event_id=None): self.state = "STARTED" self.started_timestamp = unix_time() self.started_event_id = started_event_id + self.previous_started_event_id = previous_started_event_id def complete(self): self._check_workflow_execution_open() diff --git a/moto/swf/models/workflow_execution.py b/moto/swf/models/workflow_execution.py index 17ce819fb..035a47558 100644 --- a/moto/swf/models/workflow_execution.py +++ b/moto/swf/models/workflow_execution.py @@ -82,6 +82,7 @@ class WorkflowExecution(BaseModel): self._events = [] # child workflows self.child_workflow_executions = [] + self._previous_started_event_id = None def __repr__(self): return "WorkflowExecution(run_id: {0})".format(self.run_id) @@ -295,7 +296,8 @@ class WorkflowExecution(BaseModel): scheduled_event_id=dt.scheduled_event_id, identity=identity, ) - dt.start(evt.event_id) + dt.start(evt.event_id, self._previous_started_event_id) + self._previous_started_event_id = evt.event_id def complete_decision_task( self, task_token, decisions=None, execution_context=None diff --git a/tests/test_swf/models/test_decision_task.py b/tests/test_swf/models/test_decision_task.py index 8296f0472..8ddb230e2 100644 --- a/tests/test_swf/models/test_decision_task.py +++ b/tests/test_swf/models/test_decision_task.py @@ -30,9 +30,10 @@ def test_decision_task_full_dict_representation(): fd["workflowExecution"].should.equal(wfe.to_short_dict()) fd["workflowType"].should.equal(wft.to_short_dict()) - dt.start(1234) + dt.start(1234, 1230) fd = dt.to_full_dict() fd["startedEventId"].should.equal(1234) + fd["previousStartedEventId"].should.equal(1230) def test_decision_task_first_timeout(): diff --git a/tests/test_swf/responses/test_decision_tasks.py b/tests/test_swf/responses/test_decision_tasks.py index 6389536e6..6493302f9 100644 --- a/tests/test_swf/responses/test_decision_tasks.py +++ b/tests/test_swf/responses/test_decision_tasks.py @@ -30,6 +30,30 @@ def test_poll_for_decision_task_when_one(): ) +@mock_swf_deprecated +def test_poll_for_decision_task_previous_started_event_id(): + conn = setup_workflow() + + resp = conn.poll_for_decision_task("test-domain", "queue") + assert resp["workflowExecution"]["runId"] == conn.run_id + assert "previousStartedEventId" not in resp + + # Require a failing decision, in this case a non-existant activity type + attrs = { + "activityId": "spam", + "activityType": {"name": "test-activity", "version": "v1.42"}, + "taskList": "eggs", + } + decision = { + "decisionType": "ScheduleActivityTask", + "scheduleActivityTaskDecisionAttributes": attrs, + } + conn.respond_decision_task_completed(resp["taskToken"], decisions=[decision]) + resp = conn.poll_for_decision_task("test-domain", "queue") + assert resp["workflowExecution"]["runId"] == conn.run_id + assert resp["previousStartedEventId"] == 3 + + @mock_swf_deprecated def test_poll_for_decision_task_when_none(): conn = setup_workflow()