Getting Started
[Déjà Fu is] A martial art in which the user's limbs move in time as well as space, […] It is best described as "the feeling that you have been kicked in the head this way before"
-- Terry Pratchett, Thief of Time
Déjà Fu is a unit-testing library for concurrent Haskell programs. Tests are deterministic and expressive, making it easy and convenient to test your threaded code.
Available on GitHub, Hackage, and Stackage.
Features:
- An abstraction over the concurrency functionality in
IO
- Deterministic testing of nondeterministic code
- Both complete (slower) and incomplete (faster) modes
- A unit-testing-like approach to writing test cases
- A property-testing-like approach to comparing stateful operations
- Testing of potentially nonterminating programs
- Integration with HUnit and tasty
There are a few different packages under the Déjà Fu umbrella:
Version | Summary | |
---|---|---|
concurrency | 1.11.0.3 | Typeclasses, functions, and data types for concurrency and STM. |
dejafu | 2.4.0.6 | Systematic testing for Haskell concurrency. |
hunit-dejafu | 2.0.0.6 | Deja Fu support for the HUnit test framework. |
tasty-dejafu | 2.1.0.1 | Deja Fu support for the Tasty test framework. |
See the latest package documentation.
Installation
Install from Hackage globally:
$ cabal install dejafu
Or add it to your cabal file:
build-depends: ...
, dejafu
Or to your package.yaml:
dependencies:
...
- dejafu
Quick start guide
Déjà Fu supports unit testing, and comes with a helper function called
autocheck
to look for some common issues. Let's see it in action:
import Control.Concurrent.Classy
myFunction :: MonadConc m => m String
myFunction = do
var <- newEmptyMVar
fork (putMVar var "hello")
fork (putMVar var "world")
readMVar var
That MonadConc
is a typeclass abstraction over concurrency, but
we'll get onto that shortly. First, the result of testing:
> autocheck myFunction
[pass] Never Deadlocks
[pass] No Exceptions
[fail] Consistent Result
"hello" S0----S1--S0--
"world" S0----S2--S0--
False
There are no deadlocks or uncaught exceptions, which is good; but the program is (as you probably spotted) nondeterministic!
Along with each result, Déjà Fu gives us a representative execution
trace in an abbreviated form. Sn
means that thread n
started
executing, and Pn
means that thread n
pre-empted the previously
running thread.
Why Déjà Fu?
Testing concurrent programs is difficult, because in general they are nondeterministic. This leads to people using work-arounds like running their testsuite many thousands of times; or running their testsuite while putting their machine under heavy load.
These approaches are inadequate for a few reasons:
- How many runs is enough? When you are just hopping to spot a bug by coincidence, how do you know to stop?
- How do you know if you've fixed a bug you saw previously? Because the scheduler is a black box, you don't know if the previously buggy schedule has been re-run.
- You won't get that much scheduling variety! Operating systems and language runtimes like to run threads for long periods of time, which reduces the variety you get (and so drives up the number of runs you need).
Déjà Fu addresses these points by offering complete testing. You can run a test case and be guaranteed to find all results with some bounds. These bounds can be configured, or even disabled! The underlying approach used is smarter than merely trying all possible executions, and will in general explore the state-space quickly.
If your test case is just too big for complete testing, there is also
a random scheduling mode, which is necessarily incomplete. However,
Déjà Fu will tend to produce much more schedule variety than just
running your test case in IO
the same number of times, and so bugs
will tend to crop up sooner. Furthermore, as you get execution traces
out, you can be certain that a bug has been fixed by simply following
the trace by eye.
Bibliography
These libraries wouldn't be possible without prior research, which I mention in the documentation. Haddock comments get the full citation, whereas in-line comments just get the shortened name:
-
[BPOR] Bounded partial-order reduction, K. Coons, M. Musuvathi, and K. McKinley (2013)
-
[RDPOR] Dynamic Partial Order Reduction for Relaxed Memory Models, N. Zhang, M. Kusano, and C. Wang (2015)
-
[Empirical] Concurrency Testing Using Schedule Bounding: an Empirical Study, P. Thompson, A. Donaldson, and A. Betts (2014)
-
[RMMVerification] On the Verification of Programs on Relaxed Memory Models, A. Linden (2014)
There are also a few papers on dejafu itself:
-
Déjà Fu: A Concurrency Testing Library for Haskell, M. Walker and C. Runciman (2015)
This details dejafu-0.1, and was presented at the 2015 Haskell Symposium.
-
Déjà Fu: A Concurrency Testing Library for Haskell, M. Walker and C. Runciman (2016)
This is a more in-depth technical report, written between the dejafu-0.2 and dejafu-0.3 releases.
-
Revealing Behaviours of Concurrent Functional Programs by Systematic Testing, M. Walker (2018)
This is my Ph.D thesis, which discusses dejafu and my other research projects.
Typeclasses
We don't use the regular Control.Concurrent
and Control.Exception
modules,
we use typeclass-generalised ones instead from the concurrency and
exceptions packages.
Porting guide
If you want to test some existing code, you'll need to port it to the
appropriate typeclass. The typeclass is necessary, because we can't peek inside
IO
and STM
values, so we need to able to plug in an alternative
implementation when testing.
Fortunately, this tends to be a fairly mechanical and type-driven process:
-
Import
Control.Concurrent.Classy.*
instead ofControl.Concurrent.*
-
Import
Control.Monad.Catch
instead ofControl.Exception
-
Change your monad type:
IO a
becomesMonadConc m => m a
STM a
becomesMonadSTM stm => stm a
-
Parameterise your state types by the monad:
TVar
becomesTVar stm
MVar
becomesMVar m
IORef
becomesIORef m
-
Some functions are renamed:
forkIO*
becomesfork*
atomicModifyIORefCAS
becomesmodifyIORefCAS*
-
Fix the type errors
If you're lucky enough to be starting a new concurrent Haskell project, you can
just program against the MonadConc
interface.
What if I really need I/O?
You can use MonadIO
and liftIO
with MonadConc
, for instance if you need to
talk to a database (or just use some existing library which needs real I/O).
To test IO
-using code, there are some rules you need to follow:
-
Given the same set of scheduling decisions, your
IO
code must be deterministic (see below). -
As dejafu can't inspect
IO
values, they should be kept small; otherwise dejafu may miss buggy interleavings. -
You absolutely cannot block on the action of another thread inside
IO
, or the test execution will just deadlock.
Deterministic IO
is only essential if you're using the systematic testing (the
default). Nondeterministic IO
won't break the random testing, it'll just make
things more confusing.
Deriving your own instances
There are MonadConc
and MonadSTM
instances for many common monad
transformers. In the simple case, where you want an instance for a newtype
wrapper around a type that has an instance, you may be able to derive it. For
example:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
data Env = Env
newtype MyMonad m a = MyMonad { runMyMonad :: ReaderT Env m a }
deriving (Functor, Applicative, Monad)
deriving instance MonadThrow m => MonadThrow (MyMonad m)
deriving instance MonadCatch m => MonadCatch (MyMonad m)
deriving instance MonadMask m => MonadMask (MyMonad m)
deriving instance MonadConc m => MonadConc (MyMonad m)
MonadSTM
needs a slightly different set of classes:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
data Env = Env
newtype MyMonad m a = MyMonad { runMyMonad :: ReaderT Env m a }
deriving (Functor, Applicative, Monad, Alternative, MonadPlus)
deriving instance MonadThrow m => MonadThrow (MyMonad m)
deriving instance MonadCatch m => MonadCatch (MyMonad m)
deriving instance MonadSTM m => MonadSTM (MyMonad m)
Don't be put off by the use of UndecidableInstances
, it's safe here.
Unit Testing
Writing tests with Déjà Fu is a little different to traditional unit testing, as your test case may have multiple results. A "test" is a combination of your code, and a predicate which says something about the set of allowed results.
Most tests will look something like this:
dejafu "Assert the thing holds" myPredicate myAction
The dejafu
function comes from Test.DejaFu
. Another useful function is
dejafuWithSettings
(see Advanced Usage).
Actions
An action is just something with the type MonadConc m => m a
, or (MonadConc m, MonadIO m) => m a
for some a
that your chosen predicate can deal with.
For example, some users on Reddit found a couple of apparent bugs in the
auto-update package a while ago (thread here). As the
package is simple and self-contained, I translated it to the MonadConc
abstraction and wrote a couple of tests to replicate the bugs. Here they are:
deadlocks :: MonadConc m => m ()
deadlocks = do
auto <- mkAutoUpdate defaultUpdateSettings
auto
nondeterministic :: forall m. MonadConc m => m Int
nondeterministic = do
var <- newIORef 0
let settings = (defaultUpdateSettings :: UpdateSettings m ())
{ updateAction = atomicModifyIORef var (\x -> (x+1, x)) }
auto <- mkAutoUpdate settings
auto
auto
These actions action could be tested with autocheck
, and the issues would be
revealed. The use of ScopedTypeVariables
in the second is an unfortunate
example of what can happen when everything becomes more polymorphic. But other
than that, note how there is no special mention of Déjà Fu in the actions: it's
just normal concurrent Haskell, simply written against a different interface.
The modified package is included in the test suite, if you want to see the full code.
The predicates in dejafu-tests are a little confusing, as they're the opposite of what you would normally write! These predicates are checking that the bug is found, not that the code is correct.
If the RTS supports bound threads (the -threaded
flag was passed to GHC when
linking), then the main thread of an action given to Déjà Fu will be bound, and
further bound threads can be forked with the forkOS
functions. If not, then
attempting to fork a bound thread will raise an error.
Conditions
When a concurrent program of type MonadConc m => m a
is executed, it may
produce a value of type a
, or it may experience a condition such as
deadlock.
A condition does not necessarily cause your test to fail. It's important to be aware of what exactly your test is testing, to avoid drawing the wrong conclusions from a passing (or failing) test.
Setup and Teardown
Because dejafu drives the execution of the program under test, there are some tricks available to you which are not possible using normal concurrent Haskell.
If your test does some set-up work which is required for your test to work, but which is not the actual thing you are testing, you can define that as a setup action:
withSetup
:: Program Basic n x
-- ^ Setup action
-> (x -> Program Basic n a)
-- ^ Main program
-> Program (WithSetup x) n a
dejafu will save the state at the end of the setup action, and efficiently restore that state in subsequent runs of the same test with a different schedule. This can be much more efficient than dejafu running the setup action normally every single time.
If you want to examine some state you created in your setup action even if your actual test case deadlocks or something, you can define a teardown action:
withSetupAndTeardown
:: Program Basic n x
-- ^ Setup action
-> (x -> Either Condition y -> Program Basic n a)
-- ^ Teardown action
-> (x -> Program Basic n y)
-- ^ Main program
-> Program (WithSetupAndTeardown x y) n a
The teardown action is always executed.
Finally, if you want to ensure that some invariant holds over some shared state, you can define invariants in the setup action, which are checked atomically during the main action:
-- slightly contrived example
let setup = do
var <- newEmptyMVar
registerInvariant $ do
value <- inspectMVar var
when (x == Just 1) (throwM Overflow)
pure var
in withSetup setup $ \var -> do
fork $ putMVar var 0
fork $ putMVar var 1
tryReadMVar var
If the main action violates the invariant, it is terminated with an
InvariantFailure
condition, and any teardown action is run.
Predicates
There are a few predicates built in, and some helpers to define your own.
abortsNever | checks that the computation never aborts |
abortsAlways | checks that the computation always aborts |
abortsSometimes | checks that the computation aborts at least once |
An abort is where the scheduler chooses to terminate execution early. If you see it, it probably means that a test didn't terminate before it hit the execution length limit. Aborts are hidden unless you use explicitly enable them, see (see Advanced Usage).
deadlocksNever | checks that the computation never deadlocks |
deadlocksAlways | checks that the computation always deadlocks |
deadlocksSometimes | checks that the computation deadlocks at least once |
Deadlocking is where every thread becomes blocked. This can be, for
example, if every thread is trying to read from an MVar
that has been emptied.
exceptionsNever | checks that the main thread is never killed by an exception |
exceptionsAlways | checks that the main thread is always killed by an exception |
exceptionsSometimes | checks that the main thread is killed by an exception at least once |
An uncaught exception in the main thread kills the process. These can be synchronous (thrown in the main thread) or asynchronous (thrown to it from a different thread).
alwaysSame | checks that the computation is deterministic and always produces a value |
alwaysSameOn f | is like alwaysSame , but transforms the results with f first |
alwaysSameBy f | is like alwaysSame , but uses f instead of (==) to compare |
notAlwaysSame | checks that the computation is nondeterministic |
notAlwaysSameOn f | is like notAlwaysSame , but transforms the results with f first |
notAlwaysSameBy f | is like notAlwaysSame , but uses f instead of (==) to compare |
Checking for determinism will also find nondeterministic failures: deadlocking (for instance) is still a result of a test!
alwaysTrue p | checks that p is true for every result |
somewhereTrue p | checks that p is true for at least one result |
These can be used to check custom predicates. For example, you might want all your results to be less than five.
gives xs | checks that the set of results is exactly xs (which may include conditions) |
gives' xs | checks that the set of results is exactly xs (which may not include conditions) |
These let you say exactly what you want the results to be. Your test will fail if it has any extra results, or misses a result.
You can check multiple predicates against the same collection of results using
the dejafus
and dejafusWithSettings
functions. These avoid recomputing the
results, and so may be faster than multiple dejafu
/ dejafuWithSettings
calls.
Using HUnit and Tasty
By itself, Déjà Fu has no framework in place for named test groups and parallel execution or anything like that. It does one thing and does it well, which is running test cases for concurrent programs. HUnit and tasty integration is provided to get more of the features you'd expect from a testing framework.
The integration is provided by the hunit-dejafu and tasty-dejafu packages.
There's a simple naming convention used: the Test.DejaFu
function dejafuFoo
is wrapped in the appropriate way and exposed as testDejafuFoo
from
Test.HUnit.DejaFu
and Test.Tasty.DejaFu
.
Our example from the start becomes:
testDejafu "Assert the thing holds" myPredicate myAction
The autocheck
function is exposed as testAuto
.
Refinement Testing
Déjà Fu also supports a form of property-testing where you can check things
about the side-effects of stateful operations. For example, we can assert that
readMVar
is equivalent to sequencing takeMVar
and putMVar
like so:
prop_mvar_read_take_put =
sig readMVar `equivalentTo` sig (\v -> takeMVar v >>= putMVar v)
Given the signature function, sig
, defined in the next section. If we check
this, our property fails!
> check prop_mvar_read_take_put
*** Failure: (seed Just 0)
left: [(Nothing,Just 0)]
right: [(Nothing,Just 0),(Just Deadlock,Just 0)]
False
This is because readMVar
is atomic, whereas sequencing takeMVar
with
putMVar
is not, and so another thread can interfere with the MVar
in the
middle. The check
and equivalentTo
functions come from
Test.DejaFu.Refinement
(also re-exported from Test.DejaFu
).
Signatures
A signature tells the property-tester something about the state your operation acts upon, it has a few components:
data Sig s o x = Sig
{ initialise :: x -> ConcIO s
, observe :: s -> x -> ConcIO o
, interfere :: s -> x -> ConcIO ()
, expression :: s -> ConcIO ()
}
-
s
is the state type, it's the thing which your operations mutate. ForreadMVar
, the state is someMVar a
. -
o
is the observation type, it's some pure (and comparable) proxy for a snapshot of your mutable state. ForMVar a
, the observation is probably aMaybe a
. -
x
is the seed type, it's some pure value used to construct the initial mutable state. ForMVar a
, the seed is probably aMaybe a
. -
ConcIO
is just one of the instances ofMonadConc
that Déjà Fu defines for testing purposes. Just write code polymorphic in the monad as usual, and all will work.
The initialise
, observe
, and expression
functions should be
self-explanatory, but the interfere
one may not be. It's the job of the
interfere
function to change the state in some way; it's run concurrently with
the expression, to simulate the nondeterministic action of other threads.
Here's a concrete example for our MVar
example:
sig :: (MVar ConcIO Int -> ConcIO a) -> Sig (MVar ConcIO Int) (Maybe Int) (Maybe Int)
sig e = Sig
{ initialise = maybe newEmptyMVar newMVar
, observe = \v _ -> tryTakeMVar v
, interfere = \v s -> tryTakeMVar v >> maybe (pure ()) (\x -> void $ tryPutMVar v (x * 1000)) s
, expression = void . e
}
The observe
function should be deterministic, but as it is run after the
normal execution ends, it may have side-effects on the state. The interfere
function can do just about anything (there are probably some concrete rules for
a good function, but I haven't figured them out yet), but a poor one may result
in the property-checker being unable to distinguish between atomic and nonatomic
expressions.
Properties
A property is a pair of signatures linked by one of three provided functions. These functions are:
Function | Operator | Checks that... |
---|---|---|
equivalentTo | === | ... the left and right have exactly the same behaviours |
refines | =>= | ... every behaviour of the left is also a behaviour of the right |
strictlyRefines | ->- | ... left =>= right holds but left === right does not |
The signatures can have different state types, as long as the seed and
observation types are the same. This lets you compare different implementations
of the same idea: for example, comparing a concurrent stack implemented using
MVar
with one implemented using IORef
.
Properties can have parameters, given in the obvious way:
check $ \a b c -> sig1 ... `op` sig2 ...
Under the hood, seed and parameter values are generated using the leancheck
package, an enumerative property-based testing library. This means that any
types you use will need to have a Listable
instance.
You can also think about the three functions in terms of sets of results, where
a result is a (Maybe Failure, o)
value. A Failure
is something like
deadlocking, or being killed by an exception; o
is the observation type. An
observation is always made, even if execution of the expression fails.
Function | Result-set operation |
---|---|
refines | For all seed and parameter assignments, subset-or-equal |
strictlyRefines | For at least one seed and parameter assignment, proper subset; for all others, subset-or-equal |
equivalentTo | For all seed and parameter assignments, equality |
Finally, there is an expectFailure
function, which inverts the expected result
of a property.
The Déjà Fu testsuite has a collection of refinement properties, which may help you get a feel for this sort of testing.
Using HUnit and Tasty
As for unit testing, HUnit and tasty integration is provided for refinement testing in the hunit-dejafu and tasty-dejafu packages.
The testProperty
function is used to check properties. Our example from the
start becomes:
testProperty "Read is equivalent to Take then Put" prop_mvar_read_take_put
Advanced Usage
Déjà Fu tries to have a sensible set of defaults, but there are some times when the defaults are not suitable. There are a lot of knobs provided to tweak how things work.
Execution settings
The autocheckWithSettings
, dejafuWithSettings
, and dejafusWithSettings
let
you provide a Settings
value, which controls some of Déjà Fu's behaviour:
dejafuWithSettings mySettings "Assert the thing holds" myPredicate myAction
The available settings are:
-
"Way", how to explore the behaviours of the program under test.
-
Length bound, a cut-off point to terminate an execution even if it's not done yet.
-
Memory model, which affects how non-synchronised operations, such as
readIORef
andwriteIORef
behave. -
Discarding, which allows throwing away uninteresting results, rather than keeping them around in memory.
-
Early exit, which allows exiting as soon as a result matching a predicate is found.
-
Representative traces, keeping only one execution trace for each distinct result.
-
Trace simplification, rewriting execution traces into a simpler form (particularly effective with the random testing).
-
Safe IO, pruning needless schedules when your IO is only used to manage thread-local state.
See the Test.DejaFu.Settings
module for more information.
Performance tuning
-
Are you happy to trade space for time?
Consider computing the results once and running multiple predicates over the output: this is what
dejafus
/testDejafus
/ etc does. -
Can you sacrifice completeness?
Consider using the random testing functionality. See the
*WithSettings
functions. -
Would strictness help?
Consider using the strict functions in
Test.DejaFu.SCT
(the ones ending with a'
). -
Do you just want the set of results, and don't care about traces?
Consider using
Test.DejaFu.SCT.resultsSet
. -
Do you know something about the sort of results you care about?
Consider discarding results you don't care about. See the
*WithSettings
functions inTest.DejaFu
,Test.DejaFu.SCT
, andTest.{HUnit,Tasty}.DejaFu
.
For example, let's say you want to know if your test case deadlocks, but you don't care about the execution trace, and you are going to sacrifice completeness because your possible state-space is huge. You could do it like this:
dejafuWithSettings
( set ldiscard
-- "efa" == "either failure a", discard everything but deadlocks
(Just $ \efa -> Just (if either isDeadlock (const False) efa then DiscardTrace else DiscardResultAndTrace))
. set lway
-- try 10000 executions with random scheduling
(randomly (mkStdGen 42) 10000)
$ defaultSettings
)
-- the name of the test
"Never Deadlocks"
-- the predicate to check
deadlocksNever
-- your test case
testCase
1.x to 2.x
dejafu-2.0.0.0 is a super-major release which breaks compatibility with dejafu-1.x.
Highlights reel:
- Test cases are written in terms of a new
Program
type. - The
Failure
type has been replaced with aCondition
type (actually in 1.12). - Random testing takes an optional length bound.
- Atomically-checked invariants over shared mutable state.
See the changelogs for the full details.
The Program
type
The ConcT
type is now an alias for Program Basic
.
A Program Basic
has all the instances ConcT
did, defined using the ~
instance trick, so this shouldn't be a breaking change:
instance (pty ~ Basic) => MonadTrans (Program pty)
instance (pty ~ Basic) => MonadCatch (Program pty n)
instance (pty ~ Basic) => MonadThrow (Program pty n)
instance (pty ~ Basic) => MonadMask (Program pty n)
instance (pty ~ Basic, Monad n) => MonadConc (Program pty n)
instance (pty ~ Basic, MonadIO n) => MonadIO (Program pty n)
The dontCheck
function has been removed in favour of withSetup
:
do x <- dontCheck setup
action x
-- becomes
withSetup setup action
The subconcurrency
function has been removed in favour of
withSetupAndTeardown
:
do x <- setup
y <- subconcurrency (action x)
teardown x y
-- becomes
withSetupAndTeardown setup teardown action
The dontCheck
and subconcurrency
functions used to throw runtime errors if
nested. This is not possible with withSetup
and withSetupAndTeardown
due to
their types:
withSetup
:: Program Basic n x
-- ^ Setup action
-> (x -> Program Basic n a)
-- ^ Main program
-> Program (WithSetup x) n a
withSetupAndTeardown
:: Program Basic n x
-- ^ Setup action
-> (x -> Either Condition y -> Program Basic n a)
-- ^ Teardown action
-> (x -> Program Basic n y)
-- ^ Main program
-> Program (WithSetupAndTeardown x y) n a
Previously, multiple calls to subconcurrency
could be sequenced in the same
test case. This is not possible using withSetupAndTeardown
. If you rely on
this behaviour, please file an issue.
The Condition
type
This is a change in dejafu-1.12.0.0, but the alias Failure = Condition
is removed in dejafu-2.0.0.0.
- The
STMDeadlock
andDeadlock
constructors have been merged. - Internal errors have been split into the
Error
type and are raised as exceptions, instead of being returned as conditions.
The name "failure" has been a recurring source of confusion, because an individual execution can "fail" without the predicate as a whole failing. My hope is that the more neutral "condition" will prevent this confusion.
Deprecated functions
All the deprecated special-purpose functions have been removed. Use more
general *WithSettings
functions instead.
Need help?
- For general help talk to me in IRC (barrucadu in #haskell) or shoot me an email (mike@barrucadu.co.uk)
- For bugs, issues, or requests, please file an issue.
0.x to 1.x
dejafu-1.0.0.0 is a super-major release which breaks compatibility with dejafu-0.x quite significantly, but brings with it support for bound threads, and significantly improves memory usage in the general case.
Highlights reel:
- Most predicates now only need to keep around the failures, rather than all results.
- Support for bound threads (with concurrency-1.3.0.0).
- The
ST
/IO
interface duplication is gone, everything is now monadic. - Function parameter order is closer to other testing libraries.
- Much improved API documentation.
See the changelogs for the full details.
ST
and IO
functions
There is only one set of functions now. Testing bound threads requires being
able to fork actual threads, so testing with ST
is no longer possible. The
ConcST
type is gone, there is only ConcIO
.
For dejafu change:
autocheckIO
toautocheck
dejafuIO
todejafu
dejafusIO
todejafus
autocheckWayIO
toautocheckWay
dejafuWayIO
todejafuWay
dejafusWayIO
todejafusWay
dejafuDiscardIO
todejafuDiscard
runTestM
torunTest
runTestWayM
torunTestWay
If you relied on being able to get a pure result from the ConcST
functions,
you can no longer do this.
For hunit-dejafu and tasty-dejafu change:
testAutoIO
totestAuto
testDejafuIO
totestDejafu
testDejafusIO
totestDejafus
testAutoWayIO
totestAutoWay
testDejafuWayIO
totestDejafuWay
testDejafusWayIO
totestDejafusWay
testDejafuDiscardIO
totestDejafuDiscard
Function parameter order
Like HUnit, the monadic action to test is now the last parameter of the testing functions. This makes it convenient to write tests without needing to define the action elsewhere.
For dejafu change:
dejafu ma (s, p)
todejafu s p ma
dejafus ma ps
todejafus ps ma
dejafuWay way mem ma (s, p)
todejafuWay way mem s p ma
dejafusWay way mem ma ps
todejafuWay way mem ps ma
dejafuDiscard d way mem ma (s, p)
todejafuDiscard d way mem s p ma
For hunit-dejafu and tasty-dejafu change:
testDejafu ma s p
totestDejafu s p ma
testDejafus ma ps
totestDejafus ps ma
testDejafuWay way mem ma s p
totestDejafuWay way mem s p ma
testDejafusWay way mem ma ps
totestDejafusWay way mem ps ma
testDejafuDiscard d way mem ma s p
totestDejafuDiscard d way mem s p ma
Predicates
The Predicate a
type is now an alias for ProPredicate a a
, defined like so:
data ProPredicate a b = ProPredicate
{ pdiscard :: Either Failure a -> Maybe Discard
-- ^ Selectively discard results before computing the result.
, peval :: [(Either Failure a, Trace)] -> Result b
-- ^ Compute the result with the un-discarded results.
}
If you use the predicate helper functions to construct a predicate, you do not need to change anything (and should get a nice reduction in your resident memory usage). If you supply a function directly, you can recover the old behaviour like so:
old :: ([(Either Failure a, Trace)] -> Result a) -> ProPredicate a a
old p = ProPredicate
{ pdiscard = const Nothing
, peval = p
}
The alwaysTrue2
helper function is gone. If you use it, use alwaysSameOn
or
alwaysSameBy
instead.
Need help?
- For general help talk to me in IRC (barrucadu in #haskell) or shoot me an email (mike@barrucadu.co.uk)
- For bugs, issues, or requests, please file an issue.
Contributing
Thanks for caring about Déjà Fu!
Ways to contribute
Déjà Fu is a project under active development, there's always something to do. Here's a list of ideas to get you started:
- Submit bug reports.
- Submit feature requests.
- Got a particularly slow test case which you think should be faster? Open an issue for that too.
- Blog about how and why you use Déjà Fu.
- Check if any bugs which have been open for a while are still bugs.
If you want to contribute code, you could:
- Tackle one of the issues tagged "good first issue".
- Tackle a bigger issue, perhaps one of the roadmap issues!
- Run code coverage and try to fix a gap in the tests.
- Profile the test suite and try to improve a slow function.
Roadmap issues are priority issues (in my opinion), so help with those is especially appreciated.
If you have a support question, you can talk to me on IRC (#haskell on freenode) or send an email (mike@barrucadu.co.uk) rather than opening an issue. But maybe your question is a bug report about poor documentation in disguise!
Making the change
-
Talk to me!
I don't bite, and chances are I can quickly tell you where you should start. It's better to ask what seems like a stupid question than to waste a lot of time on the wrong approach.
-
Make the change.
Figure out what needs to be changed, how to change it, and do it. If you're fixing a bug, make sure to add a minimal reproduction to Cases.Regressions in dejafu-tests.
-
Document the change.
All top-level definitions should have a Haddock comment explaining what it does. If you've added or changed a top-level function, consider commenting its arguments too.
If you've added a top-level definition, or changed one in a backwards-incompatible way, add an
@since unreleased
Haddock comment to it. This is to help prevent me from missing things when I update the changelog ahead of a release. -
Submit a PR.
GitHub Actions will run some checks, which might prompt further action. You should expect a response from me in a day or two.
Don't worry about your PR being perfect the first time. We'll work through any issues together, to ensure that Déjà Fu gets the best code it can.
Coding style
There isn't really a prescribed style. It's not quite the wild west though; keep these three rules in mind:
- Be consistent.
- Run stylish-haskell to format import lists.
- Use hlint and weeder and fix lints unless you have a good reason not to.
GitHub Actions runs stylish-haskell and hlint on all PRs.
Coverage
hpc can generate a coverage report from the execution of dejafu-tests:
$ stack build --coverage
$ stack exec dejafu-tests
$ stack hpc report --all dejafu-tests.tix
This will print some stats and generate an HTML coverage report:
Generating combined report
52% expressions used (4052/7693)
48% boolean coverage (63/129)
43% guards (46/106), 31 always True, 9 always False, 20 unevaluated
68% 'if' conditions (11/16), 2 always True, 3 unevaluated
85% qualifiers (6/7), 1 unevaluated
61% alternatives used (392/635)
80% local declarations used (210/261)
26% top-level declarations used (280/1063)
The combined report is available at /home/barrucadu/projects/dejafu/.stack-work/install/x86_64-linux/nightly-2016-06-20/8.0.1/hpc/combined/custom/hpc_index.html
The highlighted code in the HTML report emphasises branch coverage:
- Red means a branch was evaluated as always false.
- Green means a branch was evaluated as always true.
- Yellow means an expression was never evaluated.
See also the stack coverage documentation.
Performance
GHC can generate performance statistics from the execution of dejafu-tests:
$ stack build --profile
$ stack exec -- dejafu-tests +RTS -p
$ less dejafu-tests.prof
This prints a detailed breakdown of where memory and time are being spent:
Mon Mar 20 19:26 2017 Time and Allocation Profiling Report (Final)
dejafu-tests +RTS -p -RTS
total time = 105.94 secs (105938 ticks @ 1000 us, 1 processor)
total alloc = 46,641,766,952 bytes (excludes profiling overheads)
COST CENTRE MODULE %time %alloc
findBacktrackSteps.doBacktrack.idxs' Test.DejaFu.SCT.Internal 21.9 12.0
== Test.DejaFu.Common 12.4 0.0
yieldCount.go Test.DejaFu.SCT 12.1 0.0
dependent' Test.DejaFu.SCT 5.1 0.0
runThreads.go Test.DejaFu.Conc.Internal 2.7 4.1
[...]
Be careful, however! Compiling with profiling can significantly affect the behaviour of a program! Use profiling to get an idea of where the hot spots are, but make sure to confirm with a non-profiled build that things are actually getting faster.
If you compile with -rtsopts
you can get some basic stats from a non-profiled
build:
$ stack exec -- dejafu-tests +RTS -s
[...]
86,659,658,504 bytes allocated in the heap
13,057,037,448 bytes copied during GC
13,346,952 bytes maximum residency (4743 sample(s))
127,824 bytes maximum slop
37 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 78860 colls, 0 par 32.659s 32.970s 0.0004s 0.0669s
Gen 1 4743 colls, 0 par 3.043s 3.052s 0.0006s 0.0086s
TASKS: 174069 (174065 bound, 4 peak workers (4 total), using -N1)
SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
INIT time 0.001s ( 0.001s elapsed)
MUT time 98.685s (101.611s elapsed)
GC time 35.702s ( 36.022s elapsed)
EXIT time 0.001s ( 0.007s elapsed)
Total time 134.388s (137.640s elapsed)
Alloc rate 878,145,635 bytes per MUT second
Productivity 73.4% of total user, 73.8% of total elapsed
Heap profiling
GHC can tell you where the memory is going:
$ stack build --profile
$ stack exec -- dejafu-tests +RTS -hc
$ hp2ps -c dejafu-tests.hp
This will produce a graph of memory usage over time, as a postscript file, broken down by cost-centre which produced the data. There are a few different views:
-hm
breaks down the graph by module-hd
breaks down the graph by closure description-hy
breaks down the graph by type
I typically find -hd
and -hy
most useful. If you're feeling particularly
brave, you can try -hr
, which is intended to help track down memory leaks
caused by unevaluated thunks.
Supported GHC Versions
Déjà Fu supports the latest four GHC releases, at least. For testing purposes, we use Stackage snapshots as a proxy for GHC versions. The currently supported versions are:
GHC | Stackage | base |
---|---|---|
9.6 | Nightly 2021-07-01 | 4.18.0.0 |
9.4 | LTS 21.0 | 4.17.0.0 |
9.2 | LTS 20.0 | 4.16.0.0 |
9.0 | LTS 19.0 | 4.15.0.0 |
8.1 | ,LTS 17.0 | 4.14.1.0 |
8.8 | LTS 15.0 | 4.13.0.0 |
8.6 | LTS 14.0 | 4.12.0.0 |
8.4 | LTS 12.0 | 4.11.0.0 |
8.2 | LTS 10.0 | 4.10.1.0 |
In practice, we may compile with older versions of GHC, but keeping them working is not a priority.
Adding new GHC releases
When a new version of GHC is released, we need to make some changes for everything to go smoothly. In general, these changes should only cause a patch level version bump.
- Bump the upper bound of base and set up any needed conditional compilation
- Add the GHC and base versions to the table.
- Remove any unsupported versions from the table.
- Make a patch release.
A new GHC release won't get a Stackage snapshot for little while. When it does:
- Add the snapshot to the GitHub Actions configuration.
- Update the resolver in the stack.yaml.
- Put the snapshot in the table.
Dropping old GHC releases
When we want to drop an unsupported version of GHC, we need to bump the version bound on base to preclude it. This is a backwards-incompatible change which causes a major version bump.
- Remove the dropped GHC version from the GitHub Actions configuration.
- Bump the lower bound of base.
- Look through the other dependencies. Some may not work with our new lower bound on base, so we should bump those too.
- Remove any now-irrelevant conditional compilation (mostly CPP, but there may also be some cabal file bits).
- Make whatever change required the bump.
- Make a major release.
GHC versions shouldn't be dropped just because we can, but here are some good reasons to do it:
- We want to bump the lower bounds of a dependency to a version which doesn't support that GHC.
- We want to add a new dependency which doesn't support that GHC.
- The conditional compilation needed to keep that GHC working is getting confusing.
Release Process
-
Figure out what the next version number is. See the PVP_ page if unsure.
-
Update version numbers in the relevant cabal files:
- Update the
version
field - Update the
tag
in thesource-repository
block
- Update the
-
Fill in all
@since unreleased
Haddock comments with the relevant version number. -
Update version numbers in the tables in the README page.
-
Ensure the relevant CHANGELOG files have all the entries they should.
-
Add the release information to the relevant CHANGELOG files:
- Change the
unreleased
title to the version number - Add the current date
- Add the git tag name
- Add the Hackage URL
- Add the contributors list
- Change the
-
Commit.
-
Push to GitHub and wait for GitHub Actions to confirm everything is OK. If it's not OK, fix what is broken before continuing.
-
Merge the PR.
-
Tag the merge commit. Tags are in the form
<package>-<version>
, and the message is the changelog entry. -
Push tags to GitHub.
When the merge commit successfully builds on master
the updated packages will
be pushed to Hackage by Concourse.
Pro tips
-
If a release would have a combination of breaking and non-breaking changes, if possible make two releases: the non-breaking ones first, and then a major release with the breaking ones.
This makes it possible for users who don't want the breaking changes to still benefit from the non-breaking improvements.
-
Before uploading to Hackage, check you have no changes to the files (for example, temporarily changing the GHC options, or adding
trace
calls, for debugging reasons).stack upload
will upload the files on the disk, not the files in version control, so your unwanted changes will be published!
Release Notes
This project is versioned according to the PVP, the de facto standard Haskell versioning scheme.
1.11.0.3 (2023-06-17)
- Git: concurrency-1.11.0.3
- Hackage: concurrency-1.11.0.3
Miscellaneous
- The upper bound on mtl is <2.4.
- The upper bound on transformers is <0.7.
1.11.0.2 (2021-08-15)
- Git: concurrency-1.11.0.2
- Hackage: concurrency-1.11.0.2
Miscellaneous
- Remove reference to freenode in README.
1.11.0.1 (2021-03-14)
- Git: concurrency-1.11.0.1
- Hackage: concurrency-1.11.0.1
Fixed
- (issue #334) Compilation error under GHC 9 due to use of
const
.
1.11.0.0 (2020-05-14)
- Git: concurrency-1.11.0.0
- Hackage: concurrency-1.11.0.0
Contributors: mitchellwrosen (pull request #319).
Added
- (issue #316)
Control.Monad.Conc.Class.unsafeUnmask
. Control.Monad.Conc.Class.interruptible
.
1.10.0.0 (2020-05-10)
- Git: concurrency-1.10.0.0
- Hackage: concurrency-1.10.0.0
Added
- (issue #312)
Control.Monad.Conc.Class.getMaskingState
.
1.9.0.0 (2020-02-26)
- Git: concurrency-1.9.0.0
- Hackage: concurrency-1.9.0.0
Changed
-
(issue #286) Pulled in changes from stm-2.5.0.0 package:
- Changed
newTBQueue
to acceptNatural
as a size. - Changed
lengthTBQueue
to return aNatural
.
- Changed
1.8.1.0 (2019-11-16)
- Git: concurrency-1.8.1.0
- Hackage: concurrency-1.8.1.0
Added
- (issue #303)
Control.Monad.Conc.Class.newTVarConc
, with a default implementation ofatomically . newTVar
.
1.8.0.0 (2019-10-04)
- Git: concurrency-1.8.0.0
- Hackage: concurrency-1.8.0.0
Added
MonadFail
instances forControl.Monad.Conc.Class.IsConc
andControl.Monad.STM.IsSTM
.
Changed
- Added
MonadFail
constraints toControl.Concurrent.Classy.QSem.newQSem
andControl.Concurrent.Classy.QSemN.newQSemN
.
Miscellaneous
- Fixed a compilation error with GHC 8.8
1.7.0.0 (2019-03-24)
- Git: concurrency-1.7.0.0
- Hackage: concurrency-1.7.0.0
Added
- The
Control.Monad.Conc.Class.supportsBoundThreads
function, likertsSupportsBoundThreads
but returns a monadic result.
Deprecated
Control.Monad.Conc.Class.rtsSupportsBoundThreads
, in favour ofsupportsBoundThreads
.
1.6.2.0 (2018-11-28)
- Git: concurrency-1.6.2.0
- Hackage: concurrency-1.6.2.0
Contributors: gip (pull request #289).
Added
- (pull request #289) The
Control.Concurrent.Classy.BoundedChan
module. - (pull request #289) The
Control.Concurrent.Classy.Lock
module. - (pull request #289) The
Control.Concurrent.Classy.RWLock
module.
1.6.1.0 (2018-09-23)
- Git: concurrency-1.6.1.0
- Hackage: concurrency-1.6.1.0
Added
-
(issue #286) Copy across additions from the stm package:
Control.Concurrent.Classy.STM.TQueue.flushTQueue
Control.Concurrent.Classy.STM.TBQueue.flushTBQueue
Control.Concurrent.Classy.STM.TBQueue.lengthTBQueue
Control.Concurrent.Classy.STM.TVar.stateTVar
-
(issue #287) The
Control.Concurrent.Classy.STM.TSem
module.
Changed
-
(issue #286) Copy across changes from the stm package:
- Make definition of
readTQueue
consistent withreadTBQueue
- Performance improvements to
peekTQueue
andpeekTBQueue
.
- Make definition of
Miscellaneous
- The upper bound on stm is <2.6.
1.6.0.0 - IORefs (2018-07-01)
- Git: concurrency-1.6.0.0
- Hackage: concurrency-1.6.0.0
Added
Control.Concurrent.Classy.CRef
, deprecated*CRef
functions and aCRef
alias.
Changed
- (issue #274)
CRef
is nowIORef
: all functions, modules, and types have been renamed.
1.5.0.0 - No More 7.10 (2018-03-28)
- Git: concurrency-1.5.0.0
- Hackage: concurrency-1.5.0.0
Added
- (issue #132)
forkOSWithUnmask
inMonadConc
Changed
- (issue #132)
Control.Monad.Conc.Class.fork
,forkOn
,forkOS
, andforkOSN
are top-level definitions.
Miscellaneous
-
GHC 7.10 support is dropped. Dependency lower bounds are:
- base: 4.9
- array: 0.5.1
- transformers: 0.5
1.4.0.2 (2018-03-11)
- Git: concurrency-1.4.0.2
- Hackage: concurrency-1.4.0.2
Miscellaneous
- (pull request #245) The upper bound on exceptions is <0.11.
1.4.0.1 (2018-02-26)
- Git: concurrency-1.4.0.1
- Hackage: concurrency-1.4.0.1
Miscellaneous
- The upper bound on exceptions is <0.10.
1.4.0.0 (2018-01-19)
- Git: concurrency-1.4.0.0
- Hackage: concurrency-1.4.0.0
Changed
-
Control.Monad.Conc.Class.peekTicket'
has a more concrete type, to make deriving newtype instances ofMonadConc
possible:- Old:
MonadConc m => proxy m -> Ticket m a -> a
- New:
MonadConc m => Proxy m -> Ticket m a -> a
- Old:
1.3.0.0 - The Bound Thread Release (2017-12-23)
- Git: concurrency-1.3.0.0
- Hackage: concurrency-1.3.0.0
Note: bound threads are only supported if you compile with GHC and link with -threaded.
Added
-
(pull request #145) Bound thread variants of the
withAsync
functions:Control.Concurrent.Classy.Async.asyncBound
Control.Concurrent.Classy.Async.asyncBoundN
Control.Concurrent.Classy.Async.withAsyncBound
Control.Concurrent.Classy.Async.withAsyncBoundN
-
(pull request #145) Bound thread functions in
MonadConc
:Control.Monad.Conc.Class.forkOS
Control.Monad.Conc.Class.forkOSN
Control.Monad.Conc.Class.isCurrentThreadBound
-
(pull request #145) Helper functions for bound threads:
Control.Monad.Conc.Class.runInBoundThread
Control.Monad.Conc.Class.runInUnboundThread
Changed
- (pull request #145)
Control.Monad.Conc.Class.rtsSupportsBoundThreads
is a re-export fromControl.Concurrent
.
1.2.3.0 (2017-11-30)
- Git: concurrency-1.2.3.0
- Hackage: concurrency-1.2.3.0
Added
-
(issue #148) Named thread variants of the
withAsync
functions:Control.Concurrent.Classy.Async.withAsyncN
Control.Concurrent.Classy.Async.withAsyncOnN
Control.Concurrent.Classy.Async.withAsyncWithUnmaskN
Control.Concurrent.Classy.Async.withAsyncOnWithUnmaskN
1.2.2.0 (2017-11-05)
- Git: concurrency-1.2.2.0
- Hackage: concurrency-1.2.2.0
Added
-
(issue #144)
IsConc
andIsSTM
wrapper types:Control.Monad.Conc.Class.IsConc
(constructor unexported)Control.Monad.Conc.Class.toIsConc
Control.Monad.Conc.Class.fromIsConc
Control.Monad.STM.Class.IsSTM
(constructor unexported)Control.Monad.STM.Class.toIsSTM
Control.Monad.STM.Class.fromIsSTM
Changed
Control.Monad.Conc.Class.modifyCRefCAS_
for transformer instances delegates to the underlying monad, rather than using the default definition in terms ofmodifyCRefCAS
.
1.2.1.2 (2017-10-14)
- Git: concurrency-1.2.1.2
- Hackage: concurrency-1.2.1.2
Fixed
- (issue #134)
Control.Monad.Conc.Class.forkWithUnmask
andforkOnWithUnmask
for theIO
instance does not infinitely loop (bug introduced in concurrency-1.2.1.1).
1.2.1.1 (2017-10-11)
- Git: concurrency-1.2.1.1
- Hackage: concurrency-1.2.1.1
Changed
- Named threads for
IO
are implemented withGHC.Conc.labelThread
.
1.2.1.0 (2017-10-02)
- Git: concurrency-1.2.1.0
- Hackage: concurrency-1.2.1.0
Added
-
(pull request #125) Named thread variants of the
async
functions:Control.Concurrent.Classy.Async.asyncN
Control.Concurrent.Classy.Async.asyncOnN
Control.Concurrent.Classy.Async.asyncWithUnmaskN
Control.Concurrent.Classy.Async.asyncOnWithUnmaskN
1.2.0.0 (2017-09-16)
- Git: concurrency-1.2.0.0
- Hackage: concurrency-1.2.0.0
Changed
MonadPlus
is a superclass ofMonadSTM
.Control.Monad.STM.Class.orElse
is a top-level alias formplus
.Control.Monad.STM.Class.retry
is a top-level alias formzero
.
1.1.2.1 (2017-06-07)
- Git: concurrency-1.1.2.1
- Hackage: concurrency-1.1.2.1
Changed
Control.Concurrent.Classy.MVar.isEmptyMVar
does not briefly empties theMVar
, and does not block.
1.1.2.0 (2017-04-05)
- Git: concurrency-1.1.2.0
- Hackage: concurrency-1.1.2.0
Added
-
Missing functions copied from async:
Control.Concurrent.Classy.Async.uninterruptibleCancel
Control.Concurrent.Classy.Async.replicateConcurrently
Control.Concurrent.Classy.Async.concurrently_
Control.Concurrent.Classy.Async.mapConcurrently_
Control.Concurrent.Classy.Async.forConcurrently_
Control.Concurrent.Classy.Async.replicateConcurrently_
-
Control.Concurrent.Classy.Async.Concurrently
has aSemigroup
instance when built with base >= 4.9. -
Control.Concurrent.Classy.Async.Concurrently
has aMonoid
instance. -
Control.Monad.Conc.Class
re-exportsControl.Monad.Catch.mask_
anduninterruptibleMask_
.
Changed
- (pull request #77) To match changes in async,
Control.Concurrent.Classy.Async.cancel
andwithAsync
block until theAsync
is killed.
Miscellaneous
- Every definition, class, and instance now has a Haddock
@since
annotation.
1.1.1.0 - The Async Release (2017-03-04)
- Git: concurrency-1.1.1.0
- Hackage: concurrency-1.1.1.0
Added
- The
Control.Concurrent.Classy.Async
module.
1.1.0.0 (2017-02-21)
- Git: concurrency-1.1.0.0
- Hackage: concurrency-1.1.0.0
Added
Control.Monad.Conc.Class.tryReadMVar
Removed
Control.Monad.Conc.Class._concMessage
1.0.0.0 - The Initial Release (2016-09-10)
- Git: concurrency-1.0.0.0
- Hackage: concurrency-1.0.0.0
Added
- Everything.
Release Notes
This project is versioned according to the PVP, the de facto standard Haskell versioning scheme.
2.4.0.6 (2024-12-11)
- Git: dejafu-2.4.0.6
- Hackage: dejafu-2.4.0.6
Contributors: telser (pull request #417).
Miscellaneous
- Update documentation link in
Test.DejaFu
. - Fix GHC compatibility warning.
- The upper bound on containers is <0.8.
2.4.0.5 (2023-06-17)
- Git: dejafu-2.4.0.5
- Hackage: dejafu-2.4.0.5
Miscellaneous
- The upper bound on transformers is <0.7.
2.4.0.4 (2022-08-22)
- Git: dejafu-2.4.0.4
- Hackage: dejafu-2.4.0.4
Miscellaneous
- Update doctest examples in
Test.DejaFu
. - The upper bound on leancheck is <2.
2.4.0.3 (2021-08-15)
- Git: dejafu-2.4.0.3
- Hackage: dejafu-2.4.0.3
Miscellaneous
- Remove reference to freenode in README.
2.4.0.2 (2021-03-14)
- Git: dejafu-2.4.0.2
- Hackage: dejafu-2.4.0.2
Fixed
- (issue #334) Compilation error under GHC 9 due to use of
const
.
2.4.0.1 (2020-12-28)
- Git: dejafu-2.4.0.1
- Hackage: dejafu-2.4.0.1
Fixed
- (issue #331) Initial TVar values from setup actions are now restored for subsequent executions.
2.4.0.0 (2020-07-01)
- Git: dejafu-2.4.0.0
- Hackage: dejafu-2.4.0.0
Added
- Thread action constructor for STM transactions which throw an
exception:
Test.DejaFu.Types.ThreadAction
ThrownSTM
Changed
Test.DejaFu.Types.ThreadAction
,Throw
, andThrowTo
now include the resultant masking state, and no bool.
Fixed
- (issue #324) Jumping out of a restored mask into an exception handler now atomically restores the masking state.
2.3.0.1 (2020-06-24)
- Git: dejafu-2.3.0.1
- Hackage: dejafu-2.3.0.1
Miscellaneous
- The upper bound on random is <1.3.
2.3.0.0 (2020-05-14)
- Git: dejafu-2.3.0.0
- Hackage: dejafu-2.3.0.0
Miscellaneous
- The version bound on concurrency is >=1.11 <1.12.
2.2.0.0 (2020-05-10)
- Git: dejafu-2.2.0.0
- Hackage: dejafu-2.2.0.0
Added
-
Thread action constructors for the
MonadConc
getMaskingState
function:Test.DejaFu.Types.ThreadAction
,GetMaskingState
Test.DejaFu.Types.Lookahead
,WillGetMaskingState
Miscellaneous
- The version bound on concurrency is >=1.10 <1.11.
2.1.0.3 (2020-02-29)
- Git: dejafu-2.1.0.3
- Hackage: dejafu-2.1.0.3
Fixed
- Fixed an internal error message.
2.1.0.2 (2020-02-29)
- Git: dejafu-2.1.0.2
- Hackage: dejafu-2.1.0.2
Miscellaneous
- The upper version bound on concurrency is <1.10.
2.1.0.1 (2019-10-04)
- Git: dejafu-2.1.0.1
- Hackage: dejafu-2.1.0.1
Miscellaneous
- Fixed a compilation error with GHC 8.8
- The upper version bound on concurrency is <1.9.
2.1.0.0 (2019-03-24)
- Git: dejafu-2.1.0.0
- Hackage: dejafu-2.1.0.0
Added
-
The
Test.DejaFu.Types.MonadDejaFu
typeclass, containing the primitives needed to run a concurrent program. There are instances for:IO
, which is probably theMonadConc
instance people used previously, so there is no breaking change there.CatchT (ST t)
, meaning that concurrent programs can be run withoutIO
once more.
-
Thread action constructors for
MonadConc
supportsBoundThreads
function:Test.DejaFu.Types.ThreadAction
,SupportsBoundThreads
Test.DejaFu.Types.Lookahead
,WillSupportsBoundThreads
Changed
-
Many functions which had a
MonadConc
constraint now have aMonadDejaFu
constraint:-
In
Test.DejaFu
autocheck
autocheckWay
autocheckWithSettings
dejafu
dejafuWay
dejafuWithSettings
dejafus
dejafusWay
dejafusWithSettings
runTest
runTestWay
runTestWithSettings
-
In
Test.DejaFu.Conc
runConcurrent
recordSnapshot
runSnapshot
-
In
Test.DejaFu.SCT
runSCT
resultsSet
runSCT'
resultsSet'
runSCTWithSettings
resultsSetWithSettings
runSCTWithSettings'
resultsSetWithSettings'
-
Miscellaneous
- The version bound on concurrency is >=1.7 and <1.8.
2.0.0.1 (2019-03-14)
- Git: dejafu-2.0.0.1
- Hackage: dejafu-2.0.0.1
Fixed
- (issue #267) Throwing an asynchronous exception to the current thread interrupts the current thread even if it is masked.
2.0.0.0 (2019-02-12)
- Git: dejafu-2.0.0.0
- Hackage: dejafu-2.0.0.0
Added
-
The
Program
types and their constructors (re-exported fromTest.DejaFu
):Test.DejaFu.Conc.Program
Test.DejaFu.Conc.Basic
Test.DejaFu.Conc.WithSetup
Test.DejaFu.Conc.WithSetupAndTeardown
Test.DejaFu.Conc.withSetup
Test.DejaFu.Conc.withTeardown
Test.DejaFu.Conc.withSetupAndTeardown
-
The
Invariant
type and associated functions (re-exported fromTest.DejaFu
):Test.DejaFu.Conc.Invariant
Test.DejaFu.Conc.registerInvariant
Test.DejaFu.Conc.inspectIORef
Test.DejaFu.Conc.inspectMVar
Test.DejaFu.Conc.inspectTVar
-
New snapshotting functions:
Test.DejaFu.Conc.Snapshot
Test.DejaFu.Conc.recordSnapshot
Test.DejaFu.Conc.runSnapshot
-
Test.DejaFu.Settings.llengthBound
, which now applies to all ways of testing. -
Test.DejaFu.Types.isInvariantFailure
(re-exported fromTest.DejaFu
). -
Test.DejaFu.runTestWithSettings
function. -
A simplified form of the concurrency state:
Test.DejaFu.Types.ConcurrencyState
Test.DejaFu.Types.isBuffered
Test.DejaFu.Types.numBuffered
Test.DejaFu.Types.isFull
Test.DejaFu.Types.canInterrupt
Test.DejaFu.Types.canInterruptL
Test.DejaFu.Types.isMaskedInterruptible
Test.DejaFu.Types.isMaskedUninterruptible
Changed
-
Test.DejaFu.Schedule.Scheduler
has aConcurrencyState
parameter. -
Test.DejaFu.alwaysSameBy
andTest.DejaFu.notAlwaysSameBy
return a representative trace for each unique condition. -
Functions which took a
ConcT
now take aProgram pty
:Test.DejaFu.autocheck
Test.DejaFu.autocheckWay
Test.DejaFu.autocheckWithSettings
Test.DejaFu.dejafu
Test.DejaFu.dejafuWay
Test.DejaFu.dejafuWithSettings
Test.DejaFu.dejafus
Test.DejaFu.dejafusWay
Test.DejaFu.dejafusWithSettings
Test.DejaFu.runTest
Test.DejaFu.runTestWay
Test.DejaFu.runTestWithSettings
Test.DejaFu.Conc.runConcurrent
Test.DejaFu.SCT.runSCT
Test.DejaFu.SCT.resultsSet
Test.DejaFu.SCT.runSCT'
Test.DejaFu.SCT.resultsSet'
Test.DejaFu.SCT.runSCTWithSettings
Test.DejaFu.SCT.resultsSetWithSettings
Test.DejaFu.SCT.runSCTWithSettings'
Test.DejaFu.SCT.resultsSetWithSettings'
-
Test.DejaFu.Conc.ConcT
is an alias forProgram Basic
. -
Test.DejaFu.Types.Bounds
:- Removed
boundLength
field.
- Removed
-
Test.DejaFu.Types.Condition
:- Added
InvariantFailure
constructor - Removed
STMDeadlock
constructor
- Added
-
Test.DejaFu.Types.Error
:- Removed
NestedSubconcurrency
,MultithreadedSubconcurrency
, andLateDontCheck
constructors.
- Removed
-
Test.DejaFu.Types.Lookahead
:- Added
WillRegisterInvariant
constructor - Removed
WillSubconcurrency
,WillStopSubconcurrency
, andWillDontCheck
constructors
- Added
-
Test.DejaFu.Types.ThreadAction
:- Added
RegisterInvariant
constructor - Removed
Subconcurrency
,StopSubconcurrency
, andDontCheck
constructors
- Added
Removed
-
The deprecated functions:
Test.DejaFu.dejafuDiscard
Test.DejaFu.SCT.runSCTDiscard
Test.DejaFu.SCT.runSCTDiscard'
Test.DejaFu.SCT.resultsSetDiscard
Test.DejaFu.SCT.resultsSetDiscard'
Test.DejaFu.SCT.sctBound
Test.DejaFu.SCT.sctBoundDiscard
Test.DejaFu.SCT.sctUniformRandom
Test.DejaFu.SCT.sctUniformRandomDiscard
Test.DejaFu.SCT.sctWeightedRandom
Test.DejaFu.SCT.sctWeightedRandomDiscard
-
The deprecated type
Test.DejaFu.Types.Failure
-
Old snapshotting functions:
Test.DejaFu.Conc.DCSnapshot
Test.DejaFu.Conc.runForDCSnapshot
Test.DejaFu.Conc.runWithDCSnapshot
Test.DejaFu.Conc.canDCSnapshot
Test.DejaFu.Conc.threadsFromDCSnapshot
-
Test.DejaFu.Conc.dontCheck
-
Test.DejaFu.Conc.subconcurrency
-
Test.DejaFu.Settings.defaultLengthBound
-
Test.DejaFu.Types.isIncorrectUsage
1.12.0.0 (2019-01-20)
- Git: dejafu-1.12.0.0
- Hackage: dejafu-1.12.0.0
Added
-
Test.DejaFu.Types.Error
for internal errors and misuses, with predicates:Test.DejaFu.Types.isSchedulerError
Test.DejaFu.Types.isIncorrectUsage
-
Deprecated
Test.DejaFu.Types.Failure
type synonym forCondition
. -
The
Test.DejaFu.Settings.lshowAborts
option, to make SCT functions showAbort
conditions. -
Test.DejaFu.Utils.showCondition
Changed
- Renamed
Test.DejaFu.Types.Failure
toTest.DejaFu.Types.Condition
. - The SCT functions drop
Left Abort
results by default, restore the old behaviour withTest.DejaFu.Settings.lshowAborts
.
Removed
Test.DejaFu.Types.isInternalError
Test.DejaFu.Types.isIllegalDontCheck
Test.DejaFu.Types.isIllegalSubconcurrency
Test.DejaFu.Utils.showFail
1.11.0.5 (2019-01-17)
- Git: dejafu-1.11.0.5
- Hackage: dejafu-1.11.0.5
Miscellaneous
- The upper bound on leancheck is <0.10.
1.11.0.4 (2018-12-02)
- Git: dejafu-1.11.0.4
- Hackage: dejafu-1.11.0.4
Contributors: pepeiborra (pull request #290).
Miscellaneous
- (pull request #290) The upper bound on containers is <0.7.
- (pull request #290) The upper bound on leancheck is <0.9.
1.11.0.3 (2018-07-15)
- Git: dejafu-1.11.0.3
- Hackage: dejafu-1.11.0.3
Fixed
- (issue #275) In trace simplification, only remove a commit if
there are no other buffered writes for that same
IORef
.
1.11.0.2 (2018-07-08)
- Git: dejafu-1.11.0.2
- Hackage: dejafu-1.11.0.2
Miscellaneous
- The upper bound on profunctors is <6.
1.11.0.1 (2018-07-02)
- Git: dejafu-1.11.0.1
- Hackage: dejafu-1.11.0.1
Miscellaneous
- The upper bound on contravariant is <1.6.
1.11.0.0 - IORefs (2018-07-01)
- Git: dejafu-1.11.0.0
- Hackage: dejafu-1.11.0.0
Changed
- (issue #274)
CRef
is nowIORef
: all functions, data constructors, and types have been renamed. - The lower bound on concurrency is 1.6.
1.10.1.0 (2018-06-17)
- Git: dejafu-1.10.1.0
- Hackage: dejafu-1.10.1.0
Added
- (issue #224) The
Test.DejaFu.Settings.lsafeIO
option, for when all lifted IO is thread-safe (such as exclusively managing thread-local state).
1.10.0.0 (2018-06-17)
- Git: dejafu-1.10.0.0
- Hackage: dejafu-1.10.0.0
Added
- The
Test.DejaFu.notAlwaysSameOn
andnotAlwaysSameBy
predicates, generalisingnotAlwaysSame
.
Changed
Test.DejaFu.autocheck
and related functions use thesuccessful
predicate, rather than looking specifically for deadlocks and uncaught exceptions.- (issue #259) The
Test.DejaFu.alwaysSame
,alwaysSameOn
,alwaysSameBy
, andnotAlwaysSame
predicates fail if the computation under test fails.
1.9.1.0 (2018-06-10)
- Git: dejafu-1.9.1.0
- Hackage: dejafu-1.9.1.0
Added
- A
Test.DejaFu.successful
predicate, to check that a computation never fails.
1.9.0.0 (2018-06-10)
- Git: dejafu-1.9.0.0
- Hackage: dejafu-1.9.0.0
Changed
- (issue #190)
Test.DejaFu.Types.Throw
andThrowTo
have aBool
parameter, which isTrue
if the exception kills the thread.
1.8.0.0 (2018-06-03)
- Git: dejafu-1.8.0.0
- Hackage: dejafu-1.8.0.0
Changed
- (issue #258) Length bounding is disabled by default. This is not a breaking API change, but it is a breaking semantics change.
1.7.0.0 (2018-06-03)
- Git: dejafu-1.7.0.0
- Hackage: dejafu-1.7.0.0
Changed
- (issue #237)
Test.DejaFu.SCT.sctWeightedRandom
andsctWeightedRandomDiscard
no longer take the number of executions to use the same weights for as a parameter.
Removed
- (issue #237) The deprecated function
Test.DejaFu.Settings.swarmy
.
1.6.0.0 (2018-05-11)
- Git: dejafu-1.6.0.0
- Hackage: dejafu-1.6.0.0
Removed
- The deprecated module
Test.DejaFu.Defaults
.
1.5.1.0 (2018-03-29)
- Git: dejafu-1.5.1.0
- Hackage: dejafu-1.5.1.0
Added
- (issue #210)
Test.DejaFu.Types.Weaken
andStrengthen
newtype wrappers around discard functions, withSemigroup
,Monoid
,Contravariant
, andDivisible
instances corresponding toweakenDiscard
andstrengthenDiscard
.
1.5.0.0 - No More 7.10 (2018-03-28)
- Git: dejafu-1.5.0.0
- Hackage: dejafu-1.5.0.0
Miscellaneous
-
GHC 7.10 support is dropped. Dependency lower bounds are:
- base: 4.9
- concurrency: 1.5
- transformers: 0.5
-
The upper bound on concurrency is 1.6.
1.4.0.0 (2018-03-17)
- Git: dejafu-1.4.0.0
- Hackage: dejafu-1.4.0.0
Changed
- (issue #201)
Test.DejaFu.Conc.ConcT r n a
drops itsr
parameter, becomingConcT n a
. - (issue #201) All functions drop the
MonadConc
constraint.
Removed
- (issue #201) The
MonadRef
andMonadAtomicRef
instances forTest.DejaFu.Conc.ConcT
. - (issue #198) The
Test.DejaFu.Types.Killed
thread action, which was unused.
Fixed
- (issue #250) Add missing dependency for
throwTo
actions.
1.3.2.0 (2018-03-12)
- Git: dejafu-1.3.2.0
- Hackage: dejafu-1.3.2.0
Added
-
(issue #183) SCT settings for trace simplification:
Test.DejaFu.Settings.lequality
Test.DejaFu.Settings.lsimplify
-
(pull request #248)
Test.DejaFu.Utils.toTIdTrace
to extract thread IDs from a trace. -
(pull request #248) SCT setting to make some recoverable errors fatal:
Test.DejaFu.Settings.ldebugFatal
Performance
- (pull request #248) Prune some unnecessary interleavings of
CRef
actions in systematic testing when using sequential consistency.
1.3.1.0 (2018-03-11)
- Git: dejafu-1.3.1.0
- Hackage: dejafu-1.3.1.0
Added
-
(pull request #246)
Generic
instances for:Test.DejaFu.Types.ThreadId
Test.DejaFu.Types.CRefId
Test.DejaFu.Types.MVarId
Test.DejaFu.Types.TVarId
Test.DejaFu.Types.Id
Test.DejaFu.Types.ThreadAction
Test.DejaFu.Types.Lookahead
Test.DejaFu.Types.TAction
Test.DejaFu.Types.Decision
Test.DejaFu.Types.Failure
Test.DejaFu.Types.Bounds
Test.DejaFu.Types.PreemptionBound
Test.DejaFu.Types.FairBound
Test.DejaFu.Types.LengthBound
Test.DejaFu.Types.Discard
Test.DejaFu.Types.MemType
Test.DejaFu.Types.MonadFailException
-
(pull request #246)
NFData
instance forTest.DejaFu.Types.MonadFailException
Fixed
- (issue #199) Missing cases in the
NFData
instances forTest.DejaFu.Types.ThreadAction
andTAction
1.3.0.3 (2018-03-11)
- Git: dejafu-1.3.0.3
- Hackage: dejafu-1.3.0.3
Miscellaneous
- (pull request #245) The upper bound on exceptions is <0.11.
1.3.0.2 (2018-03-11)
- Git: dejafu-1.3.0.2
- Hackage: dejafu-1.3.0.2
Fixed
- (pull request #244) Add missing dependency for
setNumCapabilities
actions.
1.3.0.1 (2018-03-08)
- Git: dejafu-1.3.0.1
- Hackage: dejafu-1.3.0.1
Fixed
- (pull request #242) A compilation error when building with exceptions-0.9.0.
1.3.0.0 (2018-03-06)
- Git: dejafu-1.3.0.0
- Hackage: dejafu-1.3.0.0
Deprecated
- (pull request #240)
Test.DejaFu.Settings.swarmy
1.2.0.0 - The Settings Release (2018-03-06)
- Git: dejafu-1.2.0.0
- Hackage: dejafu-1.2.0.0
Contributors: qrilka (pull request #236).
Added
-
(pull request #238) A record-based approach to SCT configuration:
-
Test.DejaFu.Settings
(re-exported fromTest.Dejafu
andTest.DejaFu.SCT
) -
Test.DejaFu.Settings.Settings
-
Test.DejaFu.Settings.defaultSettings
-
Test.DejaFu.Settings.fromWayAndMemType
-
Lenses:
Test.DejaFu.Settings.lway
Test.DejaFu.Settings.lmemtype
Test.DejaFu.Settings.ldiscard
Test.DejaFu.Settings.learlyExit
Test.DejaFu.Settings.ldebugShow
Test.DejaFu.Settings.ldebugPrint
-
Lens helpers:
Test.DejaFu.Settings.get
Test.DejaFu.Settings.set
-
Runners:
Test.DejaFu.SCT.runSCTWithSettings
Test.DejaFu.SCT.runSCTWithSettings'
Test.DejaFu.SCT.resultsSetWithSettings
Test.DejaFu.SCT.resultsSetWithSettings'
-
-
(pull request #238) Settings-based test functions:
Test.DejaFu.autocheckWithSettings
Test.DejaFu.dejafuWithSettings
Test.DejaFu.dejafusWithSettings
Test.DejaFu.runTestWithSettings
Deprecated
-
(pull request #238) SCT function variants:
Test.DejaFu.SCT.runSCTDiscard
Test.DejaFu.SCT.resultSetDiscard
Test.DejaFu.SCT.runSCTDiscard'
Test.DejaFu.SCT.resultSetDiscard'
Test.DejaFu.SCT.sctBound
Test.DejaFu.SCT.sctBoundDiscard
Test.DejaFu.SCT.sctUniformRandom
Test.DejaFu.SCT.sctUniformRandomDiscard
Test.DejaFu.SCT.sctWeightedRandom
Test.DejaFu.SCT.sctWeightedRandomDiscard
-
(pull request #238) The
Test.DejaFu.Defaults
module. ImportTest.DejaFu.Settings
instead. -
(pull request #238)
Test.DejaFu.dejafuDiscard
.
Removed
- (pull request #238)
Test.DejaFu.Defaults.defaultDiscarder
, as the discard function is optional.
1.1.0.2 (2018-03-01)
- Git: dejafu-1.1.0.2
- Hackage: dejafu-1.1.0.2
Miscellaneous
- (pull request #235) The documentation for
Test.DejaFu.Conc.dontCheck
andsubconcurrency
clarify that an illegal use does not necessarily cause a failing test.
1.1.0.1 (2018-02-26)
- Git: dejafu-1.1.0.1
- Hackage: dejafu-1.1.0.1
Contributors: qrilka (pull request #229).
Miscellaneous
- The upper bound on exceptions is <0.10.
1.1.0.0 (2018-02-22)
- Git: dejafu-1.1.0.0
- Hackage: dejafu-1.1.0.0
Contributors: qrilka (pull request #228).
Added
-
(pull request #219) The testing-only
Test.DejaFu.Conc.dontCheck
function, and associated definitions:Test.DejaFu.Types.DontCheck
Test.DejaFu.Types.WillDontCheck
Test.DejaFu.Types.IllegalDontCheck
Test.DejaFu.Types.isIllegalDontCheck
-
(pull request #219) A snapshotting approach based on
Test.DejaFu.Conc.dontCheck
:Test.DejaFu.Conc.runForDCSnapshot
Test.DejaFu.Conc.runWithDCSnapshot
Test.DejaFu.Conc.canDCSnapshot
Test.DejaFu.Conc.threadsFromDCSnapshot
Changed
- (pull request #219) SCT functions automatically use the snapshotting mechanism when possible.
1.0.0.2 (2018-02-18)
- Git: dejafu-1.0.0.2
- Hackage: dejafu-1.0.0.2
Contributors: qrilka (pull request #214).
Changed
- (issue #193) Deterministically assign commit thread IDs.
Fixed
- (issue #189) Remove an incorrect optimisation in systematic
testing for
getNumCapabilities
andsetNumCapabilities
. - (issue #204) Fix missed interleavings in systematic testing with some uses of STM.
- (issue #205) Fix
forkOS
being recorded in an execution trace as if it were afork
.
Miscellaneous
- (pull request #180) Doctest Haddock examples in
Test.DejaFu
andTest.DejaFu.Refinement
. - (pull request #185, pull request #215) Check some more internal invariants and throw on error.
- (pull request #214) Remove unnecessary use of
head
.
1.0.0.1 (2018-01-19)
- Git: dejafu-1.0.0.1
- Hackage: dejafu-1.0.0.1
Miscellaneous
- The upper bound on concurrency is <1.5.
1.0.0.0 - The API Friendliness Release (2017-12-23)
- Git: dejafu-1.0.0.0
- Hackage: dejafu-1.0.0.0
Added
-
Test.DejaFu.alwaysSameOn
andalwaysSameBy
predicate helpers. -
Test.DejaFu.SCT.strengthenDiscard
andweakenDiscard
functions to combine discard functions. -
(issue #124) The
Test.DejaFu.ProPredicate
type, which contains both an old-stylePredicate
and a discard function. It is also aProfunctor
, parameterised by the input and output types. -
(issue #124)
Test.DejaFu.alwaysNothing
andsomewhereNothing
predicate helpers, likealwaysTrue
andsomewhereTrue
, to lift regular functions into aProPredicate
. -
(issue #137) The
Test.DejaFu.Types.Id
type. -
(pull request #145) Thread action and lookahead values for bound threads:
Test.DejaFu.Types.ForkOS
Test.DejaFu.Types.IsCurrentThreadBound
Test.DejaFu.Types.WillForkOS
Test.DejaFu.Types.WillIsCurrentThreadBound
-
(issue #155)
Test.DejaFu.Types
andTest.DejaFu.Utils
modules, each containing some of what was inTest.DejaFu.Common
.
Changed
- All testing functions require
MonadConc
,MonadRef
, andMonadIO
constraints. Testing withST
is no longer possible. - The
Test.DejaFu.alwaysSame
predicate helper gives the simplest trace leading to each distinct result. - The
MonadIO Test.DejaFu.Conc.ConcIO
instance is now the more generalMonadIO n => MonadIO (ConcT r n)
. - (issue #121) The chosen thread is no longer redundantly included in trace lookahead.
- (issue #123) All testing functions in
Test.DejaFu
take the action to run as the final parameter. - (issue #124) All testing functions in
Test.DejaFu
have been generalised to take aProPredicate
instead of aPredicate
. - (issue #124) The
Test.DejaFu.Predicate
type is an alias forProPredicate a a
. - (issue #124) The
Test.DejaFu.Result
type no longer includes a number of cases checked. - (issue #137) The
Test.DejaFu.Types.ThreadId
,CRefId
,MVarId
, andTVarId
types are now wrappers for anId
. - (pull request #145) If built with the threaded runtime, the main thread in a test is executed as a bound thread.
- (issue #155) The
Test.DejaFu.SCT.Discard
type is defined inTest.DejaFu.Types
, and re-exported fromTest.DejaFu.SCT
. - (issue #155) The
Test.DejaFu.Schedule.tidOf
anddecisionOf
functions are defined inTest.DejaFu.Utils
, but not re-exported fromTest.DejaFu.Schedule
.
Removed
-
The
IO
specific testing functions:Test.DejaFu.autocheckIO
Test.DejaFu.dejafuIO
Test.DejaFu.dejafusIO
Test.DejaFu.autocheckWayIO
Test.DejaFu.dejafuWayIO
Test.DejaFu.dejafusWayIO
Test.DejaFu.dejafuDiscardIO
Test.DejaFu.runTestM
Test.DejaFu.runTestWayM
-
The
Test.DejaFu.Conc.ConcST
type alias. -
The
MonadBaseControl IO Test.DejaFu.Conc.ConcIO
typeclass instance. -
The
Test.DejaFu.alwaysTrue2
function, which had confusing behaviour. -
The
Test.DejaFu.Common.TTrace
type synonym for[TAction]
. -
The
Test.DejaFu.Common.preEmpCount
function. -
Re-exports of
Decision
andNonEmpty
fromTest.DejaFu.Schedule
. -
(issue #155) The
Test.DejaFu.Common
andTest.DejaFu.STM
modules.
Fixed
- In refinement property testing, a blocking interference function is not reported as a deadlocking execution.
Performance
- (issue #124) Passing tests should use substantially less memory.
- (issue #168) Prune some unnecessary interleavings of
MVar
actions in systematic testing.
Miscellaneous
- The lower bound on concurrency is >=1.3.
0.9.1.2 (2017-12-12)
- Git: dejafu-0.9.1.2
- Hackage: dejafu-0.9.1.2
Miscellaneous
- The upper bound on leancheck is <0.8.
0.9.1.1 (2017-12-08)
- Git: dejafu-0.9.1.1
- Hackage: dejafu-0.9.1.1
Fixed
- (issue #160) Fix an off-by-one issue with nested masks during systematic testing.
0.9.1.0 (2017-11-26)
- Git: dejafu-0.9.1.0
- Hackage: dejafu-0.9.1.0
Added
MonadFail
instance forTest.DejaFu.Conc.ConcT
.MonadFail
instance forTest.DejaFu.STM.STMLike
.
Changed
- Pretty-printed traces display a pre-emption following a yield with a little "p".
Fixed
- Some incorrect Haddock
@since
comments.
0.9.0.3 (2017-11-06)
- Git: dejafu-0.9.0.3
- Hackage: dejafu-0.9.0.3
Fixed
- (issue #138) Fix missed interleavings in systematic testing with some relaxed memory programs.
0.9.0.2 (2017-11-02)
- Git: dejafu-0.9.0.2
- Hackage: dejafu-0.9.0.2
Changed
- A fair bound of 0 prevents yielding or delaying.
Performance
- Prune some unnecessary interleavings of STM transactions in systematic testing.
0.9.0.1 (2017-10-28)
- Git: dejafu-0.9.0.1
- Hackage: dejafu-0.9.0.1
Fixed
- (issue #139) Fix double pop of exception handler stack.
0.9.0.0 (2017-10-11)
- Git: dejafu-0.9.0.0
- Hackage: dejafu-0.9.0.0
Added
-
Failure predicates (also exported from
Test.DejaFu
):Test.DejaFu.Common.isAbort
Test.DejaFu.Common.isDeadlock
Test.DejaFu.Common.isIllegalSubconcurrency
Test.DejaFu.Common.isInternalError
Test.DejaFu.Common.isUncaughtException
-
Thread action and lookahead values for
threadDelay
:Test.DejaFu.Common.ThreadDelay
Test.DejaFu.Common.WillThreadDelay
Changed
- The
UncaughtException
constructor forTest.DejaFu.Common.Failure
now includes the exception value. - Uses of
threadDelay
are no longer reported in the trace as a use ofyield
.
Removed
- The
Bounded
,Enum
, andRead
instances forTest.DejaFu.Common.Failure
.
0.8.0.0 (2017-09-26)
- Git: dejafu-0.8.0.0
- Hackage: dejafu-0.8.0.0
Changed
- (issue #80) STM traces now include the ID of a newly-created
TVar
. - (issue #106) Schedulers are not given the execution trace so far.
- (issue #120) Traces only include a single action of lookahead.
- (issue #122) The
Test.DejaFu.Scheduler.Scheduler
type is now a newtype, rather than a type synonym.
0.7.3.0 (2017-09-26)
- Git: dejafu-0.7.3.0
- Hackage: dejafu-0.7.3.0
Added
- The
Test.DejaFu.Common.threadNames
function.
Fixed
- (issue #101) Named threads which are only started by a pre-emption are shown in the pretty-printed trace key.
- (issue #118) Escaping a mask by raising an exception correctly restores the masking state (#118).
0.7.2.0 (2017-09-16)
- Git: dejafu-0.7.2.0
- Hackage: dejafu-0.7.2.0
Added
Alternative
andMonadPlus
instances forTest.DejaFu.STM.STM
.
Fixed
- The
Eq
andOrd
instances forTest.DejaFu.Common.ThreadId
,CRefId
,MVarId
, andTVarId
are consistent.
Miscellaneous
- The upper bound on concurrency is <1.2.
0.7.1.3 (2017-09-08)
- Git: dejafu-0.7.1.3
- Hackage: dejafu-0.7.1.3
Fixed
- (issue #111) Aborted STM transactions are correctly rolled back.
Performance
- (issue #105) Use a more efficient approach for an internal component of the systematic testing.
0.7.1.2 (2017-08-21)
- Git: dejafu-0.7.1.2
- Hackage: dejafu-0.7.1.2
Fixed
- (issue #110) Errors thrown with
Control.Monad.fail
are correctly treated as asynchronous exceptions.
0.7.1.1 (2017-08-16)
- Git: dejafu-0.7.1.1
- Hackage: dejafu-0.7.1.1
Performance
-
(issue #64) Greatly reduce memory usage in systematic testing when discarding traces by using an alternative data structure.
- Old:
O(max trace length * number of executions)
- New:
O(max trace length * number of traces kept)
- Old:
0.7.1.0 - The Discard Release (2017-08-10)
- Git: dejafu-0.7.1.0
- Hackage: dejafu-0.7.1.0
Added
-
(issue #90) A way to selectively discard results or traces:
- Type:
Test.DejaFu.SCT.Discard
- Functions:
Test.DejaFu.SCT.runSCTDiscard
,resultsSetDiscard
,sctBoundDiscard
,sctUniformRandomDiscard
, andsctWeightedRandomDiscard
.
- Type:
-
(issue #90) Discarding variants of the testing functions:
Test.DejaFu.dejafuDiscard
Test.DejaFu.dejafuDiscardIO
-
(issue #90)
Test.DejaFu.Defaults.defaultDiscarder
.
Performance
- (issue #90) The
Test.DejaFu.SCT.resultsSet
andresultsSet'
functions discard traces as they are produced, rather than all at the end.
0.7.0.2 (2017-06-12)
- Git: dejafu-0.7.0.2
- Hackage: dejafu-0.7.0.2
Changed
- Remove unnecessary typeclass constraints from
Test.DejaFu.Refinement.check
,check'
,checkFor
, andcounterExamples
.
Miscellaneous
- Remove an unnecessary dependency on monad-loops.
0.7.0.1 (2017-06-09)
- Git: dejafu-0.7.0.1
- Hackage: dejafu-0.7.0.1
Performance
- The
Test.DejaFu.Refinement.check
,check'
, andcheckFor
functions no longer need to compute all counterexamples before showing only one. - The above and
counterExamples
are now faster even if there is only a single counterexample in some cases.
0.7.0.0 - The Refinement Release (2017-06-07)
- Git: dejafu-0.7.0.0
- Hackage: dejafu-0.7.0.0
Added
-
The
Test.DejaFu.Refinement
module, re-exported fromTest.DejaFu
. -
The
Test.DejaFu.SCT.sctUniformRandom
function for SCT via random scheduling. -
Smart constructors for
Test.DejaFu.SCT.Way
(also re-exported fromTest.DejaFu
):Test.DejaFu.SCT.systematically
, like the oldSystematically
.Test.DejaFu.SCT.randomly
, like the oldRandomly
.Test.DejaFu.SCT.uniformly
, a new uniform (as opposed to weighted) random scheduler.Test.DejaFu.SCT.swarmy
, like the oldRandomly
but which can use the same weights for multiple executions.
Changed
- The
default*
values are defined inTest.DejaFu.Defaults
and re-exported fromTest.DejaFu
. - The
Test.DejaFu.SCT.sctRandom
function is now calledsctWeightedRandom
and can re-use the same weights for multiple executions.
Removed
-
The
Test.DejaFu.SCT.Way
type is now abstract, so its constructors are no longer exported:Test.DejaFu.SCT.Systematically
Test.DejaFu.SCT.Randomly
-
The
Test.DejaFu.SCT.sctPreBound
,sctFairBound
, andsctLengthBound
functions.
Fixed
- (issue #81)
Test.DejaFu.Conc.subconcurrency
no longer re-uses IDs.
0.6.0.0 (2017-04-08)
- Git: dejafu-0.6.0.0
- Hackage: dejafu-0.6.0.0
Changed
- The
Test.DejaFu.Conc.Conc n r a
type isConcT r n a
, and has aMonadTrans
instance. - The
Test.DejaFu.SCT.Way
type is a GADT, and does not expose the type parameter of the random generator.
Removed
- The
NFData
instance forTest.DejaFu.SCT.Way
.
Miscellaneous
Test.DejaFu.Common
forms part of the public API.- Every definition, class, and instance now has a Haddock
@since
annotation.
0.5.1.3 (2017-04-05)
- Git: dejafu-0.5.1.3
- Hackage: dejafu-0.5.1.3
Miscellaneous
- The version bounds on concurrency are 1.1.*.
0.5.1.2 (2017-03-04)
- Git: dejafu-0.5.1.2
- Hackage: dejafu-0.5.1.2
Note: this version was misnumbered! It should have caused a minor
: version bump!
Added
MonadRef
andMonadAtomicRef
instances forTest.DejaFu.Conc.Conc
usingCRef
.
Fixed
- A long-standing bug where if the main thread is killed with a
throwTo
, the throwing neither appears in the trace nor correctly terminates the execution.
Miscellaneous
- The upper bound on concurrency is <1.1.1.
0.5.1.1 (2017-02-25)
- Git: dejafu-0.5.1.1
- Hackage: dejafu-0.5.1.1
Fixed
- Fix using incorrect correct scheduler state after a
subconcurrency
action. - Fix infinite loop in SCT of subconcurrency.
0.5.1.0 (2017-02-25)
- Git: dejafu-0.5.1.0
- Hackage: dejafu-0.5.1.0
Added
-
NFData
instances for:Test.DejaFu.Result
Test.DejaFu.Common.ThreadId
Test.DejaFu.Common.CRefId
Test.DejaFu.Common.MVarId
Test.DejaFu.Common.TVarId
Test.DejaFu.Common.IdSource
Test.DejaFu.Common.ThreadAction
Test.DejaFu.Common.Lookahead
Test.DejaFu.Common.ActionType
Test.DejaFu.Common.TAction
Test.DejaFu.Common.Decision
Test.DejaFu.Common.Failure
Test.DejaFu.Common.MemType
Test.DejaFu.SCT.Bounds
Test.DejaFu.SCT.PreemptionBound
Test.DejaFu.SCT.FairBound
Test.DejaFu.SCT.LengthBound
Test.DejaFu.SCT.Way
Test.DejaFu.STM.Result
-
Eq
,Ord
, andShow
instances forTest.DejaFu.Common.IdSource
. -
Strict variants of
Test.DejaFu.SCT.runSCT
andresultsSet
:runSCT'
andresultsSet'
.
0.5.0.2 (2017-02-22)
- Git: dejafu-0.5.0.2
- Hackage: dejafu-0.5.0.2
Note: this version was misnumbered! It should have caused a major
: version bump!
Added
StopSubconcurrency
constructor forTest.DejaFu.Common.ThreadAction
.
Changed
- A
Test.DejaFu.Common.StopConcurrency
action appears in the execution trace immediately after the end of aTest.DejaFu.Conc.subconcurrency
action.
Fixed
- A
Test.DejaFu.Conc.subconcurrency
action inherits the number of capabilities from the outer computation.
Miscellaneous
Test.DejaFu.SCT
compiles withMonoLocalBinds
enabled (implied byGADTs
andTypeFamilies
), which may be relevant to hackers.
0.5.0.1 (2017-02-21)
- Git: dejafu-0.5.0.1
- Hackage: ps!**
Fixed
readMVar
is considered a "release action" for the purposes of fair-bounding.
0.5.0.0 - The Way Release (2017-02-21)
- Git: dejafu-0.5.0.0
- Hackage: dejafu-0.5.0.0
Added
-
Eq
instances forTest.DejaFu.Common.ThreadAction
andLookahead
. -
Thread action and lookahead values for
tryReadMVar
:Test.DejaFu.Common.TryReadMVar
Test.DejaFu.Common.WillTryReadMVar
-
The testing-only
Test.DejaFu.Conc.subconcurrency
function. -
SCT through weighted random scheduling:
Test.DejaFu.SCT.sctRandom
. -
The
Test.DejaFu.SCT.Way
type, used by the new functionsrunSCT
andresultsSet
.
Changed
- All the functions which took a
Test.DejaFu.SCT.Bounds
now take aWay
instead.
Fixed
- Some previously-missed
CRef
action dependencies are no longer missed.
Miscellaneous
- The version bounds on concurrency are 1.1.0.*.
- A bunch of things were called "Var" or "Ref", these are now consistently "MVar" and "CRef".
- Significant performance improvements in both time and space.
- The dpor package has been merged back into this, as it turned out not to be very generally useful.
0.4.0.0 - The Packaging Release (2016-09-10)
- Git: dejafu-0.4.0.0
- Hackage: dejafu-0.4.0.0
Added
- The
Test.DejaFu.runTestM
andrunTestM'
functions. - The
Test.DejaFu.Conc.runConcurrent
function. - The
Test.DejaFu.STM.runTransaction
function. - The
Test.DejaFu.Common
module.
Changed
- The
Control.*
modules have all been split out into a separate concurrency package. - The
Test.DejaFu.Deterministic
module has been renamed toTest.DejaFu.Conc
. - Many definitions from other modules have been moved to the
Test.DejaFu.Common
module. - The
Test.DejaFu.autocheck'
function takes the schedule bounds as a parameter. - The
Test.DejaFu.Conc.Conc
type no longer has the STM type as a parameter. - The
ST
specific functions inTest.DejaFu.SCT
are polymorphic in the monad. - The termination of the main thread in execution traces appears as a
single
Stop
, rather than the previousLift, Stop
. - Execution traces printed by the helpful functions in
Test.DejaFu
include a key of thread names.
Removed
- The
Test.DejaFu.runTestIO
andrunTestIO'
functions: userunTestM
andrunTestM'
instead. - The
Test.DejaFu.Conc.runConcST
andrunConcIO
functions: userunConcurrent
instead. - The
Test.DejaFu.STM.runTransactionST
andrunTransactionIO
functions: userunTransaction
instead. - The
IO
specific functions inTest.DejaFu.SCT
.
0.3.2.1 (2016-07-21)
- Git: dejafu-0.3.2.1
- Hackage: dejafu-0.3.2.1
Fixed
- (issue #55) Fix incorrect detection of deadlocks with some nested STM transactions.
0.3.2.0 (2016-06-06)
- Git: dejafu-0.3.2.0
- Hackage: dejafu-0.3.2.0
Fixed
- (issue #40) Fix missing executions with daemon threads with uninteresting first actions. This is significantly faster with dpor-0.2.0.0.
Performance
- When using dpor-0.2.0.0, greatly improve dependency inference of exceptions during systematic testing.
- Improve dependency inference of STM transactions during systematic testing.
0.3.1.1 (2016-05-26)
- Git: dejafu-0.3.1.1
- Hackage: dejafu-0.3.1.1
Miscellaneous
- Now supports GHC 8.
0.3.1.0 (2016-05-02)
- Git: dejafu-0.3.1.0
- Hackage: dejafu-0.3.1.0
Fixed
- Fix inaccurate counting of pre-emptions in an execution trace when relaxed memory commit actions are present.
0.3.0.0 (2016-04-03)
- Git: dejafu-0.3.0.0
- Hackage: dejafu-0.3.0.0
The minimum supported version of GHC is now 7.10.
I didn't write proper release notes, and this is so far back I don't really care to dig through the logs.
0.2.0.0 (2015-12-01)
- Git: 0.2.0.0
- Hackage: dejafu-0.2.0.0
I didn't write proper release notes, and this is so far back I don't really care to dig through the logs.
0.1.0.0 - The Initial Release (2015-08-27)
- Git: 0.1.0.0
- Hackage: dejafu-0.1.0.0
Added
- Everything.
Release Notes
This project is versioned according to the PVP, the de facto standard Haskell versioning scheme.
2.0.0.6 (2022-08-30)
- Git: hunit-dejafu-2.0.0.6
- Hackage: hunit-dejafu-2.0.0.6
Fixed
- Remove inaccurate comment about
Test.HUnit.DejaFu.testDejafus
sharing work.
2.0.0.5 (2021-08-15)
- Git: hunit-dejafu-2.0.0.5
- Hackage: hunit-dejafu-2.0.0.5
Miscellaneous
- Remove reference to freenode in README.
2.0.0.4 (2020-07-01)
- Git: hunit-dejafu-2.0.0.4
- Hackage: hunit-dejafu-2.0.0.4
Miscellaneous
- The upper bound on dejafu is <2.5
2.0.0.3 (2020-05-10)
- Git: hunit-dejafu-2.0.0.3
- Hackage: hunit-dejafu-2.0.0.3
Miscellaneous
- The upper bound on dejafu is <2.4
2.0.0.2 (2020-05-10)
- Git: hunit-dejafu-2.0.0.2
- Hackage: hunit-dejafu-2.0.0.2
Miscellaneous
- The upper bound on dejafu is <2.3
2.0.0.1 (2019-03-24)
- Git: hunit-dejafu-2.0.0.1
- Hackage: hunit-dejafu-2.0.0.1
Miscellaneous
- The upper bound on dejafu is <2.2
2.0.0.0 (2019-02-12)
- Git: hunit-dejafu-2.0.0.0
- Hackage: hunit-dejafu-2.0.0.0
Added
-
Re-exports for the
Program
types and their constructors:Test.HUnit.DejaFu.Program
Test.HUnit.DejaFu.Basic
Test.HUnit.DejaFu.ConcT
Test.HUnit.DejaFu.ConcIO
Test.HUnit.DejaFu.WithSetup
Test.HUnit.DejaFu.WithSetupAndTeardown
Test.HUnit.DejaFu.withSetup
Test.HUnit.DejaFu.withTeardown
Test.HUnit.DejaFu.withSetupAndTeardown
-
Re-exports for the
Invariant
type and its functions:Test.HUnit.DejaFu.Invariant
Test.HUnit.DejaFu.registerInvariant
Test.HUnit.DejaFu.inspectIORef
Test.HUnit.DejaFu.inspectMVar
Test.HUnit.DejaFu.inspectTVar
Changed
-
Functions which took a
ConcIO
now take aProgram pty IO
:Test.HUnit.DejaFu.testAuto
Test.HUnit.DejaFu.testAutoWay
Test.HUnit.DejaFu.testAutoWithSettings
Test.HUnit.DejaFu.testDejafu
Test.HUnit.DejaFu.testDejafuWay
Test.HUnit.DejaFu.testDejafuWithSettings
Test.HUnit.DejaFu.testDejafus
Test.HUnit.DejaFu.testDejafusWay
Test.HUnit.DejaFu.testDejafusWithSettings
Removed
-
The deprecated functions:
Test.HUnit.DejaFu.testDejafuDiscard
Test.HUnit.DejaFu.testDejafusDiscard
Miscellaneous
- The lower bound on dejafu is >=2.0.
1.2.1.0 (2019-01-20)
- Git: hunit-dejafu-1.2.1.0
- Hackage: hunit-dejafu-1.2.1.0
Added
- Re-export of the
Condition
type from dejafu. If using dejafu < 1.12, this is an alias forFailure
.
Miscellaneous
- The upper bound on dejafu is <1.13
1.2.0.6 (2018-07-01)
- Git: hunit-dejafu-1.2.0.6
- Hackage: hunit-dejafu-1.2.0.6
Miscellaneous
- The upper bound on dejafu is <1.12.
1.2.0.5 (2018-06-17)
- Git: hunit-dejafu-1.2.0.5
- Hackage: hunit-dejafu-1.2.0.5
Miscellaneous
- The upper bound on dejafu is <1.11.
1.2.0.4 (2018-06-10)
- Git: hunit-dejafu-1.2.0.4
- Hackage: hunit-dejafu-1.2.0.4
Miscellaneous
- The upper bound on dejafu is <1.10.
1.2.0.3 (2018-06-03)
- Git: hunit-dejafu-1.2.0.3
- Hackage: hunit-dejafu-1.2.0.3
Miscellaneous
- The upper bound on dejafu is <1.9.
1.2.0.2 (2018-06-03)
- Git: hunit-dejafu-1.2.0.2
- Hackage: hunit-dejafu-1.2.0.2
Miscellaneous
- The upper bound on dejafu is <1.8.
1.2.0.1 (2018-05-11)
- Git: hunit-dejafu-1.2.0.1
- Hackage: hunit-dejafu-1.2.0.1
Miscellaneous
- The upper bound on dejafu is <1.7.
1.2.0.0 - No More 7.10 (2018-03-28)
- Git: hunit-dejafu-1.2.0.0
- Hackage: hunit-dejafu-1.2.0.0
Miscellaneous
-
GHC 7.10 support is dropped. Dependency lower bounds are:
-
The upper bound on dejafu is 1.6.
1.1.0.3 (2018-03-17)
- Git: hunit-dejafu-1.1.0.3
- Hackage: hunit-dejafu-1.1.0.3
Miscellaneous
- (pull request #251) The upper bound on dejafu is <1.5.
1.1.0.2 (2018-03-11)
- Git: hunit-dejafu-1.1.0.2
- Hackage: hunit-dejafu-1.1.0.2
Miscellaneous
- (pull request #245) The upper bound on exceptions is <0.11.
1.1.0.1 (2018-03-06)
- Git: hunit-dejafu-1.1.0.1
- Hackage: hunit-dejafu-1.1.0.1
Miscellaneous
- The upper bound on dejafu is <1.4.
1.1.0.0 - The Settings Release (2018-03-06)
- Git: hunit-dejafu-1.1.0.0
- Hackage: hunit-dejafu-1.1.0.0
Added
-
(pull request #238) Settings-based test functions:
Test.HUnit.DejaFu.testAutoWithSettings
Test.HUnit.DejaFu.testDejafuWithSettings
Test.HUnit.DejaFu.testDejafusWithSettings
-
(pull request #238) Re-export of
Test.DejaFu.Settings
.
Deprecated
- (pull request #238)
Test.HUnit.DejaFu.testDejafuDiscard
andtestDejafusDiscard
.
Removed
- (pull request #238) The re-export of
Test.DejaFu.Defaults.defaultDiscarder
.
Miscellaneous
- The version bounds on dejafu are >=1.2 && <1.3.
1.0.1.2 (2018-02-26)
- Git: hunit-dejafu-1.0.1.2
- Hackage: hunit-dejafu-1.0.1.2
Miscellaneous
- The upper bound on exceptions is <0.10.
1.0.1.1 (2018-02-22)
- Git: hunit-dejafu-1.0.1.1
- Hackage: hunit-dejafu-1.0.1.1
Miscellaneous
- The upper bound on dejafu is <1.2.
1.0.1.0 (2018-02-13)
- Git: hunit-dejafu-1.0.1.0
- Hackage: hunit-dejafu-1.0.1.0
Added
- (pull request #200)
Test.HUnit.DejaFu.testDejafusDiscard
function.
1.0.0.0 - The API Friendliness Release (2017-12-23)
- Git: hunit-dejafu-1.0.0.0
- Hackage: hunit-dejafu-1.0.0.0
Added
- (issue #124) Re-exports of
Test.DejaFu.Predicate
andProPredicate
.
Changed
- All testing functions require
MonadConc
,MonadRef
, andMonadIO
constraints. Testing withST
is no longer possible. - (issue #123) All testing functions take the action to run as the final parameter.
- (issue #124) All testing functions have been generalised to take a
Test.DejaFu.ProPredicate
instead of aPredicate
.
Removed
- The
Test.DejaFu.Conc.ConcST
specific functions. - The orphan
Testable
andAssertable
instances forTest.DejaFu.Conc.ConcST t ()
.
Miscellaneous
- The version bounds on dejafu are >=1.0 && <1.1.
0.7.1.1 (2017-11-30)
- Git: hunit-dejafu-0.7.1.1
- Hackage: hunit-dejafu-0.7.1.1
Fixed
- A missing Haddock
@since
comments.
0.7.1.0 (2017-11-30)
- Git: hunit-dejafu-0.7.1.0
- Hackage: hunit-dejafu-0.7.1.0
Added
Test.HUnit.DejaFu.testPropertyFor
function.
0.7.0.2 (2017-10-11)
- Git: hunit-dejafu-0.7.0.2
- Hackage: hunit-dejafu-0.7.0.2
Miscellaneous
- The upper bound on dejafu is <0.10.
0.7.0.1 (2017-09-26)
- Git: hunit-dejafu-0.7.0.1
- Hackage: hunit-dejafu-0.7.0.1
Miscellaneous
- The upper bound on dejafu is <0.9.
0.7.0.0 - The Discard Release (2017-08-10)
- Git: hunit-dejafu-0.7.0.0
- Hackage: hunit-dejafu-0.7.0.0
Added
- Re-export for
Test.DejaFu.SCT.Discard
andTest.DejaFu.Defaults.defaultDiscarder
. Test.HUnit.DejaFu.testDejafuDiscard
andtestDejafuDiscardIO
functions.
Miscellaneous
- The lower bound on dejafu is >=0.7.1.
0.6.0.0 - The Refinement Release (2017-06-07)
- Git: hunit-dejafu-0.6.0.0
- Hackage: hunit-dejafu-0.6.0.0
Added
Test.HUnit.DejaFu.testProperty
function- Re-exports for
Test.DejaFu.SCT.systematically
,randomly
,uniformly
, andswarmy
. - Re-exports for
Test.DejaFu.Defaults.defaultWay
,defaultMemType
, anddefaultBounds
.
Removed
- Re-exports of the
Test.DejaFu.SCT.Way
constructors:Systematically
andRandomly
.
Miscellaneous
- The version bounds on dejafu are >=0.7 && <0.8.
0.5.0.0 - The Way Release (2017-04-08)
- Git: hunit-dejafu-0.5.0.0
- Hackage: hunit-dejafu-0.5.0.0
Changed
- Due to changes in dejafu, the
Way
type no longer takes a parameter; it is now a GADT.
Miscellaneous
- Every definition, class, and instance now has a Haddock
@since
annotation. - The version bounds on dejafu are >=0.6 && <0.7.
- Remove an unnecessary dependency on random.
0.4.0.1 (2017-03-20)
- Git: hunit-dejafu-0.4.0.1
- Hackage: hunit-dejafu-0.4.0.1
Miscellaneous
- The upper bound on HUnit is <1.7.
0.4.0.0 (2017-02-21)
- Git: hunit-dejafu-0.4.0.0
- Hackage: hunit-dejafu-0.4.0.0
Added
- Re-export of
Test.DejaFu.SCT.Way
.
Changed
- All the functions which took a
Test.DejaFu.SCT.Bounds
now take aWay
.
Miscellaneous
0.3.0.3 (2016-10-22)
- Git: hunit-dejafu-0.3.0.3
- Hackage: hunit-dejafu-0.3.0.3
Miscellaneous
- The upper bound on HUnit is <1.6.
0.3.0.2 (2016-09-10)
- Git: hunit-dejafu-0.3.0.2
- Hackage: hunit-dejafu-0.3.0.2
Miscellaneous
- The upper bound on dejafu is <0.5.
0.3.0.1 (2016-05-26)
- Git: hunit-dejafu-0.3.0.1
- Hackage: hunit-dejafu-0.3.0.1
Miscellaneous
0.3.0.0 (2016-04-28)
- Git: hunit-dejafu-0.3.0.0
- Hackage: hunit-dejafu-0.3.0.0
Added
- Orphan
Assertable
andTestable
instances forTest.DejaFu.Conc.ConcST t ()
andConcIO ()
. - Re-export
Test.DejaFu.SCT.Bounds
.
Miscellaneous
- The version bounds on dejafu are >=0.2
0.2.1.0 (2016-04-03)
- Git: hunit-dejafu-0.2.1.0
Note: this was never pushed to Hackage, whoops!
Miscellaneous
- The version bounds on dejafu are 0.3.*.
0.2.0.0 - The Initial Release (2015-12-01)
- Git: 0.2.0.0
- Hackage: hunit-dejafu-0.2.0.0
Added
- Everything.
Release Notes
This project is versioned according to the PVP, the de facto standard Haskell versioning scheme.
2.1.0.1 (2023-09-11)
- Git: tasty-dejafu-2.1.0.1
- Hackage: tasty-dejafu-2.1.0.1
Miscellaneous
- The upper bound on tasty is <1.6.
2.1.0.0 (2022-08-31)
- Git: tasty-dejafu-2.1.0.0
- Hackage: tasty-dejafu-2.1.0.0
Changed
-
(issue #361) The following functions take a
TestName
parameter to name the test group, rather than using "Deja Fu Tests":Test.Tasty.DejaFu.testAuto
Test.Tasty.DejaFu.testAutoWay
Test.Tasty.DejaFu.testAutoWithSettings
Test.Tasty.DejaFu.testDejafus
Test.Tasty.DejaFu.testDejafusWay
Test.Tasty.DejaFu.testDejafusWithSettings
2.0.0.9 (2022-08-30)
- Git: tasty-dejafu-2.0.0.9
- Hackage: tasty-dejafu-2.0.0.9
Fixed
- Remove inaccurate comment about
Test.Tasty.DejaFu.testDejafus
sharing work.
2.0.0.8 (2021-08-15)
- Git: tasty-dejafu-2.0.0.8
- Hackage: tasty-dejafu-2.0.0.8
Miscellaneous
- Remove reference to freenode from README.
2.0.0.7 (2020-12-27)
- Git: tasty-dejafu-2.0.0.7
- Hackage: tasty-dejafu-2.0.0.7
Miscellaneous
- The upper bound on tasty is <1.5.
2.0.0.6 (2020-07-01)
- Git: tasty-dejafu-2.0.0.6
- Hackage: tasty-dejafu-2.0.0.6
Miscellaneous
- The upper bound on dejafu is <2.5.
2.0.0.5 (2020-06-24)
- Git: tasty-dejafu-2.0.0.5
- Hackage: tasty-dejafu-2.0.0.5
Miscellaneous
- The upper bound on random is <1.3.
2.0.0.4 (2020-05-14)
- Git: tasty-dejafu-2.0.0.4
- Hackage: tasty-dejafu-2.0.0.4
Miscellaneous
- The upper bound on dejafu is <2.4
2.0.0.3 (2020-05-10)
- Git: tasty-dejafu-2.0.0.3
- Hackage: tasty-dejafu-2.0.0.3
Miscellaneous
- The upper bound on dejafu is <2.3
2.0.0.2 (2020-05-10)
- Git: tasty-dejafu-2.0.0.2
- Hackage: tasty-dejafu-2.0.0.2
Miscellaneous
- The upper bound on tasty is <1.4
2.0.0.1 (2019-03-24)
- Git: tasty-dejafu-2.0.0.1
- Hackage: tasty-dejafu-2.0.0.1
Miscellaneous
- The upper bound on dejafu is <2.2
2.0.0.0 (2019-02-12)
- Git: tasty-dejafu-2.0.0.0
- Hackage: tasty-dejafu-2.0.0.0
Added
-
Re-exports for the
Program
types and their constructors:Test.Tasty.DejaFu.Program
Test.Tasty.DejaFu.Basic
Test.Tasty.DejaFu.ConcT
Test.Tasty.DejaFu.ConcIO
Test.Tasty.DejaFu.WithSetup
Test.Tasty.DejaFu.WithSetupAndTeardown
Test.Tasty.DejaFu.withSetup
Test.Tasty.DejaFu.withTeardown
Test.Tasty.DejaFu.withSetupAndTeardown
-
Re-exports for the
Invariant
type and its functions:Test.Tasty.DejaFu.Invariant
Test.Tasty.DejaFu.registerInvariant
Test.Tasty.DejaFu.inspectIORef
Test.Tasty.DejaFu.inspectMVar
Test.Tasty.DejaFu.inspectTVar
Changed
-
Functions which took a
ConcIO
now take aProgram pty IO
:Test.Tasty.DejaFu.testAuto
Test.Tasty.DejaFu.testAutoWay
Test.Tasty.DejaFu.testAutoWithSettings
Test.Tasty.DejaFu.testDejafu
Test.Tasty.DejaFu.testDejafuWay
Test.Tasty.DejaFu.testDejafuWithSettings
Test.Tasty.DejaFu.testDejafus
Test.Tasty.DejaFu.testDejafusWay
Test.Tasty.DejaFu.testDejafusWithSettings
Removed
-
The deprecated functions:
Test.Tasty.DejaFu.testDejafuDiscard
Test.Tasty.DejaFu.testDejafusDiscard
Miscellaneous
- The lower bound on dejafu is >=2.0.
1.2.1.0 (2019-01-20)
- Git: tasty-dejafu-1.2.1.0
- Hackage: tasty-dejafu-1.2.1.0
Added
- Re-export of the
Condition
type from dejafu. If using dejafu < 1.12, this is an alias forFailure
.
Miscellaneous
- The upper bound on dejafu is <1.13
1.2.0.8 (2018-12-02)
- Git: tasty-dejafu-1.2.0.8
- Hackage: tasty-dejafu-1.2.0.8
Miscellaneous
- The upper bound on tasty is <1.3.
1.2.0.7 (2018-07-01)
- Git: tasty-dejafu-1.2.0.7
- Hackage: tasty-dejafu-1.2.0.7
Miscellaneous
- The upper bound on dejafu is <1.12.
1.2.0.6 (2018-06-17)
- Git: tasty-dejafu-1.2.0.6
- Hackage: tasty-dejafu-1.2.0.6
Miscellaneous
- The upper bound on dejafu is <1.11.
1.2.0.5 (2018-06-10)
- Git: tasty-dejafu-1.2.0.5
- Hackage: tasty-dejafu-1.2.0.5
Miscellaneous
- The upper bound on dejafu is <1.10.
1.2.0.4 (2018-06-03)
- Git: tasty-dejafu-1.2.0.4
- Hackage: tasty-dejafu-1.2.0.4
Miscellaneous
- The upper bound on dejafu is <1.9.
1.2.0.3 (2018-06-03)
- Git: tasty-dejafu-1.2.0.3
- Hackage: tasty-dejafu-1.2.0.3
Miscellaneous
- The upper bound on dejafu is <1.8.
1.2.0.2 (2018-05-12)
- Git: tasty-dejafu-1.2.0.2
- Hackage: tasty-dejafu-1.2.0.2
Miscellaneous
- The upper bound on tasty is <1.2.
1.2.0.1 (2018-05-11)
- Git: tasty-dejafu-1.2.0.1
- Hackage: tasty-dejafu-1.2.0.1
Miscellaneous
- The upper bound on dejafu is <1.7.
1.2.0.0 - No More 7.10 (2018-03-28)
- Git: tasty-dejafu-1.2.0.0
- Hackage: tasty-dejafu-1.2.0.0
Miscellaneous
-
GHC 7.10 support is dropped. Dependency lower bounds are:
-
The upper bound on dejafu is 1.6.
1.1.0.2 (2018-03-17)
- Git: tasty-dejafu-1.1.0.2
- Hackage: tasty-dejafu-1.1.0.2
Miscellaneous
- The upper bound on dejafu is <1.5.
1.1.0.1 (2018-03-06)
- Git: tasty-dejafu-1.1.0.1
- Hackage: tasty-dejafu-1.1.0.1
Miscellaneous
- The upper bound on dejafu is <1.4.
1.1.0.0 - The Settings Release (2018-03-06)
- Git: tasty-dejafu-1.1.0.0
- Hackage: tasty-dejafu-1.1.0.0
Added
-
(pull request #238) Settings-based test functions:
Test.Tasty.DejaFu.testAutoWithSettings
Test.Tasty.DejaFu.testDejafuWithSettings
Test.Tasty.DejaFu.testDejafusWithSettings
-
(pull request #238) Re-export of
Test.DejaFu.Settings
.
Deprecated
- (pull request #238)
Test.Tasty.DejaFu.testDejafuDiscard
andtestDejafusDiscard
.
Removed
- (pull request #238) The re-export of
Test.DejaFu.Defaults.defaultDiscarder
.
Miscellaneous
- The version bounds on dejafu are >=1.2 && <1.3.
1.0.1.1 (2018-02-22)
- Git: tasty-dejafu-1.0.1.1
- Hackage: tasty-dejafu-1.0.1.1
Miscellaneous
- The upper bound on dejafu is <1.2.
1.0.1.0 (2018-02-13)
- Git: tasty-dejafu-1.0.1.0
- Hackage: tasty-dejafu-1.0.1.0
Added
- (pull request #195)
Test.Tasty.DejaFu.testDejafusDiscard
function.
1.0.0.1 (2018-01-09)
- Git: tasty-dejafu-1.0.0.1
- Hackage: tasty-dejafu-1.0.0.1
Miscellaneous
- The upper bound on tasty is <1.1.
1.0.0.0 - The API Friendliness Release (2017-12-23)
- Git: tasty-dejafu-1.0.0.0
- Hackage: tasty-dejafu-1.0.0.0
Added
- (issue #124) Re-exports of
Test.DejaFu.Predicate
andProPredicate
.
Changed
- All testing functions require
MonadConc
,MonadRef
, andMonadIO
constraints. Testing withST
is no longer possible. - (issue #123) All testing functions take the action to run as the final parameter.
- (issue #124) All testing functions have been generalised to take a
Test.DejaFu.ProPredicate
instead of aPredicate
.
Removed
- The
Test.DejaFu.Conc.ConcST
specific functions. - The orphan
IsTest
instance forTest.DejaFu.Conc.ConcST t (Maybe String)
.
Miscellaneous
- The version bounds on dejafu are >=1.0 && <1.1.
0.7.1.1 (2017-11-30)
- Git: tasty-dejafu-0.7.1.1
- Hackage: tasty-dejafu-0.7.1.1
Fixed
- A missing Haddock
@since
comments.
0.7.1.0 (2017-11-30)
- Git: tasty-dejafu-0.7.1.0
- Hackage: tasty-dejafu-0.7.1.0
Added
Test.Tasty.DejaFu.testPropertyFor
function.
0.7.0.3 (2017-11-02)
- Git: tasty-dejafu-0.7.0.3
- Hackage: tasty-dejafu-0.7.0.3
Miscellaneous
- The upper bound on tasty is <0.13.
0.7.0.2 (2017-10-11)
- Git: tasty-dejafu-0.7.0.2
- Hackage: tasty-dejafu-0.7.0.2
Miscellaneous
- The upper bound on dejafu is <0.10.
0.7.0.1 (2017-09-26)
- Git: tasty-dejafu-0.7.0.1
- Hackage: tasty-dejafu-0.7.0.1
Miscellaneous
- The upper bound on dejafu is <0.9.
0.7.0.0 - The Discard Release (2017-08-10)
- Git: tasty-dejafu-0.7.0.0
- Hackage: tasty-dejafu-0.6.0.0
Added
- Re-export for
Test.DejaFu.SCT.Discard
andTest.DejaFu.Defaults.defaultDiscarder
. Test.Tasty.DejaFu.testDejafuDiscard
andtestDejafuDiscardIO
functions.
Miscellaneous
- The lower bound on dejafu is >=0.7.1.
0.6.0.0 - The Refinement Release (2017-04-08)
- Git: tasty-dejafu-0.6.0.0
- Hackage: tasty-dejafu-0.6.0.0
Added
Test.Tasty.DejaFu.testProperty
function- Re-exports for
Test.DejaFu.SCT.systematically
,randomly
,uniformly
, andswarmy
. - Re-exports for
Test.DejaFu.Defaults.defaultWay
,defaultMemType
, anddefaultBounds
.
Removed
- Re-exports of the
Test.DejaFu.SCT.Way
constructors:Systematically
andRandomly
.
Miscellaneous
- The version bounds on dejafu are >=0.7 && <0.8.
0.5.0.0 - The Way Release (2017-04-08)
- Git: tasty-dejafu-0.5.0.0
- Hackage: tasty-dejafu-0.5.0.0
Changed
- Due to changes in dejafu, the
Way
type no longer takes a parameter; it is now a GADT.
Miscellaneous
- Every definition, class, and instance now has a Haddock
@since
annotation. - The version bounds on dejafu are >=0.6 && <0.7.
0.4.0.0 (2017-02-21)
- Git: tasty-dejafu-0.4.0.0
- Hackage: tasty-dejafu-0.4.0.0
Added
-
Re-export of
Test.DejaFu.SCT.Way
. -
Orphan
IsOption
instance forTest.DejaFu.SCT.Way
. Command-line parameters are:- "systematically": systematic testing with the default bounds
- "randomly": 100 executions with a fixed random seed
Changed
- All the functions which took a
Test.DejaFu.SCT.Bounds
now take aWay
.
Miscellaneous
0.3.0.2 (2016-09-10)
- Git: tasty-dejafu-0.3.0.2
- Hackage: tasty-dejafu-0.3.0.2
Miscellaneous
- The upper bound on dejafu is <0.5.
0.3.0.1 (2016-05-26)
- Git: tasty-dejafu-0.3.0.1
- Hackage: tasty-dejafu-0.3.0.1
Miscellaneous
0.3.0.0 (2016-04-28)
- Git: tasty-dejafu-0.3.0.0
- Hackage: tasty-dejafu-0.3.0.0
Added
-
Orphan
IsTest
instances forTest.DejaFu.Conc.ConcST t (Maybe String)
andConcIO (Maybe String)
. -
Orphan
IsOption
instances forTest.DejaFu.SCT.Bounds
andMemType
. Command-line parameters are:- "sc": sequential consistency
- "tso": total store order
- "pso": partial store order
-
Re-export
Test.DejaFu.SCT.Bounds
.
Miscellaneous
- The version bounds on dejafu are >=0.2
0.1.1.0 (2016-04-03)
- Git: tasty-dejafu-0.1.1.0
Note: this was misnumbered (it should have been 0.2.1.0) and was never pushed to Hackage, whoops!
Miscellaneous
- The version bounds on dejafu are 0.3.*.
0.2.0.0 - The Initial Release (2015-12-01)
- Git: 0.2.0.0
- Hackage: tasty-dejafu-0.2.0.0
Added
- Everything.