packages feed

hunit-dejafu 0.2.0.0 → 0.3.0.0

raw patch · 2 files changed

+99/−21 lines, 2 filesdep +exceptionsdep ~dejafu

Dependencies added: exceptions

Dependency ranges changed: dejafu

Files

Test/HUnit/DejaFu.hs view
@@ -1,34 +1,101 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeSynonymInstances #-}  -- | This module allows using Deja Fu predicates with HUnit to test -- the behaviour of concurrent systems. module Test.HUnit.DejaFu-  ( -- * Testing+  ( -- * Unit testing++  -- | This is supported by the 'Assertable' and 'Testable'+  -- instances for 'ConcST' and 'ConcIO'. These instances try all+  -- executions, reporting as failures the cases which throw an+  -- 'HUnitFailure' exception.+  --+  -- @instance Testable   (ConcST t ())@+  -- @instance Assertable (ConcST t ())@+  -- @instance Testable   (ConcIO   ())@+  -- @instance Assertable (ConcIO   ())@+  --+  -- These instances use the default memory model and schedule bounds.++  -- * Property testing     testAuto   , testDejafu   , testDejafus++  , testAuto'+  , testDejafu'+  , testDejafus'++  -- ** @IO@   , testAutoIO   , testDejafuIO   , testDejafusIO -  -- * Testing under Alternative Memory Models-  , MemType(..)-  , testAuto'   , testAutoIO'-  , testDejafu'-  , testDejafus'   , testDejafuIO'   , testDejafusIO'++  -- * Re-exports+  , Bounds(..)+  , MemType(..)   ) where +import Control.Monad.Catch (try)+import Data.List (intercalate, intersperse) import Test.DejaFu-import Test.DejaFu.Deterministic (ConcST, ConcIO, showFail, showTrace)+import Test.DejaFu.Deterministic (ConcST, ConcIO, Trace, ThreadId, ThreadAction, Lookahead, showFail, showTrace) import Test.DejaFu.SCT (sctBound, sctBoundIO)-import Test.HUnit (Test(..), assertString)+import Test.HUnit (Assertable(..), Test(..), Testable(..), assertString)+import Test.HUnit.Lang (HUnitFailure(..)) +-- Can't put the necessary forall in the @Assertable ConcST t@+-- instance :(+import Unsafe.Coerce (unsafeCoerce)++#if MIN_VERSION_dejafu(0,3,0)+type Trc = Trace ThreadId ThreadAction Lookahead+#else+type Trc = Trace+#endif+ ----------------------------------------------------------------------------------- Automated testing+-- Unit testing +instance Testable (ConcST t ()) where+  test conc = TestCase (assert conc)++instance Testable (ConcIO ()) where+  test conc = TestCase (assert conc)++instance Assertable (ConcST t ()) where+  assert conc = do+    let traces = sctBound' conc'+    assertString . showErr $ assertableP traces++    where+      conc' :: ConcST t (Either HUnitFailure ())+      conc' = try conc++      sctBound' :: ConcST t (Either HUnitFailure ()) -> [(Either Failure (Either HUnitFailure ()), Trc)]+      sctBound' = unsafeCoerce $ sctBound defaultMemType defaultBounds++instance Assertable (ConcIO ()) where+  assert conc = do+    traces <- sctBoundIO defaultMemType defaultBounds (try conc)+    assertString . showErr $ assertableP traces++assertableP :: Predicate (Either HUnitFailure ())+assertableP = alwaysTrue $ \r -> case r of+  Right (Left (HUnitFailure _ _)) -> False+  _ -> True++--------------------------------------------------------------------------------+-- Property testing+ -- | Automatically test a computation. In particular, look for -- deadlocks, uncaught exceptions, and multiple return values. -- @@ -67,9 +134,6 @@   , ("Consistent Result", alwaysSame)   ] ------------------------------------------------------------------------------------ Manual testing- -- | Check that a predicate holds. testDejafu :: Show a   => (forall t. ConcST t a)@@ -82,7 +146,7 @@ testDejafu = testDejafu' defaultMemType defaultBounds  -- | Variant of 'testDejafu' which takes a memory model and--- pre-emption bound.+-- schedule bounds. testDejafu' :: Show a   => MemType   -- ^ The memory model to use for non-synchronised @CRef@ operations.@@ -108,8 +172,8 @@   -> Test testDejafus = testDejafus' defaultMemType defaultBounds --- | Variant of 'testDejafus' which takes a memory model and pre-emption--- bound.+-- | Variant of 'testDejafus' which takes a memory model and schedule+-- bounds. testDejafus' :: Show a   => MemType   -- ^ The memory model to use for non-synchronised @CRef@ operations.@@ -120,7 +184,7 @@   -> [(String, Predicate a)]   -- ^ The list of predicates (with names) to check   -> Test-testDejafus' = test+testDejafus' = testst  -- | Variant of 'testDejafu' for computations which do 'IO'. testDejafuIO :: Show a => ConcIO a -> String -> Predicate a -> Test@@ -142,8 +206,8 @@ -- HUnit integration  -- | Produce a HUnit 'Test' from a Deja Fu test.-test :: Show a => MemType -> Bounds -> (forall t. ConcST t a) -> [(String, Predicate a)] -> Test-test memtype cb conc tests = case map toTest tests of+testst :: Show a => MemType -> Bounds -> (forall t. ConcST t a) -> [(String, Predicate a)] -> Test+testst memtype cb conc tests = case map toTest tests of   [t] -> t   ts  -> TestList ts @@ -168,6 +232,9 @@       traces <- sctBoundIO memtype cb concio       assertString . showErr $ p traces +--------------------------------------------------------------------------------+-- Utilities+ -- | Convert a test result into an error message on failure (empty -- string on success). showErr :: Show a => Result a -> String@@ -177,8 +244,10 @@    msg = if null (_failureMsg res) then "" else _failureMsg res ++ "\n" -  failures = map (\(r, t) -> "\t" ++ either showFail show r ++ " " ++ showTrace t) . take 5 $ _failures res+  failures = intersperse "" . map (indent . showres) . take 5 $ _failures res +  showres (r, t) = either showFail show r ++ " " ++ showTrace t+   rest = if moreThan (_failures res) 5 then "\n\t..." else ""  -- | Check if a list has more than some number of elements.@@ -187,3 +256,6 @@ moreThan _ 0  = True moreThan (_:xs) n = moreThan xs (n-1) +-- | Indent every line of a string.+indent :: String -> String+indent = intercalate "\n" . map ('\t':) . lines
hunit-dejafu.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                hunit-dejafu-version:             0.2.0.0+version:             0.3.0.0 synopsis:            Deja Fu support for the HUnit test framework.  description:@@ -30,12 +30,18 @@   type:     git   location: https://github.com/barrucadu/dejafu.git +source-repository this+  type:     git+  location: https://github.com/barrucadu/dejafu.git+  tag:      hunit-dejafu-0.3.0.0+ library   exposed-modules:     Test.HUnit.DejaFu   -- other-modules:          -- other-extensions:       build-depends:       base >=4.5 && <5-                     , dejafu == 0.2.*+                     , exceptions+                     , dejafu >= 0.2                      , HUnit   -- hs-source-dirs:         default-language:    Haskell2010