#!/usr/bin/python
#

# Copyright (C) 2008, 2011, 2012, 2013 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.


"""Tests for LUInstance*

"""

import copy
import itertools
import re
import unittest
import mock
import operator
import os

from ganeti import backend
from ganeti import compat
from ganeti import config
from ganeti import constants
from ganeti import errors
from ganeti import ht
from ganeti import opcodes
from ganeti import objects
from ganeti.rpc import node as rpc
from ganeti import utils
from ganeti.cmdlib import instance
from ganeti.cmdlib import instance_storage
from ganeti.cmdlib import instance_create
from ganeti.cmdlib import instance_set_params
from ganeti.cmdlib import instance_utils

from cmdlib.cmdlib_unittest import _FakeLU

from testsupport import *

import testutils
from testutils.config_mock import _UpdateIvNames


class TestComputeIPolicyInstanceSpecViolation(unittest.TestCase):
  def setUp(self):
    self.ispec = {
      constants.ISPEC_MEM_SIZE: 2048,
      constants.ISPEC_CPU_COUNT: 2,
      constants.ISPEC_DISK_COUNT: 1,
      constants.ISPEC_DISK_SIZE: [512],
      constants.ISPEC_NIC_COUNT: 0,
      constants.ISPEC_SPINDLE_USE: 1,
      }
    self.stub = mock.MagicMock()
    self.stub.return_value = []

  def testPassThrough(self):
    ret = instance_utils.ComputeIPolicyInstanceSpecViolation(
        NotImplemented, self.ispec, [constants.DT_PLAIN], _compute_fn=self.stub)
    self.assertEqual(ret, [])
    self.stub.assert_called_with(NotImplemented, 2048, 2, 1, 0, [512],
                                 1, [constants.DT_PLAIN])


