michael@0: // Copyright 2008, Google Inc. michael@0: // All rights reserved. michael@0: // michael@0: // Redistribution and use in source and binary forms, with or without michael@0: // modification, are permitted provided that the following conditions are michael@0: // met: michael@0: // michael@0: // * Redistributions of source code must retain the above copyright michael@0: // notice, this list of conditions and the following disclaimer. michael@0: // * Redistributions in binary form must reproduce the above michael@0: // copyright notice, this list of conditions and the following disclaimer michael@0: // in the documentation and/or other materials provided with the michael@0: // distribution. michael@0: // * Neither the name of Google Inc. nor the names of its michael@0: // contributors may be used to endorse or promote products derived from michael@0: // this software without specific prior written permission. michael@0: // michael@0: // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS michael@0: // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT michael@0: // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR michael@0: // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT michael@0: // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, michael@0: // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT michael@0: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, michael@0: // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY michael@0: // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT michael@0: // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE michael@0: // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: // michael@0: // Author: wan@google.com (Zhanyong Wan) michael@0: michael@0: // Tests the --gtest_repeat=number flag. michael@0: michael@0: #include michael@0: #include michael@0: #include "gtest/gtest.h" michael@0: michael@0: // Indicates that this translation unit is part of Google Test's michael@0: // implementation. It must come before gtest-internal-inl.h is michael@0: // included, or there will be a compiler error. This trick is to michael@0: // prevent a user from accidentally including gtest-internal-inl.h in michael@0: // his code. michael@0: #define GTEST_IMPLEMENTATION_ 1 michael@0: #include "src/gtest-internal-inl.h" michael@0: #undef GTEST_IMPLEMENTATION_ michael@0: michael@0: namespace testing { michael@0: michael@0: GTEST_DECLARE_string_(death_test_style); michael@0: GTEST_DECLARE_string_(filter); michael@0: GTEST_DECLARE_int32_(repeat); michael@0: michael@0: } // namespace testing michael@0: michael@0: using testing::GTEST_FLAG(death_test_style); michael@0: using testing::GTEST_FLAG(filter); michael@0: using testing::GTEST_FLAG(repeat); michael@0: michael@0: namespace { michael@0: michael@0: // We need this when we are testing Google Test itself and therefore michael@0: // cannot use Google Test assertions. michael@0: #define GTEST_CHECK_INT_EQ_(expected, actual) \ michael@0: do {\ michael@0: const int expected_val = (expected);\ michael@0: const int actual_val = (actual);\ michael@0: if (::testing::internal::IsTrue(expected_val != actual_val)) {\ michael@0: ::std::cout << "Value of: " #actual "\n"\ michael@0: << " Actual: " << actual_val << "\n"\ michael@0: << "Expected: " #expected "\n"\ michael@0: << "Which is: " << expected_val << "\n";\ michael@0: ::testing::internal::posix::Abort();\ michael@0: }\ michael@0: } while (::testing::internal::AlwaysFalse()) michael@0: michael@0: michael@0: // Used for verifying that global environment set-up and tear-down are michael@0: // inside the gtest_repeat loop. michael@0: michael@0: int g_environment_set_up_count = 0; michael@0: int g_environment_tear_down_count = 0; michael@0: michael@0: class MyEnvironment : public testing::Environment { michael@0: public: michael@0: MyEnvironment() {} michael@0: virtual void SetUp() { g_environment_set_up_count++; } michael@0: virtual void TearDown() { g_environment_tear_down_count++; } michael@0: }; michael@0: michael@0: // A test that should fail. michael@0: michael@0: int g_should_fail_count = 0; michael@0: michael@0: TEST(FooTest, ShouldFail) { michael@0: g_should_fail_count++; michael@0: EXPECT_EQ(0, 1) << "Expected failure."; michael@0: } michael@0: michael@0: // A test that should pass. michael@0: michael@0: int g_should_pass_count = 0; michael@0: michael@0: TEST(FooTest, ShouldPass) { michael@0: g_should_pass_count++; michael@0: } michael@0: michael@0: // A test that contains a thread-safe death test and a fast death michael@0: // test. It should pass. michael@0: michael@0: int g_death_test_count = 0; michael@0: michael@0: TEST(BarDeathTest, ThreadSafeAndFast) { michael@0: g_death_test_count++; michael@0: michael@0: GTEST_FLAG(death_test_style) = "threadsafe"; michael@0: EXPECT_DEATH_IF_SUPPORTED(::testing::internal::posix::Abort(), ""); michael@0: michael@0: GTEST_FLAG(death_test_style) = "fast"; michael@0: EXPECT_DEATH_IF_SUPPORTED(::testing::internal::posix::Abort(), ""); michael@0: } michael@0: michael@0: #if GTEST_HAS_PARAM_TEST michael@0: int g_param_test_count = 0; michael@0: michael@0: const int kNumberOfParamTests = 10; michael@0: michael@0: class MyParamTest : public testing::TestWithParam {}; michael@0: michael@0: TEST_P(MyParamTest, ShouldPass) { michael@0: // TODO(vladl@google.com): Make parameter value checking robust michael@0: // WRT order of tests. michael@0: GTEST_CHECK_INT_EQ_(g_param_test_count % kNumberOfParamTests, GetParam()); michael@0: g_param_test_count++; michael@0: } michael@0: INSTANTIATE_TEST_CASE_P(MyParamSequence, michael@0: MyParamTest, michael@0: testing::Range(0, kNumberOfParamTests)); michael@0: #endif // GTEST_HAS_PARAM_TEST michael@0: michael@0: // Resets the count for each test. michael@0: void ResetCounts() { michael@0: g_environment_set_up_count = 0; michael@0: g_environment_tear_down_count = 0; michael@0: g_should_fail_count = 0; michael@0: g_should_pass_count = 0; michael@0: g_death_test_count = 0; michael@0: #if GTEST_HAS_PARAM_TEST michael@0: g_param_test_count = 0; michael@0: #endif // GTEST_HAS_PARAM_TEST michael@0: } michael@0: michael@0: // Checks that the count for each test is expected. michael@0: void CheckCounts(int expected) { michael@0: GTEST_CHECK_INT_EQ_(expected, g_environment_set_up_count); michael@0: GTEST_CHECK_INT_EQ_(expected, g_environment_tear_down_count); michael@0: GTEST_CHECK_INT_EQ_(expected, g_should_fail_count); michael@0: GTEST_CHECK_INT_EQ_(expected, g_should_pass_count); michael@0: GTEST_CHECK_INT_EQ_(expected, g_death_test_count); michael@0: #if GTEST_HAS_PARAM_TEST michael@0: GTEST_CHECK_INT_EQ_(expected * kNumberOfParamTests, g_param_test_count); michael@0: #endif // GTEST_HAS_PARAM_TEST michael@0: } michael@0: michael@0: // Tests the behavior of Google Test when --gtest_repeat is not specified. michael@0: void TestRepeatUnspecified() { michael@0: ResetCounts(); michael@0: GTEST_CHECK_INT_EQ_(1, RUN_ALL_TESTS()); michael@0: CheckCounts(1); michael@0: } michael@0: michael@0: // Tests the behavior of Google Test when --gtest_repeat has the given value. michael@0: void TestRepeat(int repeat) { michael@0: GTEST_FLAG(repeat) = repeat; michael@0: michael@0: ResetCounts(); michael@0: GTEST_CHECK_INT_EQ_(repeat > 0 ? 1 : 0, RUN_ALL_TESTS()); michael@0: CheckCounts(repeat); michael@0: } michael@0: michael@0: // Tests using --gtest_repeat when --gtest_filter specifies an empty michael@0: // set of tests. michael@0: void TestRepeatWithEmptyFilter(int repeat) { michael@0: GTEST_FLAG(repeat) = repeat; michael@0: GTEST_FLAG(filter) = "None"; michael@0: michael@0: ResetCounts(); michael@0: GTEST_CHECK_INT_EQ_(0, RUN_ALL_TESTS()); michael@0: CheckCounts(0); michael@0: } michael@0: michael@0: // Tests using --gtest_repeat when --gtest_filter specifies a set of michael@0: // successful tests. michael@0: void TestRepeatWithFilterForSuccessfulTests(int repeat) { michael@0: GTEST_FLAG(repeat) = repeat; michael@0: GTEST_FLAG(filter) = "*-*ShouldFail"; michael@0: michael@0: ResetCounts(); michael@0: GTEST_CHECK_INT_EQ_(0, RUN_ALL_TESTS()); michael@0: GTEST_CHECK_INT_EQ_(repeat, g_environment_set_up_count); michael@0: GTEST_CHECK_INT_EQ_(repeat, g_environment_tear_down_count); michael@0: GTEST_CHECK_INT_EQ_(0, g_should_fail_count); michael@0: GTEST_CHECK_INT_EQ_(repeat, g_should_pass_count); michael@0: GTEST_CHECK_INT_EQ_(repeat, g_death_test_count); michael@0: #if GTEST_HAS_PARAM_TEST michael@0: GTEST_CHECK_INT_EQ_(repeat * kNumberOfParamTests, g_param_test_count); michael@0: #endif // GTEST_HAS_PARAM_TEST michael@0: } michael@0: michael@0: // Tests using --gtest_repeat when --gtest_filter specifies a set of michael@0: // failed tests. michael@0: void TestRepeatWithFilterForFailedTests(int repeat) { michael@0: GTEST_FLAG(repeat) = repeat; michael@0: GTEST_FLAG(filter) = "*ShouldFail"; michael@0: michael@0: ResetCounts(); michael@0: GTEST_CHECK_INT_EQ_(1, RUN_ALL_TESTS()); michael@0: GTEST_CHECK_INT_EQ_(repeat, g_environment_set_up_count); michael@0: GTEST_CHECK_INT_EQ_(repeat, g_environment_tear_down_count); michael@0: GTEST_CHECK_INT_EQ_(repeat, g_should_fail_count); michael@0: GTEST_CHECK_INT_EQ_(0, g_should_pass_count); michael@0: GTEST_CHECK_INT_EQ_(0, g_death_test_count); michael@0: #if GTEST_HAS_PARAM_TEST michael@0: GTEST_CHECK_INT_EQ_(0, g_param_test_count); michael@0: #endif // GTEST_HAS_PARAM_TEST michael@0: } michael@0: michael@0: } // namespace michael@0: michael@0: int main(int argc, char **argv) { michael@0: testing::InitGoogleTest(&argc, argv); michael@0: testing::AddGlobalTestEnvironment(new MyEnvironment); michael@0: michael@0: TestRepeatUnspecified(); michael@0: TestRepeat(0); michael@0: TestRepeat(1); michael@0: TestRepeat(5); michael@0: michael@0: TestRepeatWithEmptyFilter(2); michael@0: TestRepeatWithEmptyFilter(3); michael@0: michael@0: TestRepeatWithFilterForSuccessfulTests(3); michael@0: michael@0: TestRepeatWithFilterForFailedTests(4); michael@0: michael@0: // It would be nice to verify that the tests indeed loop forever michael@0: // when GTEST_FLAG(repeat) is negative, but this test will be quite michael@0: // complicated to write. Since this flag is for interactive michael@0: // debugging only and doesn't affect the normal test result, such a michael@0: // test would be an overkill. michael@0: michael@0: printf("PASS\n"); michael@0: return 0; michael@0: }