os-testr/os_testr/regex_builder.py
Szymon Datko 96db91056a Fix regex builder
Currently when the blacklist_file and regex string is provided,
the constructed regex looks like '^((?!black1|black2|...).)*$regex'.
This is incorrect, as it will match nothing - some string
is expected after end of the line [denoted as $ in the regex].

The proper construction is like ^(?!black1|black2|...).*(regex).*$
This solves the issue with Tempest, where using blacklist for smoke
tests is not working now, as it leads into the issue described above.

Change-Id: Icdeb3c311f7eb414158aedb4c030494b419211c0
Closes-Bug: #1506215
Closes-Bug: #1595119
Closes-Bug: #1622722
Closes-Bug: #1669455
2017-11-24 16:59:10 +01:00

117 lines
3.6 KiB
Python

# Copyright 2016 Hewlett-Packard Development Company, L.P.
#
# 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 copy
import os
import subprocess
def _get_test_list(regex, env=None):
env = env or copy.deepcopy(os.environ)
testr_args = ['stestr', 'list']
if regex:
testr_args.append(regex)
proc = subprocess.Popen(testr_args, env=env,
stdout=subprocess.PIPE, universal_newlines=True)
out = proc.communicate()[0]
raw_test_list = out.split('\n')
bad = False
test_list = []
exclude_list = ['OS_', 'CAPTURE', 'TEST_TIMEOUT', 'PYTHON',
'subunit.run discover']
for line in raw_test_list:
for exclude in exclude_list:
if exclude in line or not line:
bad = True
break
if not bad:
test_list.append(line)
bad = False
return test_list
def print_skips(regex, message):
test_list = _get_test_list(regex)
if test_list:
if message:
print(message)
else:
print('Skipped because of regex %s:' % regex)
for test in test_list:
print(test)
# Extra whitespace to separate
print('\n')
def path_to_regex(path):
root, _ = os.path.splitext(path)
return root.replace('/', '.')
def get_regex_from_whitelist_file(file_path):
lines = []
with open(file_path) as white_file:
for line in white_file.read().splitlines():
split_line = line.strip().split('#')
# Before the # is the regex
line_regex = split_line[0].strip()
if line_regex:
lines.append(line_regex)
return '|'.join(lines)
def get_regex_from_blacklist_file(file_path, print_exclude=False):
exclude_regex = ''
with open(file_path, 'r') as black_file:
exclude_regex = ''
for line in black_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 = split_line[1].strip()
else:
comment = ''
if line_regex:
if print_exclude:
print_skips(line_regex, comment)
if exclude_regex:
exclude_regex = '|'.join([line_regex, exclude_regex])
else:
exclude_regex = line_regex
if exclude_regex:
exclude_regex = "(?!" + exclude_regex + ")"
return exclude_regex
def construct_regex(blacklist_file, whitelist_file, regex, print_exclude):
"""Deprecated, please use testlist_builder.construct_list instead."""
bregex = ''
wregex = ''
pregex = ''
if blacklist_file:
bregex = get_regex_from_blacklist_file(blacklist_file, print_exclude)
if whitelist_file:
wregex = get_regex_from_whitelist_file(whitelist_file)
if regex:
pregex = regex
combined_regex = '^%s.*(%s).*$' % (bregex, '|'.join(
filter(None, [pregex, wregex])
))
return combined_regex