Skip to content

Commit 99097c7

Browse files
committed
tx-submission: refactored test
Use `IOSim` API. `evaluateTrace` from `Test.Ouroboros.Network.LedgerPeers` has the annoying property that once the trace was evaluated in won't show the trace again, which makes it hard to work with `cabal repl`. Refactored `checkMempools` to improve readablity. Should be squashed onto `c9d45673ca New txSubmissionV2 simulation`
1 parent 2541e95 commit 99097c7

File tree

1 file changed

+74
-55
lines changed

1 file changed

+74
-55
lines changed

ouroboros-network/sim-tests-lib/Test/Ouroboros/Network/TxSubmission/TxSubmissionV2.hs

Lines changed: 74 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import Prelude hiding (seq)
1919
import NoThunks.Class
2020

2121
import Control.Concurrent.Class.MonadMVar (MonadMVar)
22-
import Control.Concurrent.Class.MonadSTM
22+
import Control.Concurrent.Class.MonadSTM.Strict
2323
import Control.Monad.Class.MonadAsync
2424
import Control.Monad.Class.MonadFork
2525
import Control.Monad.Class.MonadSay
@@ -34,7 +34,7 @@ import Control.Tracer (Tracer (..), contramap)
3434
import Data.ByteString.Lazy (ByteString)
3535
import Data.ByteString.Lazy qualified as BSL
3636
import Data.Function (on)
37-
import Data.List (intercalate, nubBy)
37+
import Data.List (nubBy)
3838
import Data.Map.Strict (Map)
3939
import Data.Map.Strict qualified as Map
4040
import Data.Maybe (fromMaybe)
@@ -59,7 +59,6 @@ import Test.Tasty (TestTree, testGroup)
5959
import Test.Tasty.QuickCheck (testProperty)
6060

