diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 2f3f7b65e18d251d63775b82a8ce8d130fbc7224..f5876f26e1af58d27df9d3e40dd68753eeedab06 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -10285,9 +10285,10 @@ def _LoadNodeEvacResult(lu, alloc_result, early_release, use_nodes): (moved, failed, jobs) = alloc_result if failed: - lu.LogWarning("Unable to evacuate instances %s", - utils.CommaJoin("%s (%s)" % (name, reason) - for (name, reason) in failed)) + failreason = utils.CommaJoin("%s (%s)" % (name, reason) + for (name, reason) in failed) + lu.LogWarning("Unable to evacuate instances %s", failreason) + raise errors.OpExecError("Unable to evacuate instances %s" % failreason) if moved: lu.LogInfo("Instances to be moved: %s", diff --git a/test/ganeti.cmdlib_unittest.py b/test/ganeti.cmdlib_unittest.py index 40eebe0aa8c734ef96720e9a1134973ab49542ee..08cbc6138d4448504a26c7e49ced57391b55f4f5 100755 --- a/test/ganeti.cmdlib_unittest.py +++ b/test/ganeti.cmdlib_unittest.py @@ -28,6 +28,7 @@ import time import tempfile import shutil import operator +import itertools from ganeti import constants from ganeti import mcpu @@ -363,5 +364,71 @@ class TestClusterVerifyFiles(unittest.TestCase): ])) +class _FakeLU: + def __init__(self): + self.warning_log = [] + self.info_log = [] + + def LogWarning(self, text, *args): + self.warning_log.append((text, args)) + + def LogInfo(self, text, *args): + self.info_log.append((text, args)) + + +class TestLoadNodeEvacResult(unittest.TestCase): + def testSuccess(self): + for moved in [[], [ + ("inst20153.example.com", "grp2", ["nodeA4509", "nodeB2912"]), + ]]: + for early_release in [False, True]: + for use_nodes in [False, True]: + jobs = [ + [opcodes.OpInstanceReplaceDisks().__getstate__()], + [opcodes.OpInstanceMigrate().__getstate__()], + ] + + alloc_result = (moved, [], jobs) + assert cmdlib.IAllocator._NEVAC_RESULT(alloc_result) + + lu = _FakeLU() + result = cmdlib._LoadNodeEvacResult(lu, alloc_result, + early_release, use_nodes) + + if moved: + (_, (info_args, )) = lu.info_log.pop(0) + for (instname, instgroup, instnodes) in moved: + self.assertTrue(instname in info_args) + if use_nodes: + for i in instnodes: + self.assertTrue(i in info_args) + else: + self.assertTrue(instgroup in info_args) + + self.assertFalse(lu.info_log) + self.assertFalse(lu.warning_log) + + for op in itertools.chain(*result): + if hasattr(op.__class__, "early_release"): + self.assertEqual(op.early_release, early_release) + else: + self.assertFalse(hasattr(op, "early_release")) + + def testFailed(self): + alloc_result = ([], [ + ("inst5191.example.com", "errormsg21178"), + ], []) + assert cmdlib.IAllocator._NEVAC_RESULT(alloc_result) + + lu = _FakeLU() + self.assertRaises(errors.OpExecError, cmdlib._LoadNodeEvacResult, + lu, alloc_result, False, False) + self.assertFalse(lu.info_log) + (_, (args, )) = lu.warning_log.pop(0) + self.assertTrue("inst5191.example.com" in args) + self.assertTrue("errormsg21178" in args) + self.assertFalse(lu.warning_log) + + if __name__ == "__main__": testutils.GanetiTestProgram()