From 45fb82f3fdc4115c022e740db461f98a95cfd177 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Mon, 25 Feb 2008 12:08:59 +0000 Subject: [PATCH] Fixed the tests in UsageCheckTest that had been temporarily commented out --- checks/UsageCheckTest.hs | 115 +++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 65 deletions(-) diff --git a/checks/UsageCheckTest.hs b/checks/UsageCheckTest.hs index 392789e..9ded938 100644 --- a/checks/UsageCheckTest.hs +++ b/checks/UsageCheckTest.hs @@ -18,16 +18,19 @@ with this program. If not, see . module UsageCheckTest (tests) where +import Control.Monad.Error import Control.Monad.Identity +import Control.Monad.Reader import Data.Graph.Inductive import qualified Data.Map as Map import qualified Data.Set as Set import Prelude hiding (fail) import Test.HUnit - import qualified AST as A import Check +import CompState +import Errors import FlowGraph import Metadata import TestUtils hiding (Var) @@ -51,6 +54,7 @@ tvC = Var $ vC tvD = Var $ vD tvL = Var $ vL +m :: Meta m = emptyMeta --These are all shorthand for some useful "building block" processes @@ -77,7 +81,6 @@ testGetVarProc = TestList (map doTest tests) [ --TODO test channel reads and writes (incl. reads in alts) --TODO test process calls ---TODO test function calls --Test assignments on non-sub variables: (0,[],[tvA],[],a_eq_0) @@ -112,50 +115,32 @@ testGetVarProc = TestList (map doTest tests) --TODO test declarations being recorded, when I've decided how to record them -{- -testParUsageCheck :: Test -testParUsageCheck = TestList (map doTest tests) - where - tests = - [ - (0,makePar [a_eq_0,a_eq_b],Just [makePar [a_eq_0,a_eq_b]]) - ,(1,makeSeq [a_eq_0,a_eq_b],Nothing) - ,(2,makePar [a_eq_b,c_eq_d],Nothing) - ,(3,makePar [a_eq_b,c_eq_b],Nothing) - ,(4,makeSeq [makePar [a_eq_0,a_eq_b],makePar [c_eq_b,c_eq_d]],Just [makePar [a_eq_0,a_eq_b],makePar [c_eq_b,c_eq_d]]) - ,(5,makePar [makePar [a_eq_0,a_eq_b],makePar [c_eq_b,c_eq_d]],Just [makePar [a_eq_0,a_eq_b],makePar [c_eq_b,c_eq_d]]) - ,(6,makePar [makeSeq [a_eq_0,c_eq_d],c_eq_b],Just [makePar [makeSeq [a_eq_0,c_eq_d],c_eq_b]]) - ,(7,makePar [makeSeq [a_eq_0,a_eq_b],c_eq_b],Nothing) +type TestM = ReaderT CompState (Either String) +instance Die TestM where + dieReport (_,s) = throwError s +instance Warn TestM where + warnReport (_,s) = throwError s - --Replicated PARs: - --TODO change this to par each loops: - - ,(300,makeRepPar a_eq_0,Just [makeRepPar a_eq_0]) - ,(301,makeRepPar $ makeSeq [a_eq_0],Just [makeRepPar $ makeSeq [a_eq_0]]) - ,(302,makeRepPar $ makePar [a_eq_0],Just [makeRepPar $ makePar [a_eq_0]]) +assertTestCheck :: String -> Bool -> TestM () -> Assertion +assertTestCheck msg exp act = case (exp, runReaderT act emptyState) of + (True, Left err) -> assertFailure (msg ++ " expected pass but failed: " ++ show err) + (False, Right _) -> assertFailure (msg ++ " expected fail but passed") + _ -> return () - ] - doTest :: (Int,A.Process,Maybe [A.Process]) -> Test - doTest (index,proc,exp) = TestCase $ assertEqual ("testParUsageCheck-" ++ (show index)) exp (UC.parUsageCheck proc) --} - ---TODO add tests for initialising a variable before use. ---TODO especially test things like only initialising the variable in one part of an if - -buildTestFlowGraph :: [(Int, [Var], [Var])] -> [(Int, Int, EdgeLabel)] -> Int -> Int -> String -> FlowGraph Identity UsageLabel +buildTestFlowGraph :: [(Int, [Var], [Var])] -> [(Int, Int, EdgeLabel)] -> Int -> Int -> String -> FlowGraph TestM UsageLabel buildTestFlowGraph ns es start end v = mkGraph ([(-1,makeTestNode emptyMeta $ Usage Nothing (Just $ ScopeIn False v) emptyVars),(-2,makeTestNode emptyMeta $ Usage Nothing (Just $ ScopeOut v) emptyVars)] ++ (map transNode ns)) ([(-1,start,ESeq),(end,-2,ESeq)] ++ es) where - transNode :: (Int, [Var], [Var]) -> (Int, FNode Identity UsageLabel) + transNode :: (Int, [Var], [Var]) -> (Int, FNode TestM UsageLabel) transNode (n,r,w) = (n,makeTestNode emptyMeta (Usage Nothing Nothing $ vars r w [])) +--TODO add tests for initialising a variable before use. +--TODO especially test things like only initialising the variable in one part of an if testInitVar :: Test testInitVar = TestList - [] -{- TODO fix these tests [ -- Single node, x not touched testInitVarPass 0 [(0,[],[])] [] 0 0 "x" @@ -166,92 +151,93 @@ testInitVar = TestList -- Single node, x read from and written to (FAIL - x must be written to before the read. -- This line is akin to x = x + 1, so x must be written to beforehand) ,testInitVarFail 3 [(0,[variable "x"],[variable "x"])] [] 0 0 "x" - + -- Two nodes, x written to then read - ,testInitVarPass 10 [(0,[],[variable "x"]), (1,[variable "x"],[],[])] [(0,1,ESeq)] 0 1 "x" + ,testInitVarPass 10 [(0,[],[variable "x"]), (1,[variable "x"],[])] [(0,1,ESeq)] 0 1 "x" -- Two nodes, x read then written to (FAIL) - ,testInitVarFail 11 [(0,[],[variable "x"]), (1,[variable "x"],[],[])] [(1,0,ESeq)] 1 0 "x" - -- Two nodes, x maybe-written to then read (FAIL) - ,testInitVarFail 12 [(0,[],[variable "x"],[]), (1,[variable "x"],[],[])] [(0,1,ESeq)] 0 1 "x" + ,testInitVarFail 11 [(0,[],[variable "x"]), (1,[variable "x"],[])] [(1,0,ESeq)] 1 0 "x" -- As test 10 (x written to then read) but using the par edges. - ,testInitVarPass 13 [(0,[],[],[variable "x"]), (1,[variable "x"],[],[])] [(0,1,EStartPar 0)] 0 1 "x" - ,testInitVarPass 14 [(0,[],[],[variable "x"]), (1,[variable "x"],[],[])] [(0,1,EEndPar 0)] 0 1 "x" + ,testInitVarPass 13 [(0,[],[variable "x"]), (1,[variable "x"],[])] [(0,1,EStartPar 0)] 0 1 "x" + ,testInitVarPass 14 [(0,[],[variable "x"]), (1,[variable "x"],[])] [(0,1,EEndPar 0)] 0 1 "x" -- Diamond tests (0 branches to 1 and 2, which both merge to 3): -- x written to in 0 and 1, then read in 3 - ,testInitVarPass 20 [(0,[],[],[]),(1,[],[],[variable "x"]), (2,[],[],[variable "x"]), (3,[variable "x"],[],[])] + ,testInitVarPass 20 [(0,[],[]),(1,[],[variable "x"]), (2,[],[variable "x"]), (3,[variable "x"],[])] [(0,1,ESeq),(0,2,ESeq),(1,3,ESeq),(2,3,ESeq)] 0 3 "x" -- x written to only in 2 then read in 3 (FAIL) - ,testInitVarFail 21 [(0,[],[],[]),(1,[],[],[]), (2,[],[],[variable "x"]), (3,[variable "x"],[],[])] + ,testInitVarFail 21 [(0,[],[]),(1,[],[]), (2,[],[variable "x"]), (3,[variable "x"],[])] [(0,1,ESeq),(0,2,ESeq),(1,3,ESeq),(2,3,ESeq)] 0 3 "x" -- x definitely written to in 2, but not 1 (FAIL) - ,testInitVarFail 22 [(0,[],[],[]),(1,[],[variable "x"],[]), (2,[],[],[variable "x"]), (3,[variable "x"],[],[])] + ,testInitVarFail 22 [(0,[],[]),(1,[],[]), (2,[],[variable "x"]), (3,[variable "x"],[])] [(0,1,ESeq),(0,2,ESeq),(1,3,ESeq),(2,3,ESeq)] 0 3 "x" -- like test 21, but the link missing from 1 to 3, so test will pass - ,testInitVarPass 23 [(0,[],[],[]),(1,[],[],[]), (2,[],[],[variable "x"]), (3,[variable "x"],[],[])] + ,testInitVarPass 23 [(0,[],[]),(1,[],[]), (2,[],[variable "x"]), (3,[variable "x"],[])] [(0,1,ESeq),(0,2,ESeq),(2,3,ESeq)] 0 3 "x" -- variable written to in 0, read in 3 - ,testInitVarPass 24 [(0,[],[],[variable "x"]),(1,[],[],[]), (2,[],[],[]), (3,[variable "x"],[],[])] + ,testInitVarPass 24 [(0,[],[variable "x"]),(1,[],[]), (2,[],[]), (3,[variable "x"],[])] [(0,1,ESeq),(0,2,ESeq),(1,3,ESeq),(2,3,ESeq)] 0 3 "x" -- variable never written to, but read in 3 - ,testInitVarFail 25 [(0,[],[],[]),(1,[],[],[]), (2,[],[],[]), (3,[variable "x"],[],[])] + ,testInitVarFail 25 [(0,[],[]),(1,[],[]), (2,[],[]), (3,[variable "x"],[])] [(0,1,ESeq),(0,2,ESeq),(1,3,ESeq),(2,3,ESeq)] 0 3 "x" -- variable written to in 2 and 3, but read in 1 (FAIL): - ,testInitVarFail 26 [(0,[],[],[]),(1,[variable "x"],[],[]), (2,[],[],[variable "x"]), (3,[],[],[variable "x"])] + ,testInitVarFail 26 [(0,[],[]),(1,[variable "x"],[]), (2,[],[variable "x"]), (3,[],[variable "x"])] [(0,1,ESeq),(0,2,ESeq),(1,3,ESeq),(2,3,ESeq)] 0 3 "x" -- Test parallel diamonds: -- written to in 1 and 2, read in 3 -- This would fail CREW, but that's not what we're testing here: - ,testInitVarPass 30 [(0,[],[],[]),(1,[],[],[variable "x"]), (2,[],[],[variable "x"]), (3,[variable "x"],[],[])] + ,testInitVarPass 30 [(0,[],[]),(1,[],[variable "x"]), (2,[],[variable "x"]), (3,[variable "x"],[])] [(0,1,EStartPar 0),(0,2,EStartPar 0),(1,3,EEndPar 0),(2,3,EEndPar 0)] 0 3 "x" -- written to in 1, read in 3 - ,testInitVarPass 31 [(0,[],[],[]),(1,[],[],[variable "x"]), (2,[],[],[]), (3,[variable "x"],[],[])] + ,testInitVarPass 31 [(0,[],[]),(1,[],[variable "x"]), (2,[],[]), (3,[variable "x"],[])] [(0,1,EStartPar 0),(0,2,EStartPar 0),(1,3,EEndPar 0),(2,3,EEndPar 0)] 0 3 "x" -- written to in 0, read in 3 - ,testInitVarPass 32 [(0,[],[],[variable "x"]),(1,[],[],[]), (2,[],[],[]), (3,[variable "x"],[],[])] + ,testInitVarPass 32 [(0,[],[variable "x"]),(1,[],[]), (2,[],[]), (3,[variable "x"],[])] [(0,1,EStartPar 0),(0,2,EStartPar 0),(1,3,EEndPar 0),(2,3,EEndPar 0)] 0 3 "x" -- never written to, but read in 3: - ,testInitVarFail 33 [(0,[],[],[]),(1,[],[],[]), (2,[],[],[]), (3,[variable "x"],[],[])] + ,testInitVarFail 33 [(0,[],[]),(1,[],[]), (2,[],[]), (3,[variable "x"],[])] [(0,1,EStartPar 0),(0,2,EStartPar 0),(1,3,EEndPar 0),(2,3,EEndPar 0)] 0 3 "x" -- written to in 1, read in 2 (again, would fail CREW) (FAIL): - ,testInitVarFail 34 [(0,[],[],[]),(1,[],[],[variable "x"]), (2,[variable "x"],[],[]), (3,[],[],[])] + ,testInitVarFail 34 [(0,[],[]),(1,[],[variable "x"]), (2,[variable "x"],[]), (3,[],[])] [(0,1,EStartPar 0),(0,2,EStartPar 0),(1,3,EEndPar 0),(2,3,EEndPar 0)] 0 3 "x" -- written to in 1, read in 2 and 3 (again, would fail CREW) (FAIL): - ,testInitVarFail 35 [(0,[],[],[]),(1,[],[],[variable "x"]), (2,[variable "x"],[],[]), (3,[variable "x"],[],[])] + ,testInitVarFail 35 [(0,[],[]),(1,[],[variable "x"]), (2,[variable "x"],[]), (3,[variable "x"],[])] [(0,1,EStartPar 0),(0,2,EStartPar 0),(1,3,EEndPar 0),(2,3,EEndPar 0)] 0 3 "x" - + -- Test loops (0 -> 1, 1 -> 2 -> 3 -> 1, 1 -> 4) -- Loop, nothing happens: - ,testInitVarPass 100 [(0,[],[],[]),(1,[],[],[]),(2,[],[],[]),(3,[],[],[]),(4,[],[],[])] + ,testInitVarPass 100 [(0,[],[]),(1,[],[]),(2,[],[]),(3,[],[]),(4,[],[])] [(0,1,ESeq), (1,2,ESeq), (2,3,ESeq), (3,1,ESeq), (1,4,ESeq)] 0 4 "x" -- Loop, written to before the loop, read afterwards: - ,testInitVarPass 101 [(0,[],[],[variable "x"]),(1,[],[],[]),(2,[],[],[]),(3,[],[],[]),(4,[variable "x"],[],[])] + ,testInitVarPass 101 [(0,[],[variable "x"]),(1,[],[]),(2,[],[]),(3,[],[]),(4,[variable "x"],[])] [(0,1,ESeq), (1,2,ESeq), (2,3,ESeq), (3,1,ESeq), (1,4,ESeq)] 0 4 "x" -- Loop, written to before the loop, read during the loop - ,testInitVarPass 102 [(0,[],[],[variable "x"]),(1,[],[],[]),(2,[],[],[]),(3,[variable "x"],[],[]),(4,[],[],[])] + ,testInitVarPass 102 [(0,[],[variable "x"]),(1,[],[]),(2,[],[]),(3,[variable "x"],[]),(4,[],[])] [(0,1,ESeq), (1,2,ESeq), (2,3,ESeq), (3,1,ESeq), (1,4,ESeq)] 0 4 "x" -- Loop, written to during the loop, read afterwards (FAIL - loop might not be executed) - ,testInitVarFail 103 [(0,[],[],[]),(1,[],[],[]),(2,[],[],[variable "x"]),(3,[],[],[]),(4,[variable "x"],[],[])] + ,testInitVarFail 103 [(0,[],[]),(1,[],[]),(2,[],[variable "x"]),(3,[],[]),(4,[variable "x"],[])] [(0,1,ESeq), (1,2,ESeq), (2,3,ESeq), (3,1,ESeq), (1,4,ESeq)] 0 4 "x" -- Loop, written to and then read during the loop: - ,testInitVarPass 104 [(0,[],[],[]),(1,[],[],[]),(2,[],[],[variable "x"]),(3,[variable "x"],[],[]),(4,[],[],[])] + ,testInitVarPass 104 [(0,[],[]),(1,[],[]),(2,[],[variable "x"]),(3,[variable "x"],[]),(4,[],[])] [(0,1,ESeq), (1,2,ESeq), (2,3,ESeq), (3,1,ESeq), (1,4,ESeq)] 0 4 "x" -- Loop, read then written to during the loop (FAIL): - ,testInitVarFail 105 [(0,[],[],[]),(1,[],[],[]),(2,[variable "x"],[],[]),(3,[],[],[variable "x"]),(4,[],[],[])] + ,testInitVarFail 105 [(0,[],[]),(1,[],[]),(2,[variable "x"],[]),(3,[],[variable "x"]),(4,[],[])] [(0,1,ESeq), (1,2,ESeq), (2,3,ESeq), (3,1,ESeq), (1,4,ESeq)] 0 4 "x" -- TODO work out (and test) par loops -- TODO test dereferenced variables + ] where testInitVarPass :: Int -> [(Int, [Var], [Var])] -> [(Int, Int, EdgeLabel)] -> Int -> Int -> String -> Test - testInitVarPass testNum ns es start end v = TestCase $ assertEither ("testInitVar " ++ show testNum) () $ checkInitVar (buildTestFlowGraph ns es start end v) (-1) + testInitVarPass testNum ns es start end v = TestCase $ assertEither ("testInitVar " ++ show testNum) () $ flip runReaderT emptyState $ checkInitVar emptyMeta (buildTestFlowGraph ns es start end v) (-1) testInitVarFail :: Int -> [(Int, [Var], [Var])] -> [(Int, Int, EdgeLabel)] -> Int -> Int -> String -> Test - testInitVarFail testNum ns es start end v = TestCase $ assertEitherFail ("testInitVar " ++ show testNum) $ checkInitVar (buildTestFlowGraph ns es start end v) (-1) --} + testInitVarFail testNum ns es start end v = TestCase $ assertEitherFail ("testInitVar " ++ show testNum) $ flip runReaderT emptyState $ checkInitVar emptyMeta (buildTestFlowGraph ns es start end v) (-1) + + variable = Var . A.Variable emptyMeta . simpleName + testReachDef :: Test testReachDef = TestList @@ -310,6 +296,5 @@ tests = TestLabel "RainUsageCheckTest" $ TestList [ testGetVarProc ,testInitVar --- ,testParUsageCheck ,testReachDef ]