diff options
Diffstat (limited to 'src/spdk/test/pmem')
-rw-r--r-- | src/spdk/test/pmem/common.sh | 107 | ||||
-rwxr-xr-x | src/spdk/test/pmem/json_config/json_config.sh | 25 | ||||
-rwxr-xr-x | src/spdk/test/pmem/pmem.sh | 701 | ||||
-rw-r--r-- | src/spdk/test/pmem/test_plan.md | 310 |
4 files changed, 1143 insertions, 0 deletions
diff --git a/src/spdk/test/pmem/common.sh b/src/spdk/test/pmem/common.sh new file mode 100644 index 00000000..add36719 --- /dev/null +++ b/src/spdk/test/pmem/common.sh @@ -0,0 +1,107 @@ +BASE_DIR=$(readlink -f $(dirname $0)) +[[ -z "$TEST_DIR" ]] && TEST_DIR="$(cd $BASE_DIR/../../ && pwd)" +rpc_py="$TEST_DIR/scripts/rpc.py " + +source $TEST_DIR/test/common/autotest_common.sh + +# Prints error message and return error code, closes vhost app and remove +# pmem pool file +# input: error message, error code +function error() +{ + local error_code=${2:-1} + echo "===========" + echo -e "ERROR: $1" + echo "error code: $error_code" + echo "===========" + vhost_kill + pmem_clean_pool_file + return $error_code +} + +# check if there is pool file & remove it +# input: path to pool file +# default: $TEST_DIR/test/pmem/pool_file +function pmem_clean_pool_file() +{ + local pool_file=${1:-$TEST_DIR/test/pmem/pool_file} + + if [ -f $pool_file ]; then + echo "Deleting old pool_file" + rm $pool_file + fi +} + +# create new pmem file +# input: path to pool file, size in MB, block_size +# default: $TEST_DIR/test/pmem/pool_file 32 512 +function pmem_create_pool_file() +{ + local pool_file=${1:-$TEST_DIR/test/pmem/pool_file} + local size=${2:-32} + local block_size=${3:-512} + + pmem_clean_pool_file $pool_file + echo "Creating new pool file" + if ! $rpc_py create_pmem_pool $pool_file $size $block_size; then + error "Creating pool_file failed!" + fi + + if [ ! -f $pool_file ]; then + error "Creating pool_file failed!" + fi +} + +function pmem_unmount_ramspace +{ + if [ -d "$TEST_DIR/test/pmem/ramspace" ]; then + if mount | grep -q "$TEST_DIR/test/pmem/ramspace"; then + umount $TEST_DIR/test/pmem/ramspace + fi + + rm -rf $TEST_DIR/test/pmem/ramspace + fi +} + +function pmem_print_tc_name +{ + echo "" + echo "===============================================================" + echo "Now running: $1" + echo "===============================================================" +} + +function vhost_start() +{ + local vhost_pid + + $TEST_DIR/app/vhost/vhost & + if [ $? != 0 ]; then + echo -e "ERROR: Failed to launch vhost!" + return 1 + fi + + vhost_pid=$! + echo $vhost_pid > $TEST_DIR/test/pmem/vhost.pid + waitforlisten $vhost_pid +} + +function vhost_kill() +{ + local vhost_pid_file="$TEST_DIR/test/pmem/vhost.pid" + local vhost_pid="$(cat $vhost_pid_file)" + + if [[ ! -f $TEST_DIR/test/pmem/vhost.pid ]]; then + echo -e "ERROR: No vhost pid file found!" + return 1 + fi + + if ! kill -s INT $vhost_pid; then + echo -e "ERROR: Failed to exit vhost / invalid pid!" + rm $vhost_pid_file + return 1 + fi + + sleep 1 + rm $vhost_pid_file +} diff --git a/src/spdk/test/pmem/json_config/json_config.sh b/src/spdk/test/pmem/json_config/json_config.sh new file mode 100755 index 00000000..bd232b8f --- /dev/null +++ b/src/spdk/test/pmem/json_config/json_config.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -ex +VHOST_JSON_DIR=$(readlink -f $(dirname $0)) +. $VHOST_JSON_DIR/../../json_config/common.sh + +function test_subsystems() { + run_spdk_tgt + + rpc_py="$spdk_rpc_py" + clear_config_py="$spdk_clear_config_py" + $rpc_py start_subsystem_init + + create_pmem_bdev_subsytem_config + test_json_config + clear_pmem_bdev_subsystem_config + + kill_targets +} + +trap 'on_error_exit "${FUNCNAME}" "${LINENO}"' ERR +timing_enter json_config_pmem + +test_subsystems +timing_exit json_config_pmem +report_test_completion json_config_pmem diff --git a/src/spdk/test/pmem/pmem.sh b/src/spdk/test/pmem/pmem.sh new file mode 100755 index 00000000..15188635 --- /dev/null +++ b/src/spdk/test/pmem/pmem.sh @@ -0,0 +1,701 @@ +#!/usr/bin/env bash + +BASE_DIR=$(readlink -f $(dirname $0)) +[[ -z "$TEST_DIR" ]] && TEST_DIR="$(cd $BASE_DIR/../../ && pwd)" + +enable_script_debug=false +test_info=false +test_create=false +test_delete=false +test_construct_bdev=false +test_delete_bdev=false +test_all=true +test_all_get=false +default_pool_file=$TEST_DIR/test/pmem/pool_file +obj_pool_file=$TEST_DIR/test/pmem/obj_pool_file +bdev_name=pmem0 + +function usage() +{ + [[ ! -z $2 ]] && ( echo "$2"; echo ""; ) + echo "Shortcut script for automated RPC tests for PMEM" + echo "For test details, check test_plan.md or" + echo "https://review.gerrithub.io/#/c/378618/18/test/pmem/test_plan.md" + echo + echo "Usage: $(basename $1) [OPTIONS]" + echo + echo "-h, --help Print help and exit" + echo "-x set -x for script debug" + echo " --info Run test cases for pmem_pool_info" + echo " --create Run test cases for create_pmem_pool" + echo " --delete Run test cases for delete_pmem_pool" + echo " --construct_bdev Run test cases for constructing pmem bdevs" + echo " --delete_bdev Run test cases for deleting pmem bdevs" + echo " --all Run all test cases (default)" + exit 0 +} + +while getopts 'xh-:' optchar; do + case "$optchar" in + -) + case "$OPTARG" in + help) usage $0 ;; + info) test_info=true; test_all=false;; + create) test_create=true; test_all=false;; + delete) test_delete=true; test_all=false;; + construct_bdev) test_construct_bdev=true; test_all=false;; + delete_bdev) test_delete_bdev=true; test_all=false;; + all) test_all_get=true;; + *) usage $0 "Invalid argument '$OPTARG'" ;; + esac + ;; + h) usage $0 ;; + x) enable_script_debug=true ;; + *) usage $0 "Invalid argument '$OPTARG'" + esac +done + +if $test_all_get; then + test_all=true +fi + +if [[ $EUID -ne 0 ]]; then + echo "Go away user come back as root" + exit 1 +fi + +source $TEST_DIR/test/pmem/common.sh +source $TEST_DIR/test/common/autotest_common.sh + +#================================================ +# pmem_pool_info tests +#================================================ +function pmem_pool_info_tc1() +{ + pmem_print_tc_name ${FUNCNAME[0]} + + if $rpc_py pmem_pool_info; then + error "pmem_pool_info passed with missing argument!" + fi + + return 0 +} + +function pmem_pool_info_tc2() +{ + pmem_print_tc_name ${FUNCNAME[0]} + + if $rpc_py pmem_pool_info $TEST_DIR/non/existing/path/non_existent_file; then + error "pmem_pool_info passed with invalid path!" + fi + + return 0 +} + +function pmem_pool_info_tc3() +{ + pmem_print_tc_name ${FUNCNAME[0]} + pmem_clean_pool_file $TEST_DIR/test/pmem/obj_pool_file + + echo "Creating new type OBJ pool file" + if hash pmempool; then + pmempool create -s 32000000 obj $obj_pool_file + else + echo "Warning: pmempool package not found! Creating stub file." + truncate -s "32M" $obj_pool_file + fi + + if $rpc_py pmem_pool_info $TEST_DIR/test/pmem/obj_pool_file; then + pmem_clean_pool_file $TEST_DIR/test/pmem/obj_pool_file + error "Pmem_pool_info passed with invalid pool_file type!" + fi + + pmem_clean_pool_file $TEST_DIR/test/pmem/obj_pool_file + return 0 +} + +function pmem_pool_info_tc4() +{ + pmem_print_tc_name ${FUNCNAME[0]} + pmem_clean_pool_file + + pmem_create_pool_file + if ! $rpc_py pmem_pool_info $default_pool_file; then + error "Failed to get pmem_pool_info!" + fi + + pmem_clean_pool_file + return 0 +} + +#================================================ +# create_pmem_pool tests +#================================================ +function create_pmem_pool_tc1() +{ + pmem_print_tc_name ${FUNCNAME[0]} + pmem_clean_pool_file + + if $rpc_py create_pmem_pool 32 512; then + error "Mem pool file created w/out given path!" + fi + + if $rpc_py create_pmem_pool $default_pool_file; then + error "Mem pool file created w/out size & block size arguments!" + fi + + if $rpc_py pmem_pool_info $default_pool_file; then + error "create_pmem_pool created invalid pool file!" + fi + + if $rpc_py create_pmem_pool $default_pool_file 32; then + error "Mem pool file created w/out block size argument!" + fi + + if $rpc_py pmem_pool_info $default_pool_file; then + error "create_pmem_pool created invalid pool file!" + fi + + pmem_clean_pool_file + return 0 +} + +function create_pmem_pool_tc2() +{ + pmem_print_tc_name ${FUNCNAME[0]} + pmem_clean_pool_file + + if $rpc_py create_pmem_pool $TEST_DIR/non/existing/path/non_existent_file 32 512; then + error "Mem pool file created with incorrect path!" + fi + + if $rpc_py pmem_pool_info $TEST_DIR/non/existing/path/non_existent_file; then + error "create_pmem_pool created invalid pool file!" + fi + + pmem_clean_pool_file + return 0 +} + +function create_pmem_pool_tc3() +{ + pmem_print_tc_name ${FUNCNAME[0]} + pmem_clean_pool_file + + if ! $rpc_py create_pmem_pool $default_pool_file 256 512; then + error "Failed to create pmem pool!" + fi + + if ! $rpc_py pmem_pool_info $default_pool_file; then + error "Failed to get pmem info" + fi + + if ! $rpc_py delete_pmem_pool $default_pool_file; then + error "Failed to delete pool file!" + fi + + if $rpc_py pmem_pool_info $default_pool_file; then + error "Got pmem file info but file should be deleted" + fi + + if [ -f $default_pool_file ]; then + error "Failed to delete pmem file!" + fi + + pmem_clean_pool_file + return 0 +} + +function create_pmem_pool_tc4() +{ + pmem_print_tc_name ${FUNCNAME[0]} + + pmem_unmount_ramspace + mkdir $TEST_DIR/test/pmem/ramspace + mount -t tmpfs -o size=300m tmpfs $TEST_DIR/test/pmem/ramspace + if ! $rpc_py create_pmem_pool $TEST_DIR/test/pmem/ramspace/pool_file 256 512; then + pmem_unmount_ramspace + error "Failed to create pmem pool!" + fi + + if ! $rpc_py pmem_pool_info $TEST_DIR/test/pmem/ramspace/pool_file; then + pmem_unmount_ramspace + error "Failed to get pmem info" + fi + + if ! $rpc_py delete_pmem_pool $TEST_DIR/test/pmem/ramspace/pool_file; then + pmem_unmount_ramspace + error "Failed to delete pool file!" + fi + + if [ -f $TEST_DIR/test/pmem/ramspace/pool_file ]; then + pmem_unmount_ramspace + error "Failed to delete pmem file / file still exists!" + fi + + pmem_unmount_ramspace + return 0 +} + +function create_pmem_pool_tc5() +{ + pmem_print_tc_name ${FUNCNAME[0]} + pmem_clean_pool_file + local pmem_block_size + local pmem_num_block + + if ! $rpc_py create_pmem_pool $default_pool_file 256 512; then + error "Failed to create pmem pool!" + fi + + if $rpc_py pmem_pool_info $default_pool_file; then + pmem_block_size=$($rpc_py pmem_pool_info $default_pool_file | jq -r '.[] .block_size') + pmem_num_block=$($rpc_py pmem_pool_info $default_pool_file | jq -r '.[] .num_blocks') + else + error "Failed to get pmem info!" + fi + + if $rpc_py create_pmem_pool $default_pool_file 512 4096; then + error "Pmem pool with already occupied path has been created!" + fi + + if $rpc_py pmem_pool_info $default_pool_file; then + if [ $pmem_block_size != $($rpc_py pmem_pool_info $default_pool_file | jq -r '.[] .block_size') ]; then + error "Invalid block size of pmem pool!" + fi + + if [ $pmem_num_block != $($rpc_py pmem_pool_info $default_pool_file | jq -r '.[] .num_blocks') ]; then + error "Invalid number of blocks of pmem pool!" + fi + else + error "Failed to get pmem info!" + fi + + if ! $rpc_py delete_pmem_pool $default_pool_file; then + error "Failed to delete pmem file!" + fi + + pmem_clean_pool_file + return 0 +} + +function create_pmem_pool_tc6() +{ + pmem_print_tc_name ${FUNCNAME[0]} + pmem_clean_pool_file + local created_pmem_block_size + + for i in 511 512 1024 2048 4096 131072 262144 + do + if ! $rpc_py create_pmem_pool $default_pool_file 256 $i; then + error "Failed to create pmem pool!" + fi + + created_pmem_block_size=$($rpc_py pmem_pool_info $default_pool_file | jq -r '.[] .block_size') + if [ $? != 0 ]; then + error "Failed to get pmem info!" + fi + + if [ $i != $created_pmem_block_size ]; then + error "Invalid block size of pmem pool!" + fi + + if ! $rpc_py delete_pmem_pool $default_pool_file; then + error "Failed to delete pmem file!" + fi + done + + pmem_clean_pool_file + return 0 +} + +function create_pmem_pool_tc7() +{ + pmem_print_tc_name ${FUNCNAME[0]} + pmem_clean_pool_file + + if $rpc_py create_pmem_pool $default_pool_file 15 512; then + error "Created pmem pool with invalid size!" + fi + + if $rpc_py pmem_pool_info $default_pool_file; then + error "Pmem file shouldn' exist!" + fi + + pmem_clean_pool_file + return 0 +} + +function create_pmem_pool_tc8() +{ + pmem_print_tc_name "create_pmem_pool_tc8" + pmem_clean_pool_file + + if $rpc_py create_pmem_pool $default_pool_file 32 65536; then + error "Created pmem pool with invalid block number!" + fi + + if $rpc_py pmem_pool_info $default_pool_file; then + error "Pmem file shouldn' exist!" + fi + + pmem_clean_pool_file + return 0 +} + +function create_pmem_pool_tc9() +{ + pmem_print_tc_name ${FUNCNAME[0]} + pmem_clean_pool_file + + if $rpc_py create_pmem_pool $default_pool_file 256 -1; then + error "Created pmem pool with negative block size number!" + fi + + if $rpc_py pmem_pool_info $default_pool_file; then + error "create_pmem_pool create invalid pool file!" + fi + + if $rpc_py create_pmem_pool $default_pool_file -1 512; then + error "Created pmem pool with negative size number!" + fi + + if $rpc_py pmem_pool_info $default_pool_file; then + error "create_pmem_pool create invalid pool file!" + fi + + pmem_clean_pool_file + return 0 +} + +#================================================ +# delete_pmem_pool tests +#================================================ +function delete_pmem_pool_tc1() +{ + pmem_print_tc_name ${FUNCNAME[0]} + pmem_clean_pool_file + + if $rpc_py delete_pmem_pool $default_pool_file; then + error "delete_pmem_pool deleted inexistant pool file!" + fi + + return 0 +} + +function delete_pmem_pool_tc2() +{ + pmem_print_tc_name "delete_pmem_pool_tc2" + pmem_clean_pool_file $TEST_DIR/test/pmem/obj_pool_file + + echo "Creating new type OBJ pool file" + if hash pmempool; then + pmempool create -s 32000000 obj $obj_pool_file + else + echo "Warning: pmempool package not found! Creating stub file." + truncate -s "32M" $obj_pool_file + fi + + if $rpc_py delete_pmem_pool $TEST_DIR/test/pmem/obj_pool_file; then + pmem_clean_pool_file $TEST_DIR/test/pmem/obj_pool_file + error "delete_pmem_pool deleted invalid pmem pool type!" + fi + + pmem_clean_pool_file $TEST_DIR/test/pmem/obj_pool_file + return 0 +} + +function delete_pmem_pool_tc3() +{ + pmem_print_tc_name ${FUNCNAME[0]} + pmem_clean_pool_file + + pmem_create_pool_file + if ! $rpc_py pmem_pool_info $default_pool_file; then + error "Failed to get info on pmem pool file!" + fi + + if ! $rpc_py delete_pmem_pool $default_pool_file; then + error "Failed to delete pmem pool file!" + fi + + if $rpc_py pmem_pool_info $default_pool_file; then + error "Pmem pool file exists after using pmem_pool_info!" + fi + + return 0 +} + +function delete_pmem_pool_tc4() +{ + pmem_print_tc_name ${FUNCNAME[0]} + + delete_pmem_pool_tc3 + if $rpc_py delete_pmem_pool $default_pool_file; then + error "Deleted pmem pool file that shouldn't exist!" + fi + + return 0 +} + +#================================================ +# construct_pmem_bdev tests +#================================================ +function construct_pmem_bdev_tc1() +{ + pmem_print_tc_name ${FUNCNAME[0]} + pmem_clean_pool_file + + pmem_create_pool_file + if $rpc_py construct_pmem_bdev; then + error "construct_pmem_bdev passed with missing argument!" + fi + + pmem_clean_pool_file + return 0 +} + +function construct_pmem_bdev_tc2() +{ + pmem_print_tc_name ${FUNCNAME[0]} + pmem_clean_pool_file + + pmem_create_pool_file + if $rpc_py construct_pmem_bdev -n $bdev_name $TEST_DIR/non/existing/path/non_existent_file; then + error "Created pmem bdev w/out valid pool file!" + fi + + if $rpc_py get_bdevs | jq -r '.[] .name' | grep -qi pmem; then + error "construct_pmem_bdev passed with invalid argument!" + fi + + pmem_clean_pool_file + return 0 +} + +function construct_pmem_bdev_tc3() +{ + pmem_print_tc_name ${FUNCNAME[0]} + + truncate -s 32M $TEST_DIR/test/pmem/random_file + if $rpc_py construct_pmem_bdev -n $bdev_name $TEST_DIR/test/pmem/random_file; then + error "Created pmem bdev from random file!" + fi + + if [ -f $TEST_DIR/test/pmem/random_file ]; then + echo "Deleting previously created random file" + rm $TEST_DIR/test/pmem/random_file + fi + + return 0 +} + +function construct_pmem_bdev_tc4() +{ + pmem_print_tc_name ${FUNCNAME[0]} + pmem_clean_pool_file $TEST_DIR/test/pmem/obj_pool_file + + echo "Creating new type OBJ pool file" + if hash pmempool; then + pmempool create -s 32000000 obj $obj_pool_file + else + echo "Warning: pmempool package not found! Creating stub file." + truncate -s "32M" $obj_pool_file + fi + + if $rpc_py construct_pmem_bdev -n $bdev_name $TEST_DIR/test/pmem/obj_pool_file; then + pmem_clean_pool_file $TEST_DIR/test/pmem/obj_pool_file + error "Created pmem bdev from obj type pmem file!" + fi + + pmem_clean_pool_file $TEST_DIR/test/pmem/obj_pool_file + return 0 +} + +function construct_pmem_bdev_tc5() +{ + pmem_print_tc_name ${FUNCNAME[0]} + pmem_clean_pool_file + pmem_create_pool_file + local pmem_bdev_name + + if ! $rpc_py pmem_pool_info $default_pool_file; then + error "Failed to get pmem info!" + fi + + pmem_bdev_name=$($rpc_py construct_pmem_bdev -n $bdev_name $default_pool_file) + if [ $? != 0 ]; then + error "Failed to create pmem bdev" + fi + + if ! $rpc_py get_bdevs | jq -r '.[] .name' | grep -qi $pmem_bdev_name; then + error "Pmem bdev not found!" + fi + + if ! $rpc_py delete_pmem_bdev $pmem_bdev_name; then + error "Failed to delete pmem bdev!" + fi + + if ! $rpc_py delete_pmem_pool $default_pool_file; then + error "Failed to delete pmem pool file!" + fi + + pmem_clean_pool_file + return 0 +} + +function construct_pmem_bdev_tc6() +{ + pmem_print_tc_name ${FUNCNAME[0]} + local pmem_bdev_name + pmem_clean_pool_file + + pmem_create_pool_file + if ! $rpc_py pmem_pool_info $default_pool_file; then + error "Failed to get info on pmem pool file!" + fi + + pmem_bdev_name=$($rpc_py construct_pmem_bdev -n $bdev_name $default_pool_file) + if [ $? != 0 ]; then + error "Failed to create pmem bdev!" + fi + + if ! $rpc_py get_bdevs | jq -r '.[] .name' | grep -qi $pmem_bdev_name; then + error "Pmem bdev not found!" + fi + + if $rpc_py construct_pmem_bdev -n $bdev_name $default_pool_file; then + error "Constructed pmem bdev with occupied path!" + fi + + if ! $rpc_py delete_pmem_bdev $pmem_bdev_name; then + error "Failed to delete pmem bdev!" + fi + + if ! $rpc_py delete_pmem_pool $default_pool_file; then + error "Failed to delete pmem pool file!" + fi + + pmem_clean_pool_file + return 0 +} + +#================================================ +# delete_pmem_bdev tests +#================================================ +function delete_bdev_tc1() +{ + pmem_print_tc_name ${FUNCNAME[0]} + local pmem_bdev_name + local bdevs_names + pmem_clean_pool_file + + pmem_create_pool_file $default_pool_file 256 512 + if ! $rpc_py pmem_pool_info $default_pool_file; then + error "Failed to get pmem info!" + fi + + pmem_bdev_name=$($rpc_py construct_pmem_bdev -n $bdev_name $default_pool_file) + if [ $? != 0 ]; then + error "Failed to create pmem bdev!" + fi + + if ! $rpc_py get_bdevs | jq -r '.[] .name' | grep -qi $pmem_bdev_name; then + error "$pmem_bdev_name bdev not found!" + fi + + if ! $rpc_py delete_pmem_bdev $pmem_bdev_name; then + error "Failed to delete $pmem_bdev_name bdev!" + fi + + bdevs_names=$($rpc_py get_bdevs | jq -r '.[] .name') + if echo $bdevs_names | grep -qi $pmem_bdev_name; then + error "$pmem_bdev_name bdev is not deleted!" + fi + + pmem_clean_pool_file + return 0 +} + +function delete_bdev_tc2() +{ + pmem_print_tc_name ${FUNCNAME[0]} + pmem_clean_pool_file + pmem_create_pool_file $default_pool_file 256 512 + local pmem_bdev_name + + if ! $rpc_py pmem_pool_info $default_pool_file; then + error "Failed to get pmem info!" + fi + + pmem_bdev_name=$($rpc_py construct_pmem_bdev -n $bdev_name $default_pool_file) + if [ $? != 0 ]; then + error "Failed to create pmem bdev" + fi + + if ! $rpc_py get_bdevs | jq -r '.[] .name' | grep -qi $pmem_bdev_name; then + error "Pmem bdev not found!" + fi + + if ! $rpc_py delete_pmem_bdev $pmem_bdev_name; then + error "Failed to delete pmem bdev!" + fi + + if $rpc_py delete_pmem_bdev $pmem_bdev_name; then + error "delete_pmem_bdev deleted pmem bdev for second time!" + fi + + pmem_clean_pool_file + return 0 +} + +timing_enter pmem +vhost_start +if ! $enable_script_debug; then + set +x +fi + +if $test_info || $test_all; then + pmem_pool_info_tc1 + pmem_pool_info_tc2 + pmem_pool_info_tc3 + pmem_pool_info_tc4 +fi + +if $test_create || $test_all; then + create_pmem_pool_tc1 + create_pmem_pool_tc2 + create_pmem_pool_tc3 + create_pmem_pool_tc4 + create_pmem_pool_tc5 + create_pmem_pool_tc6 + create_pmem_pool_tc7 + create_pmem_pool_tc8 + create_pmem_pool_tc9 +fi + +if $test_delete || $test_all; then + delete_pmem_pool_tc1 + delete_pmem_pool_tc2 + delete_pmem_pool_tc3 + delete_pmem_pool_tc4 +fi + +if $test_construct_bdev || $test_all; then + construct_pmem_bdev_tc1 + construct_pmem_bdev_tc2 + construct_pmem_bdev_tc3 + construct_pmem_bdev_tc4 + construct_pmem_bdev_tc5 + construct_pmem_bdev_tc6 +fi + +if $test_delete_bdev || $test_all; then + delete_bdev_tc1 + delete_bdev_tc2 +fi + +pmem_clean_pool_file +report_test_completion "pmem" +vhost_kill +timing_exit pmem diff --git a/src/spdk/test/pmem/test_plan.md b/src/spdk/test/pmem/test_plan.md new file mode 100644 index 00000000..18e99f36 --- /dev/null +++ b/src/spdk/test/pmem/test_plan.md @@ -0,0 +1,310 @@ +# PMEM bdev feature test plan + +## Objective +The purpose of these tests is to verify possibility of using pmem bdev +configuration in SPDK by running functional tests FIO traffic verification +tests. + +## Configuration +Configuration in tests is to be done using example stub application +(spdk/example/bdev/io/bdev_io). +All possible management is done using RPC calls with the exception of +use of split bdevs which have to be configured in .conf file. + +Functional tests are executed as scenarios - sets of smaller test steps +in which results and return codes of RPC calls are validated. +Some configuration calls may also additionally be validated +by use of "get" (e.g. get_bdevs) RPC calls, which provide additional +information for veryfing results. +In some steps additional write/read operations will be performed on +PMEM bdevs in order to check IO path correct behavior. + +FIO traffic verification tests will serve as integration tests and will +be executed to config correct behavior of PMEM bdev when working with vhost, +nvmf_tgt and iscsi_tgt applications. + +## Functional tests + +### pmem_pool_info + +#### pmem_pool_info_tc1 +Negative test for checking pmem pool file. +Call with missing path argument. +Steps & expected results: +- Call pmem_pool_info with missing path argument +- Check that return code != 0 and error code = + +#### pmem_pool_info_tc2 +Negative test for checking pmem pool file. +Call with non-existant path argument. +Steps & expected results: +- Call pmem_pool_info with path argument that points to not existing file. +- Check that return code != 0 and error code = ENODEV + +#### pmem_pool_info_tc3 +Negative test for checking pmem pool file. +Call with other type of pmem pool file. +Steps & expected results: +- Using pmem utility tools create pool of OBJ type instead of BLK +(if needed utility tools are not available - create random file in filesystem) +- Call pmem_pool_info and point to file created in previous step. +- Check that return code != 0 and error code = ENODEV + +#### pmem_pool_info_tc4 +Positive test for checking pmem pool file. +Call with existing pmem pool file. +Steps & expected results: +- Call pmem_pool_info with path argument that points to existing file. +- Check that return code == 0 + +### create_pmem_pool +From libpmemblk documentation: +- PMEM block size has to be bigger than 512 internal blocks; if lower value +is used then PMEM library will silently round it up to 512 which is defined +in pmem/libpmemblk.h file as PMEMBLK_MIN_BLK. +- Total pool size cannot be less than 16MB which is defined i +pmem/libpmemblk.h file as PMEMBLK_MIN_POOL +- Total number of segments in PMEP pool file cannot be less than 256 + +#### create_pmem_pool_tc1 +Negative test case for creating a new pmem. +Call create_pmem_pool with missing arguments. +Steps & expected results: +- call create_pmem_pool without path argument +- call return code != 0 +- call pmem_pool_info and check that pmem pool file was not created +- call return code != 0 +- call create_pmem_pool with path but without size and block size arguments +- call return code != 0 +- call pmem_pool_info and check that pmem pool file was not created +- call return code != 0 +- call create_pmem_pool with path and size but without block size arguments +- call return code != 0 +- call pmem_pool_info and check that pmem pool file was not created +- call return code != 0 + +#### create_pmem_pool_tc2 +Negative test case for creating a new pmem. +Call create_pmem_pool with non existing path argument. +Steps & expected results: +- call create_pmem_pool with path that does not exist +- call return code != 0 +- call pmem_pool_info and check that pmem pool file was not created +- call return code != 0 + +#### create_pmem_pool_tc3 +Positive test case for creating a new pmem pool on disk space. +Steps & expected results: +- call create_pmem_pool with correct path argument, +blocksize=512 and total size=256MB +- call return code = 0 +- call pmem_pool_info and check that pmem file was created +- call return code = 0 +- call delete_pmem_pool on previously created pmem +- return code = 0 and no error code + +#### create_pmem_pool_tc4 +Positive test case for creating a new pmem pool in RAM space. +# TODO: Research test steps for creating a pool in RAM!!! +Steps & expected results: +- call create_pmem_pool with correct path argument, +blocksize=512 and total size=256MB +- call return code = 0 +- call pmem_pool_info and check that pmem file was created +- call return code = 0 +- call delete_pmem_pool on previously created pmem +- return code = 0 and no error code + +#### create_pmem_pool_tc5 +Negative test case for creating two pmems with same path. +Steps & expected results: +- call create_pmem_pool with correct path argument, +blocksize=512 and total size=256MB +- call return code = 0 +- call pmem_pool_info and check that pmem file was created +- call return code = 0 +- call create_pmem_pool with the same path argument as before, +blocksize=4096 and total size=512MB +- call return code != 0, error code = EEXIST +- call create_pmem_pool and check that first pmem pool file is still +available and not modified (block size and total size stay the same) +- call return code = 0 +- call delete_pmem_pool on first created pmem pool +- return code =0 and no error code + +#### create_pmem_pool_tc6 +Positive test case for creating pmem pool file with various block sizes. +Steps & expected results: +- call create_pmem_pool with correct path argument, total size=256MB +with different block size arguments - 1, 511, 512, 513, 1024, 4096, 128k and 256k +- call pmem_pool_info on each of created pmem pool and check if it was created; +For pool files created with block size <512 their block size should be rounded up +to 512; other pool files should have the same block size as specified in create +command +- call return code = 0; block sizes as expected +- call delete_pmem_pool on all created pool files + +#### create_pmem_pool_tc7 +Negative test case for creating pmem pool file with total size of less than 16MB. +Steps & expected results: +- call create_pmem_pool with correct path argument, block size=512 and +total size less than 16MB +- return code !=0 and error code !=0 +- call pmem_pool_info to verify pmem pool file was not created +- return code = 0 + +#### create_pmem_pool_tc8 +Negative test case for creating pmem pool file with less than 256 blocks. +Steps & expected results: +- call create_pmem_pool with correct path argument, block size=128k and +total size=30MB +- return code !=0 and error code !=0 +- call pmem_pool_info to verify pmem pool file was not created +- return code = 0 + +### delete_pmem_pool + +#### delete_pmem_pool_tc1 +Negative test case for deleting a pmem. +Call delete_pmem_pool on non-exisiting pmem. +Steps & expected results: +- call delete_pmem_pool on non-existing pmem. +- return code !=0 and error code = ENOENT + +#### delete_pmem_pool_tc2 +Negative test case for deleting a pmem. +Call delete_pmem_pool on a file of wrong type +Steps & expected results: +- Using pmem utility tools create pool of OBJ type instead of BLK +(if needed utility tools are not available - create random file in filesystem) +- Call delete_pmem_pool and point to file created in previous step. +- return code !=0 and error code = ENOTBLK + +#### delete_pmem_pool_tc3 +Positive test case for creating and deleting a pemem. +Steps & expected results: +- call create_pmem_pool with correct arguments +- return code = 0 and no error code +- using pmem_pool_info check that pmem was created +- return code = 0 and no error code +- call delete_pmem_pool on previously created pmem +- return code = 0 and no error code +- using pmem_pool_info check that pmem no longer exists +- return code !=0 and error code = ENODEV + +#### delete_pmem_pool_tc4 +Negative test case for creating and deleting a pemem. +Steps & expected results: +- run scenario from test case 3 +- call delete_pmem_pool on already deleted pmem pool +- return code !=0 and error code = ENODEV + +### construct_pmem_bdev + +#### construct_pmem_bdev_tc1 +Negative test for constructing new pmem bdev. +Call create_pmem_bdev with missing argument. +Steps & expected results: +- Call construct_pmem_bdev with missing path argument. +- Check that return code != 0 + +#### construct_pmem_bdev_tc2 +Negative test for constructing new pmem bdev. +Call construct_pmem_bdev with not existing path argument. +Steps & expected results: +- call construct_pmem_bdev with incorrect (not existing) path +- call return code != 0 and error code = ENODEV +- using get_bdevs check that no pmem bdev was created + +#### construct_pmem_bdev_tc3 +Negative test for constructing pmem bdevs with random file instead of pmemblk pool. +Steps & expected results: +- using a system tool (like dd) create a random file +- call construct_pmem_bdev with path pointing to that file +- return code != 0, error code = ENOTBLK + +#### construct_pmem_bdev_tc4 +Negative test for constructing pmem bdevs with pmemobj instead of pmemblk pool. +Steps & expected results: +- Using pmem utility tools create pool of OBJ type instead of BLK +(if needed utility tools are not available - create random file in filesystem) +- call construct_pmem_bdev with path pointing to that pool +- return code != 0, error code = ENOTBLK + +#### construct_pmem_bdev_tc5 +Positive test for constructing pmem bdev. +Steps & expected results: +- call create_pmem_pool with correct arguments +- return code = 0, no errors +- call pmem_pool_info and check if pmem files exists +- return code = 0, no errors +- call construct_pmem_bdev with with correct arguments to create a pmem bdev +- return code = 0, no errors +- using get_bdevs check that pmem bdev was created +- delete pmem bdev using delete_bdev +- return code = 0, no error code +- delete previously created pmem pool +- return code = 0, no error code + +#### construct_pmem_bdev_tc6 +Negative test for constructing pmem bdevs twice on the same pmem. +Steps & expected results: +- call create_pmem_pool with correct arguments +- return code = 0, no errors +- call pmem_pool_info and check if pmem files exists +- return code = 0, no errors +- call construct_pmem_bdev with with correct arguments to create a pmem bdev +- return code = 0, no errors +- using get_bdevs check that pmem bdev was created +- call construct_pmem_bdev again on the same pmem file +- return code != 0, error code = EEXIST +- delete pmem bdev using delete_bdev +- return code = 0, no error code +- delete previously created pmem pool +- return code = 0, no error code + +### delete_bdev + +#### delete_bdev_tc1 +Positive test for deleting pmem bdevs using common delete_bdev call. +Steps & expected results: +- construct malloc and aio bdevs (also NVMe if possible) +- all calls - return code = 0, no errors; bdevs created +- call create_pmem_pool with correct path argument, +block size=512, total size=256M +- return code = 0, no errors +- call pmem_pool_info and check if pmem file exists +- return code = 0, no errors +- call construct_pmem_bdev and create a pmem bdev +- return code = 0, no errors +- using get_bdevs check that pmem bdev was created +- delete pmem bdev using delete_bdev +- return code = 0, no errors +- using get_bdevs confirm that pmem bdev was deleted and other bdevs +were unaffected. + +#### delete_bdev_tc2 +Negative test for deleting pmem bdev twice. +Steps & expected results: +- call create_pmem_pool with correct path argument, +block size=512, total size=256M +- return code = 0, no errors +- call pmem_pool_info and check if pmem file exists +- return code = 0, no errors +- call construct_pmem_bdev and create a pmem bdev +- return code = 0, no errors +- using get_bdevs check that pmem bdev was created +- delete pmem bdev using delete_bdev +- return code = 0, no errors +- using get_bdevs confirm that pmem bdev was deleted +- delete pmem bdev using delete_bdev second time +- return code != 0, error code = ENODEV + + +## Integration tests +Description of integration tests which run FIO verification traffic against +pmem_bdevs used in vhost, iscsi_tgt and nvmf_tgt applications can be found in +test directories for these components: +- spdk/test/vhost +- spdk/test/nvmf +- spdk/test/iscsi_tgt |