From: Venky Shankar Date: Thu, 20 Jun 2019 10:00:40 +0000 (-0400) Subject: test: add basic purge queue validation test X-Git-Tag: v14.2.3~168^2~10 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2004ab53ae41ae4658a596f583ba26625ad50c94;p=ceph.git test: add basic purge queue validation test .. and since we have async subvolume deletes now, check trash directory for emptiness in other tests. Fixes: http://tracker.ceph.com/issues/40036 Signed-off-by: Venky Shankar (cherry picked from commit aec1d90b3611fec19556c9e4c639cb8abf90e4b6) --- diff --git a/qa/tasks/cephfs/mount.py b/qa/tasks/cephfs/mount.py index bcc9aefd8954..1fffaa3ffea4 100644 --- a/qa/tasks/cephfs/mount.py +++ b/qa/tasks/cephfs/mount.py @@ -208,6 +208,22 @@ class CephFSMount(object): return rproc + def wait_for_dir_empty(self, dirname, timeout=30): + i = 0 + dirpath = os.path.join(self.mountpoint, dirname) + while i < timeout: + nr_entries = int(self.getfattr(dirpath, "ceph.dir.entries")) + if nr_entries == 0: + log.debug("Directory {0} seen empty from {1} after {2}s ".format( + dirname, self.client_id, i)) + return + else: + time.sleep(1) + i += 1 + + raise RuntimeError("Timed out after {0}s waiting for {1} to become empty from {2}".format( + i, dirname, self.client_id)) + def wait_for_visible(self, basename="background_file", timeout=30): i = 0 while i < timeout: diff --git a/qa/tasks/cephfs/test_volumes.py b/qa/tasks/cephfs/test_volumes.py index 11857a75a3a6..510d75d7561f 100644 --- a/qa/tasks/cephfs/test_volumes.py +++ b/qa/tasks/cephfs/test_volumes.py @@ -14,6 +14,14 @@ class TestVolumes(CephFSTestCase): TEST_SUBVOLUME_PREFIX="subvolume" TEST_GROUP_PREFIX="group" TEST_SNAPSHOT_PREFIX="snapshot" + TEST_FILE_NAME_PREFIX="subvolume_file" + + # for filling subvolume with data + CLIENTS_REQUIRED = 1 + + # io defaults + DEFAULT_FILE_SIZE = 1 # MB + DEFAULT_NUMBER_OF_FILES = 1024 def _fs_cmd(self, *args): return self.mgr_cluster.mon_manager.raw_cluster_cmd("fs", *args) @@ -51,6 +59,24 @@ class TestVolumes(CephFSTestCase): def _delete_test_volume(self): self._fs_cmd("volume", "rm", self.volname) + def _do_subvolume_io(self, subvolume, number_of_files=DEFAULT_NUMBER_OF_FILES, + file_size=DEFAULT_FILE_SIZE): + # get subvolume path for IO + subvolpath = self._fs_cmd("subvolume", "getpath", self.volname, subvolume) + self.assertNotEqual(subvolpath, None) + subvolpath = subvolpath[1:].rstrip() # remove "/" prefix and any trailing newline + + log.debug("filling subvolume {0} with {1} files each {2}MB size".format(subvolume, number_of_files, file_size)) + for i in range(number_of_files): + filename = "{0}.{1}".format(TestVolumes.TEST_FILE_NAME_PREFIX, i) + self.mount_a.write_n_mb(os.path.join(subvolpath, filename), file_size) + + def _wait_for_trash_empty(self, timeout=30): + # XXX: construct the trash dir path (note that there is no mgr + # [sub]volume interface for this). + trashdir = os.path.join("./", "volumes", "_deleting") + self.mount_a.wait_for_dir_empty(trashdir) + def setUp(self): super(TestVolumes, self).setUp() self.volname = None @@ -83,6 +109,9 @@ class TestVolumes(CephFSTestCase): if ce.exitstatus != errno.ENOENT: raise + # verify trash dir is clean + self._wait_for_trash_empty() + def test_subvolume_create_idempotence(self): # create subvolume subvolume = self._generate_random_subvolume_name() @@ -94,6 +123,9 @@ class TestVolumes(CephFSTestCase): # remove subvolume self._fs_cmd("subvolume", "rm", self.volname, subvolume) + # verify trash dir is clean + self._wait_for_trash_empty() + def test_nonexistent_subvolume_rm(self): # remove non-existing subvolume subvolume = "non_existent_subvolume" @@ -134,6 +166,9 @@ class TestVolumes(CephFSTestCase): # remove subvolume self._fs_cmd("subvolume", "rm", self.volname, subvolume, group) + # verify trash dir is clean + self._wait_for_trash_empty() + # remove group self._fs_cmd("subvolumegroup", "rm", self.volname, group) @@ -285,6 +320,9 @@ class TestVolumes(CephFSTestCase): # remove subvolume self._fs_cmd("subvolume", "rm", self.volname, subvolume) + # verify trash dir is clean + self._wait_for_trash_empty() + def test_subvolume_snapshot_create_idempotence(self): subvolume = self._generate_random_subvolume_name() snapshot = self._generate_random_snapshot_name() @@ -304,6 +342,9 @@ class TestVolumes(CephFSTestCase): # remove subvolume self._fs_cmd("subvolume", "rm", self.volname, subvolume) + # verify trash dir is clean + self._wait_for_trash_empty() + def test_nonexistent_subvolume_snapshot_rm(self): subvolume = self._generate_random_subvolume_name() snapshot = self._generate_random_snapshot_name() @@ -330,6 +371,9 @@ class TestVolumes(CephFSTestCase): # remove subvolume self._fs_cmd("subvolume", "rm", self.volname, subvolume) + # verify trash dir is clean + self._wait_for_trash_empty() + def test_subvolume_snapshot_in_group(self): subvolume = self._generate_random_subvolume_name() group = self._generate_random_group_name() @@ -350,6 +394,9 @@ class TestVolumes(CephFSTestCase): # remove subvolume self._fs_cmd("subvolume", "rm", self.volname, subvolume, group) + # verify trash dir is clean + self._wait_for_trash_empty() + # remove group self._fs_cmd("subvolumegroup", "rm", self.volname, group) @@ -373,6 +420,9 @@ class TestVolumes(CephFSTestCase): # remove subvolume self._fs_cmd("subvolume", "rm", self.volname, subvolume, group) + # verify trash dir is clean + self._wait_for_trash_empty() + # remove group self._fs_cmd("subvolumegroup", "rm", self.volname, group) @@ -399,6 +449,9 @@ class TestVolumes(CephFSTestCase): # remove subvolume self._fs_cmd("subvolume", "rm", self.volname, subvolume, group) + # verify trash dir is clean + self._wait_for_trash_empty() + # remove group self._fs_cmd("subvolumegroup", "rm", self.volname, group) @@ -429,5 +482,27 @@ class TestVolumes(CephFSTestCase): # remove subvolume self._fs_cmd("subvolume", "rm", self.volname, subvolume, group) + # verify trash dir is clean + self._wait_for_trash_empty() + # remove group self._fs_cmd("subvolumegroup", "rm", self.volname, group) + + def test_async_subvolume_rm(self): + subvolume = self._generate_random_subvolume_name() + + # create subvolume + self._fs_cmd("subvolume", "create", self.volname, subvolume) + + # fill subvolume w/ some data + self._do_subvolume_io(subvolume) + + self.mount_a.umount_wait() + + # remove subvolume + self._fs_cmd("subvolume", "rm", self.volname, subvolume) + + self.mount_a.mount() + + # verify trash dir is clean + self._wait_for_trash_empty()