def test_get_attach_point(self, mock_vm_info, mock_controller_disks):
        mock_vm_info.return_value = mock.sentinel.instance_info
        mock_controller_disks.return_value = {
            (0, 0): {"path": mock.sentinel.path,
                     "uuid": mock.sentinel.uuid}
        }

        self.assertEqual((0, 0), vhdutils.get_attach_point(
            self._instance, "SATA", mock.sentinel.uuid))
        self.assertIsNone(vhdutils.get_attach_point(
            self._instance, "SATA", mock.sentinel.alt_uuid))
    def test_get_attach_point(self, mock_vm_info, mock_controller_disks):
        mock_vm_info.return_value = mock.sentinel.instance_info
        mock_controller_disks.return_value = {
            (0, 0): {
                "path": mock.sentinel.path,
                "uuid": mock.sentinel.uuid
            }
        }

        self.assertEqual((0, 0),
                         vhdutils.get_attach_point(self._instance, "SATA",
                                                   mock.sentinel.uuid))
        self.assertIsNone(
            vhdutils.get_attach_point(self._instance, "SATA",
                                      mock.sentinel.alt_uuid))
    def detach_volume(self, instance, connection_info):
        """Detach a volume to the SCSI controller.

        .. notes:
            This action require the instance to be powered off
        """
        LOG.debug("Detach_volume: %(connection_info)s from %(instance_name)s",
                  {'connection_info': connection_info,
                   'instance_name': instance.name})
        volume_uuid = volumeutils.volume_uuid(connection_info)
        if not volume_uuid:
            LOG.warning(
                _LW("The volume %(connection_info)s is not registered."),
                {"connection_info": connection_info})
            return

        try:
            device, port = vhdutils.get_attach_point(
                instance, constants.SYSTEM_BUS_SCSI.upper(), volume_uuid)
        except TypeError:
            LOG.warning(
                _LW("Fail to get attach point for %(volume_uuid)s"),
                {"volume_uuid": volume_uuid})
            self._vbox_manage.close_medium(constants.MEDIUM_DISK, volume_uuid)
            return

        try:
            self._vbox_manage.storage_attach(
                instance, constants.SYSTEM_BUS_SCSI.upper(), port, device,
                drive_type=constants.STORAGE_HDD,
                medium=constants.MEDIUM_NONE)
            self._vbox_manage.close_medium(constants.MEDIUM_DISK, volume_uuid)
        except (vbox_exc.VBoxException, exception.InstanceInvalidState) as exc:
            with excutils.save_and_reraise_exception():
                LOG.error(_LE("Unable to attach volume to "
                              "instance %(instance)s: %(reason)s"),
                          {"instance": instance.name, "reason": exc})