diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d04a47d..f3f6994 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -93,17 +93,15 @@ jobs: --health-interval 10s --health-timeout 10s --health-retries 10 - localstack: - # Pinned to the last community release. Newer images quit with - # "License activation failed" unless LOCALSTACK_AUTH_TOKEN is set. - image: localstack/localstack:4.14.0 + elasticmq: + image: softwaremill/elasticmq-native:1.7.1 ports: - - 4566:4566 - env: - SERVICES: sqs - DEBUG: 0 + - 9324:9324 + # The image is Alpine plus the server binary, so wget is the only HTTP + # client in it. A bare GET answers 400 because SQS wants an Action, so + # ask for one: ListQueues needs no credentials and answers 200. options: >- - --health-cmd "curl -f http://localhost:4566/_localstack/health || exit 1" + --health-cmd "wget -q -O /dev/null 'http://localhost:9324/?Action=ListQueues' || exit 1" --health-interval 5s --health-timeout 5s --health-retries 10 @@ -214,17 +212,15 @@ jobs: --health-interval 10s --health-timeout 10s --health-retries 10 - localstack: - # Pinned to the last community release. Newer images quit with - # "License activation failed" unless LOCALSTACK_AUTH_TOKEN is set. - image: localstack/localstack:4.14.0 + elasticmq: + image: softwaremill/elasticmq-native:1.7.1 ports: - - 4566:4566 - env: - SERVICES: sqs - DEBUG: 0 + - 9324:9324 + # The image is Alpine plus the server binary, so wget is the only HTTP + # client in it. A bare GET answers 400 because SQS wants an Action, so + # ask for one: ListQueues needs no credentials and answers 200. options: >- - --health-cmd "curl -f http://localhost:4566/_localstack/health || exit 1" + --health-cmd "wget -q -O /dev/null 'http://localhost:9324/?Action=ListQueues' || exit 1" --health-interval 5s --health-timeout 5s --health-retries 10 @@ -324,17 +320,15 @@ jobs: --health-interval 10s --health-timeout 10s --health-retries 10 - localstack: - # Pinned to the last community release. Newer images quit with - # "License activation failed" unless LOCALSTACK_AUTH_TOKEN is set. - image: localstack/localstack:4.14.0 + elasticmq: + image: softwaremill/elasticmq-native:1.7.1 ports: - - 4566:4566 - env: - SERVICES: sqs - DEBUG: 0 + - 9324:9324 + # The image is Alpine plus the server binary, so wget is the only HTTP + # client in it. A bare GET answers 400 because SQS wants an Action, so + # ask for one: ListQueues needs no credentials and answers 200. options: >- - --health-cmd "curl -f http://localhost:4566/_localstack/health || exit 1" + --health-cmd "wget -q -O /dev/null 'http://localhost:9324/?Action=ListQueues' || exit 1" --health-interval 5s --health-timeout 5s --health-retries 10 diff --git a/compose.yaml b/compose.yaml index 5dba621..883d0a0 100644 --- a/compose.yaml +++ b/compose.yaml @@ -118,17 +118,23 @@ services: timeout: 5s retries: 10 - localstack: - # Pinned to the last community release. Newer images quit with - # "License activation failed" unless LOCALSTACK_AUTH_TOKEN is set. - image: localstack/localstack:4.14.0 + elasticmq: + image: softwaremill/elasticmq-native:1.7.1 ports: - - "4566:4566" - environment: - SERVICES: sqs - DEBUG: 0 + - "9324:9324" healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:4566/_localstack/health"] + # The image is Alpine plus the server binary, so wget is the only HTTP + # client in it. A bare GET answers 400 because SQS wants an Action, so + # ask for one: ListQueues needs no credentials and answers 200. + test: + [ + "CMD", + "wget", + "-q", + "-O", + "/dev/null", + "http://localhost:9324/?Action=ListQueues", + ] interval: 5s timeout: 5s retries: 10 diff --git a/probitas/13-client-sqs.probitas.ts b/probitas/13-client-sqs.probitas.ts index 07ba1c6..ae9703f 100644 --- a/probitas/13-client-sqs.probitas.ts +++ b/probitas/13-client-sqs.probitas.ts @@ -1,24 +1,33 @@ /** * SQS Client Scenario Example * - * Target: localstack service on port 4566 (compose.yaml) - * Uses LocalStack for AWS SQS emulation + * Target: elasticmq service on port 9324 (compose.yaml) + * Uses ElasticMQ for AWS SQS emulation */ import { client, expect, scenario, Skip } from "jsr:@probitas/probitas@^0"; import type { SqsMessage } from "jsr:@probitas/client-sqs@^0"; -const BASE_URL = "http://localhost:4566"; +const BASE_URL = "http://localhost:9324"; export default scenario("SQS Client Example", { tags: ["integration", "sqs", "aws"], }) - .setup("Check LocalStack availability", async () => { + .setup("Check ElasticMQ availability", async () => { + let response: Response; try { - await fetch(`${BASE_URL}/_localstack/health`, { + // ListQueues rather than a bare GET: SQS answers 400 without an Action, + // so a plain request would look like a failure. It needs no credentials. + response = await fetch(`${BASE_URL}/?Action=ListQueues`, { signal: AbortSignal.timeout(1000), }); } catch { - throw new Skip(`LocalStack not available at ${BASE_URL}`); + throw new Skip(`ElasticMQ not available at ${BASE_URL}`); + } + await response.body?.cancel(); + if (!response.ok) { + throw new Skip( + `ElasticMQ at ${BASE_URL} answered ${response.status}`, + ); } }) .resource("sqs", () =>