Skip to content

Serialization.V2: integration proof suite (remoting, persistence, Delivery, DData) - #8407

Closed
Aaronontheweb wants to merge 3 commits into
akkadotnet:devfrom
Aaronontheweb:feature/serialization-v2-integration-proofs
Closed

Aaronontheweb wants to merge 3 commits into
akkadotnet:devfrom
Aaronontheweb:feature/serialization-v2-integration-proofs

Conversation

@Aaronontheweb

@Aaronontheweb Aaronontheweb commented Jul 18, 2026 •

Copy link
Copy Markdown
Member

Serialization.V2 integration proof suite

Implements openspec tasks 6.4–6.6, 6.9–6.10, 8.5–8.6 of messagepack-sourcegen-validation: proves source-generated V2 serializers work end-to-end through real Akka machinery, not just unit round-trips. Tests only — zero product code changed. Headline result: no product gaps found — every integration point worked against the generated serializers without a single workaround.

Coverage

Task Proof Spec
6.4 Classic (non-Artery) remoting round-trip between two ActorSystems, dynamic ports Akka.Serialization.V2.Tests/ClassicRemotingSpec.cs
6.5 V2 event persisted + recovered through a genuinely-serializing journal Akka.Serialization.V2.Tests/PersistenceIntegrationSpec.cs
6.6 V2 snapshot saved + loaded through the real LocalSnapshotStore file plugin same file
6.9 ReliableDeliverySerializer wrapper + live ProducerController/ConsumerController exchange under serialize-messages = on Akka.Cluster.Tests/ReliableDeliveryIntegrationSpec.cs
6.10 DData ReplicatedDataSerializer wrapper interaction Akka.DistributedData.Tests/Serialization/GeneratedV2WrapperSpec.cs
8.5/8.6 Focused Remote/Persistence verification runs above specs, 2/2 each

Notable test-integrity decision

The built-in akka.persistence.journal.inmem (MemoryJournal) stores live object references and never serializes — an event round-trip "proof" through it would be a no-op. The event test instead uses a small test-only WireFormatJournal that does what real journal plugins do (FindSerializerFor → ToBinary/FromBinary, storing only bytes + manifest + serializer ID), documented inline. Snapshots use the real shipped LocalSnapshotStore, which already round-trips through actual serialization.

Placement

The Delivery/DData wrapper specs live in Akka.Cluster.Tests / Akka.DistributedData.Tests (those serializers are internal to those assemblies); the projects gained lightweight test-only ProjectReferences to Akka.Serialization.V2 — no shipping dependency changes anywhere.

Verification

  • Akka.Serialization.V2.Tests: 260/260 (256 pre-existing + 4 new), stable across repeated runs
  • Akka.Cluster.Tests: full suite 381/381; Akka.DistributedData.Tests: 192 passed / 1 pre-existing unrelated skip
  • dotnet format + -warnaserror clean on touched projects
  • Openspec tasks checked off with citations in messagepack-sourcegen-validation/tasks.md

Note for reviewers: the branch history contains a mid-flight port commit — the specs were originally authored against a stale base that predated the #8385 attribute-surface reshape; they are fully ported to the current [AkkaSerializer<TProtocol>(name, id)] / AkkaSerializer surface and validated against current dev.

…e, delivery, DData (tasks 6.4-6.10, 8.5-8.6)

Implements the remaining openspec integration-validation tasks from
messagepack-sourcegen-validation/tasks.md: source-generated V2 MessagePack
serializers now have end-to-end proof through real Akka.NET machinery, not
just direct Serialization.cs round-trips.

- ClassicRemotingSpec (Akka.Serialization.V2.Tests): two independent
  ActorSystems exchange generated V2 payloads over classic
  akka.remote.dot-netty.tcp, HOCON-registered the same way
  ArteryControlMessageSerializer is registered in Remote.conf. Covers a
  scalar+IActorRef payload and a nested-value-object payload. (task 6.4)

- PersistenceIntegrationSpec (Akka.Serialization.V2.Tests): events persist
  and recover through a small test-only WireFormatJournal that genuinely
  serializes bytes via Serialization.FindSerializerFor/ToBinary/FromBinary
  (the built-in in-memory journal holds live object references and would
  prove nothing about the wire format); snapshots save and load through the
  real, shipped akka.persistence.snapshot-store.local plugin. (tasks 6.5, 6.6)

- ReliableDeliveryIntegrationSpec (Akka.Cluster.Tests): a generated V2
  payload survives the real (internal) ReliableDeliverySerializer wrapper
  via ConsumerController.SequencedMessage<T>, plus a live
  ProducerController/ConsumerController exchange under
  serialize-messages=on. (task 6.9)

- GeneratedV2WrapperSpec (Akka.DistributedData.Tests): a generated V2
  payload survives ReplicatedDataSerializer's OtherMessage wrapper as both
  an LWWRegister<T> value and ORSet<T> elements. (task 6.10)

