Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / qa / tasks / cram.py
1 """
2 Cram tests
3 """
4 import logging
5 import os
6
7 from teuthology import misc as teuthology
8 from teuthology.parallel import parallel
9 from teuthology.orchestra import run
10 from teuthology.config import config as teuth_config
11
12 log = logging.getLogger(__name__)
13
14 def task(ctx, config):
15     """
16     Run all cram tests from the specified urls on the specified
17     clients. Each client runs tests in parallel.
18
19     Limitations:
20     Tests must have a .t suffix. Tests with duplicate names will
21     overwrite each other, so only the last one will run.
22
23     For example::
24
25         tasks:
26         - ceph:
27         - cram:
28             clients:
29               client.0:
30               - http://download.ceph.com/qa/test.t
31               - http://download.ceph.com/qa/test2.t]
32               client.1: [http://download.ceph.com/qa/test.t]
33             branch: foo
34
35     You can also run a list of cram tests on all clients::
36
37         tasks:
38         - ceph:
39         - cram:
40             clients:
41               all: [http://download.ceph.com/qa/test.t]
42
43     :param ctx: Context
44     :param config: Configuration
45     """
46     assert isinstance(config, dict)
47     assert 'clients' in config and isinstance(config['clients'], dict), \
48            'configuration must contain a dictionary of clients'
49
50     clients = teuthology.replace_all_with_clients(ctx.cluster,
51                                                   config['clients'])
52     testdir = teuthology.get_testdir(ctx)
53
54     overrides = ctx.config.get('overrides', {})
55     teuthology.deep_merge(config, overrides.get('workunit', {}))
56
57     refspec = config.get('branch')
58     if refspec is None:
59         refspec = config.get('tag')
60     if refspec is None:
61         refspec = config.get('sha1')
62     if refspec is None:
63         refspec = 'HEAD'
64
65     # hack: the git_url is always ceph-ci or ceph
66     git_url = teuth_config.get_ceph_git_url()
67     repo_name = 'ceph.git'
68     if git_url.count('ceph-ci'):
69         repo_name = 'ceph-ci.git'
70
71     try:
72         for client, tests in clients.iteritems():
73             (remote,) = ctx.cluster.only(client).remotes.iterkeys()
74             client_dir = '{tdir}/archive/cram.{role}'.format(tdir=testdir, role=client)
75             remote.run(
76                 args=[
77                     'mkdir', '--', client_dir,
78                     run.Raw('&&'),
79                     'virtualenv', '{tdir}/virtualenv'.format(tdir=testdir),
80                     run.Raw('&&'),
81                     '{tdir}/virtualenv/bin/pip'.format(tdir=testdir),
82                     'install', 'cram==0.6',
83                     ],
84                 )
85             for test in tests:
86                 url = test.format(repo=repo_name, branch=refspec)
87                 log.info('fetching test %s for %s', url, client)
88                 assert test.endswith('.t'), 'tests must end in .t'
89                 remote.run(
90                     args=[
91                         'wget', '-nc', '-nv', '-P', client_dir, '--', url,
92                         ],
93                     )
94
95         with parallel() as p:
96             for role in clients.iterkeys():
97                 p.spawn(_run_tests, ctx, role)
98     finally:
99         for client, tests in clients.iteritems():
100             (remote,) = ctx.cluster.only(client).remotes.iterkeys()
101             client_dir = '{tdir}/archive/cram.{role}'.format(tdir=testdir, role=client)
102             test_files = set([test.rsplit('/', 1)[1] for test in tests])
103
104             # remove test files unless they failed
105             for test_file in test_files:
106                 abs_file = os.path.join(client_dir, test_file)
107                 remote.run(
108                     args=[
109                         'test', '-f', abs_file + '.err',
110                         run.Raw('||'),
111                         'rm', '-f', '--', abs_file,
112                         ],
113                     )
114
115             # ignore failure since more than one client may
116             # be run on a host, and the client dir should be
117             # non-empty if the test failed
118             remote.run(
119                 args=[
120                     'rm', '-rf', '--',
121                     '{tdir}/virtualenv'.format(tdir=testdir),
122                     run.Raw(';'),
123                     'rmdir', '--ignore-fail-on-non-empty', client_dir,
124                     ],
125                 )
126
127 def _run_tests(ctx, role):
128     """
129     For each role, check to make sure it's a client, then run the cram on that client
130
131     :param ctx: Context
132     :param role: Roles
133     """
134     assert isinstance(role, basestring)
135     PREFIX = 'client.'
136     assert role.startswith(PREFIX)
137     id_ = role[len(PREFIX):]
138     (remote,) = ctx.cluster.only(role).remotes.iterkeys()
139     ceph_ref = ctx.summary.get('ceph-sha1', 'master')
140
141     testdir = teuthology.get_testdir(ctx)
142     log.info('Running tests for %s...', role)
143     remote.run(
144         args=[
145             run.Raw('CEPH_REF={ref}'.format(ref=ceph_ref)),
146             run.Raw('CEPH_ID="{id}"'.format(id=id_)),
147             'adjust-ulimits',
148             'ceph-coverage',
149             '{tdir}/archive/coverage'.format(tdir=testdir),
150             '{tdir}/virtualenv/bin/cram'.format(tdir=testdir),
151             '-v', '--',
152             run.Raw('{tdir}/archive/cram.{role}/*.t'.format(tdir=testdir, role=role)),
153             ],
154         logger=log.getChild(role),
155         )