Skip to content

Commit 46cf889

Browse files
authored
Merge pull request #429 from IntersectMBO/jdral/lockstep-improvements-2
Shrink `TableConfig` in `StateMachine` tests
2 parents 23eeb41 + 18d2e5d commit 46cf889

File tree

1 file changed

+44
-3
lines changed

1 file changed

+44
-3
lines changed

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

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,17 +208,58 @@ propLockstep_ModelIOImpl =
208208
= Nothing
209209

210210
instance Arbitrary R.TableConfig where
211-
arbitrary :: Gen R.TableConfig
212-
arbitrary = pure $ R.TableConfig {
211+
arbitrary = do
212+
confWriteBufferAlloc <- QC.arbitrary
213+
pure $ R.TableConfig {
213214
R.confMergePolicy = R.MergePolicyLazyLevelling
214215
, R.confSizeRatio = R.Four
215-
, R.confWriteBufferAlloc = R.AllocNumEntries (R.NumEntries 30)
216+
, confWriteBufferAlloc
216217
, R.confBloomFilterAlloc = R.AllocFixed 10
217218
, R.confFencePointerIndex = R.CompactIndex
218219
, R.confDiskCachePolicy = R.DiskCacheNone
219220
, R.confMergeSchedule = R.OneShot
220221
}
221222

223+
shrink R.TableConfig{..} =
224+
[ R.TableConfig {
225+
confWriteBufferAlloc = confWriteBufferAlloc'
226+
, ..
227+
}
228+
| confWriteBufferAlloc' <- QC.shrink confWriteBufferAlloc
229+
]
230+
231+
-- TODO: the current generator is suboptimal, and should be improved. There are
232+
-- some aspects to consider, and since they are at tension with each other, we
233+
-- should try find a good balance.
234+
--
235+
-- Say the write buffer allocation is @n@.
236+
--
237+
-- * If @n@ is too large, then the tests degrade to only testing the write
238+
-- buffer, because there are no flushes/merges.
239+
--
240+
-- * If @n@ is too small, then the resulting runs are also small. They might
241+
-- consist of only a few disk pages, or they might consist of only 1 underfull
242+
-- disk page. This means there are some parts of the code that we would rarely
243+
-- cover in the state machine tests.
244+
--
245+
-- * If @n@ is too small, then we flush/merge very frequently, which may exhaust
246+
-- the number of open file handles when using the real file system. Specially
247+
-- if the test fails and the shrinker kicks in, then @n@ can currently become
248+
-- very small. This is good for finding a minimal counterexample, but it might
249+
-- also make the real filesystem run out of file descriptors. Arguably, you
250+
-- could overcome this specific issue by only generating or shrinking to small
251+
-- @n@ when we use the mocked file system. This would require some boilerplate
252+
-- to add type level tags to distinguish between the two cases.
253+
instance Arbitrary R.WriteBufferAlloc where
254+
arbitrary = QC.scale (max 30) $ do
255+
QC.Positive x <- QC.arbitrary
256+
pure (R.AllocNumEntries (R.NumEntries x))
257+
258+
shrink (R.AllocNumEntries (R.NumEntries x)) =
259+
[ R.AllocNumEntries (R.NumEntries x')
260+
| QC.Positive x' <- QC.shrink (QC.Positive x)
261+
]
262+
222263
propLockstep_RealImpl_RealFS_IO ::
223264
Tracer IO R.LSMTreeTrace
224265
-> Actions (Lockstep (ModelState R.TableHandle))

0 commit comments

Comments
 (0)