Tasks 8.5/8.6 (focused Remote/Persistence generated-serializer test runs)
are satisfied by the above specs.

Placement: ReliableDeliverySerializer and ReplicatedDataSerializer are
production wrappers that live in Akka.Cluster / Akka.DistributedData, so
those two specs live in their existing test projects (with new test-only
ProjectReferences to Akka.Serialization.V2) rather than pulling
Akka.Cluster/Akka.DistributedData into Akka.Serialization.V2.Tests.
Classic remoting and persistence specs live in Akka.Serialization.V2.Tests
per the task brief, with new test-only ProjectReferences to Akka.Remote and
Akka.Persistence. No product code (generator or V2 runtime) was touched.

Verification: full suites pass with no regressions -
Akka.Serialization.V2.Tests 110/110, Akka.Cluster.Tests 381/381,
Akka.DistributedData.Tests 192/193 (1 pre-existing unrelated skip). All new
remoting/persistence/delivery/DData specs were run multiple times with no
flakiness observed. dotnet format --verify-no-changes and
dotnet build -warnaserror both clean on all touched projects.
…net#8385+)

The worktree's original base (84524b3) predated the Akka.Serialization.V2
surface reshape that landed via PR akkadotnet#8385 and successors. After the
coordinator merged current dev into this branch, the four new integration
specs from the prior commit no longer compiled against the new surface:

- Attribute/base-class rename: `[AkkaSerializer(Name = ..., SerializerId = ...)]`
  + `MessagePackSerializer<TProtocol>` became the generic
  `[AkkaSerializer<TProtocol>("name", id)]` (positional, required args) +
  non-generic `AkkaSerializer` base class. `CreateRegistration()` partial
  method declarations were unaffected. Fixed in all four new files
  (ClassicRemotingSpec, PersistenceIntegrationSpec, ReliableDeliveryIntegrationSpec,
  GeneratedV2WrapperSpec).

- Type collision: dev's GeneratedUnionSpec.cs (new since the base commit)
  declares a top-level `Akka.Serialization.V2.Tests.OrderPlaced` record with
  manifest "order-placed-v1". PersistenceIntegrationSpec.cs declared its own
  `OrderPlaced`/`OrderState`, causing CS0101/CS0579/CS8863 and a knock-on
  AKKASG012 + CS0534 on the unrelated UnionTestSerializer (the duplicate
  symbol confused the generator's per-serializer manifest scan). Renamed to
  `PersistedOrderPlaced`/`PersistedOrderState` with distinct manifests
  ("persisted-order-placed-v1"/"persisted-order-state-v1"); confirmed no
  other identifier collisions exist against the merged tree (checked every
  type declared across all four new spec files).

Verification against the merged tree:
- dotnet test src/core/Akka.Serialization.V2.Tests -c Release: 260/260 passing
  (was 106 pre-merge baseline + our 4; merged dev tip's own baseline is 256,
  confirming the orchestrator's original "256 tests" figure referred to
  current dev, not the stale base this worktree started from).
- dotnet test src/core/Akka.Cluster.Tests --filter ReliableDeliveryIntegrationSpec: 2/2 passing.
- dotnet test src/contrib/cluster/Akka.DistributedData.Tests --filter GeneratedV2WrapperSpec: 2/2 passing.
- dotnet format --verify-no-changes: clean on all three touched projects.
- dotnet build -warnaserror: clean on Akka.Cluster.Tests and
  Akka.DistributedData.Tests. Akka.Serialization.V2.Tests only fails
  -warnaserror when built as a standalone .csproj outside solution context,
  because the Verify package's build props can't auto-discover SolutionDir/
  SolutionName from a project 3 directories below the repo root (its search
  only walks 2 parents) and downgrades that to a real warning under
  -warnaserror; this is pre-existing since dev's wire-format-snapshot Verify
  tests (86976dd), reproducible on an unmodified file in that project, and
  resolves cleanly once SolutionDir/SolutionName are supplied (confirmed with
  explicit /p:SolutionDir/SolutionName, matching how CI builds via the
  solution) -- not something introduced by or fixable in these test files.

All new specs re-run twice post-fix with no flakiness. No product code
(generator or V2 runtime) touched.
@Aaronontheweb

Copy link
Copy Markdown
Member Author

Plan for this PR: harvest its WireFormatJournal test journal and its live ProducerController/ConsumerController Delivery spec into the Serialization V2 work, then close it. Issue #8714 (V2 port test kit) carries the harvested pieces. Tracked under #8675.

@Aaronontheweb

Copy link
Copy Markdown
Member Author

Closing without merging. The V2 port test kit (#8725) covers what this suite proved with golden-bytes tests (V2 and legacy bytes per manifest) and a mixed-binding round trip, so nothing from here is carried over. Part of #8675.

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