Skip to content

Commit 0b4f00b

Browse files
committed
Test that uncommitted forkers do not leak handles
1 parent 002b71e commit 0b4f00b

File tree

2 files changed

+29
-12
lines changed

2 files changed

+29
-12
lines changed

ouroboros-consensus/ouroboros-consensus.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,7 @@ test-suite storage-test
742742
ouroboros-consensus,
743743
ouroboros-network-api,
744744
ouroboros-network-mock,
745+
ouroboros-network-protocols,
745746
pretty-show,
746747
quickcheck-dynamic,
747748
quickcheck-lockstep ^>=0.8,

ouroboros-consensus/test/storage-test/Test/Ouroboros/Storage/LedgerDB/StateMachine.hs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ import Ouroboros.Consensus.Util hiding (Some)
7272
import Ouroboros.Consensus.Util.Args
7373
import Ouroboros.Consensus.Util.IOLike
7474
import qualified Ouroboros.Network.AnchoredSeq as AS
75+
import Ouroboros.Network.Protocol.LocalStateQuery.Type
7576
import qualified System.Directory as Dir
7677
import System.FS.API
7778
import qualified System.FS.IO as FSIO
@@ -114,9 +115,11 @@ prop_sequential ::
114115
QC.Property
115116
prop_sequential maxSuccess mkTestArguments getLmdbDir fsOps as = QC.withMaxSuccess maxSuccess $
116117
QC.monadicIO $ do
117-
ref <- lift $ initialEnvironment fsOps getLmdbDir mkTestArguments =<< initChainDB
118-
(_, env@(Environment _ testInternals _ _ _ _ clean)) <- runPropertyStateT (runActions as) ref
118+
reg <- lift $ unsafeNewRegistry
119+
ref <- lift $ initialEnvironment fsOps getLmdbDir mkTestArguments reg =<< initChainDB
120+
(_, env@(Environment _ testInternals _ _ _ _ clean _)) <- runPropertyStateT (runActions as) ref
119121
checkNoLeakedHandles env
122+
lift $ closeRegistry reg
120123
QC.run $ closeLedgerDB testInternals >> clean
121124
QC.assert True
122125

@@ -129,9 +132,10 @@ initialEnvironment ::
129132
IO (SomeHasFS IO, IO ()) ->
130133
IO (FilePath, IO ()) ->
131134
(SecurityParam -> FilePath -> TestArguments IO) ->
135+
ResourceRegistry IO ->
132136
ChainDB IO ->
133137
IO Environment
134-
initialEnvironment fsOps getLmdbDir mkTestArguments cdb = do
138+
initialEnvironment fsOps getLmdbDir mkTestArguments reg cdb = do
135139
(sfs, cleanupFS) <- fsOps
136140
(lmdbDir, cleanupLMDB) <- getLmdbDir
137141
pure $
@@ -143,6 +147,7 @@ initialEnvironment fsOps getLmdbDir mkTestArguments cdb = do
143147
sfs
144148
(pure $ NumOpenHandles 0)
145149
(cleanupFS >> cleanupLMDB)
150+
reg
146151

147152
{-------------------------------------------------------------------------------
148153
Arguments
@@ -280,6 +285,7 @@ instance StateModel Model where
280285
Action Model (ExtLedgerState TestBlock EmptyMK, ExtLedgerState TestBlock EmptyMK)
281286
Init :: SecurityParam -> Action Model ()
282287
ValidateAndCommit :: Word64 -> [TestBlock] -> Action Model ()
288+
OpenAndCloseForker :: Action Model ()
283289

284290
actionName WipeLedgerDB{} = "WipeLedgerDB"
285291
actionName TruncateSnapshots{} = "TruncateSnapshots"
@@ -288,6 +294,7 @@ instance StateModel Model where
288294
actionName GetState{} = "GetState"
289295
actionName Init{} = "Init"
290296
actionName ValidateAndCommit{} = "ValidateAndCommit"
297+
actionName OpenAndCloseForker = "OpenAndCloseForker"
291298

292299
arbitraryAction _ UnInit = Some . Init <$> QC.arbitrary
293300
arbitraryAction _ model@(Model chain secParam) =
@@ -316,6 +323,7 @@ instance StateModel Model where
316323
)
317324
, (1, pure $ Some WipeLedgerDB)
318325
, (1, pure $ Some TruncateSnapshots)
326+
, (1, pure $ Some OpenAndCloseForker)
319327
]
320328

