You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

237 lines
9.7 KiB

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