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