]>
Commit | Line | Data |
---|---|---|
31f18b77 FG |
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 | ||
1e59de90 TL |
33 | This script invokes googletest-catch-exceptions-test_ and |
34 | googletest-catch-exceptions-ex-test_ (programs written with | |
31f18b77 FG |
35 | Google Test) and verifies their output. |
36 | """ | |
37 | ||
31f18b77 FG |
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 | ||
1e59de90 | 46 | # Path to the googletest-catch-exceptions-ex-test_ binary, compiled with |
31f18b77 FG |
47 | # exceptions enabled. |
48 | EX_EXE_PATH = gtest_test_utils.GetTestExecutablePath( | |
1e59de90 | 49 | 'googletest-catch-exceptions-ex-test_') |
31f18b77 | 50 | |
1e59de90 | 51 | # Path to the googletest-catch-exceptions-test_ binary, compiled with |
31f18b77 FG |
52 | # exceptions disabled. |
53 | EXE_PATH = gtest_test_utils.GetTestExecutablePath( | |
1e59de90 | 54 | 'googletest-catch-exceptions-no-ex-test_') |
31f18b77 FG |
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) | |
1e59de90 | 92 | self.assert_('SEH exception with code 0x2a thrown in SetUpTestSuite()' |
31f18b77 | 93 | in test_output) |
1e59de90 | 94 | self.assert_('SEH exception with code 0x2a thrown in TearDownTestSuite()' |
31f18b77 FG |
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): | |
1e59de90 TL |
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) | |
31f18b77 FG |
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): | |
1e59de90 TL |
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) | |
31f18b77 FG |
142 | |
143 | def testCatchesCxxExceptionsInSetUpTestCase(self): | |
1e59de90 TL |
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) | |
31f18b77 FG |
165 | |
166 | def testCatchesCxxExceptionsInTearDownTestCase(self): | |
1e59de90 TL |
167 | self.assertTrue( |
168 | 'C++ exception with description "Standard C++ exception"' | |
169 | ' thrown in TearDownTestSuite()' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) | |
31f18b77 FG |
170 | |
171 | def testCatchesCxxExceptionsInSetUp(self): | |
1e59de90 TL |
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) | |
31f18b77 FG |
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): | |
1e59de90 TL |
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) | |
31f18b77 FG |
199 | |
200 | def testCatchesCxxExceptionsInTestBody(self): | |
1e59de90 TL |
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) | |
31f18b77 FG |
213 | |
214 | def testCatchesNonStdCxxExceptions(self): | |
1e59de90 TL |
215 | self.assertTrue( |
216 | 'Unknown C++ exception thrown in the test body' in EX_BINARY_OUTPUT, | |
217 | EX_BINARY_OUTPUT) | |
31f18b77 FG |
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() |