Statistics
| Branch: | Tag: | Revision:

root / Ganeti / HTools / QC.hs @ 79a72ce7

History | View | Annotate | Download (6.3 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 79a72ce7 Iustin Pop
-- | Simple checker for whether OpResult is fail or pass
50 79a72ce7 Iustin Pop
isFailure :: Types.OpResult a -> Bool
51 79a72ce7 Iustin Pop
isFailure (Types.OpFail _) = True
52 79a72ce7 Iustin Pop
isFailure _ = False
53 79a72ce7 Iustin Pop
54 15f4c8ca Iustin Pop
-- copied from the introduction to quickcheck
55 15f4c8ca Iustin Pop
instance Arbitrary Char where
56 095d7ac0 Iustin Pop
    arbitrary = choose ('\32', '\128')
57 15f4c8ca Iustin Pop
58 15f4c8ca Iustin Pop
-- let's generate a random instance
59 15f4c8ca Iustin Pop
instance Arbitrary Instance.Instance where
60 15f4c8ca Iustin Pop
    arbitrary = do
61 15f4c8ca Iustin Pop
      name <- arbitrary
62 15f4c8ca Iustin Pop
      mem <- choose(0, 100)
63 15f4c8ca Iustin Pop
      dsk <- choose(0, 100)
64 15f4c8ca Iustin Pop
      run_st <- arbitrary
65 15f4c8ca Iustin Pop
      pn <- arbitrary
66 15f4c8ca Iustin Pop
      sn <- arbitrary
67 79a72ce7 Iustin Pop
      vcpus <- arbitrary
68 79a72ce7 Iustin Pop
      return $ Instance.create name mem dsk vcpus run_st pn sn
69 15f4c8ca Iustin Pop
70 15f4c8ca Iustin Pop
-- and a random node
71 15f4c8ca Iustin Pop
instance Arbitrary Node.Node where
72 15f4c8ca Iustin Pop
    arbitrary = do
73 15f4c8ca Iustin Pop
      name <- arbitrary
74 15f4c8ca Iustin Pop
      mem_t <- arbitrary
75 15f4c8ca Iustin Pop
      mem_f <- choose (0, mem_t)
76 15f4c8ca Iustin Pop
      mem_n <- choose (0, mem_t - mem_f)
77 15f4c8ca Iustin Pop
      dsk_t <- arbitrary
78 15f4c8ca Iustin Pop
      dsk_f <- choose (0, dsk_t)
79 79a72ce7 Iustin Pop
      cpu_t <- arbitrary
80 15f4c8ca Iustin Pop
      offl <- arbitrary
81 15f4c8ca Iustin Pop
      let n = Node.create name (fromIntegral mem_t) mem_n mem_f
82 79a72ce7 Iustin Pop
              (fromIntegral dsk_t) dsk_f cpu_t offl
83 9cf4267a Iustin Pop
          n' = Node.buildPeers n Container.empty
84 15f4c8ca Iustin Pop
      return n'
85 15f4c8ca Iustin Pop
86 15f4c8ca Iustin Pop
-- | Make sure add is idempotent
87 15f4c8ca Iustin Pop
prop_PeerMap_addIdempotent pmap key elem =
88 15f4c8ca Iustin Pop
    fn puniq == fn (fn puniq)
89 7bc82927 Iustin Pop
    where _types = (pmap::PeerMap.PeerMap,
90 15f4c8ca Iustin Pop
                    key::PeerMap.Key, elem::PeerMap.Elem)
91 7bc82927 Iustin Pop
          fn = PeerMap.add key elem
92 7bc82927 Iustin Pop
          puniq = PeerMap.accumArray const pmap
93 15f4c8ca Iustin Pop
94 15f4c8ca Iustin Pop
-- | Make sure remove is idempotent
95 15f4c8ca Iustin Pop
prop_PeerMap_removeIdempotent pmap key =
96 15f4c8ca Iustin Pop
    fn puniq == fn (fn puniq)
97 7bc82927 Iustin Pop
    where _types = (pmap::PeerMap.PeerMap, key::PeerMap.Key)
98 7bc82927 Iustin Pop
          fn = PeerMap.remove key
99 15f4c8ca Iustin Pop
          puniq = PeerMap.accumArray const pmap
100 15f4c8ca Iustin Pop
101 15f4c8ca Iustin Pop
-- | Make sure a missing item returns 0
102 15f4c8ca Iustin Pop
prop_PeerMap_findMissing pmap key =
103 15f4c8ca Iustin Pop
    PeerMap.find key (PeerMap.remove key puniq) == 0
104 7bc82927 Iustin Pop
    where _types = (pmap::PeerMap.PeerMap, key::PeerMap.Key)
105 15f4c8ca Iustin Pop
          puniq = PeerMap.accumArray const pmap
106 15f4c8ca Iustin Pop
107 15f4c8ca Iustin Pop
-- | Make sure an added item is found
108 15f4c8ca Iustin Pop
prop_PeerMap_addFind pmap key elem =
109 15f4c8ca Iustin Pop
    PeerMap.find key (PeerMap.add key elem puniq) == elem
110 7bc82927 Iustin Pop
    where _types = (pmap::PeerMap.PeerMap,
111 15f4c8ca Iustin Pop
                    key::PeerMap.Key, elem::PeerMap.Elem)
112 7bc82927 Iustin Pop
          puniq = PeerMap.accumArray const pmap
113 15f4c8ca Iustin Pop
114 15f4c8ca Iustin Pop
-- | Manual check that maxElem returns the maximum indeed, or 0 for null
115 15f4c8ca Iustin Pop
prop_PeerMap_maxElem pmap =
116 15f4c8ca Iustin Pop
    PeerMap.maxElem puniq == if null puniq then 0
117 15f4c8ca Iustin Pop
                             else (maximum . snd . unzip) puniq
118 7bc82927 Iustin Pop
    where _types = pmap::PeerMap.PeerMap
119 15f4c8ca Iustin Pop
          puniq = PeerMap.accumArray const pmap
120 15f4c8ca Iustin Pop
121 7dd5ee6c Iustin Pop
test_PeerMap =
122 7dd5ee6c Iustin Pop
    [ run prop_PeerMap_addIdempotent
123 7dd5ee6c Iustin Pop
    , run prop_PeerMap_removeIdempotent
124 7dd5ee6c Iustin Pop
    , run prop_PeerMap_maxElem
125 7dd5ee6c Iustin Pop
    , run prop_PeerMap_addFind
126 7dd5ee6c Iustin Pop
    , run prop_PeerMap_findMissing
127 7dd5ee6c Iustin Pop
    ]
128 7dd5ee6c Iustin Pop
129 095d7ac0 Iustin Pop
-- Container tests
130 095d7ac0 Iustin Pop
131 095d7ac0 Iustin Pop
prop_Container_addTwo cdata i1 i2 =
132 095d7ac0 Iustin Pop
    fn i1 i2 cont == fn i2 i1 cont &&
133 095d7ac0 Iustin Pop
       fn i1 i2 cont == fn i1 i2 (fn i1 i2 cont)
134 095d7ac0 Iustin Pop
    where _types = (cdata::[Int],
135 095d7ac0 Iustin Pop
                    i1::Int, i2::Int)
136 095d7ac0 Iustin Pop
          cont = foldl (\c x -> Container.add x x c) Container.empty cdata
137 095d7ac0 Iustin Pop
          fn x1 x2 = Container.addTwo x1 x1 x2 x2
138 095d7ac0 Iustin Pop
139 7dd5ee6c Iustin Pop
test_Container =
140 7dd5ee6c Iustin Pop
    [ run prop_Container_addTwo ]
141 095d7ac0 Iustin Pop
142 7bc82927 Iustin Pop
-- Simple instance tests, we only have setter/getters
143 7bc82927 Iustin Pop
144 7bc82927 Iustin Pop
prop_Instance_setIdx inst idx =
145 7bc82927 Iustin Pop
    Instance.idx (Instance.setIdx inst idx) == idx
146 7bc82927 Iustin Pop
    where _types = (inst::Instance.Instance, idx::Types.Idx)
147 7bc82927 Iustin Pop
148 7bc82927 Iustin Pop
prop_Instance_setName inst name =
149 7bc82927 Iustin Pop
    Instance.name (Instance.setName inst name) == name
150 7bc82927 Iustin Pop
    where _types = (inst::Instance.Instance, name::String)
151 7bc82927 Iustin Pop
152 7bc82927 Iustin Pop
prop_Instance_setPri inst pdx =
153 7bc82927 Iustin Pop
    Instance.pnode (Instance.setPri inst pdx) == pdx
154 7bc82927 Iustin Pop
    where _types = (inst::Instance.Instance, pdx::Types.Ndx)
155 7bc82927 Iustin Pop
156 7bc82927 Iustin Pop
prop_Instance_setSec inst sdx =
157 7bc82927 Iustin Pop
    Instance.snode (Instance.setSec inst sdx) == sdx
158 7bc82927 Iustin Pop
    where _types = (inst::Instance.Instance, sdx::Types.Ndx)
159 7bc82927 Iustin Pop
160 7bc82927 Iustin Pop
prop_Instance_setBoth inst pdx sdx =
161 7bc82927 Iustin Pop
    Instance.pnode si == pdx && Instance.snode si == sdx
162 7bc82927 Iustin Pop
    where _types = (inst::Instance.Instance, pdx::Types.Ndx, sdx::Types.Ndx)
163 7bc82927 Iustin Pop
          si = Instance.setBoth inst pdx sdx
164 7bc82927 Iustin Pop
165 7dd5ee6c Iustin Pop
test_Instance =
166 7dd5ee6c Iustin Pop
    [ run prop_Instance_setIdx
167 7dd5ee6c Iustin Pop
    , run prop_Instance_setName
168 7dd5ee6c Iustin Pop
    , run prop_Instance_setPri
169 7dd5ee6c Iustin Pop
    , run prop_Instance_setSec
170 7dd5ee6c Iustin Pop
    , run prop_Instance_setBoth
171 7dd5ee6c Iustin Pop
    ]
172 7dd5ee6c Iustin Pop
173 7dd5ee6c Iustin Pop
-- Node tests
174 7dd5ee6c Iustin Pop
175 7bc82927 Iustin Pop
-- | Check that an instance add with too high memory or disk will be rejected
176 15f4c8ca Iustin Pop
prop_Node_addPri node inst = (Instance.mem inst >= Node.f_mem node ||
177 15f4c8ca Iustin Pop
                              Instance.dsk inst >= Node.f_dsk node) &&
178 9f6dcdea Iustin Pop
                             not (Node.failN1 node)
179 15f4c8ca Iustin Pop
                             ==>
180 79a72ce7 Iustin Pop
                             isFailure (Node.addPri node inst)
181 15f4c8ca Iustin Pop
    where _types = (node::Node.Node, inst::Instance.Instance)
182 15f4c8ca Iustin Pop
183 7bc82927 Iustin Pop
184 7bc82927 Iustin Pop
-- | Check that an instance add with too high memory or disk will be rejected
185 15f4c8ca Iustin Pop
prop_Node_addSec node inst pdx =
186 15f4c8ca Iustin Pop
    (Instance.mem inst >= (Node.f_mem node - Node.r_mem node) ||
187 15f4c8ca Iustin Pop
     Instance.dsk inst >= Node.f_dsk node) &&
188 9f6dcdea Iustin Pop
    not (Node.failN1 node)
189 79a72ce7 Iustin Pop
    ==> isFailure (Node.addSec node inst pdx)
190 15f4c8ca Iustin Pop
        where _types = (node::Node.Node, inst::Instance.Instance, pdx::Int)
191 7dd5ee6c Iustin Pop
192 7dd5ee6c Iustin Pop
test_Node =
193 7dd5ee6c Iustin Pop
    [ run prop_Node_addPri
194 7dd5ee6c Iustin Pop
    , run prop_Node_addSec
195 7dd5ee6c Iustin Pop
    ]