X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fqa%2Fworkunits%2Fmon%2Ftest_mon_config_key.py;fp=src%2Fceph%2Fqa%2Fworkunits%2Fmon%2Ftest_mon_config_key.py;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=168f6db168cd5f0b379dace41949174ca0a4f7fa;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git 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()