class TestLUInstanceCreate(CmdlibTestCase):
  def _setupOSDiagnose(self):
    os_result = [(self.os.name,
                  self.os.path,
                  True,
                  "",
                  self.os.supported_variants,
                  self.os.supported_parameters,
                  self.os.api_versions,
                  True)]
    self.rpc.call_os_diagnose.return_value = \
      self.RpcResultsBuilder() \
        .AddSuccessfulNode(self.master, os_result) \
        .AddSuccessfulNode(self.node1, os_result) \
        .AddSuccessfulNode(self.node2, os_result) \
        .Build()

  def setUp(self):
    super(TestLUInstanceCreate, self).setUp()
    self.ResetMocks()

    self.MockOut(instance_create, 'netutils', self.netutils_mod)
    self.MockOut(instance_utils, 'netutils', self.netutils_mod)

    self.net = self.cfg.AddNewNetwork()
    self.cfg.ConnectNetworkToGroup(self.net, self.group)

    self.node1 = self.cfg.AddNewNode()
    self.node2 = self.cfg.AddNewNode()

    hv_info = ("bootid",
               [{
                 "type": constants.ST_LVM_VG,
                 "storage_free": 10000
               }],
               ({"memory_free": 10000}, ))
    self.rpc.call_node_info.return_value = \
      self.RpcResultsBuilder() \
        .AddSuccessfulNode(self.master, hv_info) \
        .AddSuccessfulNode(self.node1, hv_info) \
        .AddSuccessfulNode(self.node2, hv_info) \
        .Build()

    self._setupOSDiagnose()

    self.rpc.call_blockdev_getmirrorstatus.side_effect = \
      lambda node, _: self.RpcResultsBuilder() \
                        .CreateSuccessfulNodeResult(node, [])

    self.iallocator_cls.return_value.result = [self.node1.name, self.node2.name]

    self.diskless_op = opcodes.OpInstanceCreate(
      instance_name="diskless.example.com",
      pnode=self.master.name,
      disk_template=constants.DT_DISKLESS,
      mode=constants.INSTANCE_CREATE,
      nics=[{}],
      disks=[],
      os_type=self.os_name_variant)

    self.plain_op = opcodes.OpInstanceCreate(
      instance_name="plain.example.com",
      pnode=self.master.name,
      disk_template=constants.DT_PLAIN,
      mode=constants.INSTANCE_CREATE,
      nics=[{}],
      disks=[{
        constants.IDISK_SIZE: 1024
      }],
      os_type=self.os_name_variant)

    self.block_op = opcodes.OpInstanceCreate(
      instance_name="block.example.com",
      pnode=self.master.name,
      disk_template=constants.DT_BLOCK,
      mode=constants.INSTANCE_CREATE,
      nics=[{}],
      disks=[{
        constants.IDISK_SIZE: 1024,
        constants.IDISK_ADOPT: "/dev/disk/block0"
      }],
      os_type=self.os_name_variant)

    self.drbd_op = opcodes.OpInstanceCreate(
      instance_name="drbd.example.com",
      pnode=self.node1.name,
      snode=self.node2.name,
      disk_template=constants.DT_DRBD8,
      mode=constants.INSTANCE_CREATE,
      nics=[{}],
      disks=[{
        constants.IDISK_SIZE: 1024
      }],
      os_type=self.os_name_variant)

    self.file_op = opcodes.OpInstanceCreate(
      instance_name="file.example.com",
      pnode=self.node1.name,
      disk_template=constants.DT_FILE,
      mode=constants.INSTANCE_CREATE,
      nics=[{}],
      disks=[{
        constants.IDISK_SIZE: 1024
      }],
      os_type=self.os_name_variant)

    self.shared_file_op = opcodes.OpInstanceCreate(
      instance_name="shared-file.example.com",
      pnode=self.node1.name,
      disk_template=constants.DT_SHARED_FILE,
      mode=constants.INSTANCE_CREATE,
      nics=[{}],
      disks=[{
        constants.IDISK_SIZE: 1024
      }],
      os_type=self.os_name_variant)

    self.gluster_op = opcodes.OpInstanceCreate(
      instance_name="gluster.example.com",
      pnode=self.node1.name,
      disk_template=constants.DT_GLUSTER,
      mode=constants.INSTANCE_CREATE,
      nics=[{}],
      disks=[{
        constants.IDISK_SIZE: 1024
      }],
      os_type=self.os_name_variant)

    self.rbd_op = opcodes.OpInstanceCreate(
      instance_name="gluster.example.com",
      pnode=self.node1.name,
      disk_template=constants.DT_RBD,
      mode=constants.INSTANCE_CREATE,
      nics=[{}],
      disks=[{
        constants.IDISK_SIZE: 1024
      }],
      os_type=self.os_name_variant)

  def testSimpleCreate(self):
    op = self.CopyOpCode(self.diskless_op)
    self.ExecOpCode(op)

  def testStrangeHostnameResolve(self):
    op = self.CopyOpCode(self.diskless_op)
    self.netutils_mod.GetHostname.return_value = \
      HostnameMock("random.host.example.com", "203.0.113.1")
    self.ExecOpCodeExpectOpPrereqError(
      op, "Resolved hostname .* does not look the same as given hostname")

  def testOpportunisticLockingNoIAllocator(self):
    op = self.CopyOpCode(self.diskless_op,
                         opportunistic_locking=True,
                         iallocator=None)
    self.ExecOpCodeExpectOpPrereqError(
      op, "Opportunistic locking is only available in combination with an"
          " instance allocator")

  def testNicWithNetAndMode(self):
    op = self.CopyOpCode(self.diskless_op,
                         nics=[{
                           constants.INIC_NETWORK: self.net.name,
                           constants.INIC_MODE: constants.NIC_MODE_BRIDGED
                         }])
    self.ExecOpCodeExpectOpPrereqError(
      op, "If network is given, no mode or link is allowed to be passed")

  def testAutoIpNoNameCheck(self):
    op = self.CopyOpCode(self.diskless_op,
                         nics=[{
                           constants.INIC_IP: constants.VALUE_AUTO
                         }],
                         ip_check=False,
                         name_check=False)
    self.ExecOpCodeExpectOpPrereqError(
      op, "IP address set to auto but name checks have been skipped")

  def testAutoIp(self):
    op = self.CopyOpCode(self.diskless_op,
                         nics=[{
                           constants.INIC_IP: constants.VALUE_AUTO
                         }])
    self.ExecOpCode(op)

  def testPoolIpNoNetwork(self):
    op = self.CopyOpCode(self.diskless_op,
                         nics=[{
                           constants.INIC_IP: constants.NIC_IP_POOL
                         }])
    self.ExecOpCodeExpectOpPrereqError(
      op, "if ip=pool, parameter network must be passed too")

  def testValidIp(self):
    op = self.CopyOpCode(self.diskless_op,
                         nics=[{
                           constants.INIC_IP: "203.0.113.1"
                         }])
    self.ExecOpCode(op)

  def testRoutedNoIp(self):
    op = self.CopyOpCode(self.diskless_op,
                         nics=[{
                           constants.INIC_NETWORK: constants.VALUE_NONE,
                           constants.INIC_MODE: constants.NIC_MODE_ROUTED
                         }])
    self.ExecOpCodeExpectOpPrereqError(
      op, "Routed nic mode requires an ip address"
      " if not attached to a network")

  def testValicMac(self):
    op = self.CopyOpCode(self.diskless_op,
                         nics=[{
                           constants.INIC_MAC: "f0:df:f4:a3:d1:cf"
                         }])
    self.ExecOpCode(op)

  def testValidNicParams(self):
    op = self.CopyOpCode(self.diskless_op,
                         nics=[{
                           constants.INIC_MODE: constants.NIC_MODE_BRIDGED,
                           constants.INIC_LINK: "br_mock"
                         }])
    self.ExecOpCode(op)

  def testValidNicParamsOpenVSwitch(self):
    op = self.CopyOpCode(self.diskless_op,
                         nics=[{
                           constants.INIC_MODE: constants.NIC_MODE_OVS,
                           constants.INIC_VLAN: "1"
                         }])
    self.ExecOpCode(op)

  def testNicNoneName(self):
    op = self.CopyOpCode(self.diskless_op,
                         nics=[{
                           constants.INIC_NAME: constants.VALUE_NONE
                         }])
    self.ExecOpCode(op)

  def testConflictingIP(self):
    op = self.CopyOpCode(self.diskless_op,
                         nics=[{
                           constants.INIC_IP: self.net.gateway[:-1] + "2"
                         }])
    self.ExecOpCodeExpectOpPrereqError(
      op, "The requested IP address .* belongs to network .*, but the target"
          " NIC does not.")

  def testVLanFormat(self):
    for vlan in [".pinky", ":bunny", ":1:pinky", "bunny"]:
      self.ResetMocks()
      op = self.CopyOpCode(self.diskless_op,
                           nics=[{
                             constants.INIC_VLAN: vlan
                           }])
      self.ExecOpCodeExpectOpPrereqError(
        op, "Specified VLAN parameter is invalid")

  def testPoolIp(self):
    op = self.CopyOpCode(self.diskless_op,
                         nics=[{
                           constants.INIC_IP: constants.NIC_IP_POOL,
                           constants.INIC_NETWORK: self.net.name
                         }])
    self.ExecOpCode(op)

  def testPoolIpUnconnectedNetwork(self):
    net = self.cfg.AddNewNetwork()
    op = self.CopyOpCode(self.diskless_op,
                         nics=[{
                           constants.INIC_IP: constants.NIC_IP_POOL,
                           constants.INIC_NETWORK: net.name
                         }])
    self.ExecOpCodeExpectOpPrereqError(
      op, "No netparams found for network .*.")

  def testIpNotInNetwork(self):
    op = self.CopyOpCode(self.diskless_op,
                         nics=[{
                           constants.INIC_IP: "203.0.113.1",
                           constants.INIC_NETWORK: self.net.name
                         }])
    self.ExecOpCodeExpectOpPrereqError(
      op, "IP address .* already in use or does not belong to network .*")

  def testMixAdoptAndNotAdopt(self):
    op = self.CopyOpCode(self.diskless_op,
                         disk_template=constants.DT_PLAIN,
                         disks=[{
                           constants.IDISK_ADOPT: "lv1"
                         }, {}])
    self.ExecOpCodeExpectOpPrereqError(
      op, "Either all disks are adopted or none is")

  def testMustAdoptWithoutAdopt(self):
    op = self.CopyOpCode(self.diskless_op,
                         disk_template=constants.DT_BLOCK,
                         disks=[{}])
    self.ExecOpCodeExpectOpPrereqError(
      op, "Disk template blockdev requires disk adoption, but no 'adopt'"
          " parameter given")

  def testDontAdoptWithAdopt(self):
    op = self.CopyOpCode(self.diskless_op,
                         disk_template=constants.DT_DRBD8,
                         disks=[{
                           constants.IDISK_ADOPT: "lv1"
                         }])
    self.ExecOpCodeExpectOpPrereqError(
      op, "Disk adoption is not supported for the 'drbd' disk template")

  def testAdoptWithIAllocator(self):
    op = self.CopyOpCode(self.diskless_op,
                         disk_template=constants.DT_PLAIN,
                         disks=[{
                           constants.IDISK_ADOPT: "lv1"
                         }],
                         iallocator="mock")
    self.ExecOpCodeExpectOpPrereqError(
      op, "Disk adoption not allowed with an iallocator script")

  def testAdoptWithImport(self):
    op = self.CopyOpCode(self.diskless_op,
                         disk_template=constants.DT_PLAIN,
                         disks=[{
                           constants.IDISK_ADOPT: "lv1"
                         }],
                         mode=constants.INSTANCE_IMPORT)
    self.ExecOpCodeExpectOpPrereqError(
      op, "Disk adoption not allowed for instance import")

  def testArgumentCombinations(self):
    op = self.CopyOpCode(self.diskless_op,
                         # start flag will be flipped
                         no_install=True,
                         start=True,
                         # no allowed combination
                         ip_check=True,
                         name_check=False)
    self.ExecOpCodeExpectOpPrereqError(
      op, "Cannot do IP address check without a name check")

  def testInvalidFileDriver(self):
    op = self.CopyOpCode(self.diskless_op,
                         file_driver="invalid_file_driver")
    self.ExecOpCodeExpectOpPrereqError(
      op, "Parameter 'OP_INSTANCE_CREATE.file_driver' fails validation")

  def testMissingSecondaryNode(self):
    op = self.CopyOpCode(self.diskless_op,
                         pnode=self.master.name,
                         disk_template=constants.DT_DRBD8)
    self.ExecOpCodeExpectOpPrereqError(
      op, "The networked disk templates need a mirror node")

  def testIgnoredSecondaryNode(self):
    op = self.CopyOpCode(self.diskless_op,
                         pnode=self.master.name,
                         snode=self.node1.name,
                         disk_template=constants.DT_PLAIN)
    try:
      self.ExecOpCode(op)
    except Exception:
      pass
    self.mcpu.assertLogContainsRegex(
      "Secondary node will be ignored on non-mirrored disk template")

  def testMissingOsType(self):
    op = self.CopyOpCode(self.diskless_op,
                         os_type=self.REMOVE)
    self.ExecOpCodeExpectOpPrereqError(op, "No guest OS or OS image specified")

  def testBlacklistedOs(self):
    self.cluster.blacklisted_os = [self.os_name_variant]
    op = self.CopyOpCode(self.diskless_op)
    self.ExecOpCodeExpectOpPrereqError(
      op, "Guest OS .* is not allowed for installation")

  def testMissingDiskTemplate(self):
    self.cluster.enabled_disk_templates = [constants.DT_DISKLESS]
    op = self.CopyOpCode(self.diskless_op,
                         disk_template=self.REMOVE)
    self.ExecOpCode(op)

  def testExistingInstance(self):
    inst = self.cfg.AddNewInstance()
    op = self.CopyOpCode(self.diskless_op,
                         instance_name=inst.name)
    self.ExecOpCodeExpectOpPrereqError(
      op, "Instance .* is already in the cluster")

  def testPlainInstance(self):
    op = self.CopyOpCode(self.plain_op)
    self.ExecOpCode(op)

  def testPlainIAllocator(self):
    op = self.CopyOpCode(self.plain_op,
                         pnode=self.REMOVE,
                         iallocator="mock")
    self.ExecOpCode(op)

  def testIAllocatorOpportunisticLocking(self):
    op = self.CopyOpCode(self.plain_op,
                         pnode=self.REMOVE,
                         iallocator="mock",
                         opportunistic_locking=True)
    self.ExecOpCode(op)

  def testFailingIAllocator(self):
    self.iallocator_cls.return_value.success = False
    op = self.CopyOpCode(self.plain_op,
                         pnode=self.REMOVE,
                         iallocator="mock")
    self.ExecOpCodeExpectOpPrereqError(
      op, "Can't compute nodes using iallocator")

  def testDrbdInstance(self):
    op = self.CopyOpCode(self.drbd_op)
    self.ExecOpCode(op)

  def testDrbdIAllocator(self):
    op = self.CopyOpCode(self.drbd_op,
                         pnode=self.REMOVE,
                         snode=self.REMOVE,
                         iallocator="mock")
    self.ExecOpCode(op)

  def testFileInstance(self):
    op = self.CopyOpCode(self.file_op)
    self.ExecOpCode(op)

  def testFileInstanceNoClusterStorage(self):
    self.cluster.file_storage_dir = None
    op = self.CopyOpCode(self.file_op)
    self.ExecOpCodeExpectOpPrereqError(
      op, "Cluster file storage dir for 'file' storage type not defined")

  def testFileInstanceAdditionalPath(self):
    op = self.CopyOpCode(self.file_op,
                         file_storage_dir="mock_dir")
    self.ExecOpCode(op)

  def testIdentifyDefaults(self):
    op = self.CopyOpCode(self.plain_op,
                         hvparams={
                           constants.HV_BOOT_ORDER: "cd"
                         },
                         beparams=constants.BEC_DEFAULTS.copy(),
                         nics=[{
                           constants.NIC_MODE: constants.NIC_MODE_BRIDGED
                         }],
                         osparams={
                           self.os_name_variant: {}
                         },
                         osparams_private={},
                         identify_defaults=True)
    self.ExecOpCode(op)

    inst = self.cfg.GetAllInstancesInfo().values()[0]
    self.assertEqual(0, len(inst.hvparams))
    self.assertEqual(0, len(inst.beparams))
    assert self.os_name_variant not in inst.osparams or \
            len(inst.osparams[self.os_name_variant]) == 0

  def testOfflineNode(self):
    self.node1.offline = True
    op = self.CopyOpCode(self.diskless_op,
                         pnode=self.node1.name)
    self.ExecOpCodeExpectOpPrereqError(op, "Cannot use offline primary node")

  def testDrainedNode(self):
    self.node1.drained = True
    op = self.CopyOpCode(self.diskless_op,
                         pnode=self.node1.name)
    self.ExecOpCodeExpectOpPrereqError(op, "Cannot use drained primary node")

  def testNonVmCapableNode(self):
    self.node1.vm_capable = False
    op = self.CopyOpCode(self.diskless_op,
                         pnode=self.node1.name)
    self.ExecOpCodeExpectOpPrereqError(
      op, "Cannot use non-vm_capable primary node")

  def testNonEnabledHypervisor(self):
    self.cluster.enabled_hypervisors = [constants.HT_XEN_HVM]
    op = self.CopyOpCode(self.diskless_op,
                         hypervisor=constants.HT_FAKE)
    self.ExecOpCodeExpectOpPrereqError(
      op, "Selected hypervisor .* not enabled in the cluster")

  def testAddTag(self):
    op = self.CopyOpCode(self.diskless_op,
                         tags=["tag"])
    self.ExecOpCode(op)

  def testInvalidTag(self):
    op = self.CopyOpCode(self.diskless_op,
                         tags=["too_long" * 20])
    self.ExecOpCodeExpectException(op, errors.TagError, "Tag too long")

  def testPingableInstanceName(self):
    self.netutils_mod.TcpPing.return_value = True
    op = self.CopyOpCode(self.diskless_op)
    self.ExecOpCodeExpectOpPrereqError(
      op, "IP .* of instance diskless.example.com already in use")

  def testPrimaryIsSecondaryNode(self):
    op = self.CopyOpCode(self.drbd_op,
                         snode=self.drbd_op.pnode)
    self.ExecOpCodeExpectOpPrereqError(
      op, "The secondary node cannot be the primary node")

  def testPrimarySecondaryDifferentNodeGroups(self):
    group = self.cfg.AddNewNodeGroup()
    self.node2.group = group.uuid
    op = self.CopyOpCode(self.drbd_op)
    self.ExecOpCode(op)
    self.mcpu.assertLogContainsRegex(
      "The primary and secondary nodes are in two different node groups")

  def testExclusiveStorageUnsupportedDiskTemplate(self):
    self.node1.ndparams[constants.ND_EXCLUSIVE_STORAGE] = True
    op = self.CopyOpCode(self.drbd_op)
    self.ExecOpCodeExpectOpPrereqError(
      op, "Disk template drbd not supported with exclusive storage")

  def testAdoptPlain(self):
    self.rpc.call_lv_list.return_value = \
      self.RpcResultsBuilder() \
        .AddSuccessfulNode(self.master, {
          "xenvg/mock_disk_1": (10000, None, False)
        }) \
        .Build()
    op = self.CopyOpCode(self.plain_op)
    op.disks[0].update({constants.IDISK_ADOPT: "mock_disk_1"})
    self.ExecOpCode(op)

  def testAdoptPlainMissingLv(self):
    self.rpc.call_lv_list.return_value = \
      self.RpcResultsBuilder() \
        .AddSuccessfulNode(self.master, {}) \
        .Build()
    op = self.CopyOpCode(self.plain_op)
    op.disks[0].update({constants.IDISK_ADOPT: "mock_disk_1"})
    self.ExecOpCodeExpectOpPrereqError(op, "Missing logical volume")

  def testAdoptPlainOnlineLv(self):
    self.rpc.call_lv_list.return_value = \
      self.RpcResultsBuilder() \
        .AddSuccessfulNode(self.master, {
          "xenvg/mock_disk_1": (10000, None, True)
        }) \
        .Build()
    op = self.CopyOpCode(self.plain_op)
    op.disks[0].update({constants.IDISK_ADOPT: "mock_disk_1"})
    self.ExecOpCodeExpectOpPrereqError(
      op, "Online logical volumes found, cannot adopt")

  def testAdoptBlock(self):
    self.rpc.call_bdev_sizes.return_value = \
      self.RpcResultsBuilder() \
        .AddSuccessfulNode(self.master, {
          "/dev/disk/block0": 10000
        }) \
        .Build()
    op = self.CopyOpCode(self.block_op)
    self.ExecOpCode(op)

  def testAdoptBlockDuplicateNames(self):
    op = self.CopyOpCode(self.block_op,
                         disks=[{
                           constants.IDISK_SIZE: 0,
                           constants.IDISK_ADOPT: "/dev/disk/block0"
                         }, {
                           constants.IDISK_SIZE: 0,
                           constants.IDISK_ADOPT: "/dev/disk/block0"
                         }])
    self.ExecOpCodeExpectOpPrereqError(
      op, "Duplicate disk names given for adoption")

  def testAdoptBlockInvalidNames(self):
    op = self.CopyOpCode(self.block_op,
                         disks=[{
                           constants.IDISK_SIZE: 0,
                           constants.IDISK_ADOPT: "/invalid/block0"
                         }])
    self.ExecOpCodeExpectOpPrereqError(
      op, "Device node.* lie outside .* and cannot be adopted")

  def testAdoptBlockMissingDisk(self):
    self.rpc.call_bdev_sizes.return_value = \
      self.RpcResultsBuilder() \
        .AddSuccessfulNode(self.master, {}) \
        .Build()
    op = self.CopyOpCode(self.block_op)
    self.ExecOpCodeExpectOpPrereqError(op, "Missing block device")

  def testNoWaitForSyncDrbd(self):
    op = self.CopyOpCode(self.drbd_op,
                         wait_for_sync=False)
    self.ExecOpCode(op)

  def testNoWaitForSyncPlain(self):
    op = self.CopyOpCode(self.plain_op,
                         wait_for_sync=False)
    self.ExecOpCode(op)

  def testImportPlainFromGivenSrcNode(self):
    exp_info = """
[export]
version=0
os=%s
[instance]
name=old_name.example.com
""" % self.os.name

    self.rpc.call_export_info.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master, exp_info)
    op = self.CopyOpCode(self.plain_op,
                         mode=constants.INSTANCE_IMPORT,
                         src_node=self.master.name)
    self.ExecOpCode(op)

  def testImportPlainWithoutSrcNodeNotFound(self):
    op = self.CopyOpCode(self.plain_op,
                         mode=constants.INSTANCE_IMPORT)
    self.ExecOpCodeExpectOpPrereqError(
      op, "No export found for relative path")

  def testImportPlainWithoutSrcNode(self):
    exp_info = """
[export]
version=0
os=%s
[instance]
name=old_name.example.com
""" % self.os.name

    self.rpc.call_export_list.return_value = \
      self.RpcResultsBuilder() \
        .AddSuccessfulNode(self.master, {"mock_path": {}}) \
        .Build()
    self.rpc.call_export_info.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master, exp_info)

    op = self.CopyOpCode(self.plain_op,
                         mode=constants.INSTANCE_IMPORT,
                         src_path="mock_path")
    self.ExecOpCode(op)

  def testImportPlainCorruptExportInfo(self):
    exp_info = ""
    self.rpc.call_export_info.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master, exp_info)
    op = self.CopyOpCode(self.plain_op,
                         mode=constants.INSTANCE_IMPORT,
                         src_node=self.master.name)
    self.ExecOpCodeExpectException(op, errors.ProgrammerError,
                                   "Corrupted export config")

  def testImportPlainWrongExportInfoVersion(self):
    exp_info = """
[export]
version=1
"""
    self.rpc.call_export_info.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master, exp_info)
    op = self.CopyOpCode(self.plain_op,
                         mode=constants.INSTANCE_IMPORT,
                         src_node=self.master.name)
    self.ExecOpCodeExpectOpPrereqError(op, "Wrong export version")

  def testImportPlainWithParametersAndImport(self):
    exp_info = """
[export]
version=0
os=%s
[instance]
name=old_name.example.com
disk0_size=1024
disk1_size=1500
disk1_dump=mock_path
nic0_mode=bridged
nic0_link=br_mock
nic0_mac=f6:ab:f4:45:d1:af
nic0_ip=192.0.2.1
tags=tag1 tag2
hypervisor=xen-hvm
[hypervisor]
boot_order=cd
[backend]
memory=1024
vcpus=8
[os]
param1=val1
""" % self.os.name

    self.rpc.call_export_info.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master, exp_info)
    self.rpc.call_import_start.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master, "daemon_name")
    self.rpc.call_impexp_status.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master,
                                    [
                                      objects.ImportExportStatus(exit_status=0)
                                    ])
    self.rpc.call_impexp_cleanup.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master, True)

    op = self.CopyOpCode(self.plain_op,
                         disks=[],
                         nics=[],
                         tags=[],
                         hypervisor=None,
                         hvparams={},
                         mode=constants.INSTANCE_IMPORT,
                         src_node=self.master.name)
    self.ExecOpCode(op)


