Skip to content

[CTC 2] Port genesis tests into new TestSuite data structure#1915

Merged
jasagredo merged 1 commit intomainfrom
ctc/test-suites
Apr 7, 2026
Merged

[CTC 2] Port genesis tests into new TestSuite data structure#1915
jasagredo merged 1 commit intomainfrom
ctc/test-suites

Conversation

@ninioArtillero
Copy link
Copy Markdown
Contributor

@ninioArtillero ninioArtillero commented Mar 5, 2026

The new ConformanceTest record contains fields for all data formerly used to run a test via forAllGenesisTest helper, plus other fields that adjust its evaluation as a test property on aTestTree. It is worth noting that a GenesisTest is more general than what its name suggests; it is the type representing the "Node-vs-Environment" or point schedule tests.

All such ConformanceTests are arranged in TestSuites, a data structure introduced with the goal of eventually exporting them as part of a new sublibrary for the Conformance Testing of Consensus (CTC) harness. This data structure is designed to optimize single test lookups, while retaining the necessary structure to be compiled back to a TestTree, in such a way that the introduced changes preserve the semantics of the ouroboros-consensus:test:consensus-diffusion-test test suite. Those, TestSuites lay out an interface between the internal property test execution and the up-coming CTC harness.

To accomplish this, a new TestKey data type is introduced in each module as a key for the locally defined TestSuite, such that each test in the module corresponds to a unique value (nullary constructor) of this type. This means that including a new test in a TestSuite requires the extension of TestKey by e.g. introducing a new data constructor. These TestKey types are aggregated into higher level key types (sums of other test key unary constructors) to reify the nested grouping of the original tasty TestTrees by combining them using mkTestSuite.

The new SmallKey constraint is morally equivalent to Universe.Class.Finite from the universe-base package, but includes a set of measures to prevent large finite types from instantiating it. The reason for this is that its allKeys method is used for the exhaustive construction of TestSuites via newTestSuite and mkTestSuite; as implemented, a TestSuite is a total map.

@ninioArtillero ninioArtillero force-pushed the ctc/test-suites branch 2 times, most recently from f31b469 to 5e10769 Compare March 5, 2026 15:20
@ninioArtillero ninioArtillero marked this pull request as ready for review March 5, 2026 15:34
@ninioArtillero ninioArtillero changed the title Reify and port genesis tests into new TestSuite data structure [CTC 2] Reify and port genesis tests into new TestSuite data structure Mar 5, 2026
@ninioArtillero ninioArtillero changed the title [CTC 2] Reify and port genesis tests into new TestSuite data structure [CTC 2] Port genesis tests into new TestSuite data structure Mar 5, 2026
@ninioArtillero
Copy link
Copy Markdown
Contributor Author

ninioArtillero commented Mar 5, 2026

Added the no changelog tag, as it was done for #1879, given that this PR introduces no visible changes. Is this ok, or should we add a fragment because in this case we introduce a new dependency on monoidal-containers?

Copy link
Copy Markdown
Member

@dnadales dnadales left a comment

Choose a reason for hiding this comment

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

My biggest concern is the use of SmallKey and the complexity that it brings vs the actual safety it provides.

Comment thread ouroboros-consensus-diffusion/test/consensus-test/Test/Consensus/Genesis/Setup.hs Outdated
Comment thread ouroboros-consensus-diffusion/test/consensus-test/Test/Consensus/Genesis/Setup.hs Outdated
Comment thread ouroboros-consensus-diffusion/test/consensus-test/Test/Consensus/Genesis/Setup.hs Outdated
Comment thread ouroboros-consensus.cabal Outdated
@ninioArtillero ninioArtillero force-pushed the ctc/test-suites branch 3 times, most recently from 6b502ca to 8f68873 Compare March 24, 2026 22:27
@ninioArtillero
Copy link
Copy Markdown
Contributor Author

@dnadales The pending comments have been resolved and the proposed changes done, most notably:

  • Refactored the SmallKey instance tests and added the suggested cases.
  • Extended SmallKey docstring to be more specific to the use case.

I did also proposed changing the GenesisTest type name to either PointScheduleTest or NodeVsEnvTest to better clarify their role, but decided this is better left for a separate PR; possibly bundled along with some re-organization of the module structure for the new library we intend to expose (we can discuss the specifics of this later on).

