diff options
Diffstat (limited to 'sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program')
95 files changed, 6691 insertions, 0 deletions
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/Makefile.am new file mode 100644 index 000000000000..3886863d1dfb --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/Makefile.am @@ -0,0 +1,6 @@ +SUBDIRS = \ + lua_core \ + synctask_core + +pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/channel_program +dist_pkgdata_DATA = channel_common.kshlib diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/channel_common.kshlib b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/channel_common.kshlib new file mode 100644 index 000000000000..a828ba29065e --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/channel_common.kshlib @@ -0,0 +1,230 @@ +# +# 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) 2016, 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +ZCP_ROOT=$STF_SUITE/tests/functional/channel_program + +# +# Note: In case of failure (log_fail) in this function +# we delete the file passed as <input file> so the +# test suite doesn't leak temp files on failures. So it +# is expected that <input file> is a temp file and not +# an installed file. +# +# <exitcode> <expected error string> <input file> <zfs program args> +# e.g. log_program 0 "" tmp.7a12V $POOL foo.zcp arg1 arg2 +function log_program +{ + typeset expectexit=$1 + shift + typeset expecterror=$1 + shift + typeset tmpin=$1 + shift + typeset cmdargs=$@ tmpout=$(mktemp) tmperr=$(mktemp) + + # Expected output/error filename is the same as the .zcp name + typeset basename + if [[ $2 != "-" ]]; then + basename=${2%.*} + fi + + log_note "running: zfs program $cmdargs:" + + zfs program $cmdargs >$tmpout 2>$tmperr + typeset ret=$? + + log_note "input:\n$(cat $tmpin)" + log_note "output:\n$(cat $tmpout)" + log_note "error:\n$(cat $tmperr)" + + # + # Verify correct return value + # + if [[ $ret -ne $expectexit ]]; then + rm $tmpout $tmperr $tmpin + log_fail "return mismatch: expected $expectexit, got $ret" + fi + + # + # Check the output or reported error for successful or error returns, + # respectively. + # + if [[ -f "$basename.out" ]] && [[ $expectexit -eq 0 ]]; then + + outdiff=$(diff "$basename.out" "$tmpout") + if [[ $? -ne 0 ]]; then + output=$(<$tmpout) + rm $tmpout $tmperr $tmpin + log_fail "Output mismatch. Expected:\n" \ + "$(<$basename.out)\nBut got:\n$output\n" \ + "Diff:\n$outdiff" + fi + + elif [[ -f "$basename.err" ]] && [[ $expectexit -ne 0 ]]; then + + outdiff=$(diff "$basename.err" "$tmperr") + if [[ $? -ne 0 ]]; then + outputerror=$(<$tmperr) + rm $tmpout $tmperr $tmpin + log_fail "Error mismatch. Expected:\n" \ + "$(<$basename.err)\nBut got:\n$outputerror\n" \ + "Diff:\n$outdiff" + fi + + elif [[ -n $expecterror ]] && [[ $expectexit -ne 0 ]]; then + + grep -q "$expecterror" $tmperr + if [[ $? -ne 0 ]]; then + outputerror=$(<$tmperr) + rm $tmpout $tmperr $tmpin + log_fail "Error mismatch. Expected to contain:\n" \ + "$expecterror\nBut got:\n$outputerror\n" + fi + + elif [[ $expectexit -ne 0 ]]; then + # + # If there's no expected output, error reporting is allowed to + # vary, but ensure that we didn't fail silently. + # + if [[ -z "$(<$tmperr)" ]]; then + rm $tmpout $tmperr $tmpin + log_fail "error with no stderr output" + fi + fi + + # + # Clean up all temp files except $tmpin which is + # reused for the second invocation of log_program. + # + rm $tmpout $tmperr +} + +# +# Even though the command's arguments are passed correctly +# to the log_must_program family of wrappers the majority +# of the time, zcp scripts passed as HERE documents can +# make things trickier (see comment within the function +# below) in the ordering of the commands arguments and how +# they are passed. Thus, with this function we reconstruct +# them to ensure that they are passed properly. +# +function log_program_construct_args +{ + typeset tmpin=$1 + shift + + args="" + i=0 + while getopts "nt:m:" opt; do + case $opt in + t) args="$args -t $OPTARG"; i=$(($i + 2)) ;; + m) args="$args -m $OPTARG"; i=$(($i + 2)) ;; + n) args="$args -n"; i=$(($i + 1)) ;; + esac + done + shift $i + + pool=$1 + shift + + infile=$1 + shift + + # + # Copy the contents of the original channel program to $tmpin. + # + # If $infile currently holds "-" (a dash) it means that we consume a + # HERE doc from stdin, otherwise $infile is a file path. + # + cat $infile > $tmpin + + lua_args=$@ + + echo "$args $pool $tmpin $lua_args" +} + +# +# Program should complete successfully +# when run in either context. +# +function log_must_program +{ + typeset tmpin=$(mktemp) + + program_args=$(log_program_construct_args $tmpin $@) + + log_program 0 "" $tmpin "-n $program_args" + log_program 0 "" $tmpin "$program_args" + + rm $tmpin +} +# +# Program should error as expected in +# the same way in both contexts. +# +function log_mustnot_checkerror_program +{ + typeset expecterror=$1 + shift + typeset tmpin=$(mktemp) + + program_args=$(log_program_construct_args $tmpin $@) + + log_program 1 "$expecterror" $tmpin "-n $program_args" + log_program 1 "$expecterror" $tmpin "$program_args" + + rm $tmpin +} + +# +# Program should fail when run in either +# context. +# +function log_mustnot_program +{ + log_mustnot_checkerror_program "" $@ +} + + +# +# Program should error as expected in +# open context but complete successfully +# in syncing context. +# +function log_mustnot_checkerror_program_open +{ + typeset expecterror=$1 + shift + typeset tmpin=$(mktemp) + + program_args=$(log_program_construct_args $tmpin $@) + + log_program 1 "$expecterror" $tmpin "-n $program_args" + log_program 0 "" $tmpin "$program_args" + + rm $tmpin +} + +# +# Program should complete successfully +# when run in syncing context but fail +# when attempted to run in open context. +# +function log_must_program_sync +{ + log_mustnot_checkerror_program_open "requires passing sync=TRUE" $@ +} diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/Makefile.am new file mode 100644 index 000000000000..fb352081190c --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/Makefile.am @@ -0,0 +1,46 @@ +pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/channel_program/lua_core +dist_pkgdata_SCRIPTS = \ + cleanup.ksh \ + setup.ksh \ + tst.args_to_lua.ksh \ + tst.divide_by_zero.ksh \ + tst.exists.ksh \ + tst.integer_illegal.ksh \ + tst.integer_overflow.ksh \ + tst.language_functions_neg.ksh \ + tst.language_functions_pos.ksh \ + tst.large_prog.ksh \ + tst.libraries.ksh \ + tst.memory_limit.ksh \ + tst.nested_neg.ksh \ + tst.nested_pos.ksh \ + tst.nvlist_to_lua.ksh \ + tst.recursive_neg.ksh \ + tst.recursive_pos.ksh \ + tst.return_large.ksh \ + tst.return_nvlist_neg.ksh \ + tst.return_nvlist_pos.ksh \ + tst.return_recursive_table.ksh \ + tst.stack_gsub.ksh \ + tst.timeout.ksh + +dist_pkgdata_DATA = \ + tst.args_to_lua.out \ + tst.args_to_lua.zcp \ + tst.divide_by_zero.err \ + tst.divide_by_zero.zcp \ + tst.exists.zcp \ + tst.large_prog.out \ + tst.large_prog.zcp \ + tst.lib_base.lua \ + tst.lib_coroutine.lua \ + tst.lib_strings.lua \ + tst.lib_table.lua \ + tst.nested_neg.zcp \ + tst.nested_pos.zcp \ + tst.recursive.zcp \ + tst.return_large.zcp \ + tst.return_recursive_table.zcp \ + tst.stack_gsub.err \ + tst.stack_gsub.zcp \ + tst.timeout.zcp diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/cleanup.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/cleanup.ksh new file mode 100755 index 000000000000..281f639a4276 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/cleanup.ksh @@ -0,0 +1,19 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +default_cleanup diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/setup.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/setup.ksh new file mode 100755 index 000000000000..2516b6b8ad9e --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/setup.ksh @@ -0,0 +1,21 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +DISK=${DISKS%% *} + +default_setup ${DISK} diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.args_to_lua.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.args_to_lua.ksh new file mode 100755 index 000000000000..6ec5610639de --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.args_to_lua.ksh @@ -0,0 +1,30 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Passing arguments to lua programs should work correctly. +# + +verify_runnable "global" + +log_assert "Passing arguments to lua programs should work correctly." + +log_must_program $TESTPOOL $ZCP_ROOT/lua_core/tst.args_to_lua.zcp foo bar + +log_pass "Passing arguments to lua programs should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.args_to_lua.out b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.args_to_lua.out new file mode 100644 index 000000000000..84191f8f803c --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.args_to_lua.out @@ -0,0 +1 @@ +Channel program fully executed with no return value. diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.args_to_lua.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.args_to_lua.zcp new file mode 100644 index 000000000000..f6f14e5222f9 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.args_to_lua.zcp @@ -0,0 +1,25 @@ +-- +-- 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) 2016 by Delphix. All rights reserved. +-- + +-- This program should be invoked as "zfs program <pool> <prog> foo bar" + +arg = ... +argv = arg["argv"] + +assert(#argv == 2) +assert(argv[1] == "foo") +assert(argv[2] == "bar") + +return diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.divide_by_zero.err b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.divide_by_zero.err new file mode 100644 index 000000000000..fd67d09f7309 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.divide_by_zero.err @@ -0,0 +1,4 @@ +Channel program execution failed: +[string "channel program"]:16: attempt to divide by zero +stack traceback: + [string "channel program"]:16: in main chunk diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.divide_by_zero.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.divide_by_zero.ksh new file mode 100755 index 000000000000..2587c594da0d --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.divide_by_zero.ksh @@ -0,0 +1,30 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Divide by zero should fail gracefully. +# + +verify_runnable "global" + +log_assert "Divide by zero should fail gracefully." + +log_mustnot_program $TESTPOOL $ZCP_ROOT/lua_core/tst.divide_by_zero.zcp + +log_pass "Divide by zero should fail gracefully." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.divide_by_zero.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.divide_by_zero.zcp new file mode 100644 index 000000000000..bd882d493b63 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.divide_by_zero.zcp @@ -0,0 +1,16 @@ +-- +-- 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) 2016 by Delphix. All rights reserved. +-- + +return 1 / 0 diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.exists.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.exists.ksh new file mode 100755 index 000000000000..d486c25f4487 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.exists.ksh @@ -0,0 +1,45 @@ +#!/bin/ksh -p +# +# 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) 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# zfs.exists should accurately report whether a dataset exists, and +# report an error if a dataset is in another pool. + +verify_runnable "global" + +# create $TESTSNAP and $TESTCLONE +create_snapshot +create_clone + +function cleanup +{ + datasetexists $TESTPOOL/$TESTFS@$TESTSNAP && \ + log_must zfs destroy -R $TESTPOOL/$TESTFS@$TESTSNAP +} + +log_must_program $TESTPOOL $ZCP_ROOT/lua_core/tst.exists.zcp \ + $TESTPOOL $TESTPOOL/$TESTFS $TESTPOOL/$TESTFS@$TESTSNAP \ + $TESTPOOL/$TESTCLONE + +log_mustnot_checkerror_program "not in the target pool" \ + $TESTPOOL - <<-EOF + return zfs.exists('rpool') +EOF + +log_pass "zfs.exists() gives correct results" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.exists.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.exists.zcp new file mode 100644 index 000000000000..e44cf4560502 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.exists.zcp @@ -0,0 +1,26 @@ +-- +-- 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) 2017 by Delphix. All rights reserved. +-- + +-- ensure zfs.exists works as expected. + +args = ... +argv = args['argv'] +pool = argv[1] + +for i = 1,4 do + assert(zfs.exists(argv[i])) +end + +assert(not zfs.exists(pool .. '/notadataset')) diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.integer_illegal.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.integer_illegal.ksh new file mode 100755 index 000000000000..c34f2afd9e18 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.integer_illegal.ksh @@ -0,0 +1,41 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Constructing integers that are doubles, too large, or too +# small should fail gracefully. +# + +verify_runnable "global" + +log_assert "constructing illegal integer values should fail gracefully" + +set -A args "1.0" \ + "1.5" \ + "-1.5" + +typeset -i i=0 +while (( i < ${#args[*]} )); do + log_mustnot_checkerror_program "malformed number" $TESTPOOL - <<-EOF + return ${args[i]} + EOF + ((i = i + 1)) +done + +log_pass "constructing illegal integer values should fail gracefully" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.integer_overflow.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.integer_overflow.ksh new file mode 100755 index 000000000000..c129bae51b04 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.integer_overflow.ksh @@ -0,0 +1,32 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Overflowing a 64-bit integer should wrap around. +# + +verify_runnable "global" + +log_assert "overflowing a 64-bit integer should wrap around" + +log_must_program $TESTPOOL - <<-EOF + assert(18446744073709551615 + 1 == (-18446744073709551616)) +EOF + +log_pass "overflowing a 64-bit integer should wrap around" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.language_functions_neg.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.language_functions_neg.ksh new file mode 100755 index 000000000000..0125d76c7036 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.language_functions_neg.ksh @@ -0,0 +1,52 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Try channel programs with various lua runtime issues. +# the program should fail, but the system should not crash. +# Issues include: +# * syntax errors +# * misuse of language constructs (e.g. indexing non-tables) +# * the error() function +# * the assert() function +# + +verify_runnable "global" + +set -A args "{]" \ + "retrn 1" \ + "abc = nil; abc.deref" \ + "abc = nil; abc()" \ + "error(0)" \ + "error(\"string\")" \ + "error(true)" \ + "error({})" \ + "assert(false)" + +log_assert "Runtime errors in lua scripts fail as expected." + +typeset -i i=0 +while (( i < ${#args[*]} )); do + log_mustnot_checkerror_program "execution failed" $TESTPOOL - <<-EOF + ${args[i]} + EOF + ((i = i + 1)) +done + +log_pass "Runtime errors in lua scripts fail as expected." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.language_functions_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.language_functions_pos.ksh new file mode 100755 index 000000000000..924d8e2c6944 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.language_functions_pos.ksh @@ -0,0 +1,42 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Try very simple programs that interact with the core lua +# runtime rather than ZFS functions, just to make sure the +# runtime is hooked up correctly. +# + +verify_runnable "global" + +set -A args "" \ + "assert(true)" \ + "x = 1 + 1" + +log_assert "Simple lua scripts pass." + +typeset -i i=0 +while (( i < ${#args[*]} )); do + log_must_program $TESTPOOL - <<-EOF + ${args[i]} + EOF + ((i = i + 1)) +done + +log_pass "Simple lua scripts pass." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.large_prog.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.large_prog.ksh new file mode 100755 index 000000000000..21ab69adb1c7 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.large_prog.ksh @@ -0,0 +1,30 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Running a large program file should work correctly. +# + +verify_runnable "global" + +log_assert "Running a large program file should work correctly." + +log_must_program $TESTPOOL $ZCP_ROOT/lua_core/tst.large_prog.zcp + +log_pass "Running a large program file should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.large_prog.out b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.large_prog.out new file mode 100644 index 000000000000..84191f8f803c --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.large_prog.out @@ -0,0 +1 @@ +Channel program fully executed with no return value. diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.large_prog.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.large_prog.zcp new file mode 100644 index 000000000000..add68973349e --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.large_prog.zcp @@ -0,0 +1,280 @@ +-- +-- 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) 2016 by Delphix. All rights reserved. +-- + +-- /sbin/zfs initially allocates 1KB for the channel program file. This +-- program file is larger than that, to test the reallocation and +-- passing of a large channel string to the kernel. +-- This file is at least 16KB long. + +--[[ +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +1234567890123456789012345678901234567890123456789012345678901234 +]] + +return diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_base.lua b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_base.lua new file mode 100644 index 000000000000..c39144959a3f --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_base.lua @@ -0,0 +1,469 @@ +--[[ +--***************************************************************************** +--* Copyright (C) 1994-2016 Lua.org, PUC-Rio. +--* +--* Permission is hereby granted, free of charge, to any person obtaining +--* a copy of this software and associated documentation files (the +--* "Software"), to deal in the Software without restriction, including +--* without limitation the rights to use, copy, modify, merge, publish, +--* distribute, sublicense, and/or sell copies of the Software, and to +--* permit persons to whom the Software is furnished to do so, subject to +--* the following conditions: +--* +--* The above copyright notice and this permission notice shall be +--* included in all copies or substantial portions of the Software. +--* +--* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +--* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +--* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +--* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +--* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +--* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +--* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--***************************************************************************** +--]] + +-- testing metatables + +X = 20; B = 30 + +_ENV = setmetatable({}, {__index=_G}) + +collectgarbage() + +X = X+10 +assert(X == 30 and _G.X == 20) +B = false +assert(B == false) +B = nil +assert(B == 30) + +assert(getmetatable{} == nil) +assert(getmetatable(4) == nil) +assert(getmetatable(nil) == nil) +a={name = "NAME"}; setmetatable(a, {__metatable = "xuxu", + __tostring=function(x) return x.name end}) +assert(getmetatable(a) == "xuxu") +assert(tostring(a) == "NAME") + +local a, t = {10,20,30; x="10", y="20"}, {} +assert(setmetatable(a,t) == a) +assert(getmetatable(a) == t) +assert(setmetatable(a,nil) == a) +assert(getmetatable(a) == nil) +assert(setmetatable(a,t) == a) + + +function f (t, i, e) + assert(not e) + local p = rawget(t, "parent") + return (p and p[i]+3), "dummy return" +end + +t.__index = f + +a.parent = {z=25, x=12, [4] = 24} +assert(a[1] == 10 and a.z == 28 and a[4] == 27 and a.x == "10") + +collectgarbage() + +a = setmetatable({}, t) +function f(t, i, v) rawset(t, i, v-3) end +setmetatable(t, t) -- causes a bug in 5.1 ! +t.__newindex = f +a[1] = 30; a.x = "101"; a[5] = 200 +assert(a[1] == 27 and a.x == 98 and a[5] == 197) + + +local c = {} +a = setmetatable({}, t) +t.__newindex = c +a[1] = 10; a[2] = 20; a[3] = 90 +assert(c[1] == 10 and c[2] == 20 and c[3] == 90) + + +do + local a; + a = setmetatable({}, {__index = setmetatable({}, + {__index = setmetatable({}, + {__index = function (_,n) return a[n-3]+4, "lixo" end})})}) + a[0] = 20 + for i=0,10 do + assert(a[i*3] == 20 + i*4) + end +end + + +do -- newindex + local foi + local a = {} + for i=1,10 do a[i] = 0; a['a'..i] = 0; end + setmetatable(a, {__newindex = function (t,k,v) foi=true; rawset(t,k,v) end}) + foi = false; a[1]=0; assert(not foi) + foi = false; a['a1']=0; assert(not foi) + foi = false; a['a11']=0; assert(foi) + foi = false; a[11]=0; assert(foi) + foi = false; a[1]=nil; assert(not foi) + foi = false; a[1]=nil; assert(foi) +end + + +setmetatable(t, nil) +function f (t, ...) return t, {...} end +t.__call = f + +do + local x,y = a(table.unpack{'a', 1}) + assert(x==a and y[1]=='a' and y[2]==1 and y[3]==nil) + x,y = a() + assert(x==a and y[1]==nil) +end + + +local b = setmetatable({}, t) +setmetatable(b,t) + +function f(op) + return function (...) cap = {[0] = op, ...} ; return (...) end +end +t.__add = f("add") +t.__sub = f("sub") +t.__mul = f("mul") +t.__div = f("div") +t.__mod = f("mod") +t.__unm = f("unm") +t.__pow = f("pow") +t.__len = f("len") + +assert(b+5 == b) +assert(cap[0] == "add" and cap[1] == b and cap[2] == 5 and cap[3]==nil) +assert(b+'5' == b) +assert(cap[0] == "add" and cap[1] == b and cap[2] == '5' and cap[3]==nil) +assert(5+b == 5) +assert(cap[0] == "add" and cap[1] == 5 and cap[2] == b and cap[3]==nil) +assert('5'+b == '5') +assert(cap[0] == "add" and cap[1] == '5' and cap[2] == b and cap[3]==nil) +b=b-3; assert(getmetatable(b) == t) +assert(5-a == 5) +assert(cap[0] == "sub" and cap[1] == 5 and cap[2] == a and cap[3]==nil) +assert('5'-a == '5') +assert(cap[0] == "sub" and cap[1] == '5' and cap[2] == a and cap[3]==nil) +assert(a*a == a) +assert(cap[0] == "mul" and cap[1] == a and cap[2] == a and cap[3]==nil) +assert(a/0 == a) +assert(cap[0] == "div" and cap[1] == a and cap[2] == 0 and cap[3]==nil) +assert(a%2 == a) +assert(cap[0] == "mod" and cap[1] == a and cap[2] == 2 and cap[3]==nil) +assert(-a == a) +assert(cap[0] == "unm" and cap[1] == a) +assert(a^4 == a) +assert(cap[0] == "pow" and cap[1] == a and cap[2] == 4 and cap[3]==nil) +assert(a^'4' == a) +assert(cap[0] == "pow" and cap[1] == a and cap[2] == '4' and cap[3]==nil) +assert(4^a == 4) +assert(cap[0] == "pow" and cap[1] == 4 and cap[2] == a and cap[3]==nil) +assert('4'^a == '4') +assert(cap[0] == "pow" and cap[1] == '4' and cap[2] == a and cap[3]==nil) +assert(#a == a) +assert(cap[0] == "len" and cap[1] == a) + + +-- test for rawlen +t = setmetatable({1,2,3}, {__len = function () return 10 end}) +assert(#t == 10 and rawlen(t) == 3) +assert(rawlen"abc" == 3) +assert(rawlen(string.rep('a', 1000)) == 1000) + +t = {} +t.__lt = function (a,b,c) + collectgarbage() + assert(c == nil) + if type(a) == 'table' then a = a.x end + if type(b) == 'table' then b = b.x end + return a<b, "dummy" +end + +function Op(x) return setmetatable({x=x}, t) end + +local function test () + assert(not(Op(1)<Op(1)) and (Op(1)<Op(2)) and not(Op(2)<Op(1))) + assert(not(1 < Op(1)) and (Op(1) < 2) and not(2 < Op(1))) + assert(not(Op('a')<Op('a')) and (Op('a')<Op('b')) and not(Op('b')<Op('a'))) + assert(not('a' < Op('a')) and (Op('a') < 'b') and not(Op('b') < Op('a'))) + assert((Op(1)<=Op(1)) and (Op(1)<=Op(2)) and not(Op(2)<=Op(1))) + assert((Op('a')<=Op('a')) and (Op('a')<=Op('b')) and not(Op('b')<=Op('a'))) + assert(not(Op(1)>Op(1)) and not(Op(1)>Op(2)) and (Op(2)>Op(1))) + assert(not(Op('a')>Op('a')) and not(Op('a')>Op('b')) and (Op('b')>Op('a'))) + assert((Op(1)>=Op(1)) and not(Op(1)>=Op(2)) and (Op(2)>=Op(1))) + assert((1 >= Op(1)) and not(1 >= Op(2)) and (Op(2) >= 1)) + assert((Op('a')>=Op('a')) and not(Op('a')>=Op('b')) and (Op('b')>=Op('a'))) + assert(('a' >= Op('a')) and not(Op('a') >= 'b') and (Op('b') >= Op('a'))) +end + +test() + +t.__le = function (a,b,c) + assert(c == nil) + if type(a) == 'table' then a = a.x end + if type(b) == 'table' then b = b.x end + return a<=b, "dummy" +end + +test() -- retest comparisons, now using both `lt' and `le' + + +-- test `partial order' + +local function Set(x) + local y = {} + for _,k in pairs(x) do y[k] = 1 end + return setmetatable(y, t) +end + +t.__lt = function (a,b) + for k in pairs(a) do + if not b[k] then return false end + b[k] = nil + end + return next(b) ~= nil +end + +t.__le = nil + +assert(Set{1,2,3} < Set{1,2,3,4}) +assert(not(Set{1,2,3,4} < Set{1,2,3,4})) +assert((Set{1,2,3,4} <= Set{1,2,3,4})) +assert((Set{1,2,3,4} >= Set{1,2,3,4})) +assert((Set{1,3} <= Set{3,5})) -- wrong!! model needs a `le' method ;-) + +t.__le = function (a,b) + for k in pairs(a) do + if not b[k] then return false end + end + return true +end + +assert(not (Set{1,3} <= Set{3,5})) -- now its OK! +assert(not(Set{1,3} <= Set{3,5})) +assert(not(Set{1,3} >= Set{3,5})) + +t.__eq = function (a,b) + for k in pairs(a) do + if not b[k] then return false end + b[k] = nil + end + return next(b) == nil +end + +local s = Set{1,3,5} +assert(s == Set{3,5,1}) +assert(not rawequal(s, Set{3,5,1})) +assert(rawequal(s, s)) +assert(Set{1,3,5,1} == Set{3,5,1}) +assert(Set{1,3,5} ~= Set{3,5,1,6}) +t[Set{1,3,5}] = 1 +assert(t[Set{1,3,5}] == nil) -- `__eq' is not valid for table accesses + + +t.__concat = function (a,b,c) + assert(c == nil) + if type(a) == 'table' then a = a.val end + if type(b) == 'table' then b = b.val end + if A then return a..b + else + return setmetatable({val=a..b}, t) + end +end + +c = {val="c"}; setmetatable(c, t) +d = {val="d"}; setmetatable(d, t) + +A = true +assert(c..d == 'cd') +assert(0 .."a".."b"..c..d.."e".."f"..(5+3).."g" == "0abcdef8g") + +A = false +assert((c..d..c..d).val == 'cdcd') +x = c..d +assert(getmetatable(x) == t and x.val == 'cd') +x = 0 .."a".."b"..c..d.."e".."f".."g" +assert(x.val == "0abcdefg") + + +-- concat metamethod x numbers (bug in 5.1.1) +c = {} +local x +setmetatable(c, {__concat = function (a,b) + assert(type(a) == "number" and b == c or type(b) == "number" and a == c) + return c +end}) +assert(c..5 == c and 5 .. c == c) +assert(4 .. c .. 5 == c and 4 .. 5 .. 6 .. 7 .. c == c) + + +-- test comparison compatibilities +local t1, t2, c, d +t1 = {}; c = {}; setmetatable(c, t1) +d = {} +t1.__eq = function () return true end +t1.__lt = function () return true end +setmetatable(d, t1) +assert(c == d and c < d and not(d <= c)) +t2 = {} +t2.__eq = t1.__eq +t2.__lt = t1.__lt +setmetatable(d, t2) +assert(c == d and c < d and not(d <= c)) + + + +-- test for several levels of calls +local i +local tt = { + __call = function (t, ...) + i = i+1 + if t.f then return t.f(...) + else return {...} + end + end +} + +local a = setmetatable({}, tt) +local b = setmetatable({f=a}, tt) +local c = setmetatable({f=b}, tt) + +i = 0 +x = c(3,4,5) +assert(i == 3 and x[1] == 3 and x[3] == 5) + + +assert(_G.X == 20) + + +local _g = _G +_ENV = setmetatable({}, {__index=function (_,k) return _g[k] end}) + + +a = {} +rawset(a, "x", 1, 2, 3) +assert(a.x == 1 and rawget(a, "x", 3) == 1) + + +-- bug in 5.1 +T, K, V = nil +grandparent = {} +grandparent.__newindex = function(t,k,v) T=t; K=k; V=v end + +parent = {} +parent.__newindex = parent +setmetatable(parent, grandparent) + +child = setmetatable({}, parent) +child.foo = 10 --> CRASH (on some machines) +assert(T == parent and K == "foo" and V == 10) + + +-- testing 'tonumber' +assert(tonumber{} == nil) +assert(tonumber('-012') == -010-2) +assert(tonumber("0xffffffffffff") == 2^(4*12) - 1) +assert(tonumber("0x"..string.rep("f", 150)) == 2^(4*150) - 1) + +-- testing 'tonumber' with base +assert(tonumber(' 001010 ', 2) == 10) +assert(tonumber(' 001010 ', 10) == 1010) +assert(tonumber(' -1010 ', 2) == -10) +assert(tonumber('10', 36) == 36) +assert(tonumber(' -10 ', 36) == -36) +assert(tonumber(' +1Z ', 36) == 36 + 35) +assert(tonumber(' -1z ', 36) == -36 + -35) +assert(tonumber('-fFfa', 16) == -(10+(16*(15+(16*(15+(16*15))))))) +assert(tonumber(string.rep('1', 42), 2) + 1 == 2^42) +assert(tonumber(string.rep('1', 34), 2) + 1 == 2^34) +assert(tonumber('ffffFFFF', 16)+1 == 2^32) +assert(tonumber('0ffffFFFF', 16)+1 == 2^32) +assert(tonumber('-0ffffffFFFF', 16) - 1 == -2^40) +for i = 2,36 do + assert(tonumber('\t10000000000\t', i) == i^10) +end + +-- testing 'tonumber' for invalid formats +function f(...) + if select('#', ...) == 1 then + return (...) + else + return "***" + end +end + +assert(f(tonumber('fFfa', 15)) == nil) +assert(f(tonumber('099', 8)) == nil) +assert(f(tonumber('1\0', 2)) == nil) +assert(f(tonumber('', 8)) == nil) +assert(f(tonumber(' ', 9)) == nil) +assert(f(tonumber('0xf', 10)) == nil) + +assert(f(tonumber('inf')) == nil) +assert(f(tonumber(' INF ')) == nil) +assert(f(tonumber('Nan')) == nil) +assert(f(tonumber('nan')) == nil) + +assert(f(tonumber('')) == nil) +assert(f(tonumber('1 a')) == nil) +assert(f(tonumber('1\0')) == nil) +assert(f(tonumber('1 \0')) == nil) +assert(f(tonumber('1\0 ')) == nil) +assert(f(tonumber('e1')) == nil) +assert(f(tonumber('e 1')) == nil) + + +-- testing 'tonumber' for invalid hexadecimal formats +assert(tonumber('0x') == nil) +assert(tonumber('x') == nil) +assert(tonumber('x3') == nil) +assert(tonumber('00x2') == nil) +assert(tonumber('0x 2') == nil) +assert(tonumber('0 x2') == nil) +assert(tonumber('23x') == nil) +assert(tonumber('- 0xaa') == nil) + + +-- testing hexadecimal numerals +assert(tonumber('+0x2') == 2) +assert(tonumber('-0xaA') == -170) +assert(tonumber('-0xffFFFfff') == -2^32 + 1) + + +-- testing 'tostring' +assert(tostring("alo") == "alo") +assert(tostring(12) == "12") +assert(tostring(1234567890123) == '1234567890123') +assert(type(tostring("hello")) == "string") +assert(tostring(true) == "true") +assert(tostring(false) == "false") +assert(string.find(tostring{}, 'table:')) +assert(string.find(tostring(select), 'function:')) +assert(#tostring('\0') == 1) + + +-- testing ipairs +local x = 0 +for k,v in ipairs{10,20,30;x=12} do + x = x + 1 + assert(k == x and v == x * 10) +end + +for _ in ipairs{x=12, y=24} do assert(nil) end + +-- test for 'false' x ipair +x = false +local i = 0 +for k,v in ipairs{true,false,true,false} do + i = i + 1 + x = not x + assert(x == v) +end +assert(i == 4) + + +return "OK" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_coroutine.lua b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_coroutine.lua new file mode 100644 index 000000000000..e0e9e2a64fbc --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_coroutine.lua @@ -0,0 +1,362 @@ +--[[ +--***************************************************************************** +--* Copyright (C) 1994-2016 Lua.org, PUC-Rio. +--* +--* Permission is hereby granted, free of charge, to any person obtaining +--* a copy of this software and associated documentation files (the +--* "Software"), to deal in the Software without restriction, including +--* without limitation the rights to use, copy, modify, merge, publish, +--* distribute, sublicense, and/or sell copies of the Software, and to +--* permit persons to whom the Software is furnished to do so, subject to +--* the following conditions: +--* +--* The above copyright notice and this permission notice shall be +--* included in all copies or substantial portions of the Software. +--* +--* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +--* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +--* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +--* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +--* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +--* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +--* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--***************************************************************************** +--]] + +local f + +local main, ismain = coroutine.running() +assert(type(main) == "thread" and ismain) +assert(not coroutine.resume(main)) + + +-- tests for multiple yield/resume arguments + +local function eqtab (t1, t2) + assert(#t1 == #t2) + for i = 1, #t1 do + local v = t1[i] + assert(t2[i] == v) + end +end + +_G.x = nil -- declare x +function foo (a, ...) + local x, y = coroutine.running() + assert(x == f and y == false) + -- next call should not corrupt coroutine (but must fail, + -- as it attempts to resume the running coroutine) + assert(coroutine.resume(f) == false) + assert(coroutine.status(f) == "running") + local arg = {...} + for i=1,#arg do + _G.x = {coroutine.yield(table.unpack(arg[i]))} + end + return table.unpack(a) +end + +f = coroutine.create(foo) +assert(type(f) == "thread" and coroutine.status(f) == "suspended") +assert(string.find(tostring(f), "thread")) +local s,a,b,c,d +s,a,b,c,d = coroutine.resume(f, {1,2,3}, {}, {1}, {'a', 'b', 'c'}) +assert(s and a == nil and coroutine.status(f) == "suspended") +s,a,b,c,d = coroutine.resume(f) +eqtab(_G.x, {}) +assert(s and a == 1 and b == nil) +s,a,b,c,d = coroutine.resume(f, 1, 2, 3) +eqtab(_G.x, {1, 2, 3}) +assert(s and a == 'a' and b == 'b' and c == 'c' and d == nil) +s,a,b,c,d = coroutine.resume(f, "xuxu") +eqtab(_G.x, {"xuxu"}) +assert(s and a == 1 and b == 2 and c == 3 and d == nil) +assert(coroutine.status(f) == "dead") +s, a = coroutine.resume(f, "xuxu") +assert(not s and string.find(a, "dead") and coroutine.status(f) == "dead") + + +-- yields in tail calls +local function foo (i) return coroutine.yield(i) end +f = coroutine.wrap(function () + for i=1,10 do + assert(foo(i) == _G.x) + end + return 'a' +end) +for i=1,10 do _G.x = i; assert(f(i) == i) end +_G.x = 'xuxu'; assert(f('xuxu') == 'a') + +-- recursive +function pf (n, i) + coroutine.yield(n) + pf(n*i, i+1) +end + +f = coroutine.wrap(pf) +local s=1 +for i=1,10 do + assert(f(1, 1) == s) + s = s*i +end + +-- sieve implemented with co-routines + +-- generate all the numbers from 2 to n +function gen (n) + return coroutine.wrap(function () + for i=2,n do coroutine.yield(i) end + end) +end + +-- filter the numbers generated by 'g', removing multiples of 'p' +function filter (p, g) + return coroutine.wrap(function () + for n in g do + if n%p ~= 0 then coroutine.yield(n) end + end + end) +end + +-- generate primes up to 20 +local x = gen(20) +local a = {} +while 1 do + local n = x() + if n == nil then break end + table.insert(a, n) + x = filter(n, x) +end + +-- expect 8 primes and last one is 19 +assert(#a == 8 and a[#a] == 19) +x, a = nil + + +-- yielding across C boundaries + +co = coroutine.wrap(function() + coroutine.yield(20) + return 30 + end) + +assert(co() == 20) +assert(co() == 30) + + +local f = function (s, i) return coroutine.yield(i) end +function f (a, b) a = coroutine.yield(a); error{a + b} end +function g(x) return x[1]*2 end + + +-- unyieldable C call +do + local function f (c) + return c .. c + end + + local co = coroutine.wrap(function (c) + local s = string.gsub("a", ".", f) + return s + end) + assert(co() == "aa") +end + + +-- errors in coroutines +function foo () + coroutine.yield(3) + error(foo) +end + +function goo() foo() end +x = coroutine.wrap(goo) +assert(x() == 3) +x = coroutine.create(goo) +a,b = coroutine.resume(x) +assert(a and b == 3) +a,b = coroutine.resume(x) +assert(not a and b == foo and coroutine.status(x) == "dead") +a,b = coroutine.resume(x) +assert(not a and string.find(b, "dead") and coroutine.status(x) == "dead") + + +-- co-routines x for loop +function all (a, n, k) + if k == 0 then coroutine.yield(a) + else + for i=1,n do + a[k] = i + all(a, n, k-1) + end + end +end + +local a = 0 +for t in coroutine.wrap(function () all({}, 5, 4) end) do + a = a+1 +end +assert(a == 5^4) + + +-- access to locals of collected corroutines +local C = {}; setmetatable(C, {__mode = "kv"}) +local x = coroutine.wrap (function () + local a = 10 + local function f () a = a+10; return a end + while true do + a = a+1 + coroutine.yield(f) + end + end) + +C[1] = x; + +local f = x() +assert(f() == 21 and x()() == 32 and x() == f) +x = nil +collectgarbage() +assert(C[1] == nil) +assert(f() == 43 and f() == 53) + + +-- old bug: attempt to resume itself + +function co_func (current_co) + assert(coroutine.running() == current_co) + assert(coroutine.resume(current_co) == false) + coroutine.yield(10, 20) + assert(coroutine.resume(current_co) == false) + coroutine.yield(23) + return 10 +end + +local co = coroutine.create(co_func) +local a,b,c = coroutine.resume(co, co) +assert(a == true and b == 10 and c == 20) +a,b = coroutine.resume(co, co) +assert(a == true and b == 23) +a,b = coroutine.resume(co, co) +assert(a == true and b == 10) +assert(coroutine.resume(co, co) == false) +assert(coroutine.resume(co, co) == false) + + +-- attempt to resume 'normal' coroutine +local co1, co2 +co1 = coroutine.create(function () return co2() end) +co2 = coroutine.wrap(function () + assert(coroutine.status(co1) == 'normal') + assert(not coroutine.resume(co1)) + coroutine.yield(3) + end) + +a,b = coroutine.resume(co1) +assert(a and b == 3) +assert(coroutine.status(co1) == 'dead') + + +-- access to locals of erroneous coroutines +local x = coroutine.create (function () + local a = 10 + _G.f = function () a=a+1; return a end + error('x') + end) + +assert(not coroutine.resume(x)) +-- overwrite previous position of local `a' +assert(not coroutine.resume(x, 1, 1, 1, 1, 1, 1, 1)) +assert(_G.f() == 11) +assert(_G.f() == 12) + + +-- leaving a pending coroutine open +_X = coroutine.wrap(function () + local a = 10 + local x = function () a = a+1 end + coroutine.yield() + end) + +_X() + +assert(coroutine.running() == main) + + + +-- testing yields inside metamethods + +local mt = { + __eq = function(a,b) coroutine.yield(nil, "eq"); return a.x == b.x end, + __lt = function(a,b) coroutine.yield(nil, "lt"); return a.x < b.x end, + __le = function(a,b) coroutine.yield(nil, "le"); return a - b <= 0 end, + __add = function(a,b) coroutine.yield(nil, "add"); return a.x + b.x end, + __sub = function(a,b) coroutine.yield(nil, "sub"); return a.x - b.x end, + __mod = function(a,b) coroutine.yield(nil, "mod"); return a.x % b.x end, + __unm = function(a,b) coroutine.yield(nil, "unm"); return -a.x end, + + __concat = function(a,b) + coroutine.yield(nil, "concat"); + a = type(a) == "table" and a.x or a + b = type(b) == "table" and b.x or b + return a .. b + end, + __index = function (t,k) coroutine.yield(nil, "idx"); return t.k[k] end, + __newindex = function (t,k,v) coroutine.yield(nil, "nidx"); t.k[k] = v end, +} + + +local function new (x) + return setmetatable({x = x, k = {}}, mt) +end + + +local a = new(10) +local b = new(12) +local c = new"hello" + +local function run (f, t) + local i = 1 + local c = coroutine.wrap(f) + while true do + local res, stat = c() + if res then assert(t[i] == nil); return res, t end + assert(stat == t[i]) + i = i + 1 + end +end + + +assert(run(function () if (a>=b) then return '>=' else return '<' end end, + {"le", "sub"}) == "<") +-- '<=' using '<' +mt.__le = nil +assert(run(function () if (a<=b) then return '<=' else return '>' end end, + {"lt"}) == "<=") +assert(run(function () if (a==b) then return '==' else return '~=' end end, + {"eq"}) == "~=") + +assert(run(function () return a % b end, {"mod"}) == 10) + +assert(run(function () return a..b end, {"concat"}) == "1012") + +assert(run(function() return a .. b .. c .. a end, + {"concat", "concat", "concat"}) == "1012hello10") + +assert(run(function() return "a" .. "b" .. a .. "c" .. c .. b .. "x" end, + {"concat", "concat", "concat"}) == "ab10chello12x") + + +-- testing yields inside 'for' iterators + +local f = function (s, i) + if i%2 == 0 then coroutine.yield(nil, "for") end + if i < s then return i + 1 end + end + +assert(run(function () + local s = 0 + for i in f, 4, 0 do s = s + i end + return s + end, {"for", "for", "for"}) == 10) + + +return "OK" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_strings.lua b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_strings.lua new file mode 100644 index 000000000000..1725fd123796 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_strings.lua @@ -0,0 +1,241 @@ +--[[ +--***************************************************************************** +--* Copyright (C) 1994-2016 Lua.org, PUC-Rio. +--* +--* Permission is hereby granted, free of charge, to any person obtaining +--* a copy of this software and associated documentation files (the +--* "Software"), to deal in the Software without restriction, including +--* without limitation the rights to use, copy, modify, merge, publish, +--* distribute, sublicense, and/or sell copies of the Software, and to +--* permit persons to whom the Software is furnished to do so, subject to +--* the following conditions: +--* +--* The above copyright notice and this permission notice shall be +--* included in all copies or substantial portions of the Software. +--* +--* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +--* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +--* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +--* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +--* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +--* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +--* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--***************************************************************************** +--]] + +-- testing string library + +local maxi, mini = 0x7fffffffffffffff, 0x8000000000000000 + +-- testing string.sub +assert(string.sub("123456789",2,4) == "234") +assert(string.sub("123456789",7) == "789") +assert(string.sub("123456789",7,6) == "") +assert(string.sub("123456789",7,7) == "7") +assert(string.sub("123456789",0,0) == "") +assert(string.sub("123456789",-10,10) == "123456789") +assert(string.sub("123456789",1,9) == "123456789") +assert(string.sub("123456789",-10,-20) == "") +assert(string.sub("123456789",-1) == "9") +assert(string.sub("123456789",-4) == "6789") +assert(string.sub("123456789",-6, -4) == "456") +assert(string.sub("123456789", mini, -4) == "123456") +assert(string.sub("123456789", mini, maxi) == "123456789") +assert(string.sub("123456789", mini, mini) == "") +assert(string.sub("\000123456789",3,5) == "234") +assert(("\000123456789"):sub(8) == "789") + +-- testing string.find +assert(string.find("123456789", "345") == 3) +a,b = string.find("123456789", "345") +assert(string.sub("123456789", a, b) == "345") +assert(string.find("1234567890123456789", "345", 3) == 3) +assert(string.find("1234567890123456789", "345", 4) == 13) +assert(string.find("1234567890123456789", "346", 4) == nil) +assert(string.find("1234567890123456789", ".45", -9) == 13) +assert(string.find("abcdefg", "\0", 5, 1) == nil) +assert(string.find("", "") == 1) +assert(string.find("", "", 1) == 1) +assert(not string.find("", "", 2)) +assert(string.find('', 'aaa', 1) == nil) +assert(('alo(.)alo'):find('(.)', 1, 1) == 4) + +assert(string.len("") == 0) +assert(string.len("\0\0\0") == 3) +assert(string.len("1234567890") == 10) + +assert(#"" == 0) +assert(#"\0\0\0" == 3) +assert(#"1234567890" == 10) + +-- testing string.byte/string.char +assert(string.byte("a") == 97) +assert(string.byte("\xe4") > 127) +assert(string.byte(string.char(255)) == 255) +assert(string.byte(string.char(0)) == 0) +assert(string.byte("\0") == 0) +assert(string.byte("\0\0alo\0x", -1) == string.byte('x')) +assert(string.byte("ba", 2) == 97) +assert(string.byte("\n\n", 2, -1) == 10) +assert(string.byte("\n\n", 2, 2) == 10) +assert(string.byte("") == nil) +assert(string.byte("hi", -3) == nil) +assert(string.byte("hi", 3) == nil) +assert(string.byte("hi", 9, 10) == nil) +assert(string.byte("hi", 2, 1) == nil) +assert(string.char() == "") +assert(string.char(0, 255, 0) == "\0\255\0") +assert(string.char(0, string.byte("\xe4"), 0) == "\0\xe4\0") +assert(string.char(string.byte("\xe4l\0\195\179u", 1, -1)) == "\xe4l\0\195\179u") +assert(string.char(string.byte("\xe4l\0\195\179u", 1, 0)) == "") +assert(string.char(string.byte("\xe4l\0\195\179u", -10, 100)) == "\xe4l\0\195\179u") + +assert(string.upper("ab\0c") == "AB\0C") +assert(string.lower("\0ABCc%$") == "\0abcc%$") +assert(string.rep('teste', 0) == '') +assert(string.rep('t\195\169s\00t\195\170', 2) == 't\195\169s\0t\195\170t\195\169s\000t\195\170') +assert(string.rep('', 10) == '') + +-- repetitions with separator +assert(string.rep('teste', 0, 'xuxu') == '') +assert(string.rep('teste', 1, 'xuxu') == 'teste') +assert(string.rep('\1\0\1', 2, '\0\0') == '\1\0\1\0\0\1\0\1') +assert(string.rep('', 10, '.') == string.rep('.', 9)) + +assert(string.reverse"" == "") +assert(string.reverse"\0\1\2\3" == "\3\2\1\0") +assert(string.reverse"\0001234" == "4321\0") + +for i=0,30 do assert(string.len(string.rep('a', i)) == i) end + + +x = '"\195\174lo"\n\\' +assert(string.format('%q%s', x, x) == '"\\"\195\174lo\\"\\\n\\\\""\195\174lo"\n\\') +assert(string.format('%q', "\0") == [["\0"]]) +x = "\0\1\0023\5\0009" +assert(string.format("\0%c\0%c%x\0", string.byte("\xe4"), string.byte("b"), 140) == + "\0\xe4\0b8c\0") +assert(string.format('') == "") +assert(string.format("%c",34)..string.format("%c",48)..string.format("%c",90)..string.format("%c",100) == + string.format("%c%c%c%c", 34, 48, 90, 100)) +assert(string.format("%s\0 is not \0%s", 'not be', 'be') == 'not be\0 is not \0be') +assert(string.format("%%%d %010d", 10, 23) == "%10 0000000023") +x = string.format('"%-50s"', 'a') +assert(#x == 52) +assert(string.sub(x, 1, 4) == '"a ') + +assert(string.format("-%.20s.20s", string.rep("%", 2000)) == + "-"..string.rep("%", 20)..".20s") +assert(string.format('"-%20s.20s"', string.rep("%", 2000)) == + string.format("%q", "-"..string.rep("%", 2000)..".20s")) + +-- format x tostring +assert(string.format("%s %s", nil, true) == "nil true") +assert(string.format("%s %.4s", false, true) == "false true") +assert(string.format("%.3s %.3s", false, true) == "fal tru") + + +-- testing large numbers for format +do + local max, min = 0x7fffffff, -0x80000000 -- "large" for 32 bits + assert(string.sub(string.format("%8x", -1), -8) == "ffffffff") + assert(string.format("%x", max) == "7fffffff") + assert(string.sub(string.format("%x", min), -8) == "80000000") + assert(string.format("%d", max) == "2147483647") + assert(string.format("%d", min) == "-2147483648") + assert(string.format("%u", 0xffffffff) == "4294967295") + assert(string.format("%o", 0xABCD) == "125715") + + max, min = 0x7fffffffffffffff, -0x8000000000000000 + assert(string.format("0x%8X", 0x8f000003) == "0x8F000003") + assert(string.format("%d", 2^53) == "9007199254740992") + assert(string.format("%x", max) == "7fffffffffffffff") + assert(string.format("%x", min) == "8000000000000000") + assert(string.format("%d", max) == "9223372036854775807") + assert(string.format("%d", min) == "-9223372036854775808") +end + + +assert(table.concat{} == "") +assert(table.concat({}, 'x') == "") +assert(table.concat({'\0', '\0\1', '\0\1\2'}, '.\0.') == "\0.\0.\0\1.\0.\0\1\2") +local a = {}; for i=1,300 do a[i] = "xuxu" end +assert(table.concat(a, "123").."123" == string.rep("xuxu123", 300)) +assert(table.concat(a, "b", 20, 20) == "xuxu") +assert(table.concat(a, "", 20, 21) == "xuxuxuxu") +assert(table.concat(a, "x", 22, 21) == "") +assert(table.concat(a, "3", 299) == "xuxu3xuxu") +assert(table.concat({}, "x", 2^31-1, 2^31-2) == "") +assert(table.concat({}, "x", -2^31+1, -2^31) == "") +assert(table.concat({}, "x", 2^31-1, -2^31) == "") +assert(table.concat({[2^31-1] = "alo"}, "x", 2^31-1, 2^31-1) == "alo") + +a = {"a","b","c"} +assert(table.concat(a, ",", 1, 0) == "") +assert(table.concat(a, ",", 1, 1) == "a") +assert(table.concat(a, ",", 1, 2) == "a,b") +assert(table.concat(a, ",", 2) == "b,c") +assert(table.concat(a, ",", 3) == "c") +assert(table.concat(a, ",", 4) == "") + + +-- tests for gmatch +local a = 0 +for i in string.gmatch('abcde', '()') do assert(i == a+1); a=i end +assert(a==6) + +t = {n=0} +for w in string.gmatch("first second word", "%w+") do + t.n=t.n+1; t[t.n] = w +end +assert(t[1] == "first" and t[2] == "second" and t[3] == "word") + +t = {3, 6, 9} +for i in string.gmatch ("xuxx uu ppar r", "()(.)%2") do + assert(i == table.remove(t, 1)) +end +assert(#t == 0) + +t = {} +for i,j in string.gmatch("13 14 10 = 11, 15= 16, 22=23", "(%d+)%s*=%s*(%d+)") do + t[i] = j +end +a = 0 +for k,v in pairs(t) do assert(k+1 == v+0); a=a+1 end +assert(a == 3) + + +-- tests for gsub +function f1(s, p) + p = string.gsub(p, "%%([0-9])", function (s) return "%" .. (s+1) end) + p = string.gsub(p, "^(^?)", "%1()", 1) + p = string.gsub(p, "($?)$", "()%1", 1) + local t = {string.match(s, p)} + return string.sub(s, t[1], t[#t] - 1) +end + +assert(f1('alo alx 123 b\0o b\0o', '(..*) %1') == "b\0o b\0o") +assert(f1('axz123= 4= 4 34', '(.+)=(.*)=%2 %1') == '3= 4= 4 3') +assert(f1('=======', '^(=*)=%1$') == '=======') + +-- gsub with tables +assert(string.gsub("alo alo", ".", {}) == "alo alo") +assert(string.gsub("alo alo", "(.)", {a="AA", l=""}) == "AAo AAo") +assert(string.gsub("alo alo", "(.).", {a="AA", l="K"}) == "AAo AAo") +assert(string.gsub("alo alo", "((.)(.?))", {al="AA", o=false}) == "AAo AAo") + +assert(string.gsub("alo alo", "().", {2,5,6}) == "256 alo") + +t = {}; setmetatable(t, {__index = function (t,s) return string.upper(s) end}) +assert(string.gsub("a alo b hi", "%w%w+", t) == "a ALO b HI") + + +-- tests for match +assert(string.match('==========', '^([=]*)=%1$') == nil) +assert(string.match("alo xyzK", "(%w+)K") == "xyz") +assert(string.match("254 K", "(%d*)K") == "") +assert(string.match("alo ", "(%w*)$") == "") +assert(string.match("alo ", "(%w+)$") == nil) +assert(string.match("ab\0\1\2c", "[\0-\2]+") == "\0\1\2") + +return "OK" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_table.lua b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_table.lua new file mode 100644 index 000000000000..500117b19d90 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_table.lua @@ -0,0 +1,252 @@ +--[[ +--***************************************************************************** +--* Copyright (C) 1994-2016 Lua.org, PUC-Rio. +--* +--* Permission is hereby granted, free of charge, to any person obtaining +--* a copy of this software and associated documentation files (the +--* "Software"), to deal in the Software without restriction, including +--* without limitation the rights to use, copy, modify, merge, publish, +--* distribute, sublicense, and/or sell copies of the Software, and to +--* permit persons to whom the Software is furnished to do so, subject to +--* the following conditions: +--* +--* The above copyright notice and this permission notice shall be +--* included in all copies or substantial portions of the Software. +--* +--* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +--* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +--* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +--* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +--* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +--* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +--* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--***************************************************************************** +--]] + +-- testing table library + +-- workaround missing pcall in zfs lua implementation +local function tuple(...) + return {n=select('#', ...), ...} +end + +function pcall(f, ...) + local co = coroutine.create(f) + local res = tuple(coroutine.resume(co, ...)) + if res[1] and coroutine.status(co) == "suspended" then + res[1] = false + end + return table.unpack(res, 1, res.n) +end + + +-- workaround missing math lib in zfs lua implementation +local A1, A2 = 727595, 798405 -- 5^17=D20*A1+A2 +local D20, D40 = 1048576, 1099511627776 -- 2^20, 2^40 +local X1, X2 = 0, 1 +function rand() + local U = X2*A2 + local V = (X1*A2 + X2*A1) % D20 + V = (V*D20 + U) % D40 + X1 = V/D20 + X2 = V - X1*D20 + return V*100/D40 +end + + +-- testing unpack + +local unpack = table.unpack + +local x,y,z,a,n +a = {}; lim = 2000 +for i=1, lim do a[i]=i end +assert(select(lim, unpack(a)) == lim and select('#', unpack(a)) == lim) +x = unpack(a) +assert(x == 1) +x = {unpack(a)} +assert(#x == lim and x[1] == 1 and x[lim] == lim) +x = {unpack(a, lim-2)} +assert(#x == 3 and x[1] == lim-2 and x[3] == lim) +x = {unpack(a, 10, 6)} +assert(next(x) == nil) -- no elements +x = {unpack(a, 11, 10)} +assert(next(x) == nil) -- no elements +x,y = unpack(a, 10, 10) +assert(x == 10 and y == nil) +x,y,z = unpack(a, 10, 11) +assert(x == 10 and y == 11 and z == nil) +a,x = unpack{1} +assert(a==1 and x==nil) +a,x = unpack({1,2}, 1, 1) +assert(a==1 and x==nil) + +if not _no32 then + assert(not pcall(unpack, {}, 0, 2^31-1)) + assert(not pcall(unpack, {}, 1, 2^31-1)) + assert(not pcall(unpack, {}, -(2^31), 2^31-1)) + assert(not pcall(unpack, {}, -(2^31 - 1), 2^31-1)) + assert(pcall(unpack, {}, 2^31-1, 0)) + assert(pcall(unpack, {}, 2^31-1, 1)) + pcall(unpack, {}, 1, 2^31) + a, b = unpack({[2^31-1] = 20}, 2^31-1, 2^31-1) + assert(a == 20 and b == nil) + a, b = unpack({[2^31-1] = 20}, 2^31-2, 2^31-1) + assert(a == nil and b == 20) +end + +-- testing pack + +a = table.pack() +assert(a[1] == nil and a.n == 0) + +a = table.pack(table) +assert(a[1] == table and a.n == 1) + +a = table.pack(nil, nil, nil, nil) +assert(a[1] == nil and a.n == 4) + + +-- testing sort + + +-- test checks for invalid order functions +local function check (t) + local function f(a, b) assert(a and b); return true end + local s, e = pcall(table.sort, t, f) + assert(not s and e:find("invalid order function")) +end + +check{1,2,3,4} +check{1,2,3,4,5} +check{1,2,3,4,5,6} + + +function check (a, f) + f = f or function (x,y) return x<y end; + for n = #a, 2, -1 do + assert(not f(a[n], a[n-1])) + end +end + +a = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", + "Oct", "Nov", "Dec"} + +table.sort(a) +check(a) + +function perm (s, n) + n = n or #s + if n == 1 then + local t = {unpack(s)} + table.sort(t) + check(t) + else + for i = 1, n do + s[i], s[n] = s[n], s[i] + perm(s, n - 1) + s[i], s[n] = s[n], s[i] + end + end +end + +perm{} +perm{1} +perm{1,2} +perm{1,2,3} +perm{1,2,3,4} +perm{2,2,3,4} +perm{1,2,3,4,5} +perm{1,2,3,3,5} +perm{1,2,3,4,5,6} +perm{2,2,3,3,5,6} + +limit = 5000 + +a = {} +for i=1,limit do + a[i] = rand() +end + +table.sort(a) +check(a) + +table.sort(a) +check(a) + +a = {} +for i=1,limit do + a[i] = rand() +end + +i=0 +table.sort(a, function(x,y) i=i+1; return y<x end) +check(a, function(x,y) return y<x end) + + +table.sort{} -- empty array + +for i=1,limit do a[i] = false end +table.sort(a, function(x,y) return nil end) +check(a, function(x,y) return nil end) +for i,v in pairs(a) do assert(not v or i=='n' and v==limit) end + +A = {"álo", "\0first :-)", "alo", "then this one", "45", "and a new"} +table.sort(A) +check(A) + +tt = {__lt = function (a,b) return a.val < b.val end} +a = {} +for i=1,10 do a[i] = {val=rand(100)}; setmetatable(a[i], tt); end +table.sort(a) +check(a, tt.__lt) +check(a) + + +-- test remove +local function test (a) + table.insert(a, 10); table.insert(a, 2, 20); + table.insert(a, 1, -1); table.insert(a, 40); + table.insert(a, #a+1, 50) + table.insert(a, 2, -2) + assert(table.remove(a,1) == -1) + assert(table.remove(a,1) == -2) + assert(table.remove(a,1) == 10) + assert(table.remove(a,1) == 20) + assert(table.remove(a,1) == 40) + assert(table.remove(a,1) == 50) + assert(table.remove(a,1) == nil) +end + +a = {n=0, [-7] = "ban"} +test(a) +assert(a.n == 0 and a[-7] == "ban") + +a = {[-7] = "ban"}; +test(a) +assert(a.n == nil and #a == 0 and a[-7] == "ban") + + +table.insert(a, 1, 10); table.insert(a, 1, 20); table.insert(a, 1, -1) +assert(table.remove(a) == 10) +assert(table.remove(a) == 20) +assert(table.remove(a) == -1) + +a = {'c', 'd'} +table.insert(a, 3, 'a') +table.insert(a, 'b') +assert(table.remove(a, 1) == 'c') +assert(table.remove(a, 1) == 'd') +assert(table.remove(a, 1) == 'a') +assert(table.remove(a, 1) == 'b') +assert(#a == 0 and a.n == nil) + +a = {10,20,30,40} +assert(a[#a] == 40) +assert(table.remove(a, #a) == 40) +assert(a[#a] == 30) +assert(table.remove(a, 2) == 20) +assert(a[#a] == 30 and #a == 2) + + +return "OK" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.libraries.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.libraries.ksh new file mode 100755 index 000000000000..71afabdbe2d3 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.libraries.ksh @@ -0,0 +1,31 @@ +#!/bin/ksh -p +# +# 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) 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +verify_runnable "global" +arch=$(uname -m) + +if [[ "$arch" == "sparc64" ]]; then + log_note "Skipping lib_base and lib_coroutine on sparc64 to avoid stack overflow" +else + log_must_program $TESTPOOL $ZCP_ROOT/lua_core/tst.lib_base.lua + log_must_program $TESTPOOL $ZCP_ROOT/lua_core/tst.lib_coroutine.lua +fi +log_must_program $TESTPOOL $ZCP_ROOT/lua_core/tst.lib_strings.lua +log_must_program -m 40000000 $TESTPOOL $ZCP_ROOT/lua_core/tst.lib_table.lua + +log_pass "lua libraries work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.memory_limit.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.memory_limit.ksh new file mode 100755 index 000000000000..0533b8fa306f --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.memory_limit.ksh @@ -0,0 +1,77 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + + +# +# DESCRIPTION: +# Passing memory limit options to channel programs should work correctly. +# Programs that exceed these limits should fail gracefully. + + +verify_runnable "global" + +log_mustnot_checkerror_program "Memory limit exhausted" \ + -t 100000000 $TESTPOOL - <<-EOF + a = {}; + i = 0; + while true do + i = i + 1 + a[i] = "Here is the " .. i .. "th entry of a" + end; + return a +EOF + +log_assert "memory limit options work" +log_mustnot_checkerror_program "Memory limit exhausted" \ + -m 100000 -t 100000000 $TESTPOOL - <<-EOF + a = {}; + i = 0; + while true do + i = i + 1 + a[i] = "Here is the " .. i .. "th entry of a" + end; + return a +EOF + +log_must_program -m 100000 $TESTPOOL - <<-EOF + s = "teststring" + s = s .. s .. s .. s + return s +EOF + +log_assert "very small memory limits fail correctly" +log_mustnot_checkerror_program "Memory limit exhausted" -m 1 $TESTPOOL - <<-EOF + s = "teststring" + s = s .. s .. s .. s + return s +EOF + +# Set the memlimit, in case it is a non-default value +log_must set_tunable32 LUA_MAX_MEMLIMIT 100000000 + +log_mustnot_checkerror_program "Invalid instruction or memory limit" \ + -m 200000000 $TESTPOOL - <<-EOF + return 1; +EOF + +log_mustnot_checkerror_program "Return value too large" \ + -m 9223372036854775808 $TESTPOOL - <<-EOF + return 1; +EOF + +log_pass "Memory limits work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.nested_neg.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.nested_neg.ksh new file mode 100755 index 000000000000..2be9150c34fa --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.nested_neg.ksh @@ -0,0 +1,30 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +verify_runnable "global" + +arch=$(uname -m) + +if [[ "$arch" == "sparc64" ]]; then + log_unsupported "May cause stack overflow on sparc64 due to recursion" +else + log_mustnot_checkerror_program "too many C levels" \ + $TESTPOOL $ZCP_ROOT/lua_core/tst.nested_neg.zcp + + log_pass "Too many nested lua statements fail cleanly." +fi diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.nested_neg.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.nested_neg.zcp new file mode 100644 index 000000000000..afe3aa8f4f58 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.nested_neg.zcp @@ -0,0 +1,770 @@ +-- +-- 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) 2016 by Delphix. All rights reserved. +-- + +-- This program contains deeply nested LUA statements, such that the LUA +-- parser can not process it, given the limited size of the C stack. +-- This program contains 243 levels, well beyond the LUAI_MAXCCALLS limit + +i = 0 +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +return i diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.nested_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.nested_pos.ksh new file mode 100755 index 000000000000..0c8b8dd8d0ca --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.nested_pos.ksh @@ -0,0 +1,23 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +verify_runnable "global" + +log_must_program $TESTPOOL $ZCP_ROOT/lua_core/tst.nested_pos.zcp + +log_pass "Nested lua statements work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.nested_pos.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.nested_pos.zcp new file mode 100644 index 000000000000..02af95d99d18 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.nested_pos.zcp @@ -0,0 +1,71 @@ +-- +-- 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) 2016 by Delphix. All rights reserved. +-- + +-- This program should work with LUAI_MAXCCALLS=20 + +i = 0 +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +if true then +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end +i = i + 1 +end + +return i diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.nvlist_to_lua.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.nvlist_to_lua.ksh new file mode 100755 index 000000000000..eaba6427c96c --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.nvlist_to_lua.ksh @@ -0,0 +1,30 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# run C program which tests passing different nvlists to lua +# + +verify_runnable "global" + +log_assert "nvlist arguments can be passed to LUA." + +log_must nvlist_to_lua $TESTPOOL + +log_pass "nvlist arguments can be passed to LUA." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.recursive.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.recursive.zcp new file mode 100644 index 000000000000..9a13c1e7dc29 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.recursive.zcp @@ -0,0 +1,31 @@ +-- +-- 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) 2016 by Delphix. All rights reserved. +-- + +-- Test recursion in LUA. Deep recursion should work because it does +-- not use the C stack. The LUA stack is is allocated from the kernel's +-- heap, up to the specified memory limit. + +arg = ... +argv = arg["argv"] + +function f (x) + if (x == 0) then + return x + end + return f(x-1) + 1 +end + +r = f(argv[1]) +return r diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.recursive_neg.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.recursive_neg.ksh new file mode 100755 index 000000000000..c75048ae7d66 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.recursive_neg.ksh @@ -0,0 +1,24 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +verify_runnable "global" + +log_mustnot_checkerror_program "Memory limit exhausted" \ + $TESTPOOL $ZCP_ROOT/lua_core/tst.recursive.zcp 10000000 + +log_pass "Nearly-infinite recursive LUA calls fail cleanly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.recursive_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.recursive_pos.ksh new file mode 100755 index 000000000000..18d5d0f1ee47 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.recursive_pos.ksh @@ -0,0 +1,23 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +verify_runnable "global" + +log_must_program $TESTPOOL $ZCP_ROOT/lua_core/tst.recursive.zcp 10000 + +log_pass "Deeply recursive LUA calls succeed." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_large.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_large.ksh new file mode 100755 index 000000000000..ba9c40739471 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_large.ksh @@ -0,0 +1,54 @@ +#!/bin/ksh -p +# +# 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) 2016, 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: Returning very large (up to the memory limit) lists should +# function correctly. +# + +verify_runnable "global" + +fs=$TESTPOOL/$TESTFS/testchild + +function cleanup +{ + datasetexists $fs && log_must zfs destroy -R $fs +} + +log_onexit cleanup + +log_must zfs create $fs + +# +# Actually checking in the ~500kb expected result of this program would be +# awful, so we just make sure it was as long as we expected. +# +output_lines=$(log_must zfs program $TESTPOOL \ + $ZCP_ROOT/lua_core/tst.return_large.zcp | wc -l) + +[[ $output_lines -lt 5000 ]] && + log_fail "Expected return of full list but only got $output_lines lines" + +# +# Make sure we fail if the return is over the memory limit +# +log_mustnot_program -m 10000 $TESTPOOL \ + $ZCP_ROOT/lua_core/tst.return_large.zcp + +log_pass "Large return values work properly" + diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_large.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_large.zcp new file mode 100644 index 000000000000..0ea9f8930eac --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_large.zcp @@ -0,0 +1,24 @@ +-- +-- 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) 2016, 2017 by Delphix. All rights reserved. +-- + +basestring = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" .. + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + +ret = {} +for i=1,5000 do + table.insert(ret, basestring) +end + +return ret diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_nvlist_neg.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_nvlist_neg.ksh new file mode 100755 index 000000000000..10afa6727847 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_nvlist_neg.ksh @@ -0,0 +1,63 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Try returning various values that lua allows you to construct, +# but that cannot be represented as nvlists and therefore should +# cause the script to fail (but not panic). Try sending the values +# back to userland from both "return" and "error()". +# + +verify_runnable "both" + +set -A args 'function() return 1 end' \ + '{[{}]=true}' \ + '{[function() return 1 end]=0}' \ + 'assert' \ + '0, assert' \ + 'true, {[{}]=0}' \ + '{val=true}, {val=false}' \ + '{1, 2, 3}, {[4]=5}' \ + 'nil, true, 1, "test", {}, {val=true}' \ + '{[false]=true, ["false"]=false}' \ + '{[true]=false, ["true"]=true}' \ + '{[0]=true, ["0"]=false}' \ + '{0,0,0,["1"]=0}' \ + '{0,0,0,["2"]=0}' \ + '{0,0,0,["3"]=0}' + +typeset -i last_index=$((${#args[*]} - 1)) +for i in $(seq 0 $last_index); do + log_note "running program: ${args[i]}" + log_mustnot_checkerror_program "execution failed" $TESTPOOL - <<-EOF + return ${args[i]} + EOF + ((i = i + 1)) +done + +for i in $(seq 0 $last_index); do + log_note "running program: ${args[i]}" + log_mustnot_checkerror_program "execution failed" $TESTPOOL - <<-EOF + error(${args[i]}) + EOF + ((i = i + 1)) +done + +log_pass "Returning lua constructs that cannot be converted to " \ + "nvlists fails as expected." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_nvlist_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_nvlist_pos.ksh new file mode 100755 index 000000000000..8b4ef6e760b0 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_nvlist_pos.ksh @@ -0,0 +1,57 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Try returning various lua values that should be converted +# to nvlists. Also, try to pass them to error(). +# + +verify_runnable "global" + +set -A args "" \ + "nil" \ + "true" \ + "1" \ + "\"test\"" \ + "{}" \ + "{val=0}" \ + "{{1, {2, 3}, {val1={val2=true}}}, {test=\"yes\"}}" \ + "EINVAL" + +log_assert "Returning valid lua constructs works." + +typeset -i i=0 +while (( i < ${#args[*]} )); do + log_note "running program: return ${args[i]}" + log_must_program $TESTPOOL - <<-EOF + return ${args[i]} + EOF + ((i = i + 1)) +done + +typeset -i i=0 +while (( i < ${#args[*]} )); do + log_note "running program: error(${args[i]})" + log_mustnot_checkerror_program "in function 'error'" $TESTPOOL - <<-EOF + error(${args[i]}) + EOF + ((i = i + 1)) +done + +log_pass "Returning valid lua constructs works." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_recursive_table.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_recursive_table.ksh new file mode 100755 index 000000000000..18c035e0464b --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_recursive_table.ksh @@ -0,0 +1,31 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Returning a recursive table should fail gracefully +# + +verify_runnable "both" + +log_assert "Returning a recursive table should fail gracefully." + +log_mustnot_checkerror_program "Maximum table depth" \ + $TESTPOOL $ZCP_ROOT/lua_core/tst.return_recursive_table.zcp + +log_pass "Returning a recursive table should fail gracefully." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_recursive_table.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_recursive_table.zcp new file mode 100644 index 000000000000..21e6c60d8e26 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.return_recursive_table.zcp @@ -0,0 +1,21 @@ +-- +-- 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) 2016 by Delphix. All rights reserved. +-- + +-- This program returns a self-referential data structure. + +a = {} +a["key"] = "val" +a["self"] = a +return a diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.stack_gsub.err b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.stack_gsub.err new file mode 100644 index 000000000000..45f2d9ef0ea6 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.stack_gsub.err @@ -0,0 +1,18 @@ +Channel program execution failed: +C stack overflow +stack traceback: + [C]: in function 'gsub' + [string "channel program"]:17: in function <[string "channel program"]:16> + [C]: in function 'gsub' + [string "channel program"]:17: in function <[string "channel program"]:16> + [C]: in function 'gsub' + [string "channel program"]:17: in function <[string "channel program"]:16> + [C]: in function 'gsub' + [string "channel program"]:17: in function <[string "channel program"]:16> + [C]: in function 'gsub' + [string "channel program"]:17: in function <[string "channel program"]:16> + [C]: in function 'gsub' + [string "channel program"]:17: in function <[string "channel program"]:16> + [C]: in function 'gsub' + [string "channel program"]:17: in function <[string "channel program"]:16> + (...tail calls...)
\ No newline at end of file diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.stack_gsub.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.stack_gsub.ksh new file mode 100755 index 000000000000..ecabf3a3fec7 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.stack_gsub.ksh @@ -0,0 +1,33 @@ +#!/bin/ksh -p +# +# 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) 2020 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Overflowing the C stack using recursive gsub() should be handled +# gracefully. gsub() uses more stack space than typical, so it relies +# on LUAI_MINCSTACK to ensure that we don't overflow the Linux kernel's +# stack. +# + +verify_runnable "global" + +log_assert "recursive gsub() should be handled gracefully" + +log_mustnot_program $TESTPOOL $ZCP_ROOT/lua_core/tst.stack_gsub.zcp + +log_pass "recursive gsub() should be handled gracefully" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.stack_gsub.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.stack_gsub.zcp new file mode 100644 index 000000000000..a493363ca68d --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.stack_gsub.zcp @@ -0,0 +1,20 @@ +-- +-- 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) 2020 by Delphix. All rights reserved. +-- + +function f(s) + return string.gsub(s, ".", f) +end + +return f("foo") diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.timeout.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.timeout.ksh new file mode 100755 index 000000000000..22ea37548173 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.timeout.ksh @@ -0,0 +1,55 @@ +#!/bin/ksh -p +# +# 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) 2016, 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Passing the instruction limit option to channel programs should work +# correctly. Programs that exceed these instruction limits should fail +# gracefully. +# + +verify_runnable "both" + +log_assert "Timeouts work correctly." + +log_mustnot_checkerror_program "Channel program timed out" \ + $TESTPOOL $ZCP_ROOT/lua_core/tst.timeout.zcp + +function test_instr_limit +{ + typeset lim=$1 + + error=$(zfs program -t $lim $TESTPOOL $ZCP_ROOT/lua_core/tst.timeout.zcp 2>&1) + [[ $? -ne 0 ]] || log_fail "Channel program with limit $lim exited 0: $error" + + instrs_run=$(echo $error | awk -F "chunk" '{print $2}' | awk '{print $1}') + if [[ $instrs_run -lt $(( $lim - 100 )) ]]; then + log_fail "Runtime (${instrs_run} instr) < limit (${lim} - 100 instr)" + elif [[ $instrs_run -gt $(( $lim + 100 )) ]]; then + log_fail "Runtime (${instrs_run} instr) > limit (${lim} + 100 instr)" + fi + log_note "With limit $lim the program ended after $instrs_run instructions" +} + +test_instr_limit 1000 +test_instr_limit 10000 +test_instr_limit 100000 +test_instr_limit 1000000 +test_instr_limit 2000000 + +log_pass "Timeouts work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.timeout.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.timeout.zcp new file mode 100644 index 000000000000..d74b1a73c2e5 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.timeout.zcp @@ -0,0 +1,22 @@ +-- +-- 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) 2016 by Delphix. All rights reserved. +-- + +-- This program runs forever (until timed out). + +i = 1; +while true do + i = i + 1 +end; +return i diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/Makefile.am new file mode 100644 index 000000000000..4d9aa9cebbfc --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/Makefile.am @@ -0,0 +1,53 @@ +pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/channel_program/synctask_core +dist_pkgdata_SCRIPTS = \ + cleanup.ksh \ + setup.ksh \ + tst.destroy_fs.ksh \ + tst.destroy_snap.ksh \ + tst.get_count_and_limit.ksh \ + tst.get_index_props.ksh \ + tst.get_mountpoint.ksh \ + tst.get_neg.ksh \ + tst.get_number_props.ksh \ + tst.get_string_props.ksh \ + tst.get_type.ksh \ + tst.get_userquota.ksh \ + tst.get_written.ksh \ + tst.inherit.ksh \ + tst.list_bookmarks.ksh \ + tst.list_children.ksh \ + tst.list_clones.ksh \ + tst.list_holds.ksh \ + tst.list_snapshots.ksh \ + tst.list_system_props.ksh \ + tst.list_user_props.ksh \ + tst.parse_args_neg.ksh \ + tst.promote_conflict.ksh \ + tst.promote_multiple.ksh \ + tst.promote_simple.ksh \ + tst.rollback_mult.ksh \ + tst.rollback_one.ksh \ + tst.set_props.ksh \ + tst.snapshot_destroy.ksh \ + tst.snapshot_neg.ksh \ + tst.snapshot_recursive.ksh \ + tst.bookmark.create.ksh \ + tst.bookmark.copy.ksh \ + tst.snapshot_simple.ksh \ + tst.terminate_by_signal.ksh + +dist_pkgdata_DATA = \ + tst.get_index_props.out \ + tst.get_index_props.zcp \ + tst.get_number_props.out \ + tst.get_number_props.zcp \ + tst.get_string_props.out \ + tst.get_string_props.zcp \ + tst.promote_conflict.zcp \ + tst.set_props.zcp \ + tst.snapshot_destroy.zcp \ + tst.snapshot_neg.zcp \ + tst.snapshot_recursive.zcp \ + tst.snapshot_simple.zcp \ + tst.bookmark.create.zcp \ + tst.bookmark.copy.zcp diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/cleanup.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/cleanup.ksh new file mode 100755 index 000000000000..3ddcb4d2759c --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/cleanup.ksh @@ -0,0 +1,22 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +default_cleanup_noexit +destroy_pool testpool2 + +log_pass diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/setup.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/setup.ksh new file mode 100755 index 000000000000..5837bf1a14c7 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/setup.ksh @@ -0,0 +1,25 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +DISK=${DISKS%% *} + +TESTPOOLDISK=${DISKS%% *} +TESTPOOL2DISK=${DISKS##* } + +default_setup ${TESTPOOLDISK} +create_pool testpool2 ${TESTPOOL2DISK} diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.bookmark.copy.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.bookmark.copy.ksh new file mode 100755 index 000000000000..81f570d9e1e2 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.bookmark.copy.ksh @@ -0,0 +1,45 @@ +#!/bin/ksh -p +# +# 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) 2019, 2020 by Christian Schwarz. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: Make sure bookmark copying works in channel programs +# + +verify_runnable "global" + +fs=$TESTPOOL/$TESTFS/testchild +snapname=testsnap +bookname=testbookmark +bookcopyname=testbookmark_copy + +function cleanup +{ + destroy_dataset $fs "-R" +} + +log_onexit cleanup + +log_must zfs create $fs + +log_must zfs snapshot $fs@$snapname +log_must zfs bookmark $fs@$snapname "$fs#$bookname" + +log_must_program_sync $TESTPOOL \ + $ZCP_ROOT/synctask_core/tst.bookmark.copy.zcp $fs $bookname $bookcopyname + +log_pass "Simple bookmark copying works" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.bookmark.copy.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.bookmark.copy.zcp new file mode 100644 index 000000000000..9473035f025b --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.bookmark.copy.zcp @@ -0,0 +1,32 @@ +-- +-- 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) 2019, 2020 by Christian Schwarz. All rights reserved. +-- + +-- This program should be invoked as "zfs program <pool> <prog> <fs> <source_book> <new_book>" + +args = ... +argv = args["argv"] +fs = argv[1] +source = fs .. "#" .. argv[2] +new = fs .. "#" .. argv[3] +assert(zfs.sync.bookmark(source, new) == 0) +books = {} +count = 0 +for s in zfs.list.bookmarks(fs) do + count = count + 1 + books[s] = 1 +end +assert(count == 2) +assert(books[source] == 1) +assert(books[new] == 1) diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.bookmark.create.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.bookmark.create.ksh new file mode 100755 index 000000000000..05ec9cc67602 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.bookmark.create.ksh @@ -0,0 +1,43 @@ +#!/bin/ksh -p +# +# 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) 2019, 2020 by Christian Schwarz. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: Make sure basic bookmark functionality works in channel programs +# + +verify_runnable "global" + +fs=$TESTPOOL/$TESTFS/testchild +snapname=testsnap +bookname=testbookmark + +function cleanup +{ + destroy_dataset $fs "-R" +} + +log_onexit cleanup + +log_must zfs create $fs + +log_must zfs snapshot $fs@$snapname + +log_must_program_sync $TESTPOOL \ + $ZCP_ROOT/synctask_core/tst.bookmark.create.zcp $fs $snapname $bookname + +log_pass "Simple bookmark creation works" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.bookmark.create.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.bookmark.create.zcp new file mode 100644 index 000000000000..eb53fd16ce16 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.bookmark.create.zcp @@ -0,0 +1,26 @@ +-- +-- 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) 2019, 2020 by Christian Schwarz. All rights reserved. +-- + +-- This program should be invoked as "zfs program <pool> <prog> <fs> <snap> <book>" + +args = ... +argv = args["argv"] +assert(zfs.sync.bookmark(argv[1] .. "@" .. argv[2], argv[1] .. "#" .. argv[3]) == 0) +books = {} +for s in zfs.list.bookmarks(argv[1]) do + table.insert(books, s) +end +assert(#books == 1) +assert(books[1] == (argv[1] .. "#" .. argv[3])) diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.destroy_fs.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.destroy_fs.ksh new file mode 100755 index 000000000000..45a3fdb66a6f --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.destroy_fs.ksh @@ -0,0 +1,45 @@ +#!/bin/ksh -p +# +# 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) 2016, 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +verify_runnable "global" + +fs=$TESTPOOL/$TESTFS/testchild + +function cleanup +{ + destroy_dataset $fs +} + +log_onexit cleanup + +log_must zfs create $fs +log_must zfs unmount $fs + +log_must datasetexists $fs + +log_must_program_sync $TESTPOOL - $fs <<-EOF + arg = ... + fs = arg["argv"][1] + err = zfs.sync.destroy(fs) + msg = "destroying " .. fs .. " err=" .. err + return msg +EOF + +log_mustnot datasetexists $fs + +log_pass "Destroying filesystem with channel program works." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.destroy_snap.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.destroy_snap.ksh new file mode 100755 index 000000000000..571d7f87c1b5 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.destroy_snap.ksh @@ -0,0 +1,44 @@ +#!/bin/ksh -p +# +# 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) 2016, 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +verify_runnable "global" + +snap=$TESTPOOL/$TESTFS@$TESTSNAP + +function cleanup +{ + destroy_dataset $snap +} + +log_onexit cleanup + +create_snapshot $TESTPOOL/$TESTFS $TESTSNAP + +log_must snapexists $snap + +log_must_program_sync $TESTPOOL - $snap <<-EOF + arg = ... + snap = arg["argv"][1] + err = zfs.sync.destroy(snap) + msg = "destroying " .. snap .. " err=" .. err + return msg +EOF + +log_mustnot snapexists $snap + +log_pass "Destroying snapshot with channel program works." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_count_and_limit.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_count_and_limit.ksh new file mode 100755 index 000000000000..70330c91a0e7 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_count_and_limit.ksh @@ -0,0 +1,89 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib +. $STF_SUITE/tests/functional/zvol/zvol_common.shlib + +# +# DESCRIPTION: +# Getting filesystem and snapshot count/limit props should work correctly. +# + +verify_runnable "global" + +fs=$TESTPOOL/testchild +snap=$fs@$TESTSNAP + +function cleanup +{ + destroy_dataset $fs "-R" + log_must rm -rf $fs/foo + log_must rm -rf $fs/bar +} + +log_onexit cleanup + +log_must zfs create $fs +log_must zfs create $fs/foo +create_snapshot $fs $TESTSNAP + +log_must_program $TESTPOOL - <<-EOF + ans, src = zfs.get_prop("$fs", "snapshot_limit") + assert(ans == -1) + assert(src == 'default') + + ans, src = zfs.get_prop("$fs", "snapshot_count") + assert(ans == nil) + assert(src == nil) +EOF + +log_must_program $TESTPOOL - <<-EOF + ans, src = zfs.get_prop("$fs", "filesystem_limit") + assert(ans == -1) + assert(src == 'default') + + ans, src = zfs.get_prop("$fs", "filesystem_count") + assert(ans == nil) + assert(src == nil) +EOF + +log_must zfs set snapshot_limit=10 $fs + +log_must_program $TESTPOOL - <<-EOF + ans, src = zfs.get_prop("$fs", "snapshot_limit") + assert(ans == 10) + assert(src == '$fs') + + ans, src = zfs.get_prop("$fs", "snapshot_count") + assert(ans == 1) + assert(src == nil) +EOF + +log_must zfs set filesystem_limit=8 $fs + +log_must zfs create $fs/bar + +log_must_program $TESTPOOL - <<-EOF + ans, src = zfs.get_prop("$fs", "filesystem_limit") + assert(ans == 8) + assert(src == '$fs') + + ans, src = zfs.get_prop("$fs", "filesystem_count") + assert(ans == 2) + assert(src == nil) +EOF + +log_pass "Getting filesystem and snapshot count/limit props should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_index_props.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_index_props.ksh new file mode 100755 index 000000000000..eed3e0bce5fc --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_index_props.ksh @@ -0,0 +1,41 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Getting index props should work correctly. +# + +verify_runnable "global" + +fs=$TESTPOOL/$TESTFS/testchild +snap=$fs@$TESTSNAP +function cleanup +{ + destroy_dataset $fs "-R" +} + +log_onexit cleanup + +log_must zfs create -o version=5 $fs +create_snapshot $fs $TESTSNAP + +os=$(uname) +log_must_program $TESTPOOL $ZCP_ROOT/synctask_core/tst.get_index_props.zcp $fs $snap $os + +log_pass "Getting index props should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_index_props.out b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_index_props.out new file mode 100644 index 000000000000..40c58b4b3aea --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_index_props.out @@ -0,0 +1,4 @@ +Channel program fully executed with return value: + return: + 1: + 2: diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_index_props.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_index_props.zcp new file mode 100644 index 000000000000..10ef8e7f839a --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_index_props.zcp @@ -0,0 +1,77 @@ +-- +-- 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) 2016 by Delphix. All rights reserved. +-- + +arg = ... +fs = arg["argv"][1] +snap = arg["argv"][2] +os = arg["argv"][3] + +props = {} + +-- prop filesystem snapshot +props['redundant_metadata'] = {{'all', 'default'}, {nil, nil}} +props['sync'] = {{'standard', 'default'}, {nil, nil}} +props['checksum'] = {{'on', 'default'}, {nil, nil}} +props['dedup'] = {{'off', 'default'}, {nil, nil}} +props['compression'] = {{'off', 'default'}, {nil, nil}} +props['snapdir'] = {{'hidden', 'default'}, {nil, nil}} +if os == "Linux" then + props['acltype'] = {{'off', 'default'}, {'off', 'default'}} +elseif os == "FreeBSD" then + props['aclmode'] = {{'discard', 'default'}, {'discard', 'default'}} +end +props['aclinherit'] = {{'restricted','default'}, {nil, nil}} +props['copies'] = {{'1', 'default'}, {nil, nil}} +props['primarycache'] = {{'all', 'default'}, {'all', 'default'}} +props['secondarycache'] = {{'all', 'default'}, {'all', 'default'}} +props['logbias'] = {{'latency', 'default'}, {nil, nil}} +props['atime'] = {{'on', 'default'}, {nil, nil}} +props['devices'] = {{'on', 'default'}, {'on', 'default'}} +props['exec'] = {{'on', 'default'}, {'on', 'default'}} +props['setuid'] = {{'on', 'default'}, {'on', 'default'}} +props['readonly'] = {{'off', 'default'}, {nil, nil}} +if os == "FreeBSD" then + props['jailed'] = {{'off', 'default'}, {nil, nil}} +else + props['zoned'] = {{'off', 'default'}, {nil, nil}} +end +props['vscan'] = {{'off', 'default'}, {nil, nil}} +props['nbmand'] = {{'off', 'default'}, {'off', 'default'}} +props['version'] = {{'5', nil}, {'5', nil}} +props['canmount'] = {{'on', 'default'}, {nil, nil}} +props['mounted'] = {{nil, nil}, {nil, nil}} +props['defer_destroy'] = {{nil, nil}, {'off', nil}} +props['normalization'] = {{'none', nil}, {'none', nil}} +props['casesensitivity'] = {{'sensitive', nil}, {'sensitive', nil}} +props['utf8only'] = {{'off', nil}, {'off', nil}} +props['dnodesize'] = {{'legacy', 'default'}, {nil, nil}} +props['relatime'] = {{'off', 'default'}, {nil, nil}} +props['overlay'] = {{'off', 'default'}, {nil, nil}} + +fs_fails = {} +snap_fails = {} +for prop, expected in pairs(props) do + ans, src = zfs.get_prop(fs, prop) + if ((ans ~= expected[1][1]) or (src ~= expected[1][2])) then + fs_fails[prop] = {ans, src} + end + + ans, src = zfs.get_prop(snap, prop) + if ((ans ~= expected[2][1]) or (src ~= expected[2][2])) then + snap_fails[prop] = {ans, src} + end +end + +return {fs_fails, snap_fails} diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_mountpoint.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_mountpoint.ksh new file mode 100755 index 000000000000..f3cf396aa1f2 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_mountpoint.ksh @@ -0,0 +1,88 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Getting dataset mountpoint should work correctly. +# + +verify_runnable "global" + +fs=$TESTPOOL/testmount +snap=$fs@$TESTSNAP +clone=$TESTPOOL/$TESTCLONE +mnt1=/$fs/mnt1 +mnt2=/$fs/mnt2 + +function cleanup +{ + destroy_dataset $clone + destroy_dataset $fs "-R" + log_must rm -rf $mnt1 + log_must rm -rf $mnt2 +} + +log_onexit cleanup + +log_must zfs create $fs +create_snapshot $fs $TESTSNAP +create_clone $snap $clone + +log_must_program $TESTPOOL - <<-EOF + ans, src = zfs.get_prop("$fs", "mountpoint") + assert(ans == '/$fs') + assert(src == 'default') +EOF + +log_must_program $TESTPOOL - <<-EOF + ans, src = zfs.get_prop("$snap", "mountpoint") + assert(ans == nil) + assert(src == nil) +EOF + +log_must_program $TESTPOOL - <<-EOF + ans, src = zfs.get_prop("$clone", "mountpoint") + assert(ans == '/$clone') + assert(src == 'default') +EOF + +log_must mkdir $mnt1 +log_must mkdir $mnt2 + +log_must zfs set mountpoint=$mnt1 $fs +log_must zfs set mountpoint=$mnt2 $clone + +log_must_program $TESTPOOL - <<-EOF + ans, src = zfs.get_prop("$fs", "mountpoint") + assert(ans == '$mnt1') + assert(src == '$fs') +EOF + +log_must_program $TESTPOOL - <<-EOF + ans, src = zfs.get_prop("$snap", "mountpoint") + assert(ans == nil) + assert(src == nil) +EOF + +log_must_program $TESTPOOL - <<-EOF + ans, src = zfs.get_prop("$clone", "mountpoint") + assert(ans == '$mnt2') + assert(src == '$clone') +EOF + +log_pass "Getting dataset mountpoint should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_neg.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_neg.ksh new file mode 100755 index 000000000000..17f7a8fd9749 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_neg.ksh @@ -0,0 +1,43 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Getting failures should work correctly. +# + +verify_runnable "global" +fs=$TESTPOOL/$TESTFS/testchild +function cleanup +{ + destroy_dataset $fs +} + +log_onexit cleanup + +log_must zfs create $fs + +log_mustnot_program $TESTPOOL - <<-EOF + ans, setpoint = zfs.get_prop("$fs", "notaprop") +EOF + +log_mustnot_program $TESTPOOL - <<-EOF + ans, setpoint = zfs.get_prop("notadataset", "type") +EOF + +log_pass "Getting failures should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_number_props.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_number_props.ksh new file mode 100755 index 000000000000..942930fa6923 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_number_props.ksh @@ -0,0 +1,52 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Getting number props should work correctly on filesystems, +# snapshots and volumes. +# + +verify_runnable "global" + +fs=$TESTPOOL/$TESTFS/testchild +snap=$fs@$TESTSNAP +vol=$TESTPOOL/$TESTVOL + +function cleanup +{ + destroy_dataset $fs "-R" + destroy_dataset $vol +} + +log_onexit cleanup + +log_must zfs create $fs +create_snapshot $fs $TESTSNAP +log_must zfs create -V $VOLSIZE $TESTPOOL/$TESTVOL + +# +# Set snapshot_limit and filesystem_limit for the filesystem so that the +# snapshot_count and filesystem_count properties return a value. +# +log_must zfs set snapshot_limit=10 filesystem_limit=10 $fs +log_must zfs set snapshot_limit=10 $vol + +log_must_program $TESTPOOL $ZCP_ROOT/synctask_core/tst.get_number_props.zcp $fs $snap $vol + +log_pass "Getting number props should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_number_props.out b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_number_props.out new file mode 100644 index 000000000000..be68500097ad --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_number_props.out @@ -0,0 +1,5 @@ +Channel program fully executed with return value: + return: + 1: + 2: + 3: diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_number_props.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_number_props.zcp new file mode 100644 index 000000000000..79969509be89 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_number_props.zcp @@ -0,0 +1,101 @@ +-- +-- 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) 2016 by Delphix. All rights reserved. +-- + +arg = ... +fs = arg["argv"][1] +snap = arg["argv"][2] +vol = arg["argv"][3] + +props = {} + +-- The values indicate whether or not a property should be returned, +-- not the value of the property. A better approach might be to compare +-- their values to the output of 'zfs get <prop>' + +-- prop filesystem snapshot volume +props['used'] = {{true, nil}, {true, nil}, {true, nil}} +props['available'] = {{true, nil}, {nil, nil}, {true, nil}} +props['referenced'] = {{true, nil}, {true, nil}, {true, nil}} +props['compressratio'] = {{true, nil}, {true, nil}, {true, nil}} +props['refcompressratio'] = {{true, nil}, {true, nil}, {true, nil}} +props['volblocksize'] = {{nil, nil}, {nil, nil}, {true, nil}} +props['usedbysnapshots'] = {{true, nil}, {nil, nil}, {true, nil}} +props['usedbydataset'] = {{true, nil}, {nil, nil}, {true, nil}} +props['usedbychildren'] = {{true, nil}, {nil, nil}, {true, nil}} +props['usedbyrefreservation'] = {{true, nil}, {nil, nil}, {true, nil}} +props['userrefs'] = {{nil, nil}, {true, nil}, {nil, nil}} +props['written'] = {{true, nil}, {true, nil}, {true, nil}} +props['logicalused'] = {{true, nil}, {nil, nil}, {true, nil}} +props['logicalreferenced'] = {{true, nil}, {true, nil}, {true, nil}} +props['quota'] = {{true, 'default'}, {nil, nil}, {nil, nil}} +props['reservation'] = {{true, 'default'}, {nil, nil}, {true, 'default'}} +-- Note that zfsonlinux allows volsize for snapshot which differs from openzfs +-- props['volsize'] = {{nil, nil}, {nil, nil}, {true, vol}} +props['refquota'] = {{true, 'default'}, {nil, nil}, {nil, nil}} +props['refreservation'] = {{true, 'default'}, {nil, nil}, {true, vol}} +props['filesystem_limit'] = {{true, fs}, {nil, nil}, {nil, nil}} +props['snapshot_limit'] = {{true, fs}, {nil, nil}, {true, vol}} +props['filesystem_count'] = {{true, nil}, {nil, nil}, {nil, nil}} +props['snapshot_count'] = {{true, nil}, {nil, nil}, {true, nil}} +props['recordsize'] = {{true, 'default'}, {nil, nil}, {nil, nil}} +props['creation'] = {{true, nil}, {true, nil}, {true, nil}} +-- hidden props +props['createtxg'] = {{true, nil}, {true, nil}, {true, nil}} +props['numclones'] = {{nil, nil}, {true, nil}, {nil, nil}} +props['guid'] = {{true, nil}, {true, nil}, {true, nil}} +props['useraccounting'] = {{true, nil}, {true, nil}, {true, nil}} +props['unique'] = {{true, nil}, {true, nil}, {true, nil}} +props['objsetid'] = {{true, nil}, {true, nil}, {true, nil}} +props['inconsistent'] = {{true, nil}, {true, nil}, {true, nil}} + + +fs_fails = {} +snap_fails = {} +vol_fails = {} + +function match(n, ans, src, expected) + if ((expected[n][1] == nil) and (ans ~= nil)) then + return false + end + + if ((expected[n][1] == true) and (ans == nil)) then + return false + end + + if (expected[n][2] ~= src) then + return false + end + + return true +end + +for prop, expected in pairs(props) do + ans, src = zfs.get_prop(fs, prop) + if not (match(1, ans, src, expected)) then + fs_fails[prop] = {ans, src} + end + + ans, src = zfs.get_prop(snap, prop) + if not (match(2, ans, src, expected)) then + snap_fails[prop] = {ans, src} + end + + ans, src = zfs.get_prop(vol, prop) + if not (match(3, ans, src, expected)) then + vol_fails[prop] = {ans, src} + end +end + +return {fs_fails, snap_fails, vol_fails} diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_string_props.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_string_props.ksh new file mode 100755 index 000000000000..b7d784489ac8 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_string_props.ksh @@ -0,0 +1,45 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Getting string props should work correctly. +# + +verify_runnable "global" + +fs=$TESTPOOL/testchild +snap=$fs@$TESTSNAP +clone=$TESTPOOL/$TESTCLONE + + +function cleanup +{ + datasetexists $clone && log_must zfs destroy $clone + datasetexists $fs && log_must zfs destroy -R $fs +} + +log_onexit cleanup + +log_must zfs create $fs +create_snapshot $fs $TESTSNAP +create_clone $snap $clone + +log_must_program $TESTPOOL $ZCP_ROOT/synctask_core/tst.get_string_props.zcp $fs $snap $clone + +log_pass "Getting string props should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_string_props.out b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_string_props.out new file mode 100644 index 000000000000..be68500097ad --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_string_props.out @@ -0,0 +1,5 @@ +Channel program fully executed with return value: + return: + 1: + 2: + 3: diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_string_props.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_string_props.zcp new file mode 100644 index 000000000000..899bdc0336c0 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_string_props.zcp @@ -0,0 +1,73 @@ +-- +-- 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) 2016 by Delphix. All rights reserved. +-- + +arg = ... +fs = arg["argv"][1] +snap = arg["argv"][2] +clone = arg["argv"][3] + +props = {} + +-- prop filesystem snapshot clone +props['origin'] = {{nil, nil}, {nil, nil}, {snap, nil}} +props['clones'] = {{nil, nil}, {{clone}, nil}, {nil, nil}} +props['mountpoint'] = {{'/' .. fs, 'default'}, {nil, nil}, {'/' .. clone, 'default'}} +props['sharenfs'] = {{'off', 'default'}, {nil, nil}, {'off', 'default'}} +props['type'] = {{'filesystem', nil}, {'snapshot', nil}, {'filesystem', nil}} +props['sharesmb'] = {{'off', 'default'}, {nil, nil}, {'off', 'default'}} +props['mlslabel'] = {{'none', 'default'}, {'none', 'default'}, {'none', 'default'}} +props['receive_resume_token'] = {{nil, nil}, {nil, nil}, {nil, nil}} +-- hidden props +props['name'] = {{fs, nil}, {snap, nil}, {clone, nil}} +props['iscsioptions'] = {{nil, nil}, {nil, nil}, {nil, nil}} +props['prevsnap'] = {{snap, nil}, {nil, nil}, {snap, nil}} + + +fs_fails = {} +snap_fails = {} +clone_fails = {} + + +function list_match(t1, t2) + if t1 == t2 then return true end + return (t1[1] == t2[1]) +end + +function match(n, prop, ans, src, expected) + if ((prop == 'clones') or (prop == 'redact_snaps')) then + return (list_match(ans, expected[n][1]) and (src == expected[n][2])) + else + return ((ans == expected[n][1]) and (src == expected[n][2])) + end +end + +for prop, expected in pairs(props) do + ans, src = zfs.get_prop(fs, prop) + if not (match(1, prop, ans, src, expected)) then + fs_fails[prop] = {ans, src} + end + + ans, src = zfs.get_prop(snap, prop) + if not (match(2, prop, ans, src, expected)) then + snap_fails[prop] = {ans, src} + end + + ans, src = zfs.get_prop(clone, prop) + if not (match(3, prop, ans, src, expected)) then + clone_fails[prop] = {ans, src} + end +end + +return {fs_fails, snap_fails, clone_fails} diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_type.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_type.ksh new file mode 100755 index 000000000000..d040e8962e06 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_type.ksh @@ -0,0 +1,54 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib +. $STF_SUITE/tests/functional/zvol/zvol_common.shlib + +# +# DESCRIPTION: +# Getting type should work correctly. +# + +verify_runnable "global" +fs=$TESTPOOL/$TESTFS/testchild +snap=$fs@$TESTSNAP +vol=$TESTPOOL/$TESTVOL +function cleanup +{ + destroy_dataset $snap + destroy_dataset $fs + destroy_dataset $vol +} + +log_onexit cleanup + +log_must zfs create $fs +create_snapshot $fs $TESTSNAP +log_must zfs create -V $VOLSIZE $vol + +log_must_program $TESTPOOL - <<-EOF + ans, setpoint = zfs.get_prop("$fs", "type") + assert(ans == "filesystem") + + ans, setpoint = zfs.get_prop("$snap", "type") + assert(ans == "snapshot") + + ans, setpoint = zfs.get_prop("$vol", "type") + assert(ans == "volume") +EOF + + +log_pass "Getting type should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_userquota.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_userquota.ksh new file mode 100755 index 000000000000..80cc4ad418cc --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_userquota.ksh @@ -0,0 +1,80 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib +. $STF_SUITE/tests/functional/userquota/userquota_common.kshlib + +# +# DESCRIPTION: +# "Getting {user,group}{quota,used}, should work correctly." +# + +verify_runnable "global" + +fs=$TESTPOOL/$TESTFS/testchild +fs1=$TESTPOOL/$TESTFS/nextchild +userid='123' +groupid='456' + +function cleanup +{ + destroy_dataset $fs + destroy_dataset $fs1 +} + +log_onexit cleanup + +log_must zfs create -o userquota@$userid=$UQUOTA_SIZE \ + -o groupquota@$groupid=$GQUOTA_SIZE $fs + +log_must_program $TESTPOOL - <<-EOF + ans, setpoint = zfs.get_prop("$fs", "userquota@$userid") + assert(ans == $UQUOTA_SIZE) + assert(setpoint == "$fs") + + ans, setpoint = zfs.get_prop("$fs", "userused@$userid") + assert(ans == 0) + assert(setpoint == "$fs") + + ans, setpoint = zfs.get_prop("$fs", "groupquota@$groupid") + assert(ans == $GQUOTA_SIZE) + assert(setpoint == "$fs") + + ans, setpoint = zfs.get_prop("$fs", "groupused@$groupid") + assert(ans == 0) + assert(setpoint == "$fs") +EOF + +log_must zfs create $fs1 +log_must_program $TESTPOOL - <<-EOF + ans, setpoint = zfs.get_prop("$fs1", "userquota@$userid") + assert(ans == nil) + assert(setpoint == nil) + + ans, setpoint = zfs.get_prop("$fs1", "userused@$userid") + assert(ans == 0) + assert(setpoint == "$fs1") + + ans, setpoint = zfs.get_prop("$fs1", "groupquota@$groupid") + assert(ans == nil) + assert(setpoint == nil) + + ans, setpoint = zfs.get_prop("$fs1", "groupused@$groupid") + assert(ans == 0) + assert(setpoint == "$fs1") +EOF + +log_pass "Getting {user,group}{quota,used}, should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_written.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_written.ksh new file mode 100755 index 000000000000..9755e6f82e58 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.get_written.ksh @@ -0,0 +1,57 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib +. $STF_SUITE/tests/functional/zvol/zvol_common.shlib + +# +# DESCRIPTION: +# Getting written@ props should work correctly. +# + +verify_runnable "global" + +fs=$TESTPOOL/testchild +snap=$fs@$TESTSNAP +dir=/$fs/dir + +function cleanup +{ + destroy_dataset $fs "-R" + log_must rm -rf $dir +} + +log_onexit cleanup + +log_must zfs create $fs +create_snapshot $fs $TESTSNAP + +log_must_program $TESTPOOL - <<-EOF + ans, setpoint = zfs.get_prop("$fs", "written@$TESTSNAP") + assert(ans == 0) + +EOF + +log_must mkdir $dir +sync + +log_must_program $TESTPOOL - <<-EOF + ans, setpoint = zfs.get_prop("$fs", "written@$TESTSNAP") + assert(ans > 0) + +EOF + +log_pass "Getting written@ props should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.inherit.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.inherit.ksh new file mode 100755 index 000000000000..e199b4c8b07d --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.inherit.ksh @@ -0,0 +1,39 @@ +#!/bin/ksh -p +# +# 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 2020 Joyent, Inc. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +verify_runnable "global" + +fs=$TESTPOOL/$TESTFS +testprop="com.joyent:testprop" +testval="testval" + +log_must dataset_setprop $fs $testprop $testval +log_must_program_sync $TESTPOOL - $fs $testprop <<-EOF + arg = ... + fs = arg["argv"][1] + prop = arg["argv"][2] + err = zfs.sync.inherit(fs, prop) + msg = "resetting " .. prop .. " on " .. fs .. " err=" .. err + return msg +EOF + + +prop=$(get_prop $testprop $fs) +[[ "$prop" == "-" ]] || log_fail "Property still set after inheriting" + +log_pass "Inherit/clear property with channel program works." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_bookmarks.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_bookmarks.ksh new file mode 100755 index 000000000000..7456177f725b --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_bookmarks.ksh @@ -0,0 +1,120 @@ +#!/bin/ksh -p +# +# 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) 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Listing zfs bookmarks should work correctly. +# + +verify_runnable "global" + +TESTBOOK=$TESTPOOL/$TESTFS#testbook +TESTBOOK1=$TESTBOOK-1 +TESTBOOK2=$TESTBOOK-2 +TESTBOOK3=$TESTBOOK-3 + +function cleanup +{ + bkmarkexists $TESTBOOK && log_must zfs destroy $TESTBOOK + bkmarkexists $TESTBOOK1 && log_must zfs destroy $TESTBOOK1 + bkmarkexists $TESTBOOK2 && log_must zfs destroy $TESTBOOK2 + bkmarkexists $TESTBOOK3 && log_must zfs destroy $TESTBOOK3 + destroy_snapshot +} + +log_onexit cleanup + +create_snapshot + +# 0 bookmarks handled correctly +log_must_program $TESTPOOL - <<-EOF + n = 0 + for s in zfs.list.bookmarks("$TESTPOOL/$TESTFS") do + n = n + 1 + end + assert(n == 0) + return 0 +EOF + +# Create a bookmark +log_must zfs bookmark $TESTPOOL/$TESTFS@$TESTSNAP $TESTBOOK + +log_must_program $TESTPOOL - <<-EOF + n = 0 + for s in zfs.list.bookmarks("$TESTPOOL/$TESTFS") do + assert(s == "$TESTBOOK") + n = n + 1 + end + assert(n == 1) + return 0 +EOF + +log_must zfs bookmark $TESTPOOL/$TESTFS@$TESTSNAP $TESTBOOK1 +log_must zfs bookmark $TESTPOOL/$TESTFS@$TESTSNAP $TESTBOOK2 +log_must zfs bookmark $TESTPOOL/$TESTFS@$TESTSNAP $TESTBOOK3 + +# All bookmarks appear exactly once +log_must_program $TESTPOOL - <<-EOF + a = {} + a["$TESTBOOK"] = false + a["$TESTBOOK1"] = false + a["$TESTBOOK2"] = false + a["$TESTBOOK3"] = false + n = 0 + for s in zfs.list.bookmarks("$TESTPOOL/$TESTFS") do + assert(not a[s]) + a[s] = true + n = n + 1 + end + assert(n == 4) + assert(a["$TESTBOOK"] and + a["$TESTBOOK1"] and + a["$TESTBOOK2"] and + a["$TESTBOOK3"]) + return 0 +EOF + +# Nonexistent input +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.bookmarks("$TESTPOOL/nonexistent-fs") + return 0 +EOF +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.bookmarks("nonexistent-pool/$TESTFS") + return 0 +EOF + +# Can't look in a different pool than the one specified on command line +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.bookmarks("testpool2") + return 0 +EOF + +# Can't have bookmarks on snapshots, only on filesystems +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.bookmarks("$TESTPOOL/$TESTFS@$TESTSNAP") + return 0 +EOF + +# Can't have bookmarks on bookmarks, only on filesystems +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.bookmarks("$TESTBOOK") + return 0 +EOF + +log_pass "Listing zfs bookmarks should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_children.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_children.ksh new file mode 100755 index 000000000000..06b82cab4f34 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_children.ksh @@ -0,0 +1,125 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Listing zfs children should work correctly. +# + +verify_runnable "global" + +log_assert "Listing zfs children should work correctly." + +TESTCHILD=$TESTPOOL/$TESTFS/testchild +TESTCHILD1=$TESTCHILD-1 +TESTCHILD2=$TESTCHILD-2 +TESTCHILD3=$TESTCHILD-3 + +function cleanup +{ + destroy_dataset $TESTCHILD + destroy_dataset $TESTCHILD1 + destroy_dataset $TESTCHILD2 + destroy_dataset $TESTCHILD3 +} + +log_onexit cleanup + +# 0 children handled correctly +log_must_program $TESTPOOL - <<-EOF + n = 0 + for s in zfs.list.children("$TESTPOOL/$TESTFS") do + n = n + 1 + end + assert(n == 0) + return 0 +EOF + +log_must_program $TESTPOOL - <<-EOF + n = 0 + for s in zfs.list.children("$TESTPOOL") do + assert(s == "$TESTPOOL/$TESTFS") + n = n + 1 + end + assert(n == 1) + return 0 +EOF + +# Create a child fs +log_must zfs create $TESTCHILD + +log_must_program $TESTPOOL - <<-EOF + n = 0 + for s in zfs.list.children("$TESTPOOL/$TESTFS") do + assert(s == "$TESTCHILD") + n = n + 1 + end + assert(n == 1) + return 0 +EOF + +log_must zfs create $TESTCHILD1 +log_must zfs create $TESTCHILD2 +log_must zfs create $TESTCHILD3 + +# All children appear exactly once +log_must_program $TESTPOOL - <<-EOF + a = {} + a["$TESTCHILD"] = false + a["$TESTCHILD1"] = false + a["$TESTCHILD2"] = false + a["$TESTCHILD3"] = false + n = 0 + for s in zfs.list.children("$TESTPOOL/$TESTFS") do + assert(not a[s]) + a[s] = true + n = n + 1 + end + assert(n == 4) + assert(a["$TESTCHILD"] and + a["$TESTCHILD1"] and + a["$TESTCHILD2"] and + a["$TESTCHILD3"]) + return 0 +EOF + +# Bad input +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.children("$TESTPOOL/not-a-fs") + return 0 +EOF + +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.children("not-a-pool/$TESTFS") + return 0 +EOF + +# Can't look in a different pool than the one specified on command line +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.children("rpool") + return 0 +EOF + +create_snapshot +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.children("$TESTPOOL/$TESTFS@$TESTSNAP") + return 0 +EOF +destroy_snapshot + +log_pass "Listing zfs children should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_clones.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_clones.ksh new file mode 100755 index 000000000000..68d053283d31 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_clones.ksh @@ -0,0 +1,116 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Listing zfs clones should work correctly. +# + +verify_runnable "global" + +log_assert "Listing zfs clones should work correctly." + +function cleanup +{ + destroy_dataset $TESTPOOL/$TESTFS@$TESTSNAP "-R" +} + +log_onexit cleanup + +# Take snapshot to test with ($TESTSNAP) +create_snapshot + +# 0 clones handled correctly +log_must_program $TESTPOOL - <<-EOF + n = 0 + for s in zfs.list.clones("$TESTPOOL/$TESTFS@$TESTSNAP") do + n = n + 1 + end + assert(n == 0) + return 0 +EOF + +# Create a clone ($TESTCLONE) +create_clone + +log_must_program $TESTPOOL - <<-EOF + n = 0 + for s in zfs.list.clones("$TESTPOOL/$TESTFS@$TESTSNAP") do + assert(s == "$TESTPOOL/$TESTCLONE") + n = n + 1 + end + assert(n == 1) + return 0 +EOF + +TESTCLONE1=${TESTCLONE}-1 +TESTCLONE2=${TESTCLONE}-2 +TESTCLONE3=${TESTCLONE}-3 +create_clone $TESTPOOL/$TESTFS@$TESTSNAP $TESTPOOL/$TESTCLONE1 +create_clone $TESTPOOL/$TESTFS@$TESTSNAP $TESTPOOL/$TESTCLONE2 +create_clone $TESTPOOL/$TESTFS@$TESTSNAP $TESTPOOL/$TESTCLONE3 + +# All clones appear exactly once +log_must_program $TESTPOOL - <<-EOF + a = {} + a["$TESTPOOL/$TESTCLONE"] = false + a["$TESTPOOL/$TESTCLONE1"] = false + a["$TESTPOOL/$TESTCLONE2"] = false + a["$TESTPOOL/$TESTCLONE3"] = false + n = 0 + for s in zfs.list.clones("$TESTPOOL/$TESTFS@$TESTSNAP") do + assert(not a[s]) + a[s] = true + n = n + 1 + end + assert(n == 4) + assert(a["$TESTPOOL/$TESTCLONE"] and + a["$TESTPOOL/$TESTCLONE1"] and + a["$TESTPOOL/$TESTCLONE2"] and + a["$TESTPOOL/$TESTCLONE3"]) + return 0 +EOF + +# Bad input +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.clones("$TESTPOOL/not-a-fs@$TESTSNAP") + return 0 +EOF + +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.clones("$TESTPOOL/$TESTFS@not-a-snap") + return 0 +EOF + +# Can't look in a different pool than the one specified on command line +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.clones("rpool") + return 0 +EOF + +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.clones("not-a-pool/$TESTFS@$TESTSNAP") + return 0 +EOF + +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.clones("$TESTPOOL/$TESTFS") + return 0 +EOF + +log_pass "Listing zfs clones should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_holds.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_holds.ksh new file mode 100755 index 000000000000..2a471bdecbfc --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_holds.ksh @@ -0,0 +1,121 @@ +#!/bin/ksh -p +# +# 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) 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Listing zfs holds should work correctly. +# + +verify_runnable "global" + +TESTHOLD=testhold-tag +TESTHOLD1=$TESTHOLD-1 +TESTHOLD2=$TESTHOLD-2 +TESTHOLD3=$TESTHOLD-3 +SNAP=$TESTPOOL/$TESTFS@$TESTSNAP + +function cleanup +{ + holdexists $TESTHOLD $SNAP && log_must zfs release $TESTHOLD $SNAP + holdexists $TESTHOLD1 $SNAP && log_must zfs release $TESTHOLD1 $SNAP + holdexists $TESTHOLD2 $SNAP && log_must zfs release $TESTHOLD2 $SNAP + holdexists $TESTHOLD3 $SNAP && log_must zfs release $TESTHOLD3 $SNAP + destroy_snapshot +} + +log_onexit cleanup + +create_snapshot + +# 0 holds handled correctly +log_must_program $TESTPOOL - <<-EOF + n = 0 + for s in zfs.list.holds("$SNAP") do + n = n + 1 + end + assert(n == 0) + return 0 +EOF + +# Create a hold +log_must zfs hold $TESTHOLD $SNAP + +log_must_program $TESTPOOL - <<-EOF + n = 0 + for s in zfs.list.holds("$SNAP") do + assert(s == "$TESTHOLD") + n = n + 1 + end + assert(n == 1) + return 0 +EOF + +log_must zfs hold $TESTHOLD1 $SNAP +log_must zfs hold $TESTHOLD2 $SNAP +log_must zfs hold $TESTHOLD3 $SNAP + +# All holds appear exactly once +log_must_program $TESTPOOL - <<-EOF + a = {} + a["$TESTHOLD"] = false + a["$TESTHOLD1"] = false + a["$TESTHOLD2"] = false + a["$TESTHOLD3"] = false + n = 0 + for s in zfs.list.holds("$SNAP") do + assert(not a[s]) + a[s] = true + n = n + 1 + end + assert(n == 4) + assert(a["$TESTHOLD"] and + a["$TESTHOLD1"] and + a["$TESTHOLD2"] and + a["$TESTHOLD3"]) + return 0 +EOF + +# Nonexistent input +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.holds("$TESTPOOL/nonexistent-fs@nonexistent-snap") + return 0 +EOF +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.holds("nonexistent-pool/$TESTFS") + return 0 +EOF + +# Can't look in a different pool than the one specified on command line +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.holds("testpool2") + return 0 +EOF + +# Can't have holds on filesystems +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.holds("$TESTPOOL/$TESTFS") + return 0 +EOF + +# Can't have holds on bookmarks +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.holds("$TESTPOOL/$TESTFS#bookmark") + return 0 +EOF + +log_pass "Listing zfs holds should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_snapshots.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_snapshots.ksh new file mode 100755 index 000000000000..7bc36606c957 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_snapshots.ksh @@ -0,0 +1,112 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Listing zfs snapshots should work correctly. +# + +verify_runnable "global" + +log_assert "Listing zfs snapshots should work correctly." + +function cleanup +{ + destroy_dataset $TESTPOOL/$TESTFS@$TESTSNAP + destroy_dataset $TESTPOOL/$TESTFS@$TESTSNAP1 + destroy_dataset $TESTPOOL/$TESTFS@$TESTSNAP2 + destroy_dataset $TESTPOOL/$TESTFS@$TESTSNAP3 +} + +log_onexit cleanup + +# 0 snapshots handled correctly +log_must_program $TESTPOOL - <<-EOF + n = 0 + for s in zfs.list.snapshots("$TESTPOOL/$TESTFS") do + zfs.debug("ERROR: found snapshot " .. s) + n = n + 1 + end + assert(n == 0) + return 0 +EOF + +# Take a snapshot, make sure it appears +create_snapshot $TESTPOOL/$TESTFS $TESTSNAP + +log_must_program $TESTPOOL - <<-EOF + n = 0 + for s in zfs.list.snapshots("$TESTPOOL/$TESTFS") do + assert(s == "$TESTPOOL/$TESTFS@$TESTSNAP") + n = n + 1 + end + assert(n == 1) + return 0 +EOF + +TESTSNAP1=${TESTSNAP}-1 +TESTSNAP2=${TESTSNAP}-2 +TESTSNAP3=${TESTSNAP}-3 +create_snapshot $TESTPOOL/$TESTFS $TESTSNAP1 +create_snapshot $TESTPOOL/$TESTFS $TESTSNAP2 +create_snapshot $TESTPOOL/$TESTFS $TESTSNAP3 + +# All snapshots appear exactly once +log_must_program $TESTPOOL - <<-EOF + a = {} + a["$TESTPOOL/$TESTFS@$TESTSNAP"] = false + a["$TESTPOOL/$TESTFS@$TESTSNAP1"] = false + a["$TESTPOOL/$TESTFS@$TESTSNAP2"] = false + a["$TESTPOOL/$TESTFS@$TESTSNAP3"] = false + n = 0 + for s in zfs.list.snapshots("$TESTPOOL/$TESTFS") do + assert(not a[s]) + a[s] = true + n = n + 1 + end + assert(n == 4) + assert(a["$TESTPOOL/$TESTFS@$TESTSNAP"] and + a["$TESTPOOL/$TESTFS@$TESTSNAP1"] and + a["$TESTPOOL/$TESTFS@$TESTSNAP2"] and + a["$TESTPOOL/$TESTFS@$TESTSNAP3"]) + return 0 +EOF + +# Bad input +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.snapshots("$TESTPOOL/not-a-fs") + return 0 +EOF + +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.snapshots("not-a-pool/$TESTFS") + return 0 +EOF + +# Can't look in a different pool than the one specified on command line +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.snapshots("rpool") + return 0 +EOF + +log_mustnot_program $TESTPOOL - <<-EOF + zfs.list.snapshots("$TESTPOOL/${TESTFS}@$TESTSNAP") + return 0 +EOF + +log_pass "Listing zfs snapshots should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_system_props.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_system_props.ksh new file mode 100755 index 000000000000..24ab65a195b9 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_system_props.ksh @@ -0,0 +1,54 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib +. $STF_SUITE/tests/functional/zvol/zvol_common.shlib + +# +# DESCRIPTION: +# Listing system properties should succeed +# + +verify_runnable "global" +fs=$TESTPOOL/$TESTFS/testchild +snap=$fs@$TESTSNAP +vol=$TESTPOOL/$TESTVOL +function cleanup +{ + destroy_dataset $snap + destroy_dataset $fs + destroy_dataset $vol +} + +log_onexit cleanup + +log_must zfs create $fs +create_snapshot $fs $TESTSNAP +log_must zfs create -V $VOLSIZE $vol + +log_must_program $TESTPOOL - <<-EOF + zfs.list.system_properties("$fs") +EOF + +log_must_program $TESTPOOL - <<-EOF + zfs.list.system_properties("$snap") +EOF + +log_must_program $TESTPOOL - <<-EOF + zfs.list.system_properties("$vol") +EOF + +log_pass "Listing system properties should succeed." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_user_props.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_user_props.ksh new file mode 100755 index 000000000000..a454a2753302 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.list_user_props.ksh @@ -0,0 +1,147 @@ +#!/bin/ksh -p +# +# 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) 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Listing zfs user properties should work correctly. +# +# Note, that this file tests both zfs.list.user_properties +# and it's alias zfs.list.properties. +# + +verify_runnable "global" + +TESTPROP="org.openzfs:test_property" +TESTPROP1=$TESTPROP-1 +TESTPROP2=$TESTPROP-2 +TESTPROP3=$TESTPROP-3 +TESTPROP4=$TESTPROP-4 + +TESTVAL="true" +TESTVAL1="busy" +TESTVAL2="9223372036854775808" +TESTVAL3="801f2266-3715-41f4-9080-3d5e913b0f15" +TESTVAL4="TOZwOfACvQtmDyiq68elB3a3g9YYyxBjSnLtN3ZyQYNOAKykzIE2khKKOBncJiDx" + + +# 0 properties handled correctly +log_must_program $TESTPOOL - <<-EOF + n = 0 + for p in zfs.list.user_properties("$TESTPOOL/$TESTFS") do + n = n + 1 + end + assert(n == 0) + return 0 +EOF +log_must_program $TESTPOOL - <<-EOF + n = 0 + for p in zfs.list.properties("$TESTPOOL/$TESTFS") do + n = n + 1 + end + assert(n == 0) + return 0 +EOF + +# Add a single user property +log_must zfs set $TESTPROP="$TESTVAL" $TESTPOOL/$TESTFS + +log_must_program $TESTPOOL - <<-EOF + n = 0 + for p,v in zfs.list.user_properties("$TESTPOOL/$TESTFS") do + assert(p == "$TESTPROP") + assert(v == "$TESTVAL") + n = n + 1 + end + assert(n == 1) + return 0 +EOF +log_must_program $TESTPOOL - <<-EOF + n = 0 + for p,v in zfs.list.properties("$TESTPOOL/$TESTFS") do + assert(p == "$TESTPROP") + assert(v == "$TESTVAL") + n = n + 1 + end + assert(n == 1) + return 0 +EOF + +log_must zfs set $TESTPROP1="$TESTVAL1" $TESTPOOL/$TESTFS +log_must zfs set $TESTPROP2="$TESTVAL2" $TESTPOOL/$TESTFS +log_must zfs set $TESTPROP3="$TESTVAL3" $TESTPOOL/$TESTFS +log_must zfs set $TESTPROP4="$TESTVAL4" $TESTPOOL/$TESTFS + +# All user properties have correct value and appear exactly once +log_must_program $TESTPOOL - <<-EOF + a = {} + a["$TESTPROP"] = false + a["$TESTPROP1"] = false + a["$TESTPROP2"] = false + a["$TESTPROP3"] = false + a["$TESTPROP4"] = false + m = {} + m["$TESTPROP"] = "$TESTVAL" + m["$TESTPROP1"] = "$TESTVAL1" + m["$TESTPROP2"] = "$TESTVAL2" + m["$TESTPROP3"] = "$TESTVAL3" + m["$TESTPROP4"] = "$TESTVAL4" + n = 0 + for p,v in zfs.list.user_properties("$TESTPOOL/$TESTFS") do + assert(not a[p]) + a[p] = true + assert(v == m[p]) + n = n + 1 + end + assert(n == 5) + assert(a["$TESTPROP"] and + a["$TESTPROP1"] and + a["$TESTPROP2"] and + a["$TESTPROP3"] and + a["$TESTPROP4"]) + return 0 +EOF +log_must_program $TESTPOOL - <<-EOF + a = {} + a["$TESTPROP"] = false + a["$TESTPROP1"] = false + a["$TESTPROP2"] = false + a["$TESTPROP3"] = false + a["$TESTPROP4"] = false + m = {} + m["$TESTPROP"] = "$TESTVAL" + m["$TESTPROP1"] = "$TESTVAL1" + m["$TESTPROP2"] = "$TESTVAL2" + m["$TESTPROP3"] = "$TESTVAL3" + m["$TESTPROP4"] = "$TESTVAL4" + n = 0 + for p,v in zfs.list.properties("$TESTPOOL/$TESTFS") do + assert(not a[p]) + a[p] = true + assert(v == m[p]) + n = n + 1 + end + assert(n == 5) + assert(a["$TESTPROP"] and + a["$TESTPROP1"] and + a["$TESTPROP2"] and + a["$TESTPROP3"] and + a["$TESTPROP4"]) + return 0 +EOF + +log_pass "Listing zfs user properties should work correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.parse_args_neg.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.parse_args_neg.ksh new file mode 100755 index 000000000000..01bdb63eb678 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.parse_args_neg.ksh @@ -0,0 +1,50 @@ +#!/bin/ksh -p +# +# 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) 2016, 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Try calling zfs.sync.destroy with various arguments that are not +# valid. The script should fail. +# + +verify_runnable "global" + +set -A progs "zfs.sync.destroy(\"foo\", \"bar\")" \ + "zfs.sync.destroy(\"foo\", 12345)" \ + "zfs.sync.destroy(12345)" \ + "zfs.sync.destroy()" \ + "zfs.sync.destroy{\"foo\", bar=true}" \ + "zfs.sync.destroy{\"foo\", defer=12345}" \ + "zfs.sync.destroy{\"foo\", defer=true, 12345}" \ + "zfs.sync.destroy{\"foo\", defer=true, bar=12345}" \ + "zfs.sync.destroy{\"foo\", bar=true, defer=true}" \ + "zfs.sync.destroy{defer=true}" \ + "zfs.sync.destroy{12345, defer=true}" + + +typeset -i i=0 +while (( i < ${#progs[*]} )); do + log_note "running program: ${progs[i]}" + # output should contain the usage message, which contains "destroy{" + log_mustnot_checkerror_program "destroy{" $TESTPOOL - <<-EOF + ${progs[i]} + EOF + ((i = i + 1)) +done + +log_pass "Invalid arguments to zfs.sync.destroy generate errors." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.promote_conflict.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.promote_conflict.ksh new file mode 100755 index 000000000000..b2840377b559 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.promote_conflict.ksh @@ -0,0 +1,55 @@ +#!/bin/ksh -p +# +# 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) 2016, 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Attempting to promote a clone when it shares a snapshot name with +# its parent filesystem should fail and return the name of the +# conflicting snapshot. +# + +verify_runnable "global" + +fs=$TESTPOOL/$TESTFS/testchild +clone=$TESTPOOL/$TESTFS/testchild_clone +snap=promote_conflict_snap + +function cleanup +{ + for to_destroy in $fs $clone; do + destroy_dataset $to_destroy "-R" + done +} + +log_onexit cleanup + +log_must zfs create $fs +log_must zfs snapshot $fs@$snap +log_must zfs clone $fs@$snap $clone +log_must zfs snapshot $clone@$snap + +# +# This channel program is expected to return successfully, but fail to execute +# the promote command since the snapshot names collide. It returns the error +# code and description, which should be EEXIST (17) and the name of the +# conflicting snapshot. +# +log_must_program_sync $TESTPOOL \ + $ZCP_ROOT/synctask_core/tst.promote_conflict.zcp $clone + +log_pass "Promoting a clone with a conflicting snapshot fails." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.promote_conflict.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.promote_conflict.zcp new file mode 100644 index 000000000000..287328a40d31 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.promote_conflict.zcp @@ -0,0 +1,23 @@ +-- +-- 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) 2016 by Delphix. All rights reserved. +-- + +-- This program should be invoked as "zfs program <pool> <prog> <clone>" + +args = ... +argv = args["argv"] +err, desc = zfs.sync.promote(argv[1]) +assert(err == EEXIST) +assert(#desc == 1) +assert(desc[1] == "promote_conflict_snap") diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.promote_multiple.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.promote_multiple.ksh new file mode 100755 index 000000000000..7618a34bc8e1 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.promote_multiple.ksh @@ -0,0 +1,71 @@ +#!/bin/ksh -p +# +# 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) 2016, 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Multiple interacting promotions in a single txg should succeed. +# + +verify_runnable "global" + +fs=$TESTPOOL/$TESTFS/testchild +clone1=$TESTPOOL/$TESTFS/testchild_clone1 +clone2=$TESTPOOL/$TESTFS/testchild_clone2 +snap1=$fs@testchild_snap1 +snap2=$clone1@testchild_snap2 + +function cleanup +{ + for to_destroy in $fs $clone1 $clone2; do + destroy_dataset $to_destroy "-R" + done +} + +log_onexit cleanup + +# +# Create a chain of clones and snapshots: +# +# snap1 -----------> fs +# \--> snap2 --> clone1 +# \---> clone2 +# +# Then promote clone2 twice, resulting in: +# +# snap1 --> snap2 --> clone2 +# \ \---> clone1 +# \------------> fs +# +# We then attempt to destroy clone1, which should succeed since it no +# longer has any dependents. +# +log_must zfs create $fs +log_must zfs snapshot $snap1 +log_must zfs clone $snap1 $clone1 +log_must zfs snapshot $snap2 +log_must zfs clone $snap2 $clone2 + +log_must zfs unmount -f $clone1 + +log_must_program_sync $TESTPOOL - <<-EOF + assert(zfs.sync.promote("$clone2") == 0) + assert(zfs.sync.promote("$clone2") == 0) + assert(zfs.sync.destroy("$clone1") == 0) +EOF + +log_pass "Multiple promotes and destroying a demoted fs in one txg works." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.promote_simple.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.promote_simple.ksh new file mode 100755 index 000000000000..541c6840e0c0 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.promote_simple.ksh @@ -0,0 +1,47 @@ +#!/bin/ksh -p +# +# 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) 2016, 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Promoting a clone should work correctly. +# + +verify_runnable "global" + +fs=$TESTPOOL/$TESTFS/testchild +clone=$TESTPOOL/$TESTFS/testchild_clone +snap=$fs@$TESTSNAP + +function cleanup +{ + for to_destroy in $fs $clone; do + destroy_dataset $to_destroy "-R" + done +} + +log_onexit cleanup + +log_must zfs create $fs +log_must zfs snapshot $snap +log_must zfs clone $snap $clone + +log_must_program_sync $TESTPOOL - <<-EOF + assert(zfs.sync.promote("$clone") == 0) +EOF + +log_pass "Promoting a clone with a channel program works." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.rollback_mult.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.rollback_mult.ksh new file mode 100755 index 000000000000..2fbbc73d5fe8 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.rollback_mult.ksh @@ -0,0 +1,60 @@ +#!/bin/ksh -p +# +# 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) 2016, 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +verify_runnable "global" +snap1=$TESTPOOL/$TESTFS@$TESTSNAP1 +snap2=$TESTPOOL/$TESTFS@$TESTSNAP2 +fs=$TESTPOOL/$TESTFS +file=$TESTDIR/$TESTFILE0 + +function cleanup +{ + destroy_dataset $snap1 && log_must rm $file +} + +log_onexit cleanup + +log_must mkfile 128b $file +create_snapshot $TESTPOOL/$TESTFS $TESTSNAP1 +log_must rm $file +create_snapshot $TESTPOOL/$TESTFS $TESTSNAP2 + +log_must snapexists $snap1 +log_must snapexists $snap2 +log_must zfs unmount $fs + +log_must_program_sync $TESTPOOL - $fs $snap2 <<-EOF + arg = ... + fs = arg["argv"][1] + snap = arg["argv"][2] + err = zfs.sync.rollback(fs) + if err == 0 then + err = zfs.sync.destroy(snap) + end + if err == 0 then + err = zfs.sync.rollback(fs) + end + msg = "rolling back " .. fs .. " err=" .. err + return msg +EOF + +log_must zfs mount $fs +log_must [ -f $file ] +log_mustnot snapexists $snap2 + +log_pass "Rolling back snapshot with channel program works." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.rollback_one.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.rollback_one.ksh new file mode 100755 index 000000000000..12834430163c --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.rollback_one.ksh @@ -0,0 +1,49 @@ +#!/bin/ksh -p +# +# 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) 2016, 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +verify_runnable "global" +snap=$TESTPOOL/$TESTFS@$TESTSNAP +fs=$TESTPOOL/$TESTFS +file=$TESTDIR/$TESTFILE0 + +function cleanup +{ + destroy_dataset $snap && log_must rm $file +} + +log_onexit cleanup + +log_must mkfile 128b $file +create_snapshot $TESTPOOL/$TESTFS $TESTSNAP +log_must rm $file + +log_must snapexists $snap +log_must zfs unmount $fs + +log_must_program_sync $TESTPOOL - $fs <<-EOF + arg = ... + fs = arg["argv"][1] + err = zfs.sync.rollback(fs) + msg = "rolling back " .. fs .. " err=" .. err + return msg +EOF + +log_must zfs mount $fs +log_must [ -f $file ] + +log_pass "Rolling back snapshot with channel program works." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.set_props.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.set_props.ksh new file mode 100755 index 000000000000..6ac1c2b205cd --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.set_props.ksh @@ -0,0 +1,39 @@ +#!/bin/ksh -p +# +# 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) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Setting user props should work correctly on datasets. +# + +verify_runnable "global" + +fs=$TESTPOOL/$TESTFS/testchild + +function cleanup +{ + destroy_dataset $fs "-R" +} + +log_onexit cleanup + +log_must zfs create $fs + +log_must_program_sync $TESTPOOL $ZCP_ROOT/synctask_core/tst.set_props.zcp $fs + +log_pass "Setting props from channel program works correctly." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.set_props.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.set_props.zcp new file mode 100644 index 000000000000..756263a9d082 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.set_props.zcp @@ -0,0 +1,109 @@ +-- +-- 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) 2017 by Delphix. All rights reserved. +-- Copyright 2020 Joyent, Inc. +-- + +arg = ... +fs = arg["argv"][1] + +-- values from zfs.h +maxname = 256 -- ZAP_MAXNAMELEN +maxvalue = 8192 -- ZAP_MAXVALUELEN + +pos_props = {} +neg_props = {} + +-- In lua, strings are immutable, so to avoid a bunch of copies, we +-- build the value in a table and use concat (which appears to be the +-- recommend method for such things). +largeprop = {} +for i = 0,maxvalue,8 +do + table.insert(largeprop, "aaaaaaaa") +end +-- add an extra character so we spill over the limit +table.insert(largeprop, "b") + +largepropv = table.concat(largeprop) + +largepropname = { "b:" } +for i = 0,maxname,8 +do + table.insert(largepropname, "aaaaaaaa") +end +largepropnamev = table.concat(largepropname) + +pos_props["a:prop"] = {"hello"} + +-- For neg_props, an optional expected error value can be added after the +-- property value as seen below. +neg_props["notaproperty"] = {"hello", EINVAL} +neg_props["a:very.long.property.value"] = { largepropv, E2BIG } +neg_props[largepropnamev] = {"greetings", ENAMETOOLONG } + +-- non-user properties aren't currently supported +-- Even if they were, the argument must be a string due to requirements of +-- the ZCP api. +neg_props["mountpoint"] = {"/foo/bar"} +neg_props["copies"] = { "2" } + +-- read-only properties should never succeed +neg_props["guid"] = { "12345" } + +set_fail = {} +val_fail = {} + +-- Test properties that should work +for prop, values in pairs(pos_props) do + for i, val in ipairs(values) do + old_val, src = zfs.get_prop(fs, prop) + + -- Attempt to set the property to the specified value + err = zfs.sync.set_prop(fs, prop, val) + + if (err ~= 0) then + set_fail[prop] = err -- tuple of prop, val that resulted in error + else + -- use get_prop to check that the set took affect + new_val, src = zfs.get_prop(fs, prop) + if (tostring(new_val) ~= tostring(val)) then + val_fail[prop] = new_val + end + + -- We modified the prop, restore old value (if one existed) + if (old_val ~= nil) then + err = zfs.sync.set_prop(fs, prop, old_val) + if (err ~= 0) then return err end + else + -- Didn't have an old value, delete (inherit) instead + err = zfs.sync.inherit(fs, prop) + if (err ~= 0) then return err end + end + end + end +end + +-- Test properties that should fail +for prop, expected in pairs(neg_props) do + exp_val = expected[1] + exp_err = expected[2] + + -- Attempt to set the property to the specified value + err = zfs.sync.set_prop(fs, prop, exp_val) + if (err == 0 or (exp_err ~= nil and err ~= exp_err)) then + set_fail[prop] = err -- tuple of prop, val that resulted in error + end +end + +return {set_fail, val_fail} diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_destroy.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_destroy.ksh new file mode 100755 index 000000000000..b0cdfb84f4ea --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_destroy.ksh @@ -0,0 +1,39 @@ +#!/bin/ksh -p +# +# 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) 2016, 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: Creating and destroying snapshots in the same txg should work. +# + +verify_runnable "global" + +fs=$TESTPOOL/$TESTFS/testchild + +function cleanup +{ + destroy_dataset $fs "-R" +} + +log_onexit cleanup + +log_must zfs create $fs + +log_must_program_sync $TESTPOOL \ + $ZCP_ROOT/synctask_core/tst.snapshot_destroy.zcp $fs + +log_pass "Creating/destroying snapshots in one channel program works" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_destroy.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_destroy.zcp new file mode 100644 index 000000000000..6fbfb06ad433 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_destroy.zcp @@ -0,0 +1,24 @@ +-- +-- 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) 2016, 2017 by Delphix. All rights reserved. +-- + +args = ... +argv = args["argv"] + +assert(zfs.sync.snapshot(argv[1] .. "@snap1") == 0) +assert(zfs.sync.destroy(argv[1] .. "@snap1") == 0) + +for s in zfs.list.snapshots(argv[1]) do + assert(false) +end diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_neg.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_neg.ksh new file mode 100755 index 000000000000..8d6cd38310e6 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_neg.ksh @@ -0,0 +1,45 @@ +#!/bin/ksh -p +# +# 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) 2016, 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: Check various invalid snapshot error cases +# + +verify_runnable "global" + +fs1=$TESTPOOL/$TESTFS/testchild1 +fs2=$TESTPOOL/$TESTFS/testchild2 + +function cleanup +{ + for fs in $fs1 $fs2; do + destroy_dataset $fs "-R" + done +} + +log_onexit cleanup + +log_must zfs create $fs1 +log_must zfs create $fs2 +log_must zfs snapshot $fs1@snap1 + +log_must_program_sync $TESTPOOL \ + $ZCP_ROOT/synctask_core/tst.snapshot_neg.zcp $fs1 $fs2 + +log_pass "zfs.sync.snapshot returns correct errors on invalid input" + diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_neg.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_neg.zcp new file mode 100644 index 000000000000..5cae324bc90e --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_neg.zcp @@ -0,0 +1,35 @@ +-- +-- 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) 2016, 2017 by Delphix. All rights reserved. +-- + +args = ... +argv = args["argv"] +fs1 = argv[1] +fs2 = argv[2] + +longstring = "a" +for i=1,9 do + longstring = longstring .. longstring +end + +-- invalid snapshot names +assert(zfs.sync.snapshot("ceci_nest_pas_une_dataset") == EINVAL); +assert(zfs.sync.snapshot(fs1) == EINVAL) +assert(zfs.sync.snapshot(fs1 .. "@" .. longstring) == ENAMETOOLONG) + +assert(zfs.sync.snapshot(fs2 .. "@snap1") == 0) +-- only one snapshot of a filesystem is allowed per TXG. +assert(zfs.sync.snapshot(fs2 .. "@snap2") == EAGAIN) +-- snapshot already exists +assert(zfs.sync.snapshot(fs1 .. "@snap1") == EEXIST) diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_recursive.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_recursive.ksh new file mode 100755 index 000000000000..e3bf10b69168 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_recursive.ksh @@ -0,0 +1,61 @@ +#!/bin/ksh -p +# +# 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) 2016, 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: Construct a set of nested filesystems, then recursively snapshot +# all of them. +# + +verify_runnable "global" + +rootfs=$TESTPOOL/$TESTFS/root +snapname=snap + +function cleanup +{ + destroy_dataset $rootfs "-R" +} + +log_onexit cleanup + +filesystems="$rootfs \ +$rootfs/child1 \ +$rootfs/child1/subchild1 \ +$rootfs/child1/subchild2 \ +$rootfs/child1/subchild3 \ +$rootfs/child2 \ +$rootfs/child2/subchild4 \ +$rootfs/child2/subchild5" + +for fs in $filesystems; do + log_must zfs create $fs +done + +log_must_program_sync $TESTPOOL \ + $ZCP_ROOT/synctask_core/tst.snapshot_recursive.zcp $rootfs $snapname + +# +# Make sure all of the snapshots we expect were created. +# +for fs in $filesystems; do + log_must snapexists $fs@$snapname +done + +log_pass "Recursively snapshotting multiple filesystems works." + + diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_recursive.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_recursive.zcp new file mode 100644 index 000000000000..097940d71198 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_recursive.zcp @@ -0,0 +1,28 @@ +-- +-- 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) 2016, 2017 by Delphix. All rights reserved. +-- + +args = ... +argv = args["argv"] +fs = argv[1] +snap = argv[2] + +function snapshot_recursive(root) + assert(zfs.sync.snapshot(root .. "@" .. snap) == 0) + for child in zfs.list.children(root) do + snapshot_recursive(child) + end +end + +snapshot_recursive(fs) diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_simple.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_simple.ksh new file mode 100755 index 000000000000..4a7acaddaf8f --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_simple.ksh @@ -0,0 +1,40 @@ +#!/bin/ksh -p +# +# 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) 2016, 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: Make sure basic snapshot functionality works in channel programs +# + +verify_runnable "global" + +fs=$TESTPOOL/$TESTFS/testchild +snapname=testsnap + +function cleanup +{ + destroy_dataset $fs "-R" +} + +log_onexit cleanup + +log_must zfs create $fs + +log_must_program_sync $TESTPOOL \ + $ZCP_ROOT/synctask_core/tst.snapshot_simple.zcp $fs $snapname + +log_pass "Simple snapshotting works" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_simple.zcp b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_simple.zcp new file mode 100644 index 000000000000..215e013df1d2 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_simple.zcp @@ -0,0 +1,26 @@ +-- +-- 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) 2016, 2017 by Delphix. All rights reserved. +-- + +-- This program should be invoked as "zfs program <pool> <prog> <fs> <snap>" + +args = ... +argv = args["argv"] +assert(zfs.sync.snapshot(argv[1] .. "@" .. argv[2]) == 0) +snaps = {} +for s in zfs.list.snapshots(argv[1]) do + table.insert(snaps, s) +end +assert(#snaps == 1) +assert(snaps[1] == (argv[1] .. "@" .. argv[2])) diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.terminate_by_signal.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.terminate_by_signal.ksh new file mode 100755 index 000000000000..0a5fb804ac39 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.terminate_by_signal.ksh @@ -0,0 +1,98 @@ +#!/bin/ksh -p +# +# 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) 2017 by Delphix. All rights reserved. +# +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: Execute a long-running zfs channel program and attempt to +# cancel it by sending a signal. +# + +verify_runnable "global" + +rootfs=$TESTPOOL/$TESTFS +snapname=snap +limit=50000000 + +function cleanup +{ + datasetexists $rootfs && log_must zfs destroy -R $rootfs +} + +log_onexit cleanup + +# +# Create a working set of 100 file systems +# +for i in {1..100}; do + log_must zfs create "$rootfs/child$i" +done + +# +# Attempt to create 100 snapshots with zfs.sync.snapshot() along with some +# time consuming efforts. We use loops of zfs.check.* (dry run operations) +# to consume instructions before the next zfs.sync.snapshot() occurs. +# +# Without a signal interruption this ZCP would take several minutes and +# generate over 30 million Lua instructions. +# +function chan_prog +{ +zfs program -t $limit $TESTPOOL - $rootfs $snapname <<-EOF + arg = ... + fs = arg["argv"][1] + snap = arg["argv"][2] + for child in zfs.list.children(fs) do + local snapname = child .. "@" .. snap + zfs.check.snapshot(snapname) + zfs.sync.snapshot(snapname) + for i=1,20000,1 do + zfs.check.snapshot(snapname) + zfs.check.destroy(snapname) + zfs.check.destroy(fs) + end + end + return "should not have reached here" +EOF +} + +log_note "Executing a long-running zfs program in the background" +chan_prog & +CHILD=$! + +# +# After waiting, send a kill signal to the channel program process. +# This should stop the ZCP near a million instructions but still have +# created some of the snapshots. Note that since the above zfs program +# command might get wrapped, we also issue a kill to the group. +# +sleep 10 +log_pos pkill -P $CHILD +log_pos kill $CHILD + +# +# Make sure the channel program did not fully complete by enforcing +# that not all of the snapshots were created. +# +snap_count=$(zfs list -t snapshot | grep $TESTPOOL | wc -l) +log_note "$snap_count snapshots created by ZCP" + +if [ "$snap_count" -eq 0 ]; then + log_fail "Channel program failed to run." +elif [ "$snap_count" -gt 90 ]; then + log_fail "Too many snapshots after a cancel ($snap_count)." +else + log_pass "Canceling a long-running channel program works." +fi |