class TestDiskTemplateDiskTypeBijection(TestLUInstanceCreate):
  """Tests that one disk template corresponds to exactly one disk type."""

  def GetSingleInstance(self):
    instances = self.cfg.GetInstancesInfoByFilter(lambda _: True)
    self.assertEqual(len(instances), 1,
      "Expected 1 instance, got\n%s" % instances)
    return instances.values()[0]

  def testDiskTemplateLogicalIdBijectionDiskless(self):
    op = self.CopyOpCode(self.diskless_op)
    self.ExecOpCode(op)
    instance = self.GetSingleInstance()
    self.assertEqual(instance.disk_template, constants.DT_DISKLESS)
    self.assertEqual(instance.disks, [])

  def testDiskTemplateLogicalIdBijectionPlain(self):
    op = self.CopyOpCode(self.plain_op)
    self.ExecOpCode(op)
    instance = self.GetSingleInstance()
    self.assertEqual(instance.disk_template, constants.DT_PLAIN)
    disks = self.cfg.GetInstanceDisks(instance.uuid)
    self.assertEqual(disks[0].dev_type, constants.DT_PLAIN)

  def testDiskTemplateLogicalIdBijectionBlock(self):
    self.rpc.call_bdev_sizes.return_value = \
      self.RpcResultsBuilder() \
        .AddSuccessfulNode(self.master, {
          "/dev/disk/block0": 10000
        }) \
        .Build()
    op = self.CopyOpCode(self.block_op)
    self.ExecOpCode(op)
    instance = self.GetSingleInstance()
    self.assertEqual(instance.disk_template, constants.DT_BLOCK)
    disks = self.cfg.GetInstanceDisks(instance.uuid)
    self.assertEqual(disks[0].dev_type, constants.DT_BLOCK)

  def testDiskTemplateLogicalIdBijectionDrbd(self):
    op = self.CopyOpCode(self.drbd_op)
    self.ExecOpCode(op)
    instance = self.GetSingleInstance()
    self.assertEqual(instance.disk_template, constants.DT_DRBD8)
    disks = self.cfg.GetInstanceDisks(instance.uuid)
    self.assertEqual(disks[0].dev_type, constants.DT_DRBD8)

  def testDiskTemplateLogicalIdBijectionFile(self):
    op = self.CopyOpCode(self.file_op)
    self.ExecOpCode(op)
    instance = self.GetSingleInstance()
    self.assertEqual(instance.disk_template, constants.DT_FILE)
    disks = self.cfg.GetInstanceDisks(instance.uuid)
    self.assertEqual(disks[0].dev_type, constants.DT_FILE)

  def testDiskTemplateLogicalIdBijectionSharedFile(self):
    self.cluster.shared_file_storage_dir = '/tmp'
    op = self.CopyOpCode(self.shared_file_op)
    self.ExecOpCode(op)
    instance = self.GetSingleInstance()
    self.assertEqual(instance.disk_template, constants.DT_SHARED_FILE)
    disks = self.cfg.GetInstanceDisks(instance.uuid)
    self.assertEqual(disks[0].dev_type, constants.DT_SHARED_FILE)

  def testDiskTemplateLogicalIdBijectionGluster(self):
    self.cluster.gluster_storage_dir = '/tmp'
    op = self.CopyOpCode(self.gluster_op)
    self.ExecOpCode(op)
    instance = self.GetSingleInstance()
    self.assertEqual(instance.disk_template, constants.DT_GLUSTER)
    disks = self.cfg.GetInstanceDisks(instance.uuid)
    self.assertEqual(disks[0].dev_type, constants.DT_GLUSTER)

  def testDiskTemplateLogicalIdBijectionRbd(self):
    op = self.CopyOpCode(self.rbd_op)
    self.ExecOpCode(op)
    instance = self.GetSingleInstance()
    self.assertEqual(instance.disk_template, constants.DT_RBD)
    disks = self.cfg.GetInstanceDisks(instance.uuid)
    self.assertEqual(disks[0].dev_type, constants.DT_RBD)


class TestCheckOSVariant(CmdlibTestCase):
  def testNoVariantsSupported(self):
    os = self.cfg.CreateOs(supported_variants=[])
    self.assertRaises(backend.RPCFail, backend._CheckOSVariant,
                      os, "os+variant")

  def testNoVariantGiven(self):
    os = self.cfg.CreateOs(supported_variants=["default"])
    self.assertRaises(backend.RPCFail, backend._CheckOSVariant,
                      os, "os")

  def testWrongVariantGiven(self):
    os = self.cfg.CreateOs(supported_variants=["default"])
    self.assertRaises(backend.RPCFail, backend._CheckOSVariant,
                      os, "os+wrong_variant")

  def testOkWithVariant(self):
    os = self.cfg.CreateOs(supported_variants=["default"])
    backend._CheckOSVariant(os, "os+default")

  def testOkWithoutVariant(self):
    os = self.cfg.CreateOs(supported_variants=[])
    backend._CheckOSVariant(os, "os")


class TestCheckTargetNodeIPolicy(TestLUInstanceCreate):
  def setUp(self):
    super(TestCheckTargetNodeIPolicy, self).setUp()

    self.op = self.diskless_op

    self.instance = self.cfg.AddNewInstance()
    self.target_group = self.cfg.AddNewNodeGroup()
    self.target_node = self.cfg.AddNewNode(group=self.target_group)

  @withLockedLU
  def testNoViolation(self, lu):
    compute_recoder = mock.Mock(return_value=[])
    instance.CheckTargetNodeIPolicy(lu, NotImplemented, self.instance,
                                    self.target_node, NotImplemented,
                                    _compute_fn=compute_recoder)
    self.assertTrue(compute_recoder.called)
    self.mcpu.assertLogIsEmpty()

  @withLockedLU
  def testNoIgnore(self, lu):
    compute_recoder = mock.Mock(return_value=["mem_size not in range"])
    self.assertRaises(errors.OpPrereqError, instance.CheckTargetNodeIPolicy,
                      lu, NotImplemented, self.instance,
                      self.target_node, NotImplemented,
                      _compute_fn=compute_recoder)
    self.assertTrue(compute_recoder.called)
    self.mcpu.assertLogIsEmpty()

  @withLockedLU
  def testIgnoreViolation(self, lu):
    compute_recoder = mock.Mock(return_value=["mem_size not in range"])
    instance.CheckTargetNodeIPolicy(lu, NotImplemented, self.instance,
                                    self.target_node, NotImplemented,
                                    ignore=True, _compute_fn=compute_recoder)
    self.assertTrue(compute_recoder.called)
    msg = ("Instance does not meet target node group's .* instance policy:"
           " mem_size not in range")
    self.mcpu.assertLogContainsRegex(msg)


class TestIndexOperations(unittest.TestCase):

  """Test if index operations on containers work as expected."""

  def testGetIndexFromIdentifierTail(self):
    """Check if -1 is translated to tail index."""
    container = ['item1134']

    idx = instance_utils.GetIndexFromIdentifier("-1", "test", container)
    self.assertEqual(1, idx)

  def testGetIndexFromIdentifierEmpty(self):
    """Check if empty containers return 0 as index."""
    container = []

    idx = instance_utils.GetIndexFromIdentifier("0", "test", container)
    self.assertEqual(0, idx)
    idx = instance_utils.GetIndexFromIdentifier("-1", "test", container)
    self.assertEqual(0, idx)

  def testGetIndexFromIdentifierError(self):
    """Check if wrong input raises an exception."""
    container = []

    self.assertRaises(errors.OpPrereqError,
                      instance_utils.GetIndexFromIdentifier,
                      "lala", "test", container)

  def testGetIndexFromIdentifierOffByOne(self):
    """Check for off-by-one errors."""
    container = []

    self.assertRaises(IndexError, instance_utils.GetIndexFromIdentifier,
                      "1", "test", container)

  def testGetIndexFromIdentifierOutOfRange(self):
    """Check for identifiers out of the container range."""
    container = []

    self.assertRaises(IndexError, instance_utils.GetIndexFromIdentifier,
                      "-1134", "test", container)
    self.assertRaises(IndexError, instance_utils.GetIndexFromIdentifier,
                      "1134", "test", container)

  def testInsertItemtoIndex(self):
    """Test if we can insert an item to a container at a specified index."""
    container = []

    instance_utils.InsertItemToIndex(0, 2, container)
    self.assertEqual([2], container)

    instance_utils.InsertItemToIndex(0, 1, container)
    self.assertEqual([1, 2], container)

    instance_utils.InsertItemToIndex(-1, 3, container)
    self.assertEqual([1, 2, 3], container)

    self.assertRaises(AssertionError, instance_utils.InsertItemToIndex, -2,
                      1134, container)

    self.assertRaises(AssertionError, instance_utils.InsertItemToIndex, 4, 1134,
                      container)


