def verify_replica_mode(grpc_c, addr, mode): if not addr.startswith("tcp://"): addr = "tcp://" + addr verified = False for i in range(RETRY_COUNTS_SHORT): replicas = grpc_c.replica_list() snapList = cmd.snapshot_ls(grpc_c.address) for r in replicas: if r.address == addr and r.mode == mode: verified = True break if verified: break time.sleep(RETRY_INTERVAL_SHORT) assert verified
def snapshot_revert_test(dev, address, engine_name): # NOQA existings = {} snap1 = Snapshot(dev, generate_random_data(existings), address) snap2 = Snapshot(dev, generate_random_data(existings), address) snap3 = Snapshot(dev, generate_random_data(existings), address) snapList = cmd.snapshot_ls(address) assert snap1.name in snapList assert snap2.name in snapList assert snap3.name in snapList snapshot_revert_with_frontend(address, engine_name, snap2.name) snap3.refute_data() snap2.verify_checksum() snap1.verify_data() snapshot_revert_with_frontend(address, engine_name, snap1.name) snap3.refute_data() snap2.refute_data() snap1.verify_checksum()
def snapshot_tree_verify_relationship(address, snap, strict): info = cmd.snapshot_info(address) assert snap["0a"] in info assert snap["0b"] in info[snap["0a"]]["children"] assert snap["0b"] in info assert info[snap["0b"]]["parent"] == snap["0a"] assert len(info[snap["0b"]]["children"]) == 3 assert snap["0c"] in info[snap["0b"]]["children"] assert snap["1a"] in info[snap["0b"]]["children"] assert snap["2a"] in info[snap["0b"]]["children"] assert snap["0c"] in info assert info[snap["0c"]]["parent"] == snap["0b"] assert not info[snap["0c"]]["children"] assert snap["1a"] in info assert info[snap["1a"]]["parent"] == snap["0b"] assert snap["1b"] in info[snap["1a"]]["children"] assert snap["1b"] in info assert info[snap["1b"]]["parent"] == snap["1a"] assert snap["1c"] in info[snap["1b"]]["children"] assert snap["1c"] in info assert info[snap["1c"]]["parent"] == snap["1b"] assert not info[snap["1c"]]["children"] assert snap["2a"] in info assert info[snap["2a"]]["parent"] == snap["0b"] assert len(info[snap["2a"]]["children"]) == 2 assert snap["2b"] in info[snap["2a"]]["children"] assert snap["3a"] in info[snap["2a"]]["children"] assert snap["2b"] in info assert info[snap["2b"]]["parent"] == snap["2a"] assert snap["2c"] in info[snap["2b"]]["children"] assert snap["2c"] in info assert info[snap["2c"]]["parent"] == snap["2b"] assert not info[snap["2c"]]["children"] assert snap["3a"] in info assert info[snap["3a"]]["parent"] == snap["2a"] assert snap["3b"] in info[snap["3a"]]["children"] assert snap["3b"] in info assert info[snap["3b"]]["parent"] == snap["3a"] assert snap["3c"] in info[snap["3b"]]["children"] assert snap["3c"] in info assert info[snap["3c"]]["parent"] == snap["3b"] if strict: assert len(info) == 13 assert info[snap["0a"]]["parent"] == "" assert VOLUME_HEAD in info[snap["3c"]]["children"] assert VOLUME_HEAD in info assert info[VOLUME_HEAD]["parent"] == snap["3c"] assert not info[VOLUME_HEAD]["children"] output = cmd.snapshot_ls(address) assert output == '''ID {} {} {} {} {} {} '''.format(snap["3c"], snap["3b"], snap["3a"], snap["2a"], snap["0b"], snap["0a"])
def test_snapshot_rm_rolling(grpc_controller, # NOQA grpc_replica1, grpc_replica2): # NOQA address = grpc_controller.address dev = get_dev(grpc_replica1, grpc_replica2, grpc_controller) existings = {} snap1 = Snapshot(dev, generate_random_data(existings), address) snapList = cmd.snapshot_ls(address) assert snap1.name in snapList cmd.snapshot_rm(address, snap1.name) # cannot do anything because it's the parent of volume head cmd.snapshot_purge(address) wait_for_purge_completion(address) snap2 = Snapshot(dev, generate_random_data(existings), address) info = cmd.snapshot_info(address) assert len(info) == 3 assert snap1.name in info assert snap2.name in info assert info[snap1.name]["removed"] is True assert info[snap2.name]["removed"] is False cmd.snapshot_rm(address, snap2.name) # this should trigger the deletion of snap1 cmd.snapshot_purge(address) wait_for_purge_completion(address) snap2.verify_checksum() snap1.verify_data() snap3 = Snapshot(dev, generate_random_data(existings), address) snap4 = Snapshot(dev, generate_random_data(existings), address) snap5 = Snapshot(dev, generate_random_data(existings), address) snapList = cmd.snapshot_ls(address) assert snap1.name not in snapList assert snap2.name not in snapList assert snap3.name in snapList assert snap4.name in snapList assert snap5.name in snapList info = cmd.snapshot_info(address) assert len(info) == 5 assert snap1.name not in info assert snap2.name in info assert snap3.name in info assert snap4.name in info assert snap5.name in info assert info[snap2.name]["removed"] is True cmd.snapshot_rm(address, snap3.name) cmd.snapshot_rm(address, snap4.name) cmd.snapshot_rm(address, snap5.name) # this should trigger the deletion of snap2 - snap4 # and snap5 marked as removed cmd.snapshot_purge(address) wait_for_purge_completion(address) info = cmd.snapshot_info(address) assert len(info) == 2 assert snap1.name not in info assert snap2.name not in info assert snap3.name not in info assert snap4.name not in info assert snap5.name in info assert info[snap5.name]["removed"] is True snap5.verify_checksum() snap4.verify_data() snap3.verify_data() snap2.verify_data() snap1.verify_data()
def snapshot_mounted_filesystem_test(volume_name, dev, address, engine_name): # NOQA dev_path = dev.dev mnt_path = "/tmp/mnt-" + volume_name test_file = mnt_path + "/test" length = 128 print("dev_path: " + dev_path + "\n") print("mnt_path: " + mnt_path + "\n") # create & mount a ext4 filesystem on dev nsenter_cmd = [ "nsenter", "--mount=/host/proc/1/ns/mnt", "--net=/host/proc/1/ns/net", "--" ] mount_cmd = nsenter_cmd + ["mount", "--make-shared", dev_path, mnt_path] umount_cmd = nsenter_cmd + ["umount", mnt_path] findmnt_cmd = nsenter_cmd + ["findmnt", dev_path] subprocess.check_call(nsenter_cmd + ["mkfs.ext4", dev_path]) subprocess.check_call(nsenter_cmd + ["mkdir", "-p", mnt_path]) subprocess.check_call(mount_cmd) subprocess.check_call(findmnt_cmd) def checksum_test_file(): read_cmd = nsenter_cmd + ["cat", test_file] data = subprocess.check_output(read_cmd) return checksum_data(str(data).encode('utf-8')) def write_test_file(): # beware don't touch this write command data = random_string(length) write_cmd = [ "/bin/sh -c '/bin/echo", '"' + data + '"', ">", test_file + "'" ] shell_cmd = " ".join(nsenter_cmd + write_cmd) subprocess.check_call(shell_cmd, shell=True) return checksum_test_file() # create snapshot1 with empty fs # NOTE: we cannot use checksum_dev since it assumes # asci data for device data instead of raw bytes snap1 = cmd.snapshot_create(address) # create snapshot2 with a new test file test2_checksum = write_test_file() snap2 = cmd.snapshot_create(address) # create snapshot3 overwriting the test file test3_checksum = write_test_file() snap3 = cmd.snapshot_create(address) # verify existence of the snapshots snapshots = cmd.snapshot_ls(address) assert snap1 in snapshots assert snap2 in snapshots assert snap3 in snapshots # unmount the volume, since each revert will shutdown the device subprocess.check_call(umount_cmd) # restore snapshots 1,2,3 & verify filesystem state print("\nsnapshot_revert_with_frontend snap1 begin") snapshot_revert_with_frontend(address, engine_name, snap1) print("snapshot_revert_with_frontend snap1 finish\n") subprocess.check_call(mount_cmd) # should error since the file does not exist in snapshot 1 with pytest.raises(subprocess.CalledProcessError): print("is expected error, since the file does not exist.") checksum_test_file() subprocess.check_call(umount_cmd) print("\nsnapshot_revert_with_frontend snap2 begin") snapshot_revert_with_frontend(address, engine_name, snap2) print("snapshot_revert_with_frontend snap2 finish\n") subprocess.check_call(mount_cmd) assert checksum_test_file() == test2_checksum subprocess.check_call(umount_cmd) print("\nsnapshot_revert_with_frontend snap3 begin") snapshot_revert_with_frontend(address, engine_name, snap3) print("snapshot_revert_with_frontend snap3 finish\n") subprocess.check_call(mount_cmd) assert checksum_test_file() == test3_checksum subprocess.check_call(umount_cmd) # remove the created mount folder subprocess.check_call(nsenter_cmd + ["rmdir", mnt_path])