Revision 1cb92fac
b/htools/Ganeti/HTools/QC.hs | ||
---|---|---|
334 | 334 |
tlist = map (\e -> (True, e)) lst2 |
335 | 335 |
cndlist = flist ++ tlist ++ [undefined] |
336 | 336 |
|
337 |
prop_Utils_parseUnit (NonNegative n) = |
|
338 |
Utils.parseUnit (show n) == Types.Ok n && |
|
339 |
Utils.parseUnit (show n ++ "m") == Types.Ok n && |
|
340 |
(case Utils.parseUnit (show n ++ "M") of |
|
341 |
Types.Ok m -> if n > 0 |
|
342 |
then m < n -- for positive values, X MB is less than X MiB |
|
343 |
else m == 0 -- but for 0, 0 MB == 0 MiB |
|
344 |
Types.Bad _ -> False) && |
|
345 |
Utils.parseUnit (show n ++ "g") == Types.Ok (n*1024) && |
|
346 |
Utils.parseUnit (show n ++ "t") == Types.Ok (n*1048576) && |
|
347 |
Types.isBad (Utils.parseUnit (show n ++ "x")::Types.Result Int) |
|
348 |
where _types = (n::Int) |
|
349 |
|
|
337 | 350 |
-- | Test list for the Utils module. |
338 | 351 |
testUtils = |
339 | 352 |
[ run prop_Utils_commaJoinSplit |
... | ... | |
343 | 356 |
, run prop_Utils_select |
344 | 357 |
, run prop_Utils_select_undefd |
345 | 358 |
, run prop_Utils_select_undefv |
359 |
, run prop_Utils_parseUnit |
|
346 | 360 |
] |
347 | 361 |
|
348 | 362 |
-- ** PeerMap tests |
b/htools/Ganeti/HTools/Types.hs | ||
---|---|---|
264 | 264 |
data Result a |
265 | 265 |
= Bad String |
266 | 266 |
| Ok a |
267 |
deriving (Show, Read) |
|
267 |
deriving (Show, Read, Eq)
|
|
268 | 268 |
|
269 | 269 |
instance Monad Result where |
270 | 270 |
(>>=) (Bad x) _ = Bad x |
b/htools/Ganeti/HTools/Utils.hs | ||
---|---|---|
46 | 46 |
, formatTable |
47 | 47 |
, annotateResult |
48 | 48 |
, defaultGroupID |
49 |
, parseUnit |
|
49 | 50 |
) where |
50 | 51 |
|
51 | 52 |
import Control.Monad (liftM) |
53 |
import Data.Char (toUpper) |
|
52 | 54 |
import Data.List |
53 | 55 |
import Data.Maybe (fromMaybe) |
54 | 56 |
import qualified Text.JSON as J |
... | ... | |
252 | 254 |
-- | Default group UUID (just a string, not a real UUID). |
253 | 255 |
defaultGroupID :: GroupID |
254 | 256 |
defaultGroupID = "00000000-0000-0000-0000-000000000000" |
257 |
|
|
258 |
-- | Tries to extract number and scale from the given string. |
|
259 |
-- |
|
260 |
-- Input must be in the format NUMBER+ SPACE* [UNIT]. If no unit is |
|
261 |
-- specified, it defaults to MiB. Return value is always an integral |
|
262 |
-- value in MiB. |
|
263 |
parseUnit :: (Monad m, Integral a, Read a) => String -> m a |
|
264 |
parseUnit str = |
|
265 |
-- TODO: enhance this by splitting the unit parsing code out and |
|
266 |
-- accepting floating-point numbers |
|
267 |
case reads str of |
|
268 |
[(v, suffix)] -> |
|
269 |
let unit = dropWhile (== ' ') suffix |
|
270 |
upper = map toUpper unit |
|
271 |
siConvert x = x * 1000000 `div` 1048576 |
|
272 |
in case () of |
|
273 |
_ | null unit -> return v |
|
274 |
| unit == "m" || upper == "MIB" -> return v |
|
275 |
| unit == "M" || upper == "MB" -> return $ siConvert v |
|
276 |
| unit == "g" || upper == "GIB" -> return $ v * 1024 |
|
277 |
| unit == "G" || upper == "GB" -> return $ siConvert |
|
278 |
(v * 1000) |
|
279 |
| unit == "t" || upper == "TIB" -> return $ v * 1048576 |
|
280 |
| unit == "T" || upper == "TB" -> return $ |
|
281 |
siConvert (v * 1000000) |
|
282 |
| otherwise -> fail $ "Unknown unit '" ++ unit ++ "'" |
|
283 |
_ -> fail $ "Can't parse string '" ++ str ++ "'" |
Also available in: Unified diff