2 Admin Socket task -- used in rados, powercycle, and smoke testing
4 from cStringIO import StringIO
11 from teuthology.orchestra import run
12 from teuthology import misc as teuthology
13 from teuthology.parallel import parallel
14 from teuthology.config import config as teuth_config
16 log = logging.getLogger(__name__)
19 def task(ctx, config):
21 Run an admin socket command, make sure the output is json, and run
22 a test program on it. The test program should read json from
23 stdin. This task succeeds if the test program exits with status 0.
25 To run the same test on all clients::
33 test: http://example.com/script
35 To restrict it to certain clients::
43 test: http://example.com/script
45 If an admin socket command has arguments, they can be specified as
54 test: http://example.com/script
56 test: http://example.com/test_help_version
59 Note that there must be a ceph client with an admin socket running
60 before this task is run. The tests are parallelized at the client
61 level. Tests for a single client are run serially.
64 :param config: Configuration
66 assert isinstance(config, dict), \
67 'admin_socket task requires a dict for configuration'
68 teuthology.replace_all_with_clients(ctx.cluster, config)
70 with parallel() as ptask:
71 for client, tests in config.iteritems():
72 ptask.spawn(_run_tests, ctx, client, tests)
75 def _socket_command(ctx, remote, socket_path, command, args):
77 Run an admin socket command and return the result as a string.
80 :param remote: Remote site
81 :param socket_path: path to socket
82 :param command: command to be run remotely
83 :param args: command arguments
85 :returns: output of command in json format
88 testdir = teuthology.get_testdir(ctx)
96 '{tdir}/archive/coverage'.format(tdir=testdir),
98 '--admin-daemon', socket_path,
99 ] + command.split(' ') + args,
103 if proc.exitstatus == 0:
107 log.info('ceph cli returned an error, command not registered yet?')
108 log.info('sleeping and retrying ...')
110 out = json_fp.getvalue()
112 log.debug('admin socket command %s returned %s', command, out)
113 return json.loads(out)
115 def _run_tests(ctx, client, tests):
117 Create a temp directory and wait for a client socket to be created.
118 For each test, copy the executable locally and run the test.
119 Remove temp directory when finished.
122 :param client: client machine to run the test
123 :param tests: list of tests to run
125 testdir = teuthology.get_testdir(ctx)
126 log.debug('Running admin socket tests on %s', client)
127 (remote,) = ctx.cluster.only(client).remotes.iterkeys()
128 socket_path = '/var/run/ceph/ceph-{name}.asok'.format(name=client)
129 overrides = ctx.config.get('overrides', {}).get('admin_socket', {})
132 tmp_dir = os.path.join(
134 'admin_socket_{client}'.format(client=client),
142 # wait for client process to create the socket
143 'while', 'test', '!', '-e', socket_path, run.Raw(';'),
144 'do', 'sleep', '1', run.Raw(';'), 'done',
148 for command, config in tests.iteritems():
151 teuthology.deep_merge(config, overrides)
152 log.debug('Testing %s with config %s', command, str(config))
156 # hack: the git_url is always ceph-ci or ceph
157 git_url = teuth_config.get_ceph_git_url()
158 repo_name = 'ceph.git'
159 if git_url.count('ceph-ci'):
160 repo_name = 'ceph-ci.git'
161 url = config['test'].format(
162 branch=config.get('branch', 'master'),
165 test_path = os.path.join(tmp_dir, command)
182 args = config.get('args', [])
183 assert isinstance(args, list), \
184 'admin socket command args must be a list'
185 sock_out = _socket_command(ctx, remote, socket_path, command, args)
186 if test_path is not None:
191 stdin=json.dumps(sock_out),
197 'rm', '-rf', '--', tmp_dir,