root / test / hs / Test / Ganeti / Hypervisor / Xen / XmParser.hs @ c5a957c3
History | View | Annotate | Download (6.3 kB)
1 | b8585908 | Michele Tartara | {-# LANGUAGE TemplateHaskell #-} |
---|---|---|---|
2 | b8585908 | Michele Tartara | {-# OPTIONS_GHC -fno-warn-orphans #-} |
3 | b8585908 | Michele Tartara | |
4 | b8585908 | Michele Tartara | {-| Unittests for @xm list --long@ parser -} |
5 | b8585908 | Michele Tartara | |
6 | b8585908 | Michele Tartara | {- |
7 | b8585908 | Michele Tartara | |
8 | b8585908 | Michele Tartara | Copyright (C) 2013 Google Inc. |
9 | b8585908 | Michele Tartara | |
10 | b8585908 | Michele Tartara | This program is free software; you can redistribute it and/or modify |
11 | b8585908 | Michele Tartara | it under the terms of the GNU General Public License as published by |
12 | b8585908 | Michele Tartara | the Free Software Foundation; either version 2 of the License, or |
13 | b8585908 | Michele Tartara | (at your option) any later version. |
14 | b8585908 | Michele Tartara | |
15 | b8585908 | Michele Tartara | This program is distributed in the hope that it will be useful, but |
16 | b8585908 | Michele Tartara | WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | b8585908 | Michele Tartara | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
18 | b8585908 | Michele Tartara | General Public License for more details. |
19 | b8585908 | Michele Tartara | |
20 | b8585908 | Michele Tartara | You should have received a copy of the GNU General Public License |
21 | b8585908 | Michele Tartara | along with this program; if not, write to the Free Software |
22 | b8585908 | Michele Tartara | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
23 | b8585908 | Michele Tartara | 02110-1301, USA. |
24 | b8585908 | Michele Tartara | |
25 | b8585908 | Michele Tartara | -} |
26 | b8585908 | Michele Tartara | |
27 | b8585908 | Michele Tartara | module Test.Ganeti.Hypervisor.Xen.XmParser |
28 | b8585908 | Michele Tartara | ( testHypervisor_Xen_XmParser |
29 | b8585908 | Michele Tartara | ) where |
30 | b8585908 | Michele Tartara | |
31 | b8585908 | Michele Tartara | import Test.HUnit |
32 | b8585908 | Michele Tartara | import Test.QuickCheck as QuickCheck hiding (Result) |
33 | b8585908 | Michele Tartara | |
34 | b8585908 | Michele Tartara | import Test.Ganeti.TestHelper |
35 | b8585908 | Michele Tartara | import Test.Ganeti.TestCommon |
36 | b8585908 | Michele Tartara | |
37 | b8585908 | Michele Tartara | import Control.Monad (liftM) |
38 | b8585908 | Michele Tartara | import qualified Data.Attoparsec.Text as A |
39 | b8585908 | Michele Tartara | import Data.Text (pack) |
40 | b8585908 | Michele Tartara | import Data.Char |
41 | b8585908 | Michele Tartara | import qualified Data.Map as Map |
42 | c5a957c3 | Michele Tartara | import Text.Printf |
43 | b8585908 | Michele Tartara | |
44 | b8585908 | Michele Tartara | import Ganeti.Hypervisor.Xen.Types |
45 | b8585908 | Michele Tartara | import Ganeti.Hypervisor.Xen.XmParser |
46 | b8585908 | Michele Tartara | |
47 | b8585908 | Michele Tartara | {-# ANN module "HLint: ignore Use camelCase" #-} |
48 | b8585908 | Michele Tartara | |
49 | b8585908 | Michele Tartara | -- * Arbitraries |
50 | b8585908 | Michele Tartara | |
51 | b8585908 | Michele Tartara | -- | Arbitrary instance for generating configurations. |
52 | b8585908 | Michele Tartara | -- A completely arbitrary configuration would contain too many lists and its |
53 | b8585908 | Michele Tartara | -- size would be to big to be actually parsable in reasonable time. |
54 | b8585908 | Michele Tartara | -- This Arbitrary builds a random Config that is still of a reasonable size. |
55 | b8585908 | Michele Tartara | -- Avoid generating strings that might be interpreted as numbers. |
56 | b8585908 | Michele Tartara | instance Arbitrary LispConfig where |
57 | b8585908 | Michele Tartara | arbitrary = frequency |
58 | b8585908 | Michele Tartara | [ (5, liftM LCString (genName `suchThat` (not . canBeNumber))) |
59 | b8585908 | Michele Tartara | , (5, liftM LCDouble arbitrary) |
60 | b8585908 | Michele Tartara | , (1, liftM LCList (choose(1,20) >>= (`vectorOf` arbitrary))) |
61 | b8585908 | Michele Tartara | ] |
62 | b8585908 | Michele Tartara | |
63 | b8585908 | Michele Tartara | -- | Determines conservatively whether a string could be a number. |
64 | b8585908 | Michele Tartara | canBeNumber :: String -> Bool |
65 | b8585908 | Michele Tartara | canBeNumber [] = False |
66 | b8585908 | Michele Tartara | canBeNumber (c:[]) = canBeNumberChar c |
67 | b8585908 | Michele Tartara | canBeNumber (c:xs) = canBeNumberChar c && canBeNumber xs |
68 | b8585908 | Michele Tartara | |
69 | b8585908 | Michele Tartara | -- | Determines whether a char can be part of the string representation of a |
70 | b8585908 | Michele Tartara | -- number (even in scientific notation). |
71 | b8585908 | Michele Tartara | canBeNumberChar :: Char -> Bool |
72 | b8585908 | Michele Tartara | canBeNumberChar c = isDigit c || (c `elem` "eE-") |
73 | b8585908 | Michele Tartara | |
74 | c5a957c3 | Michele Tartara | -- | Generates an arbitrary @xm uptime@ output line. |
75 | c5a957c3 | Michele Tartara | instance Arbitrary UptimeInfo where |
76 | c5a957c3 | Michele Tartara | arbitrary = do |
77 | c5a957c3 | Michele Tartara | name <- genFQDN |
78 | c5a957c3 | Michele Tartara | NonNegative idNum <- arbitrary :: Gen (NonNegative Int) |
79 | c5a957c3 | Michele Tartara | NonNegative days <- arbitrary :: Gen (NonNegative Int) |
80 | c5a957c3 | Michele Tartara | hours <- choose (0, 23) :: Gen Int |
81 | c5a957c3 | Michele Tartara | mins <- choose (0, 59) :: Gen Int |
82 | c5a957c3 | Michele Tartara | secs <- choose (0, 59) :: Gen Int |
83 | c5a957c3 | Michele Tartara | let uptime :: String |
84 | c5a957c3 | Michele Tartara | uptime = |
85 | c5a957c3 | Michele Tartara | if days /= 0 |
86 | c5a957c3 | Michele Tartara | then printf "%d days, %d:%d:%d" days hours mins secs |
87 | c5a957c3 | Michele Tartara | else printf "%d:%d:%d" hours mins secs |
88 | c5a957c3 | Michele Tartara | return $ UptimeInfo name idNum uptime |
89 | c5a957c3 | Michele Tartara | |
90 | b8585908 | Michele Tartara | -- * Helper functions for tests |
91 | b8585908 | Michele Tartara | |
92 | b8585908 | Michele Tartara | -- | Function for testing whether a domain configuration is parsed correctly. |
93 | b8585908 | Michele Tartara | testDomain :: String -> Map.Map String Domain -> Assertion |
94 | b8585908 | Michele Tartara | testDomain fileName expectedContent = do |
95 | c5a957c3 | Michele Tartara | fileContent <- readTestData fileName |
96 | c5a957c3 | Michele Tartara | case A.parseOnly xmListParser $ pack fileContent of |
97 | c5a957c3 | Michele Tartara | Left msg -> assertFailure $ "Parsing failed: " ++ msg |
98 | c5a957c3 | Michele Tartara | Right obtained -> assertEqual fileName expectedContent obtained |
99 | c5a957c3 | Michele Tartara | |
100 | c5a957c3 | Michele Tartara | -- | Function for testing whether a @xm uptime@ output (stored in a file) |
101 | c5a957c3 | Michele Tartara | -- is parsed correctly. |
102 | c5a957c3 | Michele Tartara | testUptimeInfo :: String -> Map.Map Int UptimeInfo -> Assertion |
103 | c5a957c3 | Michele Tartara | testUptimeInfo fileName expectedContent = do |
104 | c5a957c3 | Michele Tartara | fileContent <- readTestData fileName |
105 | c5a957c3 | Michele Tartara | case A.parseOnly xmUptimeParser $ pack fileContent of |
106 | c5a957c3 | Michele Tartara | Left msg -> assertFailure $ "Parsing failed: " ++ msg |
107 | c5a957c3 | Michele Tartara | Right obtained -> assertEqual fileName expectedContent obtained |
108 | b8585908 | Michele Tartara | |
109 | b8585908 | Michele Tartara | -- | Determines whether two LispConfig are equal, with the exception of Double |
110 | b8585908 | Michele Tartara | -- values, that just need to be "almost equal". |
111 | b8585908 | Michele Tartara | -- Meant mainly for testing purposes, given that Double values may be slightly |
112 | b8585908 | Michele Tartara | -- rounded during parsing. |
113 | b8585908 | Michele Tartara | isAlmostEqual :: LispConfig -> LispConfig -> Bool |
114 | b8585908 | Michele Tartara | isAlmostEqual (LCList c1) (LCList c2) = |
115 | b8585908 | Michele Tartara | (length c1 == length c2) && |
116 | b8585908 | Michele Tartara | foldr |
117 | b8585908 | Michele Tartara | (\current acc -> (acc && uncurry isAlmostEqual current)) |
118 | b8585908 | Michele Tartara | True |
119 | b8585908 | Michele Tartara | (zip c1 c2) |
120 | b8585908 | Michele Tartara | isAlmostEqual (LCString s1) (LCString s2) = s1 == s2 |
121 | b8585908 | Michele Tartara | isAlmostEqual (LCDouble d1) (LCDouble d2) = abs (d1-d2) <= 1e-12 |
122 | b8585908 | Michele Tartara | isAlmostEqual _ _ = False |
123 | b8585908 | Michele Tartara | |
124 | b8585908 | Michele Tartara | -- | Function to serialize LispConfigs in such a way that they can be rebuilt |
125 | b8585908 | Michele Tartara | -- again by the lispConfigParser. |
126 | b8585908 | Michele Tartara | serializeConf :: LispConfig -> String |
127 | b8585908 | Michele Tartara | serializeConf (LCList c) = "(" ++ unwords (map serializeConf c) ++ ")" |
128 | b8585908 | Michele Tartara | serializeConf (LCString s) = s |
129 | b8585908 | Michele Tartara | serializeConf (LCDouble d) = show d |
130 | b8585908 | Michele Tartara | |
131 | c5a957c3 | Michele Tartara | -- | Function to serialize UptimeInfos in such a way that they can be rebuilt |
132 | c5a957c3 | Michele Tartara | -- againg by the uptimeLineParser. |
133 | c5a957c3 | Michele Tartara | serializeUptime :: UptimeInfo -> String |
134 | c5a957c3 | Michele Tartara | serializeUptime (UptimeInfo name idNum uptime) = |
135 | c5a957c3 | Michele Tartara | printf "%s\t%d\t%s" name idNum uptime |
136 | c5a957c3 | Michele Tartara | |
137 | b8585908 | Michele Tartara | -- | Test whether a randomly generated config can be parsed. |
138 | b8585908 | Michele Tartara | -- Implicitly, this also tests that the Show instance of Config is correct. |
139 | b8585908 | Michele Tartara | prop_config :: LispConfig -> Property |
140 | b8585908 | Michele Tartara | prop_config conf = |
141 | b8585908 | Michele Tartara | case A.parseOnly lispConfigParser . pack . serializeConf $ conf of |
142 | b8585908 | Michele Tartara | Left msg -> fail $ "Parsing failed: " ++ msg |
143 | b8585908 | Michele Tartara | Right obtained -> property $ isAlmostEqual obtained conf |
144 | b8585908 | Michele Tartara | |
145 | c5a957c3 | Michele Tartara | -- | Test whether a randomly generated UptimeInfo text line can be parsed. |
146 | c5a957c3 | Michele Tartara | prop_uptimeInfo :: UptimeInfo -> Property |
147 | c5a957c3 | Michele Tartara | prop_uptimeInfo uInfo = |
148 | c5a957c3 | Michele Tartara | case A.parseOnly uptimeLineParser . pack . serializeUptime $ uInfo of |
149 | c5a957c3 | Michele Tartara | Left msg -> fail $ "Parsing failed: " ++ msg |
150 | c5a957c3 | Michele Tartara | Right obtained -> obtained ==? uInfo |
151 | c5a957c3 | Michele Tartara | |
152 | b8585908 | Michele Tartara | -- | Test a Xen 4.0.1 @xm list --long@ output. |
153 | b8585908 | Michele Tartara | case_xen401list :: Assertion |
154 | b8585908 | Michele Tartara | case_xen401list = testDomain "xen-xm-list-long-4.0.1.txt" $ |
155 | b8585908 | Michele Tartara | Map.fromList |
156 | b8585908 | Michele Tartara | [ ("Domain-0", Domain 0 "Domain-0" 184000.41332 ActualRunning Nothing) |
157 | b8585908 | Michele Tartara | , ("instance1.example.com", Domain 119 "instance1.example.com" 24.116146647 |
158 | b8585908 | Michele Tartara | ActualBlocked Nothing) |
159 | b8585908 | Michele Tartara | ] |
160 | b8585908 | Michele Tartara | |
161 | c5a957c3 | Michele Tartara | -- | Test a Xen 4.0.1 @xm uptime@ output. |
162 | c5a957c3 | Michele Tartara | case_xen401uptime :: Assertion |
163 | c5a957c3 | Michele Tartara | case_xen401uptime = testUptimeInfo "xen-xm-uptime-4.0.1.txt" $ |
164 | c5a957c3 | Michele Tartara | Map.fromList |
165 | c5a957c3 | Michele Tartara | [ (0, UptimeInfo "Domain-0" 0 "98 days, 2:27:44") |
166 | c5a957c3 | Michele Tartara | , (119, UptimeInfo "instance1.example.com" 119 "15 days, 20:57:07") |
167 | c5a957c3 | Michele Tartara | ] |
168 | c5a957c3 | Michele Tartara | |
169 | b8585908 | Michele Tartara | testSuite "Hypervisor/Xen/XmParser" |
170 | b8585908 | Michele Tartara | [ 'prop_config |
171 | c5a957c3 | Michele Tartara | , 'prop_uptimeInfo |
172 | b8585908 | Michele Tartara | , 'case_xen401list |
173 | c5a957c3 | Michele Tartara | , 'case_xen401uptime |
174 | b8585908 | Michele Tartara | ] |