Rewrite deprecated SWF tests (#3891)

This commit is contained in:
Bert Blommers 2021-09-21 22:00:20 +00:00 committed by GitHub
parent f7ce1c73fe
commit 5b10671af4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 1851 additions and 5 deletions

View File

@ -1,14 +1,20 @@
from boto.swf.exceptions import SWFResponseError from boto.swf.exceptions import SWFResponseError
from botocore.exceptions import ClientError
from freezegun import freeze_time from freezegun import freeze_time
from unittest import SkipTest
import pytest
import sure # noqa import sure # noqa
from moto import mock_swf_deprecated from moto import mock_swf, mock_swf_deprecated
from moto import settings
from moto.swf import swf_backend from moto.swf import swf_backend
from ..utils import setup_workflow, SCHEDULE_ACTIVITY_TASK_DECISION from ..utils import setup_workflow, SCHEDULE_ACTIVITY_TASK_DECISION
from ..utils import setup_workflow_boto3
# PollForActivityTask endpoint # PollForActivityTask endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_poll_for_activity_task_when_one(): def test_poll_for_activity_task_when_one():
conn = setup_workflow() conn = setup_workflow()
@ -31,6 +37,34 @@ def test_poll_for_activity_task_when_one():
) )
@mock_swf
def test_poll_for_activity_task_when_one_boto3():
client = setup_workflow_boto3()
decision_token = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)["taskToken"]
client.respond_decision_task_completed(
taskToken=decision_token, decisions=[SCHEDULE_ACTIVITY_TASK_DECISION]
)
resp = client.poll_for_activity_task(
domain="test-domain",
taskList={"name": "activity-task-list"},
identity="surprise",
)
resp["activityId"].should.equal("my-activity-001")
resp["taskToken"].should_not.be.none
resp = client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
resp["events"][-1]["eventType"].should.equal("ActivityTaskStarted")
resp["events"][-1]["activityTaskStartedEventAttributes"].should.equal(
{"identity": "surprise", "scheduledEventId": 5}
)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_poll_for_activity_task_when_none(): def test_poll_for_activity_task_when_none():
conn = setup_workflow() conn = setup_workflow()
@ -38,6 +72,7 @@ def test_poll_for_activity_task_when_none():
resp.should.equal({"startedEventId": 0}) resp.should.equal({"startedEventId": 0})
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_poll_for_activity_task_on_non_existent_queue(): def test_poll_for_activity_task_on_non_existent_queue():
conn = setup_workflow() conn = setup_workflow()
@ -45,7 +80,20 @@ def test_poll_for_activity_task_on_non_existent_queue():
resp.should.equal({"startedEventId": 0}) resp.should.equal({"startedEventId": 0})
@pytest.mark.parametrize("task_name", ["activity-task-list", "non-existent-queue"])
@mock_swf
def test_poll_for_activity_task_when_none_boto3(task_name):
client = setup_workflow_boto3()
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": task_name}
)
resp.shouldnt.have.key("taskToken")
resp.should.have.key("startedEventId").equal(0)
resp.should.have.key("previousStartedEventId").equal(0)
# CountPendingActivityTasks endpoint # CountPendingActivityTasks endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_count_pending_activity_tasks(): def test_count_pending_activity_tasks():
conn = setup_workflow() conn = setup_workflow()
@ -58,6 +106,7 @@ def test_count_pending_activity_tasks():
resp.should.equal({"count": 1, "truncated": False}) resp.should.equal({"count": 1, "truncated": False})
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_count_pending_decision_tasks_on_non_existent_task_list(): def test_count_pending_decision_tasks_on_non_existent_task_list():
conn = setup_workflow() conn = setup_workflow()
@ -65,7 +114,28 @@ def test_count_pending_decision_tasks_on_non_existent_task_list():
resp.should.equal({"count": 0, "truncated": False}) resp.should.equal({"count": 0, "truncated": False})
@pytest.mark.parametrize(
"task_name,cnt", [("activity-task-list", 1), ("non-existent", 0)]
)
@mock_swf
def test_count_pending_activity_tasks_boto3(task_name, cnt):
client = setup_workflow_boto3()
decision_token = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)["taskToken"]
client.respond_decision_task_completed(
taskToken=decision_token, decisions=[SCHEDULE_ACTIVITY_TASK_DECISION]
)
resp = client.count_pending_activity_tasks(
domain="test-domain", taskList={"name": task_name}
)
resp.should.have.key("count").equal(cnt)
resp.should.have.key("truncated").equal(False)
# RespondActivityTaskCompleted endpoint # RespondActivityTaskCompleted endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_respond_activity_task_completed(): def test_respond_activity_task_completed():
conn = setup_workflow() conn = setup_workflow()
@ -91,6 +161,34 @@ def test_respond_activity_task_completed():
) )
@mock_swf
def test_respond_activity_task_completed_boto3():
client = setup_workflow_boto3()
decision_token = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)["taskToken"]
client.respond_decision_task_completed(
taskToken=decision_token, decisions=[SCHEDULE_ACTIVITY_TASK_DECISION]
)
activity_token = client.poll_for_activity_task(
domain="test-domain", taskList={"name": "activity-task-list"}
)["taskToken"]
client.respond_activity_task_completed(
taskToken=activity_token, result="result of the task"
)
resp = client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
resp["events"][-2]["eventType"].should.equal("ActivityTaskCompleted")
resp["events"][-2]["activityTaskCompletedEventAttributes"].should.equal(
{"result": "result of the task", "scheduledEventId": 5, "startedEventId": 6}
)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_respond_activity_task_completed_on_closed_workflow_execution(): def test_respond_activity_task_completed_on_closed_workflow_execution():
conn = setup_workflow() conn = setup_workflow()
@ -113,6 +211,33 @@ def test_respond_activity_task_completed_on_closed_workflow_execution():
) )
@mock_swf
def test_respond_activity_task_completed_on_closed_workflow_execution_boto3():
client = setup_workflow_boto3()
decision_token = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)["taskToken"]
client.respond_decision_task_completed(
taskToken=decision_token, decisions=[SCHEDULE_ACTIVITY_TASK_DECISION]
)
activity_token = client.poll_for_activity_task(
domain="test-domain", taskList={"name": "activity-task-list"}
)["taskToken"]
client.terminate_workflow_execution(domain="test-domain", workflowId="uid-abcd1234")
with pytest.raises(ClientError) as ex:
client.respond_activity_task_completed(taskToken=activity_token)
ex.value.response["Error"]["Code"].should.equal("UnknownResourceFault")
ex.value.response["Error"]["Message"].should.equal(
"Unknown execution: WorkflowExecution=[workflowId=uid-abcd1234, runId={}]".format(
client.run_id
)
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_respond_activity_task_completed_with_task_already_completed(): def test_respond_activity_task_completed_with_task_already_completed():
conn = setup_workflow() conn = setup_workflow()
@ -131,7 +256,32 @@ def test_respond_activity_task_completed_with_task_already_completed():
) )
@mock_swf
def test_respond_activity_task_completed_with_task_already_completed_boto3():
client = setup_workflow_boto3()
decision_token = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)["taskToken"]
client.respond_decision_task_completed(
taskToken=decision_token, decisions=[SCHEDULE_ACTIVITY_TASK_DECISION]
)
activity_token = client.poll_for_activity_task(
domain="test-domain", taskList={"name": "activity-task-list"}
)["taskToken"]
client.respond_activity_task_completed(taskToken=activity_token)
with pytest.raises(ClientError) as ex:
client.respond_activity_task_completed(taskToken=activity_token)
ex.value.response["Error"]["Code"].should.equal("UnknownResourceFault")
ex.value.response["Error"]["Message"].should.equal(
"Unknown activity, scheduledEventId = 5"
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# RespondActivityTaskFailed endpoint # RespondActivityTaskFailed endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_respond_activity_task_failed(): def test_respond_activity_task_failed():
conn = setup_workflow() conn = setup_workflow()
@ -162,6 +312,39 @@ def test_respond_activity_task_failed():
) )
@mock_swf
def test_respond_activity_task_failed_boto3():
client = setup_workflow_boto3()
decision_token = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)["taskToken"]
client.respond_decision_task_completed(
taskToken=decision_token, decisions=[SCHEDULE_ACTIVITY_TASK_DECISION]
)
activity_token = client.poll_for_activity_task(
domain="test-domain", taskList={"name": "activity-task-list"}
)["taskToken"]
client.respond_activity_task_failed(
taskToken=activity_token, reason="short reason", details="long details"
)
resp = client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
resp["events"][-2]["eventType"].should.equal("ActivityTaskFailed")
resp["events"][-2]["activityTaskFailedEventAttributes"].should.equal(
{
"reason": "short reason",
"details": "long details",
"scheduledEventId": 5,
"startedEventId": 6,
}
)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_respond_activity_task_completed_with_wrong_token(): def test_respond_activity_task_completed_with_wrong_token():
# NB: we just test ONE failure case for RespondActivityTaskFailed # NB: we just test ONE failure case for RespondActivityTaskFailed
@ -178,7 +361,31 @@ def test_respond_activity_task_completed_with_wrong_token():
).should.throw(SWFResponseError, "Invalid token") ).should.throw(SWFResponseError, "Invalid token")
@mock_swf
def test_respond_activity_task_completed_with_wrong_token_boto3():
# NB: we just test ONE failure case for RespondActivityTaskFailed
# because the safeguards are shared with RespondActivityTaskCompleted, so
# no need to retest everything end-to-end.
client = setup_workflow_boto3()
decision_token = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)["taskToken"]
client.respond_decision_task_completed(
taskToken=decision_token, decisions=[SCHEDULE_ACTIVITY_TASK_DECISION]
)
client.poll_for_activity_task(
domain="test-domain", taskList={"name": "activity-task-list"}
)["taskToken"]
with pytest.raises(ClientError) as ex:
client.respond_activity_task_failed(taskToken="not-a-correct-token")
ex.value.response["Error"]["Code"].should.equal("ValidationException")
ex.value.response["Error"]["Message"].should.equal("Invalid token")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# RecordActivityTaskHeartbeat endpoint # RecordActivityTaskHeartbeat endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_record_activity_task_heartbeat(): def test_record_activity_task_heartbeat():
conn = setup_workflow() conn = setup_workflow()
@ -194,6 +401,24 @@ def test_record_activity_task_heartbeat():
resp.should.equal({"cancelRequested": False}) resp.should.equal({"cancelRequested": False})
@mock_swf
def test_record_activity_task_heartbeat_boto3():
client = setup_workflow_boto3()
decision_token = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)["taskToken"]
client.respond_decision_task_completed(
taskToken=decision_token, decisions=[SCHEDULE_ACTIVITY_TASK_DECISION]
)
activity_token = client.poll_for_activity_task(
domain="test-domain", taskList={"name": "activity-task-list"}
)["taskToken"]
resp = client.record_activity_task_heartbeat(taskToken=activity_token)
resp.should.have.key("cancelRequested").equal(False)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_record_activity_task_heartbeat_with_wrong_token(): def test_record_activity_task_heartbeat_with_wrong_token():
conn = setup_workflow() conn = setup_workflow()
@ -208,6 +433,27 @@ def test_record_activity_task_heartbeat_with_wrong_token():
).should.throw(SWFResponseError) ).should.throw(SWFResponseError)
@mock_swf
def test_record_activity_task_heartbeat_with_wrong_token_boto3():
client = setup_workflow_boto3()
decision_token = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)["taskToken"]
client.respond_decision_task_completed(
taskToken=decision_token, decisions=[SCHEDULE_ACTIVITY_TASK_DECISION]
)
client.poll_for_activity_task(
domain="test-domain", taskList={"name": "activity-task-list"}
)["taskToken"]
with pytest.raises(ClientError) as ex:
client.record_activity_task_heartbeat(taskToken="bad-token")
ex.value.response["Error"]["Code"].should.equal("ValidationException")
ex.value.response["Error"]["Message"].should.equal("Invalid token")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_record_activity_task_heartbeat_sets_details_in_case_of_timeout(): def test_record_activity_task_heartbeat_sets_details_in_case_of_timeout():
conn = setup_workflow() conn = setup_workflow()
@ -231,3 +477,34 @@ def test_record_activity_task_heartbeat_sets_details_in_case_of_timeout():
resp["events"][-2]["eventType"].should.equal("ActivityTaskTimedOut") resp["events"][-2]["eventType"].should.equal("ActivityTaskTimedOut")
attrs = resp["events"][-2]["activityTaskTimedOutEventAttributes"] attrs = resp["events"][-2]["activityTaskTimedOutEventAttributes"]
attrs["details"].should.equal("some progress details") attrs["details"].should.equal("some progress details")
@mock_swf
def test_record_activity_task_heartbeat_sets_details_in_case_of_timeout_boto3():
if settings.TEST_SERVER_MODE:
raise SkipTest("Unable to manipulate time in ServerMode")
client = setup_workflow_boto3()
decision_token = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)["taskToken"]
client.respond_decision_task_completed(
taskToken=decision_token, decisions=[SCHEDULE_ACTIVITY_TASK_DECISION]
)
with freeze_time("2015-01-01 12:00:00"):
activity_token = client.poll_for_activity_task(
domain="test-domain", taskList={"name": "activity-task-list"}
)["taskToken"]
client.record_activity_task_heartbeat(
taskToken=activity_token, details="some progress details"
)
with freeze_time("2015-01-01 12:05:30"):
# => Activity Task Heartbeat timeout reached!!
resp = client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
resp["events"][-2]["eventType"].should.equal("ActivityTaskTimedOut")
attrs = resp["events"][-2]["activityTaskTimedOutEventAttributes"]
attrs["details"].should.equal("some progress details")

