Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / qa / workunits / mon / ping.py
1 #!/usr/bin/python
2
3 import json
4 import shlex
5 import subprocess
6 import sys
7
8 if sys.version_info[0] == 2:
9     string = basestring
10     unicode = unicode
11 elif sys.version_info[0] == 3:
12     string = str
13     unicode = str
14
15
16 class UnexpectedReturn(Exception):
17     def __init__(self, cmd, ret, expected, msg):
18         if isinstance(cmd, list):
19             self.cmd = ' '.join(cmd)
20         else:
21             assert isinstance(cmd, string) or isinstance(cmd, unicode), \
22                 'cmd needs to be either a list or a str'
23             self.cmd = cmd
24         self.cmd = str(self.cmd)
25         self.ret = int(ret)
26         self.expected = int(expected)
27         self.msg = str(msg)
28
29     def __str__(self):
30         return repr('{c}: expected return {e}, got {r} ({o})'.format(
31             c=self.cmd, e=self.expected, r=self.ret, o=self.msg))
32
33
34 def call(cmd):
35     if isinstance(cmd, list):
36         args = cmd
37     elif isinstance(cmd, string) or isinstance(cmd, unicode):
38         args = shlex.split(cmd)
39     else:
40         assert False, 'cmd is not a string/unicode nor a list!'
41
42     print('call: {0}'.format(args))
43     proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
44     procout, procerr = proc.communicate(None)
45
46     return proc.returncode, procout, procerr
47
48
49 def expect(cmd, expected_ret):
50     try:
51         (r, out, err) = call(cmd)
52     except ValueError as e:
53         assert False, \
54             'unable to run {c}: {err}'.format(c=repr(cmd), err=str(e))
55
56     if r != expected_ret:
57         raise UnexpectedReturn(repr(cmd), r, expected_ret, err)
58
59     return out.decode() if isinstance(out, bytes) else out
60
61
62 def get_quorum_status(timeout=300):
63     cmd = 'ceph quorum_status'
64     if timeout > 0:
65         cmd += ' --connect-timeout {0}'.format(timeout)
66
67     out = expect(cmd, 0)
68     j = json.loads(out)
69     return j
70
71
72 def main():
73     quorum_status = get_quorum_status()
74     mon_names = [mon['name'] for mon in quorum_status['monmap']['mons']]
75
76     print('ping all monitors')
77     for m in mon_names:
78         print('ping mon.{0}'.format(m))
79         out = expect('ceph ping mon.{0}'.format(m), 0)
80         reply = json.loads(out)
81
82         assert reply['mon_status']['name'] == m, \
83             'reply obtained from mon.{0}, expected mon.{1}'.format(
84                 reply['mon_status']['name'], m)
85
86     print('test out-of-quorum reply')
87     for m in mon_names:
88         print('testing mon.{0}'.format(m))
89         expect('ceph daemon mon.{0} quorum exit'.format(m), 0)
90
91         quorum_status = get_quorum_status()
92         assert m not in quorum_status['quorum_names'], \
93             'mon.{0} was not supposed to be in quorum ({1})'.format(
94                 m, quorum_status['quorum_names'])
95
96         out = expect('ceph ping mon.{0}'.format(m), 0)
97         reply = json.loads(out)
98         mon_status = reply['mon_status']
99
100         assert mon_status['name'] == m, \
101             'reply obtained from mon.{0}, expected mon.{1}'.format(
102                 mon_status['name'], m)
103
104         assert mon_status['state'] == 'electing', \
105             'mon.{0} is in state {1}, expected electing'.format(
106                 m, mon_status['state'])
107
108         expect('ceph daemon mon.{0} quorum enter'.format(m), 0)
109
110     print('OK')
111
112
113 if __name__ == '__main__':
114     main()