/** * 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 #include #include using ::testing::_; using namespace hdfs; namespace hdfs { TEST(ConfigurationTest, TestDegenerateInputs) { /* Completely empty stream */ { std::stringstream stream; ConfigurationLoader config_loader; config_loader.ClearSearchPath(); optional config = config_loader.Load(""); EXPECT_FALSE(config && "Empty stream"); } /* No values */ { std::string data = ""; ConfigurationLoader config_loader; config_loader.ClearSearchPath(); optional config = config_loader.Load(data); EXPECT_TRUE(config && "Blank config"); } /* Extraneous values */ { std::string data = ""; ConfigurationLoader config_loader; config_loader.ClearSearchPath(); optional config = config_loader.Load(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 config = config_loader.Load(stream.str()); EXPECT_TRUE(config && "Parse single value"); EXPECT_EQ("value1", config->GetWithDefault("key1", "")); } /* Multiple values */ { optional 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 config = config_loader.Load(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 config = config_loader.Load(stream.str()); EXPECT_TRUE(config && "Parse single value"); optional value = config->Get("key1"); EXPECT_TRUE((bool)value); EXPECT_EQ("value1", *value); EXPECT_FALSE(config->Get("key2")); } } TEST(ConfigurationTest, TestCompactValues) { { std::stringstream stream; stream << ""; ConfigurationLoader config_loader; config_loader.ClearSearchPath(); optional config = config_loader.Load(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 config = config_loader.Load(stream.str()); EXPECT_TRUE(config && "Parse first stream"); EXPECT_EQ("value1", config->GetWithDefault("key1", "")); std::stringstream stream2; simpleConfigStream(stream2, "key2", "value2"); optional 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 config = config_loader.Load(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 << "" "key1value1false" "final2value2true" ""; optional config = loader.Load(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 << "key1value1false"; ConfigurationLoader config_loader; config_loader.ClearSearchPath(); optional config = config_loader.Load(stream.str()); EXPECT_TRUE(config && "Parse first stream"); EXPECT_EQ("value1", config->GetWithDefault("key1", "")); std::stringstream stream2; simpleConfigStream(stream2, "key1", "value2"); optional 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 << "key1value1true"; ConfigurationLoader config_loader; config_loader.ClearSearchPath(); optional config = config_loader.Load(stream.str()); EXPECT_TRUE(config && "Parse first stream"); EXPECT_EQ("value1", config->GetWithDefault("key1", "")); std::stringstream stream2; simpleConfigStream(stream2, "key1", "value2"); optional 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 << ""; ConfigurationLoader config_loader; config_loader.ClearSearchPath(); optional config = config_loader.Load(stream.str()); EXPECT_TRUE(config && "Parse first stream"); EXPECT_EQ("value1", config->GetWithDefault("key1", "")); std::stringstream stream2; simpleConfigStream(stream2, "key1", "value2"); optional 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 << ""; ConfigurationLoader config_loader; config_loader.ClearSearchPath(); optional config = config_loader.Load(stream.str()); EXPECT_TRUE(config && "Parse first stream"); EXPECT_EQ("value1", config->GetWithDefault("key1", "")); std::stringstream stream2; simpleConfigStream(stream2, "key1", "value2"); optional 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 << "key1value1spam"; ConfigurationLoader config_loader; config_loader.ClearSearchPath(); optional config = config_loader.Load(stream.str()); EXPECT_TRUE(config && "Parse first stream"); EXPECT_EQ("value1", config->GetWithDefault("key1", "")); std::stringstream stream2; simpleConfigStream(stream2, "key1", "value2"); optional 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 << "key1value1"; ConfigurationLoader config_loader; config_loader.ClearSearchPath(); optional config = config_loader.Load(stream.str()); EXPECT_TRUE(config && "Parse first stream"); EXPECT_EQ("value1", config->GetWithDefault("key1", "")); std::stringstream stream2; simpleConfigStream(stream2, "key1", "value2"); optional 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 config = config_loader.LoadFromFile(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 config = loader.LoadFromFile(tempFile.filename); ASSERT_TRUE(config && "Parse first stream"); EXPECT_EQ("value1", config->GetWithDefault("key1", "")); TempFile tempFile2; writeSimpleConfig(tempFile2.filename, "key2", "value2"); optional 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 config = config_loader.LoadFromFile(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 config1 = loader.LoadFromFile("file1.xml"); EXPECT_TRUE(config1 && "Parse first stream"); optional config2 = loader.OverlayResourceFile(*config1, "file2.xml"); EXPECT_TRUE(config2 && "Parse second stream"); optional 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 config = loader.LoadDefaultResources(); 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 config = config_loader.Load(stream.str()); EXPECT_TRUE(config && "Parse single value"); optional value = config->GetInt("key1"); EXPECT_TRUE((bool)value); EXPECT_EQ(1, *value); EXPECT_FALSE(config->GetInt("key2")); } { optional config = simpleConfig("key1", "1"); EXPECT_EQ(1, config->GetIntWithDefault("key1", -1)); } { optional config = simpleConfig("key1", "-100"); EXPECT_EQ(-100, config->GetIntWithDefault("key1", -1)); } { optional config = simpleConfig("key1", " 1 "); EXPECT_EQ(1, config->GetIntWithDefault("key1", -1)); } { optional config = simpleConfig("key1", ""); EXPECT_EQ(-1, config->GetIntWithDefault("key1", -1)); } { optional config = simpleConfig("key1", "spam"); EXPECT_EQ(-1, config->GetIntWithDefault("key1", -1)); } { optional 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 config = config_loader.Load(stream.str()); EXPECT_TRUE(config && "Parse single value"); optional value = config->GetDouble("key1"); EXPECT_TRUE((bool)value); EXPECT_EQ(1, *value); EXPECT_FALSE(config->GetDouble("key2")); } { optional config = simpleConfig("key1", "1"); EXPECT_EQ(1, config->GetDoubleWithDefault("key1", -1)); } { optional config = simpleConfig("key1", "-100"); EXPECT_EQ(-100, config->GetDoubleWithDefault("key1", -1)); } { optional config = simpleConfig("key1", " 1 "); EXPECT_EQ(1, config->GetDoubleWithDefault("key1", -1)); } { optional config = simpleConfig("key1", ""); EXPECT_EQ(-1, config->GetDoubleWithDefault("key1", -1)); } { optional config = simpleConfig("key1", "spam"); EXPECT_EQ(-1, config->GetDoubleWithDefault("key1", -1)); } { optional config = simpleConfig("key2", ""); EXPECT_EQ(-1, config->GetDoubleWithDefault("key1", -1)); } { /* Out of range */ optional 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 config = config_loader.Load(stream.str()); EXPECT_TRUE(config && "Parse single value"); optional value = config->GetBool("key1"); EXPECT_TRUE((bool)value); EXPECT_EQ(true, *value); EXPECT_FALSE(config->GetBool("key2")); } { optional config = simpleConfig("key1", "true"); EXPECT_EQ(true, config->GetBoolWithDefault("key1", false)); } { optional config = simpleConfig("key1", "tRuE"); EXPECT_EQ(true, config->GetBoolWithDefault("key1", false)); } { optional config = simpleConfig("key1", "false"); EXPECT_FALSE(config->GetBoolWithDefault("key1", true)); } { optional config = simpleConfig("key1", "FaLsE"); EXPECT_FALSE(config->GetBoolWithDefault("key1", true)); } { optional config = simpleConfig("key1", " FaLsE "); EXPECT_FALSE(config->GetBoolWithDefault("key1", true)); } { optional config = simpleConfig("key1", ""); EXPECT_EQ(true, config->GetBoolWithDefault("key1", true)); } { optional config = simpleConfig("key1", "spam"); EXPECT_EQ(true, config->GetBoolWithDefault("key1", true)); } { optional 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 config = config_loader.Load(stream.str()); EXPECT_TRUE(config && "Parse single value"); optional value = config->GetUri("key1"); EXPECT_TRUE((bool)value); EXPECT_EQ("hdfs:///", value->str()); EXPECT_FALSE(config->GetUri("key2")); } { optional config = simpleConfig("key1", "hdfs:///"); EXPECT_EQ("hdfs:///", config->GetUriWithDefault("key1", "http:///").str()); } { optional config = simpleConfig("key1", " hdfs:/// "); EXPECT_EQ("hdfs:///", config->GetUriWithDefault("key1", "http:///").str()); } { optional config = simpleConfig("key1", ""); EXPECT_EQ("", config->GetUriWithDefault("key1", "http:///").str()); } { optional config = simpleConfig("key1", "%%"); // invalid URI EXPECT_EQ("http:///", config->GetUriWithDefault("key1", "http:///").str()); } { optional 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(); } }