@@ -54,7 +54,34 @@ tests = testGroup "Test.Database.LSMTree.Class"
5454 action (SessionArgs hfs hbio (FS. mkFsPath [] ))
5555 }
5656
57- expectFailures2 = repeat False
57+ expectFailures2 = [
58+ False
59+ , False
60+ , False
61+ , False
62+ , False
63+ , False
64+ , False
65+ , False
66+ , False
67+ , False
68+ , False
69+ , False
70+ , False
71+ , False
72+ , False
73+ , False
74+ , False
75+ , False
76+ , False
77+ , False
78+ , False
79+ , False
80+ , False
81+ , False
82+ , False
83+ , True -- merge
84+ ] ++ repeat False
5885
5986 props tbl =
6087 [ testProperty' " lookup-insert" $ prop_lookupInsert tbl
@@ -81,6 +108,8 @@ tests = testGroup "Test.Database.LSMTree.Class"
81108 , testProperty' " readCursor-offset" $ prop_readCursorOffset tbl
82109 , testProperty' " snapshot-nochanges" $ prop_snapshotNoChanges tbl
83110 , testProperty' " snapshot-nochanges2" $ prop_snapshotNoChanges2 tbl
111+ , testProperty' " lookup-mupsert" $ prop_lookupUpdate tbl
112+ , testProperty' " merge" $ prop_union tbl
84113 ]
85114
86115testProperty' :: forall a . Testable a => TestName -> a -> Bool -> TestTree
@@ -97,7 +126,12 @@ type Blob = BS.ByteString
97126newtype Value = Value BS. ByteString
98127 deriving stock (Eq , Show )
99128 deriving newtype (Arbitrary , SerialiseValue )
100- deriving ResolveValue via ResolveAsFirst Value
129+
130+ instance ResolveValue Value where
131+ resolveValue = resolveDeserialised resolve
132+
133+ resolve :: Value -> Value -> Value
134+ resolve (Value x) (Value y) = Value (x <> y)
101135
102136label :: SnapshotLabel
103137label = SnapshotLabel " Word64 ByteString ByteString"
@@ -560,13 +594,69 @@ prop_updatesMayInvalidateBlobRefs h ups k1 v1 blob1 ups' = monadicIO $ do
560594-- implement classic QC tests for monoidal updates
561595-------------------------------------------------------------------------------
562596
563- {- Not applicable -}
597+ -- | You can lookup what you inserted.
598+ prop_lookupUpdate ::
599+ IsTable h
600+ => Proxy h -> [(Key , Update Value Blob )]
601+ -> Key -> Value -> Maybe Blob -> Value -> Property
602+ prop_lookupUpdate h ups k v1 mb1 v2 = ioProperty $ do
603+ withSessionAndTableNew h ups $ \ s hdl -> do
604+
605+ -- the main dish
606+ inserts hdl (V. singleton (k, v1, mb1))
607+ mupserts hdl (V. singleton (k, v2))
608+ res <- lookupsWithBlobs hdl s (V. singleton k)
609+
610+ -- notice the order.
611+ return $ case mb1 of
612+ Nothing -> res === V. singleton (Found (resolve v2 v1))
613+ Just b1 -> res === V. singleton (FoundWithBlob (resolve v2 v1) b1)
564614
565615-------------------------------------------------------------------------------
566616-- implement classic QC tests for monoidal table unions
567617-------------------------------------------------------------------------------
568618
569- {- Not applicable -}
619+ prop_union :: forall h .
620+ IsTable h
621+ => Proxy h -> [(Key , Update Value Blob )] -> [(Key , Update Value Blob )]
622+ -> [Key ] -> Property
623+ prop_union h ups1 ups2 (V. fromList -> testKeys) = ioProperty $ do
624+ withSessionAndTableNew h ups1 $ \ s hdl1 -> do
625+ withTableNew s (testTableConfig h) $ \ hdl2 -> do
626+ updates hdl2 $ V. fromList ups2
627+
628+ -- union them.
629+ withTableUnion hdl1 hdl2 $ \ hdl3 -> do
630+
631+ -- results in parts and the union table
632+ res1 <- lookupsWithBlobs hdl1 s testKeys
633+ res2 <- lookupsWithBlobs hdl2 s testKeys
634+ res3 <- lookupsWithBlobs hdl3 s testKeys
635+
636+ let unionResult ::
637+ LookupResult Value Blob
638+ -> LookupResult Value Blob
639+ -> LookupResult Value Blob
640+
641+ unionResult r@ NotFound NotFound = r
642+ unionResult NotFound r@ (Found _) = r
643+ unionResult NotFound r@ (FoundWithBlob _ _) = r
644+
645+ unionResult r@ (Found _) NotFound
646+ = r
647+ unionResult (Found v1) (Found v2)
648+ = Found (resolve v1 v2)
649+ unionResult (Found v1) (FoundWithBlob v2 b2)
650+ = FoundWithBlob (resolve v1 v2) b2
651+
652+ unionResult r@ (FoundWithBlob _ _) NotFound
653+ = r
654+ unionResult (FoundWithBlob v1 b1) (Found v2)
655+ = FoundWithBlob (resolve v1 v2) b1
656+ unionResult (FoundWithBlob v1 b1) (FoundWithBlob v2 _b2)
657+ = FoundWithBlob (resolve v1 v2) b1
658+
659+ return $ V. zipWith unionResult res1 res2 == res3
570660
571661-------------------------------------------------------------------------------
572662-- implement classic QC tests for snapshots
0 commit comments