blob: 885d19f7cd8dc2109b7477d920af09e6d35e9e13 [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.
"""Utility functions for processing test names."""
import re
# Regular expression used to get the suite name of a normalized gtest name.
GTEST_REGEX = re.compile(r'^([a-zA-Z_]\w*)\.[a-zA-Z_]\w*$')
# Used to identify the prefix in gtests.
_GTEST_PREFIXES = ['PRE_', '*']
# Regular expressions to identify parameterized gtests. Note that instantiation
# names can be empty. For example: ColorSpaceTest.testNullTransform/1.
_VALUE_PARAMETERIZED_GTESTS_REGEX = re.compile(
r'^([\w\*]+/)?(\w+\.\w+)/[\w\*]+$')
_TYPE_PARAMETERIZED_GTESTS_REGEX = re.compile(
r'^([\w\*]+/)?(\w+)/[\w\*]+\.(\w+)$')
# Regular expression for a blink_web_test name.
_LAYOUT_TEST_NAME_PATTERN = re.compile(r'^(([^/]+/)+[^/]+\.[a-zA-Z]+).*$')
_VIRTUAL_LAYOUT_TEST_NAME_PATTERN = re.compile(r'^virtual/[^/]+/(.*)$')
# Regular expression used to get the suite name of a normalized java test name.
_JAVA_TEST_REGEX = re.compile(r'(?:[a-zA-Z_]\w*\.)*([a-zA-Z_]\w*)#[a-zA-Z_]\w+')
def RemoveParametersFromGTestName(test_name):
"""Removes parameters from parameterized gtest names.
There are two types of parameterized gtest: value-parameterized tests and
type-paramerized tests, and for example:
value-parameterized:
'A/ColorSpaceTest.testNullTransform/11'
type-parameterized:
'1/GLES2DecoderPassthroughFixedCommandTest/5.InvalidCommand'
After removing the parameters, the examples become
'ColorSpaceTest.testNullTransform' and
'GLES2DecoderPassthroughFixedCommandTest.InvalidCommand' respectively.
For more information of parameterized gtests, please refer to:
https://github.com/google/googletest/blob/master/googletest/docs/
AdvancedGuide.md
"""
value_match = _VALUE_PARAMETERIZED_GTESTS_REGEX.match(test_name)
if value_match:
return value_match.group(2)
type_match = _TYPE_PARAMETERIZED_GTESTS_REGEX.match(test_name)
if type_match:
return type_match.group(2) + '.' + type_match.group(3)
return test_name
def ReplaceParametersFromGtestNameWithMask(test_name):
"""Replaces the parameters parts of gtest names with mask: '*'.
This method works the same way as |RemoveParametersFromGTestName| except that
the parameters parts are replaced with '*' instead of being removed. For
example, 'A/suite.test/8' -> '*/suite.test/*'.
Args:
test_name: Original test names, may contain parameters.
Returns:
A test name with parameters being replaced with '*'.
"""
value_match = _VALUE_PARAMETERIZED_GTESTS_REGEX.match(test_name)
if value_match:
suite_test = value_match.group(2)
prefix_mask = '*/' if value_match.group(1) else ''
return '%s%s/*' % (prefix_mask, suite_test)
type_match = _TYPE_PARAMETERIZED_GTESTS_REGEX.match(test_name)
if type_match:
suite = type_match.group(2)
test = type_match.group(3)
prefix_mask = '*/' if type_match.group(1) else ''
return '%s%s/*.%s' % (prefix_mask, suite, test)
return test_name
def RemoveAllPrefixesFromGTestName(test):
"""Removes prefixes from test names.
Args:
test (str): A test's name, eg: 'suite1.PRE_test1'.
Returns:
base_test (str): A base test name, eg: 'suite1.test1'.
"""
test_name_start = max(test.find('.'), 0)
if test_name_start == 0:
return test
test_suite = test[:test_name_start]
test_name = test[test_name_start + 1:]
for prefix in _GTEST_PREFIXES:
while test_name.startswith(prefix):
test_name = test_name[len(prefix):]
base_test = '%s.%s' % (test_suite, test_name)
return base_test
def ReplaceAllPrefixesFromGtestNameWithMask(test_name):
"""Replaces the prefixes parts of gtest names with mask: '*'.
This method works the same way as |RemoveAllPrefixesFromGTestName| except that
the prefixes parts are replaced with '*' instead of being removed. For
example, 'suite.PRE_PRE_test' -> 'suite.*test'.
Args:
test_name: Original test names, may contain parameters.
Returns:
A test name with prefixes being replaced with '*'.
"""
test_name_without_prefixes = RemoveAllPrefixesFromGTestName(test_name)
if test_name_without_prefixes == test_name:
return test_name
suite = test_name_without_prefixes.split('.')[0]
test = test_name_without_prefixes.split('.')[1]
return '%s.*%s' % (suite, test)
def RemoveSuffixFromBlinkWebTestName(test_name):
"""Removes suffix part from blink_web_test names if applicable.
For example, 'external/wpt/editing/run/delete.html?1001-2000' should become
'external/wpt/editing/run/delete.html' after removing the queries.
Args:
test_name: Name of the test to be processed.
Returns:
A string representing the name after removing suffix.
"""
match = _LAYOUT_TEST_NAME_PATTERN.match(test_name)
if match:
return match.group(1)
return test_name
def ReplaceSuffixFromBlinkWebTestNameWithMask(test_name):
"""Replaces the suffix parts of blink_web_test names with mask: '*'.
This method works the same way as |RemoveSuffixFromBlinkWebTestName|
except that the suffix parts are replaced with '*' instead of being removed.
For example, 'external/delete.html?1001-2000' -> 'external/delete.html?*'.
Args:
test_name: Original test names, may contain suffixes.
Returns:
A test name with suffixes being replaced with '*'.
"""
test_name_without_suffixes = RemoveSuffixFromBlinkWebTestName(test_name)
if test_name_without_suffixes == test_name:
return test_name
return '%s?*' % test_name_without_suffixes
def RemoveVirtualLayersFromBlinkWebTestName(test_name):
"""Removes virtual layers from blink_web_test names if applicable.
For example, 'virtual/abc/def/g.html' should become 'def/g.html' after
removing the layers.
Args:
test_name: Name of the test to be processed.
Returns:
A string representing the name after removing virtual layers.
"""
match = _VIRTUAL_LAYOUT_TEST_NAME_PATTERN.match(test_name)
if match:
return match.group(1)
return test_name
def GetTestSuiteName(normalized_test_name, step_ui_name):
"""Returns the test suite name of the given test in the given test step.
Assumption:
* All gtests are in suite.test format, while other tests are not.
* All webkit layout tests are in path/to/file.html format.
* All Java tests are in package.path.to.ClassName#testCase format.
Currently, only supports these three types, for other type of tests,
returns None.
Args:
normalized_test_name: A normalized test name.
Returns:
The test suite name if it's gtest/layout test/java test, otherwise None.
"""
# TODO(crbug.com/1050188): remove 'webkit_layout_tests' after 2 weeks from the
# step rename is completed.
# For blink_web_tests, the suite name is the immediate directory.
if 'webkit_layout_tests' in step_ui_name or 'blink_web_tests' in step_ui_name:
index = normalized_test_name.rfind('/')
if index > 0:
return normalized_test_name[:index]
return None
# For gtests, the suite name is the class name.
gtest_match = GTEST_REGEX.match(normalized_test_name)
if gtest_match:
return gtest_match.group(1)
# For Java tests, the suite name is the class name.
java_match = _JAVA_TEST_REGEX.match(normalized_test_name)
if java_match:
return java_match.group(1)
return None