]> git.proxmox.com Git - mirror_qemu.git/blob - tests/qemu-iotests/check
build: Remove --enable-gprof
[mirror_qemu.git] / tests / qemu-iotests / check
1 #!/usr/bin/env python3
2 #
3 # Configure environment and run group of tests in it.
4 #
5 # Copyright (c) 2020-2021 Virtuozzo International GmbH
6 #
7 # This program is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU General Public License as
9 # published by the Free Software Foundation.
10 #
11 # This program is distributed in the hope that it would be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19 import os
20 import sys
21 import argparse
22 import shutil
23 from pathlib import Path
24
25 from findtests import TestFinder
26 from testenv import TestEnv
27 from testrunner import TestRunner
28
29 def get_default_path(follow_link=False):
30 """
31 Try to automagically figure out the path we are running from.
32 """
33 # called from the build tree?
34 if os.path.islink(sys.argv[0]):
35 if follow_link:
36 return os.path.dirname(os.readlink(sys.argv[0]))
37 else:
38 return os.path.dirname(os.path.abspath(sys.argv[0]))
39 else: # or source tree?
40 return os.getcwd()
41
42 def make_argparser() -> argparse.ArgumentParser:
43 p = argparse.ArgumentParser(
44 description="Test run options",
45 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
46
47 p.add_argument('-n', '--dry-run', action='store_true',
48 help='show me, do not run tests')
49 p.add_argument('-j', dest='jobs', type=int, default=1,
50 help='run tests in multiple parallel jobs')
51
52 p.add_argument('-d', dest='debug', action='store_true', help='debug')
53 p.add_argument('-p', dest='print', action='store_true',
54 help='redirects qemu\'s stdout and stderr to '
55 'the test output')
56 p.add_argument('-gdb', action='store_true',
57 help="start gdbserver with $GDB_OPTIONS options "
58 "('localhost:12345' if $GDB_OPTIONS is empty)")
59 p.add_argument('-valgrind', action='store_true',
60 help='use valgrind, sets VALGRIND_QEMU environment '
61 'variable')
62
63 p.add_argument('-misalign', action='store_true',
64 help='misalign memory allocations')
65 p.add_argument('--color', choices=['on', 'off', 'auto'],
66 default='auto', help="use terminal colors. The default "
67 "'auto' value means use colors if terminal stdout detected")
68 p.add_argument('-tap', action='store_true',
69 help='produce TAP output')
70
71 g_env = p.add_argument_group('test environment options')
72 mg = g_env.add_mutually_exclusive_group()
73 # We don't set default for cachemode, as we need to distinguish default
74 # from user input later.
75 mg.add_argument('-nocache', dest='cachemode', action='store_const',
76 const='none', help='set cache mode "none" (O_DIRECT), '
77 'sets CACHEMODE environment variable')
78 mg.add_argument('-c', dest='cachemode',
79 help='sets CACHEMODE environment variable')
80
81 g_env.add_argument('-i', dest='aiomode', default='threads',
82 help='sets AIOMODE environment variable')
83
84 p.set_defaults(imgfmt='raw', imgproto='file')
85
86 format_list = ['raw', 'bochs', 'cloop', 'parallels', 'qcow', 'qcow2',
87 'qed', 'vdi', 'vpc', 'vhdx', 'vmdk', 'luks', 'dmg']
88 g_fmt = p.add_argument_group(
89 ' image format options',
90 'The following options set the IMGFMT environment variable. '
91 'At most one choice is allowed, default is "raw"')
92 mg = g_fmt.add_mutually_exclusive_group()
93 for fmt in format_list:
94 mg.add_argument('-' + fmt, dest='imgfmt', action='store_const',
95 const=fmt, help=f'test {fmt}')
96
97 protocol_list = ['file', 'rbd', 'nbd', 'ssh', 'nfs', 'fuse']
98 g_prt = p.add_argument_group(
99 ' image protocol options',
100 'The following options set the IMGPROTO environment variable. '
101 'At most one choice is allowed, default is "file"')
102 mg = g_prt.add_mutually_exclusive_group()
103 for prt in protocol_list:
104 mg.add_argument('-' + prt, dest='imgproto', action='store_const',
105 const=prt, help=f'test {prt}')
106
107 g_bash = p.add_argument_group('bash tests options',
108 'The following options are ignored by '
109 'python tests.')
110 # TODO: make support for the following options in iotests.py
111 g_bash.add_argument('-o', dest='imgopts',
112 help='options to pass to qemu-img create/convert, '
113 'sets IMGOPTS environment variable')
114
115 g_sel = p.add_argument_group('test selecting options',
116 'The following options specify test set '
117 'to run.')
118 g_sel.add_argument('-g', '--groups', metavar='group1,...',
119 help='include tests from these groups')
120 g_sel.add_argument('-x', '--exclude-groups', metavar='group1,...',
121 help='exclude tests from these groups')
122 g_sel.add_argument('--start-from', metavar='TEST',
123 help='Start from specified test: make sorted sequence '
124 'of tests as usual and then drop tests from the first '
125 'one to TEST (not inclusive). This may be used to '
126 'rerun failed ./check command, starting from the '
127 'middle of the process.')
128 g_sel.add_argument('tests', metavar='TEST_FILES', nargs='*',
129 help='tests to run, or "--" followed by a command')
130 g_sel.add_argument('--build-dir', default=get_default_path(),
131 help='Path to iotests build directory')
132 g_sel.add_argument('--source-dir',
133 default=get_default_path(follow_link=True),
134 help='Path to iotests build directory')
135
136 return p
137
138
139 if __name__ == '__main__':
140 args = make_argparser().parse_args()
141
142 env = TestEnv(source_dir=args.source_dir,
143 build_dir=args.build_dir,
144 imgfmt=args.imgfmt, imgproto=args.imgproto,
145 aiomode=args.aiomode, cachemode=args.cachemode,
146 imgopts=args.imgopts, misalign=args.misalign,
147 debug=args.debug, valgrind=args.valgrind,
148 gdb=args.gdb, qprint=args.print,
149 dry_run=args.dry_run)
150
151 if len(sys.argv) > 1 and sys.argv[-len(args.tests)-1] == '--':
152 if not args.tests:
153 sys.exit("missing command after '--'")
154 cmd = args.tests
155 env.print_env()
156 exec_pathstr = shutil.which(cmd[0])
157 if exec_pathstr is None:
158 sys.exit('command not found: ' + cmd[0])
159 exec_path = Path(exec_pathstr).resolve()
160 cmd[0] = str(exec_path)
161 full_env = env.prepare_subprocess(cmd)
162 os.chdir(exec_path.parent)
163 os.execve(cmd[0], cmd, full_env)
164
165 testfinder = TestFinder(test_dir=env.source_iotests)
166
167 groups = args.groups.split(',') if args.groups else None
168 x_groups = args.exclude_groups.split(',') if args.exclude_groups else None
169
170 group_local = os.path.join(env.source_iotests, 'group.local')
171 if os.path.isfile(group_local):
172 try:
173 testfinder.add_group_file(group_local)
174 except ValueError as e:
175 sys.exit(f"Failed to parse group file '{group_local}': {e}")
176
177 try:
178 tests = testfinder.find_tests(groups=groups, exclude_groups=x_groups,
179 tests=args.tests,
180 start_from=args.start_from)
181 if not tests:
182 raise ValueError('No tests selected')
183 except ValueError as e:
184 sys.exit(str(e))
185
186 if args.dry_run:
187 print('\n'.join([os.path.basename(t) for t in tests]))
188 else:
189 with TestRunner(env, tap=args.tap,
190 color=args.color) as tr:
191 paths = [os.path.join(env.source_iotests, t) for t in tests]
192 ok = tr.run_tests(paths, args.jobs)
193 if not ok:
194 sys.exit(1)