#!/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source.  A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#

#
# Copyright (c) 2012 by Delphix. All rights reserved.
#

# DESCRIPTION
#	zfs destroy <dataset@snap1,snap2..> can destroy a list of multiple
#	snapshots from the same datasets
#
# STRATEGY
#	1. Create multiple snapshots for the same datset
#	2. Run zfs destroy for these snapshots for a mix of valid and
#	   invalid snapshot names
#	3. Run zfs destroy for snapshots from different datasets and
#	   pools

. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zfs_destroy/zfs_destroy.cfg

function cleanup
{
	destroy_dataset -R $TESTPOOL/$TESTFS1
	destroy_dataset -R $TESTPOOL/$TESTFS2
	destroy_pool $TESTPOOL2
	$RM -rf $VIRTUAL_DISK
}

log_assert "zfs destroy for multiple snapshot is handled correctly"
log_onexit cleanup

$ZFS create $TESTPOOL/$TESTFS1
typeset -i i=1
snaplist=""
log_note "zfs destroy on valid snapshot names"
for i in 1 2 3 4 5; do
	log_must $ZFS snapshot $TESTPOOL/$TESTFS1@snap$i
	snaplist=$snaplist,snap$i
done
snaplist=${snaplist#,}
destroy_dataset $TESTPOOL/$TESTFS1@$snaplist
for i in 1 2 3 4 5; do
	log_mustnot snapexists $TESTPOOL/$TESFS1@snap$i
done

log_note "zfs destroy with all bogus snapshot names"
log_mustnot $ZFS destroy $TESTPOOL/$TESTFS1@snap12,snap21,sna@pple1@,s""nappy2

log_note "zfs destroy with some bogus snapshot names"
for i in 1 2 3; do
	log_must $ZFS snapshot $TESTPOOL/$TESTFS1@snap$i
done
destroy_dataset $TESTPOOL/$TESTFS1@snap1,snap2,snapple1,snappy2,snap3
for i in 1 2 3; do
	log_mustnot snapexists $TESTPOOL/$TESTFS1@snap$i
done

log_note "zfs destroy with some snapshot names having special characters"
for i in 1 2 3; do
	log_must $ZFS snapshot $TESTPOOL/$TESTFS1@snap$i
done
destroy_dataset $TESTPOOL/$TESTFS1@snap1,@,snap2,,,,snap3,
for i in 1 2 3; do
	log_mustnot snapexists $TESTPOOL/$TESTFS1@snap$i
done
log_note "zfs destroy for too many snapshots"
snaplist=""
for i in {1..100}; do
	log_must $ZFS snapshot $TESTPOOL/$TESTFS1@snap$i
	snaplist=$snaplist,snap$i
done
snaplist=${snaplist#,}
destroy_dataset $TESTPOOL/$TESTFS1@$snaplist
for i in {1..100}; do
	log_mustnot snapexists $TESTPOOL/$TESTFS1@snap$i
done
log_note "zfs destroy multiple snapshots with hold"
snaplist=""
for i in 1 2 3 4 5; do
	log_must $ZFS snapshot $TESTPOOL/$TESTFS1@snap$i
	log_must $ZFS hold keep $TESTPOOL/$TESTFS1@snap$i
	snaplist=$snaplist,snap$i
done
snaplist=${snaplist#,}
log_mustnot $ZFS destroy $TESTPOOL/$TESTFS1@$snaplist
for i in 1 2 3 4 5; do
	log_must $ZFS release keep $TESTPOOL/$TESTFS1@snap$i
done
destroy_dataset $TESTPOOL/$TESTFS1@$snaplist

log_note "zfs destroy for multiple snapshots having clones"
for i in 1 2 3 4 5; do
	log_must $ZFS snapshot $TESTPOOL/$TESTFS1@snap$i
done
snaplist=""
for i in 1 2 3 4 5; do
	log_must $ZFS clone $TESTPOOL/$TESTFS1@snap$i $TESTPOOL/$TESTFS1/clone$i
	snaplist=$snaplist,snap$i
done
snaplist=${snaplist#,}
log_mustnot $ZFS destroy $TESTPOOL/$TESTFS1@$snaplist
for i in 1 2 3 4 5; do
	log_must snapexists $TESTPOOL/$TESTFS1@snap$i
	destroy_dataset $TESTPOOL/$TESTFS1/clone$i
done

log_note "zfs destroy for snapshots for different datasets"
log_must $ZFS create $TESTPOOL/$TESTFS2
log_must $ZFS snapshot $TESTPOOL/$TESTFS2@fs2snap
log_must $ZFS create $TESTPOOL/$TESTFS1/$TESTFS2
log_must $ZFS snapshot $TESTPOOL/$TESTFS1/$TESTFS2@fs12snap

long_arg=$TESTPOOL/$TESTFS1@snap1,$TESTPOOL/$TESTFS2@fs2snap,
long_arg=$long_arg$TESTPOOL/$TESTFS1/$TESTFS2@fs12snap
destroy_dataset $long_arg
log_mustnot snapexists $TESTPOOL/$TESTFS1@snap1
log_must snapexists $TESTPOOL/$TESTFS2@fs2snap
log_must snapexists $TESTPOOL/$TESTFS1/$TESTFS2@fs12snap

destroy_dataset $TESTPOOL/$TESTFS1@fs2snap,fs12snap,snap2
log_must snapexists $TESTPOOL/$TESTFS2@fs2snap
log_must snapexists $TESTPOOL/$TESTFS1/$TESTFS2@fs12snap
log_mustnot snapexists $TESTPOOL/$TESTFS1@snap2

destroy_dataset $TESTPOOL/$TESTFS2@fs2snap,fs12snap,snap3
log_mustnot snapexists $TESTPOOL/$TESTFS2@fs2snap
log_must snapexists $TESTPOOL/$TESTFS1/$TESTFS2@fs12snap
log_must snapexists $TESTPOOL/$TESTFS1@snap3

log_note "zfs destroy for snapshots from different pools"
VIRTUAL_DISK=/var/tmp/disk

if [[ -n "$OSX" ]]; then
    log_must $DD if=/dev/urandom of=$VIRTUAL_DISK bs=1m count=64
else
    log_must $DD if=/dev/urandom of=$VIRTUAL_DISK bs=1M count=64
fi
log_must $ZPOOL create $TESTPOOL2 $VIRTUAL_DISK
log_must poolexists $TESTPOOL2

log_must $ZFS create $TESTPOOL2/$TESTFS1
log_must $ZFS snapshot $TESTPOOL2/$TESTFS1@snap
long_arg=$TESTPOOL2/$TESTFS1@snap,$TESTPOOL/$TESTFS1@snap3,
long_arg=$long_arg$TESTPOOL/$TESTFS1@snap5
destroy_dataset $long_arg
log_mustnot snapexists $TESTPOOL2/$TESTFS1@snap
log_must snapexists $TESTPOOL/$TESTFS1@snap3
log_must snapexists $TESTPOOL/$TESTFS1@snap5

log_must $ZFS snapshot $TESTPOOL2/$TESTFS1@snap
destroy_dataset $TESTPOOL2/$TESTFS1@snap5,snap3,snap
log_mustnot snapexists $TESTPOOL2/$TESTFS1@snap
log_must snapexists $TESTPOOL/$TESTFS1@snap3
log_must snapexists $TESTPOOL/$TESTFS1@snap5

log_pass "zfs destroy for multiple snapshots passes"