View File

@ -2,6 +2,7 @@ import boto
from boto.swf.exceptions import SWFResponseError from boto.swf.exceptions import SWFResponseError
import boto3 import boto3
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
import pytest
import sure # noqa import sure # noqa
from moto import mock_swf_deprecated from moto import mock_swf_deprecated
@ -9,6 +10,7 @@ from moto import mock_swf
# RegisterActivityType endpoint # RegisterActivityType endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_register_activity_type(): def test_register_activity_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -21,6 +23,26 @@ def test_register_activity_type():
actype["activityType"]["version"].should.equal("v1.0") actype["activityType"]["version"].should.equal("v1.0")
@mock_swf
def test_register_activity_type_boto3():
client = boto3.client("swf", region_name="us-west-2")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60"
)
client.register_activity_type(
domain="test-domain", name="test-activity", version="v1.0"
)
types = client.list_activity_types(
domain="test-domain", registrationStatus="REGISTERED"
)["typeInfos"]
types.should.have.length_of(1)
actype = types[0]
actype["activityType"]["name"].should.equal("test-activity")
actype["activityType"]["version"].should.equal("v1.0")
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_register_already_existing_activity_type(): def test_register_already_existing_activity_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -32,6 +54,28 @@ def test_register_already_existing_activity_type():
).should.throw(SWFResponseError) ).should.throw(SWFResponseError)
@mock_swf
def test_register_already_existing_activity_type_boto3():
client = boto3.client("swf", region_name="us-west-2")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60"
)
client.register_activity_type(
domain="test-domain", name="test-activity", version="v1.0"
)
with pytest.raises(ClientError) as ex:
client.register_activity_type(
domain="test-domain", name="test-activity", version="v1.0"
)
ex.value.response["Error"]["Code"].should.equal("TypeAlreadyExistsFault")
ex.value.response["Error"]["Message"].should.equal(
"ActivityType=[name=test-activity, version=v1.0]"
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_register_with_wrong_parameter_type(): def test_register_with_wrong_parameter_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -43,6 +87,7 @@ def test_register_with_wrong_parameter_type():
# ListActivityTypes endpoint # ListActivityTypes endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_list_activity_types(): def test_list_activity_types():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -59,6 +104,33 @@ def test_list_activity_types():
names.should.equal(["a-test-activity", "b-test-activity", "c-test-activity"]) names.should.equal(["a-test-activity", "b-test-activity", "c-test-activity"])
# ListActivityTypes endpoint
@mock_swf
def test_list_activity_types_boto3():
client = boto3.client("swf", region_name="us-west-2")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60"
)
client.register_activity_type(
domain="test-domain", name="b-test-activity", version="v1.0"
)
client.register_activity_type(
domain="test-domain", name="a-test-activity", version="v1.0"
)
client.register_activity_type(
domain="test-domain", name="c-test-activity", version="v1.0"
)
types = client.list_activity_types(
domain="test-domain", registrationStatus="REGISTERED"
)
names = [
activity_type["activityType"]["name"] for activity_type in types["typeInfos"]
]
names.should.equal(["a-test-activity", "b-test-activity", "c-test-activity"])
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_list_activity_types_reverse_order(): def test_list_activity_types_reverse_order():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -77,7 +149,34 @@ def test_list_activity_types_reverse_order():
names.should.equal(["c-test-activity", "b-test-activity", "a-test-activity"]) names.should.equal(["c-test-activity", "b-test-activity", "a-test-activity"])
@mock_swf
def test_list_activity_types_reverse_order_boto3():
client = boto3.client("swf", region_name="us-west-2")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60"
)
client.register_activity_type(
domain="test-domain", name="b-test-activity", version="v1.0"
)
client.register_activity_type(
domain="test-domain", name="a-test-activity", version="v1.0"
)
client.register_activity_type(
domain="test-domain", name="c-test-activity", version="v1.0"
)
types = client.list_activity_types(
domain="test-domain", registrationStatus="REGISTERED", reverseOrder=True
)
names = [
activity_type["activityType"]["name"] for activity_type in types["typeInfos"]
]
names.should.equal(["c-test-activity", "b-test-activity", "a-test-activity"])
# DeprecateActivityType endpoint # DeprecateActivityType endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_deprecate_activity_type(): def test_deprecate_activity_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -91,6 +190,30 @@ def test_deprecate_activity_type():
actype["activityType"]["version"].should.equal("v1.0") actype["activityType"]["version"].should.equal("v1.0")
# DeprecateActivityType endpoint
@mock_swf
def test_deprecate_activity_type_boto3():
client = boto3.client("swf", region_name="us-west-2")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60"
)
client.register_activity_type(
domain="test-domain", name="test-activity", version="v1.0"
)
client.deprecate_activity_type(
domain="test-domain", activityType={"name": "test-activity", "version": "v1.0"}
)
types = client.list_activity_types(
domain="test-domain", registrationStatus="DEPRECATED"
)
types.should.have.key("typeInfos").being.length_of(1)
actype = types["typeInfos"][0]
actype["activityType"]["name"].should.equal("test-activity")
actype["activityType"]["version"].should.equal("v1.0")
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_deprecate_already_deprecated_activity_type(): def test_deprecate_already_deprecated_activity_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -103,6 +226,32 @@ def test_deprecate_already_deprecated_activity_type():
).should.throw(SWFResponseError) ).should.throw(SWFResponseError)
@mock_swf
def test_deprecate_already_deprecated_activity_type_boto3():
client = boto3.client("swf", region_name="us-west-2")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60"
)
client.register_activity_type(
domain="test-domain", name="test-activity", version="v1.0"
)
client.deprecate_activity_type(
domain="test-domain", activityType={"name": "test-activity", "version": "v1.0"}
)
with pytest.raises(ClientError) as ex:
client.deprecate_activity_type(
domain="test-domain",
activityType={"name": "test-activity", "version": "v1.0"},
)
ex.value.response["Error"]["Code"].should.equal("TypeDeprecatedFault")
ex.value.response["Error"]["Message"].should.equal(
"ActivityType=[name=test-activity, version=v1.0]"
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_deprecate_non_existent_activity_type(): def test_deprecate_non_existent_activity_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -113,6 +262,25 @@ def test_deprecate_non_existent_activity_type():
).should.throw(SWFResponseError) ).should.throw(SWFResponseError)
@mock_swf
def test_deprecate_non_existent_activity_type_boto3():
client = boto3.client("swf", region_name="us-west-2")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60"
)
with pytest.raises(ClientError) as ex:
client.deprecate_activity_type(
domain="test-domain",
activityType={"name": "test-activity", "version": "v1.0"},
)
ex.value.response["Error"]["Code"].should.equal("UnknownResourceFault")
ex.value.response["Error"]["Message"].should.equal(
"Unknown type: ActivityType=[name=test-activity, version=v1.0]"
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# DeprecateActivityType endpoint # DeprecateActivityType endpoint
@mock_swf @mock_swf
def test_undeprecate_activity_type(): def test_undeprecate_activity_type():
@ -185,6 +353,7 @@ def test_undeprecate_non_existent_activity_type():
# DescribeActivityType endpoint # DescribeActivityType endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_describe_activity_type(): def test_describe_activity_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -205,6 +374,31 @@ def test_describe_activity_type():
infos["status"].should.equal("REGISTERED") infos["status"].should.equal("REGISTERED")
@mock_swf
def test_describe_activity_type_boto3():
client = boto3.client("swf", region_name="us-east-1")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60"
)
client.register_activity_type(
domain="test-domain",
name="test-activity",
version="v1.0",
defaultTaskList={"name": "foo"},
defaultTaskHeartbeatTimeout="32",
)
actype = client.describe_activity_type(
domain="test-domain", activityType={"name": "test-activity", "version": "v1.0"}
)
actype["configuration"]["defaultTaskList"]["name"].should.equal("foo")
infos = actype["typeInfo"]
infos["activityType"]["name"].should.equal("test-activity")
infos["activityType"]["version"].should.equal("v1.0")
infos["status"].should.equal("REGISTERED")
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_describe_non_existent_activity_type(): def test_describe_non_existent_activity_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -213,3 +407,22 @@ def test_describe_non_existent_activity_type():
conn.describe_activity_type.when.called_with( conn.describe_activity_type.when.called_with(
"test-domain", "non-existent", "v1.0" "test-domain", "non-existent", "v1.0"
).should.throw(SWFResponseError) ).should.throw(SWFResponseError)
@mock_swf
def test_describe_non_existent_activity_type_boto3():
client = boto3.client("swf", region_name="us-east-1")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60"
)
with pytest.raises(ClientError) as ex:
client.describe_activity_type(
domain="test-domain",
activityType={"name": "test-activity", "version": "v1.0"},
)
ex.value.response["Error"]["Code"].should.equal("UnknownResourceFault")
ex.value.response["Error"]["Message"].should.equal(
"Unknown type: ActivityType=[name=test-activity, version=v1.0]"
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)

