root / Ganeti / HTools / QC.hs @ 49f9627a
History | View | Annotate | Download (13.8 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 | c15f7183 | Iustin Pop | ( testPeerMap |
28 | c15f7183 | Iustin Pop | , testContainer |
29 | c15f7183 | Iustin Pop | , testInstance |
30 | c15f7183 | Iustin Pop | , testNode |
31 | c15f7183 | Iustin Pop | , testText |
32 | c15f7183 | Iustin Pop | , testCluster |
33 | 7dd5ee6c | Iustin Pop | ) where |
34 | 15f4c8ca | Iustin Pop | |
35 | 15f4c8ca | Iustin Pop | import Test.QuickCheck |
36 | 7dd5ee6c | Iustin Pop | import Test.QuickCheck.Batch |
37 | 15f4c8ca | Iustin Pop | import Data.Maybe |
38 | 8fcf251f | Iustin Pop | import qualified Data.Map |
39 | 15f4c8ca | Iustin Pop | import qualified Ganeti.HTools.CLI as CLI |
40 | 15f4c8ca | Iustin Pop | import qualified Ganeti.HTools.Cluster as Cluster |
41 | 15f4c8ca | Iustin Pop | import qualified Ganeti.HTools.Container as Container |
42 | 15f4c8ca | Iustin Pop | import qualified Ganeti.HTools.IAlloc as IAlloc |
43 | 15f4c8ca | Iustin Pop | import qualified Ganeti.HTools.Instance as Instance |
44 | 15f4c8ca | Iustin Pop | import qualified Ganeti.HTools.Loader as Loader |
45 | 15f4c8ca | Iustin Pop | import qualified Ganeti.HTools.Node as Node |
46 | 15f4c8ca | Iustin Pop | import qualified Ganeti.HTools.PeerMap as PeerMap |
47 | 15f4c8ca | Iustin Pop | import qualified Ganeti.HTools.Text as Text |
48 | 15f4c8ca | Iustin Pop | import qualified Ganeti.HTools.Types as Types |
49 | 15f4c8ca | Iustin Pop | import qualified Ganeti.HTools.Utils as Utils |
50 | 15f4c8ca | Iustin Pop | |
51 | 8fcf251f | Iustin Pop | -- | Maximum memory (1TiB, somewhat random value) |
52 | 8fcf251f | Iustin Pop | maxMem :: Int |
53 | 8fcf251f | Iustin Pop | maxMem = 1024 * 1024 |
54 | 8fcf251f | Iustin Pop | |
55 | 49f9627a | Iustin Pop | -- | Maximum disk (8TiB, somewhat random value) |
56 | 8fcf251f | Iustin Pop | maxDsk :: Int |
57 | 49f9627a | Iustin Pop | maxDsk = 1024 * 1024 * 8 |
58 | 8fcf251f | Iustin Pop | |
59 | 8fcf251f | Iustin Pop | -- | Max CPUs (1024, somewhat random value) |
60 | 8fcf251f | Iustin Pop | maxCpu :: Int |
61 | 8fcf251f | Iustin Pop | maxCpu = 1024 |
62 | 8fcf251f | Iustin Pop | |
63 | 79a72ce7 | Iustin Pop | -- | Simple checker for whether OpResult is fail or pass |
64 | 79a72ce7 | Iustin Pop | isFailure :: Types.OpResult a -> Bool |
65 | 79a72ce7 | Iustin Pop | isFailure (Types.OpFail _) = True |
66 | 79a72ce7 | Iustin Pop | isFailure _ = False |
67 | 79a72ce7 | Iustin Pop | |
68 | 8fcf251f | Iustin Pop | -- | Simple checker for whether Result is fail or pass |
69 | 8fcf251f | Iustin Pop | isOk :: Types.Result a -> Bool |
70 | 8fcf251f | Iustin Pop | isOk (Types.Ok _ ) = True |
71 | 8fcf251f | Iustin Pop | isOk _ = False |
72 | 8fcf251f | Iustin Pop | |
73 | 15f4c8ca | Iustin Pop | -- copied from the introduction to quickcheck |
74 | 15f4c8ca | Iustin Pop | instance Arbitrary Char where |
75 | 095d7ac0 | Iustin Pop | arbitrary = choose ('\32', '\128') |
76 | 15f4c8ca | Iustin Pop | |
77 | 15f4c8ca | Iustin Pop | -- let's generate a random instance |
78 | 15f4c8ca | Iustin Pop | instance Arbitrary Instance.Instance where |
79 | 15f4c8ca | Iustin Pop | arbitrary = do |
80 | 15f4c8ca | Iustin Pop | name <- arbitrary |
81 | 8fcf251f | Iustin Pop | mem <- choose (0, maxMem) |
82 | 8fcf251f | Iustin Pop | dsk <- choose (0, maxDsk) |
83 | 1ae7a904 | Iustin Pop | run_st <- elements ["ERROR_up", "ERROR_down", "ADMIN_down" |
84 | 1ae7a904 | Iustin Pop | , "ERROR_nodedown", "ERROR_nodeoffline" |
85 | 1ae7a904 | Iustin Pop | , "running" |
86 | 1ae7a904 | Iustin Pop | , "no_such_status1", "no_such_status2"] |
87 | 15f4c8ca | Iustin Pop | pn <- arbitrary |
88 | 15f4c8ca | Iustin Pop | sn <- arbitrary |
89 | 8fcf251f | Iustin Pop | vcpus <- choose (0, maxCpu) |
90 | 434c15d5 | Iustin Pop | return $ Instance.create name mem dsk vcpus run_st [] pn sn |
91 | 15f4c8ca | Iustin Pop | |
92 | 15f4c8ca | Iustin Pop | -- and a random node |
93 | 15f4c8ca | Iustin Pop | instance Arbitrary Node.Node where |
94 | 15f4c8ca | Iustin Pop | arbitrary = do |
95 | 15f4c8ca | Iustin Pop | name <- arbitrary |
96 | 8fcf251f | Iustin Pop | mem_t <- choose (0, maxMem) |
97 | 15f4c8ca | Iustin Pop | mem_f <- choose (0, mem_t) |
98 | 15f4c8ca | Iustin Pop | mem_n <- choose (0, mem_t - mem_f) |
99 | 8fcf251f | Iustin Pop | dsk_t <- choose (0, maxDsk) |
100 | 15f4c8ca | Iustin Pop | dsk_f <- choose (0, dsk_t) |
101 | 8fcf251f | Iustin Pop | cpu_t <- choose (0, maxCpu) |
102 | 15f4c8ca | Iustin Pop | offl <- arbitrary |
103 | 15f4c8ca | Iustin Pop | let n = Node.create name (fromIntegral mem_t) mem_n mem_f |
104 | 8fcf251f | Iustin Pop | (fromIntegral dsk_t) dsk_f (fromIntegral cpu_t) offl |
105 | 9cf4267a | Iustin Pop | n' = Node.buildPeers n Container.empty |
106 | 15f4c8ca | Iustin Pop | return n' |
107 | 15f4c8ca | Iustin Pop | |
108 | 8fcf251f | Iustin Pop | setInstanceSmallerThanNode node inst = |
109 | 8fcf251f | Iustin Pop | inst { Instance.mem = (Node.availMem node) `div` 2 |
110 | 8fcf251f | Iustin Pop | , Instance.dsk = (Node.availDisk node) `div` 2 |
111 | 8fcf251f | Iustin Pop | , Instance.vcpus = (Node.availCpu node) `div` 2 |
112 | 8fcf251f | Iustin Pop | } |
113 | 8fcf251f | Iustin Pop | |
114 | 15f4c8ca | Iustin Pop | -- | Make sure add is idempotent |
115 | fbb95f28 | Iustin Pop | prop_PeerMap_addIdempotent pmap key em = |
116 | 15f4c8ca | Iustin Pop | fn puniq == fn (fn puniq) |
117 | 7bc82927 | Iustin Pop | where _types = (pmap::PeerMap.PeerMap, |
118 | fbb95f28 | Iustin Pop | key::PeerMap.Key, em::PeerMap.Elem) |
119 | fbb95f28 | Iustin Pop | fn = PeerMap.add key em |
120 | 7bc82927 | Iustin Pop | puniq = PeerMap.accumArray const pmap |
121 | 15f4c8ca | Iustin Pop | |
122 | 15f4c8ca | Iustin Pop | -- | Make sure remove is idempotent |
123 | 15f4c8ca | Iustin Pop | prop_PeerMap_removeIdempotent pmap key = |
124 | 15f4c8ca | Iustin Pop | fn puniq == fn (fn puniq) |
125 | 7bc82927 | Iustin Pop | where _types = (pmap::PeerMap.PeerMap, key::PeerMap.Key) |
126 | 7bc82927 | Iustin Pop | fn = PeerMap.remove key |
127 | 15f4c8ca | Iustin Pop | puniq = PeerMap.accumArray const pmap |
128 | 15f4c8ca | Iustin Pop | |
129 | 15f4c8ca | Iustin Pop | -- | Make sure a missing item returns 0 |
130 | 15f4c8ca | Iustin Pop | prop_PeerMap_findMissing pmap key = |
131 | 15f4c8ca | Iustin Pop | PeerMap.find key (PeerMap.remove key puniq) == 0 |
132 | 7bc82927 | Iustin Pop | where _types = (pmap::PeerMap.PeerMap, key::PeerMap.Key) |
133 | 15f4c8ca | Iustin Pop | puniq = PeerMap.accumArray const pmap |
134 | 15f4c8ca | Iustin Pop | |
135 | 15f4c8ca | Iustin Pop | -- | Make sure an added item is found |
136 | fbb95f28 | Iustin Pop | prop_PeerMap_addFind pmap key em = |
137 | fbb95f28 | Iustin Pop | PeerMap.find key (PeerMap.add key em puniq) == em |
138 | 7bc82927 | Iustin Pop | where _types = (pmap::PeerMap.PeerMap, |
139 | fbb95f28 | Iustin Pop | key::PeerMap.Key, em::PeerMap.Elem) |
140 | 7bc82927 | Iustin Pop | puniq = PeerMap.accumArray const pmap |
141 | 15f4c8ca | Iustin Pop | |
142 | 15f4c8ca | Iustin Pop | -- | Manual check that maxElem returns the maximum indeed, or 0 for null |
143 | 15f4c8ca | Iustin Pop | prop_PeerMap_maxElem pmap = |
144 | 15f4c8ca | Iustin Pop | PeerMap.maxElem puniq == if null puniq then 0 |
145 | 15f4c8ca | Iustin Pop | else (maximum . snd . unzip) puniq |
146 | 7bc82927 | Iustin Pop | where _types = pmap::PeerMap.PeerMap |
147 | 15f4c8ca | Iustin Pop | puniq = PeerMap.accumArray const pmap |
148 | 15f4c8ca | Iustin Pop | |
149 | c15f7183 | Iustin Pop | testPeerMap = |
150 | 7dd5ee6c | Iustin Pop | [ run prop_PeerMap_addIdempotent |
151 | 7dd5ee6c | Iustin Pop | , run prop_PeerMap_removeIdempotent |
152 | 7dd5ee6c | Iustin Pop | , run prop_PeerMap_maxElem |
153 | 7dd5ee6c | Iustin Pop | , run prop_PeerMap_addFind |
154 | 7dd5ee6c | Iustin Pop | , run prop_PeerMap_findMissing |
155 | 7dd5ee6c | Iustin Pop | ] |
156 | 7dd5ee6c | Iustin Pop | |
157 | 095d7ac0 | Iustin Pop | -- Container tests |
158 | 095d7ac0 | Iustin Pop | |
159 | 095d7ac0 | Iustin Pop | prop_Container_addTwo cdata i1 i2 = |
160 | 095d7ac0 | Iustin Pop | fn i1 i2 cont == fn i2 i1 cont && |
161 | 095d7ac0 | Iustin Pop | fn i1 i2 cont == fn i1 i2 (fn i1 i2 cont) |
162 | 095d7ac0 | Iustin Pop | where _types = (cdata::[Int], |
163 | 095d7ac0 | Iustin Pop | i1::Int, i2::Int) |
164 | 095d7ac0 | Iustin Pop | cont = foldl (\c x -> Container.add x x c) Container.empty cdata |
165 | 095d7ac0 | Iustin Pop | fn x1 x2 = Container.addTwo x1 x1 x2 x2 |
166 | 095d7ac0 | Iustin Pop | |
167 | c15f7183 | Iustin Pop | testContainer = |
168 | 7dd5ee6c | Iustin Pop | [ run prop_Container_addTwo ] |
169 | 095d7ac0 | Iustin Pop | |
170 | 7bc82927 | Iustin Pop | -- Simple instance tests, we only have setter/getters |
171 | 7bc82927 | Iustin Pop | |
172 | 7bc82927 | Iustin Pop | prop_Instance_setIdx inst idx = |
173 | 7bc82927 | Iustin Pop | Instance.idx (Instance.setIdx inst idx) == idx |
174 | 7bc82927 | Iustin Pop | where _types = (inst::Instance.Instance, idx::Types.Idx) |
175 | 7bc82927 | Iustin Pop | |
176 | 7bc82927 | Iustin Pop | prop_Instance_setName inst name = |
177 | 7bc82927 | Iustin Pop | Instance.name (Instance.setName inst name) == name |
178 | 7bc82927 | Iustin Pop | where _types = (inst::Instance.Instance, name::String) |
179 | 7bc82927 | Iustin Pop | |
180 | 7bc82927 | Iustin Pop | prop_Instance_setPri inst pdx = |
181 | 2060348b | Iustin Pop | Instance.pNode (Instance.setPri inst pdx) == pdx |
182 | 7bc82927 | Iustin Pop | where _types = (inst::Instance.Instance, pdx::Types.Ndx) |
183 | 7bc82927 | Iustin Pop | |
184 | 7bc82927 | Iustin Pop | prop_Instance_setSec inst sdx = |
185 | 2060348b | Iustin Pop | Instance.sNode (Instance.setSec inst sdx) == sdx |
186 | 7bc82927 | Iustin Pop | where _types = (inst::Instance.Instance, sdx::Types.Ndx) |
187 | 7bc82927 | Iustin Pop | |
188 | 7bc82927 | Iustin Pop | prop_Instance_setBoth inst pdx sdx = |
189 | 2060348b | Iustin Pop | Instance.pNode si == pdx && Instance.sNode si == sdx |
190 | 7bc82927 | Iustin Pop | where _types = (inst::Instance.Instance, pdx::Types.Ndx, sdx::Types.Ndx) |
191 | 7bc82927 | Iustin Pop | si = Instance.setBoth inst pdx sdx |
192 | 7bc82927 | Iustin Pop | |
193 | 1ae7a904 | Iustin Pop | prop_Instance_runStatus_True inst = |
194 | 1ae7a904 | Iustin Pop | let run_st = Instance.running inst |
195 | 2060348b | Iustin Pop | run_tx = Instance.runSt inst |
196 | 1ae7a904 | Iustin Pop | in |
197 | a46f34d7 | Iustin Pop | run_tx `elem` Instance.runningStates ==> run_st |
198 | 1ae7a904 | Iustin Pop | |
199 | 1ae7a904 | Iustin Pop | prop_Instance_runStatus_False inst = |
200 | 1ae7a904 | Iustin Pop | let run_st = Instance.running inst |
201 | 2060348b | Iustin Pop | run_tx = Instance.runSt inst |
202 | 1ae7a904 | Iustin Pop | in |
203 | a46f34d7 | Iustin Pop | run_tx `notElem` Instance.runningStates ==> not run_st |
204 | 1ae7a904 | Iustin Pop | |
205 | 8fcf251f | Iustin Pop | prop_Instance_shrinkMG inst = |
206 | 8fcf251f | Iustin Pop | Instance.mem inst >= 2 * Types.unitMem ==> |
207 | 8fcf251f | Iustin Pop | case Instance.shrinkByType inst Types.FailMem of |
208 | 8fcf251f | Iustin Pop | Types.Ok inst' -> |
209 | 8fcf251f | Iustin Pop | Instance.mem inst' == Instance.mem inst - Types.unitMem |
210 | 8fcf251f | Iustin Pop | _ -> False |
211 | 8fcf251f | Iustin Pop | where _types = (inst::Instance.Instance) |
212 | 8fcf251f | Iustin Pop | |
213 | 8fcf251f | Iustin Pop | prop_Instance_shrinkMF inst = |
214 | 8fcf251f | Iustin Pop | Instance.mem inst < 2 * Types.unitMem ==> |
215 | 8fcf251f | Iustin Pop | not . isOk $ Instance.shrinkByType inst Types.FailMem |
216 | 8fcf251f | Iustin Pop | where _types = (inst::Instance.Instance) |
217 | 8fcf251f | Iustin Pop | |
218 | 8fcf251f | Iustin Pop | prop_Instance_shrinkCG inst = |
219 | 8fcf251f | Iustin Pop | Instance.vcpus inst >= 2 * Types.unitCpu ==> |
220 | 8fcf251f | Iustin Pop | case Instance.shrinkByType inst Types.FailCPU of |
221 | 8fcf251f | Iustin Pop | Types.Ok inst' -> |
222 | 8fcf251f | Iustin Pop | Instance.vcpus inst' == Instance.vcpus inst - Types.unitCpu |
223 | 8fcf251f | Iustin Pop | _ -> False |
224 | 8fcf251f | Iustin Pop | where _types = (inst::Instance.Instance) |
225 | 8fcf251f | Iustin Pop | |
226 | 8fcf251f | Iustin Pop | prop_Instance_shrinkCF inst = |
227 | 8fcf251f | Iustin Pop | Instance.vcpus inst < 2 * Types.unitCpu ==> |
228 | 8fcf251f | Iustin Pop | not . isOk $ Instance.shrinkByType inst Types.FailCPU |
229 | 8fcf251f | Iustin Pop | where _types = (inst::Instance.Instance) |
230 | 8fcf251f | Iustin Pop | |
231 | 8fcf251f | Iustin Pop | prop_Instance_shrinkDG inst = |
232 | 8fcf251f | Iustin Pop | Instance.dsk inst >= 2 * Types.unitDsk ==> |
233 | 8fcf251f | Iustin Pop | case Instance.shrinkByType inst Types.FailDisk of |
234 | 8fcf251f | Iustin Pop | Types.Ok inst' -> |
235 | 8fcf251f | Iustin Pop | Instance.dsk inst' == Instance.dsk inst - Types.unitDsk |
236 | 8fcf251f | Iustin Pop | _ -> False |
237 | 8fcf251f | Iustin Pop | where _types = (inst::Instance.Instance) |
238 | 8fcf251f | Iustin Pop | |
239 | 8fcf251f | Iustin Pop | prop_Instance_shrinkDF inst = |
240 | 8fcf251f | Iustin Pop | Instance.dsk inst < 2 * Types.unitDsk ==> |
241 | 8fcf251f | Iustin Pop | not . isOk $ Instance.shrinkByType inst Types.FailDisk |
242 | 8fcf251f | Iustin Pop | where _types = (inst::Instance.Instance) |
243 | 8fcf251f | Iustin Pop | |
244 | 8fcf251f | Iustin Pop | prop_Instance_setMovable inst m = |
245 | 8fcf251f | Iustin Pop | Instance.movable inst' == m |
246 | 8fcf251f | Iustin Pop | where _types = (inst::Instance.Instance, m::Bool) |
247 | 8fcf251f | Iustin Pop | inst' = Instance.setMovable inst m |
248 | 8fcf251f | Iustin Pop | |
249 | c15f7183 | Iustin Pop | testInstance = |
250 | 7dd5ee6c | Iustin Pop | [ run prop_Instance_setIdx |
251 | 7dd5ee6c | Iustin Pop | , run prop_Instance_setName |
252 | 7dd5ee6c | Iustin Pop | , run prop_Instance_setPri |
253 | 7dd5ee6c | Iustin Pop | , run prop_Instance_setSec |
254 | 7dd5ee6c | Iustin Pop | , run prop_Instance_setBoth |
255 | 1ae7a904 | Iustin Pop | , run prop_Instance_runStatus_True |
256 | 1ae7a904 | Iustin Pop | , run prop_Instance_runStatus_False |
257 | 8fcf251f | Iustin Pop | , run prop_Instance_shrinkMG |
258 | 8fcf251f | Iustin Pop | , run prop_Instance_shrinkMF |
259 | 8fcf251f | Iustin Pop | , run prop_Instance_shrinkCG |
260 | 8fcf251f | Iustin Pop | , run prop_Instance_shrinkCF |
261 | 8fcf251f | Iustin Pop | , run prop_Instance_shrinkDG |
262 | 8fcf251f | Iustin Pop | , run prop_Instance_shrinkDF |
263 | 8fcf251f | Iustin Pop | , run prop_Instance_setMovable |
264 | 1ae7a904 | Iustin Pop | ] |
265 | 1ae7a904 | Iustin Pop | |
266 | 1ae7a904 | Iustin Pop | -- Instance text loader tests |
267 | 1ae7a904 | Iustin Pop | |
268 | 1ae7a904 | Iustin Pop | prop_Text_Load_Instance name mem dsk vcpus status pnode snode pdx sdx = |
269 | 1ae7a904 | Iustin Pop | let vcpus_s = show vcpus |
270 | 1ae7a904 | Iustin Pop | dsk_s = show dsk |
271 | 1ae7a904 | Iustin Pop | mem_s = show mem |
272 | 1ae7a904 | Iustin Pop | rsnode = snode ++ "a" -- non-empty secondary node |
273 | 1ae7a904 | Iustin Pop | rsdx = if pdx == sdx |
274 | 1ae7a904 | Iustin Pop | then sdx + 1 |
275 | 1ae7a904 | Iustin Pop | else sdx |
276 | 1ae7a904 | Iustin Pop | ndx = [(pnode, pdx), (rsnode, rsdx)] |
277 | 434c15d5 | Iustin Pop | tags = "" |
278 | 1ae7a904 | Iustin Pop | inst = Text.loadInst ndx |
279 | 434c15d5 | Iustin Pop | [name, mem_s, dsk_s, vcpus_s, status, pnode, rsnode, tags]:: |
280 | 1ae7a904 | Iustin Pop | Maybe (String, Instance.Instance) |
281 | 1ae7a904 | Iustin Pop | _types = ( name::String, mem::Int, dsk::Int |
282 | 1ae7a904 | Iustin Pop | , vcpus::Int, status::String |
283 | 1ae7a904 | Iustin Pop | , pnode::String, snode::String |
284 | 1ae7a904 | Iustin Pop | , pdx::Types.Ndx, sdx::Types.Ndx) |
285 | 1ae7a904 | Iustin Pop | in |
286 | 1ae7a904 | Iustin Pop | case inst of |
287 | 1ae7a904 | Iustin Pop | Nothing -> False |
288 | 1ae7a904 | Iustin Pop | Just (_, i) -> |
289 | 1ae7a904 | Iustin Pop | (Instance.name i == name && |
290 | 1ae7a904 | Iustin Pop | Instance.vcpus i == vcpus && |
291 | 1ae7a904 | Iustin Pop | Instance.mem i == mem && |
292 | 2060348b | Iustin Pop | Instance.pNode i == pdx && |
293 | 2060348b | Iustin Pop | Instance.sNode i == rsdx) |
294 | 1ae7a904 | Iustin Pop | |
295 | c15f7183 | Iustin Pop | testText = |
296 | 1ae7a904 | Iustin Pop | [ run prop_Text_Load_Instance |
297 | 7dd5ee6c | Iustin Pop | ] |
298 | 7dd5ee6c | Iustin Pop | |
299 | 7dd5ee6c | Iustin Pop | -- Node tests |
300 | 7dd5ee6c | Iustin Pop | |
301 | 7bc82927 | Iustin Pop | -- | Check that an instance add with too high memory or disk will be rejected |
302 | 8fcf251f | Iustin Pop | prop_Node_addPriFM node inst = Instance.mem inst >= Node.fMem node && |
303 | 8fcf251f | Iustin Pop | not (Node.failN1 node) |
304 | 8fcf251f | Iustin Pop | ==> |
305 | 8fcf251f | Iustin Pop | case Node.addPri node inst'' of |
306 | 8fcf251f | Iustin Pop | Types.OpFail Types.FailMem -> True |
307 | 8fcf251f | Iustin Pop | _ -> False |
308 | 15f4c8ca | Iustin Pop | where _types = (node::Node.Node, inst::Instance.Instance) |
309 | 8fcf251f | Iustin Pop | inst' = setInstanceSmallerThanNode node inst |
310 | 8fcf251f | Iustin Pop | inst'' = inst' { Instance.mem = Instance.mem inst } |
311 | 8fcf251f | Iustin Pop | |
312 | 8fcf251f | Iustin Pop | prop_Node_addPriFD node inst = Instance.dsk inst >= Node.fDsk node && |
313 | 8fcf251f | Iustin Pop | not (Node.failN1 node) |
314 | 8fcf251f | Iustin Pop | ==> |
315 | 8fcf251f | Iustin Pop | case Node.addPri node inst'' of |
316 | 8fcf251f | Iustin Pop | Types.OpFail Types.FailDisk -> True |
317 | 8fcf251f | Iustin Pop | _ -> False |
318 | 8fcf251f | Iustin Pop | where _types = (node::Node.Node, inst::Instance.Instance) |
319 | 8fcf251f | Iustin Pop | inst' = setInstanceSmallerThanNode node inst |
320 | 8fcf251f | Iustin Pop | inst'' = inst' { Instance.dsk = Instance.dsk inst } |
321 | 8fcf251f | Iustin Pop | |
322 | 8fcf251f | Iustin Pop | prop_Node_addPriFC node inst = Instance.vcpus inst > Node.availCpu node && |
323 | 8fcf251f | Iustin Pop | not (Node.failN1 node) |
324 | 8fcf251f | Iustin Pop | ==> |
325 | 8fcf251f | Iustin Pop | case Node.addPri node inst'' of |
326 | 8fcf251f | Iustin Pop | Types.OpFail Types.FailCPU -> True |
327 | 8fcf251f | Iustin Pop | _ -> False |
328 | 8fcf251f | Iustin Pop | where _types = (node::Node.Node, inst::Instance.Instance) |
329 | 8fcf251f | Iustin Pop | inst' = setInstanceSmallerThanNode node inst |
330 | 8fcf251f | Iustin Pop | inst'' = inst' { Instance.vcpus = Instance.vcpus inst } |
331 | 7bc82927 | Iustin Pop | |
332 | 7bc82927 | Iustin Pop | -- | Check that an instance add with too high memory or disk will be rejected |
333 | 15f4c8ca | Iustin Pop | prop_Node_addSec node inst pdx = |
334 | 2060348b | Iustin Pop | (Instance.mem inst >= (Node.fMem node - Node.rMem node) || |
335 | 2060348b | Iustin Pop | Instance.dsk inst >= Node.fDsk node) && |
336 | 9f6dcdea | Iustin Pop | not (Node.failN1 node) |
337 | 79a72ce7 | Iustin Pop | ==> isFailure (Node.addSec node inst pdx) |
338 | 15f4c8ca | Iustin Pop | where _types = (node::Node.Node, inst::Instance.Instance, pdx::Int) |
339 | 7dd5ee6c | Iustin Pop | |
340 | 8fcf251f | Iustin Pop | newtype SmallRatio = SmallRatio Double deriving Show |
341 | 8fcf251f | Iustin Pop | instance Arbitrary SmallRatio where |
342 | 8fcf251f | Iustin Pop | arbitrary = do |
343 | 8fcf251f | Iustin Pop | v <- choose (0, 1) |
344 | 8fcf251f | Iustin Pop | return $ SmallRatio v |
345 | 8fcf251f | Iustin Pop | |
346 | 8fcf251f | Iustin Pop | -- | Check mdsk setting |
347 | 8fcf251f | Iustin Pop | prop_Node_setMdsk node mx = |
348 | 8fcf251f | Iustin Pop | Node.loDsk node' >= 0 && |
349 | 8fcf251f | Iustin Pop | fromIntegral (Node.loDsk node') <= Node.tDsk node && |
350 | 8fcf251f | Iustin Pop | Node.availDisk node' >= 0 && |
351 | 8fcf251f | Iustin Pop | Node.availDisk node' <= Node.fDsk node' && |
352 | 8fcf251f | Iustin Pop | fromIntegral (Node.availDisk node') <= Node.tDsk node' |
353 | 8fcf251f | Iustin Pop | where _types = (node::Node.Node, mx::SmallRatio) |
354 | 8fcf251f | Iustin Pop | node' = Node.setMdsk node mx' |
355 | 8fcf251f | Iustin Pop | SmallRatio mx' = mx |
356 | 8fcf251f | Iustin Pop | |
357 | 8fcf251f | Iustin Pop | -- Check tag maps |
358 | 8fcf251f | Iustin Pop | prop_Node_tagMaps_idempotent tags = |
359 | 8fcf251f | Iustin Pop | Node.delTags (Node.addTags m tags) tags == m |
360 | 8fcf251f | Iustin Pop | where _types = (tags::[String]) |
361 | 8fcf251f | Iustin Pop | m = Data.Map.empty |
362 | 8fcf251f | Iustin Pop | |
363 | 8fcf251f | Iustin Pop | prop_Node_tagMaps_reject tags = |
364 | 8fcf251f | Iustin Pop | not (null tags) ==> |
365 | 8fcf251f | Iustin Pop | any (\t -> Node.rejectAddTags m [t]) tags |
366 | 8fcf251f | Iustin Pop | where _types = (tags::[String]) |
367 | 8fcf251f | Iustin Pop | m = Node.addTags (Data.Map.empty) tags |
368 | 8fcf251f | Iustin Pop | |
369 | c15f7183 | Iustin Pop | testNode = |
370 | 8fcf251f | Iustin Pop | [ run prop_Node_addPriFM |
371 | 8fcf251f | Iustin Pop | , run prop_Node_addPriFD |
372 | 8fcf251f | Iustin Pop | , run prop_Node_addPriFC |
373 | 7dd5ee6c | Iustin Pop | , run prop_Node_addSec |
374 | 8fcf251f | Iustin Pop | , run prop_Node_setMdsk |
375 | 8fcf251f | Iustin Pop | , run prop_Node_tagMaps_idempotent |
376 | 8fcf251f | Iustin Pop | , run prop_Node_tagMaps_reject |
377 | 7dd5ee6c | Iustin Pop | ] |
378 | cf35a869 | Iustin Pop | |
379 | cf35a869 | Iustin Pop | |
380 | cf35a869 | Iustin Pop | -- Cluster tests |
381 | cf35a869 | Iustin Pop | |
382 | cf35a869 | Iustin Pop | -- | Check that the cluster score is close to zero for a homogeneous cluster |
383 | cf35a869 | Iustin Pop | prop_Score_Zero node count = |
384 | 3a3c1eb4 | Iustin Pop | (not (Node.offline node) && not (Node.failN1 node) && (count > 0) && |
385 | 2060348b | Iustin Pop | (Node.tDsk node > 0) && (Node.tMem node > 0)) ==> |
386 | cf35a869 | Iustin Pop | let fn = Node.buildPeers node Container.empty |
387 | 3a3c1eb4 | Iustin Pop | nlst = zip [1..] $ replicate count fn::[(Types.Ndx, Node.Node)] |
388 | cf35a869 | Iustin Pop | nl = Container.fromAssocList nlst |
389 | cf35a869 | Iustin Pop | score = Cluster.compCV nl |
390 | cf35a869 | Iustin Pop | -- we can't say == 0 here as the floating point errors accumulate; |
391 | cf35a869 | Iustin Pop | -- this should be much lower than the default score in CLI.hs |
392 | 685f5bc6 | Iustin Pop | in score <= 1e-15 |
393 | cf35a869 | Iustin Pop | |
394 | 8fcf251f | Iustin Pop | -- | Check that cluster stats are sane |
395 | 8fcf251f | Iustin Pop | prop_CStats_sane node count = |
396 | 8fcf251f | Iustin Pop | (not (Node.offline node) && not (Node.failN1 node) && (count > 0) && |
397 | 8fcf251f | Iustin Pop | (Node.tDsk node > 0) && (Node.tMem node > 0)) ==> |
398 | 8fcf251f | Iustin Pop | let fn = Node.buildPeers node Container.empty |
399 | 8fcf251f | Iustin Pop | nlst = zip [1..] $ replicate count fn::[(Types.Ndx, Node.Node)] |
400 | 8fcf251f | Iustin Pop | nl = Container.fromAssocList nlst |
401 | 8fcf251f | Iustin Pop | cstats = Cluster.totalResources nl |
402 | 8fcf251f | Iustin Pop | in Cluster.csAdsk cstats >= 0 && |
403 | 8fcf251f | Iustin Pop | Cluster.csAdsk cstats <= Cluster.csFdsk cstats |
404 | 8fcf251f | Iustin Pop | |
405 | c15f7183 | Iustin Pop | testCluster = |
406 | cf35a869 | Iustin Pop | [ run prop_Score_Zero |
407 | 8fcf251f | Iustin Pop | , run prop_CStats_sane |
408 | cf35a869 | Iustin Pop | ] |