From f937d3464b2b256b3dd068b6ed84a7f0b24aee56 Mon Sep 17 00:00:00 2001 From: Anirudha Bose Date: Thu, 18 Aug 2016 18:44:54 +0530 Subject: [PATCH 01/11] qa/workunits: Python 3 compat fixes for mon/ping.py Signed-off-by: Anirudha Bose --- qa/workunits/mon/ping.py | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/qa/workunits/mon/ping.py b/qa/workunits/mon/ping.py index 6a381034e3b9f..266667d0e3992 100755 --- a/qa/workunits/mon/ping.py +++ b/qa/workunits/mon/ping.py @@ -1,18 +1,25 @@ #!/usr/bin/python import json -import subprocess import shlex -import errno +import subprocess import sys +if sys.version_info[0] == 2: + string = basestring + unicode = unicode +elif sys.version_info[0] == 3: + string = str + unicode = str + + 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' + assert isinstance(cmd, string) or isinstance(cmd, unicode), \ self.cmd = cmd self.cmd = str(self.cmd) self.ret = int(ret) @@ -26,12 +33,12 @@ def __str__(self): def call(cmd): if isinstance(cmd, list): args = cmd - elif isinstance(cmd, basestring): + elif isinstance(cmd, string) or isinstance(cmd, unicode): args = shlex.split(cmd) else: assert False, 'cmd is not a string/unicode nor a list!' - print 'call: {0}'.format(args) + print('call: {0}'.format(args)) proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (procout,procerr) = proc.communicate(None) @@ -43,12 +50,13 @@ def expect(cmd, expected_ret): (r, out, err) = call(cmd) except ValueError as e: assert False, \ - 'unable to run {c}: {err}'.format(c=repr(cmd), err=e.message) + 'unable to run {c}: {err}'.format(c=repr(cmd), err=str(e)) if r != expected_ret: raise UnexpectedReturn(repr(cmd), r, expected_ret, err) - return out + return out.decode() if isinstance(out, bytes) else out + def get_quorum_status(timeout=300): cmd = 'ceph quorum_status' @@ -64,9 +72,9 @@ def main(): quorum_status = get_quorum_status() mon_names = [mon['name'] for mon in quorum_status['monmap']['mons']] - print 'ping all monitors' + print('ping all monitors') for m in mon_names: - print 'ping mon.{0}'.format(m) + print('ping mon.{0}'.format(m)) out = expect('ceph ping mon.{0}'.format(m), 0) reply = json.loads(out) @@ -74,9 +82,9 @@ def main(): 'reply obtained from mon.{0}, expected mon.{1}'.format( reply['mon_status']['name'], m) - print 'test out-of-quorum reply' + print('test out-of-quorum reply') for m in mon_names: - print 'testing mon.{0}'.format(m) + print('testing mon.{0}'.format(m)) expect('ceph daemon mon.{0} quorum exit'.format(m), 0) quorum_status = get_quorum_status() @@ -98,7 +106,8 @@ def main(): expect('ceph daemon mon.{0} quorum enter'.format(m), 0) - print 'OK' + print('OK') + if __name__ == '__main__': main() From 4409bb5aef4a290804bd348eb5ebdbb86d5819b4 Mon Sep 17 00:00:00 2001 From: Anirudha Bose Date: Thu, 18 Aug 2016 19:15:54 +0530 Subject: [PATCH 02/11] qa/workunits: Python 3 compat fixes for mon/test_mon_config_key.py Signed-off-by: Anirudha Bose --- qa/workunits/mon/test_mon_config_key.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/qa/workunits/mon/test_mon_config_key.py b/qa/workunits/mon/test_mon_config_key.py index 037d5d133682f..20f64c412bade 100755 --- a/qa/workunits/mon/test_mon_config_key.py +++ b/qa/workunits/mon/test_mon_config_key.py @@ -78,10 +78,10 @@ def run_cmd(cmd, expects=0): try: (out, err) = proc.communicate() if out is not None: - stdout += str(out).split('\n') + stdout += out.decode().split('\n') cmdlog.debug('stdout: {s}'.format(s=out)) if err is not None: - stdout += str(err).split('\n') + stdout += err.decode().split('\n') cmdlog.debug('stderr: {s}'.format(s=err)) except ValueError: ret = proc.wait() @@ -118,7 +118,7 @@ def destroy_tmp_file(fpath): def write_data_file(data, rnd): file_path = gen_tmp_file_path(rnd) - data_file = open(file_path, 'wr+') + data_file = open(file_path, 'a+') data_file.truncate() data_file.write(data) data_file.close() @@ -126,7 +126,9 @@ def write_data_file(data, rnd): #end write_data_file def choose_random_op(rnd): - op = rnd.choice(OPS.keys()) + op = rnd.choice( + list(OPS.keys()) + ) sop = rnd.choice(OPS[op]) return (op, sop) @@ -206,7 +208,7 @@ def main(): expected = 0 # the store just overrides the value if the key exists #end if sop == 'existing' elif sop == 'new': - for x in xrange(0, 10): + for x in range(0, 10): key = gen_key(rnd) if key not in CONFIG_EXISTING: break @@ -263,8 +265,8 @@ def main(): 'key \'{k_}\' not in CONFIG_EXISTING'.format(k_=key) if sop == 'enoent': - for x in xrange(0, 10): - key = base64.b64encode(os.urandom(20)) + for x in range(0, 10): + key = base64.b64encode(os.urandom(20)).decode() if key not in CONFIG_EXISTING: break key = None @@ -301,8 +303,8 @@ def main(): 'key \'{k_}\' not in CONFIG_EXISTING'.format(k_=key) if sop == 'enoent': - for x in xrange(0, 10): - key = base64.b64encode(os.urandom(20)) + for x in range(0, 10): + key = base64.b64encode(os.urandom(20)).decode() if key not in CONFIG_EXISTING: break key = None @@ -335,8 +337,8 @@ def main(): 'key \'{k_}\' not in CONFIG_EXISTING'.format(k_=key) if sop == 'enoent': - for x in xrange(0, 10): - key = base64.b64encode(os.urandom(20)) + for x in range(0, 10): + key = base64.b64encode(os.urandom(20)).decode() if key not in CONFIG_EXISTING: break key = None From b8233cc77e310c38eafc21c97a0d33c7e685045b Mon Sep 17 00:00:00 2001 From: Anirudha Bose Date: Fri, 19 Aug 2016 10:53:53 +0530 Subject: [PATCH 03/11] qa/workunits: Python 3 compat fixes for fs/misc/filelock_interrupt.py Signed-off-by: Anirudha Bose --- qa/workunits/fs/misc/filelock_interrupt.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/qa/workunits/fs/misc/filelock_interrupt.py b/qa/workunits/fs/misc/filelock_interrupt.py index a17fa39e9dc62..3ce559e09c39f 100755 --- a/qa/workunits/fs/misc/filelock_interrupt.py +++ b/qa/workunits/fs/misc/filelock_interrupt.py @@ -29,7 +29,7 @@ def main(): signal.alarm(5); try: fcntl.flock(f2, fcntl.LOCK_EX) - except IOError, e: + except IOError as e: if e.errno != errno.EINTR: raise else: @@ -40,11 +40,11 @@ def main(): lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 10, 0, 0) try: fcntl.fcntl(f1, fcntl.F_OFD_SETLK, lockdata) - except IOError, e: + except IOError as e: if e.errno != errno.EINVAL: raise else: - print 'kernel does not support fcntl.F_OFD_SETLK' + print('kernel does not support fcntl.F_OFD_SETLK') return lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 10, 10, 0, 0) @@ -58,7 +58,7 @@ def main(): try: lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0) fcntl.fcntl(f2, fcntl.F_OFD_SETLKW, lockdata) - except IOError, e: + except IOError as e: if e.errno != errno.EINTR: raise else: @@ -70,7 +70,7 @@ def main(): try: lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 10, 10, 0, 0) fcntl.fcntl(f1, fcntl.F_OFD_SETLK, lockdata) - except IOError, e: + except IOError as e: if e.errno == errno.EAGAIN: pass else: @@ -80,6 +80,7 @@ def main(): fcntl.fcntl(f1, fcntl.F_OFD_SETLK, lockdata) fcntl.fcntl(f2, fcntl.F_OFD_SETLK, lockdata) - print 'ok' + print('ok') + main() From c148526462b24e767f2c46b310bd936a834f1c15 Mon Sep 17 00:00:00 2001 From: Anirudha Bose Date: Fri, 19 Aug 2016 10:55:20 +0530 Subject: [PATCH 04/11] qa/workunits: Python 3 compat fixes for fs/misc/filelock_deadlock.py Signed-off-by: Anirudha Bose --- qa/workunits/fs/misc/filelock_deadlock.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qa/workunits/fs/misc/filelock_deadlock.py b/qa/workunits/fs/misc/filelock_deadlock.py index a34476107ab05..32322ba66af89 100755 --- a/qa/workunits/fs/misc/filelock_deadlock.py +++ b/qa/workunits/fs/misc/filelock_deadlock.py @@ -21,7 +21,7 @@ def lock_two(f1, f2): exitcode = 0; try: fcntl.fcntl(f2, fcntl.F_SETLKW, lockdata) - except IOError, e: + except IOError as e: if e.errno == errno.EDEADLK: exitcode = 1 elif e.errno == errno.EINTR: @@ -63,6 +63,7 @@ def main(): if deadlk_count != 1: raise RuntimeError("unexpect count of EDEADLK") - print 'ok' + print('ok') + main() From 5d800fa47db5c7a77c0f55486154031502235904 Mon Sep 17 00:00:00 2001 From: Anirudha Bose Date: Fri, 19 Aug 2016 11:17:32 +0530 Subject: [PATCH 05/11] qa/workunits: Python 3 compat fixes for rest/test.py Signed-off-by: Anirudha Bose --- qa/workunits/rest/test.py | 49 +++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/qa/workunits/rest/test.py b/qa/workunits/rest/test.py index c93da1366e9a1..649e39005fa4d 100755 --- a/qa/workunits/rest/test.py +++ b/qa/workunits/rest/test.py @@ -1,6 +1,7 @@ #!/usr/bin/python -import exceptions +from __future__ import print_function + import json import os import requests @@ -12,13 +13,15 @@ BASEURL = os.environ.get('BASEURL', 'http://localhost:5000/api/v0.1') + def fail(r, msg): - print >> sys.stderr, 'FAILURE: url ', r.url - print >> sys.stderr, msg - print >> sys.stderr, 'Response content: ', r.content - print >> sys.stderr, 'Headers: ', r.headers + print('FAILURE: url ', r.url, file=sys.stderr) + print(msg, file=sys.stderr) + print('Response content: ', r.text, file=sys.stderr) + print('Headers: ', r.headers, file=sys.stderr) sys.exit(1) + def expect(url, method, respcode, contenttype, extra_hdrs=None, data=None): failmsg, r = expect_nofail(url, method, respcode, contenttype, extra_hdrs, data) @@ -33,7 +36,7 @@ def expect_nofail(url, method, respcode, contenttype, extra_hdrs=None, f = fdict[method.lower()] r = f(BASEURL + '/' + url, headers=extra_hdrs, data=data) - print '{0} {1}: {2} {3}'.format(method, url, contenttype, r.status_code) + print('{0} {1}: {2} {3}'.format(method, url, contenttype, r.status_code)) if r.status_code != respcode: return 'expected {0}, got {1}'.format(respcode, r.status_code), r @@ -52,15 +55,15 @@ def expect_nofail(url, method, respcode, contenttype, extra_hdrs=None, if r_contenttype == 'application/json': try: # older requests.py doesn't create r.myjson; create it myself - r.myjson = json.loads(r.content) - assert(r.myjson != None) + r.myjson = json.loads(r.text) + assert(r.myjson is not None) except Exception as e: return 'Invalid JSON returned: "{0}"'.format(str(e)), r if r_contenttype == 'application/xml': try: # if it's there, squirrel it away for use in the caller - r.tree = xml.etree.ElementTree.fromstring(r.content) + r.tree = xml.etree.ElementTree.fromstring(r.text) except Exception as e: return 'Invalid XML returned: "{0}"'.format(str(e)), r @@ -84,10 +87,10 @@ def expect_nofail(url, method, respcode, contenttype, extra_hdrs=None, r = expect('auth/export?entity=client.xx', 'GET', 200, 'plain') # must use text/plain; default is application/x-www-form-urlencoded expect('auth/add?entity=client.xx', 'PUT', 200, 'plain', - {'Content-Type':'text/plain'}, data=r.content) + {'Content-Type':'text/plain'}, data=r.text) r = expect('auth/list', 'GET', 200, 'plain') - assert('client.xx' in r.content) + assert('client.xx' in r.text) r = expect('auth/list.json', 'GET', 200, 'json') dictlist = r.myjson['output']['auth_dump'] @@ -114,21 +117,21 @@ def expect_nofail(url, method, respcode, contenttype, extra_hdrs=None, # export/import/export, compare r = expect('auth/export', 'GET', 200, 'plain') - exp1 = r.content + exp1 = r.text assert('client.xx' in exp1) r = expect('auth/import', 'PUT', 200, 'plain', - {'Content-Type':'text/plain'}, data=r.content) + {'Content-Type':'text/plain'}, data=r.text) r2 = expect('auth/export', 'GET', 200, 'plain') - assert(exp1 == r2.content) + assert(exp1 == r2.text) expect('auth/del?entity=client.xx', 'PUT', 200, 'json', JSONHDR) r = expect('osd/dump', 'GET', 200, 'json', JSONHDR) assert('epoch' in r.myjson['output']) - assert('GLOBAL' in expect('df', 'GET', 200, 'plain').content) - assert('CATEGORY' in expect('df?detail=detail', 'GET', 200, 'plain').content) + assert('GLOBAL' in expect('df', 'GET', 200, 'plain').text) + assert('CATEGORY' in expect('df?detail=detail', 'GET', 200, 'plain').text) # test param with no value (treated as param=param) - assert('CATEGORY' in expect('df?detail', 'GET', 200, 'plain').content) + assert('CATEGORY' in expect('df?detail', 'GET', 200, 'plain').text) r = expect('df', 'GET', 200, 'json', JSONHDR) assert('total_used_bytes' in r.myjson['output']['stats']) @@ -207,7 +210,7 @@ def expect_nofail(url, method, respcode, contenttype, extra_hdrs=None, expect('mon/dump.xml', 'GET', 200, 'xml') r = expect('mon/getmap', 'GET', 200, '') - assert(len(r.content) != 0) + assert(len(r.text) != 0) r = expect('mon_status.json', 'GET', 200, 'json') assert('name' in r.myjson['output']) r = expect('mon_status.xml', 'GET', 200, 'xml') @@ -243,7 +246,7 @@ def expect_nofail(url, method, respcode, contenttype, extra_hdrs=None, if r.myjson['output']['osds'][0]['up'] == 1: break else: - print >> sys.stderr, "waiting for osd.0 to come back up" + print("waiting for osd.0 to come back up", file=sys.stderr) time.sleep(10) r = expect('osd/dump', 'GET', 200, 'json', JSONHDR) @@ -340,7 +343,7 @@ def expect_nofail(url, method, respcode, contenttype, extra_hdrs=None, expect('pg/dump_stuck?stuckops=stale', 'GET', 200, '') r = expect('pg/getmap', 'GET', 200, '') - assert(len(r.content) != 0) + assert(len(r.text) != 0) r = expect('pg/map?pgid=0.0', 'GET', 200, 'json', JSONHDR) assert('acting' in r.myjson['output']) @@ -384,12 +387,12 @@ def expect_nofail(url, method, respcode, contenttype, extra_hdrs=None, assert(r.tree.find('output/status/osdmap') is not None) r = expect('tell/osd.0/version', 'GET', 200, '') - assert('ceph version' in r.content) + assert('ceph version' in r.text) expect('tell/osd.999/version', 'GET', 400, '') expect('tell/osd.foo/version', 'GET', 400, '') r = expect('tell/osd.0/dump_pg_recovery_stats', 'GET', 200, '') - assert('Started' in r.content) + assert('Started' in r.text) expect('osd/reweight?id=0&weight=0.9', 'PUT', 200, '') expect('osd/reweight?id=0&weight=-1', 'PUT', 400, '') @@ -414,4 +417,4 @@ def expect_nofail(url, method, respcode, contenttype, extra_hdrs=None, r = expect('osd/pool/get.json?pool=rbd&var=crush_ruleset', 'GET', 200, 'json') assert(r.myjson['output']['crush_ruleset'] == 0) - print 'OK' + print('OK') From 12f9be0c9f15ea5fc8ad2d977e2e42d820f37b7f Mon Sep 17 00:00:00 2001 From: Anirudha Bose Date: Fri, 19 Aug 2016 11:20:20 +0530 Subject: [PATCH 06/11] qa/workunits: Python 3 compat fixes for restart/test-backtraces.py Signed-off-by: Anirudha Bose --- qa/workunits/restart/test-backtraces.py | 76 ++++++++++++++----------- 1 file changed, 43 insertions(+), 33 deletions(-) diff --git a/qa/workunits/restart/test-backtraces.py b/qa/workunits/restart/test-backtraces.py index 0b173a65a49ea..2fa67a23f3852 100755 --- a/qa/workunits/restart/test-backtraces.py +++ b/qa/workunits/restart/test-backtraces.py @@ -1,12 +1,22 @@ #!/usr/bin/env python -import subprocess as sub -from cStringIO import StringIO +from __future__ import print_function + +import subprocess import json import os import time import sys -import thread + +if sys.version_info[0] == 2: + from cStringIO import StringIO + + range = xrange + +elif sys.version_info[0] == 3: + from io import StringIO + + range = range import rados as rados import cephfs as cephfs @@ -18,24 +28,24 @@ def get_name(b, i, j): return c, b + '/' + c def mkdir(ceph, d): - print >>sys.stderr, "mkdir {d}".format(d=d) - ceph.mkdir(d, 0755) + print("mkdir {d}".format(d=d), file=sys.stderr) + ceph.mkdir(d, 0o755) return ceph.stat(d)['st_ino'] def create(ceph, f): - print >>sys.stderr, "creating {f}".format(f=f) - fd = ceph.open(f, os.O_CREAT|os.O_RDWR, 0644) + print("creating {f}".format(f=f), file=sys.stderr) + fd = ceph.open(f, os.O_CREAT | os.O_RDWR, 0o644) ceph.close(fd) return ceph.stat(f)['st_ino'] def set_mds_config_param(ceph, param): - with file('/dev/null', 'rb') as devnull: + with open('/dev/null', 'rb') as devnull: confarg = '' if conf != '': confarg = '-c {c}'.format(c=conf) - r = sub.call("ceph {ca} mds tell a injectargs '{p}'".format(ca=confarg, p=param), shell=True, stdout=devnull) - if (r != 0): - raise + r = subprocess.call("ceph {ca} mds tell a injectargs '{p}'".format(ca=confarg, p=param), shell=True, stdout=devnull) + if r != 0: + raise Exception import ConfigParser import contextlib @@ -54,34 +64,34 @@ def _optionxform(s): return s def conf_set_kill_mds(location, killnum): - print >>sys.stderr, 'setting mds kill config option for {l}.{k}'.format(l=location, k=killnum) - print "restart mds a mds_kill_{l}_at {k}".format(l=location, k=killnum) + print('setting mds kill config option for {l}.{k}'.format(l=location, k=killnum), file=sys.stderr) + print("restart mds a mds_kill_{l}_at {k}".format(l=location, k=killnum)) sys.stdout.flush() for l in sys.stdin.readline(): if l == 'restarted': break def flush(ceph, testnum): - print >>sys.stderr, 'flushing {t}'.format(t=testnum) + print('flushing {t}'.format(t=testnum), file=sys.stderr) set_mds_config_param(ceph, '--mds_log_max_segments 1') for i in range(1, 500): f = '{p}.{pid}.{t}.{i}'.format(p=prefix, pid=os.getpid(), t=testnum, i=i) - print >>sys.stderr, 'flushing with create {f}'.format(f=f) - fd = ceph.open(f, os.O_CREAT | os.O_RDWR, 0644) + print('flushing with create {f}'.format(f=f), file=sys.stderr) + fd = ceph.open(f, os.O_CREAT | os.O_RDWR, 0o644) ceph.close(fd) ceph.unlink(f) - print >> sys.stderr, 'flush doing shutdown' + print('flush doing shutdown', file=sys.stderr) ceph.shutdown() - print >> sys.stderr, 'flush reinitializing ceph' + print('flush reinitializing ceph', file=sys.stderr) ceph = cephfs.LibCephFS(conffile=conf) - print >> sys.stderr, 'flush doing mount' + print('flush doing mount', file=sys.stderr) ceph.mount() return ceph def kill_mds(ceph, location, killnum): - print >>sys.stderr, 'killing mds: {l}.{k}'.format(l=location, k=killnum) + print('killing mds: {l}.{k}'.format(l=location, k=killnum), file=sys.stderr) set_mds_config_param(ceph, '--mds_kill_{l}_at {k}'.format(l=location, k=killnum)) def wait_for_mds(ceph): @@ -90,7 +100,7 @@ def wait_for_mds(ceph): confarg = '' if conf != '': confarg = '-c {c}'.format(c=conf) - r = sub.check_output("ceph {ca} mds stat".format(ca=confarg), shell=True) + r = subprocess.check_output("ceph {ca} mds stat".format(ca=confarg), shell=True).decode() if r.find('a=up:active'): break time.sleep(1) @@ -101,7 +111,7 @@ def decode(value): with open(tmpfile, 'w+') as f: f.write(value) - p = sub.Popen( + p = subprocess.Popen( [ 'ceph-dencoder', 'import', @@ -111,13 +121,13 @@ def decode(value): 'decode', 'dump_json', ], - stdin=sub.PIPE, - stdout=sub.PIPE, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, ) (stdout, _) = p.communicate(input=value) p.stdin.close() - if (p.returncode != 0): - raise + if p.returncode != 0: + raise Exception os.remove(tmpfile) return json.loads(stdout) @@ -125,7 +135,7 @@ class VerifyFailure(Exception): pass def verify(rados_ioctx, ino, values, pool): - print >>sys.stderr, 'getting parent attr for ino: %lx.00000000' % ino + print('getting parent attr for ino: %lx.00000000' % ino, file=sys.stderr) savede = None for i in range(1, 20): try: @@ -201,7 +211,7 @@ def make_abc(ceph, rooti, i): i = 0 if test < 0 or test == i: - print >>sys.stderr, 'Running test %d: basic verify' % i + print('Running test %d: basic verify' % i, file=sys.stderr) ino, expected_bt = make_abc(ceph, rooti, i) ceph = flush(ceph, i) verify(ioctx, ino, expected_bt, 0) @@ -215,8 +225,8 @@ def make_abc(ceph, rooti, i): # verify if test < 0 or test == i: - print >>sys.stderr, 'Running test %d: kill openc' % i - print "restart mds a" + print('Running test %d: kill openc' % i, file=sys.stderr) + print("restart mds a") sys.stdout.flush() kill_mds(ceph, 'openc', 1) ino, expected_bt = make_abc(ceph, rooti, i) @@ -232,11 +242,11 @@ def make_abc(ceph, rooti, i): # flush # verify if test < 0 or test == i: - print >>sys.stderr, 'Running test %d: kill openc/replay' % i + print('Running test %d: kill openc/replay' % i, file=sys.stderr) # these are reversed because we want to prepare the config conf_set_kill_mds('journal_replay', 1) kill_mds(ceph, 'openc', 1) - print "restart mds a" + print("restart mds a") sys.stdout.flush() ino, expected_bt = make_abc(ceph, rooti, i) ceph = flush(ceph, i) @@ -248,5 +258,5 @@ def make_abc(ceph, rooti, i): radosobj.shutdown() ceph.shutdown() -print "done" +print("done") sys.stdout.flush() From 0b32fd50f8027572e22816c6f555f86c3bd977f8 Mon Sep 17 00:00:00 2001 From: Anirudha Bose Date: Fri, 19 Aug 2016 11:28:13 +0530 Subject: [PATCH 07/11] qa/workunits: Python 3 compat fixes for fs/multiclient_sync_read_eof.py Signed-off-by: Anirudha Bose --- qa/workunits/fs/multiclient_sync_read_eof.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/qa/workunits/fs/multiclient_sync_read_eof.py b/qa/workunits/fs/multiclient_sync_read_eof.py index 03293d8d94a87..d3e0f8e652e96 100755 --- a/qa/workunits/fs/multiclient_sync_read_eof.py +++ b/qa/workunits/fs/multiclient_sync_read_eof.py @@ -12,33 +12,33 @@ def main(): parser.add_argument('fn') args = parser.parse_args() - file(os.path.join(args.mnt1, args.fn), 'w') - f1 = file(os.path.join(args.mnt1, args.fn), 'r+') - f2 = file(os.path.join(args.mnt2, args.fn), 'r+') + open(os.path.join(args.mnt1, args.fn), 'w') + f1 = open(os.path.join(args.mnt1, args.fn), 'r+') + f2 = open(os.path.join(args.mnt2, args.fn), 'r+') f1.write('foo') f1.flush() a = f2.read(3) - print 'got "%s"' % a + print('got "%s"' % a) assert a == 'foo' f2.write('bar') f2.flush() a = f1.read(3) - print 'got "%s"' % a + print('got "%s"' % a) assert a == 'bar' ## test short reads f1.write('short') f1.flush() a = f2.read(100) - print 'got "%s"' % a + print('got "%s"' % a) assert a == 'short' f2.write('longer') f2.flush() a = f1.read(1000) - print 'got "%s"' % a + print('got "%s"' % a) assert a == 'longer' - print 'ok' + print('ok') main() From 92dbeabfdd60c6b7a45d2c0f872c29eace3afb4c Mon Sep 17 00:00:00 2001 From: Anirudha Bose Date: Fri, 19 Aug 2016 11:52:42 +0530 Subject: [PATCH 08/11] qa/workunits: Python 3 compat fixes for ceph-disk/ceph-disk-test.py Signed-off-by: Anirudha Bose --- qa/workunits/ceph-disk/ceph-disk-test.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/qa/workunits/ceph-disk/ceph-disk-test.py b/qa/workunits/ceph-disk/ceph-disk-test.py index 5fedde4d3638b..0e4a50b2df2d8 100644 --- a/qa/workunits/ceph-disk/ceph-disk-test.py +++ b/qa/workunits/ceph-disk/ceph-disk-test.py @@ -64,7 +64,7 @@ def __init__(self): self.conf = configobj.ConfigObj('/etc/ceph/ceph.conf') def save_conf(self): - self.conf.write(open('/etc/ceph/ceph.conf', 'w')) + self.conf.write(open('/etc/ceph/ceph.conf', 'wb')) @staticmethod def helper(command): @@ -97,8 +97,7 @@ def sh(command): return "".join(lines) def unused_disks(self, pattern='[vs]d.'): - names = filter( - lambda x: re.match(pattern, x), os.listdir("/sys/block")) + names = [x for x in os.listdir("/sys/block") if re.match(pattern, x)] if not names: return [] disks = json.loads( From 07b15e708639aeaa393b7e3f28afb35807ae23ef Mon Sep 17 00:00:00 2001 From: Anirudha Bose Date: Fri, 19 Aug 2016 12:15:49 +0530 Subject: [PATCH 09/11] qa/workunits: Allow setting $PYTHON in ceph-disk/ceph-disk.sh $PYTHON defaults to "python" Signed-off-by: Anirudha Bose --- qa/workunits/ceph-disk/ceph-disk.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/qa/workunits/ceph-disk/ceph-disk.sh b/qa/workunits/ceph-disk/ceph-disk.sh index cf36324fb4522..1566d6048828a 100755 --- a/qa/workunits/ceph-disk/ceph-disk.sh +++ b/qa/workunits/ceph-disk/ceph-disk.sh @@ -24,16 +24,19 @@ perl -pi -e 's|pid file.*|pid file = /var/run/ceph/\$cluster-\$name.pid|' /etc/c PATH=$(dirname $0):$(dirname $0)/..:$PATH -if ! which py.test > /dev/null; then - echo "py.test not installed" +: ${PYTHON:=python} +PY_VERSION=$($PYTHON --version 2>&1) + +if ! ${PYTHON} -m pytest --version > /dev/null 2>&1; then + echo "py.test not installed for ${PY_VERSION}" exit 1 fi -sudo env PATH=$(dirname $0):$(dirname $0)/..:$PATH py.test -s -v $(dirname $0)/ceph-disk-test.py +sudo env PATH=$(dirname $0):$(dirname $0)/..:$PATH ${PYTHON} -m pytest -s -v $(dirname $0)/ceph-disk-test.py result=$? # own whatever was created as a side effect of the py.test run -# so that it can successfully be removed later on by a non privileged +# so that it can successfully be removed later on by a non privileged # process sudo chown -R $(id -u) $(dirname $0) exit $result From 922c977c8b410e683c9cfcee8b69558e84370dc7 Mon Sep 17 00:00:00 2001 From: Anirudha Bose Date: Sat, 20 Aug 2016 22:30:12 +0530 Subject: [PATCH 10/11] qa/workunits: Python 3 compat fixes for fs/misc/direct_io.py Signed-off-by: Anirudha Bose --- qa/workunits/fs/misc/direct_io.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/qa/workunits/fs/misc/direct_io.py b/qa/workunits/fs/misc/direct_io.py index 48be584ef71eb..b5c422654e209 100755 --- a/qa/workunits/fs/misc/direct_io.py +++ b/qa/workunits/fs/misc/direct_io.py @@ -1,9 +1,10 @@ #!/usr/bin/python -import os +import json import mmap +import os import subprocess -import json + def get_data_pool(): cmd = ['ceph', 'fs', 'ls', '--format=json-pretty'] @@ -11,19 +12,20 @@ def get_data_pool(): out = proc.communicate()[0] return json.loads(out)[0]['data_pools'][0] + def main(): - fd = os.open("testfile", os.O_RDWR | os.O_CREAT | os.O_TRUNC | os.O_DIRECT, 0644) + fd = os.open("testfile", os.O_RDWR | os.O_CREAT | os.O_TRUNC | os.O_DIRECT, 0o644) ino = os.fstat(fd).st_ino obj_name = "{ino:x}.00000000".format(ino=ino) pool_name = get_data_pool() - buf = mmap.mmap(-1, 1); - buf.write('1'); - os.write(fd, buf); + buf = mmap.mmap(-1, 1) + buf.write('1') + os.write(fd, buf) proc = subprocess.Popen(['rados', '-p', pool_name, 'get', obj_name, 'tmpfile']) - proc.wait(); + proc.wait() with open('tmpfile', 'r') as tmpf: out = tmpf.read() @@ -34,14 +36,15 @@ def main(): tmpf.write('2') proc = subprocess.Popen(['rados', '-p', pool_name, 'put', obj_name, 'tmpfile']) - proc.wait(); + proc.wait() os.lseek(fd, 0, os.SEEK_SET) - out = os.read(fd, 1); + out = os.read(fd, 1) if out != '2': raise RuntimeError("data were not directly read from object store") - os.close(fd); - print 'ok' + os.close(fd) + print('ok') + main() From 724febf5ca3fe7067cecbf9bd3444b02728e4f7b Mon Sep 17 00:00:00 2001 From: Anirudha Bose Date: Thu, 18 Aug 2016 18:45:58 +0530 Subject: [PATCH 11/11] qa/workunits: PEP8ify Signed-off-by: Anirudha Bose --- qa/workunits/fs/misc/filelock_deadlock.py | 25 +++-- qa/workunits/fs/misc/filelock_interrupt.py | 19 ++-- qa/workunits/mon/ping.py | 29 ++--- qa/workunits/mon/test_mon_config_key.py | 122 +++++++++++---------- qa/workunits/rest/test.py | 2 +- 5 files changed, 105 insertions(+), 92 deletions(-) diff --git a/qa/workunits/fs/misc/filelock_deadlock.py b/qa/workunits/fs/misc/filelock_deadlock.py index 32322ba66af89..3ebc9777bd25e 100755 --- a/qa/workunits/fs/misc/filelock_deadlock.py +++ b/qa/workunits/fs/misc/filelock_deadlock.py @@ -1,24 +1,26 @@ #!/usr/bin/python -import time -import os -import fcntl import errno +import fcntl +import os import signal import struct +import time + def handler(signum, frame): pass + def lock_two(f1, f2): lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 10, 0, 0) fcntl.fcntl(f1, fcntl.F_SETLKW, lockdata) time.sleep(10) # don't wait forever - signal.signal(signal.SIGALRM, handler); - signal.alarm(10); - exitcode = 0; + signal.signal(signal.SIGALRM, handler) + signal.alarm(10) + exitcode = 0 try: fcntl.fcntl(f2, fcntl.F_SETLKW, lockdata) except IOError as e: @@ -27,8 +29,9 @@ def lock_two(f1, f2): elif e.errno == errno.EINTR: exitcode = 2 else: - exitcode = 3; - os._exit(exitcode); + exitcode = 3 + os._exit(exitcode) + def main(): pid1 = os.fork() @@ -52,13 +55,13 @@ def main(): deadlk_count = 0 i = 0 while i < 3: - pid, status = os.wait(); + pid, status = os.wait() exitcode = status >> 8 if exitcode == 1: - deadlk_count = deadlk_count + 1; + deadlk_count += 1 elif exitcode != 0: raise RuntimeError("unexpect exit code of child") - i = i + 1 + i += 1 if deadlk_count != 1: raise RuntimeError("unexpect count of EDEADLK") diff --git a/qa/workunits/fs/misc/filelock_interrupt.py b/qa/workunits/fs/misc/filelock_interrupt.py index 3ce559e09c39f..2a413a66e8353 100755 --- a/qa/workunits/fs/misc/filelock_interrupt.py +++ b/qa/workunits/fs/misc/filelock_interrupt.py @@ -1,21 +1,22 @@ #!/usr/bin/python -import time -import fcntl import errno +import fcntl import signal import struct """ introduced by Linux 3.15 """ -fcntl.F_OFD_GETLK=36 -fcntl.F_OFD_SETLK=37 -fcntl.F_OFD_SETLKW=38 +fcntl.F_OFD_GETLK = 36 +fcntl.F_OFD_SETLK = 37 +fcntl.F_OFD_SETLKW = 38 + def handler(signum, frame): pass + def main(): f1 = open("testfile", 'w') f2 = open("testfile", 'w') @@ -25,8 +26,8 @@ def main(): """ is flock interruptable? """ - signal.signal(signal.SIGALRM, handler); - signal.alarm(5); + signal.signal(signal.SIGALRM, handler) + signal.alarm(5) try: fcntl.flock(f2, fcntl.LOCK_EX) except IOError as e: @@ -53,8 +54,8 @@ def main(): """ is poxis lock interruptable? """ - signal.signal(signal.SIGALRM, handler); - signal.alarm(5); + signal.signal(signal.SIGALRM, handler) + signal.alarm(5) try: lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0) fcntl.fcntl(f2, fcntl.F_OFD_SETLKW, lockdata) diff --git a/qa/workunits/mon/ping.py b/qa/workunits/mon/ping.py index 266667d0e3992..1773c7369317d 100755 --- a/qa/workunits/mon/ping.py +++ b/qa/workunits/mon/ping.py @@ -18,8 +18,8 @@ def __init__(self, cmd, ret, expected, msg): if isinstance(cmd, list): self.cmd = ' '.join(cmd) else: - 'cmd needs to be either a list or a str' assert isinstance(cmd, string) 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) @@ -28,7 +28,8 @@ def __init__(self, cmd, ret, expected, 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)) + c=self.cmd, e=self.expected, r=self.ret, o=self.msg)) + def call(cmd): if isinstance(cmd, list): @@ -40,12 +41,12 @@ def call(cmd): print('call: {0}'.format(args)) proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - (procout,procerr) = proc.communicate(None) + procout, procerr = proc.communicate(None) - return (proc.returncode, procout, procerr) + return proc.returncode, procout, procerr -def expect(cmd, expected_ret): +def expect(cmd, expected_ret): try: (r, out, err) = call(cmd) except ValueError as e: @@ -67,8 +68,8 @@ def get_quorum_status(timeout=300): j = json.loads(out) return j -def main(): +def main(): quorum_status = get_quorum_status() mon_names = [mon['name'] for mon in quorum_status['monmap']['mons']] @@ -79,8 +80,8 @@ def main(): reply = json.loads(out) assert reply['mon_status']['name'] == m, \ - 'reply obtained from mon.{0}, expected mon.{1}'.format( - 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: @@ -89,20 +90,20 @@ def main(): 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']) + '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) + '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']) + 'mon.{0} is in state {1}, expected electing'.format( + m, mon_status['state']) expect('ceph daemon mon.{0} quorum enter'.format(m), 0) diff --git a/qa/workunits/mon/test_mon_config_key.py b/qa/workunits/mon/test_mon_config_key.py index 20f64c412bade..9e7537a743cff 100755 --- a/qa/workunits/mon/test_mon_config_key.py +++ b/qa/workunits/mon/test_mon_config_key.py @@ -9,17 +9,16 @@ # License version 2.1, as published by the Free Software # Foundation. See file COPYING. # -import sys -import os +import argparse import base64 -import time import errno +import logging +import os import random -import subprocess import string -import logging -import argparse - +import subprocess +import sys +import time # # Accepted Environment variables: @@ -34,7 +33,7 @@ # -LOG = logging.getLogger(os.path.basename(sys.argv[0].replace('.py',''))) +LOG = logging.getLogger(os.path.basename(sys.argv[0].replace('.py', ''))) SIZES = [ (0, 0), @@ -46,21 +45,22 @@ (4096, 0), (4097, -errno.EFBIG), (8192, -errno.EFBIG) - ] +] OPS = { - 'put':['existing','new'], - 'del':['existing','enoent'], - 'exists':['existing','enoent'], - 'get':['existing','enoent'] - } + 'put': ['existing', 'new'], + 'del': ['existing', 'enoent'], + 'exists': ['existing', 'enoent'], + 'get': ['existing', 'enoent'] +} + +CONFIG_PUT = [] # list: keys +CONFIG_DEL = [] # list: keys +CONFIG_EXISTING = {} # map: key -> size -CONFIG_PUT = [] #list: keys -CONFIG_DEL = [] #list: keys -CONFIG_EXISTING = {} #map: key -> size def run_cmd(cmd, expects=0): - full_cmd = [ 'ceph', 'config-key' ] + cmd + full_cmd = ['ceph', 'config-key'] + cmd if expects < 0: expects = -expects @@ -69,14 +69,14 @@ def run_cmd(cmd, expects=0): cmdlog.debug('{fc}'.format(fc=' '.join(full_cmd))) proc = subprocess.Popen(full_cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) stdout = [] stderr = [] while True: try: - (out, err) = proc.communicate() + out, err = proc.communicate() if out is not None: stdout += out.decode().split('\n') cmdlog.debug('stdout: {s}'.format(s=out)) @@ -89,8 +89,8 @@ def run_cmd(cmd, expects=0): if ret != expects: cmdlog.error('cmd > {cmd}'.format(cmd=full_cmd)) - cmdlog.error('expected return \'{expected}\' got \'{got}\''.format( - expected=expects,got=ret)) + cmdlog.error("expected return '{expected}' got '{got}'".format( + expected=expects, got=ret)) cmdlog.error('stdout') for i in stdout: cmdlog.error('{x}'.format(x=i)) @@ -98,24 +98,29 @@ def run_cmd(cmd, expects=0): for i in stderr: cmdlog.error('{x}'.format(x=i)) -#end run_cmd + +# end run_cmd def gen_data(size, rnd): chars = string.ascii_letters + string.digits - return ''.join(rnd.choice(chars) for i in range(size)) + return ''.join(rnd.choice(chars) for _ in range(size)) + def gen_key(rnd): return gen_data(20, rnd) + def gen_tmp_file_path(rnd): file_name = gen_data(20, rnd) - file_path = os.path.join('/tmp', 'ceph-test.'+file_name) + file_path = os.path.join('/tmp', 'ceph-test.' + file_name) return file_path + def destroy_tmp_file(fpath): if os.path.exists(fpath) and os.path.isfile(fpath): os.unlink(fpath) + def write_data_file(data, rnd): file_path = gen_tmp_file_path(rnd) data_file = open(file_path, 'a+') @@ -123,44 +128,46 @@ def write_data_file(data, rnd): data_file.write(data) data_file.close() return file_path -#end write_data_file + + +# end write_data_file def choose_random_op(rnd): op = rnd.choice( list(OPS.keys()) ) sop = rnd.choice(OPS[op]) - return (op, sop) + return op, sop def parse_args(args): parser = argparse.ArgumentParser( - description='Test the monitor\'s \'config-key\' API', - ) + description="Test the monitor's 'config-key' API", + ) parser.add_argument( '-v', '--verbose', action='store_true', help='be more verbose', - ) + ) parser.add_argument( '-s', '--seed', metavar='SEED', help='use SEED instead of generating it in run-time', - ) + ) parser.add_argument( '-d', '--duration', metavar='SECS', help='run test for SECS seconds (default: 300)', - ) + ) parser.set_defaults( seed=None, duration=300, verbose=False, - ) + ) return parser.parse_args(args) -def main(): +def main(): args = parse_args(sys.argv[1:]) verbose = args.verbose @@ -178,7 +185,7 @@ def main(): if verbose: loglevel = logging.DEBUG - logging.basicConfig(level=loglevel,) + logging.basicConfig(level=loglevel) LOG.info('seed: {s}'.format(s=seed)) @@ -194,7 +201,7 @@ def main(): via_file = (rnd.uniform(0, 100) < 50.0) expected = 0 - cmd = [ 'put' ] + cmd = ['put'] key = None if sop == 'existing': @@ -203,10 +210,10 @@ def main(): continue key = rnd.choice(CONFIG_PUT) assert key in CONFIG_EXISTING, \ - 'key \'{k_}\' not in CONFIG_EXISTING'.format(k_=key) + "key '{k_}' not in CONFIG_EXISTING".format(k_=key) - expected = 0 # the store just overrides the value if the key exists - #end if sop == 'existing' + expected = 0 # the store just overrides the value if the key exists + # end if sop == 'existing' elif sop == 'new': for x in range(0, 10): key = gen_key(rnd) @@ -223,14 +230,15 @@ def main(): assert key is not None, \ 'key must be != None' - cmd += [ key ] + cmd += [key] (size, error) = rnd.choice(SIZES) if size > 25: via_file = True data = gen_data(size, rnd) - if error == 0: # only add if we expect the put to be successful + + if error == 0: # only add if we expect the put to be successful if sop == 'new': CONFIG_PUT.append(key) CONFIG_EXISTING[key] = size @@ -238,14 +246,14 @@ def main(): if via_file: data_file = write_data_file(data, rnd) - cmd += [ '-i', data_file ] + cmd += ['-i', data_file] else: - cmd += [ data ] + cmd += [data] op_log.debug('size: {sz}, via: {v}'.format( sz=size, v='file: {f}'.format(f=data_file) if via_file == True else 'cli') - ) + ) run_cmd(cmd, expects=expected) if via_file: destroy_tmp_file(data_file) @@ -253,7 +261,7 @@ def main(): elif op == 'del': expected = 0 - cmd = [ 'del' ] + cmd = ['del'] key = None if sop == 'existing': @@ -262,7 +270,7 @@ def main(): continue key = rnd.choice(CONFIG_PUT) assert key in CONFIG_EXISTING, \ - 'key \'{k_}\' not in CONFIG_EXISTING'.format(k_=key) + "key '{k_}' not in CONFIG_EXISTING".format(k_=key) if sop == 'enoent': for x in range(0, 10): @@ -280,7 +288,7 @@ def main(): assert key is not None, \ 'key must be != None' - cmd += [ key ] + cmd += [key] op_log.debug('key: {k}'.format(k=key)) run_cmd(cmd, expects=expected) if sop == 'existing': @@ -291,7 +299,7 @@ def main(): elif op == 'exists': expected = 0 - cmd = [ 'exists' ] + cmd = ['exists'] key = None if sop == 'existing': @@ -300,7 +308,7 @@ def main(): continue key = rnd.choice(CONFIG_PUT) assert key in CONFIG_EXISTING, \ - 'key \'{k_}\' not in CONFIG_EXISTING'.format(k_=key) + "key '{k_}' not in CONFIG_EXISTING".format(k_=key) if sop == 'enoent': for x in range(0, 10): @@ -318,14 +326,14 @@ def main(): assert key is not None, \ 'key must be != None' - cmd += [ key ] + cmd += [key] op_log.debug('key: {k}'.format(k=key)) run_cmd(cmd, expects=expected) continue elif op == 'get': expected = 0 - cmd = [ 'get' ] + cmd = ['get'] key = None if sop == 'existing': @@ -334,7 +342,7 @@ def main(): continue key = rnd.choice(CONFIG_PUT) assert key in CONFIG_EXISTING, \ - 'key \'{k_}\' not in CONFIG_EXISTING'.format(k_=key) + "key '{k_}' not in CONFIG_EXISTING".format(k_=key) if sop == 'enoent': for x in range(0, 10): @@ -353,7 +361,7 @@ def main(): 'key must be != None' file_path = gen_tmp_file_path(rnd) - cmd += [ key, '-o', file_path ] + cmd += [key, '-o', file_path] op_log.debug('key: {k}'.format(k=key)) run_cmd(cmd, expects=expected) if sop == 'existing': @@ -362,7 +370,7 @@ def main(): except IOError as err: if err.errno == errno.ENOENT: assert CONFIG_EXISTING[key] == 0, \ - 'error opening \'{fp}\': {e}'.format(fp=file_path,e=err) + "error opening '{fp}': {e}".format(fp=file_path, e=err) continue else: assert False, \ @@ -374,8 +382,8 @@ def main(): break cnt += len(read_data) assert cnt == CONFIG_EXISTING[key], \ - 'wrong size from store for key \'{k}\': {sz}, expected {es}'.format( - k=key,sz=cnt,es=CONFIG_EXISTING[key]) + "wrong size from store for key '{k}': {sz}, expected {es}".format( + k=key, sz=cnt, es=CONFIG_EXISTING[key]) destroy_tmp_file(file_path) continue else: diff --git a/qa/workunits/rest/test.py b/qa/workunits/rest/test.py index 649e39005fa4d..f12cf2be1356e 100755 --- a/qa/workunits/rest/test.py +++ b/qa/workunits/rest/test.py @@ -29,6 +29,7 @@ def expect(url, method, respcode, contenttype, extra_hdrs=None, data=None): fail(r, failmsg) return r + def expect_nofail(url, method, respcode, contenttype, extra_hdrs=None, data=None): @@ -293,7 +294,6 @@ def expect_nofail(url, method, respcode, contenttype, extra_hdrs=None, r = expect('osd/ls', 'GET', 200, 'xml', XMLHDR) assert(r.tree.find('output/osds/osd') is not None) - expect('osd/pause', 'PUT', 200, '') r = expect('osd/dump', 'GET', 200, 'json', JSONHDR) assert('pauserd,pausewr' in r.myjson['output']['flags'])