--- /dev/null
+{-# LANGUAGE TemplateHaskell #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+{-| Unittests for "Ganeti.Runtime".
+
+-}
+
+{-
+
+Copyright (C) 2013 Google Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+-}
+
+module Test.Ganeti.Runtime (testRuntime) where
+
+import Test.HUnit
+import qualified Text.JSON as J
+
+import Test.Ganeti.TestHelper
+import Test.Ganeti.TestCommon
+
+import Ganeti.Runtime
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+-- | Tests the compatibility between Haskell and Python log files.
+case_LogFiles :: Assertion
+case_LogFiles = do
+ let daemons = [minBound..maxBound]::[GanetiDaemon]
+ dnames = map daemonName daemons
+ dfiles <- mapM daemonLogFile daemons
+ let serialized = J.encode dnames
+ py_stdout <-
+ runPython "from ganeti import constants\n\
+ \from ganeti import serializer\n\
+ \import sys\n\
+ \daemons = serializer.Load(sys.stdin.read())\n\
+ \logfiles = [constants.DAEMONS_LOGFILES[d] for d in daemons]\n\
+ \print serializer.Dump(logfiles)" serialized
+ >>= checkPythonResult
+ let deserialised = J.decode py_stdout::J.Result [String]
+ decoded <- case deserialised of
+ J.Ok ops -> return ops
+ J.Error msg ->
+ assertFailure ("Unable to decode log files: " ++ msg)
+ -- this already raised an expection, but we need it
+ -- for proper types
+ >> fail "Unable to decode log files"
+ assertEqual "Mismatch in number of returned log files"
+ (length decoded) (length daemons)
+ mapM_ (uncurry (assertEqual "Different result after encoding/decoding")
+ ) $ zip decoded dfiles
+
+-- | Tests the compatibility between Haskell and Python users.
+case_UsersGroups :: Assertion
+case_UsersGroups = do
+ -- note: we don't have here a programatic way to list all users, so
+ -- we harcode some parts of the two (hs/py) lists
+ let daemons = [minBound..maxBound]::[GanetiDaemon]
+ users = map daemonUser daemons
+ groups = map daemonGroup $
+ map DaemonGroup daemons ++ map ExtraGroup [minBound..maxBound]
+ py_stdout <-
+ runPython "from ganeti import constants\n\
+ \from ganeti import serializer\n\
+ \import sys\n\
+ \users = [constants.MASTERD_GROUP,\n\
+ \ constants.NODED_USER,\n\
+ \ constants.RAPI_USER,\n\
+ \ constants.CONFD_USER,\n\
+ \ ]\n\
+ \groups = [constants.MASTERD_GROUP,\n\
+ \ constants.NODED_GROUP,\n\
+ \ constants.RAPI_GROUP,\n\
+ \ constants.CONFD_GROUP,\n\
+ \ constants.DAEMONS_GROUP,\n\
+ \ constants.ADMIN_GROUP]\n\
+ \encoded = (users, groups)\n\
+ \print serializer.Dump(encoded)" ""
+ >>= checkPythonResult
+ let deserialised = J.decode py_stdout::J.Result ([String], [String])
+ (py_users, py_groups) <-
+ case deserialised of
+ J.Ok ops -> return ops
+ J.Error msg ->
+ assertFailure ("Unable to decode users/groups: " ++ msg)
+ -- this already raised an expection, but we need it for proper
+ -- types
+ >> fail "Unable to decode users/groups"
+ assertEqual "Mismatch in number of returned users"
+ (length py_users) (length users)
+ assertEqual "Mismatch in number of returned users"
+ (length py_groups) (length groups)
+ mapM_ (uncurry (assertEqual "Different result for users")
+ ) $ zip py_users users
+ mapM_ (uncurry (assertEqual "Different result for groups")
+ ) $ zip py_groups groups
+
+testSuite "Runtime"
+ [ 'case_LogFiles
+ , 'case_UsersGroups
+ ]