qemu/tests/qemu-iotests/check
Emanuele Giuseppe Esposito a9b4c6bb64 qemu-iotests: extend the check script to prepare supporting valgrind for python tests
Currently, the check script only parses the option and sets the
VALGRIND_QEMU environmental variable to "y".
Add another local python variable that prepares the command line,
identical to the one provided in the test scripts.

Because the python script does not know in advance the valgrind
PID to assign to the log file name, use the "%p" flag in valgrind
log file name that automatically puts the process PID at runtime.

Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20210809090114.64834-11-eesposit@redhat.com>
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
2021-09-01 12:57:31 +02:00

168 lines
7.0 KiB
Python
Executable File

#!/usr/bin/env python3
#
# Configure environment and run group of tests in it.
#
# Copyright (c) 2020-2021 Virtuozzo International GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it would be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import sys
import argparse
import shutil
from pathlib import Path
from findtests import TestFinder
from testenv import TestEnv
from testrunner import TestRunner
def make_argparser() -> argparse.ArgumentParser:
p = argparse.ArgumentParser(description="Test run options")
p.add_argument('-n', '--dry-run', action='store_true',
help='show me, do not run tests')
p.add_argument('-makecheck', action='store_true',
help='pretty print output for make check')
p.add_argument('-d', dest='debug', action='store_true', help='debug')
p.add_argument('-gdb', action='store_true',
help="start gdbserver with $GDB_OPTIONS options \
('localhost:12345' if $GDB_OPTIONS is empty)")
p.add_argument('-valgrind', action='store_true',
help='use valgrind, sets VALGRIND_QEMU environment '
'variable')
p.add_argument('-misalign', action='store_true',
help='misalign memory allocations')
p.add_argument('--color', choices=['on', 'off', 'auto'],
default='auto', help="use terminal colors. The default "
"'auto' value means use colors if terminal stdout detected")
g_env = p.add_argument_group('test environment options')
mg = g_env.add_mutually_exclusive_group()
# We don't set default for cachemode, as we need to distinguish default
# from user input later.
mg.add_argument('-nocache', dest='cachemode', action='store_const',
const='none', help='set cache mode "none" (O_DIRECT), '
'sets CACHEMODE environment variable')
mg.add_argument('-c', dest='cachemode',
help='sets CACHEMODE environment variable')
g_env.add_argument('-i', dest='aiomode', default='threads',
help='sets AIOMODE environment variable')
p.set_defaults(imgfmt='raw', imgproto='file')
format_list = ['raw', 'bochs', 'cloop', 'parallels', 'qcow', 'qcow2',
'qed', 'vdi', 'vpc', 'vhdx', 'vmdk', 'luks', 'dmg']
g_fmt = p.add_argument_group(
' image format options',
'The following options set the IMGFMT environment variable. '
'At most one choice is allowed, default is "raw"')
mg = g_fmt.add_mutually_exclusive_group()
for fmt in format_list:
mg.add_argument('-' + fmt, dest='imgfmt', action='store_const',
const=fmt, help=f'test {fmt}')
protocol_list = ['file', 'rbd', 'nbd', 'ssh', 'nfs', 'fuse']
g_prt = p.add_argument_group(
' image protocol options',
'The following options set the IMGPROTO environment variable. '
'At most one choice is allowed, default is "file"')
mg = g_prt.add_mutually_exclusive_group()
for prt in protocol_list:
mg.add_argument('-' + prt, dest='imgproto', action='store_const',
const=prt, help=f'test {prt}')
g_bash = p.add_argument_group('bash tests options',
'The following options are ignored by '
'python tests.')
# TODO: make support for the following options in iotests.py
g_bash.add_argument('-o', dest='imgopts',
help='options to pass to qemu-img create/convert, '
'sets IMGOPTS environment variable')
g_sel = p.add_argument_group('test selecting options',
'The following options specify test set '
'to run.')
g_sel.add_argument('-g', '--groups', metavar='group1,...',
help='include tests from these groups')
g_sel.add_argument('-x', '--exclude-groups', metavar='group1,...',
help='exclude tests from these groups')
g_sel.add_argument('--start-from', metavar='TEST',
help='Start from specified test: make sorted sequence '
'of tests as usual and then drop tests from the first '
'one to TEST (not inclusive). This may be used to '
'rerun failed ./check command, starting from the '
'middle of the process.')
g_sel.add_argument('tests', metavar='TEST_FILES', nargs='*',
help='tests to run, or "--" followed by a command')
return p
if __name__ == '__main__':
args = make_argparser().parse_args()
env = TestEnv(imgfmt=args.imgfmt, imgproto=args.imgproto,
aiomode=args.aiomode, cachemode=args.cachemode,
imgopts=args.imgopts, misalign=args.misalign,
debug=args.debug, valgrind=args.valgrind,
gdb=args.gdb)
if len(sys.argv) > 1 and sys.argv[-len(args.tests)-1] == '--':
if not args.tests:
sys.exit("missing command after '--'")
cmd = args.tests
env.print_env()
exec_pathstr = shutil.which(cmd[0])
if exec_pathstr is None:
sys.exit('command not found: ' + cmd[0])
exec_path = Path(exec_pathstr).resolve()
cmd[0] = str(exec_path)
full_env = env.prepare_subprocess(cmd)
os.chdir(exec_path.parent)
os.execve(cmd[0], cmd, full_env)
testfinder = TestFinder(test_dir=env.source_iotests)
groups = args.groups.split(',') if args.groups else None
x_groups = args.exclude_groups.split(',') if args.exclude_groups else None
group_local = os.path.join(env.source_iotests, 'group.local')
if os.path.isfile(group_local):
try:
testfinder.add_group_file(group_local)
except ValueError as e:
sys.exit(f"Failed to parse group file '{group_local}': {e}")
try:
tests = testfinder.find_tests(groups=groups, exclude_groups=x_groups,
tests=args.tests,
start_from=args.start_from)
if not tests:
raise ValueError('No tests selected')
except ValueError as e:
sys.exit(e)
if args.dry_run:
print('\n'.join(tests))
else:
with TestRunner(env, makecheck=args.makecheck,
color=args.color) as tr:
paths = [os.path.join(env.source_iotests, t) for t in tests]
ok = tr.run_tests(paths)
if not ok:
sys.exit(1)