summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLingzhi Deng <lingzhi.deng@mongodb.com>2019-07-15 18:52:37 -0400
committerLingzhi Deng <lingzhi.deng@mongodb.com>2019-07-15 22:42:27 -0400
commit92fc2a914c7938b1135192ed55e984b346db2c3e (patch)
treeabb54c38a4904933439d9b3457f454abff0b8782
parent59413869159fa884f2dd7ce63f9a4171fc65763b (diff)
downloadmongo-92fc2a914c7938b1135192ed55e984b346db2c3e.tar.gz
parseBSON
-rw-r--r--src/mongo/util/fail_point.cpp36
-rw-r--r--src/mongo/util/fail_point.h7
-rw-r--r--src/mongo/util/fail_point_test.cpp65
3 files changed, 105 insertions, 3 deletions
diff --git a/src/mongo/util/fail_point.cpp b/src/mongo/util/fail_point.cpp
index 5755620be7a..b705e6a01bf 100644
--- a/src/mongo/util/fail_point.cpp
+++ b/src/mongo/util/fail_point.cpp
@@ -296,6 +296,42 @@ FailPoint::parseBSON(const BSONObj& obj) {
}
SyncConfig syncConfig;
+ const BSONElement syncElem(obj["sync"]);
+ if (!syncElem.eoo()) {
+ if (syncElem.type() != Object) {
+ return {ErrorCodes::TypeMismatch, "'sync' must be a JSON object"};
+ }
+ const BSONObj syncObj(syncElem.Obj());
+ if (syncObj.hasField("signals")) {
+ const BSONElement signals(syncObj["signals"]);
+ if (!signals.ok() || signals.type() != Array) {
+ return {ErrorCodes::TypeMismatch, "'sync.signals' must be an array of strings"};
+ }
+ auto it = BSONObjIterator(signals.Obj());
+ while (it.more()) {
+ auto e = it.next();
+ if (e.type() != String) {
+ return {ErrorCodes::TypeMismatch, "'sync.signals' must be an array of strings"};
+ }
+ syncConfig.signals.insert(e.String());
+ }
+ }
+ if (syncObj.hasField("waitFor")) {
+ const BSONElement waitFor(syncObj["waitFor"]);
+ if (!waitFor.ok() || waitFor.type() != Array) {
+ return {ErrorCodes::TypeMismatch, "'sync.waitFor' must be an array of strings"};
+ }
+ auto it = BSONObjIterator(waitFor.Obj());
+ while (it.more()) {
+ auto e = it.next();
+ if (e.type() != String) {
+ return {ErrorCodes::TypeMismatch, "'sync.waitFor' must be an array of strings"};
+ }
+ syncConfig.waitFor.insert(e.String());
+ }
+ }
+ syncConfig.enabled = true;
+ }
return std::make_tuple(mode, val, data, syncConfig);
}
diff --git a/src/mongo/util/fail_point.h b/src/mongo/util/fail_point.h
index fbabb169ffc..832d90349ef 100644
--- a/src/mongo/util/fail_point.h
+++ b/src/mongo/util/fail_point.h
@@ -78,8 +78,9 @@ public:
enum RetCode { fastOff = 0, slowOff, slowOn, userIgnored };
struct SyncConfig {
+ SyncConfig() {}
// Is this failpoint configured for failpoints synchronization.
- bool enabled;
+ bool enabled = false;
// Signals to emit when the failpoint is reached.
std::unordered_set<std::string> signals;
// Signals to wait for when the failpoint is reached.
@@ -146,8 +147,6 @@ public:
void sync() const;
- bool isSynced() const;
-
bool syncEnabled() const;
/**
@@ -215,6 +214,8 @@ private:
*/
void disableFailPoint();
+ bool isSynced() const;
+
/**
* slow path for #shouldFailOpenBlock
*
diff --git a/src/mongo/util/fail_point_test.cpp b/src/mongo/util/fail_point_test.cpp
index 2a759a5216a..823c83eb763 100644
--- a/src/mongo/util/fail_point_test.cpp
+++ b/src/mongo/util/fail_point_test.cpp
@@ -403,6 +403,71 @@ TEST(FailPoint, parseBSONValidDataSucceeds) {
ASSERT_TRUE(swTuple.isOK());
}
+TEST(FailPoint, parseBSONValidSync) {
+ auto swTuple = FailPoint::parseBSON(BSON("mode"
+ << "alwaysOn"
+ << "sync"
+ << BSON("signals" << BSON_ARRAY("a"
+ << "b"
+ << "c"))));
+ std::cout << swTuple.getStatus() << std::endl;
+ ASSERT_TRUE(swTuple.isOK());
+
+ swTuple = FailPoint::parseBSON(BSON("mode"
+ << "alwaysOn"
+ << "sync"
+ << BSON("waitFor" << BSON_ARRAY("a"
+ << "b"
+ << "c"))));
+ std::cout << swTuple.getStatus() << std::endl;
+ ASSERT_TRUE(swTuple.isOK());
+
+ swTuple = FailPoint::parseBSON(BSON("mode"
+ << "alwaysOn"
+ << "sync"
+ << BSON("signals" << BSON_ARRAY("a"
+ << "b"
+ << "c")
+ << "waitFor"
+ << BSON_ARRAY("c"
+ << "d"
+ << "e"))));
+ std::cout << swTuple.getStatus() << std::endl;
+ ASSERT_TRUE(swTuple.isOK());
+}
+
+TEST(FailPoint, parseBSONInvalidSyncFails) {
+ auto swTuple = FailPoint::parseBSON(BSON("mode"
+ << "alwaysOn"
+ << "sync"
+ << BSON("signals"
+ << "a")));
+ std::cout << swTuple.getStatus() << std::endl;
+ ASSERT_FALSE(swTuple.isOK());
+
+ swTuple = FailPoint::parseBSON(BSON("mode"
+ << "alwaysOn"
+ << "sync"
+ << BSON("signals" << BSON_ARRAY(1 << 2))));
+ std::cout << swTuple.getStatus() << std::endl;
+ ASSERT_FALSE(swTuple.isOK());
+
+ swTuple = FailPoint::parseBSON(BSON("mode"
+ << "alwaysOn"
+ << "sync"
+ << BSON("waitFor"
+ << "a")));
+ std::cout << swTuple.getStatus() << std::endl;
+ ASSERT_FALSE(swTuple.isOK());
+
+ swTuple = FailPoint::parseBSON(BSON("mode"
+ << "alwaysOn"
+ << "sync"
+ << BSON("waitFor" << BSON_ARRAY(1 << 2))));
+ std::cout << swTuple.getStatus() << std::endl;
+ ASSERT_FALSE(swTuple.isOK());
+}
+
TEST(FailPoint, FailPointBlockBasicTest) {
auto failPoint = getGlobalFailPointRegistry()->getFailPoint("dummy");