From 23e5ecbdbb4b37c6c6666ff6b2d6d057c266fd15 Mon Sep 17 00:00:00 2001 From: Yaniv Kaul Date: Thu, 5 Jul 2018 23:01:11 +0300 Subject: Tests: ensure volume deletion works when intended. It could have failed without anyone noticing. Added 'xfail' - do we expect to fail in deletion (and changed tests accordingly) On the way, ensure stdout and stderr are logged in case of such failures. Change-Id: Ibdf7a43cadb0393707a6c68c19a664453a971eb1 Signed-off-by: Yaniv Kaul --- .../glustolibs/gluster/volume_ops.py | 59 +++++++++++++++++----- tests/functional/glusterd/test_peer_probe.py | 9 ++-- .../functional/glusterd/test_volume_operations.py | 46 +++++++++-------- 3 files changed, 77 insertions(+), 37 deletions(-) diff --git a/glustolibs-gluster/glustolibs/gluster/volume_ops.py b/glustolibs-gluster/glustolibs/gluster/volume_ops.py index 6cf038dbf..4302f2780 100644 --- a/glustolibs-gluster/glustolibs/gluster/volume_ops.py +++ b/glustolibs-gluster/glustolibs/gluster/volume_ops.py @@ -200,7 +200,7 @@ def volume_stop(mnode, volname, force=False): return g.run(mnode, cmd) -def volume_delete(mnode, volname): +def volume_delete(mnode, volname, xfail=False): """Deletes the gluster volume if given volume exists in gluster and deletes the directories in the bricks associated with the given volume @@ -208,6 +208,7 @@ def volume_delete(mnode, volname): Args: mnode (str): Node on which cmd has to be executed. volname (str): volume name + xfail (bool): expect to fail (non existent volume, etc.) Returns: bool: True, if volume is deleted @@ -217,10 +218,20 @@ def volume_delete(mnode, volname): volume_delete("abc.xyz.com", "testvol") """ - volinfo = get_volume_info(mnode, volname) + volinfo = get_volume_info(mnode, volname, xfail) if volinfo is None or volname not in volinfo: - g.log.info("Volume %s does not exist in %s" % (volname, mnode)) - return True + if xfail: + g.log.info( + "Volume {} does not exist in {}" + .format(volname, mnode) + ) + return True + else: + g.log.error( + "Unexpected: volume {} does not exist in {}" + .format(volname, mnode) + ) + return False if volinfo[volname]['typeStr'] == 'Tier': tmp_hot_brick = volinfo[volname]["bricks"]["hotBricks"]["brick"] @@ -231,14 +242,32 @@ def volume_delete(mnode, volname): else: bricks = [x["name"] for x in volinfo[volname]["bricks"]["brick"] if "name" in x] - ret, _, _ = g.run(mnode, "gluster volume delete %s --mode=script" - % volname) + ret, out, err = g.run(mnode, "gluster volume delete {} --mode=script" + .format(volname)) if ret != 0: - return False + if xfail: + g.log.info( + "Volume {} deletion failed - as expected" + .format(volname) + ) + return True + else: + g.log.error( + "Unexpected: volume {} deletion failed: {} ({} : {})" + .format(volname, ret, out, err) + ) + return False for brick in bricks: node, vol_dir = brick.split(":") - ret = g.run(node, "rm -rf %s" % vol_dir) + ret, out, err = g.run(node, "rm -rf %s" % vol_dir) + if ret != 0: + if not xfail: + g.log.err( + "Unexpected: rm -rf {} failed ({}: {})" + .format(vol_dir, out, err) + ) + return False return True @@ -281,12 +310,11 @@ def volume_status(mnode, volname='all', service='', options=''): Args: mnode (str): Node on which cmd has to be executed. - volname (str): volume name Kwargs: volname (str): volume name. Defaults to 'all' service (str): name of the service to get status. - serivce can be, [nfs|shd||quotad]], If not given, + service can be, [nfs|shd||quotad]], If not given, the function returns all the services options (str): options can be, [detail|clients|mem|inode|fd|callpool|tasks]. If not given, @@ -594,12 +622,13 @@ def volume_info(mnode, volname='all'): return g.run(mnode, cmd) -def get_volume_info(mnode, volname='all'): +def get_volume_info(mnode, volname='all', xfail=False): """Fetches the volume information as displayed in the volume info. Uses xml output of volume info and parses the into to a dict Args: mnode (str): Node on which cmd has to be executed. + xfail (bool): Expect failure to get volume info Kwargs: volname (str): volume name. Defaults to 'all' @@ -635,9 +664,13 @@ def get_volume_info(mnode, volname='all'): """ cmd = "gluster volume info %s --xml" % volname - ret, out, _ = g.run(mnode, cmd, log_level='DEBUG') + ret, out, err = g.run(mnode, cmd, log_level='DEBUG') if ret != 0: - g.log.error("volume info returned error") + if not xfail: + g.log.error( + "Unexpected: volume info {} returned error ({} : {})" + .format(volname, out, err) + ) return None root = etree.XML(out) volinfo = {} diff --git a/tests/functional/glusterd/test_peer_probe.py b/tests/functional/glusterd/test_peer_probe.py index a3fe5240d..242681343 100644 --- a/tests/functional/glusterd/test_peer_probe.py +++ b/tests/functional/glusterd/test_peer_probe.py @@ -226,10 +226,11 @@ class TestPeerProbe(GlusterBaseClass): g.log.info("Volume %s start with force is success", self.volname) # Volume delete should fail without stopping volume - ret = volume_delete(self.servers[2], self.volname) - self.assertFalse(ret, ("Unexpected Error: Volume deleted " - "successfully without stopping" - "volume %s", self.volname)) + self.assertTrue( + volume_delete(self.servers[2], self.volname, xfail=True), + "Unexpected Error: Volume deleted " + "successfully without stopping volume" + ) g.log.info("Expected: volume delete should fail without " "stopping volume: %s", self.volname) diff --git a/tests/functional/glusterd/test_volume_operations.py b/tests/functional/glusterd/test_volume_operations.py index fc8d8b0b6..47807c6f9 100644 --- a/tests/functional/glusterd/test_volume_operations.py +++ b/tests/functional/glusterd/test_volume_operations.py @@ -179,11 +179,12 @@ class TestVolumeCreate(GlusterBaseClass): g.log.info("Stopping a non existing volume is failed") # Deleting a non existing volume should fail - ret = volume_delete(self.mnode, "no_vol") - self.assertTrue(ret, "Expected: It should fail to delete a " - "non existing volume. Actual:Successfully deleted " - "a non existing volume") - g.log.info("Deleting a non existing volume is failed") + self.assertTrue( + volume_delete(self.mnode, "no_vol", xfail=True), + "Expected: It should fail to delete a " + "non existing volume. Actual:Successfully deleted " + "a non existing volume" + ) # Detach a server and try to create volume with node # which is not in cluster @@ -220,11 +221,14 @@ class TestVolumeCreate(GlusterBaseClass): g.log.info("Starting a already started volume is Failed.") # Deleting a volume without stopping should fail - ret = volume_delete(self.mnode, self.volname) - self.assertFalse(ret, ("Expected: It should fail to delete a volume" - " without stopping. Actual: Successfully " - "deleted a volume without stopping it")) - g.log.error("Failed to delete a volume without stopping it") + self.assertTrue( + volume_delete(self.mnode, self.volname, xfail=True), + "Expected: It should fail to delete a volume" + " without stopping. Actual: Successfully " + "deleted a volume without stopping it" + ) + g.log.info("Expected: volume delete should fail without " + "stopping volume: %s", self.volname) # Stopping a volume should succeed ret, _, _ = volume_stop(self.mnode, self.volname) @@ -239,16 +243,18 @@ class TestVolumeCreate(GlusterBaseClass): g.log.info("Volume stop is failed on already stopped volume") # Deleting a volume should succeed - ret = volume_delete(self.mnode, self.volname) - self.assertTrue(ret, ("Volume delete is failed")) - g.log.info("Volume delete is success") - - # Deleting a non existing volume should fail - ret = volume_delete(self.mnode, self.volname) - self.assertTrue(ret, "Expected: It should fail to delete a non " - "existing volume. Actual:Successfully deleted a " - "non existing volume") - g.log.info("Volume delete is failed for non existing volume") + self.assertTrue( + volume_delete(self.mnode, self.volname), + "Volume delete is failed" + ) + + # Deleting an already deleted volume should fail + self.assertTrue( + volume_delete(self.mnode, self.volname, xfail=True), + "Expected: It should fail to delete an " + "already deleted volume. Actual:Successfully " + "deleted an already deleted volume" + ) # Volume info command should succeed ret = get_volume_info(self.mnode) -- cgit