-- -- To process raw data, and produce averaged scores per tool. Just run the "main" function. -- import Data.List import System.IO dirt3dumb = "./t3/" dirt3custom = "./t3custom/" dirEvo = "./evosuite/" dirManual = "./manual/" dirRandoop = "./randoop/" evofiles = [ dirEvo ++ run ++ "/transcript.txt" | run <- ["run1", "run2", "run3"]] manualfiles = [ dirManual ++ run ++ "/transcript.txt" | run <- ["run1", "run2", "run3"]] randoopfiles = [ dirRandoop ++ run ++ "/transcript.txt" | run <- ["run1", "run2", "run3"]] t3dumbfiles = [ dirt3dumb ++ run ++ "/transcript.txt" | run <- ["run1", "run2", "run3"]] t3customBSTfiles = [ dirt3custom ++ "customconf/" ++ dir ++ "/transcript.txt" | dir <- ["bstrun1","bstrun2","bstrun3"] ] t3customXshowfiles = [ dirt3custom ++ "customconf/" ++ dir ++ "/transcript.txt" | dir <- ["xshowrun1","xshowrun2","xshowrun3"] ] t3customRestfiles = [ dirt3custom ++ "customconf/" ++ dir ++ "/transcript.txt" | dir <- ["restrun1","restrun2","restrun3"] ] t3valgenBSTfiles = [ dirt3custom ++ "customconfAndValgen/" ++ dir ++ "/transcript.txt" | dir <- ["bstrun1","bstrun2","bstrun3"] ] t3valgenXshowfiles = [ dirt3custom ++ "customconfAndValgen/" ++ dir ++ "/transcript.txt" | dir <- ["xshowrun1","xshowrun2","xshowrun3"] ] t3valgenXpoolfiles = [ dirt3custom ++ "customconfAndValgen/" ++ dir ++ "/transcript.txt" | dir <- ["restrun1","xpoolrun2","xpoolrun3"] ] t3valgenRestfiles = [ dirt3custom ++ "customconfAndValgen/" ++ dir ++ "/transcript.txt" | dir <- ["restrun1","restrun2","restrun3"] ] t3specBSTfiles = [ dirt3custom ++ "withSpec/" ++ dir ++ "/transcript.txt" | dir <- ["bstrun1","bstrun2","bstrun3"] ] t3specXshowfiles = [ dirt3custom ++ "withSpec/" ++ dir ++ "/transcript.txt" | dir <- ["xshowrun1","xshowrun2","xshowrun3"] ] t3specRestfiles = [ dirt3custom ++ "withSpec/" ++ dir ++ "/transcript.txt" | dir <- ["restrun1","restrun2","restrun3"] ] data ScoreTable = ScoreTable { tool :: String, rows :: [Row] } deriving Show data Row = Row { cut :: String, gentime :: Float , -- in secs testExectime :: Float , nmethod :: Int , -- num of methods vmethod :: Float, -- num or visited methods mcov :: Float, -- in percentage nbranch :: Int, vbranch :: Float, bcov :: Float, cbm :: Int, kcbm :: Float, -- killed cb mutation ncm :: Int, kncm :: Float, mm :: Int, kmm :: Float, im :: Int, kim :: Float, inm :: Int, kinm :: Float, rvm :: Int, krvm :: Float, vmcm :: Int, kvmcm :: Float, mut :: Int, kmut :: Float, mutcov :: Float} deriving Show mkPairs :: Row -> [(String,String)] mkPairs info = [("CUT" , show (cut info)) , ("Gentime" , show (gentime info)) , ("Exectime" , show (testExectime info)), ("Methods" , show (nmethod info)), ("vMethods" , show (vmethod info)), ("Mcov" , show(mcov info)), ("Branch" , show(nbranch info)), ("vBranch" , show(vbranch info)) , ("Bcov" , show(bcov info)), ("CBM" , show(cbm info)), ("kCBM" , show (kcbm info)), ("NCM" , show (ncm info)), ("kNCM" , show (kncm info)), ("MM", show(mm info)), ("kMM" , show(kmm info)), ("IM" , show(im info)), ("kIM" , show(kim info)), ("INM" , show(inm info)), ("kINM" , show(kinm info)), ("RVM" , show(rvm info)), ("kRVM" , show(krvm info)), ("VMCM" , show(vmcm info)), ("kVMCM", show(kvmcm info)), ("Mutations", show (mut info)), ("kMutations" , show (kmut info)), ("Mutcov" , show (mutcov info)) ] toSCformat :: ScoreTable -> String toSCformat (ScoreTable tool rows) = unlines (("Tool : " ++ tool) : header : rows_) where header = intercalate ";" . map fst . mkPairs $ (rows!!0) rows_ = [ intercalate ";" . map snd . mkPairs $ thisRow | thisRow <- rows] calcAverage :: [ScoreTable] -> ScoreTable calcAverage scores = ScoreTable (tool (scores!!0)) averagedEntries where averagedEntries = map caclAverageOfEntry . transpose . map rows $ scores caclAverageOfEntry :: [Row] -> Row caclAverageOfEntry scores = Row cut_ gentime_ testExectime_ nmethod_ vmethod_ mcov_ nbranch_ vbranch_ bcov_ cbm_ kcbm_ ncm_ kncm_ mm_ kmm_ im_ kim_ inm_ kinm_ rvm_ krvm_ vmcm_ kvmcm_ mut_ kmut_ mutcov_ where fix = head scores n = length scores avrg f = (sum (map f scores)) / (fromIntegral n) coverage n v = if (n==0) then 0.0 else 100.0 * v/ fromIntegral n cut_ = cut fix gentime_ = avrg gentime testExectime_ = avrg testExectime nmethod_ = nmethod fix vmethod_ = avrg vmethod mcov_ = coverage nmethod_ vmethod_ nbranch_ = nbranch fix vbranch_ = avrg vbranch bcov_ = coverage nbranch_ vbranch_ cbm_ = cbm fix kcbm_ = avrg kcbm ncm_ = ncm fix kncm_ = avrg kncm mm_ = mm fix kmm_ = avrg kmm im_ = im fix kim_ = avrg kim inm_ = inm fix kinm_ = avrg kinm rvm_ = rvm fix krvm_ = avrg krvm vmcm_ = vmcm fix kvmcm_ = avrg kvmcm mut_ = cbm_ + ncm_ + mm_ + im_ + inm_ + rvm_ + vmcm_ kmut_ = kcbm_ + kncm_ + kmm_ + kim_ + kinm_ + krvm_ + kvmcm_ mutcov_ = coverage mut_ kmut_ -- -- to parse a transcript.txt file to a ScoreTable -- parseFile :: String -> (String->Bool) -> String -> IO ScoreTable parseFile cutName selector file = do { content <- readFile file ; rows <- return . filter selector . filter (not . emptyRow) . drop 3 . lines $ content ; return (ScoreTable cutName [parseLine . words_ $ thisLine | thisLine <- rows]) } where emptyRow row = all (== ' ') row -- get the words separated by semicolon: words_ [] = [] words_ s = if null s2 then [s1] else s1 : words_ (tail s2) where (s1,s2) = span (/= ';') s parseLine :: [String] -> Row parseLine [className,generationTime,nTestCases,executionTime, cbmGenerated,cbmKilled,ncmGenerated,ncmKilled,mmGenerated,mmKilled,imGenerated,imKilled, inmGenerated,inmKilled,rvmGenerated,rvmKilled,vmcmGenerated,vmcmKilled, instructions,instrCovered, branches,branchesCovered, methods,methodsCovered, lines,linesCovered] = Row className -- 26x cells ((read generationTime)/1000.0) ((read executionTime)/1000.0) (read methods) (read methodsCovered) (-1.0) (read branches) (read branchesCovered) (-1.0) (read cbmGenerated) (read cbmKilled) (read ncmGenerated) (read ncmKilled) (read mmGenerated) (read mmKilled) (read imGenerated) (read imKilled) (read inmGenerated) (read inmKilled) (read rvmGenerated) (read rvmKilled) (read vmcmGenerated) (read vmcmKilled) (-1) (-1.0) (-1.0) testReadFile file = do { content <- readFile file ; putStrLn . show $ (map words_ . lines $ content) ; } process selector toolName toolReportFiles = do { putStr ("reading " ++ toolName ++ " files...") ; tables <- sequence (map (parseFile toolName selector) toolReportFiles) ; score <- return . calcAverage $ tables ; score_ <- return . toSCformat $ score ; -- putStrLn (show score) ; putStrLn score_ ; writeFile (toolName ++ "AvrgScore.txt") score_ ; putStrLn "average calcucated and saved in a file." } stdProcess = process (\r-> True) processAlmostAll = sequence_ . map (uncurry stdProcess) $ [("randoop", randoopfiles), ("evosuite", evofiles), ("manual", manualfiles), ("t3dumb", t3dumbfiles) ] processt3xBST = do { process selector "t3customBST" t3customBSTfiles ; process selector "t3valgetBST" t3valgenBSTfiles ; process selector "t3specBST" t3specBSTfiles } where selector row = "Examples.BinarySearchTree" `isPrefixOf` row processt3xXshow = do { process selector "t3customXshow" t3customXshowfiles ; process selector "t3valgenXshow" t3valgenXshowfiles ; process selector "t3specXshow" t3specXshowfiles } where selector row = "Sequenic.T2.Obj.XShow" `isPrefixOf` row processt3xRest = do { process selector "t3customRest" t3customRestfiles ; process selector "t3specRest" t3specRestfiles } where selector row = not ("Sequenic.T2.Obj.XShow" `isPrefixOf` row || "Examples.BinarySearchTree" `isPrefixOf` row) processt3ValGenXPool = do { process selector "t3valgenXpool" t3valgenXpoolfiles ; } where selector row = "Sequenic.T2.XPool" `isPrefixOf` row processt3ValGenRest = do { process selector "t3valgenRest" t3valgenRestfiles ; } where selector row = "Examples.Triangle" `isPrefixOf` row || "org.scribe.model.Token" `isPrefixOf` row -- -- run this main function to process all raw report-files, and produce the -- derived averaged results per tool -- main = do { processAlmostAll ; processt3xBST ; processt3xXshow ; processt3xRest ; processt3ValGenXPool ; processt3ValGenRest } testRow = Row "cut" 0.0 0.0 0 0.0 0.0 0 0.0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0.0