{-# LANGUAGE RecordWildCards, TupleSections #-} module Development.Bake.Server.Property( rejectable, plausible, mergeable, extendActive, restrictActive ) where import Development.Bake.Server.Memory import Development.Bake.Server.Store import qualified Data.Set as Set import qualified Data.Map as Map import Development.Bake.Core.Type import Data.Maybe import General.Extra import Data.List -- | I can reject the tests rejected because of the given patches rejectable :: Memory -> [(Patch, Maybe Test)] -- only look at failing tests in the current state -- find tests which have a passed/failed one apart -- assume the state passes everything -- if a test isn't avaiable at a point, it passes rejectable Memory{..} = [(last ps, t) | ps <- tail $ inits $ snd active , let me = storePoint store (fst active, ps) , let prev = if length ps == 1 then piState else storePoint store (fst active, init ps) , t <- failed , poTest me t == Just False && poTest prev t == Just True] where piState = PointInfo (Just Set.empty) (Set.singleton Nothing) Set.empty -- tests that are failing in self, interesting to consider failed = Set.toList $ poFail $ storePoint store active -- | I can mark all active patches as plausible plausible :: Memory -> Bool plausible Memory{..} | all (isNothing . paReject . storePatch store) $ snd active , PointInfo{..} <- storePoint store active , Just tests <- poTodo , Set.null poFail , tests `Set.isSubsetOf` Set.union (storeSupersetPass store active) (catMaybesSet poPass) = True plausible _ = False -- | I can merge all active patches mergeable :: Memory -> Bool mergeable mem@Memory{..} | plausible mem , PointInfo{..} <- storePoint store active , Just tests <- poTodo , tests == catMaybesSet poPass = True mergeable _ = False -- | Add in all extra patches that are queued extendActive :: Memory -> Bool -- either there are no patches being tested, or the ones being tested are all plausible -- relies on throwing out the rejected ones with restrictActive first extendActive Memory{..} = all (isJust . paPlausible . storePatch store) $ snd active -- | Throw out the patches that have been rejected restrictActive :: Memory -> Bool restrictActive Memory{..} -- I can reject someone for failing preparation | Nothing `Set.member` rejectedTests = True -- if all tests either (passed on active or a superset) -- or (failed on active and lead to a rejection) -- or (depend on a test that failed) | not $ Set.null rejectedTests , PointInfo{..} <- storePoint store active , Just tests <- poTodo , let pass = Set.union (storeSupersetPass store active) $ catMaybesSet $ poPass `Set.difference` poFail , flip all (Set.toList tests) $ \t -> t `Set.member` pass || any (flip Set.member rejectedTests . Just) (transitiveClosure (testDepend . ovenTestInfo oven) [t]) = True | otherwise = False where rejectedTests = Set.unions $ mapMaybe (fmap (Map.keysSet . snd) . paReject . storePatch store) $ snd active