github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/src/third_party/googlemock/gtest/test/gtest_stress_test.cc (about)

     1  // Copyright 2007, Google Inc.
     2  // All rights reserved.
     3  //
     4  // Redistribution and use in source and binary forms, with or without
     5  // modification, are permitted provided that the following conditions are
     6  // met:
     7  //
     8  //     * Redistributions of source code must retain the above copyright
     9  // notice, this list of conditions and the following disclaimer.
    10  //     * Redistributions in binary form must reproduce the above
    11  // copyright notice, this list of conditions and the following disclaimer
    12  // in the documentation and/or other materials provided with the
    13  // distribution.
    14  //     * Neither the name of Google Inc. nor the names of its
    15  // contributors may be used to endorse or promote products derived from
    16  // this software without specific prior written permission.
    17  //
    18  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    19  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    20  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    21  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    22  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    23  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    24  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    25  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    26  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    27  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    28  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    29  //
    30  // Author: wan@google.com (Zhanyong Wan)
    31  
    32  // Tests that SCOPED_TRACE() and various Google Test assertions can be
    33  // used in a large number of threads concurrently.
    34  
    35  #include "gtest/gtest.h"
    36  
    37  #include <iostream>
    38  #include <vector>
    39  
    40  // We must define this macro in order to #include
    41  // gtest-internal-inl.h.  This is how Google Test prevents a user from
    42  // accidentally depending on its internal implementation.
    43  #define GTEST_IMPLEMENTATION_ 1
    44  #include "src/gtest-internal-inl.h"
    45  #undef GTEST_IMPLEMENTATION_
    46  
    47  #if GTEST_IS_THREADSAFE
    48  
    49  namespace testing {
    50  namespace {
    51  
    52  using internal::Notification;
    53  using internal::TestPropertyKeyIs;
    54  using internal::ThreadWithParam;
    55  using internal::scoped_ptr;
    56  
    57  // In order to run tests in this file, for platforms where Google Test is
    58  // thread safe, implement ThreadWithParam. See the description of its API
    59  // in gtest-port.h, where it is defined for already supported platforms.
    60  
    61  // How many threads to create?
    62  const int kThreadCount = 50;
    63  
    64  std::string IdToKey(int id, const char* suffix) {
    65    Message key;
    66    key << "key_" << id << "_" << suffix;
    67    return key.GetString();
    68  }
    69  
    70  std::string IdToString(int id) {
    71    Message id_message;
    72    id_message << id;
    73    return id_message.GetString();
    74  }
    75  
    76  void ExpectKeyAndValueWereRecordedForId(
    77      const std::vector<TestProperty>& properties,
    78      int id, const char* suffix) {
    79    TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str());
    80    const std::vector<TestProperty>::const_iterator property =
    81        std::find_if(properties.begin(), properties.end(), matches_key);
    82    ASSERT_TRUE(property != properties.end())
    83        << "expecting " << suffix << " value for id " << id;
    84    EXPECT_STREQ(IdToString(id).c_str(), property->value());
    85  }
    86  
    87  // Calls a large number of Google Test assertions, where exactly one of them
    88  // will fail.
    89  void ManyAsserts(int id) {
    90    GTEST_LOG_(INFO) << "Thread #" << id << " running...";
    91  
    92    SCOPED_TRACE(Message() << "Thread #" << id);
    93  
    94    for (int i = 0; i < kThreadCount; i++) {
    95      SCOPED_TRACE(Message() << "Iteration #" << i);
    96  
    97      // A bunch of assertions that should succeed.
    98      EXPECT_TRUE(true);
    99      ASSERT_FALSE(false) << "This shouldn't fail.";
   100      EXPECT_STREQ("a", "a");
   101      ASSERT_LE(5, 6);
   102      EXPECT_EQ(i, i) << "This shouldn't fail.";
   103  
   104      // RecordProperty() should interact safely with other threads as well.
   105      // The shared_key forces property updates.
   106      Test::RecordProperty(IdToKey(id, "string").c_str(), IdToString(id).c_str());
   107      Test::RecordProperty(IdToKey(id, "int").c_str(), id);
   108      Test::RecordProperty("shared_key", IdToString(id).c_str());
   109  
   110      // This assertion should fail kThreadCount times per thread.  It
   111      // is for testing whether Google Test can handle failed assertions in a
   112      // multi-threaded context.
   113      EXPECT_LT(i, 0) << "This should always fail.";
   114    }
   115  }
   116  
   117  void CheckTestFailureCount(int expected_failures) {
   118    const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
   119    const TestResult* const result = info->result();
   120    GTEST_CHECK_(expected_failures == result->total_part_count())
   121        << "Logged " << result->total_part_count() << " failures "
   122        << " vs. " << expected_failures << " expected";
   123  }
   124  
   125  // Tests using SCOPED_TRACE() and Google Test assertions in many threads
   126  // concurrently.
   127  TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) {
   128    {
   129      scoped_ptr<ThreadWithParam<int> > threads[kThreadCount];
   130      Notification threads_can_start;
   131      for (int i = 0; i != kThreadCount; i++)
   132        threads[i].reset(new ThreadWithParam<int>(&ManyAsserts,
   133                                                  i,
   134                                                  &threads_can_start));
   135  
   136      threads_can_start.Notify();
   137  
   138      // Blocks until all the threads are done.
   139      for (int i = 0; i != kThreadCount; i++)
   140        threads[i]->Join();
   141    }
   142  
   143    // Ensures that kThreadCount*kThreadCount failures have been reported.
   144    const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
   145    const TestResult* const result = info->result();
   146  
   147    std::vector<TestProperty> properties;
   148    // We have no access to the TestResult's list of properties but we can
   149    // copy them one by one.
   150    for (int i = 0; i < result->test_property_count(); ++i)
   151      properties.push_back(result->GetTestProperty(i));
   152  
   153    EXPECT_EQ(kThreadCount * 2 + 1, result->test_property_count())
   154        << "String and int values recorded on each thread, "
   155        << "as well as one shared_key";
   156    for (int i = 0; i < kThreadCount; ++i) {
   157      ExpectKeyAndValueWereRecordedForId(properties, i, "string");
   158      ExpectKeyAndValueWereRecordedForId(properties, i, "int");
   159    }
   160    CheckTestFailureCount(kThreadCount*kThreadCount);
   161  }
   162  
   163  void FailingThread(bool is_fatal) {
   164    if (is_fatal)
   165      FAIL() << "Fatal failure in some other thread. "
   166             << "(This failure is expected.)";
   167    else
   168      ADD_FAILURE() << "Non-fatal failure in some other thread. "
   169                    << "(This failure is expected.)";
   170  }
   171  
   172  void GenerateFatalFailureInAnotherThread(bool is_fatal) {
   173    ThreadWithParam<bool> thread(&FailingThread, is_fatal, NULL);
   174    thread.Join();
   175  }
   176  
   177  TEST(NoFatalFailureTest, ExpectNoFatalFailureIgnoresFailuresInOtherThreads) {
   178    EXPECT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true));
   179    // We should only have one failure (the one from
   180    // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE
   181    // should succeed.
   182    CheckTestFailureCount(1);
   183  }
   184  
   185  void AssertNoFatalFailureIgnoresFailuresInOtherThreads() {
   186    ASSERT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true));
   187  }
   188  TEST(NoFatalFailureTest, AssertNoFatalFailureIgnoresFailuresInOtherThreads) {
   189    // Using a subroutine, to make sure, that the test continues.
   190    AssertNoFatalFailureIgnoresFailuresInOtherThreads();
   191    // We should only have one failure (the one from
   192    // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE
   193    // should succeed.
   194    CheckTestFailureCount(1);
   195  }
   196  
   197  TEST(FatalFailureTest, ExpectFatalFailureIgnoresFailuresInOtherThreads) {
   198    // This statement should fail, since the current thread doesn't generate a
   199    // fatal failure, only another one does.
   200    EXPECT_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true), "expected");
   201    CheckTestFailureCount(2);
   202  }
   203  
   204  TEST(FatalFailureOnAllThreadsTest, ExpectFatalFailureOnAllThreads) {
   205    // This statement should succeed, because failures in all threads are
   206    // considered.
   207    EXPECT_FATAL_FAILURE_ON_ALL_THREADS(
   208        GenerateFatalFailureInAnotherThread(true), "expected");
   209    CheckTestFailureCount(0);
   210    // We need to add a failure, because main() checks that there are failures.
   211    // But when only this test is run, we shouldn't have any failures.
   212    ADD_FAILURE() << "This is an expected non-fatal failure.";
   213  }
   214  
   215  TEST(NonFatalFailureTest, ExpectNonFatalFailureIgnoresFailuresInOtherThreads) {
   216    // This statement should fail, since the current thread doesn't generate a
   217    // fatal failure, only another one does.
   218    EXPECT_NONFATAL_FAILURE(GenerateFatalFailureInAnotherThread(false),
   219                            "expected");
   220    CheckTestFailureCount(2);
   221  }
   222  
   223  TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) {
   224    // This statement should succeed, because failures in all threads are
   225    // considered.
   226    EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(
   227        GenerateFatalFailureInAnotherThread(false), "expected");
   228    CheckTestFailureCount(0);
   229    // We need to add a failure, because main() checks that there are failures,
   230    // But when only this test is run, we shouldn't have any failures.
   231    ADD_FAILURE() << "This is an expected non-fatal failure.";
   232  }
   233  
   234  }  // namespace
   235  }  // namespace testing
   236  
   237  int main(int argc, char **argv) {
   238    testing::InitGoogleTest(&argc, argv);
   239  
   240    const int result = RUN_ALL_TESTS();  // Expected to fail.
   241    GTEST_CHECK_(result == 1) << "RUN_ALL_TESTS() did not fail as expected";
   242  
   243    printf("\nPASS\n");
   244    return 0;
   245  }
   246  
   247  #else
   248  TEST(StressTest,
   249       DISABLED_ThreadSafetyTestsAreSkippedWhenGoogleTestIsNotThreadSafe) {
   250  }
   251  
   252  int main(int argc, char **argv) {
   253    testing::InitGoogleTest(&argc, argv);
   254    return RUN_ALL_TESTS();
   255  }
   256  #endif  // GTEST_IS_THREADSAFE