blob: c532f324e175c14e70e922910a7b7d8611e8d1c4 [file] [log] [blame]
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import re
_CMDLINE_NAME_SEGMENT_RE = re.compile(
r' with(?:out)? \{[^\}]*\}')
def ParseFilterFile(input_lines):
"""Converts test filter file contents to positive and negative pattern lists.
See //testing/buildbot/filters/README.md for description of the
syntax that |input_lines| are expected to follow.
See
https://github.com/google/googletest/blob/main/docs/advanced.md#running-a-subset-of-the-tests
for description of the syntax that --gtest_filter argument should follow.
Args:
input_lines: An iterable (e.g. a list or a file) containing input lines.
Returns:
tuple containing the lists of positive patterns and negative patterns
"""
# Strip comments and whitespace from each line and filter non-empty lines.
stripped_lines = (l.split('#', 1)[0].strip() for l in input_lines)
filter_lines = [l for l in stripped_lines if l]
# Split the tests into positive and negative patterns (gtest treats
# every pattern after the first '-' sign as an exclusion).
positive_patterns = [l for l in filter_lines if l[0] != '-']
negative_patterns = [l[1:] for l in filter_lines if l[0] == '-']
return positive_patterns, negative_patterns
def AddFilterOptions(parser):
"""Adds filter command-line options to the provided parser.
Args:
parser: an argparse.ArgumentParser instance.
"""
parser.add_argument(
# Deprecated argument.
'--gtest-filter-file',
# New argument.
'--test-launcher-filter-file',
action='append',
dest='test_filter_files',
help='Path to file that contains googletest-style filter strings. '
'See also //testing/buildbot/filters/README.md.')
filter_group = parser.add_mutually_exclusive_group()
filter_group.add_argument('-f',
'--test-filter',
'--gtest_filter',
'--gtest-filter',
dest='test_filters',
action='append',
help='googletest-style filter string.',
default=os.environ.get('GTEST_FILTER'))
filter_group.add_argument(
'--isolated-script-test-filter',
action='append',
dest='isolated_script_test_filters',
help='isolated script filter string. '
'Like gtest filter strings, but with :: separators instead of :')
def AppendPatternsToFilter(test_filter, positive_patterns=None,
negative_patterns=None):
"""Returns a test-filter string with additional patterns.
Args:
test_filter: test filter string
positive_patterns: list of positive patterns to add to string
negative_patterns: list of negative patterns to add to string
"""
positives = []
negatives = []
positive = ''
negative = ''
split_filter = test_filter.split('-', 1)
if len(split_filter) == 1:
positive = split_filter[0]
else:
positive, negative = split_filter
positives += [f for f in positive.split(':') if f]
negatives += [f for f in negative.split(':') if f]
positives += positive_patterns if positive_patterns else []
negatives += negative_patterns if negative_patterns else []
final_filter = ':'.join([p.replace('#', '.') for p in positives])
if negatives:
final_filter += '-' + ':'.join([n.replace('#', '.') for n in negatives])
return final_filter
def HasPositivePatterns(test_filter):
"""Returns True if test_filter contains a positive pattern, else False
Args:
test_filter: test-filter style string
"""
return bool(len(test_filter) > 0 and test_filter[0] != '-')
def InitializeFiltersFromArgs(args):
"""Returns a filter string from the command-line option values.
Args:
args: an argparse.Namespace instance resulting from a using parser
to which the filter options above were added.
"""
test_filters = []
if args.isolated_script_test_filters:
args.test_filters = [
isolated_script_test_filter.replace('::', ':')
for isolated_script_test_filter in args.isolated_script_test_filters
]
if args.test_filters:
for filt in args.test_filters:
test_filters.append(
_CMDLINE_NAME_SEGMENT_RE.sub('', filt.replace('#', '.')))
if not args.test_filter_files:
return test_filters
# At this point it's potentially several files, in a list and ; separated
for test_filter_files in args.test_filter_files:
# At this point it's potentially several files, ; separated
for test_filter_file in test_filter_files.split(';'):
# At this point it's individual files
with open(test_filter_file, 'r') as f:
positive_patterns, negative_patterns = ParseFilterFile(f)
filter_string = AppendPatternsToFilter('', positive_patterns,
negative_patterns)
test_filters.append(filter_string)
return test_filters