ceph/teuthology/task/s3tests.py

259 lines
8.6 KiB
Python
Raw Normal View History

2011-06-25 00:09:47 +00:00
from cStringIO import StringIO
from configobj import ConfigObj
import base64
import contextlib
import logging
import os
import random
import string
2011-06-25 00:09:47 +00:00
from teuthology import misc as teuthology
from teuthology import contextutil
from ..orchestra import run
from ..orchestra.connection import split_user
2011-06-25 00:09:47 +00:00
log = logging.getLogger(__name__)
@contextlib.contextmanager
def download(ctx, config):
assert isinstance(config, dict)
2011-06-25 00:09:47 +00:00
log.info('Downloading s3-tests...')
testdir = teuthology.get_testdir(ctx)
for (client, cconf) in config.items():
branch = cconf.get('force-branch', None)
if not branch:
branch = cconf.get('branch', 'master')
sha1 = cconf.get('sha1')
2011-06-25 00:09:47 +00:00
ctx.cluster.only(client).run(
args=[
'git', 'clone',
'-b', branch,
# 'https://github.com/ceph/s3-tests.git',
2012-06-06 23:00:55 +00:00
'git://ceph.com/git/s3-tests.git',
'{tdir}/s3-tests'.format(tdir=testdir),
2011-06-25 00:09:47 +00:00
],
)
if sha1 is not None:
ctx.cluster.only(client).run(
args=[
'cd', '{tdir}/s3-tests'.format(tdir=testdir),
run.Raw('&&'),
'git', 'reset', '--hard', sha1,
],
)
2011-06-25 00:09:47 +00:00
try:
yield
finally:
log.info('Removing s3-tests...')
testdir = teuthology.get_testdir(ctx)
for client in config:
ctx.cluster.only(client).run(
args=[
'rm',
'-rf',
'{tdir}/s3-tests'.format(tdir=testdir),
],
)
2011-06-25 00:09:47 +00:00
2011-06-25 00:09:47 +00:00
def _config_user(s3tests_conf, section, user):
s3tests_conf[section].setdefault('user_id', user)
s3tests_conf[section].setdefault('email', '{user}+test@test.test'.format(user=user))
s3tests_conf[section].setdefault('display_name', 'Mr. {user}'.format(user=user))
s3tests_conf[section].setdefault('access_key', ''.join(random.choice(string.uppercase) for i in xrange(20)))
s3tests_conf[section].setdefault('secret_key', base64.b64encode(os.urandom(40)))
2011-06-25 00:09:47 +00:00
@contextlib.contextmanager
def create_users(ctx, config):
2011-06-25 00:09:47 +00:00
assert isinstance(config, dict)
log.info('Creating rgw users...')
testdir = teuthology.get_testdir(ctx)
users = {'s3 main': 'foo', 's3 alt': 'bar'}
2011-06-25 00:09:47 +00:00
for client in config['clients']:
s3tests_conf = config['s3tests_conf'][client]
s3tests_conf.setdefault('fixtures', {})
s3tests_conf['fixtures'].setdefault('bucket prefix', 'test-' + client + '-{random}-')
for section, user in users.iteritems():
2011-06-25 00:09:47 +00:00
_config_user(s3tests_conf, section, '{user}.{client}'.format(user=user, client=client))
ctx.cluster.only(client).run(
args=[
'{tdir}/adjust-ulimits'.format(tdir=testdir),
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'radosgw-admin',
2011-06-25 00:09:47 +00:00
'user', 'create',
'--uid', s3tests_conf[section]['user_id'],
'--display-name', s3tests_conf[section]['display_name'],
'--access-key', s3tests_conf[section]['access_key'],
'--secret', s3tests_conf[section]['secret_key'],
'--email', s3tests_conf[section]['email'],
],
)
try:
yield
finally:
for client in config['clients']:
for user in users.itervalues():
uid = '{user}.{client}'.format(user=user, client=client)
ctx.cluster.only(client).run(
args=[
'{tdir}/adjust-ulimits'.format(tdir=testdir),
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'radosgw-admin',
'user', 'rm',
'--uid', uid,
'--purge-data',
],
)
2011-06-25 00:09:47 +00:00
@contextlib.contextmanager
def configure(ctx, config):
2011-06-25 00:09:47 +00:00
assert isinstance(config, dict)
log.info('Configuring s3-tests...')
testdir = teuthology.get_testdir(ctx)
2011-06-25 00:09:47 +00:00
for client, properties in config['clients'].iteritems():
s3tests_conf = config['s3tests_conf'][client]
if properties is not None and 'rgw_server' in properties:
host = None
for target, roles in zip(ctx.config['targets'].iterkeys(), ctx.config['roles']):
2011-06-25 00:09:47 +00:00
log.info('roles: ' + str(roles))
log.info('target: ' + str(target))
if properties['rgw_server'] in roles:
_, host = split_user(target)
assert host is not None, "Invalid client specified as the rgw_server"
s3tests_conf['DEFAULT']['host'] = host
else:
s3tests_conf['DEFAULT']['host'] = 'localhost'
(remote,) = ctx.cluster.only(client).remotes.keys()
remote.run(
args=[
'cd',
'{tdir}/s3-tests'.format(tdir=testdir),
2011-06-25 00:09:47 +00:00
run.Raw('&&'),
'./bootstrap',
],
)
conf_fp = StringIO()
s3tests_conf.write(conf_fp)
teuthology.write_file(
remote=remote,
path='{tdir}/archive/s3-tests.{client}.conf'.format(tdir=testdir, client=client),
2011-06-25 00:09:47 +00:00
data=conf_fp.getvalue(),
)
yield
@contextlib.contextmanager
def run_tests(ctx, config):
2011-06-25 00:09:47 +00:00
assert isinstance(config, dict)
testdir = teuthology.get_testdir(ctx)
2011-06-25 00:09:47 +00:00
for client, client_config in config.iteritems():
args = [
'S3TEST_CONF={tdir}/archive/s3-tests.{client}.conf'.format(tdir=testdir, client=client),
'{tdir}/s3-tests/virtualenv/bin/nosetests'.format(tdir=testdir),
2011-06-25 00:09:47 +00:00
'-w',
'{tdir}/s3-tests'.format(tdir=testdir),
2011-06-25 00:09:47 +00:00
'-v',
'-a', '!fails_on_rgw',
2011-06-25 00:09:47 +00:00
]
if client_config is not None and 'extra_args' in client_config:
args.extend(client_config['extra_args'])
ctx.cluster.only(client).run(
args=args,
)
yield
2011-06-25 00:09:47 +00:00
@contextlib.contextmanager
def task(ctx, config):
"""
Run the s3-tests suite against rgw.
To run all tests on all clients::
tasks:
- ceph:
- rgw:
- s3tests:
To restrict testing to particular clients::
tasks:
- ceph:
- rgw: [client.0]
- s3tests: [client.0]
To run against a server on client.1::
tasks:
- ceph:
- rgw: [client.1]
- s3tests:
client.0:
rgw_server: client.1
To pass extra arguments to nose (e.g. to run a certain test)::
tasks:
- ceph:
- rgw: [client.0]
- s3tests:
client.0:
extra_args: ['test_s3:test_object_acl_grand_public_read']
client.1:
extra_args: ['--exclude', 'test_100_continue']
"""
assert config is None or isinstance(config, list) \
or isinstance(config, dict), \
"task s3tests only supports a list or dictionary for configuration"
all_clients = ['client.{id}'.format(id=id_)
for id_ in teuthology.all_roles_of_type(ctx.cluster, 'client')]
if config is None:
config = all_clients
if isinstance(config, list):
config = dict.fromkeys(config)
clients = config.keys()
overrides = ctx.config.get('overrides', {})
# merge each client section, not the top level.
for client in config.iterkeys():
if not config[client]:
config[client] = {}
teuthology.deep_merge(config[client], overrides.get('s3tests', {}))
log.debug('config is %s', config)
2011-06-25 00:09:47 +00:00
s3tests_conf = {}
for client in clients:
s3tests_conf[client] = ConfigObj(
indent_type='',
infile={
'DEFAULT':
{
'port' : 7280,
'is_secure' : 'no',
},
'fixtures' : {},
's3 main' : {},
's3 alt' : {},
}
)
with contextutil.nested(
lambda: download(ctx=ctx, config=config),
2011-06-25 00:09:47 +00:00
lambda: create_users(ctx=ctx, config=dict(
clients=clients,
s3tests_conf=s3tests_conf,
)),
lambda: configure(ctx=ctx, config=dict(
clients=config,
s3tests_conf=s3tests_conf,
)),
lambda: run_tests(ctx=ctx, config=config),
):
pass
yield