Skip to content

feat(conformance): measure AWS Batch; fix the gaps the probe found - #2739

Merged
vieiralucas merged 7 commits into
mainfrom
batch-conformance
Oct 18, 2026
Merged

vieiralucas merged 7 commits into
mainfrom
batch-conformance

Conversation

@vieiralucas

@vieiralucas vieiralucas commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

Summary

AWS Batch shipped in June (fakecloud-batch, 45 ops, registered in the server) but aws-models/service-map.json had no batch entry, so the conformance sweep never loaded its model. Batch was missing from conformance-baseline.json, the parity matrix and every headline count, while the site claimed true 100% across every implemented service. #2740 flagged it in the gate as PENDING_PARITY_ROW; this lands the row and empties that list.

  • Probe wiring: batch in service-map.json, routed as restJson1 in service_detection.rs, 45 #[test_action] annotations in crates/fakecloud-conformance/tests/batch.rs, audit mapping in audit.rs.
  • Batch fixes surfaced by the 1,257 variants (1,230 passed on first probe):
    • CancelJob / TerminateJob require reason; RegisterJobDefinition requires type (container / multinode).
    • Tag operations parse the label with the shared ARN helper and reject an ARN that names no Batch resource; TagResource requires tags; deleting a compute environment, job queue or scheduling policy drops its tags.
    • computeEnvironmentOrder (required on JobQueueDetail) is stored at create (API + CloudFormation) and on update.
  • Termination is real (found in self-review): TerminateJob / CancelJob stop the job's ECS task(s), including an array job's children. Every background status writer (launch, retry relaunch, poll, dependency/consumable admission, terminal write) goes through one compare-and-set (live_job) under the write lock, so a stop that races a launch, a retry or a container exit is never undone, and a task launched for a job stopped meanwhile is stopped. Stops pass the caller's reason to ECS and run concurrently. (Out of scope here: an attempt that overruns its timeout is marked FAILED but its container is not stopped, as before; ECS rewrites a stopped task's stoppedReason to the container exit code.)
  • Baseline: batch 1,257/1,257; total 258,545/258,545.
  • Docs: Batch row (45 ops) in the parity matrix, supported-services, services index, llms.txt / llms-full.txt; headline counts cascade to 107 services, 7,657 operations. The GitHub repo description is synced after merge.

Test plan

  • fakecloud-conformance run --services batch: 1,257/1,257
  • fakecloud-conformance audit: batch 45/45, all 4,148 implemented actions covered
  • cargo test -p fakecloud-batch (40 tests; new: required inputs, tags only on existing resources, tags dropped on delete, stopped jobs never revived, array terminate stops children, computeEnvironmentOrder)
  • cargo test -p fakecloud-e2e --test batch_real_execution (Docker; new terminate_job_stops_the_running_container: no task left RUNNING, one STOPPED, and the job stays FAILED with the caller's reason past the point the container would have exited 0), --test batch --test cloudformation_batch --test cloudformation_batch_persistence
  • cargo test -p fakecloud-conformance --lib --test checksum_annotations --test batch
  • cargo +stable clippy -p fakecloud-batch -p fakecloud-cloudformation -p fakecloud-conformance -p fakecloud-e2e --all-targets -- -D warnings, cargo fmt --check
  • bash scripts/check-doc-counts.sh OK; operations index regenerated with no diff

AWS Batch shipped in June but `aws-models/service-map.json` had no `batch`
entry, so the conformance sweep never loaded its model: Batch was absent
from the baseline, the parity matrix and every headline count, while the
site claimed true 100% across every implemented service.

- Probe: map the model, route it as restJson1, add the 45 `#[test_action]`
  annotations and the audit mapping.
- Batch fixes surfaced by the 1,257 variants (1,230 passed before):
  - `CancelJob` / `TerminateJob` require `reason` (ClientException).
  - `RegisterJobDefinition` requires `type` and accepts only `container` /
    `multinode`.
  - Tag operations reject a `resourceArn` that is not a Batch ARN instead
    of tagging an arbitrary string.
  - `DescribeJobQueues` always returns the required
    `computeEnvironmentOrder` (empty for service-environment queues).
- Baseline: batch 1,257/1,257; total 258,545/258,545.
- Docs: Batch row in the parity matrix (45 ops) and service lists;
  headline counts cascade to 107 services, 7,598 operations.
…ources

Review follow-ups:

- TerminateJob / CancelJob now stop the job's ECS task (and an array
  job's children), and the status poller leaves a job the user stopped
  terminal instead of flipping it back to RUNNING and then SUCCEEDED
  when the container exits 0.
- Tag operations parse the label with the shared ARN helper (known
  partitions, any account format) and reject an ARN naming no Batch
  resource, so tags never attach to resources that do not exist;
  TagResource requires `tags`.
- Required inputs share `required_str`; `computeEnvironmentOrder` is
  stored at create (API and CloudFormation) and on update.
Every async status writer (launch, retry relaunch, poll, dependency and
consumable admission, terminal write) now goes through live_job under the
write lock, so a CancelJob/TerminateJob that races a launch or a container
exit is never undone; a task launched for a job stopped meanwhile is
stopped, and the poller stops its own task when the job was stopped (a
retry for a failed StopTask). TerminateJob stops tasks concurrently and
accepts an empty reason. Deleting a compute environment, job queue or
scheduling policy drops its tags.
…ces, 7,657 ops)

Batch row (45 ops) and entries in supported-services, the services index
and llms*.txt; headline counts cascade to 107 services, 7,657 operations
and 258,545/258,545 variants. PENDING_PARITY_ROW is now empty, and its
loop expands safely when empty under set -u on bash < 4.4.
- An attempt that overruns timeout.attemptDurationSeconds has its task
  stopped before the retry or the FAILED write.
- TerminateJob passes the caller's reason to StopTask; background stops
  use a fixed reason. Stops defer ECS's snapshot and persist once.
- A retry keeps the cluster its relaunch returned; a cancelled dependent
  job's waiter exits at once; one is_terminal predicate backs every
  terminal check.
- Docs: only TerminateJob stops a running container.
Cut back the last commit's scope: the timeout-path StopTask and the
poller's own re-stop are removed (the re-stop overwrote the caller's
StopTask reason and an exited task's real stop reason; the timeout stop
also fired on the poll cap and on lookup failures). TerminateJob still
stops the task, and a task launched for an already-stopped job is still
stopped. A retry records its cluster with its task, and the parity row's
data plane reads Partial (service jobs never execute).
TagResource now rejects an ARN naming no resource, as AWS does, so the
test creates a scheduling policy and tags its ARN instead.
@vieiralucas
vieiralucas merged commit 76c4e86 into main Oct 18, 2026
162 checks passed
@vieiralucas
vieiralucas deleted the batch-conformance branch October 18, 2026 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant