From 50868a528dd422c741e654c3f3e742be010ea1a0 Mon Sep 17 00:00:00 2001 From: Joao Eduardo Luis Date: Fri, 22 Nov 2013 01:43:06 +0000 Subject: [PATCH] qa: workunits: mon: ping.py: test 'ceph ping' Basic testing by forcing each monitor out of quorum at a time and making sure they still reply to ping requests. Fixes: #6705 Signed-off-by: Joao Eduardo Luis --- qa/workunits/mon/ping.py | 104 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100755 qa/workunits/mon/ping.py diff --git a/qa/workunits/mon/ping.py b/qa/workunits/mon/ping.py new file mode 100755 index 000000000000..6a381034e3b9 --- /dev/null +++ b/qa/workunits/mon/ping.py @@ -0,0 +1,104 @@ +#!/usr/bin/python + +import json +import subprocess +import shlex +import errno +import sys + +class UnexpectedReturn(Exception): + def __init__(self, cmd, ret, expected, msg): + if isinstance(cmd, list): + self.cmd = ' '.join(cmd) + else: + assert isinstance(cmd, str) or isinstance(cmd, unicode), \ + 'cmd needs to be either a list or a str' + self.cmd = cmd + self.cmd = str(self.cmd) + self.ret = int(ret) + self.expected = int(expected) + self.msg = str(msg) + + def __str__(self): + return repr('{c}: expected return {e}, got {r} ({o})'.format( + c=self.cmd, e=self.expected, r=self.ret, o=self.msg)) + +def call(cmd): + if isinstance(cmd, list): + args = cmd + elif isinstance(cmd, basestring): + args = shlex.split(cmd) + else: + assert False, 'cmd is not a string/unicode nor a list!' + + print 'call: {0}'.format(args) + proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + (procout,procerr) = proc.communicate(None) + + return (proc.returncode, procout, procerr) + +def expect(cmd, expected_ret): + + try: + (r, out, err) = call(cmd) + except ValueError as e: + assert False, \ + 'unable to run {c}: {err}'.format(c=repr(cmd), err=e.message) + + if r != expected_ret: + raise UnexpectedReturn(repr(cmd), r, expected_ret, err) + + return out + +def get_quorum_status(timeout=300): + cmd = 'ceph quorum_status' + if timeout > 0: + cmd += ' --connect-timeout {0}'.format(timeout) + + out = expect(cmd, 0) + j = json.loads(out) + return j + +def main(): + + quorum_status = get_quorum_status() + mon_names = [mon['name'] for mon in quorum_status['monmap']['mons']] + + print 'ping all monitors' + for m in mon_names: + print 'ping mon.{0}'.format(m) + out = expect('ceph ping mon.{0}'.format(m), 0) + reply = json.loads(out) + + assert reply['mon_status']['name'] == m, \ + 'reply obtained from mon.{0}, expected mon.{1}'.format( + reply['mon_status']['name'], m) + + print 'test out-of-quorum reply' + for m in mon_names: + print 'testing mon.{0}'.format(m) + expect('ceph daemon mon.{0} quorum exit'.format(m), 0) + + quorum_status = get_quorum_status() + assert m not in quorum_status['quorum_names'], \ + 'mon.{0} was not supposed to be in quorum ({1})'.format( + m, quorum_status['quorum_names']) + + out = expect('ceph ping mon.{0}'.format(m), 0) + reply = json.loads(out) + mon_status = reply['mon_status'] + + assert mon_status['name'] == m, \ + 'reply obtained from mon.{0}, expected mon.{1}'.format( + mon_status['name'], m) + + assert mon_status['state'] == 'electing', \ + 'mon.{0} is in state {1}, expected electing'.format( + m,mon_status['state']) + + expect('ceph daemon mon.{0} quorum enter'.format(m), 0) + + print 'OK' + +if __name__ == '__main__': + main() -- 2.47.3