Types.hs 6.19 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

{-| Unittests for ganeti-htools.

-}

{-

Copyright (C) 2009, 2010, 2011, 2012 Google Inc.

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

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

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

-}

module Test.Ganeti.HTools.Types
Iustin Pop's avatar
Iustin Pop committed
30
  ( testHTools_Types
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
  , Types.AllocPolicy(..)
  , Types.DiskTemplate(..)
  , Types.FailMode(..)
  , Types.EvacMode(..)
  , Types.OpResult(..)
  , Types.ISpec(..)
  , Types.IPolicy(..)
  , nullIPolicy
  ) where

import Test.QuickCheck

import Control.Applicative
import qualified Text.JSON as J

import Test.Ganeti.TestHelper
import Test.Ganeti.TestCommon
import Test.Ganeti.TestHTools

import qualified Ganeti.HTools.Types as Types

-- * Helpers

-- | All disk templates (used later)
allDiskTemplates :: [Types.DiskTemplate]
allDiskTemplates = [minBound..maxBound]

-- * Arbitrary instance

instance Arbitrary Types.AllocPolicy where
  arbitrary = elements [minBound..maxBound]

instance Arbitrary Types.DiskTemplate where
  arbitrary = elements [minBound..maxBound]

instance Arbitrary Types.FailMode where
  arbitrary = elements [minBound..maxBound]

instance Arbitrary Types.EvacMode where
  arbitrary = elements [minBound..maxBound]

instance Arbitrary a => Arbitrary (Types.OpResult a) where
  arbitrary = arbitrary >>= \c ->
              if c
                then Types.OpGood <$> arbitrary
                else Types.OpFail <$> arbitrary

instance Arbitrary Types.ISpec where
  arbitrary = do
    mem_s <- arbitrary::Gen (NonNegative Int)
    dsk_c <- arbitrary::Gen (NonNegative Int)
    dsk_s <- arbitrary::Gen (NonNegative Int)
    cpu_c <- arbitrary::Gen (NonNegative Int)
    nic_c <- arbitrary::Gen (NonNegative Int)
    su    <- arbitrary::Gen (NonNegative Int)
    return Types.ISpec { Types.iSpecMemorySize = fromIntegral mem_s
                       , Types.iSpecCpuCount   = fromIntegral cpu_c
                       , Types.iSpecDiskSize   = fromIntegral dsk_s
                       , Types.iSpecDiskCount  = fromIntegral dsk_c
                       , Types.iSpecNicCount   = fromIntegral nic_c
                       , Types.iSpecSpindleUse = fromIntegral su
                       }

-- | Generates an ispec bigger than the given one.
genBiggerISpec :: Types.ISpec -> Gen Types.ISpec
genBiggerISpec imin = do
  mem_s <- choose (Types.iSpecMemorySize imin, maxBound)
  dsk_c <- choose (Types.iSpecDiskCount imin, maxBound)
  dsk_s <- choose (Types.iSpecDiskSize imin, maxBound)
  cpu_c <- choose (Types.iSpecCpuCount imin, maxBound)
  nic_c <- choose (Types.iSpecNicCount imin, maxBound)
  su    <- choose (Types.iSpecSpindleUse imin, maxBound)
  return Types.ISpec { Types.iSpecMemorySize = fromIntegral mem_s
                     , Types.iSpecCpuCount   = fromIntegral cpu_c
                     , Types.iSpecDiskSize   = fromIntegral dsk_s
                     , Types.iSpecDiskCount  = fromIntegral dsk_c
                     , Types.iSpecNicCount   = fromIntegral nic_c
                     , Types.iSpecSpindleUse = fromIntegral su
                     }

instance Arbitrary Types.IPolicy where
  arbitrary = do
    imin <- arbitrary
    istd <- genBiggerISpec imin
    imax <- genBiggerISpec istd
    num_tmpl <- choose (0, length allDiskTemplates)
    dts  <- genUniquesList num_tmpl
    vcpu_ratio <- choose (1.0, maxVcpuRatio)
    spindle_ratio <- choose (1.0, maxSpindleRatio)
    return Types.IPolicy { Types.iPolicyMinSpec = imin
                         , Types.iPolicyStdSpec = istd
                         , Types.iPolicyMaxSpec = imax
                         , Types.iPolicyDiskTemplates = dts
                         , Types.iPolicyVcpuRatio = vcpu_ratio
                         , Types.iPolicySpindleRatio = spindle_ratio
                         }

-- * Test cases

130
131
prop_AllocPolicy_serialisation :: Types.AllocPolicy -> Property
prop_AllocPolicy_serialisation apol =
132
133
134
135
  case J.readJSON (J.showJSON apol) of
    J.Ok p -> p ==? apol
    J.Error s -> failTest $ "Failed to deserialise: " ++ s

136
137
prop_DiskTemplate_serialisation :: Types.DiskTemplate -> Property
prop_DiskTemplate_serialisation dt =
138
139
140
141
  case J.readJSON (J.showJSON dt) of
    J.Ok p -> p ==? dt
    J.Error s -> failTest $ "Failed to deserialise: " ++ s

142
143
prop_ISpec_serialisation :: Types.ISpec -> Property
prop_ISpec_serialisation ispec =
144
145
146
147
  case J.readJSON (J.showJSON ispec) of
    J.Ok p -> p ==? ispec
    J.Error s -> failTest $ "Failed to deserialise: " ++ s

148
149
prop_IPolicy_serialisation :: Types.IPolicy -> Property
prop_IPolicy_serialisation ipol =
150
151
152
153
  case J.readJSON (J.showJSON ipol) of
    J.Ok p -> p ==? ipol
    J.Error s -> failTest $ "Failed to deserialise: " ++ s

154
155
prop_EvacMode_serialisation :: Types.EvacMode -> Property
prop_EvacMode_serialisation em =
156
157
158
159
  case J.readJSON (J.showJSON em) of
    J.Ok p -> p ==? em
    J.Error s -> failTest $ "Failed to deserialise: " ++ s

160
161
prop_opToResult :: Types.OpResult Int -> Bool
prop_opToResult op =
162
163
164
165
166
167
168
  case op of
    Types.OpFail _ -> Types.isBad r
    Types.OpGood v -> case r of
                        Types.Bad _ -> False
                        Types.Ok v' -> v == v'
  where r = Types.opToResult op

169
170
prop_eitherToResult :: Either String Int -> Bool
prop_eitherToResult ei =
171
172
173
174
175
176
177
  case ei of
    Left _ -> Types.isBad r
    Right v -> case r of
                 Types.Bad _ -> False
                 Types.Ok v' -> v == v'
    where r = Types.eitherToResult ei

Iustin Pop's avatar
Iustin Pop committed
178
testSuite "HTools/Types"
179
180
181
182
183
184
185
            [ 'prop_AllocPolicy_serialisation
            , 'prop_DiskTemplate_serialisation
            , 'prop_ISpec_serialisation
            , 'prop_IPolicy_serialisation
            , 'prop_EvacMode_serialisation
            , 'prop_opToResult
            , 'prop_eitherToResult
186
            ]