View File

@ -1,14 +1,18 @@
from boto.swf.exceptions import SWFResponseError from boto.swf.exceptions import SWFResponseError
from botocore.exceptions import ClientError
from datetime import datetime
from freezegun import freeze_time from freezegun import freeze_time
import pytest
import sure # noqa import sure # noqa
from moto import mock_swf_deprecated from moto import mock_swf_deprecated, mock_swf, settings
from moto.swf import swf_backend from moto.swf import swf_backend
from ..utils import setup_workflow from ..utils import setup_workflow, setup_workflow_boto3
# PollForDecisionTask endpoint # PollForDecisionTask endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_poll_for_decision_task_when_one(): def test_poll_for_decision_task_when_one():
conn = setup_workflow() conn = setup_workflow()
@ -30,6 +34,31 @@ def test_poll_for_decision_task_when_one():
) )
@mock_swf
def test_poll_for_decision_task_when_one_boto3():
client = setup_workflow_boto3()
resp = client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
types = [evt["eventType"] for evt in resp["events"]]
types.should.equal(["WorkflowExecutionStarted", "DecisionTaskScheduled"])
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}, identity="srv01"
)
types = [evt["eventType"] for evt in resp["events"]]
types.should.equal(
["WorkflowExecutionStarted", "DecisionTaskScheduled", "DecisionTaskStarted"]
)
resp["events"][-1]["decisionTaskStartedEventAttributes"]["identity"].should.equal(
"srv01"
)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_poll_for_decision_task_previous_started_event_id(): def test_poll_for_decision_task_previous_started_event_id():
conn = setup_workflow() conn = setup_workflow()
@ -54,6 +83,37 @@ def test_poll_for_decision_task_previous_started_event_id():
assert resp["previousStartedEventId"] == 3 assert resp["previousStartedEventId"] == 3
@mock_swf
def test_poll_for_decision_task_previous_started_event_id_boto3():
client = setup_workflow_boto3()
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)
assert resp["workflowExecution"]["runId"] == client.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": {"name": "eggs"},
}
decision = {
"decisionType": "ScheduleActivityTask",
"scheduleActivityTaskDecisionAttributes": attrs,
}
client.respond_decision_task_completed(
taskToken=resp["taskToken"], decisions=[decision]
)
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)
assert resp["workflowExecution"]["runId"] == client.run_id
assert resp["previousStartedEventId"] == 3
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_poll_for_decision_task_when_none(): def test_poll_for_decision_task_when_none():
conn = setup_workflow() conn = setup_workflow()
@ -65,6 +125,22 @@ def test_poll_for_decision_task_when_none():
resp.should.equal({"previousStartedEventId": 0, "startedEventId": 0}) resp.should.equal({"previousStartedEventId": 0, "startedEventId": 0})
@mock_swf
def test_poll_for_decision_task_when_none_boto3():
client = setup_workflow_boto3()
client.poll_for_decision_task(domain="test-domain", taskList={"name": "queue"})
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "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.have.key("previousStartedEventId").equal(0)
resp.should.have.key("startedEventId").equal(0)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_poll_for_decision_task_on_non_existent_queue(): def test_poll_for_decision_task_on_non_existent_queue():
conn = setup_workflow() conn = setup_workflow()
@ -72,6 +148,17 @@ def test_poll_for_decision_task_on_non_existent_queue():
resp.should.equal({"previousStartedEventId": 0, "startedEventId": 0}) resp.should.equal({"previousStartedEventId": 0, "startedEventId": 0})
@mock_swf
def test_poll_for_decision_task_on_non_existent_queue_boto3():
client = setup_workflow_boto3()
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "non-existent-queue"}
)
resp.should.have.key("previousStartedEventId").equal(0)
resp.should.have.key("startedEventId").equal(0)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_poll_for_decision_task_with_reverse_order(): def test_poll_for_decision_task_with_reverse_order():
conn = setup_workflow() conn = setup_workflow()
@ -82,7 +169,20 @@ def test_poll_for_decision_task_with_reverse_order():
) )
@mock_swf
def test_poll_for_decision_task_with_reverse_order_boto3():
client = setup_workflow_boto3()
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}, reverseOrder=True
)
types = [evt["eventType"] for evt in resp["events"]]
types.should.equal(
["DecisionTaskStarted", "DecisionTaskScheduled", "WorkflowExecutionStarted"]
)
# CountPendingDecisionTasks endpoint # CountPendingDecisionTasks endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_count_pending_decision_tasks(): def test_count_pending_decision_tasks():
conn = setup_workflow() conn = setup_workflow()
@ -91,6 +191,18 @@ def test_count_pending_decision_tasks():
resp.should.equal({"count": 1, "truncated": False}) resp.should.equal({"count": 1, "truncated": False})
@mock_swf
def test_count_pending_decision_tasks_boto3():
client = setup_workflow_boto3()
client.poll_for_decision_task(domain="test-domain", taskList={"name": "queue"})
resp = client.count_pending_decision_tasks(
domain="test-domain", taskList={"name": "queue"}
)
resp.should.have.key("count").equal(1)
resp.should.have.key("truncated").equal(False)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_count_pending_decision_tasks_on_non_existent_task_list(): def test_count_pending_decision_tasks_on_non_existent_task_list():
conn = setup_workflow() conn = setup_workflow()
@ -98,6 +210,17 @@ def test_count_pending_decision_tasks_on_non_existent_task_list():
resp.should.equal({"count": 0, "truncated": False}) resp.should.equal({"count": 0, "truncated": False})
@mock_swf
def test_count_pending_decision_tasks_on_non_existent_task_list_boto3():
client = setup_workflow_boto3()
resp = client.count_pending_decision_tasks(
domain="test-domain", taskList={"name": "non-existent"}
)
resp.should.have.key("count").equal(0)
resp.should.have.key("truncated").equal(False)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_count_pending_decision_tasks_after_decision_completes(): def test_count_pending_decision_tasks_after_decision_completes():
conn = setup_workflow() conn = setup_workflow()
@ -108,7 +231,23 @@ def test_count_pending_decision_tasks_after_decision_completes():
resp.should.equal({"count": 0, "truncated": False}) resp.should.equal({"count": 0, "truncated": False})
@mock_swf
def test_count_pending_decision_tasks_after_decision_completes_boto3():
client = setup_workflow_boto3()
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)
client.respond_decision_task_completed(taskToken=resp["taskToken"])
resp = client.count_pending_decision_tasks(
domain="test-domain", taskList={"name": "queue"}
)
resp.should.have.key("count").equal(0)
resp.should.have.key("truncated").equal(False)
# RespondDecisionTaskCompleted endpoint # RespondDecisionTaskCompleted endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_respond_decision_task_completed_with_no_decision(): def test_respond_decision_task_completed_with_no_decision():
conn = setup_workflow() conn = setup_workflow()
@ -146,6 +285,48 @@ def test_respond_decision_task_completed_with_no_decision():
resp["latestExecutionContext"].should.equal("free-form context") resp["latestExecutionContext"].should.equal("free-form context")
@mock_swf
def test_respond_decision_task_completed_with_no_decision_boto3():
client = setup_workflow_boto3()
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)
task_token = resp["taskToken"]
client.respond_decision_task_completed(
taskToken=task_token, executionContext="free-form context"
)
resp = client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
types = [evt["eventType"] for evt in resp["events"]]
types.should.equal(
[
"WorkflowExecutionStarted",
"DecisionTaskScheduled",
"DecisionTaskStarted",
"DecisionTaskCompleted",
]
)
evt = resp["events"][-1]
evt["decisionTaskCompletedEventAttributes"].should.equal(
{
"executionContext": "free-form context",
"scheduledEventId": 2,
"startedEventId": 3,
}
)
resp = client.describe_workflow_execution(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
resp["latestExecutionContext"].should.equal("free-form context")
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_respond_decision_task_completed_with_wrong_token(): def test_respond_decision_task_completed_with_wrong_token():
conn = setup_workflow() conn = setup_workflow()
@ -155,6 +336,18 @@ def test_respond_decision_task_completed_with_wrong_token():
).should.throw(SWFResponseError) ).should.throw(SWFResponseError)
@mock_swf
def test_respond_decision_task_completed_with_wrong_token_boto3():
client = setup_workflow_boto3()
client.poll_for_decision_task(domain="test-domain", taskList={"name": "queue"})
with pytest.raises(ClientError) as ex:
client.respond_decision_task_completed(taskToken="not-a-correct-token")
ex.value.response["Error"]["Code"].should.equal("ValidationException")
ex.value.response["Error"]["Message"].should.equal("Invalid token")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_respond_decision_task_completed_on_close_workflow_execution(): def test_respond_decision_task_completed_on_close_workflow_execution():
conn = setup_workflow() conn = setup_workflow()
@ -172,6 +365,28 @@ def test_respond_decision_task_completed_on_close_workflow_execution():
) )
@mock_swf
def test_respond_decision_task_completed_on_close_workflow_execution_boto3():
client = setup_workflow_boto3()
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)
task_token = resp["taskToken"]
client.terminate_workflow_execution(domain="test-domain", workflowId="uid-abcd1234")
with pytest.raises(ClientError) as ex:
client.respond_decision_task_completed(taskToken=task_token)
ex.value.response["Error"]["Code"].should.equal("UnknownResourceFault")
ex.value.response["Error"]["Message"].should.equal(
"Unknown execution: WorkflowExecution=[workflowId=uid-abcd1234, runId={}]".format(
client.run_id
)
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_respond_decision_task_completed_with_task_already_completed(): def test_respond_decision_task_completed_with_task_already_completed():
conn = setup_workflow() conn = setup_workflow()
@ -184,6 +399,25 @@ def test_respond_decision_task_completed_with_task_already_completed():
) )
@mock_swf
def test_respond_decision_task_completed_with_task_already_completed_boto3():
client = setup_workflow_boto3()
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)
task_token = resp["taskToken"]
client.respond_decision_task_completed(taskToken=task_token)
with pytest.raises(ClientError) as ex:
client.respond_decision_task_completed(taskToken=task_token)
ex.value.response["Error"]["Code"].should.equal("UnknownResourceFault")
ex.value.response["Error"]["Message"].should.equal(
"Unknown decision task, scheduledEventId = 2"
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_respond_decision_task_completed_with_complete_workflow_execution(): def test_respond_decision_task_completed_with_complete_workflow_execution():
conn = setup_workflow() conn = setup_workflow()
@ -217,6 +451,42 @@ def test_respond_decision_task_completed_with_complete_workflow_execution():
].should.equal("foo bar") ].should.equal("foo bar")
@mock_swf
def test_respond_decision_task_completed_with_complete_workflow_execution_boto3():
client = setup_workflow_boto3()
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)
task_token = resp["taskToken"]
decisions = [
{
"decisionType": "CompleteWorkflowExecution",
"completeWorkflowExecutionDecisionAttributes": {"result": "foo bar"},
}
]
client.respond_decision_task_completed(taskToken=task_token, decisions=decisions)
resp = client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
types = [evt["eventType"] for evt in resp["events"]]
types.should.equal(
[
"WorkflowExecutionStarted",
"DecisionTaskScheduled",
"DecisionTaskStarted",
"DecisionTaskCompleted",
"WorkflowExecutionCompleted",
]
)
resp["events"][-1]["workflowExecutionCompletedEventAttributes"][
"result"
].should.equal("foo bar")
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_respond_decision_task_completed_with_close_decision_not_last(): def test_respond_decision_task_completed_with_close_decision_not_last():
conn = setup_workflow() conn = setup_workflow()
@ -233,6 +503,31 @@ def test_respond_decision_task_completed_with_close_decision_not_last():
).should.throw(SWFResponseError, r"Close must be last decision in list") ).should.throw(SWFResponseError, r"Close must be last decision in list")
@mock_swf
def test_respond_decision_task_completed_with_close_decision_not_last_boto3():
client = setup_workflow_boto3()
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)
task_token = resp["taskToken"]
decisions = [
{"decisionType": "CompleteWorkflowExecution"},
{"decisionType": "WeDontCare"},
]
with pytest.raises(ClientError) as ex:
client.respond_decision_task_completed(
taskToken=task_token, decisions=decisions
)
ex.value.response["Error"]["Code"].should.equal("ValidationException")
ex.value.response["Error"]["Message"].should.equal(
"Close must be last decision in list"
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_respond_decision_task_completed_with_invalid_decision_type(): def test_respond_decision_task_completed_with_invalid_decision_type():
conn = setup_workflow() conn = setup_workflow()
@ -252,6 +547,31 @@ def test_respond_decision_task_completed_with_invalid_decision_type():
) )
@mock_swf
def test_respond_decision_task_completed_with_invalid_decision_type_boto3():
client = setup_workflow_boto3()
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)
task_token = resp["taskToken"]
decisions = [
{"decisionType": "BadDecisionType"},
{"decisionType": "CompleteWorkflowExecution"},
]
with pytest.raises(ClientError) as ex:
client.respond_decision_task_completed(
taskToken=task_token, decisions=decisions
)
ex.value.response["Error"]["Code"].should.equal("ValidationException")
ex.value.response["Error"]["Message"].should.match(
"Value 'BadDecisionType' at 'decisions.1.member.decisionType'"
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_respond_decision_task_completed_with_missing_attributes(): def test_respond_decision_task_completed_with_missing_attributes():
conn = setup_workflow() conn = setup_workflow()
@ -274,6 +594,7 @@ def test_respond_decision_task_completed_with_missing_attributes():
) )
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_respond_decision_task_completed_with_missing_attributes_totally(): def test_respond_decision_task_completed_with_missing_attributes_totally():
conn = setup_workflow() conn = setup_workflow()
@ -291,6 +612,28 @@ def test_respond_decision_task_completed_with_missing_attributes_totally():
) )
@mock_swf
def test_respond_decision_task_completed_with_missing_attributes_totally_boto3():
client = setup_workflow_boto3()
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)
task_token = resp["taskToken"]
decisions = [{"decisionType": "StartTimer"}]
with pytest.raises(ClientError) as ex:
client.respond_decision_task_completed(
taskToken=task_token, decisions=decisions
)
ex.value.response["Error"]["Code"].should.equal("ValidationException")
ex.value.response["Error"]["Message"].should.match(
"Value null at 'decisions.1.member.startTimerDecisionAttributes.timerId' failed to satisfy constraint"
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_respond_decision_task_completed_with_fail_workflow_execution(): def test_respond_decision_task_completed_with_fail_workflow_execution():
conn = setup_workflow() conn = setup_workflow()
@ -327,6 +670,45 @@ def test_respond_decision_task_completed_with_fail_workflow_execution():
attrs["details"].should.equal("foo") attrs["details"].should.equal("foo")
@mock_swf
def test_respond_decision_task_completed_with_fail_workflow_execution_boto3():
client = setup_workflow_boto3()
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)
task_token = resp["taskToken"]
decisions = [
{
"decisionType": "FailWorkflowExecution",
"failWorkflowExecutionDecisionAttributes": {
"reason": "my rules",
"details": "foo",
},
}
]
client.respond_decision_task_completed(taskToken=task_token, decisions=decisions)
resp = client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
types = [evt["eventType"] for evt in resp["events"]]
types.should.equal(
[
"WorkflowExecutionStarted",
"DecisionTaskScheduled",
"DecisionTaskStarted",
"DecisionTaskCompleted",
"WorkflowExecutionFailed",
]
)
attrs = resp["events"][-1]["workflowExecutionFailedEventAttributes"]
attrs["reason"].should.equal("my rules")
attrs["details"].should.equal("foo")
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
@freeze_time("2015-01-01 12:00:00") @freeze_time("2015-01-01 12:00:00")
def test_respond_decision_task_completed_with_schedule_activity_task(): def test_respond_decision_task_completed_with_schedule_activity_task():
@ -375,3 +757,61 @@ def test_respond_decision_task_completed_with_schedule_activity_task():
resp = conn.describe_workflow_execution("test-domain", conn.run_id, "uid-abcd1234") resp = conn.describe_workflow_execution("test-domain", conn.run_id, "uid-abcd1234")
resp["latestActivityTaskTimestamp"].should.equal(1420113600.0) resp["latestActivityTaskTimestamp"].should.equal(1420113600.0)
@mock_swf
@freeze_time("2015-01-01 12:00:00")
def test_respond_decision_task_completed_with_schedule_activity_task_boto3():
client = setup_workflow_boto3()
resp = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)
task_token = resp["taskToken"]
decisions = [
{
"decisionType": "ScheduleActivityTask",
"scheduleActivityTaskDecisionAttributes": {
"activityId": "my-activity-001",
"activityType": {"name": "test-activity", "version": "v1.1"},
"heartbeatTimeout": "60",
"input": "123",
"taskList": {"name": "my-task-list"},
},
}
]
client.respond_decision_task_completed(taskToken=task_token, decisions=decisions)
resp = client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
types = [evt["eventType"] for evt in resp["events"]]
types.should.equal(
[
"WorkflowExecutionStarted",
"DecisionTaskScheduled",
"DecisionTaskStarted",
"DecisionTaskCompleted",
"ActivityTaskScheduled",
]
)
resp["events"][-1]["activityTaskScheduledEventAttributes"].should.equal(
{
"decisionTaskCompletedEventId": 4,
"activityId": "my-activity-001",
"activityType": {"name": "test-activity", "version": "v1.1"},
"heartbeatTimeout": "60",
"input": "123",
"taskList": {"name": "my-task-list"},
}
)
resp = client.describe_workflow_execution(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
resp["latestActivityTaskTimestamp"].should.be.a(datetime)
if not settings.TEST_SERVER_MODE:
ts = resp["latestActivityTaskTimestamp"].strftime("%Y-%m-%d %H:%M:%S")
ts.should.equal("2015-01-01 12:00:00")

View File

@ -2,6 +2,7 @@ import boto
from boto.swf.exceptions import SWFResponseError from boto.swf.exceptions import SWFResponseError
import boto3 import boto3
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
import pytest
import sure # noqa import sure # noqa
from moto import mock_swf_deprecated from moto import mock_swf_deprecated
@ -10,6 +11,7 @@ from moto.core import ACCOUNT_ID
# RegisterDomain endpoint # RegisterDomain endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_register_domain(): def test_register_domain():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -26,6 +28,28 @@ def test_register_domain():
) )
@mock_swf
def test_register_domain_boto3():
client = boto3.client("swf", region_name="us-west-1")
client.register_domain(
name="test-domain",
workflowExecutionRetentionPeriodInDays="60",
description="A test domain",
)
all_domains = client.list_domains(registrationStatus="REGISTERED")
all_domains.should.have.key("domainInfos").being.length_of(1)
domain = all_domains["domainInfos"][0]
domain["name"].should.equal("test-domain")
domain["status"].should.equal("REGISTERED")
domain["description"].should.equal("A test domain")
domain["arn"].should.equal(
"arn:aws:swf:us-west-1:{0}:/domain/test-domain".format(ACCOUNT_ID)
)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_register_already_existing_domain(): def test_register_already_existing_domain():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -36,6 +60,27 @@ def test_register_already_existing_domain():
).should.throw(SWFResponseError) ).should.throw(SWFResponseError)
@mock_swf
def test_register_already_existing_domain_boto3():
client = boto3.client("swf", region_name="us-west-1")
client.register_domain(
name="test-domain",
workflowExecutionRetentionPeriodInDays="60",
description="A test domain",
)
with pytest.raises(ClientError) as ex:
client.register_domain(
name="test-domain",
workflowExecutionRetentionPeriodInDays="60",
description="A test domain",
)
ex.value.response["Error"]["Code"].should.equal("DomainAlreadyExistsFault")
ex.value.response["Error"]["Message"].should.equal("test-domain")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_register_with_wrong_parameter_type(): def test_register_with_wrong_parameter_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -46,6 +91,7 @@ def test_register_with_wrong_parameter_type():
# ListDomains endpoint # ListDomains endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_list_domains_order(): def test_list_domains_order():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -58,6 +104,27 @@ def test_list_domains_order():
names.should.equal(["a-test-domain", "b-test-domain", "c-test-domain"]) names.should.equal(["a-test-domain", "b-test-domain", "c-test-domain"])
@mock_swf
def test_list_domains_order_boto3():
client = boto3.client("swf", region_name="us-west-1")
client.register_domain(
name="b-test-domain", workflowExecutionRetentionPeriodInDays="60"
)
client.register_domain(
name="a-test-domain", workflowExecutionRetentionPeriodInDays="60"
)
client.register_domain(
name="c-test-domain", workflowExecutionRetentionPeriodInDays="60"
)
all_domains = client.list_domains(registrationStatus="REGISTERED")
all_domains.should.have.key("domainInfos").being.length_of(3)
names = [domain["name"] for domain in all_domains["domainInfos"]]
names.should.equal(["a-test-domain", "b-test-domain", "c-test-domain"])
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_list_domains_reverse_order(): def test_list_domains_reverse_order():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -70,7 +137,30 @@ def test_list_domains_reverse_order():
names.should.equal(["c-test-domain", "b-test-domain", "a-test-domain"]) names.should.equal(["c-test-domain", "b-test-domain", "a-test-domain"])
@mock_swf
def test_list_domains_reverse_order_boto3():
client = boto3.client("swf", region_name="us-west-1")
client.register_domain(
name="b-test-domain", workflowExecutionRetentionPeriodInDays="60"
)
client.register_domain(
name="a-test-domain", workflowExecutionRetentionPeriodInDays="60"
)
client.register_domain(
name="c-test-domain", workflowExecutionRetentionPeriodInDays="60"
)
all_domains = client.list_domains(
registrationStatus="REGISTERED", reverseOrder=True
)
all_domains.should.have.key("domainInfos").being.length_of(3)
names = [domain["name"] for domain in all_domains["domainInfos"]]
names.should.equal(["c-test-domain", "b-test-domain", "a-test-domain"])
# DeprecateDomain endpoint # DeprecateDomain endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_deprecate_domain(): def test_deprecate_domain():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -83,6 +173,25 @@ def test_deprecate_domain():
domain["name"].should.equal("test-domain") domain["name"].should.equal("test-domain")
@mock_swf
def test_deprecate_domain_boto3():
client = boto3.client("swf", region_name="us-west-1")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60"
)
client.deprecate_domain(name="test-domain")
all_domains = client.list_domains(registrationStatus="REGISTERED")
all_domains.should.have.key("domainInfos").being.length_of(0)
all_domains = client.list_domains(registrationStatus="DEPRECATED")
all_domains.should.have.key("domainInfos").being.length_of(1)
domain = all_domains["domainInfos"][0]
domain["name"].should.equal("test-domain")
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_deprecate_already_deprecated_domain(): def test_deprecate_already_deprecated_domain():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -92,6 +201,22 @@ def test_deprecate_already_deprecated_domain():
conn.deprecate_domain.when.called_with("test-domain").should.throw(SWFResponseError) conn.deprecate_domain.when.called_with("test-domain").should.throw(SWFResponseError)
@mock_swf
def test_deprecate_already_deprecated_domain_boto3():
client = boto3.client("swf", region_name="us-west-1")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60"
)
client.deprecate_domain(name="test-domain")
with pytest.raises(ClientError) as ex:
client.deprecate_domain(name="test-domain")
ex.value.response["Error"]["Code"].should.equal("DomainDeprecatedFault")
ex.value.response["Error"]["Message"].should.equal("test-domain")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_deprecate_non_existent_domain(): def test_deprecate_non_existent_domain():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -101,6 +226,17 @@ def test_deprecate_non_existent_domain():
) )
@mock_swf
def test_deprecate_non_existent_domain_boto3():
client = boto3.client("swf", region_name="us-west-1")
with pytest.raises(ClientError) as ex:
client.deprecate_domain(name="non-existent")
ex.value.response["Error"]["Code"].should.equal("UnknownResourceFault")
ex.value.response["Error"]["Message"].should.equal("Unknown domain: non-existent")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# UndeprecateDomain endpoint # UndeprecateDomain endpoint
@mock_swf @mock_swf
def test_undeprecate_domain(): def test_undeprecate_domain():
@ -152,6 +288,7 @@ def test_undeprecate_non_existent_domain():
# DescribeDomain endpoint # DescribeDomain endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_describe_domain(): def test_describe_domain():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -164,8 +301,36 @@ def test_describe_domain():
domain["domainInfo"]["status"].should.equal("REGISTERED") domain["domainInfo"]["status"].should.equal("REGISTERED")
@mock_swf
def test_describe_domain_boto3():
client = boto3.client("swf", region_name="us-east-1")
client.register_domain(
name="test-domain",
workflowExecutionRetentionPeriodInDays="60",
description="A test domain",
)
domain = client.describe_domain(name="test-domain")
domain["configuration"]["workflowExecutionRetentionPeriodInDays"].should.equal("60")
domain["domainInfo"]["description"].should.equal("A test domain")
domain["domainInfo"]["name"].should.equal("test-domain")
domain["domainInfo"]["status"].should.equal("REGISTERED")
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_describe_non_existent_domain(): def test_describe_non_existent_domain():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
conn.describe_domain.when.called_with("non-existent").should.throw(SWFResponseError) conn.describe_domain.when.called_with("non-existent").should.throw(SWFResponseError)
@mock_swf
def test_describe_non_existent_domain_boto3():
client = boto3.client("swf", region_name="us-west-1")
with pytest.raises(ClientError) as ex:
client.describe_domain(name="non-existent")
ex.value.response["Error"]["Code"].should.equal("UnknownResourceFault")
ex.value.response["Error"]["Message"].should.equal("Unknown domain: non-existent")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)

