summaryrefslogtreecommitdiffstats
path: root/tests/functional/dht/test_lookup_dir.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/functional/dht/test_lookup_dir.py')
-rw-r--r--tests/functional/dht/test_lookup_dir.py280
1 files changed, 280 insertions, 0 deletions
diff --git a/tests/functional/dht/test_lookup_dir.py b/tests/functional/dht/test_lookup_dir.py
new file mode 100644
index 000000000..861b91aeb
--- /dev/null
+++ b/tests/functional/dht/test_lookup_dir.py
@@ -0,0 +1,280 @@
+# Copyright (C) 2018-2019 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 lookup directory with subvol down
+"""
+
+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,
+ bring_bricks_online)
+from glustolibs.gluster.brickdir import BrickDir
+from glustolibs.gluster.volume_libs import get_subvols
+from glustolibs.gluster.constants import FILETYPE_DIRS
+from glustolibs.gluster.constants import \
+ TEST_LAYOUT_IS_COMPLETE as LAYOUT_IS_COMPLETE
+from glustolibs.gluster.dht_test_utils import validate_files_in_dir,\
+ find_hashed_subvol, find_nonhashed_subvol
+
+
+@runs_on([['distributed-replicated', 'distributed', 'distributed-dispersed'],
+ ['glusterfs', 'nfs', 'samba']])
+class TestLookupDir(GlusterBaseClass):
+ '''
+ test case: (directory lookup)
+ case -1:
+ - bring down a subvol
+ - create a directory so that it does not hash to down subvol
+ - make sure stat is successful on the dir
+
+ case -2:
+ - create directory
+ - bring down hashed subvol
+ - make sure stat is successful on the dir
+
+ case -3:
+ - create dir
+ - bringdown unhashed subvol
+ - make sure stat is successful on the dir
+ '''
+ # Create Volume and mount according to config file
+ def setUp(self):
+ """
+ Setup and mount volume or raise ExecutionError
+ """
+ GlusterBaseClass.setUp.im_func(self)
+
+ # Setup Volume
+ ret = self.setup_volume_and_mount_volume(self.mounts)
+ if not ret:
+ g.log.error("Failed to Setup and Mount Volume")
+ raise ExecutionError("Failed to Setup and Mount Volume")
+
+ def mkdir_post_hashdown(self, subvols, parent_dir):
+ '''
+ case -1:
+ - bring down a subvol
+ - create a directory so that it does not hash to down subvol
+ - make sure stat is successful on the dir
+ '''
+ # pylint: disable=protected-access
+ # pylint: disable=pointless-string-statement
+ # Find a non hashed subvolume(or brick)
+ nonhashed_subvol, count = find_nonhashed_subvol(subvols, "/", "parent")
+ if nonhashed_subvol is None:
+ g.log.error('Error in finding nonhashed subvol for parent')
+ return False
+
+ # bring nonhashed_subbvol offline
+ ret = bring_bricks_offline(self.volname, subvols[count])
+ if ret == 0:
+ g.log.error('Error in bringing down subvolume %s',
+ subvols[count])
+ return False
+
+ g.log.info('target subvol %s is offline', subvols[count])
+
+ # create parent dir
+ ret, _, err = g.run(self.clients[0], ("mkdir %s" % parent_dir))
+ if ret != 0:
+ g.log.error('mkdir failed for %s err: %s', parent_dir, err)
+ return False
+ g.log.info("mkdir of parent directory %s successful", parent_dir)
+
+ # this confirms both layout and stat of the directory
+ ret = validate_files_in_dir(self.clients[0],
+ self.mounts[0].mountpoint + '/parent_dir',
+ test_type=LAYOUT_IS_COMPLETE,
+ file_type=FILETYPE_DIRS)
+ self.assertTrue(ret, "Layout is not complete")
+ g.log.info('Layout is complete')
+
+ # bring up the subvol
+ ret = bring_bricks_online(self.mnode, self.volname, subvols[count],
+ bring_bricks_online_methods=None)
+ if ret == 0:
+ g.log.error("Error in bringing back subvol online")
+ return False
+
+ g.log.info('Subvol is back online')
+
+ # delete parent_dir
+ ret, _, err = g.run(self.clients[0], ("rmdir %s" % parent_dir))
+ if ret != 0:
+ g.log.error('rmdir failed for %s err: %s', parent_dir, err)
+ g.log.info("rmdir of directory %s successful", parent_dir)
+
+ return True
+
+ def mkdir_before_hashdown(self, subvols, parent_dir):
+ '''
+ case -2:
+ - create directory
+ - bring down hashed subvol
+ - make sure stat is successful on the dir
+ '''
+ # pylint: disable=protected-access
+ # pylint: disable=pointless-string-statement
+ # create parent dir
+ ret, _, err = g.run(self.clients[0], ("mkdir %s" % parent_dir))
+ if ret != 0:
+ g.log.error('mkdir failed for %s err: %s', parent_dir, err)
+ return False
+ g.log.info("mkdir of parent directory %s successful", parent_dir)
+
+ # find hashed subvol
+ hashed_subvol, count = find_hashed_subvol(subvols, "/", "parent")
+ if hashed_subvol is None:
+ g.log.error('Error in finding hash value')
+ return False
+
+ g.log.info("hashed subvol %s", hashed_subvol._host)
+
+ # bring hashed_subvol offline
+ ret = bring_bricks_offline(self.volname, subvols[count])
+ if ret == 0:
+ g.log.error('Error in bringing down subvolume %s', subvols[count])
+ return False
+ g.log.info('target subvol %s is offline', subvols[count])
+
+ # this confirms both layout and stat of the directory
+ ret = validate_files_in_dir(self.clients[0],
+ self.mounts[0].mountpoint + '/parent_dir',
+ test_type=LAYOUT_IS_COMPLETE,
+ file_type=FILETYPE_DIRS)
+ self.assertTrue(ret, "Layout is not complete")
+ g.log.info('Layout is complete')
+
+ # bring up the subvol
+ ret = bring_bricks_online(self.mnode, self.volname, subvols[count],
+ bring_bricks_online_methods=None)
+ if ret == 0:
+ g.log.error("Error in bringing back subvol online")
+ return False
+ g.log.info('Subvol is back online')
+
+ # delete parent_dir
+ ret, _, err = g.run(self.clients[0], ("rmdir %s" % parent_dir))
+ if ret == 0:
+ g.log.error('rmdir failed for %s err: %s', parent_dir, err)
+ g.log.info("rmdir of directory %s successful", parent_dir)
+ return True
+
+ def mkdir_nonhashed_down(self, subvols, parent_dir):
+ '''
+ case -3:
+ - create dir
+ - bringdown a non-hashed subvol
+ - make sure stat is successful on the dir
+ '''
+ # pylint: disable=protected-access
+ # pylint: disable=pointless-string-statement
+ # create parent dir
+ ret, _, err = g.run(self.clients[0], ("mkdir %s" % parent_dir))
+ if ret != 0:
+ g.log.error('mkdir failed for %s err: %s', parent_dir, err)
+ return False
+
+ g.log.info("mkdir of parent directory %s successful", parent_dir)
+
+ # Find a non hashed subvolume(or brick)
+ nonhashed_subvol, count = find_nonhashed_subvol(subvols, "/", "parent")
+ if nonhashed_subvol is None:
+ g.log.error('Error in finding hash value')
+ return False
+
+ # bring nonhashed_subbvol offline
+ ret = bring_bricks_offline(self.volname, subvols[count])
+ if ret == 0:
+ g.log.error('Error in bringing down subvolume %s', subvols[count])
+ return False
+ g.log.info('target subvol %s is offline', subvols[count])
+
+ # this confirms both layout and stat of the directory
+ ret = validate_files_in_dir(self.clients[0],
+ self.mounts[0].mountpoint + '/parent_dir',
+ test_type=LAYOUT_IS_COMPLETE,
+ file_type=FILETYPE_DIRS)
+ self.assertTrue(ret, "Expected - Layout is complete")
+ g.log.info('Layout is complete')
+
+ # bring up the subvol
+ ret = bring_bricks_online(self.mnode, self.volname, subvols[count],
+ bring_bricks_online_methods=None)
+ if ret == 0:
+ g.log.error("Error in bringing back subvol online")
+ return False
+ g.log.info('Subvol is back online')
+
+ # delete parent_dir
+ ret, _, err = g.run(self.clients[0], ("rmdir %s" % parent_dir))
+ if ret != 0:
+ g.log.error('rmdir failed for %s err: %s', parent_dir, err)
+ return False
+ g.log.info("rmdir of directory %s successful", parent_dir)
+ return True
+
+ def test_lookup_dir(self):
+ '''
+ Test directory lookup.
+ '''
+ # pylint: disable=too-many-locals
+ mount_obj = self.mounts[0]
+ mountpoint = mount_obj.mountpoint
+
+ # directory that needs to be created
+ parent_dir = mountpoint + '/parent'
+
+ # calculate hash for name "parent"
+ subvols = (get_subvols(self.mnode, self.volname))['volume_subvols']
+
+ # This populates one brick from one subvolume
+ secondary_bricks = []
+ for subvol in subvols:
+ secondary_bricks.append(subvol[0])
+
+ for subvol in secondary_bricks:
+ g.log.debug("secondary bricks %s", subvol)
+
+ brickobject = []
+ for item in secondary_bricks:
+ temp = BrickDir(item)
+ brickobject.append(temp)
+
+ ret = self.mkdir_post_hashdown(subvols, parent_dir)
+ self.assertTrue(ret, 'mkdir_post_hashdown failed')
+
+ ret = self.mkdir_before_hashdown(subvols, parent_dir)
+ self.assertTrue(ret, 'mkdir_before_hashdown failed')
+
+ ret = self.mkdir_nonhashed_down(subvols, parent_dir)
+ self.assertTrue(ret, 'mkdir_nonhashed_down failed')
+
+ @classmethod
+ def tearDownClass(cls):
+ # Unmount Volume and Cleanup Volume
+ g.log.info("Starting to Unmount Volume and Cleanup Volume")
+ ret = cls.unmount_volume_and_cleanup_volume(mounts=cls.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
+ GlusterBaseClass.tearDownClass.im_func(cls)