Revision 00b70680

b/htools/Ganeti/HTools/QC.hs
321 321
                then liftM Types.OpGood arbitrary
322 322
                else liftM Types.OpFail arbitrary
323 323

  
324
instance Arbitrary Types.ISpec where
325
  arbitrary = do
326
    mem <- arbitrary::Gen (NonNegative Int)
327
    dsk_c <- arbitrary::Gen (NonNegative Int)
328
    dsk_s <- arbitrary::Gen (NonNegative Int)
329
    cpu <- arbitrary::Gen (NonNegative Int)
330
    nic <- arbitrary::Gen (NonNegative Int)
331
    return Types.ISpec { Types.iSpecMemorySize = fromIntegral mem
332
                       , Types.iSpecCpuCount   = fromIntegral cpu
333
                       , Types.iSpecDiskSize   = fromIntegral dsk_s
334
                       , Types.iSpecDiskCount  = fromIntegral dsk_c
335
                       , Types.iSpecNicCount   = fromIntegral nic
336
                       }
337

  
338
-- | Helper function to check whether a spec is LTE than another
339
iSpecSmaller :: Types.ISpec -> Types.ISpec -> Bool
340
iSpecSmaller imin imax =
341
  Types.iSpecMemorySize imin <= Types.iSpecMemorySize imax &&
342
  Types.iSpecCpuCount imin   <= Types.iSpecCpuCount imax &&
343
  Types.iSpecDiskSize imin   <= Types.iSpecDiskSize imax &&
344
  Types.iSpecDiskCount imin  <= Types.iSpecDiskCount imax &&
345
  Types.iSpecNicCount imin   <= Types.iSpecNicCount imax
346

  
347
instance Arbitrary Types.IPolicy where
348
  arbitrary = do
349
    imin <- arbitrary
350
    istd <- arbitrary `suchThat` (iSpecSmaller imin)
351
    imax <- arbitrary `suchThat` (iSpecSmaller istd)
352
    dts  <- arbitrary
353
    return Types.IPolicy { Types.iPolicyMinSpec = imin
354
                         , Types.iPolicyStdSpec = istd
355
                         , Types.iPolicyMaxSpec = imax
356
                         , Types.iPolicyDiskTemplates = dts
357
                         }
358

  
324 359
-- * Actual tests
325 360

  
326 361
-- ** Utils tests
......
995 1030
     all (\(guuid, (nl'', _)) -> all ((== guuid) . Node.group)
996 1031
                                 (Container.elems nl'')) gni
997 1032

  
1033
-- | Helper function to check if we can allocate an instance on a
1034
-- given node list.
1035
canAllocOn :: Node.List -> Int -> Instance.Instance -> Bool
1036
canAllocOn nl reqnodes inst =
1037
  case Cluster.genAllocNodes defGroupList nl reqnodes True >>=
1038
       Cluster.tryAlloc nl (Container.empty) inst of
1039
       Types.Bad _ -> False
1040
       Types.Ok as ->
1041
         case Cluster.asSolution as of
1042
           Nothing -> False
1043
           Just _ -> True
1044

  
1045
-- | Checks that allocation obeys minimum and maximum instance
1046
-- policies. The unittest generates a random node, duplicates it count
1047
-- times, and generates a random instance that can be allocated on
1048
-- this mini-cluster; it then checks that after applying a policy that
1049
-- the instance doesn't fits, the allocation fails.
1050
prop_ClusterAllocPolicy node =
1051
  -- rqn is the required nodes (1 or 2)
1052
  forAll (choose (1, 2)) $ \rqn ->
1053
  forAll (choose (5, 20)) $ \count ->
1054
  forAll (arbitrary `suchThat` (canAllocOn (makeSmallCluster node count) rqn))
1055
         $ \inst ->
1056
  forAll (arbitrary `suchThat` (isFailure .
1057
                                Instance.instMatchesPolicy inst)) $ \ipol ->
1058
  let node' = Node.setPolicy ipol node
1059
      nl = makeSmallCluster node' count
1060
  in not $ canAllocOn nl rqn inst
1061

  
998 1062
testSuite "Cluster"
999 1063
            [ 'prop_Score_Zero
1000 1064
            , 'prop_CStats_sane
......
1004 1068
            , 'prop_ClusterAllocBalance
1005 1069
            , 'prop_ClusterCheckConsistency
1006 1070
            , 'prop_ClusterSplitCluster
1071
            , 'prop_ClusterAllocPolicy
1007 1072
            ]
1008 1073

  
1009 1074
-- ** OpCodes tests

Also available in: Unified diff