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 botocore.exceptions import ClientError
from freezegun import freeze_time
from unittest import SkipTest
import pytest
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 ..utils import setup_workflow, SCHEDULE_ACTIVITY_TASK_DECISION
from ..utils import setup_workflow_boto3
# PollForActivityTask endpoint
# Has boto3 equivalent
@mock_swf_deprecated
def test_poll_for_activity_task_when_one():
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
def test_poll_for_activity_task_when_none():
conn = setup_workflow()
@ -38,6 +72,7 @@ def test_poll_for_activity_task_when_none():
resp.should.equal({"startedEventId": 0})
# Has boto3 equivalent
@mock_swf_deprecated
def test_poll_for_activity_task_on_non_existent_queue():
conn = setup_workflow()
@ -45,7 +80,20 @@ def test_poll_for_activity_task_on_non_existent_queue():
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
# Has boto3 equivalent
@mock_swf_deprecated
def test_count_pending_activity_tasks():
conn = setup_workflow()
@ -58,6 +106,7 @@ def test_count_pending_activity_tasks():
resp.should.equal({"count": 1, "truncated": False})
# Has boto3 equivalent
@mock_swf_deprecated
def test_count_pending_decision_tasks_on_non_existent_task_list():
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})
@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
# Has boto3 equivalent
@mock_swf_deprecated
def test_respond_activity_task_completed():
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
def test_respond_activity_task_completed_on_closed_workflow_execution():
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
def test_respond_activity_task_completed_with_task_already_completed():
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
# Has boto3 equivalent
@mock_swf_deprecated
def test_respond_activity_task_failed():
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
def test_respond_activity_task_completed_with_wrong_token():
# 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")
@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
# Has boto3 equivalent
@mock_swf_deprecated
def test_record_activity_task_heartbeat():
conn = setup_workflow()
@ -194,6 +401,24 @@ def test_record_activity_task_heartbeat():
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
def test_record_activity_task_heartbeat_with_wrong_token():
conn = setup_workflow()
@ -208,6 +433,27 @@ def test_record_activity_task_heartbeat_with_wrong_token():
).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
def test_record_activity_task_heartbeat_sets_details_in_case_of_timeout():
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")
attrs = resp["events"][-2]["activityTaskTimedOutEventAttributes"]
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
import boto3
from botocore.exceptions import ClientError
import pytest
import sure # noqa
from moto import mock_swf_deprecated
@ -9,6 +10,7 @@ from moto import mock_swf
# RegisterActivityType endpoint
# Has boto3 equivalent
@mock_swf_deprecated
def test_register_activity_type():
conn = boto.connect_swf("the_key", "the_secret")
@ -21,6 +23,26 @@ def test_register_activity_type():
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
def test_register_already_existing_activity_type():
conn = boto.connect_swf("the_key", "the_secret")
@ -32,6 +54,28 @@ def test_register_already_existing_activity_type():
).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
def test_register_with_wrong_parameter_type():
conn = boto.connect_swf("the_key", "the_secret")
@ -43,6 +87,7 @@ def test_register_with_wrong_parameter_type():
# ListActivityTypes endpoint
# Has boto3 equivalent
@mock_swf_deprecated
def test_list_activity_types():
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"])
# 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
def test_list_activity_types_reverse_order():
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"])
@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
# Has boto3 equivalent
@mock_swf_deprecated
def test_deprecate_activity_type():
conn = boto.connect_swf("the_key", "the_secret")
@ -91,6 +190,30 @@ def test_deprecate_activity_type():
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
def test_deprecate_already_deprecated_activity_type():
conn = boto.connect_swf("the_key", "the_secret")
@ -103,6 +226,32 @@ def test_deprecate_already_deprecated_activity_type():
).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
def test_deprecate_non_existent_activity_type():
conn = boto.connect_swf("the_key", "the_secret")
@ -113,6 +262,25 @@ def test_deprecate_non_existent_activity_type():
).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
@mock_swf
def test_undeprecate_activity_type():
@ -185,6 +353,7 @@ def test_undeprecate_non_existent_activity_type():
# DescribeActivityType endpoint
# Has boto3 equivalent
@mock_swf_deprecated
def test_describe_activity_type():
conn = boto.connect_swf("the_key", "the_secret")
@ -205,6 +374,31 @@ def test_describe_activity_type():
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
def test_describe_non_existent_activity_type():
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(
"test-domain", "non-existent", "v1.0"
).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 botocore.exceptions import ClientError
from datetime import datetime
from freezegun import freeze_time
import pytest
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 ..utils import setup_workflow
from ..utils import setup_workflow, setup_workflow_boto3
# PollForDecisionTask endpoint
# Has boto3 equivalent
@mock_swf_deprecated
def test_poll_for_decision_task_when_one():
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
def test_poll_for_decision_task_previous_started_event_id():
conn = setup_workflow()
@ -54,6 +83,37 @@ def test_poll_for_decision_task_previous_started_event_id():
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
def test_poll_for_decision_task_when_none():
conn = setup_workflow()
@ -65,6 +125,22 @@ def test_poll_for_decision_task_when_none():
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
def test_poll_for_decision_task_on_non_existent_queue():
conn = setup_workflow()
@ -72,6 +148,17 @@ def test_poll_for_decision_task_on_non_existent_queue():
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
def test_poll_for_decision_task_with_reverse_order():
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
# Has boto3 equivalent
@mock_swf_deprecated
def test_count_pending_decision_tasks():
conn = setup_workflow()
@ -91,6 +191,18 @@ def test_count_pending_decision_tasks():
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
def test_count_pending_decision_tasks_on_non_existent_task_list():
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})
@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
def test_count_pending_decision_tasks_after_decision_completes():
conn = setup_workflow()
@ -108,7 +231,23 @@ def test_count_pending_decision_tasks_after_decision_completes():
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
# Has boto3 equivalent
@mock_swf_deprecated
def test_respond_decision_task_completed_with_no_decision():
conn = setup_workflow()
@ -146,6 +285,48 @@ def test_respond_decision_task_completed_with_no_decision():
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
def test_respond_decision_task_completed_with_wrong_token():
conn = setup_workflow()
@ -155,6 +336,18 @@ def test_respond_decision_task_completed_with_wrong_token():
).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
def test_respond_decision_task_completed_on_close_workflow_execution():
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
def test_respond_decision_task_completed_with_task_already_completed():
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
def test_respond_decision_task_completed_with_complete_workflow_execution():
conn = setup_workflow()
@ -217,6 +451,42 @@ def test_respond_decision_task_completed_with_complete_workflow_execution():
].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
def test_respond_decision_task_completed_with_close_decision_not_last():
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")
@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
def test_respond_decision_task_completed_with_invalid_decision_type():
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
def test_respond_decision_task_completed_with_missing_attributes():
conn = setup_workflow()
@ -274,6 +594,7 @@ def test_respond_decision_task_completed_with_missing_attributes():
)
# Has boto3 equivalent
@mock_swf_deprecated
def test_respond_decision_task_completed_with_missing_attributes_totally():
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
def test_respond_decision_task_completed_with_fail_workflow_execution():
conn = setup_workflow()
@ -327,6 +670,45 @@ def test_respond_decision_task_completed_with_fail_workflow_execution():
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
@freeze_time("2015-01-01 12:00:00")
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["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
import boto3
from botocore.exceptions import ClientError
import pytest
import sure # noqa
from moto import mock_swf_deprecated
@ -10,6 +11,7 @@ from moto.core import ACCOUNT_ID
# RegisterDomain endpoint
# Has boto3 equivalent
@mock_swf_deprecated
def test_register_domain():
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
def test_register_already_existing_domain():
conn = boto.connect_swf("the_key", "the_secret")
@ -36,6 +60,27 @@ def test_register_already_existing_domain():
).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
def test_register_with_wrong_parameter_type():
conn = boto.connect_swf("the_key", "the_secret")
@ -46,6 +91,7 @@ def test_register_with_wrong_parameter_type():
# ListDomains endpoint
# Has boto3 equivalent
@mock_swf_deprecated
def test_list_domains_order():
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"])
@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
def test_list_domains_reverse_order():
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"])
@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
# Has boto3 equivalent
@mock_swf_deprecated
def test_deprecate_domain():
conn = boto.connect_swf("the_key", "the_secret")
@ -83,6 +173,25 @@ def test_deprecate_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
def test_deprecate_already_deprecated_domain():
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)
@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
def test_deprecate_non_existent_domain():
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
@mock_swf
def test_undeprecate_domain():
@ -152,6 +288,7 @@ def test_undeprecate_non_existent_domain():
# DescribeDomain endpoint
# Has boto3 equivalent
@mock_swf_deprecated
def test_describe_domain():
conn = boto.connect_swf("the_key", "the_secret")
@ -164,8 +301,36 @@ def test_describe_domain():
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
def test_describe_non_existent_domain():
conn = boto.connect_swf("the_key", "the_secret")
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 unittest import SkipTest
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_boto3
# Activity Task Heartbeat timeout
# Default value in workflow helpers: 5 mins
# Has boto3 equivalent
@mock_swf_deprecated
def test_activity_task_heartbeat_timeout():
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")
# 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
# Default value in workflow helpers: 5 mins
# Has boto3 equivalent
@mock_swf_deprecated
def test_decision_task_start_to_close_timeout():
pass
@ -90,8 +138,62 @@ def test_decision_task_start_to_close_timeout():
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
# Default value in workflow helpers: 2 hours
# Has boto3 equivalent
@mock_swf_deprecated
def test_workflow_execution_start_to_close_timeout():
pass
@ -124,3 +226,44 @@ def test_workflow_execution_start_to_close_timeout():
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.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 boto3
from boto.swf.exceptions import SWFResponseError
from botocore.exceptions import ClientError
from datetime import datetime, timedelta
import pytest
import sure # noqa
from moto import mock_swf_deprecated
from moto import mock_swf_deprecated, mock_swf
from moto.core.utils import unix_time
@ -26,7 +29,30 @@ def setup_swf_environment():
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
# Has boto3 equivalent
@mock_swf_deprecated
def test_start_workflow_execution():
conn = setup_swf_environment()
@ -37,6 +63,20 @@ def test_start_workflow_execution():
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
def test_signal_workflow_execution():
conn = setup_swf_environment()
@ -54,6 +94,32 @@ def test_signal_workflow_execution():
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
def test_start_already_started_workflow_execution():
conn = setup_swf_environment()
@ -66,6 +132,29 @@ def test_start_already_started_workflow_execution():
).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
def test_start_workflow_execution_on_deprecated_type():
conn = setup_swf_environment()
@ -76,7 +165,28 @@ def test_start_workflow_execution_on_deprecated_type():
).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
# Has boto3 equivalent
@mock_swf_deprecated
def test_describe_workflow_execution():
conn = setup_swf_environment()
@ -90,6 +200,25 @@ def test_describe_workflow_execution():
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
def test_describe_non_existent_workflow_execution():
conn = setup_swf_environment()
@ -99,7 +228,24 @@ def test_describe_non_existent_workflow_execution():
).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
# Has boto3 equivalent
@mock_swf_deprecated
def test_get_workflow_execution_history():
conn = setup_swf_environment()
@ -113,6 +259,25 @@ def test_get_workflow_execution_history():
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
def test_get_workflow_execution_history_with_reverse_order():
conn = setup_swf_environment()
@ -128,6 +293,26 @@ def test_get_workflow_execution_history_with_reverse_order():
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
def test_get_workflow_execution_history_on_non_existent_workflow_execution():
conn = setup_swf_environment()
@ -137,7 +322,24 @@ def test_get_workflow_execution_history_on_non_existent_workflow_execution():
).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
# Has boto3 equivalent
@mock_swf_deprecated
def test_list_open_workflow_executions():
conn = setup_swf_environment()
@ -175,7 +377,52 @@ def test_list_open_workflow_executions():
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
# Has boto3 equivalent
@mock_swf_deprecated
def test_list_closed_workflow_executions():
conn = setup_swf_environment()
@ -213,7 +460,52 @@ def test_list_closed_workflow_executions():
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
# Has boto3 equivalent
@mock_swf_deprecated
def test_terminate_workflow_execution():
conn = setup_swf_environment()
@ -239,6 +531,36 @@ def test_terminate_workflow_execution():
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
def test_terminate_workflow_execution_with_wrong_workflow_or_run_id():
conn = setup_swf_environment()
@ -272,3 +594,58 @@ def test_terminate_workflow_execution_with_wrong_workflow_or_run_id():
).should.throw(
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 boto
import boto3
import pytest
from moto import mock_swf_deprecated
from moto import mock_swf
@ -9,6 +10,7 @@ from botocore.exceptions import ClientError
# RegisterWorkflowType endpoint
# Has boto3 equivalent
@mock_swf_deprecated
def test_register_workflow_type():
conn = boto.connect_swf("the_key", "the_secret")
@ -21,6 +23,26 @@ def test_register_workflow_type():
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
def test_register_already_existing_workflow_type():
conn = boto.connect_swf("the_key", "the_secret")
@ -32,6 +54,27 @@ def test_register_already_existing_workflow_type():
).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
def test_register_with_wrong_parameter_type():
conn = boto.connect_swf("the_key", "the_secret")
@ -43,6 +86,7 @@ def test_register_with_wrong_parameter_type():
# ListWorkflowTypes endpoint
# Has boto3 equivalent
@mock_swf_deprecated
def test_list_workflow_types():
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"])
# 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
def test_list_workflow_types_reverse_order():
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"])
# 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
# Has boto3 equivalent
@mock_swf_deprecated
def test_deprecate_workflow_type():
conn = boto.connect_swf("the_key", "the_secret")
@ -91,6 +191,29 @@ def test_deprecate_workflow_type():
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
def test_deprecate_already_deprecated_workflow_type():
conn = boto.connect_swf("the_key", "the_secret")
@ -103,6 +226,31 @@ def test_deprecate_already_deprecated_workflow_type():
).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
def test_deprecate_non_existent_workflow_type():
conn = boto.connect_swf("the_key", "the_secret")
@ -113,6 +261,24 @@ def test_deprecate_non_existent_workflow_type():
).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
@mock_swf
def test_undeprecate_workflow_type():
@ -185,6 +351,7 @@ def test_undeprecate_non_existent_workflow_type():
# DescribeWorkflowType endpoint
# Has boto3 equivalent
@mock_swf_deprecated
def test_describe_workflow_type():
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")
# Has boto3 equivalent
@mock_swf_deprecated
def test_describe_non_existent_workflow_type():
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(
"test-domain", "non-existent", "v1.0"
).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 boto3
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():
args, kwargs = _generic_workflow_type_attributes()
return WorkflowType(*args, **kwargs)
@ -58,6 +70,12 @@ def mock_basic_workflow_type(domain_name, 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
def make_workflow_execution(**kwargs):
domain = get_basic_domain()
@ -93,6 +111,33 @@ def setup_workflow():
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
def process_first_timeout(obj):
_timeout = obj.first_timeout()