Skip to content

Commit 991dcab

Browse files
authored
Added Dotnet Lambda E2E Tests (#332)
*Description of changes:* This change adds workflow files and terraform scripts that builds the infrastructure (lambda function and lambda layer) for DotNet lambda layer. For now, the cron schedule in [dotnet-lambda-canary.yml](https://github.com/aws-observability/aws-application-signals-test-framework/compare/dotnetLambdaE2E?expand=1#diff-7f7da6fc2394c58665b91c661888dfc9afec0edf64c1a53701e56a7fcdf943bd) is disabled which means that tests won't run yet. We will need to wait until we officially release the lambda layer. However, I updated the aws-otel-dotnet-instrumentation build workflow to run the lambda tests on main build/merge. Testing: Check this run for details, especially dotnet-lambda-default step: https://github.com/aws-observability/aws-otel-dotnet-instrumentation/actions/runs/12283246401/job/34276401374. This verifies that E2E tests work and that it runs as part of the main build for the `aws-otel-dotnet-instrumentation`. (I disabled other E2E tests for the run above just to save time.) By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent b25d6b1 commit 991dcab

File tree

21 files changed

+941
-2
lines changed

21 files changed

+941
-2
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
## Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
## SPDX-License-Identifier: Apache-2.0
3+
4+
## This workflow aims to run the Application Signals end-to-end tests as a canary to
5+
## test the artifacts for App Signals enablement.
6+
name: DotNet Lambda Enablement Canary Testing
7+
on:
8+
#schedule:
9+
#- cron: '14,39 * * * *' # run the workflow at 14th and 39th minute of every hour
10+
workflow_dispatch: # be able to run the workflow on demand
11+
12+
permissions:
13+
id-token: write
14+
contents: read
15+
16+
jobs:
17+
default:
18+
strategy:
19+
fail-fast: false
20+
matrix:
21+
aws-region: ['af-south-1','ap-east-1','ap-northeast-1','ap-northeast-2','ap-northeast-3','ap-south-1','ap-south-2','ap-southeast-1',
22+
'ap-southeast-2','ap-southeast-3','ap-southeast-4','ca-central-1','eu-central-1','eu-central-2','eu-north-1',
23+
'eu-south-1','eu-south-2','eu-west-1','eu-west-2','eu-west-3','il-central-1','me-central-1','me-south-1', 'sa-east-1',
24+
'us-east-1','us-east-2', 'us-west-1', 'us-west-2']
25+
uses: ./.github/workflows/dotnet-lambda-retry.yml
26+
secrets: inherit
27+
with:
28+
aws-region: ${{ matrix.aws-region }}
29+
caller-workflow-name: 'appsignals-dotnet-e2e-lambda-canary-test'
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
## Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
## SPDX-License-Identifier: Apache-2.0
3+
4+
# This is a reusable workflow for running the Enablement test for App Signals.
5+
# It is meant to be called from another workflow.
6+
# Read more about reusable workflows: https://docs.github.com/en/actions/using-workflows/reusing-workflows#overview
7+
name: DotNet Lambda Retry
8+
on:
9+
workflow_call:
10+
inputs:
11+
aws-region:
12+
required: true
13+
type: string
14+
caller-workflow-name:
15+
required: true
16+
type: string
17+
18+
permissions:
19+
id-token: write
20+
contents: read
21+
22+
jobs:
23+
dotnet-lambda-attempt-1:
24+
uses: ./.github/workflows/dotnet-lambda-test.yml
25+
secrets: inherit
26+
with:
27+
aws-region: ${{ inputs.aws-region }}
28+
caller-workflow-name: ${{ inputs.caller-workflow-name }}
29+
30+
dotnet-lambda-attempt-2:
31+
needs: [ dotnet-lambda-attempt-1 ]
32+
if: ${{ needs.dotnet-lambda-attempt-1.outputs.job-started != 'true' }}
33+
uses: ./.github/workflows/dotnet-lambda-test.yml
34+
secrets: inherit
35+
with:
36+
aws-region: ${{ inputs.aws-region }}
37+
caller-workflow-name: ${{ inputs.caller-workflow-name }}
38+
39+
publish-metric-attempt-1:
40+
needs: [ dotnet-lambda-attempt-1, dotnet-lambda-attempt-2 ]
41+
if: always()
42+
uses: ./.github/workflows/enablement-test-publish-result.yml
43+
secrets: inherit
44+
with:
45+
aws-region: ${{ inputs.aws-region }}
46+
caller-workflow-name: ${{ inputs.caller-workflow-name }}
47+
validation-result: ${{ needs.dotnet-lambda-attempt-1.outputs.validation-result || needs.dotnet-lambda-attempt-2.outputs.validation-result }}
48+
49+
publish-metric-attempt-2:
50+
needs: [ dotnet-lambda-attempt-1, dotnet-lambda-attempt-2, publish-metric-attempt-1 ]
51+
if: ${{ always() && needs.publish-metric-attempt-1.outputs.job-started != 'true' }}
52+
uses: ./.github/workflows/enablement-test-publish-result.yml
53+
secrets: inherit
54+
with:
55+
aws-region: ${{ inputs.aws-region }}
56+
caller-workflow-name: ${{ inputs.caller-workflow-name }}
57+
validation-result: ${{ needs.dotnet-lambda-attempt-1.outputs.validation-result || needs.dotnet-lambda-attempt-2.outputs.validation-result }}
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
## Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
## SPDX-License-Identifier: Apache-2.0
3+
4+
# This is a reusable workflow for running the Enablement test for App Signals.
5+
# It is meant to be called from another workflow.
6+
# Read more about reusable workflows: https://docs.github.com/en/actions/using-workflows/reusing-workflows#overview
7+
name: DotNet Lambda Use Case
8+
on:
9+
workflow_call:
10+
inputs:
11+
aws-region:
12+
required: true
13+
type: string
14+
caller-workflow-name:
15+
required: true
16+
type: string
17+
outputs:
18+
job-started:
19+
value: ${{ jobs.dotnet-lambda-default.outputs.job-started }}
20+
validation-result:
21+
value: ${{ jobs.dotnet-lambda-default.outputs.validation-result }}
22+
23+
permissions:
24+
id-token: write
25+
contents: read
26+
27+
env:
28+
E2E_TEST_AWS_REGION: ${{ inputs.aws-region }}
29+
CALLER_WORKFLOW_NAME: ${{ inputs.caller-workflow-name }}
30+
E2E_TEST_ACCOUNT_ID: ${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ACCOUNT_ID }}
31+
E2E_TEST_ROLE_NAME: ${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ROLE_NAME }}
32+
SAMPLE_APP_ZIP: s3://aws-appsignals-sample-app-prod-${{ inputs.aws-region }}/dotnet-function.zip
33+
METRIC_NAMESPACE: ApplicationSignals
34+
LOG_GROUP_NAME: /aws/application-signals/data
35+
TEST_RESOURCES_FOLDER: ${GITHUB_WORKSPACE}
36+
STAGING_S3_BUCKET: adot-autoinstrumentation-dotnet-staging
37+
IS_CANARY: false
38+
39+
jobs:
40+
dotnet-lambda-default:
41+
runs-on: ubuntu-latest
42+
timeout-minutes: 30
43+
outputs:
44+
job-started: ${{ steps.job-started.outputs.job-started }}
45+
validation-result: ${{ steps.validation-result.outputs.validation-result }}
46+
steps:
47+
- name: Check if the job started
48+
id: job-started
49+
run: echo "job-started=true" >> $GITHUB_OUTPUT
50+
51+
- name: Generate testing id
52+
run: echo TESTING_ID="${{ github.job }}-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}" >> $GITHUB_ENV
53+
54+
- uses: actions/checkout@v4
55+
with:
56+
repository: 'aws-observability/aws-application-signals-test-framework'
57+
ref: ${{ env.CALLER_WORKFLOW_NAME == 'main-build' && 'main' || github.ref }}
58+
fetch-depth: 0
59+
60+
# We initialize Gradlew Daemon early on during the workflow because sometimes initialization
61+
# fails due to transient issues. If it fails here, then we will try again later before the validators
62+
- name: Initiate Gradlew Daemon
63+
id: initiate-gradlew
64+
uses: ./.github/workflows/actions/execute_and_retry
65+
continue-on-error: true
66+
with:
67+
command: "./gradlew :validator:build"
68+
cleanup: "./gradlew clean"
69+
max_retry: 3
70+
sleep_time: 60
71+
72+
- name: Configure AWS Credentials
73+
uses: aws-actions/configure-aws-credentials@v4
74+
with:
75+
role-to-assume: arn:aws:iam::${{ env.E2E_TEST_ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }}
76+
aws-region: us-east-1
77+
78+
- name: Retrieve account
79+
uses: aws-actions/aws-secretsmanager-get-secrets@v1
80+
with:
81+
secret-ids:
82+
ACCOUNT_ID, region-account/${{ env.E2E_TEST_AWS_REGION }}
83+
84+
# If the workflow is running as a canary, then we want to log in to the aws account in the appropriate region
85+
- name: Configure AWS Credentials
86+
if: ${{ github.event.repository.name == 'aws-application-signals-test-framework' }}
87+
uses: aws-actions/configure-aws-credentials@v4
88+
with:
89+
role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }}
90+
aws-region: ${{ env.E2E_TEST_AWS_REGION }}
91+
92+
- name: Set Lambda Layer artifact directory path
93+
run: echo ARTIFACTS_DIR="${{ github.workspace }}/lambda_artifacts" >> $GITHUB_ENV
94+
95+
- name: Download Lambda Layer and Function artifacts for E2E Test
96+
if: ${{ env.CALLER_WORKFLOW_NAME != 'appsignals-dotnet-e2e-lambda-canary-test' }}
97+
run: |
98+
aws s3 cp s3://${{ env.STAGING_S3_BUCKET }}/aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip ${{ env.ARTIFACTS_DIR }}/layer.zip |
99+
aws s3 cp s3://${{ env.STAGING_S3_BUCKET }}/function-${{ github.run_id }}.zip ${{ env.ARTIFACTS_DIR }}/dotnet-function.zip
100+
101+
- name: Set Canary Environment Variable
102+
if: ${{ env.CALLER_WORKFLOW_NAME == 'appsignals-dotnet-e2e-lambda-canary-test' }}
103+
run: |
104+
echo IS_CANARY=true >> $GITHUB_ENV |
105+
aws s3 cp ${{ env.SAMPLE_APP_ZIP }} ${{ env.ARTIFACTS_DIR }}/dotnet-function.zip
106+
107+
- name: Set up terraform
108+
uses: ./.github/workflows/actions/execute_and_retry
109+
with:
110+
command: "wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg"
111+
post-command: 'echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
112+
&& sudo apt update && sudo apt install terraform'
113+
sleep_time: 60
114+
115+
- name: Initiate Terraform
116+
uses: ./.github/workflows/actions/execute_and_retry
117+
with:
118+
command: "cd ${{ env.TEST_RESOURCES_FOLDER }}/terraform/dotnet/lambda/lambda && terraform init && terraform validate"
119+
cleanup: "rm -rf .terraform && rm -rf .terraform.lock.hcl"
120+
max_retry: 6
121+
sleep_time: 60
122+
123+
- name: Get terraform Lambda function name
124+
shell: bash
125+
run: |
126+
echo TERRAFORM_LAMBDA_FUNCTION_NAME="AdotLambdaDotNetSampleApp-${{ github.run_id }}"|
127+
tee --append $GITHUB_ENV
128+
- name: Apply terraform
129+
uses: ./.github/workflows/actions/execute_and_retry
130+
with:
131+
command: 'cd ${{ env.TEST_RESOURCES_FOLDER }}/terraform/dotnet/lambda/lambda && terraform apply -auto-approve
132+
-var="sdk_layer_name=AWSOpenTelemetryDistroDotNet-${{ github.run_id }}"
133+
-var="function_name=${{env.TERRAFORM_LAMBDA_FUNCTION_NAME}}"
134+
-var="layer_artifacts_directory=${{ env.ARTIFACTS_DIR }}"
135+
-var="region=${{ env.E2E_TEST_AWS_REGION }}"
136+
-var="is_canary=${{ env.IS_CANARY }}"'
137+
max_retry: 6
138+
sleep_time: 60
139+
- name: Extract endpoint
140+
id: extract-endpoint
141+
shell: bash
142+
run: cd ${{ env.TEST_RESOURCES_FOLDER }}/terraform/dotnet/lambda/lambda && echo API_GATEWAY_URL=$(terraform output -raw api-gateway-url) >> $GITHUB_ENV
143+
- name: Send request to endpoint
144+
shell: bash
145+
run: sleep 30s; curl -sS ${{ env.API_GATEWAY_URL }}
146+
147+
# Validation for pulse telemetry data
148+
- name: Validate generated EMF logs
149+
id: log-validation
150+
# will be removed after data quality bug fixed
151+
continue-on-error: true
152+
run: ./gradlew validator:run --args='-c dotnet/lambda/log-validation.yml
153+
--testing-id ${{ env.TESTING_ID }}
154+
--endpoint http://${{ env.API_GATEWAY_URL }}
155+
--region ${{ inputs.aws-region }}
156+
--account-id ${{ env.ACCOUNT_ID }}
157+
--metric-namespace ${{ env.METRIC_NAMESPACE }}
158+
--log-group ${{ env.LOG_GROUP_NAME }}
159+
--service-name ${{ env.TERRAFORM_LAMBDA_FUNCTION_NAME }}
160+
--rollup'
161+
162+
- name: Validate generated metrics
163+
id: metric-validation
164+
if: (success() || steps.log-validation.outcome == 'failure') && !cancelled()
165+
# will be removed after data quality bug fixed
166+
continue-on-error: true
167+
run: ./gradlew validator:run --args='-c dotnet/lambda/metric-validation.yml
168+
--testing-id ${{ env.TESTING_ID }}
169+
--endpoint http://${{ env.API_GATEWAY_URL }}
170+
--region ${{ inputs.aws-region }}
171+
--account-id ${{ env.ACCOUNT_ID }}
172+
--metric-namespace ${{ env.METRIC_NAMESPACE }}
173+
--log-group ${{ env.LOG_GROUP_NAME }}
174+
--service-name ${{ env.TERRAFORM_LAMBDA_FUNCTION_NAME }}
175+
--rollup'
176+
177+
- name: Validate generated traces
178+
id: trace-validation
179+
if: (success() || steps.log-validation.outcome == 'failure' || steps.metric-validation.outcome == 'failure') && !cancelled()
180+
# will be removed after data quality bug fixed
181+
continue-on-error: true
182+
run: ./gradlew validator:run --args='-c dotnet/lambda/trace-validation.yml
183+
--testing-id ${{ env.TESTING_ID }}
184+
--endpoint http://${{ env.API_GATEWAY_URL }}
185+
--region ${{ inputs.aws-region }}
186+
--account-id ${{ env.ACCOUNT_ID }}
187+
--metric-namespace ${{ env.METRIC_NAMESPACE }}
188+
--log-group ${{ env.LOG_GROUP_NAME }}
189+
--service-name ${{ env.TERRAFORM_LAMBDA_FUNCTION_NAME }}
190+
--rollup'
191+
192+
- name: Refresh AWS Credentials
193+
if: ${{ always() && github.event.repository.name == 'aws-application-signals-test-framework' }}
194+
uses: aws-actions/configure-aws-credentials@v4
195+
with:
196+
role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }}
197+
aws-region: ${{ env.E2E_TEST_AWS_REGION }}
198+
199+
- name: Save test results
200+
if: always()
201+
id: validation-result
202+
run: |
203+
if [ "${{ steps.log-validation.outcome }}" = "success" ] && [ "${{ steps.metric-validation.outcome }}" = "success" ] && [ "${{ steps.trace-validation.outcome }}" = "success" ]; then
204+
echo "validation-result=success" >> $GITHUB_OUTPUT
205+
else
206+
echo "validation-result=failure" >> $GITHUB_OUTPUT
207+
fi
208+
209+
# Clean up Procedures
210+
- name: Terraform destroy
211+
if: always()
212+
continue-on-error: true
213+
run: |
214+
cd ${{ env.TEST_RESOURCES_FOLDER }}/terraform/dotnet/lambda/lambda && terraform destroy -auto-approve \
215+
-var="sdk_layer_name=AWSOpenTelemetryDistroDotNet-${{ github.run_id }}" \
216+
-var="function_name=${{env.TERRAFORM_LAMBDA_FUNCTION_NAME}}" \
217+
-var="layer_artifacts_directory=${{ env.ARTIFACTS_DIR }}" \
218+
-var="region=${{ env.E2E_TEST_AWS_REGION }}" \
219+
-var="is_canary=${{ env.IS_CANARY }}"