View File

@ -1,13 +1,17 @@
from datetime import datetime
from freezegun import freeze_time from freezegun import freeze_time
from unittest import SkipTest
import sure # noqa import sure # noqa
from moto import mock_swf_deprecated from moto import mock_swf_deprecated, mock_swf, settings
from ..utils import setup_workflow, SCHEDULE_ACTIVITY_TASK_DECISION from ..utils import setup_workflow, SCHEDULE_ACTIVITY_TASK_DECISION
from ..utils import setup_workflow_boto3
# Activity Task Heartbeat timeout # Activity Task Heartbeat timeout
# Default value in workflow helpers: 5 mins # Default value in workflow helpers: 5 mins
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_activity_task_heartbeat_timeout(): def test_activity_task_heartbeat_timeout():
with freeze_time("2015-01-01 12:00:00"): with freeze_time("2015-01-01 12:00:00"):
@ -43,8 +47,52 @@ def test_activity_task_heartbeat_timeout():
resp["events"][-1]["eventType"].should.equal("DecisionTaskScheduled") resp["events"][-1]["eventType"].should.equal("DecisionTaskScheduled")
# Activity Task Heartbeat timeout
# Default value in workflow helpers: 5 mins
@mock_swf
def test_activity_task_heartbeat_timeout_boto3():
if settings.TEST_SERVER_MODE:
raise SkipTest("Unable to manipulate time in ServerMode")
with freeze_time("2015-01-01 12:00:00"):
client = setup_workflow_boto3()
decision_token = client.poll_for_decision_task(
domain="test-domain", taskList={"name": "queue"}
)["taskToken"]
client.respond_decision_task_completed(
taskToken=decision_token, decisions=[SCHEDULE_ACTIVITY_TASK_DECISION]
)
client.poll_for_activity_task(
domain="test-domain",
taskList={"name": "activity-task-list"},
identity="surprise",
)
with freeze_time("2015-01-01 12:04:30"):
resp = client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
resp["events"][-1]["eventType"].should.equal("ActivityTaskStarted")
with freeze_time("2015-01-01 12:05:30"):
# => Activity Task Heartbeat timeout reached!!
resp = client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
resp["events"][-2]["eventType"].should.equal("ActivityTaskTimedOut")
attrs = resp["events"][-2]["activityTaskTimedOutEventAttributes"]
attrs["timeoutType"].should.equal("HEARTBEAT")
# checks that event has been emitted at 12:05:00, not 12:05:30
resp["events"][-2]["eventTimestamp"].should.be.a(datetime)
ts = resp["events"][-2]["eventTimestamp"].strftime("%Y-%m-%d %H:%M:%S")
ts.should.equal("2015-01-01 12:05:00")
# Decision Task Start to Close timeout # Decision Task Start to Close timeout
# Default value in workflow helpers: 5 mins # Default value in workflow helpers: 5 mins
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_decision_task_start_to_close_timeout(): def test_decision_task_start_to_close_timeout():
pass pass
@ -90,8 +138,62 @@ def test_decision_task_start_to_close_timeout():
resp["events"][-2]["eventTimestamp"].should.equal(1420113900.0) resp["events"][-2]["eventTimestamp"].should.equal(1420113900.0)
# Decision Task Start to Close timeout
# Default value in workflow helpers: 5 mins
@mock_swf
def test_decision_task_start_to_close_timeout_boto3():
if settings.TEST_SERVER_MODE:
raise SkipTest("Unable to manipulate time in ServerMode")
with freeze_time("2015-01-01 12:00:00"):
client = setup_workflow_boto3()
client.poll_for_decision_task(domain="test-domain", taskList={"name": "queue"})
with freeze_time("2015-01-01 12:04:30"):
resp = client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
event_types = [evt["eventType"] for evt in resp["events"]]
event_types.should.equal(
["WorkflowExecutionStarted", "DecisionTaskScheduled", "DecisionTaskStarted"]
)
with freeze_time("2015-01-01 12:05:30"):
# => Decision Task Start to Close timeout reached!!
resp = client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
event_types = [evt["eventType"] for evt in resp["events"]]
event_types.should.equal(
[
"WorkflowExecutionStarted",
"DecisionTaskScheduled",
"DecisionTaskStarted",
"DecisionTaskTimedOut",
"DecisionTaskScheduled",
]
)
attrs = resp["events"][-2]["decisionTaskTimedOutEventAttributes"]
attrs.should.equal(
{
"scheduledEventId": 2,
"startedEventId": 3,
"timeoutType": "START_TO_CLOSE",
}
)
# checks that event has been emitted at 12:05:00, not 12:05:30
resp["events"][-2]["eventTimestamp"].should.be.a(datetime)
ts = resp["events"][-2]["eventTimestamp"].strftime("%Y-%m-%d %H:%M:%S")
ts.should.equal("2015-01-01 12:05:00")
# Workflow Execution Start to Close timeout # Workflow Execution Start to Close timeout
# Default value in workflow helpers: 2 hours # Default value in workflow helpers: 2 hours
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_workflow_execution_start_to_close_timeout(): def test_workflow_execution_start_to_close_timeout():
pass pass
@ -124,3 +226,44 @@ def test_workflow_execution_start_to_close_timeout():
attrs.should.equal({"childPolicy": "ABANDON", "timeoutType": "START_TO_CLOSE"}) attrs.should.equal({"childPolicy": "ABANDON", "timeoutType": "START_TO_CLOSE"})
# checks that event has been emitted at 14:00:00, not 14:00:30 # checks that event has been emitted at 14:00:00, not 14:00:30
resp["events"][-1]["eventTimestamp"].should.equal(1420120800.0) resp["events"][-1]["eventTimestamp"].should.equal(1420120800.0)
# Workflow Execution Start to Close timeout
# Default value in workflow helpers: 2 hours
@mock_swf
def test_workflow_execution_start_to_close_timeout_boto3():
if settings.TEST_SERVER_MODE:
raise SkipTest("Unable to manipulate time in ServerMode")
with freeze_time("2015-01-01 12:00:00"):
client = setup_workflow_boto3()
with freeze_time("2015-01-01 13:59:30"):
resp = client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
event_types = [evt["eventType"] for evt in resp["events"]]
event_types.should.equal(["WorkflowExecutionStarted", "DecisionTaskScheduled"])
with freeze_time("2015-01-01 14:00:30"):
# => Workflow Execution Start to Close timeout reached!!
resp = client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": client.run_id, "workflowId": "uid-abcd1234"},
)
event_types = [evt["eventType"] for evt in resp["events"]]
event_types.should.equal(
[
"WorkflowExecutionStarted",
"DecisionTaskScheduled",
"WorkflowExecutionTimedOut",
]
)
attrs = resp["events"][-1]["workflowExecutionTimedOutEventAttributes"]
attrs.should.equal({"childPolicy": "ABANDON", "timeoutType": "START_TO_CLOSE"})
# checks that event has been emitted at 14:00:00, not 14:00:30
resp["events"][-1]["eventTimestamp"].should.be.a(datetime)
ts = resp["events"][-1]["eventTimestamp"].strftime("%Y-%m-%d %H:%M:%S")
ts.should.equal("2015-01-01 14:00:00")

