blob: 6db62438d424480c17dda8b5b61bfffe26fd4f41 [file] [log] [blame]
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import re
r' with(?:out)? \{[^\}]*\}')
class ConflictingPositiveFiltersException(Exception):
"""Raised when both filter file and filter argument have positive filters."""
def ParseFilterFile(input_lines):
"""Converts test filter file contents to positive and negative pattern lists.
See //testing/buildbot/filters/ for description of the
syntax that |input_lines| are expected to follow.
for description of the syntax that --gtest_filter argument should follow.
input_lines: An iterable (e.g. a list or a file) containing input lines.
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.
parser: an argparse.ArgumentParser instance.
# Deprecated argument.
# New argument.
help='Path to file that contains googletest-style filter strings. '
'See also //testing/buildbot/filters/')
filter_group = parser.add_mutually_exclusive_group()
'-f', '--test-filter', '--gtest_filter', '--gtest-filter',
help='googletest-style filter string.',
help='isolated script filter string. '
'Like gtest filter strings, but with :: separators instead of :')
def AppendPatternsToFilter(test_filter, positive_patterns=None,
"""Returns a test-filter string with additional patterns.
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]
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
test_filter: test-filter style string
return bool(len(test_filter) > 0 and test_filter[0] != '-')
def InitializeFilterFromArgs(args):
"""Returns a filter string from the command-line option values.
args: an argparse.Namespace instance resulting from a using parser
to which the filter options above were added.
ConflictingPositiveFiltersException if both filter file and command line
specify positive filters.
test_filter = ''
if args.isolated_script_test_filter:
args.test_filter = args.isolated_script_test_filter.replace('::', ':')
if args.test_filter:
test_filter = _CMDLINE_NAME_SEGMENT_RE.sub(
'', args.test_filter.replace('#', '.'))
if args.test_filter_file:
for test_filter_file in args.test_filter_file.split(';'):
with open(test_filter_file, 'r') as f:
positive_file_patterns, negative_file_patterns = ParseFilterFile(f)
if positive_file_patterns and HasPositivePatterns(test_filter):
raise ConflictingPositiveFiltersException(
'Cannot specify positive pattern in both filter file and ' +
'filter command line argument')
test_filter = AppendPatternsToFilter(
return test_filter