Skip to content

Add Flat encoding test coverage across all packages#7678

Open
Unisay wants to merge 2 commits intomasterfrom
yura/flat-test-coverage
Open

Add Flat encoding test coverage across all packages#7678
Unisay wants to merge 2 commits intomasterfrom
yura/flat-test-coverage

Conversation

@Unisay
Copy link
Contributor

@Unisay Unisay commented Mar 18, 2026

Context

  • What: Add roundtrip and stable byte encoding tests for every Flat instance across all packages
  • Why: Pay down test coverage debt before attempting to fix the Generic Flat derivation bug (512+ constructor crash). Encoding stability must be verified by tests first.
  • Related: Preparatory work for fixing the Generic derivation bug discussed in Remove Generic-based Flat derivation machinery #7662

Approach

Added two categories of tests for Flat instances:

  1. Stable byte encoding tests (a.k.a. golden/characterization tests) pin the exact byte representation of on-chain-critical types (Version, DeBruijn, DefaultFun, DefaultUni, Binder variants, UPLC Program, PIR Recursivity/Strictness). These detect any accidental encoding changes that would break on-chain script compatibility.

  2. Roundtrip property tests verify unflat (flat x) == Right x for all Flat instances including library-internal types (monoid/semigroup wrappers, containers, etc.) where encoding stability is less critical but correctness still matters.

A standalone encoding generator executable (cabal run flat-encoding-generator) is included so anyone can reproduce the expected byte constants without GHCi sessions. It regenerates test fixtures from source so they don't remain opaque blobs of bits.

BLS12_381 types are deliberately skipped (their encode/decode implementations are error/fail).

Changes

Flat library tests (flat/test/Spec.hs)

  • Stable byte encoding tests for: Maybe, Either, NonEmpty, Complex, Ratio, Set, Tree, Map, Seq, Filler, PreAligned
  • Roundtrip QC tests for: Tree, Set, Identity, All, Any, Dual, Sum, Product, Min, Max, First, Last, Alt, Fixed, PreAligned, String

TPLC tests (plutus-core/test/Flat/Spec.hs — new module)

  • Stable byte encoding for: Version, Name, Kind, DeBruijn, NamedDeBruijn, Index, SrcSpan, SrcSpans, DefaultFun (AddInteger, SubtractInteger), SomeTypeIn DefaultUniInteger
  • Roundtrip tests for: SrcSpan, SrcSpans, NamedDeBruijn, Version, Name, Kind
  • Newtype wrapper delegation tests: TyName, TyDeBruijn, NamedTyDeBruijn, FakeNamedDeBruijn

UPLC tests (untyped-plutus-core/testlib/Flat/Spec.hs)

  • Binder stable encoding: zero-cost verification for Binder DeBruijn and Binder FakeNamedDeBruijn, delegation checks for Binder Name/TyName/NamedDeBruijn/NamedTyDeBruijn
  • Binder newtype roundtrip tests
  • Minimal UPLC Program roundtrip and stable byte test: (program 1.1.0 (con integer 0))
  • Wired test_flat into the UPLC test entry point (was previously defined but not imported)

PIR tests (plutus-ir/test/PlutusIR/Core/Tests.hs)

  • Stable byte encoding for Recursivity (NonRec/Rec) and Strictness (NonStrict/Strict)

Value tests (plutus-core/test/Value/Spec.hs)

  • K encodes identically to ByteString
  • Quantity encodes identically to Integer

Infrastructure

  • Encoding generator executable (plutus-core/tools/GenerateEncodings.hs)
  • Added FOURMOLU_DISABLE to flat/test/Spec.hs (CPP-heavy file that fourmolu cannot parse)

@Unisay Unisay self-assigned this Mar 18, 2026
@Unisay Unisay requested a review from zliu41 March 18, 2026 17:14
-- | Stable byte encoding tests for flat library container/composite types.
-- Wrapper types (Identity, All, Any, Dual, etc.) only have roundtrip tests
-- since their encoding stability is not critical (they are never on-chain).
testNewEncodings = testGroup "stable byte encodings"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are not introducing any new encodings, so this should just be called "testEncodings"

Copy link
Contributor Author

@Unisay Unisay Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to testEncodingStability. Tell me if you have another idea of a better name.

-- | Reproducible encoding generator for Flat test coverage.
-- Run: cabal run flat-encoding-generator
-- Prints expected byte sequences for all Flat test values.
executable flat-encoding-generator
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of this, and in what scenario would someone want to use this executable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replied by changing the code comment:

-- Golden file generator for Flat encoding stability tests.
--
-- The encoding stability tests compare encoded values against expected
-- byte sequences captured as test fixtures. This tool regenerates those
-- fixtures from source, so they don't remain opaque blobs of bits.
--
-- Example: if a bug in a Flat instance is found and the encoding must
-- change in a backward-incompatible way, the stability tests will fail.
-- Run this tool to see the new wire format, update the test fixtures,
-- and confirm the encoding change was intentional.
--
-- See: https://en.wikipedia.org/wiki/Characterization_test
-- Usage: cabal run flat-encoding-generator


ghc-options:
-Wno-missing-signatures -Wno-missing-deriving-strategies
-Wno-unused-packages
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need these flags? Can you just fix the warnings?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, I just copied these from the vendored flat and flat-test stanzas without thinking. Removed them; none were actually needed here.

The vendored code itself still has a bunch of these (flat-test alone has 10). All inherited from the original upstream style. Happy to clean those up too, though that's probably a separate PR since it touches vendored code. Worth it?

@Unisay Unisay force-pushed the yura/flat-test-coverage branch from b8964e3 to 6cdd889 Compare March 20, 2026 11:52
@Unisay Unisay requested a review from zliu41 March 20, 2026 11:52
@Unisay Unisay force-pushed the yura/flat-test-coverage branch from 6cdd889 to 0aad87c Compare March 20, 2026 14:10
Unisay added 2 commits March 20, 2026 17:05
Pay down test coverage debt for Flat serialization instances.
This ensures encoding stability is verified by tests before
we attempt to fix the Generic derivation bug in a follow-up PR.

Adds roundtrip and stable byte encoding tests for:
- Flat library types (Maybe, Either, NonEmpty, Complex, Ratio,
  Set, Tree, Map, Seq, DList, Filler, PreAligned, and
  monoid/semigroup wrappers)
- TPLC types (Version, Name, Kind, DeBruijn, NamedDeBruijn,
  SrcSpan, SrcSpans, DefaultFun, DefaultUni, and all newtype
  wrappers including TyName, Unique, TyDeBruijn, etc.)
- PIR types (Recursivity, Strictness)
- UPLC types (Binder variants, FakeNamedDeBruijn, minimal
  Program encoding)
- Value types (K encodes as ByteString, Quantity as Integer)

Also adds a standalone encoding generator executable
(cabal run flat-encoding-generator) for reproducing expected
byte constants.
Rename testNewEncodings to testEncodingStability for clarity.
Fix plutus-core ^>=1.59 version bound to ^>=1.60. Remove
unnecessary -Wno-* flags and unused text dependency from
flat-encoding-generator. Improve executable comment with
golden testing context and Wikipedia reference.
@Unisay Unisay force-pushed the yura/flat-test-coverage branch from 0aad87c to d3cc240 Compare March 20, 2026 16:06
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