summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkshithijiyer <kshithij.ki@gmail.com>2020-03-19 15:07:47 +0530
committerKshithij Iyer <kiyer@redhat.com>2020-03-19 10:11:59 +0000
commit2e567185989009ef0543b38282659c39ca8940f6 (patch)
tree18c9ddff92c10f5502eabe83312d21ec222976e4
parent36418ed2d794ad34dd80d85dbaacac8bcab2cd20 (diff)
[Test+libfix] Add testcase to access of file
Testcase steps: (file access) - rename the file so that the hashed and cached are different - make sure file can be accessed as long as cached is up Fixes a library issue as well in find_new_hashed() Change-Id: Id81264848d6470b9fe477b50290f5ecf917ceda3 Co-authored-by: Susant Palai <spalai@redhat.com> Signed-off-by: Susant Palai <spalai@redhat.com> Signed-off-by: kshithijiyer <kshithij.ki@gmail.com>
-rw-r--r--glustolibs-gluster/glustolibs/gluster/dht_test_utils.py18
-rw-r--r--tests/functional/dht/test_access_file.py172
2 files changed, 187 insertions, 3 deletions
diff --git a/glustolibs-gluster/glustolibs/gluster/dht_test_utils.py b/glustolibs-gluster/glustolibs/gluster/dht_test_utils.py
index 1a62ab241..8cef3015b 100644
--- a/glustolibs-gluster/glustolibs/gluster/dht_test_utils.py
+++ b/glustolibs-gluster/glustolibs/gluster/dht_test_utils.py
@@ -297,11 +297,22 @@ def find_new_hashed(subvols, parent_path, oldname):
g.log.error("could not form brickobject list")
return None
+ for bro in brickobject:
+ bro._get_hashrange()
+ low = bro._hashrange_low
+ high = bro._hashrange_high
+ g.log.debug("low hashrange %s high hashrange %s", str(low), str(high))
+ g.log.debug("absoulte path %s", bro._fqpath)
+
+ hash_num = calculate_hash(brickobject[0]._host, oldname)
oldhashed, _ = find_hashed_subvol(subvols, parent_path, oldname)
if oldhashed is None:
g.log.error("could not find old hashed subvol")
return None
+ g.log.debug("oldhashed: %s oldname: %s oldhash %s", oldhashed._host,
+ oldname, hash_num)
+
count = -1
for item in range(1, 5000, 1):
newhash = calculate_hash(brickobject[0]._host, str(item))
@@ -309,9 +320,10 @@ def find_new_hashed(subvols, parent_path, oldname):
count += 1
ret = brickdir.hashrange_contains_hash(newhash)
if ret == 1:
- g.log.debug("oldhashed %s new %s count %s",
- oldhashed, brickdir._host, str(count))
- return NewHashed(item, brickdir, count)
+ if oldhashed._fqpath != brickdir._fqpath:
+ g.log.debug("oldhashed %s new %s count %s",
+ oldhashed, brickdir._host, str(count))
+ return NewHashed(item, brickdir, count)
count = -1
return None
diff --git a/tests/functional/dht/test_access_file.py b/tests/functional/dht/test_access_file.py
new file mode 100644
index 000000000..ac8074a81
--- /dev/null
+++ b/tests/functional/dht/test_access_file.py
@@ -0,0 +1,172 @@
+# Copyright (C) 2018-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 file access 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.glusterfile import get_file_stat
+from glustolibs.gluster.brick_libs import bring_bricks_offline
+from glustolibs.gluster.brick_libs import bring_bricks_online
+from glustolibs.gluster.volume_libs import get_subvols
+from glustolibs.gluster.dht_test_utils import (
+ find_new_hashed,
+ find_hashed_subvol)
+from glustolibs.gluster.mount_ops import mount_volume, umount_volume
+
+
+@runs_on([['distributed-dispersed', 'distributed', 'distributed-replicated'],
+ ['glusterfs']])
+class TestFileAccessSubvolDown(GlusterBaseClass):
+ """
+ test case: (file access)
+ - rename the file so that the hashed and cached are different
+ - make sure file can be accessed as long as cached is up
+ """
+ # Create Volume and mount according to config file
+ def setUp(self):
+ """
+ Setup and mount volume or raise ExecutionError
+ """
+ self.get_super_method(self, 'setUp')()
+
+ # 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 test_file_access(self):
+ """
+ Test file access.
+ """
+ # pylint: disable=protected-access
+ # pylint: disable=too-many-locals
+ # pylint: disable=too-many-statements
+ mount_obj = self.mounts[0]
+ mountpoint = mount_obj.mountpoint
+
+ # get subvol list
+ subvols = (get_subvols(self.mnode, self.volname))['volume_subvols']
+ self.assertIsNotNone(subvols, "failed to get subvols")
+
+ # create a file
+ srcfile = mountpoint + '/testfile'
+ ret, _, err = g.run(self.clients[0], ("touch %s" % srcfile))
+ self.assertEqual(ret, 0, ("File creation failed for %s err %s",
+ srcfile, err))
+ g.log.info("testfile creation successful")
+
+ # find hashed subvol
+ srchashed, scount = find_hashed_subvol(subvols, "/", "testfile")
+ self.assertIsNotNone(srchashed, "could not find srchashed")
+ g.log.info("hashed subvol for srcfile %s subvol count %s",
+ srchashed._host, str(scount))
+
+ # rename the file such that the new name hashes to a new subvol
+ tmp = find_new_hashed(subvols, "/", "testfile")
+ self.assertIsNotNone(tmp, "could not find new hashed for dstfile")
+ g.log.info("dst file name : %s dst hashed_subvol : %s "
+ "subvol count : %s", tmp.newname,
+ tmp.hashedbrickobject._host, str(tmp.subvol_count))
+
+ dstname = str(tmp.newname)
+ dstfile = mountpoint + "/" + dstname
+ dsthashed = tmp.hashedbrickobject
+ dcount = tmp.subvol_count
+ ret, _, err = g.run(self.clients[0], ("mv %s %s" %
+ (srcfile, dstfile)))
+ self.assertEqual(ret, 0, ("rename failed for %s err %s",
+ srcfile, err))
+ g.log.info("cmd: mv srcfile dstfile successful")
+
+ # check that on dsthash_subvol the file is a linkto file
+ filepath = dsthashed._fqpath + "/" + dstname
+ file_stat = get_file_stat(dsthashed._host, filepath)
+ self.assertEqual(file_stat['access'], "1000", ("Expected file "
+ "permission to be 1000"
+ " on subvol %s",
+ dsthashed._host))
+ g.log.info("dsthash_subvol has the expected linkto file")
+
+ # check on srchashed the file is a data file
+ filepath = srchashed._fqpath + "/" + dstname
+ file_stat = get_file_stat(srchashed._host, filepath)
+ self.assertNotEqual(file_stat['access'], "1000", ("Expected file "
+ "permission not to"
+ "be 1000 on subvol"
+ "%s",
+ srchashed._host))
+
+ # Bring down the hashed subvol of dstfile(linkto file)
+ ret = bring_bricks_offline(self.volname, subvols[dcount])
+ self.assertTrue(ret, ('Error in bringing down subvolume %s',
+ subvols[dcount]))
+ g.log.info('dst subvol %s is offline', subvols[dcount])
+
+ # Need to access the file through a fresh lookup through a new mount
+ # create a new dir(choosing server to do a mount)
+ ret, _, _ = g.run(self.mnode, ("mkdir -p /mnt"))
+ self.assertEqual(ret, 0, ('mkdir of mount dir failed'))
+ g.log.info("mkdir of mount dir succeeded")
+
+ # do a temp mount
+ ret = mount_volume(self.volname, self.mount_type, "/mnt",
+ self.mnode, self.mnode)
+ self.assertTrue(ret, ('temporary mount failed'))
+ g.log.info("temporary mount succeeded")
+
+ # check that file is accessible (stat)
+ ret, _, _ = g.run(self.mnode, ("stat /mnt/%s" % dstname))
+ self.assertEqual(ret, 0, ('stat error on for dst file %s', dstname))
+ g.log.info("stat on /mnt/%s successful", dstname)
+
+ # cleanup temporary mount
+ ret = umount_volume(self.mnode, "/mnt")
+ self.assertTrue(ret, ('temporary mount failed'))
+ g.log.info("umount successful")
+
+ # Bring up the hashed subvol
+ ret = bring_bricks_online(self.mnode, self.volname, subvols[dcount],
+ bring_bricks_online_methods=None)
+ self.assertTrue(ret, "Error in bringing back subvol online")
+ g.log.info('Subvol is back online')
+
+ # now bring down the cached subvol
+ ret = bring_bricks_offline(self.volname, subvols[scount])
+ self.assertTrue(ret, ('Error in bringing down subvolume %s',
+ subvols[scount]))
+ g.log.info('target subvol %s is offline', subvols[scount])
+
+ # file access should fail
+ ret, _, _ = g.run(self.clients[0], ("stat %s" % dstfile))
+ self.assertEqual(ret, 1, ('stat error on for file %s', dstfile))
+ g.log.info("dstfile access failed as expected")
+
+ @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
+ cls.get_super_method(cls, 'tearDownClass')()