root / test / hs / Test / Ganeti / Hypervisor / Xen / XmParser.hs @ b8585908
History | View | Annotate | Download (4.4 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 | b8585908 | Michele Tartara | |
43 | b8585908 | Michele Tartara | import Ganeti.Hypervisor.Xen.Types |
44 | b8585908 | Michele Tartara | import Ganeti.Hypervisor.Xen.XmParser |
45 | b8585908 | Michele Tartara | |
46 | b8585908 | Michele Tartara | {-# ANN module "HLint: ignore Use camelCase" #-} |
47 | b8585908 | Michele Tartara | |
48 | b8585908 | Michele Tartara | -- * Arbitraries |
49 | b8585908 | Michele Tartara | |
50 | b8585908 | Michele Tartara | -- | Arbitrary instance for generating configurations. |
51 | b8585908 | Michele Tartara | -- A completely arbitrary configuration would contain too many lists and its |
52 | b8585908 | Michele Tartara | -- size would be to big to be actually parsable in reasonable time. |
53 | b8585908 | Michele Tartara | -- This Arbitrary builds a random Config that is still of a reasonable size. |
54 | b8585908 | Michele Tartara | -- Avoid generating strings that might be interpreted as numbers. |
55 | b8585908 | Michele Tartara | instance Arbitrary LispConfig where |
56 | b8585908 | Michele Tartara | arbitrary = frequency |
57 | b8585908 | Michele Tartara | [ (5, liftM LCString (genName `suchThat` (not . canBeNumber))) |
58 | b8585908 | Michele Tartara | , (5, liftM LCDouble arbitrary) |
59 | b8585908 | Michele Tartara | , (1, liftM LCList (choose(1,20) >>= (`vectorOf` arbitrary))) |
60 | b8585908 | Michele Tartara | ] |
61 | b8585908 | Michele Tartara | |
62 | b8585908 | Michele Tartara | -- | Determines conservatively whether a string could be a number. |
63 | b8585908 | Michele Tartara | canBeNumber :: String -> Bool |
64 | b8585908 | Michele Tartara | canBeNumber [] = False |
65 | b8585908 | Michele Tartara | canBeNumber (c:[]) = canBeNumberChar c |
66 | b8585908 | Michele Tartara | canBeNumber (c:xs) = canBeNumberChar c && canBeNumber xs |
67 | b8585908 | Michele Tartara | |
68 | b8585908 | Michele Tartara | -- | Determines whether a char can be part of the string representation of a |
69 | b8585908 | Michele Tartara | -- number (even in scientific notation). |
70 | b8585908 | Michele Tartara | canBeNumberChar :: Char -> Bool |
71 | b8585908 | Michele Tartara | canBeNumberChar c = isDigit c || (c `elem` "eE-") |
72 | b8585908 | Michele Tartara | |
73 | b8585908 | Michele Tartara | -- * Helper functions for tests |
74 | b8585908 | Michele Tartara | |
75 | b8585908 | Michele Tartara | -- | Function for testing whether a domain configuration is parsed correctly. |
76 | b8585908 | Michele Tartara | testDomain :: String -> Map.Map String Domain -> Assertion |
77 | b8585908 | Michele Tartara | testDomain fileName expectedContent = do |
78 | b8585908 | Michele Tartara | fileContent <- readTestData fileName |
79 | b8585908 | Michele Tartara | case A.parseOnly xmListParser $ pack fileContent of |
80 | b8585908 | Michele Tartara | Left msg -> assertFailure $ "Parsing failed: " ++ msg |
81 | b8585908 | Michele Tartara | Right obtained -> assertEqual fileName expectedContent obtained |
82 | b8585908 | Michele Tartara | |
83 | b8585908 | Michele Tartara | -- | Determines whether two LispConfig are equal, with the exception of Double |
84 | b8585908 | Michele Tartara | -- values, that just need to be "almost equal". |
85 | b8585908 | Michele Tartara | -- Meant mainly for testing purposes, given that Double values may be slightly |
86 | b8585908 | Michele Tartara | -- rounded during parsing. |
87 | b8585908 | Michele Tartara | isAlmostEqual :: LispConfig -> LispConfig -> Bool |
88 | b8585908 | Michele Tartara | isAlmostEqual (LCList c1) (LCList c2) = |
89 | b8585908 | Michele Tartara | (length c1 == length c2) && |
90 | b8585908 | Michele Tartara | foldr |
91 | b8585908 | Michele Tartara | (\current acc -> (acc && uncurry isAlmostEqual current)) |
92 | b8585908 | Michele Tartara | True |
93 | b8585908 | Michele Tartara | (zip c1 c2) |
94 | b8585908 | Michele Tartara | isAlmostEqual (LCString s1) (LCString s2) = s1 == s2 |
95 | b8585908 | Michele Tartara | isAlmostEqual (LCDouble d1) (LCDouble d2) = abs (d1-d2) <= 1e-12 |
96 | b8585908 | Michele Tartara | isAlmostEqual _ _ = False |
97 | b8585908 | Michele Tartara | |
98 | b8585908 | Michele Tartara | -- | Function to serialize LispConfigs in such a way that they can be rebuilt |
99 | b8585908 | Michele Tartara | -- again by the lispConfigParser. |
100 | b8585908 | Michele Tartara | serializeConf :: LispConfig -> String |
101 | b8585908 | Michele Tartara | serializeConf (LCList c) = "(" ++ unwords (map serializeConf c) ++ ")" |
102 | b8585908 | Michele Tartara | serializeConf (LCString s) = s |
103 | b8585908 | Michele Tartara | serializeConf (LCDouble d) = show d |
104 | b8585908 | Michele Tartara | |
105 | b8585908 | Michele Tartara | -- | Test whether a randomly generated config can be parsed. |
106 | b8585908 | Michele Tartara | -- Implicitly, this also tests that the Show instance of Config is correct. |
107 | b8585908 | Michele Tartara | prop_config :: LispConfig -> Property |
108 | b8585908 | Michele Tartara | prop_config conf = |
109 | b8585908 | Michele Tartara | case A.parseOnly lispConfigParser . pack . serializeConf $ conf of |
110 | b8585908 | Michele Tartara | Left msg -> fail $ "Parsing failed: " ++ msg |
111 | b8585908 | Michele Tartara | Right obtained -> property $ isAlmostEqual obtained conf |
112 | b8585908 | Michele Tartara | |
113 | b8585908 | Michele Tartara | -- | Test a Xen 4.0.1 @xm list --long@ output. |
114 | b8585908 | Michele Tartara | case_xen401list :: Assertion |
115 | b8585908 | Michele Tartara | case_xen401list = testDomain "xen-xm-list-long-4.0.1.txt" $ |
116 | b8585908 | Michele Tartara | Map.fromList |
117 | b8585908 | Michele Tartara | [ ("Domain-0", Domain 0 "Domain-0" 184000.41332 ActualRunning Nothing) |
118 | b8585908 | Michele Tartara | , ("instance1.example.com", Domain 119 "instance1.example.com" 24.116146647 |
119 | b8585908 | Michele Tartara | ActualBlocked Nothing) |
120 | b8585908 | Michele Tartara | ] |
121 | b8585908 | Michele Tartara | |
122 | b8585908 | Michele Tartara | testSuite "Hypervisor/Xen/XmParser" |
123 | b8585908 | Michele Tartara | [ 'prop_config |
124 | b8585908 | Michele Tartara | , 'case_xen401list |
125 | b8585908 | Michele Tartara | ] |