]>
git.proxmox.com Git - ceph.git/blob - ceph/qa/tasks/ragweed.py
2 Run a set of s3 tests on rgw.
5 from configobj
import ConfigObj
14 from teuthology
import misc
as teuthology
15 from teuthology
import contextutil
16 from teuthology
.config
import config
as teuth_config
17 from teuthology
.orchestra
import run
19 log
= logging
.getLogger(__name__
)
21 @contextlib.contextmanager
22 def download(ctx
, config
):
24 Download the s3 tests from the git builder.
25 Remove downloaded s3 file upon exit.
27 The context passed in should be identical to the context
28 passed in to the main task.
30 assert isinstance(config
, dict)
31 log
.info('Downloading ragweed...')
32 testdir
= teuthology
.get_testdir(ctx
)
33 s3_branches
= [ 'master', 'nautilus', 'mimic', 'luminous', 'kraken', 'jewel' ]
34 for (client
, cconf
) in config
.items():
36 branch
= cconf
.get('force-branch', None)
38 default_branch
= cconf
.get('default-branch', None)
39 ceph_branch
= ctx
.config
.get('branch')
40 suite_branch
= ctx
.config
.get('suite_branch', ceph_branch
)
41 ragweed_repo
= ctx
.config
.get('ragweed_repo', teuth_config
.ceph_git_base_url
+ 'ragweed.git')
42 if suite_branch
in s3_branches
:
43 branch
= cconf
.get('branch', 'ceph-' + suite_branch
)
45 branch
= cconf
.get('branch', suite_branch
)
48 "Could not determine what branch to use for ragweed!")
50 log
.info("Using branch '%s' for ragweed", branch
)
51 sha1
= cconf
.get('sha1')
53 ctx
.cluster
.only(client
).run(
58 '{tdir}/ragweed'.format(tdir
=testdir
),
61 except Exception as e
:
62 if not default_branch
:
64 ctx
.cluster
.only(client
).run(
69 '{tdir}/ragweed'.format(tdir
=testdir
),
74 ctx
.cluster
.only(client
).run(
76 'cd', '{tdir}/ragweed'.format(tdir
=testdir
),
78 'git', 'reset', '--hard', sha1
,
84 log
.info('Removing ragweed...')
85 testdir
= teuthology
.get_testdir(ctx
)
87 ctx
.cluster
.only(client
).run(
91 '{tdir}/ragweed'.format(tdir
=testdir
),
96 def _config_user(ragweed_conf
, section
, user
):
98 Configure users for this section by stashing away keys, ids, and
101 ragweed_conf
[section
].setdefault('user_id', user
)
102 ragweed_conf
[section
].setdefault('email', '{user}+test@test.test'.format(user
=user
))
103 ragweed_conf
[section
].setdefault('display_name', 'Mr. {user}'.format(user
=user
))
104 ragweed_conf
[section
].setdefault('access_key', ''.join(random
.choice(string
.ascii_uppercase
) for i
in range(20)))
105 ragweed_conf
[section
].setdefault('secret_key', base64
.b64encode(os
.urandom(40)).decode('ascii'))
108 @contextlib.contextmanager
109 def create_users(ctx
, config
, run_stages
):
111 Create a main and an alternate s3 user.
113 assert isinstance(config
, dict)
115 for client
, properties
in config
['config'].items():
116 run_stages
[client
] = properties
.get('stages', 'prepare,check').split(',')
118 log
.info('Creating rgw users...')
119 testdir
= teuthology
.get_testdir(ctx
)
120 users
= {'user regular': 'ragweed', 'user system': 'sysuser'}
121 for client
in config
['clients']:
122 if not 'prepare' in run_stages
[client
]:
123 # should have been prepared in a previous run
126 ragweed_conf
= config
['ragweed_conf'][client
]
127 ragweed_conf
.setdefault('fixtures', {})
128 ragweed_conf
['rgw'].setdefault('bucket_prefix', 'test-' + client
)
129 for section
, user
in users
.items():
130 _config_user(ragweed_conf
, section
, '{user}.{client}'.format(user
=user
, client
=client
))
131 log
.debug('Creating user {user} on {host}'.format(user
=ragweed_conf
[section
]['user_id'], host
=client
))
132 if user
== 'sysuser':
136 ctx
.cluster
.only(client
).run(
140 '{tdir}/archive/coverage'.format(tdir
=testdir
),
144 '--uid', ragweed_conf
[section
]['user_id'],
145 '--display-name', ragweed_conf
[section
]['display_name'],
146 '--access-key', ragweed_conf
[section
]['access_key'],
147 '--secret', ragweed_conf
[section
]['secret_key'],
148 '--email', ragweed_conf
[section
]['email'],
155 for client
in config
['clients']:
156 if not 'check' in run_stages
[client
]:
157 # only remove user if went through the check stage
159 for user
in users
.values():
160 uid
= '{user}.{client}'.format(user
=user
, client
=client
)
161 ctx
.cluster
.only(client
).run(
165 '{tdir}/archive/coverage'.format(tdir
=testdir
),
175 @contextlib.contextmanager
176 def configure(ctx
, config
, run_stages
):
178 Configure the ragweed. This includes the running of the
179 bootstrap code and the updating of local conf files.
181 assert isinstance(config
, dict)
182 log
.info('Configuring ragweed...')
183 testdir
= teuthology
.get_testdir(ctx
)
184 for client
, properties
in config
['clients'].items():
185 (remote
,) = ctx
.cluster
.only(client
).remotes
.keys()
189 '{tdir}/ragweed'.format(tdir
=testdir
),
195 preparing
= 'prepare' in run_stages
[client
]
197 # should have been prepared in a previous run
200 ragweed_conf
= config
['ragweed_conf'][client
]
201 if properties
is not None and 'slow_backend' in properties
:
202 ragweed_conf
['fixtures']['slow backend'] = properties
['slow_backend']
205 ragweed_conf
.write(conf_fp
)
206 teuthology
.write_file(
208 path
='{tdir}/archive/ragweed.{client}.conf'.format(tdir
=testdir
, client
=client
),
209 data
=conf_fp
.getvalue(),
212 log
.info('Configuring boto...')
213 boto_src
= os
.path
.join(os
.path
.dirname(__file__
), 'boto.cfg.template')
214 for client
, properties
in config
['clients'].items():
215 with
open(boto_src
, 'r') as f
:
216 (remote
,) = ctx
.cluster
.only(client
).remotes
.keys()
217 conf
= f
.read().format(
218 idle_timeout
=config
.get('idle_timeout', 30)
220 teuthology
.write_file(
222 path
='{tdir}/boto.cfg'.format(tdir
=testdir
),
230 log
.info('Cleaning up boto...')
231 for client
, properties
in config
['clients'].items():
232 (remote
,) = ctx
.cluster
.only(client
).remotes
.keys()
236 '{tdir}/boto.cfg'.format(tdir
=testdir
),
240 @contextlib.contextmanager
241 def run_tests(ctx
, config
, run_stages
):
243 Run the ragweed after everything is set up.
245 :param ctx: Context passed to task
246 :param config: specific configuration information
248 assert isinstance(config
, dict)
249 testdir
= teuthology
.get_testdir(ctx
)
250 attrs
= ["!fails_on_rgw"]
251 for client
, client_config
in config
.items():
252 stages
= ','.join(run_stages
[client
])
254 'RAGWEED_CONF={tdir}/archive/ragweed.{client}.conf'.format(tdir
=testdir
, client
=client
),
255 'RAGWEED_STAGES={stages}'.format(stages
=stages
),
256 'BOTO_CONFIG={tdir}/boto.cfg'.format(tdir
=testdir
),
257 '{tdir}/ragweed/virtualenv/bin/python'.format(tdir
=testdir
),
260 '{tdir}/ragweed'.format(tdir
=testdir
),
262 '-a', ','.join(attrs
),
264 if client_config
is not None and 'extra_args' in client_config
:
265 args
.extend(client_config
['extra_args'])
267 ctx
.cluster
.only(client
).run(
269 label
="ragweed tests against rgw"
273 @contextlib.contextmanager
274 def task(ctx
, config
):
276 Run the ragweed suite against rgw.
278 To run all tests on all clients::
285 To restrict testing to particular clients::
290 - ragweed: [client.0]
292 To run against a server on client.1 and increase the boto timeout to 10m::
301 stages: prepare,check
303 To pass extra arguments to nose (e.g. to run a certain test)::
310 extra_args: ['test_s3:test_object_acl_grand_public_read']
312 extra_args: ['--exclude', 'test_100_continue']
314 assert hasattr(ctx
, 'rgw'), 'ragweed must run after the rgw task'
315 assert config
is None or isinstance(config
, list) \
316 or isinstance(config
, dict), \
317 "task ragweed only supports a list or dictionary for configuration"
318 all_clients
= ['client.{id}'.format(id=id_
)
319 for id_
in teuthology
.all_roles_of_type(ctx
.cluster
, 'client')]
322 if isinstance(config
, list):
323 config
= dict.fromkeys(config
)
324 clients
= config
.keys()
326 overrides
= ctx
.config
.get('overrides', {})
327 # merge each client section, not the top level.
328 for client
in config
.keys():
329 if not config
[client
]:
331 teuthology
.deep_merge(config
[client
], overrides
.get('ragweed', {}))
333 log
.debug('ragweed config is %s', config
)
336 for client
in clients
:
337 # use rgw_server endpoint if given, or default to same client
338 target
= config
[client
].get('rgw_server', client
)
340 endpoint
= ctx
.rgw
.role_endpoints
.get(target
)
341 assert endpoint
, 'ragweed: no rgw endpoint for {}'.format(target
)
343 ragweed_conf
[client
] = ConfigObj(
348 'host' : endpoint
.dns_name
,
349 'port' : endpoint
.port
,
350 'is_secure' : endpoint
.cert
is not None,
357 'ceph_conf' : '/etc/ceph/ceph.conf',
364 with contextutil
.nested(
365 lambda: download(ctx
=ctx
, config
=config
),
366 lambda: create_users(ctx
=ctx
, config
=dict(
368 ragweed_conf
=ragweed_conf
,
371 run_stages
=run_stages
),
372 lambda: configure(ctx
=ctx
, config
=dict(
374 ragweed_conf
=ragweed_conf
,
376 run_stages
=run_stages
),
377 lambda: run_tests(ctx
=ctx
, config
=config
, run_stages
=run_stages
),