Furthermore, the history has been cleaned-up back to a single commit, tests pass locally, a CI error from a missing LedgerSupportsPeras constraint has been fixed, and the PR was rebased onto current main. Please let me know if further changes are required.

Copy link
Copy Markdown
Contributor

@jasagredo jasagredo left a comment

Choose a reason for hiding this comment

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

The transformation looks consistent. There is a bunch of code to reify the test-suite which looks fine and the mkConformanceTest is basically a re-shaping of what was there before. I think this looks good, however I have a bunch of comments I would like to clarify or suggest, but I am open to debate them.

Comment on lines +62 to +68
data TestKey
= WithNoAdversariesAndOneScheduleForAllPeers
| WithNoAdversariesAndOneSchedulePerHonestPeer
| WithAdversariesAndOneScheduleForAllPeers
| WithAdversariesAndOneSchedulePerHonestPeer
deriving stock (Eq, Ord, Generic)
deriving SmallKey via Generically TestKey
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It might be interesting to create a TH splice that defines this datatype by grouping all the functions with a specific pattern like

test_withNoAdversariesAndOneScheduleForAllPeers :: ...
test_withNoAdversariesAndOneSchedulePerHonestPeer :: ...

return []
tests = $mkTests

But that would be a nice to have and I don't even know how to do this myself.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Very much like quickCheckAll

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't know how to do it either 😅 , and can just wonder about how much complexity would it introduce. Such an automation seems pretty desirable, but the cognitive burden of a naming convention seems to be a slight improvement over that of adding a constructor per test (and have the compiler ensure the test is included) IMO.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I can advise on doing this later down the line if we're so inclined

Comment thread ouroboros-consensus-diffusion/test/consensus-test/Test/Consensus/Genesis/Setup.hs Outdated
The new `ConformanceTest` record contains fields for all data formerly used
to run a test via `forAllGenesisTest` helper, plus other fields that pertain
to its evaluation as a test property on a`TestTree`.
A value of this type is defined for each point-schedule/genesis test.

All such `ConformanceTest`s are arranged in a `TestSuite`s, a data
structure introduced with the goal of eventually exporting them as
part of a new sublibrary for the Conformance Testing of Consensus harness
(see https://github.com/tweag/cardano-conformance-testing-of-consensus).
This data structure is designed to optimize single test lookups,
while retaining the necessary structure to be compiled back to a `TestTree`,
so that the introduced changes preserve the semantics of the
`ouroboros-consensus:test:consensus-diffusion-test` test suite.

To accomplish this, a new data type is introduced in each module as a `key`
for the locally defined `TestSuite`, such that each test in the module
corresponds to a unique value (nullary constructor) of this type. This means
that including a new test in a `TestSuite` requires the extension of such key
type by introducing a new data constructor. These `key` types are aggregated
into higher level key types to reify the nested grouping of the original
tasty `TestTree`s. It is by means of `mkTestSuite` and `at` that a higher
level `TestSuite` can be defined. The `SmallKey key` constraint is needed for
their exhaustive construction, via `newTestSuite` and `mkTestSuite`; as
implemented, a `TestSuite` is a total map.

Co-authored-by: Sandy Maguire <sandy.maguire@tweag.io>
@jasagredo jasagredo merged commit 4414e10 into main Apr 7, 2026
29 of 30 checks passed
@jasagredo jasagredo deleted the ctc/test-suites branch April 7, 2026 07:04
ninioArtillero added a commit to tweag/ouroboros-consensus-testing that referenced this pull request Apr 7, 2026
Backports from
IntersectMBO/ouroboros-consensus#1915

- Documentation updates + fixes
- `newtypes` for adjustment fields of `ConformanceTest`:
`AdjustTestCount` and `AdjustMaxSize`
- Introduced `getAllKeys` function to hide the `SmallKey` class method
`allKeys`
- Blacklisted more big type `SmallKey` instances (`Int`s, `Word`s and
`Text`).
- Refactored `SmallKey` tests to extend case variety
- Recovered the former `TestTree` structure inside the `CSJ.testSuite`
   - Added `grouping` combinator to `TestSuite.hs`
- Changed snake_case `ConformanceTest`s names to camelCase
- Removed use of `RecordWildCards` in `Genesis.Setup.hs`
- Added version bound to `monoidal-containers`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants