Statistics
| Branch: | Tag: | Revision:

root / htools / test.hs @ 00152519

History | View | Annotate | Download (4.2 kB)

1 525bfb36 Iustin Pop
{-| Unittest runner for ganeti-htools.
2 15f4c8ca Iustin Pop
3 15f4c8ca Iustin Pop
-}
4 15f4c8ca Iustin Pop
5 e2fa2baf Iustin Pop
{-
6 e2fa2baf Iustin Pop
7 8e4f6d56 Iustin Pop
Copyright (C) 2009, 2011 Google Inc.
8 e2fa2baf Iustin Pop
9 e2fa2baf Iustin Pop
This program is free software; you can redistribute it and/or modify
10 e2fa2baf Iustin Pop
it under the terms of the GNU General Public License as published by
11 e2fa2baf Iustin Pop
the Free Software Foundation; either version 2 of the License, or
12 e2fa2baf Iustin Pop
(at your option) any later version.
13 e2fa2baf Iustin Pop
14 e2fa2baf Iustin Pop
This program is distributed in the hope that it will be useful, but
15 e2fa2baf Iustin Pop
WITHOUT ANY WARRANTY; without even the implied warranty of
16 e2fa2baf Iustin Pop
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 e2fa2baf Iustin Pop
General Public License for more details.
18 e2fa2baf Iustin Pop
19 e2fa2baf Iustin Pop
You should have received a copy of the GNU General Public License
20 e2fa2baf Iustin Pop
along with this program; if not, write to the Free Software
21 e2fa2baf Iustin Pop
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 e2fa2baf Iustin Pop
02110-1301, USA.
23 e2fa2baf Iustin Pop
24 e2fa2baf Iustin Pop
-}
25 e2fa2baf Iustin Pop
26 15f4c8ca Iustin Pop
module Main(main) where
27 15f4c8ca Iustin Pop
28 38f536cb Iustin Pop
import Data.IORef
29 8e4f6d56 Iustin Pop
import Test.QuickCheck
30 509809db Iustin Pop
import System.Console.GetOpt
31 38f536cb Iustin Pop
import System.IO
32 38f536cb Iustin Pop
import System.Exit
33 06fe0cea Iustin Pop
import System (getArgs)
34 8e4f6d56 Iustin Pop
import Text.Printf
35 38f536cb Iustin Pop
36 15f4c8ca Iustin Pop
import Ganeti.HTools.QC
37 509809db Iustin Pop
import Ganeti.HTools.CLI
38 509809db Iustin Pop
import Ganeti.HTools.Utils (sepSplit)
39 509809db Iustin Pop
40 509809db Iustin Pop
-- | Options list and functions
41 509809db Iustin Pop
options :: [OptType]
42 509809db Iustin Pop
options =
43 509809db Iustin Pop
    [ oReplay
44 509809db Iustin Pop
    , oVerbose
45 509809db Iustin Pop
    , oShowVer
46 509809db Iustin Pop
    , oShowHelp
47 509809db Iustin Pop
    ]
48 15f4c8ca Iustin Pop
49 8e4f6d56 Iustin Pop
fast :: Args
50 8e4f6d56 Iustin Pop
fast = stdArgs
51 8e4f6d56 Iustin Pop
       { maxSuccess = 500
52 8e4f6d56 Iustin Pop
       , chatty     = False
53 8e4f6d56 Iustin Pop
       }
54 15f4c8ca Iustin Pop
55 8e4f6d56 Iustin Pop
slow :: Args
56 8e4f6d56 Iustin Pop
slow = stdArgs
57 8e4f6d56 Iustin Pop
       { maxSuccess = 50
58 8e4f6d56 Iustin Pop
       , chatty     = False
59 8e4f6d56 Iustin Pop
       }
60 38f536cb Iustin Pop
61 38f536cb Iustin Pop
incIORef :: IORef Int -> IO ()
62 38f536cb Iustin Pop
incIORef ir = atomicModifyIORef ir (\x -> (x + 1, ()))
63 38f536cb Iustin Pop
64 38f536cb Iustin Pop
-- | Wrapper over a test runner with error counting
65 38f536cb Iustin Pop
wrapTest :: IORef Int
66 8e4f6d56 Iustin Pop
         -> (Args -> IO Result)
67 8e4f6d56 Iustin Pop
         -> Args
68 8e4f6d56 Iustin Pop
         -> IO (Result, Char)
69 8e4f6d56 Iustin Pop
wrapTest ir test opts = do
70 8e4f6d56 Iustin Pop
  r <- test opts
71 8e4f6d56 Iustin Pop
  c <- case r of
72 8e4f6d56 Iustin Pop
         Success {} -> return '.'
73 8e4f6d56 Iustin Pop
         GaveUp  {} -> return '?'
74 8e4f6d56 Iustin Pop
         Failure {} -> incIORef ir >> return '#'
75 8e4f6d56 Iustin Pop
         NoExpectedFailure {} -> incIORef ir >> return '*'
76 8e4f6d56 Iustin Pop
  return (r, c)
77 8e4f6d56 Iustin Pop
78 8e4f6d56 Iustin Pop
runTests name opts tests max_count = do
79 8e4f6d56 Iustin Pop
  _ <- printf "%25s : " name
