Statistics
| Branch: | Tag: | Revision:

root / Ganeti / HTools / QC.hs @ 18b6444b

History | View | Annotate | Download (6.1 kB)

1 9b1e1cc9 Iustin Pop
{-| Unittests for ganeti-htools
2 e2fa2baf Iustin Pop
3 e2fa2baf Iustin Pop
-}
4 e2fa2baf Iustin Pop
5 e2fa2baf Iustin Pop
{-
6 e2fa2baf Iustin Pop
7 e2fa2baf Iustin Pop
Copyright (C) 2009 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 Ganeti.HTools.QC
27 7dd5ee6c Iustin Pop
    ( test_PeerMap
28 7dd5ee6c Iustin Pop
    , test_Container
29 7dd5ee6c Iustin Pop
    , test_Instance
30 7dd5ee6c Iustin Pop
    , test_Node
31 7dd5ee6c Iustin Pop
    ) where
32 15f4c8ca Iustin Pop
33 15f4c8ca Iustin Pop
import Test.QuickCheck
34 7dd5ee6c Iustin Pop
import Test.QuickCheck.Batch
35 15f4c8ca Iustin Pop
import Data.Maybe
36 15f4c8ca Iustin Pop
import qualified Ganeti.HTools.CLI as CLI
37 15f4c8ca Iustin Pop
import qualified Ganeti.HTools.Cluster as Cluster
38 15f4c8ca Iustin Pop
import qualified Ganeti.HTools.Container as Container
39 15f4c8ca Iustin Pop
import qualified Ganeti.HTools.IAlloc as IAlloc
40 15f4c8ca Iustin Pop
import qualified Ganeti.HTools.Instance as Instance
41 15f4c8ca Iustin Pop
import qualified Ganeti.HTools.Loader as Loader
42 15f4c8ca Iustin Pop
import qualified Ganeti.HTools.Node as Node
43 15f4c8ca Iustin Pop
import qualified Ganeti.HTools.PeerMap as PeerMap
44 15f4c8ca Iustin Pop
import qualified Ganeti.HTools.Rapi as Rapi
45 15f4c8ca Iustin Pop
import qualified Ganeti.HTools.Text as Text
46 15f4c8ca Iustin Pop
import qualified Ganeti.HTools.Types as Types
47 15f4c8ca Iustin Pop
import qualified Ganeti.HTools.Utils as Utils
48 15f4c8ca Iustin Pop
49 15f4c8ca Iustin Pop
-- copied from the introduction to quickcheck
50 15f4c8ca Iustin Pop
instance Arbitrary Char where
51 095d7ac0 Iustin Pop
    arbitrary = choose ('\32', '\128')
52 15f4c8ca Iustin Pop
53 15f4c8ca Iustin Pop
-- let's generate a random instance
54 15f4c8ca Iustin Pop
instance Arbitrary Instance.Instance where
55 15f4c8ca Iustin Pop
    arbitrary = do
56 15f4c8ca Iustin Pop
      name <- arbitrary
57 15f4c8ca Iustin Pop
      mem <- choose(0, 100)
58 15f4c8ca Iustin Pop
      dsk <- choose(0, 100)
59 15f4c8ca Iustin Pop
      run_st <- arbitrary
60 15f4c8ca Iustin Pop
      pn <- arbitrary
61 15f4c8ca Iustin Pop
      sn <- arbitrary
62 15f4c8ca Iustin Pop
      return $ Instance.create name mem dsk run_st pn sn
63 15f4c8ca Iustin Pop
64 15f4c8ca Iustin Pop
-- and a random node
65 15f4c8ca Iustin Pop
instance Arbitrary Node.Node where
66 15f4c8ca Iustin Pop
    arbitrary = do
67 15f4c8ca Iustin Pop
      name <- arbitrary
68 15f4c8ca Iustin Pop
      mem_t <- arbitrary
69 15f4c8ca Iustin Pop
      mem_f <- choose (0, mem_t)
70 15f4c8ca Iustin Pop
      mem_n <- choose (0, mem_t - mem_f)
71 15f4c8ca Iustin Pop
      dsk_t <- arbitrary
72 15f4c8ca Iustin Pop
      dsk_f <- choose (0, dsk_t)
73 15f4c8ca Iustin Pop
      offl <- arbitrary
74 15f4c8ca Iustin Pop
      let n = Node.create name (fromIntegral mem_t) mem_n mem_f
75 15f4c8ca Iustin Pop
              (fromIntegral dsk_t) dsk_f offl
76 9cf4267a Iustin Pop
          n' = Node.buildPeers n Container.empty
77 15f4c8ca Iustin Pop
      return n'
78 15f4c8ca Iustin Pop
79 15f4c8ca Iustin Pop
-- | Make sure add is idempotent
80 15f4c8ca Iustin Pop
prop_PeerMap_addIdempotent pmap key elem =
81 15f4c8ca Iustin Pop
    fn puniq == fn (fn puniq)
82 7bc82927 Iustin Pop
    where _types = (pmap::PeerMap.PeerMap,
83 15f4c8ca Iustin Pop
                    key::PeerMap.Key, elem::PeerMap.Elem)
84 7bc82927 Iustin Pop
          fn = PeerMap.add key elem
85 7bc82927 Iustin Pop
          puniq = PeerMap.accumArray const pmap
86 15f4c8ca Iustin Pop
87 15f4c8ca Iustin Pop
-- | Make sure remove is idempotent
88 15f4c8ca Iustin Pop
prop_PeerMap_removeIdempotent pmap key =
89 15f4c8ca Iustin Pop
    fn puniq == fn (fn puniq)
90 7bc82927 Iustin Pop
    where _types = (pmap::PeerMap.PeerMap, key::PeerMap.Key)
91 7bc82927 Iustin Pop
          fn = PeerMap.remove key
92 15f4c8ca Iustin Pop
          puniq = PeerMap.accumArray const pmap
93 15f4c8ca Iustin Pop
94 15f4c8ca Iustin Pop
-- | Make sure a missing item returns 0
95 15f4c8ca Iustin Pop
prop_PeerMap_findMissing pmap key =
96 15f4c8ca Iustin Pop
    PeerMap.find key (PeerMap.remove key puniq) == 0
97 7bc82927 Iustin Pop
    where _types = (pmap::PeerMap.PeerMap, key::PeerMap.Key)
98 15f4c8ca Iustin Pop
          puniq = PeerMap.accumArray const pmap
99 15f4c8ca Iustin Pop
100 15f4c8ca Iustin Pop
-- | Make sure an added item is found
101 15f4c8ca Iustin Pop
prop_PeerMap_addFind pmap key elem =
102 15f4c8ca Iustin Pop
    PeerMap.find key (PeerMap.add key elem puniq) == elem
103 7bc82927 Iustin Pop
    where _types = (pmap::PeerMap.PeerMap,
104 15f4c8ca Iustin Pop
                    key::PeerMap.Key, elem::PeerMap.Elem)
105 7bc82927 Iustin Pop
          puniq = PeerMap.accumArray const pmap
106 15f4c8ca Iustin Pop
107 15f4c8ca Iustin Pop
-- | Manual check that maxElem returns the maximum indeed, or 0 for null
108 15f4c8ca Iustin Pop
prop_PeerMap_maxElem pmap =
109 15f4c8ca Iustin Pop
    PeerMap.maxElem puniq == if null puniq then 0
110 15f4c8ca Iustin Pop
                             else (maximum . snd . unzip) puniq
111 7bc82927 Iustin Pop
    where _types = pmap::PeerMap.PeerMap
112 15f4c8ca Iustin Pop
          puniq = PeerMap.accumArray const pmap
113 15f4c8ca Iustin Pop
114 7dd5ee6c Iustin Pop
test_PeerMap =
115 7dd5ee6c Iustin Pop
    [ run prop_PeerMap_addIdempotent
116 7dd5ee6c Iustin Pop
    , run prop_PeerMap_removeIdempotent
117 7dd5ee6c Iustin Pop
    , run prop_PeerMap_maxElem
118 7dd5ee6c Iustin Pop
    , run prop_PeerMap_addFind
119 7dd5ee6c Iustin Pop
    , run prop_PeerMap_findMissing
120 7dd5ee6c Iustin Pop
    ]
121 7dd5ee6c Iustin Pop
122 095d7ac0 Iustin Pop
-- Container tests
123 095d7ac0 Iustin Pop
124 095d7ac0 Iustin Pop
prop_Container_addTwo cdata i1 i2 =
125 095d7ac0 Iustin Pop
    fn i1 i2 cont == fn i2 i1 cont &&
126 095d7ac0 Iustin Pop
       fn i1 i2 cont == fn i1 i2 (fn i1 i2 cont)
127 095d7ac0 Iustin Pop
    where _types = (cdata::[Int],
128 095d7ac0 Iustin Pop
                    i1::Int, i2::Int)
129 095d7ac0 Iustin Pop
          cont = foldl (\c x -> Container.add x x c) Container.empty cdata
130 095d7ac0 Iustin Pop
          fn x1 x2 = Container.addTwo x1 x1 x2 x2
131 095d7ac0 Iustin Pop
132 7dd5ee6c Iustin Pop
test_Container =
133 7dd5ee6c Iustin Pop
    [ run prop_Container_addTwo ]
134 095d7ac0 Iustin Pop
135 7bc82927 Iustin Pop
-- Simple instance tests, we only have setter/getters
136 7bc82927 Iustin Pop
137 7bc82927 Iustin Pop
prop_Instance_setIdx inst idx =
138 7bc82927 Iustin Pop
    Instance.idx (Instance.setIdx inst idx) == idx
139 7bc82927 Iustin Pop
    where _types = (inst::Instance.Instance, idx::Types.Idx)
140 7bc82927 Iustin Pop
141 7bc82927 Iustin Pop
prop_Instance_setName inst name =
142 7bc82927 Iustin Pop
    Instance.name (Instance.setName inst name) == name
143 7bc82927 Iustin Pop
    where _types = (inst::Instance.Instance, name::String)
144 7bc82927 Iustin Pop
145 7bc82927 Iustin Pop
prop_Instance_setPri inst pdx =
146 7bc82927 Iustin Pop
    Instance.pnode (Instance.setPri inst pdx) == pdx
147 7bc82927 Iustin Pop
    where _types = (inst::Instance.Instance, pdx::Types.Ndx)
148 7bc82927 Iustin Pop
149 7bc82927 Iustin Pop
prop_Instance_setSec inst sdx =
150 7bc82927 Iustin Pop
    Instance.snode (Instance.setSec inst sdx) == sdx
151 7bc82927 Iustin Pop
    where _types = (inst::Instance.Instance, sdx::Types.Ndx)
152 7bc82927 Iustin Pop
153 7bc82927 Iustin Pop
prop_Instance_setBoth inst pdx sdx =
154 7bc82927 Iustin Pop
    Instance.pnode si == pdx && Instance.snode si == sdx
155 7bc82927 Iustin Pop
    where _types = (inst::Instance.Instance, pdx::Types.Ndx, sdx::Types.Ndx)
156 7bc82927 Iustin Pop
          si = Instance.setBoth inst pdx sdx
157 7bc82927 Iustin Pop
158 7dd5ee6c Iustin Pop
test_Instance =
159 7dd5ee6c Iustin Pop
    [ run prop_Instance_setIdx
160 7dd5ee6c Iustin Pop
    , run prop_Instance_setName
161 7dd5ee6c Iustin Pop
    , run prop_Instance_setPri
162 7dd5ee6c Iustin Pop
    , run prop_Instance_setSec
163 7dd5ee6c Iustin Pop
    , run prop_Instance_setBoth
164 7dd5ee6c Iustin Pop
    ]
165 7dd5ee6c Iustin Pop
166 7dd5ee6c Iustin Pop
-- Node tests
167 7dd5ee6c Iustin Pop
168 7bc82927 Iustin Pop
-- | Check that an instance add with too high memory or disk will be rejected
169 15f4c8ca Iustin Pop
prop_Node_addPri node inst = (Instance.mem inst >= Node.f_mem node ||
170 15f4c8ca Iustin Pop
                              Instance.dsk inst >= Node.f_dsk node) &&
171 15f4c8ca Iustin Pop
                             (not $ Node.failN1 node)
172 15f4c8ca Iustin Pop
                             ==>
173 15f4c8ca Iustin Pop
                             isNothing(Node.addPri node inst)
174 15f4c8ca Iustin Pop
    where _types = (node::Node.Node, inst::Instance.Instance)
175 15f4c8ca Iustin Pop
176 7bc82927 Iustin Pop
177 7bc82927 Iustin Pop
-- | Check that an instance add with too high memory or disk will be rejected
178 15f4c8ca Iustin Pop
prop_Node_addSec node inst pdx =
179 15f4c8ca Iustin Pop
    (Instance.mem inst >= (Node.f_mem node - Node.r_mem node) ||
180 15f4c8ca Iustin Pop
     Instance.dsk inst >= Node.f_dsk node) &&
181 15f4c8ca Iustin Pop
    (not $ Node.failN1 node)
182 15f4c8ca Iustin Pop
    ==> isNothing(Node.addSec node inst pdx)
183 15f4c8ca Iustin Pop
        where _types = (node::Node.Node, inst::Instance.Instance, pdx::Int)
184 7dd5ee6c Iustin Pop
185 7dd5ee6c Iustin Pop
test_Node =
186 7dd5ee6c Iustin Pop
    [ run prop_Node_addPri
187 7dd5ee6c Iustin Pop
    , run prop_Node_addSec
188 7dd5ee6c Iustin Pop
    ]