'Make sure volume can be attached and detached from instance.'

@ddt.data(False, True)
def test_run_attach_detach_volume_for_instance(self, volume_object):

    mountpoint = '/dev/sdf'
    instance_uuid = '12345678-1234-5678-1234-567812345678'
    volume = tests_utils.create_volume(self.user_context, **self.volume_params)
    with volume.obj_as_admin():
        volume.admin_metadata['readonly'] = True
        volume.save()
    volume_id = volume.id
    self.volume.create_volume(self.user_context, volume=volume)
    volume_passed = (volume if volume_object else None)
    attachment = self.volume.attach_volume(self.user_context, volume_id, instance_uuid, None, mountpoint, 'ro', volume=volume_passed)
    attachment2 = self.volume.attach_volume(self.user_context, volume_id, instance_uuid, None, mountpoint, 'ro', volume=volume_passed)
    self.assertEqual(attachment.id, attachment2.id)
    vol = objects.Volume.get_by_id(self.context, volume_id)
    self.assertEqual('in-use', vol.status)
    self.assertEqual(fields.VolumeAttachStatus.ATTACHED, attachment.attach_status)
    self.assertEqual(mountpoint, attachment.mountpoint)
    self.assertEqual(instance_uuid, attachment.instance_uuid)
    self.assertIsNone(attachment.attached_host)
    admin_metadata = vol.volume_admin_metadata
    self.assertEqual(2, len(admin_metadata))
    expected = dict(readonly='True', attached_mode='ro')
    ret = {}
    for item in admin_metadata:
        ret.update({item['key']: item['value']})
    self.assertDictEqual(expected, ret)
    connector = {'initiator': 'iqn.2012-07.org.fake:01'}
    volume = (volume if volume_object else vol)
    conn_info = self.volume.initialize_connection(self.context, volume, connector)
    self.assertEqual('ro', conn_info['data']['access_mode'])
    self.assertRaises(exception.VolumeAttached, self.volume.delete_volume, self.context, volume=volume)
    self.volume.detach_volume(self.context, volume_id, attachment.id, volume=volume_passed)
    vol = objects.Volume.get_by_id(self.context, volume_id)
    self.assertEqual('available', vol.status)
    self.volume.delete_volume(self.context, volume)
    self.assertRaises(exception.VolumeNotFound, db.volume_get, self.context, volume_id)
