From a53a97d136054e2acf134e6a28d707f02cbabe5b Mon Sep 17 00:00:00 2001 From: Steve Pulec Date: Sun, 17 Jan 2016 18:00:57 -0500 Subject: [PATCH] Cleanup SWF to use HTTP exceptions so that the standalone server will work. Closes #495. --- moto/core/exceptions.py | 28 ++++++- moto/swf/exceptions.py | 44 +++++------ tests/test_swf/models/test_decision_task.py | 3 +- tests/test_swf/models/test_domain.py | 12 +-- .../models/test_workflow_execution.py | 5 +- .../test_swf/responses/test_activity_tasks.py | 15 ++-- .../test_swf/responses/test_activity_types.py | 17 ++--- .../test_swf/responses/test_decision_tasks.py | 20 ++--- tests/test_swf/responses/test_domains.py | 17 ++--- .../responses/test_workflow_executions.py | 26 +++---- .../test_swf/responses/test_workflow_types.py | 17 ++--- tests/test_swf/test_exceptions.py | 74 +++++++++---------- 12 files changed, 136 insertions(+), 142 deletions(-) diff --git a/moto/core/exceptions.py b/moto/core/exceptions.py index d5a754e78..fcb6ec96e 100644 --- a/moto/core/exceptions.py +++ b/moto/core/exceptions.py @@ -1,12 +1,13 @@ from werkzeug.exceptions import HTTPException from jinja2 import DictLoader, Environment +from six import text_type ERROR_RESPONSE = u""" - {{code}} + {{error_type}} {{message}} {% block extra %}{% endblock %} @@ -15,14 +16,33 @@ ERROR_RESPONSE = u""" """ +ERROR_JSON_RESPONSE = u"""{ + "message": "{{message}}", + "__type": "{{error_type}}" +} +""" class RESTError(HTTPException): templates = { - 'error': ERROR_RESPONSE + 'error': ERROR_RESPONSE, + 'error_json': ERROR_JSON_RESPONSE, } - def __init__(self, code, message, template='error', **kwargs): + def __init__(self, error_type, message, template='error', **kwargs): super(RESTError, self).__init__() env = Environment(loader=DictLoader(self.templates)) + self.error_type = error_type + self.message = message self.description = env.get_template(template).render( - code=code, message=message, **kwargs) + error_type=error_type, message=message, **kwargs) + + +class JsonRESTError(RESTError): + def __init__(self, error_type, message, template='error_json', **kwargs): + super(JsonRESTError, self).__init__(error_type, message, template, **kwargs) + + def get_headers(self, *args, **kwargs): + return [('Content-Type', 'application/json')] + + def get_body(self, *args, **kwargs): + return self.description diff --git a/moto/swf/exceptions.py b/moto/swf/exceptions.py index a2e12fd73..010460ed5 100644 --- a/moto/swf/exceptions.py +++ b/moto/swf/exceptions.py @@ -1,14 +1,10 @@ from __future__ import unicode_literals -from boto.exception import JSONResponseError +from moto.core.exceptions import JsonRESTError -class SWFClientError(JSONResponseError): - def __init__(self, message, __type): - super(SWFClientError, self).__init__( - 400, "Bad Request", - body={"message": message, "__type": __type} - ) +class SWFClientError(JsonRESTError): + code = 400 class SWFUnknownResourceFault(SWFClientError): @@ -18,54 +14,59 @@ class SWFUnknownResourceFault(SWFClientError): else: message = "Unknown {0}".format(resource_type) super(SWFUnknownResourceFault, self).__init__( + "com.amazonaws.swf.base.model#UnknownResourceFault", message, - "com.amazonaws.swf.base.model#UnknownResourceFault") + ) class SWFDomainAlreadyExistsFault(SWFClientError): def __init__(self, domain_name): super(SWFDomainAlreadyExistsFault, self).__init__( + "com.amazonaws.swf.base.model#DomainAlreadyExistsFault", domain_name, - "com.amazonaws.swf.base.model#DomainAlreadyExistsFault") + ) class SWFDomainDeprecatedFault(SWFClientError): def __init__(self, domain_name): super(SWFDomainDeprecatedFault, self).__init__( + "com.amazonaws.swf.base.model#DomainDeprecatedFault", domain_name, - "com.amazonaws.swf.base.model#DomainDeprecatedFault") + ) -class SWFSerializationException(JSONResponseError): +class SWFSerializationException(SWFClientError): def __init__(self, value): message = "class java.lang.Foo can not be converted to an String " message += " (not a real SWF exception ; happened on: {0})".format(value) __type = "com.amazonaws.swf.base.model#SerializationException" super(SWFSerializationException, self).__init__( - 400, "Bad Request", - body={"Message": message, "__type": __type} + __type, + message, ) class SWFTypeAlreadyExistsFault(SWFClientError): def __init__(self, _type): super(SWFTypeAlreadyExistsFault, self).__init__( + "com.amazonaws.swf.base.model#TypeAlreadyExistsFault", "{0}=[name={1}, version={2}]".format(_type.__class__.__name__, _type.name, _type.version), - "com.amazonaws.swf.base.model#TypeAlreadyExistsFault") + ) class SWFTypeDeprecatedFault(SWFClientError): def __init__(self, _type): super(SWFTypeDeprecatedFault, self).__init__( + "com.amazonaws.swf.base.model#TypeDeprecatedFault", "{0}=[name={1}, version={2}]".format(_type.__class__.__name__, _type.name, _type.version), - "com.amazonaws.swf.base.model#TypeDeprecatedFault") + ) -class SWFWorkflowExecutionAlreadyStartedFault(JSONResponseError): +class SWFWorkflowExecutionAlreadyStartedFault(SWFClientError): def __init__(self): super(SWFWorkflowExecutionAlreadyStartedFault, self).__init__( - 400, "Bad Request", - body={"__type": "com.amazonaws.swf.base.model#WorkflowExecutionAlreadyStartedFault"} + "com.amazonaws.swf.base.model#WorkflowExecutionAlreadyStartedFault", + "Already Started", ) @@ -77,15 +78,16 @@ class SWFDefaultUndefinedFault(SWFClientError): for word in words: key_camel_case += word.capitalize() super(SWFDefaultUndefinedFault, self).__init__( - key_camel_case, "com.amazonaws.swf.base.model#DefaultUndefinedFault" + "com.amazonaws.swf.base.model#DefaultUndefinedFault", + key_camel_case, ) class SWFValidationException(SWFClientError): def __init__(self, message): super(SWFValidationException, self).__init__( + "com.amazon.coral.validate#ValidationException", message, - "com.amazon.coral.validate#ValidationException" ) @@ -116,8 +118,8 @@ class SWFDecisionValidationException(SWFClientError): else: prefix = "{0} validation errors detected: " super(SWFDecisionValidationException, self).__init__( + "com.amazon.coral.validate#ValidationException", prefix.format(count) + "; ".join(messages), - "com.amazon.coral.validate#ValidationException" ) diff --git a/tests/test_swf/models/test_decision_task.py b/tests/test_swf/models/test_decision_task.py index 2c4439dd5..85453e0e4 100644 --- a/tests/test_swf/models/test_decision_task.py +++ b/tests/test_swf/models/test_decision_task.py @@ -1,8 +1,9 @@ +from boto.swf.exceptions import SWFResponseError from freezegun import freeze_time from sure import expect -from moto.swf.exceptions import SWFWorkflowExecutionClosedError from moto.swf.models import DecisionTask, Timeout +from moto.swf.exceptions import SWFWorkflowExecutionClosedError from ..utils import make_workflow_execution, process_first_timeout diff --git a/tests/test_swf/models/test_domain.py b/tests/test_swf/models/test_domain.py index 515e633f9..549400e6a 100644 --- a/tests/test_swf/models/test_domain.py +++ b/tests/test_swf/models/test_domain.py @@ -4,6 +4,9 @@ from sure import expect from moto.swf.exceptions import SWFUnknownResourceFault from moto.swf.models import Domain +# Ensure 'assert_raises' context manager support for Python 2.6 +import tests.backport_assert_raises # noqa +from nose.tools import assert_raises # Fake WorkflowExecution for tests purposes WorkflowExecution = namedtuple( @@ -69,11 +72,11 @@ def test_domain_get_workflow_execution(): domain.get_workflow_execution("wf-id-1", run_id="run-id-1").should.equal(wfe1) domain.get_workflow_execution("wf-id-1", run_id="run-id-2").should.equal(wfe2) domain.get_workflow_execution("wf-id-3", run_id="run-id-4").should.equal(wfe4) + domain.get_workflow_execution.when.called_with( "wf-id-1", run_id="non-existent" ).should.throw( SWFUnknownResourceFault, - "Unknown execution: WorkflowExecution=[workflowId=wf-id-1, runId=non-existent]" ) # get OPEN workflow execution by default if no run_id @@ -81,12 +84,12 @@ def test_domain_get_workflow_execution(): domain.get_workflow_execution.when.called_with( "wf-id-3" ).should.throw( - SWFUnknownResourceFault, "Unknown execution, workflowId = wf-id-3" + SWFUnknownResourceFault ) domain.get_workflow_execution.when.called_with( "wf-id-non-existent" ).should.throw( - SWFUnknownResourceFault, "Unknown execution, workflowId = wf-id-non-existent" + SWFUnknownResourceFault ) # raise_if_closed attribute @@ -94,8 +97,7 @@ def test_domain_get_workflow_execution(): domain.get_workflow_execution.when.called_with( "wf-id-3", run_id="run-id-4", raise_if_closed=True ).should.throw( - SWFUnknownResourceFault, - "Unknown execution: WorkflowExecution=[workflowId=wf-id-3, runId=run-id-4]" + SWFUnknownResourceFault ) # raise_if_none attribute diff --git a/tests/test_swf/models/test_workflow_execution.py b/tests/test_swf/models/test_workflow_execution.py index 0546c2f93..00fbe0032 100644 --- a/tests/test_swf/models/test_workflow_execution.py +++ b/tests/test_swf/models/test_workflow_execution.py @@ -7,10 +7,7 @@ from moto.swf.models import ( WorkflowType, WorkflowExecution, ) -from moto.swf.exceptions import ( - SWFDefaultUndefinedFault, -) - +from moto.swf.exceptions import SWFDefaultUndefinedFault from ..utils import ( auto_start_decision_tasks, get_basic_domain, diff --git a/tests/test_swf/responses/test_activity_tasks.py b/tests/test_swf/responses/test_activity_tasks.py index 6f84c663e..eba5eb32d 100644 --- a/tests/test_swf/responses/test_activity_tasks.py +++ b/tests/test_swf/responses/test_activity_tasks.py @@ -1,13 +1,10 @@ import boto +from boto.swf.exceptions import SWFResponseError from freezegun import freeze_time from sure import expect from moto import mock_swf from moto.swf import swf_backend -from moto.swf.exceptions import ( - SWFValidationException, - SWFUnknownResourceFault, -) from ..utils import setup_workflow, SCHEDULE_ACTIVITY_TASK_DECISION @@ -91,7 +88,7 @@ def test_respond_activity_task_completed_with_wrong_token(): conn.poll_for_activity_task("test-domain", "activity-task-list") conn.respond_activity_task_completed.when.called_with( "not-a-correct-token" - ).should.throw(SWFValidationException, "Invalid token") + ).should.throw(SWFResponseError, "Invalid token") @mock_swf def test_respond_activity_task_completed_on_closed_workflow_execution(): @@ -109,7 +106,7 @@ def test_respond_activity_task_completed_on_closed_workflow_execution(): conn.respond_activity_task_completed.when.called_with( activity_token - ).should.throw(SWFUnknownResourceFault, "WorkflowExecution=") + ).should.throw(SWFResponseError, "WorkflowExecution=") @mock_swf def test_respond_activity_task_completed_with_task_already_completed(): @@ -124,7 +121,7 @@ def test_respond_activity_task_completed_with_task_already_completed(): conn.respond_activity_task_completed.when.called_with( activity_token - ).should.throw(SWFUnknownResourceFault, "Unknown activity, scheduledEventId = 5") + ).should.throw(SWFResponseError, "Unknown activity, scheduledEventId = 5") # RespondActivityTaskFailed endpoint @@ -162,7 +159,7 @@ def test_respond_activity_task_completed_with_wrong_token(): conn.poll_for_activity_task("test-domain", "activity-task-list") conn.respond_activity_task_failed.when.called_with( "not-a-correct-token" - ).should.throw(SWFValidationException, "Invalid token") + ).should.throw(SWFResponseError, "Invalid token") # RecordActivityTaskHeartbeat endpoint @@ -189,7 +186,7 @@ def test_record_activity_task_heartbeat_with_wrong_token(): conn.record_activity_task_heartbeat.when.called_with( "bad-token", details="some progress details" - ).should.throw(SWFValidationException) + ).should.throw(SWFResponseError) @mock_swf def test_record_activity_task_heartbeat_sets_details_in_case_of_timeout(): diff --git a/tests/test_swf/responses/test_activity_types.py b/tests/test_swf/responses/test_activity_types.py index e8612ef0f..99f39c474 100644 --- a/tests/test_swf/responses/test_activity_types.py +++ b/tests/test_swf/responses/test_activity_types.py @@ -1,13 +1,8 @@ import boto +from boto.swf.exceptions import SWFResponseError from sure import expect from moto import mock_swf -from moto.swf.exceptions import ( - SWFUnknownResourceFault, - SWFTypeAlreadyExistsFault, - SWFTypeDeprecatedFault, - SWFSerializationException, -) # RegisterActivityType endpoint @@ -30,7 +25,7 @@ def test_register_already_existing_activity_type(): conn.register_activity_type.when.called_with( "test-domain", "test-activity", "v1.0" - ).should.throw(SWFTypeAlreadyExistsFault) + ).should.throw(SWFResponseError) @mock_swf def test_register_with_wrong_parameter_type(): @@ -39,7 +34,7 @@ def test_register_with_wrong_parameter_type(): conn.register_activity_type.when.called_with( "test-domain", "test-activity", 12 - ).should.throw(SWFSerializationException) + ).should.throw(SWFResponseError) # ListActivityTypes endpoint @mock_swf @@ -90,7 +85,7 @@ def test_deprecate_already_deprecated_activity_type(): conn.deprecate_activity_type.when.called_with( "test-domain", "test-activity", "v1.0" - ).should.throw(SWFTypeDeprecatedFault) + ).should.throw(SWFResponseError) @mock_swf def test_deprecate_non_existent_activity_type(): @@ -99,7 +94,7 @@ def test_deprecate_non_existent_activity_type(): conn.deprecate_activity_type.when.called_with( "test-domain", "non-existent", "v1.0" - ).should.throw(SWFUnknownResourceFault) + ).should.throw(SWFResponseError) # DescribeActivityType endpoint @mock_swf @@ -123,4 +118,4 @@ def test_describe_non_existent_activity_type(): conn.describe_activity_type.when.called_with( "test-domain", "non-existent", "v1.0" - ).should.throw(SWFUnknownResourceFault) + ).should.throw(SWFResponseError) diff --git a/tests/test_swf/responses/test_decision_tasks.py b/tests/test_swf/responses/test_decision_tasks.py index 7e9ecddb1..eb2af5674 100644 --- a/tests/test_swf/responses/test_decision_tasks.py +++ b/tests/test_swf/responses/test_decision_tasks.py @@ -1,14 +1,10 @@ import boto +from boto.swf.exceptions import SWFResponseError from freezegun import freeze_time from sure import expect from moto import mock_swf from moto.swf import swf_backend -from moto.swf.exceptions import ( - SWFUnknownResourceFault, - SWFValidationException, - SWFDecisionValidationException, -) from ..utils import setup_workflow @@ -114,7 +110,7 @@ def test_respond_decision_task_completed_with_wrong_token(): resp = conn.poll_for_decision_task("test-domain", "queue") conn.respond_decision_task_completed.when.called_with( "not-a-correct-token" - ).should.throw(SWFValidationException) + ).should.throw(SWFResponseError) @mock_swf def test_respond_decision_task_completed_on_close_workflow_execution(): @@ -129,7 +125,7 @@ def test_respond_decision_task_completed_on_close_workflow_execution(): conn.respond_decision_task_completed.when.called_with( task_token - ).should.throw(SWFUnknownResourceFault) + ).should.throw(SWFResponseError) @mock_swf def test_respond_decision_task_completed_with_task_already_completed(): @@ -140,7 +136,7 @@ def test_respond_decision_task_completed_with_task_already_completed(): conn.respond_decision_task_completed.when.called_with( task_token - ).should.throw(SWFUnknownResourceFault) + ).should.throw(SWFResponseError) @mock_swf def test_respond_decision_task_completed_with_complete_workflow_execution(): @@ -179,7 +175,7 @@ def test_respond_decision_task_completed_with_close_decision_not_last(): conn.respond_decision_task_completed.when.called_with( task_token, decisions=decisions - ).should.throw(SWFValidationException, r"Close must be last decision in list") + ).should.throw(SWFResponseError, r"Close must be last decision in list") @mock_swf def test_respond_decision_task_completed_with_invalid_decision_type(): @@ -195,7 +191,7 @@ def test_respond_decision_task_completed_with_invalid_decision_type(): conn.respond_decision_task_completed.when.called_with( task_token, decisions=decisions ).should.throw( - SWFDecisionValidationException, + SWFResponseError, r"Value 'BadDecisionType' at 'decisions.1.member.decisionType'" ) @@ -215,7 +211,7 @@ def test_respond_decision_task_completed_with_missing_attributes(): conn.respond_decision_task_completed.when.called_with( task_token, decisions=decisions ).should.throw( - SWFDecisionValidationException, + SWFResponseError, r"Value null at 'decisions.1.member.startTimerDecisionAttributes.timerId' " \ r"failed to satisfy constraint: Member must not be null" ) @@ -233,7 +229,7 @@ def test_respond_decision_task_completed_with_missing_attributes_totally(): conn.respond_decision_task_completed.when.called_with( task_token, decisions=decisions ).should.throw( - SWFDecisionValidationException, + SWFResponseError, r"Value null at 'decisions.1.member.startTimerDecisionAttributes.timerId' " \ r"failed to satisfy constraint: Member must not be null" ) diff --git a/tests/test_swf/responses/test_domains.py b/tests/test_swf/responses/test_domains.py index f43200aaf..5d77e55af 100644 --- a/tests/test_swf/responses/test_domains.py +++ b/tests/test_swf/responses/test_domains.py @@ -1,13 +1,8 @@ import boto +from boto.swf.exceptions import SWFResponseError from sure import expect from moto import mock_swf -from moto.swf.exceptions import ( - SWFUnknownResourceFault, - SWFDomainAlreadyExistsFault, - SWFDomainDeprecatedFault, - SWFSerializationException, -) # RegisterDomain endpoint @@ -30,7 +25,7 @@ def test_register_already_existing_domain(): conn.register_domain.when.called_with( "test-domain", "60", description="A test domain" - ).should.throw(SWFDomainAlreadyExistsFault) + ).should.throw(SWFResponseError) @mock_swf def test_register_with_wrong_parameter_type(): @@ -38,7 +33,7 @@ def test_register_with_wrong_parameter_type(): conn.register_domain.when.called_with( "test-domain", 60, description="A test domain" - ).should.throw(SWFSerializationException) + ).should.throw(SWFResponseError) # ListDomains endpoint @@ -85,7 +80,7 @@ def test_deprecate_already_deprecated_domain(): conn.deprecate_domain.when.called_with( "test-domain" - ).should.throw(SWFDomainDeprecatedFault) + ).should.throw(SWFResponseError) @mock_swf def test_deprecate_non_existent_domain(): @@ -93,7 +88,7 @@ def test_deprecate_non_existent_domain(): conn.deprecate_domain.when.called_with( "non-existent" - ).should.throw(SWFUnknownResourceFault) + ).should.throw(SWFResponseError) # DescribeDomain endpoint @@ -114,4 +109,4 @@ def test_describe_non_existent_domain(): conn.describe_domain.when.called_with( "non-existent" - ).should.throw(SWFUnknownResourceFault) + ).should.throw(SWFResponseError) diff --git a/tests/test_swf/responses/test_workflow_executions.py b/tests/test_swf/responses/test_workflow_executions.py index f4125f77c..1ba4c9280 100644 --- a/tests/test_swf/responses/test_workflow_executions.py +++ b/tests/test_swf/responses/test_workflow_executions.py @@ -1,12 +1,12 @@ import boto +from boto.swf.exceptions import SWFResponseError + +# Ensure 'assert_raises' context manager support for Python 2.6 +import tests.backport_assert_raises # noqa +from nose.tools import assert_raises from sure import expect from moto import mock_swf -from moto.swf.exceptions import ( - SWFWorkflowExecutionAlreadyStartedFault, - SWFTypeDeprecatedFault, - SWFUnknownResourceFault, -) # Utils @@ -39,7 +39,7 @@ def test_start_already_started_workflow_execution(): conn.start_workflow_execution.when.called_with( "test-domain", "uid-abcd1234", "test-workflow", "v1.0" - ).should.throw(SWFWorkflowExecutionAlreadyStartedFault) + ).should.throw(SWFResponseError) @mock_swf def test_start_workflow_execution_on_deprecated_type(): @@ -48,7 +48,7 @@ def test_start_workflow_execution_on_deprecated_type(): conn.start_workflow_execution.when.called_with( "test-domain", "uid-abcd1234", "test-workflow", "v1.0" - ).should.throw(SWFTypeDeprecatedFault) + ).should.throw(SWFResponseError) # DescribeWorkflowExecution endpoint @@ -68,7 +68,7 @@ def test_describe_non_existent_workflow_execution(): conn.describe_workflow_execution.when.called_with( "test-domain", "wrong-run-id", "wrong-workflow-id" - ).should.throw(SWFUnknownResourceFault) + ).should.throw(SWFResponseError) # GetWorkflowExecutionHistory endpoint @@ -99,7 +99,7 @@ def test_get_workflow_execution_history_on_non_existent_workflow_execution(): conn.get_workflow_execution_history.when.called_with( "test-domain", "wrong-run-id", "wrong-workflow-id" - ).should.throw(SWFUnknownResourceFault) + ).should.throw(SWFResponseError) # TerminateWorkflowExecution endpoint @@ -138,26 +138,26 @@ def test_terminate_workflow_execution_with_wrong_workflow_or_run_id(): conn.terminate_workflow_execution.when.called_with( "test-domain", "uid-abcd1234", run_id=run_id ).should.throw( - SWFUnknownResourceFault, "WorkflowExecution=[workflowId=uid-abcd1234, runId=" + SWFResponseError, "WorkflowExecution=[workflowId=uid-abcd1234, runId=" ) # already closed, without run_id conn.terminate_workflow_execution.when.called_with( "test-domain", "uid-abcd1234" ).should.throw( - SWFUnknownResourceFault, "Unknown execution, workflowId = uid-abcd1234" + SWFResponseError, "Unknown execution, workflowId = uid-abcd1234" ) # wrong workflow id conn.terminate_workflow_execution.when.called_with( "test-domain", "uid-non-existent" ).should.throw( - SWFUnknownResourceFault, "Unknown execution, workflowId = uid-non-existent" + SWFResponseError, "Unknown execution, workflowId = uid-non-existent" ) # wrong run_id conn.terminate_workflow_execution.when.called_with( "test-domain", "uid-abcd1234", run_id="foo" ).should.throw( - SWFUnknownResourceFault, "WorkflowExecution=[workflowId=uid-abcd1234, runId=" + SWFResponseError, "WorkflowExecution=[workflowId=uid-abcd1234, runId=" ) diff --git a/tests/test_swf/responses/test_workflow_types.py b/tests/test_swf/responses/test_workflow_types.py index adcd81cc6..445de12d5 100644 --- a/tests/test_swf/responses/test_workflow_types.py +++ b/tests/test_swf/responses/test_workflow_types.py @@ -2,12 +2,7 @@ import boto from sure import expect from moto import mock_swf -from moto.swf.exceptions import ( - SWFUnknownResourceFault, - SWFTypeAlreadyExistsFault, - SWFTypeDeprecatedFault, - SWFSerializationException, -) +from boto.swf.exceptions import SWFResponseError # RegisterWorkflowType endpoint @@ -30,7 +25,7 @@ def test_register_already_existing_workflow_type(): conn.register_workflow_type.when.called_with( "test-domain", "test-workflow", "v1.0" - ).should.throw(SWFTypeAlreadyExistsFault) + ).should.throw(SWFResponseError) @mock_swf def test_register_with_wrong_parameter_type(): @@ -39,7 +34,7 @@ def test_register_with_wrong_parameter_type(): conn.register_workflow_type.when.called_with( "test-domain", "test-workflow", 12 - ).should.throw(SWFSerializationException) + ).should.throw(SWFResponseError) # ListWorkflowTypes endpoint @@ -91,7 +86,7 @@ def test_deprecate_already_deprecated_workflow_type(): conn.deprecate_workflow_type.when.called_with( "test-domain", "test-workflow", "v1.0" - ).should.throw(SWFTypeDeprecatedFault) + ).should.throw(SWFResponseError) @mock_swf def test_deprecate_non_existent_workflow_type(): @@ -100,7 +95,7 @@ def test_deprecate_non_existent_workflow_type(): conn.deprecate_workflow_type.when.called_with( "test-domain", "non-existent", "v1.0" - ).should.throw(SWFUnknownResourceFault) + ).should.throw(SWFResponseError) # DescribeWorkflowType endpoint @@ -127,4 +122,4 @@ def test_describe_non_existent_workflow_type(): conn.describe_workflow_type.when.called_with( "test-domain", "non-existent", "v1.0" - ).should.throw(SWFUnknownResourceFault) + ).should.throw(SWFResponseError) diff --git a/tests/test_swf/test_exceptions.py b/tests/test_swf/test_exceptions.py index 394493dbc..d32a60ac6 100644 --- a/tests/test_swf/test_exceptions.py +++ b/tests/test_swf/test_exceptions.py @@ -1,5 +1,8 @@ from __future__ import unicode_literals +import json +import sure + from moto.swf.exceptions import ( SWFClientError, SWFUnknownResourceFault, @@ -18,11 +21,10 @@ from moto.swf.models import ( ) def test_swf_client_error(): - ex = SWFClientError("error message", "ASpecificType") + ex = SWFClientError("ASpecificType", "error message") - ex.status.should.equal(400) - ex.error_code.should.equal("ASpecificType") - ex.body.should.equal({ + ex.code.should.equal(400) + json.loads(ex.get_body()).should.equal({ "__type": "ASpecificType", "message": "error message" }) @@ -30,9 +32,8 @@ def test_swf_client_error(): def test_swf_unknown_resource_fault(): ex = SWFUnknownResourceFault("type", "detail") - ex.status.should.equal(400) - ex.error_code.should.equal("UnknownResourceFault") - ex.body.should.equal({ + ex.code.should.equal(400) + json.loads(ex.get_body()).should.equal({ "__type": "com.amazonaws.swf.base.model#UnknownResourceFault", "message": "Unknown type: detail" }) @@ -40,9 +41,8 @@ def test_swf_unknown_resource_fault(): def test_swf_unknown_resource_fault_with_only_one_parameter(): ex = SWFUnknownResourceFault("foo bar baz") - ex.status.should.equal(400) - ex.error_code.should.equal("UnknownResourceFault") - ex.body.should.equal({ + ex.code.should.equal(400) + json.loads(ex.get_body()).should.equal({ "__type": "com.amazonaws.swf.base.model#UnknownResourceFault", "message": "Unknown foo bar baz" }) @@ -50,9 +50,8 @@ def test_swf_unknown_resource_fault_with_only_one_parameter(): def test_swf_domain_already_exists_fault(): ex = SWFDomainAlreadyExistsFault("domain-name") - ex.status.should.equal(400) - ex.error_code.should.equal("DomainAlreadyExistsFault") - ex.body.should.equal({ + ex.code.should.equal(400) + json.loads(ex.get_body()).should.equal({ "__type": "com.amazonaws.swf.base.model#DomainAlreadyExistsFault", "message": "domain-name" }) @@ -60,9 +59,8 @@ def test_swf_domain_already_exists_fault(): def test_swf_domain_deprecated_fault(): ex = SWFDomainDeprecatedFault("domain-name") - ex.status.should.equal(400) - ex.error_code.should.equal("DomainDeprecatedFault") - ex.body.should.equal({ + ex.code.should.equal(400) + json.loads(ex.get_body()).should.equal({ "__type": "com.amazonaws.swf.base.model#DomainDeprecatedFault", "message": "domain-name" }) @@ -70,18 +68,18 @@ def test_swf_domain_deprecated_fault(): def test_swf_serialization_exception(): ex = SWFSerializationException("value") - ex.status.should.equal(400) - ex.error_code.should.equal("SerializationException") - ex.body["__type"].should.equal("com.amazonaws.swf.base.model#SerializationException") - ex.body["Message"].should.match(r"class java.lang.Foo can not be converted to an String") + ex.code.should.equal(400) + json.loads(ex.get_body()).should.equal({ + "__type": "com.amazonaws.swf.base.model#SerializationException", + "message": "class java.lang.Foo can not be converted to an String (not a real SWF exception ; happened on: value)" + }) def test_swf_type_already_exists_fault(): wft = WorkflowType("wf-name", "wf-version") ex = SWFTypeAlreadyExistsFault(wft) - ex.status.should.equal(400) - ex.error_code.should.equal("TypeAlreadyExistsFault") - ex.body.should.equal({ + ex.code.should.equal(400) + json.loads(ex.get_body()).should.equal({ "__type": "com.amazonaws.swf.base.model#TypeAlreadyExistsFault", "message": "WorkflowType=[name=wf-name, version=wf-version]" }) @@ -90,9 +88,8 @@ def test_swf_type_deprecated_fault(): wft = WorkflowType("wf-name", "wf-version") ex = SWFTypeDeprecatedFault(wft) - ex.status.should.equal(400) - ex.error_code.should.equal("TypeDeprecatedFault") - ex.body.should.equal({ + ex.code.should.equal(400) + json.loads(ex.get_body()).should.equal({ "__type": "com.amazonaws.swf.base.model#TypeDeprecatedFault", "message": "WorkflowType=[name=wf-name, version=wf-version]" }) @@ -100,18 +97,17 @@ def test_swf_type_deprecated_fault(): def test_swf_workflow_execution_already_started_fault(): ex = SWFWorkflowExecutionAlreadyStartedFault() - ex.status.should.equal(400) - ex.error_code.should.equal("WorkflowExecutionAlreadyStartedFault") - ex.body.should.equal({ + ex.code.should.equal(400) + json.loads(ex.get_body()).should.equal({ "__type": "com.amazonaws.swf.base.model#WorkflowExecutionAlreadyStartedFault", + 'message': 'Already Started', }) def test_swf_default_undefined_fault(): ex = SWFDefaultUndefinedFault("execution_start_to_close_timeout") - ex.status.should.equal(400) - ex.error_code.should.equal("DefaultUndefinedFault") - ex.body.should.equal({ + ex.code.should.equal(400) + json.loads(ex.get_body()).should.equal({ "__type": "com.amazonaws.swf.base.model#DefaultUndefinedFault", "message": "executionStartToCloseTimeout", }) @@ -119,9 +115,8 @@ def test_swf_default_undefined_fault(): def test_swf_validation_exception(): ex = SWFValidationException("Invalid token") - ex.status.should.equal(400) - ex.error_code.should.equal("ValidationException") - ex.body.should.equal({ + ex.code.should.equal(400) + json.loads(ex.get_body()).should.equal({ "__type": "com.amazon.coral.validate#ValidationException", "message": "Invalid token", }) @@ -136,12 +131,11 @@ def test_swf_decision_validation_error(): "possible_values": "Foo, Bar, Baz"}, ]) - ex.status.should.equal(400) - ex.error_code.should.equal("ValidationException") - ex.body["__type"].should.equal("com.amazon.coral.validate#ValidationException") + ex.code.should.equal(400) + ex.error_type.should.equal("com.amazon.coral.validate#ValidationException") - msg = ex.body["message"] - msg.should.match(r"^2 validation errors detected:") + msg = ex.get_body() + msg.should.match(r"2 validation errors detected:") msg.should.match( r"Value null at 'decisions.1.member.startTimerDecisionAttributes.startToFireTimeout' "\ r"failed to satisfy constraint: Member must not be null;"