Open dnadales opened 1 year ago
One example where abstraction would be applicable is the lockstep
function, which is defined separately in each state-machine test setup, though the definitions are very similar:
test-storage.Test.Ouroboros.Storage.LedgerDB.OnDisk
lockstep :: Eq1 r
=> Model r
-> Cmd :@ r
-> Resp :@ r
-> Event r
lockstep m@(Model _ hs) cmd (At resp) = Event {
eventBefore = m
, eventCmd = cmd
, eventResp = At resp
, eventAfter = Model mock' (hs' <> hs) -- new references override old!
, eventMockResp = resp'
}
where
(resp', mock') = step m cmd
hs' = zip (toList resp) (toList resp')
test-consensus.Test.Consensus.ResourceRegistry.hs
lockstep :: (Eq1 r, Show1 r, IOLike m)
=> Model m r
-> At m Cmd r
-> At m Resp r
-> Event m r
lockstep m@(Model _ hs) c (At resp) = Event {
before = m
, cmd = c
, after = Model mock' (hs <> hs')
, mockResp = resp'
}
where
(resp', mock') = step m c
hs' = zip (newHandles resp) (newHandles resp')
newHandles :: Resp r -> [r]
newHandles (Resp (Left _)) = []
newHandles (Resp (Right (Unit ()))) = []
newHandles (Resp (Right (Spawned t))) = [t]
newHandles (Resp (Right (Threads _))) = []
https://github.com/input-output-hk/ouroboros-network/issues/4116 is a related issue that proposes to explore the use of the quickcheck-dynamic
package in Conensus, which seems to require less boilerplate code to run state-machine tests
At the moment all the quick-check state-machine from consensus use the scaffolding described in this blogpost. Each new test requires around 500 LOC of boilerplate. If we continue using QSM we should abstract this away.
Also, we need to evaluate if the scaffolding above is suitable for running parallel tests.