Merge branch 'master' into bugfix/#2567
This commit is contained in:
commit
fbb449aa48
@ -7272,9 +7272,9 @@
|
||||
- [X] start_workflow_execution
|
||||
- [ ] tag_resource
|
||||
- [X] terminate_workflow_execution
|
||||
- [ ] undeprecate_activity_type
|
||||
- [ ] undeprecate_domain
|
||||
- [ ] undeprecate_workflow_type
|
||||
- [X] undeprecate_activity_type
|
||||
- [X] undeprecate_domain
|
||||
- [X] undeprecate_workflow_type
|
||||
- [ ] untag_resource
|
||||
|
||||
## textract
|
||||
|
@ -450,9 +450,9 @@ class Item(BaseModel):
|
||||
old_list_key = list_append_re.group(1)
|
||||
# old_key could be a function itself (if_not_exists)
|
||||
if old_list_key.startswith("if_not_exists"):
|
||||
old_list = DynamoType(
|
||||
expression_attribute_values[self._get_default(old_list_key)]
|
||||
)
|
||||
old_list = self._get_default(old_list_key)
|
||||
if not isinstance(old_list, DynamoType):
|
||||
old_list = DynamoType(expression_attribute_values[old_list])
|
||||
else:
|
||||
old_list = self.attrs[old_list_key.split(".")[0]]
|
||||
if "." in old_list_key:
|
||||
|
@ -88,6 +88,8 @@ class RecordSet(BaseModel):
|
||||
self.hosted_zone_name = kwargs.get("HostedZoneName")
|
||||
self.hosted_zone_id = kwargs.get("HostedZoneId")
|
||||
self.alias_target = kwargs.get("AliasTarget")
|
||||
self.failover = kwargs.get("Failover")
|
||||
self.geo_location = kwargs.get("GeoLocation")
|
||||
|
||||
@classmethod
|
||||
def create_from_cloudformation_json(
|
||||
@ -154,6 +156,16 @@ class RecordSet(BaseModel):
|
||||
{% if record_set.ttl %}
|
||||
<TTL>{{ record_set.ttl }}</TTL>
|
||||
{% endif %}
|
||||
{% if record_set.failover %}
|
||||
<Failover>{{ record_set.failover }}</Failover>
|
||||
{% endif %}
|
||||
{% if record_set.geo_location %}
|
||||
<GeoLocation>
|
||||
{% for geo_key in ['ContinentCode','CountryCode','SubdivisionCode'] %}
|
||||
{% if record_set.geo_location[geo_key] %}<{{ geo_key }}>{{ record_set.geo_location[geo_key] }}</{{ geo_key }}>{% endif %}
|
||||
{% endfor %}
|
||||
</GeoLocation>
|
||||
{% endif %}
|
||||
{% if record_set.alias_target %}
|
||||
<AliasTarget>
|
||||
<HostedZoneId>{{ record_set.alias_target['HostedZoneId'] }}</HostedZoneId>
|
||||
|
@ -278,10 +278,7 @@ class SimpleSystemManagerBackend(BaseBackend):
|
||||
self._region = region
|
||||
|
||||
def delete_parameter(self, name):
|
||||
try:
|
||||
del self._parameters[name]
|
||||
except KeyError:
|
||||
pass
|
||||
return self._parameters.pop(name, None)
|
||||
|
||||
def delete_parameters(self, names):
|
||||
result = []
|
||||
|
@ -22,7 +22,13 @@ class SimpleSystemManagerResponse(BaseResponse):
|
||||
|
||||
def delete_parameter(self):
|
||||
name = self._get_param("Name")
|
||||
self.ssm_backend.delete_parameter(name)
|
||||
result = self.ssm_backend.delete_parameter(name)
|
||||
if result is None:
|
||||
error = {
|
||||
"__type": "ParameterNotFound",
|
||||
"message": "Parameter {0} not found.".format(name),
|
||||
}
|
||||
return json.dumps(error), dict(status=400)
|
||||
return json.dumps({})
|
||||
|
||||
def delete_parameters(self):
|
||||
|
@ -121,6 +121,12 @@ class SWFBackend(BaseBackend):
|
||||
raise SWFDomainDeprecatedFault(name)
|
||||
domain.status = "DEPRECATED"
|
||||
|
||||
def undeprecate_domain(self, name):
|
||||
domain = self._get_domain(name)
|
||||
if domain.status == "REGISTERED":
|
||||
raise SWFDomainAlreadyExistsFault(name)
|
||||
domain.status = "REGISTERED"
|
||||
|
||||
def describe_domain(self, name):
|
||||
return self._get_domain(name)
|
||||
|
||||
@ -148,6 +154,13 @@ class SWFBackend(BaseBackend):
|
||||
raise SWFTypeDeprecatedFault(_type)
|
||||
_type.status = "DEPRECATED"
|
||||
|
||||
def undeprecate_type(self, kind, domain_name, name, version):
|
||||
domain = self._get_domain(domain_name)
|
||||
_type = domain.get_type(kind, name, version)
|
||||
if _type.status == "REGISTERED":
|
||||
raise SWFTypeAlreadyExistsFault(_type)
|
||||
_type.status = "REGISTERED"
|
||||
|
||||
def describe_type(self, kind, domain_name, name, version):
|
||||
domain = self._get_domain(domain_name)
|
||||
return domain.get_type(kind, name, version)
|
||||
|
@ -15,7 +15,7 @@ class DecisionTask(BaseModel):
|
||||
self.workflow_type = workflow_execution.workflow_type
|
||||
self.task_token = str(uuid.uuid4())
|
||||
self.scheduled_event_id = scheduled_event_id
|
||||
self.previous_started_event_id = 0
|
||||
self.previous_started_event_id = None
|
||||
self.started_event_id = None
|
||||
self.started_timestamp = None
|
||||
self.start_to_close_timeout = (
|
||||
@ -40,18 +40,20 @@ class DecisionTask(BaseModel):
|
||||
hsh = {
|
||||
"events": [evt.to_dict() for evt in events],
|
||||
"taskToken": self.task_token,
|
||||
"previousStartedEventId": self.previous_started_event_id,
|
||||
"workflowExecution": self.workflow_execution.to_short_dict(),
|
||||
"workflowType": self.workflow_type.to_short_dict(),
|
||||
}
|
||||
if self.previous_started_event_id is not None:
|
||||
hsh["previousStartedEventId"] = self.previous_started_event_id
|
||||
if self.started_event_id:
|
||||
hsh["startedEventId"] = self.started_event_id
|
||||
return hsh
|
||||
|
||||
def start(self, started_event_id):
|
||||
def start(self, started_event_id, previous_started_event_id=None):
|
||||
self.state = "STARTED"
|
||||
self.started_timestamp = unix_time()
|
||||
self.started_event_id = started_event_id
|
||||
self.previous_started_event_id = previous_started_event_id
|
||||
|
||||
def complete(self):
|
||||
self._check_workflow_execution_open()
|
||||
|
@ -82,6 +82,7 @@ class WorkflowExecution(BaseModel):
|
||||
self._events = []
|
||||
# child workflows
|
||||
self.child_workflow_executions = []
|
||||
self._previous_started_event_id = None
|
||||
|
||||
def __repr__(self):
|
||||
return "WorkflowExecution(run_id: {0})".format(self.run_id)
|
||||
@ -295,7 +296,8 @@ class WorkflowExecution(BaseModel):
|
||||
scheduled_event_id=dt.scheduled_event_id,
|
||||
identity=identity,
|
||||
)
|
||||
dt.start(evt.event_id)
|
||||
dt.start(evt.event_id, self._previous_started_event_id)
|
||||
self._previous_started_event_id = evt.event_id
|
||||
|
||||
def complete_decision_task(
|
||||
self, task_token, decisions=None, execution_context=None
|
||||
|
@ -92,6 +92,17 @@ class SWFResponse(BaseResponse):
|
||||
self.swf_backend.deprecate_type(kind, domain, name, version)
|
||||
return ""
|
||||
|
||||
def _undeprecate_type(self, kind):
|
||||
domain = self._params["domain"]
|
||||
_type_args = self._params["{0}Type".format(kind)]
|
||||
name = _type_args["name"]
|
||||
version = _type_args["version"]
|
||||
self._check_string(domain)
|
||||
self._check_string(name)
|
||||
self._check_string(version)
|
||||
self.swf_backend.undeprecate_type(kind, domain, name, version)
|
||||
return ""
|
||||
|
||||
# TODO: implement pagination
|
||||
def list_domains(self):
|
||||
status = self._params["registrationStatus"]
|
||||
@ -219,6 +230,12 @@ class SWFResponse(BaseResponse):
|
||||
self.swf_backend.deprecate_domain(name)
|
||||
return ""
|
||||
|
||||
def undeprecate_domain(self):
|
||||
name = self._params["name"]
|
||||
self._check_string(name)
|
||||
self.swf_backend.undeprecate_domain(name)
|
||||
return ""
|
||||
|
||||
def describe_domain(self):
|
||||
name = self._params["name"]
|
||||
self._check_string(name)
|
||||
@ -278,6 +295,9 @@ class SWFResponse(BaseResponse):
|
||||
def deprecate_activity_type(self):
|
||||
return self._deprecate_type("activity")
|
||||
|
||||
def undeprecate_activity_type(self):
|
||||
return self._undeprecate_type("activity")
|
||||
|
||||
def describe_activity_type(self):
|
||||
return self._describe_type("activity")
|
||||
|
||||
@ -333,6 +353,9 @@ class SWFResponse(BaseResponse):
|
||||
def deprecate_workflow_type(self):
|
||||
return self._deprecate_type("workflow")
|
||||
|
||||
def undeprecate_workflow_type(self):
|
||||
return self._undeprecate_type("workflow")
|
||||
|
||||
def describe_workflow_type(self):
|
||||
return self._describe_type("workflow")
|
||||
|
||||
@ -423,7 +446,9 @@ class SWFResponse(BaseResponse):
|
||||
if decision:
|
||||
return json.dumps(decision.to_full_dict(reverse_order=reverse_order))
|
||||
else:
|
||||
return json.dumps({"previousStartedEventId": 0, "startedEventId": 0})
|
||||
return json.dumps(
|
||||
{"previousStartedEventId": 0, "startedEventId": 0, "taskToken": ""}
|
||||
)
|
||||
|
||||
def count_pending_decision_tasks(self):
|
||||
domain_name = self._params["domain"]
|
||||
@ -457,7 +482,7 @@ class SWFResponse(BaseResponse):
|
||||
if activity_task:
|
||||
return json.dumps(activity_task.to_full_dict())
|
||||
else:
|
||||
return json.dumps({"startedEventId": 0})
|
||||
return json.dumps({"startedEventId": 0, "taskToken": ""})
|
||||
|
||||
def count_pending_activity_tasks(self):
|
||||
domain_name = self._params["domain"]
|
||||
|
@ -1,5 +1,5 @@
|
||||
-r requirements.txt
|
||||
mock
|
||||
mock==3.0.5 # Last version compatible with Python 2.7
|
||||
nose
|
||||
black; python_version >= '3.6'
|
||||
regex==2019.11.1; python_version >= '3.6' # Needed for black
|
||||
|
13
setup.py
13
setup.py
@ -1,20 +1,20 @@
|
||||
#!/usr/bin/env python
|
||||
from __future__ import unicode_literals
|
||||
import codecs
|
||||
from io import open
|
||||
import os
|
||||
import re
|
||||
import setuptools
|
||||
from setuptools import setup, find_packages
|
||||
import sys
|
||||
|
||||
|
||||
# Borrowed from pip at https://github.com/pypa/pip/blob/62c27dee45625e1b63d1e023b0656310f276e050/setup.py#L11-L15
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
def read(*parts):
|
||||
# intentionally *not* adding an encoding option to open, See:
|
||||
# https://github.com/pypa/virtualenv/issues/201#issuecomment-3145690
|
||||
with codecs.open(os.path.join(here, *parts), 'r') as fp:
|
||||
with open(os.path.join(here, *parts), 'r') as fp:
|
||||
return fp.read()
|
||||
|
||||
|
||||
@ -28,7 +28,8 @@ def get_version():
|
||||
|
||||
|
||||
install_requires = [
|
||||
"Jinja2>=2.10.1",
|
||||
"setuptools==44.0.0",
|
||||
"Jinja2==2.11.0",
|
||||
"boto>=2.36.0",
|
||||
"boto3>=1.9.201",
|
||||
"botocore>=1.12.201",
|
||||
@ -41,14 +42,16 @@ install_requires = [
|
||||
"pytz",
|
||||
"python-dateutil<3.0.0,>=2.1",
|
||||
"python-jose<4.0.0",
|
||||
"mock",
|
||||
"mock==3.0.5",
|
||||
"docker>=2.5.1",
|
||||
"jsondiff>=1.1.2",
|
||||
"aws-xray-sdk!=0.96,>=0.93",
|
||||
"responses>=0.9.0",
|
||||
"idna<2.9,>=2.5",
|
||||
"cfn-lint>=0.4.0",
|
||||
"sshpubkeys>=3.1.0,<4.0"
|
||||
"sshpubkeys>=3.1.0,<4.0",
|
||||
"zipp==0.6.0",
|
||||
"more-itertools==5.0.0"
|
||||
]
|
||||
|
||||
extras_require = {
|
||||
|
@ -274,9 +274,7 @@ def test_access_denied_with_not_allowing_policy():
|
||||
user_name = "test-user"
|
||||
inline_policy_document = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{"Effect": "Allow", "Action": ["ec2:Describe*"], "Resource": "*"}
|
||||
],
|
||||
"Statement": [{"Effect": "Allow", "Action": ["ec2:Run*"], "Resource": "*"}],
|
||||
}
|
||||
access_key = create_user_with_access_key_and_inline_policy(
|
||||
user_name, inline_policy_document
|
||||
@ -288,12 +286,14 @@ def test_access_denied_with_not_allowing_policy():
|
||||
aws_secret_access_key=access_key["SecretAccessKey"],
|
||||
)
|
||||
with assert_raises(ClientError) as ex:
|
||||
client.run_instances(MaxCount=1, MinCount=1)
|
||||
client.describe_instances()
|
||||
ex.exception.response["Error"]["Code"].should.equal("AccessDenied")
|
||||
ex.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(403)
|
||||
ex.exception.response["Error"]["Message"].should.equal(
|
||||
"User: arn:aws:iam::{account_id}:user/{user_name} is not authorized to perform: {operation}".format(
|
||||
account_id=ACCOUNT_ID, user_name=user_name, operation="ec2:RunInstances"
|
||||
account_id=ACCOUNT_ID,
|
||||
user_name=user_name,
|
||||
operation="ec2:DescribeInstances",
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -3634,6 +3634,31 @@ def test_update_supports_list_append_with_nested_if_not_exists_operation():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
def test_update_supports_list_append_with_nested_if_not_exists_operation_and_property_already_exists():
|
||||
dynamo = boto3.resource("dynamodb", region_name="us-west-1")
|
||||
table_name = "test"
|
||||
|
||||
dynamo.create_table(
|
||||
TableName=table_name,
|
||||
AttributeDefinitions=[{"AttributeName": "Id", "AttributeType": "S"}],
|
||||
KeySchema=[{"AttributeName": "Id", "KeyType": "HASH"}],
|
||||
ProvisionedThroughput={"ReadCapacityUnits": 20, "WriteCapacityUnits": 20},
|
||||
)
|
||||
|
||||
table = dynamo.Table(table_name)
|
||||
|
||||
table.put_item(Item={"Id": "item-id", "event_history": ["other_value"]})
|
||||
table.update_item(
|
||||
Key={"Id": "item-id"},
|
||||
UpdateExpression="SET event_history = list_append(if_not_exists(event_history, :empty_list), :new_value)",
|
||||
ExpressionAttributeValues={":empty_list": [], ":new_value": ["some_value"]},
|
||||
)
|
||||
table.get_item(Key={"Id": "item-id"})["Item"].should.equal(
|
||||
{"Id": "item-id", "event_history": ["other_value", "some_value"]}
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
def test_update_catches_invalid_list_append_operation():
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
@ -753,6 +753,79 @@ def test_change_weighted_resource_record_sets():
|
||||
record["Weight"].should.equal(10)
|
||||
|
||||
|
||||
@mock_route53
|
||||
def test_failover_record_sets():
|
||||
conn = boto3.client("route53", region_name="us-east-2")
|
||||
conn.create_hosted_zone(Name="test.zone.", CallerReference=str(hash("test")))
|
||||
zones = conn.list_hosted_zones_by_name(DNSName="test.zone.")
|
||||
hosted_zone_id = zones["HostedZones"][0]["Id"]
|
||||
|
||||
# Create geolocation record
|
||||
conn.change_resource_record_sets(
|
||||
HostedZoneId=hosted_zone_id,
|
||||
ChangeBatch={
|
||||
"Changes": [
|
||||
{
|
||||
"Action": "CREATE",
|
||||
"ResourceRecordSet": {
|
||||
"Name": "failover.test.zone.",
|
||||
"Type": "A",
|
||||
"TTL": 10,
|
||||
"ResourceRecords": [{"Value": "127.0.0.1"}],
|
||||
"Failover": "PRIMARY",
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
response = conn.list_resource_record_sets(HostedZoneId=hosted_zone_id)
|
||||
record = response["ResourceRecordSets"][0]
|
||||
record["Failover"].should.equal("PRIMARY")
|
||||
|
||||
|
||||
@mock_route53
|
||||
def test_geolocation_record_sets():
|
||||
conn = boto3.client("route53", region_name="us-east-2")
|
||||
conn.create_hosted_zone(Name="test.zone.", CallerReference=str(hash("test")))
|
||||
zones = conn.list_hosted_zones_by_name(DNSName="test.zone.")
|
||||
hosted_zone_id = zones["HostedZones"][0]["Id"]
|
||||
|
||||
# Create geolocation record
|
||||
conn.change_resource_record_sets(
|
||||
HostedZoneId=hosted_zone_id,
|
||||
ChangeBatch={
|
||||
"Changes": [
|
||||
{
|
||||
"Action": "CREATE",
|
||||
"ResourceRecordSet": {
|
||||
"Name": "georecord1.test.zone.",
|
||||
"Type": "A",
|
||||
"TTL": 10,
|
||||
"ResourceRecords": [{"Value": "127.0.0.1"}],
|
||||
"GeoLocation": {"ContinentCode": "EU"},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Action": "CREATE",
|
||||
"ResourceRecordSet": {
|
||||
"Name": "georecord2.test.zone.",
|
||||
"Type": "A",
|
||||
"TTL": 10,
|
||||
"ResourceRecords": [{"Value": "127.0.0.2"}],
|
||||
"GeoLocation": {"CountryCode": "US", "SubdivisionCode": "NY"},
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
response = conn.list_resource_record_sets(HostedZoneId=hosted_zone_id)
|
||||
rrs = response["ResourceRecordSets"]
|
||||
rrs[0]["GeoLocation"].should.equal({"ContinentCode": "EU"})
|
||||
rrs[1]["GeoLocation"].should.equal({"CountryCode": "US", "SubdivisionCode": "NY"})
|
||||
|
||||
|
||||
@mock_route53
|
||||
def test_change_resource_record_invalid():
|
||||
conn = boto3.client("route53", region_name="us-east-1")
|
||||
|
@ -30,6 +30,18 @@ def test_delete_parameter():
|
||||
len(response["Parameters"]).should.equal(0)
|
||||
|
||||
|
||||
@mock_ssm
|
||||
def test_delete_nonexistent_parameter():
|
||||
client = boto3.client("ssm", region_name="us-east-1")
|
||||
|
||||
with assert_raises(ClientError) as ex:
|
||||
client.delete_parameter(Name="test_noexist")
|
||||
ex.exception.response["Error"]["Code"].should.equal("ParameterNotFound")
|
||||
ex.exception.response["Error"]["Message"].should.equal(
|
||||
"Parameter test_noexist not found."
|
||||
)
|
||||
|
||||
|
||||
@mock_ssm
|
||||
def test_delete_parameters():
|
||||
client = boto3.client("ssm", region_name="us-east-1")
|
||||
|
@ -24,15 +24,16 @@ def test_decision_task_full_dict_representation():
|
||||
|
||||
fd = dt.to_full_dict()
|
||||
fd["events"].should.be.a("list")
|
||||
fd["previousStartedEventId"].should.equal(0)
|
||||
fd.should_not.contain("previousStartedEventId")
|
||||
fd.should_not.contain("startedEventId")
|
||||
fd.should.contain("taskToken")
|
||||
fd["workflowExecution"].should.equal(wfe.to_short_dict())
|
||||
fd["workflowType"].should.equal(wft.to_short_dict())
|
||||
|
||||
dt.start(1234)
|
||||
dt.start(1234, 1230)
|
||||
fd = dt.to_full_dict()
|
||||
fd["startedEventId"].should.equal(1234)
|
||||
fd["previousStartedEventId"].should.equal(1230)
|
||||
|
||||
|
||||
def test_decision_task_first_timeout():
|
||||
|
@ -35,14 +35,14 @@ def test_poll_for_activity_task_when_one():
|
||||
def test_poll_for_activity_task_when_none():
|
||||
conn = setup_workflow()
|
||||
resp = conn.poll_for_activity_task("test-domain", "activity-task-list")
|
||||
resp.should.equal({"startedEventId": 0})
|
||||
resp.should.equal({"startedEventId": 0, "taskToken": ""})
|
||||
|
||||
|
||||
@mock_swf_deprecated
|
||||
def test_poll_for_activity_task_on_non_existent_queue():
|
||||
conn = setup_workflow()
|
||||
resp = conn.poll_for_activity_task("test-domain", "non-existent-queue")
|
||||
resp.should.equal({"startedEventId": 0})
|
||||
resp.should.equal({"startedEventId": 0, "taskToken": ""})
|
||||
|
||||
|
||||
# CountPendingActivityTasks endpoint
|
||||
|
@ -1,8 +1,11 @@
|
||||
import boto
|
||||
from boto.swf.exceptions import SWFResponseError
|
||||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_swf_deprecated
|
||||
from moto import mock_swf
|
||||
|
||||
|
||||
# RegisterActivityType endpoint
|
||||
@ -110,6 +113,77 @@ def test_deprecate_non_existent_activity_type():
|
||||
).should.throw(SWFResponseError)
|
||||
|
||||
|
||||
# DeprecateActivityType endpoint
|
||||
@mock_swf
|
||||
def test_undeprecate_activity_type():
|
||||
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"
|
||||
)
|
||||
client.deprecate_activity_type(
|
||||
domain="test-domain", activityType={"name": "test-activity", "version": "v1.0"}
|
||||
)
|
||||
client.undeprecate_activity_type(
|
||||
domain="test-domain", activityType={"name": "test-activity", "version": "v1.0"}
|
||||
)
|
||||
|
||||
resp = client.describe_activity_type(
|
||||
domain="test-domain", activityType={"name": "test-activity", "version": "v1.0"}
|
||||
)
|
||||
resp["typeInfo"]["status"].should.equal("REGISTERED")
|
||||
|
||||
|
||||
@mock_swf
|
||||
def test_undeprecate_already_undeprecated_activity_type():
|
||||
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"
|
||||
)
|
||||
client.deprecate_activity_type(
|
||||
domain="test-domain", activityType={"name": "test-activity", "version": "v1.0"}
|
||||
)
|
||||
client.undeprecate_activity_type(
|
||||
domain="test-domain", activityType={"name": "test-activity", "version": "v1.0"}
|
||||
)
|
||||
|
||||
client.undeprecate_activity_type.when.called_with(
|
||||
domain="test-domain", activityType={"name": "test-activity", "version": "v1.0"}
|
||||
).should.throw(ClientError)
|
||||
|
||||
|
||||
@mock_swf
|
||||
def test_undeprecate_never_deprecated_activity_type():
|
||||
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"
|
||||
)
|
||||
|
||||
client.undeprecate_activity_type.when.called_with(
|
||||
domain="test-domain", activityType={"name": "test-activity", "version": "v1.0"}
|
||||
).should.throw(ClientError)
|
||||
|
||||
|
||||
@mock_swf
|
||||
def test_undeprecate_non_existent_activity_type():
|
||||
client = boto3.client("swf", region_name="us-east-1")
|
||||
client.register_domain(
|
||||
name="test-domain", workflowExecutionRetentionPeriodInDays="60"
|
||||
)
|
||||
|
||||
client.undeprecate_activity_type.when.called_with(
|
||||
domain="test-domain", activityType={"name": "test-activity", "version": "v1.0"}
|
||||
).should.throw(ClientError)
|
||||
|
||||
|
||||
# DescribeActivityType endpoint
|
||||
@mock_swf_deprecated
|
||||
def test_describe_activity_type():
|
||||
|
@ -30,6 +30,30 @@ def test_poll_for_decision_task_when_one():
|
||||
)
|
||||
|
||||
|
||||
@mock_swf_deprecated
|
||||
def test_poll_for_decision_task_previous_started_event_id():
|
||||
conn = setup_workflow()
|
||||
|
||||
resp = conn.poll_for_decision_task("test-domain", "queue")
|
||||
assert resp["workflowExecution"]["runId"] == conn.run_id
|
||||
assert "previousStartedEventId" not in resp
|
||||
|
||||
# Require a failing decision, in this case a non-existant activity type
|
||||
attrs = {
|
||||
"activityId": "spam",
|
||||
"activityType": {"name": "test-activity", "version": "v1.42"},
|
||||
"taskList": "eggs",
|
||||
}
|
||||
decision = {
|
||||
"decisionType": "ScheduleActivityTask",
|
||||
"scheduleActivityTaskDecisionAttributes": attrs,
|
||||
}
|
||||
conn.respond_decision_task_completed(resp["taskToken"], decisions=[decision])
|
||||
resp = conn.poll_for_decision_task("test-domain", "queue")
|
||||
assert resp["workflowExecution"]["runId"] == conn.run_id
|
||||
assert resp["previousStartedEventId"] == 3
|
||||
|
||||
|
||||
@mock_swf_deprecated
|
||||
def test_poll_for_decision_task_when_none():
|
||||
conn = setup_workflow()
|
||||
@ -38,14 +62,18 @@ def test_poll_for_decision_task_when_none():
|
||||
resp = conn.poll_for_decision_task("test-domain", "queue")
|
||||
# this is the DecisionTask representation you get from the real SWF
|
||||
# after waiting 60s when there's no decision to be taken
|
||||
resp.should.equal({"previousStartedEventId": 0, "startedEventId": 0})
|
||||
resp.should.equal(
|
||||
{"previousStartedEventId": 0, "startedEventId": 0, "taskToken": ""}
|
||||
)
|
||||
|
||||
|
||||
@mock_swf_deprecated
|
||||
def test_poll_for_decision_task_on_non_existent_queue():
|
||||
conn = setup_workflow()
|
||||
resp = conn.poll_for_decision_task("test-domain", "non-existent-queue")
|
||||
resp.should.equal({"previousStartedEventId": 0, "startedEventId": 0})
|
||||
resp.should.equal(
|
||||
{"previousStartedEventId": 0, "startedEventId": 0, "taskToken": ""}
|
||||
)
|
||||
|
||||
|
||||
@mock_swf_deprecated
|
||||
|
@ -1,8 +1,11 @@
|
||||
import boto
|
||||
from boto.swf.exceptions import SWFResponseError
|
||||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_swf_deprecated
|
||||
from moto import mock_swf
|
||||
|
||||
|
||||
# RegisterDomain endpoint
|
||||
@ -94,6 +97,56 @@ def test_deprecate_non_existent_domain():
|
||||
)
|
||||
|
||||
|
||||
# UndeprecateDomain endpoint
|
||||
@mock_swf
|
||||
def test_undeprecate_domain():
|
||||
client = boto3.client("swf", region_name="us-east-1")
|
||||
client.register_domain(
|
||||
name="test-domain", workflowExecutionRetentionPeriodInDays="60"
|
||||
)
|
||||
client.deprecate_domain(name="test-domain")
|
||||
client.undeprecate_domain(name="test-domain")
|
||||
|
||||
resp = client.describe_domain(name="test-domain")
|
||||
|
||||
resp["domainInfo"]["status"].should.equal("REGISTERED")
|
||||
|
||||
|
||||
@mock_swf
|
||||
def test_undeprecate_already_undeprecated_domain():
|
||||
client = boto3.client("swf", region_name="us-east-1")
|
||||
client.register_domain(
|
||||
name="test-domain", workflowExecutionRetentionPeriodInDays="60"
|
||||
)
|
||||
client.deprecate_domain(name="test-domain")
|
||||
client.undeprecate_domain(name="test-domain")
|
||||
|
||||
client.undeprecate_domain.when.called_with(name="test-domain").should.throw(
|
||||
ClientError
|
||||
)
|
||||
|
||||
|
||||
@mock_swf
|
||||
def test_undeprecate_never_deprecated_domain():
|
||||
client = boto3.client("swf", region_name="us-east-1")
|
||||
client.register_domain(
|
||||
name="test-domain", workflowExecutionRetentionPeriodInDays="60"
|
||||
)
|
||||
|
||||
client.undeprecate_domain.when.called_with(name="test-domain").should.throw(
|
||||
ClientError
|
||||
)
|
||||
|
||||
|
||||
@mock_swf
|
||||
def test_undeprecate_non_existent_domain():
|
||||
client = boto3.client("swf", region_name="us-east-1")
|
||||
|
||||
client.undeprecate_domain.when.called_with(name="non-existent").should.throw(
|
||||
ClientError
|
||||
)
|
||||
|
||||
|
||||
# DescribeDomain endpoint
|
||||
@mock_swf_deprecated
|
||||
def test_describe_domain():
|
||||
|
@ -5,6 +5,7 @@ import boto3
|
||||
from moto import mock_swf_deprecated
|
||||
from moto import mock_swf
|
||||
from boto.swf.exceptions import SWFResponseError
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
|
||||
# RegisterWorkflowType endpoint
|
||||
@ -112,6 +113,77 @@ def test_deprecate_non_existent_workflow_type():
|
||||
).should.throw(SWFResponseError)
|
||||
|
||||
|
||||
# UndeprecateWorkflowType endpoint
|
||||
@mock_swf
|
||||
def test_undeprecate_workflow_type():
|
||||
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"}
|
||||
)
|
||||
client.undeprecate_workflow_type(
|
||||
domain="test-domain", workflowType={"name": "test-workflow", "version": "v1.0"}
|
||||
)
|
||||
|
||||
resp = client.describe_workflow_type(
|
||||
domain="test-domain", workflowType={"name": "test-workflow", "version": "v1.0"}
|
||||
)
|
||||
resp["typeInfo"]["status"].should.equal("REGISTERED")
|
||||
|
||||
|
||||
@mock_swf
|
||||
def test_undeprecate_already_undeprecated_workflow_type():
|
||||
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"}
|
||||
)
|
||||
client.undeprecate_workflow_type(
|
||||
domain="test-domain", workflowType={"name": "test-workflow", "version": "v1.0"}
|
||||
)
|
||||
|
||||
client.undeprecate_workflow_type.when.called_with(
|
||||
domain="test-domain", workflowType={"name": "test-workflow", "version": "v1.0"}
|
||||
).should.throw(ClientError)
|
||||
|
||||
|
||||
@mock_swf
|
||||
def test_undeprecate_never_deprecated_workflow_type():
|
||||
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.undeprecate_workflow_type.when.called_with(
|
||||
domain="test-domain", workflowType={"name": "test-workflow", "version": "v1.0"}
|
||||
).should.throw(ClientError)
|
||||
|
||||
|
||||
@mock_swf
|
||||
def test_undeprecate_non_existent_workflow_type():
|
||||
client = boto3.client("swf", region_name="us-east-1")
|
||||
client.register_domain(
|
||||
name="test-domain", workflowExecutionRetentionPeriodInDays="60"
|
||||
)
|
||||
|
||||
client.undeprecate_workflow_type.when.called_with(
|
||||
domain="test-domain", workflowType={"name": "test-workflow", "version": "v1.0"}
|
||||
).should.throw(ClientError)
|
||||
|
||||
|
||||
# DescribeWorkflowType endpoint
|
||||
@mock_swf_deprecated
|
||||
def test_describe_workflow_type():
|
||||
|
Loading…
Reference in New Issue
Block a user