On Sat, Dec 13, 2014 at 05:06:51PM +0200, Alex Pyrgiotis wrote:
> On 11/10/2014 06:21 PM, Aaron Karper wrote:
> > On Thu, Nov 06, 2014 at 12:30:51AM +0200, Alex Pyrgiotis wrote:
> >> Also, update the mocked config to create orphan disks for attach
> >> purposes.
> >>
> >> Signed-off-by: Alex Pyrgiotis <[email protected] <mailto:[email protected]>>
> >>
> >> diff --git a/test/py/cmdlib/instance___unittest.py
> > b/test/py/cmdlib/instance___unittest.py
> >> index 9ff2cde..902c070 100644
> >> --- a/test/py/cmdlib/instance___unittest.py
> >> +++ b/test/py/cmdlib/instance___unittest.py
> >> @@ -2235,6 +2235,12 @@ class TestLUInstanceSetParams(__CmdlibTestCase):
> >>                           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, {})],
> >> @@ -2377,6 +2383,12 @@ class TestLUInstanceSetParams(__CmdlibTestCase):
> >>                           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()])
> >> @@ -2425,6 +2437,15 @@ class TestLUInstanceSetParams(__CmdlibTestCase):
> >>      self.__ExecOpCodeExpectException(
> >>        op, errors.TypeEnforcementError, "is not a valid size")
> >>
> >> +  def testAddDiskUnkownParam(self):
> > 
> > s/Unkown/Unknown/
> > 
> 
> ACK
> 
> >>
> >> +    op = self.CopyOpCode(self.op,
> >> +                         disks=[[constants.DDM_ADD, -1,
> >> +                                 {
> >> +                                   "uuid": "mock_uuid_1134"
> >> +                                 }]])
> >> +    self.__ExecOpCodeExpectException(
> >> +      op, errors.TypeEnforcementError, "Unknown parameter 'uuid'")
> >> +
> >>    def testAddDiskRunningInstanceNoWa__itForSync(self):
> >>      op = self.CopyOpCode(self.running___op,
> >>                           disks=[[constants.DDM_ADD, -1,
> >> @@ -2454,7 +2475,7 @@ class TestLUInstanceSetParams(__CmdlibTestCase):
> >>                           wait_for_sync=False)
> >>      self.__ExecOpCodeExpectOpPrereqError(
> >>        op, "Can't add a disk to an instance with deactivated disks"
> >> -          " and --no-wait-for-sync given.")
> >> +          " and --no-wait-for-sync given")
> >>
> >>    def testAddDiskRunningInstance(__self):
> >>      op = self.CopyOpCode(self.running___op,
> >> @@ -2496,6 +2517,113 @@ class TestLUInstanceSetParams(__CmdlibTestCase):
> >>      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"
> >> +    self.cfg.AddOrphanDisk()
> > 
> > This seems unrelated, you don't give uuid or name. Can this be removed?
> > 
> 
> ACK, you're right.
> 
> >> +    op = self.CopyOpCode(self.op,
> >> +                         disks=[[constants.DDM_ATTACH, -1,
> >> +                                 {
> >> +                                   constants.IDISK_SIZE: 1134
> >> +                                 }]],
> >> +                         )
> >> +    self.__ExecOpCodeExpectOpPrereqError(__op, msg)
> > 
> > break into test methods.
> > 
> 
> Hm, isn't this an overkill? After all, this test case contains three
> assertions that test just one thing; if the client produces an error
> when it is not given either a UUID or a disk name in an attach operation.
> 
> Splitting the test case is not a problem of course, it's just that I
> believe that in this case the "One concept per test" paradigm fits
> better than the "One assertion per test". Also, if I'm not mistaken,
> most tests in Ganeti follow the former way of testing and I was trying
> to be consistent.
> 

You're right, we can keep it as concept/scenario per test case.

> >>
> >> +    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="__mock_disk_1134",
> > dev_type=constants.DT_BLOCK)
> >> +    op = self.CopyOpCode(self.op,
> >> +                         disks=[[constants.DDM_ATTACH, -1,
> >> +                                 {
> >> +                                   constants.IDISK_NAME: "mock_disk_1134"
> >> +                                 }]],
> >> +                         )
> >> +    self.__ExecOpCodeExpectOpPrereqError(__op, msg)
> >> +
> >> +  def testAttachDiskWrongNodes(self)__:
> >> +    msg = "Disk nodes are \['mock_node_1134'\]"
> >> +
> >> +    self.cfg.AddOrphanDisk(name="__mock_disk_1134",
> > primary_node="mock_node_1134")
> >> +    op = self.CopyOpCode(self.op,
> >> +                         disks=[[constants.DDM_ATTACH, -1,
> >> +                                 {
> >> +                                   constants.IDISK_NAME: "mock_disk_1134"
> >> +                                 }]],
> >> +                         )
> >> +    self.__ExecOpCodeExpectOpPrereqError(__op, msg)
> >> +
> >> +  def testAttachDiskRunningInstanceN__oWaitForSync(self):
> >> +    self.cfg.AddOrphanDisk(name="__mock_disk_1134")
> >> +    op = self.CopyOpCode(self.running___op,
> >> +                         disks=[[constants.DDM_ATTACH, -1,
> >> +                                 {
> >> +                                   constants.IDISK_NAME: "mock_disk_1134"
> >> +                                 }]],
> >> +                         wait_for_sync=False)
> >> +    self.ExecOpCode(op)
> >> +    self.assertFalse(self.rpc.__call_blockdev_shutdown.called)
> >> +
> >> +  def testAttachDiskDownInstance(__self):
> >> +    self.cfg.AddOrphanDisk(name="__mock_disk_1134")
> >> +    op = self.CopyOpCode(self.op,
> >> +                         disks=[[constants.DDM_ATTACH, -1,
> >> +                                 {
> >> +                                   constants.IDISK_NAME: "mock_disk_1134"
> >> +                                 }]])
> >> +    self.ExecOpCode(op)
> >> +
> >> +    self.assertTrue(self.rpc.call___blockdev_shutdown.called)
> >> +
> >> +  def testAttachDiskDownInstanceNoWa__itForSync(self):
> >> +    self.cfg.AddOrphanDisk(name="__mock_disk_1134")
> >> +    op = self.CopyOpCode(self.op,
> >> +                         disks=[[constants.DDM_ATTACH, -1,
> >> +                                 {
> >> +                                   constants.IDISK_NAME: "mock_disk_1134"
> >> +                                 }]],
> >> +                         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="__mock_disk_1134")
> >> +    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: "mock_disk_1134"
> >> +                                 }]],
> >> +                         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()])
> >> @@ -2513,6 +2641,60 @@ class TestLUInstanceSetParams(__CmdlibTestCase):
> >>      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 <http://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 testAttachDetachDisk(self):
> >> +    """Check if the disks can be attached and detached in sequence.
> >> +
> >> +    Also, check if the operations succeed both with name and uuid.
> >> +    """
> >> +    inst = self.cfg.AddNewInstance(disks=__[
> >> +      self.cfg.CreateDisk(uuid="__mock_uuid_1134"),
> >> +      self.cfg.CreateDisk(name="__mock_name_1134")
> >> +    ])
> >> +    disks = self.cfg.GetInstanceDisks(__inst.uuid)
> >> +    disks.reverse()
> > 
> > nitpic: disks = reversed(self.cfg.__GetInstanceDisks(inst.uuid))
> > 
> 
> ACK
> 
> >> +
> >> +    op = self.CopyOpCode(self.op,
> >> +                         instance_name=inst.name <http://inst.name>,
> >> +                         disks=[[constants.DDM_DETACH, "mock_uuid_1134",
> >> +                                 {}]])
> >> +    self.ExecOpCode(op)
> > 
> > Assert that there are no disks attached to the instance.
> > 
> 
> ACK
> 
> >> +    op = self.CopyOpCode(self.op,
> >> +                         instance_name=inst.name <http://inst.name>,
> >> +                         disks=[[constants.DDM_ATTACH, 0,
> >> +                                 {
> >> +                                   'uuid': "mock_uuid_1134"
> >> +                                 }]])
> >> +    self.ExecOpCode(op)
> > 
> > Assert that the disk is attached now.
> > 
> 
> ACK
> 
> >> +    op = self.CopyOpCode(self.op,
> >> +                         instance_name=inst.name <http://inst.name>,
> >> +                         disks=[[constants.DDM_DETACH, "mock_name_1134",
> >> +                                 {}]])
> > 
> > Assert that there are no disks attached to the instance.
> > 
> 
> ACK
> 
> >> +    self.ExecOpCode(op)
> >> +    op = self.CopyOpCode(self.op,
> >> +                         instance_name=inst.name <http://inst.name>,
> >> +                         disks=[[constants.DDM_ATTACH, 0,
> >> +                                 {
> >> +                                   constants.IDISK_NAME: "mock_name_1134"
> >> +                                 }]])
> >> +    self.ExecOpCode(op)
> >> +    self.assertEqual(disks, self.cfg.GetInstanceDisks(__inst.uuid))
> >> +
> >>    def testModifyDiskWithSize(self):
> >>      op = self.CopyOpCode(self.op,
> >>                           disks=[[constants.DDM_MODIFY, 0,
> >> diff --git a/test/py/cmdlib/testsupport/__config_mock.py
> > b/test/py/cmdlib/testsupport/__config_mock.py
> >> index 984a14d..97fc615 100644
> >> --- a/test/py/cmdlib/testsupport/__config_mock.py
> >> +++ b/test/py/cmdlib/testsupport/__config_mock.py
> >> @@ -345,6 +345,10 @@ class ConfigMock(config.__ConfigWriter):
> >>      self.AddNetwork(net, None)
> >>      return net
> >>
> >> +  def AddOrphanDisk(self, **params):
> >> +    disk = self.CreateDisk(**params)  # pylint: disable=W0142
> >> +    self._UnlockedAddDisk(disk)
> >> +
> >>    def ConnectNetworkToGroup(self, net, group, netparams=None):
> >>      """Connect the given network to the group.
> >>
> >> @@ -385,6 +389,7 @@ class ConfigMock(config.__ConfigWriter):
> >>                   dev_type=constants.DT_PLAIN,
> >>                   logical_id=None,
> >>                   children=None,
> >> +                 nodes=[],
> > 
> > You can't use mutable objects as default arguments because if they are
> > modified in the function body, the next call will use the updated
> > version. Of course this isn't the case here, but our lint prohibits it
> > anyway.
> > 
> 
> ACK
> 
> >>                   iv_name=None,
> >>                   size=1024,
> >>                   mode=constants.DISK_RDWR,
> >> @@ -435,12 +440,20 @@ class ConfigMock(config.__ConfigWriter):
> >>          meta_child = self.CreateDisk(dev_type=__constants.DT_PLAIN,
> >>                                       size=constants.DRBD_META_SIZE)
> >>          children = [data_child, meta_child]
> >> +
> >> +      if nodes is []:
> >> +        nodes = [pnode_uuid, snode_uuid]
> > 
> > This would fail, since '[] is []' is 'False' (they are not the same
> > reference). Use 'nodes is None' and that as the default argument.
> > 
> 
> ACK
> 
> >>      elif dev_type == constants.DT_PLAIN:
> >>        if logical_id is None:
> >>          logical_id = ("mockvg", "mock_disk_%d" % disk_id)
> >> +      if nodes == [] and primary_node is not None:
> >> +          nodes = [primary_node]
> >>      elif dev_type in constants.DTS_FILEBASED:
> >>        if logical_id is None:
> >>          logical_id = (constants.FD_LOOP, "/file/storage/disk%d" %
> > disk_id)
> >> +      if (nodes == [] and primary_node is not None and
> >> +          dev_type == constants.DT_FILE):
> >> +          nodes = [primary_node]
> >>      elif dev_type == constants.DT_BLOCK:
> >>        if logical_id is None:
> >>          logical_id = (constants.BLOCKDEV_DRIVER___MANUAL,
> >> @@ -463,6 +476,7 @@ class ConfigMock(config.__ConfigWriter):
> >>                          dev_type=dev_type,
> >>                          logical_id=logical_id,
> >>                          children=children,
> >> +                        nodes=nodes,
> >>                          iv_name=iv_name,
> >>                          size=size,
> >>                          mode=mode,
> >> --
> >> 1.7.10.4
> >>
> > 
> > --
> > Google Germany GmbH
> > Dienerstr. 12
> > 80331 München
> > 
> > Registergericht und -nummer: Hamburg, HRB 86891
> > Sitz der Gesellschaft: Hamburg
> > Geschäftsführer: Graham Law, Christine Elizabeth Flores
> 
> 
> -- 
> Alex | [email protected]

-- 
Google Germany GmbH
Dienerstr. 12
80331 München

Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg
Geschäftsführer: Graham Law, Christine Elizabeth Flores

Reply via email to