]> git.proxmox.com Git - ceph.git/blame - ceph/qa/tasks/s3tests_java.py
import quincy beta 17.1.0
[ceph.git] / ceph / qa / tasks / s3tests_java.py
CommitLineData
9f95a23c
TL
1"""
2Task for running RGW S3 tests with the AWS Java SDK
3"""
e306af50 4from io import BytesIO
9f95a23c
TL
5import logging
6
7import base64
8import os
9import random
10import string
11import yaml
12import getpass
13
14from teuthology import misc as teuthology
15from teuthology.task import Task
16from teuthology.orchestra import run
17
18log = logging.getLogger(__name__)
19
20"""
21 Task for running RGW S3 tests with the AWS Java SDK
22
23 Tests run only on clients specified in the s3tests-java config section.
24 If no client is given a default 'client.0' is chosen.
25 If such does not match the rgw client the task will fail.
26
27 tasks:
28 - ceph:
29 - rgw: [client.0]
30 - s3tests-java:
31 client.0:
32
33 Extra arguments can be passed by adding options to the corresponding client
34 section under the s3tests-java task (e.g. to run a certain test,
35 specify a different repository and branch for the test suite,
36 run in info/debug mode (for the java suite) or forward the gradle output to a log file):
37
38 tasks:
39 - ceph:
40 - rgw: [client.0]
41 - s3tests-java:
42 client.0:
43 force-branch: wip
44 force-repo: 'https://github.com/adamyanova/java_s3tests.git'
45 log-fwd: '../s3tests-java.log'
46 log-level: info
47 extra-args: ['--tests', 'ObjectTest.testEncryptionKeySSECInvalidMd5']
48
49 To run a specific test, provide its name to the extra-args section e.g.:
50 - s3tests-java:
51 client.0:
52 extra-args: ['--tests', 'ObjectTest.testEncryptionKeySSECInvalidMd5']
53
54"""
55
56
57class S3tests_java(Task):
58 """
59 Download and install S3 tests in Java
60 This will require openjdk and gradle
61 """
62
63 def __init__(self, ctx, config):
64 super(S3tests_java, self).__init__(ctx, config)
65 self.log = log
66 log.debug('S3 Tests Java: __INIT__ ')
67 assert hasattr(ctx, 'rgw'), 'S3tests_java must run after the rgw task'
68 clients = ['client.{id}'.format(id=id_)
69 for id_ in teuthology.all_roles_of_type(self.ctx.cluster, 'client')]
70 self.all_clients = []
71 for client in clients:
72 if client in self.config:
73 self.all_clients.extend([client])
74 if self.all_clients is None:
75 self.all_clients = 'client.0'
76 self.users = {'s3main': 'tester',
77 's3alt': 'johndoe', 'tenanted': 'testx$tenanteduser'}
78
79 def setup(self):
80 super(S3tests_java, self).setup()
81 log.debug('S3 Tests Java: SETUP')
82 for client in self.all_clients:
83 self.download_test_suite(client)
84 self.install_required_packages(client)
85
86 def begin(self):
87 super(S3tests_java, self).begin()
88 log.debug('S3 Tests Java: BEGIN')
89 for (host, roles) in self.ctx.cluster.remotes.items():
90 log.debug(
91 'S3 Tests Java: Cluster config is: {cfg}'.format(cfg=roles))
92 log.debug('S3 Tests Java: Host is: {host}'.format(host=host))
93 self.create_users()
94 self.run_tests()
95
96 def end(self):
97 super(S3tests_java, self).end()
98 log.debug('S3 Tests Java: END')
99 for client in self.all_clients:
100 self.remove_tests(client)
101 self.delete_users(client)
102
103 def download_test_suite(self, client):
104 log.info("S3 Tests Java: Downloading test suite...")
105 testdir = teuthology.get_testdir(self.ctx)
106 branch = 'master'
107 repo = 'https://github.com/ceph/java_s3tests.git'
108 if client in self.config and self.config[client] is not None:
109 if 'force-branch' in self.config[client] and self.config[client]['force-branch'] is not None:
110 branch = self.config[client]['force-branch']
111 if 'force-repo' in self.config[client] and self.config[client]['force-repo'] is not None:
112 repo = self.config[client]['force-repo']
113 self.ctx.cluster.only(client).run(
114 args=[
115 'git', 'clone',
116 '-b', branch,
117 repo,
118 '{tdir}/s3-tests-java'.format(tdir=testdir),
119 ],
e306af50 120 stdout=BytesIO()
9f95a23c
TL
121 )
122 if client in self.config and self.config[client] is not None:
123 if 'sha1' in self.config[client] and self.config[client]['sha1'] is not None:
124 self.ctx.cluster.only(client).run(
125 args=[
126 'cd', '{tdir}/s3-tests-java'.format(tdir=testdir),
127 run.Raw('&&'),
128 'git', 'reset', '--hard', self.config[client]['sha1'],
129 ],
130 )
131
132 if 'log-level' in self.config[client]:
133 if self.config[client]['log-level'] == 'info':
134 self.ctx.cluster.only(client).run(
135 args=[
136 'sed', '-i', '\'s/log4j.rootLogger=WARN/log4j.rootLogger=INFO/g\'',
137 '{tdir}/s3-tests-java/src/main/resources/log4j.properties'.format(
138 tdir=testdir)
139 ]
140 )
141 if self.config[client]['log-level'] == 'debug':
142 self.ctx.cluster.only(client).run(
143 args=[
144 'sed', '-i', '\'s/log4j.rootLogger=WARN/log4j.rootLogger=DEBUG/g\'',
145 '{tdir}/s3-tests-java/src/main/resources/log4j.properties'.format(
146 tdir=testdir)
147 ]
148 )
149
150 def install_required_packages(self, client):
151 """
152 Run bootstrap script to install openjdk and gradle.
153 Add certificates to java keystore
154 """
155 log.info("S3 Tests Java: Installing required packages...")
156 testdir = teuthology.get_testdir(self.ctx)
157 self.ctx.cluster.only(client).run(
158 args=['{tdir}/s3-tests-java/bootstrap.sh'.format(tdir=testdir)],
e306af50 159 stdout=BytesIO()
9f95a23c
TL
160 )
161
162 endpoint = self.ctx.rgw.role_endpoints[client]
163 if endpoint.cert:
164 path = 'lib/security/cacerts'
165 self.ctx.cluster.only(client).run(
166 args=['sudo',
167 'keytool',
168 '-import', '-alias', '{alias}'.format(
169 alias=endpoint.hostname),
170 '-keystore',
171 run.Raw(
172 '$(readlink -e $(dirname $(readlink -e $(which keytool)))/../{path})'.format(path=path)),
173 '-file', endpoint.cert.certificate,
174 '-storepass', 'changeit',
175 ],
e306af50 176 stdout=BytesIO()
9f95a23c
TL
177 )
178
179 def create_users(self):
180 """
181 Create a main and an alternative s3 user.
182 Configuration is read from a skelethon config file
183 s3tests.teuth.config.yaml in the java-s3tests repository
184 and missing information is added from the task.
185 Existing values are NOT overriden unless they are empty!
186 """
187 log.info("S3 Tests Java: Creating S3 users...")
188 testdir = teuthology.get_testdir(self.ctx)
189 for client in self.all_clients:
190 endpoint = self.ctx.rgw.role_endpoints.get(client)
191 local_user = getpass.getuser()
192 remote_user = teuthology.get_test_user()
193 os.system("scp {remote}@{host}:{tdir}/s3-tests-java/s3tests.teuth.config.yaml /home/{local}/".format(
194 host=endpoint.hostname, tdir=testdir, remote=remote_user, local=local_user))
195 s3tests_conf = teuthology.config_file(
196 '/home/{local}/s3tests.teuth.config.yaml'.format(local=local_user))
197 log.debug("S3 Tests Java: s3tests_conf is {s3cfg}".format(
198 s3cfg=s3tests_conf))
e306af50 199 for section, user in list(self.users.items()):
9f95a23c
TL
200 if section in s3tests_conf:
201 s3_user_id = '{user}.{client}'.format(
202 user=user, client=client)
203 log.debug(
204 'S3 Tests Java: Creating user {s3_user_id}'.format(s3_user_id=s3_user_id))
205 self._config_user(s3tests_conf=s3tests_conf,
206 section=section, user=s3_user_id, client=client)
207 cluster_name, daemon_type, client_id = teuthology.split_role(
208 client)
209 client_with_id = daemon_type + '.' + client_id
210 args = [
211 'adjust-ulimits',
212 'ceph-coverage',
213 '{tdir}/archive/coverage'.format(tdir=testdir),
214 'radosgw-admin',
215 '-n', client_with_id,
216 'user', 'create',
217 '--uid', s3tests_conf[section]['user_id'],
218 '--display-name', s3tests_conf[section]['display_name'],
219 '--access-key', s3tests_conf[section]['access_key'],
220 '--secret', s3tests_conf[section]['access_secret'],
221 '--email', s3tests_conf[section]['email'],
222 '--cluster', cluster_name,
223 ]
224 log.info('{args}'.format(args=args))
225 self.ctx.cluster.only(client).run(
226 args=args,
e306af50 227 stdout=BytesIO()
9f95a23c
TL
228 )
229 else:
230 self.users.pop(section)
231 self._write_cfg_file(s3tests_conf, client)
232 os.system(
233 "rm -rf /home/{local}/s3tests.teuth.config.yaml".format(local=local_user))
234
235 def _config_user(self, s3tests_conf, section, user, client):
236 """
237 Generate missing users data for this section by stashing away keys, ids, and
238 email addresses.
239 """
240 access_key = ''.join(random.choice(string.ascii_uppercase)
241 for i in range(20))
e306af50 242 access_secret = base64.b64encode(os.urandom(40)).decode('ascii')
9f95a23c
TL
243 endpoint = self.ctx.rgw.role_endpoints.get(client)
244
245 self._set_cfg_entry(
246 s3tests_conf[section], 'user_id', '{user}'.format(user=user))
247 self._set_cfg_entry(
248 s3tests_conf[section], 'email', '{user}_test@test.test'.format(user=user))
249 self._set_cfg_entry(
250 s3tests_conf[section], 'display_name', 'Ms. {user}'.format(user=user))
251 self._set_cfg_entry(
252 s3tests_conf[section], 'access_key', '{ak}'.format(ak=access_key))
253 self._set_cfg_entry(
254 s3tests_conf[section], 'access_secret', '{asc}'.format(asc=access_secret))
255 self._set_cfg_entry(
256 s3tests_conf[section], 'region', 'us-east-1')
257 self._set_cfg_entry(
258 s3tests_conf[section], 'endpoint', '{ip}:{port}'.format(
259 ip=endpoint.hostname, port=endpoint.port))
260 self._set_cfg_entry(
261 s3tests_conf[section], 'host', endpoint.hostname)
262 self._set_cfg_entry(
263 s3tests_conf[section], 'port', endpoint.port)
264 self._set_cfg_entry(
265 s3tests_conf[section], 'is_secure', True if endpoint.cert else False)
266
267 log.debug("S3 Tests Java: s3tests_conf[{sect}] is {s3cfg}".format(
268 sect=section, s3cfg=s3tests_conf[section]))
269 log.debug('S3 Tests Java: Setion, User = {sect}, {user}'.format(
270 sect=section, user=user))
271
272 def _write_cfg_file(self, cfg_dict, client):
273 """
f67539c2 274 Write s3 tests java config file on the remote node.
9f95a23c
TL
275 """
276 testdir = teuthology.get_testdir(self.ctx)
277 (remote,) = self.ctx.cluster.only(client).remotes.keys()
f67539c2
TL
278 data = yaml.safe_dump(cfg_dict, default_flow_style=False)
279 path = testdir + '/archive/s3-tests-java.' + client + '.conf'
280 remote.write_file(path, data)
9f95a23c
TL
281
282 def _set_cfg_entry(self, cfg_dict, key, value):
283 if not (key in cfg_dict):
284 cfg_dict.setdefault(key, value)
285 elif cfg_dict[key] is None:
286 cfg_dict[key] = value
287
288 def run_tests(self):
289 log.info("S3 Tests Java: Running tests...")
290 testdir = teuthology.get_testdir(self.ctx)
291 for client in self.all_clients:
292 self.ctx.cluster.only(client).run(
293 args=['cp',
294 '{tdir}/archive/s3-tests-java.{client}.conf'.format(
295 tdir=testdir, client=client),
296 '{tdir}/s3-tests-java/config.properties'.format(
297 tdir=testdir)
298 ],
e306af50 299 stdout=BytesIO()
9f95a23c
TL
300 )
301 args = ['cd',
302 '{tdir}/s3-tests-java'.format(tdir=testdir),
303 run.Raw('&&'),
304 '/opt/gradle/gradle/bin/gradle', 'clean', 'test',
305 '--rerun-tasks', '--no-build-cache',
306 ]
307 extra_args = []
308 suppress_groups = False
309 self.log_fwd = False
310 self.log_name = ''
311 if client in self.config and self.config[client] is not None:
312 if 'extra-args' in self.config[client]:
313 extra_args.extend(self.config[client]['extra-args'])
314 suppress_groups = True
315 if 'log-level' in self.config[client] and self.config[client]['log-level'] == 'debug':
316 extra_args += ['--debug']
317 if 'log-fwd' in self.config[client]:
318 self.log_fwd = True
319 self.log_name = '{tdir}/s3tests_log.txt'.format(
320 tdir=testdir)
321 if self.config[client]['log-fwd'] is not None:
322 self.log_name = self.config[client]['log-fwd']
323 extra_args += [run.Raw('>>'),
324 self.log_name]
325
326 if not suppress_groups:
327 test_groups = ['AWS4Test', 'BucketTest', 'ObjectTest']
328 else:
329 test_groups = ['All']
330
331 for gr in test_groups:
332 for i in range(2):
333 self.ctx.cluster.only(client).run(
334 args=['radosgw-admin', 'gc',
335 'process', '--include-all'],
e306af50 336 stdout=BytesIO()
9f95a23c
TL
337 )
338
339 if gr != 'All':
340 self.ctx.cluster.only(client).run(
341 args=args + ['--tests'] + [gr] + extra_args,
e306af50 342 stdout=BytesIO()
9f95a23c
TL
343 )
344 else:
345 self.ctx.cluster.only(client).run(
346 args=args + extra_args,
e306af50 347 stdout=BytesIO()
9f95a23c
TL
348 )
349
350 for i in range(2):
351 self.ctx.cluster.only(client).run(
352 args=['radosgw-admin', 'gc',
353 'process', '--include-all'],
e306af50 354 stdout=BytesIO()
9f95a23c
TL
355 )
356
357 def remove_tests(self, client):
358 log.info('S3 Tests Java: Cleaning up s3-tests-java...')
359 testdir = teuthology.get_testdir(self.ctx)
360
361 if self.log_fwd:
362 self.ctx.cluster.only(client).run(
363 args=['cd',
364 '{tdir}/s3-tests-java'.format(tdir=testdir),
365 run.Raw('&&'),
366 'cat', self.log_name,
367 run.Raw('&&'),
368 'rm', self.log_name],
e306af50 369 stdout=BytesIO()
9f95a23c
TL
370 )
371
372 self.ctx.cluster.only(client).run(
373 args=[
374 'rm',
375 '-rf',
376 '{tdir}/s3-tests-java'.format(tdir=testdir),
377 ],
e306af50 378 stdout=BytesIO()
9f95a23c
TL
379 )
380
381 def delete_users(self, client):
382 log.info("S3 Tests Java: Deleting S3 users...")
383 testdir = teuthology.get_testdir(self.ctx)
384 for section, user in self.users.items():
385 s3_user_id = '{user}.{client}'.format(user=user, client=client)
386 self.ctx.cluster.only(client).run(
387 args=[
388 'adjust-ulimits',
389 'ceph-coverage',
390 '{tdir}/archive/coverage'.format(tdir=testdir),
391 'radosgw-admin',
392 '-n', client,
393 'user', 'rm',
394 '--uid', s3_user_id,
395 '--purge-data',
396 '--cluster', 'ceph',
397 ],
e306af50 398 stdout=BytesIO()
9f95a23c
TL
399 )
400
401
402task = S3tests_java