summaryrefslogtreecommitdiff
path: root/src/mongo/util
diff options
context:
space:
mode:
authorShaun Verch <shaun.verch@10gen.com>2013-10-08 12:04:58 -0400
committerShaun Verch <shaun.verch@10gen.com>2013-10-09 10:06:37 -0400
commitfc67141dcb245aaaa47321c863c8d26aef6bb5ee (patch)
tree21ecf40bb45e20948d014ee9c75a5dbac0263abb /src/mongo/util
parent606b6ee6cab9809a0124d13b5a7aebcddad027cc (diff)
downloadmongo-fc67141dcb245aaaa47321c863c8d26aef6bb5ee.tar.gz
SERVER-8510 Add comments in JSON config files
Diffstat (limited to 'src/mongo/util')
-rw-r--r--src/mongo/util/options_parser/options_parser.cpp27
-rw-r--r--src/mongo/util/options_parser/options_parser_test.cpp210
2 files changed, 235 insertions, 2 deletions
diff --git a/src/mongo/util/options_parser/options_parser.cpp b/src/mongo/util/options_parser/options_parser.cpp
index f8e51e2a557..96bda76e445 100644
--- a/src/mongo/util/options_parser/options_parser.cpp
+++ b/src/mongo/util/options_parser/options_parser.cpp
@@ -249,8 +249,31 @@ namespace optionenvironment {
BSONElement elem = iterator.next();
string fieldName= elem.fieldName();
- std::string dottedName = ( parentPath.empty() ? fieldName
- : parentPath+'.'+fieldName );
+ // The following code should allow the following comment styles:
+ // { "option" : { "value" : <value>, "comment" : "comment string" } }
+ // { "option" : <value>, "comment" : "comment string" }
+
+ // Ignore fields with a name of "comment"
+ if (fieldName == "comment") {
+ continue;
+ }
+
+ std::string dottedName;
+ if (parentPath.empty()) {
+ // We are at the top level, so the full specifier is just the current field name
+ dottedName = fieldName;
+ }
+ else {
+ // If our field name is "value", assume this contains the value for the parent
+ if (fieldName == "value") {
+ dottedName = parentPath;
+ }
+ // If this is not a special field name, and we are in a sub object, append our
+ // current fieldName to the selector for the sub object we are traversing
+ else {
+ dottedName = parentPath + '.' + fieldName;
+ }
+ }
if (elem.type() == ::mongo::Object) {
addBSONElementsToEnvironment( elem.Obj(), options, dottedName, environment );
diff --git a/src/mongo/util/options_parser/options_parser_test.cpp b/src/mongo/util/options_parser/options_parser_test.cpp
index 33de98fb731..9c1abff4353 100644
--- a/src/mongo/util/options_parser/options_parser_test.cpp
+++ b/src/mongo/util/options_parser/options_parser_test.cpp
@@ -1416,4 +1416,214 @@ namespace {
}
}
+ TEST(JSONConfigFile, NestedComments) {
+ OptionsParserTester parser;
+ moe::Environment environment;
+
+ moe::OptionSection testOpts;
+ testOpts.addOption(moe::OptionDescription("config", "config",
+ moe::String, "Config file to parse"));
+ testOpts.addOption(moe::OptionDescription("port", "port", moe::Int, "Port"));
+ testOpts.addOption(moe::OptionDescription("host", "host", moe::String, "Host"));
+
+ std::vector<std::string> argv;
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.json");
+ std::map<std::string, std::string> env_map;
+
+ parser.setConfig("config.json",
+ "{ port : { comment : \"comment on port\", value : 5 },"
+ "host : { comment : \"comment on host\", value : \"localhost\" } }");
+
+ moe::Value value;
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_OK(environment.get(moe::Key("port"), &value));
+ int port;
+ ASSERT_OK(value.get(&port));
+ ASSERT_EQUALS(port, 5);
+ ASSERT_OK(environment.get(moe::Key("host"), &value));
+ std::string host;
+ ASSERT_OK(value.get(&host));
+ ASSERT_EQUALS(host, "localhost");
+ }
+
+ TEST(JSONConfigFile, FlatComments) {
+ OptionsParserTester parser;
+ moe::Environment environment;
+
+ moe::OptionSection testOpts;
+ testOpts.addOption(moe::OptionDescription("config", "config",
+ moe::String, "Config file to parse"));
+ testOpts.addOption(moe::OptionDescription("port", "port", moe::Int, "Port"));
+ testOpts.addOption(moe::OptionDescription("host", "host", moe::String, "Host"));
+
+ std::vector<std::string> argv;
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.json");
+ std::map<std::string, std::string> env_map;
+
+ parser.setConfig("config.json",
+ "{ comment : \"comment on port\", port : 5 ,"
+ " comment : \"comment on host\", host : \"localhost\" }");
+
+ moe::Value value;
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_OK(environment.get(moe::Key("port"), &value));
+ int port;
+ ASSERT_OK(value.get(&port));
+ ASSERT_EQUALS(port, 5);
+ ASSERT_OK(environment.get(moe::Key("host"), &value));
+ std::string host;
+ ASSERT_OK(value.get(&host));
+ ASSERT_EQUALS(host, "localhost");
+ }
+
+ TEST(JSONConfigFile, MixedComments) {
+ OptionsParserTester parser;
+ moe::Environment environment;
+
+ moe::OptionSection testOpts;
+ testOpts.addOption(moe::OptionDescription("config", "config",
+ moe::String, "Config file to parse"));
+ testOpts.addOption(moe::OptionDescription("port", "port", moe::Int, "Port"));
+ testOpts.addOption(moe::OptionDescription("host", "host", moe::String, "Host"));
+
+ std::vector<std::string> argv;
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.json");
+ std::map<std::string, std::string> env_map;
+
+ parser.setConfig("config.json",
+ "{ port : { comment : \"comment on port\", value : 5 },"
+ " comment : \"comment on host\", host : \"localhost\" }");
+
+ moe::Value value;
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_OK(environment.get(moe::Key("port"), &value));
+ int port;
+ ASSERT_OK(value.get(&port));
+ ASSERT_EQUALS(port, 5);
+ ASSERT_OK(environment.get(moe::Key("host"), &value));
+ std::string host;
+ ASSERT_OK(value.get(&host));
+ ASSERT_EQUALS(host, "localhost");
+ }
+
+ TEST(JSONConfigFile, NestedCommentsBadValue) {
+ OptionsParserTester parser;
+ moe::Environment environment;
+
+ moe::OptionSection testOpts;
+ testOpts.addOption(moe::OptionDescription("config", "config",
+ moe::String, "Config file to parse"));
+ testOpts.addOption(moe::OptionDescription("port", "port", moe::Int, "Port"));
+ testOpts.addOption(moe::OptionDescription("host", "host", moe::String, "Host"));
+
+ std::vector<std::string> argv;
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.json");
+ std::map<std::string, std::string> env_map;
+
+ parser.setConfig("config.json",
+ "{ port : { comment : \"comment on port\", value : \"string\" },"
+ "host : { comment : \"comment on host\", value : \"localhost\" } }");
+
+ moe::Value value;
+ ASSERT_NOT_OK(parser.run(testOpts, argv, env_map, &environment));
+ }
+
+ TEST(JSONConfigFile, FlatCommentsBadValue) {
+ OptionsParserTester parser;
+ moe::Environment environment;
+
+ moe::OptionSection testOpts;
+ testOpts.addOption(moe::OptionDescription("config", "config",
+ moe::String, "Config file to parse"));
+ testOpts.addOption(moe::OptionDescription("port", "port", moe::Int, "Port"));
+ testOpts.addOption(moe::OptionDescription("host", "host", moe::String, "Host"));
+
+ std::vector<std::string> argv;
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.json");
+ std::map<std::string, std::string> env_map;
+
+ parser.setConfig("config.json",
+ "{ comment : \"comment on port\", port : \"string\" ,"
+ " comment : \"comment on host\", host : \"localhost\" }");
+
+ moe::Value value;
+ ASSERT_NOT_OK(parser.run(testOpts, argv, env_map, &environment));
+ }
+
+ TEST(JSONConfigFile, NestedCommentsOtherTypes) {
+ OptionsParserTester parser;
+ moe::Environment environment;
+
+ moe::OptionSection testOpts;
+ testOpts.addOption(moe::OptionDescription("config", "config",
+ moe::String, "Config file to parse"));
+ testOpts.addOption(moe::OptionDescription("port", "port", moe::Int, "Port"));
+ testOpts.addOption(moe::OptionDescription("host", "host", moe::String, "Host"));
+
+ std::vector<std::string> argv;
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.json");
+ std::map<std::string, std::string> env_map;
+
+ parser.setConfig("config.json",
+ "{ port : { comment : [ \"can\", \"be\", \"array\", true ], value : 5 },"
+ " host : { comment : { nestedcomment : \"really descriptive\" },"
+ " value : \"localhost\" } }");
+
+ moe::Value value;
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_OK(environment.get(moe::Key("port"), &value));
+ int port;
+ ASSERT_OK(value.get(&port));
+ ASSERT_EQUALS(port, 5);
+ ASSERT_OK(environment.get(moe::Key("host"), &value));
+ std::string host;
+ ASSERT_OK(value.get(&host));
+ ASSERT_EQUALS(host, "localhost");
+ }
+
+ TEST(JSONConfigFile, FlatCommentsOtherTypes) {
+ OptionsParserTester parser;
+ moe::Environment environment;
+
+ moe::OptionSection testOpts;
+ testOpts.addOption(moe::OptionDescription("config", "config",
+ moe::String, "Config file to parse"));
+ testOpts.addOption(moe::OptionDescription("port", "port", moe::Int, "Port"));
+ testOpts.addOption(moe::OptionDescription("host", "host", moe::String, "Host"));
+
+ std::vector<std::string> argv;
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.json");
+ std::map<std::string, std::string> env_map;
+
+ parser.setConfig("config.json",
+ "{ comment : [ \"can\", \"be\", \"array\", true ], port : 5,"
+ " comment : { nestedcomment : \"really descriptive\" },"
+ " host : \"localhost\" }");
+
+ moe::Value value;
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_OK(environment.get(moe::Key("port"), &value));
+ int port;
+ ASSERT_OK(value.get(&port));
+ ASSERT_EQUALS(port, 5);
+ ASSERT_OK(environment.get(moe::Key("host"), &value));
+ std::string host;
+ ASSERT_OK(value.get(&host));
+ ASSERT_EQUALS(host, "localhost");
+ }
+
} // unnamed namespace