#!/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 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

    for params in disk_info:
      utils.ForceDictType(params, constants.IDISK_PARAMS_TYPES)

    # 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([d.iv_name for d in 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([d.logical_id for d in result], [
      ("xenvg", "ec1-uq0.disk3"),
      ("othervg", "ec1-uq1.disk4"),
      ])
    self.assertEqual([d.nodes for d in 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([d.logical_id for d in result],
                         expected)
        self.assertEqual([d.nodes for d in result], [
          [], [], []])
      else:
        if disk_template == constants.DT_FILE:
          self.assertEqual([d.nodes for d in result], [
            ["node21741.example.com"], ["node21741.example.com"],
            ["node21741.example.com"]])
        else:
          self.assertEqual([d.nodes for d in 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([d.logical_id for d in result], [
      (constants.BLOCKDEV_DRIVER_MANUAL, "/tmp/some/block/dev"),
      ])
    self.assertEqual([d.nodes for d in 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([d.logical_id for d in result], [
      ("rbd", "ec1-uq0.rbd.disk0"),
      ("rbd", "ec1-uq1.rbd.disk1"),
      ])
    self.assertEqual([d.nodes for d in 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)

    for params in disk_info:
      utils.ForceDictType(params, constants.IDISK_PARAMS_TYPES)

    # 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([d.logical_id for d in 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([d.logical_id for d in 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()
