Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (6.1 kB)

1
{-| Unittests for ganeti-htools
2

    
3
-}
4

    
5
{-
6

    
7
Copyright (C) 2009 Google Inc.
8

    
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
13

    
14
This program is distributed in the hope that it will be useful, but
15
WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
General Public License for more details.
18

    
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22
02110-1301, USA.
23

    
24
-}
25

    
26
module Ganeti.HTools.QC
27
    ( test_PeerMap
28
    , test_Container
29
    , test_Instance
30
    , test_Node
31
    ) where
32

    
33
import Test.QuickCheck
34
import Test.QuickCheck.Batch
35
import Data.Maybe
36
import qualified Ganeti.HTools.CLI as CLI
37
import qualified Ganeti.HTools.Cluster as Cluster
38
import qualified Ganeti.HTools.Container as Container
39
import qualified Ganeti.HTools.IAlloc as IAlloc
40
import qualified Ganeti.HTools.Instance as Instance
41
import qualified Ganeti.HTools.Loader as Loader
42
import qualified Ganeti.HTools.Node as Node
43
import qualified Ganeti.HTools.PeerMap as PeerMap
44
import qualified Ganeti.HTools.Rapi as Rapi
45
import qualified Ganeti.HTools.Text as Text
46
import qualified Ganeti.HTools.Types as Types
47
import qualified Ganeti.HTools.Utils as Utils
48

    
49
-- copied from the introduction to quickcheck
50
instance Arbitrary Char where
51
    arbitrary = choose ('\32', '\128')
52

    
53
-- let's generate a random instance
54
instance Arbitrary Instance.Instance where
55
    arbitrary = do
56
      name <- arbitrary
57
      mem <- choose(0, 100)
58
      dsk <- choose(0, 100)
59
      run_st <- arbitrary
60
      pn <- arbitrary
61
      sn <- arbitrary
62
      return $ Instance.create name mem dsk run_st pn sn
63

    
64
-- and a random node
65
instance Arbitrary Node.Node where
66
    arbitrary = do
67
      name <- arbitrary
68
      mem_t <- arbitrary
69
      mem_f <- choose (0, mem_t)
70
      mem_n <- choose (0, mem_t - mem_f)
71
      dsk_t <- arbitrary
72
      dsk_f <- choose (0, dsk_t)
73
      offl <- arbitrary
74
      let n = Node.create name (fromIntegral mem_t) mem_n mem_f
75
              (fromIntegral dsk_t) dsk_f offl
76
          n' = Node.buildPeers n Container.empty
77
      return n'
78

    
79
-- | Make sure add is idempotent
80
prop_PeerMap_addIdempotent pmap key elem =
81
    fn puniq == fn (fn puniq)
82
    where _types = (pmap::PeerMap.PeerMap,
83
                    key::PeerMap.Key, elem::PeerMap.Elem)
84
          fn = PeerMap.add key elem
85
          puniq = PeerMap.accumArray const pmap
86

    
87
-- | Make sure remove is idempotent
88
prop_PeerMap_removeIdempotent pmap key =
89
    fn puniq == fn (fn puniq)
90
    where _types = (pmap::PeerMap.PeerMap, key::PeerMap.Key)
91
          fn = PeerMap.remove key
92
          puniq = PeerMap.accumArray const pmap
93

    
94
-- | Make sure a missing item returns 0
95
prop_PeerMap_findMissing pmap key =
96
    PeerMap.find key (PeerMap.remove key puniq) == 0
97
    where _types = (pmap::PeerMap.PeerMap, key::PeerMap.Key)
98
          puniq = PeerMap.accumArray const pmap
99

    
100
-- | Make sure an added item is found
101
prop_PeerMap_addFind pmap key elem =
102
    PeerMap.find key (PeerMap.add key elem puniq) == elem
103
    where _types = (pmap::PeerMap.PeerMap,
104
                    key::PeerMap.Key, elem::PeerMap.Elem)
105
          puniq = PeerMap.accumArray const pmap
106

    
107
-- | Manual check that maxElem returns the maximum indeed, or 0 for null
108
prop_PeerMap_maxElem pmap =
109
    PeerMap.maxElem puniq == if null puniq then 0
110
                             else (maximum . snd . unzip) puniq
111
    where _types = pmap::PeerMap.PeerMap
112
          puniq = PeerMap.accumArray const pmap
113

    
114
test_PeerMap =
115
    [ run prop_PeerMap_addIdempotent
116
    , run prop_PeerMap_removeIdempotent
117
    , run prop_PeerMap_maxElem
118
    , run prop_PeerMap_addFind
119
    , run prop_PeerMap_findMissing
120
    ]
121

    
122
-- Container tests
123

    
124
prop_Container_addTwo cdata i1 i2 =
125
    fn i1 i2 cont == fn i2 i1 cont &&
126
       fn i1 i2 cont == fn i1 i2 (fn i1 i2 cont)
127
    where _types = (cdata::[Int],
128
                    i1::Int, i2::Int)
129
          cont = foldl (\c x -> Container.add x x c) Container.empty cdata
130
          fn x1 x2 = Container.addTwo x1 x1 x2 x2
131

    
132
test_Container =
133
    [ run prop_Container_addTwo ]
134

    
135
-- Simple instance tests, we only have setter/getters
136

    
137
prop_Instance_setIdx inst idx =
138
    Instance.idx (Instance.setIdx inst idx) == idx
139
    where _types = (inst::Instance.Instance, idx::Types.Idx)
140

    
141
prop_Instance_setName inst name =
142
    Instance.name (Instance.setName inst name) == name
143
    where _types = (inst::Instance.Instance, name::String)
144

    
145
prop_Instance_setPri inst pdx =
146
    Instance.pnode (Instance.setPri inst pdx) == pdx
147
    where _types = (inst::Instance.Instance, pdx::Types.Ndx)
148

    
149
prop_Instance_setSec inst sdx =
150
    Instance.snode (Instance.setSec inst sdx) == sdx
151
    where _types = (inst::Instance.Instance, sdx::Types.Ndx)
152

    
153
prop_Instance_setBoth inst pdx sdx =
154
    Instance.pnode si == pdx && Instance.snode si == sdx
155
    where _types = (inst::Instance.Instance, pdx::Types.Ndx, sdx::Types.Ndx)
156
          si = Instance.setBoth inst pdx sdx
157

    
158
test_Instance =
159
    [ run prop_Instance_setIdx
160
    , run prop_Instance_setName
161
    , run prop_Instance_setPri
162
    , run prop_Instance_setSec
163
    , run prop_Instance_setBoth
164
    ]
165

    
166
-- Node tests
167

    
168
-- | Check that an instance add with too high memory or disk will be rejected
169
prop_Node_addPri node inst = (Instance.mem inst >= Node.f_mem node ||
170
                              Instance.dsk inst >= Node.f_dsk node) &&
171
                             (not $ Node.failN1 node)
172
                             ==>
173
                             isNothing(Node.addPri node inst)
174
    where _types = (node::Node.Node, inst::Instance.Instance)
175

    
176

    
177
-- | Check that an instance add with too high memory or disk will be rejected
178
prop_Node_addSec node inst pdx =
179
    (Instance.mem inst >= (Node.f_mem node - Node.r_mem node) ||
180
     Instance.dsk inst >= Node.f_dsk node) &&
181
    (not $ Node.failN1 node)
182
    ==> isNothing(Node.addSec node inst pdx)
183
        where _types = (node::Node.Node, inst::Instance.Instance, pdx::Int)
184

    
185
test_Node =
186
    [ run prop_Node_addPri
187
    , run prop_Node_addSec
188
    ]