* fix(cloudwatch): reject PutMetricData datums without a MetricName MetricName is the one required member of MetricDatum. The JSON handler stored a nameless datum under an empty name, and the Query handler treated a member without MetricName as the end of the list, silently dropping it and every later datum while still storing the earlier ones. Both handlers now reject a missing or empty MetricName in top-level MetricData and in EntityMetricData[].MetricData with MissingParameter (400), the error PutMetricData declares for a missing required input, naming the offending member. A whitespace name is still accepted, since AWS constrains MetricName only to 1 to 255 characters. Every datum is validated before any is stored, so a rejected request leaves no state behind. On Query, a member index with no keys at all still ends that MetricData list. * fix(cloudwatch): return MissingRequiredParameterException on JSON and CBOR CloudWatch is awsQueryCompatible. MissingParameter is the awsQueryError code of the MissingRequiredParameterException shape, so it belongs in the Query <Code> and the x-amzn-query-error header, while a JSON 1.0 or CBOR body's __type names the shape. With the code in __type the AWS SDK v2 raised a generic CloudWatchException instead of the modelled one. A package-private CloudWatchMetricsException keeps the Query code as its error code and overrides jsonType() with the shape name, the same split SwfException makes. The shared query-code table in AwsException is left alone because SQS reports MissingParameter as its JSON type. (cherry picked from commit b8d87df05413ea8c4f9497fa05f388c19d4124ec)
floci-compatibility-tests
Compatibility test suite for Floci — a local AWS emulator.
Verifies that standard AWS tooling (SDKs, CDK, OpenTofu/Terraform) works correctly against the emulator without modification. Tests run against a live Floci instance and use real AWS SDK clients — no mocks.
Quick Start
# Install just (task runner)
# macOS: brew install just
# Linux: cargo install just
# Copy and configure environment
cp env.example .env
# Install dependencies
just setup
# Run all tests
just test-all
# Run specific SDK tests
just test-python
just test-typescript
just test-awscli
Test Runners
| Module | Language | Test Framework | Command |
|---|---|---|---|
sdk-test-python |
Python 3 | pytest | just test-python |
sdk-test-node |
TypeScript | vitest | just test-typescript |
sdk-test-awscli |
Bash / AWS CLI | bats-core | just test-awscli |
sdk-test-java |
Java 17 | JUnit 5 | just test-java |
sdk-test-go |
Go 1.24 | go test | just test-go |
IaC Compatibility
| Module | Tool | Command |
|---|---|---|
compat-cdk |
AWS CDK v2 | ./run.sh |
compat-opentofu |
OpenTofu | ./run.sh |
compat-terraform |
Terraform | ./run.sh |
The Terraform suite uses the standard hashicorp/aws provider against Floci's local endpoint. It validates init, validate, plan, apply, resource reads, and destroy without creating resources in a real AWS account. See the Terraform with Floci guide for a copy-paste setup.
Prerequisites
- Floci running on
http://localhost:4566(or setFLOCI_ENDPOINT) - Docker — required for Lambda invocation tests
- just — task runner for orchestration
Per-module requirements:
| Module | Requirements |
|---|---|
sdk-test-python |
Python 3.9+, pip |
sdk-test-node |
Node.js 20+, npm, vitest |
sdk-test-awscli |
AWS CLI v2, bash, jq |
sdk-test-java |
Java 17+, Maven |
sdk-test-go |
Go 1.24+ |
compat-cdk |
Node.js 20+, npm, Python 3, bats-core |
Setup
# Setup all SDKs
just setup
# Setup individual SDKs
just setup-python # pip install -r requirements.txt
just setup-typescript # npm install
just setup-awscli # Clone bats-core, bats-support, bats-assert
Running Tests
All SDKs
just test-all
Individual SDKs
# Python (pytest)
just test-python
# TypeScript (vitest)
just test-typescript
# AWS CLI (bats-core)
just test-awscli
IaC tools
The Terraform, OpenTofu, and CDK suites aren't part of just test-all — run them individually by name:
# Terraform
compat-terraform/run.sh
# OpenTofu
compat-opentofu/run.sh
# AWS CDK
compat-cdk/run.sh
Bats-based suites keep their normal console output and also write JUnit XML reports:
sdk-test-awscli/test-results/junit.xmlcompat-cdk/test-results/junit.xmlcompat-terraform/test-results/junit-<bats file>.xmlcompat-opentofu/test-results/junit-<bats file>.xml
The Terraform and OpenTofu suites run each test/*.bats file in its own process
concurrently, so they write one report per file rather than a single junit.xml.
Every consumer globs the directory, so nothing downstream changes. Set
BATS_PARALLEL_FILES=0 to run the files one at a time when isolating a failure.
Each file also runs under a BATS_FILE_TIMEOUT (default 12m): a fixture that hangs
fails under its own name with its TAP output ending at the stuck test, and the reports of
the files that finished are still published, instead of the whole job dying at the
workflow's 20 minute limit with nothing reported.
Configuration
All modules read from environment variables (see .env.example):
FLOCI_ENDPOINT=http://localhost:4566
AWS_ACCESS_KEY_ID=test
AWS_SECRET_ACCESS_KEY=test
AWS_DEFAULT_REGION=us-east-1
Running with Docker
Each module includes a Dockerfile for isolated execution:
# Python
docker build -t floci-sdk-python sdk-test-python/
docker run --rm --network host floci-sdk-python pytest
# TypeScript
docker build -t floci-sdk-node sdk-test-node/
docker run --rm --network host floci-sdk-node npm test
On macOS/Windows, use host.docker.internal instead of localhost:
docker run --rm -e FLOCI_ENDPOINT=http://host.docker.internal:4566 floci-sdk-python pytest
Exit Codes
All test runners exit 0 on full pass and non-zero if any test fails — suitable for CI pipelines.