235 lines
7.8 KiB
Python
235 lines
7.8 KiB
Python
import boto3
|
|
import json
|
|
import requests
|
|
|
|
from moto import mock_apigateway, mock_dynamodb
|
|
from moto import settings
|
|
from moto.core.models import responses_mock
|
|
from unittest import SkipTest
|
|
|
|
|
|
@mock_apigateway
|
|
def test_http_integration():
|
|
if settings.TEST_SERVER_MODE:
|
|
raise SkipTest("Cannot test mock of execute-api.apigateway in ServerMode")
|
|
responses_mock.add(
|
|
responses_mock.GET, "http://httpbin.org/robots.txt", body="a fake response"
|
|
)
|
|
|
|
region_name = "us-west-2"
|
|
client = boto3.client("apigateway", region_name=region_name)
|
|
response = client.create_rest_api(name="my_api", description="this is my api")
|
|
api_id = response["id"]
|
|
|
|
resources = client.get_resources(restApiId=api_id)
|
|
root_id = [resource for resource in resources["items"] if resource["path"] == "/"][
|
|
0
|
|
]["id"]
|
|
|
|
client.put_method(
|
|
restApiId=api_id, resourceId=root_id, httpMethod="GET", authorizationType="none"
|
|
)
|
|
|
|
client.put_method_response(
|
|
restApiId=api_id, resourceId=root_id, httpMethod="GET", statusCode="200"
|
|
)
|
|
|
|
response = client.put_integration(
|
|
restApiId=api_id,
|
|
resourceId=root_id,
|
|
httpMethod="GET",
|
|
type="HTTP",
|
|
uri="http://httpbin.org/robots.txt",
|
|
integrationHttpMethod="GET",
|
|
requestParameters={"integration.request.header.X-Custom": "'Custom'"},
|
|
)
|
|
|
|
stage_name = "staging"
|
|
client.create_deployment(restApiId=api_id, stageName=stage_name)
|
|
|
|
deploy_url = (
|
|
f"https://{api_id}.execute-api.{region_name}.amazonaws.com/{stage_name}"
|
|
)
|
|
|
|
requests.get(deploy_url).content.should.equal(b"a fake response")
|
|
|
|
|
|
@mock_apigateway
|
|
@mock_dynamodb
|
|
def test_aws_integration_dynamodb():
|
|
if settings.TEST_SERVER_MODE:
|
|
raise SkipTest("Cannot test mock of execute-api.apigateway in ServerMode")
|
|
|
|
client = boto3.client("apigateway", region_name="us-west-2")
|
|
dynamodb = boto3.client("dynamodb", region_name="us-west-2")
|
|
table_name = "test_1"
|
|
integration_action = "arn:aws:apigateway:us-west-2:dynamodb:action/PutItem"
|
|
stage_name = "staging"
|
|
|
|
create_table(dynamodb, table_name)
|
|
api_id, _ = create_integration_test_api(client, integration_action)
|
|
|
|
client.create_deployment(restApiId=api_id, stageName=stage_name)
|
|
|
|
res = requests.put(
|
|
f"https://{api_id}.execute-api.us-west-2.amazonaws.com/{stage_name}",
|
|
json={"TableName": table_name, "Item": {"name": {"S": "the-key"}}},
|
|
)
|
|
res.status_code.should.equal(200)
|
|
res.content.should.equal(b"{}")
|
|
|
|
|
|
@mock_apigateway
|
|
@mock_dynamodb
|
|
def test_aws_integration_dynamodb_multiple_stages():
|
|
if settings.TEST_SERVER_MODE:
|
|
raise SkipTest("Cannot test mock of execute-api.apigateway in ServerMode")
|
|
|
|
client = boto3.client("apigateway", region_name="us-west-2")
|
|
dynamodb = boto3.client("dynamodb", region_name="us-west-2")
|
|
table_name = "test_1"
|
|
integration_action = "arn:aws:apigateway:us-west-2:dynamodb:action/PutItem"
|
|
|
|
create_table(dynamodb, table_name)
|
|
api_id, _ = create_integration_test_api(client, integration_action)
|
|
|
|
client.create_deployment(restApiId=api_id, stageName="dev")
|
|
client.create_deployment(restApiId=api_id, stageName="staging")
|
|
|
|
res = requests.put(
|
|
f"https://{api_id}.execute-api.us-west-2.amazonaws.com/dev",
|
|
json={"TableName": table_name, "Item": {"name": {"S": "the-key"}}},
|
|
)
|
|
res.status_code.should.equal(200)
|
|
|
|
res = requests.put(
|
|
f"https://{api_id}.execute-api.us-west-2.amazonaws.com/staging",
|
|
json={"TableName": table_name, "Item": {"name": {"S": "the-key"}}},
|
|
)
|
|
res.status_code.should.equal(200)
|
|
|
|
# We haven't pushed to prod yet
|
|
res = requests.put(
|
|
f"https://{api_id}.execute-api.us-west-2.amazonaws.com/prod",
|
|
json={"TableName": table_name, "Item": {"name": {"S": "the-key"}}},
|
|
)
|
|
res.status_code.should.equal(400)
|
|
|
|
|
|
@mock_apigateway
|
|
@mock_dynamodb
|
|
def test_aws_integration_dynamodb_multiple_resources():
|
|
if settings.TEST_SERVER_MODE:
|
|
raise SkipTest("Cannot test mock of execute-api.apigateway in ServerMode")
|
|
|
|
client = boto3.client("apigateway", region_name="us-west-2")
|
|
dynamodb = boto3.client("dynamodb", region_name="us-west-2")
|
|
table_name = "test_1"
|
|
create_table(dynamodb, table_name)
|
|
|
|
# Create API integration to PutItem
|
|
integration_action = "arn:aws:apigateway:us-west-2:dynamodb:action/PutItem"
|
|
api_id, root_id = create_integration_test_api(client, integration_action)
|
|
|
|
# Create API integration to GetItem
|
|
res = client.create_resource(restApiId=api_id, parentId=root_id, pathPart="item")
|
|
parent_id = res["id"]
|
|
integration_action = "arn:aws:apigateway:us-west-2:dynamodb:action/GetItem"
|
|
api_id, root_id = create_integration_test_api(
|
|
client,
|
|
integration_action,
|
|
api_id=api_id,
|
|
parent_id=parent_id,
|
|
http_method="GET",
|
|
)
|
|
|
|
client.create_deployment(restApiId=api_id, stageName="dev")
|
|
|
|
# Put item at the root resource
|
|
res = requests.put(
|
|
f"https://{api_id}.execute-api.us-west-2.amazonaws.com/dev",
|
|
json={
|
|
"TableName": table_name,
|
|
"Item": {"name": {"S": "the-key"}, "attr2": {"S": "sth"}},
|
|
},
|
|
)
|
|
res.status_code.should.equal(200)
|
|
|
|
# Get item from child resource
|
|
res = requests.get(
|
|
f"https://{api_id}.execute-api.us-west-2.amazonaws.com/dev/item",
|
|
json={"TableName": table_name, "Key": {"name": {"S": "the-key"}}},
|
|
)
|
|
res.status_code.should.equal(200)
|
|
json.loads(res.content).should.equal(
|
|
{"Item": {"name": {"S": "the-key"}, "attr2": {"S": "sth"}}}
|
|
)
|
|
|
|
|
|
@mock_apigateway
|
|
def test_aws_integration_sagemaker():
|
|
region = "us-west-2"
|
|
client = boto3.client("apigateway", region_name=region)
|
|
sagemaker_endpoint = "non-existing"
|
|
integration_action = f"arn:aws:apigateway:{region}:runtime.sagemaker:path//endpoints/{sagemaker_endpoint}/invocations"
|
|
|
|
api_id, resource_id = create_integration_test_api(client, integration_action)
|
|
|
|
# We can't invoke Sagemaker
|
|
# Just verify that the integration action was successful
|
|
response = client.get_integration(
|
|
restApiId=api_id, resourceId=resource_id, httpMethod="PUT"
|
|
)
|
|
response.should.have.key("uri").equals(integration_action)
|
|
|
|
|
|
def create_table(dynamodb, table_name):
|
|
# Create DynamoDB table
|
|
dynamodb.create_table(
|
|
TableName=table_name,
|
|
KeySchema=[{"AttributeName": "name", "KeyType": "HASH"}],
|
|
AttributeDefinitions=[{"AttributeName": "name", "AttributeType": "S"}],
|
|
BillingMode="PAY_PER_REQUEST",
|
|
)
|
|
|
|
|
|
def create_integration_test_api(
|
|
client, integration_action, api_id=None, parent_id=None, http_method="PUT"
|
|
):
|
|
if not api_id:
|
|
# We do not have a root yet - create the API first
|
|
response = client.create_rest_api(name="my_api", description="this is my api")
|
|
api_id = response["id"]
|
|
if not parent_id:
|
|
resources = client.get_resources(restApiId=api_id)
|
|
parent_id = [
|
|
resource for resource in resources["items"] if resource["path"] == "/"
|
|
][0]["id"]
|
|
|
|
client.put_method(
|
|
restApiId=api_id,
|
|
resourceId=parent_id,
|
|
httpMethod=http_method,
|
|
authorizationType="NONE",
|
|
)
|
|
client.put_method_response(
|
|
restApiId=api_id, resourceId=parent_id, httpMethod=http_method, statusCode="200"
|
|
)
|
|
client.put_integration(
|
|
restApiId=api_id,
|
|
resourceId=parent_id,
|
|
httpMethod=http_method,
|
|
type="AWS",
|
|
uri=integration_action,
|
|
integrationHttpMethod=http_method,
|
|
)
|
|
client.put_integration_response(
|
|
restApiId=api_id,
|
|
resourceId=parent_id,
|
|
httpMethod=http_method,
|
|
statusCode="200",
|
|
selectionPattern="",
|
|
responseTemplates={"application/json": "{}"},
|
|
)
|
|
return api_id, parent_id
|