1#!/usr/bin/env python
2#
3# Copyright 2005 Google Inc. All Rights Reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are
7# met:
8#
9#     * Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11#     * Redistributions in binary form must reproduce the above
12# copyright notice, this list of conditions and the following disclaimer
13# in the documentation and/or other materials provided with the
14# distribution.
15#     * Neither the name of Google Inc. nor the names of its
16# contributors may be used to endorse or promote products derived from
17# this software without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31"""Unit test for Google Test test filters.
32
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.
38
39Note that test sharding may also influence which tests are filtered. Therefore,
40we test that here also.
41"""
42
43import os
44import re
45
46try:
47  from sets import Set as set  # For Python 2.3 compatibility
48except ImportError:
49  pass
50import sys
51from googletest.test import gtest_test_utils
52
53# Constants.
54
55# Checks if this platform can pass empty environment variables to child
56# processes.  We set an env variable to an empty string and invoke a python
57# script in a subprocess to print whether the variable is STILL in
58# os.environ.  We then use 'eval' to parse the child's output so that an
59# exception is thrown if the input is anything other than 'True' nor 'False'.
60CAN_PASS_EMPTY_ENV = False
61if sys.executable:
62  os.environ['EMPTY_VAR'] = ''
63  child = gtest_test_utils.Subprocess(
64      [sys.executable, '-c', "import os; print('EMPTY_VAR' in os.environ)"]
65  )
66  CAN_PASS_EMPTY_ENV = eval(child.output)
67
68
69# Check if this platform can unset environment variables in child processes.
70# We set an env variable to a non-empty string, unset it, and invoke
71# a python script in a subprocess to print whether the variable
72# is NO LONGER in os.environ.
73# We use 'eval' to parse the child's output so that an exception
74# is thrown if the input is neither 'True' nor 'False'.
75CAN_UNSET_ENV = False
76if sys.executable:
77  os.environ['UNSET_VAR'] = 'X'
78  del os.environ['UNSET_VAR']
79  child = gtest_test_utils.Subprocess(
80      [sys.executable, '-c', "import os; print('UNSET_VAR' not in os.environ)"]
81  )
82  CAN_UNSET_ENV = eval(child.output)
83
84
85# Checks if we should test with an empty filter. This doesn't
86# make sense on platforms that cannot pass empty env variables (Win32)
87# and on platforms that cannot unset variables (since we cannot tell
88# the difference between "" and NULL -- Borland and Solaris < 5.10)
89CAN_TEST_EMPTY_FILTER = CAN_PASS_EMPTY_ENV and CAN_UNSET_ENV
90
91
92# The environment variable for specifying the test filters.
93FILTER_ENV_VAR = 'GTEST_FILTER'
94
95# The environment variables for test sharding.
96TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS'
97SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX'
98SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE'
99
100# The command line flag for specifying the test filters.
101FILTER_FLAG = 'gtest_filter'
102
103# The command line flag for including disabled tests.
104ALSO_RUN_DISABLED_TESTS_FLAG = 'gtest_also_run_disabled_tests'
105
106# Command to run the googletest-filter-unittest_ program.
107COMMAND = gtest_test_utils.GetTestExecutablePath('googletest-filter-unittest_')
108
109# Regex for determining whether parameterized tests are enabled in the binary.
110PARAM_TEST_REGEX = re.compile(r'/ParamTest')
111
112# Regex for parsing test case names from Google Test's output.
113TEST_CASE_REGEX = re.compile(r'^\[\-+\] \d+ tests? from (\w+(/\w+)?)')
114
115# Regex for parsing test names from Google Test's output.
116TEST_REGEX = re.compile(r'^\[\s*RUN\s*\].*\.(\w+(/\w+)?)')
117
118# Regex for parsing disabled banner from Google Test's output
119DISABLED_BANNER_REGEX = re.compile(r'^\[\s*DISABLED\s*\] (.*)')
120
121# The command line flag to tell Google Test to output the list of tests it
122# will run.
123LIST_TESTS_FLAG = '--gtest_list_tests'
124
125# Indicates whether Google Test supports death tests.
126SUPPORTS_DEATH_TESTS = (
127    'HasDeathTest'
128    in gtest_test_utils.Subprocess([COMMAND, LIST_TESTS_FLAG]).output
129)
130
131# Full names of all tests in googletest-filter-unittests_.
132PARAM_TESTS = [
133    'SeqP/ParamTest.TestX/0',
134    'SeqP/ParamTest.TestX/1',
135    'SeqP/ParamTest.TestY/0',
136    'SeqP/ParamTest.TestY/1',
137    'SeqQ/ParamTest.TestX/0',
138    'SeqQ/ParamTest.TestX/1',
139    'SeqQ/ParamTest.TestY/0',
140    'SeqQ/ParamTest.TestY/1',
141]
142
143DISABLED_TESTS = [
144    'BarTest.DISABLED_TestFour',
145    'BarTest.DISABLED_TestFive',
146    'BazTest.DISABLED_TestC',
147    'DISABLED_FoobarTest.Test1',
148    'DISABLED_FoobarTest.DISABLED_Test2',
149    'DISABLED_FoobarbazTest.TestA',
150]
151
152if SUPPORTS_DEATH_TESTS:
153  DEATH_TESTS = [
154      'HasDeathTest.Test1',
155      'HasDeathTest.Test2',
156  ]
157else:
158  DEATH_TESTS = []
159
160# All the non-disabled tests.
161ACTIVE_TESTS = (
162    [
163        'FooTest.Abc',
164        'FooTest.Xyz',
165        'BarTest.TestOne',
166        'BarTest.TestTwo',
167        'BarTest.TestThree',
168        'BazTest.TestOne',
169        'BazTest.TestA',
170        'BazTest.TestB',
171    ]
172    + DEATH_TESTS
173    + PARAM_TESTS
174)
175
176param_tests_present = None
177
178# Utilities.
179
180environ = os.environ.copy()
181
182
183def SetEnvVar(env_var, value):
184  """Sets the env variable to 'value'; unsets it when 'value' is None."""
185
186  if value is not None:
187    environ[env_var] = value
188  elif env_var in environ:
189    del environ[env_var]
190
191
192def RunAndReturnOutput(args=None):
193  """Runs the test program and returns its output."""
194
195  return gtest_test_utils.Subprocess(
196      [COMMAND] + (args or []), env=environ
197  ).output
198
199
200def RunAndExtractTestList(args=None):
201  """Runs the test program and returns its exit code and a list of tests run."""
202
203  p = gtest_test_utils.Subprocess([COMMAND] + (args or []), env=environ)
204  tests_run = []
205  test_case = ''
206  test = ''
207  for line in p.output.split('\n'):
208    match = TEST_CASE_REGEX.match(line)
209    if match is not None:
210      test_case = match.group(1)
211    else:
212      match = TEST_REGEX.match(line)
213      if match is not None:
214        test = match.group(1)
215        tests_run.append(test_case + '.' + test)
216  return (tests_run, p.exit_code)
217
218
219def RunAndExtractDisabledBannerList(args=None):
220  """Runs the test program and returns tests that printed a disabled banner."""
221  p = gtest_test_utils.Subprocess([COMMAND] + (args or []), env=environ)
222  banners_printed = []
223  for line in p.output.split('\n'):
224    match = DISABLED_BANNER_REGEX.match(line)
225    if match is not None:
226      banners_printed.append(match.group(1))
227  return banners_printed
228
229
230def InvokeWithModifiedEnv(extra_env, function, *args, **kwargs):
231  """Runs the given function and arguments in a modified environment."""
232  try:
233    original_env = environ.copy()
234    environ.update(extra_env)
235    return function(*args, **kwargs)
236  finally:
237    environ.clear()
238    environ.update(original_env)
239
240
241def RunWithSharding(total_shards, shard_index, command):
242  """Runs a test program shard and returns exit code and a list of tests run."""
243
244  extra_env = {
245      SHARD_INDEX_ENV_VAR: str(shard_index),
246      TOTAL_SHARDS_ENV_VAR: str(total_shards),
247  }
248  return InvokeWithModifiedEnv(extra_env, RunAndExtractTestList, command)
249
250
251# The unit test.
252
253
254class GTestFilterUnitTest(gtest_test_utils.TestCase):
255  """Tests the env variable or the command line flag to filter tests."""
256
257  # Utilities.
258
259  def AssertSetEqual(self, lhs, rhs):
260    """Asserts that two sets are equal."""
261
262    for elem in lhs:
263      self.assertTrue(elem in rhs, '%s in %s' % (elem, rhs))
264
265    for elem in rhs:
266      self.assertTrue(elem in lhs, '%s in %s' % (elem, lhs))
267
268  def AssertPartitionIsValid(self, set_var, list_of_sets):
269    """Asserts that list_of_sets is a valid partition of set_var."""
270
271    full_partition = []
272    for slice_var in list_of_sets:
273      full_partition.extend(slice_var)
274    self.assertEqual(len(set_var), len(full_partition))
275    self.assertEqual(set(set_var), set(full_partition))
276
277  def AdjustForParameterizedTests(self, tests_to_run):
278    """Adjust tests_to_run in case value parameterized tests are disabled."""
279
280    global param_tests_present
281    if not param_tests_present:
282      return list(set(tests_to_run) - set(PARAM_TESTS))
283    else:
284      return tests_to_run
285
286  def RunAndVerify(self, gtest_filter, tests_to_run):
287    """Checks that the binary runs correct set of tests for a given filter."""
288
289    tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
290
291    # First, tests using the environment variable.
292
293    # Windows removes empty variables from the environment when passing it
294    # to a new process.  This means it is impossible to pass an empty filter
295    # into a process using the environment variable.  However, we can still
296    # test the case when the variable is not supplied (i.e., gtest_filter is
297    # None).
298    # pylint: disable=g-explicit-bool-comparison
299    if CAN_TEST_EMPTY_FILTER or gtest_filter != '':
300      SetEnvVar(FILTER_ENV_VAR, gtest_filter)
301      tests_run = RunAndExtractTestList()[0]
302      SetEnvVar(FILTER_ENV_VAR, None)
303      self.AssertSetEqual(tests_run, tests_to_run)
304    # pylint: enable=g-explicit-bool-comparison
305
306    # Next, tests using the command line flag.
307
308    if gtest_filter is None:
309      args = []
310    else:
311      args = ['--%s=%s' % (FILTER_FLAG, gtest_filter)]
312
313    tests_run = RunAndExtractTestList(args)[0]
314    self.AssertSetEqual(tests_run, tests_to_run)
315
316  def RunAndVerifyWithSharding(
317      self,
318      gtest_filter,
319      total_shards,
320      tests_to_run,
321      args=None,
322      check_exit_0=False,
323  ):
324    """Checks that binary runs correct tests for the given filter and shard.
325
326    Runs all shards of googletest-filter-unittest_ with the given filter, and
327    verifies that the right set of tests were run. The union of tests run
328    on each shard should be identical to tests_to_run, without duplicates.
329    If check_exit_0, .
330
331    Args:
332      gtest_filter: A filter to apply to the tests.
333      total_shards: A total number of shards to split test run into.
334      tests_to_run: A set of tests expected to run.
335      args: Arguments to pass to the to the test binary.
336      check_exit_0: When set to a true value, make sure that all shards return
337        0.
338    """
339
340    tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
341
342    # Windows removes empty variables from the environment when passing it
343    # to a new process.  This means it is impossible to pass an empty filter
344    # into a process using the environment variable.  However, we can still
345    # test the case when the variable is not supplied (i.e., gtest_filter is
346    # None).
347    # pylint: disable=g-explicit-bool-comparison
348    if CAN_TEST_EMPTY_FILTER or gtest_filter != '':
349      SetEnvVar(FILTER_ENV_VAR, gtest_filter)
350      partition = []
351      for i in range(0, total_shards):
352        (tests_run, exit_code) = RunWithSharding(total_shards, i, args)
353        if check_exit_0:
354          self.assertEqual(0, exit_code)
355        partition.append(tests_run)
356
357      self.AssertPartitionIsValid(tests_to_run, partition)
358      SetEnvVar(FILTER_ENV_VAR, None)
359    # pylint: enable=g-explicit-bool-comparison
360
361  def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run):
362    """Checks that the binary runs correct set of tests for the given filter.
363
364    Runs googletest-filter-unittest_ with the given filter, and enables
365    disabled tests. Verifies that the right set of tests were run.
366
367    Args:
368      gtest_filter: A filter to apply to the tests.
369      tests_to_run: A set of tests expected to run.
370    """
371
372    tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
373
374    # Construct the command line.
375    args = ['--%s' % ALSO_RUN_DISABLED_TESTS_FLAG]
376    if gtest_filter is not None:
377      args.append('--%s=%s' % (FILTER_FLAG, gtest_filter))
378
379    tests_run = RunAndExtractTestList(args)[0]
380    self.AssertSetEqual(tests_run, tests_to_run)
381
382  def setUp(self):
383    """Sets up test case.
384
385    Determines whether value-parameterized tests are enabled in the binary and
386    sets the flags accordingly.
387    """
388
389    global param_tests_present
390    if param_tests_present is None:
391      param_tests_present = (
392          PARAM_TEST_REGEX.search(RunAndReturnOutput()) is not None
393      )
394
395  def testDefaultBehavior(self):
396    """Tests the behavior of not specifying the filter."""
397
398    self.RunAndVerify(None, ACTIVE_TESTS)
399
400  def testDefaultBehaviorWithShards(self):
401    """Tests the behavior without the filter, with sharding enabled."""
402
403    self.RunAndVerifyWithSharding(None, 1, ACTIVE_TESTS)
404    self.RunAndVerifyWithSharding(None, 2, ACTIVE_TESTS)
405    self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) - 1, ACTIVE_TESTS)
406    self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS), ACTIVE_TESTS)
407    self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) + 1, ACTIVE_TESTS)
408
409  def testEmptyFilter(self):
410    """Tests an empty filter."""
411
412    self.RunAndVerify('', [])
413    self.RunAndVerifyWithSharding('', 1, [])
414    self.RunAndVerifyWithSharding('', 2, [])
415
416  def testBadFilter(self):
417    """Tests a filter that matches nothing."""
418
419    self.RunAndVerify('BadFilter', [])
420    self.RunAndVerifyAllowingDisabled('BadFilter', [])
421
422  def testFullName(self):
423    """Tests filtering by full name."""
424
425    self.RunAndVerify('FooTest.Xyz', ['FooTest.Xyz'])
426    self.RunAndVerifyAllowingDisabled('FooTest.Xyz', ['FooTest.Xyz'])
427    self.RunAndVerifyWithSharding('FooTest.Xyz', 5, ['FooTest.Xyz'])
428
429  def testUniversalFilters(self):
430    """Tests filters that match everything."""
431
432    self.RunAndVerify('*', ACTIVE_TESTS)
433    self.RunAndVerify('*.*', ACTIVE_TESTS)
434    self.RunAndVerifyWithSharding('*.*', len(ACTIVE_TESTS) - 3, ACTIVE_TESTS)
435    self.RunAndVerifyAllowingDisabled('*', ACTIVE_TESTS + DISABLED_TESTS)
436    self.RunAndVerifyAllowingDisabled('*.*', ACTIVE_TESTS + DISABLED_TESTS)
437
438  def testFilterByTestCase(self):
439    """Tests filtering by test case name."""
440
441    self.RunAndVerify('FooTest.*', ['FooTest.Abc', 'FooTest.Xyz'])
442
443    BAZ_TESTS = ['BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB']
444    self.RunAndVerify('BazTest.*', BAZ_TESTS)
445    self.RunAndVerifyAllowingDisabled(
446        'BazTest.*', BAZ_TESTS + ['BazTest.DISABLED_TestC']
447    )
448
449  def testFilterByTest(self):
450    """Tests filtering by test name."""
451
452    self.RunAndVerify('*.TestOne', ['BarTest.TestOne', 'BazTest.TestOne'])
453
454  def testFilterDisabledTests(self):
455    """Select only the disabled tests to run."""
456
457    self.RunAndVerify('DISABLED_FoobarTest.Test1', [])
458    self.RunAndVerifyAllowingDisabled(
459        'DISABLED_FoobarTest.Test1', ['DISABLED_FoobarTest.Test1']
460    )
461
462    self.RunAndVerify('*DISABLED_*', [])
463    self.RunAndVerifyAllowingDisabled('*DISABLED_*', DISABLED_TESTS)
464
465    self.RunAndVerify('*.DISABLED_*', [])
466    self.RunAndVerifyAllowingDisabled(
467        '*.DISABLED_*',
468        [
469            'BarTest.DISABLED_TestFour',
470            'BarTest.DISABLED_TestFive',
471            'BazTest.DISABLED_TestC',
472            'DISABLED_FoobarTest.DISABLED_Test2',
473        ],
474    )
475
476    self.RunAndVerify('DISABLED_*', [])
477    self.RunAndVerifyAllowingDisabled(
478        'DISABLED_*',
479        [
480            'DISABLED_FoobarTest.Test1',
481            'DISABLED_FoobarTest.DISABLED_Test2',
482            'DISABLED_FoobarbazTest.TestA',
483        ],
484    )
485
486  def testWildcardInTestCaseName(self):
487    """Tests using wildcard in the test case name."""
488
489    self.RunAndVerify(
490        '*a*.*',
491        [
492            'BarTest.TestOne',
493            'BarTest.TestTwo',
494            'BarTest.TestThree',
495            'BazTest.TestOne',
496            'BazTest.TestA',
497            'BazTest.TestB',
498        ]
499        + DEATH_TESTS
500        + PARAM_TESTS,
501    )
502
503  def testWildcardInTestName(self):
504    """Tests using wildcard in the test name."""
505
506    self.RunAndVerify('*.*A*', ['FooTest.Abc', 'BazTest.TestA'])
507
508  def testFilterWithoutDot(self):
509    """Tests a filter that has no '.' in it."""
510
511    self.RunAndVerify(
512        '*z*',
513        [
514            'FooTest.Xyz',
515            'BazTest.TestOne',
516            'BazTest.TestA',
517            'BazTest.TestB',
518        ],
519    )
520
521  def testTwoPatterns(self):
522    """Tests filters that consist of two patterns."""
523
524    self.RunAndVerify(
525        'Foo*.*:*A*',
526        [
527            'FooTest.Abc',
528            'FooTest.Xyz',
529            'BazTest.TestA',
530        ],
531    )
532
533    # An empty pattern + a non-empty one
534    self.RunAndVerify(':*A*', ['FooTest.Abc', 'BazTest.TestA'])
535
536  def testThreePatterns(self):
537    """Tests filters that consist of three patterns."""
538
539    self.RunAndVerify(
540        '*oo*:*A*:*One',
541        [
542            'FooTest.Abc',
543            'FooTest.Xyz',
544            'BarTest.TestOne',
545            'BazTest.TestOne',
546            'BazTest.TestA',
547        ],
548    )
549
550    # The 2nd pattern is empty.
551    self.RunAndVerify(
552        '*oo*::*One',
553        [
554            'FooTest.Abc',
555            'FooTest.Xyz',
556            'BarTest.TestOne',
557            'BazTest.TestOne',
558        ],
559    )
560
561    # The last 2 patterns are empty.
562    self.RunAndVerify(
563        '*oo*::',
564        [
565            'FooTest.Abc',
566            'FooTest.Xyz',
567        ],
568    )
569
570  def testNegativeFilters(self):
571    self.RunAndVerify(
572        '*-BazTest.TestOne',
573        [
574            'FooTest.Abc',
575            'FooTest.Xyz',
576            'BarTest.TestOne',
577            'BarTest.TestTwo',
578            'BarTest.TestThree',
579            'BazTest.TestA',
580            'BazTest.TestB',
581        ]
582        + DEATH_TESTS
583        + PARAM_TESTS,
584    )
585
586    self.RunAndVerify(
587        '*-FooTest.Abc:BazTest.*',
588        [
589            'FooTest.Xyz',
590            'BarTest.TestOne',
591            'BarTest.TestTwo',
592            'BarTest.TestThree',
593        ]
594        + DEATH_TESTS
595        + PARAM_TESTS,
596    )
597
598    self.RunAndVerify(
599        'BarTest.*-BarTest.TestOne',
600        [
601            'BarTest.TestTwo',
602            'BarTest.TestThree',
603        ],
604    )
605
606    # Tests without leading '*'.
607    self.RunAndVerify(
608        '-FooTest.Abc:FooTest.Xyz:BazTest.*',
609        [
610            'BarTest.TestOne',
611            'BarTest.TestTwo',
612            'BarTest.TestThree',
613        ]
614        + DEATH_TESTS
615        + PARAM_TESTS,
616    )
617
618    # Value parameterized tests.
619    self.RunAndVerify('*/*', PARAM_TESTS)
620
621    # Value parameterized tests filtering by the sequence name.
622    self.RunAndVerify(
623        'SeqP/*',
624        [
625            'SeqP/ParamTest.TestX/0',
626            'SeqP/ParamTest.TestX/1',
627            'SeqP/ParamTest.TestY/0',
628            'SeqP/ParamTest.TestY/1',
629        ],
630    )
631
632    # Value parameterized tests filtering by the test name.
633    self.RunAndVerify(
634        '*/0',
635        [
636            'SeqP/ParamTest.TestX/0',
637            'SeqP/ParamTest.TestY/0',
638            'SeqQ/ParamTest.TestX/0',
639            'SeqQ/ParamTest.TestY/0',
640        ],
641    )
642
643  def testFlagOverridesEnvVar(self):
644    """Tests that the filter flag overrides the filtering env. variable."""
645
646    SetEnvVar(FILTER_ENV_VAR, 'Foo*')
647    args = ['--%s=%s' % (FILTER_FLAG, '*One')]
648    tests_run = RunAndExtractTestList(args)[0]
649    SetEnvVar(FILTER_ENV_VAR, None)
650
651    self.AssertSetEqual(tests_run, ['BarTest.TestOne', 'BazTest.TestOne'])
652
653  def testShardStatusFileIsCreated(self):
654    """Tests that the shard file is created if specified in the environment."""
655
656    shard_status_file = os.path.join(
657        gtest_test_utils.GetTempDir(), 'shard_status_file'
658    )
659    self.assertTrue(not os.path.exists(shard_status_file))
660
661    extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file}
662    try:
663      InvokeWithModifiedEnv(extra_env, RunAndReturnOutput)
664    finally:
665      self.assertTrue(os.path.exists(shard_status_file))
666      os.remove(shard_status_file)
667
668  def testShardStatusFileIsCreatedWithListTests(self):
669    """Tests that the shard file is created with the "list_tests" flag."""
670
671    shard_status_file = os.path.join(
672        gtest_test_utils.GetTempDir(), 'shard_status_file2'
673    )
674    self.assertTrue(not os.path.exists(shard_status_file))
675
676    extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file}
677    try:
678      output = InvokeWithModifiedEnv(
679          extra_env, RunAndReturnOutput, [LIST_TESTS_FLAG]
680      )
681    finally:
682      # This assertion ensures that Google Test enumerated the tests as
683      # opposed to running them.
684      self.assertTrue(
685          '[==========]' not in output,
686          (
687              'Unexpected output during test enumeration.\n'
688              'Please ensure that LIST_TESTS_FLAG is assigned the\n'
689              'correct flag value for listing Google Test tests.'
690          ),
691      )
692
693      self.assertTrue(os.path.exists(shard_status_file))
694      os.remove(shard_status_file)
695
696  def testDisabledBanner(self):
697    """Tests that the disabled banner prints only tests that match filter."""
698    make_filter = lambda s: ['--%s=%s' % (FILTER_FLAG, s)]
699
700    banners = RunAndExtractDisabledBannerList(make_filter('*'))
701    self.AssertSetEqual(
702        banners,
703        [
704            'BarTest.DISABLED_TestFour',
705            'BarTest.DISABLED_TestFive',
706            'BazTest.DISABLED_TestC',
707        ],
708    )
709
710    banners = RunAndExtractDisabledBannerList(make_filter('Bar*'))
711    self.AssertSetEqual(
712        banners, ['BarTest.DISABLED_TestFour', 'BarTest.DISABLED_TestFive']
713    )
714
715    banners = RunAndExtractDisabledBannerList(make_filter('*-Bar*'))
716    self.AssertSetEqual(banners, ['BazTest.DISABLED_TestC'])
717
718  if SUPPORTS_DEATH_TESTS:
719
720    def testShardingWorksWithDeathTests(self):
721      """Tests integration with death tests and sharding."""
722
723      gtest_filter = 'HasDeathTest.*:SeqP/*'
724      expected_tests = [
725          'HasDeathTest.Test1',
726          'HasDeathTest.Test2',
727          'SeqP/ParamTest.TestX/0',
728          'SeqP/ParamTest.TestX/1',
729          'SeqP/ParamTest.TestY/0',
730          'SeqP/ParamTest.TestY/1',
731      ]
732
733      for flag in [
734          '--gtest_death_test_style=threadsafe',
735          '--gtest_death_test_style=fast',
736      ]:
737        self.RunAndVerifyWithSharding(
738            gtest_filter, 3, expected_tests, check_exit_0=True, args=[flag]
739        )
740        self.RunAndVerifyWithSharding(
741            gtest_filter, 5, expected_tests, check_exit_0=True, args=[flag]
742        )
743
744
745if __name__ == '__main__':
746  gtest_test_utils.Main()
747