def testStrangeHostnameResolve(self):
op = self.CopyOpCode(self.diskless_op)
self.netutils_mod.GetHostname.return_value = \
- HostnameMock("random.host.com", "1.2.3.4")
+ HostnameMock("random.host.example.com", "203.0.113.1")
self.ExecOpCodeExpectOpPrereqError(
op, "Resolved hostname .* does not look the same as given hostname")
def testValidIp(self):
op = self.CopyOpCode(self.diskless_op,
nics=[{
- constants.INIC_IP: "1.2.3.4"
+ constants.INIC_IP: "203.0.113.1"
}])
self.ExecOpCode(op)
def testIpNotInNetwork(self):
op = self.CopyOpCode(self.diskless_op,
nics=[{
- constants.INIC_IP: "1.2.3.4",
+ constants.INIC_IP: "203.0.113.1",
constants.INIC_NETWORK: self.net.name
}])
self.ExecOpCodeExpectOpPrereqError(
nic0_mode=bridged
nic0_link=br_mock
nic0_mac=f6:ab:f4:45:d1:af
-nic0_ip=123.123.123.1
+nic0_ip=192.0.2.1
tags=tag1 tag2
hypervisor=xen-hvm
[hypervisor]
}]
result = self._TestTrivialDisk(constants.DT_PLAIN, disk_info, 3,
- constants.LD_LV)
+ constants.DT_PLAIN)
self.assertEqual(map(operator.attrgetter("logical_id"), result), [
("xenvg", "ec1-uq0.disk3"),
self.cluster.enabled_disk_templates = [disk_template]
result = self._TestTrivialDisk(
- disk_template, disk_info, 2, constants.LD_FILE,
+ disk_template, disk_info, 2, disk_template,
file_storage_dir="/tmp", file_driver=constants.FD_BLKTAP)
self.assertEqual(map(operator.attrgetter("logical_id"), result), [
}]
result = self._TestTrivialDisk(constants.DT_BLOCK, disk_info, 10,
- constants.LD_BLOCKDEV)
+ constants.DT_BLOCK)
self.assertEqual(map(operator.attrgetter("logical_id"), result), [
(constants.BLOCKDEV_DRIVER_MANUAL, "/tmp/some/block/dev"),
}]
result = self._TestTrivialDisk(constants.DT_RBD, disk_info, 0,
- constants.LD_RBD)
+ constants.DT_RBD)
self.assertEqual(map(operator.attrgetter("logical_id"), result), [
("rbd", "ec1-uq0.rbd.disk0"),
def testDrbd8(self):
gdt = instance.GenerateDiskTemplate
- drbd8_defaults = constants.DISK_LD_DEFAULTS[constants.LD_DRBD8]
+ drbd8_defaults = constants.DISK_LD_DEFAULTS[constants.DT_DRBD8]
drbd8_default_metavg = drbd8_defaults[constants.LDP_DEFAULT_METAVG]
disk_info = [{
for (idx, disk) in enumerate(result):
self.assertTrue(isinstance(disk, objects.Disk))
- self.assertEqual(disk.dev_type, constants.LD_DRBD8)
+ self.assertEqual(disk.dev_type, constants.DT_DRBD8)
self.assertEqual(disk.size, disk_info[idx][constants.IDISK_SIZE])
self.assertEqual(disk.mode, disk_info[idx][constants.IDISK_MODE])
for child in disk.children:
self.assertTrue(isinstance(disk, objects.Disk))
- self.assertEqual(child.dev_type, constants.LD_LV)
+ self.assertEqual(child.dev_type, constants.DT_PLAIN)
self.assertTrue(child.children is None)
self.assertEqual(map(operator.attrgetter("logical_id"), disk.children),
def __init__(self, exp_node_uuid):
self._exp_node_uuid = exp_node_uuid
- def SetDiskID(self, device, node_uuid):
- assert isinstance(device, objects.Disk)
- assert node_uuid == self._exp_node_uuid
-
def GetNodeName(self, node_uuid):
assert node_uuid == self._exp_node_uuid
return "name.of.expected.node"
cfg=_ConfigForDiskWipe(node_name))
disks = [
- objects.Disk(dev_type=constants.LD_LV),
- objects.Disk(dev_type=constants.LD_LV),
- objects.Disk(dev_type=constants.LD_LV),
+ objects.Disk(dev_type=constants.DT_PLAIN),
+ objects.Disk(dev_type=constants.DT_PLAIN),
+ objects.Disk(dev_type=constants.DT_PLAIN),
]
inst = objects.Instance(name="inst21201",
cfg=_ConfigForDiskWipe(node_uuid))
disks = [
- objects.Disk(dev_type=constants.LD_LV, logical_id="disk0",
+ objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk0",
size=100 * 1024),
- objects.Disk(dev_type=constants.LD_LV, logical_id="disk1",
+ objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk1",
size=500 * 1024),
- objects.Disk(dev_type=constants.LD_LV, logical_id="disk2", size=256),
+ objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk2", size=256),
]
inst = objects.Instance(name="inst562",
def testNormalWipe(self):
disks = [
- objects.Disk(dev_type=constants.LD_LV, logical_id="disk0", size=1024),
- objects.Disk(dev_type=constants.LD_LV, logical_id="disk1",
+ objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk0", size=1024),
+ objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk1",
size=500 * 1024),
- objects.Disk(dev_type=constants.LD_LV, logical_id="disk2", size=128),
- objects.Disk(dev_type=constants.LD_LV, logical_id="disk3",
+ objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk2", size=128),
+ objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk3",
size=constants.MAX_WIPE_CHUNK),
]
def testWipeWithStartOffset(self):
for start_offset in [0, 280, 8895, 1563204]:
disks = [
- objects.Disk(dev_type=constants.LD_LV, logical_id="disk0",
+ objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk0",
size=128),
- objects.Disk(dev_type=constants.LD_LV, logical_id="disk1",
+ objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk1",
size=start_offset + (100 * 1024)),
]
op, "Can't compute nodes using iallocator")
+class TestLUInstanceSetParams(CmdlibTestCase):
+ def setUp(self):
+ super(TestLUInstanceSetParams, self).setUp()
+
+ self.inst = self.cfg.AddNewInstance()
+ self.op = opcodes.OpInstanceSetParams(instance_name=self.inst.name)
+
+ self.running_inst = \
+ self.cfg.AddNewInstance(admin_state=constants.ADMINST_UP)
+ self.running_op = \
+ opcodes.OpInstanceSetParams(instance_name=self.running_inst.name)
+
+ self.snode = self.cfg.AddNewNode()
+
+ self.mocked_storage_type = constants.ST_LVM_VG
+ self.mocked_storage_free = 10000
+ self.mocked_master_cpu_total = 16
+ self.mocked_master_memory_free = 2048
+ self.mocked_snode_cpu_total = 16
+ self.mocked_snode_memory_free = 512
+
+ self.mocked_running_inst_memory = 1024
+ self.mocked_running_inst_vcpus = 8
+ self.mocked_running_inst_state = "running"
+ self.mocked_running_inst_time = 10938474
+
+ bootid = "mock_bootid"
+ storage_info = [
+ {
+ "type": self.mocked_storage_type,
+ "storage_free": self.mocked_storage_free
+ }
+ ]
+ hv_info_master = {
+ "cpu_total": self.mocked_master_cpu_total,
+ "memory_free": self.mocked_master_memory_free
+ }
+ hv_info_snode = {
+ "cpu_total": self.mocked_snode_cpu_total,
+ "memory_free": self.mocked_snode_memory_free
+ }
+
+ self.rpc.call_node_info.return_value = \
+ self.RpcResultsBuilder() \
+ .AddSuccessfulNode(self.master,
+ (bootid, storage_info, (hv_info_master, ))) \
+ .AddSuccessfulNode(self.snode,
+ (bootid, storage_info, (hv_info_snode, ))) \
+ .Build()
+
+ def _InstanceInfo(_, instance, __, ___):
+ if instance == self.inst.name:
+ return self.RpcResultsBuilder() \
+ .CreateSuccessfulNodeResult(self.master, None)
+ elif instance == self.running_inst.name:
+ return self.RpcResultsBuilder() \
+ .CreateSuccessfulNodeResult(
+ self.master, {
+ "memory": self.mocked_running_inst_memory,
+ "vcpus": self.mocked_running_inst_vcpus,
+ "state": self.mocked_running_inst_state,
+ "time": self.mocked_running_inst_time
+ })
+ else:
+ raise AssertionError()
+ self.rpc.call_instance_info.side_effect = _InstanceInfo
+
+ self.rpc.call_bridges_exist.return_value = \
+ self.RpcResultsBuilder() \
+ .CreateSuccessfulNodeResult(self.master, True)
+
+ self.rpc.call_blockdev_getmirrorstatus.side_effect = \
+ lambda node, _: self.RpcResultsBuilder() \
+ .CreateSuccessfulNodeResult(node, [])
+
+ self.rpc.call_blockdev_shutdown.side_effect = \
+ lambda node, _: self.RpcResultsBuilder() \
+ .CreateSuccessfulNodeResult(node, [])
+
+ def testNoChanges(self):
+ op = self.CopyOpCode(self.op)
+ self.ExecOpCodeExpectOpPrereqError(op, "No changes submitted")
+
+ def testGlobalHvparams(self):
+ op = self.CopyOpCode(self.op,
+ hvparams={constants.HV_MIGRATION_PORT: 1234})
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "hypervisor parameters are global and cannot be customized")
+
+ def testHvparams(self):
+ op = self.CopyOpCode(self.op,
+ hvparams={constants.HV_BOOT_ORDER: "cd"})
+ self.ExecOpCode(op)
+
+ def testDisksAndDiskTemplate(self):
+ op = self.CopyOpCode(self.op,
+ disk_template=constants.DT_PLAIN,
+ disks=[[constants.DDM_ADD, -1, {}]])
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Disk template conversion and other disk changes not supported at"
+ " the same time")
+
+ def testDiskTemplateToMirroredNoRemoteNode(self):
+ op = self.CopyOpCode(self.op,
+ disk_template=constants.DT_DRBD8)
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Changing the disk template to a mirrored one requires specifying"
+ " a secondary node")
+
+ def testPrimaryNodeToOldPrimaryNode(self):
+ op = self.CopyOpCode(self.op,
+ pnode=self.master.name)
+ self.ExecOpCode(op)
+
+ def testPrimaryNodeChange(self):
+ node = self.cfg.AddNewNode()
+ op = self.CopyOpCode(self.op,
+ pnode=node.name)
+ self.ExecOpCode(op)
+
+ def testPrimaryNodeChangeRunningInstance(self):
+ node = self.cfg.AddNewNode()
+ op = self.CopyOpCode(self.running_op,
+ pnode=node.name)
+ self.ExecOpCodeExpectOpPrereqError(op, "Instance is still running")
+
+ def testOsChange(self):
+ os = self.cfg.CreateOs(supported_variants=[])
+ self.rpc.call_os_get.return_value = \
+ self.RpcResultsBuilder() \
+ .CreateSuccessfulNodeResult(self.master, os)
+ op = self.CopyOpCode(self.op,
+ os_name=os.name)
+ self.ExecOpCode(op)
+
+ def testVCpuChange(self):
+ op = self.CopyOpCode(self.op,
+ beparams={
+ constants.BE_VCPUS: 4
+ })
+ self.ExecOpCode(op)
+
+ def testWrongCpuMask(self):
+ op = self.CopyOpCode(self.op,
+ beparams={
+ constants.BE_VCPUS: 4
+ },
+ hvparams={
+ constants.HV_CPU_MASK: "1,2:3,4"
+ })
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Number of vCPUs .* does not match the CPU mask .*")
+
+ def testCorrectCpuMask(self):
+ op = self.CopyOpCode(self.op,
+ beparams={
+ constants.BE_VCPUS: 4
+ },
+ hvparams={
+ constants.HV_CPU_MASK: "1,2:3,4:all:1,4"
+ })
+ self.ExecOpCode(op)
+
+ def testOsParams(self):
+ op = self.CopyOpCode(self.op,
+ osparams={
+ self.os.supported_parameters[0]: "test_param_val"
+ })
+ self.ExecOpCode(op)
+
+ def testIncreaseMemoryTooMuch(self):
+ op = self.CopyOpCode(self.running_op,
+ beparams={
+ constants.BE_MAXMEM:
+ self.mocked_master_memory_free * 2
+ })
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "This change will prevent the instance from starting")
+
+ def testIncreaseMemory(self):
+ op = self.CopyOpCode(self.running_op,
+ beparams={
+ constants.BE_MAXMEM: self.mocked_master_memory_free
+ })
+ self.ExecOpCode(op)
+
+ def testIncreaseMemoryTooMuchForSecondary(self):
+ inst = self.cfg.AddNewInstance(admin_state=constants.ADMINST_UP,
+ disk_template=constants.DT_DRBD8,
+ secondary_node=self.snode)
+ self.rpc.call_instance_info.side_effect = [
+ self.RpcResultsBuilder()
+ .CreateSuccessfulNodeResult(self.master,
+ {
+ "memory":
+ self.mocked_snode_memory_free * 2,
+ "vcpus": self.mocked_running_inst_vcpus,
+ "state": self.mocked_running_inst_state,
+ "time": self.mocked_running_inst_time
+ })]
+
+ op = self.CopyOpCode(self.op,
+ instance_name=inst.name,
+ beparams={
+ constants.BE_MAXMEM:
+ self.mocked_snode_memory_free * 2,
+ constants.BE_AUTO_BALANCE: True
+ })
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "This change will prevent the instance from failover to its"
+ " secondary node")
+
+ def testInvalidRuntimeMemory(self):
+ op = self.CopyOpCode(self.running_op,
+ runtime_mem=self.mocked_master_memory_free * 2)
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Instance .* must have memory between .* and .* of memory")
+
+ def testIncreaseRuntimeMemory(self):
+ op = self.CopyOpCode(self.running_op,
+ runtime_mem=self.mocked_master_memory_free,
+ beparams={
+ constants.BE_MAXMEM: self.mocked_master_memory_free
+ })
+ self.ExecOpCode(op)
+
+ def testAddNicWithPoolIpNoNetwork(self):
+ op = self.CopyOpCode(self.op,
+ nics=[(constants.DDM_ADD, -1,
+ {
+ constants.INIC_IP: constants.NIC_IP_POOL
+ })])
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "If ip=pool, parameter network cannot be none")
+
+ def testAddNicWithPoolIp(self):
+ net = self.cfg.AddNewNetwork()
+ self.cfg.ConnectNetworkToGroup(net, self.group)
+ op = self.CopyOpCode(self.op,
+ nics=[(constants.DDM_ADD, -1,
+ {
+ constants.INIC_IP: constants.NIC_IP_POOL,
+ constants.INIC_NETWORK: net.name
+ })])
+ self.ExecOpCode(op)
+
+ def testAddNicWithInvalidIp(self):
+ op = self.CopyOpCode(self.op,
+ nics=[(constants.DDM_ADD, -1,
+ {
+ constants.INIC_IP: "invalid"
+ })])
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Invalid IP address")
+
+ def testAddNic(self):
+ op = self.CopyOpCode(self.op,
+ nics=[(constants.DDM_ADD, -1, {})])
+ self.ExecOpCode(op)
+
+ def testAddNicWithIp(self):
+ op = self.CopyOpCode(self.op,
+ nics=[(constants.DDM_ADD, -1,
+ {
+ constants.INIC_IP: "2.3.1.4"
+ })])
+ self.ExecOpCode(op)
+
+ def testModifyNicRoutedWithoutIp(self):
+ op = self.CopyOpCode(self.op,
+ nics=[(constants.DDM_MODIFY, 0,
+ {
+ constants.INIC_MODE: constants.NIC_MODE_ROUTED
+ })])
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Cannot set the NIC IP address to None on a routed NIC")
+
+ def testModifyNicSetMac(self):
+ op = self.CopyOpCode(self.op,
+ nics=[(constants.DDM_MODIFY, 0,
+ {
+ constants.INIC_MAC: "0a:12:95:15:bf:75"
+ })])
+ self.ExecOpCode(op)
+
+ def testModifyNicWithPoolIpNoNetwork(self):
+ op = self.CopyOpCode(self.op,
+ nics=[(constants.DDM_MODIFY, -1,
+ {
+ constants.INIC_IP: constants.NIC_IP_POOL
+ })])
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "ip=pool, but no network found")
+
+ def testModifyNicSetNet(self):
+ old_net = self.cfg.AddNewNetwork()
+ self.cfg.ConnectNetworkToGroup(old_net, self.group)
+ inst = self.cfg.AddNewInstance(nics=[
+ self.cfg.CreateNic(network=old_net,
+ ip="198.51.100.2")])
+
+ new_net = self.cfg.AddNewNetwork(mac_prefix="be")
+ self.cfg.ConnectNetworkToGroup(new_net, self.group)
+ op = self.CopyOpCode(self.op,
+ instance_name=inst.name,
+ nics=[(constants.DDM_MODIFY, 0,
+ {
+ constants.INIC_NETWORK: new_net.name
+ })])
+ self.ExecOpCode(op)
+
+ def testModifyNicSetLinkWhileConnected(self):
+ old_net = self.cfg.AddNewNetwork()
+ self.cfg.ConnectNetworkToGroup(old_net, self.group)
+ inst = self.cfg.AddNewInstance(nics=[
+ self.cfg.CreateNic(network=old_net)])
+
+ op = self.CopyOpCode(self.op,
+ instance_name=inst.name,
+ nics=[(constants.DDM_MODIFY, 0,
+ {
+ constants.INIC_LINK: "mock_link"
+ })])
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Not allowed to change link or mode of a NIC that is connected"
+ " to a network")
+
+ def testModifyNicSetNetAndIp(self):
+ net = self.cfg.AddNewNetwork(mac_prefix="be", network="123.123.123.0/24")
+ self.cfg.ConnectNetworkToGroup(net, self.group)
+ op = self.CopyOpCode(self.op,
+ nics=[(constants.DDM_MODIFY, 0,
+ {
+ constants.INIC_NETWORK: net.name,
+ constants.INIC_IP: "123.123.123.1"
+ })])
+ self.ExecOpCode(op)
+
+ def testModifyNic(self):
+ op = self.CopyOpCode(self.op,
+ nics=[(constants.DDM_MODIFY, 0, {})])
+ self.ExecOpCode(op)
+
+ def testRemoveLastNic(self):
+ op = self.CopyOpCode(self.op,
+ nics=[(constants.DDM_REMOVE, 0, {})])
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "violates policy")
+
+ def testRemoveNic(self):
+ inst = self.cfg.AddNewInstance(nics=[self.cfg.CreateNic(),
+ self.cfg.CreateNic()])
+ op = self.CopyOpCode(self.op,
+ instance_name=inst.name,
+ nics=[(constants.DDM_REMOVE, 0, {})])
+ self.ExecOpCode(op)
+
+ def testSetOffline(self):
+ op = self.CopyOpCode(self.op,
+ offline=True)
+ self.ExecOpCode(op)
+
+ def testUnsetOffline(self):
+ op = self.CopyOpCode(self.op,
+ offline=False)
+ self.ExecOpCode(op)
+
+ def testAddDiskInvalidMode(self):
+ op = self.CopyOpCode(self.op,
+ disks=[[constants.DDM_ADD, -1,
+ {
+ constants.IDISK_MODE: "invalid"
+ }]])
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Invalid disk access mode 'invalid'")
+
+ def testAddDiskMissingSize(self):
+ op = self.CopyOpCode(self.op,
+ disks=[[constants.DDM_ADD, -1, {}]])
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Required disk parameter 'size' missing")
+
+ def testAddDiskInvalidSize(self):
+ op = self.CopyOpCode(self.op,
+ disks=[[constants.DDM_ADD, -1,
+ {
+ constants.IDISK_SIZE: "invalid"
+ }]])
+ self.ExecOpCodeExpectException(
+ op, errors.TypeEnforcementError, "is not a valid size")
+
+ def testAddDiskRunningInstanceNoWaitForSync(self):
+ op = self.CopyOpCode(self.running_op,
+ disks=[[constants.DDM_ADD, -1,
+ {
+ constants.IDISK_SIZE: 1024
+ }]],
+ wait_for_sync=False)
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Can't add a disk to an instance with activated disks"
+ " and --no-wait-for-sync given.")
+
+ def testAddDiskDownInstance(self):
+ op = self.CopyOpCode(self.op,
+ disks=[[constants.DDM_ADD, -1,
+ {
+ constants.IDISK_SIZE: 1024
+ }]])
+ self.ExecOpCode(op)
+
+ self.assertTrue(self.rpc.call_blockdev_shutdown.called)
+
+ def testAddDiskRunningInstance(self):
+ op = self.CopyOpCode(self.running_op,
+ disks=[[constants.DDM_ADD, -1,
+ {
+ constants.IDISK_SIZE: 1024
+ }]])
+ self.ExecOpCode(op)
+
+ self.assertFalse(self.rpc.call_blockdev_shutdown.called)
+
+ def testAddDiskNoneName(self):
+ op = self.CopyOpCode(self.op,
+ disks=[[constants.DDM_ADD, -1,
+ {
+ constants.IDISK_SIZE: 1024,
+ constants.IDISK_NAME: constants.VALUE_NONE
+ }]])
+ self.ExecOpCode(op)
+
+ def testModifyDiskWithSize(self):
+ op = self.CopyOpCode(self.op,
+ disks=[[constants.DDM_MODIFY, 0,
+ {
+ constants.IDISK_SIZE: 1024
+ }]])
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Disk size change not possible, use grow-disk")
+
+ def testModifyDiskWithRandomParams(self):
+ op = self.CopyOpCode(self.op,
+ disks=[[constants.DDM_MODIFY, 0,
+ {
+ constants.IDISK_METAVG: "new_meta_vg",
+ constants.IDISK_MODE: "invalid",
+ constants.IDISK_NAME: "new_name"
+ }]])
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Disk modification doesn't support additional arbitrary parameters")
+
+ def testModifyDiskUnsetName(self):
+ op = self.CopyOpCode(self.op,
+ disks=[[constants.DDM_MODIFY, 0,
+ {
+ constants.IDISK_NAME: constants.VALUE_NONE
+ }]])
+ self.ExecOpCode(op)
+
+ def testSetOldDiskTemplate(self):
+ op = self.CopyOpCode(self.op,
+ disk_template=self.inst.disk_template)
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Instance already has disk template")
+
+ def testSetDisabledDiskTemplate(self):
+ self.cfg.SetEnabledDiskTemplates([self.inst.disk_template])
+ op = self.CopyOpCode(self.op,
+ disk_template=constants.DT_EXT)
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Disk template .* is not enabled for this cluster")
+
+ def testInvalidDiskTemplateConversion(self):
+ op = self.CopyOpCode(self.op,
+ disk_template=constants.DT_EXT)
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Unsupported disk template conversion from .* to .*")
+
+ def testConvertToDRBDWithSecondarySameAsPrimary(self):
+ op = self.CopyOpCode(self.op,
+ disk_template=constants.DT_DRBD8,
+ remote_node=self.master.name)
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Given new secondary node .* is the same as the primary node"
+ " of the instance")
+
+ def testConvertPlainToDRBD(self):
+ self.rpc.call_blockdev_shutdown.return_value = \
+ self.RpcResultsBuilder() \
+ .CreateSuccessfulNodeResult(self.master, True)
+ self.rpc.call_blockdev_getmirrorstatus.return_value = \
+ self.RpcResultsBuilder() \
+ .CreateSuccessfulNodeResult(self.master, [objects.BlockDevStatus()])
+
+ op = self.CopyOpCode(self.op,
+ disk_template=constants.DT_DRBD8,
+ remote_node=self.snode.name)
+ self.ExecOpCode(op)
+
+ def testConvertDRBDToPlain(self):
+ self.inst.disks = [self.cfg.CreateDisk(dev_type=constants.DT_DRBD8,
+ primary_node=self.master,
+ secondary_node=self.snode)]
+ self.inst.disk_template = constants.DT_DRBD8
+ self.rpc.call_blockdev_shutdown.return_value = \
+ self.RpcResultsBuilder() \
+ .CreateSuccessfulNodeResult(self.master, True)
+ self.rpc.call_blockdev_remove.return_value = \
+ self.RpcResultsBuilder() \
+ .CreateSuccessfulNodeResult(self.master)
+ self.rpc.call_blockdev_getmirrorstatus.return_value = \
+ self.RpcResultsBuilder() \
+ .CreateSuccessfulNodeResult(self.master, [objects.BlockDevStatus()])
+
+ op = self.CopyOpCode(self.op,
+ disk_template=constants.DT_PLAIN)
+ self.ExecOpCode(op)
+
+
+class TestLUInstanceChangeGroup(CmdlibTestCase):
+ def setUp(self):
+ super(TestLUInstanceChangeGroup, self).setUp()
+
+ self.group2 = self.cfg.AddNewNodeGroup()
+ self.node2 = self.cfg.AddNewNode(group=self.group2)
+ self.inst = self.cfg.AddNewInstance()
+ self.op = opcodes.OpInstanceChangeGroup(instance_name=self.inst.name)
+
+ def testTargetGroupIsInstanceGroup(self):
+ op = self.CopyOpCode(self.op,
+ target_groups=[self.group.name])
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Can't use group\(s\) .* as targets, they are used by the"
+ " instance .*")
+
+ def testNoTargetGroups(self):
+ inst = self.cfg.AddNewInstance(disk_template=constants.DT_DRBD8,
+ primary_node=self.master,
+ secondary_node=self.node2)
+ op = self.CopyOpCode(self.op,
+ instance_name=inst.name)
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "There are no possible target groups")
+
+ def testFailingIAllocator(self):
+ self.iallocator_cls.return_value.success = False
+ op = self.CopyOpCode(self.op)
+
+ self.ExecOpCodeExpectOpPrereqError(
+ op, "Can't compute solution for changing group of instance .*"
+ " using iallocator .*")
+
+ def testChangeGroup(self):
+ self.iallocator_cls.return_value.success = True
+ self.iallocator_cls.return_value.result = ([], [], [])
+ op = self.CopyOpCode(self.op)
+
+ self.ExecOpCode(op)
+
+
if __name__ == "__main__":
testutils.GanetiTestProgram()