Statistics
| Branch: | Tag: | Revision:

root / Ganeti / HTools / QC.hs @ 095d7ac0

History | View | Annotate | Download (4.8 kB)

1
module Ganeti.HTools.QC
2
    where
3

    
4
import Test.QuickCheck
5
import Data.Maybe
6
import qualified Ganeti.HTools.CLI as CLI
7
import qualified Ganeti.HTools.Cluster as Cluster
8
import qualified Ganeti.HTools.Container as Container
9
import qualified Ganeti.HTools.IAlloc as IAlloc
10
import qualified Ganeti.HTools.Instance as Instance
11
import qualified Ganeti.HTools.Loader as Loader
12
import qualified Ganeti.HTools.Node as Node
13
import qualified Ganeti.HTools.PeerMap as PeerMap
14
import qualified Ganeti.HTools.Rapi as Rapi
15
import qualified Ganeti.HTools.Text as Text
16
import qualified Ganeti.HTools.Types as Types
17
import qualified Ganeti.HTools.Utils as Utils
18

    
19
-- copied from the introduction to quickcheck
20
instance Arbitrary Char where
21
    arbitrary = choose ('\32', '\128')
22

    
23
-- let's generate a random instance
24
instance Arbitrary Instance.Instance where
25
    arbitrary = do
26
      name <- arbitrary
27
      mem <- choose(0, 100)
28
      dsk <- choose(0, 100)
29
      run_st <- arbitrary
30
      pn <- arbitrary
31
      sn <- arbitrary
32
      return $ Instance.create name mem dsk run_st pn sn
33

    
34
-- and a random node
35
instance Arbitrary Node.Node where
36
    arbitrary = do
37
      name <- arbitrary
38
      mem_t <- arbitrary
39
      mem_f <- choose (0, mem_t)
40
      mem_n <- choose (0, mem_t - mem_f)
41
      dsk_t <- arbitrary
42
      dsk_f <- choose (0, dsk_t)
43
      offl <- arbitrary
44
      let n = Node.create name (fromIntegral mem_t) mem_n mem_f
45
              (fromIntegral dsk_t) dsk_f offl
46
          n' = Node.buildPeers n Container.empty
47
      return n'
48

    
49
-- | Make sure add is idempotent
50
prop_PeerMap_addIdempotent pmap key elem =
51
    fn puniq == fn (fn puniq)
52
    where _types = (pmap::PeerMap.PeerMap,
53
                    key::PeerMap.Key, elem::PeerMap.Elem)
54
          fn = PeerMap.add key elem
55
          puniq = PeerMap.accumArray const pmap
56

    
57
-- | Make sure remove is idempotent
58
prop_PeerMap_removeIdempotent pmap key =
59
    fn puniq == fn (fn puniq)
60
    where _types = (pmap::PeerMap.PeerMap, key::PeerMap.Key)
61
          fn = PeerMap.remove key
62
          puniq = PeerMap.accumArray const pmap
63

    
64
-- | Make sure a missing item returns 0
65
prop_PeerMap_findMissing pmap key =
66
    PeerMap.find key (PeerMap.remove key puniq) == 0
67
    where _types = (pmap::PeerMap.PeerMap, key::PeerMap.Key)
68
          puniq = PeerMap.accumArray const pmap
69

    
70
-- | Make sure an added item is found
71
prop_PeerMap_addFind pmap key elem =
72
    PeerMap.find key (PeerMap.add key elem puniq) == elem
73
    where _types = (pmap::PeerMap.PeerMap,
74
                    key::PeerMap.Key, elem::PeerMap.Elem)
75
          puniq = PeerMap.accumArray const pmap
76

    
77
-- | Manual check that maxElem returns the maximum indeed, or 0 for null
78
prop_PeerMap_maxElem pmap =
79
    PeerMap.maxElem puniq == if null puniq then 0
80
                             else (maximum . snd . unzip) puniq
81
    where _types = pmap::PeerMap.PeerMap
82
          puniq = PeerMap.accumArray const pmap
83

    
84
-- Container tests
85

    
86
prop_Container_addTwo cdata i1 i2 =
87
    fn i1 i2 cont == fn i2 i1 cont &&
88
       fn i1 i2 cont == fn i1 i2 (fn i1 i2 cont)
89
    where _types = (cdata::[Int],
90
                    i1::Int, i2::Int)
91
          cont = foldl (\c x -> Container.add x x c) Container.empty cdata
92
          fn x1 x2 = Container.addTwo x1 x1 x2 x2
93

    
94

    
95
-- Simple instance tests, we only have setter/getters
96

    
97
prop_Instance_setIdx inst idx =
98
    Instance.idx (Instance.setIdx inst idx) == idx
99
    where _types = (inst::Instance.Instance, idx::Types.Idx)
100

    
101
prop_Instance_setName inst name =
102
    Instance.name (Instance.setName inst name) == name
103
    where _types = (inst::Instance.Instance, name::String)
104

    
105
prop_Instance_setPri inst pdx =
106
    Instance.pnode (Instance.setPri inst pdx) == pdx
107
    where _types = (inst::Instance.Instance, pdx::Types.Ndx)
108

    
109
prop_Instance_setSec inst sdx =
110
    Instance.snode (Instance.setSec inst sdx) == sdx
111
    where _types = (inst::Instance.Instance, sdx::Types.Ndx)
112

    
113
prop_Instance_setBoth inst pdx sdx =
114
    Instance.pnode si == pdx && Instance.snode si == sdx
115
    where _types = (inst::Instance.Instance, pdx::Types.Ndx, sdx::Types.Ndx)
116
          si = Instance.setBoth inst pdx sdx
117

    
118
-- | Check that an instance add with too high memory or disk will be rejected
119
prop_Node_addPri node inst = (Instance.mem inst >= Node.f_mem node ||
120
                              Instance.dsk inst >= Node.f_dsk node) &&
121
                             (not $ Node.failN1 node)
122
                             ==>
123
                             isNothing(Node.addPri node inst)
124
    where _types = (node::Node.Node, inst::Instance.Instance)
125

    
126

    
127
-- | Check that an instance add with too high memory or disk will be rejected
128
prop_Node_addSec node inst pdx =
129
    (Instance.mem inst >= (Node.f_mem node - Node.r_mem node) ||
130
     Instance.dsk inst >= Node.f_dsk node) &&
131
    (not $ Node.failN1 node)
132
    ==> isNothing(Node.addSec node inst pdx)
133
        where _types = (node::Node.Node, inst::Instance.Instance, pdx::Int)