diff --git a/autotest.sh b/autotest.sh index 030273be9..8ccb3eb17 100755 --- a/autotest.sh +++ b/autotest.sh @@ -191,7 +191,7 @@ if [ $SPDK_TEST_LVOL -eq 1 ]; then timing_enter lvol test_cases="1,50,51,52,53,100,101,102,250,251,252,253,255," test_cases+="300,301,450,451,452,550,600,601,650,651,652,654,655," - test_cases+="700,701,10000" + test_cases+="700,701,800,801,802,803,804,10000" run_test ./test/lvol/lvol.sh --test-cases=$test_cases report_test_completion "lvol" timing_exit lvol diff --git a/test/lvol/lvol.sh b/test/lvol/lvol.sh index 18d0f3b6e..524d2df2e 100755 --- a/test/lvol/lvol.sh +++ b/test/lvol/lvol.sh @@ -58,6 +58,11 @@ function usage() { 655: 'thin_provisioning_filling_disks_less_than_lvs_size', 700: 'tasting_positive', 701: 'tasting_lvol_store_positive', + 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 diff --git a/test/lvol/rpc_commands_lib.py b/test/lvol/rpc_commands_lib.py index 804d89bf2..944e12ce5 100644 --- a/test/lvol/rpc_commands_lib.py +++ b/test/lvol/rpc_commands_lib.py @@ -28,15 +28,24 @@ 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): + 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'] @@ -52,7 +61,7 @@ class Commands_Rpc(object): json_value=json_value)) return 1 - def check_get_lvol_stores(self, base_name, uuid, cluster_size=None): + 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: @@ -60,6 +69,7 @@ class Commands_Rpc(object): 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: @@ -78,6 +88,14 @@ class Commands_Rpc(object): 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, @@ -172,3 +190,13 @@ class Commands_Rpc(object): def construct_nvme_bdev(self, nvme_name, trtype, traddr): print("INFO: Add NVMe bdev {nvme}".format(nvme=nvme_name)) self.rpc.construct_nvme_bdev("-b", nvme_name, "-t", trtype, "-a", traddr) + + 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 diff --git a/test/lvol/test_cases.py b/test/lvol/test_cases.py index 34c916ed1..3fb0943bb 100644 --- a/test/lvol/test_cases.py +++ b/test/lvol/test_cases.py @@ -63,6 +63,11 @@ def case_message(func): 655: 'thin_provisioning_filling_disks_less_than_lvs_size', 700: 'tasting_positive', 701: 'tasting_lvol_store_positive', + 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')[:]) @@ -1037,6 +1042,219 @@ class TestCases(object): fail_count += 1 return fail_count + @case_message + def test_case800(self): + fail_count = 0 + + bdev_size = (self.total_size - 1) / 4 + 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, + self.cluster_size) + fail_count += self.c.check_get_lvol_stores(base_name, + lvs_uuid, + self.cluster_size, + self.lvs_name) + 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.delete_bdev(bdev) + fail_count += self.c.destroy_lvol_store(new_lvs_name) + fail_count += self.c.delete_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 = [] + bdev_size = (self.total_size - 1) / 4 + + 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, + self.cluster_size) + 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, + self.cluster_size) + 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 + for name, alias in zip(bdev_names_1, bdev_aliases_1): + uuid = self.c.construct_lvol_bdev(lvs_uuid_1, + name, + bdev_size) + fail_count += self.c.check_get_bdevs_methods(uuid, + bdev_size, + 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) + fail_count += self.c.check_get_bdevs_methods(uuid, + bdev_size, + 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, + 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, + alias) + + # Clean configuration + for lvol_uuid in bdev_uuids_1 + bdev_uuids_2: + fail_count += self.c.delete_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_bdev(base_bdev_1) + fail_count += self.c.delete_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 + bdev_size = (self.total_size - 1) / 2 + + 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, + self.cluster_size) + fail_count += self.c.check_get_lvol_stores(base_bdev, + lvs_uuid, + self.cluster_size, + self.lvs_name) + 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.delete_bdev(bdev_uuid_1) + fail_count += self.c.delete_bdev(bdev_uuid_2) + fail_count += self.c.destroy_lvol_store(lvs_uuid) + fail_count += self.c.delete_bdev(base_bdev) + + return fail_count + @case_message def test_case10000(self): pid_path = path.join(self.path, 'vhost.pid') diff --git a/test/lvol/test_plan.md b/test/lvol/test_plan.md index 05c3a7eb8..94d4a166e 100644 --- a/test/lvol/test_plan.md +++ b/test/lvol/test_plan.md @@ -836,6 +836,91 @@ Expected result: - calls successful, return code = 0 - 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