View File

@ -1,10 +1,13 @@
import boto import boto
import boto3
from boto.swf.exceptions import SWFResponseError from boto.swf.exceptions import SWFResponseError
from botocore.exceptions import ClientError
from datetime import datetime, timedelta from datetime import datetime, timedelta
import pytest
import sure # noqa import sure # noqa
from moto import mock_swf_deprecated from moto import mock_swf_deprecated, mock_swf
from moto.core.utils import unix_time from moto.core.utils import unix_time
@ -26,7 +29,30 @@ def setup_swf_environment():
return conn return conn
def setup_swf_environment_boto3():
client = boto3.client("swf", region_name="us-west-1")
client.register_domain(
name="test-domain",
workflowExecutionRetentionPeriodInDays="60",
description="A test domain",
)
client.register_workflow_type(
domain="test-domain",
name="test-workflow",
version="v1.0",
defaultTaskList={"name": "queue"},
defaultChildPolicy="TERMINATE",
defaultTaskStartToCloseTimeout="300",
defaultExecutionStartToCloseTimeout="300",
)
client.register_activity_type(
domain="test-domain", name="test-activity", version="v1.1"
)
return client
# StartWorkflowExecution endpoint # StartWorkflowExecution endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_start_workflow_execution(): def test_start_workflow_execution():
conn = setup_swf_environment() conn = setup_swf_environment()
@ -37,6 +63,20 @@ def test_start_workflow_execution():
wf.should.contain("runId") wf.should.contain("runId")
# StartWorkflowExecution endpoint
@mock_swf
def test_start_workflow_execution_boto3():
client = setup_swf_environment_boto3()
wf = client.start_workflow_execution(
domain="test-domain",
workflowId="uid-abcd1234",
workflowType={"name": "test-workflow", "version": "v1.0"},
)
wf.should.have.key("runId")
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_signal_workflow_execution(): def test_signal_workflow_execution():
conn = setup_swf_environment() conn = setup_swf_environment()
@ -54,6 +94,32 @@ def test_signal_workflow_execution():
wfe["openCounts"]["openDecisionTasks"].should.equal(2) wfe["openCounts"]["openDecisionTasks"].should.equal(2)
@mock_swf
def test_signal_workflow_execution_boto3():
client = setup_swf_environment_boto3()
hsh = client.start_workflow_execution(
domain="test-domain",
workflowId="uid-abcd1234",
workflowType={"name": "test-workflow", "version": "v1.0"},
)
run_id = hsh["runId"]
wfe = client.signal_workflow_execution(
domain="test-domain",
signalName="my_signal",
workflowId="uid-abcd1234",
input="my_input",
runId=run_id,
)
wfe = client.describe_workflow_execution(
domain="test-domain", execution={"runId": run_id, "workflowId": "uid-abcd1234"}
)
wfe["openCounts"]["openDecisionTasks"].should.equal(2)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_start_already_started_workflow_execution(): def test_start_already_started_workflow_execution():
conn = setup_swf_environment() conn = setup_swf_environment()
@ -66,6 +132,29 @@ def test_start_already_started_workflow_execution():
).should.throw(SWFResponseError) ).should.throw(SWFResponseError)
@mock_swf
def test_start_already_started_workflow_execution_boto3():
client = setup_swf_environment_boto3()
client.start_workflow_execution(
domain="test-domain",
workflowId="uid-abcd1234",
workflowType={"name": "test-workflow", "version": "v1.0"},
)
with pytest.raises(ClientError) as ex:
client.start_workflow_execution(
domain="test-domain",
workflowId="uid-abcd1234",
workflowType={"name": "test-workflow", "version": "v1.0"},
)
ex.value.response["Error"]["Code"].should.equal(
"WorkflowExecutionAlreadyStartedFault"
)
ex.value.response["Error"]["Message"].should.equal("Already Started")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_start_workflow_execution_on_deprecated_type(): def test_start_workflow_execution_on_deprecated_type():
conn = setup_swf_environment() conn = setup_swf_environment()
@ -76,7 +165,28 @@ def test_start_workflow_execution_on_deprecated_type():
).should.throw(SWFResponseError) ).should.throw(SWFResponseError)
@mock_swf
def test_start_workflow_execution_on_deprecated_type_boto3():
client = setup_swf_environment_boto3()
client.deprecate_workflow_type(
domain="test-domain", workflowType={"name": "test-workflow", "version": "v1.0"}
)
with pytest.raises(ClientError) as ex:
client.start_workflow_execution(
domain="test-domain",
workflowId="uid-abcd1234",
workflowType={"name": "test-workflow", "version": "v1.0"},
)
ex.value.response["Error"]["Code"].should.equal("TypeDeprecatedFault")
ex.value.response["Error"]["Message"].should.equal(
"WorkflowType=[name=test-workflow, version=v1.0]"
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# DescribeWorkflowExecution endpoint # DescribeWorkflowExecution endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_describe_workflow_execution(): def test_describe_workflow_execution():
conn = setup_swf_environment() conn = setup_swf_environment()
@ -90,6 +200,25 @@ def test_describe_workflow_execution():
wfe["executionInfo"]["executionStatus"].should.equal("OPEN") wfe["executionInfo"]["executionStatus"].should.equal("OPEN")
# DescribeWorkflowExecution endpoint
@mock_swf
def test_describe_workflow_execution_boto3():
client = setup_swf_environment_boto3()
hsh = client.start_workflow_execution(
domain="test-domain",
workflowId="uid-abcd1234",
workflowType={"name": "test-workflow", "version": "v1.0"},
)
run_id = hsh["runId"]
wfe = client.describe_workflow_execution(
domain="test-domain", execution={"runId": run_id, "workflowId": "uid-abcd1234"}
)
wfe["executionInfo"]["execution"]["workflowId"].should.equal("uid-abcd1234")
wfe["executionInfo"]["executionStatus"].should.equal("OPEN")
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_describe_non_existent_workflow_execution(): def test_describe_non_existent_workflow_execution():
conn = setup_swf_environment() conn = setup_swf_environment()
@ -99,7 +228,24 @@ def test_describe_non_existent_workflow_execution():
).should.throw(SWFResponseError) ).should.throw(SWFResponseError)
@mock_swf
def test_describe_non_existent_workflow_execution_boto3():
client = setup_swf_environment_boto3()
with pytest.raises(ClientError) as ex:
client.describe_workflow_execution(
domain="test-domain",
execution={"runId": "wrong-run-id", "workflowId": "uid-abcd1234"},
)
ex.value.response["Error"]["Code"].should.equal("UnknownResourceFault")
ex.value.response["Error"]["Message"].should.equal(
"Unknown execution: WorkflowExecution=[workflowId=uid-abcd1234, runId=wrong-run-id]"
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# GetWorkflowExecutionHistory endpoint # GetWorkflowExecutionHistory endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_get_workflow_execution_history(): def test_get_workflow_execution_history():
conn = setup_swf_environment() conn = setup_swf_environment()
@ -113,6 +259,25 @@ def test_get_workflow_execution_history():
types.should.equal(["WorkflowExecutionStarted", "DecisionTaskScheduled"]) types.should.equal(["WorkflowExecutionStarted", "DecisionTaskScheduled"])
# GetWorkflowExecutionHistory endpoint
@mock_swf
def test_get_workflow_execution_history_boto3():
client = setup_swf_environment_boto3()
hsh = client.start_workflow_execution(
domain="test-domain",
workflowId="uid-abcd1234",
workflowType={"name": "test-workflow", "version": "v1.0"},
)
run_id = hsh["runId"]
resp = client.get_workflow_execution_history(
domain="test-domain", execution={"runId": run_id, "workflowId": "uid-abcd1234"},
)
types = [evt["eventType"] for evt in resp["events"]]
types.should.equal(["WorkflowExecutionStarted", "DecisionTaskScheduled"])
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_get_workflow_execution_history_with_reverse_order(): def test_get_workflow_execution_history_with_reverse_order():
conn = setup_swf_environment() conn = setup_swf_environment()
@ -128,6 +293,26 @@ def test_get_workflow_execution_history_with_reverse_order():
types.should.equal(["DecisionTaskScheduled", "WorkflowExecutionStarted"]) types.should.equal(["DecisionTaskScheduled", "WorkflowExecutionStarted"])
@mock_swf
def test_get_workflow_execution_history_with_reverse_order_boto3():
client = setup_swf_environment_boto3()
hsh = client.start_workflow_execution(
domain="test-domain",
workflowId="uid-abcd1234",
workflowType={"name": "test-workflow", "version": "v1.0"},
)
run_id = hsh["runId"]
resp = client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": run_id, "workflowId": "uid-abcd1234"},
reverseOrder=True,
)
types = [evt["eventType"] for evt in resp["events"]]
types.should.equal(["DecisionTaskScheduled", "WorkflowExecutionStarted"])
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_get_workflow_execution_history_on_non_existent_workflow_execution(): def test_get_workflow_execution_history_on_non_existent_workflow_execution():
conn = setup_swf_environment() conn = setup_swf_environment()
@ -137,7 +322,24 @@ def test_get_workflow_execution_history_on_non_existent_workflow_execution():
).should.throw(SWFResponseError) ).should.throw(SWFResponseError)
@mock_swf
def test_get_workflow_execution_history_on_non_existent_workflow_execution_boto3():
client = setup_swf_environment_boto3()
with pytest.raises(ClientError) as ex:
client.get_workflow_execution_history(
domain="test-domain",
execution={"runId": "wrong-run-id", "workflowId": "wrong-workflow-id"},
)
ex.value.response["Error"]["Code"].should.equal("UnknownResourceFault")
ex.value.response["Error"]["Message"].should.equal(
"Unknown execution: WorkflowExecution=[workflowId=wrong-workflow-id, runId=wrong-run-id]"
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# ListOpenWorkflowExecutions endpoint # ListOpenWorkflowExecutions endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_list_open_workflow_executions(): def test_list_open_workflow_executions():
conn = setup_swf_environment() conn = setup_swf_environment()
@ -175,7 +377,52 @@ def test_list_open_workflow_executions():
open_workflow["executionStatus"].should.equal("OPEN") open_workflow["executionStatus"].should.equal("OPEN")
# ListOpenWorkflowExecutions endpoint
@mock_swf
def test_list_open_workflow_executions_boto3():
client = setup_swf_environment_boto3()
# One open workflow execution
client.start_workflow_execution(
domain="test-domain",
workflowId="uid-abcd1234",
workflowType={"name": "test-workflow", "version": "v1.0"},
)
# One closed workflow execution to make sure it isn't displayed
run_id = client.start_workflow_execution(
domain="test-domain",
workflowId="uid-abcd12345",
workflowType={"name": "test-workflow", "version": "v1.0"},
)["runId"]
client.terminate_workflow_execution(
domain="test-domain",
workflowId="uid-abcd12345",
details="some details",
reason="a more complete reason",
runId=run_id,
)
yesterday = datetime.utcnow() - timedelta(days=1)
oldest_date = unix_time(yesterday)
response = client.list_open_workflow_executions(
domain="test-domain",
startTimeFilter={"oldestDate": oldest_date},
executionFilter={"workflowId": "test-workflow"},
)
execution_infos = response["executionInfos"]
len(execution_infos).should.equal(1)
open_workflow = execution_infos[0]
open_workflow["workflowType"].should.equal(
{"version": "v1.0", "name": "test-workflow"}
)
open_workflow.should.contain("startTimestamp")
open_workflow["execution"]["workflowId"].should.equal("uid-abcd1234")
open_workflow["execution"].should.contain("runId")
open_workflow["cancelRequested"].should.be(False)
open_workflow["executionStatus"].should.equal("OPEN")
# ListClosedWorkflowExecutions endpoint # ListClosedWorkflowExecutions endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_list_closed_workflow_executions(): def test_list_closed_workflow_executions():
conn = setup_swf_environment() conn = setup_swf_environment()
@ -213,7 +460,52 @@ def test_list_closed_workflow_executions():
open_workflow["executionStatus"].should.equal("CLOSED") open_workflow["executionStatus"].should.equal("CLOSED")
# ListClosedWorkflowExecutions endpoint
@mock_swf
def test_list_closed_workflow_executions_boto3():
client = setup_swf_environment_boto3()
# Leave one workflow execution open to make sure it isn't displayed
client.start_workflow_execution(
domain="test-domain",
workflowId="uid-abcd1234",
workflowType={"name": "test-workflow", "version": "v1.0"},
)
# One closed workflow execution
run_id = client.start_workflow_execution(
domain="test-domain",
workflowId="uid-abcd12345",
workflowType={"name": "test-workflow", "version": "v1.0"},
)["runId"]
client.terminate_workflow_execution(
domain="test-domain",
workflowId="uid-abcd12345",
details="some details",
reason="a more complete reason",
runId=run_id,
)
yesterday = datetime.utcnow() - timedelta(days=1)
oldest_date = unix_time(yesterday)
response = client.list_closed_workflow_executions(
domain="test-domain",
startTimeFilter={"oldestDate": oldest_date},
executionFilter={"workflowId": "test-workflow"},
)
execution_infos = response["executionInfos"]
len(execution_infos).should.equal(1)
open_workflow = execution_infos[0]
open_workflow["workflowType"].should.equal(
{"version": "v1.0", "name": "test-workflow"}
)
open_workflow.should.contain("startTimestamp")
open_workflow["execution"]["workflowId"].should.equal("uid-abcd12345")
open_workflow["execution"].should.contain("runId")
open_workflow["cancelRequested"].should.be(False)
open_workflow["executionStatus"].should.equal("CLOSED")
# TerminateWorkflowExecution endpoint # TerminateWorkflowExecution endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_terminate_workflow_execution(): def test_terminate_workflow_execution():
conn = setup_swf_environment() conn = setup_swf_environment()
@ -239,6 +531,36 @@ def test_terminate_workflow_execution():
attrs["cause"].should.equal("OPERATOR_INITIATED") attrs["cause"].should.equal("OPERATOR_INITIATED")
# TerminateWorkflowExecution endpoint
@mock_swf
def test_terminate_workflow_execution_boto3():
client = setup_swf_environment_boto3()
run_id = client.start_workflow_execution(
domain="test-domain",
workflowId="uid-abcd1234",
workflowType={"name": "test-workflow", "version": "v1.0"},
)["runId"]
client.terminate_workflow_execution(
domain="test-domain",
workflowId="uid-abcd1234",
details="some details",
reason="a more complete reason",
runId=run_id,
)
resp = client.get_workflow_execution_history(
domain="test-domain", execution={"runId": run_id, "workflowId": "uid-abcd1234"},
)
evt = resp["events"][-1]
evt["eventType"].should.equal("WorkflowExecutionTerminated")
attrs = evt["workflowExecutionTerminatedEventAttributes"]
attrs["details"].should.equal("some details")
attrs["reason"].should.equal("a more complete reason")
attrs["cause"].should.equal("OPERATOR_INITIATED")
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_terminate_workflow_execution_with_wrong_workflow_or_run_id(): def test_terminate_workflow_execution_with_wrong_workflow_or_run_id():
conn = setup_swf_environment() conn = setup_swf_environment()
@ -272,3 +594,58 @@ def test_terminate_workflow_execution_with_wrong_workflow_or_run_id():
).should.throw( ).should.throw(
SWFResponseError, "WorkflowExecution=[workflowId=uid-abcd1234, runId=" SWFResponseError, "WorkflowExecution=[workflowId=uid-abcd1234, runId="
) )
@mock_swf
def test_terminate_workflow_execution_with_wrong_workflow_or_run_id_boto3():
client = setup_swf_environment_boto3()
run_id = client.start_workflow_execution(
domain="test-domain",
workflowId="uid-abcd1234",
workflowType={"name": "test-workflow", "version": "v1.0"},
)["runId"]
# terminate workflow execution
client.terminate_workflow_execution(domain="test-domain", workflowId="uid-abcd1234")
# already closed, with run_id
with pytest.raises(ClientError) as ex:
client.terminate_workflow_execution(
domain="test-domain", workflowId="uid-abcd1234", runId=run_id
)
ex.value.response["Error"]["Code"].should.equal("UnknownResourceFault")
ex.value.response["Error"]["Message"].should.equal(
"Unknown execution: WorkflowExecution=[workflowId=uid-abcd1234, runId={}]".format(
run_id
)
)
# already closed, without run_id
with pytest.raises(ClientError) as ex:
client.terminate_workflow_execution(
domain="test-domain", workflowId="uid-abcd1234"
)
ex.value.response["Error"]["Code"].should.equal("UnknownResourceFault")
ex.value.response["Error"]["Message"].should.equal(
"Unknown execution, workflowId = uid-abcd1234"
)
# wrong workflow id
with pytest.raises(ClientError) as ex:
client.terminate_workflow_execution(
domain="test-domain", workflowId="uid-non-existent"
)
ex.value.response["Error"]["Code"].should.equal("UnknownResourceFault")
ex.value.response["Error"]["Message"].should.equal(
"Unknown execution, workflowId = uid-non-existent"
)
# wrong run_id
with pytest.raises(ClientError) as ex:
client.terminate_workflow_execution(
domain="test-domain", workflowId="uid-abcd1234", runId="foo"
)
ex.value.response["Error"]["Code"].should.equal("UnknownResourceFault")
ex.value.response["Error"]["Message"].should.equal(
"Unknown execution: WorkflowExecution=[workflowId=uid-abcd1234, runId=foo]"
)

