Skip to content

Commit 32616fe

Browse files
authored
Merge pull request #479 from IntersectMBO/jdral/344
Re-enable NoThunks tests (#444)
2 parents 31491d8 + 6cf7f51 commit 32616fe

File tree

4 files changed

+42
-19
lines changed

4 files changed

+42
-19
lines changed

lsm-tree.cabal

+1
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ library extras
320320
, contra-tracer
321321
, deepseq
322322
, fs-api
323+
, fs-sim
323324
, io-classes:strict-mvar
324325
, io-classes:strict-stm
325326
, lsm-tree

src-extras/Database/LSMTree/Extras/NoThunks.hs

+34-6
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ import KMerge.Heap
6868
import NoThunks.Class
6969
import System.FS.API
7070
import System.FS.BlockIO.API
71+
import System.FS.IO
72+
import System.FS.Sim.MockFS
7173
import Test.QuickCheck (Property, Testable (..), counterexample)
7274
import Unsafe.Coerce
7375

@@ -542,7 +544,7 @@ instance (NoThunks a, Typeable s, Typeable a) => NoThunks (MutableHeap s a) wher
542544
-- a)@, can not be satisfied for arbitrary @m@\/@s@, and must be instantiated
543545
-- for a concrete @m@\/@s@, like @IO@\/@RealWorld@.
544546
class ( forall a. NoThunks a => NoThunks (StrictTVar m a)
545-
, forall a. NoThunks a => NoThunks (StrictMVar m a)
547+
, forall a. (NoThunks a, Typeable a) => NoThunks (StrictMVar m a)
546548
) => NoThunksIOLike' m s
547549

548550
instance NoThunksIOLike' IO RealWorld
@@ -564,11 +566,37 @@ instance NoThunks a => NoThunks (StrictTVar IO a) where
564566
#endif
565567
#endif
566568

567-
instance NoThunks a => NoThunks (StrictMVar IO a) where
568-
showTypeOf (_ :: Proxy (StrictMVar IO a)) = "StrictMVar IO"
569-
wNoThunks ctx var = do
570-
x <- readMVar var
571-
noThunks ctx x
569+
-- TODO: in some cases, strict-mvar functions leave thunks behind, in particular
570+
-- modifyMVarMasked and modifyMVarMasked_. So in some specific cases we evaluate
571+
-- the contents of the MVar to WHNF, and keep checking nothunks from there. See
572+
-- lsm-tree#444.
573+
--
574+
-- TODO: we tried using overlapping instances for @StrictMVar IO a@ and
575+
-- @StrictMVar IO (MergingRunState IO h)@, but the quantified constraint in
576+
-- NoThunksIOLike' will throw a compiler error telling us to mark the instances
577+
-- for StrictMVar as incoherent. Marking them as incoherent makes the tests
578+
-- fail... We are unsure if it can be overcome, but the current casting approach
579+
-- works, so there is no priority to use rewrite this code to use overlapping
580+
-- instances.
581+
instance (NoThunks a, Typeable a) => NoThunks (StrictMVar IO a) where
582+
showTypeOf (p :: Proxy (StrictMVar IO a)) = show $ typeRep p
583+
wNoThunks ctx var
584+
| Just (Proxy :: Proxy (MergingRunState IO HandleIO))
585+
<- gcast (Proxy @a)
586+
= workAroundCheck
587+
| Just (Proxy :: Proxy (MergingRunState IO HandleMock))
588+
<- gcast (Proxy @a)
589+
= workAroundCheck
590+
| otherwise
591+
= properCheck
592+
where
593+
properCheck = do
594+
x <- readMVar var
595+
noThunks ctx x
596+
597+
workAroundCheck = do
598+
!x <- readMVar var
599+
noThunks ctx x
572600

573601
{-------------------------------------------------------------------------------
574602
vector

test/Test/Database/LSMTree/Normal/StateMachine.hs

+1-2
Original file line numberDiff line numberDiff line change
@@ -957,8 +957,7 @@ runIO action lookUp = ReaderT $ \(session, handler) -> do
957957
x <- aux (unwrapSession session) handler action
958958
case session of
959959
WrapSession sesh ->
960-
-- TODO: Re-enable NoThunks assertions. See lsm-tree#444.
961-
const id (assertNoThunks sesh) $ pure ()
960+
assertNoThunks sesh $ pure ()
962961
pure x
963962
where
964963
aux ::

test/Test/Database/LSMTree/Normal/StateMachine/DL.hs

+6-11
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,14 @@ import qualified Test.QuickCheck.Gen as QC
2020
import qualified Test.QuickCheck.Random as QC
2121
import Test.QuickCheck.StateModel.Lockstep
2222
import Test.Tasty (TestTree, testGroup)
23+
import qualified Test.Tasty.QuickCheck as QC
2324
import Test.Util.PrettyProxy
2425

2526
tests :: TestTree
2627
tests = testGroup "Test.Database.LSMTree.Normal.StateMachine.DL" [
27-
-- This one is not actually enabled, because it runs for rather a long time
28-
-- and it's not in itself a very import property.
29-
-- QC.testProperty "prop_example" prop_example
28+
29+
QC.testProperty "prop_example" prop_example
3030
]
31-
where
32-
_unused = prop_example
3331

3432
instance DynLogicModel (Lockstep (ModelState R.Table))
3533

@@ -52,22 +50,21 @@ prop_example =
5250
-- instead
5351
tr = nullTracer
5452

55-
-- | Create an initial "large" table, and then proceed with random actions as
56-
-- usual.
53+
-- | Create an initial "large" table
5754
dl_example :: DL (Lockstep (ModelState R.Table)) ()
5855
dl_example = do
5956
-- Create an initial table and fill it with some inserts
6057
var3 <- action $ New (PrettyProxy @((Key, Value, Blob))) (TableConfig {
6158
confMergePolicy = MergePolicyLazyLevelling
6259
, confSizeRatio = Four
63-
, confWriteBufferAlloc = AllocNumEntries (NumEntries 30)
60+
, confWriteBufferAlloc = AllocNumEntries (NumEntries 4)
6461
, confBloomFilterAlloc = AllocFixed 10
6562
, confFencePointerIndex = CompactIndex
6663
, confDiskCachePolicy = DiskCacheNone
6764
, confMergeSchedule = OneShot })
6865
let kvs :: Map.Map Key Value
6966
kvs = Map.fromList $
70-
QC.unGen (QC.vectorOf 678 $ (,) <$> QC.arbitrary <*> QC.arbitrary)
67+
QC.unGen (QC.vectorOf 37 $ (,) <$> QC.arbitrary <*> QC.arbitrary)
7168
(QC.mkQCGen 42) 30
7269
ups :: V.Vector (Key, Update Value Blob)
7370
ups = V.fromList
@@ -84,5 +81,3 @@ dl_example = do
8481
| Just tbl <- (Model.fromSomeTable @Key @Value @Blob smTbl)
8582
-> Map.size (Model.values tbl) == Map.size kvs
8683
_ -> False
87-
-- Perform any sequence of actions after
88-
anyActions_

0 commit comments

Comments
 (0)