From d8bcd0a8b4e6545b8f3ffbe2eb93c655dbb1c7f5 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Mon, 29 Nov 2010 17:15:19 +0000
Subject: [PATCH] Add function for nodes to (nodgroup, nodes) split

Unittests included. The function will be needed for consistency checks
in the algorithms.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Balazs Lecz <leczb@google.com>
---
 Ganeti/HTools/Node.hs | 10 ++++++++++
 Ganeti/HTools/QC.hs   | 12 +++++++++++-
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/Ganeti/HTools/Node.hs b/Ganeti/HTools/Node.hs
index 88a6000fc..2740d18ce 100644
--- a/Ganeti/HTools/Node.hs
+++ b/Ganeti/HTools/Node.hs
@@ -66,11 +66,13 @@ module Ganeti.HTools.Node
     , AssocList
     , AllocElement
     , noSecondary
+    , computeGroups
     ) where
 
 import Data.List hiding (group)
 import qualified Data.Map as Map
 import qualified Data.Foldable as Foldable
+import Data.Ord (comparing)
 import Text.Printf (printf)
 
 import qualified Ganeti.HTools.Container as Container
@@ -538,3 +540,11 @@ defaultFields =
     , "rmem", "tdsk", "fdsk", "tcpu", "ucpu", "pcnt", "scnt"
     , "pfmem", "pfdsk", "rcpu"
     , "cload", "mload", "dload", "nload" ]
+
+-- | Split a list of nodes into a list of (node group UUID, list of
+-- associated nodes)
+computeGroups :: [Node] -> [(T.GroupID, [Node])]
+computeGroups nodes =
+  let nodes' = sortBy (comparing group) nodes
+      nodes'' = groupBy (\a b -> group a == group b) nodes'
+  in map (\nl -> (group (head nl), nl)) nodes''
diff --git a/Ganeti/HTools/QC.hs b/Ganeti/HTools/QC.hs
index 8b46aa559..cd3ae64ea 100644
--- a/Ganeti/HTools/QC.hs
+++ b/Ganeti/HTools/QC.hs
@@ -38,7 +38,7 @@ module Ganeti.HTools.QC
 
 import Test.QuickCheck
 import Test.QuickCheck.Batch
-import Data.List (findIndex, intercalate)
+import Data.List (findIndex, intercalate, nub)
 import Data.Maybe
 import Control.Monad
 import qualified Text.JSON as J
@@ -564,6 +564,15 @@ prop_Node_showField node =
   fst (Node.showHeader field) /= Types.unknownField &&
   Node.showField node field /= Types.unknownField
 
+
+prop_Node_computeGroups nodes =
+  let ng = Node.computeGroups nodes
+      onlyuuid = map fst ng
+  in length nodes == sum (map (length . snd) ng) &&
+     all (\(guuid, ns) -> all ((== guuid) . Node.group) ns) ng &&
+     length (nub onlyuuid) == length onlyuuid &&
+     if null nodes then True else not (null ng)
+
 testNode =
     [ run prop_Node_setAlias
     , run prop_Node_setOffline
@@ -577,6 +586,7 @@ testNode =
     , run prop_Node_tagMaps_idempotent
     , run prop_Node_tagMaps_reject
     , run prop_Node_showField
+    , run prop_Node_computeGroups
     ]
 
 
-- 
GitLab