Skip to content

Commit 959fa23

Browse files
Merge #4248
4248: Move the contents of docs/Testing.md closer to the code r=dnadales a=dnadales This PR moves part of the content of `docs/Testing.md` to `scripts/prolog`, and the other part of the content is distributed among the relevant modules. TODO: - [ ] Ask `@nfrisby` where the right ThreadNet tests can be found (see TODOs in the prologue). Closes #4247 Co-authored-by: Damian Nadales <damian.only@gmail.com>
2 parents 79c7527 + e1a249c commit 959fa23

File tree

29 files changed

+593
-603
lines changed

29 files changed

+593
-603
lines changed

ouroboros-consensus-byron-test/test/Test/ThreadNet/DualByron.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
{-# OPTIONS_GHC -Wno-orphans #-}
77

8+
-- | This runs the Byron ledger and the Byron specification in lockstep,
9+
-- verifying that they agree at every point.
10+
--
811
module Test.ThreadNet.DualByron (tests) where
912

1013
import Control.Monad.Except

ouroboros-consensus-test/src/Test/Util/Serialisation/Golden.hs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,34 @@
1212
{-# LANGUAGE TypeApplications #-}
1313

1414
{-# OPTIONS_GHC -Wno-orphans #-}
15+
-- | Golden tests infrastructure.
16+
--
17+
-- Golden tests are implemented using
18+
-- __[tasty-golden](https://github.com/UnkindPartition/tasty-golden)__.
19+
--
20+
-- When adding a new golden test, running the test suite locally will generate
21+
-- the golden files. These files should be checked in as CI will fail if there
22+
-- are missing golden files.
23+
--
24+
-- Failing a golden test suite when the corresponding golden files are not found
25+
-- is done via the @--no-create@ flag, which surprisingly is opt-in. In our
26+
-- @nix@ infrastructure, this flag for CI is set in
27+
-- __[ouroboros-network.nix](/nix/ouroboros-network.nix)__:
28+
--
29+
-- > # Command-line options for test suites:
30+
-- > packages.ouroboros-consensus-byron-test.components.tests.test.testFlags =
31+
-- > lib.mkForce [ "-- >no-create" ];
32+
-- > packages.ouroboros-consensus-shelley-test.components.tests.test.testFlags =
33+
-- > lib.mkForce [ "-- >no-create" ];
34+
-- > packages.ouroboros-consensus-cardano-test.components.tests.test.testFlags =
35+
-- > lib.mkForce [ "-- >no-create" ];
36+
--
37+
-- In particular, if we introduce golden tests in different suites, we need to add
38+
-- a line in the nix configuration above similar to the previous ones, eg:
39+
--
40+
-- > packages.some-new-package.components.tests.test.testFlags =
41+
-- > lib.mkForce [ "-- >no-create" ];
42+
--
1543
module Test.Util.Serialisation.Golden (
1644
Examples (..)
1745
, Labelled

ouroboros-consensus-test/test-consensus/Test/Consensus/BlockchainTime/Simple.hs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,30 @@
1010
{-# LANGUAGE StandaloneDeriving #-}
1111
{-# LANGUAGE TypeFamilies #-}
1212
{-# LANGUAGE UndecidableInstances #-}
13-
13+
-- | Tests for the computation of blockchain time.
14+
--
15+
-- The @BlockchainTime@ in consensus used to be ubiquitous throughout the code
16+
-- base, but is now only used in one place: when we are checking if we should
17+
-- produce a block. It is a simple abstraction that returns the current slot
18+
-- number, /if it is known/ (it might be unknown of the current ledger state is
19+
-- too far behind the wallclock). In addition to the problem of the current slot
20+
-- being unknown, it must also deal with discontinuities in the system's
21+
-- wallclock: NTP might adjust the clock forward or backward, or, worse, the
22+
-- user might change their wallclock by a large amount. We don't try to deal
23+
-- with all of these cases:
24+
--
25+
-- * if the clock jumps forward (so we "skip slots") this is no problem
26+
-- * if the clock is moved back a small amount so that we are still in the same
27+
-- slot when we expected to be in the next, also okay
28+
-- * if the clock is moved back by more than that, so that the current slot
29+
-- would actually /decrease/, we throw an exception; it's then up to the user
30+
-- (or the wallet) to restart the node.
31+
--
32+
-- Since all our tests run in an IO simulator, we can test this by having the
33+
-- clock behave very erratically. We then compute (in a model) what we expect
34+
-- the behaviour of the @BlockchainTime@ to be given a specific erratic
35+
-- behaviour, and then verify that it matches the model.
36+
--
1437
module Test.Consensus.BlockchainTime.Simple (tests) where
1538

1639
import Control.Applicative (Alternative (..))

ouroboros-consensus-test/test-consensus/Test/Consensus/HardFork/History.hs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,22 @@
1111
{-# LANGUAGE StandaloneDeriving #-}
1212
{-# LANGUAGE TypeOperators #-}
1313

14+
-- | Hard fork history tests.
15+
--
16+
-- This is the more interesting test of the hard fork history. We construct a
17+
-- mock chain, consisting of events (events are roughly, but not quite,
18+
-- "blocks"). For every event we record its slot number, epoch number, wall
19+
-- clock, etc. Since we are constructing this chain as a whole, from genesis to
20+
-- its tip, constructing these events is trivial. We then split this chain in
21+
-- half, and construct a @Summary@ from the first half. We then use that summary
22+
-- to do conversions for any event on the chain. Since every event records all
23+
-- information, we can easily verify whether the answers we are getting back are
24+
-- correct. Moreover, since the summary is constructed from only the first part
25+
-- of the chain, but is used to do conversions across the entire chain, we
26+
-- verify that predictions about the "future" also work as correctly (including
27+
-- that the conversions say "outside range" if and only if the model expects
28+
-- them to be).
29+
--
1430
module Test.Consensus.HardFork.History (tests) where
1531

1632
import Control.Exception (throw)

ouroboros-consensus-test/test-consensus/Test/Consensus/HardFork/Summary.hs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@
77
{-# LANGUAGE ScopedTypeVariables #-}
88
{-# LANGUAGE StandaloneDeriving #-}
99

10+
-- | Tests for the hard fork summary.
11+
--
12+
-- This module verifies the property that /no matter how the summary is
13+
-- constructed/, as long as it satisfies its invariants, we should have
14+
-- roundtrip properties:
15+
--
16+
-- * Converting time to a slot and then back to time should be an identity
17+
-- (modulo the time spent in that slot).
18+
-- * Converting a slot to time and then back should be an identity.
19+
-- * Converting slot to an epoch and then back to a slot should be an identity
20+
-- (modulo the time spent in that epoch).
21+
-- * Converting an epoch to a slot and then back should be an identity.
22+
--
1023
module Test.Consensus.HardFork.Summary (tests) where
1124

1225
import Data.Time

ouroboros-consensus-test/test-consensus/Test/Consensus/Mempool.hs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,21 @@
99
{-# LANGUAGE ScopedTypeVariables #-}
1010

1111
{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
12+
-- | Property tests for the mempool.
13+
--
14+
-- The mempool collects transactions from downstream nodes, makes them
15+
-- available to upstream nodes, and of course provides the pool of transactions
16+
-- that we use when forging blocks.
17+
--
18+
-- These tests for the mempool are not model based, but instead check various
19+
-- simple properties and invariants, for instance:
20+
--
21+
-- * After adding valid transactions to the mempool, they can be retrieved.
22+
-- * Adding invalid transactions from the mempool will report them as invalid,
23+
-- and they are not added.
24+
-- * Transactions cannot be retrieved after they are removed.
25+
-- * The mempool capacity is not exceeded
26+
--
1227
module Test.Consensus.Mempool (tests) where
1328

1429
import Control.Exception (assert)

ouroboros-consensus-test/test-consensus/Test/Consensus/MiniProtocol/ChainSync/Client.hs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,22 @@
66
{-# LANGUAGE RecordWildCards #-}
77
{-# LANGUAGE ScopedTypeVariables #-}
88
{-# LANGUAGE TypeApplications #-}
9+
-- | Tests for the chain sync client.
10+
--
11+
-- The chain sync client is a stateful component that tracks the chain of an
12+
-- upstream peer. It validates the headers that it receives from the peer;
13+
-- validated headers are then reported to the block fetch client which will
14+
-- download them and offer them to the chain DB, which makes the final choice
15+
-- whether or not to adopt those blocks.
16+
--
17+
-- The tests mock a series of state changes of the up-stream node as well as the
18+
-- node's own state (the node's own state is relevant because if the node and the
19+
-- up-stream peer diverge too much we are not interested in their chain anymore,
20+
-- and we might not be able to validate their headers). We then check that the
21+
-- chain sync client is reporting the right exceptions if and only if we expect
22+
-- them to be thrown based on the mock state changes (exceptions such as
23+
-- "fork is deep", "up-stream node asked for an invalid rollback", etc.).
24+
--
925
module Test.Consensus.MiniProtocol.ChainSync.Client (tests) where
1026

1127
import Control.Monad.Class.MonadThrow (Handler (..), catches)

ouroboros-consensus-test/test-consensus/Test/Consensus/MiniProtocol/LocalStateQuery/Server.hs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33
{-# LANGUAGE ScopedTypeVariables #-}
44

55
{-# OPTIONS_GHC -Wno-orphans #-}
6+
-- | Tests for the local state query server.
7+
--
8+
-- The local state query protocol allows clients such as wallets to query the
9+
-- state of the ledger at any point within @k@ blocks from the tip. The test for
10+
-- this is quite minimal at present: it prepopulates a ledger DB with a bunch of
11+
-- blocks, and then verifies that requesting the ledger tip corresponding to the
12+
-- these blocks gives the right answers, and that asking for blocks not on the
13+
-- chain results in the right error message.
14+
--
15+
-- Note that the query protocol is abstract in the ledger, and the query
16+
-- /language/ we offer (the kinds of queries that can be asked) of course
17+
-- depends on the ledger. The tests use a mock ledger for this purpose.
18+
--
619
module Test.Consensus.MiniProtocol.LocalStateQuery.Server (tests) where
720

821
import Control.Tracer (nullTracer)

ouroboros-consensus-test/test-consensus/Test/Consensus/Node.hs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,22 @@
44
{-# LANGUAGE OverloadedStrings #-}
55
{-# LANGUAGE RankNTypes #-}
66
{-# LANGUAGE ScopedTypeVariables #-}
7+
-- | Tests for the DB marker and DB lock.
8+
--
9+
-- When the consensus layer is integrated into the main node, it provides two
10+
-- safe guards to avoid data loss and/or corruption:
11+
--
12+
-- * When the database is opened, it locks the database so that there can be no
13+
-- other processes trying to access it at the same time.
14+
-- * When we create a database directory, we place a "magic marker" in that
15+
-- directory. This allows us to distinguish the database directory from other
16+
-- directories, and avoids that we would try to "truncate" a "chain" in a
17+
-- directory which doesn't contain a DB at all (due to a misconfiguration),
18+
-- thereby potentially deleting a user's files.
19+
--
20+
-- This module contains a bunch of unit tests to make sure that these locks and
21+
-- markers are created correctly and behave as expected.
22+
--
723
module Test.Consensus.Node (tests) where
824

925
import Data.Bifunctor (second)

ouroboros-consensus-test/test-consensus/Test/Consensus/ResourceRegistry.hs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,24 @@
1313
{-# LANGUAGE StandaloneDeriving #-}
1414
{-# LANGUAGE TupleSections #-}
1515
{-# LANGUAGE TypeApplications #-}
16-
16+
-- | Tests for the resource registry
17+
--
18+
-- The resource registry is a component throughout the consensus layer that
19+
-- helps us keep track of resources and makes sure that all resources that we
20+
-- allocate are eventually also deallocated in the right order.
21+
--
22+
-- The tests for the registry are model based. The model records which resources
23+
-- we expect to be alive and which we expect to have been deallocated. The only
24+
-- resources we are modelling here are threads; the commands we then execute are
25+
--
26+
-- * Fork a thread from some other thread
27+
-- * Terminate a thread
28+
-- * Have a thread crash
29+
-- * Collect all live threads
30+
--
31+
-- We then verify that the resource registry behaves like the model, cleaning
32+
-- up resources as threads terminate or crash.
33+
--
1734
module Test.Consensus.ResourceRegistry (tests) where
1835

1936
import Prelude hiding (elem)

0 commit comments

Comments
 (0)