]> git.proxmox.com Git - ceph.git/blame - ceph/qa/tasks/s3roundtrip.py
import 14.2.4 nautilus point release
[ceph.git] / ceph / qa / tasks / s3roundtrip.py
CommitLineData
7c673cae
FG
1"""
2Run rgw roundtrip message tests
3"""
4from cStringIO import StringIO
5import base64
6import contextlib
7import logging
8import os
9import random
10import string
11import yaml
12
13from teuthology import misc as teuthology
14from teuthology import contextutil
15from teuthology.config import config as teuth_config
16from teuthology.orchestra import run
17from teuthology.orchestra.connection import split_user
18
19log = logging.getLogger(__name__)
20
21
22@contextlib.contextmanager
23def download(ctx, config):
24 """
25 Download the s3 tests from the git builder.
26 Remove downloaded s3 file upon exit.
27
28 The context passed in should be identical to the context
29 passed in to the main task.
30 """
31 assert isinstance(config, dict)
32 log.info('Downloading s3-tests...')
33 testdir = teuthology.get_testdir(ctx)
34 for (client, cconf) in config.iteritems():
35 branch = cconf.get('force-branch', None)
36 if not branch:
37 branch = cconf.get('branch', 'master')
38 ctx.cluster.only(client).run(
39 args=[
40 'git', 'clone',
41 '-b', branch,
42 teuth_config.ceph_git_base_url + 's3-tests.git',
43 '{tdir}/s3-tests'.format(tdir=testdir),
44 ],
45 )
46 try:
47 yield
48 finally:
49 log.info('Removing s3-tests...')
50 for client in config:
51 ctx.cluster.only(client).run(
52 args=[
53 'rm',
54 '-rf',
55 '{tdir}/s3-tests'.format(tdir=testdir),
56 ],
57 )
58
59def _config_user(s3tests_conf, section, user):
60 """
61 Configure users for this section by stashing away keys, ids, and
62 email addresses.
63 """
64 s3tests_conf[section].setdefault('user_id', user)
65 s3tests_conf[section].setdefault('email', '{user}+test@test.test'.format(user=user))
66 s3tests_conf[section].setdefault('display_name', 'Mr. {user}'.format(user=user))
67 s3tests_conf[section].setdefault('access_key', ''.join(random.choice(string.uppercase) for i in xrange(20)))
68 s3tests_conf[section].setdefault('secret_key', base64.b64encode(os.urandom(40)))
69
70@contextlib.contextmanager
71def create_users(ctx, config):
72 """
73 Create a default s3 user.
74 """
75 assert isinstance(config, dict)
76 log.info('Creating rgw users...')
77 testdir = teuthology.get_testdir(ctx)
78 users = {'s3': 'foo'}
79 for client in config['clients']:
80 s3tests_conf = config['s3tests_conf'][client]
81 s3tests_conf.setdefault('roundtrip', {})
82 s3tests_conf['roundtrip'].setdefault('bucket', 'rttest-' + client + '-{random}-')
83 s3tests_conf['roundtrip'].setdefault('readers', 10)
84 s3tests_conf['roundtrip'].setdefault('writers', 3)
85 s3tests_conf['roundtrip'].setdefault('duration', 300)
86 s3tests_conf['roundtrip'].setdefault('files', {})
87 rtconf = s3tests_conf['roundtrip']
88 rtconf['files'].setdefault('num', 10)
89 rtconf['files'].setdefault('size', 2000)
90 rtconf['files'].setdefault('stddev', 500)
91 for section, user in [('s3', 'foo')]:
92 _config_user(s3tests_conf, section, '{user}.{client}'.format(user=user, client=client))
93 ctx.cluster.only(client).run(
94 args=[
95 'adjust-ulimits',
96 'ceph-coverage',
97 '{tdir}/archive/coverage'.format(tdir=testdir),
98 'radosgw-admin',
99 '-n', client,
100 'user', 'create',
101 '--uid', s3tests_conf[section]['user_id'],
102 '--display-name', s3tests_conf[section]['display_name'],
103 '--access-key', s3tests_conf[section]['access_key'],
104 '--secret', s3tests_conf[section]['secret_key'],
105 '--email', s3tests_conf[section]['email'],
106 ],
107 )
108 try:
109 yield
110 finally:
111 for client in config['clients']:
112 for user in users.itervalues():
113 uid = '{user}.{client}'.format(user=user, client=client)
114 ctx.cluster.only(client).run(
115 args=[
116 'adjust-ulimits',
117 'ceph-coverage',
118 '{tdir}/archive/coverage'.format(tdir=testdir),
119 'radosgw-admin',
120 '-n', client,
121 'user', 'rm',
122 '--uid', uid,
123 '--purge-data',
124 ],
125 )
126
127@contextlib.contextmanager
128def configure(ctx, config):
129 """
130 Configure the s3-tests. This includes the running of the
131 bootstrap code and the updating of local conf files.
132 """
133 assert isinstance(config, dict)
134 log.info('Configuring s3-roundtrip-tests...')
135 testdir = teuthology.get_testdir(ctx)
136 for client, properties in config['clients'].iteritems():
137 s3tests_conf = config['s3tests_conf'][client]
138 if properties is not None and 'rgw_server' in properties:
139 host = None
140 for target, roles in zip(ctx.config['targets'].iterkeys(), ctx.config['roles']):
141 log.info('roles: ' + str(roles))
142 log.info('target: ' + str(target))
143 if properties['rgw_server'] in roles:
144 _, host = split_user(target)
145 assert host is not None, "Invalid client specified as the rgw_server"
146 s3tests_conf['s3']['host'] = host
147 else:
148 s3tests_conf['s3']['host'] = 'localhost'
149
150 def_conf = s3tests_conf['DEFAULT']
151 s3tests_conf['s3'].setdefault('port', def_conf['port'])
152 s3tests_conf['s3'].setdefault('is_secure', def_conf['is_secure'])
153
154 (remote,) = ctx.cluster.only(client).remotes.keys()
155 remote.run(
156 args=[
157 'cd',
158 '{tdir}/s3-tests'.format(tdir=testdir),
159 run.Raw('&&'),
160 './bootstrap',
161 ],
162 )
163 conf_fp = StringIO()
164 conf = dict(
165 s3=s3tests_conf['s3'],
166 roundtrip=s3tests_conf['roundtrip'],
167 )
168 yaml.safe_dump(conf, conf_fp, default_flow_style=False)
169 teuthology.write_file(
170 remote=remote,
171 path='{tdir}/archive/s3roundtrip.{client}.config.yaml'.format(tdir=testdir, client=client),
172 data=conf_fp.getvalue(),
173 )
174 yield
175
176
177@contextlib.contextmanager
178def run_tests(ctx, config):
179 """
180 Run the s3 roundtrip after everything is set up.
181
182 :param ctx: Context passed to task
183 :param config: specific configuration information
184 """
185 assert isinstance(config, dict)
186 testdir = teuthology.get_testdir(ctx)
187 for client, client_config in config.iteritems():
188 (remote,) = ctx.cluster.only(client).remotes.keys()
189 conf = teuthology.get_file(remote, '{tdir}/archive/s3roundtrip.{client}.config.yaml'.format(tdir=testdir, client=client))
190 args = [
191 '{tdir}/s3-tests/virtualenv/bin/s3tests-test-roundtrip'.format(tdir=testdir),
192 ]
193 if client_config is not None and 'extra_args' in client_config:
194 args.extend(client_config['extra_args'])
195
196 ctx.cluster.only(client).run(
197 args=args,
198 stdin=conf,
199 )
200 yield
201
202
203@contextlib.contextmanager
204def task(ctx, config):
205 """
206 Run the s3tests-test-roundtrip suite against rgw.
207
208 To run all tests on all clients::
209
210 tasks:
211 - ceph:
212 - rgw:
213 - s3roundtrip:
214
215 To restrict testing to particular clients::
216
217 tasks:
218 - ceph:
219 - rgw: [client.0]
220 - s3roundtrip: [client.0]
221
222 To run against a server on client.1::
223
224 tasks:
225 - ceph:
226 - rgw: [client.1]
227 - s3roundtrip:
228 client.0:
229 rgw_server: client.1
230
231 To pass extra test arguments
232
233 tasks:
234 - ceph:
235 - rgw: [client.0]
236 - s3roundtrip:
237 client.0:
238 roundtrip:
239 bucket: mybucket
240 readers: 10
241 writers: 3
242 duration: 600
243 files:
244 num: 10
245 size: 2000
246 stddev: 500
247 client.1:
248 ...
249
250 To override s3 configuration
251
252 tasks:
253 - ceph:
254 - rgw: [client.0]
255 - s3roundtrip:
256 client.0:
257 s3:
258 user_id: myuserid
259 display_name: myname
260 email: my@email
261 access_key: myaccesskey
262 secret_key: mysecretkey
263
264 """
494da23a 265 assert hasattr(ctx, 'rgw'), 's3roundtrip must run after the rgw task'
7c673cae
FG
266 assert config is None or isinstance(config, list) \
267 or isinstance(config, dict), \
494da23a 268 "task s3roundtrip only supports a list or dictionary for configuration"
7c673cae
FG
269 all_clients = ['client.{id}'.format(id=id_)
270 for id_ in teuthology.all_roles_of_type(ctx.cluster, 'client')]
271 if config is None:
272 config = all_clients
273 if isinstance(config, list):
274 config = dict.fromkeys(config)
275 clients = config.keys()
276
277 s3tests_conf = {}
278 for client in clients:
279 if config[client] is None:
280 config[client] = {}
281 config[client].setdefault('s3', {})
282 config[client].setdefault('roundtrip', {})
283
494da23a
TL
284 endpoint = ctx.rgw.role_endpoints.get(client)
285 assert endpoint, 's3roundtrip: no rgw endpoint for {}'.format(client)
286
7c673cae
FG
287 s3tests_conf[client] = ({
288 'DEFAULT':
289 {
494da23a
TL
290 'port' : endpoint.port,
291 'is_secure' : endpoint.cert is not None,
7c673cae
FG
292 },
293 'roundtrip' : config[client]['roundtrip'],
294 's3' : config[client]['s3'],
295 })
296
297 with contextutil.nested(
298 lambda: download(ctx=ctx, config=config),
299 lambda: create_users(ctx=ctx, config=dict(
300 clients=clients,
301 s3tests_conf=s3tests_conf,
302 )),
303 lambda: configure(ctx=ctx, config=dict(
304 clients=config,
305 s3tests_conf=s3tests_conf,
306 )),
307 lambda: run_tests(ctx=ctx, config=config),
308 ):
309 pass
310 yield