from ganeti import cmdlib
from ganeti import rpc
from ganeti import compat
+from ganeti import pathutils
from ganeti.constants import HKR_SUCCESS, HKR_FAIL, HKR_SKIP
from mocks import FakeConfig, FakeProc, FakeContext
class FakeLU(cmdlib.LogicalUnit):
HPATH = "test"
+
def BuildHooksEnv(self):
- return {}, ["localhost"], ["localhost"]
+ return {}
+
+ def BuildHooksNodes(self):
+ return ["localhost"], ["localhost"]
class TestHooksRunner(unittest.TestCase):
"""
rr = rpc.RpcResult
- return dict([(node, rr(True, [("utest", constants.HKR_SUCCESS, "ok")],
- node=node, call='FakeScriptOk'))
+ return dict([(node, rr((True, [("utest", constants.HKR_SUCCESS, "ok")]),
+ node=node, call="FakeScriptOk"))
for node in node_list])
@return: rpc failure from all nodes
"""
- return dict([(node, rpc.RpcResult('error', failed=True,
- node=node, call='FakeError')) for node in node_list])
+ return dict([(node, rpc.RpcResult("error", failed=True,
+ node=node, call="FakeError")) for node in node_list])
@staticmethod
def _call_script_fail(node_list, hpath, phase, env):
"""
rr = rpc.RpcResult
return dict([(node, rr((True, [("utest", constants.HKR_FAIL, "err")]),
- node=node, call='FakeScriptFail'))
+ node=node, call="FakeScriptFail"))
for node in node_list])
def setUp(self):
def testTotalFalse(self):
"""Test complete rpc failure"""
- hm = mcpu.HooksMaster(self._call_false, self.lu)
+ hm = mcpu.HooksMaster.BuildFromLu(self._call_false, self.lu)
self.failUnlessRaises(errors.HooksFailure,
hm.RunPhase, constants.HOOKS_PHASE_PRE)
hm.RunPhase(constants.HOOKS_PHASE_POST)
def testIndividualFalse(self):
"""Test individual node failure"""
- hm = mcpu.HooksMaster(self._call_nodes_false, self.lu)
+ hm = mcpu.HooksMaster.BuildFromLu(self._call_nodes_false, self.lu)
hm.RunPhase(constants.HOOKS_PHASE_PRE)
#self.failUnlessRaises(errors.HooksFailure,
# hm.RunPhase, constants.HOOKS_PHASE_PRE)
def testScriptFalse(self):
"""Test individual rpc failure"""
- hm = mcpu.HooksMaster(self._call_script_fail, self.lu)
+ hm = mcpu.HooksMaster.BuildFromLu(self._call_script_fail, self.lu)
self.failUnlessRaises(errors.HooksAbort,
hm.RunPhase, constants.HOOKS_PHASE_PRE)
hm.RunPhase(constants.HOOKS_PHASE_POST)
def testScriptSucceed(self):
"""Test individual rpc failure"""
- hm = mcpu.HooksMaster(FakeHooksRpcSuccess, self.lu)
+ hm = mcpu.HooksMaster.BuildFromLu(FakeHooksRpcSuccess, self.lu)
for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
hm.RunPhase(phase)
def BuildHooksEnv(self):
assert self.hook_env is not None
+ return self.hook_env
+
+ def BuildHooksNodes(self):
+ return (["localhost"], ["localhost"])
+
- return self.hook_env, ["localhost"], ["localhost"]
+class FakeNoHooksLU(cmdlib.NoHooksLU):
+ pass
class TestHooksRunnerEnv(unittest.TestCase):
self.op = opcodes.OpTestDummy(result=False, messages=[], fail=False)
self.lu = FakeEnvLU(FakeProc(), self.op, FakeContext(), None)
- self.hm = mcpu.HooksMaster(self._HooksRpc, self.lu)
def _HooksRpc(self, *args):
self._rpcs.append(args)
self.assertEqual(env["GANETI_HOOKS_PHASE"], phase)
self.assertEqual(env["GANETI_HOOKS_PATH"], hpath)
self.assertEqual(env["GANETI_OP_CODE"], self.op.OP_ID)
- self.assertEqual(env["GANETI_OBJECT_TYPE"], constants.HTYPE_GROUP)
self.assertEqual(env["GANETI_HOOKS_VERSION"], str(constants.HOOKS_VERSION))
- self.assertEqual(env["GANETI_DATA_DIR"], constants.DATA_DIR)
+ self.assertEqual(env["GANETI_DATA_DIR"], pathutils.DATA_DIR)
+ if "GANETI_OBJECT_TYPE" in env:
+ self.assertEqual(env["GANETI_OBJECT_TYPE"], constants.HTYPE_GROUP)
+ else:
+ self.assertTrue(self.lu.HTYPE is None)
def testEmptyEnv(self):
# Check pre-phase hook
self.lu.hook_env = {}
- self.hm.RunPhase(constants.HOOKS_PHASE_PRE)
+ hm = mcpu.HooksMaster.BuildFromLu(self._HooksRpc, self.lu)
+ hm.RunPhase(constants.HOOKS_PHASE_PRE)
(node_list, hpath, phase, env) = self._rpcs.pop(0)
self.assertEqual(node_list, set(["localhost"]))
# Check post-phase hook
self.lu.hook_env = {}
- self.hm.RunPhase(constants.HOOKS_PHASE_POST)
+ hm.RunPhase(constants.HOOKS_PHASE_POST)
(node_list, hpath, phase, env) = self._rpcs.pop(0)
self.assertEqual(node_list, set(["localhost"]))
self.lu.hook_env = {
"FOO": "pre-foo-value",
}
- self.hm.RunPhase(constants.HOOKS_PHASE_PRE)
+ hm = mcpu.HooksMaster.BuildFromLu(self._HooksRpc, self.lu)
+ hm.RunPhase(constants.HOOKS_PHASE_PRE)
(node_list, hpath, phase, env) = self._rpcs.pop(0)
self.assertEqual(node_list, set(["localhost"]))
"FOO": "post-value",
"BAR": 123,
}
- self.hm.RunPhase(constants.HOOKS_PHASE_POST)
+ hm.RunPhase(constants.HOOKS_PHASE_POST)
(node_list, hpath, phase, env) = self._rpcs.pop(0)
self.assertEqual(node_list, set(["localhost"]))
self.assertRaises(IndexError, self._rpcs.pop)
# Check configuration update hook
- self.hm.RunConfigUpdate()
+ hm.RunConfigUpdate()
(node_list, hpath, phase, env) = self._rpcs.pop(0)
self.assertEqual(set(node_list), set([self.lu.cfg.GetMasterNode()]))
self.assertEqual(hpath, constants.HOOKS_NAME_CFGUPDATE)
def testConflict(self):
for name in ["DATA_DIR", "OP_CODE"]:
self.lu.hook_env = { name: "value" }
+
+ # Test using a clean HooksMaster instance
+ hm = mcpu.HooksMaster.BuildFromLu(self._HooksRpc, self.lu)
+
for phase in [constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST]:
- # Test using a clean HooksMaster instance
- self.assertRaises(AssertionError,
- mcpu.HooksMaster(self._HooksRpc, self.lu).RunPhase,
- phase)
+ self.assertRaises(AssertionError, hm.RunPhase, phase)
self.assertRaises(IndexError, self._rpcs.pop)
def testNoNodes(self):
self.lu.hook_env = {}
- self.hm.RunPhase(constants.HOOKS_PHASE_PRE, nodes=[])
+ hm = mcpu.HooksMaster.BuildFromLu(self._HooksRpc, self.lu)
+ hm.RunPhase(constants.HOOKS_PHASE_PRE, nodes=[])
self.assertRaises(IndexError, self._rpcs.pop)
def testSpecificNodes(self):
"node93782.example.net",
]
+ hm = mcpu.HooksMaster.BuildFromLu(self._HooksRpc, self.lu)
+
for phase in [constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST]:
- self.hm.RunPhase(phase, nodes=nodes)
+ hm.RunPhase(phase, nodes=nodes)
(node_list, hpath, rpc_phase, env) = self._rpcs.pop(0)
self.assertEqual(set(node_list), set(nodes))
self.assertRaises(IndexError, self._rpcs.pop)
def testRunConfigUpdateNoPre(self):
- self.lu.hook_env = {}
- self.assertRaises(AssertionError, self.hm.RunConfigUpdate)
+ self.lu.hook_env = {
+ "FOO": "value",
+ }
+
+ hm = mcpu.HooksMaster.BuildFromLu(self._HooksRpc, self.lu)
+ hm.RunConfigUpdate()
+
+ (node_list, hpath, phase, env) = self._rpcs.pop(0)
+ self.assertEqual(set(node_list), set([self.lu.cfg.GetMasterNode()]))
+ self.assertEqual(hpath, constants.HOOKS_NAME_CFGUPDATE)
+ self.assertEqual(phase, constants.HOOKS_PHASE_POST)
+ self.assertEqual(env["GANETI_FOO"], "value")
+ self.assertFalse(compat.any(key.startswith("GANETI_POST") for key in env))
+ self._CheckEnv(env, constants.HOOKS_PHASE_POST,
+ constants.HOOKS_NAME_CFGUPDATE)
+
self.assertRaises(IndexError, self._rpcs.pop)
+ def testNoPreBeforePost(self):
+ self.lu.hook_env = {
+ "FOO": "value",
+ }
+
+ hm = mcpu.HooksMaster.BuildFromLu(self._HooksRpc, self.lu)
+ hm.RunPhase(constants.HOOKS_PHASE_POST)
+
+ (node_list, hpath, phase, env) = self._rpcs.pop(0)
+ self.assertEqual(node_list, set(["localhost"]))
+ self.assertEqual(hpath, self.lu.HPATH)
+ self.assertEqual(phase, constants.HOOKS_PHASE_POST)
+ self.assertEqual(env["GANETI_FOO"], "value")
+ self.assertEqual(env["GANETI_POST_FOO"], "value")
+ self._CheckEnv(env, constants.HOOKS_PHASE_POST, self.lu.HPATH)
+
+ self.assertRaises(IndexError, self._rpcs.pop)
+
+ def testNoHooksLU(self):
+ self.lu = FakeNoHooksLU(FakeProc(), self.op, FakeContext(), None)
+ self.assertRaises(AssertionError, self.lu.BuildHooksEnv)
+ self.assertRaises(AssertionError, self.lu.BuildHooksNodes)
+
+ hm = mcpu.HooksMaster.BuildFromLu(self._HooksRpc, self.lu)
+ self.assertEqual(hm.pre_env, {})
+ self.assertRaises(IndexError, self._rpcs.pop)
+
+ hm.RunPhase(constants.HOOKS_PHASE_PRE)
+ self.assertRaises(IndexError, self._rpcs.pop)
+
+ hm.RunPhase(constants.HOOKS_PHASE_POST)
+ self.assertRaises(IndexError, self._rpcs.pop)
+
+ hm.RunConfigUpdate()
+
+ (node_list, hpath, phase, env) = self._rpcs.pop(0)
+ self.assertEqual(set(node_list), set([self.lu.cfg.GetMasterNode()]))
+ self.assertEqual(hpath, constants.HOOKS_NAME_CFGUPDATE)
+ self.assertEqual(phase, constants.HOOKS_PHASE_POST)
+ self.assertFalse(compat.any(key.startswith("GANETI_POST") for key in env))
+ self._CheckEnv(env, constants.HOOKS_PHASE_POST,
+ constants.HOOKS_NAME_CFGUPDATE)
+ self.assertRaises(IndexError, self._rpcs.pop)
+
+ assert isinstance(self.lu, FakeNoHooksLU), "LU was replaced"
+
-if __name__ == '__main__':
+if __name__ == "__main__":
testutils.GanetiTestProgram()