ceph/qa/tasks/filestore_idempotent.py
Kefu Chai d7258ea7fd qa/tasks: use next(iter(..)) for accessing first element in a view
in python2, dict.values() and dict.keys() return lists. but in python3,
they return views, which cannot be indexed directly using an integer index.

there are three use cases when we access these views in python3:

1. get the first element
2. get all the elements and then *might* want to access them by index
3. get the first element assuming there is only a single element in
   the view
4. iterate thru the view

in the 1st case, we cannot assume the number of elements, so to be
python3 compatible, we should use `next(iter(a_dict))` instead.

in the 2nd case, in this change, the view is materialized using
`list(a_dict)`.

in the 3rd case, we can just continue using the short hand of
```py
(first_element,) = a_dict.keys()
```
to unpack the view. this works in both python2 and python3.

in the 4th case, the existing code works in both python2 and python3, as
both list and view can be iterated using `iter`, and `len` works as
well.

Signed-off-by: Kefu Chai <kchai@redhat.com>
2020-04-07 20:33:47 +08:00

84 lines
2.6 KiB
Python

"""
Filestore/filejournal handler
"""
import logging
from teuthology.orchestra import run
import random
from teuthology import misc as teuthology
log = logging.getLogger(__name__)
def task(ctx, config):
"""
Test filestore/filejournal handling of non-idempotent events.
Currently this is a kludge; we require the ceph task precedes us just
so that we get the tarball installed to run the test binary.
:param ctx: Context
:param config: Configuration
"""
assert config is None or isinstance(config, list) \
or isinstance(config, dict), \
"task only supports a list or dictionary for configuration"
all_clients = ['client.{id}'.format(id=id_)
for id_ in teuthology.all_roles_of_type(ctx.cluster, 'client')]
if config is None:
config = all_clients
if isinstance(config, list):
config = dict.fromkeys(config)
clients = config.keys()
# just use the first client...
client = next(iter(clients))
(remote,) = ctx.cluster.only(client).remotes.keys()
testdir = teuthology.get_testdir(ctx)
dir = '%s/ceph.data/test.%s' % (testdir, client)
seed = int(random.uniform(1,100))
start = 800 + random.randint(800,1200)
end = start + 50
try:
log.info('creating a working dir')
remote.run(args=['mkdir', dir])
remote.run(
args=[
'cd', dir,
run.Raw('&&'),
'wget','-q', '-Orun_seed_to.sh',
'http://git.ceph.com/?p=ceph.git;a=blob_plain;f=src/test/objectstore/run_seed_to.sh;hb=HEAD',
run.Raw('&&'),
'wget','-q', '-Orun_seed_to_range.sh',
'http://git.ceph.com/?p=ceph.git;a=blob_plain;f=src/test/objectstore/run_seed_to_range.sh;hb=HEAD',
run.Raw('&&'),
'chmod', '+x', 'run_seed_to.sh', 'run_seed_to_range.sh',
]);
log.info('running a series of tests')
proc = remote.run(
args=[
'cd', dir,
run.Raw('&&'),
'./run_seed_to_range.sh', str(seed), str(start), str(end),
],
wait=False,
check_status=False)
result = proc.wait()
if result != 0:
remote.run(
args=[
'cp', '-a', dir, '{tdir}/archive/idempotent_failure'.format(tdir=testdir),
])
raise Exception("./run_seed_to_range.sh errored out")
finally:
remote.run(args=[
'rm', '-rf', '--', dir
])