]> git.proxmox.com Git - ceph.git/blame - ceph/qa/tasks/swift.py
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / qa / tasks / swift.py
CommitLineData
224ce89b
WB
1"""
2Test Swift API
3"""
4from cStringIO import StringIO
5from configobj import ConfigObj
6import base64
7import contextlib
8import logging
9import os
10
11from teuthology import misc as teuthology
12from teuthology import contextutil
13from teuthology.config import config as teuth_config
14from teuthology.orchestra import run
15from teuthology.orchestra.connection import split_user
16
17log = logging.getLogger(__name__)
18
19
20@contextlib.contextmanager
21def download(ctx, config):
22 """
23 Download the Swift API.
24 """
25 testdir = teuthology.get_testdir(ctx)
11fdf7f2 26 assert isinstance(config, dict)
224ce89b 27 log.info('Downloading swift...')
11fdf7f2 28 for (client, cconf) in config.items():
224ce89b
WB
29 ctx.cluster.only(client).run(
30 args=[
11fdf7f2
TL
31 'git', 'clone',
32 '-b', cconf.get('force-branch', 'ceph-nautilus'),
224ce89b
WB
33 teuth_config.ceph_git_base_url + 'swift.git',
34 '{tdir}/swift'.format(tdir=testdir),
35 ],
36 )
37 try:
38 yield
39 finally:
40 log.info('Removing swift...')
41 testdir = teuthology.get_testdir(ctx)
11fdf7f2 42 for (client, _) in config.items():
224ce89b
WB
43 ctx.cluster.only(client).run(
44 args=[
45 'rm',
46 '-rf',
47 '{tdir}/swift'.format(tdir=testdir),
48 ],
49 )
50
51def _config_user(testswift_conf, account, user, suffix):
52 """
53 Configure a swift user
54
55 :param account: Swift account
56 :param user: User name
57 :param suffix: user name and email suffixes.
58 """
59 testswift_conf['func_test'].setdefault('account{s}'.format(s=suffix), account)
60 testswift_conf['func_test'].setdefault('username{s}'.format(s=suffix), user)
61 testswift_conf['func_test'].setdefault('email{s}'.format(s=suffix), '{account}+test@test.test'.format(account=account))
62 testswift_conf['func_test'].setdefault('display_name{s}'.format(s=suffix), 'Mr. {account} {user}'.format(account=account, user=user))
63 testswift_conf['func_test'].setdefault('password{s}'.format(s=suffix), base64.b64encode(os.urandom(40)))
64
65@contextlib.contextmanager
66def create_users(ctx, config):
67 """
68 Create rgw users to interact with the swift interface.
69 """
70 assert isinstance(config, dict)
71 log.info('Creating rgw users...')
72 testdir = teuthology.get_testdir(ctx)
73 users = {'': 'foo', '2': 'bar'}
74 for client in config['clients']:
75 cluster_name, daemon_type, client_id = teuthology.split_role(client)
76 testswift_conf = config['testswift_conf'][client]
77 for suffix, user in users.iteritems():
78 _config_user(testswift_conf, '{user}.{client}'.format(user=user, client=client), user, suffix)
79 ctx.cluster.only(client).run(
80 args=[
81 'adjust-ulimits',
82 'ceph-coverage',
83 '{tdir}/archive/coverage'.format(tdir=testdir),
84 'radosgw-admin',
85 '-n', client,
86 '--cluster', cluster_name,
87 'user', 'create',
88 '--subuser', '{account}:{user}'.format(account=testswift_conf['func_test']['account{s}'.format(s=suffix)],user=user),
89 '--display-name', testswift_conf['func_test']['display_name{s}'.format(s=suffix)],
90 '--secret', testswift_conf['func_test']['password{s}'.format(s=suffix)],
91 '--email', testswift_conf['func_test']['email{s}'.format(s=suffix)],
92 '--key-type', 'swift',
93 '--access', 'full',
94 ],
95 )
96 try:
97 yield
98 finally:
99 for client in config['clients']:
100 for user in users.itervalues():
101 uid = '{user}.{client}'.format(user=user, client=client)
102 cluster_name, daemon_type, client_id = teuthology.split_role(client)
103 ctx.cluster.only(client).run(
104 args=[
105 'adjust-ulimits',
106 'ceph-coverage',
107 '{tdir}/archive/coverage'.format(tdir=testdir),
108 'radosgw-admin',
109 '-n', client,
110 '--cluster', cluster_name,
111 'user', 'rm',
112 '--uid', uid,
113 '--purge-data',
114 ],
115 )
116
117@contextlib.contextmanager
118def configure(ctx, config):
119 """
120 Configure rgw and Swift
121 """
122 assert isinstance(config, dict)
123 log.info('Configuring testswift...')
124 testdir = teuthology.get_testdir(ctx)
125 for client, properties in config['clients'].iteritems():
126 log.info('client={c}'.format(c=client))
127 log.info('config={c}'.format(c=config))
128 testswift_conf = config['testswift_conf'][client]
129 if properties is not None and 'rgw_server' in properties:
130 host = None
131 for target, roles in zip(ctx.config['targets'].iterkeys(), ctx.config['roles']):
132 log.info('roles: ' + str(roles))
133 log.info('target: ' + str(target))
134 if properties['rgw_server'] in roles:
135 _, host = split_user(target)
136 assert host is not None, "Invalid client specified as the rgw_server"
137 testswift_conf['func_test']['auth_host'] = host
138 else:
139 testswift_conf['func_test']['auth_host'] = 'localhost'
140
141 log.info(client)
142 (remote,) = ctx.cluster.only(client).remotes.keys()
143 remote.run(
144 args=[
145 'cd',
146 '{tdir}/swift'.format(tdir=testdir),
147 run.Raw('&&'),
148 './bootstrap',
149 ],
150 )
151 conf_fp = StringIO()
152 testswift_conf.write(conf_fp)
153 teuthology.write_file(
154 remote=remote,
155 path='{tdir}/archive/testswift.{client}.conf'.format(tdir=testdir, client=client),
156 data=conf_fp.getvalue(),
157 )
158 yield
159
160
161@contextlib.contextmanager
162def run_tests(ctx, config):
163 """
164 Run an individual Swift test.
165 """
166 assert isinstance(config, dict)
167 testdir = teuthology.get_testdir(ctx)
168 for client, client_config in config.iteritems():
169 args = [
170 'SWIFT_TEST_CONFIG_FILE={tdir}/archive/testswift.{client}.conf'.format(tdir=testdir, client=client),
171 '{tdir}/swift/virtualenv/bin/nosetests'.format(tdir=testdir),
172 '-w',
173 '{tdir}/swift/test/functional'.format(tdir=testdir),
174 '-v',
175 '-a', '!fails_on_rgw',
176 ]
177 if client_config is not None and 'extra_args' in client_config:
178 args.extend(client_config['extra_args'])
179
180 ctx.cluster.only(client).run(
181 args=args,
182 )
183 yield
184
185@contextlib.contextmanager
186def task(ctx, config):
187 """
188 Run the testswift suite against rgw.
189
190 To run all tests on all clients::
191
192 tasks:
193 - ceph:
194 - rgw:
195 - testswift:
196
197 To restrict testing to particular clients::
198
199 tasks:
200 - ceph:
201 - rgw: [client.0]
202 - testswift: [client.0]
203
204 To run against a server on client.1::
205
206 tasks:
207 - ceph:
208 - rgw: [client.1]
209 - testswift:
210 client.0:
211 rgw_server: client.1
212
213 To pass extra arguments to nose (e.g. to run a certain test)::
214
215 tasks:
216 - ceph:
217 - rgw: [client.0]
218 - testswift:
219 client.0:
220 extra_args: ['test.functional.tests:TestFileUTF8', '-m', 'testCopy']
221 client.1:
222 extra_args: ['--exclude', 'TestFile']
223 """
11fdf7f2 224 assert hasattr(ctx, 'rgw'), 'swift must run after the rgw task'
224ce89b
WB
225 assert config is None or isinstance(config, list) \
226 or isinstance(config, dict), \
227 "task testswift only supports a list or dictionary for configuration"
228 all_clients = ['client.{id}'.format(id=id_)
229 for id_ in teuthology.all_roles_of_type(ctx.cluster, 'client')]
230 if config is None:
231 config = all_clients
232 if isinstance(config, list):
233 config = dict.fromkeys(config)
234 clients = config.keys()
235
236 log.info('clients={c}'.format(c=clients))
237
238 testswift_conf = {}
239 for client in clients:
11fdf7f2
TL
240 endpoint = ctx.rgw.role_endpoints.get(client)
241 assert endpoint, 'swift: no rgw endpoint for {}'.format(client)
242
224ce89b
WB
243 testswift_conf[client] = ConfigObj(
244 indent_type='',
245 infile={
246 'func_test':
247 {
11fdf7f2
TL
248 'auth_port' : endpoint.port,
249 'auth_ssl' : 'yes' if endpoint.cert else 'no',
224ce89b
WB
250 'auth_prefix' : '/auth/',
251 },
252 }
253 )
254
255 with contextutil.nested(
11fdf7f2 256 lambda: download(ctx=ctx, config=config),
224ce89b
WB
257 lambda: create_users(ctx=ctx, config=dict(
258 clients=clients,
259 testswift_conf=testswift_conf,
260 )),
261 lambda: configure(ctx=ctx, config=dict(
262 clients=config,
263 testswift_conf=testswift_conf,
264 )),
265 lambda: run_tests(ctx=ctx, config=config),
266 ):
267 pass
268 yield