class TestApplyContainerMods(unittest.TestCase):

  def applyAndAssert(self, container, inp, expected_container,
                     expected_chgdesc=[]):
    """Apply a list of changes to a container and check the container state

    Parameters:
    @type container: List
    @param container: The container on which we will apply the changes
    @type inp: List<(action, index, object)>
    @param inp: The list of changes, a tupple with three elements:
                i. action, e.g. constants.DDM_ADD
                ii. index, e.g. -1, 0, 10
                iii. object (any type)
    @type expected: List
    @param expected: The expected state of the container
    @type chgdesc: List
    @param chgdesc: List of applied changes


    """
    chgdesc = []
    mods = instance_utils.PrepareContainerMods(inp, None)
    instance_utils.ApplyContainerMods("test", container, chgdesc, mods,
                                      None, None, None, None, None)
    self.assertEqual(container, expected_container)
    self.assertEqual(chgdesc, expected_chgdesc)

  def _insertContainerSuccessFn(self, op):
    container = []
    inp = [(op, -1, "Hello"),
           (op, -1, "World"),
           (op, 0, "Start"),
           (op, -1, "End"),
           ]
    expected = ["Start", "Hello", "World", "End"]
    self.applyAndAssert(container, inp, expected)

    inp = [(op, 0, "zero"),
           (op, 3, "Added"),
           (op, 5, "four"),
           (op, 7, "xyz"),
           ]
    expected = ["zero", "Start", "Hello", "Added", "World", "four", "End",
                "xyz"]
    self.applyAndAssert(container, inp, expected)

  def _insertContainerErrorFn(self, op):
    container = []
    expected = None

    inp = [(op, 1, "error"), ]
    self.assertRaises(IndexError, self.applyAndAssert, container, inp,
                      expected)

    inp = [(op, -2, "error"), ]
    self.assertRaises(IndexError, self.applyAndAssert, container, inp,
                      expected)

  def _extractContainerSuccessFn(self, op):
    container = ["item1", "item2", "item3", "item4", "item5"]
    inp = [(op, -1, None),
           (op, -0, None),
           (op, 1, None),
           ]
    expected = ["item2", "item4"]
    chgdesc = [('test/4', op),
               ('test/0', op),
               ('test/1', op)
               ]
    self.applyAndAssert(container, inp, expected, chgdesc)

  def _extractContainerErrorFn(self, op):
    container = []
    expected = None

    inp = [(op, 0, None), ]
    self.assertRaises(IndexError, self.applyAndAssert, container, inp,
                      expected)

    inp = [(op, -1, None), ]
    self.assertRaises(IndexError, self.applyAndAssert, container, inp,
                      expected)

    inp = [(op, 2, None), ]
    self.assertRaises(IndexError, self.applyAndAssert, container, inp,
                      expected)
    container = [""]
    inp = [(op, 0, None), ]
    expected = None
    self.assertRaises(AssertionError, self.applyAndAssert, container, inp,
                      expected)

  def testEmptyContainer(self):
    container = []
    chgdesc = []
    instance_utils.ApplyContainerMods("test", container, chgdesc, [], None,
                                      None, None, None, None)
    self.assertEqual(container, [])
    self.assertEqual(chgdesc, [])

  def testAddSuccess(self):
    self._insertContainerSuccessFn(constants.DDM_ADD)

  def testAddError(self):
    self._insertContainerErrorFn(constants.DDM_ADD)

  def testAttachSuccess(self):
    self._insertContainerSuccessFn(constants.DDM_ATTACH)

  def testAttachError(self):
    self._insertContainerErrorFn(constants.DDM_ATTACH)

  def testRemoveSuccess(self):
    self._extractContainerSuccessFn(constants.DDM_REMOVE)

  def testRemoveError(self):
    self._extractContainerErrorFn(constants.DDM_REMOVE)

  def testDetachSuccess(self):
    self._extractContainerSuccessFn(constants.DDM_DETACH)

  def testDetachError(self):
    self._extractContainerErrorFn(constants.DDM_DETACH)

  def testModify(self):
    container = ["item 1", "item 2"]
    mods = instance_utils.PrepareContainerMods([
      (constants.DDM_MODIFY, -1, "a"),
      (constants.DDM_MODIFY, 0, "b"),
      (constants.DDM_MODIFY, 1, "c"),
      ], None)
    chgdesc = []
    instance_utils.ApplyContainerMods("test", container, chgdesc, mods,
                                      None, None, None, None, None)
    self.assertEqual(container, ["item 1", "item 2"])
    self.assertEqual(chgdesc, [])

    for idx in [-2, len(container) + 1]:
      mods = instance_utils.PrepareContainerMods([
        (constants.DDM_MODIFY, idx, "error"),
        ], None)
      self.assertRaises(IndexError, instance_utils.ApplyContainerMods,
                        "test", container, None, mods, None, None, None, None,
                        None)

  @staticmethod
  def _CreateTestFn(idx, params, private):
    private.data = ("add", idx, params)
    return ((100 * idx, params), [
      ("test/%s" % idx, hex(idx)),
      ])

  @staticmethod
  def _AttachTestFn(idx, params, private):
    private.data = ("attach", idx, params)
    return ((100 * idx, params), [
      ("test/%s" % idx, hex(idx)),
      ])

  @staticmethod
  def _ModifyTestFn(idx, item, params, private):
    private.data = ("modify", idx, params)
    return [
      ("test/%s" % idx, "modify %s" % params),
      ]

  @staticmethod
  def _RemoveTestFn(idx, item, private):
    private.data = ("remove", idx, item)

  @staticmethod
  def _DetachTestFn(idx, item, private):
    private.data = ("detach", idx, item)

  def testAddWithCreateFunction(self):
    container = []
    chgdesc = []
    mods = instance_utils.PrepareContainerMods([
      (constants.DDM_ADD, -1, "Hello"),
      (constants.DDM_ADD, -1, "World"),
      (constants.DDM_ADD, 0, "Start"),
      (constants.DDM_ADD, -1, "End"),
      (constants.DDM_REMOVE, 2, None),
      (constants.DDM_MODIFY, -1, "foobar"),
      (constants.DDM_REMOVE, 2, None),
      (constants.DDM_ADD, 1, "More"),
      (constants.DDM_DETACH, -1, None),
      (constants.DDM_ATTACH, 0, "Hello"),
      ], mock.Mock)
    instance_utils.ApplyContainerMods("test", container, chgdesc, mods,
                                      self._CreateTestFn, self._AttachTestFn,
                                      self._ModifyTestFn, self._RemoveTestFn,
                                      self._DetachTestFn)
    self.assertEqual(container, [
      (000, "Hello"),
      (000, "Start"),
      (100, "More"),
      ])
    self.assertEqual(chgdesc, [
      ("test/0", "0x0"),
      ("test/1", "0x1"),
      ("test/0", "0x0"),
      ("test/3", "0x3"),
      ("test/2", "remove"),
      ("test/2", "modify foobar"),
      ("test/2", "remove"),
      ("test/1", "0x1"),
      ("test/2", "detach"),
      ("test/0", "0x0"),
      ])
    self.assertTrue(compat.all(op == private.data[0]
                               for (op, _, _, private) in mods))
    self.assertEqual([private.data for (op, _, _, private) in mods], [
      ("add", 0, "Hello"),
      ("add", 1, "World"),
      ("add", 0, "Start"),
      ("add", 3, "End"),
      ("remove", 2, (100, "World")),
      ("modify", 2, "foobar"),
      ("remove", 2, (300, "End")),
      ("add", 1, "More"),
      ("detach", 2, (000, "Hello")),
      ("attach", 0, "Hello"),
      ])


class _FakeConfigForGenDiskTemplate(ConfigMock):
  def __init__(self):
    super(_FakeConfigForGenDiskTemplate, self).__init__()

    self._unique_id = itertools.count()
    self._drbd_minor = itertools.count(20)
    self._port = itertools.count(constants.FIRST_DRBD_PORT)
    self._secret = itertools.count()

  def GenerateUniqueID(self, ec_id):
    return "ec%s-uq%s" % (ec_id, self._unique_id.next())

  def AllocateDRBDMinor(self, nodes, disk):
    return [self._drbd_minor.next()
            for _ in nodes]

  def AllocatePort(self):
    return self._port.next()

  def GenerateDRBDSecret(self, ec_id):
    return "ec%s-secret%s" % (ec_id, self._secret.next())


class TestGenerateDiskTemplate(CmdlibTestCase):
  def setUp(self):
    super(TestGenerateDiskTemplate, self).setUp()

    self.cfg = _FakeConfigForGenDiskTemplate()
    self.cluster.enabled_disk_templates = list(constants.DISK_TEMPLATES)

    self.nodegroup = self.cfg.AddNewNodeGroup(name="ng")

    self.lu = self.GetMockLU()

  @staticmethod
  def GetDiskParams():
    return copy.deepcopy(constants.DISK_DT_DEFAULTS)

  def testWrongDiskTemplate(self):
    gdt = instance_storage.GenerateDiskTemplate
    disk_template = "##unknown##"

    assert disk_template not in constants.DISK_TEMPLATES

    self.assertRaises(errors.OpPrereqError, gdt, self.lu, disk_template,
                      "inst26831.example.com", "node30113.example.com", [], [],
                      NotImplemented, NotImplemented, 0, self.lu.LogInfo,
                      self.GetDiskParams())

  def testDiskless(self):
    gdt = instance_storage.GenerateDiskTemplate

    result = gdt(self.lu, constants.DT_DISKLESS, "inst27734.example.com",
                 "node30113.example.com", [], [],
                 NotImplemented, NotImplemented, 0, self.lu.LogInfo,
                 self.GetDiskParams())
    self.assertEqual(result, [])

  def _TestTrivialDisk(self, template, disk_info, base_index, exp_dev_type,
                       file_storage_dir=NotImplemented,
                       file_driver=NotImplemented):
    gdt = instance_storage.GenerateDiskTemplate

    map(lambda params: utils.ForceDictType(params,
                                           constants.IDISK_PARAMS_TYPES),
        disk_info)

    # Check if non-empty list of secondaries is rejected
    self.assertRaises(errors.ProgrammerError, gdt, self.lu,
                      template, "inst25088.example.com",
                      "node185.example.com", ["node323.example.com"], [],
                      NotImplemented, NotImplemented, base_index,
                      self.lu.LogInfo, self.GetDiskParams())

    result = gdt(self.lu, template, "inst21662.example.com",
                 "node21741.example.com", [],
                 disk_info, file_storage_dir, file_driver, base_index,
                 self.lu.LogInfo, self.GetDiskParams())

    for (idx, disk) in enumerate(result):
      self.assertTrue(isinstance(disk, objects.Disk))
      self.assertEqual(disk.dev_type, exp_dev_type)
      self.assertEqual(disk.size, disk_info[idx][constants.IDISK_SIZE])
      self.assertEqual(disk.mode, disk_info[idx][constants.IDISK_MODE])
      self.assertTrue(disk.children is None)

    self._CheckIvNames(result, base_index, base_index + len(disk_info))
    _UpdateIvNames(base_index, result)
    self._CheckIvNames(result, base_index, base_index + len(disk_info))

    return result

  def _CheckIvNames(self, disks, base_index, end_index):
    self.assertEqual(map(operator.attrgetter("iv_name"), disks),
                     ["disk/%s" % i for i in range(base_index, end_index)])

  def testPlain(self):
    disk_info = [{
      constants.IDISK_SIZE: 1024,
      constants.IDISK_MODE: constants.DISK_RDWR,
      }, {
      constants.IDISK_SIZE: 4096,
      constants.IDISK_VG: "othervg",
      constants.IDISK_MODE: constants.DISK_RDWR,
      }]

    result = self._TestTrivialDisk(constants.DT_PLAIN, disk_info, 3,
                                   constants.DT_PLAIN)

    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
      ("xenvg", "ec1-uq0.disk3"),
      ("othervg", "ec1-uq1.disk4"),
      ])
    self.assertEqual(map(operator.attrgetter("nodes"), result), [
                     ["node21741.example.com"], ["node21741.example.com"]])


  def testFile(self):
    # anything != DT_FILE would do here
    self.cluster.enabled_disk_templates = [constants.DT_PLAIN]
    self.assertRaises(errors.OpPrereqError, self._TestTrivialDisk,
                      constants.DT_FILE, [], 0, NotImplemented)
    self.assertRaises(errors.OpPrereqError, self._TestTrivialDisk,
                      constants.DT_SHARED_FILE, [], 0, NotImplemented)

    for disk_template in constants.DTS_FILEBASED:
      disk_info = [{
        constants.IDISK_SIZE: 80 * 1024,
        constants.IDISK_MODE: constants.DISK_RDONLY,
        }, {
        constants.IDISK_SIZE: 4096,
        constants.IDISK_MODE: constants.DISK_RDWR,
        }, {
        constants.IDISK_SIZE: 6 * 1024,
        constants.IDISK_MODE: constants.DISK_RDWR,
        }]

      self.cluster.enabled_disk_templates = [disk_template]
      result = self._TestTrivialDisk(
        disk_template, disk_info, 2, disk_template,
        file_storage_dir="/tmp", file_driver=constants.FD_BLKTAP)

      if disk_template == constants.DT_GLUSTER:
        # Here "inst21662.example.com" is actually the instance UUID, not its
        # name, so while this result looks wrong, it is actually correct.
        expected = [(constants.FD_BLKTAP,
                     'ganeti/inst21662.example.com.%d' % x)
                    for x in (2,3,4)]
        self.assertEqual(map(operator.attrgetter("logical_id"), result),
                         expected)
        self.assertEqual(map(operator.attrgetter("nodes"), result), [
          [], [], []])
      else:
        if disk_template == constants.DT_FILE:
          self.assertEqual(map(operator.attrgetter("nodes"), result), [
            ["node21741.example.com"], ["node21741.example.com"],
            ["node21741.example.com"]])
        else:
          self.assertEqual(map(operator.attrgetter("nodes"), result), [
            [], [], []])

        for (idx, disk) in enumerate(result):
          (file_driver, file_storage_dir) = disk.logical_id
          dir_fmt = r"^/tmp/.*\.%s\.disk%d$" % (disk_template, idx + 2)
          self.assertEqual(file_driver, constants.FD_BLKTAP)
          # FIXME: use assertIsNotNone when py 2.7 is minimum supported version
          self.assertNotEqual(re.match(dir_fmt, file_storage_dir), None)

  def testBlock(self):
    disk_info = [{
      constants.IDISK_SIZE: 8 * 1024,
      constants.IDISK_MODE: constants.DISK_RDWR,
      constants.IDISK_ADOPT: "/tmp/some/block/dev",
      }]

    result = self._TestTrivialDisk(constants.DT_BLOCK, disk_info, 10,
                                   constants.DT_BLOCK)

    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
      (constants.BLOCKDEV_DRIVER_MANUAL, "/tmp/some/block/dev"),
      ])
    self.assertEqual(map(operator.attrgetter("nodes"), result), [[]])

  def testRbd(self):
    disk_info = [{
      constants.IDISK_SIZE: 8 * 1024,
      constants.IDISK_MODE: constants.DISK_RDONLY,
      }, {
      constants.IDISK_SIZE: 100 * 1024,
      constants.IDISK_MODE: constants.DISK_RDWR,
      }]

    result = self._TestTrivialDisk(constants.DT_RBD, disk_info, 0,
                                   constants.DT_RBD)

    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
      ("rbd", "ec1-uq0.rbd.disk0"),
      ("rbd", "ec1-uq1.rbd.disk1"),
      ])
    self.assertEqual(map(operator.attrgetter("nodes"), result), [[], []])

  def testDrbd8(self):
    gdt = instance_storage.GenerateDiskTemplate
    drbd8_defaults = constants.DISK_LD_DEFAULTS[constants.DT_DRBD8]
    drbd8_default_metavg = drbd8_defaults[constants.LDP_DEFAULT_METAVG]

    disk_info = [{
      constants.IDISK_SIZE: 1024,
      constants.IDISK_MODE: constants.DISK_RDWR,
      }, {
      constants.IDISK_SIZE: 100 * 1024,
      constants.IDISK_MODE: constants.DISK_RDONLY,
      constants.IDISK_METAVG: "metavg",
      }, {
      constants.IDISK_SIZE: 4096,
      constants.IDISK_MODE: constants.DISK_RDWR,
      constants.IDISK_VG: "vgxyz",
      },
      ]

    exp_logical_ids = [
      [
        (self.lu.cfg.GetVGName(), "ec1-uq0.disk0_data"),
        (drbd8_default_metavg, "ec1-uq0.disk0_meta"),
      ], [
        (self.lu.cfg.GetVGName(), "ec1-uq1.disk1_data"),
        ("metavg", "ec1-uq1.disk1_meta"),
      ], [
        ("vgxyz", "ec1-uq2.disk2_data"),
        (drbd8_default_metavg, "ec1-uq2.disk2_meta"),
      ]]

    exp_nodes = ["node1334.example.com", "node12272.example.com"]

    assert len(exp_logical_ids) == len(disk_info)

    map(lambda params: utils.ForceDictType(params,
                                           constants.IDISK_PARAMS_TYPES),
        disk_info)

    # Check if empty list of secondaries is rejected
    self.assertRaises(errors.ProgrammerError, gdt, self.lu, constants.DT_DRBD8,
                      "inst827.example.com", "node1334.example.com", [],
                      disk_info, NotImplemented, NotImplemented, 0,
                      self.lu.LogInfo, self.GetDiskParams())

    result = gdt(self.lu, constants.DT_DRBD8, "inst827.example.com",
                 "node1334.example.com", ["node12272.example.com"],
                 disk_info, NotImplemented, NotImplemented, 0, self.lu.LogInfo,
                 self.GetDiskParams())

    for (idx, disk) in enumerate(result):
      self.assertTrue(isinstance(disk, objects.Disk))
      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.DT_PLAIN)
        self.assertTrue(child.children is None)
        self.assertEqual(child.nodes, exp_nodes)

      self.assertEqual(map(operator.attrgetter("logical_id"), disk.children),
                       exp_logical_ids[idx])
      self.assertEqual(disk.nodes, exp_nodes)

      self.assertEqual(len(disk.children), 2)
      self.assertEqual(disk.children[0].size, disk.size)
      self.assertEqual(disk.children[1].size, constants.DRBD_META_SIZE)

    self._CheckIvNames(result, 0, len(disk_info))
    _UpdateIvNames(0, result)
    self._CheckIvNames(result, 0, len(disk_info))

    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
      ("node1334.example.com", "node12272.example.com",
       constants.FIRST_DRBD_PORT, 20, 21, "ec1-secret0"),
      ("node1334.example.com", "node12272.example.com",
       constants.FIRST_DRBD_PORT + 1, 22, 23, "ec1-secret1"),
      ("node1334.example.com", "node12272.example.com",
       constants.FIRST_DRBD_PORT + 2, 24, 25, "ec1-secret2"),
      ])


