freeipa/ipatests/ipa-run-tests
Alexander Bokovoy 6a2c356da0 ipa-run-tests: add support of globs for test targets and ignores
ipa-run-tests expands arguments passed with their full paths. However,
it doesn't support expanding globs, so targets like 'test_ipa*' cannot
be specified.

Expand the code that replaces '--ignore foo' and 'foo' positional
arguments with support for '--ignore foo*' and 'foo*'.

This allows to reduce a number of additional steps in the CI pipeline
preparation.

Reviewed-By: Christian Heimes <cheimes@redhat.com>
2019-05-28 09:55:51 +03:00

123 lines
4.7 KiB
Python
Executable File

#!/usr/bin/python3
# Authors:
# Petr Viktorin <pviktori@redhat.com>
# Jason Gerard DeRose <jderose@redhat.com>
#
# Copyright (C) 2008-2013 Red Hat
# see file 'COPYING' for use and warranty information
#
# 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, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will 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/>.
"""Pytest wrapper for running an installed (not in-tree) IPA test suite
Any command-line arguments are passed directly to py.test.
The current directory is changed to the locaition of the ipatests package,
so any relative paths given will be based on the ipatests module's path
"""
import os
import copy
import sys
import glob
import pytest
import ipatests
# This is set to store --with-xunit report in an accessible place:
os.environ['IPATEST_XUNIT_PATH'] = os.path.join(os.getcwd(), 'nosetests.xml')
HERE = os.path.dirname(os.path.abspath(ipatests.__file__))
class ArgsManglePlugin(object):
"""Modify pytest arguments
* Add confcutdir if hasn't been set already
* Mangle paths to support tests both relative to basedir and ipatests/
* Default to ipatests/ if no tests are specified
"""
def pytest_load_initial_conftests(self, early_config, parser, args):
# During initial loading, parser supports only basic options
ns = early_config.known_args_namespace
if not ns.confcutdir:
# add config cut directory to only load fixtures from ipatests/
args.insert(0, '--confcutdir={}'.format(HERE))
if not ns.file_or_dir:
# No file or directory found, run all tests
args.append(HERE)
else:
vargs = []
for name in ns.file_or_dir:
idx = args.index(name)
# split on pytest separator
# ipatests/test_ipaplatform/test_importhook.py::test_override
filename, sep, suffix = name.partition('::')
# a file or directory relative to cwd or already absolute
if os.path.exists(filename):
continue
if '*' in filename:
# Expand a glob, we'll flatten the list later
paths = glob.glob(os.path.join(HERE, filename))
vargs.append([idx, paths])
else:
# a file or directory relative to ipatests package
args[idx] = sep.join((os.path.join(HERE, filename), suffix))
# flatten and insert all expanded file names
base = 0
for idx, items in vargs:
args.pop(base + idx)
for item in items:
args.insert(base + idx, item)
base += len(items)
# replace ignores, e.g. "--ignore test_integration" is changed to
# "--ignore path/to/ipatests/test_integration"
if ns.ignore:
vargs = []
for ignore in ns.ignore:
idx = args.index(ignore)
if os.path.exists(ignore):
continue
if '*' in ignore:
# expand a glob, we'll flatten the list later
paths = glob.glob(os.path.join(HERE, ignore))
vargs.append([idx, paths])
else:
args[idx] = os.path.join(HERE, ignore)
# flatten and insert all expanded file names
base = 0
for idx, items in vargs:
# since we are expanding, remove old pair
# --ignore and old file name
args.pop(base + idx)
args.pop(base + idx)
for item in items:
# careful: we need to add a pair
# --ignore and new filename
args.insert(base + idx, '--ignore')
args.insert(base + idx, item)
base += len(items) * 2 - 1
# rebuild early_config's known args with new args. The known args
# are used for initial conftest.py from ipatests, which adds
# additional arguments.
early_config.known_args_namespace = parser.parse_known_args(
args, namespace=copy.copy(early_config.option))
sys.exit(pytest.main(plugins=[ArgsManglePlugin()]))