80 8e4f6d56 Iustin Pop
  hFlush stdout
81 8e4f6d56 Iustin Pop
  results <- mapM (\t -> do
82 8e4f6d56 Iustin Pop
                     (r, c) <- t opts
83 8e4f6d56 Iustin Pop
                     putChar c
84 8e4f6d56 Iustin Pop
                     hFlush stdout
85 8e4f6d56 Iustin Pop
                     return r
86 8e4f6d56 Iustin Pop
                  ) tests
87 8e4f6d56 Iustin Pop
  let alldone = sum . map numTests $ results
88 8e4f6d56 Iustin Pop
  _ <- printf "%*s(%d)\n" (max_count - length tests + 1) " " alldone
89 8e4f6d56 Iustin Pop
  mapM_ (\(idx, r) ->
90 8e4f6d56 Iustin Pop
             case r of
91 8e4f6d56 Iustin Pop
               Failure { output = o, usedSeed = u, usedSize = size } ->
92 8e4f6d56 Iustin Pop
                   printf "Test %d failed (seed was %s, test size %d): %s\n"
93 8e4f6d56 Iustin Pop
                          idx (show u) size o
94 8e4f6d56 Iustin Pop
               GaveUp { numTests = passed } ->
95 8e4f6d56 Iustin Pop
                   printf "Test %d incomplete: gave up with only %d\
96 8e4f6d56 Iustin Pop
                          \ passes after discarding %d tests\n"
97 8e4f6d56 Iustin Pop
                          idx passed (maxDiscard opts)
98 8e4f6d56 Iustin Pop
               _ -> return ()
99 8e4f6d56 Iustin Pop
        ) $ zip ([1..]::[Int]) results
100 8e4f6d56 Iustin Pop
  return results
101 8e4f6d56 Iustin Pop
102 8e4f6d56 Iustin Pop
allTests :: [(String, Args, [Args -> IO Result])]
103 06fe0cea Iustin Pop
allTests =
104 691dcd2a Iustin Pop
  [ ("Utils", fast, testUtils)
105 691dcd2a Iustin Pop
  , ("PeerMap", fast, testPeerMap)
106 06fe0cea Iustin Pop
  , ("Container", fast, testContainer)
107 06fe0cea Iustin Pop
  , ("Instance", fast, testInstance)
108 06fe0cea Iustin Pop
  , ("Node", fast, testNode)
109 06fe0cea Iustin Pop
  , ("Text", fast, testText)
110 06fe0cea Iustin Pop
  , ("OpCodes", fast, testOpCodes)
111 db079755 Iustin Pop
  , ("Jobs", fast, testJobs)
112 c088674b Iustin Pop
  , ("Loader", fast, testLoader)
113 06fe0cea Iustin Pop
  , ("Cluster", slow, testCluster)
114 06fe0cea Iustin Pop
  ]
115 06fe0cea Iustin Pop
116 509809db Iustin Pop
transformTestOpts :: Args -> Options -> IO Args
117 509809db Iustin Pop
transformTestOpts args opts = do
118 509809db Iustin Pop
  r <- case optReplay opts of
119 509809db Iustin Pop
         Nothing -> return Nothing
120 509809db Iustin Pop
         Just str -> do
121 509809db Iustin Pop
           let vs = sepSplit ',' str
122 509809db Iustin Pop
           (case vs of
123 509809db Iustin Pop
              [rng, size] -> return $ Just (read rng, read size)
124 509809db Iustin Pop
              _ -> fail "Invalid state given")
125 509809db Iustin Pop
  return args { chatty = optVerbose opts > 1,
126 509809db Iustin Pop
                replay = r
127 509809db Iustin Pop
              }
128 509809db Iustin Pop
129 38f536cb Iustin Pop
main :: IO ()
130 15f4c8ca Iustin Pop
main = do
131 38f536cb Iustin Pop
  errs <- newIORef 0
132 3a3c1eb4 Iustin Pop
  let wrap = map (wrapTest errs)
133 509809db Iustin Pop
  cmd_args <- System.getArgs
134 509809db Iustin Pop
  (opts, args) <- parseOpts cmd_args "test" options
135 06fe0cea Iustin Pop
  let tests = if null args
136 06fe0cea Iustin Pop
              then allTests
137 06fe0cea Iustin Pop
              else filter (\(name, _, _) -> name `elem` args) allTests
138 8e4f6d56 Iustin Pop
      max_count = maximum $ map (\(_, _, t) -> length t) tests
139 509809db Iustin Pop
  mapM_ (\(name, targs, tl) ->
140 509809db Iustin Pop
             transformTestOpts targs opts >>= \newargs ->
141 509809db Iustin Pop
             runTests name newargs (wrap tl) max_count) tests
142 38f536cb Iustin Pop
  terr <- readIORef errs
143 3a3c1eb4 Iustin Pop
  (if terr > 0
144 38f536cb Iustin Pop
   then do
145 38f536cb Iustin Pop
     hPutStrLn stderr $ "A total of " ++ show terr ++ " tests failed."
146 38f536cb Iustin Pop
     exitWith $ ExitFailure 1
147 38f536cb Iustin Pop
   else putStrLn "All tests succeeded.")