Skip to content

Commit

Permalink
Merge pull request #3211 from aws/release-v1.69.0
Browse files Browse the repository at this point in the history
Release 1.69.0 (to main)
  • Loading branch information
xazhao committed Jun 15, 2023
2 parents 12a7b02 + a4fc228 commit 063ac27
Show file tree
Hide file tree
Showing 161 changed files with 29,931 additions and 3,109 deletions.
1 change: 1 addition & 0 deletions .cfnlintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ ignore_templates:
- tests/translator/output/**/function_with_runtime_config.json # RuntimeManagementConfig
- tests/translator/output/**/managed_policies_minimal.json # Intentionally has non-existent managed policy name
- tests/translator/output/**/function_with_mq.json # Property "EventSourceArn" can Fn::GetAtt to a resource of types [AWS::DynamoDB::GlobalTable, AWS::DynamoDB::Table, AWS::Kinesis::Stream, AWS::Kinesis::StreamConsumer, AWS::SQS::Queue]
- tests/translator/output/**/function_with_mq_using_autogen_role.json # Property "EventSourceArn" can Fn::GetAtt to a resource of types [AWS::DynamoDB::GlobalTable, AWS::DynamoDB::Table, AWS::Kinesis::Stream, AWS::Kinesis::StreamConsumer, AWS::SQS::Queue]
ignore_checks:
- E2531 # Deprecated runtime; not relevant for transform tests
- W2531 # EOL runtime; not relevant for transform tests
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Update schema
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * 1-5" # Weekdays
- cron: "0 18 * * 1-5" # Weekdays

jobs:
update:
Expand Down
15 changes: 11 additions & 4 deletions DEVELOPMENT_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,20 @@ one python version locally and then have our ci (appveyor) run all supported ver

### Transform tests

#### Successful transforms

Transform tests ensure a SAM template transforms into the expected CloudFormation template.

When adding new transform tests, we have provided a script to help generate the transform test input
and output files in the correct directory given a template.yaml file.
and output files in the correct directory given a `template.yaml` file.
```bash
python3 bin/add_transform_test.py --template-file template.yaml
```

This script will automatically generate the input and output files. It will guarantee that the output
files have the correct AWS partition (e.g. aws-cn, aws-us-gov).

For `AWS::ApiGateway::RestApi`, the script will automatically append `REGIONAL` EndpointConfiguration.
For `AWS::ApiGateway::RestApi`, the script will automatically append `REGIONAL` `EndpointConfiguration`.
To disable this feature, run the following command instead.
```bash
python3 bin/add_transform_test.py --template-file template.yaml --disable-api-configuration
Expand All @@ -152,8 +154,13 @@ The script automatically updates hardcoded ARN partitions to match the output pa
python3 bin/add_transform_test.py --template-file template.yaml --disable-update-partition
```

Note that please always check the generated output is as expected. This tool does not guarantee correct output.
Please always check the generated output is as expected. This tool does not guarantee correct output.

#### Transform failures

