1#!/usr/bin/env python
2#
3# Copyright 2006, 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"""Unit test for Google Test's break-on-failure mode.
33
34A user can ask Google Test to seg-fault when an assertion fails, using
35either the GTEST_BREAK_ON_FAILURE environment variable or the
36--gtest_break_on_failure flag.  This script tests such functionality
37by invoking gtest_break_on_failure_unittest_ (a program written with
38Google Test) with different environments and command line flags.
39"""
40
41__author__ = 'wan@google.com (Zhanyong Wan)'
42
43import gtest_test_utils
44import os
45import sys
46
47
48# Constants.
49
50IS_WINDOWS = os.name == 'nt'
51
52# The environment variable for enabling/disabling the break-on-failure mode.
53BREAK_ON_FAILURE_ENV_VAR = 'GTEST_BREAK_ON_FAILURE'
54
55# The command line flag for enabling/disabling the break-on-failure mode.
56BREAK_ON_FAILURE_FLAG = 'gtest_break_on_failure'
57
58# The environment variable for enabling/disabling the throw-on-failure mode.
59THROW_ON_FAILURE_ENV_VAR = 'GTEST_THROW_ON_FAILURE'
60
61# The environment variable for enabling/disabling the catch-exceptions mode.
62CATCH_EXCEPTIONS_ENV_VAR = 'GTEST_CATCH_EXCEPTIONS'
63
64# Path to the gtest_break_on_failure_unittest_ program.
65EXE_PATH = gtest_test_utils.GetTestExecutablePath(
66    'gtest_break_on_failure_unittest_')
67
68
69# Utilities.
70
71
72environ = os.environ.copy()
73
74
75def SetEnvVar(env_var, value):
76  """Sets an environment variable to a given value; unsets it when the
77  given value is None.
78  """
79
80  if value is not None:
81    environ[env_var] = value
82  elif env_var in environ:
83    del environ[env_var]
84
85
86def Run(command):
87  """Runs a command; returns 1 if it was killed by a signal, or 0 otherwise."""
88
89  p = gtest_test_utils.Subprocess(command, env=environ)
90  if p.terminated_by_signal:
91    return 1
92  else:
93    return 0
94
95
96# The tests.
97
98
99class GTestBreakOnFailureUnitTest(gtest_test_utils.TestCase):
100  """Tests using the GTEST_BREAK_ON_FAILURE environment variable or
101  the --gtest_break_on_failure flag to turn assertion failures into
102  segmentation faults.
103  """
104
105  def RunAndVerify(self, env_var_value, flag_value, expect_seg_fault):
106    """Runs gtest_break_on_failure_unittest_ and verifies that it does
107    (or does not) have a seg-fault.
108
109    Args:
110      env_var_value:    value of the GTEST_BREAK_ON_FAILURE environment
111                        variable; None if the variable should be unset.
112      flag_value:       value of the --gtest_break_on_failure flag;
113                        None if the flag should not be present.
114      expect_seg_fault: 1 if the program is expected to generate a seg-fault;
115                        0 otherwise.
116    """
117
118    SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, env_var_value)
119
120    if env_var_value is None:
121      env_var_value_msg = ' is not set'
122    else:
123      env_var_value_msg = '=' + env_var_value
124
125    if flag_value is None:
126      flag = ''
127    elif flag_value == '0':
128      flag = '--%s=0' % BREAK_ON_FAILURE_FLAG
129    else:
130      flag = '--%s' % BREAK_ON_FAILURE_FLAG
131
132    command = [EXE_PATH]
133    if flag:
134      command.append(flag)
135
136    if expect_seg_fault:
137      should_or_not = 'should'
138    else:
139      should_or_not = 'should not'
140
141    has_seg_fault = Run(command)
142
143    SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, None)
144
145    msg = ('when %s%s, an assertion failure in "%s" %s cause a seg-fault.' %
146           (BREAK_ON_FAILURE_ENV_VAR, env_var_value_msg, ' '.join(command),
147            should_or_not))
148    self.assert_(has_seg_fault == expect_seg_fault, msg)
149
150  def testDefaultBehavior(self):
151    """Tests the behavior of the default mode."""
152
153    self.RunAndVerify(env_var_value=None,
154                      flag_value=None,
155                      expect_seg_fault=0)
156
157  def testEnvVar(self):
158    """Tests using the GTEST_BREAK_ON_FAILURE environment variable."""
159
160    self.RunAndVerify(env_var_value='0',
161                      flag_value=None,
162                      expect_seg_fault=0)
163    self.RunAndVerify(env_var_value='1',
164                      flag_value=None,
165                      expect_seg_fault=1)
166
167  def testFlag(self):
168    """Tests using the --gtest_break_on_failure flag."""
169
170    self.RunAndVerify(env_var_value=None,
171                      flag_value='0',
172                      expect_seg_fault=0)
173    self.RunAndVerify(env_var_value=None,
174                      flag_value='1',
175                      expect_seg_fault=1)
176
177  def testFlagOverridesEnvVar(self):
178    """Tests that the flag overrides the environment variable."""
179
180    self.RunAndVerify(env_var_value='0',
181                      flag_value='0',
182                      expect_seg_fault=0)
183    self.RunAndVerify(env_var_value='0',
184                      flag_value='1',
185                      expect_seg_fault=1)
186    self.RunAndVerify(env_var_value='1',
187                      flag_value='0',
188                      expect_seg_fault=0)
189    self.RunAndVerify(env_var_value='1',
190                      flag_value='1',
191                      expect_seg_fault=1)
192
193  def testBreakOnFailureOverridesThrowOnFailure(self):
194    """Tests that gtest_break_on_failure overrides gtest_throw_on_failure."""
195
196    SetEnvVar(THROW_ON_FAILURE_ENV_VAR, '1')
197    try:
198      self.RunAndVerify(env_var_value=None,
199                        flag_value='1',
200                        expect_seg_fault=1)
201    finally:
202      SetEnvVar(THROW_ON_FAILURE_ENV_VAR, None)
203
204  if IS_WINDOWS:
205    def testCatchExceptionsDoesNotInterfere(self):
206      """Tests that gtest_catch_exceptions doesn't interfere."""
207
208      SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, '1')
209      try:
210        self.RunAndVerify(env_var_value='1',
211                          flag_value='1',
212                          expect_seg_fault=1)
213      finally:
214        SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, None)
215
216
217if __name__ == '__main__':
218  gtest_test_utils.Main()
219