321329
initialState = UnInit
@@ -357,6 +365,7 @@ instance StateModel Model where
357365
nextState state WipeLedgerDB _var = state
358366
nextState state TruncateSnapshots _var = state
359367
nextState state (DropAndRestore n) _var = modelRollback n state
368+
nextState state OpenAndCloseForker _var = state
360369
nextState UnInit _ _ = error "Uninitialized model created a command different than Init"
361370

362371
precondition UnInit Init{} = True
@@ -526,25 +535,26 @@ data Environment
526535
(SomeHasFS IO)
527536
(IO NumOpenHandles)
528537
(IO ())
538+
(ResourceRegistry IO)
529539

530540
instance RunModel Model (StateT Environment IO) where
531541
perform _ (Init secParam) _ = do
532-
Environment _ _ chainDb mkArgs fs _ cleanup <- get
542+
Environment _ _ chainDb mkArgs fs _ cleanup rr <- get
533543
(ldb, testInternals, getNumOpenHandles) <- lift $ do
534544
let args = mkArgs secParam
535545
openLedgerDB (argFlavorArgs args) chainDb (argLedgerDbCfg args) fs
536-
put (Environment ldb testInternals chainDb mkArgs fs getNumOpenHandles cleanup)
546+
put (Environment ldb testInternals chainDb mkArgs fs getNumOpenHandles cleanup rr)
537547
perform _ WipeLedgerDB _ = do
538-
Environment _ testInternals _ _ _ _ _ <- get
548+
Environment _ testInternals _ _ _ _ _ _ <- get
539549
lift $ wipeLedgerDB testInternals
540550
perform _ GetState _ = do
541-
Environment ldb _ _ _ _ _ _ <- get
551+
Environment ldb _ _ _ _ _ _ _ <- get
542552
lift $ atomically $ (,) <$> getImmutableTip ldb <*> getVolatileTip ldb
543553
perform _ ForceTakeSnapshot _ = do
544-
Environment _ testInternals _ _ _ _ _ <- get
554+
Environment _ testInternals _ _ _ _ _ _ <- get
545555
lift $ takeSnapshotNOW testInternals TakeAtImmutableTip Nothing
546556
perform _ (ValidateAndCommit n blks) _ = do
547-
Environment ldb _ chainDb _ _ _ _ <- get
557+
Environment ldb _ chainDb _ _ _ _ _ <- get
548558
lift $ do
549559
atomically $
550560
modifyTVar (dbBlocks chainDb) $
@@ -561,13 +571,19 @@ instance RunModel Model (StateT Environment IO) where
561571
ValidateExceededRollBack{} -> error "Unexpected Rollback"
562572
ValidateLedgerError (AnnLedgerError forker _ _) -> forkerClose forker >> error "Unexpected ledger error"
563573
perform state@(Model _ secParam) (DropAndRestore n) lk = do
564-
Environment _ testInternals chainDb _ _ _ _ <- get
574+
Environment _ testInternals chainDb _ _ _ _ _ <- get
565575
lift $ do
566576
atomically $ modifyTVar (dbChain chainDb) (drop (fromIntegral n))
567577
closeLedgerDB testInternals
568578
perform state (Init secParam) lk
579+
perform _ OpenAndCloseForker _ = do
580+
Environment ldb _ _ _ _ _ _ rr <- get
581+
eFrk <- lift $ LedgerDB.getForkerAtTarget ldb rr VolatileTip
582+
case eFrk of
583+
Left err -> error $ "Impossible: can't acquire forker at tip: " <> show err
584+
Right frk -> lift $ forkerClose frk
569585
perform _ TruncateSnapshots _ = do
570-
Environment _ testInternals _ _ _ _ _ <- get
586+
Environment _ testInternals _ _ _ _ _ _ <- get
571587
lift $ truncateSnapshots testInternals
572588
perform UnInit _ _ = error "Uninitialized model created a command different than Init"
573589

@@ -622,7 +638,7 @@ mkTrackOpenHandles = do
622638

623639
-- | Check that we didn't leak any 'LedgerTablesHandle's (with V2 only).
624640
checkNoLeakedHandles :: Environment -> QC.PropertyM IO ()
625-
checkNoLeakedHandles (Environment _ testInternals _ _ _ getNumOpenHandles _) = do
641+
checkNoLeakedHandles (Environment _ testInternals _ _ _ getNumOpenHandles _ _) = do
626642
expected <- liftIO $ NumOpenHandles <$> LedgerDB.getNumLedgerTablesHandles testInternals
627643
actual <- liftIO getNumOpenHandles
628644
QC.assertWith (actual == expected) $

0 commit comments

Comments
 (0)