summaryrefslogtreecommitdiff
path: root/src/mongo/util/fail_point_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/util/fail_point_test.cpp')
-rw-r--r--src/mongo/util/fail_point_test.cpp459
1 files changed, 222 insertions, 237 deletions
diff --git a/src/mongo/util/fail_point_test.cpp b/src/mongo/util/fail_point_test.cpp
index 0b06cb7167d..4abed25d8b5 100644
--- a/src/mongo/util/fail_point_test.cpp
+++ b/src/mongo/util/fail_point_test.cpp
@@ -45,307 +45,292 @@ using mongo::FailPoint;
namespace stdx = mongo::stdx;
namespace mongo_test {
- TEST(FailPoint, InitialState) {
- FailPoint failPoint;
- ASSERT_FALSE(failPoint.shouldFail());
+TEST(FailPoint, InitialState) {
+ FailPoint failPoint;
+ ASSERT_FALSE(failPoint.shouldFail());
+}
+
+TEST(FailPoint, AlwaysOn) {
+ FailPoint failPoint;
+ failPoint.setMode(FailPoint::alwaysOn);
+ ASSERT(failPoint.shouldFail());
+
+ MONGO_FAIL_POINT_BLOCK(failPoint, scopedFp) {
+ ASSERT(scopedFp.getData().isEmpty());
}
- TEST(FailPoint, AlwaysOn) {
- FailPoint failPoint;
- failPoint.setMode(FailPoint::alwaysOn);
+ for (size_t x = 0; x < 50; x++) {
ASSERT(failPoint.shouldFail());
+ }
+}
- MONGO_FAIL_POINT_BLOCK(failPoint, scopedFp) {
- ASSERT(scopedFp.getData().isEmpty());
- }
+TEST(FailPoint, NTimes) {
+ FailPoint failPoint;
+ failPoint.setMode(FailPoint::nTimes, 4);
+ ASSERT(failPoint.shouldFail());
+ ASSERT(failPoint.shouldFail());
+ ASSERT(failPoint.shouldFail());
+ ASSERT(failPoint.shouldFail());
- for (size_t x = 0; x < 50; x++) {
- ASSERT(failPoint.shouldFail());
- }
+ for (size_t x = 0; x < 50; x++) {
+ ASSERT_FALSE(failPoint.shouldFail());
}
+}
- TEST(FailPoint, NTimes) {
- FailPoint failPoint;
- failPoint.setMode(FailPoint::nTimes, 4);
- ASSERT(failPoint.shouldFail());
- ASSERT(failPoint.shouldFail());
- ASSERT(failPoint.shouldFail());
- ASSERT(failPoint.shouldFail());
+TEST(FailPoint, BlockOff) {
+ FailPoint failPoint;
+ bool called = false;
- for (size_t x = 0; x < 50; x++) {
- ASSERT_FALSE(failPoint.shouldFail());
- }
+ MONGO_FAIL_POINT_BLOCK(failPoint, scopedFp) {
+ called = true;
}
- TEST(FailPoint, BlockOff) {
- FailPoint failPoint;
- bool called = false;
+ ASSERT_FALSE(called);
+}
- MONGO_FAIL_POINT_BLOCK(failPoint, scopedFp) {
- called = true;
- }
+TEST(FailPoint, BlockAlwaysOn) {
+ FailPoint failPoint;
+ failPoint.setMode(FailPoint::alwaysOn);
+ bool called = false;
- ASSERT_FALSE(called);
+ MONGO_FAIL_POINT_BLOCK(failPoint, scopedFp) {
+ called = true;
}
- TEST(FailPoint, BlockAlwaysOn) {
- FailPoint failPoint;
- failPoint.setMode(FailPoint::alwaysOn);
- bool called = false;
+ ASSERT(called);
+}
+
+TEST(FailPoint, BlockNTimes) {
+ FailPoint failPoint;
+ failPoint.setMode(FailPoint::nTimes, 1);
+ size_t counter = 0;
+ for (size_t x = 0; x < 10; x++) {
MONGO_FAIL_POINT_BLOCK(failPoint, scopedFp) {
- called = true;
+ counter++;
}
-
- ASSERT(called);
}
- TEST(FailPoint, BlockNTimes) {
- FailPoint failPoint;
- failPoint.setMode(FailPoint::nTimes, 1);
- size_t counter = 0;
+ ASSERT_EQUALS(1U, counter);
+}
- for (size_t x = 0; x < 10; x++) {
- MONGO_FAIL_POINT_BLOCK(failPoint, scopedFp) {
- counter++;
- }
- }
+TEST(FailPoint, BlockWithException) {
+ FailPoint failPoint;
+ failPoint.setMode(FailPoint::alwaysOn);
+ bool threw = false;
- ASSERT_EQUALS(1U, counter);
+ try {
+ MONGO_FAIL_POINT_BLOCK(failPoint, scopedFp) {
+ throw std::logic_error("BlockWithException threw");
+ }
+ } catch (const std::logic_error&) {
+ threw = true;
}
- TEST(FailPoint, BlockWithException) {
- FailPoint failPoint;
- failPoint.setMode(FailPoint::alwaysOn);
- bool threw = false;
+ ASSERT(threw);
+ // This will get into an infinite loop if reference counter was not
+ // properly decremented
+ failPoint.setMode(FailPoint::off);
+}
- try {
- MONGO_FAIL_POINT_BLOCK(failPoint, scopedFp) {
- throw std::logic_error("BlockWithException threw");
- }
- }
- catch (const std::logic_error &) {
- threw = true;
- }
+TEST(FailPoint, SetGetParam) {
+ FailPoint failPoint;
+ failPoint.setMode(FailPoint::alwaysOn, 0, BSON("x" << 20));
- ASSERT(threw);
- // This will get into an infinite loop if reference counter was not
- // properly decremented
- failPoint.setMode(FailPoint::off);
+ MONGO_FAIL_POINT_BLOCK(failPoint, scopedFp) {
+ ASSERT_EQUALS(20, scopedFp.getData()["x"].numberInt());
}
+}
- TEST(FailPoint, SetGetParam) {
- FailPoint failPoint;
- failPoint.setMode(FailPoint::alwaysOn, 0, BSON("x" << 20));
-
- MONGO_FAIL_POINT_BLOCK(failPoint, scopedFp) {
- ASSERT_EQUALS(20, scopedFp.getData()["x"].numberInt());
- }
- }
+TEST(FailPoint, SetInvalidMode) {
+ FailPoint failPoint;
- TEST(FailPoint, SetInvalidMode) {
- FailPoint failPoint;
+ ASSERT_THROWS(failPoint.setMode(static_cast<FailPoint::Mode>(9999)), mongo::UserException);
+ ASSERT_FALSE(failPoint.shouldFail());
- ASSERT_THROWS(failPoint.setMode(static_cast<FailPoint::Mode>(9999)),
- mongo::UserException);
- ASSERT_FALSE(failPoint.shouldFail());
+ ASSERT_THROWS(failPoint.setMode(static_cast<FailPoint::Mode>(-1)), mongo::UserException);
+ ASSERT_FALSE(failPoint.shouldFail());
+}
- ASSERT_THROWS(failPoint.setMode(static_cast<FailPoint::Mode>(-1)),
- mongo::UserException);
- ASSERT_FALSE(failPoint.shouldFail());
+class FailPointStress : public mongo::unittest::Test {
+public:
+ void setUp() {
+ _fp.setMode(FailPoint::alwaysOn, 0, BSON("a" << 44));
}
- class FailPointStress: public mongo::unittest::Test {
- public:
- void setUp() {
- _fp.setMode(FailPoint::alwaysOn, 0, BSON("a" << 44));
- }
+ void tearDown() {
+ // Note: This can loop indefinitely if reference counter was off
+ _fp.setMode(FailPoint::off, 0, BSON("a" << 66));
+ }
- void tearDown() {
- // Note: This can loop indefinitely if reference counter was off
- _fp.setMode(FailPoint::off, 0, BSON("a" << 66));
- }
+ void startTest() {
+ ASSERT_EQUALS(0U, _tasks.size());
- void startTest() {
- ASSERT_EQUALS(0U, _tasks.size());
+ _tasks.emplace_back(&FailPointStress::blockTask, this);
+ _tasks.emplace_back(&FailPointStress::blockWithExceptionTask, this);
+ _tasks.emplace_back(&FailPointStress::simpleTask, this);
+ _tasks.emplace_back(&FailPointStress::flipTask, this);
+ }
- _tasks.emplace_back(&FailPointStress::blockTask, this);
- _tasks.emplace_back(&FailPointStress::blockWithExceptionTask, this);
- _tasks.emplace_back(&FailPointStress::simpleTask, this);
- _tasks.emplace_back(&FailPointStress::flipTask, this);
+ void stopTest() {
+ {
+ stdx::lock_guard<stdx::mutex> lk(_mutex);
+ _inShutdown = true;
+ }
+ for (auto& t : _tasks) {
+ t.join();
}
+ _tasks.clear();
+ }
- void stopTest() {
- {
- stdx::lock_guard<stdx::mutex> lk(_mutex);
- _inShutdown = true;
- }
- for (auto& t : _tasks) {
- t.join();
+private:
+ void blockTask() {
+ while (true) {
+ MONGO_FAIL_POINT_BLOCK(_fp, scopedFp) {
+ const mongo::BSONObj& data = scopedFp.getData();
+
+ // Expanded ASSERT_EQUALS since the error is not being
+ // printed out properly
+ if (data["a"].numberInt() != 44) {
+ mongo::error() << "blockTask thread detected anomaly"
+ << " - data: " << data << std::endl;
+ ASSERT(false);
+ }
}
- _tasks.clear();
+
+ stdx::lock_guard<stdx::mutex> lk(_mutex);
+ if (_inShutdown)
+ break;
}
+ }
- private:
- void blockTask() {
- while (true) {
+ void blockWithExceptionTask() {
+ while (true) {
+ try {
MONGO_FAIL_POINT_BLOCK(_fp, scopedFp) {
const mongo::BSONObj& data = scopedFp.getData();
- // Expanded ASSERT_EQUALS since the error is not being
- // printed out properly
if (data["a"].numberInt() != 44) {
- mongo::error() << "blockTask thread detected anomaly"
- << " - data: " << data << std::endl;
+ mongo::error() << "blockWithExceptionTask thread detected anomaly"
+ << " - data: " << data << std::endl;
ASSERT(false);
}
- }
-
- stdx::lock_guard<stdx::mutex> lk(_mutex);
- if (_inShutdown)
- break;
- }
- }
- void blockWithExceptionTask() {
- while (true) {
- try {
- MONGO_FAIL_POINT_BLOCK(_fp, scopedFp) {
- const mongo::BSONObj& data = scopedFp.getData();
-
- if (data["a"].numberInt() != 44) {
- mongo::error() << "blockWithExceptionTask thread detected anomaly"
- << " - data: " << data << std::endl;
- ASSERT(false);
- }
-
- throw std::logic_error("blockWithExceptionTask threw");
- }
- }
- catch (const std::logic_error&) {
+ throw std::logic_error("blockWithExceptionTask threw");
}
+ } catch (const std::logic_error&) {
+ }
- stdx::lock_guard<stdx::mutex> lk(_mutex);
- if (_inShutdown)
- break;
- }
+ stdx::lock_guard<stdx::mutex> lk(_mutex);
+ if (_inShutdown)
+ break;
}
+ }
- void simpleTask() {
- while (true) {
- static_cast<void>(MONGO_FAIL_POINT(_fp));
- stdx::lock_guard<stdx::mutex> lk(_mutex);
- if (_inShutdown)
- break;
- }
+ void simpleTask() {
+ while (true) {
+ static_cast<void>(MONGO_FAIL_POINT(_fp));
+ stdx::lock_guard<stdx::mutex> lk(_mutex);
+ if (_inShutdown)
+ break;
}
+ }
- void flipTask() {
- while (true) {
- if(_fp.shouldFail()) {
- _fp.setMode(FailPoint::off, 0);
- }
- else {
- _fp.setMode(FailPoint::alwaysOn, 0, BSON("a" << 44));
- }
-
- stdx::lock_guard<stdx::mutex> lk(_mutex);
- if (_inShutdown)
- break;
+ void flipTask() {
+ while (true) {
+ if (_fp.shouldFail()) {
+ _fp.setMode(FailPoint::off, 0);
+ } else {
+ _fp.setMode(FailPoint::alwaysOn, 0, BSON("a" << 44));
}
+
+ stdx::lock_guard<stdx::mutex> lk(_mutex);
+ if (_inShutdown)
+ break;
}
+ }
- FailPoint _fp;
- std::vector<stdx::thread> _tasks;
- stdx::mutex _mutex;
- bool _inShutdown = false;
- };
+ FailPoint _fp;
+ std::vector<stdx::thread> _tasks;
+ stdx::mutex _mutex;
+ bool _inShutdown = false;
+};
- TEST_F(FailPointStress, Basic) {
- startTest();
- mongo::sleepsecs(30);
- stopTest();
- }
+TEST_F(FailPointStress, Basic) {
+ startTest();
+ mongo::sleepsecs(30);
+ stopTest();
+}
- static void parallelFailPointTestThread(FailPoint* fp,
- const int64_t numIterations,
- const int32_t seed,
- int64_t* outNumActivations) {
- fp->setThreadPRNGSeed(seed);
- int64_t numActivations = 0;
- for (int64_t i = 0; i < numIterations; ++i) {
- if (fp->shouldFail()) {
- ++numActivations;
- }
+static void parallelFailPointTestThread(FailPoint* fp,
+ const int64_t numIterations,
+ const int32_t seed,
+ int64_t* outNumActivations) {
+ fp->setThreadPRNGSeed(seed);
+ int64_t numActivations = 0;
+ for (int64_t i = 0; i < numIterations; ++i) {
+ if (fp->shouldFail()) {
+ ++numActivations;
}
- *outNumActivations = numActivations;
}
- /**
- * Encounters a failpoint with the given fpMode and fpVal numEncountersPerThread
- * times in each of numThreads parallel threads, and returns the number of total
- * times that the failpoint was activiated.
- */
- static int64_t runParallelFailPointTest(
- FailPoint::Mode fpMode,
- FailPoint::ValType fpVal,
- const int32_t numThreads,
- const int32_t numEncountersPerThread) {
-
- ASSERT_GT(numThreads, 0);
- ASSERT_GT(numEncountersPerThread, 0);
- FailPoint failPoint;
- failPoint.setMode(fpMode, fpVal);
- std::vector<stdx::thread*> tasks;
- std::vector<int64_t> counts(numThreads, 0);
- ASSERT_EQUALS(static_cast<uint32_t>(numThreads), counts.size());
- for (int32_t i = 0; i < numThreads; ++i) {
- tasks.push_back(new stdx::thread(parallelFailPointTestThread,
- &failPoint,
- numEncountersPerThread,
- i, // hardcoded seed, different for each thread.
- &counts[i]));
- }
- int64_t totalActivations = 0;
- for (int32_t i = 0; i < numThreads; ++i) {
- tasks[i]->join();
- delete tasks[i];
- totalActivations += counts[i];
- }
- return totalActivations;
+ *outNumActivations = numActivations;
+}
+/**
+ * Encounters a failpoint with the given fpMode and fpVal numEncountersPerThread
+ * times in each of numThreads parallel threads, and returns the number of total
+ * times that the failpoint was activiated.
+ */
+static int64_t runParallelFailPointTest(FailPoint::Mode fpMode,
+ FailPoint::ValType fpVal,
+ const int32_t numThreads,
+ const int32_t numEncountersPerThread) {
+ ASSERT_GT(numThreads, 0);
+ ASSERT_GT(numEncountersPerThread, 0);
+ FailPoint failPoint;
+ failPoint.setMode(fpMode, fpVal);
+ std::vector<stdx::thread*> tasks;
+ std::vector<int64_t> counts(numThreads, 0);
+ ASSERT_EQUALS(static_cast<uint32_t>(numThreads), counts.size());
+ for (int32_t i = 0; i < numThreads; ++i) {
+ tasks.push_back(new stdx::thread(parallelFailPointTestThread,
+ &failPoint,
+ numEncountersPerThread,
+ i, // hardcoded seed, different for each thread.
+ &counts[i]));
}
-
- TEST(FailPoint, RandomActivationP0) {
- ASSERT_EQUALS(0, runParallelFailPointTest(FailPoint::random, 0, 1, 1000000));
+ int64_t totalActivations = 0;
+ for (int32_t i = 0; i < numThreads; ++i) {
+ tasks[i]->join();
+ delete tasks[i];
+ totalActivations += counts[i];
}
+ return totalActivations;
+}
- TEST(FailPoint, RandomActivationP5) {
- ASSERT_APPROX_EQUAL(
- 500000,
- runParallelFailPointTest(FailPoint::random,
- std::numeric_limits<int32_t>::max() / 2,
- 10,
- 100000),
- 500);
- }
+TEST(FailPoint, RandomActivationP0) {
+ ASSERT_EQUALS(0, runParallelFailPointTest(FailPoint::random, 0, 1, 1000000));
+}
- TEST(FailPoint, RandomActivationP01) {
- ASSERT_APPROX_EQUAL(
- 10000,
- runParallelFailPointTest(FailPoint::random,
- std::numeric_limits<int32_t>::max() / 100,
- 10,
- 100000),
- 500);
- }
+TEST(FailPoint, RandomActivationP5) {
+ ASSERT_APPROX_EQUAL(500000,
+ runParallelFailPointTest(
+ FailPoint::random, std::numeric_limits<int32_t>::max() / 2, 10, 100000),
+ 500);
+}
- TEST(FailPoint, RandomActivationP001) {
- ASSERT_APPROX_EQUAL(
- 1000,
- runParallelFailPointTest(FailPoint::random,
- std::numeric_limits<int32_t>::max() / 1000,
- 10,
- 100000),
- 500);
- }
+TEST(FailPoint, RandomActivationP01) {
+ ASSERT_APPROX_EQUAL(
+ 10000,
+ runParallelFailPointTest(
+ FailPoint::random, std::numeric_limits<int32_t>::max() / 100, 10, 100000),
+ 500);
+}
+TEST(FailPoint, RandomActivationP001) {
+ ASSERT_APPROX_EQUAL(
+ 1000,
+ runParallelFailPointTest(
+ FailPoint::random, std::numeric_limits<int32_t>::max() / 1000, 10, 100000),
+ 500);
+}
}