From 35aa4fe9245590721146af854789913c04c2c7fb Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Wed, 1 Aug 2018 13:32:07 -0400 Subject: gtest catch exceptions test and gtest shuffle test --- googletest/test/BUILD.bazel | 36 +-- .../test/googletest-catch-exceptions-test.py | 235 +++++++++++++++ .../test/googletest-catch-exceptions-test_.cc | 311 ++++++++++++++++++++ googletest/test/googletest-listener-test.cc | 311 ++++++++++++++++++++ googletest/test/googletest-shuffle-test.py | 325 +++++++++++++++++++++ googletest/test/googletest-shuffle-test_.cc | 103 +++++++ googletest/test/gtest_catch_exceptions_test.py | 235 --------------- googletest/test/gtest_catch_exceptions_test_.cc | 311 -------------------- googletest/test/gtest_shuffle_test.py | 325 --------------------- googletest/test/gtest_shuffle_test_.cc | 103 ------- 10 files changed, 1301 insertions(+), 994 deletions(-) create mode 100755 googletest/test/googletest-catch-exceptions-test.py create mode 100644 googletest/test/googletest-catch-exceptions-test_.cc create mode 100644 googletest/test/googletest-listener-test.cc create mode 100755 googletest/test/googletest-shuffle-test.py create mode 100644 googletest/test/googletest-shuffle-test_.cc delete mode 100755 googletest/test/gtest_catch_exceptions_test.py delete mode 100644 googletest/test/gtest_catch_exceptions_test_.cc delete mode 100755 googletest/test/gtest_shuffle_test.py delete mode 100644 googletest/test/gtest_shuffle_test_.cc diff --git a/googletest/test/BUILD.bazel b/googletest/test/BUILD.bazel index 090c463f..319c8494 100644 --- a/googletest/test/BUILD.bazel +++ b/googletest/test/BUILD.bazel @@ -107,14 +107,10 @@ cc_test( #These googletest tests have their own main() cc_test( - name = "gtest-listener_test", + name = "googletest-listener-test", size = "small", - srcs = [ - "gtest-listener_test.cc", - ], - deps = [ - "//:gtest", - ], + srcs = ["googletest-listener-test.cc"], + deps = ["//:gtest_main"], ) cc_test( @@ -301,41 +297,41 @@ py_test( ) cc_binary( - name = "gtest_shuffle_test_", - srcs = ["gtest_shuffle_test_.cc"], + name = "googletest-shuffle-test_", + srcs = ["googletest-shuffle-test_.cc"], deps = ["//:gtest"], ) py_test( - name = "gtest_shuffle_test", + name = "googletest-shuffle-test", size = "small", - srcs = ["gtest_shuffle_test.py"], - data = [":gtest_shuffle_test_"], + srcs = ["googletest-shuffle-test.py"], + data = [":googletest-shuffle-test_"], deps = [":gtest_test_utils"], ) cc_binary( - name = "gtest_catch_exceptions_no_ex_test_", + name = "googletest_catch_exceptions_no_ex_test_", testonly = 1, - srcs = ["gtest_catch_exceptions_test_.cc"], + srcs = ["googletest-catch-exceptions-test_.cc"], deps = ["//:gtest_main"], ) cc_binary( - name = "gtest_catch_exceptions_ex_test_", + name = "googletest_catch_exceptions_ex_test_", testonly = 1, - srcs = ["gtest_catch_exceptions_test_.cc"], + srcs = ["googletest-catch-exceptions-test_.cc"], copts = ["-fexceptions"], deps = ["//:gtest_main"], ) py_test( - name = "gtest_catch_exceptions_test", + name = "googletest-catch-exceptions-test", size = "small", - srcs = ["gtest_catch_exceptions_test.py"], + srcs = ["googletest-catch-exceptions-test.py"], data = [ - ":gtest_catch_exceptions_ex_test_", - ":gtest_catch_exceptions_no_ex_test_", + ":googletest_catch_exceptions_ex_test_", + ":googletest_catch_exceptions_no_ex_test_", ], deps = [":gtest_test_utils"], ) diff --git a/googletest/test/googletest-catch-exceptions-test.py b/googletest/test/googletest-catch-exceptions-test.py new file mode 100755 index 00000000..d12a32a9 --- /dev/null +++ b/googletest/test/googletest-catch-exceptions-test.py @@ -0,0 +1,235 @@ +#!/usr/bin/env python +# +# Copyright 2010 Google Inc. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Tests Google Test's exception catching behavior. + +This script invokes gtest_catch_exceptions_test_ and +gtest_catch_exceptions_ex_test_ (programs written with +Google Test) and verifies their output. +""" + +__author__ = 'vladl@google.com (Vlad Losev)' + +import gtest_test_utils + +# Constants. +FLAG_PREFIX = '--gtest_' +LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests' +NO_CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions=0' +FILTER_FLAG = FLAG_PREFIX + 'filter' + +# Path to the gtest_catch_exceptions_ex_test_ binary, compiled with +# exceptions enabled. +EX_EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'googletest_catch_exceptions_ex_test_') + +# Path to the gtest_catch_exceptions_test_ binary, compiled with +# exceptions disabled. +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'googletest_catch_exceptions_no_ex_test_') + +environ = gtest_test_utils.environ +SetEnvVar = gtest_test_utils.SetEnvVar + +# Tests in this file run a Google-Test-based test program and expect it +# to terminate prematurely. Therefore they are incompatible with +# the premature-exit-file protocol by design. Unset the +# premature-exit filepath to prevent Google Test from creating +# the file. +SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None) + +TEST_LIST = gtest_test_utils.Subprocess( + [EXE_PATH, LIST_TESTS_FLAG], env=environ).output + +SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST + +if SUPPORTS_SEH_EXCEPTIONS: + BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH], env=environ).output + +EX_BINARY_OUTPUT = gtest_test_utils.Subprocess( + [EX_EXE_PATH], env=environ).output + + +# The tests. +if SUPPORTS_SEH_EXCEPTIONS: + # pylint:disable-msg=C6302 + class CatchSehExceptionsTest(gtest_test_utils.TestCase): + """Tests exception-catching behavior.""" + + + def TestSehExceptions(self, test_output): + self.assert_('SEH exception with code 0x2a thrown ' + 'in the test fixture\'s constructor' + in test_output) + self.assert_('SEH exception with code 0x2a thrown ' + 'in the test fixture\'s destructor' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in SetUpTestCase()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in TearDownTestCase()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in SetUp()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in TearDown()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in the test body' + in test_output) + + def testCatchesSehExceptionsWithCxxExceptionsEnabled(self): + self.TestSehExceptions(EX_BINARY_OUTPUT) + + def testCatchesSehExceptionsWithCxxExceptionsDisabled(self): + self.TestSehExceptions(BINARY_OUTPUT) + + +class CatchCxxExceptionsTest(gtest_test_utils.TestCase): + """Tests C++ exception-catching behavior. + + Tests in this test case verify that: + * C++ exceptions are caught and logged as C++ (not SEH) exceptions + * Exception thrown affect the remainder of the test work flow in the + expected manner. + """ + + def testCatchesCxxExceptionsInFixtureConstructor(self): + self.assert_('C++ exception with description ' + '"Standard C++ exception" thrown ' + 'in the test fixture\'s constructor' + in EX_BINARY_OUTPUT) + self.assert_('unexpected' not in EX_BINARY_OUTPUT, + 'This failure belongs in this test only if ' + '"CxxExceptionInConstructorTest" (no quotes) ' + 'appears on the same line as words "called unexpectedly"') + + if ('CxxExceptionInDestructorTest.ThrowsExceptionInDestructor' in + EX_BINARY_OUTPUT): + + def testCatchesCxxExceptionsInFixtureDestructor(self): + self.assert_('C++ exception with description ' + '"Standard C++ exception" thrown ' + 'in the test fixture\'s destructor' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInDestructorTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInSetUpTestCase(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in SetUpTestCase()' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInConstructorTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest constructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest::SetUp() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest::TearDown() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest test body ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInTearDownTestCase(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in TearDownTestCase()' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInSetUp(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in SetUp()' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTest::TearDown() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('unexpected' not in EX_BINARY_OUTPUT, + 'This failure belongs in this test only if ' + '"CxxExceptionInSetUpTest" (no quotes) ' + 'appears on the same line as words "called unexpectedly"') + + def testCatchesCxxExceptionsInTearDown(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in TearDown()' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTearDownTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTearDownTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInTestBody(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in the test body' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTestBodyTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTestBodyTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTestBodyTest::TearDown() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesNonStdCxxExceptions(self): + self.assert_('Unknown C++ exception thrown in the test body' + in EX_BINARY_OUTPUT) + + def testUnhandledCxxExceptionsAbortTheProgram(self): + # Filters out SEH exception tests on Windows. Unhandled SEH exceptions + # cause tests to show pop-up windows there. + FITLER_OUT_SEH_TESTS_FLAG = FILTER_FLAG + '=-*Seh*' + # By default, Google Test doesn't catch the exceptions. + uncaught_exceptions_ex_binary_output = gtest_test_utils.Subprocess( + [EX_EXE_PATH, + NO_CATCH_EXCEPTIONS_FLAG, + FITLER_OUT_SEH_TESTS_FLAG], + env=environ).output + + self.assert_('Unhandled C++ exception terminating the program' + in uncaught_exceptions_ex_binary_output) + self.assert_('unexpected' not in uncaught_exceptions_ex_binary_output) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/googletest/test/googletest-catch-exceptions-test_.cc b/googletest/test/googletest-catch-exceptions-test_.cc new file mode 100644 index 00000000..c6d953c0 --- /dev/null +++ b/googletest/test/googletest-catch-exceptions-test_.cc @@ -0,0 +1,311 @@ +// Copyright 2010, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: vladl@google.com (Vlad Losev) +// +// Tests for Google Test itself. Tests in this file throw C++ or SEH +// exceptions, and the output is verified by gtest_catch_exceptions_test.py. + +#include "gtest/gtest.h" + +#include // NOLINT +#include // For exit(). + +#if GTEST_HAS_SEH +# include +#endif + +#if GTEST_HAS_EXCEPTIONS +# include // For set_terminate(). +# include +#endif + +using testing::Test; + +#if GTEST_HAS_SEH + +class SehExceptionInConstructorTest : public Test { + public: + SehExceptionInConstructorTest() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInConstructorTest, ThrowsExceptionInConstructor) {} + +class SehExceptionInDestructorTest : public Test { + public: + ~SehExceptionInDestructorTest() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInDestructorTest, ThrowsExceptionInDestructor) {} + +class SehExceptionInSetUpTestCaseTest : public Test { + public: + static void SetUpTestCase() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInSetUpTestCaseTest, ThrowsExceptionInSetUpTestCase) {} + +class SehExceptionInTearDownTestCaseTest : public Test { + public: + static void TearDownTestCase() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInTearDownTestCaseTest, ThrowsExceptionInTearDownTestCase) {} + +class SehExceptionInSetUpTest : public Test { + protected: + virtual void SetUp() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInSetUpTest, ThrowsExceptionInSetUp) {} + +class SehExceptionInTearDownTest : public Test { + protected: + virtual void TearDown() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInTearDownTest, ThrowsExceptionInTearDown) {} + +TEST(SehExceptionTest, ThrowsSehException) { + RaiseException(42, 0, 0, NULL); +} + +#endif // GTEST_HAS_SEH + +#if GTEST_HAS_EXCEPTIONS + +class CxxExceptionInConstructorTest : public Test { + public: + CxxExceptionInConstructorTest() { + // Without this macro VC++ complains about unreachable code at the end of + // the constructor. + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( + throw std::runtime_error("Standard C++ exception")); + } + + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInConstructorTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInConstructorTest() { + ADD_FAILURE() << "CxxExceptionInConstructorTest destructor " + << "called unexpectedly."; + } + + virtual void SetUp() { + ADD_FAILURE() << "CxxExceptionInConstructorTest::SetUp() " + << "called unexpectedly."; + } + + virtual void TearDown() { + ADD_FAILURE() << "CxxExceptionInConstructorTest::TearDown() " + << "called unexpectedly."; + } +}; + +TEST_F(CxxExceptionInConstructorTest, ThrowsExceptionInConstructor) { + ADD_FAILURE() << "CxxExceptionInConstructorTest test body " + << "called unexpectedly."; +} + +// Exceptions in destructors are not supported in C++11. +#if !GTEST_LANG_CXX11 +class CxxExceptionInDestructorTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInDestructorTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInDestructorTest() { + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( + throw std::runtime_error("Standard C++ exception")); + } +}; + +TEST_F(CxxExceptionInDestructorTest, ThrowsExceptionInDestructor) {} +#endif // C++11 mode + +class CxxExceptionInSetUpTestCaseTest : public Test { + public: + CxxExceptionInSetUpTestCaseTest() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest constructor " + "called as expected.\n"); + } + + static void SetUpTestCase() { + throw std::runtime_error("Standard C++ exception"); + } + + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInSetUpTestCaseTest() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest destructor " + "called as expected.\n"); + } + + virtual void SetUp() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest::SetUp() " + "called as expected.\n"); + } + + virtual void TearDown() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInSetUpTestCaseTest, ThrowsExceptionInSetUpTestCase) { + printf("%s", + "CxxExceptionInSetUpTestCaseTest test body " + "called as expected.\n"); +} + +class CxxExceptionInTearDownTestCaseTest : public Test { + public: + static void TearDownTestCase() { + throw std::runtime_error("Standard C++ exception"); + } +}; + +TEST_F(CxxExceptionInTearDownTestCaseTest, ThrowsExceptionInTearDownTestCase) {} + +class CxxExceptionInSetUpTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInSetUpTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInSetUpTest() { + printf("%s", + "CxxExceptionInSetUpTest destructor " + "called as expected.\n"); + } + + virtual void SetUp() { throw std::runtime_error("Standard C++ exception"); } + + virtual void TearDown() { + printf("%s", + "CxxExceptionInSetUpTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInSetUpTest, ThrowsExceptionInSetUp) { + ADD_FAILURE() << "CxxExceptionInSetUpTest test body " + << "called unexpectedly."; +} + +class CxxExceptionInTearDownTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInTearDownTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInTearDownTest() { + printf("%s", + "CxxExceptionInTearDownTest destructor " + "called as expected.\n"); + } + + virtual void TearDown() { + throw std::runtime_error("Standard C++ exception"); + } +}; + +TEST_F(CxxExceptionInTearDownTest, ThrowsExceptionInTearDown) {} + +class CxxExceptionInTestBodyTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInTestBodyTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInTestBodyTest() { + printf("%s", + "CxxExceptionInTestBodyTest destructor " + "called as expected.\n"); + } + + virtual void TearDown() { + printf("%s", + "CxxExceptionInTestBodyTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInTestBodyTest, ThrowsStdCxxException) { + throw std::runtime_error("Standard C++ exception"); +} + +TEST(CxxExceptionTest, ThrowsNonStdCxxException) { + throw "C-string"; +} + +// This terminate handler aborts the program using exit() rather than abort(). +// This avoids showing pop-ups on Windows systems and core dumps on Unix-like +// ones. +void TerminateHandler() { + fprintf(stderr, "%s\n", "Unhandled C++ exception terminating the program."); + fflush(NULL); + exit(3); +} + +#endif // GTEST_HAS_EXCEPTIONS + +int main(int argc, char** argv) { +#if GTEST_HAS_EXCEPTIONS + std::set_terminate(&TerminateHandler); +#endif + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/googletest/test/googletest-listener-test.cc b/googletest/test/googletest-listener-test.cc new file mode 100644 index 00000000..639529c5 --- /dev/null +++ b/googletest/test/googletest-listener-test.cc @@ -0,0 +1,311 @@ +// Copyright 2009 Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: vladl@google.com (Vlad Losev) +// +// The Google C++ Testing and Mocking Framework (Google Test) +// +// This file verifies Google Test event listeners receive events at the +// right times. + +#include "gtest/gtest.h" +#include + +using ::testing::AddGlobalTestEnvironment; +using ::testing::Environment; +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::TestCase; +using ::testing::TestEventListener; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; + +// Used by tests to register their events. +std::vector* g_events = NULL; + +namespace testing { +namespace internal { + +class EventRecordingListener : public TestEventListener { + public: + explicit EventRecordingListener(const char* name) : name_(name) {} + + protected: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnTestProgramStart")); + } + + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int iteration) { + Message message; + message << GetFullMethodName("OnTestIterationStart") + << "(" << iteration << ")"; + g_events->push_back(message.GetString()); + } + + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpStart")); + } + + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpEnd")); + } + + virtual void OnTestCaseStart(const TestCase& /*test_case*/) { + g_events->push_back(GetFullMethodName("OnTestCaseStart")); + } + + virtual void OnTestStart(const TestInfo& /*test_info*/) { + g_events->push_back(GetFullMethodName("OnTestStart")); + } + + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) { + g_events->push_back(GetFullMethodName("OnTestPartResult")); + } + + virtual void OnTestEnd(const TestInfo& /*test_info*/) { + g_events->push_back(GetFullMethodName("OnTestEnd")); + } + + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) { + g_events->push_back(GetFullMethodName("OnTestCaseEnd")); + } + + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownStart")); + } + + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownEnd")); + } + + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int iteration) { + Message message; + message << GetFullMethodName("OnTestIterationEnd") + << "(" << iteration << ")"; + g_events->push_back(message.GetString()); + } + + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnTestProgramEnd")); + } + + private: + std::string GetFullMethodName(const char* name) { + return name_ + "." + name; + } + + std::string name_; +}; + +class EnvironmentInvocationCatcher : public Environment { + protected: + virtual void SetUp() { + g_events->push_back("Environment::SetUp"); + } + + virtual void TearDown() { + g_events->push_back("Environment::TearDown"); + } +}; + +class ListenerTest : public Test { + protected: + static void SetUpTestCase() { + g_events->push_back("ListenerTest::SetUpTestCase"); + } + + static void TearDownTestCase() { + g_events->push_back("ListenerTest::TearDownTestCase"); + } + + virtual void SetUp() { + g_events->push_back("ListenerTest::SetUp"); + } + + virtual void TearDown() { + g_events->push_back("ListenerTest::TearDown"); + } +}; + +TEST_F(ListenerTest, DoesFoo) { + // Test execution order within a test case is not guaranteed so we are not + // recording the test name. + g_events->push_back("ListenerTest::* Test Body"); + SUCCEED(); // Triggers OnTestPartResult. +} + +TEST_F(ListenerTest, DoesBar) { + g_events->push_back("ListenerTest::* Test Body"); + SUCCEED(); // Triggers OnTestPartResult. +} + +} // namespace internal + +} // namespace testing + +using ::testing::internal::EnvironmentInvocationCatcher; +using ::testing::internal::EventRecordingListener; + +void VerifyResults(const std::vector& data, + const char* const* expected_data, + size_t expected_data_size) { + const size_t actual_size = data.size(); + // If the following assertion fails, a new entry will be appended to + // data. Hence we save data.size() first. + EXPECT_EQ(expected_data_size, actual_size); + + // Compares the common prefix. + const size_t shorter_size = expected_data_size <= actual_size ? + expected_data_size : actual_size; + size_t i = 0; + for (; i < shorter_size; ++i) { + ASSERT_STREQ(expected_data[i], data[i].c_str()) + << "at position " << i; + } + + // Prints extra elements in the actual data. + for (; i < actual_size; ++i) { + printf(" Actual event #%lu: %s\n", + static_cast(i), data[i].c_str()); + } +} + +int main(int argc, char **argv) { + std::vector events; + g_events = &events; + InitGoogleTest(&argc, argv); + + UnitTest::GetInstance()->listeners().Append( + new EventRecordingListener("1st")); + UnitTest::GetInstance()->listeners().Append( + new EventRecordingListener("2nd")); + + AddGlobalTestEnvironment(new EnvironmentInvocationCatcher); + + GTEST_CHECK_(events.size() == 0) + << "AddGlobalTestEnvironment should not generate any events itself."; + + ::testing::GTEST_FLAG(repeat) = 2; + int ret_val = RUN_ALL_TESTS(); + + const char* const expected_events[] = { + "1st.OnTestProgramStart", + "2nd.OnTestProgramStart", + "1st.OnTestIterationStart(0)", + "2nd.OnTestIterationStart(0)", + "1st.OnEnvironmentsSetUpStart", + "2nd.OnEnvironmentsSetUpStart", + "Environment::SetUp", + "2nd.OnEnvironmentsSetUpEnd", + "1st.OnEnvironmentsSetUpEnd", + "1st.OnTestCaseStart", + "2nd.OnTestCaseStart", + "ListenerTest::SetUpTestCase", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "ListenerTest::TearDownTestCase", + "2nd.OnTestCaseEnd", + "1st.OnTestCaseEnd", + "1st.OnEnvironmentsTearDownStart", + "2nd.OnEnvironmentsTearDownStart", + "Environment::TearDown", + "2nd.OnEnvironmentsTearDownEnd", + "1st.OnEnvironmentsTearDownEnd", + "2nd.OnTestIterationEnd(0)", + "1st.OnTestIterationEnd(0)", + "1st.OnTestIterationStart(1)", + "2nd.OnTestIterationStart(1)", + "1st.OnEnvironmentsSetUpStart", + "2nd.OnEnvironmentsSetUpStart", + "Environment::SetUp", + "2nd.OnEnvironmentsSetUpEnd", + "1st.OnEnvironmentsSetUpEnd", + "1st.OnTestCaseStart", + "2nd.OnTestCaseStart", + "ListenerTest::SetUpTestCase", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "ListenerTest::TearDownTestCase", + "2nd.OnTestCaseEnd", + "1st.OnTestCaseEnd", + "1st.OnEnvironmentsTearDownStart", + "2nd.OnEnvironmentsTearDownStart", + "Environment::TearDown", + "2nd.OnEnvironmentsTearDownEnd", + "1st.OnEnvironmentsTearDownEnd", + "2nd.OnTestIterationEnd(1)", + "1st.OnTestIterationEnd(1)", + "2nd.OnTestProgramEnd", + "1st.OnTestProgramEnd" + }; + VerifyResults(events, + expected_events, + sizeof(expected_events)/sizeof(expected_events[0])); + + // We need to check manually for ad hoc test failures that happen after + // RUN_ALL_TESTS finishes. + if (UnitTest::GetInstance()->Failed()) + ret_val = 1; + + return ret_val; +} diff --git a/googletest/test/googletest-shuffle-test.py b/googletest/test/googletest-shuffle-test.py new file mode 100755 index 00000000..5ae96552 --- /dev/null +++ b/googletest/test/googletest-shuffle-test.py @@ -0,0 +1,325 @@ +#!/usr/bin/env python +# +# Copyright 2009 Google Inc. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Verifies that test shuffling works.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import gtest_test_utils + +# Command to run the googletest-shuffle-test_ program. +COMMAND = gtest_test_utils.GetTestExecutablePath('googletest-shuffle-test_') + +# The environment variables for test sharding. +TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' +SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' + +TEST_FILTER = 'A*.A:A*.B:C*' + +ALL_TESTS = [] +ACTIVE_TESTS = [] +FILTERED_TESTS = [] +SHARDED_TESTS = [] + +SHUFFLED_ALL_TESTS = [] +SHUFFLED_ACTIVE_TESTS = [] +SHUFFLED_FILTERED_TESTS = [] +SHUFFLED_SHARDED_TESTS = [] + + +def AlsoRunDisabledTestsFlag(): + return '--gtest_also_run_disabled_tests' + + +def FilterFlag(test_filter): + return '--gtest_filter=%s' % (test_filter,) + + +def RepeatFlag(n): + return '--gtest_repeat=%s' % (n,) + + +def ShuffleFlag(): + return '--gtest_shuffle' + + +def RandomSeedFlag(n): + return '--gtest_random_seed=%s' % (n,) + + +def RunAndReturnOutput(extra_env, args): + """Runs the test program and returns its output.""" + + environ_copy = os.environ.copy() + environ_copy.update(extra_env) + + return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy).output + + +def GetTestsForAllIterations(extra_env, args): + """Runs the test program and returns a list of test lists. + + Args: + extra_env: a map from environment variables to their values + args: command line flags to pass to googletest-shuffle-test_ + + Returns: + A list where the i-th element is the list of tests run in the i-th + test iteration. + """ + + test_iterations = [] + for line in RunAndReturnOutput(extra_env, args).split('\n'): + if line.startswith('----'): + tests = [] + test_iterations.append(tests) + elif line.strip(): + tests.append(line.strip()) # 'TestCaseName.TestName' + + return test_iterations + + +def GetTestCases(tests): + """Returns a list of test cases in the given full test names. + + Args: + tests: a list of full test names + + Returns: + A list of test cases from 'tests', in their original order. + Consecutive duplicates are removed. + """ + + test_cases = [] + for test in tests: + test_case = test.split('.')[0] + if not test_case in test_cases: + test_cases.append(test_case) + + return test_cases + + +def CalculateTestLists(): + """Calculates the list of tests run under different flags.""" + + if not ALL_TESTS: + ALL_TESTS.extend( + GetTestsForAllIterations({}, [AlsoRunDisabledTestsFlag()])[0]) + + if not ACTIVE_TESTS: + ACTIVE_TESTS.extend(GetTestsForAllIterations({}, [])[0]) + + if not FILTERED_TESTS: + FILTERED_TESTS.extend( + GetTestsForAllIterations({}, [FilterFlag(TEST_FILTER)])[0]) + + if not SHARDED_TESTS: + SHARDED_TESTS.extend( + GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [])[0]) + + if not SHUFFLED_ALL_TESTS: + SHUFFLED_ALL_TESTS.extend(GetTestsForAllIterations( + {}, [AlsoRunDisabledTestsFlag(), ShuffleFlag(), RandomSeedFlag(1)])[0]) + + if not SHUFFLED_ACTIVE_TESTS: + SHUFFLED_ACTIVE_TESTS.extend(GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1)])[0]) + + if not SHUFFLED_FILTERED_TESTS: + SHUFFLED_FILTERED_TESTS.extend(GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), FilterFlag(TEST_FILTER)])[0]) + + if not SHUFFLED_SHARDED_TESTS: + SHUFFLED_SHARDED_TESTS.extend( + GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [ShuffleFlag(), RandomSeedFlag(1)])[0]) + + +class GTestShuffleUnitTest(gtest_test_utils.TestCase): + """Tests test shuffling.""" + + def setUp(self): + CalculateTestLists() + + def testShufflePreservesNumberOfTests(self): + self.assertEqual(len(ALL_TESTS), len(SHUFFLED_ALL_TESTS)) + self.assertEqual(len(ACTIVE_TESTS), len(SHUFFLED_ACTIVE_TESTS)) + self.assertEqual(len(FILTERED_TESTS), len(SHUFFLED_FILTERED_TESTS)) + self.assertEqual(len(SHARDED_TESTS), len(SHUFFLED_SHARDED_TESTS)) + + def testShuffleChangesTestOrder(self): + self.assert_(SHUFFLED_ALL_TESTS != ALL_TESTS, SHUFFLED_ALL_TESTS) + self.assert_(SHUFFLED_ACTIVE_TESTS != ACTIVE_TESTS, SHUFFLED_ACTIVE_TESTS) + self.assert_(SHUFFLED_FILTERED_TESTS != FILTERED_TESTS, + SHUFFLED_FILTERED_TESTS) + self.assert_(SHUFFLED_SHARDED_TESTS != SHARDED_TESTS, + SHUFFLED_SHARDED_TESTS) + + def testShuffleChangesTestCaseOrder(self): + self.assert_(GetTestCases(SHUFFLED_ALL_TESTS) != GetTestCases(ALL_TESTS), + GetTestCases(SHUFFLED_ALL_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_ACTIVE_TESTS) != GetTestCases(ACTIVE_TESTS), + GetTestCases(SHUFFLED_ACTIVE_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_FILTERED_TESTS) != GetTestCases(FILTERED_TESTS), + GetTestCases(SHUFFLED_FILTERED_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_SHARDED_TESTS) != GetTestCases(SHARDED_TESTS), + GetTestCases(SHUFFLED_SHARDED_TESTS)) + + def testShuffleDoesNotRepeatTest(self): + for test in SHUFFLED_ALL_TESTS: + self.assertEqual(1, SHUFFLED_ALL_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_ACTIVE_TESTS: + self.assertEqual(1, SHUFFLED_ACTIVE_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_FILTERED_TESTS: + self.assertEqual(1, SHUFFLED_FILTERED_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_SHARDED_TESTS: + self.assertEqual(1, SHUFFLED_SHARDED_TESTS.count(test), + '%s appears more than once' % (test,)) + + def testShuffleDoesNotCreateNewTest(self): + for test in SHUFFLED_ALL_TESTS: + self.assert_(test in ALL_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_ACTIVE_TESTS: + self.assert_(test in ACTIVE_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_FILTERED_TESTS: + self.assert_(test in FILTERED_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_SHARDED_TESTS: + self.assert_(test in SHARDED_TESTS, '%s is an invalid test' % (test,)) + + def testShuffleIncludesAllTests(self): + for test in ALL_TESTS: + self.assert_(test in SHUFFLED_ALL_TESTS, '%s is missing' % (test,)) + for test in ACTIVE_TESTS: + self.assert_(test in SHUFFLED_ACTIVE_TESTS, '%s is missing' % (test,)) + for test in FILTERED_TESTS: + self.assert_(test in SHUFFLED_FILTERED_TESTS, '%s is missing' % (test,)) + for test in SHARDED_TESTS: + self.assert_(test in SHUFFLED_SHARDED_TESTS, '%s is missing' % (test,)) + + def testShuffleLeavesDeathTestsAtFront(self): + non_death_test_found = False + for test in SHUFFLED_ACTIVE_TESTS: + if 'DeathTest.' in test: + self.assert_(not non_death_test_found, + '%s appears after a non-death test' % (test,)) + else: + non_death_test_found = True + + def _VerifyTestCasesDoNotInterleave(self, tests): + test_cases = [] + for test in tests: + [test_case, _] = test.split('.') + if test_cases and test_cases[-1] != test_case: + test_cases.append(test_case) + self.assertEqual(1, test_cases.count(test_case), + 'Test case %s is not grouped together in %s' % + (test_case, tests)) + + def testShuffleDoesNotInterleaveTestCases(self): + self._VerifyTestCasesDoNotInterleave(SHUFFLED_ALL_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_ACTIVE_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_FILTERED_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_SHARDED_TESTS) + + def testShuffleRestoresOrderAfterEachIteration(self): + # Get the test lists in all 3 iterations, using random seed 1, 2, + # and 3 respectively. Google Test picks a different seed in each + # iteration, and this test depends on the current implementation + # picking successive numbers. This dependency is not ideal, but + # makes the test much easier to write. + [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( + GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) + + # Make sure running the tests with random seed 1 gets the same + # order as in iteration 1 above. + [tests_with_seed1] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1)]) + self.assertEqual(tests_in_iteration1, tests_with_seed1) + + # Make sure running the tests with random seed 2 gets the same + # order as in iteration 2 above. Success means that Google Test + # correctly restores the test order before re-shuffling at the + # beginning of iteration 2. + [tests_with_seed2] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(2)]) + self.assertEqual(tests_in_iteration2, tests_with_seed2) + + # Make sure running the tests with random seed 3 gets the same + # order as in iteration 3 above. Success means that Google Test + # correctly restores the test order before re-shuffling at the + # beginning of iteration 3. + [tests_with_seed3] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(3)]) + self.assertEqual(tests_in_iteration3, tests_with_seed3) + + def testShuffleGeneratesNewOrderInEachIteration(self): + [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( + GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) + + self.assert_(tests_in_iteration1 != tests_in_iteration2, + tests_in_iteration1) + self.assert_(tests_in_iteration1 != tests_in_iteration3, + tests_in_iteration1) + self.assert_(tests_in_iteration2 != tests_in_iteration3, + tests_in_iteration2) + + def testShuffleShardedTestsPreservesPartition(self): + # If we run M tests on N shards, the same M tests should be run in + # total, regardless of the random seeds used by the shards. + [tests1] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '0'}, + [ShuffleFlag(), RandomSeedFlag(1)]) + [tests2] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [ShuffleFlag(), RandomSeedFlag(20)]) + [tests3] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '2'}, + [ShuffleFlag(), RandomSeedFlag(25)]) + sorted_sharded_tests = tests1 + tests2 + tests3 + sorted_sharded_tests.sort() + sorted_active_tests = [] + sorted_active_tests.extend(ACTIVE_TESTS) + sorted_active_tests.sort() + self.assertEqual(sorted_active_tests, sorted_sharded_tests) + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/googletest/test/googletest-shuffle-test_.cc b/googletest/test/googletest-shuffle-test_.cc new file mode 100644 index 00000000..6fb441bd --- /dev/null +++ b/googletest/test/googletest-shuffle-test_.cc @@ -0,0 +1,103 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Verifies that test shuffling works. + +#include "gtest/gtest.h" + +namespace { + +using ::testing::EmptyTestEventListener; +using ::testing::InitGoogleTest; +using ::testing::Message; +using ::testing::Test; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::UnitTest; +using ::testing::internal::scoped_ptr; + +// The test methods are empty, as the sole purpose of this program is +// to print the test names before/after shuffling. + +class A : public Test {}; +TEST_F(A, A) {} +TEST_F(A, B) {} + +TEST(ADeathTest, A) {} +TEST(ADeathTest, B) {} +TEST(ADeathTest, C) {} + +TEST(B, A) {} +TEST(B, B) {} +TEST(B, C) {} +TEST(B, DISABLED_D) {} +TEST(B, DISABLED_E) {} + +TEST(BDeathTest, A) {} +TEST(BDeathTest, B) {} + +TEST(C, A) {} +TEST(C, B) {} +TEST(C, C) {} +TEST(C, DISABLED_D) {} + +TEST(CDeathTest, A) {} + +TEST(DISABLED_D, A) {} +TEST(DISABLED_D, DISABLED_B) {} + +// This printer prints the full test names only, starting each test +// iteration with a "----" marker. +class TestNamePrinter : public EmptyTestEventListener { + public: + virtual void OnTestIterationStart(const UnitTest& /* unit_test */, + int /* iteration */) { + printf("----\n"); + } + + virtual void OnTestStart(const TestInfo& test_info) { + printf("%s.%s\n", test_info.test_case_name(), test_info.name()); + } +}; + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + // Replaces the default printer with TestNamePrinter, which prints + // the test name only. + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + delete listeners.Release(listeners.default_result_printer()); + listeners.Append(new TestNamePrinter); + + return RUN_ALL_TESTS(); +} diff --git a/googletest/test/gtest_catch_exceptions_test.py b/googletest/test/gtest_catch_exceptions_test.py deleted file mode 100755 index 760f914f..00000000 --- a/googletest/test/gtest_catch_exceptions_test.py +++ /dev/null @@ -1,235 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2010 Google Inc. All Rights Reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Tests Google Test's exception catching behavior. - -This script invokes gtest_catch_exceptions_test_ and -gtest_catch_exceptions_ex_test_ (programs written with -Google Test) and verifies their output. -""" - -__author__ = 'vladl@google.com (Vlad Losev)' - -import gtest_test_utils - -# Constants. -FLAG_PREFIX = '--gtest_' -LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests' -NO_CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions=0' -FILTER_FLAG = FLAG_PREFIX + 'filter' - -# Path to the gtest_catch_exceptions_ex_test_ binary, compiled with -# exceptions enabled. -EX_EXE_PATH = gtest_test_utils.GetTestExecutablePath( - 'gtest_catch_exceptions_ex_test_') - -# Path to the gtest_catch_exceptions_test_ binary, compiled with -# exceptions disabled. -EXE_PATH = gtest_test_utils.GetTestExecutablePath( - 'gtest_catch_exceptions_no_ex_test_') - -environ = gtest_test_utils.environ -SetEnvVar = gtest_test_utils.SetEnvVar - -# Tests in this file run a Google-Test-based test program and expect it -# to terminate prematurely. Therefore they are incompatible with -# the premature-exit-file protocol by design. Unset the -# premature-exit filepath to prevent Google Test from creating -# the file. -SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None) - -TEST_LIST = gtest_test_utils.Subprocess( - [EXE_PATH, LIST_TESTS_FLAG], env=environ).output - -SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST - -if SUPPORTS_SEH_EXCEPTIONS: - BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH], env=environ).output - -EX_BINARY_OUTPUT = gtest_test_utils.Subprocess( - [EX_EXE_PATH], env=environ).output - - -# The tests. -if SUPPORTS_SEH_EXCEPTIONS: - # pylint:disable-msg=C6302 - class CatchSehExceptionsTest(gtest_test_utils.TestCase): - """Tests exception-catching behavior.""" - - - def TestSehExceptions(self, test_output): - self.assert_('SEH exception with code 0x2a thrown ' - 'in the test fixture\'s constructor' - in test_output) - self.assert_('SEH exception with code 0x2a thrown ' - 'in the test fixture\'s destructor' - in test_output) - self.assert_('SEH exception with code 0x2a thrown in SetUpTestCase()' - in test_output) - self.assert_('SEH exception with code 0x2a thrown in TearDownTestCase()' - in test_output) - self.assert_('SEH exception with code 0x2a thrown in SetUp()' - in test_output) - self.assert_('SEH exception with code 0x2a thrown in TearDown()' - in test_output) - self.assert_('SEH exception with code 0x2a thrown in the test body' - in test_output) - - def testCatchesSehExceptionsWithCxxExceptionsEnabled(self): - self.TestSehExceptions(EX_BINARY_OUTPUT) - - def testCatchesSehExceptionsWithCxxExceptionsDisabled(self): - self.TestSehExceptions(BINARY_OUTPUT) - - -class CatchCxxExceptionsTest(gtest_test_utils.TestCase): - """Tests C++ exception-catching behavior. - - Tests in this test case verify that: - * C++ exceptions are caught and logged as C++ (not SEH) exceptions - * Exception thrown affect the remainder of the test work flow in the - expected manner. - """ - - def testCatchesCxxExceptionsInFixtureConstructor(self): - self.assert_('C++ exception with description ' - '"Standard C++ exception" thrown ' - 'in the test fixture\'s constructor' - in EX_BINARY_OUTPUT) - self.assert_('unexpected' not in EX_BINARY_OUTPUT, - 'This failure belongs in this test only if ' - '"CxxExceptionInConstructorTest" (no quotes) ' - 'appears on the same line as words "called unexpectedly"') - - if ('CxxExceptionInDestructorTest.ThrowsExceptionInDestructor' in - EX_BINARY_OUTPUT): - - def testCatchesCxxExceptionsInFixtureDestructor(self): - self.assert_('C++ exception with description ' - '"Standard C++ exception" thrown ' - 'in the test fixture\'s destructor' - in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInDestructorTest::TearDownTestCase() ' - 'called as expected.' - in EX_BINARY_OUTPUT) - - def testCatchesCxxExceptionsInSetUpTestCase(self): - self.assert_('C++ exception with description "Standard C++ exception"' - ' thrown in SetUpTestCase()' - in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInConstructorTest::TearDownTestCase() ' - 'called as expected.' - in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInSetUpTestCaseTest constructor ' - 'called as expected.' - in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInSetUpTestCaseTest destructor ' - 'called as expected.' - in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInSetUpTestCaseTest::SetUp() ' - 'called as expected.' - in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInSetUpTestCaseTest::TearDown() ' - 'called as expected.' - in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInSetUpTestCaseTest test body ' - 'called as expected.' - in EX_BINARY_OUTPUT) - - def testCatchesCxxExceptionsInTearDownTestCase(self): - self.assert_('C++ exception with description "Standard C++ exception"' - ' thrown in TearDownTestCase()' - in EX_BINARY_OUTPUT) - - def testCatchesCxxExceptionsInSetUp(self): - self.assert_('C++ exception with description "Standard C++ exception"' - ' thrown in SetUp()' - in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInSetUpTest::TearDownTestCase() ' - 'called as expected.' - in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInSetUpTest destructor ' - 'called as expected.' - in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInSetUpTest::TearDown() ' - 'called as expected.' - in EX_BINARY_OUTPUT) - self.assert_('unexpected' not in EX_BINARY_OUTPUT, - 'This failure belongs in this test only if ' - '"CxxExceptionInSetUpTest" (no quotes) ' - 'appears on the same line as words "called unexpectedly"') - - def testCatchesCxxExceptionsInTearDown(self): - self.assert_('C++ exception with description "Standard C++ exception"' - ' thrown in TearDown()' - in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInTearDownTest::TearDownTestCase() ' - 'called as expected.' - in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInTearDownTest destructor ' - 'called as expected.' - in EX_BINARY_OUTPUT) - - def testCatchesCxxExceptionsInTestBody(self): - self.assert_('C++ exception with description "Standard C++ exception"' - ' thrown in the test body' - in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInTestBodyTest::TearDownTestCase() ' - 'called as expected.' - in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInTestBodyTest destructor ' - 'called as expected.' - in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInTestBodyTest::TearDown() ' - 'called as expected.' - in EX_BINARY_OUTPUT) - - def testCatchesNonStdCxxExceptions(self): - self.assert_('Unknown C++ exception thrown in the test body' - in EX_BINARY_OUTPUT) - - def testUnhandledCxxExceptionsAbortTheProgram(self): - # Filters out SEH exception tests on Windows. Unhandled SEH exceptions - # cause tests to show pop-up windows there. - FITLER_OUT_SEH_TESTS_FLAG = FILTER_FLAG + '=-*Seh*' - # By default, Google Test doesn't catch the exceptions. - uncaught_exceptions_ex_binary_output = gtest_test_utils.Subprocess( - [EX_EXE_PATH, - NO_CATCH_EXCEPTIONS_FLAG, - FITLER_OUT_SEH_TESTS_FLAG], - env=environ).output - - self.assert_('Unhandled C++ exception terminating the program' - in uncaught_exceptions_ex_binary_output) - self.assert_('unexpected' not in uncaught_exceptions_ex_binary_output) - - -if __name__ == '__main__': - gtest_test_utils.Main() diff --git a/googletest/test/gtest_catch_exceptions_test_.cc b/googletest/test/gtest_catch_exceptions_test_.cc deleted file mode 100644 index c6d953c0..00000000 --- a/googletest/test/gtest_catch_exceptions_test_.cc +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: vladl@google.com (Vlad Losev) -// -// Tests for Google Test itself. Tests in this file throw C++ or SEH -// exceptions, and the output is verified by gtest_catch_exceptions_test.py. - -#include "gtest/gtest.h" - -#include // NOLINT -#include // For exit(). - -#if GTEST_HAS_SEH -# include -#endif - -#if GTEST_HAS_EXCEPTIONS -# include // For set_terminate(). -# include -#endif - -using testing::Test; - -#if GTEST_HAS_SEH - -class SehExceptionInConstructorTest : public Test { - public: - SehExceptionInConstructorTest() { RaiseException(42, 0, 0, NULL); } -}; - -TEST_F(SehExceptionInConstructorTest, ThrowsExceptionInConstructor) {} - -class SehExceptionInDestructorTest : public Test { - public: - ~SehExceptionInDestructorTest() { RaiseException(42, 0, 0, NULL); } -}; - -TEST_F(SehExceptionInDestructorTest, ThrowsExceptionInDestructor) {} - -class SehExceptionInSetUpTestCaseTest : public Test { - public: - static void SetUpTestCase() { RaiseException(42, 0, 0, NULL); } -}; - -TEST_F(SehExceptionInSetUpTestCaseTest, ThrowsExceptionInSetUpTestCase) {} - -class SehExceptionInTearDownTestCaseTest : public Test { - public: - static void TearDownTestCase() { RaiseException(42, 0, 0, NULL); } -}; - -TEST_F(SehExceptionInTearDownTestCaseTest, ThrowsExceptionInTearDownTestCase) {} - -class SehExceptionInSetUpTest : public Test { - protected: - virtual void SetUp() { RaiseException(42, 0, 0, NULL); } -}; - -TEST_F(SehExceptionInSetUpTest, ThrowsExceptionInSetUp) {} - -class SehExceptionInTearDownTest : public Test { - protected: - virtual void TearDown() { RaiseException(42, 0, 0, NULL); } -}; - -TEST_F(SehExceptionInTearDownTest, ThrowsExceptionInTearDown) {} - -TEST(SehExceptionTest, ThrowsSehException) { - RaiseException(42, 0, 0, NULL); -} - -#endif // GTEST_HAS_SEH - -#if GTEST_HAS_EXCEPTIONS - -class CxxExceptionInConstructorTest : public Test { - public: - CxxExceptionInConstructorTest() { - // Without this macro VC++ complains about unreachable code at the end of - // the constructor. - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( - throw std::runtime_error("Standard C++ exception")); - } - - static void TearDownTestCase() { - printf("%s", - "CxxExceptionInConstructorTest::TearDownTestCase() " - "called as expected.\n"); - } - - protected: - ~CxxExceptionInConstructorTest() { - ADD_FAILURE() << "CxxExceptionInConstructorTest destructor " - << "called unexpectedly."; - } - - virtual void SetUp() { - ADD_FAILURE() << "CxxExceptionInConstructorTest::SetUp() " - << "called unexpectedly."; - } - - virtual void TearDown() { - ADD_FAILURE() << "CxxExceptionInConstructorTest::TearDown() " - << "called unexpectedly."; - } -}; - -TEST_F(CxxExceptionInConstructorTest, ThrowsExceptionInConstructor) { - ADD_FAILURE() << "CxxExceptionInConstructorTest test body " - << "called unexpectedly."; -} - -// Exceptions in destructors are not supported in C++11. -#if !GTEST_LANG_CXX11 -class CxxExceptionInDestructorTest : public Test { - public: - static void TearDownTestCase() { - printf("%s", - "CxxExceptionInDestructorTest::TearDownTestCase() " - "called as expected.\n"); - } - - protected: - ~CxxExceptionInDestructorTest() { - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( - throw std::runtime_error("Standard C++ exception")); - } -}; - -TEST_F(CxxExceptionInDestructorTest, ThrowsExceptionInDestructor) {} -#endif // C++11 mode - -class CxxExceptionInSetUpTestCaseTest : public Test { - public: - CxxExceptionInSetUpTestCaseTest() { - printf("%s", - "CxxExceptionInSetUpTestCaseTest constructor " - "called as expected.\n"); - } - - static void SetUpTestCase() { - throw std::runtime_error("Standard C++ exception"); - } - - static void TearDownTestCase() { - printf("%s", - "CxxExceptionInSetUpTestCaseTest::TearDownTestCase() " - "called as expected.\n"); - } - - protected: - ~CxxExceptionInSetUpTestCaseTest() { - printf("%s", - "CxxExceptionInSetUpTestCaseTest destructor " - "called as expected.\n"); - } - - virtual void SetUp() { - printf("%s", - "CxxExceptionInSetUpTestCaseTest::SetUp() " - "called as expected.\n"); - } - - virtual void TearDown() { - printf("%s", - "CxxExceptionInSetUpTestCaseTest::TearDown() " - "called as expected.\n"); - } -}; - -TEST_F(CxxExceptionInSetUpTestCaseTest, ThrowsExceptionInSetUpTestCase) { - printf("%s", - "CxxExceptionInSetUpTestCaseTest test body " - "called as expected.\n"); -} - -class CxxExceptionInTearDownTestCaseTest : public Test { - public: - static void TearDownTestCase() { - throw std::runtime_error("Standard C++ exception"); - } -}; - -TEST_F(CxxExceptionInTearDownTestCaseTest, ThrowsExceptionInTearDownTestCase) {} - -class CxxExceptionInSetUpTest : public Test { - public: - static void TearDownTestCase() { - printf("%s", - "CxxExceptionInSetUpTest::TearDownTestCase() " - "called as expected.\n"); - } - - protected: - ~CxxExceptionInSetUpTest() { - printf("%s", - "CxxExceptionInSetUpTest destructor " - "called as expected.\n"); - } - - virtual void SetUp() { throw std::runtime_error("Standard C++ exception"); } - - virtual void TearDown() { - printf("%s", - "CxxExceptionInSetUpTest::TearDown() " - "called as expected.\n"); - } -}; - -TEST_F(CxxExceptionInSetUpTest, ThrowsExceptionInSetUp) { - ADD_FAILURE() << "CxxExceptionInSetUpTest test body " - << "called unexpectedly."; -} - -class CxxExceptionInTearDownTest : public Test { - public: - static void TearDownTestCase() { - printf("%s", - "CxxExceptionInTearDownTest::TearDownTestCase() " - "called as expected.\n"); - } - - protected: - ~CxxExceptionInTearDownTest() { - printf("%s", - "CxxExceptionInTearDownTest destructor " - "called as expected.\n"); - } - - virtual void TearDown() { - throw std::runtime_error("Standard C++ exception"); - } -}; - -TEST_F(CxxExceptionInTearDownTest, ThrowsExceptionInTearDown) {} - -class CxxExceptionInTestBodyTest : public Test { - public: - static void TearDownTestCase() { - printf("%s", - "CxxExceptionInTestBodyTest::TearDownTestCase() " - "called as expected.\n"); - } - - protected: - ~CxxExceptionInTestBodyTest() { - printf("%s", - "CxxExceptionInTestBodyTest destructor " - "called as expected.\n"); - } - - virtual void TearDown() { - printf("%s", - "CxxExceptionInTestBodyTest::TearDown() " - "called as expected.\n"); - } -}; - -TEST_F(CxxExceptionInTestBodyTest, ThrowsStdCxxException) { - throw std::runtime_error("Standard C++ exception"); -} - -TEST(CxxExceptionTest, ThrowsNonStdCxxException) { - throw "C-string"; -} - -// This terminate handler aborts the program using exit() rather than abort(). -// This avoids showing pop-ups on Windows systems and core dumps on Unix-like -// ones. -void TerminateHandler() { - fprintf(stderr, "%s\n", "Unhandled C++ exception terminating the program."); - fflush(NULL); - exit(3); -} - -#endif // GTEST_HAS_EXCEPTIONS - -int main(int argc, char** argv) { -#if GTEST_HAS_EXCEPTIONS - std::set_terminate(&TerminateHandler); -#endif - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/googletest/test/gtest_shuffle_test.py b/googletest/test/gtest_shuffle_test.py deleted file mode 100755 index 30d0303d..00000000 --- a/googletest/test/gtest_shuffle_test.py +++ /dev/null @@ -1,325 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2009 Google Inc. All Rights Reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Verifies that test shuffling works.""" - -__author__ = 'wan@google.com (Zhanyong Wan)' - -import os -import gtest_test_utils - -# Command to run the gtest_shuffle_test_ program. -COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_shuffle_test_') - -# The environment variables for test sharding. -TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' -SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' - -TEST_FILTER = 'A*.A:A*.B:C*' - -ALL_TESTS = [] -ACTIVE_TESTS = [] -FILTERED_TESTS = [] -SHARDED_TESTS = [] - -SHUFFLED_ALL_TESTS = [] -SHUFFLED_ACTIVE_TESTS = [] -SHUFFLED_FILTERED_TESTS = [] -SHUFFLED_SHARDED_TESTS = [] - - -def AlsoRunDisabledTestsFlag(): - return '--gtest_also_run_disabled_tests' - - -def FilterFlag(test_filter): - return '--gtest_filter=%s' % (test_filter,) - - -def RepeatFlag(n): - return '--gtest_repeat=%s' % (n,) - - -def ShuffleFlag(): - return '--gtest_shuffle' - - -def RandomSeedFlag(n): - return '--gtest_random_seed=%s' % (n,) - - -def RunAndReturnOutput(extra_env, args): - """Runs the test program and returns its output.""" - - environ_copy = os.environ.copy() - environ_copy.update(extra_env) - - return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy).output - - -def GetTestsForAllIterations(extra_env, args): - """Runs the test program and returns a list of test lists. - - Args: - extra_env: a map from environment variables to their values - args: command line flags to pass to gtest_shuffle_test_ - - Returns: - A list where the i-th element is the list of tests run in the i-th - test iteration. - """ - - test_iterations = [] - for line in RunAndReturnOutput(extra_env, args).split('\n'): - if line.startswith('----'): - tests = [] - test_iterations.append(tests) - elif line.strip(): - tests.append(line.strip()) # 'TestCaseName.TestName' - - return test_iterations - - -def GetTestCases(tests): - """Returns a list of test cases in the given full test names. - - Args: - tests: a list of full test names - - Returns: - A list of test cases from 'tests', in their original order. - Consecutive duplicates are removed. - """ - - test_cases = [] - for test in tests: - test_case = test.split('.')[0] - if not test_case in test_cases: - test_cases.append(test_case) - - return test_cases - - -def CalculateTestLists(): - """Calculates the list of tests run under different flags.""" - - if not ALL_TESTS: - ALL_TESTS.extend( - GetTestsForAllIterations({}, [AlsoRunDisabledTestsFlag()])[0]) - - if not ACTIVE_TESTS: - ACTIVE_TESTS.extend(GetTestsForAllIterations({}, [])[0]) - - if not FILTERED_TESTS: - FILTERED_TESTS.extend( - GetTestsForAllIterations({}, [FilterFlag(TEST_FILTER)])[0]) - - if not SHARDED_TESTS: - SHARDED_TESTS.extend( - GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', - SHARD_INDEX_ENV_VAR: '1'}, - [])[0]) - - if not SHUFFLED_ALL_TESTS: - SHUFFLED_ALL_TESTS.extend(GetTestsForAllIterations( - {}, [AlsoRunDisabledTestsFlag(), ShuffleFlag(), RandomSeedFlag(1)])[0]) - - if not SHUFFLED_ACTIVE_TESTS: - SHUFFLED_ACTIVE_TESTS.extend(GetTestsForAllIterations( - {}, [ShuffleFlag(), RandomSeedFlag(1)])[0]) - - if not SHUFFLED_FILTERED_TESTS: - SHUFFLED_FILTERED_TESTS.extend(GetTestsForAllIterations( - {}, [ShuffleFlag(), RandomSeedFlag(1), FilterFlag(TEST_FILTER)])[0]) - - if not SHUFFLED_SHARDED_TESTS: - SHUFFLED_SHARDED_TESTS.extend( - GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', - SHARD_INDEX_ENV_VAR: '1'}, - [ShuffleFlag(), RandomSeedFlag(1)])[0]) - - -class GTestShuffleUnitTest(gtest_test_utils.TestCase): - """Tests test shuffling.""" - - def setUp(self): - CalculateTestLists() - - def testShufflePreservesNumberOfTests(self): - self.assertEqual(len(ALL_TESTS), len(SHUFFLED_ALL_TESTS)) - self.assertEqual(len(ACTIVE_TESTS), len(SHUFFLED_ACTIVE_TESTS)) - self.assertEqual(len(FILTERED_TESTS), len(SHUFFLED_FILTERED_TESTS)) - self.assertEqual(len(SHARDED_TESTS), len(SHUFFLED_SHARDED_TESTS)) - - def testShuffleChangesTestOrder(self): - self.assert_(SHUFFLED_ALL_TESTS != ALL_TESTS, SHUFFLED_ALL_TESTS) - self.assert_(SHUFFLED_ACTIVE_TESTS != ACTIVE_TESTS, SHUFFLED_ACTIVE_TESTS) - self.assert_(SHUFFLED_FILTERED_TESTS != FILTERED_TESTS, - SHUFFLED_FILTERED_TESTS) - self.assert_(SHUFFLED_SHARDED_TESTS != SHARDED_TESTS, - SHUFFLED_SHARDED_TESTS) - - def testShuffleChangesTestCaseOrder(self): - self.assert_(GetTestCases(SHUFFLED_ALL_TESTS) != GetTestCases(ALL_TESTS), - GetTestCases(SHUFFLED_ALL_TESTS)) - self.assert_( - GetTestCases(SHUFFLED_ACTIVE_TESTS) != GetTestCases(ACTIVE_TESTS), - GetTestCases(SHUFFLED_ACTIVE_TESTS)) - self.assert_( - GetTestCases(SHUFFLED_FILTERED_TESTS) != GetTestCases(FILTERED_TESTS), - GetTestCases(SHUFFLED_FILTERED_TESTS)) - self.assert_( - GetTestCases(SHUFFLED_SHARDED_TESTS) != GetTestCases(SHARDED_TESTS), - GetTestCases(SHUFFLED_SHARDED_TESTS)) - - def testShuffleDoesNotRepeatTest(self): - for test in SHUFFLED_ALL_TESTS: - self.assertEqual(1, SHUFFLED_ALL_TESTS.count(test), - '%s appears more than once' % (test,)) - for test in SHUFFLED_ACTIVE_TESTS: - self.assertEqual(1, SHUFFLED_ACTIVE_TESTS.count(test), - '%s appears more than once' % (test,)) - for test in SHUFFLED_FILTERED_TESTS: - self.assertEqual(1, SHUFFLED_FILTERED_TESTS.count(test), - '%s appears more than once' % (test,)) - for test in SHUFFLED_SHARDED_TESTS: - self.assertEqual(1, SHUFFLED_SHARDED_TESTS.count(test), - '%s appears more than once' % (test,)) - - def testShuffleDoesNotCreateNewTest(self): - for test in SHUFFLED_ALL_TESTS: - self.assert_(test in ALL_TESTS, '%s is an invalid test' % (test,)) - for test in SHUFFLED_ACTIVE_TESTS: - self.assert_(test in ACTIVE_TESTS, '%s is an invalid test' % (test,)) - for test in SHUFFLED_FILTERED_TESTS: - self.assert_(test in FILTERED_TESTS, '%s is an invalid test' % (test,)) - for test in SHUFFLED_SHARDED_TESTS: - self.assert_(test in SHARDED_TESTS, '%s is an invalid test' % (test,)) - - def testShuffleIncludesAllTests(self): - for test in ALL_TESTS: - self.assert_(test in SHUFFLED_ALL_TESTS, '%s is missing' % (test,)) - for test in ACTIVE_TESTS: - self.assert_(test in SHUFFLED_ACTIVE_TESTS, '%s is missing' % (test,)) - for test in FILTERED_TESTS: - self.assert_(test in SHUFFLED_FILTERED_TESTS, '%s is missing' % (test,)) - for test in SHARDED_TESTS: - self.assert_(test in SHUFFLED_SHARDED_TESTS, '%s is missing' % (test,)) - - def testShuffleLeavesDeathTestsAtFront(self): - non_death_test_found = False - for test in SHUFFLED_ACTIVE_TESTS: - if 'DeathTest.' in test: - self.assert_(not non_death_test_found, - '%s appears after a non-death test' % (test,)) - else: - non_death_test_found = True - - def _VerifyTestCasesDoNotInterleave(self, tests): - test_cases = [] - for test in tests: - [test_case, _] = test.split('.') - if test_cases and test_cases[-1] != test_case: - test_cases.append(test_case) - self.assertEqual(1, test_cases.count(test_case), - 'Test case %s is not grouped together in %s' % - (test_case, tests)) - - def testShuffleDoesNotInterleaveTestCases(self): - self._VerifyTestCasesDoNotInterleave(SHUFFLED_ALL_TESTS) - self._VerifyTestCasesDoNotInterleave(SHUFFLED_ACTIVE_TESTS) - self._VerifyTestCasesDoNotInterleave(SHUFFLED_FILTERED_TESTS) - self._VerifyTestCasesDoNotInterleave(SHUFFLED_SHARDED_TESTS) - - def testShuffleRestoresOrderAfterEachIteration(self): - # Get the test lists in all 3 iterations, using random seed 1, 2, - # and 3 respectively. Google Test picks a different seed in each - # iteration, and this test depends on the current implementation - # picking successive numbers. This dependency is not ideal, but - # makes the test much easier to write. - [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( - GetTestsForAllIterations( - {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) - - # Make sure running the tests with random seed 1 gets the same - # order as in iteration 1 above. - [tests_with_seed1] = GetTestsForAllIterations( - {}, [ShuffleFlag(), RandomSeedFlag(1)]) - self.assertEqual(tests_in_iteration1, tests_with_seed1) - - # Make sure running the tests with random seed 2 gets the same - # order as in iteration 2 above. Success means that Google Test - # correctly restores the test order before re-shuffling at the - # beginning of iteration 2. - [tests_with_seed2] = GetTestsForAllIterations( - {}, [ShuffleFlag(), RandomSeedFlag(2)]) - self.assertEqual(tests_in_iteration2, tests_with_seed2) - - # Make sure running the tests with random seed 3 gets the same - # order as in iteration 3 above. Success means that Google Test - # correctly restores the test order before re-shuffling at the - # beginning of iteration 3. - [tests_with_seed3] = GetTestsForAllIterations( - {}, [ShuffleFlag(), RandomSeedFlag(3)]) - self.assertEqual(tests_in_iteration3, tests_with_seed3) - - def testShuffleGeneratesNewOrderInEachIteration(self): - [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( - GetTestsForAllIterations( - {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) - - self.assert_(tests_in_iteration1 != tests_in_iteration2, - tests_in_iteration1) - self.assert_(tests_in_iteration1 != tests_in_iteration3, - tests_in_iteration1) - self.assert_(tests_in_iteration2 != tests_in_iteration3, - tests_in_iteration2) - - def testShuffleShardedTestsPreservesPartition(self): - # If we run M tests on N shards, the same M tests should be run in - # total, regardless of the random seeds used by the shards. - [tests1] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', - SHARD_INDEX_ENV_VAR: '0'}, - [ShuffleFlag(), RandomSeedFlag(1)]) - [tests2] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', - SHARD_INDEX_ENV_VAR: '1'}, - [ShuffleFlag(), RandomSeedFlag(20)]) - [tests3] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', - SHARD_INDEX_ENV_VAR: '2'}, - [ShuffleFlag(), RandomSeedFlag(25)]) - sorted_sharded_tests = tests1 + tests2 + tests3 - sorted_sharded_tests.sort() - sorted_active_tests = [] - sorted_active_tests.extend(ACTIVE_TESTS) - sorted_active_tests.sort() - self.assertEqual(sorted_active_tests, sorted_sharded_tests) - -if __name__ == '__main__': - gtest_test_utils.Main() diff --git a/googletest/test/gtest_shuffle_test_.cc b/googletest/test/gtest_shuffle_test_.cc deleted file mode 100644 index 6fb441bd..00000000 --- a/googletest/test/gtest_shuffle_test_.cc +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - -// Verifies that test shuffling works. - -#include "gtest/gtest.h" - -namespace { - -using ::testing::EmptyTestEventListener; -using ::testing::InitGoogleTest; -using ::testing::Message; -using ::testing::Test; -using ::testing::TestEventListeners; -using ::testing::TestInfo; -using ::testing::UnitTest; -using ::testing::internal::scoped_ptr; - -// The test methods are empty, as the sole purpose of this program is -// to print the test names before/after shuffling. - -class A : public Test {}; -TEST_F(A, A) {} -TEST_F(A, B) {} - -TEST(ADeathTest, A) {} -TEST(ADeathTest, B) {} -TEST(ADeathTest, C) {} - -TEST(B, A) {} -TEST(B, B) {} -TEST(B, C) {} -TEST(B, DISABLED_D) {} -TEST(B, DISABLED_E) {} - -TEST(BDeathTest, A) {} -TEST(BDeathTest, B) {} - -TEST(C, A) {} -TEST(C, B) {} -TEST(C, C) {} -TEST(C, DISABLED_D) {} - -TEST(CDeathTest, A) {} - -TEST(DISABLED_D, A) {} -TEST(DISABLED_D, DISABLED_B) {} - -// This printer prints the full test names only, starting each test -// iteration with a "----" marker. -class TestNamePrinter : public EmptyTestEventListener { - public: - virtual void OnTestIterationStart(const UnitTest& /* unit_test */, - int /* iteration */) { - printf("----\n"); - } - - virtual void OnTestStart(const TestInfo& test_info) { - printf("%s.%s\n", test_info.test_case_name(), test_info.name()); - } -}; - -} // namespace - -int main(int argc, char **argv) { - InitGoogleTest(&argc, argv); - - // Replaces the default printer with TestNamePrinter, which prints - // the test name only. - TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); - delete listeners.Release(listeners.default_result_printer()); - listeners.Append(new TestNamePrinter); - - return RUN_ALL_TESTS(); -} -- cgit v1.2.3