Revision 305e174c htools/Ganeti/HTools/QC.hs
b/htools/Ganeti/HTools/QC.hs | ||
---|---|---|
48 | 48 |
, testJSON |
49 | 49 |
, testLuxi |
50 | 50 |
, testSsconf |
51 |
, testRpc |
|
52 | 51 |
, testQlang |
53 |
, testConfd |
|
54 | 52 |
) where |
55 | 53 |
|
56 | 54 |
import qualified Test.HUnit as HUnit |
... | ... | |
87 | 85 |
import qualified Ganeti.Luxi as Luxi |
88 | 86 |
import qualified Ganeti.Objects as Objects |
89 | 87 |
import qualified Ganeti.OpCodes as OpCodes |
90 |
import qualified Ganeti.Rpc as Rpc |
|
91 | 88 |
import qualified Ganeti.Query.Language as Qlang |
92 | 89 |
import qualified Ganeti.Runtime as Runtime |
93 | 90 |
import qualified Ganeti.Ssconf as Ssconf |
... | ... | |
281 | 278 |
n <- choose (1, 32) |
282 | 279 |
vectorOf n getName |
283 | 280 |
|
284 |
-- | Defines a tag type. |
|
285 |
newtype TagChar = TagChar { tagGetChar :: Char } |
|
286 |
|
|
287 |
-- | All valid tag chars. This doesn't need to match _exactly_ |
|
288 |
-- Ganeti's own tag regex, just enough for it to be close. |
|
289 |
tagChar :: [Char] |
|
290 |
tagChar = ['a'..'z'] ++ ['A'..'Z'] ++ ['0'..'9'] ++ ".+*/:@-" |
|
291 |
|
|
292 |
instance Arbitrary TagChar where |
|
293 |
arbitrary = do |
|
294 |
c <- elements tagChar |
|
295 |
return (TagChar c) |
|
296 |
|
|
297 |
-- | Generates a tag |
|
298 |
genTag :: Gen [TagChar] |
|
299 |
genTag = do |
|
300 |
-- the correct value would be C.maxTagLen, but that's way too |
|
301 |
-- verbose in unittests, and at the moment I don't see any possible |
|
302 |
-- bugs with longer tags and the way we use tags in htools |
|
303 |
n <- choose (1, 10) |
|
304 |
vector n |
|
305 |
|
|
306 |
-- | Generates a list of tags (correctly upper bounded). |
|
307 |
genTags :: Gen [String] |
|
308 |
genTags = do |
|
309 |
-- the correct value would be C.maxTagsPerObj, but per the comment |
|
310 |
-- in genTag, we don't use tags enough in htools to warrant testing |
|
311 |
-- such big values |
|
312 |
n <- choose (0, 10::Int) |
|
313 |
tags <- mapM (const genTag) [1..n] |
|
314 |
return $ map (map tagGetChar) tags |
|
315 |
|
|
316 | 281 |
instance Arbitrary Types.InstanceStatus where |
317 | 282 |
arbitrary = elements [minBound..maxBound] |
318 | 283 |
|
... | ... | |
489 | 454 |
, Types.iPolicySpindleRatio = spindle_ratio |
490 | 455 |
} |
491 | 456 |
|
492 |
instance Arbitrary Objects.Hypervisor where |
|
493 |
arbitrary = elements [minBound..maxBound] |
|
494 |
|
|
495 |
instance Arbitrary Objects.PartialNDParams where |
|
496 |
arbitrary = Objects.PartialNDParams <$> arbitrary <*> arbitrary |
|
497 |
|
|
498 |
instance Arbitrary Objects.Node where |
|
499 |
arbitrary = Objects.Node <$> getFQDN <*> getFQDN <*> getFQDN |
|
500 |
<*> arbitrary <*> arbitrary <*> arbitrary <*> getFQDN |
|
501 |
<*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary |
|
502 |
<*> arbitrary <*> arbitrary <*> getFQDN <*> arbitrary |
|
503 |
<*> (Set.fromList <$> genTags) |
|
504 |
|
|
505 |
instance Arbitrary Rpc.RpcCallAllInstancesInfo where |
|
506 |
arbitrary = Rpc.RpcCallAllInstancesInfo <$> arbitrary |
|
507 |
|
|
508 |
instance Arbitrary Rpc.RpcCallInstanceList where |
|
509 |
arbitrary = Rpc.RpcCallInstanceList <$> arbitrary |
|
510 |
|
|
511 |
instance Arbitrary Rpc.RpcCallNodeInfo where |
|
512 |
arbitrary = Rpc.RpcCallNodeInfo <$> arbitrary <*> arbitrary |
|
513 |
|
|
514 | 457 |
-- | Custom 'Qlang.Filter' generator (top-level), which enforces a |
515 | 458 |
-- (sane) limit on the depth of the generated filters. |
516 | 459 |
genFilter :: Gen (Qlang.Filter Qlang.FilterField) |
... | ... | |
1976 | 1919 |
[ 'prop_Ssconf_filename |
1977 | 1920 |
] |
1978 | 1921 |
|
1979 |
-- * Rpc tests |
|
1980 |
|
|
1981 |
-- | Monadic check that, for an offline node and a call that does not |
|
1982 |
-- offline nodes, we get a OfflineNodeError response. |
|
1983 |
-- FIXME: We need a way of generalizing this, running it for |
|
1984 |
-- every call manually will soon get problematic |
|
1985 |
prop_Rpc_noffl_request_allinstinfo :: Rpc.RpcCallAllInstancesInfo -> Property |
|
1986 |
prop_Rpc_noffl_request_allinstinfo call = |
|
1987 |
forAll (arbitrary `suchThat` Objects.nodeOffline) $ \node -> monadicIO $ do |
|
1988 |
res <- run $ Rpc.executeRpcCall [node] call |
|
1989 |
stop $ res ==? [(node, Left (Rpc.OfflineNodeError node))] |
|
1990 |
|
|
1991 |
prop_Rpc_noffl_request_instlist :: Rpc.RpcCallInstanceList -> Property |
|
1992 |
prop_Rpc_noffl_request_instlist call = |
|
1993 |
forAll (arbitrary `suchThat` Objects.nodeOffline) $ \node -> monadicIO $ do |
|
1994 |
res <- run $ Rpc.executeRpcCall [node] call |
|
1995 |
stop $ res ==? [(node, Left (Rpc.OfflineNodeError node))] |
|
1996 |
|
|
1997 |
prop_Rpc_noffl_request_nodeinfo :: Rpc.RpcCallNodeInfo -> Property |
|
1998 |
prop_Rpc_noffl_request_nodeinfo call = |
|
1999 |
forAll (arbitrary `suchThat` Objects.nodeOffline) $ \node -> monadicIO $ do |
|
2000 |
res <- run $ Rpc.executeRpcCall [node] call |
|
2001 |
stop $ res ==? [(node, Left (Rpc.OfflineNodeError node))] |
|
2002 |
|
|
2003 |
testSuite "Rpc" |
|
2004 |
[ 'prop_Rpc_noffl_request_allinstinfo |
|
2005 |
, 'prop_Rpc_noffl_request_instlist |
|
2006 |
, 'prop_Rpc_noffl_request_nodeinfo |
|
2007 |
] |
|
2008 |
|
|
2009 | 1922 |
-- * Qlang tests |
2010 | 1923 |
|
2011 | 1924 |
-- | Tests that serialisation/deserialisation of filters is |
Also available in: Unified diff