View File

@ -1,6 +1,7 @@
import sure import sure
import boto import boto
import boto3 import boto3
import pytest
from moto import mock_swf_deprecated from moto import mock_swf_deprecated
from moto import mock_swf from moto import mock_swf
@ -9,6 +10,7 @@ from botocore.exceptions import ClientError
# RegisterWorkflowType endpoint # RegisterWorkflowType endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_register_workflow_type(): def test_register_workflow_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -21,6 +23,26 @@ def test_register_workflow_type():
actype["workflowType"]["version"].should.equal("v1.0") actype["workflowType"]["version"].should.equal("v1.0")
# RegisterWorkflowType endpoint
@mock_swf
def test_register_workflow_type_boto3():
client = boto3.client("swf", region_name="us-east-1")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60",
)
client.register_workflow_type(
domain="test-domain", name="test-workflow", version="v1.0"
)
types = client.list_workflow_types(
domain="test-domain", registrationStatus="REGISTERED"
)
actype = types["typeInfos"][0]
actype["workflowType"]["name"].should.equal("test-workflow")
actype["workflowType"]["version"].should.equal("v1.0")
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_register_already_existing_workflow_type(): def test_register_already_existing_workflow_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -32,6 +54,27 @@ def test_register_already_existing_workflow_type():
).should.throw(SWFResponseError) ).should.throw(SWFResponseError)
@mock_swf
def test_register_already_existing_workflow_type_boto3():
client = boto3.client("swf", region_name="us-east-1")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60",
)
client.register_workflow_type(
domain="test-domain", name="test-workflow", version="v1.0"
)
with pytest.raises(ClientError) as ex:
client.register_workflow_type(
domain="test-domain", name="test-workflow", version="v1.0"
)
ex.value.response["Error"]["Code"].should.equal("TypeAlreadyExistsFault")
ex.value.response["Error"]["Message"].should.equal(
"WorkflowType=[name=test-workflow, version=v1.0]"
)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_register_with_wrong_parameter_type(): def test_register_with_wrong_parameter_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -43,6 +86,7 @@ def test_register_with_wrong_parameter_type():
# ListWorkflowTypes endpoint # ListWorkflowTypes endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_list_workflow_types(): def test_list_workflow_types():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -59,6 +103,34 @@ def test_list_workflow_types():
names.should.equal(["a-test-workflow", "b-test-workflow", "c-test-workflow"]) names.should.equal(["a-test-workflow", "b-test-workflow", "c-test-workflow"])
# ListWorkflowTypes endpoint
@mock_swf
def test_list_workflow_types_boto3():
client = boto3.client("swf", region_name="us-east-1")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60",
)
client.register_workflow_type(
domain="test-domain", name="b-test-workflow", version="v1.0"
)
client.register_workflow_type(
domain="test-domain", name="a-test-workflow", version="v1.0"
)
client.register_workflow_type(
domain="test-domain", name="c-test-workflow", version="v1.0"
)
all_workflow_types = client.list_workflow_types(
domain="test-domain", registrationStatus="REGISTERED"
)
names = [
activity_type["workflowType"]["name"]
for activity_type in all_workflow_types["typeInfos"]
]
names.should.equal(["a-test-workflow", "b-test-workflow", "c-test-workflow"])
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_list_workflow_types_reverse_order(): def test_list_workflow_types_reverse_order():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -77,7 +149,35 @@ def test_list_workflow_types_reverse_order():
names.should.equal(["c-test-workflow", "b-test-workflow", "a-test-workflow"]) names.should.equal(["c-test-workflow", "b-test-workflow", "a-test-workflow"])
# ListWorkflowTypes endpoint
@mock_swf
def test_list_workflow_types_reverse_order_boto3():
client = boto3.client("swf", region_name="us-east-1")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60",
)
client.register_workflow_type(
domain="test-domain", name="b-test-workflow", version="v1.0"
)
client.register_workflow_type(
domain="test-domain", name="a-test-workflow", version="v1.0"
)
client.register_workflow_type(
domain="test-domain", name="c-test-workflow", version="v1.0"
)
all_workflow_types = client.list_workflow_types(
domain="test-domain", registrationStatus="REGISTERED", reverseOrder=True
)
names = [
activity_type["workflowType"]["name"]
for activity_type in all_workflow_types["typeInfos"]
]
names.should.equal(["c-test-workflow", "b-test-workflow", "a-test-workflow"])
# DeprecateWorkflowType endpoint # DeprecateWorkflowType endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_deprecate_workflow_type(): def test_deprecate_workflow_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -91,6 +191,29 @@ def test_deprecate_workflow_type():
actype["workflowType"]["version"].should.equal("v1.0") actype["workflowType"]["version"].should.equal("v1.0")
# DeprecateWorkflowType endpoint
@mock_swf
def test_deprecate_workflow_type_boto3():
client = boto3.client("swf", region_name="us-east-1")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60",
)
client.register_workflow_type(
domain="test-domain", name="test-workflow", version="v1.0"
)
client.deprecate_workflow_type(
domain="test-domain", workflowType={"name": "test-workflow", "version": "v1.0"}
)
actypes = client.list_workflow_types(
domain="test-domain", registrationStatus="DEPRECATED"
)
actype = actypes["typeInfos"][0]
actype["workflowType"]["name"].should.equal("test-workflow")
actype["workflowType"]["version"].should.equal("v1.0")
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_deprecate_already_deprecated_workflow_type(): def test_deprecate_already_deprecated_workflow_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -103,6 +226,31 @@ def test_deprecate_already_deprecated_workflow_type():
).should.throw(SWFResponseError) ).should.throw(SWFResponseError)
@mock_swf
def test_deprecate_already_deprecated_workflow_type_boto3():
client = boto3.client("swf", region_name="us-east-1")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60",
)
client.register_workflow_type(
domain="test-domain", name="test-workflow", version="v1.0"
)
client.deprecate_workflow_type(
domain="test-domain", workflowType={"name": "test-workflow", "version": "v1.0"}
)
with pytest.raises(ClientError) as ex:
client.deprecate_workflow_type(
domain="test-domain",
workflowType={"name": "test-workflow", "version": "v1.0"},
)
ex.value.response["Error"]["Code"].should.equal("TypeDeprecatedFault")
ex.value.response["Error"]["Message"].should.equal(
"WorkflowType=[name=test-workflow, version=v1.0]"
)
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_deprecate_non_existent_workflow_type(): def test_deprecate_non_existent_workflow_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -113,6 +261,24 @@ def test_deprecate_non_existent_workflow_type():
).should.throw(SWFResponseError) ).should.throw(SWFResponseError)
@mock_swf
def test_deprecate_non_existent_workflow_type_boto3():
client = boto3.client("swf", region_name="us-east-1")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60",
)
with pytest.raises(ClientError) as ex:
client.deprecate_workflow_type(
domain="test-domain",
workflowType={"name": "test-workflow", "version": "v1.0"},
)
ex.value.response["Error"]["Code"].should.equal("UnknownResourceFault")
ex.value.response["Error"]["Message"].should.equal(
"Unknown type: WorkflowType=[name=test-workflow, version=v1.0]"
)
# UndeprecateWorkflowType endpoint # UndeprecateWorkflowType endpoint
@mock_swf @mock_swf
def test_undeprecate_workflow_type(): def test_undeprecate_workflow_type():
@ -185,6 +351,7 @@ def test_undeprecate_non_existent_workflow_type():
# DescribeWorkflowType endpoint # DescribeWorkflowType endpoint
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_describe_workflow_type(): def test_describe_workflow_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -242,6 +409,7 @@ def test_describe_workflow_type_full_boto3():
resp["configuration"]["defaultLambdaRole"].should.equal("arn:bar") resp["configuration"]["defaultLambdaRole"].should.equal("arn:bar")
# Has boto3 equivalent
@mock_swf_deprecated @mock_swf_deprecated
def test_describe_non_existent_workflow_type(): def test_describe_non_existent_workflow_type():
conn = boto.connect_swf("the_key", "the_secret") conn = boto.connect_swf("the_key", "the_secret")
@ -250,3 +418,21 @@ def test_describe_non_existent_workflow_type():
conn.describe_workflow_type.when.called_with( conn.describe_workflow_type.when.called_with(
"test-domain", "non-existent", "v1.0" "test-domain", "non-existent", "v1.0"
).should.throw(SWFResponseError) ).should.throw(SWFResponseError)
@mock_swf
def test_describe_non_existent_workflow_type_boto3():
client = boto3.client("swf", region_name="us-east-1")
client.register_domain(
name="test-domain", workflowExecutionRetentionPeriodInDays="60",
)
with pytest.raises(ClientError) as ex:
client.describe_workflow_type(
domain="test-domain",
workflowType={"name": "non-existent", "version": "v1.0"},
)
ex.value.response["Error"]["Code"].should.equal("UnknownResourceFault")
ex.value.response["Error"]["Message"].should.equal(
"Unknown type: WorkflowType=[name=non-existent, version=v1.0]"
)

