Skip to content

Stabilize workflow fixture assertions#362

Merged
rmcdaniel merged 1 commit intomasterfrom
fix/test-flake
Mar 24, 2026
Merged

Stabilize workflow fixture assertions#362
rmcdaniel merged 1 commit intomasterfrom
fix/test-flake

Conversation

@rmcdaniel
Copy link
Copy Markdown
Member

Summary

  • replace assertion-driven workflow fixture checks with explicit AssertionError guards so test behavior does not depend on PHP assert settings
  • keep the runningInConsole() preconditions explicit in test fixtures instead of letting them disappear when assertions are disabled
  • update WorkflowTest::testCompletedDelay() to expect the deterministic TestWorkflow side-effect log entry

Testing

  • composer feature -- --filter AsyncWorkflowTest
  • vendor/bin/phpunit --testdox --testsuite feature --filter '^Tests\\Feature\\WorkflowTest(::.*)?$'
  • composer unit -- --filter WorkflowStubTest

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (68e47cd) to head (537389f).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff             @@
##              master      #362   +/-   ##
===========================================
  Coverage     100.00%   100.00%           
  Complexity       579       579           
===========================================
  Files             62        62           
  Lines           2007      2007           
===========================================
  Hits            2007      2007           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@rmcdaniel rmcdaniel merged commit a8f4e97 into master Mar 24, 2026
3 checks passed
@rmcdaniel rmcdaniel deleted the fix/test-flake branch March 24, 2026 02:32
rmcdaniel pushed a commit that referenced this pull request Apr 17, 2026
Command and update payload previews rendered in RunDetailView,
HistoryTimeline, and RunUpdateView previously went through the legacy
Serializer::unserialize sniffer. The sniffer routes by first byte (base64
prefix → Base64, JSON markers → Json, otherwise → Y) and cannot detect
binary Avro blobs, so Avro-coded commands rendered as opaque base64
strings (or worse, as the failed Y-decoded garbage) in Waterline's
payload inspector and in the CLI's describe/history output.

Thread the persisted payload_codec through CommandPayloadPreview and
RunUpdateView::normalizeTypedValue so the stored codec is used for
decode when known. When codec is null (rows persisted before
payload_codec was populated), behavior is unchanged — both helpers still
fall through to the sniffer.

Advances acceptance criteria on the release-gating parity suite (#362):
"Waterline renders Avro payloads readably" and "CLI renders Avro
payloads readably" transitively inherit the fix through the shared
observability view helpers they already consume.

Decode failures in the preview helpers continue to fall back to the raw
blob rather than throwing — these are display helpers, not strict
decoders. Strict codec-mismatch detection remains at ingress
(PayloadEnvelopeResolver).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rmcdaniel pushed a commit that referenced this pull request Apr 17, 2026
… Avro export

Two pieces of the release-gating Avro parity surface:

1. Loud, typed codec-mismatch ingress errors

Add Workflow\Serializers\CodecDecodeException — a typed exception that
names the declared codec, what the decoder actually saw, and a
remediation hint. The Avro and Json codecs now throw it instead of a
generic RuntimeException when the bytes don't match the declared codec.

The ingress diagnosers cover the two most common cross-codec mistakes:
 - JSON bytes labeled `avro` (producer JSON-encoded but tagged it Avro)
 - Avro bytes labeled `json` (producer Avro-encoded but tagged it JSON)

In both cases the message names the codec, describes the symptom, and
tells the operator how to fix it ("change the codec tag to X" or
"re-encode the payload"). The wrapping ValidationException at the HTTP
ingress (PayloadEnvelopeResolver) preserves the typed message verbatim
so it shows up in API responses without losing context.

Covers acceptance criteria from the issue:
 - "Sending JSON bytes under an `avro` codec tag produces a loud, typed
   error — not silent garbage"
 - "Sending Avro bytes under a `json` codec tag produces a loud, typed
   error"
 - "Avro decode failure names the codec, expected schema, and a
   remediation — not a generic RuntimeException"

2. Self-describing Avro history-export bundles

HistoryExport bundles now include a top-level `codec_schemas` map. When
the bundle contains any payload encoded with the Avro codec (whether on
the run, commands, updates, signals, or tasks), the map embeds the
generic-wrapper schema JSON plus the documented prefix bytes (0x00
generic wrapper, 0x01 typed schema). An offline consumer reading the
export — without the workflow runtime in scope — can decode the
0x00-prefixed Avro payloads using only the bundle.

Bundles with no Avro payloads keep `codec_schemas: {}` so the field is
always present and shape-stable, simplifying consumer code.

Tests: 7 new ingress-mismatch unit tests; 2 new HistoryExport tests
covering the Avro-present and Avro-absent codec_schemas cases. All 130
tests across the changed surface pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rmcdaniel pushed a commit that referenced this pull request Apr 17, 2026
Mixed-codec runs (JSON run payload with an Avro signal or update) could
previously produce history-export bundles where the update and signal
rows lacked their own payload_codec field. collectCodecSchemas() already
scanned those rows for Avro, so an Avro signal/update went undetected
and the offline consumer never got the avro wrapper schema.

- HistoryExport::update() and ::signal() now emit payload_codec alongside
  the encoded arguments/result, so codec_schemas detection and offline
  decode both see row-local codec metadata.
- Fix latent typo where update export read \$update->name instead of the
  real \$update->update_name column; the exported 'name' field was always
  null, including in redaction-context callbacks.
- Regression test asserts mixed-codec bundle carries row-local
  payload_codec and triggers codec_schemas.avro even when the run itself
  is JSON-coded. Existing full-snapshot test now asserts signal
  payload_codec round-trips.
rmcdaniel pushed a commit that referenced this pull request Apr 17, 2026
…rence

8 tests, 35 assertions covering:
- Start input round-trips under Avro with type fidelity
- Full workflow lifecycle: start -> activity -> signal -> complete
- Float/int fidelity (3.14 stays float, 42 stays int)
- Every payload row tagged avro (no json codec leaks)
- History export includes codec metadata
- Schema evolution: v1 payload decodes with v2 reader schema
- Negative: non-Avro bytes under avro tag produce typed errors
- JSON-tagged-as-avro gets diagnostic mentioning JSON

Documents generic wrapper limitation: integer-valued floats like
3.0 lose precision through json_encode (becomes 3). Typed Avro
schemas (#288) would fix this; generic wrapper does not.
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.

2 participants