summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPranav <prprakas@redhat.com>2020-05-06 15:48:49 +0530
committerBala Konda Reddy M <bala12352@gmail.com>2020-05-13 12:21:44 +0000
commitcec002f91bee8417e6ff20c3969ccf2853689746 (patch)
tree005f51f8717f24ae1031061a256775379f6c100e
parent83a351ac545831023ff94ed140e31746a39520f7 (diff)
[Test] test rmdir with subvol down
test case: (rmdir with subvol down) case -1: - create parent - bring down a non-hashed subvolume for directory child - create parent/child - rmdir /mnt/parent will fail with ENOTCONN case -2: - create dir1 and dir2 - bring down hashed subvol for dir1 - bring down a non-hashed subvol for dir2 - rmdir dir1 should fail with ENOTCONN - rmdir dir2 should fail with ENOTCONN case -3: - create parent - mkdir parent/child - touch parent/child/file - bringdown a subvol where file is not present - rm -rf parent - Only file should be deleted - rm -rf should fail with ENOTCONN case -4: - Bring down a non-hashed subvol for parent_dir - mkdir parent - rmdir parent should fails with ENOTCONN Change-Id: I8fbd425729aaf04eabfced315f94167178918e31 Co-authored-by: Susant Palai <spalai@redhat.com> Signed-off-by: Susant Palai <spalai@redhat.com> Signed-off-by: Pranav <prprakas@redhat.com>
-rw-r--r--tests/functional/dht/test_rmdir_subvol_down.py361
1 files changed, 361 insertions, 0 deletions
diff --git a/tests/functional/dht/test_rmdir_subvol_down.py b/tests/functional/dht/test_rmdir_subvol_down.py
new file mode 100644
index 000000000..492158551
--- /dev/null
+++ b/tests/functional/dht/test_rmdir_subvol_down.py
@@ -0,0 +1,361 @@
+# Copyright (C) 2020 Red Hat, Inc. <http://www.redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+"""
+Description:
+ Test cases in this module tests directory rmdir with subvol down
+"""
+
+from time import sleep
+from glusto.core import Glusto as g
+from glustolibs.gluster.exceptions import ExecutionError
+from glustolibs.gluster.gluster_base_class import GlusterBaseClass, runs_on
+from glustolibs.gluster.brick_libs import bring_bricks_offline
+from glustolibs.gluster.volume_libs import get_subvols, volume_start
+from glustolibs.gluster.glusterfile import file_exists
+from glustolibs.gluster.dht_test_utils import (find_hashed_subvol,
+ find_nonhashed_subvol,
+ create_brickobjectlist)
+from glustolibs.gluster.dht_test_utils import validate_files_in_dir
+from glustolibs.gluster.constants import FILETYPE_DIRS
+from glustolibs.gluster.constants import (TEST_LAYOUT_IS_COMPLETE as
+ LAYOUT_IS_COMPLETE)
+from glustolibs.gluster.glusterdir import mkdir, rmdir
+from glustolibs.gluster.mount_ops import umount_volume, mount_volume
+
+
+@runs_on([['distributed-replicated', 'distributed',
+ 'distributed-dispersed', 'distributed-arbiter'],
+ ['glusterfs']])
+class TestLookupDir(GlusterBaseClass):
+ # Create Volume and mount according to config file
+ def setUp(self):
+ """
+ Setup and mount volume or raise ExecutionError
+ """
+ self.get_super_method(self, 'setUp')()
+ # Change the dist count to 4 in case of 'distributed-replicated' ,
+ # 'distributed-dispersed' and 'distributed-arbiter'
+ if self.volume_type in ("distributed-replicated",
+ "distributed-dispersed",
+ "distributed-arbiter"):
+ self.volume['voltype']['dist_count'] = 4
+
+ # Setup Volume
+ ret = self.setup_volume_and_mount_volume(self.mounts)
+ if not ret:
+ raise ExecutionError("Failed to Setup and Mount Volume")
+ mount_obj = self.mounts[0]
+ self.mountpoint = mount_obj.mountpoint
+
+ # Collect subvols
+ self.subvols = (get_subvols
+ (self.mnode, self.volname))['volume_subvols']
+
+ def test_rmdir_child_when_nonhash_vol_down(self):
+ """
+ case -1:
+ - create parent
+ - bring down a non-hashed subvolume for directory child
+ - create parent/child
+ - rmdir /mnt/parent will fail with ENOTCONN
+ """
+ # pylint: disable=protected-access
+ # pylint: disable=too-many-statements
+ # pylint: disable=unsubscriptable-object
+ # Find a non hashed subvolume(or brick)
+
+ # Create parent dir
+ parent_dir = self.mountpoint + '/parent'
+ child_dir = parent_dir + '/child'
+ ret = mkdir(self.clients[0], parent_dir)
+ self.assertTrue(ret, "mkdir failed")
+ g.log.info("mkdir of parent directory %s successful", parent_dir)
+
+ # Find a non hashed subvolume(or brick)
+ nonhashed_subvol, count = find_nonhashed_subvol(self.subvols,
+ "parent", "child")
+ self.assertIsNotNone("Error in finding nonhashed value")
+ g.log.info("nonhashed_subvol %s", nonhashed_subvol._host)
+
+ # Bring nonhashed_subbvol offline
+ ret = bring_bricks_offline(self.volname, self.subvols[count])
+ self.assertTrue(ret, ("Error in bringing down subvolume %s"
+ % self.subvols[count]))
+ g.log.info('target subvol %s is offline', self.subvols[count])
+
+ # Create child-dir
+ ret = mkdir(self.clients[0], child_dir)
+ self.assertTrue(ret, ('mkdir failed for %s ' % child_dir))
+ g.log.info("mkdir of child directory %s successful", child_dir)
+
+ # 'rmdir' on parent should fail with ENOTCONN
+ ret = rmdir(self.clients[0], parent_dir)
+ self.assertFalse(ret, ('Expected rmdir to fail for %s' % parent_dir))
+ g.log.info("rmdir of parent directory %s failed as expected",
+ parent_dir)
+
+ # Cleanup
+ # Bring up the subvol - restart volume
+ ret = volume_start(self.mnode, self.volname, force=True)
+ self.assertTrue(ret, "Error in force start the volume")
+ g.log.info('Volume restart success')
+ sleep(10)
+
+ # Delete parent_dir
+ ret = rmdir(self.clients[0], parent_dir, force=True)
+ self.assertTrue(ret, ('rmdir failed for %s ' % parent_dir))
+ g.log.info("rmdir of directory %s successful", parent_dir)
+
+ def test_rmdir_dir_when_hash_nonhash_vol_down(self):
+ """
+ case -2:
+ - create dir1 and dir2
+ - bring down hashed subvol for dir1
+ - bring down a non-hashed subvol for dir2
+ - rmdir dir1 should fail with ENOTCONN
+ - rmdir dir2 should fail with ENOTCONN
+ """
+ # pylint: disable=protected-access
+ # pylint: disable=too-many-statements
+ # pylint: disable=unsubscriptable-object
+
+ # Create dir1 and dir2
+ directory_list = []
+ for number in range(1, 3):
+ directory_list.append('{}/dir{}'.format(self.mountpoint, number))
+ ret = mkdir(self.clients[0], directory_list[-1])
+ self.assertTrue(ret, ('mkdir failed for %s '
+ % directory_list[-1]))
+ g.log.info("mkdir of directory %s successful",
+ directory_list[-1])
+
+ # Find a non hashed subvolume(or brick)
+ nonhashed_subvol, count = find_nonhashed_subvol(self.subvols, "/",
+ "dir1")
+ self.assertIsNotNone(nonhashed_subvol,
+ "Error in finding nonhashed value")
+ g.log.info("nonhashed_subvol %s", nonhashed_subvol._host)
+
+ # Bring nonhashed_subbvol offline
+ ret = bring_bricks_offline(self.volname, self.subvols[count])
+ self.assertTrue(ret, ('Error in bringing down subvolume %s'
+ % self.subvols[count]))
+ g.log.info('target subvol %s is offline', self.subvols[count])
+
+ # 'rmdir' on dir1 should fail with ENOTCONN
+ ret = rmdir(self.clients[0], directory_list[0])
+ self.assertFalse(ret, ('Expected rmdir to fail for %s'
+ % directory_list[0]))
+ g.log.info("rmdir of directory %s failed as expected",
+ directory_list[0])
+
+ # Bring up the subvol - restart volume
+ ret = volume_start(self.mnode, self.volname, force=True)
+ self.assertTrue(ret, "Error in force start the volume")
+ g.log.info('Volume restart success')
+ sleep(10)
+
+ # Unmounting and Mounting the volume back to Heal
+ ret, _, err = umount_volume(self.clients[1], self.mountpoint)
+ self.assertFalse(ret, "Error in creating temp mount %s" % err)
+
+ ret, _, err = mount_volume(self.volname,
+ mtype='glusterfs',
+ mpoint=self.mountpoint,
+ mserver=self.servers[0],
+ mclient=self.clients[1])
+ self.assertFalse(ret, "Error in creating temp mount")
+
+ ret, _, _ = g.run(self.clients[1], ("ls %s/dir1" % self.mountpoint))
+ self.assertEqual(ret, 0, "Error in lookup for dir1")
+ g.log.info("lookup successful for dir1")
+
+ # This confirms that healing is done on dir1
+ ret = validate_files_in_dir(self.clients[0],
+ directory_list[0],
+ test_type=LAYOUT_IS_COMPLETE,
+ file_type=FILETYPE_DIRS)
+ self.assertTrue(ret, "validate_files_in_dir for dir1 failed")
+ g.log.info("healing successful for dir1")
+
+ # Bring down the hashed subvol
+ # Find a hashed subvolume(or brick)
+ hashed_subvol, count = find_hashed_subvol(self.subvols, "/", "dir2")
+ self.assertIsNotNone(hashed_subvol,
+ "Error in finding nonhashed value")
+ g.log.info("hashed_subvol %s", hashed_subvol._host)
+
+ # Bring hashed_subbvol offline
+ ret = bring_bricks_offline(self.volname, self.subvols[count])
+ self.assertTrue(ret, ('Error in bringing down subvolume %s',
+ self.subvols[count]))
+ g.log.info('target subvol %s is offline', self.subvols[count])
+
+ # 'rmdir' on dir2 should fail with ENOTCONN
+ ret = rmdir(self.clients[0], directory_list[1])
+ self.assertFalse(ret, ('Expected rmdir to fail for %s'
+ % directory_list[1]))
+ g.log.info("rmdir of dir2 directory %s failed as expected",
+ directory_list[1])
+
+ # Cleanup
+ # Bring up the subvol - restart the volume
+ ret = volume_start(self.mnode, self.volname, force=True)
+ self.assertTrue(ret, "Error in force start the volume")
+ g.log.info('Volume restart success')
+ sleep(10)
+
+ # Delete dirs
+ for directory in directory_list:
+ ret = rmdir(self.clients[0], directory)
+ self.assertTrue(ret, ('rmdir failed for %s ' % directory))
+ g.log.info("rmdir of directory %s successful", directory)
+
+ def test_rm_file_when_nonhash_vol_down(self):
+ """
+ case -3:
+ - create parent
+ - mkdir parent/child
+ - touch parent/child/file
+ - bringdown a subvol where file is not present
+ - rm -rf parent
+ - Only file should be deleted
+ - rm -rf of parent should fail with ENOTCONN
+ """
+ # pylint: disable=protected-access
+ # pylint: disable=too-many-statements
+ # pylint: disable=unsubscriptable-object
+
+ # Find a non hashed subvolume(or brick)
+ # Create parent dir
+ parent_dir = self.mountpoint + '/parent'
+ child_dir = parent_dir + '/child'
+ ret = mkdir(self.clients[0], parent_dir)
+ self.assertTrue(ret, ('mkdir failed for %s ' % parent_dir))
+ g.log.info("mkdir of parent directory %s successful", parent_dir)
+
+ # Create child dir
+ ret = mkdir(self.clients[0], child_dir)
+ self.assertTrue(ret, ('mkdir failed for %s ' % child_dir))
+ g.log.info("mkdir of child directory %s successful", child_dir)
+
+ # Create a file under child_dir
+ file_one = child_dir + '/file_one'
+ ret, _, err = g.run(self.clients[0], ("touch %s" % file_one))
+ self.assertFalse(ret, ('touch failed for %s err: %s' %
+ (file_one, err)))
+
+ # Find a non hashed subvolume(or brick)
+ nonhashed_subvol, count = find_nonhashed_subvol(self.subvols,
+ "parent/child",
+ "file_one")
+ self.assertIsNotNone(nonhashed_subvol,
+ "Error in finding nonhashed value")
+ g.log.info("nonhashed_subvol %s", nonhashed_subvol._host)
+
+ # Bring nonhashed_subbvol offline
+ ret = bring_bricks_offline(self.volname, self.subvols[count])
+ self.assertTrue(ret, ('Error in bringing down subvolume %s'
+ % self.subvols[count]))
+ g.log.info('target subvol %s is offline', self.subvols[count])
+
+ # 'rm -rf' on parent should fail with ENOTCONN
+ ret = rmdir(self.clients[0], parent_dir)
+ self.assertFalse(ret, ('Expected rmdir to fail for %s' % parent_dir))
+ g.log.info("rmdir of parent directory %s failed as expected"
+ " with err %s", parent_dir, err)
+
+ brickobject = create_brickobjectlist(self.subvols, "parent/child")
+ self.assertIsNotNone(brickobject,
+ "could not create brickobject list")
+ # Make sure file_one is deleted
+ for brickdir in brickobject:
+ dir_path = "%s/parent/child/file_one" % brickdir.path
+ brick_path = dir_path.split(":")
+ self.assertTrue((file_exists(brickdir._host, brick_path[1])) == 0,
+ ('Expected file %s not to exist on servers'
+ % parent_dir))
+ g.log.info("file is deleted as expected")
+
+ # Cleanup
+ # Bring up the subvol - restart volume
+ ret = volume_start(self.mnode, self.volname, force=True)
+ self.assertTrue(ret, "Error in force start the volume")
+ g.log.info('Volume restart success.')
+ sleep(10)
+
+ # Delete parent_dir
+ ret = rmdir(self.clients[0], parent_dir, force=True)
+ self.assertTrue(ret, ('rmdir failed for %s ' % parent_dir))
+ g.log.info("rmdir of directory %s successful", parent_dir)
+
+ def test_rmdir_parent_pre_nonhash_vol_down(self):
+ """
+ case -4:
+ - Bring down a non-hashed subvol for parent_dir
+ - mkdir parent
+ - rmdir parent should fails with ENOTCONN
+ """
+ # pylint: disable=protected-access
+ # pylint: disable=too-many-statements
+ # pylint: disable=unsubscriptable-object
+
+ nonhashed_subvol, count = find_nonhashed_subvol(self.subvols,
+ "/", "parent")
+ self.assertIsNotNone(nonhashed_subvol,
+ 'Error in finding nonhashed subvol')
+ g.log.info("nonhashed subvol %s", nonhashed_subvol._host)
+
+ # Bring nonhashed_subbvol offline
+ ret = bring_bricks_offline(self.volname, self.subvols[count])
+ self.assertTrue(ret, ('Error in bringing down subvolume %s'
+ % self.subvols[count]))
+ g.log.info('target subvol %s is offline', self.subvols[count])
+
+ parent_dir = self.mountpoint + '/parent'
+ ret = mkdir(self.clients[0], parent_dir)
+ self.assertTrue(ret, ('mkdir failed for %s ' % parent_dir))
+ g.log.info("mkdir of parent directory %s successful", parent_dir)
+
+ # 'rmdir' on parent should fail with ENOTCONN
+ ret = rmdir(self.clients[0], parent_dir)
+ self.assertFalse(ret, ('Expected rmdir to fail for %s' % parent_dir))
+ g.log.info("rmdir of parent directory %s failed as expected",
+ parent_dir)
+
+ # Cleanup
+ # Bring up the subvol - restart volume
+ ret = volume_start(self.mnode, self.volname, force=True)
+ self.assertTrue(ret, "Error in force start the volume")
+ g.log.info('Volume restart success.')
+ sleep(10)
+
+ # Delete parent_dir
+ ret = rmdir(self.clients[0], parent_dir, force=True)
+ self.assertTrue(ret, ('rmdir failed for %s ' % parent_dir))
+ g.log.info("rmdir of directory %s successful", parent_dir)
+
+ def tearDown(self):
+ """
+ Unmount Volume and Cleanup Volume
+ """
+ ret = self.unmount_volume_and_cleanup_volume(mounts=self.mounts)
+ if not ret:
+ raise ExecutionError("Failed to Unmount Volume and Cleanup Volume")
+ g.log.info("Successful in Unmount Volume and Cleanup Volume")
+
+ # Calling GlusterBaseClass tearDown
+ self.get_super_method(self, 'tearDown')()