]>
git.proxmox.com Git - ceph.git/blob - ceph/qa/tasks/ragweed.py
2 Run a set of s3 tests on rgw.
4 from cStringIO
import StringIO
5 from configobj
import ConfigObj
13 from teuthology
import misc
as teuthology
14 from teuthology
import contextutil
15 from teuthology
.config
import config
as teuth_config
16 from teuthology
.orchestra
import run
18 log
= logging
.getLogger(__name__
)
20 @contextlib.contextmanager
21 def download(ctx
, config
):
23 Download the s3 tests from the git builder.
24 Remove downloaded s3 file upon exit.
26 The context passed in should be identical to the context
27 passed in to the main task.
29 assert isinstance(config
, dict)
30 log
.info('Downloading ragweed...')
31 testdir
= teuthology
.get_testdir(ctx
)
32 s3_branches
= [ 'master', 'nautilus', 'mimic', 'luminous', 'kraken', 'jewel' ]
33 for (client
, cconf
) in config
.items():
35 branch
= cconf
.get('force-branch', None)
37 default_branch
= cconf
.get('default-branch', None)
38 ceph_branch
= ctx
.config
.get('branch')
39 suite_branch
= ctx
.config
.get('suite_branch', ceph_branch
)
40 ragweed_repo
= ctx
.config
.get('ragweed_repo', teuth_config
.ceph_git_base_url
+ 'ragweed.git')
41 if suite_branch
in s3_branches
:
42 branch
= cconf
.get('branch', 'ceph-' + suite_branch
)
44 branch
= cconf
.get('branch', suite_branch
)
47 "Could not determine what branch to use for ragweed!")
49 log
.info("Using branch '%s' for ragweed", branch
)
50 sha1
= cconf
.get('sha1')
52 ctx
.cluster
.only(client
).run(
57 '{tdir}/ragweed'.format(tdir
=testdir
),
60 except Exception as e
:
61 if not default_branch
:
63 ctx
.cluster
.only(client
).run(
68 '{tdir}/ragweed'.format(tdir
=testdir
),
73 ctx
.cluster
.only(client
).run(
75 'cd', '{tdir}/ragweed'.format(tdir
=testdir
),
77 'git', 'reset', '--hard', sha1
,
83 log
.info('Removing ragweed...')
84 testdir
= teuthology
.get_testdir(ctx
)
86 ctx
.cluster
.only(client
).run(
90 '{tdir}/ragweed'.format(tdir
=testdir
),
95 def _config_user(ragweed_conf
, section
, user
):
97 Configure users for this section by stashing away keys, ids, and
100 ragweed_conf
[section
].setdefault('user_id', user
)
101 ragweed_conf
[section
].setdefault('email', '{user}+test@test.test'.format(user
=user
))
102 ragweed_conf
[section
].setdefault('display_name', 'Mr. {user}'.format(user
=user
))
103 ragweed_conf
[section
].setdefault('access_key', ''.join(random
.choice(string
.uppercase
) for i
in range(20)))
104 ragweed_conf
[section
].setdefault('secret_key', base64
.b64encode(os
.urandom(40)))
107 @contextlib.contextmanager
108 def create_users(ctx
, config
, run_stages
):
110 Create a main and an alternate s3 user.
112 assert isinstance(config
, dict)
114 for client
, properties
in config
['config'].items():
115 run_stages
[client
] = string
.split(properties
.get('stages', 'prepare,check'), ',')
117 log
.info('Creating rgw users...')
118 testdir
= teuthology
.get_testdir(ctx
)
119 users
= {'user regular': 'ragweed', 'user system': 'sysuser'}
120 for client
in config
['clients']:
121 if not 'prepare' in run_stages
[client
]:
122 # should have been prepared in a previous run
125 ragweed_conf
= config
['ragweed_conf'][client
]
126 ragweed_conf
.setdefault('fixtures', {})
127 ragweed_conf
['rgw'].setdefault('bucket_prefix', 'test-' + client
)
128 for section
, user
in users
.items():
129 _config_user(ragweed_conf
, section
, '{user}.{client}'.format(user
=user
, client
=client
))
130 log
.debug('Creating user {user} on {host}'.format(user
=ragweed_conf
[section
]['user_id'], host
=client
))
131 if user
== 'sysuser':
135 ctx
.cluster
.only(client
).run(
139 '{tdir}/archive/coverage'.format(tdir
=testdir
),
143 '--uid', ragweed_conf
[section
]['user_id'],
144 '--display-name', ragweed_conf
[section
]['display_name'],
145 '--access-key', ragweed_conf
[section
]['access_key'],
146 '--secret', ragweed_conf
[section
]['secret_key'],
147 '--email', ragweed_conf
[section
]['email'],
154 for client
in config
['clients']:
155 if not 'check' in run_stages
[client
]:
156 # only remove user if went through the check stage
158 for user
in users
.itervalues():
159 uid
= '{user}.{client}'.format(user
=user
, client
=client
)
160 ctx
.cluster
.only(client
).run(
164 '{tdir}/archive/coverage'.format(tdir
=testdir
),
174 @contextlib.contextmanager
175 def configure(ctx
, config
, run_stages
):
177 Configure the ragweed. This includes the running of the
178 bootstrap code and the updating of local conf files.
180 assert isinstance(config
, dict)
181 log
.info('Configuring ragweed...')
182 testdir
= teuthology
.get_testdir(ctx
)
183 for client
, properties
in config
['clients'].items():
184 (remote
,) = ctx
.cluster
.only(client
).remotes
.keys()
188 '{tdir}/ragweed'.format(tdir
=testdir
),
194 preparing
= 'prepare' in run_stages
[client
]
196 # should have been prepared in a previous run
199 ragweed_conf
= config
['ragweed_conf'][client
]
200 if properties
is not None and 'slow_backend' in properties
:
201 ragweed_conf
['fixtures']['slow backend'] = properties
['slow_backend']
204 ragweed_conf
.write(conf_fp
)
205 teuthology
.write_file(
207 path
='{tdir}/archive/ragweed.{client}.conf'.format(tdir
=testdir
, client
=client
),
208 data
=conf_fp
.getvalue(),
211 log
.info('Configuring boto...')
212 boto_src
= os
.path
.join(os
.path
.dirname(__file__
), 'boto.cfg.template')
213 for client
, properties
in config
['clients'].items():
214 with
open(boto_src
, 'rb') as f
:
215 (remote
,) = ctx
.cluster
.only(client
).remotes
.keys()
216 conf
= f
.read().format(
217 idle_timeout
=config
.get('idle_timeout', 30)
219 teuthology
.write_file(
221 path
='{tdir}/boto.cfg'.format(tdir
=testdir
),
229 log
.info('Cleaning up boto...')
230 for client
, properties
in config
['clients'].items():
231 (remote
,) = ctx
.cluster
.only(client
).remotes
.keys()
235 '{tdir}/boto.cfg'.format(tdir
=testdir
),
239 @contextlib.contextmanager
240 def run_tests(ctx
, config
, run_stages
):
242 Run the ragweed after everything is set up.
244 :param ctx: Context passed to task
245 :param config: specific configuration information
247 assert isinstance(config
, dict)
248 testdir
= teuthology
.get_testdir(ctx
)
249 attrs
= ["!fails_on_rgw"]
250 for client
, client_config
in config
.items():
251 stages
= string
.join(run_stages
[client
], ',')
253 'RAGWEED_CONF={tdir}/archive/ragweed.{client}.conf'.format(tdir
=testdir
, client
=client
),
254 'RAGWEED_STAGES={stages}'.format(stages
=stages
),
255 'BOTO_CONFIG={tdir}/boto.cfg'.format(tdir
=testdir
),
256 '{tdir}/ragweed/virtualenv/bin/python'.format(tdir
=testdir
),
259 '{tdir}/ragweed'.format(tdir
=testdir
),
261 '-a', ','.join(attrs
),
263 if client_config
is not None and 'extra_args' in client_config
:
264 args
.extend(client_config
['extra_args'])
266 ctx
.cluster
.only(client
).run(
268 label
="ragweed tests against rgw"
272 @contextlib.contextmanager
273 def task(ctx
, config
):
275 Run the ragweed suite against rgw.
277 To run all tests on all clients::
284 To restrict testing to particular clients::
289 - ragweed: [client.0]
291 To run against a server on client.1 and increase the boto timeout to 10m::
300 stages: prepare,check
302 To pass extra arguments to nose (e.g. to run a certain test)::
309 extra_args: ['test_s3:test_object_acl_grand_public_read']
311 extra_args: ['--exclude', 'test_100_continue']
313 assert hasattr(ctx
, 'rgw'), 'ragweed must run after the rgw task'
314 assert config
is None or isinstance(config
, list) \
315 or isinstance(config
, dict), \
316 "task ragweed only supports a list or dictionary for configuration"
317 all_clients
= ['client.{id}'.format(id=id_
)
318 for id_
in teuthology
.all_roles_of_type(ctx
.cluster
, 'client')]
321 if isinstance(config
, list):
322 config
= dict.fromkeys(config
)
323 clients
= config
.keys()
325 overrides
= ctx
.config
.get('overrides', {})
326 # merge each client section, not the top level.
327 for client
in config
.keys():
328 if not config
[client
]:
330 teuthology
.deep_merge(config
[client
], overrides
.get('ragweed', {}))
332 log
.debug('ragweed config is %s', config
)
335 for client
in clients
:
336 # use rgw_server endpoint if given, or default to same client
337 target
= config
[client
].get('rgw_server', client
)
339 endpoint
= ctx
.rgw
.role_endpoints
.get(target
)
340 assert endpoint
, 'ragweed: no rgw endpoint for {}'.format(target
)
342 ragweed_conf
[client
] = ConfigObj(
347 'host' : endpoint
.dns_name
,
348 'port' : endpoint
.port
,
349 'is_secure' : endpoint
.cert
is not None,
356 'ceph_conf' : '/etc/ceph/ceph.conf',
363 with contextutil
.nested(
364 lambda: download(ctx
=ctx
, config
=config
),
365 lambda: create_users(ctx
=ctx
, config
=dict(
367 ragweed_conf
=ragweed_conf
,
370 run_stages
=run_stages
),
371 lambda: configure(ctx
=ctx
, config
=dict(
373 ragweed_conf
=ragweed_conf
,
375 run_stages
=run_stages
),
376 lambda: run_tests(ctx
=ctx
, config
=config
, run_stages
=run_stages
),