Statistics
| Branch: | Tag: | Revision:

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
          ]