diff options
Diffstat (limited to 'src/ceph/qa/workunits/mon')
-rwxr-xr-x | src/ceph/qa/workunits/mon/auth_caps.sh | 130 | ||||
-rw-r--r-- | src/ceph/qa/workunits/mon/caps.py | 366 | ||||
-rwxr-xr-x | src/ceph/qa/workunits/mon/caps.sh | 55 | ||||
-rwxr-xr-x | src/ceph/qa/workunits/mon/crush_ops.sh | 205 | ||||
-rwxr-xr-x | src/ceph/qa/workunits/mon/osd.sh | 24 | ||||
-rwxr-xr-x | src/ceph/qa/workunits/mon/ping.py | 114 | ||||
-rwxr-xr-x | src/ceph/qa/workunits/mon/pool_ops.sh | 49 | ||||
-rwxr-xr-x | src/ceph/qa/workunits/mon/rbd_snaps_ops.sh | 61 | ||||
-rwxr-xr-x | src/ceph/qa/workunits/mon/test_mon_config_key.py | 481 |
9 files changed, 0 insertions, 1485 deletions
diff --git a/src/ceph/qa/workunits/mon/auth_caps.sh b/src/ceph/qa/workunits/mon/auth_caps.sh deleted file mode 100755 index b8c1094..0000000 --- a/src/ceph/qa/workunits/mon/auth_caps.sh +++ /dev/null @@ -1,130 +0,0 @@ -#!/bin/bash - -set -e -set -x -declare -A keymap - -combinations="r w x rw rx wx rwx" - -for i in ${combinations}; do - k="foo_$i" - k=`ceph auth get-or-create-key client.$i mon "allow $i"` || exit 1 - keymap["$i"]=$k -done - -# add special caps -keymap["all"]=`ceph auth get-or-create-key client.all mon 'allow *'` || exit 1 - -tmp=`mktemp` -ceph auth export > $tmp - -trap "rm $tmp" INT ERR EXIT QUIT 0 - -expect() { - - set +e - - local expected_ret=$1 - local ret - - shift - cmd=$@ - - eval $cmd - ret=$? - - set -e - - if [[ $ret -ne $expected_ret ]]; then - echo "ERROR: running \'$cmd\': expected $expected_ret got $ret" - return 1 - fi - - return 0 -} - -read_ops() { - local caps=$1 - local has_read=1 has_exec=1 - local ret - local args - - ( echo $caps | grep 'r' ) || has_read=0 - ( echo $caps | grep 'x' ) || has_exec=0 - - if [[ "$caps" == "all" ]]; then - has_read=1 - has_exec=1 - fi - - ret=13 - if [[ $has_read -gt 0 && $has_exec -gt 0 ]]; then - ret=0 - fi - - args="--id $caps --key ${keymap[$caps]}" - - expect $ret ceph auth get client.admin $args - expect $ret ceph auth get-key client.admin $args - expect $ret ceph auth export $args - expect $ret ceph auth export client.admin $args - expect $ret ceph auth ls $args - expect $ret ceph auth print-key client.admin $args - expect $ret ceph auth print_key client.admin $args -} - -write_ops() { - - local caps=$1 - local has_read=1 has_write=1 has_exec=1 - local ret - local args - - ( echo $caps | grep 'r' ) || has_read=0 - ( echo $caps | grep 'w' ) || has_write=0 - ( echo $caps | grep 'x' ) || has_exec=0 - - if [[ "$caps" == "all" ]]; then - has_read=1 - has_write=1 - has_exec=1 - fi - - ret=13 - if [[ $has_read -gt 0 && $has_write -gt 0 && $has_exec -gt 0 ]]; then - ret=0 - fi - - args="--id $caps --key ${keymap[$caps]}" - - expect $ret ceph auth add client.foo $args - expect $ret "ceph auth caps client.foo mon 'allow *' $args" - expect $ret ceph auth get-or-create client.admin $args - expect $ret ceph auth get-or-create-key client.admin $args - expect $ret ceph auth get-or-create-key client.baz $args - expect $ret ceph auth del client.foo $args - expect $ret ceph auth del client.baz $args - expect $ret ceph auth import -i $tmp $args -} - -echo "running combinations: ${!keymap[@]}" - -subcmd=$1 - -for i in ${!keymap[@]}; do - echo "caps: $i" - if [[ -z "$subcmd" || "$subcmd" == "read" || "$subcmd" == "all" ]]; then - read_ops $i - fi - - if [[ -z "$subcmd" || "$subcmd" == "write" || "$subcmd" == "all" ]]; then - write_ops $i - fi -done - -# cleanup -for i in ${combinations} all; do - ceph auth del client.$i || exit 1 -done - -echo "OK" diff --git a/src/ceph/qa/workunits/mon/caps.py b/src/ceph/qa/workunits/mon/caps.py deleted file mode 100644 index 65a6956..0000000 --- a/src/ceph/qa/workunits/mon/caps.py +++ /dev/null @@ -1,366 +0,0 @@ -#!/usr/bin/python - -import json -import subprocess -import shlex -from StringIO import StringIO -import errno -import sys -import os -import io -import re - - -import rados -from ceph_argparse import * - -keyring_base = '/tmp/cephtest-caps.keyring' - -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, str) 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) - proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - ret = proc.wait() - - return (ret, proc) - -def expect(cmd, expected_ret): - - try: - (r, p) = call(cmd) - except ValueError as e: - print >> sys.stderr, \ - 'unable to run {c}: {err}'.format(c=repr(cmd), err=e.message) - return errno.EINVAL - - assert r == p.returncode, \ - 'wth? r was supposed to match returncode!' - - if r != expected_ret: - raise UnexpectedReturn(repr(cmd), r, expected_ret, str(p.stderr.read())) - - return p - -def expect_to_file(cmd, expected_ret, out_file, mode='a'): - - # Let the exception be propagated to the caller - p = expect(cmd, expected_ret) - assert p.returncode == expected_ret, \ - 'expected result doesn\'t match and no exception was thrown!' - - with io.open(out_file, mode) as file: - file.write(unicode(p.stdout.read())) - - return p - -class Command: - def __init__(self, cid, j): - self.cid = cid[3:] - self.perms = j['perm'] - self.module = j['module'] - - self.sig = '' - self.args = [] - for s in j['sig']: - if not isinstance(s, dict): - assert isinstance(s, str) or isinstance(s,unicode), \ - 'malformatted signature cid {0}: {1}\n{2}'.format(cid,s,j) - if len(self.sig) > 0: - self.sig += ' ' - self.sig += s - else: - self.args.append(s) - - def __str__(self): - return repr('command {0}: {1} (requires \'{2}\')'.format(self.cid,\ - self.sig, self.perms)) - - -def destroy_keyring(path): - if not os.path.exists(path): - raise Exception('oops! cannot remove inexistent keyring {0}'.format(path)) - - # grab all client entities from the keyring - entities = [m.group(1) for m in [re.match(r'\[client\.(.*)\]', l) - for l in [str(line.strip()) - for line in io.open(path,'r')]] if m is not None] - - # clean up and make sure each entity is gone - for e in entities: - expect('ceph auth del client.{0}'.format(e), 0) - expect('ceph auth get client.{0}'.format(e), errno.ENOENT) - - # remove keyring - os.unlink(path) - - return True - -def test_basic_auth(): - # make sure we can successfully add/del entities, change their caps - # and import/export keyrings. - - expect('ceph auth add client.basicauth', 0) - expect('ceph auth caps client.basicauth mon \'allow *\'', 0) - # entity exists and caps do not match - expect('ceph auth add client.basicauth', errno.EINVAL) - # this command attempts to change an existing state and will fail - expect('ceph auth add client.basicauth mon \'allow w\'', errno.EINVAL) - expect('ceph auth get-or-create client.basicauth', 0) - expect('ceph auth get-key client.basicauth', 0) - expect('ceph auth get-or-create client.basicauth2', 0) - # cleanup - expect('ceph auth del client.basicauth', 0) - expect('ceph auth del client.basicauth2', 0) - - return True - -def gen_module_keyring(module): - module_caps = [ - ('all', '{t} \'allow service {s} rwx\'', 0), - ('none', '', errno.EACCES), - ('wrong', '{t} \'allow service foobar rwx\'', errno.EACCES), - ('right', '{t} \'allow service {s} {p}\'', 0), - ('no-execute', '{t} \'allow service {s} x\'', errno.EACCES) - ] - - keyring = '{0}.service-{1}'.format(keyring_base,module) - for perms in 'r rw x'.split(): - for (n,p,r) in module_caps: - c = p.format(t='mon', s=module, p=perms) - expect_to_file( - 'ceph auth get-or-create client.{cn}-{cp} {caps}'.format( - cn=n,cp=perms,caps=c), 0, keyring) - - return keyring - - -def test_all(): - - - perms = { - 'good': { - 'broad':[ - ('rwx', 'allow *'), - ('r', 'allow r'), - ('rw', 'allow rw'), - ('x', 'allow x'), - ], - 'service':[ - ('rwx', 'allow service {s} rwx'), - ('r', 'allow service {s} r'), - ('rw', 'allow service {s} rw'), - ('x', 'allow service {s} x'), - ], - 'command':[ - ('rwx', 'allow command "{c}"'), - ], - 'command-with':[ - ('rwx', 'allow command "{c}" with {kv}') - ], - 'command-with-prefix':[ - ('rwx', 'allow command "{c}" with {key} prefix {val}') - ] - }, - 'bad': { - 'broad':[ - ('none', ''), - ], - 'service':[ - ('none1', 'allow service foo rwx'), - ('none2', 'allow service foo r'), - ('none3', 'allow service foo rw'), - ('none4', 'allow service foo x'), - ], - 'command':[ - ('none', 'allow command foo'), - ], - 'command-with':[ - ('none', 'allow command "{c}" with foo=bar'), - ], - 'command-with-prefix':[ - ('none', 'allow command "{c}" with foo prefix bar'), - ], - } - } - - cmds = { - '':[ - { - 'cmd':('status', '', 'r') - }, - { - 'pre':'heap start_profiler', - 'cmd':('heap', 'heapcmd=stats', 'rw'), - 'post':'heap stop_profiler' - } - ], - 'auth':[ - { - 'pre':'', - 'cmd':('auth ls', '', 'r'), - 'post':'' - }, - { - 'pre':'auth get-or-create client.foo mon \'allow *\'', - 'cmd':('auth caps', 'entity="client.foo"', 'rw'), - 'post':'auth del client.foo' - } - ], - 'pg':[ - { - 'cmd':('pg getmap', '', 'r'), - }, - ], - 'mds':[ - { - 'cmd':('mds getmap', '', 'r'), - }, - { - 'cmd':('mds cluster_down', '', 'rw'), - 'post':'mds cluster_up' - }, - ], - 'mon':[ - { - 'cmd':('mon getmap', '', 'r') - }, - { - 'cmd':('mon remove', 'name=a', 'rw') - } - ], - 'osd':[ - { - 'cmd':('osd getmap', '', 'r'), - }, - { - 'cmd':('osd pause', '', 'rw'), - 'post':'osd unpause' - }, - { - 'cmd':('osd crush dump', '', 'r') - }, - ], - 'config-key':[ - { - 'pre':'config-key set foo bar', - 'cmd':('config-key get', 'key=foo', 'r') - }, - { - 'pre':'config-key set foo bar', - 'cmd':('config-key del', 'key=foo', 'rw') - } - ] - } - - for (module,cmd_lst) in cmds.iteritems(): - k = keyring_base + '.' + module - for cmd in cmd_lst: - - (cmd_cmd, cmd_args, cmd_perm) = cmd['cmd'] - cmd_args_key = '' - cmd_args_val = '' - if len(cmd_args) > 0: - (cmd_args_key, cmd_args_val) = cmd_args.split('=') - - print 'generating keyring for {m}/{c}'.format(m=module,c=cmd_cmd) - # gen keyring - for (good_or_bad,kind_map) in perms.iteritems(): - for (kind,lst) in kind_map.iteritems(): - for (perm, cap) in lst: - cap_formatted = cap.format( - s=module, - c=cmd_cmd, - kv=cmd_args, - key=cmd_args_key, - val=cmd_args_val) - - if len(cap_formatted) == 0: - run_cap = '' - else: - run_cap = 'mon \'{fc}\''.format(fc=cap_formatted) - - cname = 'client.{gb}-{kind}-{p}'.format( - gb=good_or_bad,kind=kind,p=perm) - expect_to_file( - 'ceph auth get-or-create {n} {c}'.format( - n=cname,c=run_cap), 0, k) - # keyring generated - print 'testing {m}/{c}'.format(m=module,c=cmd_cmd) - - # test - for good_bad in perms.iterkeys(): - for (kind,lst) in perms[good_bad].iteritems(): - for (perm,_) in lst: - cname = 'client.{gb}-{k}-{p}'.format(gb=good_bad,k=kind,p=perm) - - if good_bad == 'good': - expect_ret = 0 - else: - expect_ret = errno.EACCES - - if ( cmd_perm not in perm ): - expect_ret = errno.EACCES - if 'with' in kind and len(cmd_args) == 0: - expect_ret = errno.EACCES - if 'service' in kind and len(module) == 0: - expect_ret = errno.EACCES - - if 'pre' in cmd and len(cmd['pre']) > 0: - expect('ceph {0}'.format(cmd['pre']), 0) - expect('ceph -n {cn} -k {k} {c} {arg_val}'.format( - cn=cname,k=k,c=cmd_cmd,arg_val=cmd_args_val), expect_ret) - if 'post' in cmd and len(cmd['post']) > 0: - expect('ceph {0}'.format(cmd['post']), 0) - # finish testing - destroy_keyring(k) - - - return True - - -def test_misc(): - - k = keyring_base + '.misc' - expect_to_file( - 'ceph auth get-or-create client.caps mon \'allow command "auth caps"' \ - ' with entity="client.caps"\'', 0, k) - expect('ceph -n client.caps -k {kf} mon_status'.format(kf=k), errno.EACCES) - expect('ceph -n client.caps -k {kf} auth caps client.caps mon \'allow *\''.format(kf=k), 0) - expect('ceph -n client.caps -k {kf} mon_status'.format(kf=k), 0) - destroy_keyring(k) - -def main(): - - test_basic_auth() - test_all() - test_misc() - - print 'OK' - - return 0 - -if __name__ == '__main__': - main() diff --git a/src/ceph/qa/workunits/mon/caps.sh b/src/ceph/qa/workunits/mon/caps.sh deleted file mode 100755 index e00247d..0000000 --- a/src/ceph/qa/workunits/mon/caps.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash - -tmp=/tmp/cephtest-mon-caps-madness - -exit_on_error=1 - -[[ ! -z $TEST_EXIT_ON_ERROR ]] && exit_on_error=$TEST_EXIT_ON_ERROR - -expect() -{ - cmd=$1 - expected_ret=$2 - - echo $cmd - eval $cmd >&/dev/null - ret=$? - - if [[ $ret -ne $expected_ret ]]; then - echo "Error: Expected return $expected_ret, got $ret" - [[ $exit_on_error -eq 1 ]] && exit 1 - return 1 - fi - - return 0 -} - -expect "ceph auth get-or-create client.bazar > $tmp.bazar.keyring" 0 -expect "ceph -k $tmp.bazar.keyring --user bazar mon_status" 13 -ceph auth del client.bazar - -c="'allow command \"auth ls\", allow command mon_status'" -expect "ceph auth get-or-create client.foo mon $c > $tmp.foo.keyring" 0 -expect "ceph -k $tmp.foo.keyring --user foo mon_status" 0 -expect "ceph -k $tmp.foo.keyring --user foo auth ls" 0 -expect "ceph -k $tmp.foo.keyring --user foo auth export" 13 -expect "ceph -k $tmp.foo.keyring --user foo auth del client.bazar" 13 -expect "ceph -k $tmp.foo.keyring --user foo osd dump" 13 -expect "ceph -k $tmp.foo.keyring --user foo pg dump" 13 -expect "ceph -k $tmp.foo.keyring --user foo quorum_status" 13 -ceph auth del client.foo - -c="'allow command service with prefix=list, allow command mon_status'" -expect "ceph auth get-or-create client.bar mon $c > $tmp.bar.keyring" 0 -expect "ceph -k $tmp.bar.keyring --user bar mon_status" 0 -expect "ceph -k $tmp.bar.keyring --user bar auth ls" 13 -expect "ceph -k $tmp.bar.keyring --user bar auth export" 13 -expect "ceph -k $tmp.bar.keyring --user bar auth del client.foo" 13 -expect "ceph -k $tmp.bar.keyring --user bar osd dump" 13 -expect "ceph -k $tmp.bar.keyring --user bar pg dump" 13 -expect "ceph -k $tmp.bar.keyring --user bar quorum_status" 13 -ceph auth del client.bar - -rm $tmp.bazar.keyring $tmp.foo.keyring $tmp.bar.keyring - -echo OK diff --git a/src/ceph/qa/workunits/mon/crush_ops.sh b/src/ceph/qa/workunits/mon/crush_ops.sh deleted file mode 100755 index 348811e..0000000 --- a/src/ceph/qa/workunits/mon/crush_ops.sh +++ /dev/null @@ -1,205 +0,0 @@ -#!/bin/bash -x - -set -e - -function expect_false() -{ - set -x - if "$@"; then return 1; else return 0; fi -} - -ceph osd crush dump - -# rules -ceph osd crush rule dump -ceph osd crush rule ls -ceph osd crush rule list - -ceph osd crush rule create-simple foo default host -ceph osd crush rule create-simple foo default host -ceph osd crush rule create-simple bar default host - -# make sure we're at luminous+ before using crush device classes -ceph osd require-osd-release luminous -ceph osd crush rm-device-class all -ceph osd crush set-device-class ssd osd.0 -ceph osd crush set-device-class hdd osd.1 -ceph osd crush rule create-replicated foo-ssd default host ssd -ceph osd crush rule create-replicated foo-hdd default host hdd -ceph osd crush rule ls-by-class ssd | grep 'foo-ssd' -ceph osd crush rule ls-by-class ssd | expect_false grep 'foo-hdd' -ceph osd crush rule ls-by-class hdd | grep 'foo-hdd' -ceph osd crush rule ls-by-class hdd | expect_false grep 'foo-ssd' - -ceph osd erasure-code-profile set ec-foo-ssd crush-device-class=ssd m=2 k=2 -ceph osd pool create ec-foo 2 erasure ec-foo-ssd -ceph osd pool rm ec-foo ec-foo --yes-i-really-really-mean-it - -ceph osd crush rule ls | grep foo - -ceph osd crush rule rename foo foo-asdf -ceph osd crush rule rename foo foo-asdf # idempotent -ceph osd crush rule rename bar bar-asdf -ceph osd crush rule ls | grep 'foo-asdf' -ceph osd crush rule ls | grep 'bar-asdf' -ceph osd crush rule rm foo 2>&1 | grep 'does not exist' -ceph osd crush rule rm bar 2>&1 | grep 'does not exist' -ceph osd crush rule rename foo-asdf foo -ceph osd crush rule rename foo-asdf foo # idempotent -ceph osd crush rule rename bar-asdf bar -ceph osd crush rule ls | expect_false grep 'foo-asdf' -ceph osd crush rule ls | expect_false grep 'bar-asdf' -ceph osd crush rule rm foo -ceph osd crush rule rm foo # idempotent -ceph osd crush rule rm bar - -# can't delete in-use rules, tho: -ceph osd pool create pinning_pool 1 -expect_false ceph osd crush rule rm replicated_rule -ceph osd pool rm pinning_pool pinning_pool --yes-i-really-really-mean-it - -# build a simple map -expect_false ceph osd crush add-bucket foo osd -ceph osd crush add-bucket foo root -o1=`ceph osd create` -o2=`ceph osd create` -ceph osd crush add $o1 1 host=host1 root=foo -ceph osd crush add $o1 1 host=host1 root=foo # idemptoent -ceph osd crush add $o2 1 host=host2 root=foo -ceph osd crush add $o2 1 host=host2 root=foo # idempotent -ceph osd crush add-bucket bar root -ceph osd crush add-bucket bar root # idempotent -ceph osd crush link host1 root=bar -ceph osd crush link host1 root=bar # idempotent -ceph osd crush link host2 root=bar -ceph osd crush link host2 root=bar # idempotent - -ceph osd tree | grep -c osd.$o1 | grep -q 2 -ceph osd tree | grep -c host1 | grep -q 2 -ceph osd tree | grep -c osd.$o2 | grep -q 2 -ceph osd tree | grep -c host2 | grep -q 2 -expect_false ceph osd crush rm host1 foo # not empty -ceph osd crush unlink host1 foo -ceph osd crush unlink host1 foo -ceph osd tree | grep -c host1 | grep -q 1 - -expect_false ceph osd crush rm foo # not empty -expect_false ceph osd crush rm bar # not empty -ceph osd crush unlink host1 bar -ceph osd tree | grep -c host1 | grep -q 1 # now an orphan -ceph osd crush rm osd.$o1 host1 -ceph osd crush rm host1 -ceph osd tree | grep -c host1 | grep -q 0 - -expect_false ceph osd crush rm bar # not empty -ceph osd crush unlink host2 - -# reference foo and bar with a rule -ceph osd crush rule create-simple foo-rule foo host firstn -expect_false ceph osd crush rm foo -ceph osd crush rule rm foo-rule - -ceph osd crush rm bar -ceph osd crush rm foo -ceph osd crush rm osd.$o2 host2 -ceph osd crush rm host2 - -ceph osd crush add-bucket foo host -ceph osd crush move foo root=default rack=localrack - -ceph osd crush create-or-move osd.$o1 1.0 root=default -ceph osd crush move osd.$o1 host=foo -ceph osd find osd.$o1 | grep host | grep foo - -ceph osd crush rm osd.$o1 -ceph osd crush rm osd.$o2 - -ceph osd crush rm foo - -# test reweight -o3=`ceph osd create` -ceph osd crush add $o3 123 root=default -ceph osd tree | grep osd.$o3 | grep 123 -ceph osd crush reweight osd.$o3 113 -expect_false ceph osd crush reweight osd.$o3 123456 -ceph osd tree | grep osd.$o3 | grep 113 -ceph osd crush rm osd.$o3 -ceph osd rm osd.$o3 - -# test reweight-subtree -o4=`ceph osd create` -o5=`ceph osd create` -ceph osd crush add $o4 123 root=default host=foobaz -ceph osd crush add $o5 123 root=default host=foobaz -ceph osd tree | grep osd.$o4 | grep 123 -ceph osd tree | grep osd.$o5 | grep 123 -ceph osd crush reweight-subtree foobaz 155 -expect_false ceph osd crush reweight-subtree foobaz 123456 -ceph osd tree | grep osd.$o4 | grep 155 -ceph osd tree | grep osd.$o5 | grep 155 -ceph osd crush rm osd.$o4 -ceph osd crush rm osd.$o5 -ceph osd rm osd.$o4 -ceph osd rm osd.$o5 - -# weight sets -# make sure we require luminous before testing weight-sets -ceph osd set-require-min-compat-client luminous -ceph osd crush weight-set dump -ceph osd crush weight-set ls -expect_false ceph osd crush weight-set reweight fooset osd.0 .9 -ceph osd pool create fooset 8 -ceph osd pool create barset 8 -ceph osd pool set barset size 3 -expect_false ceph osd crush weight-set reweight fooset osd.0 .9 -ceph osd crush weight-set create fooset flat -ceph osd crush weight-set create barset positional -ceph osd crush weight-set ls | grep fooset -ceph osd crush weight-set ls | grep barset -ceph osd crush weight-set dump -ceph osd crush weight-set reweight fooset osd.0 .9 -expect_false ceph osd crush weight-set reweight fooset osd.0 .9 .9 -expect_false ceph osd crush weight-set reweight barset osd.0 .9 -ceph osd crush weight-set reweight barset osd.0 .9 .9 .9 -ceph osd crush weight-set ls | grep -c fooset | grep -q 1 -ceph osd crush weight-set rm fooset -ceph osd crush weight-set ls | grep -c fooset | grep -q 0 -ceph osd crush weight-set ls | grep barset -ceph osd crush weight-set rm barset -ceph osd crush weight-set ls | grep -c barset | grep -q 0 -ceph osd crush weight-set create-compat -ceph osd crush weight-set ls | grep '(compat)' -ceph osd crush weight-set rm-compat - -# weight set vs device classes -ceph osd pool create cool 2 -ceph osd pool create cold 2 -ceph osd pool set cold size 2 -ceph osd crush weight-set create-compat -ceph osd crush weight-set create cool flat -ceph osd crush weight-set create cold positional -ceph osd crush rm-device-class osd.0 -ceph osd crush weight-set reweight-compat osd.0 10.5 -ceph osd crush weight-set reweight cool osd.0 11.5 -ceph osd crush weight-set reweight cold osd.0 12.5 12.4 -ceph osd crush set-device-class fish osd.0 -ceph osd crush tree --show-shadow | grep osd\\.0 | grep fish | grep 10\\. -ceph osd crush tree --show-shadow | grep osd\\.0 | grep fish | grep 11\\. -ceph osd crush tree --show-shadow | grep osd\\.0 | grep fish | grep 12\\. -ceph osd crush rm-device-class osd.0 -ceph osd crush set-device-class globster osd.0 -ceph osd crush tree --show-shadow | grep osd\\.0 | grep globster | grep 10\\. -ceph osd crush tree --show-shadow | grep osd\\.0 | grep globster | grep 11\\. -ceph osd crush tree --show-shadow | grep osd\\.0 | grep globster | grep 12\\. -ceph osd crush weight-set reweight-compat osd.0 7.5 -ceph osd crush weight-set reweight cool osd.0 8.5 -ceph osd crush weight-set reweight cold osd.0 6.5 6.6 -ceph osd crush tree --show-shadow | grep osd\\.0 | grep globster | grep 7\\. -ceph osd crush tree --show-shadow | grep osd\\.0 | grep globster | grep 8\\. -ceph osd crush tree --show-shadow | grep osd\\.0 | grep globster | grep 6\\. -ceph osd crush rm-device-class osd.0 -ceph osd pool rm cool cool --yes-i-really-really-mean-it -ceph osd pool rm cold cold --yes-i-really-really-mean-it -ceph osd crush weight-set rm-compat - -echo OK diff --git a/src/ceph/qa/workunits/mon/osd.sh b/src/ceph/qa/workunits/mon/osd.sh deleted file mode 100755 index 75bf220..0000000 --- a/src/ceph/qa/workunits/mon/osd.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -x - -set -e - -ua=`uuidgen` -ub=`uuidgen` - -# shoudl get same id with same uuid -na=`ceph osd create $ua` -test $na -eq `ceph osd create $ua` - -nb=`ceph osd create $ub` -test $nb -eq `ceph osd create $ub` -test $nb -ne $na - -ceph osd rm $na -ceph osd rm $na -ceph osd rm $nb -ceph osd rm 1000 - -na2=`ceph osd create $ua` - -echo OK - diff --git a/src/ceph/qa/workunits/mon/ping.py b/src/ceph/qa/workunits/mon/ping.py deleted file mode 100755 index 1773c73..0000000 --- a/src/ceph/qa/workunits/mon/ping.py +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/python - -import json -import shlex -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, 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) - 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, 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)) - 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=str(e)) - - if r != expected_ret: - raise UnexpectedReturn(repr(cmd), r, expected_ret, err) - - return out.decode() if isinstance(out, bytes) else 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() diff --git a/src/ceph/qa/workunits/mon/pool_ops.sh b/src/ceph/qa/workunits/mon/pool_ops.sh deleted file mode 100755 index b19dbd1..0000000 --- a/src/ceph/qa/workunits/mon/pool_ops.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash -x - -set -e - -function expect_false() -{ - set -x - if "$@"; then return 1; else return 0; fi -} - -# note: we need to pass the other args or ceph_argparse.py will take -# 'invalid' that is not replicated|erasure and assume it is the next -# argument, which is a string. -expect_false ceph osd pool create foo 123 123 invalid foo-profile foo-ruleset - -ceph osd pool create foo 123 123 replicated -ceph osd pool create fooo 123 123 erasure default -ceph osd pool create foooo 123 - -ceph osd pool create foo 123 # idempotent - -ceph osd pool set foo size 1 -ceph osd pool set foo size 4 -ceph osd pool set foo size 10 -expect_false ceph osd pool set foo size 0 -expect_false ceph osd pool set foo size 20 - -# should fail due to safety interlock -expect_false ceph osd pool delete foo -expect_false ceph osd pool delete foo foo -expect_false ceph osd pool delete foo foo --force -expect_false ceph osd pool delete foo fooo --yes-i-really-mean-it -expect_false ceph osd pool delete foo --yes-i-really-mean-it foo - -ceph osd pool delete foooo foooo --yes-i-really-really-mean-it -ceph osd pool delete fooo fooo --yes-i-really-really-mean-it -ceph osd pool delete foo foo --yes-i-really-really-mean-it - -# idempotent -ceph osd pool delete foo foo --yes-i-really-really-mean-it -ceph osd pool delete fooo fooo --yes-i-really-really-mean-it -ceph osd pool delete fooo fooo --yes-i-really-really-mean-it - -# non-existent pool -ceph osd pool delete fuggg fuggg --yes-i-really-really-mean-it - -echo OK - - diff --git a/src/ceph/qa/workunits/mon/rbd_snaps_ops.sh b/src/ceph/qa/workunits/mon/rbd_snaps_ops.sh deleted file mode 100755 index 2bff335..0000000 --- a/src/ceph/qa/workunits/mon/rbd_snaps_ops.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash - -# attempt to trigger #6047 - - -cmd_no=0 -expect() -{ - cmd_no=$(($cmd_no+1)) - cmd="$1" - expected=$2 - echo "[$cmd_no] $cmd" - eval $cmd - ret=$? - if [[ $ret -ne $expected ]]; then - echo "[$cmd_no] unexpected return '$ret', expected '$expected'" - exit 1 - fi -} - -ceph osd pool delete test test --yes-i-really-really-mean-it || true -expect 'ceph osd pool create test 256 256' 0 -expect 'rbd --pool=test pool init' 0 -expect 'ceph osd pool mksnap test snapshot' 0 -expect 'ceph osd pool rmsnap test snapshot' 0 - -expect 'rbd --pool=test --rbd_validate_pool=false create --size=102400 image' 0 -expect 'rbd --pool=test snap create image@snapshot' 22 - -expect 'ceph osd pool delete test test --yes-i-really-really-mean-it' 0 -expect 'ceph osd pool create test 256 256' 0 -expect 'rbd --pool=test pool init' 0 -expect 'rbd --pool=test create --size=102400 image' 0 -expect 'rbd --pool=test snap create image@snapshot' 0 -expect 'rbd --pool=test snap ls image' 0 -expect 'rbd --pool=test snap rm image@snapshot' 0 - -expect 'ceph osd pool mksnap test snapshot' 22 - -expect 'ceph osd pool delete test test --yes-i-really-really-mean-it' 0 - -# reproduce 7210 and expect it to be fixed -# basically create such a scenario where we end up deleting what used to -# be an unmanaged snapshot from a not-unmanaged pool - -ceph osd pool delete test-foo test-foo --yes-i-really-really-mean-it || true -expect 'rados mkpool test-foo' 0 -expect 'rbd pool init test-foo' -expect 'rbd --pool test-foo create --size 1024 image' 0 -expect 'rbd --pool test-foo snap create image@snapshot' 0 - -ceph osd pool delete test-bar test-bar --yes-i-really-really-mean-it || true -expect 'rados mkpool test-bar' 0 -expect 'rbd pool init test-bar' -expect 'rados cppool test-foo test-bar --yes-i-really-mean-it' 0 -expect 'rbd --pool test-bar snap rm image@snapshot' 95 -expect 'ceph osd pool delete test-foo test-foo --yes-i-really-really-mean-it' 0 -expect 'ceph osd pool delete test-bar test-bar --yes-i-really-really-mean-it' 0 - - -echo OK diff --git a/src/ceph/qa/workunits/mon/test_mon_config_key.py b/src/ceph/qa/workunits/mon/test_mon_config_key.py deleted file mode 100755 index 168f6db..0000000 --- a/src/ceph/qa/workunits/mon/test_mon_config_key.py +++ /dev/null @@ -1,481 +0,0 @@ -#!/usr/bin/python -# -# test_mon_config_key - Test 'ceph config-key' interface -# -# Copyright (C) 2013 Inktank -# -# This is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License version 2.1, as published by the Free Software -# Foundation. See file COPYING. -# -import argparse -import base64 -import errno -import json -import logging -import os -import random -import string -import subprocess -import sys -import time - -# -# Accepted Environment variables: -# CEPH_TEST_VERBOSE - be more verbose; '1' enables; '0' disables -# CEPH_TEST_DURATION - test duration in seconds -# CEPH_TEST_SEED - seed to be used during the test -# -# Accepted arguments and options (see --help): -# -v, --verbose - be more verbose -# -d, --duration SECS - test duration in seconds -# -s, --seed SEED - seed to be used during the test -# - - -LOG = logging.getLogger(os.path.basename(sys.argv[0].replace('.py', ''))) - -SIZES = [ - (0, 0), - (10, 0), - (25, 0), - (50, 0), - (100, 0), - (1000, 0), - (4096, 0), - (4097, -errno.EFBIG), - (8192, -errno.EFBIG) -] - -# tests will be randomly selected from the keys here, and the test -# suboperation will be randomly selected from the list in the values -# here. i.e. 'exists/existing' would test that a key the test put into -# the store earlier actually does still exist in the config store, -# and that's a separate test case from 'exists/enoent', which tests -# nonexistence of a key known to not be present. - -OPS = { - 'put': ['existing', 'new'], - 'del': ['existing', 'enoent'], - 'exists': ['existing', 'enoent'], - 'get': ['existing', 'enoent'], - 'list': ['existing', 'enoent'], - 'dump': ['existing', 'enoent'], -} - -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 - - if expects < 0: - expects = -expects - - cmdlog = LOG.getChild('run_cmd') - cmdlog.debug('{fc}'.format(fc=' '.join(full_cmd))) - - proc = subprocess.Popen(full_cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - - stdout = [] - stderr = [] - while True: - try: - out, err = proc.communicate() - if out is not None: - stdout += out.decode().split('\n') - cmdlog.debug('stdout: {s}'.format(s=out)) - if err is not None: - stdout += err.decode().split('\n') - cmdlog.debug('stderr: {s}'.format(s=err)) - except ValueError: - ret = proc.wait() - break - - 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('stdout') - for i in stdout: - cmdlog.error('{x}'.format(x=i)) - cmdlog.error('stderr') - for i in stderr: - cmdlog.error('{x}'.format(x=i)) - - -# end run_cmd - -def gen_data(size, rnd): - chars = string.ascii_letters + string.digits - 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) - 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+') - data_file.truncate() - data_file.write(data) - data_file.close() - return file_path - - -# end write_data_file - -def choose_random_op(rnd): - op = rnd.choice( - list(OPS.keys()) - ) - sop = rnd.choice(OPS[op]) - return op, sop - - -def parse_args(args): - parser = argparse.ArgumentParser( - 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(): - args = parse_args(sys.argv[1:]) - - verbose = args.verbose - if os.environ.get('CEPH_TEST_VERBOSE') is not None: - verbose = (os.environ.get('CEPH_TEST_VERBOSE') == '1') - - duration = int(os.environ.get('CEPH_TEST_DURATION', args.duration)) - seed = os.environ.get('CEPH_TEST_SEED', args.seed) - seed = int(time.time()) if seed is None else int(seed) - - rnd = random.Random() - rnd.seed(seed) - - loglevel = logging.INFO - if verbose: - loglevel = logging.DEBUG - - logging.basicConfig(level=loglevel) - - LOG.info('seed: {s}'.format(s=seed)) - - start = time.time() - - while (time.time() - start) < duration: - (op, sop) = choose_random_op(rnd) - - LOG.info('{o}({s})'.format(o=op, s=sop)) - op_log = LOG.getChild('{o}({s})'.format(o=op, s=sop)) - - if op == 'put': - via_file = (rnd.uniform(0, 100) < 50.0) - - expected = 0 - cmd = ['put'] - key = None - - if sop == 'existing': - if len(CONFIG_EXISTING) == 0: - op_log.debug('no existing keys; continue') - continue - key = rnd.choice(CONFIG_PUT) - assert key in CONFIG_EXISTING, \ - "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' - elif sop == 'new': - for x in range(0, 10): - key = gen_key(rnd) - if key not in CONFIG_EXISTING: - break - key = None - if key is None: - op_log.error('unable to generate an unique key -- try again later.') - continue - - assert key not in CONFIG_PUT and key not in CONFIG_EXISTING, \ - 'key {k} was not supposed to exist!'.format(k=key) - - assert key is not None, \ - 'key must be != None' - - 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 sop == 'new': - CONFIG_PUT.append(key) - CONFIG_EXISTING[key] = size - expected = error - - if via_file: - data_file = write_data_file(data, rnd) - cmd += ['-i', data_file] - else: - 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) - continue - - elif op == 'del': - expected = 0 - cmd = ['del'] - key = None - - if sop == 'existing': - if len(CONFIG_EXISTING) == 0: - op_log.debug('no existing keys; continue') - continue - key = rnd.choice(CONFIG_PUT) - assert key in CONFIG_EXISTING, \ - "key '{k_}' not in CONFIG_EXISTING".format(k_=key) - - if sop == 'enoent': - for x in range(0, 10): - key = base64.b64encode(os.urandom(20)).decode() - if key not in CONFIG_EXISTING: - break - key = None - if key is None: - op_log.error('unable to generate an unique key -- try again later.') - continue - assert key not in CONFIG_PUT and key not in CONFIG_EXISTING, \ - 'key {k} was not supposed to exist!'.format(k=key) - expected = 0 # deleting a non-existent key succeeds - - assert key is not None, \ - 'key must be != None' - - cmd += [key] - op_log.debug('key: {k}'.format(k=key)) - run_cmd(cmd, expects=expected) - if sop == 'existing': - CONFIG_DEL.append(key) - CONFIG_PUT.remove(key) - del CONFIG_EXISTING[key] - continue - - elif op == 'exists': - expected = 0 - cmd = ['exists'] - key = None - - if sop == 'existing': - if len(CONFIG_EXISTING) == 0: - op_log.debug('no existing keys; continue') - continue - key = rnd.choice(CONFIG_PUT) - assert key in CONFIG_EXISTING, \ - "key '{k_}' not in CONFIG_EXISTING".format(k_=key) - - if sop == 'enoent': - for x in range(0, 10): - key = base64.b64encode(os.urandom(20)).decode() - if key not in CONFIG_EXISTING: - break - key = None - if key is None: - op_log.error('unable to generate an unique key -- try again later.') - continue - assert key not in CONFIG_PUT and key not in CONFIG_EXISTING, \ - 'key {k} was not supposed to exist!'.format(k=key) - expected = -errno.ENOENT - - assert key is not None, \ - 'key must be != None' - - cmd += [key] - op_log.debug('key: {k}'.format(k=key)) - run_cmd(cmd, expects=expected) - continue - - elif op == 'get': - expected = 0 - cmd = ['get'] - key = None - - if sop == 'existing': - if len(CONFIG_EXISTING) == 0: - op_log.debug('no existing keys; continue') - continue - key = rnd.choice(CONFIG_PUT) - assert key in CONFIG_EXISTING, \ - "key '{k_}' not in CONFIG_EXISTING".format(k_=key) - - if sop == 'enoent': - for x in range(0, 10): - key = base64.b64encode(os.urandom(20)).decode() - if key not in CONFIG_EXISTING: - break - key = None - if key is None: - op_log.error('unable to generate an unique key -- try again later.') - continue - assert key not in CONFIG_PUT and key not in CONFIG_EXISTING, \ - 'key {k} was not supposed to exist!'.format(k=key) - expected = -errno.ENOENT - - assert key is not None, \ - 'key must be != None' - - file_path = gen_tmp_file_path(rnd) - cmd += [key, '-o', file_path] - op_log.debug('key: {k}'.format(k=key)) - run_cmd(cmd, expects=expected) - if sop == 'existing': - try: - temp_file = open(file_path, 'r+') - except IOError as err: - if err.errno == errno.ENOENT: - assert CONFIG_EXISTING[key] == 0, \ - "error opening '{fp}': {e}".format(fp=file_path, e=err) - continue - else: - assert False, \ - 'some error occurred: {e}'.format(e=err) - cnt = 0 - while True: - read_data = temp_file.read() - if read_data == '': - 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]) - destroy_tmp_file(file_path) - continue - - elif op == 'list' or op == 'dump': - expected = 0 - cmd = [op] - key = None - - if sop == 'existing': - if len(CONFIG_EXISTING) == 0: - op_log.debug('no existing keys; continue') - continue - key = rnd.choice(CONFIG_PUT) - assert key in CONFIG_EXISTING, \ - "key '{k_}' not in CONFIG_EXISTING".format(k_=key) - - if sop == 'enoent': - for x in range(0, 10): - key = base64.b64encode(os.urandom(20)).decode() - if key not in CONFIG_EXISTING: - break - key = None - if key is None: - op_log.error('unable to generate an unique key -- try again later.') - continue - assert key not in CONFIG_PUT and key not in CONFIG_EXISTING, \ - 'key {k} was not supposed to exist!'.format(k=key) - - assert key is not None, \ - 'key must be != None' - - file_path = gen_tmp_file_path(rnd) - cmd += ['-o', file_path] - op_log.debug('key: {k}'.format(k=key)) - run_cmd(cmd, expects=expected) - try: - temp_file = open(file_path, 'r+') - except IOError as err: - if err.errno == errno.ENOENT: - assert CONFIG_EXISTING[key] == 0, \ - "error opening '{fp}': {e}".format(fp=file_path, e=err) - continue - else: - assert False, \ - 'some error occurred: {e}'.format(e=err) - cnt = 0 - try: - read_data = json.load(temp_file) - except ValueError: - temp_file.seek(0) - assert False, "{op} output was not valid JSON:\n{filedata}".format(op, temp_file.readlines()) - - if sop == 'existing': - assert key in read_data, "key '{k}' not found in list/dump output".format(k=key) - if op == 'dump': - cnt = len(read_data[key]) - assert cnt == CONFIG_EXISTING[key], \ - "wrong size from list for key '{k}': {sz}, expected {es}".format( - k=key, sz=cnt, es=CONFIG_EXISTING[key]) - elif sop == 'enoent': - assert key not in read_data, "key '{k}' found in list/dump output".format(k=key) - destroy_tmp_file(file_path) - continue - else: - assert False, 'unknown op {o}'.format(o=op) - - # check if all keys in 'CONFIG_PUT' exist and - # if all keys on 'CONFIG_DEL' don't. - # but first however, remove all keys in CONFIG_PUT that might - # be in CONFIG_DEL as well. - config_put_set = set(CONFIG_PUT) - config_del_set = set(CONFIG_DEL).difference(config_put_set) - - LOG.info('perform sanity checks on store') - - for k in config_put_set: - LOG.getChild('check(puts)').debug('key: {k_}'.format(k_=k)) - run_cmd(['exists', k], expects=0) - for k in config_del_set: - LOG.getChild('check(dels)').debug('key: {k_}'.format(k_=k)) - run_cmd(['exists', k], expects=-errno.ENOENT) - - -if __name__ == "__main__": - main() |