2 Run rgw s3 readwite tests
4 from cStringIO import StringIO
13 from teuthology import misc as teuthology
14 from teuthology import contextutil
15 from teuthology.config import config as teuth_config
16 from teuthology.orchestra import run
17 from teuthology.orchestra.connection import split_user
19 log = logging.getLogger(__name__)
22 @contextlib.contextmanager
23 def download(ctx, config):
25 Download the s3 tests from the git builder.
26 Remove downloaded s3 file upon exit.
28 The context passed in should be identical to the context
29 passed in to the main task.
31 assert isinstance(config, dict)
32 log.info('Downloading s3-tests...')
33 testdir = teuthology.get_testdir(ctx)
34 for (client, cconf) in config.items():
35 branch = cconf.get('force-branch', None)
37 branch = cconf.get('branch', 'master')
38 sha1 = cconf.get('sha1')
39 ctx.cluster.only(client).run(
43 teuth_config.ceph_git_base_url + 's3-tests.git',
44 '{tdir}/s3-tests'.format(tdir=testdir),
48 ctx.cluster.only(client).run(
50 'cd', '{tdir}/s3-tests'.format(tdir=testdir),
52 'git', 'reset', '--hard', sha1,
58 log.info('Removing s3-tests...')
59 testdir = teuthology.get_testdir(ctx)
61 ctx.cluster.only(client).run(
65 '{tdir}/s3-tests'.format(tdir=testdir),
70 def _config_user(s3tests_conf, section, user):
72 Configure users for this section by stashing away keys, ids, and
75 s3tests_conf[section].setdefault('user_id', user)
76 s3tests_conf[section].setdefault('email', '{user}+test@test.test'.format(user=user))
77 s3tests_conf[section].setdefault('display_name', 'Mr. {user}'.format(user=user))
78 s3tests_conf[section].setdefault('access_key', ''.join(random.choice(string.uppercase) for i in xrange(20)))
79 s3tests_conf[section].setdefault('secret_key', base64.b64encode(os.urandom(40)))
81 @contextlib.contextmanager
82 def create_users(ctx, config):
84 Create a default s3 user.
86 assert isinstance(config, dict)
87 log.info('Creating rgw users...')
88 testdir = teuthology.get_testdir(ctx)
90 cached_client_user_names = dict()
91 for client in config['clients']:
92 cached_client_user_names[client] = dict()
93 s3tests_conf = config['s3tests_conf'][client]
94 s3tests_conf.setdefault('readwrite', {})
95 s3tests_conf['readwrite'].setdefault('bucket', 'rwtest-' + client + '-{random}-')
96 s3tests_conf['readwrite'].setdefault('readers', 10)
97 s3tests_conf['readwrite'].setdefault('writers', 3)
98 s3tests_conf['readwrite'].setdefault('duration', 300)
99 s3tests_conf['readwrite'].setdefault('files', {})
100 rwconf = s3tests_conf['readwrite']
101 rwconf['files'].setdefault('num', 10)
102 rwconf['files'].setdefault('size', 2000)
103 rwconf['files'].setdefault('stddev', 500)
104 for section, user in users.iteritems():
105 _config_user(s3tests_conf, section, '{user}.{client}'.format(user=user, client=client))
106 log.debug('creating user {user} on {client}'.format(user=s3tests_conf[section]['user_id'],
109 # stash the 'delete_user' flag along with user name for easier cleanup
110 delete_this_user = True
111 if 'delete_user' in s3tests_conf['s3']:
112 delete_this_user = s3tests_conf['s3']['delete_user']
113 log.debug('delete_user set to {flag} for {client}'.format(flag=delete_this_user, client=client))
114 cached_client_user_names[client][section+user] = (s3tests_conf[section]['user_id'], delete_this_user)
116 # skip actual user creation if the create_user flag is set to false for this client
117 if 'create_user' in s3tests_conf['s3'] and s3tests_conf['s3']['create_user'] == False:
118 log.debug('create_user set to False, skipping user creation for {client}'.format(client=client))
121 ctx.cluster.only(client).run(
125 '{tdir}/archive/coverage'.format(tdir=testdir),
129 '--uid', s3tests_conf[section]['user_id'],
130 '--display-name', s3tests_conf[section]['display_name'],
131 '--access-key', s3tests_conf[section]['access_key'],
132 '--secret', s3tests_conf[section]['secret_key'],
133 '--email', s3tests_conf[section]['email'],
139 for client in config['clients']:
140 for section, user in users.iteritems():
141 #uid = '{user}.{client}'.format(user=user, client=client)
142 real_uid, delete_this_user = cached_client_user_names[client][section+user]
144 ctx.cluster.only(client).run(
148 '{tdir}/archive/coverage'.format(tdir=testdir),
157 log.debug('skipping delete for user {uid} on {client}'.format(uid=real_uid, client=client))
159 @contextlib.contextmanager
160 def configure(ctx, config):
162 Configure the s3-tests. This includes the running of the
163 bootstrap code and the updating of local conf files.
165 assert isinstance(config, dict)
166 log.info('Configuring s3-readwrite-tests...')
167 for client, properties in config['clients'].iteritems():
168 s3tests_conf = config['s3tests_conf'][client]
169 if properties is not None and 'rgw_server' in properties:
171 for target, roles in zip(ctx.config['targets'].iterkeys(), ctx.config['roles']):
172 log.info('roles: ' + str(roles))
173 log.info('target: ' + str(target))
174 if properties['rgw_server'] in roles:
175 _, host = split_user(target)
176 assert host is not None, "Invalid client specified as the rgw_server"
177 s3tests_conf['s3']['host'] = host
179 s3tests_conf['s3']['host'] = 'localhost'
181 def_conf = s3tests_conf['DEFAULT']
182 s3tests_conf['s3'].setdefault('port', def_conf['port'])
183 s3tests_conf['s3'].setdefault('is_secure', def_conf['is_secure'])
185 (remote,) = ctx.cluster.only(client).remotes.keys()
189 '{tdir}/s3-tests'.format(tdir=teuthology.get_testdir(ctx)),
196 s3=s3tests_conf['s3'],
197 readwrite=s3tests_conf['readwrite'],
199 yaml.safe_dump(conf, conf_fp, default_flow_style=False)
200 teuthology.write_file(
202 path='{tdir}/archive/s3readwrite.{client}.config.yaml'.format(tdir=teuthology.get_testdir(ctx), client=client),
203 data=conf_fp.getvalue(),
208 @contextlib.contextmanager
209 def run_tests(ctx, config):
211 Run the s3readwrite tests after everything is set up.
213 :param ctx: Context passed to task
214 :param config: specific configuration information
216 assert isinstance(config, dict)
217 testdir = teuthology.get_testdir(ctx)
218 for client, client_config in config.iteritems():
219 (remote,) = ctx.cluster.only(client).remotes.keys()
220 conf = teuthology.get_file(remote, '{tdir}/archive/s3readwrite.{client}.config.yaml'.format(tdir=testdir, client=client))
222 '{tdir}/s3-tests/virtualenv/bin/s3tests-test-readwrite'.format(tdir=testdir),
224 if client_config is not None and 'extra_args' in client_config:
225 args.extend(client_config['extra_args'])
227 ctx.cluster.only(client).run(
234 @contextlib.contextmanager
235 def task(ctx, config):
237 Run the s3tests-test-readwrite suite against rgw.
239 To run all tests on all clients::
246 To restrict testing to particular clients::
251 - s3readwrite: [client.0]
253 To run against a server on client.1::
262 To pass extra test arguments
281 To override s3 configuration
292 access_key: myaccesskey
293 secret_key: mysecretkey
296 assert config is None or isinstance(config, list) \
297 or isinstance(config, dict), \
298 "task s3tests only supports a list or dictionary for configuration"
299 all_clients = ['client.{id}'.format(id=id_)
300 for id_ in teuthology.all_roles_of_type(ctx.cluster, 'client')]
303 if isinstance(config, list):
304 config = dict.fromkeys(config)
305 clients = config.keys()
307 overrides = ctx.config.get('overrides', {})
308 # merge each client section, not the top level.
309 for client in config.iterkeys():
310 if not config[client]:
312 teuthology.deep_merge(config[client], overrides.get('s3readwrite', {}))
314 log.debug('in s3readwrite, config is %s', config)
317 for client in clients:
318 if config[client] is None:
320 config[client].setdefault('s3', {})
321 config[client].setdefault('readwrite', {})
323 s3tests_conf[client] = ({
329 'readwrite' : config[client]['readwrite'],
330 's3' : config[client]['s3'],
333 with contextutil.nested(
334 lambda: download(ctx=ctx, config=config),
335 lambda: create_users(ctx=ctx, config=dict(
337 s3tests_conf=s3tests_conf,
339 lambda: configure(ctx=ctx, config=dict(
341 s3tests_conf=s3tests_conf,
343 lambda: run_tests(ctx=ctx, config=config),