Skip to content

Commit 0abc227

Browse files
qa/cephfs: test enable/disable of volumes plugin
Signed-off-by: Rishabh Dave <[email protected]>
1 parent 9962772 commit 0abc227

File tree

2 files changed

+182
-0
lines changed

2 files changed

+182
-0
lines changed

qa/cephfs/overrides/ignorelist_health.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ overrides:
2424
- BLUESTORE_SLOW_OP_ALERT
2525
- slow operation indications in BlueStore
2626
- experiencing slow operations in BlueStore
27+
- MGR_MODULE_ERROR

qa/tasks/cephfs/test_admin.py

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2740,3 +2740,184 @@ def test_when_healthy_with_confirm(self):
27402740
'''
27412741
self.fs.set_max_mds(2, confirm=True)
27422742
self.assertEqual(self.fs.get_var('max_mds'), 2)
2743+
2744+
2745+
class TestToggleVolumes(CephFSTestCase):
2746+
'''
2747+
Contains code for enabling/disabling mgr/volumes plugin.
2748+
'''
2749+
2750+
VOL_MOD_NAME = 'volumes'
2751+
CONFIRM = '--yes-i-really-mean-it'
2752+
2753+
def tearDown(self):
2754+
'''
2755+
Ensure that the volumes plugin is enabled after the test has finished
2756+
running since not doing so might affect tearDown() of CephFSTestCase or
2757+
other superclasses.
2758+
'''
2759+
json_output = self.get_ceph_cmd_stdout('mgr module ls --format json')
2760+
json_output = json.loads(json_output)
2761+
2762+
if 'volumes' in json_output['force_disabled_modules']:
2763+
self.run_ceph_cmd(f'mgr module enable {self.VOL_MOD_NAME}')
2764+
2765+
super(TestToggleVolumes, self).tearDown()
2766+
2767+
def test_force_disable_with_confirmation(self):
2768+
'''
2769+
Test that running "ceph mgr module force disable volumes
2770+
--yes-i-really-mean-it" successfully disables volumes plugin.
2771+
2772+
Also test "ceph mgr module ls" output after this.
2773+
'''
2774+
self.run_ceph_cmd(f'mgr module force disable {self.VOL_MOD_NAME} '
2775+
f'{self.CONFIRM}')
2776+
2777+
json_output = self.get_ceph_cmd_stdout('mgr module ls --format json')
2778+
json_output = json.loads(json_output)
2779+
2780+
self.assertIn(self.VOL_MOD_NAME, json_output['always_on_modules'])
2781+
self.assertIn(self.VOL_MOD_NAME, json_output['force_disabled_modules'])
2782+
2783+
self.assertNotIn(self.VOL_MOD_NAME, json_output['enabled_modules'])
2784+
self.assertNotIn(self.VOL_MOD_NAME, json_output['disabled_modules'])
2785+
2786+
def test_force_disable_fails_without_confirmation(self):
2787+
'''
2788+
Test that running "ceph mgr module force disable volumes" fails with
2789+
EPERM when confirmation flag is not passed along.
2790+
2791+
Also test that output of this command suggests user to pass
2792+
--yes-i-really-mean-it.
2793+
'''
2794+
proc = self.run_ceph_cmd(
2795+
f'mgr module force disable {self.VOL_MOD_NAME}',
2796+
stderr=StringIO(), check_status=False)
2797+
2798+
self.assertEqual(proc.returncode, errno.EPERM)
2799+
2800+
proc_stderr = proc.stderr.getvalue()
2801+
self.assertIn('EPERM', proc_stderr)
2802+
# ensure that the confirmation flag was recommended
2803+
self.assertIn(self.CONFIRM, proc_stderr)
2804+
2805+
def test_force_disable_idempotency(self):
2806+
'''
2807+
Test that running "ceph mgr module force disable volumes" passes when
2808+
volumes plugin was already force disabled.
2809+
'''
2810+
self.run_ceph_cmd(f'mgr module force disable {self.VOL_MOD_NAME} '
2811+
f'{self.CONFIRM}')
2812+
sleep(5)
2813+
2814+
json_output = self.get_ceph_cmd_stdout('mgr module ls --format '
2815+
'json-pretty')
2816+
json_output = json.loads(json_output)
2817+
2818+
self.assertIn(self.VOL_MOD_NAME, json_output['always_on_modules'])
2819+
self.assertIn(self.VOL_MOD_NAME, json_output['force_disabled_modules'])
2820+
2821+
self.assertNotIn(self.VOL_MOD_NAME, json_output['enabled_modules'])
2822+
self.assertNotIn(self.VOL_MOD_NAME, json_output['disabled_modules'])
2823+
2824+
# XXX: this this test, running this command 2nd time should pass.
2825+
self.run_ceph_cmd(f'mgr module force disable {self.VOL_MOD_NAME}')
2826+
2827+
def test_force_disable_nonexistent_mod(self):
2828+
'''
2829+
Test that passing non-existent name to "ceph mgr module force disable"
2830+
command leads to an error.
2831+
'''
2832+
proc = self.run_ceph_cmd(
2833+
f'mgr module force disable abcd {self.CONFIRM}',
2834+
check_status=False, stderr=StringIO())
2835+
self.assertEqual(proc.returncode, errno.EINVAL)
2836+
self.assertIn('EINVAL', proc.stderr.getvalue())
2837+
2838+
def test_force_disable_non_alwayson_mod(self):
2839+
'''
2840+
Test that passing non-existent name to "ceph mgr module force disable"
2841+
command leads to an error.
2842+
'''
2843+
json_output = self.get_ceph_cmd_stdout(
2844+
'mgr module ls --format json-pretty', check_status=False,
2845+
stderr=StringIO())
2846+
output_dict = json.loads(json_output)
2847+
some_non_alwayson_mod = output_dict['enabled_modules'][0]
2848+
2849+
proc = self.run_ceph_cmd(
2850+
f'mgr module force disable {some_non_alwayson_mod} {self.CONFIRM}',
2851+
check_status=False, stderr=StringIO())
2852+
self.assertEqual(proc.returncode, errno.EINVAL)
2853+
self.assertIn('EINVAL', proc.stderr.getvalue())
2854+
2855+
def test_enabled_by_default(self):
2856+
'''
2857+
Test that volumes plugin is enabled by default and is also reported as
2858+
"always on".
2859+
'''
2860+
json_output = self.get_ceph_cmd_stdout('mgr module ls --format json')
2861+
json_output = json.loads(json_output)
2862+
2863+
self.assertIn(self.VOL_MOD_NAME, json_output['always_on_modules'])
2864+
2865+
self.assertNotIn(self.VOL_MOD_NAME, json_output['enabled_modules'])
2866+
self.assertNotIn(self.VOL_MOD_NAME, json_output['disabled_modules'])
2867+
self.assertNotIn(self.VOL_MOD_NAME, json_output['force_disabled_modules'])
2868+
2869+
def test_disable_fails(self):
2870+
'''
2871+
Test that running "ceph mgr module disable volumes" fails with EPERM.
2872+
2873+
This is expected since volumes is an always-on module and therefore
2874+
it can only be disabled using command "ceph mgr module force disable
2875+
volumes".
2876+
'''
2877+
proc = self.run_ceph_cmd(f'mgr module disable {self.VOL_MOD_NAME}',
2878+
stderr=StringIO(), check_status=False)
2879+
self.assertEqual(proc.returncode, errno.EPERM)
2880+
2881+
proc_stderr = proc.stderr.getvalue()
2882+
self.assertIn('EPERM', proc_stderr)
2883+
2884+
def test_enable_idempotency(self):
2885+
'''
2886+
Test that enabling volumes plugin when it is already enabled doesn't
2887+
exit with non-zero return value.
2888+
2889+
Also test that it reports plugin as already enabled.
2890+
'''
2891+
proc = self.run_ceph_cmd(f'mgr module enable {self.VOL_MOD_NAME}',
2892+
stderr=StringIO())
2893+
self.assertEqual(proc.returncode, 0)
2894+
2895+
proc_stderr = proc.stderr.getvalue()
2896+
self.assertIn('already enabled', proc_stderr)
2897+
self.assertIn('always-on', proc_stderr)
2898+
2899+
def test_enable_post_disabling(self):
2900+
'''
2901+
Test that enabling volumes plugin after (force-)disabling it works
2902+
successfully.
2903+
2904+
Alo test "ceph mgr module ls" output for volumes plugin afterwards.
2905+
'''
2906+
self.run_ceph_cmd(f'mgr module force disable {self.VOL_MOD_NAME} '
2907+
f'{self.CONFIRM}')
2908+
# give bit of time for plugin to be disabled.
2909+
sleep(5)
2910+
2911+
self.run_ceph_cmd(f'mgr module enable {self.VOL_MOD_NAME}')
2912+
# give bit of time for plugin to be functional again
2913+
sleep(5)
2914+
json_output = self.get_ceph_cmd_stdout('mgr module ls --format json')
2915+
json_output = json.loads(json_output)
2916+
self.assertIn(self.VOL_MOD_NAME, json_output['always_on_modules'])
2917+
self.assertNotIn(self.VOL_MOD_NAME, json_output['enabled_modules'])
2918+
self.assertNotIn(self.VOL_MOD_NAME, json_output['disabled_modules'])
2919+
self.assertNotIn(self.VOL_MOD_NAME, json_output['force_disabled_modules'])
2920+
2921+
# plugin is reported properly by "ceph mgr module ls" command, check if
2922+
# it is also working fine.
2923+
self.run_ceph_cmd('fs volume ls')

0 commit comments

Comments
 (0)