6161
import Control.Concurrent.Class.MonadMVar.Strict qualified as Strict
62-
import Control.Concurrent.Class.MonadSTM.Strict (StrictTVar)
6362
import Control.Concurrent.Class.MonadSTM.Strict qualified as Strict
6463
import Control.Monad (forM)
6564
import Data.Foldable (traverse_)
@@ -287,49 +286,58 @@ txSubmissionV2Simulation (TxSubmissionV2State state txDecisionPolicy) = do
287286
--
288287
prop_txSubmission :: TxSubmissionV2State -> Property
289288
prop_txSubmission st =
290-
ioProperty $ do
291-
tr' <- evaluateTrace (runSimTrace (txSubmissionV2Simulation st))
292-
case tr' of
293-
SimException e trace -> do
294-
return $ counterexample (intercalate "\n" $ show e : trace) False
295-
SimDeadLock trace -> do
296-
return $ counterexample (intercalate "\n" $ "Deadlock" : trace) False
297-
SimReturn (inmp, outmps) _trace -> do
298-
r <- mapM (\outmp -> do
299-
let outUniqueTxIds = nubBy (on (==) getTxId) outmp
300-
outValidTxs = filter getTxValid outmp
301-
case ( length outUniqueTxIds == length outmp
302-
, length outValidTxs == length outmp
303-
) of
304-
(True, True) ->
305-
-- If we are presented with a stream of unique txids for valid
306-
-- transactions the inbound transactions should match the outbound
307-
-- transactions exactly.
308-
return $ counterexample ("(True, True) " ++ show outmp)
309-
$ checkMempools inmp (take (length inmp) outValidTxs)
310-
311-
(True, False) ->
312-
-- If we are presented with a stream of unique txids then we should have
313-
-- fetched all valid transactions.
314-
return $ counterexample ("(True, False) " ++ show outmp)
315-
$ checkMempools inmp (take (length inmp) outValidTxs)
316-
317-
(False, True) ->
318-
-- If we are presented with a stream of valid txids then we should have
319-
-- fetched some version of those transactions.
320-
return $ counterexample ("(False, True) " ++ show outmp)
321-
$ checkMempools (map getTxId inmp)
322-
(take (length inmp)
323-
(map getTxId $ filter getTxValid outUniqueTxIds))
324-
325-
(False, False) ->
326-
-- If we are presented with a stream of valid and invalid Txs with
327-
-- duplicate txids we're content with completing the protocol
328-
-- without error.
329-
return $ property True)
330-
outmps
331-
return $ counterexample (intercalate "\n" _trace)
332-
$ conjoin r
289+
let tr = runSimTrace (txSubmissionV2Simulation st) in
290+
case traceResult True tr of
291+
Left e ->
292+
counterexample (show e)
293+
. counterexample (ppTrace tr)
294+
$ False
295+
Right (inmp, outmps) ->
296+
counterexample (ppTrace tr)
297+
$ conjoin (validate inmp `map` outmps)
298+
where
299+
validate :: [Tx Int] -- the inbound mempool
300+
-> [Tx Int] -- one of the outbound mempools
301+
-> Property
302+
validate inmp outmp =
303+
let outUniqueTxIds = nubBy (on (==) getTxId) outmp
304+
outValidTxs = filter getTxValid outmp
305+
in
306+
case ( length outUniqueTxIds == length outmp
307+
, length outValidTxs == length outmp
308+
) of
309+
x@(True, True) ->
310+
-- If we are presented with a stream of unique txids for valid
311+
-- transactions the inbound transactions should match the outbound
312+
-- transactions exactly.
313+
counterexample (show x)
314+
. counterexample (show inmp)
315+
. counterexample (show outmp)
316+
$ checkMempools inmp (take (length inmp) outValidTxs)
317+
318+
x@(True, False) ->
319+
-- If we are presented with a stream of unique txids then we should have
320+
-- fetched all valid transactions.
321+
counterexample (show x)
322+
. counterexample (show inmp)
323+
. counterexample (show outmp)
324+
$ checkMempools inmp (take (length inmp) outValidTxs)
325+
326+
x@(False, True) ->
327+
-- If we are presented with a stream of valid txids then we should have
328+
-- fetched some version of those transactions.
329+
counterexample (show x)
330+
. counterexample (show inmp)
331+
. counterexample (show outmp)
332+
$ checkMempools (map getTxId inmp)
333+
(take (length inmp)
334+
(map getTxId $ filter getTxValid outUniqueTxIds))
335+
336+
(False, False) ->
337+
-- If we are presented with a stream of valid and invalid Txs with
338+
-- duplicate txids we're content with completing the protocol
339+
-- without error.
340+
property True
333341

334342
-- | This test checks that all txs are downloaded from all available peers if
335343
-- available.
@@ -371,15 +379,26 @@ prop_txSubmission_inflight st@(TxSubmissionV2State state _) =
371379
inmp
372380
in resultRepeatedValidTxs === maxRepeatedValidTxs
373381

374-
checkMempools :: (Eq a, Show a) => [a] -> [a] -> Property
375-
checkMempools [] [] = property True
376-
checkMempools _ [] = property True
377-
checkMempools [] _ = property False
378-
checkMempools inp@(i : is) outp@(o : os) =
379-
if o == i then counterexample (show inp ++ " " ++ show outp)
380-
$ checkMempools is os
381-
else counterexample (show inp ++ " " ++ show outp)
382-
$ checkMempools is outp
382+
383+
-- | Check that the inbound mempool contains all outbound `tx`s as a proper
384+
-- subsequence. It might contain more `tx`s from other peers.
385+
--
386+
checkMempools :: Eq tx
387+
=> [tx] -- inbound mempool
388+
-> [tx] -- outbound mempool
389+
-> Bool
390+
checkMempools _ [] = True -- all outbound `tx` were found in the inbound
391+
-- mempool
392+
checkMempools [] (_:_) = False -- outbound mempool contains `tx`s which were
393+
-- not transferred to the inbound mempool
394+
checkMempools (i : is') os@(o : os')
395+
| i == o
396+
= checkMempools is' os'
397+
398+
| otherwise
399+
-- `_i` is not present in the outbound mempool, we can skip it.
400+
= checkMempools is' os
401+
383402

384403
-- | Split a list into sub list of at most `n` elements.
385404
--

0 commit comments

Comments
 (0)