The masterd.instance is mocked out and checked that the correct TransferInstanceData call is placed.
Signed-off-by: Aaron Karper <[email protected]> --- Makefile.am | 1 + test/py/cmdlib/instance_unittest.py | 15 +++++++ test/py/cmdlib/testsupport/cmdlib_testcase.py | 13 ++++++ test/py/cmdlib/testsupport/masterd_mock.py | 59 +++++++++++++++++++++++++++ 4 files changed, 88 insertions(+) create mode 100644 test/py/cmdlib/testsupport/masterd_mock.py diff --git a/Makefile.am b/Makefile.am index f662831..117e1f3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1763,6 +1763,7 @@ python_test_support = \ test/py/cmdlib/testsupport/config_mock.py \ test/py/cmdlib/testsupport/iallocator_mock.py \ test/py/cmdlib/testsupport/livelock_mock.py \ + test/py/cmdlib/testsupport/masterd_mock.py \ test/py/cmdlib/testsupport/netutils_mock.py \ test/py/cmdlib/testsupport/processor_mock.py \ test/py/cmdlib/testsupport/rpc_runner_mock.py \ diff --git a/test/py/cmdlib/instance_unittest.py b/test/py/cmdlib/instance_unittest.py index 4406be9..084fef2 100644 --- a/test/py/cmdlib/instance_unittest.py +++ b/test/py/cmdlib/instance_unittest.py @@ -1594,9 +1594,24 @@ class TestLUInstanceMove(CmdlibTestCase): .CreateSuccessfulNodeResult(self.node, "") inst = self.cfg.AddNewInstance(admin_state=constants.ADMINST_UP) + old_node = inst.primary_node op = opcodes.OpInstanceMove(instance_name=inst.name, target_node=self.node.name) self.ExecOpCode(op) + self.masterd_mod.instance.TransferInstanceData.assert_called_with( + mock.ANY, mock.ANY, old_node, self.node.uuid, self.node.secondary_ip, + mock.ANY, inst, [mock.ANY]) + + def testMoveInstanceNoCopy(self): + self.masterd.instance.TransferInstanceData.return_value = [True] + inst = self.cfg.AddNewInstance(disk_template=constants.DT_SHARED_FILE) + old_node = inst.primary_node + op = opcodes.OpInstanceMove(instance_name=inst.name, + target_node=self.node.name) + self.ExecOpCode(op) + self.masterd_mod.instance.TransferInstanceData.assert_called_with( + mock.ANY, mock.ANY, old_node, self.node.uuid, self.node.secondary_ip, + mock.ANY, inst, []) def testMoveFailingStartInstance(self): self.rpc.call_node_info.return_value = \ diff --git a/test/py/cmdlib/testsupport/cmdlib_testcase.py b/test/py/cmdlib/testsupport/cmdlib_testcase.py index f245f45..1472779 100644 --- a/test/py/cmdlib/testsupport/cmdlib_testcase.py +++ b/test/py/cmdlib/testsupport/cmdlib_testcase.py @@ -39,6 +39,7 @@ import traceback from cmdlib.testsupport.config_mock import ConfigMock from cmdlib.testsupport.iallocator_mock import patchIAllocator from cmdlib.testsupport.livelock_mock import LiveLockMock +from cmdlib.testsupport.masterd_mock import patchMasterd, CreateMasterdMock from cmdlib.testsupport.netutils_mock import patchNetutils, \ SetupDefaultNetutilsMock from cmdlib.testsupport.processor_mock import ProcessorMock @@ -136,6 +137,7 @@ class CmdlibTestCase(testutils.GanetiTestCase): self._netutils_patcher = None self._ssh_patcher = None self._rpc_patcher = None + self._masterd_patcher = None try: runtime.InitArchInfo() @@ -158,6 +160,9 @@ class CmdlibTestCase(testutils.GanetiTestCase): if self._rpc_patcher is not None: self._rpc_patcher.stop() self._rpc_patcher = None + if self._masterd_patcher is not None: + self._masterd_patcher.stop() + self._masterd_patcher = None def tearDown(self): super(CmdlibTestCase, self).tearDown() @@ -183,6 +188,7 @@ class CmdlibTestCase(testutils.GanetiTestCase): self.rpc = CreateRpcRunnerMock() self.ctx = GanetiContextMock(self) self.mcpu = ProcessorMock(self.ctx) + self.masterd = CreateMasterdMock() self._StopPatchers() try: @@ -215,6 +221,13 @@ class CmdlibTestCase(testutils.GanetiTestCase): # this test module does not use rpc, no patching performed self._rpc_patcher = None + try: + self._masterd_patcher = patchMasterd(self._GetTestModule()) + self.masterd_mod = self._masterd_patcher.start() + except (ImportError, AttributeError): + # this test module does not use masterd, no patching performed + self._masterd_patcher = None + def GetMockLU(self): """Creates a mock L{LogialUnit} with access to the mocked config etc. diff --git a/test/py/cmdlib/testsupport/masterd_mock.py b/test/py/cmdlib/testsupport/masterd_mock.py new file mode 100644 index 0000000..59ba8f5 --- /dev/null +++ b/test/py/cmdlib/testsupport/masterd_mock.py @@ -0,0 +1,59 @@ +# +# + +# Copyright (C) 2014 Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +"""Support for mocking the Masterd""" + + +import mock + +from ganeti import masterd + +from cmdlib.testsupport.util import patchModule + + +# pylint: disable=C0103 +def patchMasterd(module_under_test): + """Patches the L{ganeti.masterd} module for tests. + + This function is meant to be used as a decorator for test methods. + + @type module_under_test: string + @param module_under_test: the module within cmdlib which is tested. The + "ganeti.cmdlib" prefix is optional. + + """ + return patchModule(module_under_test, "masterd", wraps=masterd) + + +def CreateMasterdMock(): + """Creates a new L{mock.MagicMock} tailored for the L{masterd} module. + + """ + return mock.MagicMock(spec=masterd) -- 2.1.0.rc2.206.gedb03e5
