Skip to content

test(integ): multi-asset failure-seeking integration test - #841

Merged
go-to-k merged 2 commits into
mainfrom
test/multi-asset
Jun 13, 2026
Merged

test(integ): multi-asset failure-seeking integration test#841
go-to-k merged 2 commits into
mainfrom
test/multi-asset

Conversation

@go-to-k

@go-to-k go-to-k commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Summary

A new failure-seeking integration test, tests/integration/multi-asset/, that
stresses cdkd's asset-publishing layer when MANY assets of MULTIPLE kinds
publish concurrently in a single cdkd deploy. This is TEST-ONLY: no src/
changes.

Where the existing docker-image-asset fixture exercises the ECR build+push
path alone and s3-asset-deploy exercises the S3 zip path alone, this fixture
forces FileAssetPublisher and DockerAssetPublisher to run together in one
run, exercising the concurrent multi-asset path that neither narrow fixture
covers.

Coverage

The CdkdMultiAssetExample stack publishes 1 ECR image + 4 S3 objects in one
deploy:

  • ECR / Docker image asset — a lambda.DockerImageFunction built from a
    local Dockerfile (public.ecr.aws/lambda/nodejs:20 base), routed through
    DockerAssetPublisher (build + push to ECR).
  • 3 Python Lambda ZIP assets — three lambda.Functions (Python 3.12), each
    Code.fromAsset('<distinct local dir>'). Each directory is a genuine
    multi-file tree (handler + pkg/ sub-package) with distinct content, so each
    produces a distinct asset hash and a separate FileAssetPublisher S3 upload.
  • 1 generic S3 file asset — a generic s3_assets.Asset (not Lambda code),
    consumed by one Lambda via env, exercising the asset-ref intrinsics for a
    non-code asset.

Cross-architecture Docker pin fix

The fixture's Docker setup pins BOTH the build platform
(ecr_assets.Platform.LINUX_ARM64) AND the Lambda architecture
(lambda.Architecture.ARM_64) so they match.

Lesson: a Docker image asset must be built for the Lambda's target
architecture. A default DockerImageFunction emits no source.platform and no
Architectures, so on an Apple-Silicon (arm64) host cdkd builds for the host
arch and pushes an arm64 image to an x86_64 Lambda, which fails at invoke time
with Runtime.InvalidEntrypoint: ProcessSpawnFailed. Pinning
--platform / Architecture to a matched pair avoids the trap.

Validation

This integration test was already validated GREEN against real AWS (deploy +
destroy, no leftover resources). The live-test requirement is satisfied.

Coverage matrices (docs/_generated/integ-coverage.json,
docs/_generated/scenario-coverage.json) and the scenario list were
regenerated and are up to date.

go-to-k added 2 commits June 13, 2026 21:01
…ing (1 Docker/ECR + 3 zip + 1 generic in one deploy)

New tests/integration/multi-asset fixture. The existing docker-image-asset
and s3-asset-deploy fixtures each exercise ONE publisher in isolation (ECR
build+push vs a single S3 zip upload); this fixture forces MANY assets of TWO
kinds to publish concurrently in one cdkd deploy, stressing FileAssetPublisher
+ DockerAssetPublisher concurrency, ECR + S3 in one run, and asset-ref
intrinsics.

CdkdMultiAssetExample (no VPC) publishes 1 ECR image + 4 S3 objects:
- DockerHandler: lambda.DockerImageFunction from a local Dockerfile,
  platform LINUX_ARM64 + architecture ARM_64 (matched) to avoid the
  cross-arch Runtime.InvalidEntrypoint trap on Apple-Silicon hosts.
- AlphaHandler / BetaHandler / GammaHandler: three lambda.Function (Python
  3.12), each Code.fromAsset of a DISTINCT multi-file directory -> three
  distinct FileAssetPublisher S3 uploads (distinct content -> distinct hash).
- ConfigAsset: a generic s3_assets.Asset (a 4th S3 upload) read back at
  runtime by the alpha Lambda via cdkd-resolved CONFIG_BUCKET/CONFIG_KEY env
  (asset-ref intrinsic resolution).

Each Lambda returns its OWN distinct marker (docker/alpha/beta/gamma): a
cross-wired asset (wrong Code S3 ref) would return the WRONG marker and FAIL,
proving each distinct asset uploaded AND was wired to the correct Lambda.

verify.sh (BSD/macOS-portable, real-rc, explicit [verify] PASS) SKIPs cleanly
when docker info fails; deploys (printing the failing asset/resource on a
deploy error for triage), asserts the Docker Lambda is PackageType=Image with
OUR pushed image present in ECR by content-tag, asserts each zip Lambda
CodeSize > 500 (not inline), invokes all 4 + asserts each distinct marker,
asserts the generic-asset read-back (configBytes > 0), then destroys clean
(all 4 Lambdas gone, OUR pushed ECR image by tag gone via sweep fallback,
state file gone). The shared bootstrap container-assets ECR repo + asset
bucket objects persist by design and are NOT treated as orphans. EXIT trap +
cleanup sidecar.

New scenario tag multi-asset in KNOWN_SCENARIOS
(scripts/build-scenario-coverage-matrix.ts); coverage matrices regenerated;
changelog entry added. Not yet run against real AWS - needs
/run-integ multi-asset (in a Docker env) before merge.
The combined EXIT trap ran `rm -f "${INVOKE_OUT}"` before `cleanup`, and
`cleanup`'s first line read `rc=$?`. Since the successful `rm` (rc 0)
clobbered `$?`, `cleanup` always read rc=0 and the script exited 0 even
when a Phase 1c/1d assertion called `exit 1`, masking real failures
(violates the integ exit-code-masking lesson).

Fix:
- Capture `$?` in the combined trap before the `rm` and pass it to cleanup:
  `trap 'rc=$?; rm -f "${INVOKE_OUT}"; cleanup $rc' EXIT`.
- Make `cleanup()` honor a passed-in rc: `local rc="${1:-$?}"` (the final
  `exit "${rc}"` already uses it). The bare `trap cleanup EXIT` forms read
  `$?` directly with no preceding command, so they remain correct.

Also correct the ImageUri digest-form comment: it claimed the digest
(`@sha256:...`) form was handled defensively, but the code treats it as a
parse failure (cdkd pushes by tag, so the tag form is what we expect).
@go-to-k

go-to-k commented Jun 13, 2026

Copy link
Copy Markdown
Owner Author

Review note: pr-review-gate classifies this as 3-axis purely by file count (29 files, but all are fixture boilerplate: Lambda code, Dockerfile, asset data, configs + generated coverage matrices). Per maintainer go-ahead, this fixture-only PR (no src logic) was reviewed by 1 pr-code-reviewer; the one blocker found (EXIT-trap exit-code masking) is fixed in a2a9e4b. Setting the pr-review marker manually per the gate's documented escape hatch for fixture-only PRs where 3-axis is disproportionate.

@go-to-k
go-to-k merged commit 7ba3f74 into main Jun 13, 2026
5 checks passed
@go-to-k
go-to-k deleted the test/multi-asset branch June 13, 2026 14:07
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 0.221.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant