1#!/usr/bin/env python
2#
3# Copyright 2009, Google Inc.
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are
8# met:
9#
10#     * Redistributions of source code must retain the above copyright
11# notice, this list of conditions and the following disclaimer.
12#     * Redistributions in binary form must reproduce the above
13# copyright notice, this list of conditions and the following disclaimer
14# in the documentation and/or other materials provided with the
15# distribution.
16#     * Neither the name of Google Inc. nor the names of its
17# contributors may be used to endorse or promote products derived from
18# this software without specific prior written permission.
19#
20# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32"""Tests the --help flag of Google C++ Testing and Mocking Framework.
33
34SYNOPSIS
35       gtest_help_test.py --build_dir=BUILD/DIR
36         # where BUILD/DIR contains the built gtest_help_test_ file.
37       gtest_help_test.py
38"""
39
40import os
41import re
42import sys
43from googletest.test import gtest_test_utils
44
45
46IS_DARWIN = os.name == 'posix' and os.uname()[0] == 'Darwin'
47IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux'
48IS_GNUHURD = os.name == 'posix' and os.uname()[0] == 'GNU'
49IS_GNUKFREEBSD = os.name == 'posix' and os.uname()[0] == 'GNU/kFreeBSD'
50IS_OPENBSD = os.name == 'posix' and os.uname()[0] == 'OpenBSD'
51IS_WINDOWS = os.name == 'nt'
52
53PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_help_test_')
54FLAG_PREFIX = '--gtest_'
55DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style'
56STREAM_RESULT_TO_FLAG = FLAG_PREFIX + 'stream_result_to'
57LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests'
58INTERNAL_FLAG_FOR_TESTING = FLAG_PREFIX + 'internal_flag_for_testing'
59
60SUPPORTS_DEATH_TESTS = (
61    'DeathTest'
62    in gtest_test_utils.Subprocess([PROGRAM_PATH, LIST_TESTS_FLAG]).output
63)
64
65HAS_ABSL_FLAGS = '--has_absl_flags' in sys.argv
66
67# The help message must match this regex.
68HELP_REGEX = re.compile(
69    FLAG_PREFIX
70    + r'list_tests.*'
71    + FLAG_PREFIX
72    + r'filter=.*'
73    + FLAG_PREFIX
74    + r'also_run_disabled_tests.*'
75    + FLAG_PREFIX
76    + r'repeat=.*'
77    + FLAG_PREFIX
78    + r'shuffle.*'
79    + FLAG_PREFIX
80    + r'random_seed=.*'
81    + FLAG_PREFIX
82    + r'color=.*'
83    + FLAG_PREFIX
84    + r'brief.*'
85    + FLAG_PREFIX
86    + r'print_time.*'
87    + FLAG_PREFIX
88    + r'output=.*'
89    + FLAG_PREFIX
90    + r'break_on_failure.*'
91    + FLAG_PREFIX
92    + r'throw_on_failure.*'
93    + FLAG_PREFIX
94    + r'catch_exceptions=0.*',
95    re.DOTALL,
96)
97
98
99def RunWithFlag(flag):
100  """Runs gtest_help_test_ with the given flag.
101
102  Returns:
103    the exit code and the text output as a tuple.
104  Args:
105    flag: the command-line flag to pass to gtest_help_test_, or None.
106  """
107
108  if flag is None:
109    command = [PROGRAM_PATH]
110  else:
111    command = [PROGRAM_PATH, flag]
112  child = gtest_test_utils.Subprocess(command)
113  return child.exit_code, child.output
114
115
116class GTestHelpTest(gtest_test_utils.TestCase):
117  """Tests the --help flag and its equivalent forms."""
118
119  def TestHelpFlag(self, flag):
120    """Verifies correct behavior when help flag is specified.
121
122    The right message must be printed and the tests must
123    skipped when the given flag is specified.
124
125    Args:
126      flag:  A flag to pass to the binary or None.
127    """
128
129    exit_code, output = RunWithFlag(flag)
130    if HAS_ABSL_FLAGS:
131      # The Abseil flags library prints the ProgramUsageMessage() with
132      # --help and returns 1.
133      self.assertEqual(1, exit_code)
134    else:
135      self.assertEqual(0, exit_code)
136
137    self.assertTrue(HELP_REGEX.search(output), output)
138
139    if IS_DARWIN or IS_LINUX or IS_GNUHURD or IS_GNUKFREEBSD or IS_OPENBSD:
140      self.assertIn(STREAM_RESULT_TO_FLAG, output)
141    else:
142      self.assertNotIn(STREAM_RESULT_TO_FLAG, output)
143
144    if SUPPORTS_DEATH_TESTS and not IS_WINDOWS:
145      self.assertIn(DEATH_TEST_STYLE_FLAG, output)
146    else:
147      self.assertNotIn(DEATH_TEST_STYLE_FLAG, output)
148
149  def TestUnknownFlagWithAbseil(self, flag):
150    """Verifies correct behavior when an unknown flag is specified.
151
152    The right message must be printed and the tests must
153    skipped when the given flag is specified.
154
155    Args:
156      flag:  A flag to pass to the binary or None.
157    """
158    exit_code, output = RunWithFlag(flag)
159    self.assertEqual(1, exit_code)
160    self.assertIn('ERROR: Unknown command line flag', output)
161
162  def TestNonHelpFlag(self, flag):
163    """Verifies correct behavior when no help flag is specified.
164
165    Verifies that when no help flag is specified, the tests are run
166    and the help message is not printed.
167
168    Args:
169      flag:  A flag to pass to the binary or None.
170    """
171
172    exit_code, output = RunWithFlag(flag)
173    self.assertNotEqual(exit_code, 0)
174    self.assertFalse(HELP_REGEX.search(output), output)
175
176  def testPrintsHelpWithFullFlag(self):
177    self.TestHelpFlag('--help')
178
179  def testRunsTestsWithoutHelpFlag(self):
180    """Verifies correct behavior when no help flag is specified.
181
182    Verifies that when no help flag is specified, the tests are run
183    and the help message is not printed.
184    """
185
186    self.TestNonHelpFlag(None)
187
188  def testRunsTestsWithGtestInternalFlag(self):
189    """Verifies correct behavior when internal testing flag is specified.
190
191    Verifies that the tests are run and no help message is printed when
192    a flag starting with Google Test prefix and 'internal_' is supplied.
193    """
194
195    self.TestNonHelpFlag(INTERNAL_FLAG_FOR_TESTING)
196
197
198if __name__ == '__main__':
199  if '--has_absl_flags' in sys.argv:
200    sys.argv.remove('--has_absl_flags')
201  gtest_test_utils.Main()
202