summaryrefslogtreecommitdiffstats
path: root/src/spdk/test/lvol
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/spdk/test/lvol
parentInitial commit. (diff)
downloadceph-upstream.tar.xz
ceph-upstream.zip
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rwxr-xr-xsrc/spdk/test/lvol/lvol.sh135
-rwxr-xr-xsrc/spdk/test/lvol/lvol_test.py45
-rw-r--r--src/spdk/test/lvol/rpc_commands_lib.py241
-rw-r--r--src/spdk/test/lvol/test_cases.py2591
-rw-r--r--src/spdk/test/lvol/test_plan.md585
5 files changed, 3597 insertions, 0 deletions
diff --git a/src/spdk/test/lvol/lvol.sh b/src/spdk/test/lvol/lvol.sh
new file mode 100755
index 00000000..a5883765
--- /dev/null
+++ b/src/spdk/test/lvol/lvol.sh
@@ -0,0 +1,135 @@
+#!/usr/bin/env bash
+set -e
+BASE_DIR=$(readlink -f $(dirname $0))
+[[ -z "$TEST_DIR" ]] && TEST_DIR="$(cd $BASE_DIR/../../ && pwd)"
+
+total_size=256
+block_size=512
+test_cases=all
+x=""
+
+rpc_py="$TEST_DIR/scripts/rpc.py "
+
+function usage() {
+ [[ ! -z $2 ]] && ( echo "$2"; echo ""; )
+ echo "Shortcut script for doing automated lvol tests"
+ echo "Usage: $(basename $1) [OPTIONS]"
+ echo
+ echo "-h, --help print help and exit"
+ echo " --total-size Size of malloc bdev in MB (int > 0)"
+ echo " --block-size Block size for this bdev"
+ echo "-x set -x for script debug"
+ echo " --test-cases= List test cases which will be run:
+ 1: 'construct_lvs_positive',
+ 50: 'construct_logical_volume_positive',
+ 51: 'construct_multi_logical_volumes_positive',
+ 52: 'construct_lvol_bdev_using_name_positive',
+ 53: 'construct_lvol_bdev_duplicate_names_positive',
+ 100: 'construct_logical_volume_nonexistent_lvs_uuid',
+ 101: 'construct_lvol_bdev_on_full_lvol_store',
+ 102: 'construct_lvol_bdev_name_twice',
+ 150: 'resize_lvol_bdev_positive',
+ 200: 'resize_logical_volume_nonexistent_logical_volume',
+ 201: 'resize_logical_volume_with_size_out_of_range',
+ 250: 'destroy_lvol_store_positive',
+ 251: 'destroy_lvol_store_use_name_positive',
+ 252: 'destroy_lvol_store_with_lvol_bdev_positive',
+ 253: 'destroy_multi_logical_volumes_positive',
+ 254: 'destroy_after_resize_lvol_bdev_positive',
+ 255: 'delete_lvol_store_persistent_positive',
+ 300: 'destroy_lvol_store_nonexistent_lvs_uuid',
+ 301: 'delete_lvol_store_underlying_bdev',
+ 350: 'nested_destroy_logical_volume_negative',
+ 400: 'nested_construct_logical_volume_positive',
+ 450: 'construct_lvs_nonexistent_bdev',
+ 451: 'construct_lvs_on_bdev_twice',
+ 452: 'construct_lvs_name_twice',
+ 500: 'nested_construct_lvol_bdev_on_full_lvol_store',
+ 550: 'delete_bdev_positive',
+ 551: 'delete_lvol_bdev',
+ 552: 'destroy_lvol_store_with_clones',
+ 553: 'unregister_lvol_bdev',
+ 600: 'construct_lvol_store_with_cluster_size_max',
+ 601: 'construct_lvol_store_with_cluster_size_min',
+ 650: 'thin_provisioning_check_space',
+ 651: 'thin_provisioning_read_empty_bdev',
+ 652: 'thin_provisionind_data_integrity_test',
+ 653: 'thin_provisioning_resize',
+ 654: 'thin_overprovisioning',
+ 655: 'thin_provisioning_filling_disks_less_than_lvs_size',
+ 700: 'tasting_positive',
+ 701: 'tasting_lvol_store_positive',
+ 750: 'snapshot_readonly',
+ 751: 'snapshot_compare_with_lvol_bdev',
+ 752: 'snapshot_during_io_traffic',
+ 753: 'snapshot_of_snapshot',
+ 754: 'clone_bdev_only',
+ 755: 'clone_writing_clone',
+ 756: 'clone_and_snapshot_consistency',
+ 757: 'clone_inflate',
+ 758: 'clone_decouple_parent',
+ 759: 'clone_decouple_parent_rw',
+ 800: 'rename_positive',
+ 801: 'rename_lvs_nonexistent',
+ 802: 'rename_lvs_EEXIST',
+ 803: 'rename_lvol_bdev_nonexistent',
+ 804: 'rename_lvol_bdev_EEXIST',
+ 10000: 'SIGTERM'
+ or
+ all: This parameter runs all tests
+ Ex: \"1,2,19,20\", default: all"
+ echo
+ echo
+}
+
+while getopts 'xh-:' optchar; do
+ case "$optchar" in
+ -)
+ case "$OPTARG" in
+ help) usage $0 && exit 0;;
+ total-size=*) total_size="${OPTARG#*=}" ;;
+ block-size=*) block_size="${OPTARG#*=}" ;;
+ test-cases=*) test_cases="${OPTARG#*=}" ;;
+ *) usage $0 "Invalid argument '$OPTARG'" && exit 1 ;;
+ esac
+ ;;
+ h) usage $0 && exit 0 ;;
+ x) set -x
+ x="-x" ;;
+ *) usage $0 "Invalid argument '$OPTARG'" && exit 1 ;;
+ esac
+done
+shift $(( OPTIND - 1 ))
+
+source $TEST_DIR/test/common/autotest_common.sh
+
+### Function starts vhost app
+function vhost_start()
+{
+ modprobe nbd
+ $TEST_DIR/app/vhost/vhost &
+ vhost_pid=$!
+ echo $vhost_pid > $BASE_DIR/vhost.pid
+ waitforlisten $vhost_pid
+}
+
+### Function stops vhost app
+function vhost_kill()
+{
+ ### Kill with SIGKILL param
+ if pkill -F $BASE_DIR/vhost.pid; then
+ sleep 1
+ fi
+ rm $BASE_DIR/vhost.pid || true
+ rmmod nbd || true
+}
+
+trap "vhost_kill; rm -f $BASE_DIR/aio_bdev_0 $BASE_DIR/aio_bdev_1; exit 1" SIGINT SIGTERM EXIT
+
+truncate -s 400M $BASE_DIR/aio_bdev_0 $BASE_DIR/aio_bdev_1
+vhost_start
+$BASE_DIR/lvol_test.py $rpc_py $total_size $block_size $BASE_DIR $TEST_DIR/app/vhost "${test_cases[@]}"
+
+vhost_kill
+rm -rf $BASE_DIR/aio_bdev_0 $BASE_DIR/aio_bdev_1
+trap - SIGINT SIGTERM EXIT
diff --git a/src/spdk/test/lvol/lvol_test.py b/src/spdk/test/lvol/lvol_test.py
new file mode 100755
index 00000000..50255f1f
--- /dev/null
+++ b/src/spdk/test/lvol/lvol_test.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python3
+
+import sys
+from test_cases import *
+
+
+if __name__ == "__main__":
+ rpc_py = None
+ total_size = None
+ block_size = None
+ num_test = None
+ fail_count = 0
+ tc_failed = []
+ tc_list = []
+
+ if len(sys.argv) == 7 and len(sys.argv[6].split(',')) <= test_counter():
+ rpc_py = sys.argv[1]
+ total_size = int(sys.argv[2])
+ block_size = int(sys.argv[3])
+ base_dir_path = sys.argv[4]
+ app_path = sys.argv[5]
+ tc_list = sys.argv[6].split(',')
+ else:
+ print("Invalid argument")
+ try:
+ tc = TestCases(rpc_py, total_size, block_size, base_dir_path, app_path)
+ if "all" in tc_list:
+ tc_list = sorted([i.split("test_case")[1] for i in dir(TestCases) if "test_case" in i], key=int)
+
+ for num_test in tc_list:
+ fail_count = 0
+ exec("fail_count += tc.test_case{num_test}"
+ "()".format(num_test=num_test))
+ if fail_count:
+ tc_failed.append(num_test)
+
+ if not tc_failed:
+ print("RESULT: All test cases - PASS")
+ elif tc_failed:
+ print("RESULT: Some test cases FAIL")
+ print(tc_failed)
+ sys.exit(1)
+ except BaseException:
+ print("Test: {num_test} - FAIL".format(num_test=num_test))
+ sys.exit(1)
diff --git a/src/spdk/test/lvol/rpc_commands_lib.py b/src/spdk/test/lvol/rpc_commands_lib.py
new file mode 100644
index 00000000..0857c73d
--- /dev/null
+++ b/src/spdk/test/lvol/rpc_commands_lib.py
@@ -0,0 +1,241 @@
+import json
+import sys
+from uuid import UUID
+from subprocess import check_output, CalledProcessError
+
+
+class Spdk_Rpc(object):
+ def __init__(self, rpc_py):
+ self.rpc_py = rpc_py
+
+ def __getattr__(self, name):
+ def call(*args):
+ cmd = "{} {} {}".format(sys.executable, self.rpc_py, name)
+ for arg in args:
+ cmd += " {}".format(arg)
+ try:
+ output = check_output(cmd, shell=True)
+ return output.decode('ascii').rstrip('\n'), 0
+ except CalledProcessError as e:
+ print("ERROR: RPC Command {cmd} "
+ "execution failed:". format(cmd=cmd))
+ print("Failed command output:")
+ print(e.output)
+ return e.output.decode('ascii'), e.returncode
+ return call
+
+
+class Commands_Rpc(object):
+ def __init__(self, rpc_py):
+ self.rpc = Spdk_Rpc(rpc_py)
+
+ def check_get_bdevs_methods(self, uuid_bdev, bdev_size_mb, bdev_alias=""):
+ print("INFO: Check RPC COMMAND get_bdevs")
+ output = self.rpc.get_bdevs()[0]
+ json_value = json.loads(output)
+ for i in range(len(json_value)):
+ uuid_json = json_value[i]['name']
+ aliases = json_value[i]['aliases']
+
+ if uuid_bdev in [uuid_json]:
+ print("Info: UUID:{uuid} is found in RPC Command: "
+ "gets_bdevs response".format(uuid=uuid_bdev))
+ # Check if human-friendly alias is as expected
+ if bdev_alias and aliases:
+ if bdev_alias not in aliases:
+ print("ERROR: Expected bdev alias not found")
+ print("Expected: {name}".format(name=bdev_alias))
+ print("Actual: {aliases}".format(aliases=aliases))
+ return 1
+ # num_block and block_size have values in bytes
+ num_blocks = json_value[i]['num_blocks']
+ block_size = json_value[i]['block_size']
+ if num_blocks * block_size == bdev_size_mb * 1024 * 1024:
+ print("Info: Response get_bdevs command is "
+ "correct. Params: uuid_bdevs: {uuid}, bdev_size "
+ "{size}".format(uuid=uuid_bdev,
+ size=bdev_size_mb))
+ return 0
+ print("INFO: UUID:{uuid} or bdev_size:{bdev_size_mb} not found in "
+ "RPC COMMAND get_bdevs: "
+ "{json_value}".format(uuid=uuid_bdev, bdev_size_mb=bdev_size_mb,
+ json_value=json_value))
+ return 1
+
+ def check_get_lvol_stores(self, base_name, uuid, cluster_size=None, lvs_name=""):
+ print("INFO: RPC COMMAND get_lvol_stores")
+ json_value = self.get_lvol_stores()
+ if json_value:
+ for i in range(len(json_value)):
+ json_uuid = json_value[i]['uuid']
+ json_cluster = json_value[i]['cluster_size']
+ json_base_name = json_value[i]['base_bdev']
+ json_name = json_value[i]['name']
+
+ if base_name in json_base_name \
+ and uuid in json_uuid:
+ print("INFO: base_name:{base_name} is found in RPC "
+ "Command: get_lvol_stores "
+ "response".format(base_name=base_name))
+ print("INFO: UUID:{uuid} is found in RPC Command: "
+ "get_lvol_stores response".format(uuid=uuid))
+ if cluster_size:
+ if str(cluster_size) in str(json_cluster):
+ print("Info: Cluster size :{cluster_size} is found in RPC "
+ "Command: get_lvol_stores "
+ "response".format(cluster_size=cluster_size))
+ else:
+ print("ERROR: Wrong cluster size in lvol store")
+ print("Expected:".format(cluster_size))
+ print("Actual:".format(json_cluster))
+ return 1
+
+ # Also check name if param is provided:
+ if lvs_name:
+ if lvs_name not in json_name:
+ print("ERROR: Lvol store human-friendly name does not match")
+ print("Expected: {lvs_name}".format(lvs_name=lvs_name))
+ print("Actual: {name}".format(name=json_name))
+ return 1
+ return 0
+ print("FAILED: UUID: lvol store {uuid} on base_bdev: "
+ "{base_name} not found in get_lvol_stores()".format(uuid=uuid,
+ base_name=base_name))
+ return 1
+ else:
+ print("INFO: Lvol store not exist")
+ return 2
+ return 0
+
+ def construct_malloc_bdev(self, total_size, block_size):
+ print("INFO: RPC COMMAND construct_malloc_bdev")
+ output = self.rpc.construct_malloc_bdev(total_size, block_size)[0]
+ return output.rstrip('\n')
+
+ def construct_lvol_store(self, base_name, lvs_name, cluster_size=None):
+ print("INFO: RPC COMMAND construct_lvol_store")
+ if cluster_size:
+ output = self.rpc.construct_lvol_store(base_name,
+ lvs_name,
+ "-c {cluster_sz}".format(cluster_sz=cluster_size))[0]
+ else:
+ output = self.rpc.construct_lvol_store(base_name, lvs_name)[0]
+ return output.rstrip('\n')
+
+ def construct_lvol_bdev(self, uuid, lbd_name, size, thin=False):
+ print("INFO: RPC COMMAND construct_lvol_bdev")
+ try:
+ uuid_obj = UUID(uuid)
+ name_opt = "-u"
+ except ValueError:
+ name_opt = "-l"
+ thin_provisioned = ""
+ if thin:
+ thin_provisioned = "-t"
+ output = self.rpc.construct_lvol_bdev(name_opt, uuid, lbd_name, size, thin_provisioned)[0]
+ return output.rstrip('\n')
+
+ def destroy_lvol_store(self, uuid):
+ print("INFO: RPC COMMAND destroy_lvol_store")
+ try:
+ uuid_obj = UUID(uuid)
+ name_opt = "-u"
+ except ValueError:
+ name_opt = "-l"
+ output, rc = self.rpc.destroy_lvol_store(name_opt, uuid)
+ return rc
+
+ def delete_bdev(self, base_name):
+ print("INFO: RPC COMMAND delete_bdev")
+ output, rc = self.rpc.delete_bdev(base_name)
+ return rc
+
+ def delete_malloc_bdev(self, base_name):
+ print("INFO: RPC COMMAND delete_malloc_bdev")
+ output, rc = self.rpc.delete_malloc_bdev(base_name)
+ return rc
+
+ def destroy_lvol_bdev(self, bdev_name):
+ print("INFO: RPC COMMAND destroy_lvol_bdev")
+ output, rc = self.rpc.destroy_lvol_bdev(bdev_name)
+ return rc
+
+ def resize_lvol_bdev(self, uuid, new_size):
+ print("INFO: RPC COMMAND resize_lvol_bdev")
+ output, rc = self.rpc.resize_lvol_bdev(uuid, new_size)
+ return rc
+
+ def start_nbd_disk(self, bdev_name, nbd_name):
+ print("INFO: RPC COMMAND start_nbd_disk")
+ output, rc = self.rpc.start_nbd_disk(bdev_name, nbd_name)
+ return rc
+
+ def stop_nbd_disk(self, nbd_name):
+ print("INFO: RPC COMMAND stop_nbd_disk")
+ output, rc = self.rpc.stop_nbd_disk(nbd_name)
+ return rc
+
+ def get_lvol_stores(self, name=None):
+ print("INFO: RPC COMMAND get_lvol_stores")
+ if name:
+ output = json.loads(self.rpc.get_lvol_stores("-l", name)[0])
+ else:
+ output = json.loads(self.rpc.get_lvol_stores()[0])
+ return output
+
+ def get_lvol_bdevs(self):
+ print("INFO: RPC COMMAND get_bdevs; lvol bdevs only")
+ output = []
+ rpc_output = json.loads(self.rpc.get_bdevs()[0])
+ for bdev in rpc_output:
+ if bdev["product_name"] == "Logical Volume":
+ output.append(bdev)
+ return output
+
+ def get_lvol_bdev_with_name(self, name):
+ print("INFO: RPC COMMAND get_bdevs; lvol bdevs only")
+ rpc_output = json.loads(self.rpc.get_bdevs("-b", name)[0])
+ if len(rpc_output) > 0:
+ return rpc_output[0]
+
+ return None
+
+ def rename_lvol_store(self, old_name, new_name):
+ print("INFO: Renaming lvol store from {old} to {new}".format(old=old_name, new=new_name))
+ output, rc = self.rpc.rename_lvol_store(old_name, new_name)
+ return rc
+
+ def rename_lvol_bdev(self, old_name, new_name):
+ print("INFO: Renaming lvol bdev from {old} to {new}".format(old=old_name, new=new_name))
+ output, rc = self.rpc.rename_lvol_bdev(old_name, new_name)
+ return rc
+
+ def snapshot_lvol_bdev(self, bdev_name, snapshot_name):
+ print("INFO: RPC COMMAND snapshot_lvol_bdev")
+ output, rc = self.rpc.snapshot_lvol_bdev(bdev_name, snapshot_name)
+ return rc
+
+ def clone_lvol_bdev(self, snapshot_name, clone_name):
+ print("INFO: RPC COMMAND clone_lvol_bdev")
+ output, rc = self.rpc.clone_lvol_bdev(snapshot_name, clone_name)
+ return rc
+
+ def inflate_lvol_bdev(self, clone_name):
+ print("INFO: RPC COMMAND inflate_lvol_bdev")
+ output, rc = self.rpc.inflate_lvol_bdev(clone_name)
+ return rc
+
+ def decouple_parent_lvol_bdev(self, clone_name):
+ print("INFO: RPC COMMAND decouple_parent_lvol_bdev")
+ output, rc = self.rpc.decouple_parent_lvol_bdev(clone_name)
+ return rc
+
+ def construct_aio_bdev(self, aio_path, aio_name, aio_bs=""):
+ print("INFO: RPC COMMAND construct_aio_bdev")
+ output, rc = self.rpc.construct_aio_bdev(aio_path, aio_name, aio_bs)
+ return rc
+
+ def delete_aio_bdev(self, aio_name):
+ print("INFO: RPC COMMAND delete_aio_bdev")
+ output, rc = self.rpc.delete_aio_bdev(aio_name)
+ return rc
diff --git a/src/spdk/test/lvol/test_cases.py b/src/spdk/test/lvol/test_cases.py
new file mode 100644
index 00000000..ad85f529
--- /dev/null
+++ b/src/spdk/test/lvol/test_cases.py
@@ -0,0 +1,2591 @@
+import io
+import time
+import sys
+import random
+import signal
+import subprocess
+import pprint
+import socket
+import threading
+import os
+
+from errno import ESRCH
+from os import kill, path, unlink, path, listdir, remove
+from rpc_commands_lib import Commands_Rpc
+from time import sleep
+from uuid import uuid4
+
+
+MEGABYTE = 1024 * 1024
+
+
+current_fio_pid = -1
+
+
+def is_process_alive(pid):
+ try:
+ os.kill(pid, 0)
+ except Exception as e:
+ return 1
+
+ return 0
+
+
+def get_fio_cmd(nbd_disk, offset, size, rw, pattern, extra_params=""):
+ fio_template = "fio --name=fio_test --filename=%(file)s --offset=%(offset)s --size=%(size)s"\
+ " --rw=%(rw)s --direct=1 %(extra_params)s %(pattern)s"
+ pattern_template = ""
+ if pattern:
+ pattern_template = "--do_verify=1 --verify=pattern --verify_pattern=%s"\
+ " --verify_state_save=0" % pattern
+ fio_cmd = fio_template % {"file": nbd_disk, "offset": offset, "size": size,
+ "rw": rw, "pattern": pattern_template,
+ "extra_params": extra_params}
+
+ return fio_cmd
+
+
+def run_fio(fio_cmd, expected_ret_value):
+ global current_fio_pid
+ try:
+ proc = subprocess.Popen([fio_cmd], shell=True)
+ current_fio_pid = proc.pid
+ proc.wait()
+ rv = proc.returncode
+ except Exception as e:
+ print("ERROR: Fio test ended with unexpected exception.")
+ rv = 1
+ if expected_ret_value == rv:
+ return 0
+
+ if rv == 0:
+ print("ERROR: Fio test ended with unexpected success")
+ else:
+ print("ERROR: Fio test ended with unexpected failure")
+ return 1
+
+
+class FioThread(threading.Thread):
+ def __init__(self, nbd_disk, offset, size, rw, pattern, expected_ret_value,
+ extra_params=""):
+ super(FioThread, self).__init__()
+ self.fio_cmd = get_fio_cmd(nbd_disk, offset, size, rw, pattern,
+ extra_params=extra_params)
+ self.rv = 1
+ self.expected_ret_value = expected_ret_value
+
+ def run(self):
+ print("INFO: Starting fio")
+ self.rv = run_fio(self.fio_cmd, self.expected_ret_value)
+ print("INFO: Fio test finished")
+
+
+def test_counter():
+ '''
+ :return: the number of tests
+ '''
+ return ['test_case' in i for i in dir(TestCases)].count(True)
+
+
+def case_message(func):
+ def inner(*args, **kwargs):
+ test_name = {
+ 1: 'construct_lvs_positive',
+ 50: 'construct_logical_volume_positive',
+ 51: 'construct_multi_logical_volumes_positive',
+ 52: 'construct_lvol_bdev_using_name_positive',
+ 53: 'construct_lvol_bdev_duplicate_names_positive',
+ 100: 'construct_logical_volume_nonexistent_lvs_uuid',
+ 101: 'construct_lvol_bdev_on_full_lvol_store',
+ 102: 'construct_lvol_bdev_name_twice',
+ 150: 'resize_lvol_bdev_positive',
+ 200: 'resize_logical_volume_nonexistent_logical_volume',
+ 201: 'resize_logical_volume_with_size_out_of_range',
+ 250: 'destroy_lvol_store_positive',
+ 251: 'destroy_lvol_store_use_name_positive',
+ 252: 'destroy_lvol_store_with_lvol_bdev_positive',
+ 253: 'destroy_multi_logical_volumes_positive',
+ 254: 'destroy_after_resize_lvol_bdev_positive',
+ 255: 'delete_lvol_store_persistent_positive',
+ 300: 'destroy_lvol_store_nonexistent_lvs_uuid',
+ 301: 'delete_lvol_store_underlying_bdev',
+ 350: 'nested_destroy_logical_volume_negative',
+ 400: 'nested_construct_logical_volume_positive',
+ 450: 'construct_lvs_nonexistent_bdev',
+ 451: 'construct_lvs_on_bdev_twice',
+ 452: 'construct_lvs_name_twice',
+ 500: 'nested_construct_lvol_bdev_on_full_lvol_store',
+ 550: 'delete_bdev_positive',
+ 551: 'delete_lvol_bdev',
+ 552: 'destroy_lvol_store_with_clones',
+ 553: 'unregister_lvol_bdev',
+ 600: 'construct_lvol_store_with_cluster_size_max',
+ 601: 'construct_lvol_store_with_cluster_size_min',
+ 650: 'thin_provisioning_check_space',
+ 651: 'thin_provisioning_read_empty_bdev',
+ 652: 'thin_provisionind_data_integrity_test',
+ 653: 'thin_provisioning_resize',
+ 654: 'thin_overprovisioning',
+ 655: 'thin_provisioning_filling_disks_less_than_lvs_size',
+ 700: 'tasting_positive',
+ 701: 'tasting_lvol_store_positive',
+ 702: 'tasting_positive_with_different_lvol_store_cluster_size',
+ 750: 'snapshot_readonly',
+ 751: 'snapshot_compare_with_lvol_bdev',
+ 752: 'snapshot_during_io_traffic',
+ 753: 'snapshot_of_snapshot',
+ 754: 'clone_bdev_only',
+ 755: 'clone_writing_clone',
+ 756: 'clone_and_snapshot_consistency',
+ 757: 'clone_inflate',
+ 758: 'decouple_parent',
+ 759: 'decouple_parent_rw',
+ 800: 'rename_positive',
+ 801: 'rename_lvs_nonexistent',
+ 802: 'rename_lvs_EEXIST',
+ 803: 'rename_lvol_bdev_nonexistent',
+ 804: 'rename_lvol_bdev_EEXIST',
+ 10000: 'SIGTERM',
+ }
+ num = int(func.__name__.strip('test_case')[:])
+ print("************************************")
+ print("START TEST CASE {name}".format(name=test_name[num]))
+ print("************************************")
+ fail_count = func(*args, **kwargs)
+ print("************************************")
+ if not fail_count:
+ print("END TEST CASE {name} PASS".format(name=test_name[num]))
+ else:
+ print("END TEST CASE {name} FAIL".format(name=test_name[num]))
+ print("************************************")
+ return fail_count
+ return inner
+
+
+class TestCases(object):
+
+ def __init__(self, rpc_py, total_size, block_size, base_dir_path, app_path):
+ self.c = Commands_Rpc(rpc_py)
+ self.total_size = total_size
+ self.block_size = block_size
+ self.cluster_size = None
+ self.path = base_dir_path
+ self.app_path = app_path
+ self.lvs_name = "lvs_test"
+ self.lbd_name = "lbd_test"
+ self.vhost_config_path = path.join(path.dirname(sys.argv[0]), 'vhost.conf')
+
+ def _gen_lvs_uuid(self):
+ return str(uuid4())
+
+ def _gen_lvb_uuid(self):
+ return "_".join([str(uuid4()), str(random.randrange(9999999999))])
+
+ def compare_two_disks(self, disk1, disk2, expected_ret_value):
+ cmp_cmd = "cmp %s %s" % (disk1, disk2)
+ try:
+ process = subprocess.check_output(cmp_cmd, stderr=subprocess.STDOUT, shell=True)
+ rv = 0
+ except subprocess.CalledProcessError as ex:
+ rv = 1
+ except Exception as e:
+ print("ERROR: Cmp ended with unexpected exception.")
+ rv = 1
+
+ if expected_ret_value == rv:
+ return 0
+ elif rv == 0:
+ print("ERROR: Cmp ended with unexpected success")
+ else:
+ print("ERROR: Cmp ended with unexpected failure")
+
+ return 1
+
+ def run_fio_test(self, nbd_disk, offset, size, rw, pattern, expected_ret_value=0):
+ fio_cmd = get_fio_cmd(nbd_disk, offset, size, rw, pattern)
+ return run_fio(fio_cmd, expected_ret_value)
+
+ def _stop_vhost(self, pid_path):
+ with io.open(pid_path, 'r') as vhost_pid:
+ pid = int(vhost_pid.readline())
+ if pid:
+ try:
+ kill(pid, signal.SIGTERM)
+ for count in range(30):
+ sleep(1)
+ kill(pid, 0)
+ except OSError as err:
+ if err.errno == ESRCH:
+ pass
+ else:
+ return 1
+ else:
+ return 1
+ else:
+ return 1
+ return 0
+
+ def _start_vhost(self, vhost_path, pid_path):
+ subprocess.call("{app} -f "
+ "{pid} &".format(app=vhost_path,
+ pid=pid_path), shell=True)
+ for timeo in range(10):
+ if timeo == 9:
+ print("ERROR: Timeout on waiting for app start")
+ return 1
+ if not path.exists(pid_path):
+ print("Info: Waiting for PID file...")
+ sleep(1)
+ continue
+ else:
+ break
+
+ # Wait for RPC to open
+ sock = socket.socket(socket.AF_UNIX)
+ for timeo in range(30):
+ if timeo == 29:
+ print("ERROR: Timeout on waiting for RPC start")
+ return 1
+ try:
+ sock.connect("/var/tmp/spdk.sock")
+ break
+ except socket.error as e:
+ print("Info: Waiting for RPC Unix socket...")
+ sleep(1)
+ continue
+ else:
+ sock.close()
+ break
+
+ with io.open(pid_path, 'r') as vhost_pid:
+ pid = int(vhost_pid.readline())
+ if not pid:
+ return 1
+ return 0
+
+ def get_lvs_size(self, lvs_name="lvs_test"):
+ lvs = self.c.get_lvol_stores(lvs_name)[0]
+ return int(int(lvs['free_clusters'] * lvs['cluster_size']) / MEGABYTE)
+
+ def get_lvs_divided_size(self, split_num, lvs_name="lvs_test"):
+ # Actual size of lvol bdevs on creation is rounded up to multiple of cluster size.
+ # In order to avoid over provisioning, this function returns
+ # lvol store size in MB divided by split_num - rounded down to multiple of cluster size."
+ lvs = self.c.get_lvol_stores(lvs_name)[0]
+ return int(int(lvs['free_clusters'] / split_num) * lvs['cluster_size'] / MEGABYTE)
+
+ def get_lvs_cluster_size(self, lvs_name="lvs_test"):
+ lvs = self.c.get_lvol_stores(lvs_name)[0]
+ return int(int(lvs['cluster_size']) / MEGABYTE)
+
+ # positive tests
+ @case_message
+ def test_case1(self):
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ self.c.destroy_lvol_store(uuid_store)
+ self.c.delete_malloc_bdev(base_name)
+ if self.c.check_get_lvol_stores("", "", "") == 1:
+ fail_count += 1
+ return fail_count
+
+ @case_message
+ def test_case50(self):
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+
+ lvs_size = self.get_lvs_size()
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name,
+ lvs_size)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev,
+ lvs_size)
+ self.c.destroy_lvol_bdev(uuid_bdev)
+ self.c.destroy_lvol_store(uuid_store)
+ self.c.delete_malloc_bdev(base_name)
+ return fail_count
+
+ @case_message
+ def test_case51(self):
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ size = self.get_lvs_divided_size(4)
+
+ for j in range(2):
+ uuid_bdevs = []
+ for i in range(4):
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name + str(i),
+ size)
+ uuid_bdevs.append(uuid_bdev)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, size)
+
+ for uuid_bdev in uuid_bdevs:
+ self.c.destroy_lvol_bdev(uuid_bdev)
+
+ self.c.destroy_lvol_store(uuid_store)
+ self.c.delete_malloc_bdev(base_name)
+ return fail_count
+
+ @case_message
+ def test_case52(self):
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ lvs_size = self.get_lvs_size()
+ uuid_bdev = self.c.construct_lvol_bdev(self.lvs_name,
+ self.lbd_name,
+ lvs_size)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev,
+ lvs_size)
+
+ fail_count += self.c.destroy_lvol_bdev(uuid_bdev)
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+ fail_count += self.c.delete_malloc_bdev(base_name)
+ return fail_count
+
+ @case_message
+ def test_case53(self):
+ base_name_1 = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ base_name_2 = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+
+ uuid_store_1 = self.c.construct_lvol_store(base_name_1,
+ self.lvs_name + "1")
+ uuid_store_2 = self.c.construct_lvol_store(base_name_2,
+ self.lvs_name + "2")
+ fail_count = self.c.check_get_lvol_stores(base_name_1, uuid_store_1,
+ self.cluster_size)
+ fail_count = self.c.check_get_lvol_stores(base_name_2, uuid_store_2,
+ self.cluster_size)
+
+ lvs_size = self.get_lvs_size(self.lvs_name + "1")
+ uuid_bdev_1 = self.c.construct_lvol_bdev(uuid_store_1,
+ self.lbd_name,
+ lvs_size)
+ uuid_bdev_2 = self.c.construct_lvol_bdev(uuid_store_2,
+ self.lbd_name,
+ lvs_size)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev_1, lvs_size)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev_2, lvs_size)
+
+ fail_count += self.c.destroy_lvol_bdev(uuid_bdev_1)
+ fail_count += self.c.destroy_lvol_bdev(uuid_bdev_2)
+ fail_count += self.c.destroy_lvol_store(uuid_store_1)
+ fail_count += self.c.destroy_lvol_store(uuid_store_2)
+ fail_count += self.c.delete_malloc_bdev(base_name_1)
+ fail_count += self.c.delete_malloc_bdev(base_name_2)
+ return fail_count
+
+ @case_message
+ def test_case100(self):
+ fail_count = 0
+ if self.c.construct_lvol_bdev(self._gen_lvs_uuid(),
+ self.lbd_name,
+ 32) == 0:
+ fail_count += 1
+ return fail_count
+
+ @case_message
+ def test_case101(self):
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ lvs_size = self.get_lvs_size()
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name,
+ lvs_size)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev,
+ lvs_size)
+ if self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name + "_1",
+ lvs_size) == 0:
+ fail_count += 1
+
+ self.c.destroy_lvol_bdev(uuid_bdev)
+ self.c.destroy_lvol_store(uuid_store)
+ self.c.delete_malloc_bdev(base_name)
+ return fail_count
+
+ @case_message
+ def test_case102(self):
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ size = self.get_lvs_size()
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name,
+ size)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev,
+ size)
+ if self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name,
+ size) == 0:
+ fail_count += 1
+
+ self.c.destroy_lvol_bdev(uuid_bdev)
+ self.c.destroy_lvol_store(uuid_store)
+ self.c.delete_malloc_bdev(base_name)
+ return fail_count
+
+ @case_message
+ def test_case150(self):
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ # size is equal to one quarter of size malloc bdev
+
+ size = self.get_lvs_divided_size(4)
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store, self.lbd_name, size)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, size)
+
+ # size is equal to half of size malloc bdev
+ size = self.get_lvs_divided_size(2)
+ self.c.resize_lvol_bdev(uuid_bdev, size)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, size)
+
+ # size is smaller by 1 cluster
+ size = (self.get_lvs_size() - self.get_lvs_cluster_size())
+ self.c.resize_lvol_bdev(uuid_bdev, size)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, size)
+
+ # size is equal 0 MiB
+ size = 0
+ self.c.resize_lvol_bdev(uuid_bdev, size)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, size)
+
+ self.c.destroy_lvol_bdev(uuid_bdev)
+ self.c.destroy_lvol_store(uuid_store)
+ self.c.delete_malloc_bdev(base_name)
+ return fail_count
+
+ @case_message
+ def test_case200(self):
+ fail_count = 0
+ if self.c.resize_lvol_bdev(self._gen_lvb_uuid(), 16) == 0:
+ fail_count += 1
+ return fail_count
+
+ @case_message
+ def test_case201(self):
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ lvs_size = self.get_lvs_size()
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name,
+ lvs_size)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev,
+ lvs_size)
+ if self.c.resize_lvol_bdev(uuid_bdev, self.total_size + 1) == 0:
+ fail_count += 1
+
+ self.c.destroy_lvol_bdev(uuid_bdev)
+ self.c.destroy_lvol_store(uuid_store)
+ self.c.delete_malloc_bdev(base_name)
+ return fail_count
+
+ @case_message
+ def test_case250(self):
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ self.c.destroy_lvol_store(uuid_store)
+ if self.c.check_get_lvol_stores("", "", "") == 1:
+ fail_count += 1
+ self.c.delete_malloc_bdev(base_name)
+ return fail_count
+
+ @case_message
+ def test_case251(self):
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ fail_count += self.c.destroy_lvol_store(self.lvs_name)
+ if self.c.check_get_lvol_stores("", "", "") == 1:
+ fail_count += 1
+ fail_count += self.c.delete_malloc_bdev(base_name)
+ return fail_count
+
+ @case_message
+ def test_case252(self):
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ lvs_size = self.get_lvs_size()
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name,
+ lvs_size)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev,
+ lvs_size)
+ if self.c.destroy_lvol_store(uuid_store) != 0:
+ fail_count += 1
+
+ if self.c.check_get_lvol_stores("", "", "") == 1:
+ fail_count += 1
+ self.c.delete_malloc_bdev(base_name)
+ return fail_count
+
+ @case_message
+ def test_case253(self):
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ size = self.get_lvs_divided_size(4)
+
+ for i in range(4):
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name + str(i),
+ size)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, size)
+
+ self.c.destroy_lvol_store(uuid_store)
+ if self.c.check_get_lvol_stores("", "", "") == 1:
+ fail_count += 1
+ self.c.delete_malloc_bdev(base_name)
+ return fail_count
+
+ @case_message
+ def test_case254(self):
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ size = self.get_lvs_divided_size(4)
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name,
+ size)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, size)
+
+ sz = size + 4
+ self.c.resize_lvol_bdev(uuid_bdev, sz)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, sz)
+ sz = size * 2
+ self.c.resize_lvol_bdev(uuid_bdev, sz)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, sz)
+ sz = size * 3
+ self.c.resize_lvol_bdev(uuid_bdev, sz)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, sz)
+ sz = (size * 4) - 4
+ self.c.resize_lvol_bdev(uuid_bdev, sz)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, sz)
+ sz = 0
+ self.c.resize_lvol_bdev(uuid_bdev, sz)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, sz)
+
+ self.c.destroy_lvol_store(uuid_store)
+ if self.c.check_get_lvol_stores("", "", "") == 1:
+ fail_count += 1
+ self.c.delete_malloc_bdev(base_name)
+ return fail_count
+
+ @case_message
+ def test_case255(self):
+ base_path = path.dirname(sys.argv[0])
+ base_name = "aio_bdev0"
+ aio_bdev0 = path.join(base_path, "aio_bdev_0")
+ self.c.construct_aio_bdev(aio_bdev0, base_name, 4096)
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ if self.c.destroy_lvol_store(self.lvs_name) != 0:
+ fail_count += 1
+
+ self.c.delete_aio_bdev(base_name)
+ self.c.construct_aio_bdev(aio_bdev0, base_name, 4096)
+ # wait 1 second to allow time for lvolstore tasting
+ sleep(1)
+
+ ret_value = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ if ret_value == 0:
+ fail_count += 1
+ self.c.delete_aio_bdev(base_name)
+ return fail_count
+
+ @case_message
+ def test_case300(self):
+ fail_count = 0
+ if self.c.destroy_lvol_store(self._gen_lvs_uuid()) == 0:
+ fail_count += 1
+ return fail_count
+
+ @case_message
+ def test_case301(self):
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+
+ if self.c.delete_malloc_bdev(base_name) != 0:
+ fail_count += 1
+
+ if self.c.destroy_lvol_store(uuid_store) == 0:
+ fail_count += 1
+
+ return fail_count
+
+ def test_case350(self):
+ print("Test of this feature not yet implemented.")
+ pass
+ return 0
+
+ def test_case400(self):
+ print("Test of this feature not yet implemented.")
+ pass
+ return 0
+
+ # negative tests
+ @case_message
+ def test_case450(self):
+ fail_count = 0
+ bad_bdev_id = random.randrange(999999999)
+ if self.c.construct_lvol_store(bad_bdev_id,
+ self.lvs_name,
+ self.cluster_size) == 0:
+ fail_count += 1
+ return fail_count
+
+ @case_message
+ def test_case451(self):
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ if self.c.construct_lvol_store(base_name,
+ self.lvs_name) == 0:
+ fail_count += 1
+ self.c.destroy_lvol_store(uuid_store)
+ self.c.delete_malloc_bdev(base_name)
+ return fail_count
+
+ @case_message
+ def test_case452(self):
+ fail_count = 0
+ base_name_1 = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ base_name_2 = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ uuid_store_1 = self.c.construct_lvol_store(base_name_1,
+ self.lvs_name)
+ fail_count += self.c.check_get_lvol_stores(base_name_1,
+ uuid_store_1,
+ self.cluster_size)
+ if self.c.construct_lvol_store(base_name_2,
+ self.lvs_name) == 0:
+ fail_count += 1
+
+ fail_count += self.c.destroy_lvol_store(uuid_store_1)
+ fail_count += self.c.delete_malloc_bdev(base_name_1)
+ fail_count += self.c.delete_malloc_bdev(base_name_2)
+
+ return fail_count
+
+ def test_case500(self):
+ """
+ nested_construct_lvol_bdev_on_full_lvol_store
+
+ Negative test for constructing a new nested lvol bdev.
+ Call construct_lvol_bdev on a full lvol store.
+ """
+ # Steps:
+ # - create a malloc bdev
+ # - construct_lvol_store on created malloc bdev
+ # - check correct uuid values in response get_lvol_stores command
+ # - construct_lvol_bdev on correct lvs_uuid and size is
+ # equal to size malloc bdev
+ # - construct nested lvol store on previously created lvol_bdev
+ # - check correct uuid values in response get_lvol_stores command
+ # - construct nested lvol bdev on previously created nested lvol store
+ # and size is equal to size lvol store
+ # - try construct another lvol bdev as in previous step; this call should fail
+ # as nested lvol store space is already claimed by lvol bdev
+ # - delete nested lvol bdev
+ # - destroy nested lvol_store
+ # - delete base lvol bdev
+ # - delete base lvol store
+ # - delete malloc bdev
+ #
+ # Expected result:
+ # - second construct_lvol_bdev call on nested lvol store return code != 0
+ # - EEXIST response printed to stdout
+ # - no other operation fails
+ print("Test of this feature not yet implemented.")
+ pass
+ return 0
+
+ @case_message
+ def test_case550(self):
+ """
+ delete_bdev_positive
+
+ Positive test for deleting malloc bdev.
+ Call construct_lvol_store with correct base bdev name.
+ """
+ # Create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # Construct_lvol_store on correct, exisitng malloc bdev
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ # Check correct uuid values in response get_lvol_stores command
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ # Delete malloc bdev
+ self.c.delete_malloc_bdev(base_name)
+ # Check response get_lvol_stores command
+ if self.c.check_get_lvol_stores("", "", "") == 1:
+ fail_count += 1
+
+ # Expected result:
+ # - get_lvol_stores: response should be of no value after destroyed lvol store
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case551(self):
+ """
+ destroy_lvol_bdev_ordering
+
+ Test for destroying lvol bdevs in particular order.
+ Check destroying wrong one is not possible and returns error.
+ """
+
+ fail_count = 0
+ snapshot_name = "snapshot"
+ clone_name = "clone"
+
+ # Create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # Construct_lvol_store on correct, exisitng malloc bdev
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name,
+ self.cluster_size)
+ # Check correct uuid values in response get_lvol_stores command
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ lvs = self.c.get_lvol_stores()
+ size = int(int(lvs[0]['free_clusters'] * lvs[0]['cluster_size']) / 4 / MEGABYTE)
+
+ # Construct thin provisioned lvol bdev
+ uuid_bdev0 = self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name, size, thin=True)
+ lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev0)
+
+ # Create snapshot of thin provisioned lvol bdev
+ fail_count += self.c.snapshot_lvol_bdev(lvol_bdev['name'], snapshot_name)
+ snapshot_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name)
+
+ # Create clone of snapshot and check if it ends with success
+ fail_count += self.c.clone_lvol_bdev(self.lvs_name + "/" + snapshot_name, clone_name)
+ clone_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + clone_name)
+
+ # Try to destroy snapshot with clones and check if it fails
+ ret_value = self.c.destroy_lvol_bdev(snapshot_bdev['name'])
+ if ret_value == 0:
+ print("ERROR: Delete snapshot should fail but didn't")
+ fail_count += 1
+
+ # Destroy clone and then snapshot
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev['name'])
+ fail_count += self.c.destroy_lvol_bdev(clone_bdev['name'])
+ fail_count += self.c.destroy_lvol_bdev(snapshot_bdev['name'])
+
+ # Destroy lvol store
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+
+ # Check response get_lvol_stores command
+ if self.c.check_get_lvol_stores("", "", "") == 1:
+ fail_count += 1
+
+ # Delete malloc bdev
+ self.c.delete_malloc_bdev(base_name)
+ # Expected result:
+ # - get_lvol_stores: response should be of no value after destroyed lvol store
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case552(self):
+ """
+ destroy_lvol_store_with_clones
+
+ Test for destroying lvol store with clones present,
+ without removing them first.
+ """
+
+ fail_count = 0
+ snapshot_name = "snapshot"
+ snapshot_name2 = "snapshot2"
+ clone_name = "clone"
+
+ # Create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # Construct_lvol_store on correct, exisitng malloc bdev
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name,
+ self.cluster_size)
+ # Check correct uuid values in response get_lvol_stores command
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ lvs = self.c.get_lvol_stores()
+ size = int(int(lvs[0]['free_clusters'] * lvs[0]['cluster_size']) / 4 / MEGABYTE)
+
+ # Create lvol bdev, snapshot it, then clone it and then snapshot the clone
+ uuid_bdev0 = self.c.construct_lvol_bdev(uuid_store, self.lbd_name, size, thin=True)
+ lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev0)
+
+ fail_count += self.c.snapshot_lvol_bdev(lvol_bdev['name'], snapshot_name)
+ snapshot_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name)
+
+ fail_count += self.c.clone_lvol_bdev(self.lvs_name + "/" + snapshot_name, clone_name)
+ clone_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + clone_name)
+
+ fail_count += self.c.snapshot_lvol_bdev(clone_bdev['name'], snapshot_name2)
+ snapshot_bdev2 = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name2)
+
+ # Try to destroy snapshots with clones and check if it fails
+ ret_value = self.c.destroy_lvol_bdev(snapshot_bdev['name'])
+ if ret_value == 0:
+ print("ERROR: Delete snapshot should fail but didn't")
+ fail_count += 1
+ ret_value = self.c.destroy_lvol_bdev(snapshot_bdev2['name'])
+ if ret_value == 0:
+ print("ERROR: Delete snapshot should fail but didn't")
+ fail_count += 1
+
+ # Destroy lvol store without deleting lvol bdevs
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+
+ # Check response get_lvol_stores command
+ if self.c.check_get_lvol_stores("", "", "") == 1:
+ fail_count += 1
+
+ # Delete malloc bdev
+ self.c.delete_malloc_bdev(base_name)
+ # Expected result:
+ # - get_lvol_stores: response should be of no value after destroyed lvol store
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case553(self):
+ """
+ unregister_lvol_bdev
+
+ Test for unregistering the lvol bdevs.
+ Removing malloc bdev under an lvol store triggers unregister of
+ all lvol bdevs. Verify it with clones present.
+ """
+
+ fail_count = 0
+ snapshot_name = "snapshot"
+ snapshot_name2 = "snapshot2"
+ clone_name = "clone"
+
+ # Create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # Construct_lvol_store on correct, exisitng malloc bdev
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name,
+ self.cluster_size)
+ # Check correct uuid values in response get_lvol_stores command
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ lvs = self.c.get_lvol_stores()
+ size = int(int(lvs[0]['free_clusters'] * lvs[0]['cluster_size']) / 4 / MEGABYTE)
+
+ # Create lvol bdev, snapshot it, then clone it and then snapshot the clone
+ uuid_bdev0 = self.c.construct_lvol_bdev(uuid_store, self.lbd_name, size, thin=True)
+ lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev0)
+
+ fail_count += self.c.snapshot_lvol_bdev(lvol_bdev['name'], snapshot_name)
+ snapshot_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name)
+
+ fail_count += self.c.clone_lvol_bdev(self.lvs_name + "/" + snapshot_name, clone_name)
+ clone_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + clone_name)
+
+ fail_count += self.c.snapshot_lvol_bdev(clone_bdev['name'], snapshot_name2)
+ snapshot_bdev2 = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name2)
+
+ # Delete malloc bdev
+ self.c.delete_malloc_bdev(base_name)
+
+ # Check response get_lvol_stores command
+ if self.c.check_get_lvol_stores("", "", "") == 1:
+ fail_count += 1
+
+ # Expected result:
+ # - get_lvol_stores: response should be of no value after destroyed lvol store
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case600(self):
+ """
+ construct_lvol_store_with_cluster_size_max
+
+ Negative test for constructing a new lvol store.
+ Call construct_lvol_store with cluster size is equal malloc bdev size + 1B.
+ """
+ fail_count = 0
+ # Create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # Construct_lvol_store on correct, exisitng malloc bdev and cluster size equal
+ # malloc bdev size in bytes + 1B
+ lvol_uuid = self.c.construct_lvol_store(base_name,
+ self.lvs_name,
+ (self.total_size * 1024 * 1024) + 1) == 0
+ if self.c.check_get_lvol_stores(base_name, lvol_uuid) == 0:
+ fail_count += 1
+ fail_count += self.c.delete_malloc_bdev(base_name)
+
+ # Expected result:
+ # - return code != 0
+ # - Error code response printed to stdout
+ return fail_count
+
+ @case_message
+ def test_case601(self):
+ """
+ construct_lvol_store_with_cluster_size_min
+
+ Negative test for constructing a new lvol store.
+ Call construct_lvol_store with cluster size smaller than minimal value of 8192.
+ """
+ fail_count = 0
+ # Create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # Try construct lvol store on malloc bdev with cluster size 8191
+ lvol_uuid = self.c.construct_lvol_store(base_name, self.lvs_name, 8191)
+ # Verify that lvol store was not created
+ if self.c.check_get_lvol_stores(base_name, lvol_uuid) == 0:
+ fail_count += 1
+ fail_count += self.c.delete_malloc_bdev(base_name)
+
+ # Expected result:
+ # - construct lvol store return code != 0
+ # - Error code response printed to stdout
+ return fail_count
+
+ @case_message
+ def test_case650(self):
+ """
+ thin_provisioning_check_space
+
+ Check if free clusters number on lvol store decreases
+ if we write to created thin provisioned lvol bdev
+ """
+ # create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # create lvol store on mamloc bdev
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ lvs = self.c.get_lvol_stores(self.lvs_name)[0]
+ free_clusters_start = int(lvs['free_clusters'])
+ bdev_size = self.get_lvs_size()
+ # create thin provisioned lvol bdev with size equals to lvol store free space
+ bdev_name = self.c.construct_lvol_bdev(uuid_store, self.lbd_name,
+ bdev_size, thin=True)
+ lvs = self.c.get_lvol_stores(self.lvs_name)[0]
+ free_clusters_create_lvol = int(lvs['free_clusters'])
+ # check and save number of free clusters for lvol store
+ if free_clusters_start != free_clusters_create_lvol:
+ fail_count += 1
+ lvol_bdev = self.c.get_lvol_bdev_with_name(bdev_name)
+ nbd_name = "/dev/nbd0"
+ fail_count += self.c.start_nbd_disk(bdev_name, nbd_name)
+
+ size = int(lvs['cluster_size'])
+ # write data (lvs cluster size) to created lvol bdev starting from offset 0.
+ fail_count += self.run_fio_test("/dev/nbd0", 0, size, "write", "0xcc")
+ lvs = self.c.get_lvol_stores(self.lvs_name)[0]
+ free_clusters_first_fio = int(lvs['free_clusters'])
+ # check that free clusters on lvol store was decremented by 1
+ if free_clusters_start != free_clusters_first_fio + 1:
+ fail_count += 1
+
+ size = int(lvs['cluster_size'])
+ # calculate size of one and half cluster
+ offset = int((int(lvol_bdev['num_blocks']) * int(lvol_bdev['block_size']) /
+ free_clusters_create_lvol) * 1.5)
+ # write data (lvs cluster size) to lvol bdev with offset set to one and half of cluster size
+ fail_count += self.run_fio_test(nbd_name, offset, size, "write", "0xcc")
+ lvs = self.c.get_lvol_stores(self.lvs_name)[0]
+ free_clusters_second_fio = int(lvs['free_clusters'])
+ # check that free clusters on lvol store was decremented by 2
+ if free_clusters_start != free_clusters_second_fio + 3:
+ fail_count += 1
+
+ size = (free_clusters_create_lvol - 3) * int(lvs['cluster_size'])
+ offset = int(int(lvol_bdev['num_blocks']) * int(lvol_bdev['block_size']) /
+ free_clusters_create_lvol * 3)
+ # write data to lvol bdev to the end of its size
+ fail_count += self.run_fio_test(nbd_name, offset, size, "write", "0xcc")
+ lvs = self.c.get_lvol_stores(self.lvs_name)[0]
+ free_clusters_third_fio = int(lvs['free_clusters'])
+ # check that lvol store free clusters number equals to 0
+ if free_clusters_third_fio != 0:
+ fail_count += 1
+
+ fail_count += self.c.stop_nbd_disk(nbd_name)
+ # destroy thin provisioned lvol bdev
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev['name'])
+ lvs = self.c.get_lvol_stores(self.lvs_name)[0]
+ free_clusters_end = int(lvs['free_clusters'])
+ # check that saved number of free clusters equals to current free clusters
+ if free_clusters_start != free_clusters_end:
+ fail_count += 1
+ # destroy lvol store
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+ # destroy malloc bdev
+ fail_count += self.c.delete_malloc_bdev(base_name)
+ # Expected result:
+ # - calls successful, return code = 0
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case651(self):
+ """
+ thin_provisioning_read_empty_bdev
+
+ Check if we can create thin provisioned bdev on empty lvol store
+ and check if we can read from this device and it returns zeroes.
+ """
+ # create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # construct lvol store on malloc bdev
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ lvs = self.c.get_lvol_stores(self.lvs_name)[0]
+ free_clusters_start = int(lvs['free_clusters'])
+ lbd_name0 = self.lbd_name + str("0")
+ lbd_name1 = self.lbd_name + str("1")
+ # calculate bdev size in megabytes
+ bdev_size = self.get_lvs_size()
+ # create thick provisioned lvol bvdev with size equal to lvol store
+ bdev_name0 = self.c.construct_lvol_bdev(uuid_store, lbd_name0,
+ bdev_size, thin=False)
+ # create thin provisioned lvol bdev with the same size
+ bdev_name1 = self.c.construct_lvol_bdev(uuid_store, lbd_name1,
+ bdev_size, thin=True)
+ lvol_bdev0 = self.c.get_lvol_bdev_with_name(bdev_name0)
+ lvol_bdev1 = self.c.get_lvol_bdev_with_name(bdev_name1)
+ nbd_name0 = "/dev/nbd0"
+ fail_count += self.c.start_nbd_disk(lvol_bdev0['name'], nbd_name0)
+ nbd_name1 = "/dev/nbd1"
+ fail_count += self.c.start_nbd_disk(lvol_bdev1['name'], nbd_name1)
+
+ size = bdev_size * MEGABYTE
+ # fill the whole thick provisioned lvol bdev
+ fail_count += self.run_fio_test(nbd_name0, 0, size, "write", False)
+
+ size = bdev_size * MEGABYTE
+ # perform read operations on thin provisioned lvol bdev
+ # and check if they return zeroes
+ fail_count += self.run_fio_test(nbd_name1, 0, size, "read", "0x00")
+
+ fail_count += self.c.stop_nbd_disk(nbd_name0)
+ fail_count += self.c.stop_nbd_disk(nbd_name1)
+ # destroy thin provisioned lvol bdev
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev0['name'])
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev1['name'])
+ # destroy lvol store
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+ # destroy malloc bdev
+ fail_count += self.c.delete_malloc_bdev(base_name)
+ # Expected result:
+ # - calls successful, return code = 0
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case652(self):
+ """
+ thin_provisioning_data_integrity_test
+
+ Check if data written to thin provisioned lvol bdev
+ were properly written (fio test with verification).
+ """
+ # create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # construct lvol store on malloc bdev
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ lvs = self.c.get_lvol_stores(self.lvs_name)[0]
+ free_clusters_start = int(lvs['free_clusters'])
+ bdev_size = self.get_lvs_size()
+ # construct thin provisioned lvol bdev with size equal to lvol store
+ bdev_name = self.c.construct_lvol_bdev(uuid_store, self.lbd_name,
+ bdev_size, thin=True)
+
+ lvol_bdev = self.c.get_lvol_bdev_with_name(bdev_name)
+ nbd_name = "/dev/nbd0"
+ fail_count += self.c.start_nbd_disk(lvol_bdev['name'], nbd_name)
+ size = bdev_size * MEGABYTE
+ # on the whole lvol bdev perform write operation with verification
+ fail_count += self.run_fio_test(nbd_name, 0, size, "write", "0xcc")
+
+ fail_count += self.c.stop_nbd_disk(nbd_name)
+ # destroy thin provisioned lvol bdev
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev['name'])
+ # destroy lvol store
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+ # destroy malloc bdev
+ fail_count += self.c.delete_malloc_bdev(base_name)
+ # Expected result:
+ # - calls successful, return code = 0
+ # - verification ends with success
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case653(self):
+ """
+ thin_provisioning_resize
+
+ Check thin provisioned bdev resize. To be implemented.
+ """
+ # TODO
+ # create malloc bdev
+ # construct lvol store on malloc bdev
+ # construct thin provisioned lvol bdevs on created lvol store
+ # with size equal to 50% of lvol store
+ # fill all free space of lvol bdev with data
+ # save number of free clusters for lvs
+ # resize bdev to full size of lvs
+ # check if bdev size changed (total_data_clusters*cluster_size
+ # equal to num_blocks*block_size)
+ # check if free_clusters on lvs remain unaffected
+ # perform write operation with verification
+ # to newly created free space of lvol bdev
+ # resize bdev to 30M and check if it ended with success
+ # check if free clusters on lvs equals to saved counter
+ # destroy thin provisioned lvol bdev
+ # destroy lvol store
+ # destroy malloc bdev
+ fail_count = 0
+ # Expected result:
+ # - calls successful, return code = 0
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case654(self):
+ """
+ thin_overprovisioning
+
+ Create two thin provisioned lvol bdevs with max size
+ and check if writting more than total size of lvol store
+ will cause failures.
+ """
+ # create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # construct lvol store on malloc bdev
+ uuid_store = self.c.construct_lvol_store(base_name, self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ lvs = self.c.get_lvol_stores(self.lvs_name)[0]
+ free_clusters_start = int(lvs['free_clusters'])
+ lbd_name0 = self.lbd_name + str("0")
+ lbd_name1 = self.lbd_name + str("1")
+ bdev_size = self.get_lvs_size()
+ # construct two thin provisioned lvol bdevs on created lvol store
+ # with size equals to free lvs size
+ bdev_name0 = self.c.construct_lvol_bdev(uuid_store, lbd_name0,
+ bdev_size, thin=True)
+ bdev_name1 = self.c.construct_lvol_bdev(uuid_store, lbd_name1,
+ bdev_size, thin=True)
+
+ lvs = self.c.get_lvol_stores(self.lvs_name)[0]
+ free_clusters_create_lvol = int(lvs['free_clusters'])
+ if free_clusters_start != free_clusters_create_lvol:
+ fail_count += 1
+ lvol_bdev0 = self.c.get_lvol_bdev_with_name(bdev_name0)
+ lvol_bdev1 = self.c.get_lvol_bdev_with_name(bdev_name1)
+
+ nbd_name0 = "/dev/nbd0"
+ nbd_name1 = "/dev/nbd1"
+ fail_count += self.c.start_nbd_disk(lvol_bdev0['name'], nbd_name0)
+ fail_count += self.c.start_nbd_disk(lvol_bdev1['name'], nbd_name1)
+
+ size = "75%"
+ # fill first bdev to 75% of its space with specific pattern
+ fail_count += self.run_fio_test(nbd_name0, 0, size, "write", "0xcc")
+
+ size = "75%"
+ # fill second bdev up to 75% of its space
+ # check that error message occured while filling second bdev with data
+ fail_count += self.run_fio_test(nbd_name1, 0, size, "write", "0xee",
+ expected_ret_value=1)
+
+ size = "75%"
+ # check if data on first disk stayed unchanged
+ fail_count += self.run_fio_test(nbd_name0, 0, size, "read", "0xcc")
+
+ size = "25%"
+ offset = "75%"
+ fail_count += self.run_fio_test(nbd_name0, offset, size, "read", "0x00")
+
+ fail_count += self.c.stop_nbd_disk(nbd_name0)
+ fail_count += self.c.stop_nbd_disk(nbd_name1)
+ # destroy thin provisioned lvol bdev
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev0['name'])
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev1['name'])
+ # destroy lvol store
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+ # destroy malloc bdev
+ fail_count += self.c.delete_malloc_bdev(base_name)
+ # Expected result:
+ # - calls successful, return code = 0
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case655(self):
+ """
+ thin_provisioning_filling_disks_less_than_lvs_size
+
+ Check if writing to two thin provisioned lvol bdevs
+ less than total size of lvol store will end with success
+ """
+ # create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # construct lvol store on malloc bdev
+ uuid_store = self.c.construct_lvol_store(base_name, self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ lvs = self.c.get_lvol_stores(self.lvs_name)[0]
+ free_clusters_start = int(lvs['free_clusters'])
+ lbd_name0 = self.lbd_name + str("0")
+ lbd_name1 = self.lbd_name + str("1")
+ lvs_size = self.get_lvs_size()
+ bdev_size = int(lvs_size * 0.7)
+ # construct two thin provisioned lvol bdevs on created lvol store
+ # with size equal to 70% of lvs size
+ bdev_name0 = self.c.construct_lvol_bdev(uuid_store, lbd_name0,
+ bdev_size, thin=True)
+ bdev_name1 = self.c.construct_lvol_bdev(uuid_store, lbd_name1,
+ bdev_size, thin=True)
+
+ lvol_bdev0 = self.c.get_lvol_bdev_with_name(bdev_name0)
+ lvol_bdev1 = self.c.get_lvol_bdev_with_name(bdev_name1)
+ # check if bdevs are available and size of every disk is equal to 70% of lvs size
+ nbd_name0 = "/dev/nbd0"
+ nbd_name1 = "/dev/nbd1"
+ fail_count += self.c.start_nbd_disk(lvol_bdev0['name'], nbd_name0)
+ fail_count += self.c.start_nbd_disk(lvol_bdev1['name'], nbd_name1)
+ size = int(int(lvol_bdev0['num_blocks']) * int(lvol_bdev0['block_size']) * 0.7)
+ # fill first disk with 70% of its size
+ # check if operation didn't fail
+ fail_count += self.run_fio_test(nbd_name0, 0, size, "write", "0xcc")
+ size = int(int(lvol_bdev1['num_blocks']) * int(lvol_bdev1['block_size']) * 0.7)
+ # fill second disk also with 70% of its size
+ # check if operation didn't fail
+ fail_count += self.run_fio_test(nbd_name1, 0, size, "write", "0xee")
+
+ fail_count += self.c.stop_nbd_disk(nbd_name0)
+ fail_count += self.c.stop_nbd_disk(nbd_name1)
+ # destroy thin provisioned lvol bdevs
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev0['name'])
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev1['name'])
+ # destroy lvol store
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+ # destroy malloc bdev
+ fail_count += self.c.delete_malloc_bdev(base_name)
+ # Expected result:
+ # - calls successful, return code = 0
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case700(self):
+ """
+ tasting_positive
+
+ Positive test for tasting a multi lvol bdev configuration.
+ Create a lvol store with some lvol bdevs on aio bdev and restart vhost app.
+ After restarting configuration should be automatically loaded and should be exactly
+ the same as before restarting.
+ Check that running configuration can be modified after restarting and tasting.
+ """
+ fail_count = 0
+ uuid_bdevs = []
+ base_name = "aio_bdev0"
+
+ base_path = path.dirname(sys.argv[0])
+ vhost_path = path.join(self.app_path, 'vhost')
+ pid_path = path.join(base_path, 'vhost.pid')
+ aio_bdev0 = path.join(base_path, 'aio_bdev_0')
+
+ self.c.construct_aio_bdev(aio_bdev0, base_name, 4096)
+ # Create initial configuration on running vhost instance
+ # create lvol store, create 5 bdevs
+ # save info of all lvs and lvol bdevs
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count += self.c.check_get_lvol_stores(base_name,
+ uuid_store,
+ self.cluster_size)
+
+ size = self.get_lvs_divided_size(10)
+
+ for i in range(5):
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name + str(i),
+ size)
+ uuid_bdevs.append(uuid_bdev)
+ # Using get_bdevs command verify lvol bdevs were correctly created
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, size)
+
+ old_bdevs = sorted(self.c.get_lvol_bdevs(), key=lambda x: x["name"])
+ old_stores = self.c.get_lvol_stores()
+
+ # Shut down vhost instance and restart with new instance
+ fail_count += self._stop_vhost(pid_path)
+ remove(pid_path)
+ if self._start_vhost(vhost_path, pid_path) != 0:
+ fail_count += 1
+ return fail_count
+
+ self.c.construct_aio_bdev(aio_bdev0, base_name, 4096)
+ # Check if configuration was properly loaded after tasting
+ # get all info all lvs and lvol bdevs, compare with previous info
+ new_bdevs = sorted(self.c.get_lvol_bdevs(), key=lambda x: x["name"])
+ new_stores = self.c.get_lvol_stores()
+
+ if old_stores != new_stores:
+ fail_count += 1
+ print("ERROR: old and loaded lvol store is not the same")
+ print("DIFF:")
+ print(old_stores)
+ print(new_stores)
+
+ if len(old_bdevs) != len(new_bdevs):
+ fail_count += 1
+ print("ERROR: old and loaded lvol bdev list count is not equal")
+
+ for o, n in zip(old_bdevs, new_bdevs):
+ if o != n:
+ fail_count += 1
+ print("ERROR: old and loaded lvol bdev is not the same")
+ print("DIFF:")
+ pprint.pprint([o, n])
+
+ if fail_count != 0:
+ self.c.delete_aio_bdev(aio_bdev0)
+ return fail_count
+
+ # Try modifying loaded configuration
+ # Add some lvol bdevs to existing lvol store then
+ # remove all lvol configuration and re-create it again
+ for i in range(5, 10):
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name + str(i),
+ size)
+ uuid_bdevs.append(uuid_bdev)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, size)
+
+ for uuid_bdev in uuid_bdevs:
+ self.c.destroy_lvol_bdev(uuid_bdev)
+
+ if self.c.destroy_lvol_store(uuid_store) != 0:
+ fail_count += 1
+
+ uuid_bdevs = []
+
+ # Create lvol store on aio bdev, create ten lvol bdevs on lvol store and
+ # verify all configuration call results
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count += self.c.check_get_lvol_stores(base_name,
+ uuid_store,
+ self.cluster_size)
+
+ for i in range(10):
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name + str(i),
+ size)
+ uuid_bdevs.append(uuid_bdev)
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, size)
+
+ # Destroy lvol store
+ if self.c.destroy_lvol_store(uuid_store) != 0:
+ fail_count += 1
+
+ self.c.delete_aio_bdev(base_name)
+
+ return fail_count
+
+ @case_message
+ def test_case701(self):
+ """
+ tasting_lvol_store_positive
+
+ Positive test for tasting lvol store.
+ """
+ base_path = path.dirname(sys.argv[0])
+ aio_bdev0 = path.join(base_path, 'aio_bdev_0')
+ base_name = "aio_bdev0"
+
+ self.c.construct_aio_bdev(aio_bdev0, base_name, 4096)
+ # construct lvol store on aio bdev
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+
+ self.c.delete_aio_bdev(base_name)
+ self.c.construct_aio_bdev(aio_bdev0, base_name, 4096)
+ # wait 1 second to allow time for lvolstore tasting
+ sleep(1)
+ # check if lvol store still exists in vhost configuration
+ if self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size) != 0:
+ fail_count += 1
+ # destroy lvol store from aio bdev
+ if self.c.destroy_lvol_store(uuid_store) != 0:
+ fail_count += 1
+
+ self.c.delete_aio_bdev(base_name)
+ return fail_count
+
+ @case_message
+ def test_case702(self):
+ """
+ tasting_positive_with_different_lvol_store_cluster_size
+
+ Positive test for tasting a multi lvol bdev configuration.
+ Create two lvol stores with different cluster sizes with some lvol bdevs on aio
+ drive and restart vhost app.
+ After restarting configuration should be automatically loaded and should be exactly
+ the same as before restarting.
+ """
+ fail_count = 0
+ uuid_bdevs = []
+ cluster_size_1M = MEGABYTE
+ cluster_size_32M = 32 * MEGABYTE
+ base_name_1M = "aio_bdev0"
+ base_name_32M = "aio_bdev1"
+
+ base_path = path.dirname(sys.argv[0])
+ vhost_path = path.join(self.app_path, 'vhost')
+ pid_path = path.join(base_path, 'vhost.pid')
+ aio_bdev0 = path.join(base_path, 'aio_bdev_0')
+ aio_bdev1 = path.join(base_path, 'aio_bdev_1')
+
+ self.c.construct_aio_bdev(aio_bdev0, base_name_1M, 4096)
+ self.c.construct_aio_bdev(aio_bdev1, base_name_32M, 4096)
+
+ # Create initial configuration on running vhost instance
+ # create lvol store, create 5 bdevs
+ # save info of all lvs and lvol bdevs
+ uuid_store_1M = self.c.construct_lvol_store(base_name_1M,
+ self.lvs_name + "_1M",
+ cluster_size_1M)
+
+ fail_count += self.c.check_get_lvol_stores(base_name_1M,
+ uuid_store_1M,
+ cluster_size_1M)
+
+ uuid_store_32M = self.c.construct_lvol_store(base_name_32M,
+ self.lvs_name + "_32M",
+ cluster_size_32M)
+
+ fail_count += self.c.check_get_lvol_stores(base_name_32M,
+ uuid_store_32M,
+ cluster_size_32M)
+
+ # size = approx 20% of total aio bdev size
+ size_1M = self.get_lvs_divided_size(5, self.lvs_name + "_1M")
+ size_32M = self.get_lvs_divided_size(5, self.lvs_name + "_32M")
+
+ for i in range(5):
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store_1M,
+ self.lbd_name + str(i) + "_1M",
+ size_1M)
+ uuid_bdevs.append(uuid_bdev)
+ # Using get_bdevs command verify lvol bdevs were correctly created
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, size_1M)
+
+ for i in range(5):
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store_32M,
+ self.lbd_name + str(i) + "_32M",
+ size_32M)
+ uuid_bdevs.append(uuid_bdev)
+ # Using get_bdevs command verify lvol bdevs were correctly created
+ fail_count += self.c.check_get_bdevs_methods(uuid_bdev, size_32M)
+
+ old_bdevs = sorted(self.c.get_lvol_bdevs(), key=lambda x: x["name"])
+ old_stores = sorted(self.c.get_lvol_stores(), key=lambda x: x["name"])
+
+ # Shut down vhost instance and restart with new instance
+ fail_count += self._stop_vhost(pid_path)
+ remove(pid_path)
+ if self._start_vhost(vhost_path, pid_path) != 0:
+ fail_count += 1
+ return fail_count
+
+ self.c.construct_aio_bdev(aio_bdev0, base_name_1M, 4096)
+ self.c.construct_aio_bdev(aio_bdev1, base_name_32M, 4096)
+
+ # Check if configuration was properly loaded after tasting
+ # get all info all lvs and lvol bdevs, compare with previous info
+ new_bdevs = sorted(self.c.get_lvol_bdevs(), key=lambda x: x["name"])
+ new_stores = sorted(self.c.get_lvol_stores(), key=lambda x: x["name"])
+
+ if old_stores != new_stores:
+ fail_count += 1
+ print("ERROR: old and loaded lvol store is not the same")
+ print("DIFF:")
+ print(old_stores)
+ print(new_stores)
+
+ if len(old_bdevs) != len(new_bdevs):
+ fail_count += 1
+ print("ERROR: old and loaded lvol bdev list count is not equal")
+
+ for o, n in zip(old_bdevs, new_bdevs):
+ if o != n:
+ fail_count += 1
+ print("ERROR: old and loaded lvol bdev is not the same")
+ print("DIFF:")
+ pprint.pprint([o, n])
+
+ if fail_count != 0:
+ self.c.delete_aio_bdev(base_name_1M)
+ self.c.delete_aio_bdev(base_name_32M)
+ return fail_count
+
+ for uuid_bdev in uuid_bdevs:
+ self.c.destroy_lvol_bdev(uuid_bdev)
+
+ if self.c.destroy_lvol_store(uuid_store_1M) != 0:
+ fail_count += 1
+
+ if self.c.destroy_lvol_store(uuid_store_32M) != 0:
+ fail_count += 1
+
+ self.c.delete_aio_bdev(base_name_1M)
+ self.c.delete_aio_bdev(base_name_32M)
+
+ return fail_count
+
+ @case_message
+ def test_case750(self):
+ """
+ snapshot readonly
+
+ Create snaphot of lvol bdev and check if it is readonly.
+ """
+ fail_count = 0
+ nbd_name0 = "/dev/nbd0"
+ snapshot_name = "snapshot0"
+ # Construct malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # Construct lvol store on malloc bdev
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count += self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+
+ lvs = self.c.get_lvol_stores()[0]
+ free_clusters_start = int(lvs['free_clusters'])
+ bdev_size = self.get_lvs_divided_size(3)
+ # Create lvol bdev with 33% of lvol store space
+ bdev_name = self.c.construct_lvol_bdev(uuid_store, self.lbd_name,
+ bdev_size)
+ lvol_bdev = self.c.get_lvol_bdev_with_name(bdev_name)
+ # Create snapshot of lvol bdev
+ fail_count += self.c.snapshot_lvol_bdev(lvol_bdev['name'], snapshot_name)
+ snapshot_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name)
+
+ fail_count += self.c.start_nbd_disk(snapshot_bdev['name'], nbd_name0)
+ size = bdev_size * MEGABYTE
+ # Try to perform write operation on created snapshot
+ # Check if filling snapshot of lvol bdev fails
+ fail_count += self.run_fio_test(nbd_name0, 0, size, "write", "0xcc", 1)
+
+ fail_count += self.c.stop_nbd_disk(nbd_name0)
+ # Destroy lvol bdev
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev['name'])
+ # Destroy snapshot
+ fail_count += self.c.destroy_lvol_bdev(snapshot_bdev['name'])
+ # Destroy lvol store
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+ # Delete malloc bdev
+ fail_count += self.c.delete_malloc_bdev(base_name)
+
+ # Expected result:
+ # - calls successful, return code = 0
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case751(self):
+ """
+ snapshot_compare_with_lvol_bdev
+
+ Check if lvol bdevs and snapshots contain the same data.
+ Check if lvol bdev and snapshot differ when writing to lvol bdev
+ after creating snapshot.
+ """
+ fail_count = 0
+ nbd_name = ["/dev/nbd0", "/dev/nbd1", "/dev/nbd2", "/dev/nbd3"]
+ snapshot_name0 = "snapshot0"
+ snapshot_name1 = "snapshot1"
+ # Construct mallov bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # Construct lvol store
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count += self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ size = self.get_lvs_divided_size(6)
+ lbd_name0 = self.lbd_name + str(0)
+ lbd_name1 = self.lbd_name + str(1)
+ # Create thin provisioned lvol bdev with size less than 25% of lvs
+ uuid_bdev0 = self.c.construct_lvol_bdev(uuid_store,
+ lbd_name0, size, thin=True)
+ # Create thick provisioned lvol bdev with size less than 25% of lvs
+ uuid_bdev1 = self.c.construct_lvol_bdev(uuid_store,
+ lbd_name1, size, thin=False)
+ lvol_bdev0 = self.c.get_lvol_bdev_with_name(uuid_bdev0)
+ fail_count += self.c.start_nbd_disk(lvol_bdev0['name'], nbd_name[0])
+ fill_size = int(size * MEGABYTE / 2)
+ # Fill thin provisoned lvol bdev with 50% of its space
+ fail_count += self.run_fio_test(nbd_name[0], 0, fill_size, "write", "0xcc", 0)
+ lvol_bdev1 = self.c.get_lvol_bdev_with_name(uuid_bdev1)
+ fail_count += self.c.start_nbd_disk(lvol_bdev1['name'], nbd_name[1])
+ fill_size = int(size * MEGABYTE)
+ # Fill whole thic provisioned lvol bdev
+ fail_count += self.run_fio_test(nbd_name[1], 0, fill_size, "write", "0xcc", 0)
+
+ # Create snapshots of lvol bdevs
+ fail_count += self.c.snapshot_lvol_bdev(uuid_bdev0, snapshot_name0)
+ fail_count += self.c.snapshot_lvol_bdev(uuid_bdev1, snapshot_name1)
+ fail_count += self.c.start_nbd_disk(self.lvs_name + "/" + snapshot_name0, nbd_name[2])
+ fail_count += self.c.start_nbd_disk(self.lvs_name + "/" + snapshot_name1, nbd_name[3])
+ # Compare every lvol bdev with corresponding snapshot
+ # and check that data are the same
+ fail_count += self.compare_two_disks(nbd_name[0], nbd_name[2], 0)
+ fail_count += self.compare_two_disks(nbd_name[1], nbd_name[3], 0)
+
+ fill_size = int(size * MEGABYTE / 2)
+ offset = fill_size
+ # Fill second half of thin provisioned lvol bdev
+ fail_count += self.run_fio_test(nbd_name[0], offset, fill_size, "write", "0xaa", 0)
+ # Compare thin provisioned lvol bdev with its snapshot and check if it fails
+ fail_count += self.compare_two_disks(nbd_name[0], nbd_name[2], 1)
+ for nbd in nbd_name:
+ fail_count += self.c.stop_nbd_disk(nbd)
+ # Delete lvol bdevs
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev0['name'])
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev1['name'])
+ # Delete snapshots
+ fail_count += self.c.destroy_lvol_bdev(self.lvs_name + "/" + snapshot_name0)
+ fail_count += self.c.destroy_lvol_bdev(self.lvs_name + "/" + snapshot_name1)
+ # Destroy snapshot
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+ # Delete malloc bdev
+ fail_count += self.c.delete_malloc_bdev(base_name)
+
+ # Expected result:
+ # - calls successful, return code = 0
+ # - removing snapshot should always end with success
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case752(self):
+ """
+ snapshot_during_io_traffic
+
+ Check that when writing to lvol bdev
+ creating snapshot ends with success
+ """
+ global current_fio_pid
+ fail_count = 0
+ nbd_name = "/dev/nbd0"
+ snapshot_name = "snapshot"
+ # Create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # Construct lvol store
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count += self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ # Create thin provisioned lvol bdev with size equal to 50% of lvs space
+ size = self.get_lvs_divided_size(2)
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store, self.lbd_name,
+ size, thin=True)
+
+ lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev)
+ fail_count += self.c.start_nbd_disk(lvol_bdev['name'], nbd_name)
+ fill_size = int(size * MEGABYTE)
+ # Create thread that will run fio in background
+ thread = FioThread(nbd_name, 0, fill_size, "write", "0xcc", 0,
+ extra_params="--time_based --runtime=8")
+ # Perform write operation with verification to created lvol bdev
+ thread.start()
+ time.sleep(4)
+ fail_count += is_process_alive(current_fio_pid)
+ # During write operation create snapshot of created lvol bdev
+ # and check that snapshot has been created successfully
+ fail_count += self.c.snapshot_lvol_bdev(lvol_bdev['name'], snapshot_name)
+ fail_count += is_process_alive(current_fio_pid)
+ thread.join()
+ # Check that write operation ended with success
+ fail_count += thread.rv
+ fail_count += self.c.stop_nbd_disk(nbd_name)
+ # Destroy lvol bdev
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev['name'])
+ # Delete snapshot
+ fail_count += self.c.destroy_lvol_bdev(self.lvs_name + "/" + snapshot_name)
+ # Destroy lvol store
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+ # Delete malloc bdevs
+ fail_count += self.c.delete_malloc_bdev(base_name)
+
+ # Expected result:
+ # - calls successful, return code = 0
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case753(self):
+ """
+ snapshot_of_snapshot
+
+ Check that creating snapshot of snapshot will fail
+ """
+ fail_count = 0
+ snapshot_name0 = "snapshot0"
+ snapshot_name1 = "snapshot1"
+ # Create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # Construct lvol store
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count += self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ # Create thick provisioned lvol bdev
+ size = self.get_lvs_divided_size(2)
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store, self.lbd_name,
+ size, thin=False)
+
+ lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev)
+ # Create snapshot of created lvol bdev
+ fail_count += self.c.snapshot_lvol_bdev(lvol_bdev['name'], snapshot_name0)
+ # Create snapshot of previously created snapshot
+ # and check if operation will fail
+ if self.c.snapshot_lvol_bdev(snapshot_name0, snapshot_name1) == 0:
+ print("ERROR: Creating snapshot of snapshot should fail")
+ fail_count += 1
+ # Delete lvol bdev
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev['name'])
+ # Destroy snapshot
+ fail_count += self.c.destroy_lvol_bdev(self.lvs_name + "/" + snapshot_name0)
+ # Destroy lvol store
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+ # Delete malloc bdev
+ fail_count += self.c.delete_malloc_bdev(base_name)
+
+ # Expected result:
+ # - calls successful, return code = 0
+ # - creating snapshot of snapshot should fail
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case754(self):
+ """
+ clone_bdev_only
+
+ Check that only clone of snapshot can be created.
+ Creating clone of lvol bdev should fail.
+ """
+ fail_count = 0
+ clone_name = "clone"
+ snapshot_name = "snapshot"
+ # Create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # Construct lvol store
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count += self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ lvs = self.c.get_lvol_stores()
+ # Create thick provisioned lvol bdev with size equal to 50% of lvs space
+ size = self.get_lvs_divided_size(2)
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store, self.lbd_name,
+ size, thin=False)
+
+ lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev)
+ # Create clone of lvol bdev and check if it fails
+ rv = self.c.clone_lvol_bdev(lvol_bdev['name'], clone_name)
+ if rv == 0:
+ print("ERROR: Creating clone of lvol bdev ended with unexpected success")
+ fail_count += 1
+ # Create snapshot of lvol bdev
+ fail_count += self.c.snapshot_lvol_bdev(lvol_bdev['name'], snapshot_name)
+ # Create again clone of lvol bdev and check if it fails
+ rv = self.c.clone_lvol_bdev(lvol_bdev['name'], clone_name)
+ if rv == 0:
+ print("ERROR: Creating clone of lvol bdev ended with unexpected success")
+ fail_count += 1
+ # Create clone of snapshot and check if it ends with success
+ rv = self.c.clone_lvol_bdev(self.lvs_name + "/" + snapshot_name, clone_name)
+ if rv != 0:
+ print("ERROR: Creating clone of snapshot ended with unexpected failure")
+ fail_count += 1
+ clone_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + clone_name)
+
+ # Delete lvol bdev
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev['name'])
+ # Destroy clone
+ fail_count += self.c.destroy_lvol_bdev(clone_bdev['name'])
+ # Delete snapshot
+ fail_count += self.c.destroy_lvol_bdev(self.lvs_name + "/" + snapshot_name)
+ # Delete lvol store
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+ # Destroy malloc bdev
+ fail_count += self.c.delete_malloc_bdev(base_name)
+
+ # Expected result:
+ # - calls successful, return code = 0
+ # - cloning thick provisioned lvol bdev should fail
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case755(self):
+ """
+ clone_writing_to_clone
+
+
+ """
+ fail_count = 0
+ nbd_name = ["/dev/nbd0", "/dev/nbd1", "/dev/nbd2", "/dev/nbd3"]
+ snapshot_name = "snapshot"
+ clone_name0 = "clone0"
+ clone_name1 = "clone1"
+ # Create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # Create lvol store
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count += self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ size = self.get_lvs_divided_size(6)
+ lbd_name0 = self.lbd_name + str(0)
+ # Construct thick provisioned lvol bdev
+ uuid_bdev0 = self.c.construct_lvol_bdev(uuid_store,
+ lbd_name0, size, thin=False)
+ lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev0)
+ # Install lvol bdev on /dev/nbd0
+ fail_count += self.c.start_nbd_disk(lvol_bdev['name'], nbd_name[0])
+ fill_size = size * MEGABYTE
+ # Fill lvol bdev with 100% of its space
+ fail_count += self.run_fio_test(nbd_name[0], 0, fill_size, "write", "0xcc", 0)
+
+ # Create snapshot of thick provisioned lvol bdev
+ fail_count += self.c.snapshot_lvol_bdev(lvol_bdev['name'], snapshot_name)
+ snapshot_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name)
+ # Create two clones of created snapshot
+ fail_count += self.c.clone_lvol_bdev(snapshot_bdev['name'], clone_name0)
+ fail_count += self.c.clone_lvol_bdev(snapshot_bdev['name'], clone_name1)
+
+ lvol_clone0 = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + clone_name0)
+ fail_count += self.c.start_nbd_disk(lvol_clone0['name'], nbd_name[1])
+ fill_size = int(size * MEGABYTE / 2)
+ # Perform write operation to first clone
+ # Change first half of its space
+ fail_count += self.run_fio_test(nbd_name[1], 0, fill_size, "write", "0xaa", 0)
+ fail_count += self.c.start_nbd_disk(self.lvs_name + "/" + snapshot_name, nbd_name[2])
+ lvol_clone1 = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + clone_name1)
+ fail_count += self.c.start_nbd_disk(lvol_clone1['name'], nbd_name[3])
+ # Compare snapshot with second clone. Data on both bdevs should be the same
+ time.sleep(1)
+ fail_count += self.compare_two_disks(nbd_name[2], nbd_name[3], 0)
+
+ for nbd in nbd_name:
+ fail_count += self.c.stop_nbd_disk(nbd)
+ # Destroy lvol bdev
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev['name'])
+ # Destroy two clones
+ fail_count += self.c.destroy_lvol_bdev(lvol_clone0['name'])
+ fail_count += self.c.destroy_lvol_bdev(lvol_clone1['name'])
+ # Delete snapshot
+ fail_count += self.c.destroy_lvol_bdev(snapshot_bdev['name'])
+ # Destroy lvol store
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+ # Delete malloc
+ fail_count += self.c.delete_malloc_bdev(base_name)
+
+ # Expected result:
+ # - calls successful, return code = 0
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case756(self):
+ """
+ clone_and_snapshot_relations
+
+ Check if relations between clones and snapshots
+ are properly set in configuration
+ """
+ fail_count = 0
+ snapshot_name = 'snapshot'
+ clone_name0 = 'clone1'
+ clone_name1 = 'clone2'
+ lbd_name = clone_name1
+
+ # Create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ # Create lvol store
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count += self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ size = self.get_lvs_divided_size(6)
+
+ # Construct thick provisioned lvol bdev
+ uuid_bdev = self.c.construct_lvol_bdev(uuid_store,
+ lbd_name, size, thin=False)
+ lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev)
+
+ # Create snapshot of thick provisioned lvol bdev
+ fail_count += self.c.snapshot_lvol_bdev(lvol_bdev['name'], snapshot_name)
+ snapshot_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name)
+
+ # Create clone of created snapshot
+ fail_count += self.c.clone_lvol_bdev(snapshot_bdev['name'], clone_name0)
+
+ # Get current bdevs configuration
+ snapshot_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name)
+ lvol_clone0 = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + clone_name0)
+ lvol_clone1 = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + clone_name1)
+
+ # Check snapshot consistency
+ snapshot_lvol = snapshot_bdev['driver_specific']['lvol']
+ if snapshot_lvol['snapshot'] is not True:
+ fail_count += 1
+ if snapshot_lvol['clone'] is not False:
+ fail_count += 1
+ if sorted([clone_name0, clone_name1]) != sorted(snapshot_lvol['clones']):
+ fail_count += 1
+
+ # Check first clone consistency
+ lvol_clone0_lvol = lvol_clone0['driver_specific']['lvol']
+ if lvol_clone0_lvol['snapshot'] is not False:
+ fail_count += 1
+ if lvol_clone0_lvol['clone'] is not True:
+ fail_count += 1
+ if lvol_clone0_lvol['base_snapshot'] != 'snapshot':
+ fail_count += 1
+
+ # Check second clone consistency
+ lvol_clone1_lvol = lvol_clone1['driver_specific']['lvol']
+ if lvol_clone1_lvol['snapshot'] is not False:
+ fail_count += 1
+ if lvol_clone1_lvol['clone'] is not True:
+ fail_count += 1
+ if lvol_clone1_lvol['base_snapshot'] != 'snapshot':
+ fail_count += 1
+
+ # Destroy first clone and check if it is deleted from snapshot
+ fail_count += self.c.destroy_lvol_bdev(lvol_clone0['name'])
+ snapshot_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name)
+ if [clone_name1] != snapshot_bdev['driver_specific']['lvol']['clones']:
+ fail_count += 1
+
+ # Destroy second clone
+ fail_count += self.c.destroy_lvol_bdev(lvol_clone1['name'])
+
+ # Delete snapshot
+ fail_count += self.c.destroy_lvol_bdev(snapshot_bdev['name'])
+
+ # Destroy lvol store
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+
+ # Delete malloc
+ fail_count += self.c.delete_malloc_bdev(base_name)
+
+ # Expected result:
+ # - calls successful, return code = 0
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case757(self):
+ """
+ clone_inflate
+
+
+ Test inflate rpc method
+ """
+ fail_count = 0
+ snapshot_name = "snapshot"
+ nbd_name = "/dev/nbd0"
+
+ # Create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+
+ # Create lvol store
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count += self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ size = self.get_lvs_divided_size(4)
+
+ # Construct thick provisioned lvol bdev
+ uuid_bdev0 = self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name, size, thin=False)
+ lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev0)
+
+ # Fill bdev with data of knonw pattern
+ fail_count += self.c.start_nbd_disk(lvol_bdev['name'], nbd_name)
+ fill_size = size * MEGABYTE
+ fail_count += self.run_fio_test(nbd_name, 0, fill_size, "write", "0xcc", 0)
+ self.c.stop_nbd_disk(nbd_name)
+
+ # Create snapshot of thick provisioned lvol bdev
+ fail_count += self.c.snapshot_lvol_bdev(lvol_bdev['name'], snapshot_name)
+ snapshot_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name)
+
+ # Create two clones of created snapshot
+ lvol_clone = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + self.lbd_name)
+ if lvol_clone['driver_specific']['lvol']['thin_provision'] is not True:
+ fail_count += 1
+
+ # Fill part of clone with data of known pattern
+ fail_count += self.c.start_nbd_disk(lvol_clone['name'], nbd_name)
+ first_fill = 0
+ second_fill = int(size * 3 / 4)
+ fail_count += self.run_fio_test(nbd_name, first_fill * MEGABYTE,
+ MEGABYTE, "write", "0xdd", 0)
+ fail_count += self.run_fio_test(nbd_name, second_fill * MEGABYTE,
+ MEGABYTE, "write", "0xdd", 0)
+ self.c.stop_nbd_disk(nbd_name)
+
+ # Do inflate
+ fail_count += self.c.inflate_lvol_bdev(lvol_clone['name'])
+ lvol_clone = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + self.lbd_name)
+ if lvol_clone['driver_specific']['lvol']['thin_provision'] is not False:
+ fail_count += 1
+
+ # Delete snapshot
+ fail_count += self.c.destroy_lvol_bdev(snapshot_bdev['name'])
+
+ # Check data consistency
+ fail_count += self.c.start_nbd_disk(lvol_clone['name'], nbd_name)
+ fail_count += self.run_fio_test(nbd_name, first_fill * MEGABYTE,
+ MEGABYTE, "read", "0xdd")
+ fail_count += self.run_fio_test(nbd_name, (first_fill + 1) * MEGABYTE,
+ (second_fill - first_fill - 1) * MEGABYTE,
+ "read", "0xcc")
+ fail_count += self.run_fio_test(nbd_name, (second_fill) * MEGABYTE,
+ MEGABYTE, "read", "0xdd")
+ fail_count += self.run_fio_test(nbd_name, (second_fill + 1) * MEGABYTE,
+ (size - second_fill - 1) * MEGABYTE,
+ "read", "0xcc")
+ self.c.stop_nbd_disk(nbd_name)
+
+ # Destroy lvol bdev
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev['name'])
+
+ # Destroy lvol store
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+
+ # Delete malloc
+ fail_count += self.c.delete_malloc_bdev(base_name)
+
+ # Expected result:
+ # - calls successful, return code = 0
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case758(self):
+ """
+ clone_decouple_parent
+
+ Detach parent from clone and check if parent can be safely removed.
+ Check data consistency.
+ """
+
+ fail_count = 0
+ snapshot_name = "snapshot"
+ nbd_name = "/dev/nbd0"
+
+ # Create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+
+ # Create lvol store
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count += self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ size = self.get_lvs_divided_size(4)
+
+ # Construct thin provisioned lvol bdev
+ uuid_bdev0 = self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name, size, thin=True)
+ lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev0)
+
+ # Decouple parent lvol bdev and check if it fails
+ ret_value = self.c.decouple_parent_lvol_bdev(lvol_bdev['name'])
+ if ret_value == 0:
+ print("ERROR: Decouple parent on bdev without parent should "
+ "fail but didn't")
+ fail_count += 1
+
+ # Create snapshot of thin provisioned lvol bdev
+ fail_count += self.c.snapshot_lvol_bdev(lvol_bdev['name'], snapshot_name)
+ snapshot_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name)
+
+ # Try to destroy snapshot and check if it fails
+ ret_value = self.c.destroy_lvol_bdev(snapshot_bdev['name'])
+ if ret_value == 0:
+ print("ERROR: Delete snapshot should fail but didn't")
+ fail_count += 1
+
+ # Decouple parent lvol bdev
+ fail_count += self.c.decouple_parent_lvol_bdev(lvol_bdev['name'])
+ lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev0)
+ snapshot_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name)
+ if lvol_bdev['driver_specific']['lvol']['thin_provision'] is not True:
+ fail_count += 1
+ if lvol_bdev['driver_specific']['lvol']['clone'] is not False:
+ fail_count += 1
+ if lvol_bdev['driver_specific']['lvol']['snapshot'] is not False:
+ fail_count += 1
+ if snapshot_bdev['driver_specific']['lvol']['clone'] is not False:
+ fail_count += 1
+
+ # Destroy snapshot
+ fail_count += self.c.destroy_lvol_bdev(snapshot_bdev['name'])
+
+ # Destroy lvol bdev
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev['name'])
+
+ # Destroy lvol store
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+
+ # Delete malloc
+ fail_count += self.c.delete_malloc_bdev(base_name)
+
+ # Expected result:
+ # - calls successful, return code = 0
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case759(self):
+ """
+ clone_decouple_parent_rw
+
+ Create tree level snaphot-snapshot2-clone structure.
+ Detach snapshot2 from clone. Check if snapshot2 can be safely removed.
+ Each time check consistency of snapshot-clone relations and written data.
+ """
+ fail_count = 0
+ snapshot_name = "snapshot"
+ snapshot_name2 = "snapshot2"
+ nbd_name = "/dev/nbd0"
+
+ # Create malloc bdev
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+
+ # Create lvol store
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count += self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+ lvs = self.c.get_lvol_stores()
+ size = int(5 * lvs[0]['cluster_size'] / MEGABYTE)
+
+ # Construct thin provisioned lvol bdev
+ uuid_bdev0 = self.c.construct_lvol_bdev(uuid_store,
+ self.lbd_name, size, thin=True)
+ lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev0)
+
+ # Fill first four out of 5 culsters of clone with data of known pattern
+ fail_count += self.c.start_nbd_disk(lvol_bdev['name'], nbd_name)
+ begin_fill = 0
+ end_fill = int(size * 4 / 5)
+ fail_count += self.run_fio_test(nbd_name, begin_fill * MEGABYTE,
+ end_fill * MEGABYTE, "write", "0xdd", 0)
+
+ # Create snapshot of thin provisioned lvol bdev
+ fail_count += self.c.snapshot_lvol_bdev(lvol_bdev['name'], snapshot_name)
+ snapshot_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name)
+
+ # Fill second and fourth cluster of clone with data of known pattern
+ start_fill = int(size / 5)
+ fill_range = int(size / 5)
+ fail_count += self.run_fio_test(nbd_name, start_fill * MEGABYTE,
+ fill_range * MEGABYTE, "write", "0xcc", 0)
+ start_fill = int(size * 3 / 5)
+ fail_count += self.run_fio_test(nbd_name, start_fill * MEGABYTE,
+ fill_range * MEGABYTE, "write", "0xcc", 0)
+
+ # Create second snapshot of thin provisioned lvol bdev
+ fail_count += self.c.snapshot_lvol_bdev(lvol_bdev['name'], snapshot_name2)
+ snapshot_bdev2 = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name2)
+
+ # Fill second cluster of clone with data of known pattern
+ start_fill = int(size / 5)
+ fail_count += self.run_fio_test(nbd_name, start_fill * MEGABYTE,
+ fill_range * MEGABYTE, "write", "0xee", 0)
+
+ # Check data consistency
+ pattern = ["0xdd", "0xee", "0xdd", "0xcc", "0x00"]
+ for i in range(0, 5):
+ begin_fill = int(size * i / 5)
+ fail_count += self.run_fio_test(nbd_name, begin_fill * MEGABYTE,
+ fill_range * MEGABYTE, "read", pattern[i])
+
+ # Delete snapshot and check if it fails
+ ret_value = self.c.destroy_lvol_bdev(snapshot_bdev2['name'])
+ if ret_value == 0:
+ print("ERROR: Delete snapshot should fail but didn't")
+ fail_count += 1
+
+ # Decouple parent
+ fail_count += self.c.decouple_parent_lvol_bdev(lvol_bdev['name'])
+ lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev0)
+
+ # Check data consistency
+ for i in range(0, 5):
+ begin_fill = int(size * i / 5)
+ fail_count += self.run_fio_test(nbd_name, begin_fill * MEGABYTE,
+ fill_range * MEGABYTE, "read", pattern[i])
+
+ # Delete second snapshot
+ ret_value = self.c.destroy_lvol_bdev(snapshot_bdev2['name'])
+
+ # Check data consistency
+ for i in range(0, 5):
+ begin_fill = int(size * i / 5)
+ fail_count += self.run_fio_test(nbd_name, begin_fill * MEGABYTE,
+ fill_range * MEGABYTE, "read", pattern[i])
+
+ # Destroy lvol bdev
+ fail_count += self.c.destroy_lvol_bdev(lvol_bdev['name'])
+
+ # Destroy snapshot
+ fail_count += self.c.destroy_lvol_bdev(snapshot_bdev['name'])
+
+ # Destroy lvol store
+ fail_count += self.c.destroy_lvol_store(uuid_store)
+
+ # Delete malloc
+ fail_count += self.c.delete_malloc_bdev(base_name)
+
+ # Expected result:
+ # - calls successful, return code = 0
+ # - no other operation fails
+ return fail_count
+
+ @case_message
+ def test_case800(self):
+ fail_count = 0
+
+ bdev_uuids = []
+ bdev_names = [self.lbd_name + str(i) for i in range(4)]
+ bdev_aliases = ["/".join([self.lvs_name, name]) for name in bdev_names]
+
+ # Create a lvol store with 4 lvol bdevs
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ lvs_uuid = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count += self.c.check_get_lvol_stores(base_name,
+ lvs_uuid,
+ self.cluster_size,
+ self.lvs_name)
+ bdev_size = self.get_lvs_divided_size(4)
+ for name, alias in zip(bdev_names, bdev_aliases):
+ uuid = self.c.construct_lvol_bdev(lvs_uuid,
+ name,
+ bdev_size)
+ fail_count += self.c.check_get_bdevs_methods(uuid,
+ bdev_size,
+ alias)
+ bdev_uuids.append(uuid)
+
+ # Rename lvol store and check if lvol store name and
+ # lvol bdev aliases were updated properly
+ new_lvs_name = "lvs_new"
+ bdev_aliases = [alias.replace(self.lvs_name, new_lvs_name) for alias in bdev_aliases]
+
+ fail_count += self.c.rename_lvol_store(self.lvs_name, new_lvs_name)
+
+ fail_count += self.c.check_get_lvol_stores(base_name,
+ lvs_uuid,
+ self.cluster_size,
+ new_lvs_name)
+
+ for uuid, alias in zip(bdev_uuids, bdev_aliases):
+ fail_count += self.c.check_get_bdevs_methods(uuid,
+ bdev_size,
+ alias)
+
+ # Now try to rename the bdevs using their uuid as "old_name"
+ bdev_names = ["lbd_new" + str(i) for i in range(4)]
+ bdev_aliases = ["/".join([new_lvs_name, name]) for name in bdev_names]
+ print(bdev_aliases)
+ for uuid, new_name, new_alias in zip(bdev_uuids, bdev_names, bdev_aliases):
+ fail_count += self.c.rename_lvol_bdev(uuid, new_name)
+ fail_count += self.c.check_get_bdevs_methods(uuid,
+ bdev_size,
+ new_alias)
+ # Same thing but only use aliases
+ bdev_names = ["lbd_even_newer" + str(i) for i in range(4)]
+ new_bdev_aliases = ["/".join([new_lvs_name, name]) for name in bdev_names]
+ print(bdev_aliases)
+ for uuid, old_alias, new_alias, new_name in zip(bdev_uuids, bdev_aliases, new_bdev_aliases, bdev_names):
+ fail_count += self.c.rename_lvol_bdev(old_alias, new_name)
+ fail_count += self.c.check_get_bdevs_methods(uuid,
+ bdev_size,
+ new_alias)
+
+ # Delete configuration using names after rename operation
+ for bdev in new_bdev_aliases:
+ fail_count += self.c.destroy_lvol_bdev(bdev)
+ fail_count += self.c.destroy_lvol_store(new_lvs_name)
+ fail_count += self.c.delete_malloc_bdev(base_name)
+
+ return fail_count
+
+ @case_message
+ def test_case801(self):
+ fail_count = 0
+ if self.c.rename_lvol_store("NOTEXIST", "WHATEVER") == 0:
+ fail_count += 1
+ return fail_count
+
+ @case_message
+ def test_case802(self):
+ fail_count = 0
+
+ lvs_name_1 = "lvs_1"
+ lvs_name_2 = "lvs_2"
+
+ # Create lists with lvol bdev names and aliases for later use
+ bdev_names_1 = ["lvol_1_" + str(i) for i in range(4)]
+ bdev_aliases_1 = ["/".join([lvs_name_1, name]) for name in bdev_names_1]
+ bdev_uuids_1 = []
+ bdev_names_2 = ["lvol_2_" + str(i) for i in range(4)]
+ bdev_aliases_2 = ["/".join([lvs_name_2, name]) for name in bdev_names_2]
+ bdev_uuids_2 = []
+
+ base_bdev_1 = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ base_bdev_2 = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+
+ # Create lvol store on each malloc bdev
+ lvs_uuid_1 = self.c.construct_lvol_store(base_bdev_1,
+ lvs_name_1)
+ fail_count += self.c.check_get_lvol_stores(base_bdev_1,
+ lvs_uuid_1,
+ self.cluster_size,
+ lvs_name_1)
+ lvs_uuid_2 = self.c.construct_lvol_store(base_bdev_2,
+ lvs_name_2)
+ fail_count += self.c.check_get_lvol_stores(base_bdev_2,
+ lvs_uuid_2,
+ self.cluster_size,
+ lvs_name_2)
+
+ # Create 4 lvol bdevs on top of each lvol store
+ bdev_size_1 = self.get_lvs_divided_size(4, lvs_name_1)
+ bdev_size_2 = self.get_lvs_divided_size(4, lvs_name_2)
+ for name, alias in zip(bdev_names_1, bdev_aliases_1):
+ uuid = self.c.construct_lvol_bdev(lvs_uuid_1,
+ name,
+ bdev_size_1)
+ fail_count += self.c.check_get_bdevs_methods(uuid,
+ bdev_size_1,
+ alias)
+ bdev_uuids_1.append(uuid)
+ for name, alias in zip(bdev_names_2, bdev_aliases_2):
+ uuid = self.c.construct_lvol_bdev(lvs_uuid_2,
+ name,
+ bdev_size_2)
+ fail_count += self.c.check_get_bdevs_methods(uuid,
+ bdev_size_2,
+ alias)
+ bdev_uuids_2.append(uuid)
+
+ # Try to rename lvol store to already existing name
+ if self.c.rename_lvol_store(lvs_name_1, lvs_name_2) == 0:
+ fail_count += 1
+
+ # Verify that names of lvol stores and lvol bdevs did not change
+ fail_count += self.c.check_get_lvol_stores(base_bdev_1,
+ lvs_uuid_1,
+ self.cluster_size,
+ lvs_name_1)
+ fail_count += self.c.check_get_lvol_stores(base_bdev_2,
+ lvs_uuid_2,
+ self.cluster_size,
+ lvs_name_2)
+
+ for name, alias, uuid in zip(bdev_names_1, bdev_aliases_1, bdev_uuids_1):
+ fail_count += self.c.check_get_bdevs_methods(uuid,
+ bdev_size_1,
+ alias)
+
+ for name, alias, uuid in zip(bdev_names_2, bdev_aliases_2, bdev_uuids_2):
+ fail_count += self.c.check_get_bdevs_methods(uuid,
+ bdev_size_2,
+ alias)
+
+ # Clean configuration
+ for lvol_uuid in bdev_uuids_1 + bdev_uuids_2:
+ fail_count += self.c.destroy_lvol_bdev(lvol_uuid)
+ fail_count += self.c.destroy_lvol_store(lvs_uuid_1)
+ fail_count += self.c.destroy_lvol_store(lvs_uuid_2)
+ fail_count += self.c.delete_malloc_bdev(base_bdev_1)
+ fail_count += self.c.delete_malloc_bdev(base_bdev_2)
+
+ return fail_count
+
+ @case_message
+ def test_case803(self):
+ fail_count = 0
+ if self.c.rename_lvol_bdev("NOTEXIST", "WHATEVER") == 0:
+ fail_count += 1
+ return fail_count
+
+ @case_message
+ def test_case804(self):
+ fail_count = 0
+
+ base_bdev = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ lvs_uuid = self.c.construct_lvol_store(base_bdev,
+ self.lvs_name)
+ fail_count += self.c.check_get_lvol_stores(base_bdev,
+ lvs_uuid,
+ self.cluster_size,
+ self.lvs_name)
+ bdev_size = self.get_lvs_divided_size(2)
+ bdev_uuid_1 = self.c.construct_lvol_bdev(lvs_uuid,
+ self.lbd_name + "1",
+ bdev_size)
+ fail_count += self.c.check_get_bdevs_methods(bdev_uuid_1,
+ bdev_size)
+ bdev_uuid_2 = self.c.construct_lvol_bdev(lvs_uuid,
+ self.lbd_name + "2",
+ bdev_size)
+ fail_count += self.c.check_get_bdevs_methods(bdev_uuid_2,
+ bdev_size)
+
+ if self.c.rename_lvol_bdev(self.lbd_name + "1", self.lbd_name + "2") == 0:
+ fail_count += 1
+ fail_count += self.c.check_get_bdevs_methods(bdev_uuid_1,
+ bdev_size,
+ "/".join([self.lvs_name, self.lbd_name + "1"]))
+
+ fail_count += self.c.destroy_lvol_bdev(bdev_uuid_1)
+ fail_count += self.c.destroy_lvol_bdev(bdev_uuid_2)
+ fail_count += self.c.destroy_lvol_store(lvs_uuid)
+ fail_count += self.c.delete_malloc_bdev(base_bdev)
+
+ return fail_count
+
+ @case_message
+ def test_case10000(self):
+ pid_path = path.join(self.path, 'vhost.pid')
+
+ base_name = self.c.construct_malloc_bdev(self.total_size,
+ self.block_size)
+ uuid_store = self.c.construct_lvol_store(base_name,
+ self.lvs_name)
+ fail_count = self.c.check_get_lvol_stores(base_name, uuid_store,
+ self.cluster_size)
+
+ fail_count += self._stop_vhost(pid_path)
+ return fail_count
diff --git a/src/spdk/test/lvol/test_plan.md b/src/spdk/test/lvol/test_plan.md
new file mode 100644
index 00000000..5e38699a
--- /dev/null
+++ b/src/spdk/test/lvol/test_plan.md
@@ -0,0 +1,585 @@
+# Lvol feature test plan
+
+## Objective
+The purpose of these tests is to verify the possibility of using lvol configuration in SPDK.
+
+## Methodology
+Configuration in test is to be done using example stub application.
+All management is done using RPC calls, including logical volumes management.
+All tests are performed using malloc backends.
+One exception to malloc backends are tests for logical volume
+tasting - these require persistent merory like NVMe backend.
+
+Tests will be executed as scenarios - sets of smaller test step
+in which return codes from RPC calls is validated.
+Some configuration calls may also be validated by use of
+"get_*" RPC calls, which provide additional information for verifying
+results.
+
+Tests with thin provisioned lvol bdevs, snapshots and clones are using nbd devices.
+Before writing/reading to lvol bdev, bdev is installed with rpc start_nbd_disk.
+After finishing writing/reading, rpc stop_nbd_disk is used.
+
+## Tests
+
+### construct_lvol_store - positive tests
+
+#### TEST CASE 1 - Name: construct_lvs_positive
+Positive test for constructing a new lvol store.
+Call construct_lvol_store with correct base bdev name.
+Steps:
+- create a malloc bdev
+- construct_lvol_store on correct, exisitng malloc bdev
+- check correct uuid values in response get_lvol_stores command
+- destroy lvol store
+- delete malloc bdev
+
+Expected result:
+- call successful, return code = 0, uuid printed to stdout
+- get_lvol_stores: backend used for construct_lvol_store has uuid
+ field set with the same uuid as returned from RPC call
+- no other operation fails
+
+### construct_lvol_bdev - positive tests
+
+#### TEST CASE 50 - Name: construct_logical_volume_positive
+Positive test for constructing a new logical volume.
+Call construct_lvol_bdev with correct lvol store UUID and size in MiB for this bdev.
+Steps:
+- create a malloc bdev
+- construct_lvol_store on correct, exisitng malloc bdev
+- check correct uuid values in response get_lvol_stores command
+- construct_lvol_bdev on correct lvs_uuid and size
+- delete lvol bdev
+- destroy lvol store
+- delete malloc bdev
+
+Expected result:
+- call successful, return code = 0
+- get_bdevs: backend used for construct_lvol_bdev has name
+ field set with the same name as returned value from call RPC method: construct_lvol_bdev
+- no other operation fails
+
+#### TEST CASE 51 - Name: construct_multi_logical_volumes_positive
+Positive test for constructing a multi logical volumes.
+Call construct_lvol_bdev with correct lvol store UUID and
+size is equal one quarter of the this bdev size.
+Steps:
+- create a malloc bdev
+- construct_lvol_store on correct, exisitng malloc bdev
+- check correct uuid values in response get_lvol_stores command
+- construct_lvol_bdev on correct lvs_uuid and size
+ (size is approximately equal to one quarter of the bdev size,
+ because of lvol metadata)
+- repeat the previous step three more times
+- delete lvol bdevs
+- create and delete four lvol bdevs again from steps above
+- destroy lvol store
+- delete malloc bdev
+
+Expected result:
+- call successful, return code = 0
+- get_lvol_store: backend used for construct_lvol_bdev has name
+ field set with the same name as returned from RPC call for all repeat
+- no other operation fails
+
+#### TEST CASE 52 - Name: construct_lvol_bdev_using_name_positive
+Positive test for constructing a logical volume using friendly names.
+Verify that logical volumes can be created by using a friendly name
+instead of uuid when referencing to lvol store.
+Steps:
+- create malloc bdev
+- create logical volume store on created malloc bdev
+- verify lvol store was created correctly
+- create logical volume on lvol store by using a friendly name
+ as a reference
+- verify logical volume was correctly created
+- delete logical volume bdev
+- destroy logical volume store
+- delete malloc bdev
+
+Expected result:
+- calls successful, return code = 0
+- no other operation fails
+
+#### TEST CASE 53 - Name: construct_lvol_bdev_duplicate_names_positive
+Positive test for constructing a logical volumes using friendly names.
+Verify that logical volumes can use the same argument for friendly names
+if they are created on separate logical volume stores.
+Steps:
+- create two malloc bdevs
+- create logical volume stores on created malloc bdevs
+- verify stores were created correctly
+- create logical volume on first lvol store
+- verify it was correctly created
+- using the same friendly name argument create logical volume on second
+ lvol store
+- verify logical volume was correctly created
+- delete logical volume bdevs
+- destroy logical volume stores
+- delete malloc bdevs
+
+Expected result:
+- calls successful, return code = 0
+- no other operation fails
+
+### construct_lvol_bdev - negative tests
+
+#### TEST CASE 100 - Name: construct_logical_volume_nonexistent_lvs_uuid
+Negative test for constructing a new logical_volume.
+Call construct_lvol_bdev with lvs_uuid which does not
+exist in configuration.
+Steps:
+- try to call construct_lvol_bdev with lvs_uuid which does not exist
+
+Expected result:
+- return code != 0
+- ENODEV response printed to stdout
+
+#### TEST CASE 101 - Name: construct_lvol_bdev_on_full_lvol_store
+Negative test for constructing a new lvol bdev.
+Call construct_lvol_bdev on a full lvol store.
+Steps:
+- create a malloc bdev
+- construct_lvol_store on created malloc bdev
+- check correct uuid values in response from get_lvol_stores command
+- construct_lvol_bdev on correct lvs_uuid and size is smaller by 1 MB
+ from the full size malloc bdev
+- try construct_lvol_bdev on the same lvs_uuid as in last step;
+ this call should fail as lvol store space is taken by previously created bdev
+- destroy_lvol_store
+- delete malloc bdev
+
+Expected result:
+- first call successful
+- second construct_lvol_bdev call return code != 0
+- EEXIST response printed to stdout
+- no other operation fails
+
+#### TEST CASE 102 - Name: construct_lvol_bdev_name_twice
+Negative test for constructing lvol bdev using the same
+friendly name twice on the same logical volume store.
+Steps:
+- create malloc bdev
+- create logical volume store on malloc bdev
+- using get_lvol_stores verify that logical volume store was correctly created
+ and has arguments as provided in step earlier (cluster size, friendly name, base bdev)
+- construct logical volume on lvol store and verify it was correctly created
+- try to create another logical volume on the same lvol store using
+the same friendly name as in previous step; this step should fail
+- delete existing lvol bdev
+- delete existing lvol store
+- delete malloc bdevs
+
+Expected results:
+- creating two logical volumes with the same friendly name within the same
+ lvol store should not be possible
+- no other operation fails
+
+### resize_lvol_store - positive tests
+
+#### TEST CASE 150 - Name: resize_logical_volume_positive
+Positive test for resizing a logical_volume.
+Call resize_lvol_bdev with correct logical_volumes name and new size.
+Steps:
+- create a malloc bdev
+- construct_lvol_store on created malloc bdev
+- check correct uuid values in response get_lvol_stores command
+- construct_lvol_bdev on correct lvs_uuid and size is
+ equal to one quarter of size malloc bdev
+- check size of the lvol bdev by command RPC : get_bdevs
+- resize_lvol_bdev on correct lvs_uuid and size is
+ equal half to size malloc bdev
+- check size of the lvol bdev by command RPC : get_bdevs
+- resize_lvol_bdev on the correct lvs_uuid and size is smaller by 1 MB
+ from the full size malloc bdev
+- check size of the lvol bdev by command RPC : get_bdevs
+- resize_lvol_bdev on the correct lvs_uuid and size is equal 0 MiB
+- check size of the lvol bdev by command RPC : get_bdevs
+- delete lvol bdev
+- destroy lvol store
+- delete malloc bdev
+
+Expected result:
+- lvol bdev should change size after resize operations
+- calls successful, return code = 0
+- no other operation fails
+
+### resize lvol store - negative tests
+
+#### TEST CASE 200 - Name: resize_logical_volume_nonexistent_logical_volume
+Negative test for resizing a logical_volume.
+Call resize_lvol_bdev with logical volume which does not
+exist in configuration.
+Steps:
+- try resize_lvol_store on logical volume which does not exist
+
+Expected result:
+- return code != 0
+- Error code: ENODEV ("No such device") response printed to stdout
+
+#### TEST CASE 201 - Name: resize_logical_volume_with_size_out_of_range
+Negative test for resizing a logical volume.
+Call resize_lvol_store with size argument bigger than size of base bdev.
+Steps:
+- create a malloc bdev
+- construct_lvol_store on created malloc bdev
+- check correct uuid values in response get_lvol_stores command
+- construct_lvol_bdev on correct lvs_uuid and
+ size is equal one quarter of size malloc bdev
+- try resize_lvol_bdev on correct lvs_uuid and size is
+ equal to size malloc bdev + 1MiB; this call should fail
+- delete lvol bdev
+- destroy lvol store
+- delete malloc bdev
+
+Expected result:
+- resize_lvol_bdev call return code != 0
+- Error code: ENODEV ("Not enough free clusters left on lvol store")
+ response printed to stdout
+- no other operation fails
+
+### destroy_lvol_store - positive tests
+
+#### TEST CASE 250 - Name: destroy_lvol_store_positive
+Positive test for destroying a logical volume store.
+Call destroy_lvol_store with correct logical_volumes name
+Steps:
+- create a malloc bdev
+- construct_lvol_store on created malloc bdev
+- check correct uuid values in response get_lvol_stores command
+- destroy_lvol_store
+- check correct response get_lvol_stores command
+- delete malloc bdev
+
+Expected result:
+- calls successful, return code = 0
+- get_lvol_stores: response should be of no value after destroyed lvol store
+- no other operation fails
+
+#### TEST CASE 251 - Name: destroy_lvol_store_use_name_positive
+Positive test for destroying a logical volume store using
+lvol store name instead of uuid for reference.
+Call destroy_lvol_store with correct logical volume name
+Steps:
+- create a malloc bdev
+- construct_lvol_store on created malloc bdev
+- check correct uuid values in response from get_lvol_stores command
+- destroy_lvol_store
+- check correct response from get_lvol_stores command
+- delete malloc bdev
+
+Expected result:
+- calls successful, return code = 0
+- get_lvol_stores: response should be of no value after destroyed lvol store
+- no other operation fails
+
+#### TEST CASE 252 - Name: destroy_lvol_store_with_lvol_bdev_positive
+Positive test for destroying a logical volume store with lvol bdev
+created on top.
+Call destroy_lvol_store with correct logical_volumes name
+Steps:
+- create a malloc bdev
+- construct_lvol_store on created malloc bdev
+- check correct uuid values in response get_lvol_stores command
+- construct_lvol_bdev on correct lvs_uuid and size is equal to size malloc bdev
+- destroy_lvol_store
+- check correct response get_lvol_stores command
+- delete malloc bdev
+
+Expected result:
+- calls successful, return code = 0
+- get_lvol_stores: response should be of no value after destroyed lvol store
+- no other operation fails
+
+#### TEST CASE 253 - Name: destroy_multi_logical_volumes_positive
+Positive test for destroying a logical volume store with multiple lvol
+bdevs created on top.
+Call construct_lvol_bdev with correct lvol store UUID and
+size is equal to one quarter of the this bdev size.
+Steps:
+- create a malloc bdev
+- construct_lvol_store on correct, exisitng malloc bdev
+- check correct uuid values in response get_lvol_stores command
+- construct_lvol_bdev on correct lvs_uuid and size
+ (size is equal to one quarter of the bdev size)
+- repeat the previous step four times
+- destroy_lvol_store
+- check correct response get_lvol_stores command
+- delete malloc bdev
+
+Expected result:
+- call successful, return code = 0
+- get_lvol_store: backend used for construct_lvol_bdev has name
+ field set with the same name as returned from RPC call for all repeat
+- no other operation fails
+
+#### TEST CASE 254 - Name: destroy_resize_logical_volume_positive
+Positive test for destroying a logical_volume after resizing.
+Call destroy_lvol_store with correct logical_volumes name.
+Steps:
+- create a malloc bdev
+- construct_lvol_store on created malloc bdev
+- check correct uuid values in response get_lvol_stores command
+- construct_lvol_bdev on correct lvs_uuid and size is
+ equal to one quarter of size malloc bdev
+- check size of the lvol bdev
+- resize_lvol_bdev on correct lvs_uuid and size is
+ equal half of size malloc bdev
+- check size of the lvol bdev by command RPC : get_bdevs
+- Resize_lvol_bdev on the correct lvs_uuid and the size is smaller by 1 MB
+ from the full size malloc bdev
+- check size of the lvol bdev by command RPC : get_bdevs
+- resize_lvol_bdev on the correct lvs_uuid and size is equal 0 MiB
+- check size of the lvol bdev by command RPC : get_bdevs
+- destroy_lvol_store
+- delete malloc bdev
+
+Expected result:
+- lvol bdev should change size after resize operations
+- calls successful, return code = 0
+- no other operation fails
+- get_lvol_stores: response should be of no value after destroyed lvol store
+
+#### TEST CASE 255 - Name: delete_lvol_store_persistent_positive
+Positive test for removing lvol store persistently
+Steps:
+- construct_lvol_store on NVMe bdev
+- destroy lvol store
+- delete NVMe bdev
+- add NVMe bdev
+- check if destroyed lvol store does not exist on NVMe bdev
+
+Expected result:
+- get_lvol_stores should not report any existsing lvol stores in configuration
+ after deleting and adding NVMe bdev
+- no other operation fails
+
+### destroy_lvol_store - negative tests
+
+#### TEST CASE 300 - Name: destroy_lvol_store_nonexistent_lvs_uuid
+Call destroy_lvol_store with nonexistent logical_volumes name
+exist in configuration.
+Steps:
+- try to call destroy_lvol_store with lvs_uuid which does not exist
+
+Expected result:
+- return code != 0
+- Error code response printed to stdout
+
+#### TEST CASE 301 - Name: delete_lvol_store_underlying_bdev
+Call destroy_lvol_store after deleting it's base bdev.
+Lvol store should be automatically removed on deleting underlying bdev.
+Steps:
+- create a malloc bdev
+- construct_lvol_store on created malloc bdev
+- check correct uuid values in response get_lvol_stores command
+- delete malloc bdev
+- try to destroy lvol store; this call should fail as lvol store
+ is no longer present
+
+Expected result:
+- destroy_lvol_store retudn code != 0
+- Error code: ENODEV ("No such device") response printed to stdout
+- no other operation fails
+
+### nested destroy_lvol_bdev - negative tests
+
+#### TEST CASE 350 - Name: nested_destroy_logical_volume_negative
+Negative test for destroying a nested first lvol store.
+Call destroy_lvol_store with correct base bdev name.
+Steps:
+- create a malloc bdev
+- construct_lvol_store on created malloc bdev
+- check correct uuid values in response get_lvol_stores command
+- construct_lvol_bdev on correct lvs_uuid and size is
+ equal to size malloc bdev
+- construct first nested lvol store on created lvol_bdev
+- check correct uuid values in response get_lvol_stores command
+- construct first nested lvol bdev on correct lvs_uuid and size
+- check size of the lvol bdev by command RPC : get_bdevs
+- destroy first lvol_store
+- delete malloc bdev
+
+Expected result:
+- Error code: ENODEV ("the device is busy") response printed to stdout
+- no other operation fails
+
+### nested construct_logical_volume - positive tests
+
+#### TEST CASE 400 - Name: nested_construct_logical_volume_positive
+Positive test for constructing a nested new lvol store.
+Call construct_lvol_store with correct base bdev name.
+Steps:
+- create a malloc bdev
+- construct_lvol_store on created malloc bdev
+- check correct uuid values in response get_lvol_stores command
+- construct_lvol_bdev on correct lvs_uuid and size is
+ equal to size malloc bdev
+- construct first nested lvol store on created lvol_bdev
+- check correct uuid values in response get_lvol_stores command
+- construct first nested lvol bdev on correct lvs_uuid and size
+- construct second nested lvol store on created first nested lvol bdev
+- check correct uuid values in response get_lvol_stores command
+- construct second nested lvol bdev on correct first nested lvs uuid and size
+- delete nested lvol bdev and lvol store
+- delete base lvol bdev and lvol store
+- delete malloc bdev
+
+Expected result:
+- calls successful, return code = 0
+- get_lvol_stores: backend used for construct_lvol_store has UUID
+ field set with the same UUID as returned from RPC call
+ backend used for construct_lvol_bdev has UUID
+ field set with the same UUID as returned from RPC call
+- no other operation fails
+
+### construct_lvol_store - negative tests
+
+#### TEST CASE 450 - Name: construct_lvs_nonexistent_bdev
+Negative test for constructing a new lvol store.
+Call construct_lvol_store with base bdev name which does not
+exist in configuration.
+Steps:
+- try construct_lvol_store on bdev which does not exist
+
+Expected result:
+- return code != 0
+- Error code: ENODEV ("No such device") response printed to stdout
+
+#### TEST CASE 451 - Name: construct_lvs_on_bdev_twice
+Negative test for constructing a new lvol store.
+Call construct_lvol_store with base bdev name twice.
+Steps:
+- create a malloc bdev
+- construct_lvol_store on created malloc bdev
+- check correct uuid values in response get_lvol_stores command
+- try construct_lvol_store on the same bdev as in last step;
+ this call should fail as base bdev is already claimed by lvol store
+- destroy lvs
+- delete malloc bdev
+
+Expected result:
+- first call successful
+- second construct_lvol_store call return code != 0
+- EEXIST response printed to stdout
+- no other operation fails
+
+#### TEST CASE 452 - Name: construct_lvs_name_twice
+Negative test for constructing a new lvol store using the same
+friendly name twice.
+Steps:
+- create two malloc bdevs
+- create logical volume store on first malloc bdev
+- using get_lvol_stores verify that logical volume store was correctly created
+ and has arguments as provided in step earlier (cluster size, friendly name, base bdev)
+- try to create another logical volume store on second malloc bdev using the
+ same friendly name as before; this step is expected to fail as lvol stores
+ cannot have the same name
+- delete existing lvol store
+- delete malloc bdevs
+
+Expected results:
+- creating two logical volume stores with the same friendly name should
+not be possible
+- no other operation fails
+
+### logical volume rename tests
+
+#### TEST CASE 800 - Name: rename_positive
+Positive test for lvol store and lvol bdev rename.
+Steps:
+- create malloc bdev
+- construct lvol store on malloc bdev
+- create 4 lvol bdevs on top of previously created lvol store
+- rename lvol store; verify that lvol store friendly name was
+ updated in get_lvol_stores output; verify that prefix in lvol bdevs
+ friendly names were also updated
+- rename lvol bdevs; use lvols UUID's to point which lvol bdev name to change;
+ verify that all bdev names were successfully updated
+- rename lvol bdevs; use lvols alias name to point which lvol bdev
+ name to change; verify that all bdev names were successfully updated
+- clean running configuration: delete lvol bdevs, destroy lvol store,
+ delete malloc bdev; use lvol store and lvol bdev friendly names for delete
+ and destroy commands to check if new names can be correctly used for performing
+ other RPC operations;
+
+Expected results:
+- lvol store and lvol bdevs correctly created
+- lvol store and lvol bdevs names updated after renaming operation
+- lvol store and lvol bdevs possible to delete using new names
+- no other operation fails
+
+#### TEST CASE 801 - Name: rename_lvs_nonexistent
+Negative test case for lvol store rename.
+Check that error is returned when trying to rename not existing lvol store.
+
+Steps:
+- call rename_lvol_store with name pointing to not existing lvol store
+
+Expected results:
+- rename_lvol_store return code != 0
+- no other operation fails
+
+#### TEST CASE 802 - Name: rename_lvs_EEXIST
+Negative test case for lvol store rename.
+Check that error is returned when trying to rename to a name which is already
+used by another lvol store.
+
+Steps:
+- create 2 malloc bdevs
+- construct lvol store on each malloc bdev
+- on each lvol store create 4 lvol bdevs
+- call rename_lvol_store on first lvol store and try to change its name to
+ the same name as used by second lvol store
+- verify that both lvol stores still have the same names as before
+- verify that lvol bdev have the same aliases as before
+
+Expected results:
+- rename_lvol_store return code != 0; not possible to rename to already
+ used name
+- no other operation fails
+
+#### TEST CASE 803 - Name: rename_lvol_bdev_nonexistent
+Negative test case for lvol bdev rename.
+Check that error is returned when trying to rename not existing lvol bdev.
+
+Steps:
+- call rename_lvol_bdev with name pointing to not existing lvol bdev
+
+Expected results:
+- rename_lvol_bdev return code != 0
+- no other operation fails
+
+#### TEST CASE 804 - Name: rename_lvol_bdev_EEXIST
+Negative test case for lvol bdev rename.
+Check that error is returned when trying to rename to a name which is already
+used by another lvol bdev.
+
+Steps:
+- create malloc bdev
+- construct lvol store on malloc bdev
+- construct 2 lvol bdevs on lvol store
+- call rename_lvol_bdev on first lvol bdev and try to change its name to
+ the same name as used by second lvol bdev
+- verify that both lvol bdev still have the same names as before
+
+Expected results:
+- rename_lvol_bdev return code != 0; not possible to rename to already
+ used name
+- no other operation fails
+
+### SIGTERM
+
+#### TEST CASE 10000 - Name: SIGTERM
+Call CTRL+C (SIGTERM) occurs after creating lvol store
+Steps:
+- create a malloc bdev
+- construct_lvol_store on created malloc bdev
+- check correct uuid values in response get_lvol_stores command
+- Send SIGTERM signal to the application
+
+Expected result:
+- calls successful, return code = 0
+- get_bdevs: no change
+- no other operation fails