123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573 |
- /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include "configuration_test.h"
- #include "common/configuration.h"
- #include "common/configuration_loader.h"
- #include <gmock/gmock.h>
- #include <cstdio>
- #include <fstream>
- using ::testing::_;
- using namespace hdfs;
- namespace hdfs {
- TEST(ConfigurationTest, TestDegenerateInputs) {
- /* Completely empty stream */
- {
- std::stringstream stream;
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>("");
- EXPECT_FALSE(config && "Empty stream");
- }
- /* No values */
- {
- std::string data = "<configuration></configuration>";
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(data);
- EXPECT_TRUE(config && "Blank config");
- }
- /* Extraneous values */
- {
- std::string data = "<configuration><spam></spam></configuration>";
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(data);
- EXPECT_TRUE(config && "Extraneous values");
- }
- }
- TEST(ConfigurationTest, TestBasicOperations) {
- /* Single value */
- {
- std::stringstream stream;
- simpleConfigStream(stream, "key1", "value1");
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Parse single value");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- }
- /* Multiple values */
- {
- optional<Configuration> config =
- simpleConfig("key1", "value1", "key2", "value2");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- EXPECT_EQ("value2", config->GetWithDefault("key2", ""));
- }
- /* Case-insensitive */
- {
- std::stringstream stream;
- simpleConfigStream(stream, "key1", "value1");
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Parse single value");
- EXPECT_EQ("value1", config->GetWithDefault("KEY1", ""));
- }
- /* No defaults */
- {
- std::stringstream stream;
- simpleConfigStream(stream, "key1", "value1");
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Parse single value");
- optional<std::string> value = config->Get("key1");
- EXPECT_TRUE((bool)value);
- EXPECT_EQ("value1", *value);
- EXPECT_FALSE(config->Get("key2"));
- }
- }
- TEST(ConfigurationTest, TestCompactValues) {
- {
- std::stringstream stream;
- stream << "<configuration><property name=\"key1\" "
- "value=\"value1\"/></configuration>";
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Compact value parse");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- }
- }
- TEST(ConfigurationTest, TestMultipleResources) {
- /* Single value */
- {
- std::stringstream stream;
- simpleConfigStream(stream, "key1", "value1");
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Parse first stream");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- std::stringstream stream2;
- simpleConfigStream(stream2, "key2", "value2");
- optional<Configuration> config2 =
- ConfigurationLoader().OverlayResourceString(config.value(), stream2.str());
- EXPECT_TRUE(config2 && "Parse second stream");
- EXPECT_EQ("value1", config2->GetWithDefault("key1", ""));
- EXPECT_EQ("value2", config2->GetWithDefault("key2", ""));
- }
- }
- TEST(ConfigurationTest, TestStringResource) {
- /* Single value */
- {
- std::stringstream stream;
- simpleConfigStream(stream, "key1", "value1");
- std::string str = stream.str();
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Parse single value");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- }
- }
- TEST(ConfigurationTest, TestValueOverlay) {
- /* Incremental updates */
- {
- ConfigurationLoader loader;
- std::stringstream stream;
- stream << "<configuration>"
- "<property><name>key1</name><value>value1</value><final>false</final></property>"
- "<property><name>final2</name><value>value2</value><final>true</final></property>"
- "</configuration>";
- optional<Configuration> config = loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Parse single value");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- EXPECT_EQ("value2", config->GetWithDefault("final2", ""));
- config = loader.OverlayValue(config.value(), "key3", "value3");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- EXPECT_EQ("value2", config->GetWithDefault("final2", ""));
- EXPECT_EQ("value3", config->GetWithDefault("key3", ""));
- config = loader.OverlayValue(config.value(), "final2", "value4");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- EXPECT_EQ("value2", config->GetWithDefault("final2", ""));
- EXPECT_EQ("value3", config->GetWithDefault("key3", ""));
- // Case insensitive overlay
- config = loader.OverlayValue(config.value(), "KEY3", "value3a");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- EXPECT_EQ("value2", config->GetWithDefault("final2", ""));
- EXPECT_EQ("value3a", config->GetWithDefault("key3", ""));
- }
- }
- TEST(ConfigurationTest, TestFinal) {
- {
- /* Explicitly non-final non-compact value */
- std::stringstream stream;
- stream << "<configuration><property><name>key1</name><value>value1</"
- "value><final>false</final></property></configuration>";
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Parse first stream");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- std::stringstream stream2;
- simpleConfigStream(stream2, "key1", "value2");
- optional<Configuration> config2 =
- ConfigurationLoader().OverlayResourceString(config.value(), stream2.str());
- EXPECT_TRUE(config2 && "Parse second stream");
- EXPECT_EQ("value2", config2->GetWithDefault("key1", ""));
- }
- {
- /* Explicitly final non-compact value */
- std::stringstream stream;
- stream << "<configuration><property><name>key1</name><value>value1</"
- "value><final>true</final></property></configuration>";
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Parse first stream");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- std::stringstream stream2;
- simpleConfigStream(stream2, "key1", "value2");
- optional<Configuration> config2 =
- ConfigurationLoader().OverlayResourceString(config.value(), stream2.str());
- EXPECT_TRUE(config2 && "Parse second stream");
- EXPECT_EQ("value1", config2->GetWithDefault("key1", ""));
- }
- {
- /* Explicitly non-final compact value */
- std::stringstream stream;
- stream << "<configuration><property name=\"key1\" value=\"value1\" "
- "final=\"false\"/></configuration>";
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Parse first stream");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- std::stringstream stream2;
- simpleConfigStream(stream2, "key1", "value2");
- optional<Configuration> config2 =
- ConfigurationLoader().OverlayResourceString(config.value(), stream2.str());
- EXPECT_TRUE(config2 && "Parse second stream");
- EXPECT_EQ("value2", config2->GetWithDefault("key1", ""));
- }
- {
- /* Explicitly final compact value */
- std::stringstream stream;
- stream << "<configuration><property name=\"key1\" value=\"value1\" "
- "final=\"true\"/></configuration>";
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Parse first stream");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- std::stringstream stream2;
- simpleConfigStream(stream2, "key1", "value2");
- optional<Configuration> config2 =
- ConfigurationLoader().OverlayResourceString(config.value(), stream2.str());
- EXPECT_TRUE(config2 && "Parse second stream");
- EXPECT_EQ("value1", config2->GetWithDefault("key1", ""));
- }
- {
- /* Bogus final value */
- std::stringstream stream;
- stream << "<configuration><property><name>key1</name><value>value1</"
- "value><final>spam</final></property></configuration>";
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Parse first stream");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- std::stringstream stream2;
- simpleConfigStream(stream2, "key1", "value2");
- optional<Configuration> config2 =
- ConfigurationLoader().OverlayResourceString(config.value(), stream2.str());
- EXPECT_TRUE(config2 && "Parse second stream");
- EXPECT_EQ("value2", config2->GetWithDefault("key1", ""));
- }
- {
- /* Blank final value */
- std::stringstream stream;
- stream << "<configuration><property><name>key1</name><value>value1</"
- "value><final></final></property></configuration>";
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Parse first stream");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- std::stringstream stream2;
- simpleConfigStream(stream2, "key1", "value2");
- optional<Configuration> config2 =
- ConfigurationLoader().OverlayResourceString(config.value(), stream2.str());
- EXPECT_TRUE(config2 && "Parse second stream");
- EXPECT_EQ("value2", config2->GetWithDefault("key1", ""));
- }
- }
- TEST(ConfigurationTest, TestFileReads)
- {
- // Single stream
- {
- TempFile tempFile;
- writeSimpleConfig(tempFile.filename, "key1", "value1");
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.LoadFromFile<Configuration>(tempFile.filename);
- EXPECT_TRUE(config && "Parse first stream");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- }
- // Multiple files
- {
- TempFile tempFile;
- writeSimpleConfig(tempFile.filename, "key1", "value1");
- ConfigurationLoader loader;
- optional<Configuration> config = loader.LoadFromFile<Configuration>(tempFile.filename);
- ASSERT_TRUE(config && "Parse first stream");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- TempFile tempFile2;
- writeSimpleConfig(tempFile2.filename, "key2", "value2");
- optional<Configuration> config2 = loader.OverlayResourceFile(*config, tempFile2.filename);
- ASSERT_TRUE(config2 && "Parse second stream");
- EXPECT_EQ("value1", config2->GetWithDefault("key1", ""));
- EXPECT_EQ("value2", config2->GetWithDefault("key2", ""));
- }
- // Try to add a directory
- {
- TempDir tempDir;
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.LoadFromFile<Configuration>(tempDir.path);
- EXPECT_FALSE(config && "Add directory as file resource");
- }
- // Search path splitting
- {
- ConfigurationLoader loader;
- loader.SetSearchPath("foo:/bar:baz/:/fioux/:/bar/bar/bong");
- // Paths will have / appended to them if not already present
- EXPECT_EQ("foo/:/bar/:baz/:/fioux/:/bar/bar/bong/", loader.GetSearchPath());
- }
- // Search path
- {
- TempDir tempDir1;
- TempFile tempFile1(tempDir1.path + "/file1.xml");
- writeSimpleConfig(tempFile1.filename, "key1", "value1");
- TempDir tempDir2;
- TempFile tempFile2(tempDir2.path + "/file2.xml");
- writeSimpleConfig(tempFile2.filename, "key2", "value2");
- TempDir tempDir3;
- TempFile tempFile3(tempDir3.path + "/file3.xml");
- writeSimpleConfig(tempFile3.filename, "key3", "value3");
- ConfigurationLoader loader;
- loader.SetSearchPath(tempDir1.path + ":" + tempDir2.path + ":" + tempDir3.path);
- optional<Configuration> config1 = loader.LoadFromFile<Configuration>("file1.xml");
- EXPECT_TRUE(config1 && "Parse first stream");
- optional<Configuration> config2 = loader.OverlayResourceFile(*config1, "file2.xml");
- EXPECT_TRUE(config2 && "Parse second stream");
- optional<Configuration> config3 = loader.OverlayResourceFile(*config2, "file3.xml");
- EXPECT_TRUE(config3 && "Parse third stream");
- EXPECT_EQ("value1", config3->GetWithDefault("key1", ""));
- EXPECT_EQ("value2", config3->GetWithDefault("key2", ""));
- EXPECT_EQ("value3", config3->GetWithDefault("key3", ""));
- }
- }
- TEST(ConfigurationTest, TestDefaultConfigs) {
- // Search path
- {
- TempDir tempDir;
- TempFile coreSite(tempDir.path + "/core-site.xml");
- writeSimpleConfig(coreSite.filename, "key1", "value1");
- ConfigurationLoader loader;
- loader.SetSearchPath(tempDir.path);
- optional<Configuration> config = loader.LoadDefaultResources<Configuration>();
- EXPECT_TRUE(config && "Parse streams");
- EXPECT_EQ("value1", config->GetWithDefault("key1", ""));
- }
- }
- TEST(ConfigurationTest, TestIntConversions) {
- /* No defaults */
- {
- std::stringstream stream;
- simpleConfigStream(stream, "key1", "1");
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Parse single value");
- optional<int64_t> value = config->GetInt("key1");
- EXPECT_TRUE((bool)value);
- EXPECT_EQ(1, *value);
- EXPECT_FALSE(config->GetInt("key2"));
- }
- {
- optional<Configuration> config = simpleConfig("key1", "1");
- EXPECT_EQ(1, config->GetIntWithDefault("key1", -1));
- }
- {
- optional<Configuration> config = simpleConfig("key1", "-100");
- EXPECT_EQ(-100, config->GetIntWithDefault("key1", -1));
- }
- {
- optional<Configuration> config = simpleConfig("key1", " 1 ");
- EXPECT_EQ(1, config->GetIntWithDefault("key1", -1));
- }
- {
- optional<Configuration> config = simpleConfig("key1", "");
- EXPECT_EQ(-1, config->GetIntWithDefault("key1", -1));
- }
- {
- optional<Configuration> config = simpleConfig("key1", "spam");
- EXPECT_EQ(-1, config->GetIntWithDefault("key1", -1));
- }
- {
- optional<Configuration> config = simpleConfig("key2", "");
- EXPECT_EQ(-1, config->GetIntWithDefault("key1", -1));
- }
- }
- TEST(ConfigurationTest, TestDoubleConversions) {
- /* No defaults */
- {
- std::stringstream stream;
- simpleConfigStream(stream, "key1", "1");
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Parse single value");
- optional<double> value = config->GetDouble("key1");
- EXPECT_TRUE((bool)value);
- EXPECT_EQ(1, *value);
- EXPECT_FALSE(config->GetDouble("key2"));
- }
- {
- optional<Configuration> config = simpleConfig("key1", "1");
- EXPECT_EQ(1, config->GetDoubleWithDefault("key1", -1));
- }
- {
- optional<Configuration> config = simpleConfig("key1", "-100");
- EXPECT_EQ(-100, config->GetDoubleWithDefault("key1", -1));
- }
- {
- optional<Configuration> config = simpleConfig("key1", " 1 ");
- EXPECT_EQ(1, config->GetDoubleWithDefault("key1", -1));
- }
- {
- optional<Configuration> config = simpleConfig("key1", "");
- EXPECT_EQ(-1, config->GetDoubleWithDefault("key1", -1));
- }
- {
- optional<Configuration> config = simpleConfig("key1", "spam");
- EXPECT_EQ(-1, config->GetDoubleWithDefault("key1", -1));
- }
- {
- optional<Configuration> config = simpleConfig("key2", "");
- EXPECT_EQ(-1, config->GetDoubleWithDefault("key1", -1));
- }
- { /* Out of range */
- optional<Configuration> config = simpleConfig("key2", "1e9999");
- EXPECT_EQ(-1, config->GetDoubleWithDefault("key1", -1));
- }
- }
- TEST(ConfigurationTest, TestBoolConversions) {
- /* No defaults */
- {
- std::stringstream stream;
- simpleConfigStream(stream, "key1", "true");
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Parse single value");
- optional<bool> value = config->GetBool("key1");
- EXPECT_TRUE((bool)value);
- EXPECT_EQ(true, *value);
- EXPECT_FALSE(config->GetBool("key2"));
- }
- {
- optional<Configuration> config = simpleConfig("key1", "true");
- EXPECT_EQ(true, config->GetBoolWithDefault("key1", false));
- }
- {
- optional<Configuration> config = simpleConfig("key1", "tRuE");
- EXPECT_EQ(true, config->GetBoolWithDefault("key1", false));
- }
- {
- optional<Configuration> config = simpleConfig("key1", "false");
- EXPECT_FALSE(config->GetBoolWithDefault("key1", true));
- }
- {
- optional<Configuration> config = simpleConfig("key1", "FaLsE");
- EXPECT_FALSE(config->GetBoolWithDefault("key1", true));
- }
- {
- optional<Configuration> config = simpleConfig("key1", " FaLsE ");
- EXPECT_FALSE(config->GetBoolWithDefault("key1", true));
- }
- {
- optional<Configuration> config = simpleConfig("key1", "");
- EXPECT_EQ(true, config->GetBoolWithDefault("key1", true));
- }
- {
- optional<Configuration> config = simpleConfig("key1", "spam");
- EXPECT_EQ(true, config->GetBoolWithDefault("key1", true));
- }
- {
- optional<Configuration> config = simpleConfig("key1", "");
- EXPECT_EQ(true, config->GetBoolWithDefault("key2", true));
- }
- }
- TEST(ConfigurationTest, TestUriConversions) {
- /* No defaults */
- {
- std::stringstream stream;
- simpleConfigStream(stream, "key1", "hdfs:///");
- ConfigurationLoader config_loader;
- config_loader.ClearSearchPath();
- optional<Configuration> config = config_loader.Load<Configuration>(stream.str());
- EXPECT_TRUE(config && "Parse single value");
- optional<URI> value = config->GetUri("key1");
- EXPECT_TRUE((bool)value);
- EXPECT_EQ("hdfs:///", value->str());
- EXPECT_FALSE(config->GetUri("key2"));
- }
- {
- optional<Configuration> config = simpleConfig("key1", "hdfs:///");
- EXPECT_EQ("hdfs:///", config->GetUriWithDefault("key1", "http:///").str());
- }
- {
- optional<Configuration> config = simpleConfig("key1", " hdfs:/// ");
- EXPECT_EQ("hdfs:///", config->GetUriWithDefault("key1", "http:///").str());
- }
- {
- optional<Configuration> config = simpleConfig("key1", "");
- EXPECT_EQ("", config->GetUriWithDefault("key1", "http:///").str());
- }
- {
- optional<Configuration> config = simpleConfig("key1", "%%"); // invalid URI
- EXPECT_EQ("http:///", config->GetUriWithDefault("key1", "http:///").str());
- }
- {
- optional<Configuration> config = simpleConfig("key2", "hdfs:///");
- EXPECT_EQ("http:///", config->GetUriWithDefault("key1", "http:///").str());
- }
- }
- int main(int argc, char *argv[]) {
- /*
- * The following line must be executed to initialize Google Mock
- * (and Google Test) before running the tests.
- */
- ::testing::InitGoogleMock(&argc, argv);
- return RUN_ALL_TESTS();
- }
- }
|