diff options
Diffstat (limited to 'tests/functional/multiplex')
-rw-r--r-- | tests/functional/multiplex/__init__.py | 0 | ||||
-rw-r--r-- | tests/functional/multiplex/test_cli_reset_commands_behaviour.py | 213 | ||||
-rwxr-xr-x | tests/functional/multiplex/test_enabling_brick_mux.py | 252 |
3 files changed, 465 insertions, 0 deletions
diff --git a/tests/functional/multiplex/__init__.py b/tests/functional/multiplex/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/functional/multiplex/__init__.py diff --git a/tests/functional/multiplex/test_cli_reset_commands_behaviour.py b/tests/functional/multiplex/test_cli_reset_commands_behaviour.py new file mode 100644 index 000000000..5048f7860 --- /dev/null +++ b/tests/functional/multiplex/test_cli_reset_commands_behaviour.py @@ -0,0 +1,213 @@ +# Copyright (C) 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 3 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. + +from time import sleep +from glusto.core import Glusto as g +from glustolibs.gluster.gluster_base_class import (GlusterBaseClass, runs_on) +from glustolibs.gluster.exceptions import ExecutionError +from glustolibs.gluster.brickmux_ops import ( + disable_brick_mux, is_brick_mux_enabled, + enable_brick_mux, get_brick_mux_status, + check_brick_pid_matches_glusterfsd_pid, get_brick_processes_count) +from glustolibs.gluster.volume_libs import setup_volume, cleanup_volume +from glustolibs.gluster.volume_ops import (get_volume_list, + volume_stop, + get_volume_options, + volume_start) + + +@runs_on([['replicated'], ['glusterfs']]) +class TestBrickMultiplexingResetCommand(GlusterBaseClass): + """ + Tests for brick multiplexing reset command + """ + def setUp(self): + # Calling GlusterBaseClass setUp + self.get_super_method(self, 'setUp')() + + # Enable brick multiplexing + g.log.info("Checking for brick multiplexing status...") + if not is_brick_mux_enabled(self.mnode): + g.log.info("Enabling brick multiplexing...") + if not enable_brick_mux(self.mnode): + raise ExecutionError("Failed to enable brick multiplexing") + g.log.info("Enabled brick multiplexing successfully") + + def tearDown(self): + # Stopping all volumes + g.log.info("Starting to Cleanup all Volumes") + volume_list = get_volume_list(self.mnode) + for volume in volume_list: + ret = cleanup_volume(self.mnode, volume) + if not ret: + raise ExecutionError("Failed to cleanup Volume %s" % volume) + g.log.info("Volume: %s cleanup is done", volume) + g.log.info("Successfully Cleanedup all Volumes") + + # Disable brick multiplexing + g.log.info("Checking for brick multiplexing status...") + if is_brick_mux_enabled(self.mnode): + g.log.info("Disabling brick multiplexing...") + if not disable_brick_mux(self.mnode): + raise ExecutionError("Failed to disable brick multiplexing") + g.log.info("Disabled brick multiplexing successfully") + + # Calling GlusterBaseClass teardown + self.get_super_method(self, 'tearDown')() + + def use_config_setup_volumes(self): + """ + A function to setup volumes based on volume_configs. + """ + for volume_config in self.volume_configs: + ret = setup_volume(mnode=self.mnode, + all_servers_info=self.all_servers_info, + volume_config=volume_config, + force=False) + if not ret: + raise ExecutionError("Failed to setup Volume %s" + % volume_config['name']) + g.log.info("Successful in setting volume %s", + volume_config['name']) + + def test_cli_reset_commands_behaviour(self): + """ + 1. Set cluster.brick-multiplex to enabled. + 2. Create and start 2 volumes of type 1x3 and 2x3. + 3. Check if cluster.brick-multiplex is enabled. + 4. Reset the cluster using "gluster v reset all". + 5. Check if cluster.brick-multiplex is disabled. + 6. Create a new volume of type 2x3. + 7. Set cluster.brick-multiplex to enabled. + 8. Stop and start all three volumes. + 9. Check the if pids match and check if more + than one pids of glusterfsd is present. + """ + # pylint: disable=too-many-statements + # Setup Volumes + self.volume_configs = [] + + # Define volumes to create + # Define replicated volume + self.volume['voltype'] = { + 'type': 'replicated', + 'replica_count': 3, + 'transport': 'tcp'} + + volume_config = {'name': '%s' % self.volume['voltype']['type'], + 'servers': self.servers, + 'voltype': self.volume['voltype']} + self.volume_configs.append(volume_config) + + # Define 2x3 distributed-replicated volume + self.volume['voltype'] = { + 'type': 'distributed-replicated', + 'dist_count': 2, + 'replica_count': 3, + 'transport': 'tcp'} + + volume_config = {'name': '%s' % self.volume['voltype']['type'], + 'servers': self.servers, + 'voltype': self.volume['voltype']} + self.volume_configs.append(volume_config) + + # Create volumes using the config. + self.use_config_setup_volumes() + + # Check if volume option cluster.brick-multiplex is enabled + volume_list = get_volume_list(self.mnode) + for volume in volume_list: + options_dict = get_volume_options(self.mnode, volume) + self.assertEqual(options_dict['cluster.brick-multiplex'], 'enable', + 'Option brick-multiplex is not enabled') + g.log.info('Option brick-multiplex is enabled for volume %s', + volume) + + # Reset cluster + g.log.info("Reset cluster...") + cmd = 'gluster v reset all' + ret, _, _ = g.run(self.mnode, cmd) + self.assertFalse(ret, "Failed on reset cluster") + g.log.info("Successfully reset cluster") + + # Check if brick-multiplex is disabled + g.log.info("Checking for brick multiplexing status...") + self.assertEqual('disable', get_brick_mux_status(self.mnode), + "Brick multiplexing status is not 'disable'") + g.log.info("Brick multiplexing status is 'disable'") + + # Create new distributed-replicated volume + # Define new 2x3 distributed-replicated volume + new_vol = 'new_vol' + self.volume['voltype'] = { + 'type': 'distributed-replicated', + 'dist_count': 2, + 'replica_count': 3, + 'transport': 'tcp'} + + volume_config = {'name': '%s' % new_vol, + 'servers': self.servers, + 'voltype': self.volume['voltype']} + self.volume_configs.append(volume_config) + + # Create volumes using the config. + self.use_config_setup_volumes() + + # Resetting brick-mux back to enabled. + g.log.info("Enabling brick multiplexing...") + if not enable_brick_mux(self.mnode): + raise ExecutionError("Failed to enable brick multiplexing") + g.log.info("Enabled brick multiplexing successfully") + + # Restart all volumes + g.log.info("Restarting all volumes...") + volume_list = get_volume_list(self.mnode) + for volume in volume_list: + # Stop the volume + g.log.info("Stopping volume %s...", volume) + ret, _, err = volume_stop(self.mnode, volume) + self.assertFalse(ret, "Failed on stopping volume %s: %s" + % (volume, err)) + g.log.info("Stopped %s successfully", volume) + + # Sleeping for 2 seconds between stop and start. + sleep(2) + + # Start the volume + g.log.info("Starting volume %s...", volume) + ret, _, err = volume_start(self.mnode, volume) + self.assertFalse(ret, "Failed on starting volume %s: %s" + % (volume, err)) + g.log.info("Started %s successfully", volume) + g.log.info("Restarted all volumes successfully") + + # Check if bricks pid don`t match glusterfsd pid + g.log.info("Checking if bricks pid don`t match glusterfsd pid...") + for volume in volume_list: + g.log.info("Checking if bricks pid don`t match glusterfsd pid " + "for %s volume...", volume) + self.assertTrue( + check_brick_pid_matches_glusterfsd_pid(self.mnode, volume), + "Bricks pid match glusterfsd pid for %s volume..." % volume) + g.log.info("Bricks pid don`t match glusterfsd pid " + "for %s volume...", volume) + + # Checking if the number of glusterfsd is more than one + for server in self.servers: + ret = get_brick_processes_count(server) + self.assertEqual(ret, 1, + "Number of glusterfsd is more than one.") + g.log.info("Only one glusterfsd found on all the nodes.") diff --git a/tests/functional/multiplex/test_enabling_brick_mux.py b/tests/functional/multiplex/test_enabling_brick_mux.py new file mode 100755 index 000000000..395de3b25 --- /dev/null +++ b/tests/functional/multiplex/test_enabling_brick_mux.py @@ -0,0 +1,252 @@ +# Copyright (C) 2019-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. + +from random import choice +import string +from glusto.core import Glusto as g +from glustolibs.gluster.gluster_base_class import (GlusterBaseClass, runs_on) +from glustolibs.gluster.exceptions import ExecutionError +from glustolibs.gluster.brickmux_ops import (disable_brick_mux, + is_brick_mux_enabled, + get_brick_mux_status, + enable_brick_mux) +from glustolibs.gluster.lib_utils import search_pattern_in_file +from glustolibs.gluster.volume_ops import (set_volume_options, + reset_volume_option) + + +@runs_on([['replicated'], + ['glusterfs']]) +class TestBrickMultiplexing(GlusterBaseClass): + """ + Tests for brick multiplexing statuses + """ + def tearDown(self): + # Disable brick multiplexing + g.log.info("Checking for brick multiplexing status...") + if is_brick_mux_enabled(self.mnode): + g.log.info("Disabling brick multiplexing...") + if not disable_brick_mux(self.mnode): + raise ExecutionError("Failed to disable brick multiplexing") + g.log.info("Disabled brick multiplexing successfully") + + ret, _, _ = reset_volume_option(self.mnode, "all", "all") + if ret: + raise ExecutionError("Unable to reset all volume options") + g.log.info("Successfully reset all the volume options.") + + # Calling GlusterBaseClass teardown + self.get_super_method(self, 'tearDown')() + + @staticmethod + def get_random_string(chars, str_len=4): + return ''.join((choice(chars) for _ in range(str_len))) + + def test_enabling_brick_mux(self): + """ + Test case: + - check if brick multiplex is disable by default + - check for warning message triggering by setting brick-multiplex and + choosing 'n' in y/n + - check if brick multiplex is disabled after triggering warning message + - check brick multiplex for all possible statuses + (positive and negative) + - check for brick multiplex status in /var/lib/glusterd/options file + """ + # Check if brickmux is disabled by default + g.log.info('Checking if brick multiplex operation is disabled...') + self.assertFalse(is_brick_mux_enabled(self.mnode), + "Brick multiplex is not disabled by default") + + # Check for warning message while changing status + warning_message = ("Brick-multiplexing is supported only for " + "OCS converged or independent mode. Also it is " + "advised to make sure that either all volumes are " + "in stopped state or no bricks are running before " + "this option is modified." + "Do you still want to continue? (y/n)") + + g.log.info('Triggering warning message...') + cmd = "gluster v set all cluster.brick-multiplex enable" + _, out, _ = g.run(self.mnode, cmd) + + g.log.info('Checking for warning message in output...') + if "volume set: success" not in out: + self.assertIn(warning_message, out, + 'There is no warning message in ' + 'output or message is incorrect.') + g.log.info('Warning message is correct.') + + else: + g.log.info('Skipped warning message check.') + + # If brick-mux is enabled then disabling it. + if is_brick_mux_enabled(self.mnode): + if not disable_brick_mux(self.mnode): + g.log.info("Disabling brick multiplexing as it" + " was enabled due to no warning message.") + + # Check if brickmux is still disabled + g.log.info('Checking if brick multiplex is still disabled') + self.assertFalse(is_brick_mux_enabled(self.mnode), + "Brick multiplex operation is not disabled") + + # Enable brick multiplex with all possible statuses + statuses = ['on', 'enable', '1', 'true', + 'off', 'disable', '0', 'false'] + for status in statuses: + g.log.info('Enabling brick multiplex with %s status...', + status) + cmd = ("yes | gluster v set all cluster.brick-multiplex %s" + % status) + _, out, _ = g.run(self.mnode, cmd) + self.assertIn('success', out, + 'Failed on enabling brick multiplexing') + + # Check if brick multiplex status is correct + g.log.info('Checking if brick multiplexing status is correct...') + gluster_status = get_brick_mux_status(self.mnode) + self.assertEqual(status, gluster_status, + "Brick multiplex status is not correct") + g.log.info('Brick multiplex status "%s" is correct', + status) + + # Check for brick multiplexing status in file 'options' + g.log.info("Checking for brick multiplexing status '%s' in file " + "'/var/lib/glusterd/options'...", status) + search_pattern = 'cluster.brick-multiplex=%s' % status + self.assertTrue(search_pattern_in_file(self.mnode, search_pattern, + '/var/lib/glusterd/options', + '', '')) + g.log.info("Brick multiplexing status '%s' in file " + "'/var/lib/glusterd/options' is correct", status) + + # Check brick multiplex with incorrect status + g.log.info('Checking brick multiplex with incorrect status...') + cmd = "yes | gluster v set all cluster.brick-multiplex incorrect" + ret, _, _ = g.run(self.mnode, cmd) + self.assertEqual(ret, 1, 'Incorrect status has passed') + + def test_enabling_brick_mux_with_wrong_values(self): + """ + Test Case: + - Create a gluster cluster + - Set cluster.brick-multiplex value to random string(Must fail) + - Set cluster.brick-multiplex value to random int(Must fail) + - Set cluster.brick-multiplex value to random + special characters(Must fail) + """ + # Creation of random data for cluster.brick-multiplex option + # Data has: alphabets, numbers, punctuations and their combinations + key = 'cluster.brick-multiplex' + for char_type in (string.ascii_letters, string.punctuation, + string.printable, string.digits): + + temp_val = self.get_random_string(char_type) + value = "{}".format(temp_val) + ret = set_volume_options(self.mnode, 'all', {key: value}) + self.assertFalse(ret, "Unexpected: Erroneous value {}, to option " + "{} should result in failure".format(value, key)) + g.log.info("Expected: Erroneous value %s, to option " + "%s resulted in failure", value, key) + + def set_max_brick_process_to_string(self): + """Set cluster.max-bricks-per-process to string""" + key = 'cluster.max-bricks-per-process' + for char_type in (string.ascii_letters, string.punctuation): + + temp_val = self.get_random_string(char_type) + value = "{}".format(temp_val) + ret = set_volume_options(self.mnode, 'all', {key: value}) + self.assertFalse(ret, "Unexpected: Erroneous value {}, to option " + "{} should result in failure".format(value, key)) + g.log.info("Expected: Erroneous value %s, to option " + "%s resulted in failure", value, key) + + def test_enable_brick_mux_with_max_bricks_per_process(self): + """ + Test Case: + - Create a gluster cluster + - With brick mux set to disable: + 1.Set cluster.max-bricks-per-process to int and check + error message(Must fail) + 2.Set cluster.max-bricks-per-process to string(Must fail) + - With brick mux set to enable: + 1.Set cluster.max-bricks-per-process to string(Must fail) + 2.Set cluster.max-bricks-per-process to 0 + 3.Set cluster.max-bricks-per-process to 1 and check + error message.(Must fail) + 4.Set cluster.max-bricks-per-process to int value > 1. + """ + # Disabling cluster.brick-multiplex if not. + if is_brick_mux_enabled(self.mnode): + ret = disable_brick_mux(self.mnode) + self.assertTrue(ret, "Unable to disable brickmux") + g.log.info("Brick mux is disabled") + + # Set cluster.max-bricks-per-process to int and check + # error message(Must fail) + cmd = "gluster v set all cluster.max-bricks-per-process 10" + ret, _, err = g.run(self.mnode, cmd) + self.assertEqual(ret, 1, 'Able to set max-bricks-per-process' + 'without enabling brick mux') + self.assertIn( + "volume set: failed: Brick-multiplexing is not enabled. " + "Please enable brick multiplexing before" + " trying to set this option.", err, + "Error message not proper on trying to " + "set max-bricks-per-process without brickmux") + + # Set cluster.max-bricks-per-process to string(Must fail) + self.set_max_brick_process_to_string() + + # Enable cluster.brick-multiplex. + ret = enable_brick_mux(self.mnode) + self.assertTrue(ret, "Unable to enable cluster.brick-multiplex") + g.log.info("Brick mux is enabled") + + # Set cluster.max-bricks-per-process to string(Must fail) + self.set_max_brick_process_to_string() + + # Set cluster.max-bricks-per-process to 0. + ret = set_volume_options(self.mnode, 'all', + {'cluster.max-bricks-per-process': '0'}) + self.assertTrue(ret, "Unable to set " + "cluster.max-bricks-per-process to 0") + g.log.info("Successfully set cluster.max-bricks-per-process to 0") + + # Set cluster.max-bricks-per-process to 1 and check + # error message.(Must fail) + cmd = "gluster v set all cluster.max-bricks-per-process 1" + ret, _, err = g.run(self.mnode, cmd) + self.assertEqual(ret, 1, 'Able to set max-bricks-per-process' + 'with enabling brick mux') + self.assertIn( + "volume set: failed: Brick-multiplexing is enabled." + " Please set this option to a value other than 1 to" + " make use of the brick-multiplexing feature.", err, + "Error message not proper on trying to set max-bricks-per-process" + " with brickmux") + + # Set cluster.max-bricks-per-process to int value > 1 + key = 'cluster.max-bricks-per-process' + temp_val = self.get_random_string(string.digits) + value = "{}".format(temp_val) + ret = set_volume_options(self.mnode, 'all', + {key: value}) + self.assertTrue(ret, "Unexpected: Erroneous value {}, to option " + "{} should not result in failure".format(value, key)) + g.log.info("Value %s, set to option %s", value, key) |