Source code for stestr.selection

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import contextlib
import re
import sys


[docs]def filter_tests(filters, test_ids): """Filter test_ids by the test_filters. :param list filters: A list of regex filters to apply to the test_ids. The output will contain any test_ids which have a re.search() match for any of the regexes in this list. If this is None all test_ids will be returned :param list test_ids: A list of test_ids that will be filtered :return: A list of test ids. """ if filters is None: return test_ids _filters = [] for f in filters: if isinstance(f, str): try: _filters.append(re.compile(f)) except re.error: print("Invalid regex: %s provided in filters" % f, file=sys.stderr) sys.exit(5) else: _filters.append(f) def include(test_id): for pred in _filters: if pred.search(test_id): return True return list(filter(include, test_ids))
def exclusion_reader(exclude_list): with contextlib.closing(open(exclude_list)) as exclude_file: regex_comment_lst = [] # tuple of (regex_compiled, msg, skipped_lst) for line in exclude_file: raw_line = line.strip() split_line = raw_line.split("#") # Before the # is the regex line_regex = split_line[0].strip() if len(split_line) > 1: # After the # is a comment comment = "".join(split_line[1:]).strip() else: comment = "Skipped because of regex %s:" % line_regex if not line_regex: continue try: regex_comment_lst.append((re.compile(line_regex), comment, [])) except re.error: print( "Invalid regex: %s in provided exclusion list file" % line_regex, file=sys.stderr, ) sys.exit(5) return regex_comment_lst def _get_regex_from_include_list(file_path): lines = [] for line in open(file_path).read().splitlines(): split_line = line.strip().split("#") # Before the # is the regex line_regex = split_line[0].strip() if line_regex: try: lines.append(re.compile(line_regex)) except re.error: print( "Invalid regex: %s in provided inclusion_list file" % line_regex, file=sys.stderr, ) sys.exit(5) return lines
[docs]def construct_list( test_ids, regexes=None, exclude_list=None, include_list=None, exclude_regex=None ): """Filters the discovered test cases :param list test_ids: The set of test_ids to be filtered :param list regexes: A list of regex filters to apply to the test_ids. The output will contain any test_ids which have a re.search() match for any of the regexes in this list. If this is None all test_ids will be returned :param str exclude_list: The path to an exclusion_list file :param str include_list: The path to an inclusion_list file :param str exclude_regex: regex pattern to exclude tests :return: iterable of strings. The strings are full test_ids :rtype: set """ if not regexes: regexes = None # handle the other false things safe_re = None if include_list: safe_re = _get_regex_from_include_list(include_list) if not regexes and safe_re: regexes = safe_re elif regexes and safe_re: regexes += safe_re if exclude_list: exclude_data = exclusion_reader(exclude_list) else: exclude_data = None if exclude_regex: msg = "Skipped because of regexp provided as a command line argument:" try: record = (re.compile(exclude_regex), msg, []) except re.error: print( "Invalid regex: %s used for exclude_regex" % exclude_regex, file=sys.stderr, ) sys.exit(5) if exclude_data: exclude_data.append(record) else: exclude_data = [record] list_of_test_cases = filter_tests(regexes, test_ids) set_of_test_cases = set(list_of_test_cases) if not exclude_data: return set_of_test_cases # NOTE(afazekas): We might use a faster logic when the # print option is not requested for (rex, msg, s_list) in exclude_data: for test_case in list_of_test_cases: if rex.search(test_case): # NOTE(mtreinish): In the case of overlapping regex the test # case might have already been removed from the set of tests if test_case in set_of_test_cases: set_of_test_cases.remove(test_case) s_list.append(test_case) return set_of_test_cases