googletest-catch-exceptions-test.py (9997B)
1 #!/usr/bin/env python 2 # 3 # Copyright 2010 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 """Tests Google Test's exception catching behavior. 32 33 This script invokes googletest-catch-exceptions-test_ and 34 googletest-catch-exceptions-ex-test_ (programs written with 35 Google Test) and verifies their output. 36 """ 37 38 import gtest_test_utils 39 40 # Constants. 41 FLAG_PREFIX = '--gtest_' 42 LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests' 43 NO_CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions=0' 44 FILTER_FLAG = FLAG_PREFIX + 'filter' 45 46 # Path to the googletest-catch-exceptions-ex-test_ binary, compiled with 47 # exceptions enabled. 48 EX_EXE_PATH = gtest_test_utils.GetTestExecutablePath( 49 'googletest-catch-exceptions-ex-test_') 50 51 # Path to the googletest-catch-exceptions-test_ binary, compiled with 52 # exceptions disabled. 53 EXE_PATH = gtest_test_utils.GetTestExecutablePath( 54 'googletest-catch-exceptions-no-ex-test_') 55 56 environ = gtest_test_utils.environ 57 SetEnvVar = gtest_test_utils.SetEnvVar 58 59 # Tests in this file run a Google-Test-based test program and expect it 60 # to terminate prematurely. Therefore they are incompatible with 61 # the premature-exit-file protocol by design. Unset the 62 # premature-exit filepath to prevent Google Test from creating 63 # the file. 64 SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None) 65 66 TEST_LIST = gtest_test_utils.Subprocess( 67 [EXE_PATH, LIST_TESTS_FLAG], env=environ).output 68 69 SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST 70 71 if SUPPORTS_SEH_EXCEPTIONS: 72 BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH], env=environ).output 73 74 EX_BINARY_OUTPUT = gtest_test_utils.Subprocess( 75 [EX_EXE_PATH], env=environ).output 76 77 78 # The tests. 79 if SUPPORTS_SEH_EXCEPTIONS: 80 # pylint:disable-msg=C6302 81 class CatchSehExceptionsTest(gtest_test_utils.TestCase): 82 """Tests exception-catching behavior.""" 83 84 85 def TestSehExceptions(self, test_output): 86 self.assert_('SEH exception with code 0x2a thrown ' 87 'in the test fixture\'s constructor' 88 in test_output) 89 self.assert_('SEH exception with code 0x2a thrown ' 90 'in the test fixture\'s destructor' 91 in test_output) 92 self.assert_('SEH exception with code 0x2a thrown in SetUpTestSuite()' 93 in test_output) 94 self.assert_('SEH exception with code 0x2a thrown in TearDownTestSuite()' 95 in test_output) 96 self.assert_('SEH exception with code 0x2a thrown in SetUp()' 97 in test_output) 98 self.assert_('SEH exception with code 0x2a thrown in TearDown()' 99 in test_output) 100 self.assert_('SEH exception with code 0x2a thrown in the test body' 101 in test_output) 102 103 def testCatchesSehExceptionsWithCxxExceptionsEnabled(self): 104 self.TestSehExceptions(EX_BINARY_OUTPUT) 105 106 def testCatchesSehExceptionsWithCxxExceptionsDisabled(self): 107 self.TestSehExceptions(BINARY_OUTPUT) 108 109 110 class CatchCxxExceptionsTest(gtest_test_utils.TestCase): 111 """Tests C++ exception-catching behavior. 112 113 Tests in this test case verify that: 114 * C++ exceptions are caught and logged as C++ (not SEH) exceptions 115 * Exception thrown affect the remainder of the test work flow in the 116 expected manner. 117 """ 118 119 def testCatchesCxxExceptionsInFixtureConstructor(self): 120 self.assertTrue( 121 'C++ exception with description ' 122 '"Standard C++ exception" thrown ' 123 'in the test fixture\'s constructor' in EX_BINARY_OUTPUT, 124 EX_BINARY_OUTPUT) 125 self.assert_('unexpected' not in EX_BINARY_OUTPUT, 126 'This failure belongs in this test only if ' 127 '"CxxExceptionInConstructorTest" (no quotes) ' 128 'appears on the same line as words "called unexpectedly"') 129 130 if ('CxxExceptionInDestructorTest.ThrowsExceptionInDestructor' in 131 EX_BINARY_OUTPUT): 132 133 def testCatchesCxxExceptionsInFixtureDestructor(self): 134 self.assertTrue( 135 'C++ exception with description ' 136 '"Standard C++ exception" thrown ' 137 'in the test fixture\'s destructor' in EX_BINARY_OUTPUT, 138 EX_BINARY_OUTPUT) 139 self.assertTrue( 140 'CxxExceptionInDestructorTest::TearDownTestSuite() ' 141 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 142 143 def testCatchesCxxExceptionsInSetUpTestCase(self): 144 self.assertTrue( 145 'C++ exception with description "Standard C++ exception"' 146 ' thrown in SetUpTestSuite()' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 147 self.assertTrue( 148 'CxxExceptionInConstructorTest::TearDownTestSuite() ' 149 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 150 self.assertTrue( 151 'CxxExceptionInSetUpTestSuiteTest constructor ' 152 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 153 self.assertTrue( 154 'CxxExceptionInSetUpTestSuiteTest destructor ' 155 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 156 self.assertTrue( 157 'CxxExceptionInSetUpTestSuiteTest::SetUp() ' 158 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 159 self.assertTrue( 160 'CxxExceptionInSetUpTestSuiteTest::TearDown() ' 161 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 162 self.assertTrue( 163 'CxxExceptionInSetUpTestSuiteTest test body ' 164 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 165 166 def testCatchesCxxExceptionsInTearDownTestCase(self): 167 self.assertTrue( 168 'C++ exception with description "Standard C++ exception"' 169 ' thrown in TearDownTestSuite()' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 170 171 def testCatchesCxxExceptionsInSetUp(self): 172 self.assertTrue( 173 'C++ exception with description "Standard C++ exception"' 174 ' thrown in SetUp()' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 175 self.assertTrue( 176 'CxxExceptionInSetUpTest::TearDownTestSuite() ' 177 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 178 self.assertTrue( 179 'CxxExceptionInSetUpTest destructor ' 180 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 181 self.assertTrue( 182 'CxxExceptionInSetUpTest::TearDown() ' 183 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 184 self.assert_('unexpected' not in EX_BINARY_OUTPUT, 185 'This failure belongs in this test only if ' 186 '"CxxExceptionInSetUpTest" (no quotes) ' 187 'appears on the same line as words "called unexpectedly"') 188 189 def testCatchesCxxExceptionsInTearDown(self): 190 self.assertTrue( 191 'C++ exception with description "Standard C++ exception"' 192 ' thrown in TearDown()' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 193 self.assertTrue( 194 'CxxExceptionInTearDownTest::TearDownTestSuite() ' 195 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 196 self.assertTrue( 197 'CxxExceptionInTearDownTest destructor ' 198 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 199 200 def testCatchesCxxExceptionsInTestBody(self): 201 self.assertTrue( 202 'C++ exception with description "Standard C++ exception"' 203 ' thrown in the test body' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 204 self.assertTrue( 205 'CxxExceptionInTestBodyTest::TearDownTestSuite() ' 206 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 207 self.assertTrue( 208 'CxxExceptionInTestBodyTest destructor ' 209 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 210 self.assertTrue( 211 'CxxExceptionInTestBodyTest::TearDown() ' 212 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) 213 214 def testCatchesNonStdCxxExceptions(self): 215 self.assertTrue( 216 'Unknown C++ exception thrown in the test body' in EX_BINARY_OUTPUT, 217 EX_BINARY_OUTPUT) 218 219 def testUnhandledCxxExceptionsAbortTheProgram(self): 220 # Filters out SEH exception tests on Windows. Unhandled SEH exceptions 221 # cause tests to show pop-up windows there. 222 FITLER_OUT_SEH_TESTS_FLAG = FILTER_FLAG + '=-*Seh*' 223 # By default, Google Test doesn't catch the exceptions. 224 uncaught_exceptions_ex_binary_output = gtest_test_utils.Subprocess( 225 [EX_EXE_PATH, 226 NO_CATCH_EXCEPTIONS_FLAG, 227 FITLER_OUT_SEH_TESTS_FLAG], 228 env=environ).output 229 230 self.assert_('Unhandled C++ exception terminating the program' 231 in uncaught_exceptions_ex_binary_output) 232 self.assert_('unexpected' not in uncaught_exceptions_ex_binary_output) 233 234 235 if __name__ == '__main__': 236 gtest_test_utils.Main()