{-# LANGUAGE OverloadedStrings #-} module Kudzu where import Control.Monad (unless) import qualified Hedgehog as HH import qualified Test.LeanCheck as LC import qualified Test.QuickCheck as QC import qualified Test.QuickCheck.Random as QC -- import Trace.Hpc.Mix import Trace.Hpc.Reflect (examineTix) import Trace.Hpc.Tix (Tix (..), TixModule (..)) testUntilSameQCMany :: (Traversable t, QC.Testable a) => Int -> t a -> IO (t (KudzuResult Integer)) testUntilSameQCMany howMany ts = do mapM (testUntilSameQC howMany) ts -- | QuickCheck testUntilSameQC :: (QC.Testable a) => Int -> a -> IO (KudzuResult Integer) testUntilSameQC n testable = do let rs = map (examineAndCount' testable) [0 .. n] grabUntilNSame n rs examineAndCount' :: (QC.Testable prop) => prop -> Int -> IO Integer examineAndCount' v size = do qcg <- QC.newQCGen QC.quickCheckWith (QC.stdArgs{QC.replay = Just (qcg, size)}) (QC.withMaxSuccess 1 v) tixModuleCount <$> examineTix -- | Hedgehog testUntilSameHHMany :: (Traversable t) => Int -> t HH.Property -> IO (t (KudzuResult Integer)) testUntilSameHHMany howMany ps = do mapM (testUntilSameHH howMany) ps testUntilSameHH :: Int -> HH.Property -> IO (KudzuResult Integer) testUntilSameHH n prop = grabUntilNSame n $ examineAndCountHH <$> repeat prop examineAndCountHH :: HH.Property -> IO Integer examineAndCountHH prop = do passed <- HH.check . HH.withTests 1 $ prop unless passed $ error "property failed" tixModuleCount <$> examineTix -- | LeanCheck testUntilSameLCMany :: (Traversable t, LC.Testable a) => Int -> t a -> IO (t (KudzuResult Integer)) testUntilSameLCMany howMany ts = do mapM (testUntilSameLC howMany) ts testUntilSameLC :: (LC.Testable a) => Int -> a -> IO (KudzuResult Integer) testUntilSameLC n testable = grabUntilNSame n $ examineAndCount <$> LC.results testable examineAndCount :: ([String], Bool) -> IO Integer examineAndCount v = unless (snd v) (error $ unwords ("test failed with:" : fst v)) >> tixModuleCount <$> examineTix data KudzuResult a = KFail Int | KSuccess Int a deriving (Show, Eq, Ord) -- | Keep running property tests until the "amount" of code coverage is the same for N iterations of one test. grabUntilNSame :: (Monad m, Eq a) => -- | How many iterations must be the same? Int -> -- | a lazy list of iterations [m a] -> m (KudzuResult a) grabUntilNSame _ [] = pure $ KFail 0 grabUntilNSame orig (a : as) = do a' <- a -- run the first iteration of the test go 0 orig as a' where go c 0 _ z = pure $ KSuccess c z -- we reached the desired window size go c _ [] _ = pure $ KFail c -- if we run out of list elements for test results, we're done go c n (b : bs) z = do a' <- b if a' == z then go (c + 1) (n - 1) bs z else go (c + 1) orig as a' -- | How many regions were executed at least once for this module? tixCount :: TixModule -> Integer tixCount (TixModule _ _ _ regions) = sum $ 1 <$ filter (> 0) regions -- | How many regions were executed at least once for all these modules? tixModuleCount :: Tix -> Integer tixModuleCount (Tix ms) = sum $ map tixCount ms -- foo = Mix "src/Data/Array/Accelerate/Trafo/Config.hs" 2024 - 04 - 22 14 : 30 : 08.311359928 UTC 3070486 8 [(41 : 18 - 41 : 32, ExpBox False), (42 : 3 - 42 : 8, ExpBox False), (42 : 15 - 42 : 20, ExpBox False), (42 : 25 - 42 : 34, ExpBox False), (42 : 24 - 42 : 39, ExpBox False), (42 : 14 - 42 : 40, ExpBox False), (42 : 3 - 42 : 40, ExpBox False), (42 : 51 - 42 : 68, ExpBox False), (42 : 46 - 42 : 68, ExpBox False), (42 : 3 - 42 : 68, ExpBox False), (43 : 15 - 43 : 26, ExpBox False), (43 : 43 - 43 : 67, ExpBox False), (43 : 32 - 43 : 67, ExpBox False), (43 : 14 - 43 : 68, ExpBox False), (42 : 3 - 43 : 68, ExpBox False), (44 : 15 - 44 : 26, ExpBox False), (44 : 43 - 44 : 69, ExpBox False), (44 : 32 - 44 : 69, ExpBox False), (44 : 14 - 44 : 70, ExpBox False), (42 : 3 - 44 : 70, ExpBox False), (41 : 18 - 44 : 70, ExpBox False), (41 : 1 - 44 : 70, TopLevelBox ["defaultOptions"]), (33 : 5 - 33 : 11, ExpBox False), (33 : 5 - 33 : 11, TopLevelBox ["options"]), (34 : 5 - 34 : 27, ExpBox False), (34 : 5 - 34 : 27, TopLevelBox ["unfolding_use_threshold"]), (35 : 5 - 35 : 29, ExpBox False), (35 : 5 - 35 : 29, TopLevelBox ["max_simplifier_iterations"]), (37 : 12 - 37 : 15, TopLevelBox ["showsPrec"]), (37 : 12 - 37 : 15, TopLevelBox ["show"]), (37 : 12 - 37 : 15, TopLevelBox ["showList"])] -- bar = Mix "src/Data/Array/Accelerate/Classes/ToFloating.hs" 2024 - 04 - 22 14 : 30 : 08.304359842 UTC 1185370804 8 [(47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"]), (47 : 2 - 79 : 2, ExpBox False), (47 : 2 - 79 : 2, TopLevelBox ["toFloating"])]