diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index d1ea599..7f7e82c 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -125,7 +125,7 @@ jobs: go tool cover -html=coverage/coverage.out -o coverage/coverage.html - name: Upload Coverage Report - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: coverage-report path: src/coverage/coverage.html diff --git a/.github/workflows/release-lambda-code.yaml b/.github/workflows/release-lambda-code.yaml index 547aae8..103ba1e 100644 --- a/.github/workflows/release-lambda-code.yaml +++ b/.github/workflows/release-lambda-code.yaml @@ -34,7 +34,7 @@ jobs: cd .. - name: Upload artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: log-forwarder-zip path: | @@ -82,7 +82,7 @@ jobs: steps: - name: Download Artifact - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: log-forwarder-zip path: ./build-artifacts diff --git a/.github/workflows/run-e2e-tests.yaml b/.github/workflows/run-e2e-tests.yaml index 718b7ae..fb413a1 100644 --- a/.github/workflows/run-e2e-tests.yaml +++ b/.github/workflows/run-e2e-tests.yaml @@ -1,22 +1,81 @@ name: E2E Test Workflow on: - pull_request: - branches: - - develop - - main + pull_request_review: + types: + - submitted + schedule: + - cron: '0 0 1 * *' jobs: - run-e2e-tests: + build-templates: + if: github.event.review.state == 'approved' runs-on: ubuntu-latest permissions: id-token: write contents: write + strategy: + matrix: + TEMPLATE_FILE: [lambda-template] + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.22' + + - name: Install AWS SAM CLI + run: | + pip install aws-sam-cli + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v3 + with: + role-to-assume: ${{ secrets.AWS_E2E_ROLE }} + aws-region: us-east-1 + + - name: Build SAM Application + env: + S3_BUCKET: unified-lambda-e2e-test-templates + run: | + sam build -u --template-file "${{ matrix.TEMPLATE_FILE }}.yaml" --build-dir ".aws-sam/build/${{ matrix.TEMPLATE_FILE }}" + sam package --s3-bucket "$S3_BUCKET" --template-file ".aws-sam/build/${{ matrix.TEMPLATE_FILE }}/template.yaml" --output-template-file ".aws-sam/build/${{ matrix.TEMPLATE_FILE }}/${{ matrix.TEMPLATE_FILE }}.yaml" + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.TEMPLATE_FILE }}.yaml + path: .aws-sam/build/${{ matrix.TEMPLATE_FILE }}/${{ matrix.TEMPLATE_FILE }}.yaml + + - name: Send failure notification to Slack + if: always() + uses: ravsamhq/notify-slack-action@v1 + with: + status: ${{ job.status }} + notify_when: 'failure' + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + + run-e2e-tests-cloudwatch: + needs: [build-templates] + runs-on: ubuntu-latest + permissions: + id-token: write + contents: write + strategy: + matrix: + test-case: [test_logs_with_filter_pattern, test_logs_for_secret_manager, test_logs_for_invalid_log_group] steps: - name: Checkout code uses: actions/checkout@v4 + - name: Download Artifact + uses: actions/download-artifact@v4 + with: + path: build-artifacts + - name: Setup Go uses: actions/setup-go@v5 with: @@ -32,29 +91,101 @@ jobs: role-to-assume: ${{ secrets.AWS_E2E_ROLE }} aws-region: us-east-1 - - name: Run e2e tests + - name: Run e2e tests for cloudwatch env: NEW_RELIC_USER_KEY: ${{ secrets.NEW_RELIC_USER_KEY }} NEW_RELIC_LICENSE_KEY: ${{ secrets.NEW_RELIC_LICENSE_KEY }} - S3_BUCKET: unified-lambda-e2e-test-templates run: | - cd e2e-tests/ - ./build-templates.sh - - echo "Running s3 and cloudwatch trigger tests parallely" - ./lambda-cloudwatch-trigger.sh & - pid1=$! - echo "Testing setting up cloudwatch trigger with PID: $pid1" - - ./lambda-s3-trigger.sh & - pid2=$! - echo "Testing setting up s3 trigger with PID: $pid2" - - wait $pid1 - wait $pid2 + cd e2e-tests + ./lambda-cloudwatch-trigger.sh ${{ matrix.test-case }} + + - name: Send failure notification to Slack + if: always() + uses: ravsamhq/notify-slack-action@v1 + with: + status: ${{ job.status }} + notify_when: 'failure' + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + + run-e2e-tests-s3: + needs: [build-templates] + runs-on: ubuntu-latest + permissions: + id-token: write + contents: write + strategy: + matrix: + test-case: [test_logs_for_prefix, test_logs_for_secret_manager, test_logs_for_invalid_bucket_name] + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download Artifact + uses: actions/download-artifact@v4 + with: + path: build-artifacts + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.22' + + - name: Install AWS SAM CLI + run: | + pip install aws-sam-cli + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v3 + with: + role-to-assume: ${{ secrets.AWS_E2E_ROLE }} + aws-region: us-east-1 + + - name: Run e2e tests for s3 + env: + NEW_RELIC_USER_KEY: ${{ secrets.NEW_RELIC_USER_KEY }} + NEW_RELIC_LICENSE_KEY: ${{ secrets.NEW_RELIC_LICENSE_KEY }} + run: | + cd e2e-tests + ./lambda-s3-trigger.sh ${{ matrix.test-case }} + + - name: Send failure notification to Slack + if: always() + uses: ravsamhq/notify-slack-action@v1 + with: + status: ${{ job.status }} + notify_when: 'failure' + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + + clean-up: + needs: [run-e2e-tests-cloudwatch, run-e2e-tests-s3] + runs-on: ubuntu-latest + permissions: + id-token: write + contents: write + steps: + - name: Install AWS SAM CLI + run: | + pip install aws-sam-cli + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v3 + with: + role-to-assume: ${{ secrets.AWS_E2E_ROLE }} + aws-region: us-east-1 - name: Delete Resources env: S3_BUCKET: unified-lambda-e2e-test-templates run: - aws s3 rm "s3://$S3_BUCKET" --recursive \ No newline at end of file + aws s3 rm "s3://$S3_BUCKET" --recursive + + - name: Send failure notification to Slack + if: always() + uses: ravsamhq/notify-slack-action@v1 + with: + status: ${{ job.status }} + notify_when: 'failure' + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} \ No newline at end of file diff --git a/e2e-tests/build-templates.sh b/e2e-tests/build-templates.sh deleted file mode 100755 index ca45abe..0000000 --- a/e2e-tests/build-templates.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -# add all templates for subsequent test cases -# make packaging and publishing of templates more efficient so every time new al2 env is not spun up -TEMPLATES=("lambda-template.yaml") - -source config-file.cfg - -for TEMPLATE_FILE in "${TEMPLATES[@]}"; do - - BASE_NAME=$(basename "$TEMPLATE_FILE" .yaml) - BUILD_DIR="$BUILD_DIR_BASE/$BASE_NAME" - - sam build -u --template-file "../$TEMPLATE_FILE" --build-dir "$BUILD_DIR" - sam package --s3-bucket "$S3_BUCKET" --template-file "$BUILD_DIR/template.yaml" --output-template-file "$BUILD_DIR/$TEMPLATE_FILE" - -done \ No newline at end of file diff --git a/e2e-tests/common-scripts/entity_synthesis_param.cfg b/e2e-tests/common-scripts/entity_synthesis_param.cfg new file mode 100644 index 0000000..a3cbd67 --- /dev/null +++ b/e2e-tests/common-scripts/entity_synthesis_param.cfg @@ -0,0 +1,4 @@ +# Entity synthesis Parameters , aws related params are dropped in pipeline. +instrumentation_provider=aws +instrumentation_name=lambda +instrumentation_version=1.0.0 \ No newline at end of file diff --git a/e2e-tests/common-scripts/logs-scripts.sh b/e2e-tests/common-scripts/logs-scripts.sh new file mode 100644 index 0000000..1b82d5e --- /dev/null +++ b/e2e-tests/common-scripts/logs-scripts.sh @@ -0,0 +1,110 @@ +#!/bin/bash + +source test-configs.cfg +source entity_synthesis_param.cfg +source stack-scripts.sh + +validate_logs_in_new_relic() { + user_key=$1 + account_id=$2 + attribute_key=$3 + attribute_value=$4 + log_message=$5 + + sleep_time=$SLEEP_TIME + attempt=1 + + while [[ $attempt -lt $MAX_RETRIES ]]; do + echo "Fetching logs from new relic for $attribute_key: $attribute_value" + sleep "$sleep_time" + response=$(fetch_new_relic_logs_api "$user_key" "$account_id" "$attribute_key" "$attribute_value") + + if echo "$response" | grep -q "$log_message"; then + echo "Log event successfully found in New Relic." + validate_logs_meta_data "$response" + return 0 + fi + + if (( sleep_time < MAX_SLEEP_TIME )); then + sleep_time=$(( sleep_time * 2 )) + fi + echo "Log event not found in New Relic. Retrying in $sleep_time seconds..." + attempt=$((attempt + 1)) + done + + exit_with_error "Log event with $attribute_key: $attribute_value not found in New Relic. Error Received: $response" +} + +validate_logs_not_present() { + user_key=$1 + account_id=$2 + attribute_key=$3 + attribute_value=$4 + log_message=$5 + + sleep_time=$SLEEP_TIME + attempt=1 + + while [[ $attempt -lt $MAX_RETRIES ]]; do + echo "Fetching logs from new relic for $attribute_key: $attribute_value" + sleep "$sleep_time" + response=$(fetch_new_relic_logs_api "$user_key" "$account_id" "$attribute_key" "$attribute_value") + + if echo "$response" | grep -q "$log_message"; then + exit_with_error "Log event found in New Relic. Validation failed" + fi + + echo "Log event not found in New Relic. Retrying in $sleep_time seconds..." + attempt=$((attempt + 1)) + done + + echo "Log event with $attribute_key: $attribute_value not found in New Relic. Validation succeeded" +} + +fetch_new_relic_logs_api() { + user_key=$1 + account_id=$2 + attribute_key=$3 + attribute_value=$4 + + nrql_query="SELECT * FROM Log WHERE $attribute_key LIKE '%$attribute_value%' SINCE $TIME_RANGE ago" + query='{"query":"query($id: Int!, $nrql: Nrql!) { actor { account(id: $id) { nrql(query: $nrql) { results } } } }","variables":{"id":'$account_id',"nrql":"'$nrql_query'"}}' + + response=$(curl -s -X POST \ + -H "Content-Type: application/json" \ + -H "API-Key: $user_key" \ + -d "$query" \ + https://api.newrelic.com/graphql) + + echo "$response" +} + +create_log_message() { + log_message=$1 + filter_pattern=$2 + + UUID=$(uuidgen) + echo "RequestId: $UUID, message: $log_message, filter: $filter_pattern" +} + +validate_logs_meta_data (){ + response=$1 + + # Validate custom attributes + if ! echo "$response" | grep -q "\"$CUSTOM_ATTRIBUTE_KEY\":\"$CUSTOM_ATTRIBUTE_VALUE\""; then + exit_with_error "Custom attribute $CUSTOM_ATTRIBUTE_KEY with value $CUSTOM_ATTRIBUTE_VALUE not found in New Relic logs." + fi + echo "Custom attributes {attributeKey: $CUSTOM_ATTRIBUTE_KEY, attributeValue: $CUSTOM_ATTRIBUTE_VALUE} validated successfully." + + # Validate common attributes + while IFS='=' read -r key value; do + if [[ $key == instrumentation_* ]]; then + new_key=$(echo "$key" | sed 's/_/./g') + if ! echo "$response" | grep -q "\"$new_key\":\"$value\""; then + exit_with_error "Entity synthesis attribute $new_key with value $value not found in New Relic logs." + fi + fi + done < entity_synthesis_param.cfg + + echo "Entity synthesis attributes validated successfully." +} \ No newline at end of file diff --git a/e2e-tests/common-scripts/resource-scripts.sh b/e2e-tests/common-scripts/resource-scripts.sh new file mode 100644 index 0000000..f1ba51f --- /dev/null +++ b/e2e-tests/common-scripts/resource-scripts.sh @@ -0,0 +1,147 @@ +#!/bin/bash + +source test-configs.cfg +source stack-scripts.sh + +get_lambda_function_arn() { + stack_name=$1 + + lambda_physical_id=$(aws cloudformation describe-stack-resources \ + --stack-name "$stack_name" \ + --logical-resource-id "$LAMBDA_LOGICAL_RESOURCE_ID" \ + --query "StackResources[0].PhysicalResourceId" \ + --output text + ) + + lambda_function_arn=$(aws lambda get-function --function-name "$lambda_physical_id" \ + --query "Configuration.FunctionArn" \ + --output text + ) + + echo "$lambda_function_arn" +} + +create_cloudwatch_log_event() { + log_group_name=$1 + log_stream_name=$2 + log_message=$3 + + echo "Creating log event in CloudWatch Log Group" + + # Check if the log stream exists else create one + log_stream_exists=$(aws logs describe-log-streams --log-group-name "$log_group_name" --log-stream-name-prefix "$log_stream_name" --query "logStreams[?logStreamName=='$log_stream_name'] | length(@)" --output text) + + if [ -n "$log_stream_exists" ] && [ "$log_stream_exists" -eq 0 ]; then + echo "Log stream does not exist. Creating log stream: $log_stream_name" + aws logs create-log-stream --log-group-name "$log_group_name" --log-stream-name "$log_stream_name" + fi + + aws logs put-log-events \ + --log-group-name "$log_group_name" \ + --log-stream-name "$log_stream_name" \ + --log-events "timestamp=$(date +%s000),message=\"$log_message\"" + + echo "Log event with message: $log_message created successfully." +} + +upload_file_to_s3_bucket() { + bucket_name=$1 + log_file=$2 + prefix=$3 + log_message=$4 + + echo "$log_message" >> "$log_file" + if [[ $? -ne 0 ]]; then + echo "Failed to write log to file." + return 1 + fi + + aws s3 cp "$log_file" "s3://$bucket_name/$prefix" + if [[ $? -ne 0 ]]; then + echo "Failed to upload log file to S3." + return 1 + fi + + echo "Log successfully uploaded as s3://$bucket_name/$prefix" +} + +validate_lambda_subscription_created() { + stack_name=$1 + log_group_name=$2 + log_group_filter=$3 + + echo "Validating cloudwatch lambda subscription for stack name: $stack_name, log group name: $log_group_name, and log group filter: $log_group_filter" + + lambda_function_arn=$(get_lambda_function_arn "$stack_name") + + subscriptions=$(aws logs describe-subscription-filters --log-group-name "$log_group_name" --query 'subscriptionFilters[*].[destinationArn, filterPattern]' --output text) + + if echo "$subscriptions" | grep -q "$lambda_function_arn" && echo "$subscriptions" | grep -q "$log_group_filter"; then + echo "Lambda function $lambda_function_arn is subscribed to log group: $log_group_name with filter: $log_group_filter" + else + exit_with_error "Lambda function $lambda_function_arn is not subscribed to log group: $log_group_name" + fi + +} + +validate_lambda_subscription_not_created() { + stack_name=$1 + log_group_name=$2 + log_group_filter=$3 + + echo "Validating cloudwatch lambda subscription for stack name: $stack_name, log group name: $log_group_name, and log group filter: $log_group_filter" + + lambda_function_arn=$(get_lambda_function_arn "$stack_name") + + event_source_mappings=$(aws lambda list-event-source-mappings --function-name lambda_function_arn --query "EventSourceMappings" --output text) + + # Check if the output is empty + if [ -z "$event_source_mappings" ]; then + echo "No event source mappings found for the Lambda function $lambda_function_arn. Validation successful" + else + exit_with_error "Event source mappings exist for the Lambda function '$lambda_function_arn'. Validation failed" + fi +} + +validate_lambda_s3_trigger_created() { + stack_name=$1 + bucket_name=$2 + bucket_prefix=$3 + + echo "Validating s3 lambda trigger event for stack name: $stack_name, bucket name: $bucket_name, and prefix: $bucket_prefix" + + lambda_function_arn=$(get_lambda_function_arn "$stack_name") + + notification_configuration=$(aws s3api get-bucket-notification-configuration --bucket "$bucket_name") + + lambda_configurations=$(echo "$notification_configuration" | + jq --arg lambda "$lambda_function_arn" --arg prefix "$bucket_prefix" ' + .LambdaFunctionConfigurations[] | + select(.LambdaFunctionArn == $lambda and (.Filter.Key.FilterRules[]? | select(.Name == "Prefix" and .Value == $prefix)?))') + + if [ -n "$lambda_configurations" ]; then + echo "S3 triggers with prefix '$bucket_prefix' found for Lambda function $lambda_function_arn on bucket $bucket_name:" + echo "$lambda_configurations" | jq '.' + else + exit_with_error "No S3 triggers with prefix '$bucket_prefix' found for Lambda function $lambda_function_arn on bucket: $bucket_name." + fi +} + +validate_lambda_s3_trigger_not_created() { + stack_name=$1 + bucket_name=$2 + bucket_prefix=$3 + + echo "Validating s3 lambda trigger event for stack name: $stack_name, bucket name: $bucket_name, and prefix: $bucket_prefix" + + lambda_function_arn=$(get_lambda_function_arn "$stack_name") + + event_source_mappings=$(aws lambda list-event-source-mappings --function-name lambda_function_arn --query "EventSourceMappings" --output text) + + # Check if the output is empty + if [ -z "$event_source_mappings" ]; then + echo "No event source mappings found for the Lambda function $lambda_function_arn. Validation successful" + else + exit_with_error "Event source mappings exist for the Lambda function '$lambda_function_arn'. Validation failed" + fi +} \ No newline at end of file diff --git a/e2e-tests/common-scripts.sh b/e2e-tests/common-scripts/stack-scripts.sh similarity index 56% rename from e2e-tests/common-scripts.sh rename to e2e-tests/common-scripts/stack-scripts.sh index 601abfc..540f9aa 100755 --- a/e2e-tests/common-scripts.sh +++ b/e2e-tests/common-scripts/stack-scripts.sh @@ -1,6 +1,50 @@ #!/bin/bash -source config-file.cfg +source test-configs.cfg + +deploy_cloudwatch_trigger_stack() { + stack_name=$1 + secret_license_key=$2 + log_group_config=$3 + common_attributes=$4 + + echo "Deploying cloudwatch trigger stack with name: $stack_name" + + sam deploy \ + --template-file "$TEMPLATE_BUILD_DIR/$LAMBDA_TEMPLATE" \ + --stack-name "$stack_name" \ + --parameter-overrides \ + LicenseKey="$NEW_RELIC_LICENSE_KEY" \ + NewRelicRegion="$NEW_RELIC_REGION" \ + NewRelicAccountId="$NEW_RELIC_ACCOUNT_ID" \ + StoreNRLicenseKeyInSecretManager="$secret_license_key" \ + S3BucketNames="''" \ + LogGroupConfig="$log_group_config" \ + CommonAttributes="$common_attributes" \ + --capabilities CAPABILITY_IAM +} + +deploy_s3_trigger_stack() { + stack_name=$1 + secret_license_key=$2 + s3_bucket_names=$3 + common_attributes=$4 + + echo "Deploying s3 trigger stack with name: $stack_name" + + sam deploy \ + --template-file "$TEMPLATE_BUILD_DIR/$LAMBDA_TEMPLATE" \ + --stack-name "$stack_name" \ + --parameter-overrides \ + LicenseKey="$NEW_RELIC_LICENSE_KEY" \ + NewRelicRegion="$NEW_RELIC_REGION" \ + NewRelicAccountId="$NEW_RELIC_ACCOUNT_ID" \ + StoreNRLicenseKeyInSecretManager="$secret_license_key" \ + S3BucketNames="$s3_bucket_names" \ + LogGroupConfig="''" \ + CommonAttributes="$common_attributes" \ + --capabilities CAPABILITY_IAM +} validate_stack_deployment_status() { stack_name=$1 @@ -43,32 +87,12 @@ delete_stack() { if [ -z "$stack_status" ]; then echo "Stack $stack_name has been successfully deleted." - elif [ "$stack_status" == "DELETE_FAILED" ]; then - echo "Failed to delete stack $stack_name." else - echo "Unexpected stack status: $stack_status." + exit_with_error "Failed to delete stack $stack_name." fi } exit_with_error() { echo "Error: $1" exit 1 -} - -get_lambda_function_arn() { - stack_name=$1 - - lambda_physical_id=$(aws cloudformation describe-stack-resources \ - --stack-name "$stack_name" \ - --logical-resource-id "$LAMBDA_LOGICAL_RESOURCE_ID" \ - --query "StackResources[0].PhysicalResourceId" \ - --output text - ) - - lambda_function_arn=$(aws lambda get-function --function-name "$lambda_physical_id" \ - --query "Configuration.FunctionArn" \ - --output text - ) - - echo "$lambda_function_arn" } \ No newline at end of file diff --git a/e2e-tests/common-scripts/test-configs.cfg b/e2e-tests/common-scripts/test-configs.cfg new file mode 100644 index 0000000..a20a663 --- /dev/null +++ b/e2e-tests/common-scripts/test-configs.cfg @@ -0,0 +1,45 @@ +# test resources +NEW_RELIC_REGION=US +NEW_RELIC_ACCOUNT_ID=2813435 +S3_BUCKET=aws-unified-lambda-e2e-test-templates + +# test case constants +CLOUDWATCH_FILTER_PATTERN_CASE=e2e-cloudwatch-filter-pattern-test +CLOUDWATCH_SECRET_MANAGER_CASE=e2e-cloudwatch-secret-manager-test +CLOUDWATCH_INVALID_LOG_GROUP_CASE=e2e-cloudwatch-invalid-log-group-test +S3_PREFIX_CASE=e2e-s3-prefix-test +S3_SECRET_MANAGER_CASE=e2e-s3-secret-manager-test +S3_INVALID_BUCKET_CASE=e2e-s3-invalid-bucket-test + +# template constants +LAMBDA_TEMPLATE=lambda-template.yaml/lambda-template.yaml +TEMPLATE_BUILD_DIR=../build-artifacts +LAMBDA_LOGICAL_RESOURCE_ID=NewRelicLogsServerlessLogForwarder + +# deployment constants for s3 bucket cases +S3_BUCKET_NAME=aws-unified-lambda-e2e-test-bucket +S3_BUCKET_NAME_SECRET_MANAGER=aws-unified-lambda-e2e-test-bucket-secret-manager-case +S3_BUCKET_NAME_INVALID=aws-unified-lambda-e2e-test-bucket-non-existent +S3_BUCKET_PREFIX=LogFolder +S3_BUCKET_PREFIX_INVALID=InvalidFolder +S3_BUCKET_OBJECT_NAME=TestTextFile.txt +S3_BUCKET_OBJECT_NAME_FOR_INVALID_CASE=TestTextFileInvalid.txt + +# deployment constants for cloudwatch log group cases +LOG_GROUP_NAME=aws-unified-lambda-e2e-test-log-group +LOG_GROUP_NAME_SECRET_MANAGER=aws-unified-lambda-e2e-test-log-group-secret-manager +LOG_GROUP_NAME_INVALID=aws-unified-lambda-e2e-test-log-group-invalid +LOG_GROUP_FILTER_PATTERN=ERROR +LOG_STREAM_NAME=aws-unified-lambda-e2e-test-stream + +# fetch nr logs constants +LOG_MESSAGE_CLOUDWATCH="This is cloudwatch logs" +LOG_MESSAGE_S3="This is s3 logs" +ATTRIBUTE_KEY_CLOUDWATCH=logStream +ATTRIBUTE_KEY_S3=logObjectKey +TIME_RANGE="5 minutes" +MAX_RETRIES=5 +SLEEP_TIME=30 +MAX_SLEEP_TIME=180 +CUSTOM_ATTRIBUTE_KEY=testKey +CUSTOM_ATTRIBUTE_VALUE=testValue \ No newline at end of file diff --git a/e2e-tests/config-file.cfg b/e2e-tests/config-file.cfg deleted file mode 100644 index 84b5d75..0000000 --- a/e2e-tests/config-file.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# test resources -NEW_RELIC_REGION=US -NEW_RELIC_ACCOUNT_ID=2813435 - -# build constants -BUILD_DIR_BASE=.aws-sam/build - -# template constants -LAMBDA_TEMPLATE=lambda-template.yaml -LAMBDA_TEMPLATE_BUILD_DIR=.aws-sam/build/lambda-template -LAMBDA_LOGICAL_RESOURCE_ID=NewRelicLogsServerlessLogForwarder - -# deployment constants -S3_BUCKET_NAME=aws-unified-lambda-e2e-test-bucket -S3_BUCKET_PREFIX=LogFolder -LOG_GROUP_NAME=aws-unified-lambda-e2e-test-log-group -LOG_GROUP_FILTER_PATTERN=ERROR - diff --git a/e2e-tests/lambda-cloudwatch-trigger.sh b/e2e-tests/lambda-cloudwatch-trigger.sh index 404a71a..2e81f99 100755 --- a/e2e-tests/lambda-cloudwatch-trigger.sh +++ b/e2e-tests/lambda-cloudwatch-trigger.sh @@ -1,65 +1,93 @@ #!/bin/bash -source common-scripts.sh -source config-file.cfg - -# test case constants -CLOUDWATCH_TRIGGER_CASE=e2e-cloudwatch-trigger-stack - -deploy_cloudwatch_trigger_stack() { - template_file=$1 - stack_name=$2 - license_key=$3 - new_relic_region=$4 - new_relic_account_id=$5 - secret_license_key=$6 - log_group_config=$7 - common_attributes=$8 - - echo "Deploying cloudwatch trigger stack with name: $stack_name" - - sam deploy \ - --template-file "$template_file" \ - --stack-name "$stack_name" \ - --parameter-overrides \ - LicenseKey="$license_key" \ - NewRelicRegion="$new_relic_region" \ - NewRelicAccountId="$new_relic_account_id" \ - StoreNRLicenseKeyInSecretManager="$secret_license_key" \ - S3BucketNames="''" \ - LogGroupConfig="$log_group_config" \ - CommonAttributes="$common_attributes" \ - --capabilities CAPABILITY_IAM -} +source common-scripts/stack-scripts.sh +source common-scripts/resource-scripts.sh +source common-scripts/logs-scripts.sh +source common-scripts/test-configs.cfg + +test_logs_with_filter_pattern() { +cat < cloudwatch-parameter.json +'[{"LogGroupName":"$LOG_GROUP_NAME","FilterPattern":"$LOG_GROUP_FILTER_PATTERN"}]' +EOF -validate_lambda_subscription_created() { - # this function fetches cloudwatch subscriptions and - # validates if lambda subscription filter is configured - stack_name=$1 - log_group_name=$2 - log_group_filter=$3 +cat < common_attribute.json +'[{"AttributeName":"$CUSTOM_ATTRIBUTE_KEY","AttributeValue":"$CUSTOM_ATTRIBUTE_VALUE"}]' +EOF +COMMON_ATTRIBUTES=$( cloudwatch-parameter.json -'[{"LogGroupName":"$LOG_GROUP_NAME","FilterPattern":"$LOG_GROUP_FILTER_PATTERN"}]' +'[{"LogGroupName":"$LOG_GROUP_NAME_SECRET_MANAGER","FilterPattern":"$LOG_GROUP_FILTER_PATTERN"}]' +EOF + +cat < common_attribute.json +'[{"AttributeName":"$CUSTOM_ATTRIBUTE_KEY","AttributeValue":"$CUSTOM_ATTRIBUTE_VALUE"}]' +EOF +COMMON_ATTRIBUTES=$( cloudwatch-parameter.json +'[{"LogGroupName":"$LOG_GROUP_NAME_INVALID","FilterPattern":"$LOG_GROUP_FILTER_PATTERN"}]' EOF -LOG_GROUP_NAMES=$( s3-parameter.json +'[{"bucket":"$S3_BUCKET_NAME","prefix":"$S3_BUCKET_PREFIX"}]' +EOF -validate_lambda_s3_trigger_created() { - # this function fetches bucket configurations and - # validates if lambda event notification is configured - stack_name=$1 - bucket_name=$2 - bucket_prefix=$3 +cat < common_attribute.json +'[{"AttributeName":"$CUSTOM_ATTRIBUTE_KEY","AttributeValue":"$CUSTOM_ATTRIBUTE_VALUE"}]' +EOF +COMMON_ATTRIBUTES=$( s3-parameter.json -'[{"bucket":"$S3_BUCKET_NAME","prefix":"$S3_BUCKET_PREFIX"}]' +'[{"bucket":"$S3_BUCKET_NAME_SECRET_MANAGER","prefix":"$S3_BUCKET_PREFIX"}]' EOF -S3_BUCKET_NAMES=$( common_attribute.json +'[{"AttributeName":"$CUSTOM_ATTRIBUTE_KEY","AttributeValue":"$CUSTOM_ATTRIBUTE_VALUE"}]' +EOF +COMMON_ATTRIBUTES=$( s3-parameter.json +'[{"bucket":"$S3_BUCKET_NAME_INVALID","prefix":"$S3_BUCKET_PREFIX"}]' +EOF + + S3_BUCKET_NAMES=$(