'Test group can be created and deleted.'

@mock.patch('cinder.db.sqlalchemy.api.volume_glance_metadata_copy_to_volume')
@mock.patch('cinder.db.sqlalchemy.api.volume_glance_metadata_copy_from_volume_to_volume')
@mock.patch.object(driver.VolumeDriver, 'create_group', return_value={'status': 'available'})
@mock.patch.object(driver.VolumeDriver, 'delete_group', return_value=({'status': 'deleted'}, []))
@mock.patch.object(driver.VolumeDriver, 'create_group_snapshot', return_value={'status': 'available'})
@mock.patch.object(driver.VolumeDriver, 'delete_group_snapshot', return_value=({'status': 'deleted'}, []))
@mock.patch.object(driver.VolumeDriver, 'create_group_from_src', return_value=(None, None))
@mock.patch('cinder.volume.drivers.lvm.LVMVolumeDriver.create_volume_from_snapshot')
@mock.patch('cinder.volume.drivers.lvm.LVMVolumeDriver.create_cloned_volume')
def test_create_group_from_src(self, mock_create_cloned_vol, mock_create_vol_from_snap, mock_create_from_src, mock_delete_grpsnap, mock_create_grpsnap, mock_delete_grp, mock_create_grp, mock_metadata_copy_volume_to_volume, mock_metadata_copy_to_volume):

    group = tests_utils.create_group(self.context, availability_zone=CONF.storage_availability_zone, status=fields.GroupStatus.AVAILABLE, volume_type_ids=[fake.VOLUME_TYPE_ID], group_type_id=fake.GROUP_TYPE_ID, host=CONF.host)
    volume = tests_utils.create_volume(self.context, group_id=group.id, status='available', multiattach=True, bootable=True, host=group.host, volume_type_id=fake.VOLUME_TYPE_ID, size=1)
    volume_id = volume['id']
    group_snapshot_returns = self._create_group_snapshot(group.id, [volume_id])
    group_snapshot = group_snapshot_returns[0]
    snapshot_id = group_snapshot_returns[1][0]['id']
    group2 = tests_utils.create_group(self.context, availability_zone=CONF.storage_availability_zone, group_snapshot_id=group_snapshot.id, volume_type_ids=[fake.VOLUME_TYPE_ID], group_type_id=fake.GROUP_TYPE_ID, host=CONF.host)
    group2 = objects.Group.get_by_id(self.context, group2.id)
    volume2 = tests_utils.create_volume(self.context, group_id=group2.id, snapshot_id=snapshot_id, status='available', host=group2.host, volume_type_id=fake.VOLUME_TYPE_ID)
    self.volume.create_volume(self.context, volume2)
    self.volume.create_group_from_src(self.context, group2, group_snapshot=group_snapshot)
    grp2 = objects.Group.get_by_id(self.context, group2.id)
    expected = {'status': fields.GroupStatus.AVAILABLE, 'name': 'test_group', 'availability_zone': 'nova', 'tenant_id': self.context.project_id, 'created_at': mock.ANY, 'user_id': fake.USER_ID, 'group_id': group2.id, 'group_type': fake.GROUP_TYPE_ID}
    self.assertEqual(fields.GroupStatus.AVAILABLE, grp2.status)
    self.assertEqual(group2.id, grp2['id'])
    self.assertEqual(group_snapshot.id, grp2['group_snapshot_id'])
    self.assertIsNone(grp2['source_group_id'])
    msg = self.notifier.notifications[2]
    self.assertEqual('group.create.start', msg['event_type'])
    self.assertDictEqual(expected, msg['payload'])
    msg = self.notifier.notifications[4]
    self.assertEqual('group.create.end', msg['event_type'])
    self.assertDictEqual(expected, msg['payload'])
    if (len(self.notifier.notifications) > 6):
        self.assertFalse(self.notifier.notifications[6], self.notifier.notifications)
    self.assertEqual(6, len(self.notifier.notifications), self.notifier.notifications)
    self.volume.delete_group(self.context, group2)
    if (len(self.notifier.notifications) > 9):
        self.assertFalse(self.notifier.notifications[10], self.notifier.notifications)
    self.assertEqual(9, len(self.notifier.notifications), self.notifier.notifications)
    msg = self.notifier.notifications[6]
    self.assertEqual('group.delete.start', msg['event_type'])
    expected['status'] = fields.GroupStatus.AVAILABLE
    self.assertDictEqual(expected, msg['payload'])
    msg = self.notifier.notifications[8]
    self.assertEqual('group.delete.end', msg['event_type'])
    expected['status'] = fields.GroupStatus.DELETED
    self.assertDictEqual(expected, msg['payload'])
    grp2 = objects.Group.get_by_id(context.get_admin_context(read_deleted='yes'), group2.id)
    self.assertEqual(fields.GroupStatus.DELETED, grp2.status)
    self.assertRaises(exception.NotFound, objects.Group.get_by_id, self.context, group2.id)
    group3 = tests_utils.create_group(self.context, availability_zone=CONF.storage_availability_zone, source_group_id=group.id, volume_type_ids=[fake.VOLUME_TYPE_ID], group_type_id=fake.GROUP_TYPE_ID, host=CONF.host)
    volume3 = tests_utils.create_volume(self.context, group_id=group3.id, source_volid=volume_id, status='available', host=group3.host, volume_type_id=fake.VOLUME_TYPE_ID)
    self.volume.create_volume(self.context, volume3)
    self.volume.create_group_from_src(self.context, group3, source_group=group)
    grp3 = objects.Group.get_by_id(self.context, group3.id)
    vol3 = objects.Volume.get_by_id(self.context, volume3.id)
    self.assertEqual(fields.GroupStatus.AVAILABLE, grp3.status)
    self.assertEqual(group3.id, grp3.id)
    self.assertEqual(group.id, grp3.source_group_id)
    self.assertIsNone(grp3.group_snapshot_id)
    self.assertEqual(volume.multiattach, vol3.multiattach)
    self.assertEqual(volume.bootable, vol3.bootable)
    self.volume.delete_group_snapshot(self.context, group_snapshot)
    self.volume.delete_group(self.context, group)