View File

@ -1,4 +1,5 @@
import boto import boto
import boto3
from moto.swf.models import ActivityType, Domain, WorkflowType, WorkflowExecution from moto.swf.models import ActivityType, Domain, WorkflowType, WorkflowExecution
@ -47,6 +48,17 @@ def _generic_workflow_type_attributes():
) )
def _generic_workflow_type_attributes_boto3():
return {
"name": "test-workflow",
"version": "v1.0",
"defaultTaskList": {"name": "queue"},
"defaultChildPolicy": "ABANDON",
"defaultExecutionStartToCloseTimeout": "7200",
"defaultTaskStartToCloseTimeout": "300",
}
def get_basic_workflow_type(): def get_basic_workflow_type():
args, kwargs = _generic_workflow_type_attributes() args, kwargs = _generic_workflow_type_attributes()
return WorkflowType(*args, **kwargs) return WorkflowType(*args, **kwargs)
@ -58,6 +70,12 @@ def mock_basic_workflow_type(domain_name, conn):
return conn return conn
def mock_basic_workflow_type_boto3(domain_name, client):
kwargs = _generic_workflow_type_attributes_boto3()
client.register_workflow_type(domain=domain_name, **kwargs)
return client
# A test WorkflowExecution # A test WorkflowExecution
def make_workflow_execution(**kwargs): def make_workflow_execution(**kwargs):
domain = get_basic_domain() domain = get_basic_domain()
@ -93,6 +111,33 @@ def setup_workflow():
return conn return conn
# Setup a complete example workflow and return the connection object
def setup_workflow_boto3():
client = boto3.client("swf", region_name="us-west-1")
client.register_domain(
name="test-domain",
workflowExecutionRetentionPeriodInDays="60",
description="A test domain",
)
mock_basic_workflow_type_boto3("test-domain", client)
client.register_activity_type(
domain="test-domain",
name="test-activity",
version="v1.1",
defaultTaskHeartbeatTimeout="600",
defaultTaskScheduleToCloseTimeout="600",
defaultTaskScheduleToStartTimeout="600",
defaultTaskStartToCloseTimeout="600",
)
wfe = client.start_workflow_execution(
domain="test-domain",
workflowId="uid-abcd1234",
workflowType={"name": "test-workflow", "version": "v1.0"},
)
client.run_id = wfe["runId"]
return client
# A helper for processing the first timeout on a given object # A helper for processing the first timeout on a given object
def process_first_timeout(obj): def process_first_timeout(obj):
_timeout = obj.first_timeout() _timeout = obj.first_timeout()