diff options
author | Shaun Verch <shaun.verch@10gen.com> | 2013-10-08 12:04:58 -0400 |
---|---|---|
committer | Shaun Verch <shaun.verch@10gen.com> | 2013-10-09 10:06:37 -0400 |
commit | fc67141dcb245aaaa47321c863c8d26aef6bb5ee (patch) | |
tree | 21ecf40bb45e20948d014ee9c75a5dbac0263abb /src/mongo/util | |
parent | 606b6ee6cab9809a0124d13b5a7aebcddad027cc (diff) | |
download | mongo-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.cpp | 27 | ||||
-rw-r--r-- | src/mongo/util/options_parser/options_parser_test.cpp | 210 |
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 |