]>
git.proxmox.com Git - ceph.git/blob - ceph/qa/tasks/tempest.py
2 Deploy and configure Tempest for Teuthology
7 from six
.moves
import configparser
9 from teuthology
import misc
as teuthology
10 from teuthology
import contextutil
11 from teuthology
.exceptions
import ConfigError
12 from teuthology
.orchestra
import run
14 log
= logging
.getLogger(__name__
)
17 def get_tempest_dir(ctx
):
18 return '{tdir}/tempest'.format(tdir
=teuthology
.get_testdir(ctx
))
20 def run_in_tempest_dir(ctx
, client
, cmdargs
, **kwargs
):
21 ctx
.cluster
.only(client
).run(
22 args
=[ 'cd', get_tempest_dir(ctx
), run
.Raw('&&'), ] + cmdargs
,
26 def run_in_tempest_rgw_dir(ctx
, client
, cmdargs
, **kwargs
):
27 ctx
.cluster
.only(client
).run(
28 args
=[ 'cd', get_tempest_dir(ctx
) + '/rgw', run
.Raw('&&'), ] + cmdargs
,
32 def run_in_tempest_venv(ctx
, client
, cmdargs
, **kwargs
):
33 run_in_tempest_dir(ctx
, client
,
35 '.tox/venv/bin/activate',
37 ] + cmdargs
, **kwargs
)
39 @contextlib.contextmanager
40 def download(ctx
, config
):
42 Download the Tempest from github.
43 Remove downloaded file upon exit.
45 The context passed in should be identical to the context
46 passed in to the main task.
48 assert isinstance(config
, dict)
49 log
.info('Downloading Tempest...')
50 for (client
, cconf
) in config
.items():
51 ctx
.cluster
.only(client
).run(
54 '-b', cconf
.get('force-branch', 'master'),
55 'https://github.com/openstack/tempest.git',
60 sha1
= cconf
.get('sha1')
62 run_in_tempest_dir(ctx
, client
, [ 'git', 'reset', '--hard', sha1
])
66 log
.info('Removing Tempest...')
68 ctx
.cluster
.only(client
).run(
69 args
=[ 'rm', '-rf', get_tempest_dir(ctx
) ],
72 def get_toxvenv_dir(ctx
):
73 return ctx
.tox
.venv_path
75 @contextlib.contextmanager
76 def setup_venv(ctx
, config
):
78 Setup the virtualenv for Tempest using tox.
80 assert isinstance(config
, dict)
81 log
.info('Setting up virtualenv for Tempest')
82 for (client
, _
) in config
.items():
83 run_in_tempest_dir(ctx
, client
,
84 [ '{tvdir}/bin/tox'.format(tvdir
=get_toxvenv_dir(ctx
)),
85 '-e', 'venv', '--notest'
89 def setup_logging(ctx
, cpar
):
90 cpar
.set('DEFAULT', 'log_dir', teuthology
.get_archive_dir(ctx
))
91 cpar
.set('DEFAULT', 'log_file', 'tempest.log')
93 def to_config(config
, params
, section
, cpar
):
94 for (k
, v
) in config
[section
].items():
95 if isinstance(v
, str):
96 v
= v
.format(**params
)
97 elif isinstance(v
, bool):
98 v
= 'true' if v
else 'false'
101 cpar
.set(section
, k
, v
)
103 @contextlib.contextmanager
104 def configure_instance(ctx
, config
):
105 assert isinstance(config
, dict)
106 log
.info('Configuring Tempest')
108 for (client
, cconfig
) in config
.items():
109 run_in_tempest_venv(ctx
, client
,
114 get_tempest_dir(ctx
) + '/workspace.yaml',
118 # prepare the config file
119 tetcdir
= '{tdir}/rgw/etc'.format(tdir
=get_tempest_dir(ctx
))
120 (remote
,) = ctx
.cluster
.only(client
).remotes
.keys()
121 local_conf
= remote
.get_file(tetcdir
+ '/tempest.conf.sample')
123 # fill the params dictionary which allows to use templatized configs
124 keystone_role
= cconfig
.get('use-keystone-role', None)
125 if keystone_role
is None \
126 or keystone_role
not in ctx
.keystone
.public_endpoints
:
127 raise ConfigError('the use-keystone-role is misconfigured')
128 public_host
, public_port
= ctx
.keystone
.public_endpoints
[keystone_role
]
130 'keystone_public_host': public_host
,
131 'keystone_public_port': str(public_port
),
134 cpar
= configparser
.ConfigParser()
135 cpar
.read(local_conf
)
136 setup_logging(ctx
, cpar
)
137 to_config(cconfig
, params
, 'auth', cpar
)
138 to_config(cconfig
, params
, 'identity', cpar
)
139 to_config(cconfig
, params
, 'object-storage', cpar
)
140 to_config(cconfig
, params
, 'object-storage-feature-enabled', cpar
)
141 cpar
.write(open(local_conf
, 'w+'))
143 remote
.put_file(local_conf
, tetcdir
+ '/tempest.conf')
146 @contextlib.contextmanager
147 def run_tempest(ctx
, config
):
148 assert isinstance(config
, dict)
149 log
.info('Configuring Tempest')
151 for (client
, cconf
) in config
.items():
152 blacklist
= cconf
.get('blacklist', [])
153 assert isinstance(blacklist
, list)
154 run_in_tempest_venv(ctx
, client
,
159 get_tempest_dir(ctx
) + '/workspace.yaml',
162 '--regex', '^tempest.api.object_storage',
163 '--black-regex', '|'.join(blacklist
)
171 @contextlib.contextmanager
172 def task(ctx
, config
):
174 Deploy and run Tempest's object storage campaign
176 Example of configuration:
182 rgw keystone api version: 3
183 rgw keystone accepted roles: admin,Member
184 rgw keystone implicit tenants: true
185 rgw keystone accepted admin roles: admin
186 rgw swift enforce content length: true
187 rgw swift account in url: true
188 rgw swift versioning enabled: true
189 rgw keystone admin domain: Default
190 rgw keystone admin user: admin
191 rgw keystone admin password: ADMIN
192 rgw keystone admin project: admin
194 # typically, the task should be preceded with install, ceph, tox,
195 # keystone and rgw. Tox and Keystone are specific requirements
198 # it's important to match the prefix with the endpoint's URL
199 # in Keystone. Additionally, if we want to test /info and its
200 # accompanying stuff, the whole Swift API must be put in root
201 # of the whole URL hierarchy (read: frontend_prefix == /swift).
202 frontend_prefix: /swift
204 use-keystone-role: client.0
208 use-keystone-role: client.0
210 admin_username: admin
211 admin_project_name: admin
212 admin_password: ADMIN
213 admin_domain_name: Default
215 uri: http://{keystone_public_host}:{keystone_public_port}/v2.0/
216 uri_v3: http://{keystone_public_host}:{keystone_public_port}/v3/
219 reseller_admin_role: admin
220 object-storage-feature-enabled:
221 container_sync: false
222 discoverability: false
224 # please strip half of these items after merging PRs #15369
226 - .*test_list_containers_reverse_order.*
227 - .*test_list_container_contents_with_end_marker.*
228 - .*test_delete_non_empty_container.*
229 - .*test_container_synchronization.*
230 - .*test_get_object_after_expiration_time.*
231 - .*test_create_object_with_transfer_encoding.*
233 assert config
is None or isinstance(config
, list) \
234 or isinstance(config
, dict), \
235 'task tempest only supports a list or dictionary for configuration'
238 raise ConfigError('tempest must run after the tox task')
240 raise ConfigError('tempest must run after the keystone task')
242 all_clients
= ['client.{id}'.format(id=id_
)
243 for id_
in teuthology
.all_roles_of_type(ctx
.cluster
, 'client')]
246 if isinstance(config
, list):
247 config
= dict.fromkeys(config
)
249 overrides
= ctx
.config
.get('overrides', {})
250 # merge each client section, not the top level.
251 for client
in config
.keys():
252 if not config
[client
]:
254 teuthology
.deep_merge(config
[client
], overrides
.get('keystone', {}))
256 log
.debug('Tempest config is %s', config
)
258 with contextutil
.nested(
259 lambda: download(ctx
=ctx
, config
=config
),
260 lambda: setup_venv(ctx
=ctx
, config
=config
),
261 lambda: configure_instance(ctx
=ctx
, config
=config
),
262 lambda: run_tempest(ctx
=ctx
, config
=config
),