31"""Unit test for Google Test test filters.
33A user can specify which test(s) in a Google Test program to run via either
34the GTEST_FILTER environment variable or the --gtest_filter flag.
35This script tests such functionality by invoking
36googletest-filter-unittest_ (a program written with Google Test) with different
37environments and command line flags.
39Note that test sharding may also influence which tests are filtered. Therefore,
40we test that here also.
46 from sets
import Set
as set
50import gtest_test_utils
59CAN_PASS_EMPTY_ENV =
False
61 os.environ[
'EMPTY_VAR'] =
''
63 [sys.executable,
'-c',
'import os; print(\'EMPTY_VAR\' in os.environ)'])
64 CAN_PASS_EMPTY_ENV = eval(child.output)
75 os.environ[
'UNSET_VAR'] =
'X'
76 del os.environ[
'UNSET_VAR']
78 [sys.executable,
'-c',
'import os; print(\'UNSET_VAR\' not in os.environ)'
80 CAN_UNSET_ENV = eval(child.output)
87CAN_TEST_EMPTY_FILTER = (CAN_PASS_EMPTY_ENV
and CAN_UNSET_ENV)
91FILTER_ENV_VAR =
'GTEST_FILTER'
94TOTAL_SHARDS_ENV_VAR =
'GTEST_TOTAL_SHARDS'
95SHARD_INDEX_ENV_VAR =
'GTEST_SHARD_INDEX'
96SHARD_STATUS_FILE_ENV_VAR =
'GTEST_SHARD_STATUS_FILE'
99FILTER_FLAG =
'gtest_filter'
102ALSO_RUN_DISABLED_TESTS_FLAG =
'gtest_also_run_disabled_tests'
108PARAM_TEST_REGEX = re.compile(
r'/ParamTest')
111TEST_CASE_REGEX = re.compile(
r'^\[\-+\] \d+ tests? from (\w+(/\w+)?)')
114TEST_REGEX = re.compile(
r'^\[\s*RUN\s*\].*\.(\w+(/\w+)?)')
118LIST_TESTS_FLAG =
'--gtest_list_tests'
122 [COMMAND, LIST_TESTS_FLAG]).output
126 'SeqP/ParamTest.TestX/0',
127 'SeqP/ParamTest.TestX/1',
128 'SeqP/ParamTest.TestY/0',
129 'SeqP/ParamTest.TestY/1',
130 'SeqQ/ParamTest.TestX/0',
131 'SeqQ/ParamTest.TestX/1',
132 'SeqQ/ParamTest.TestY/0',
133 'SeqQ/ParamTest.TestY/1',
137 'BarTest.DISABLED_TestFour',
138 'BarTest.DISABLED_TestFive',
139 'BazTest.DISABLED_TestC',
140 'DISABLED_FoobarTest.Test1',
141 'DISABLED_FoobarTest.DISABLED_Test2',
142 'DISABLED_FoobarbazTest.TestA',
145if SUPPORTS_DEATH_TESTS:
147 'HasDeathTest.Test1',
148 'HasDeathTest.Test2',
165 ] + DEATH_TESTS + PARAM_TESTS
167param_tests_present =
None
171environ = os.environ.copy()
175 """Sets the env variable to 'value'; unsets it when 'value' is None."""
177 if value
is not None:
178 environ[env_var] = value
179 elif env_var
in environ:
184 """Runs the test program and returns its output."""
191 """Runs the test program and returns its exit code and a list of tests run."""
197 for line
in p.output.split(
'\n'):
198 match = TEST_CASE_REGEX.match(line)
199 if match
is not None:
200 test_case = match.group(1)
202 match = TEST_REGEX.match(line)
203 if match
is not None:
204 test = match.group(1)
205 tests_run.append(test_case +
'.' + test)
206 return (tests_run, p.exit_code)
210 """Runs the given function and arguments in a modified environment."""
212 original_env = environ.copy()
213 environ.update(extra_env)
214 return function(*args, **kwargs)
217 environ.update(original_env)
221 """Runs a test program shard and returns exit code and a list of tests run."""
223 extra_env = {SHARD_INDEX_ENV_VAR: str(shard_index),
224 TOTAL_SHARDS_ENV_VAR: str(total_shards)}
231 """Tests the env variable or the command line flag to filter tests."""
236 """Asserts that two sets are equal."""
239 self.assert_(elem
in rhs,
'%s in %s' % (elem, rhs))
242 self.assert_(elem
in lhs,
'%s in %s' % (elem, lhs))
245 """Asserts that list_of_sets is a valid partition of set_var."""
248 for slice_var
in list_of_sets:
249 full_partition.extend(slice_var)
250 self.assertEqual(len(set_var), len(full_partition))
251 self.assertEqual(
set(set_var),
set(full_partition))
254 """Adjust tests_to_run in case value parameterized tests are disabled."""
256 global param_tests_present
257 if not param_tests_present:
258 return list(
set(tests_to_run) -
set(PARAM_TESTS))
263 """Checks that the binary runs correct set of tests for a given filter."""
275 if CAN_TEST_EMPTY_FILTER
or gtest_filter !=
'':
284 if gtest_filter
is None:
287 args = [
'--%s=%s' % (FILTER_FLAG, gtest_filter)]
293 args=None, check_exit_0=False):
294 """Checks that binary runs correct tests for the given filter and shard.
296 Runs all shards of googletest-filter-unittest_ with the given filter,
and
297 verifies that the right set of tests were run. The union of tests run
298 on each shard should be identical to tests_to_run, without duplicates.
302 gtest_filter: A filter to apply to the tests.
303 total_shards: A total number of shards to split test run into.
304 tests_to_run: A set of tests expected to run.
305 args : Arguments to
pass to the to the test binary.
306 check_exit_0: When set to a true value, make sure that all shards
318 if CAN_TEST_EMPTY_FILTER
or gtest_filter !=
'':
321 for i
in range(0, total_shards):
324 self.assertEqual(0, exit_code)
325 partition.append(tests_run)
332 """Checks that the binary runs correct set of tests for the given filter.
334 Runs googletest-filter-unittest_ with the given filter,
and enables
335 disabled tests. Verifies that the right set of tests were run.
338 gtest_filter: A filter to apply to the tests.
339 tests_to_run: A set of tests expected to run.
345 args = [
'--%s' % ALSO_RUN_DISABLED_TESTS_FLAG]
346 if gtest_filter
is not None:
347 args.append(
'--%s=%s' % (FILTER_FLAG, gtest_filter))
353 """Sets up test case.
355 Determines whether value-parameterized tests are enabled in the binary
and
356 sets the flags accordingly.
359 global param_tests_present
360 if param_tests_present
is None:
361 param_tests_present = PARAM_TEST_REGEX.search(
365 """Tests the behavior of not specifying the filter."""
370 """Tests the behavior without the filter, with sharding enabled."""
379 """Tests an empty filter."""
386 """Tests a filter that matches nothing."""
392 """Tests filtering by full name."""
399 """Tests filters that match everything."""
408 """Tests filtering by test case name."""
410 self.
RunAndVerify(
'FooTest.*', [
'FooTest.Abc',
'FooTest.Xyz'])
412 BAZ_TESTS = [
'BazTest.TestOne',
'BazTest.TestA',
'BazTest.TestB']
415 BAZ_TESTS + [
'BazTest.DISABLED_TestC'])
418 """Tests filtering by test name."""
420 self.
RunAndVerify(
'*.TestOne', [
'BarTest.TestOne',
'BazTest.TestOne'])
423 """Select only the disabled tests to run."""
427 [
'DISABLED_FoobarTest.Test1'])
434 'BarTest.DISABLED_TestFour',
435 'BarTest.DISABLED_TestFive',
436 'BazTest.DISABLED_TestC',
437 'DISABLED_FoobarTest.DISABLED_Test2',
442 'DISABLED_FoobarTest.Test1',
443 'DISABLED_FoobarTest.DISABLED_Test2',
444 'DISABLED_FoobarbazTest.TestA',
448 """Tests using wildcard in the test case name."""
457 'BazTest.TestB', ] + DEATH_TESTS + PARAM_TESTS)
460 """Tests using wildcard in the test name."""
462 self.
RunAndVerify(
'*.*A*', [
'FooTest.Abc',
'BazTest.TestA'])
465 """Tests a filter that has no '.' in it."""
476 """Tests filters that consist of two patterns."""
486 self.
RunAndVerify(
':*A*', [
'FooTest.Abc',
'BazTest.TestA'])
489 """Tests filters that consist of three patterns."""
528 ] + DEATH_TESTS + PARAM_TESTS)
536 ] + DEATH_TESTS + PARAM_TESTS)
544 self.
RunAndVerify(
'-FooTest.Abc:FooTest.Xyz:BazTest.*', [
548 ] + DEATH_TESTS + PARAM_TESTS)
555 'SeqP/ParamTest.TestX/0',
556 'SeqP/ParamTest.TestX/1',
557 'SeqP/ParamTest.TestY/0',
558 'SeqP/ParamTest.TestY/1',
563 'SeqP/ParamTest.TestX/0',
564 'SeqP/ParamTest.TestY/0',
565 'SeqQ/ParamTest.TestX/0',
566 'SeqQ/ParamTest.TestY/0',
570 """Tests that the filter flag overrides the filtering env. variable."""
573 args = [
'--%s=%s' % (FILTER_FLAG,
'*One')]
577 self.
AssertSetEqual(tests_run, [
'BarTest.TestOne',
'BazTest.TestOne'])
580 """Tests that the shard file is created if specified in the environment."""
584 self.assert_(
not os.path.exists(shard_status_file))
586 extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file}
590 self.assert_(os.path.exists(shard_status_file))
591 os.remove(shard_status_file)
594 """Tests that the shard file is created with the "list_tests" flag."""
597 'shard_status_file2')
598 self.assert_(
not os.path.exists(shard_status_file))
600 extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file}
608 self.assert_(
'[==========]' not in output,
609 'Unexpected output during test enumeration.\n'
610 'Please ensure that LIST_TESTS_FLAG is assigned the\n'
611 'correct flag value for listing Google Test tests.')
613 self.assert_(os.path.exists(shard_status_file))
614 os.remove(shard_status_file)
616 if SUPPORTS_DEATH_TESTS:
618 """Tests integration with death tests and sharding."""
620 gtest_filter =
'HasDeathTest.*:SeqP/*'
622 'HasDeathTest.Test1',
623 'HasDeathTest.Test2',
625 'SeqP/ParamTest.TestX/0',
626 'SeqP/ParamTest.TestX/1',
627 'SeqP/ParamTest.TestY/0',
628 'SeqP/ParamTest.TestY/1',
631 for flag
in [
'--gtest_death_test_style=threadsafe',
632 '--gtest_death_test_style=fast']:
634 check_exit_0=
True, args=[flag])
636 check_exit_0=
True, args=[flag])
638if __name__ ==
'__main__':
def RunAndReturnOutput(args=None)
def RunAndExtractTestList(args=None)
def SetEnvVar(env_var, value)
def RunWithSharding(total_shards, shard_index, command)
def InvokeWithModifiedEnv(extra_env, function, *args, **kwargs)
def GetTestExecutablePath(executable_name, build_dir=None)
def AdjustForParameterizedTests(self, tests_to_run)
def testFilterWithoutDot(self)
def testFlagOverridesEnvVar(self)
def testShardStatusFileIsCreated(self)
def testFilterByTest(self)
def testWildcardInTestName(self)
def testDefaultBehaviorWithShards(self)
def testUniversalFilters(self)
def testWildcardInTestCaseName(self)
def testTwoPatterns(self)
def testShardStatusFileIsCreatedWithListTests(self)
def testNegativeFilters(self)
def testShardingWorksWithDeathTests(self)
def RunAndVerifyWithSharding(self, gtest_filter, total_shards, tests_to_run, args=None, check_exit_0=False)
def testThreePatterns(self)
def testFilterByTestCase(self)
def AssertSetEqual(self, lhs, rhs)
def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run)
def testFilterDisabledTests(self)
def AssertPartitionIsValid(self, set_var, list_of_sets)
def testEmptyFilter(self)
def testDefaultBehavior(self)
def RunAndVerify(self, gtest_filter, tests_to_run)