module Test.Ganeti.Network
( testNetwork
, genBitStringMaxLen
) where
import Test.QuickCheck
import Ganeti.Network as Network
import Ganeti.Objects as Objects
import Test.Ganeti.Objects
( genBitStringMaxLen
, genValidNetwork )
import Test.Ganeti.TestHelper
import Test.Ganeti.TestCommon
import qualified Data.Vector.Unboxed as V
genAddressPool :: Int -> Gen AddressPool
genAddressPool maxLenBitVec = do
net <- genValidNetwork
lenBitVec <- choose (0, maxLenBitVec)
res <- genBitVector lenBitVec
ext_res <- genBitVector lenBitVec
return AddressPool { network = net
, reservations = res
, extReservations = ext_res }
genBitVector :: Int -> Gen (V.Vector Bool)
genBitVector len = do
boolList <- vector len::Gen [Bool]
return $ V.fromList boolList
instance Arbitrary AddressPool where
arbitrary = genAddressPool ((2::Int)^(8::Int))
prop_bitStringToBitVector :: Property
prop_bitStringToBitVector =
forAll (genBitStringMaxLen 256) $ \bs ->
let bitList = V.toList $ Network.bitStringToBitVector bs
bitCharList = Prelude.zip bitList bs
in Prelude.all checkBit bitCharList
checkBit :: (Bool, Char) -> Bool
checkBit (False, '0') = True
checkBit (True, '1') = True
checkBit _ = False
prop_createAddressPool :: Objects.Network -> Property
prop_createAddressPool n =
let valid = networkIsValid n
in case createAddressPool n of
Just _ -> True ==? valid
Nothing -> False ==? valid
prop_addressPoolProperties :: AddressPool -> Property
prop_addressPoolProperties a =
conjoin
[ printTestCase
("Not all reservations are included in 'allReservations' of " ++
"address pool:" ++ show a) (allReservationsSubsumesInternal a)
, printTestCase
("Not all external reservations are covered by 'allReservations' " ++
"of address pool: " ++ show a)
(allReservationsSubsumesExternal a)
, printTestCase
("The counts of free and reserved addresses do not add up for " ++
"address pool: " ++ show a)
(checkCounts a)
, printTestCase
("'isFull' wrongly classified the status of the address pool: " ++
show a) (checkIsFull a)
, printTestCase
("Network map is inconsistent with reservations of address pool: " ++
show a) (checkGetMap a)
]
allReservationsSubsumesInternal :: AddressPool -> Bool
allReservationsSubsumesInternal a =
bitVectorSubsumes (allReservations a) (reservations a)
allReservationsSubsumesExternal :: AddressPool -> Bool
allReservationsSubsumesExternal a =
bitVectorSubsumes (allReservations a) (extReservations a)
bitVectorSubsumes :: V.Vector Bool -> V.Vector Bool -> Bool
bitVectorSubsumes v1 v2 = V.and $
V.zipWith (\a b -> not b || a) v1 v2
checkCounts :: AddressPool -> Bool
checkCounts a =
let res = reservations a
in V.length res == getFreeCount a + getReservedCount a
checkIsFull :: AddressPool -> Bool
checkIsFull a = isFull a == V.notElem False (allReservations a)
checkGetMap :: AddressPool -> Bool
checkGetMap a =
allReservations a == V.fromList (Prelude.map (== 'X') (getMap a))
testSuite "Network"
[ 'prop_bitStringToBitVector
, 'prop_createAddressPool
, 'prop_addressPoolProperties
]