class _DiskPauseTracker:
  def __init__(self):
    self.history = []

  def __call__(self, (disks, instance), pause):
    disk_uuids = [d.uuid for d in disks]
    assert not (set(disk_uuids) - set(instance.disks))

    self.history.extend((i.logical_id, i.size, pause)
                        for i in disks)

    return (True, [True] * len(disks))


class _ConfigForDiskWipe:
  def __init__(self, exp_node_uuid, disks):
    self._exp_node_uuid = exp_node_uuid
    self._disks = disks

  def GetNodeName(self, node_uuid):
    assert node_uuid == self._exp_node_uuid
    return "name.of.expected.node"

  def GetInstanceDisks(self, _):
    return self._disks


class _RpcForDiskWipe:
  def __init__(self, exp_node, pause_cb, wipe_cb):
    self._exp_node = exp_node
    self._pause_cb = pause_cb
    self._wipe_cb = wipe_cb

  def call_blockdev_pause_resume_sync(self, node, disks, pause):
    assert node == self._exp_node
    return rpc.RpcResult(data=self._pause_cb(disks, pause))

  def call_blockdev_wipe(self, node, bdev, offset, size):
    assert node == self._exp_node
    return rpc.RpcResult(data=self._wipe_cb(bdev, offset, size))


class _DiskWipeProgressTracker:
  def __init__(self, start_offset):
    self._start_offset = start_offset
    self.progress = {}

  def __call__(self, (disk, _), offset, size):
    assert isinstance(offset, (long, int))
    assert isinstance(size, (long, int))

    max_chunk_size = (disk.size / 100.0 * constants.MIN_WIPE_CHUNK_PERCENT)

    assert offset >= self._start_offset
    assert (offset + size) <= disk.size

    assert size > 0
    assert size <= constants.MAX_WIPE_CHUNK
    assert size <= max_chunk_size

    assert offset == self._start_offset or disk.logical_id in self.progress

    # Keep track of progress
    cur_progress = self.progress.setdefault(disk.logical_id, self._start_offset)

    assert cur_progress == offset

    # Record progress
    self.progress[disk.logical_id] += size

    return (True, None)


class TestWipeDisks(unittest.TestCase):
  def _FailingPauseCb(self, (disks, _), pause):
    self.assertEqual(len(disks), 3)
    self.assertTrue(pause)
    # Simulate an RPC error
    return (False, "error")

  def testPauseFailure(self):
    node_name = "node1372.example.com"

    disks = [
      objects.Disk(dev_type=constants.DT_PLAIN, uuid="disk0"),
      objects.Disk(dev_type=constants.DT_PLAIN, uuid="disk1"),
      objects.Disk(dev_type=constants.DT_PLAIN, uuid="disk2"),
      ]

    lu = _FakeLU(rpc=_RpcForDiskWipe(node_name, self._FailingPauseCb,
                                     NotImplemented),
                 cfg=_ConfigForDiskWipe(node_name, disks))

    inst = objects.Instance(name="inst21201",
                            primary_node=node_name,
                            disk_template=constants.DT_PLAIN,
                            disks=[d.uuid for d in disks])

    self.assertRaises(errors.OpExecError, instance_create.WipeDisks, lu, inst)

  def _FailingWipeCb(self, (disk, _), offset, size):
    # This should only ever be called for the first disk
    self.assertEqual(disk.logical_id, "disk0")
    return (False, None)

  def testFailingWipe(self):
    node_uuid = "node13445-uuid"
    pt = _DiskPauseTracker()

    disks = [
      objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk0",
                   size=100 * 1024, uuid="disk0"),
      objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk1",
                   size=500 * 1024, uuid="disk1"),
      objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk2",
                   size=256, uuid="disk2"),
      ]

    lu = _FakeLU(rpc=_RpcForDiskWipe(node_uuid, pt, self._FailingWipeCb),
                 cfg=_ConfigForDiskWipe(node_uuid, disks))

    inst = objects.Instance(name="inst562",
                            primary_node=node_uuid,
                            disk_template=constants.DT_PLAIN,
                            disks=[d.uuid for d in disks])

    try:
      instance_create.WipeDisks(lu, inst)
    except errors.OpExecError, err:
      self.assertTrue(str(err), "Could not wipe disk 0 at offset 0 ")
    else:
      self.fail("Did not raise exception")

    # Check if all disks were paused and resumed
    self.assertEqual(pt.history, [
      ("disk0", 100 * 1024, True),
      ("disk1", 500 * 1024, True),
      ("disk2", 256, True),
      ("disk0", 100 * 1024, False),
      ("disk1", 500 * 1024, False),
      ("disk2", 256, False),
      ])

  def _PrepareWipeTest(self, start_offset, disks):
    node_name = "node-with-offset%s.example.com" % start_offset
    pauset = _DiskPauseTracker()
    progresst = _DiskWipeProgressTracker(start_offset)

    lu = _FakeLU(rpc=_RpcForDiskWipe(node_name, pauset, progresst),
                 cfg=_ConfigForDiskWipe(node_name, disks))

    instance = objects.Instance(name="inst3560",
                                primary_node=node_name,
                                disk_template=constants.DT_PLAIN,
                                disks=[d.uuid for d in disks])

    return (lu, instance, pauset, progresst)

  def testNormalWipe(self):
    disks = [
      objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk0",
                   size=1024, uuid="disk0"),
      objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk1",
                   size=500 * 1024, uuid="disk1"),
      objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk2",
                   size=128, uuid="disk2"),
      objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk3",
                   size=constants.MAX_WIPE_CHUNK, uuid="disk3"),
      ]

    (lu, inst, pauset, progresst) = self._PrepareWipeTest(0, disks)

    instance_create.WipeDisks(lu, inst)

    self.assertEqual(pauset.history, [
      ("disk0", 1024, True),
      ("disk1", 500 * 1024, True),
      ("disk2", 128, True),
      ("disk3", constants.MAX_WIPE_CHUNK, True),
      ("disk0", 1024, False),
      ("disk1", 500 * 1024, False),
      ("disk2", 128, False),
      ("disk3", constants.MAX_WIPE_CHUNK, False),
      ])

    # Ensure the complete disk has been wiped
    self.assertEqual(progresst.progress,
                     dict((i.logical_id, i.size) for i in disks))

  def testWipeWithStartOffset(self):
    for start_offset in [0, 280, 8895, 1563204]:
      disks = [
        objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk0",
                     size=128, uuid="disk0"),
        objects.Disk(dev_type=constants.DT_PLAIN, logical_id="disk1",
                     size=start_offset + (100 * 1024), uuid="disk1"),
        ]

      (lu, inst, pauset, progresst) = \
        self._PrepareWipeTest(start_offset, disks)

      # Test start offset with only one disk
      instance_create.WipeDisks(lu, inst,
                                disks=[(1, disks[1], start_offset)])

      # Only the second disk may have been paused and wiped
      self.assertEqual(pauset.history, [
        ("disk1", start_offset + (100 * 1024), True),
        ("disk1", start_offset + (100 * 1024), False),
        ])
      self.assertEqual(progresst.progress, {
        "disk1": disks[1].size,
        })


class TestCheckOpportunisticLocking(unittest.TestCase):
  class OpTest(opcodes.OpCode):
    OP_PARAMS = [
      ("opportunistic_locking", False, ht.TBool, None),
      ("iallocator", None, ht.TMaybe(ht.TNonEmptyString), "")
      ]

  @classmethod
  def _MakeOp(cls, **kwargs):
    op = cls.OpTest(**kwargs)
    op.Validate(True)
    return op

  def testMissingAttributes(self):
    self.assertRaises(AttributeError, instance.CheckOpportunisticLocking,
                      object())

  def testDefaults(self):
    op = self._MakeOp()
    instance.CheckOpportunisticLocking(op)

  def test(self):
    for iallocator in [None, "something", "other"]:
      for opplock in [False, True]:
        op = self._MakeOp(iallocator=iallocator,
                          opportunistic_locking=opplock)
        if opplock and not iallocator:
          self.assertRaises(errors.OpPrereqError,
                            instance.CheckOpportunisticLocking, op)
        else:
          instance.CheckOpportunisticLocking(op)


