Fix heartbeatTimeout of NONE and polling responses when there are no tasks (#3680)

* fix heartbeatTimeout of NONE resulting in ValueError and polling returning empty string taskToken when it shouldn't be returned

* fix expected taskToken in impacted tests

Co-authored-by: Clint Parham <cparham@aligntech.com>
This commit is contained in:
redparham 2021-02-12 08:01:42 -05:00 committed by GitHub
parent f246d4162f
commit b60de10c79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 28 additions and 13 deletions

View File

@ -73,7 +73,10 @@ class ActivityTask(BaseModel):
def first_timeout(self):
if not self.open or not self.workflow_execution.open:
return None
# TODO: handle the "NONE" case
if self.timeouts["heartbeatTimeout"] == "NONE":
return None
heartbeat_timeout_at = self.last_heartbeat_timestamp + int(
self.timeouts["heartbeatTimeout"]
)

View File

@ -446,9 +446,7 @@ class SWFResponse(BaseResponse):
if decision:
return json.dumps(decision.to_full_dict(reverse_order=reverse_order))
else:
return json.dumps(
{"previousStartedEventId": 0, "startedEventId": 0, "taskToken": ""}
)
return json.dumps({"previousStartedEventId": 0, "startedEventId": 0})
def count_pending_decision_tasks(self):
domain_name = self._params["domain"]
@ -482,7 +480,7 @@ class SWFResponse(BaseResponse):
if activity_task:
return json.dumps(activity_task.to_full_dict())
else:
return json.dumps({"startedEventId": 0, "taskToken": ""})
return json.dumps({"startedEventId": 0})
def count_pending_activity_tasks(self):
domain_name = self._params["domain"]

View File

@ -108,6 +108,24 @@ def test_activity_task_first_timeout():
task.timeout_type.should.equal("HEARTBEAT")
def test_activity_task_first_timeout_with_heartbeat_timeout_none():
wfe = make_workflow_execution()
activity_task_timeouts = ACTIVITY_TASK_TIMEOUTS.copy()
activity_task_timeouts["heartbeatTimeout"] = "NONE"
with freeze_time("2015-01-01 12:00:00"):
task = ActivityTask(
activity_id="my-activity-123",
activity_type="foo",
input="optional",
scheduled_event_id=117,
timeouts=activity_task_timeouts,
workflow_execution=wfe,
)
task.first_timeout().should.be.none
def test_activity_task_cannot_timeout_on_closed_workflow_execution():
with freeze_time("2015-01-01 12:00:00"):
wfe = make_workflow_execution()

View File

@ -35,14 +35,14 @@ def test_poll_for_activity_task_when_one():
def test_poll_for_activity_task_when_none():
conn = setup_workflow()
resp = conn.poll_for_activity_task("test-domain", "activity-task-list")
resp.should.equal({"startedEventId": 0, "taskToken": ""})
resp.should.equal({"startedEventId": 0})
@mock_swf_deprecated
def test_poll_for_activity_task_on_non_existent_queue():
conn = setup_workflow()
resp = conn.poll_for_activity_task("test-domain", "non-existent-queue")
resp.should.equal({"startedEventId": 0, "taskToken": ""})
resp.should.equal({"startedEventId": 0})
# CountPendingActivityTasks endpoint

View File

@ -62,18 +62,14 @@ def test_poll_for_decision_task_when_none():
resp = conn.poll_for_decision_task("test-domain", "queue")
# this is the DecisionTask representation you get from the real SWF
# after waiting 60s when there's no decision to be taken
resp.should.equal(
{"previousStartedEventId": 0, "startedEventId": 0, "taskToken": ""}
)
resp.should.equal({"previousStartedEventId": 0, "startedEventId": 0})
@mock_swf_deprecated
def test_poll_for_decision_task_on_non_existent_queue():
conn = setup_workflow()
resp = conn.poll_for_decision_task("test-domain", "non-existent-queue")
resp.should.equal(
{"previousStartedEventId": 0, "startedEventId": 0, "taskToken": ""}
)
resp.should.equal({"previousStartedEventId": 0, "startedEventId": 0})
@mock_swf_deprecated