def create_request_context(self, request: HttpRequest) -> RequestContext: context = RequestContext() context.service = self.service context.request = request context.region = get_region(request) context.account_id = get_account_id(request) return context
def test_dispatch_missing_method_returns_internal_failure(): table: DispatchTable = dict() sqs_service = load_service("sqs") skeleton = Skeleton(sqs_service, table) context = RequestContext() context.account = "test" context.region = "us-west-1" context.service = sqs_service context.request = { "method": "POST", "path": "/", "body": "Action=DeleteQueue&Version=2012-11-05&QueueUrl=http%3A%2F%2Flocalhost%3A4566%2F000000000000%2Ftf-acc-test-queue", "headers": _get_sqs_request_headers(), } result = skeleton.invoke(context) # Use the parser from botocore to parse the serialized response response_parser = create_parser(sqs_service.protocol) parsed_response = response_parser.parse( result, sqs_service.operation_model("SendMessage").output_shape) assert "Error" in parsed_response assert parsed_response["Error"] == { "Code": "InternalFailure", "Message": "API action 'DeleteQueue' for service 'sqs' not yet implemented", }
def test_dispatch_common_service_exception(): def delete_queue(_context: RequestContext, _request: ServiceRequest): raise CommonServiceException("NonExistentQueue", "No such queue") table: DispatchTable = dict() table["DeleteQueue"] = delete_queue sqs_service = load_service("sqs") skeleton = Skeleton(sqs_service, table) context = RequestContext() context.account = "test" context.region = "us-west-1" context.service = sqs_service context.request = { "method": "POST", "path": "/", "body": "Action=DeleteQueue&Version=2012-11-05&QueueUrl=http%3A%2F%2Flocalhost%3A4566%2F000000000000%2Ftf-acc-test-queue", "headers": _get_sqs_request_headers(), } result = skeleton.invoke(context) # Use the parser from botocore to parse the serialized response response_parser = create_parser(sqs_service.protocol) parsed_response = response_parser.parse( result, sqs_service.operation_model("SendMessage").output_shape) assert "Error" in parsed_response assert parsed_response["Error"] == { "Code": "NonExistentQueue", "Message": "No such queue", }
def create_aws_request_context( service_name: str, action: str, parameters: Mapping[str, Any] = None, region: str = None, endpoint_url: Optional[str] = None, ) -> RequestContext: """ This is a stripped-down version of what the botocore client does to perform an HTTP request from a client call. A client call looks something like this: boto3.client("sqs").create_queue(QueueName="myqueue"), which will be serialized into an HTTP request. This method does the same, without performing the actual request, and with a more low-level interface. An equivalent call would be create_aws_request_context("sqs", "CreateQueue", {"QueueName": "myqueue"}) :param service_name: the AWS service :param action: the action to invoke :param parameters: the invocation parameters :param region: the region name (default is us-east-1) :param endpoint_url: the endpoint to call (defaults to localstack) :return: a RequestContext object that describes this request """ if parameters is None: parameters = {} if region is None: region = config.AWS_REGION_US_EAST_1 service = load_service(service_name) operation = service.operation_model(action) # we re-use botocore internals here to serialize the HTTP request, but don't send it client = aws_stack.connect_to_service(service_name, endpoint_url=endpoint_url, region_name=region) request_context = { "client_region": region, "has_streaming_input": operation.has_streaming_input, "auth_type": operation.auth_type, } request_dict = client._convert_to_request_dict(parameters, operation, context=request_context) aws_request = client._endpoint.create_request(request_dict, operation) context = RequestContext() context.service = service context.operation = operation context.region = region context.request = create_http_request(aws_request) return context
def test_skeleton_e2e_sqs_send_message(): sqs_service = load_service("sqs") skeleton = Skeleton(sqs_service, TestSqsApi()) context = RequestContext() context.account = "test" context.region = "us-west-1" context.service = sqs_service context.request = HttpRequest( **{ "method": "POST", "path": "/", "body": "Action=SendMessage&Version=2012-11-05&QueueUrl=http%3A%2F%2Flocalhost%3A4566%2F000000000000%2Ftf-acc-test-queue&MessageBody=%7B%22foo%22%3A+%22bared%22%7D&DelaySeconds=2", "headers": _get_sqs_request_headers(), }) result = skeleton.invoke(context) # Use the parser from botocore to parse the serialized response response_parser = create_parser(sqs_service.protocol) parsed_response = response_parser.parse( result.to_readonly_response_dict(), sqs_service.operation_model("SendMessage").output_shape) # Test the ResponseMetadata and delete it afterwards assert "ResponseMetadata" in parsed_response assert "RequestId" in parsed_response["ResponseMetadata"] assert len(parsed_response["ResponseMetadata"]["RequestId"]) == 52 assert "HTTPStatusCode" in parsed_response["ResponseMetadata"] assert parsed_response["ResponseMetadata"]["HTTPStatusCode"] == 200 del parsed_response["ResponseMetadata"] # Compare the (remaining) actual payload assert parsed_response == { "MD5OfMessageBody": "String", "MD5OfMessageAttributes": "String", "MD5OfMessageSystemAttributes": "String", "MessageId": "String", "SequenceNumber": "String", }
def test_skeleton_e2e_sqs_send_message_not_implemented(): sqs_service = load_service("sqs") skeleton = Skeleton(sqs_service, TestSqsApiNotImplemented()) context = RequestContext() context.account = "test" context.region = "us-west-1" context.service = sqs_service context.request = HttpRequest( **{ "method": "POST", "path": "/", "body": "Action=SendMessage&Version=2012-11-05&QueueUrl=http%3A%2F%2Flocalhost%3A4566%2F000000000000%2Ftf-acc-test-queue&MessageBody=%7B%22foo%22%3A+%22bared%22%7D&DelaySeconds=2", "headers": _get_sqs_request_headers(), }) result = skeleton.invoke(context) # Use the parser from botocore to parse the serialized response response_parser = create_parser(sqs_service.protocol) parsed_response = response_parser.parse( result.to_readonly_response_dict(), sqs_service.operation_model("SendMessage").output_shape) # Test the ResponseMetadata assert "ResponseMetadata" in parsed_response assert "RequestId" in parsed_response["ResponseMetadata"] assert len(parsed_response["ResponseMetadata"]["RequestId"]) == 52 assert "HTTPStatusCode" in parsed_response["ResponseMetadata"] assert parsed_response["ResponseMetadata"]["HTTPStatusCode"] == 501 # Compare the (remaining) actual eror payload assert "Error" in parsed_response assert parsed_response["Error"] == { "Code": "InternalFailure", "Message": "API action 'SendMessage' for service 'sqs' not yet implemented", }