class TestLUInstanceMove(CmdlibTestCase):
  def setUp(self):
    super(TestLUInstanceMove, self).setUp()

    self.node = self.cfg.AddNewNode()

    self.rpc.call_blockdev_assemble.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.node, ("/dev/mocked_path",
                                    "/var/run/ganeti/instance-disks/mocked_d",
                                    None))
    self.rpc.call_blockdev_remove.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master, "")

    def ImportStart(node_uuid, opt, inst, component, args):
      return self.RpcResultsBuilder() \
               .CreateSuccessfulNodeResult(node_uuid,
                                           "deamon_on_%s" % node_uuid)
    self.rpc.call_import_start.side_effect = ImportStart

    def ImpExpStatus(node_uuid, name):
      return self.RpcResultsBuilder() \
               .CreateSuccessfulNodeResult(node_uuid,
                                           [objects.ImportExportStatus(
                                             exit_status=0
                                           )])
    self.rpc.call_impexp_status.side_effect = ImpExpStatus

    def ImpExpCleanup(node_uuid, name):
      return self.RpcResultsBuilder() \
               .CreateSuccessfulNodeResult(node_uuid)
    self.rpc.call_impexp_cleanup.side_effect = ImpExpCleanup

  def testMissingInstance(self):
    op = opcodes.OpInstanceMove(instance_name="missing.inst",
                                target_node=self.node.name)
    self.ExecOpCodeExpectOpPrereqError(op, "Instance 'missing.inst' not known")

  def testUncopyableDiskTemplate(self):
    inst = self.cfg.AddNewInstance(disk_template=constants.DT_SHARED_FILE)
    op = opcodes.OpInstanceMove(instance_name=inst.name,
                                target_node=self.node.name)
    self.ExecOpCodeExpectOpPrereqError(
      op, "Instance disk 0 has disk type sharedfile and is not suitable"
      " for copying")

  def testAlreadyOnTargetNode(self):
    inst = self.cfg.AddNewInstance()
    op = opcodes.OpInstanceMove(instance_name=inst.name,
                                target_node=self.master.name)
    self.ExecOpCodeExpectOpPrereqError(
      op, "Instance .* is already on the node .*")

  def testMoveStoppedInstance(self):
    inst = self.cfg.AddNewInstance()
    op = opcodes.OpInstanceMove(instance_name=inst.name,
                                target_node=self.node.name)
    self.ExecOpCode(op)

  def testMoveRunningInstance(self):
    self.rpc.call_node_info.return_value = \
      self.RpcResultsBuilder() \
        .AddSuccessfulNode(self.node,
                           (NotImplemented, NotImplemented,
                            ({"memory_free": 10000}, ))) \
        .Build()
    self.rpc.call_instance_start.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.node, "")

    inst = self.cfg.AddNewInstance(admin_state=constants.ADMINST_UP)
    op = opcodes.OpInstanceMove(instance_name=inst.name,
                                target_node=self.node.name)
    self.ExecOpCode(op)

  def testMoveFailingStartInstance(self):
    self.rpc.call_node_info.return_value = \
      self.RpcResultsBuilder() \
        .AddSuccessfulNode(self.node,
                           (NotImplemented, NotImplemented,
                            ({"memory_free": 10000}, ))) \
        .Build()
    self.rpc.call_instance_start.return_value = \
      self.RpcResultsBuilder() \
        .CreateFailedNodeResult(self.node)

    inst = self.cfg.AddNewInstance(admin_state=constants.ADMINST_UP)
    op = opcodes.OpInstanceMove(instance_name=inst.name,
                                target_node=self.node.name)
    self.ExecOpCodeExpectOpExecError(
      op, "Could not start instance .* on node .*")

  def testMoveFailingImpExpDaemonExitCode(self):
    inst = self.cfg.AddNewInstance()
    self.rpc.call_impexp_status.side_effect = None
    self.rpc.call_impexp_status.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.node,
                                    [objects.ImportExportStatus(
                                      exit_status=1,
                                      recent_output=["mock output"]
                                    )])
    op = opcodes.OpInstanceMove(instance_name=inst.name,
                                target_node=self.node.name)
    self.ExecOpCodeExpectOpExecError(op, "Errors during disk copy")

  def testMoveFailingStartImpExpDaemon(self):
    inst = self.cfg.AddNewInstance()
    self.rpc.call_import_start.side_effect = None
    self.rpc.call_import_start.return_value = \
      self.RpcResultsBuilder() \
        .CreateFailedNodeResult(self.node)
    op = opcodes.OpInstanceMove(instance_name=inst.name,
                                target_node=self.node.name)
    self.ExecOpCodeExpectOpExecError(op, "Errors during disk copy")


class TestLUInstanceRename(CmdlibTestCase):
  def setUp(self):
    super(TestLUInstanceRename, self).setUp()

    self.MockOut(instance_utils, 'netutils', self.netutils_mod)

    self.inst = self.cfg.AddNewInstance()

    self.op = opcodes.OpInstanceRename(instance_name=self.inst.name,
                                       new_name="new_name.example.com")

  def testIpCheckWithoutNameCheck(self):
    op = self.CopyOpCode(self.op,
                         ip_check=True,
                         name_check=False)
    self.ExecOpCodeExpectOpPrereqError(
      op, "IP address check requires a name check")

  def testIpAlreadyInUse(self):
    self.netutils_mod.TcpPing.return_value = True
    op = self.CopyOpCode(self.op)
    self.ExecOpCodeExpectOpPrereqError(
      op, "IP .* of instance .* already in use")

  def testExistingInstanceName(self):
    self.cfg.AddNewInstance(name="new_name.example.com")
    op = self.CopyOpCode(self.op)
    self.ExecOpCodeExpectOpPrereqError(
      op, "Instance .* is already in the cluster")

  def testFileInstance(self):
    self.rpc.call_blockdev_assemble.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master, (None, None, None))
    self.rpc.call_blockdev_shutdown.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master, (None, None))

    inst = self.cfg.AddNewInstance(disk_template=constants.DT_FILE)
    op = self.CopyOpCode(self.op,
                         instance_name=inst.name)
    self.ExecOpCode(op)


class TestLUInstanceMultiAlloc(CmdlibTestCase):
  def setUp(self):
    super(TestLUInstanceMultiAlloc, self).setUp()

    self.inst_op = opcodes.OpInstanceCreate(instance_name="inst.example.com",
                                            disk_template=constants.DT_DRBD8,
                                            disks=[],
                                            nics=[],
                                            os_type="mock_os",
                                            hypervisor=constants.HT_XEN_HVM,
                                            mode=constants.INSTANCE_CREATE)

  def testInstanceWithIAllocator(self):
    inst = self.CopyOpCode(self.inst_op,
                           iallocator="mock")
    op = opcodes.OpInstanceMultiAlloc(instances=[inst])
    self.ExecOpCodeExpectOpPrereqError(
      op, "iallocator are not allowed to be set on instance objects")

  def testOnlySomeNodesGiven(self):
    inst1 = self.CopyOpCode(self.inst_op,
                            pnode=self.master.name)
    inst2 = self.CopyOpCode(self.inst_op)
    op = opcodes.OpInstanceMultiAlloc(instances=[inst1, inst2])
    self.ExecOpCodeExpectOpPrereqError(
      op, "There are instance objects providing pnode/snode while others"
          " do not")

  def testMissingIAllocator(self):
    self.cluster.default_iallocator = None
    inst = self.CopyOpCode(self.inst_op)
    op = opcodes.OpInstanceMultiAlloc(instances=[inst])
    self.ExecOpCodeExpectOpPrereqError(
      op, "No iallocator or nodes on the instances given and no cluster-wide"
          " default iallocator found")

  def testDuplicateInstanceNames(self):
    inst1 = self.CopyOpCode(self.inst_op)
    inst2 = self.CopyOpCode(self.inst_op)
    op = opcodes.OpInstanceMultiAlloc(instances=[inst1, inst2])
    self.ExecOpCodeExpectOpPrereqError(
      op, "There are duplicate instance names")

  def testWithGivenNodes(self):
    snode = self.cfg.AddNewNode()
    inst = self.CopyOpCode(self.inst_op,
                           pnode=self.master.name,
                           snode=snode.name)
    op = opcodes.OpInstanceMultiAlloc(instances=[inst])
    self.ExecOpCode(op)

  def testDryRun(self):
    snode = self.cfg.AddNewNode()
    inst = self.CopyOpCode(self.inst_op,
                           pnode=self.master.name,
                           snode=snode.name)
    op = opcodes.OpInstanceMultiAlloc(instances=[inst],
                                      dry_run=True)
    self.ExecOpCode(op)

  def testWithIAllocator(self):
    snode = self.cfg.AddNewNode()
    self.iallocator_cls.return_value.result = \
      ([("inst.example.com", [self.master.name, snode.name])], [])

    inst = self.CopyOpCode(self.inst_op)
    op = opcodes.OpInstanceMultiAlloc(instances=[inst],
                                      iallocator="mock_ialloc")
    self.ExecOpCode(op)

  def testManyInstancesWithIAllocator(self):
    snode = self.cfg.AddNewNode()

    inst1 = self.CopyOpCode(self.inst_op)
    inst2 = self.CopyOpCode(self.inst_op, instance_name="inst2.example.com")

    self.iallocator_cls.return_value.result = \
      ([("inst.example.com",  [self.master.name, snode.name]),
        ("inst2.example.com", [self.master.name, snode.name])],
       [])

    op = opcodes.OpInstanceMultiAlloc(instances=[inst1, inst2],
                                      iallocator="mock_ialloc")
    self.ExecOpCode(op)

  def testWithIAllocatorOpportunisticLocking(self):
    snode = self.cfg.AddNewNode()
    self.iallocator_cls.return_value.result = \
      ([("inst.example.com", [self.master.name, snode.name])], [])

    inst = self.CopyOpCode(self.inst_op)
    op = opcodes.OpInstanceMultiAlloc(instances=[inst],
                                      iallocator="mock_ialloc",
                                      opportunistic_locking=True)
    self.ExecOpCode(op)

  def testFailingIAllocator(self):
    self.iallocator_cls.return_value.success = False

    inst = self.CopyOpCode(self.inst_op)
    op = opcodes.OpInstanceMultiAlloc(instances=[inst],
                                      iallocator="mock_ialloc")
    self.ExecOpCodeExpectOpPrereqError(
      op, "Can't compute nodes using iallocator")


class TestLUInstanceSetParams(CmdlibTestCase):
  def setUp(self):
    super(TestLUInstanceSetParams, self).setUp()

    self.MockOut(instance_set_params, 'netutils', self.netutils_mod)
    self.MockOut(instance_utils, 'netutils', self.netutils_mod)

    self.dev_type = constants.DT_PLAIN
    self.inst = self.cfg.AddNewInstance(disk_template=self.dev_type)
    self.op = opcodes.OpInstanceSetParams(instance_name=self.inst.name)

    self.cfg._cluster.default_iallocator=None

    self.running_inst = \
      self.cfg.AddNewInstance(admin_state=constants.ADMINST_UP)
    self.running_op = \
      opcodes.OpInstanceSetParams(instance_name=self.running_inst.name)

    ext_disks = [self.cfg.CreateDisk(dev_type=constants.DT_EXT,
                                     params={
                                       constants.IDISK_PROVIDER: "pvdr"
                                     })]
    self.ext_storage_inst = \
      self.cfg.AddNewInstance(disk_template=constants.DT_EXT,
                              disks=ext_disks)
    self.ext_storage_op = \
      opcodes.OpInstanceSetParams(instance_name=self.ext_storage_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

    self.mocked_disk_uuid = "mock_uuid_1134"
    self.mocked_disk_name = "mock_disk_1134"

    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 in [self.inst.name, self.ext_storage_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, "No iallocator or node given and no cluster-wide default iallocator"
          " found; please specify either an iallocator or a node, or set a"
          " cluster-wide default iallocator")

  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_validate.return_value = True
    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 testAttachNICs(self):
    msg = "Attach operation is not supported for NICs"
    op = self.CopyOpCode(self.op,
                         nics=[(constants.DDM_ATTACH, -1, {})])
    self.ExecOpCodeExpectOpPrereqError(op, msg)

  def testNoHotplugSupport(self):
    op = self.CopyOpCode(self.op,
                         nics=[(constants.DDM_ADD, -1, {})],
                         hotplug=True)
    self.rpc.call_hotplug_supported.return_value = \
      self.RpcResultsBuilder() \
        .CreateFailedNodeResult(self.master)
    self.ExecOpCodeExpectOpPrereqError(op, "Hotplug is not possible")
    self.assertTrue(self.rpc.call_hotplug_supported.called)

  def testHotplugIfPossible(self):
    op = self.CopyOpCode(self.op,
                         nics=[(constants.DDM_ADD, -1, {})],
                         hotplug_if_possible=True)
    self.rpc.call_hotplug_supported.return_value = \
      self.RpcResultsBuilder() \
        .CreateFailedNodeResult(self.master)
    self.ExecOpCode(op)
    self.assertTrue(self.rpc.call_hotplug_supported.called)
    self.assertFalse(self.rpc.call_hotplug_device.called)

  def testHotAddNic(self):
    op = self.CopyOpCode(self.op,
                         nics=[(constants.DDM_ADD, -1, {})],
                         hotplug=True)
    self.rpc.call_hotplug_supported.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master)
    self.ExecOpCode(op)
    self.assertTrue(self.rpc.call_hotplug_supported.called)
    self.assertTrue(self.rpc.call_hotplug_device.called)

  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_NETWORK: constants.VALUE_NONE,
                                  constants.INIC_MODE: constants.NIC_MODE_ROUTED
                                })])
    self.ExecOpCodeExpectOpPrereqError(
      op, "Cannot set the NIC IP address to None on a routed NIC"
      " if not attached to a network")

  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 testHotModifyNic(self):
    op = self.CopyOpCode(self.op,
                         nics=[(constants.DDM_MODIFY, 0, {})],
                         hotplug=True)
    self.rpc.call_hotplug_supported.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master)
    self.ExecOpCode(op)
    self.assertTrue(self.rpc.call_hotplug_supported.called)
    self.assertTrue(self.rpc.call_hotplug_device.called)

  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 testDetachNICs(self):
    msg = "Detach operation is not supported for NICs"
    op = self.CopyOpCode(self.op,
                         nics=[(constants.DDM_DETACH, -1, {})])
    self.ExecOpCodeExpectOpPrereqError(op, msg)

  def testHotRemoveNic(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, {})],
                         hotplug=True)
    self.rpc.call_hotplug_supported.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master)
    self.ExecOpCode(op)
    self.assertTrue(self.rpc.call_hotplug_supported.called)
    self.assertTrue(self.rpc.call_hotplug_device.called)

  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 testAddDiskUnknownParam(self):
    op = self.CopyOpCode(self.op,
                         disks=[[constants.DDM_ADD, -1,
                                 {
                                   "uuid": self.mocked_disk_uuid
                                 }]])
    self.ExecOpCodeExpectException(
      op, errors.TypeEnforcementError, "Unknown parameter 'uuid'")

  def testAddDiskRunningInstanceNoWaitForSync(self):
    op = self.CopyOpCode(self.running_op,
                         disks=[[constants.DDM_ADD, -1,
                                 {
                                   constants.IDISK_SIZE: 1024
                                 }]],
                         wait_for_sync=False)
    self.ExecOpCode(op)
    self.assertFalse(self.rpc.call_blockdev_shutdown.called)

  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 testAddDiskIndexBased(self):
    SPECIFIC_SIZE = 435 * 4
    insertion_index = len(self.inst.disks)
    op = self.CopyOpCode(self.op,
                         disks=[[constants.DDM_ADD, insertion_index,
                                 {
                                   constants.IDISK_SIZE: SPECIFIC_SIZE
                                 }]])
    self.ExecOpCode(op)
    self.assertEqual(len(self.inst.disks), insertion_index + 1)
    new_disk = self.cfg.GetDisk(self.inst.disks[insertion_index])
    self.assertEqual(new_disk.size, SPECIFIC_SIZE)

  def testAddDiskHugeIndex(self):
    op = self.CopyOpCode(self.op,
                         disks=[[constants.DDM_ADD, 5,
                                 {
                                   constants.IDISK_SIZE: 1024
                                 }]])
    self.ExecOpCodeExpectException(
      op, IndexError, "Got disk index.*but there are only.*"
    )

  def testAddExtDisk(self):
    op = self.CopyOpCode(self.ext_storage_op,
                         disks=[[constants.DDM_ADD, -1,
                                 {
                                   constants.IDISK_SIZE: 1024
                                 }]])
    self.ExecOpCodeExpectOpPrereqError(op,
                                       "Missing provider for template 'ext'")

    op = self.CopyOpCode(self.ext_storage_op,
                         disks=[[constants.DDM_ADD, -1,
                                 {
                                   constants.IDISK_SIZE: 1024,
                                   constants.IDISK_PROVIDER: "bla"
                                 }]])
    self.ExecOpCode(op)

  def testAddDiskDownInstanceNoWaitForSync(self):
    op = self.CopyOpCode(self.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 deactivated disks"
          " and --no-wait-for-sync given")

  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 testHotAddDisk(self):
    self.rpc.call_blockdev_assemble.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master, ("/dev/mocked_path",
                                    "/var/run/ganeti/instance-disks/mocked_d",
                                    None))
    op = self.CopyOpCode(self.op,
                         disks=[[constants.DDM_ADD, -1,
                                 {
                                   constants.IDISK_SIZE: 1024,
                                 }]],
                         hotplug=True)
    self.rpc.call_hotplug_supported.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master)
    self.ExecOpCode(op)
    self.assertTrue(self.rpc.call_hotplug_supported.called)
    self.assertTrue(self.rpc.call_blockdev_create.called)
    self.assertTrue(self.rpc.call_blockdev_assemble.called)
    self.assertTrue(self.rpc.call_hotplug_device.called)

  def testAttachDiskWrongParams(self):
    msg = "Only one argument is permitted in attach op, either name or uuid"
    op = self.CopyOpCode(self.op,
                         disks=[[constants.DDM_ATTACH, -1,
                                 {
                                   constants.IDISK_SIZE: 1134
                                 }]],
                         )
    self.ExecOpCodeExpectOpPrereqError(op, msg)
    op = self.CopyOpCode(self.op,
                         disks=[[constants.DDM_ATTACH, -1,
                                 {
                                   'uuid': "1134",
                                   constants.IDISK_NAME: "1134",
                                 }]],
                         )
    self.ExecOpCodeExpectOpPrereqError(op, msg)
    op = self.CopyOpCode(self.op,
                         disks=[[constants.DDM_ATTACH, -1,
                                 {
                                   'uuid': "1134",
                                   constants.IDISK_SIZE: 1134,
                                 }]],
                         )
    self.ExecOpCodeExpectOpPrereqError(op, msg)

  def testAttachDiskWrongTemplate(self):
    msg = "Instance has '%s' template while disk has '%s' template" % \
      (constants.DT_PLAIN, constants.DT_BLOCK)
    self.cfg.AddOrphanDisk(name=self.mocked_disk_name,
                           dev_type=constants.DT_BLOCK)
    op = self.CopyOpCode(self.op,
                         disks=[[constants.DDM_ATTACH, -1,
                                 {
                                   constants.IDISK_NAME: self.mocked_disk_name
                                 }]],
                         )
    self.ExecOpCodeExpectOpPrereqError(op, msg)

  def testAttachDiskWrongNodes(self):
    msg = "Disk nodes are \['mock_node_1134'\]"

    self.cfg.AddOrphanDisk(name=self.mocked_disk_name,
                           primary_node="mock_node_1134")
    op = self.CopyOpCode(self.op,
                         disks=[[constants.DDM_ATTACH, -1,
                                 {
                                   constants.IDISK_NAME: self.mocked_disk_name
                                 }]],
                         )
    self.ExecOpCodeExpectOpPrereqError(op, msg)

  def testAttachDiskRunningInstance(self):
    self.cfg.AddOrphanDisk(name=self.mocked_disk_name,
                           primary_node=self.master.uuid)
    self.rpc.call_blockdev_assemble.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master,
                                    ("/dev/mocked_path",
                                     "/var/run/ganeti/instance-disks/mocked_d",
                                     None))
    op = self.CopyOpCode(self.running_op,
                         disks=[[constants.DDM_ATTACH, -1,
                                 {
                                   constants.IDISK_NAME: self.mocked_disk_name
                                 }]],
                         )
    self.ExecOpCode(op)
    self.assertTrue(self.rpc.call_blockdev_assemble.called)
    self.assertFalse(self.rpc.call_blockdev_shutdown.called)

  def testAttachDiskRunningInstanceNoWaitForSync(self):
    self.cfg.AddOrphanDisk(name=self.mocked_disk_name,
                           primary_node=self.master.uuid)
    self.rpc.call_blockdev_assemble.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master,
                                    ("/dev/mocked_path",
                                     "/var/run/ganeti/instance-disks/mocked_d",
                                     None))
    op = self.CopyOpCode(self.running_op,
                         disks=[[constants.DDM_ATTACH, -1,
                                 {
                                   constants.IDISK_NAME: self.mocked_disk_name
                                 }]],
                         wait_for_sync=False)
    self.ExecOpCode(op)
    self.assertTrue(self.rpc.call_blockdev_assemble.called)
    self.assertFalse(self.rpc.call_blockdev_shutdown.called)

  def testAttachDiskDownInstance(self):
    self.cfg.AddOrphanDisk(name=self.mocked_disk_name,
                           primary_node=self.master.uuid)
    op = self.CopyOpCode(self.op,
                         disks=[[constants.DDM_ATTACH, -1,
                                 {
                                   constants.IDISK_NAME: self.mocked_disk_name
                                 }]])
    self.ExecOpCode(op)

    self.assertTrue(self.rpc.call_blockdev_assemble.called)
    self.assertTrue(self.rpc.call_blockdev_shutdown.called)

  def testAttachDiskDownInstanceNoWaitForSync(self):
    self.cfg.AddOrphanDisk(name=self.mocked_disk_name)
    op = self.CopyOpCode(self.op,
                         disks=[[constants.DDM_ATTACH, -1,
                                 {
                                   constants.IDISK_NAME: self.mocked_disk_name
                                 }]],
                         wait_for_sync=False)
    self.ExecOpCodeExpectOpPrereqError(
      op, "Can't attach a disk to an instance with deactivated disks"
          " and --no-wait-for-sync given.")

  def testHotAttachDisk(self):
    self.cfg.AddOrphanDisk(name=self.mocked_disk_name,
                           primary_node=self.master.uuid)
    self.rpc.call_blockdev_assemble.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master,
                                    ("/dev/mocked_path",
                                     "/var/run/ganeti/instance-disks/mocked_d",
                                     None))
    op = self.CopyOpCode(self.op,
                         disks=[[constants.DDM_ATTACH, -1,
                                 {
                                   constants.IDISK_NAME: self.mocked_disk_name
                                 }]],
                         hotplug=True)
    self.rpc.call_hotplug_supported.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master)
    self.ExecOpCode(op)
    self.assertTrue(self.rpc.call_hotplug_supported.called)
    self.assertTrue(self.rpc.call_blockdev_assemble.called)
    self.assertTrue(self.rpc.call_hotplug_device.called)

  def testHotRemoveDisk(self):
    inst = self.cfg.AddNewInstance(disks=[self.cfg.CreateDisk(),
                                          self.cfg.CreateDisk()])
    op = self.CopyOpCode(self.op,
                         instance_name=inst.name,
                         disks=[[constants.DDM_REMOVE, -1,
                                 {}]],
                         hotplug=True)
    self.rpc.call_hotplug_supported.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master)
    self.ExecOpCode(op)
    self.assertTrue(self.rpc.call_hotplug_supported.called)
    self.assertTrue(self.rpc.call_hotplug_device.called)
    self.assertTrue(self.rpc.call_blockdev_shutdown.called)
    self.assertTrue(self.rpc.call_blockdev_remove.called)

  def testHotDetachDisk(self):
    inst = self.cfg.AddNewInstance(disks=[self.cfg.CreateDisk(),
                                          self.cfg.CreateDisk()])
    op = self.CopyOpCode(self.op,
                         instance_name=inst.name,
                         disks=[[constants.DDM_DETACH, -1,
                                 {}]],
                         hotplug=True)
    self.rpc.call_hotplug_supported.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master)
    self.ExecOpCode(op)
    self.assertTrue(self.rpc.call_hotplug_supported.called)
    self.assertTrue(self.rpc.call_hotplug_device.called)
    self.assertTrue(self.rpc.call_blockdev_shutdown.called)

  def testDetachAttachFileBasedDisk(self):
    """Detach and re-attach a disk from a file-based instance."""
    # Create our disk and calculate the path where it is stored, its name, as
    # well as the expected path where it will be moved.
    mock_disk = self.cfg.CreateDisk(
      name='mock_disk_1134', dev_type=constants.DT_FILE,
      logical_id=('loop', '/tmp/instance/disk'), primary_node=self.master.uuid)

    # Create a file-based instance
    file_disk = self.cfg.CreateDisk(
      dev_type=constants.DT_FILE,
      logical_id=('loop', '/tmp/instance/disk2'))
    inst = self.cfg.AddNewInstance(name='instance',
                                   disk_template=constants.DT_FILE,
                                   disks=[file_disk, mock_disk],
                                  )

    # Detach the disk and assert that it has been moved to the upper directory
    op = self.CopyOpCode(self.op,
                         instance_name=inst.name,
                         disks=[[constants.DDM_DETACH, -1,
                                 {}]],
                         )
    self.ExecOpCode(op)
    mock_disk = self.cfg.GetDiskInfo(mock_disk.uuid)
    self.assertEqual('/tmp/disk', mock_disk.logical_id[1])

    # Re-attach the disk and assert that it has been moved to the original
    # directory
    op = self.CopyOpCode(self.op,
                         instance_name=inst.name,
                         disks=[[constants.DDM_ATTACH, -1,
                                 {
                                   constants.IDISK_NAME: self.mocked_disk_name
                                 }]],
                         )
    self.ExecOpCode(op)
    mock_disk = self.cfg.GetDiskInfo(mock_disk.uuid)
    self.assertIn('/tmp/instance', mock_disk.logical_id[1])

  def testAttachDetachDisk(self):
    """Check if the disks can be attached and detached in sequence.

    Also, check if the operations succeed both with name and uuid.
    """
    disk1 = self.cfg.CreateDisk(uuid=self.mocked_disk_uuid,
                                primary_node=self.master.uuid)
    disk2 = self.cfg.CreateDisk(name="mock_name_1134",
                                primary_node=self.master.uuid)

    inst = self.cfg.AddNewInstance(disks=[disk1, disk2])

    op = self.CopyOpCode(self.op,
                         instance_name=inst.name,
                         disks=[[constants.DDM_DETACH, self.mocked_disk_uuid,
                                 {}]])
    self.ExecOpCode(op)
    self.assertEqual([disk2], self.cfg.GetInstanceDisks(inst.uuid))

    op = self.CopyOpCode(self.op,
                         instance_name=inst.name,
                         disks=[[constants.DDM_ATTACH, 0,
                                 {
                                   'uuid': self.mocked_disk_uuid
                                 }]])
    self.ExecOpCode(op)
    self.assertEqual([disk1, disk2], self.cfg.GetInstanceDisks(inst.uuid))

    op = self.CopyOpCode(self.op,
                         instance_name=inst.name,
                         disks=[[constants.DDM_DETACH, 1,
                                 {}]])
    self.ExecOpCode(op)
    self.assertEqual([disk1], self.cfg.GetInstanceDisks(inst.uuid))

    op = self.CopyOpCode(self.op,
                         instance_name=inst.name,
                         disks=[[constants.DDM_ATTACH, 0,
                                 {
                                   constants.IDISK_NAME: "mock_name_1134"
                                 }]])
    self.ExecOpCode(op)
    self.assertEqual([disk2, disk1], self.cfg.GetInstanceDisks(inst.uuid))

  def testDetachAndAttachToDisklessInstance(self):
    """Check if a disk can be detached and then re-attached if the instance is
    diskless inbetween.

    """
    disk = self.cfg.CreateDisk(uuid=self.mocked_disk_uuid,
                               primary_node=self.master.uuid)

    inst = self.cfg.AddNewInstance(disks=[disk], primary_node=self.master)

    op = self.CopyOpCode(self.op,
                         instance_name=inst.name,
                         disks=[[constants.DDM_DETACH,
                         self.mocked_disk_uuid, {}]])

    self.ExecOpCode(op)
    self.assertEqual([], self.cfg.GetInstanceDisks(inst.uuid))

    op = self.CopyOpCode(self.op,
                         instance_name=inst.name,
                         disks=[[constants.DDM_ATTACH, 0,
                                 {
                                   'uuid': self.mocked_disk_uuid
                                 }]])
    self.ExecOpCode(op)
    self.assertEqual([disk], self.cfg.GetInstanceDisks(inst.uuid))

  def testDetachAttachDrbdDisk(self):
    """Check if a DRBD disk can be detached and then re-attached.

    """
    disk = self.cfg.CreateDisk(uuid=self.mocked_disk_uuid,
                               primary_node=self.master.uuid,
                               secondary_node=self.snode.uuid,
                               dev_type=constants.DT_DRBD8)

    inst = self.cfg.AddNewInstance(disks=[disk], primary_node=self.master)

    op = self.CopyOpCode(self.op,
                         instance_name=inst.name,
                         disks=[[constants.DDM_DETACH,
                         self.mocked_disk_uuid, {}]])

    self.ExecOpCode(op)
    self.assertEqual([], self.cfg.GetInstanceDisks(inst.uuid))

    op = self.CopyOpCode(self.op,
                         instance_name=inst.name,
                         disks=[[constants.DDM_ATTACH, 0,
                                 {
                                   'uuid': self.mocked_disk_uuid
                                 }]])
    self.ExecOpCode(op)
    self.assertEqual([disk], self.cfg.GetInstanceDisks(inst.uuid))

  def testDetachAttachDrbdDiskWithWrongPrimaryNode(self):
    """Check if disk attachment with a wrong primary node fails.

    """
    disk1 = self.cfg.CreateDisk(uuid=self.mocked_disk_uuid,
                               primary_node=self.master.uuid,
                               secondary_node=self.snode.uuid,
                               dev_type=constants.DT_DRBD8)

    inst1 = self.cfg.AddNewInstance(disks=[disk1], primary_node=self.master,
                                    secondary_node=self.snode)

    op = self.CopyOpCode(self.op,
                         instance_name=inst1.name,
                         disks=[[constants.DDM_DETACH,
                         self.mocked_disk_uuid, {}]])

    self.ExecOpCode(op)
    self.assertEqual([], self.cfg.GetInstanceDisks(inst1.uuid))

    disk2 = self.cfg.CreateDisk(uuid="mock_uuid_1135",
                               primary_node=self.snode.uuid,
                               secondary_node=self.master.uuid,
                               dev_type=constants.DT_DRBD8)

    inst2 = self.cfg.AddNewInstance(disks=[disk2], primary_node=self.snode,
                                    secondary_node=self.master)

    op = self.CopyOpCode(self.op,
                         instance_name=inst2.name,
                         disks=[[constants.DDM_ATTACH, 0,
                                 {
                                   'uuid': self.mocked_disk_uuid
                                 }]])

    self.assertRaises(errors.OpExecError, self.ExecOpCode, op)


  def testDetachAttachExtDisk(self):
    """Check attach/detach functionality of ExtStorage disks.

    """
    disk = self.cfg.CreateDisk(uuid=self.mocked_disk_uuid,
                               dev_type=constants.DT_EXT,
                               params={
                                 constants.IDISK_PROVIDER: "pvdr"
                               })

    inst = self.cfg.AddNewInstance(disks=[disk], primary_node=self.master)

    op = self.CopyOpCode(self.op,
                         instance_name=inst.name,
                         disks=[[constants.DDM_DETACH,
                         self.mocked_disk_uuid, {}]])

    self.ExecOpCode(op)
    self.assertEqual([], self.cfg.GetInstanceDisks(inst.uuid))

    op = self.CopyOpCode(self.op,
                         instance_name=inst.name,
                         disks=[[constants.DDM_ATTACH, 0,
                                 {
                                   'uuid': self.mocked_disk_uuid
                                 }]])
    self.ExecOpCode(op)
    self.assertEqual([disk], self.cfg.GetInstanceDisks(inst.uuid))

  def testRemoveDiskRemovesStorageDir(self):
    inst = self.cfg.AddNewInstance(disks=[self.cfg.CreateDisk(dev_type='file')])
    op = self.CopyOpCode(self.op,
                         instance_name=inst.name,
                         disks=[[constants.DDM_REMOVE, -1,
                                 {}]])
    self.rpc.call_file_storage_dir_remove.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master)
    self.ExecOpCode(op)
    self.rpc.call_file_storage_dir_remove.assert_called_with(
        self.master.uuid, '/file/storage')

  def testRemoveDiskKeepsStorageForRemaining(self):
    inst = self.cfg.AddNewInstance(disks=[self.cfg.CreateDisk(dev_type='file'),
                                          self.cfg.CreateDisk(dev_type='file')])
    op = self.CopyOpCode(self.op,
                         instance_name=inst.name,
                         disks=[[constants.DDM_REMOVE, -1,
                                 {}]])
    self.rpc.call_file_storage_dir_remove.return_value = \
      self.RpcResultsBuilder() \
        .CreateSuccessfulNodeResult(self.master)
    self.ExecOpCode(op)
    self.assertFalse(self.rpc.call_file_storage_dir_remove.called)

  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.ExecOpCodeExpectException(op, errors.TypeEnforcementError,
                                   "Unknown parameter 'metavg'")

  def testModifyDiskUnsetName(self):
    op = self.CopyOpCode(self.op,
                         disks=[[constants.DDM_MODIFY, 0,
                                  {
                                    constants.IDISK_NAME: constants.VALUE_NONE
                                  }]])
    self.ExecOpCode(op)

  def testModifyExtDiskProvider(self):
    mod = [[constants.DDM_MODIFY, 0,
             {
               constants.IDISK_PROVIDER: "anything"
             }]]
    op = self.CopyOpCode(self.op, disks=mod)
    self.ExecOpCodeExpectException(op, errors.TypeEnforcementError,
                                   "Unknown parameter 'provider'")

    op = self.CopyOpCode(self.ext_storage_op, disks=mod)
    self.ExecOpCodeExpectOpPrereqError(op, "Disk 'provider' parameter change"
                                           " is not possible")

  def testSetOldDiskTemplate(self):
    op = self.CopyOpCode(self.op,
                         disk_template=self.dev_type)
    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 testConvertToExtWithMissingProvider(self):
    op = self.CopyOpCode(self.op,
                         disk_template=constants.DT_EXT)
    self.ExecOpCodeExpectOpPrereqError(
      op, "Missing provider for template .*")

  def testConvertToNotExtWithProvider(self):
    op = self.CopyOpCode(self.op,
                         disk_template=constants.DT_FILE,
                         ext_params={constants.IDISK_PROVIDER: "pvdr"})
    self.ExecOpCodeExpectOpPrereqError(
      op, "The 'provider' option is only valid for the ext disk"
          " template, not .*")

  def testConvertToExtWithSameProvider(self):
    op = self.CopyOpCode(self.ext_storage_op,
                         disk_template=constants.DT_EXT,
                         ext_params={constants.IDISK_PROVIDER: "pvdr"})
    self.ExecOpCodeExpectOpPrereqError(
      op, "Not converting, 'disk/0' of type ExtStorage already using"
          " provider 'pvdr'")

  def testConvertToInvalidDiskTemplate(self):
    for disk_template in constants.DTS_NOT_CONVERTIBLE_TO:
      op = self.CopyOpCode(self.op,
                           disk_template=disk_template)
      self.ExecOpCodeExpectOpPrereqError(
        op, "Conversion to the .* disk template is not supported")

  def testConvertFromInvalidDiskTemplate(self):
    for disk_template in constants.DTS_NOT_CONVERTIBLE_FROM:
      inst = self.cfg.AddNewInstance(disk_template=disk_template)
      op = self.CopyOpCode(self.op,
                           instance_name=inst.name,
                           disk_template=constants.DT_PLAIN)
      self.ExecOpCodeExpectOpPrereqError(
        op, "Conversion from the .* disk template is not supported")

  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):
    for disk_uuid in self.inst.disks:
      self.cfg.RemoveInstanceDisk(self.inst.uuid, disk_uuid)
    disk = self.cfg.CreateDisk(dev_type=constants.DT_DRBD8,
                               primary_node=self.master,
                               secondary_node=self.snode)
    self.cfg.AddInstanceDisk(self.inst.uuid, disk)
    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()
