From 557f64b261f0090b0b31d32dfaf314bb11d79134 Mon Sep 17 00:00:00 2001 From: Corey Pyle Date: Wed, 1 Nov 2023 17:59:23 -0400 Subject: [PATCH] JavaScript (v3): Update Dockerfile to correctly build for, and run, integ tests. (#5589) * JavaScript (v3): Update scripts location in dockerfile and log all test output * JavaScript (v3): Update docker file to correctly run integ tests. --- javascriptv3/.dockerignore | 1 - javascriptv3/Dockerfile | 25 ++++++++++------ javascriptv3/Dockerfile.dockerignore | 2 ++ javascriptv3/README.md | 27 +++++------------ .../dynamodb/tests/hello.integration.test.js | 8 ++--- .../tests/eventbridge.integration.test.js | 30 ++++++++++++------- javascriptv3/package.json | 3 +- javascriptv3/scripts/run_tests.sh | 30 ------------------- 8 files changed, 50 insertions(+), 76 deletions(-) delete mode 100644 javascriptv3/.dockerignore create mode 100644 javascriptv3/Dockerfile.dockerignore delete mode 100755 javascriptv3/scripts/run_tests.sh diff --git a/javascriptv3/.dockerignore b/javascriptv3/.dockerignore deleted file mode 100644 index b512c09d476..00000000000 --- a/javascriptv3/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -node_modules \ No newline at end of file diff --git a/javascriptv3/Dockerfile b/javascriptv3/Dockerfile index 1c0f2cd88cd..b265959db43 100644 --- a/javascriptv3/Dockerfile +++ b/javascriptv3/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1 -FROM node:18 +FROM node:20 # Update image RUN apt-get update && \ @@ -7,16 +7,23 @@ RUN apt-get update && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* -# Copy source code -COPY . /javascriptv3 - -# Perform build steps -RUN npm install -C /javascriptv3 - # Set non-root user RUN useradd -m automation && \ - chown -R automation:automation /javascriptv3/ + chown -R automation:automation /home/automation USER automation:automation +# Add config +RUN mkdir /home/automation/.aws && \ + echo "[default]\nregion = us-east-1" > /home/automation/.aws/config + +# Copy source code +COPY --chown=automation:automation ./javascriptv3 /home/automation/javascriptv3 + +# Copy resources +COPY --chown=automation:automation ./resources /home/automation/resources +COPY --chown=automation:automation ./python/example_code/glue/flight_etl_job_script.py /home/automation/python/example_code/glue/flight_etl_job_script.py +COPY --chown=automation:automation ./workflows /home/automation/workflows + # Set default command -CMD ["./scripts/run_tests.sh", "integration"] \ No newline at end of file +# `npm i` needs to be run in the container. Otherwise it causes a dependency issue: https://github.com/evanw/esbuild/issues/1646#issuecomment-1238080595 +CMD npm i --prefix /home/automation/javascriptv3 && npm run --prefix /home/automation/javascriptv3 integration-test diff --git a/javascriptv3/Dockerfile.dockerignore b/javascriptv3/Dockerfile.dockerignore new file mode 100644 index 00000000000..480af175c87 --- /dev/null +++ b/javascriptv3/Dockerfile.dockerignore @@ -0,0 +1,2 @@ +*/node_modules +*/package-lock.json \ No newline at end of file diff --git a/javascriptv3/README.md b/javascriptv3/README.md index 19d0e4f503e..b424c978468 100644 --- a/javascriptv3/README.md +++ b/javascriptv3/README.md @@ -39,17 +39,13 @@ Cross-service examples are located in the [_cross-services folder_](./example_co You can run tests for a specific service, or for every service in this repository. Choose whether to run unit tests, integration tests, or both. -- To run both unit and integration tests for all services, run the following from this directory: +- To run unit tests, use the following command: `npm test` -- To run only unit tests, use the "unit" argument: +- To run integration tests, use the following command: - `npm test unit` - -- To run only integration tests, use the "integration" argument: - - `npm test integration` + `npm run integration-test` - To run tests for a specific service, follow the instructions in the service's README. @@ -59,27 +55,20 @@ If you run tests using the preceding commands, output will be stored in `unit_te ## Docker image (Beta) -This example is available in a container image -hosted on [Amazon Elastic Container Registry (ECR)](https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html). This image will be pre-loaded -with all JavaScript v3 examples with dependencies pre-resolved, allowing you to explore -these examples in an isolated environment. +This example is available in a container image hosted on [Amazon Elastic Container Registry (ECR)](https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html). This image will be pre-loaded with all JavaScript v3 examples with dependencies pre-resolved. It is used for running tests. - [SDK for JavaScript v3 image](https://gallery.ecr.aws/b4v4v1s0/javascriptv3) ### Build the Docker image 1. Install and run Docker on your machine. -2. Navigate to the same directory as this readme. -3. Run `docker build -t .` and replace `image_name` with a name for the image. +2. Navigate to the root directory of this repository. +3. Run `docker build -t -f javascriptv3/Dockerfile .` and replace `` with a name for the image. ### Launch the Docker container -1. Run `docker run -it -v ~/.aws/credentials:/root/.aws/credentials `. `-it` launches an - interactive terminal. `-v ~/.aws...` is optional but recommended. It will mount your local credentials - file to the container. -2. The terminal initiates a bash instance at the root of the container. Run `cd javascriptv3` and then you - can run tests from here by following the steps in the [Tests](#tests) section. Run examples by navigating - to a service folder and following the README instructions there. +1. Run `docker run -it -v /Users/corepyle/.aws/credentials:/home/automation/.aws/credentials `. `-it` launches an interactive terminal. `-v ~/.aws...` is optional but recommended. It will mount your local credentials file to the container. +2. The Dockerfile is configured to automatically run integration tests when the container is run. ## Contribute diff --git a/javascriptv3/example_code/dynamodb/tests/hello.integration.test.js b/javascriptv3/example_code/dynamodb/tests/hello.integration.test.js index 1d7ac55bc84..218827392d5 100644 --- a/javascriptv3/example_code/dynamodb/tests/hello.integration.test.js +++ b/javascriptv3/example_code/dynamodb/tests/hello.integration.test.js @@ -1,4 +1,4 @@ -import { describe, it, expect, vi } from "vitest"; +import { describe, it, expect } from "vitest"; import { main } from "../hello.js"; import { getUniqueName } from "@aws-sdk-examples/libs/utils/util-string.js"; @@ -10,10 +10,8 @@ describe("hello test", () => { tableSetupTeardown(tableName, [{ AttributeName: "Id", AttributeType: "N" }]); it("should list tables", async () => { - const spy = vi.spyOn(console, "log"); + const { TableNames } = await main(); - await main(); - - expect(spy).toHaveBeenCalledWith(`${tableName}`); + expect(TableNames.includes(tableName)).toBe(true); }); }); diff --git a/javascriptv3/example_code/eventbridge/tests/eventbridge.integration.test.js b/javascriptv3/example_code/eventbridge/tests/eventbridge.integration.test.js index f8c2268e598..d9fac63af90 100644 --- a/javascriptv3/example_code/eventbridge/tests/eventbridge.integration.test.js +++ b/javascriptv3/example_code/eventbridge/tests/eventbridge.integration.test.js @@ -20,7 +20,7 @@ import { SetQueueAttributesCommand, } from "@aws-sdk/client-sqs"; -import { retry } from "@aws-sdk-examples/libs/utils/util-timers.js"; +import { retry, wait } from "@aws-sdk-examples/libs/utils/util-timers.js"; import { putEvents } from "../actions/put-events.js"; import { putRule } from "../actions/put-rule.js"; @@ -77,9 +77,11 @@ test("target should receive message", async () => { // Ensure the queue allows the rule to send messages. await addQueuePolicy(Clients.SQSClient, queueArn, RuleArn, queueUrl); + await wait(15); // Put the target. await putTarget(ruleName, queueArn, targetId); + await wait(15); // Put the event. await putEvents("eventbridge.integration.test", "greeting", []); @@ -162,14 +164,20 @@ async function addQueuePolicy(sqsClient, queueArn, ruleArn, queueUrl) { * @param {SQSClient} sqsClient * @param {string} queueUrl */ -async function getMessagesFromQueue(sqsClient, queueUrl) { - const { Messages } = await sqsClient.send( - new ReceiveMessageCommand({ - QueueUrl: queueUrl, - MaxNumberOfMessages: 1, - WaitTimeSeconds: 20, - }), - ); - - return Messages; +function getMessagesFromQueue(sqsClient, queueUrl) { + return retry({ intervalInMs: 0, maxRetries: 3 }, async () => { + const { Messages } = await sqsClient.send( + new ReceiveMessageCommand({ + QueueUrl: queueUrl, + MaxNumberOfMessages: 1, + WaitTimeSeconds: 20, + }), + ); + + if (!Messages || Messages.length === 0) { + throw new Error("No messages received."); + } + + return Messages; + }); } diff --git a/javascriptv3/package.json b/javascriptv3/package.json index 3b6e85b2a60..43ab638b279 100644 --- a/javascriptv3/package.json +++ b/javascriptv3/package.json @@ -2,7 +2,8 @@ "name": "root", "private": true, "scripts": { - "test": "scripts/run_tests.sh", + "test": "npm run test --workspaces --if-present -- --reporter verbose", + "integration-test": "npm run integration-test --workspaces --if-present -- --reporter verbose", "lint": "lint-staged", "ci-lint": "eslint" }, diff --git a/javascriptv3/scripts/run_tests.sh b/javascriptv3/scripts/run_tests.sh deleted file mode 100755 index bbcbf493e27..00000000000 --- a/javascriptv3/scripts/run_tests.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -run_unit_tests() { - # Write stdout to a file and stderr to stdout - npm run test --workspaces --if-present -- --silent 2>&1 > unit_test.log -} - -run_integration_tests() { - # Write stdout to a file and stderr to stdout - npm run integration-test --workspaces --if-present --silent 2>&1 > integration_test.log -} - -run_all() { - if ! run_unit_tests || ! run_integration_tests; then - exit 1 - fi -} - -if [[ $# -eq 0 ]]; then - run_unit_tests -elif [[ "$1" == "unit" && "$2" == "integration" ]] || [[ "$1" == "integration" && "$2" == "unit" ]]; then - run_all -elif [[ "$1" == "unit" || "$2" == "unit" ]]; then - run_unit_tests -elif [[ "$1" == "integration" || "$2" == "integration" ]]; then - run_integration_tests -else - echo "Usage: $0 [unit|integration]" - exit 1 -fi