Testing and Operating AWS Integrations
Latest stable Based on AWS release 0.4.0
Test the AWS boundary that can fail in production: request mapping, endpoint and credentials selection, retry and acknowledgement behavior, client ownership, and shutdown. A mocked client is useful for pure delegation logic, but it does not prove transport, serialization, emulator compatibility, or lifecycle.

Evidence ladder
Section titled “Evidence ladder”| Level | What it proves | What it does not prove |
|---|---|---|
| Unit or mock test | Request mapping, branching, conversion, retry classification | Real SDK transport, endpoint behavior, IAM, or lifecycle |
| Floci integration test | Fast default path for supported AWS APIs through Testcontainers | Operations not implemented by Floci or AWS production behavior |
| LocalStack fallback | An operation or cross-service path supported by LocalStack | AWS IAM, quota, latency, managed-service policy, or full semantic parity |
| AWS environment smoke test | Current credentials, region, endpoint, and selected service can work together | Repeatable failure recovery, scale, or broad policy coverage |
| Load or resilience test | One declared workload and failure model | A universal throughput or cost claim |
Floci first, LocalStack explicitly
Section titled “Floci first, LocalStack explicitly”Repository tests default bluetape4k.aws.emulator to floci. Keep that default for fast supported paths. When Floci lacks an operation or a cross-service integration needs LocalStack, select it explicitly:
./gradlew :bluetape4k-aws-java:test \ -Dbluetape4k.aws.emulator=localstack
./gradlew :aws-spring-boot-sqs-examples:test \ -Dbluetape4k.aws.emulator=localstackDo not hide emulator gaps by skipping assertions. Mark unsupported operations clearly and keep mock or fallback coverage tied to the gap. Passing against either emulator does not prove production IAM or service limits.
Run the smallest relevant example
Section titled “Run the smallest relevant example”./gradlew :aws-ktor-s3-examples:test./gradlew :aws-ktor-dynamodb-examples:test./gradlew :aws-ktor-sqs-examples:test./gradlew :aws-ktor-exposed-examples:test
./gradlew :aws-spring-boot-s3-examples:test./gradlew :aws-spring-boot-dynamodb-examples:test./gradlew :aws-spring-boot-sqs-examples:test./gradlew :aws-spring-boot-exposed-examples:testFor service code, add failure cases: duplicate SQS delivery, visibility timeout expiry, conditional DynamoDB write failure, partial S3 transfer, expired presigned URL, unavailable secret source, and shutdown while work is in flight.
Operational checklist
Section titled “Operational checklist”- Credentials and region — use the provider chain appropriate to the deployment. Never log access keys, session tokens, secret payloads, or signed headers.
- Retries and idempotency — retry only operations whose business effect is safe. Carry idempotency keys into consumers and writes where duplicates are possible.
- Timeouts — configure connect, request, polling, handler, and shutdown timeouts against the service-level budget.
- Readiness — report ready only after required clients, queues, tables, buckets, or database pools can serve the path the application requires.
- Observability — record service, operation, outcome, retry count, latency, queue phase, and low-cardinality resource identifiers. Avoid bucket keys, message bodies, and secret names when they can expose user data.
- Shutdown — stop polling, drain or cancel in-flight work, flush bounded buffers, close clients and pools, then close any explicitly shared HTTP engine.
Ownership tests
Section titled “Ownership tests”Add a lifecycle test whenever a component can either create or receive a client. Verify that owned clients close exactly once and injected clients remain open. For shared Kotlin SDK engines, verify the engine stays available while another client uses it and is closed by the application only after every client stops.