'Tests a swap volume operation with a new style volume attachment
passed in from the compute API, and the case that Cinder initiated
the swap volume because of a volume retype situation. This is a happy
path test. Since it is a retype there is no volume size change.'

@mock.patch.object(compute_utils, 'notify_about_volume_swap')
@mock.patch.object(objects.BlockDeviceMapping, 'get_by_volume_and_instance')
@mock.patch('nova.volume.cinder.API.get')
@mock.patch('nova.volume.cinder.API.attachment_update')
@mock.patch('nova.volume.cinder.API.attachment_delete')
@mock.patch('nova.volume.cinder.API.migrate_volume_completion', return_value={'save_volume_id': uuids.old_volume_id})
def test_swap_volume_with_new_attachment_id_cinder_migrate_true(self, migrate_volume_completion, attachment_delete, attachment_update, get_volume, get_bdm, notify_about_volume_swap):

    bdm = objects.BlockDeviceMapping(volume_id=uuids.old_volume_id, device_name='/dev/vda', attachment_id=uuids.old_attachment_id, connection_info='{"data":    {}}', volume_size=1)
    old_volume = {'id': uuids.old_volume_id, 'size': 1, 'status': 'retyping'}
    new_volume = {'id': uuids.new_volume_id, 'size': 1, 'status': 'reserved'}
    attachment_update.return_value = {'connection_info': {'data': {}}}
    get_bdm.return_value = bdm
    get_volume.side_effect = (old_volume, new_volume)
    instance = fake_instance.fake_instance_obj(self.context)
    with test.nested(mock.patch.object(self.context, 'elevated', return_value=self.context), mock.patch.object(self.compute.driver, 'get_volume_connector', return_value=mock.sentinel.connector), mock.patch.object(bdm, 'save')) as (mock_elevated, mock_get_volume_connector, mock_save):
        self.compute.swap_volume(self.context, uuids.old_volume_id, uuids.new_volume_id, instance, uuids.new_attachment_id)
        get_bdm.assert_called_once_with(self.context, uuids.old_volume_id, instance.uuid)
        attachment_update.assert_called_once_with(self.context, uuids.new_attachment_id, mock.sentinel.connector)
        attachment_delete.assert_called_once_with(self.context, uuids.old_attachment_id)
        migrate_volume_completion.assert_called_once_with(self.context, uuids.old_volume_id, uuids.new_volume_id, error=False)
        mock_save.assert_called_once_with()
        self.assertEqual(uuids.old_volume_id, bdm.volume_id)
        self.assertEqual(uuids.new_attachment_id, bdm.attachment_id)
        self.assertEqual(1, bdm.volume_size)
        self.assertEqual(uuids.old_volume_id, jsonutils.loads(bdm.connection_info)['serial'])