To test a SAM template results in a specific transform error, add the SAM template under [`tests/translator/input`](https://github.com/aws/serverless-application-model/tree/develop/tests/translator/input), and a JSON file with the expected `errorMessage` as a top-level value under [`tests/translator/output`](https://github.com/aws/serverless-application-model/tree/develop/tests/translator/output). Both files must have the same basename and be prefixed with `error_` (e.g. `error_my_cool_template.yaml` for input, and `error_my_cool_template.json` for the expected error).

See https://github.com/aws/serverless-application-model/pull/2993 for an example.

### Integration tests

Expand Down Expand Up @@ -205,7 +212,7 @@ The AWS SAM specification includes a JSON schema (see https://github.com/aws/ser

To add new properties, do the following:

1. Add the property to the relevant resource schema under [`samtranslator/schema`](https://github.com/aws/serverless-application-model/tree/develop/samtranslator/schema) (e.g. [`samtranslator/schema/aws_serverless_function.py`](https://github.com/aws/serverless-application-model/blob/develop/samtranslator/schema/aws_serverless_function.py) for `AWS::Serverless::Function`).
1. Add the property to the relevant resource schema under [`samtranslator/internal/schema_source`](https://github.com/aws/serverless-application-model/tree/develop/samtranslator/internal/schema_source) (e.g. [`samtranslator/internal/schema_source/aws_serverless_function.py`](https://github.com/aws/serverless-application-model/blob/develop/samtranslator/internal/schema_source/aws_serverless_function.py) for `AWS::Serverless::Function`).
2. You can leave out the assignement part; it adds documentation to the schema properties. The team will take care of documentation updates once code changes are merged. Typically we update documentation by running `make update-schema-data`.
3. Run `make schema`.

Expand Down
2 changes: 2 additions & 0 deletions integration/combination/test_custom_http_api_domains_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

from integration.config.service_names import CUSTOM_DOMAIN
from integration.helpers.base_internal_test import BaseInternalTest
from integration.helpers.base_test import nonblocking
from integration.helpers.resource import current_region_not_included


@skipIf(
current_region_not_included([CUSTOM_DOMAIN]),
"CustomDomain is not supported in this testing region",
)
@nonblocking
class TestCustomHttpApiDomains(BaseInternalTest):
def test_custom_http_api_domains_regional(self):
self.create_and_verify_stack("combination/http_api_with_custom_domains_regional")
Expand Down
2 changes: 2 additions & 0 deletions integration/combination/test_custom_rest_api_domains.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

from integration.config.service_names import CUSTOM_DOMAIN
from integration.helpers.base_internal_test import BaseInternalTest
from integration.helpers.base_test import nonblocking
from integration.helpers.resource import current_region_not_included


@skipIf(
current_region_not_included([CUSTOM_DOMAIN]),
"CustomDomain is not supported in this testing region",
)
@nonblocking
class TestCustomRestApiDomains(BaseInternalTest):
def test_custom_rest_api_domains_edge(self):
self.create_and_verify_stack("combination/api_with_custom_domains_edge")
Expand Down
7 changes: 2 additions & 5 deletions integration/combination/test_function_with_mq.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from parameterized import parameterized

from integration.config.service_names import MQ
from integration.helpers.base_test import BaseTest
from integration.helpers.base_test import BaseTest, nonblocking
from integration.helpers.resource import current_region_does_not_support, generate_suffix


Expand All @@ -25,11 +25,8 @@ def companion_stack_outputs(self, get_companion_stack_outputs):
),
]
)
@nonblocking
def test_function_with_mq(self, file_name, mq_broker, mq_secret, subnet_key):
# Temporarily skip this test and we should either re-enable this once the AZ issue is fixed
# or once we figure out a way to trigger integ test only when transform output changes.
if subnet_key == "PreCreatedSubnetOne":
pytest.skip("Skipping this test to temporarily bypass AvailabilityZone issue.")
companion_stack_outputs = self.companion_stack_outputs
parameters = self.get_parameters(companion_stack_outputs, subnet_key)
secret_name = mq_secret + "-" + generate_suffix()
Expand Down
3 changes: 2 additions & 1 deletion integration/combination/test_function_with_msk.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import pytest

from integration.config.service_names import MSK
from integration.helpers.base_test import BaseTest
from integration.helpers.base_test import BaseTest, nonblocking
from integration.helpers.resource import current_region_does_not_support, generate_suffix


@skipIf(current_region_does_not_support([MSK]), "MSK is not supported in this testing region")
@nonblocking
class TestFunctionWithMsk(BaseTest):
@pytest.fixture(autouse=True)
def companion_stack_outputs(self, get_companion_stack_outputs):
Expand Down
101 changes: 101 additions & 0 deletions integration/combination/test_graphqlapi_lambda_resolver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import json
from unittest.case import skipIf

import requests

from integration.config.service_names import APP_SYNC
from integration.helpers.base_test import BaseTest
from integration.helpers.resource import current_region_does_not_support


def execute_and_verify_appsync_query(url, api_key, query):
"""
Executes a query to an AppSync GraphQLApi.
Also checks that the response is 200 and does not contain errors before returning.
"""
headers = {
"Content-Type": "application/json",
"x-api-key": api_key,
}
payload = {"query": query}

response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
data = response.json()
if "errors" in data:
raise Exception(json.dumps(data["errors"]))

return data


@skipIf(current_region_does_not_support([APP_SYNC]), "AppSync is not supported in this testing region")
class TestGraphQLApiPipelineResolver(BaseTest):
def test_api(self):
file_name = "combination/graphqlapi_lambda_resolver"
self.create_and_verify_stack(file_name)

outputs = self.get_stack_outputs()

author = "AUTHORNAME"
title = "Our first post!"
content = "This is our first post."

query = f"""
mutation addPost {{
addPost(
id: 100
author: "{author}"
title: "{title}"
content: "{content}"
) {{
id
author
title
content
}}
}}
"""

url = outputs["SuperCoolAPI"]
api_key = outputs["SuperCoolAPIMyApiKey"]

response = execute_and_verify_appsync_query(url, api_key, query)

add_post = response["data"]["addPost"]

self.assertEqual(add_post["id"], "100")
self.assertEqual(add_post["author"], author)
self.assertEqual(add_post["title"], title)
self.assertEqual(add_post["content"], content)

query = """
query getPost {
getPost(id:"1") {
id
author
title
content
ups
downs
}
}
"""

response = execute_and_verify_appsync_query(url, api_key, query)

get_post = response["data"]["getPost"]

# These values are hardcoded inside the Lambda function for a post with id "1".
author = "Author1"
title = "First book"
content = "Book 1 has this content"
ups = 100
downs = 10

self.assertEqual(get_post["id"], "1")
self.assertEqual(get_post["author"], author)
self.assertEqual(get_post["title"], title)
self.assertEqual(get_post["content"], content)
self.assertEqual(get_post["ups"], ups)
self.assertEqual(get_post["downs"], downs)
101 changes: 101 additions & 0 deletions integration/combination/test_graphqlapi_pipeline_resolver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import json
from unittest.case import skipIf

import requests

from integration.config.service_names import APP_SYNC
from integration.helpers.base_test import BaseTest
from integration.helpers.resource import current_region_does_not_support


def execute_and_verify_appsync_query(url, api_key, query):
"""
Executes a query to an AppSync GraphQLApi.
Also checks that the response is 200 and does not contain errors before returning.
"""
headers = {
"Content-Type": "application/json",
"x-api-key": api_key,
}
payload = {"query": query}

response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
data = response.json()
if "errors" in data:
raise Exception(json.dumps(data["errors"]))

return data


@skipIf(current_region_does_not_support([APP_SYNC]), "AppSync is not supported in this testing region")
class TestGraphQLApiPipelineResolver(BaseTest):
def test_api(self):
file_name = "combination/graphqlapi_pipeline_resolver"
self.create_and_verify_stack(file_name)

outputs = self.get_stack_outputs()

author = "AUTHORNAME"
title = "Our first post!"
content = "This is our first post."

query = f"""
mutation addPost {{
addPost(
author: "{author}"
title: "{title}"
content: "{content}"
) {{
id
author
title
content
ups
downs
version
}}
}}
"""

url = outputs["SuperCoolAPI"]
api_key = outputs["MyApiKey"]

response = execute_and_verify_appsync_query(url, api_key, query)

add_post = response["data"]["addPost"]

self.assertEqual(add_post["author"], author)
self.assertEqual(add_post["title"], title)
self.assertEqual(add_post["content"], content)
self.assertEqual(add_post["ups"], 1)
self.assertEqual(add_post["downs"], 0)
self.assertEqual(add_post["version"], 1)

post_id = add_post["id"]
query = f"""
query getPost {{
getPost(id:"{post_id}") {{
id
author
title
content
ups
downs
version
}}
}}
"""

response = execute_and_verify_appsync_query(url, api_key, query)

get_post = response["data"]["getPost"]

self.assertEqual(get_post["author"], author)
self.assertEqual(get_post["title"], title)
self.assertEqual(get_post["content"], content)
self.assertEqual(get_post["ups"], 1)
self.assertEqual(get_post["downs"], 0)
self.assertEqual(get_post["version"], 1)
self.assertEqual(get_post["id"], post_id)
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[
{
"LogicalResourceId": "MyLambdaFunction",
"ResourceType": "AWS::Lambda::Function"
},
{
"LogicalResourceId": "LambdaFunctionRole",
"ResourceType": "AWS::IAM::Role"
},
{
"LogicalResourceId": "SuperCoolAPI",
"ResourceType": "AWS::AppSync::GraphQLApi"
},
{
"LogicalResourceId": "SuperCoolAPISchema",
"ResourceType": "AWS::AppSync::GraphQLSchema"
},
{
"LogicalResourceId": "SuperCoolAPICloudWatchRole",
"ResourceType": "AWS::IAM::Role"
},
{
"LogicalResourceId": "SuperCoolAPIMyApiKey",
"ResourceType": "AWS::AppSync::ApiKey"
},
{
"LogicalResourceId": "SuperCoolAPIMyLambdaDataSourceLambdaDataSource",
"ResourceType": "AWS::AppSync::DataSource"
},
{
"LogicalResourceId": "SuperCoolAPIMyLambdaDataSourceLambdaDataSourceRole",
"ResourceType": "AWS::IAM::Role"
},
{
"LogicalResourceId": "SuperCoolAPIMyLambdaDataSourceLambdaDataSourceToLambdaConnectorPolicy",
"ResourceType": "AWS::IAM::ManagedPolicy"
},
{
"LogicalResourceId": "SuperCoolAPIlambdaInvoker",
"ResourceType": "AWS::AppSync::FunctionConfiguration"
},
{
"LogicalResourceId": "SuperCoolAPIMutationaddPost",
"ResourceType": "AWS::AppSync::Resolver"
},
{
"LogicalResourceId": "SuperCoolAPIQuerygetPost",
"ResourceType": "AWS::AppSync::Resolver"
}
]
Loading

0 comments on commit 063ac27

Please sign in to comment.