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