.github/workflows/dotnet-sample-app-s3-deploy.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,22 @@ jobs:
5656
aws s3api put-object --bucket aws-appsignals-sample-app-prod-${{ matrix.aws-region }} --body ./dotnet-ec2-win-main-setup.ps1 --key dotnet-ec2-win-main-setup.ps1
5757
aws s3api put-object --bucket aws-appsignals-sample-app-prod-${{ matrix.aws-region }} --body ./dotnet-ec2-win-remote-setup.ps1 --key dotnet-ec2-win-remote-setup.ps1
5858
aws s3api put-object --bucket aws-appsignals-sample-app-prod-${{ matrix.aws-region }} --body ./amazon-cloudwatch-agent.json --key amazon-cloudwatch-agent.json
59+
60+
- name: Build Lambda Sample App
61+
uses: actions/checkout@v4
62+
with:
63+
repository: 'aws-observability/aws-otel-dotnet-instrumentation'
64+
- name: Setup .NET
65+
uses: actions/setup-dotnet@v2
66+
with:
67+
dotnet-version: '8.0.x'
68+
- name: Build Lambda Sample App
69+
shell: bash
70+
run: dotnet lambda package -pl ./src/SimpleLambdaFunction
71+
working-directory: sample-applications/lambda-test-apps/SimpleLambdaFunction
72+
73+
- name: Upload to Lambda Sample App to S3
74+
working-directory: sample-applications/lambda-test-apps/SimpleLambdaFunction
75+
run: aws s3api put-object --bucket aws-appsignals-sample-app-prod-${{ matrix.aws-region }} --body ./src/SimpleLambdaFunction/bin/Release/net8.0/SimpleLambdaFunction.zip --key dotnet-function.zip
5976

6077

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@
77
build
88

99
# Ignore NodeJS build outputs
10-
node_modules/
10+
node_modules/
11+
12+
# Ignore Bin files from validator folder
13+
validator/bin

0 commit comments

Comments
 (0)