Add whitelist file support

A whitelist files allows the user to specify a list of regexes
that ostestr will expand and run. It is mutually exclusive with
blacklist, but not mutually exclusive with --regex/path.
The value of --regex/path is appended to the whitelist.

Co-Authored-By: Davanum Srinivas <davanum@gmail.com>
Change-Id: Ic397212ef3127c176a5870676f67d8a5e0de0441
This commit is contained in:
Assaf Muller 2015-08-25 20:10:57 -04:00 committed by Davanum Srinivas
parent ba77bab8fb
commit 368a2553cd
2 changed files with 56 additions and 12 deletions

View File

@ -26,9 +26,14 @@ from testtools import run as testtools_run
def get_parser(args): def get_parser(args):
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description='Tool to run openstack tests') description='Tool to run openstack tests')
parser.add_argument('--blacklist_file', '-b', list_files = parser.add_mutually_exclusive_group()
help='Path to a blacklist file, this file contains a' list_files.add_argument('--blacklist_file', '-b',
' separate regex exclude on each newline') help='Path to a blacklist file, this file '
'contains a separate regex exclude on each '
'newline')
list_files.add_argument('--whitelist_file', '-w',
help='Path to a whitelist file, this file '
'contains a separate regex on each newline.')
group = parser.add_mutually_exclusive_group() group = parser.add_mutually_exclusive_group()
group.add_argument('--regex', '-r', group.add_argument('--regex', '-r',
help='A normal testr selection regex. If a blacklist ' help='A normal testr selection regex. If a blacklist '
@ -124,7 +129,11 @@ def path_to_regex(path):
return root.replace('/', '.') return root.replace('/', '.')
def construct_regex(blacklist_file, regex, print_exclude): def get_regex_from_whitelist_file(file_path):
return '|'.join(open(file_path).read().splitlines())
def construct_regex(blacklist_file, whitelist_file, regex, print_exclude):
if not blacklist_file: if not blacklist_file:
exclude_regex = '' exclude_regex = ''
else: else:
@ -148,6 +157,8 @@ def construct_regex(blacklist_file, regex, print_exclude):
exclude_regex = "(?!.*" + exclude_regex + ")" exclude_regex = "(?!.*" + exclude_regex + ")"
if regex: if regex:
exclude_regex += regex exclude_regex += regex
if whitelist_file:
exclude_regex += '%s' % get_regex_from_whitelist_file(whitelist_file)
return exclude_regex return exclude_regex
@ -280,7 +291,9 @@ def main():
regex = path_to_regex(opts.path) regex = path_to_regex(opts.path)
else: else:
regex = opts.regex regex = opts.regex
exclude_regex = construct_regex(opts.blacklist_file, regex, exclude_regex = construct_regex(opts.blacklist_file,
opts.whitelist_file,
regex,
opts.print_exclude) opts.print_exclude)
exit(_select_and_call_runner(opts, exclude_regex)) exit(_select_and_call_runner(opts, exclude_regex))

View File

@ -129,7 +129,7 @@ class TestCallers(base.TestCase):
class TestConstructRegex(base.TestCase): class TestConstructRegex(base.TestCase):
def test_regex_passthrough(self): def test_regex_passthrough(self):
result = os_testr.construct_regex(None, 'fake_regex', False) result = os_testr.construct_regex(None, None, 'fake_regex', False)
self.assertEqual(result, 'fake_regex') self.assertEqual(result, 'fake_regex')
def test_blacklist_regex_with_comments(self): def test_blacklist_regex_with_comments(self):
@ -139,7 +139,7 @@ class TestConstructRegex(base.TestCase):
blacklist_file.seek(0) blacklist_file.seek(0)
with mock.patch('six.moves.builtins.open', with mock.patch('six.moves.builtins.open',
return_value=blacklist_file): return_value=blacklist_file):
result = os_testr.construct_regex('fake_path', None, False) result = os_testr.construct_regex('fake_path', None, None, False)
self.assertEqual( self.assertEqual(
result, result,
"(?!.*fake_regex_3|fake_regex_2|fake_regex_1|fake_regex_0|)") "(?!.*fake_regex_3|fake_regex_2|fake_regex_1|fake_regex_0|)")
@ -151,7 +151,7 @@ class TestConstructRegex(base.TestCase):
blacklist_file.seek(0) blacklist_file.seek(0)
with mock.patch('six.moves.builtins.open', with mock.patch('six.moves.builtins.open',
return_value=blacklist_file): return_value=blacklist_file):
result = os_testr.construct_regex('fake_path', None, False) result = os_testr.construct_regex('fake_path', None, None, False)
self.assertEqual( self.assertEqual(
result, result,
"(?!.*fake_regex_3|fake_regex_2|fake_regex_1|fake_regex_0|)") "(?!.*fake_regex_3|fake_regex_2|fake_regex_1|fake_regex_0|)")
@ -163,7 +163,8 @@ class TestConstructRegex(base.TestCase):
blacklist_file.seek(0) blacklist_file.seek(0)
with mock.patch('six.moves.builtins.open', with mock.patch('six.moves.builtins.open',
return_value=blacklist_file): return_value=blacklist_file):
result = os_testr.construct_regex('fake_path', 'fake_regex', False) result = os_testr.construct_regex('fake_path', None,
'fake_regex', False)
expected_regex = ("(?!.*fake_regex_3|fake_regex_2|fake_regex_1|" expected_regex = ("(?!.*fake_regex_3|fake_regex_2|fake_regex_1|"
"fake_regex_0|)fake_regex") "fake_regex_0|)fake_regex")
@ -176,7 +177,8 @@ class TestConstructRegex(base.TestCase):
blacklist_file.seek(0) blacklist_file.seek(0)
with mock.patch('six.moves.builtins.open', with mock.patch('six.moves.builtins.open',
return_value=blacklist_file): return_value=blacklist_file):
result = os_testr.construct_regex('fake_path', 'fake_regex', False) result = os_testr.construct_regex('fake_path', None,
'fake_regex', False)
expected_regex = ("(?!.*fake_regex_3|fake_regex_2|fake_regex_1|" expected_regex = ("(?!.*fake_regex_3|fake_regex_2|fake_regex_1|"
"fake_regex_0|)fake_regex") "fake_regex_0|)fake_regex")
@ -190,7 +192,8 @@ class TestConstructRegex(base.TestCase):
blacklist_file.seek(0) blacklist_file.seek(0)
with mock.patch('six.moves.builtins.open', with mock.patch('six.moves.builtins.open',
return_value=blacklist_file): return_value=blacklist_file):
result = os_testr.construct_regex('fake_path', None, True) result = os_testr.construct_regex('fake_path', None,
None, True)
expected_regex = ("(?!.*fake_regex_3|fake_regex_2|fake_regex_1|" expected_regex = ("(?!.*fake_regex_3|fake_regex_2|fake_regex_1|"
"fake_regex_0|)") "fake_regex_0|)")
@ -211,7 +214,8 @@ class TestConstructRegex(base.TestCase):
blacklist_file.seek(0) blacklist_file.seek(0)
with mock.patch('six.moves.builtins.open', with mock.patch('six.moves.builtins.open',
return_value=blacklist_file): return_value=blacklist_file):
result = os_testr.construct_regex('fake_path', None, True) result = os_testr.construct_regex('fake_path', None,
None, True)
expected_regex = ("(?!.*fake_regex_3|fake_regex_2|fake_regex_1|" expected_regex = ("(?!.*fake_regex_3|fake_regex_2|fake_regex_1|"
"fake_regex_0|)") "fake_regex_0|)")
@ -223,3 +227,30 @@ class TestConstructRegex(base.TestCase):
self.assertIn(('fake_regex_1', ''), args) self.assertIn(('fake_regex_1', ''), args)
self.assertIn(('fake_regex_2', ''), args) self.assertIn(('fake_regex_2', ''), args)
self.assertIn(('fake_regex_3', ''), args) self.assertIn(('fake_regex_3', ''), args)
class TestWhitelistFile(base.TestCase):
def test_read_whitelist_file(self):
file_contents = """regex_a
regex_b"""
whitelist_file = six.StringIO()
whitelist_file.write(file_contents)
whitelist_file.seek(0)
with mock.patch('six.moves.builtins.open',
return_value=whitelist_file):
regex = os_testr.get_regex_from_whitelist_file('/path/to/not_used')
self.assertEqual('regex_a|regex_b', regex)
def test_whitelist_regex_without_comments_and_regex(self):
file_contents = """regex_a
regex_b"""
whitelist_file = six.StringIO()
whitelist_file.write(file_contents)
whitelist_file.seek(0)
with mock.patch('six.moves.builtins.open',
return_value=whitelist_file):
result = os_testr.construct_regex(None, 'fake_path',
None, False)
expected_regex = 'regex_a|regex_b'
self.assertEqual(result, expected_regex)