blob: a5760e8ed8150d4acf54f58e24b3c5c40320b454 [file] [log] [blame]
/*
* 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 <fstream>
#include <iostream>
#include <glog/logging.h>
#include <boost/filesystem.hpp>
#include "hbase/client/configuration.h"
#include "hbase/client/hbase-configuration-loader.h"
#include "hbase/test-util/test-util.h"
#include "hbase/utils/optional.h"
using namespace hbase;
const std::string kDefHBaseConfPath("./build/test-data/hbase-configuration-test/conf/");
const std::string kHBaseConfPath("./build/test-data/hbase-configuration-test/custom-conf/");
const std::string kHBaseDefaultXml("hbase-default.xml");
const std::string kHBaseSiteXml("hbase-site.xml");
const std::string kHBaseDefaultXmlData(
"<?xml version=\"1.0\"?>\n<?xml-stylesheet type=\"text/xsl\" "
"href=\"configuration.xsl\"?>\n<!--\n/**\n *\n * Licensed to the Apache "
"Software Foundation (ASF) under one\n * or more contributor license "
"agreements. See the NOTICE file\n * distributed with this work for "
"additional information\n * regarding copyright ownership. The ASF "
"licenses this file\n * to you under the Apache License, Version 2.0 "
"(the\n * \"License\"); you may not use this file except in compliance\n * "
"with the License. You may obtain a copy of the License at\n *\n * "
"http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by "
"applicable law or agreed to in writing, software\n * distributed under "
"the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES "
"OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License "
"for the specific language governing permissions and\n * limitations under "
"the License.\n "
"*/\n-->\n<configuration>\n\n<property>\n<name>hbase.rootdir</"
"name>\n<value>/root/hbase-docker/apps/hbase/data</value>\n<final>true</"
"final>\n</"
"property>\n\n<property>\n<name>hbase.zookeeper.property.datadir</"
"name>\n<value>This value will be "
"overwritten</value>\n<final>false</final>\n</"
"property>\n\n<property>\n<name>default-prop</name>\n<value>default-value</"
"value>\n</property>\n\n</configuration>");
const std::string kHBaseSiteXmlData(
"<?xml version=\"1.0\"?>\n<?xml-stylesheet type=\"text/xsl\" "
"href=\"configuration.xsl\"?>\n<!--\n/**\n *\n * Licensed to the Apache "
"Software Foundation (ASF) under one\n * or more contributor license "
"agreements. See the NOTICE file\n * distributed with this work for "
"additional information\n * regarding copyright ownership. The ASF "
"licenses this file\n * to you under the Apache License, Version 2.0 "
"(the\n * \"License\"); you may not use this file except in compliance\n * "
"with the License. You may obtain a copy of the License at\n *\n * "
"http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by "
"applicable law or agreed to in writing, software\n * distributed under "
"the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES "
"OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License "
"for the specific language governing permissions and\n * limitations under "
"the License.\n "
"*/\n-->\n<configuration>\n\n<property>\n<name>hbase.rootdir</"
"name>\n<value>This value will not be be "
"overwritten</value>\n</"
"property>\n\n<property>\n<name>hbase.zookeeper.property.datadir</"
"name>\n<value>/root/hbase-docker/zookeeper</value>\n</"
"property>\n\n<property>\n<name>hbase-client.user.name</"
"name>\n<value>${user.name}</value>\n</"
"property>\n\n<property>\n<name>hbase-client.user.dir</"
"name>\n<value>${user.dir}</value>\n</"
"property>\n\n<property>\n<name>hbase-client.user.home</"
"name>\n<value>${user.home}</value>\n</"
"property>\n\n<property>\n<name>selfRef</name>\n<value>${selfRef}</"
"value>\n</property>\n\n<property>\n<name>foo.substs</"
"name>\n<value>${bar},${bar},${bar},${bar},${bar},${bar},${bar},${bar},${"
"bar},${bar},</value>\n</"
"property>\n\n<property>\n<name>foo.substs.exception</"
"name>\n<value>${bar},${bar},${bar},${bar},${bar},${bar},${bar},${bar},${"
"bar},${bar},${bar},${bar},${bar},${bar},${bar},${bar},${bar},${bar},${bar}"
",${bar},${bar}</value>\n</property>\n\n<property>\n<name>bar</"
"name>\n<value>bar-value</value>\n</"
"property>\n\n<property>\n<name>custom-prop</name>\n<value>custom-value</"
"value>\n</property>\n\n<property>\n<name>int</name>\n<value>16000</"
"value>\n</property>\n\n<property>\n<name>int.largevalue</"
"name>\n<value>2147483646</value>\n</"
"property>\n\n<property>\n<name>int.exception</name>\n<value>2147483648</"
"value>\n</property>\n\n<property>\n<name>long</name>\n<value>2147483850</"
"value>\n</property>\n\n<property>\n<name>long.largevalue</"
"name>\n<value>9223372036854775807</value>\n</"
"property>\n\n<property>\n<name>long.exception</"
"name>\n<value>9223372036854775810</value>\n</"
"property>\n\n<property>\n<name>double</name>\n<value>17.9769e+100</"
"value>\n</property>\n\n<property>\n<name>double.largevalue</"
"name>\n<value>170.769e+200</value>\n</"
"property>\n\n<property>\n<name>double.exception</"
"name>\n<value>1.79769e+310</value>\n</"
"property>\n\n<property>\n<name>bool.true</name>\n<value>true</value>\n</"
"property>\n\n<property>\n<name>bool.false</name>\n<value>false</value>\n</"
"property>\n\n<property>\n<name>bool.exception</name>\n<value>unknown "
"bool</value>\n</property>\n\n</configuration>");
void WriteDataToFile(const std::string &file, const std::string &xml_data) {
std::ofstream hbase_conf;
hbase_conf.open(file.c_str());
hbase_conf << xml_data;
hbase_conf.close();
}
void CreateHBaseConf(const std::string &dir, const std::string &file, const std::string xml_data) {
// Directory will be created if not present
if (!boost::filesystem::exists(dir)) {
boost::filesystem::create_directories(dir);
}
// Remove temp file always
boost::filesystem::remove((dir + file).c_str());
WriteDataToFile((dir + file), xml_data);
}
void CreateHBaseConfWithEnv() {
CreateHBaseConf(kDefHBaseConfPath, kHBaseDefaultXml, kHBaseDefaultXmlData);
CreateHBaseConf(kDefHBaseConfPath, kHBaseSiteXml, kHBaseSiteXmlData);
setenv("HBASE_CONF", kDefHBaseConfPath.c_str(), 1);
}
/*
* Config will be loaded from $HBASE_CONF. We set it @ kDefHBaseConfPath
* Config values will be loaded from hbase-default.xml and hbase-site.xml
* present in the above path.
*/
TEST(Configuration, LoadConfFromDefaultLocation) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConf(kDefHBaseConfPath, kHBaseDefaultXml, kHBaseDefaultXmlData);
CreateHBaseConf(kDefHBaseConfPath, kHBaseSiteXml, kHBaseSiteXmlData);
setenv("HBASE_CONF", kDefHBaseConfPath.c_str(), 0);
HBaseConfigurationLoader loader;
hbase::optional<Configuration> conf = loader.LoadDefaultResources();
ASSERT_TRUE(conf != none) << "No configuration object present.";
EXPECT_STREQ((*conf).Get("custom-prop", "Set this value").c_str(), "custom-value");
EXPECT_STREQ((*conf).Get("default-prop", "Set this value").c_str(), "default-value");
}
/*
* Config will be loaded from hbase-site.xml defined at
* kHBaseConfPath
*/
TEST(Configuration, LoadConfFromCustomLocation) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConf(kHBaseConfPath, kHBaseSiteXml, kHBaseSiteXmlData);
HBaseConfigurationLoader loader;
std::vector<std::string> resources{kHBaseSiteXml};
hbase::optional<Configuration> conf = loader.LoadResources(kHBaseConfPath, resources);
ASSERT_TRUE(conf != none) << "No configuration object present.";
EXPECT_STREQ((*conf).Get("custom-prop", "").c_str(), "custom-value");
EXPECT_STRNE((*conf).Get("custom-prop", "").c_str(), "some-value");
}
/*
* Config will be loaded from hbase-defualt.xml and hbase-site.xml @
* kDefHBaseConfPath and kHBaseConfPath respectively.
*/
TEST(Configuration, LoadConfFromMultipleLocatons) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConf(kDefHBaseConfPath, kHBaseDefaultXml, kHBaseDefaultXmlData);
CreateHBaseConf(kDefHBaseConfPath, kHBaseSiteXml, kHBaseSiteXmlData);
CreateHBaseConf(kHBaseConfPath, kHBaseDefaultXml, kHBaseDefaultXmlData);
CreateHBaseConf(kHBaseConfPath, kHBaseSiteXml, kHBaseSiteXmlData);
HBaseConfigurationLoader loader;
std::string conf_paths = kDefHBaseConfPath + ":" + kHBaseConfPath;
std::vector<std::string> resources{kHBaseDefaultXml, kHBaseSiteXml};
hbase::optional<Configuration> conf = loader.LoadResources(conf_paths, resources);
ASSERT_TRUE(conf != none) << "No configuration object present.";
EXPECT_STREQ((*conf).Get("default-prop", "From hbase-default.xml").c_str(), "default-value");
EXPECT_STREQ((*conf).Get("custom-prop", "").c_str(), "custom-value");
EXPECT_STRNE((*conf).Get("custom-prop", "").c_str(), "some-value");
}
/*
* Config will be loaded from hbase-defualt.xml and hbase-site.xml @
* $HBASE_CONF.
* We set HBASE_CONF to kDefHBaseConfPath
* Below tests load the conf files in the same way unless specified.
*/
TEST(Configuration, DefaultValues) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConfWithEnv();
HBaseConfigurationLoader loader;
hbase::optional<Configuration> conf = loader.LoadDefaultResources();
ASSERT_TRUE(conf != none) << "No configuration object present.";
EXPECT_STREQ((*conf).Get("default-prop", "Set this value.").c_str(), "default-value");
EXPECT_STREQ((*conf).Get("custom-prop", "Set this value.").c_str(), "custom-value");
}
TEST(Configuration, FinalValues) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConfWithEnv();
HBaseConfigurationLoader loader;
hbase::optional<Configuration> conf = loader.LoadDefaultResources();
ASSERT_TRUE(conf != none) << "No configuration object present.";
EXPECT_STREQ((*conf).Get("hbase.rootdir", "").c_str(), "/root/hbase-docker/apps/hbase/data");
EXPECT_STREQ((*conf).Get("hbase.zookeeper.property.datadir", "").c_str(),
"/root/hbase-docker/zookeeper");
EXPECT_STRNE((*conf).Get("hbase.rootdir", "").c_str(), "This value will not be be overwritten");
EXPECT_STRNE((*conf).Get("hbase.zookeeper.property.datadir", "").c_str(),
"This value will be overwritten");
}
/*
* Config will be loaded from HBASE_CONF which we set in
* CreateHBaseConfWithEnv().
* Config values will be loaded from hbase-default.xml and hbase-site.xml in the
* above path.
*/
TEST(Configuration, EnvVars) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConfWithEnv();
HBaseConfigurationLoader loader;
hbase::optional<Configuration> conf = loader.LoadDefaultResources();
ASSERT_TRUE(conf != none) << "No configuration object present.";
EXPECT_STREQ((*conf).Get("hbase-client.user.name", "").c_str(), "${user.name}");
EXPECT_STRNE((*conf).Get("hbase-client.user.name", "root").c_str(), "test-user");
}
TEST(Configuration, SelfRef) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConfWithEnv();
HBaseConfigurationLoader loader;
hbase::optional<Configuration> conf = loader.LoadDefaultResources();
ASSERT_TRUE(conf != none) << "No configuration object present.";
EXPECT_STREQ((*conf).Get("selfRef", "${selfRef}").c_str(), "${selfRef}");
}
TEST(Configuration, VarExpansion) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConfWithEnv();
HBaseConfigurationLoader loader;
hbase::optional<Configuration> conf = loader.LoadDefaultResources();
ASSERT_TRUE(conf != none) << "No configuration object present.";
EXPECT_STREQ((*conf).Get("foo.substs", "foo-value").c_str(),
"bar-value,bar-value,bar-value,bar-value,bar-value,bar-value,"
"bar-value,bar-value,bar-value,bar-value,");
EXPECT_STRNE((*conf).Get("foo.substs", "foo-value").c_str(), "bar-value");
}
TEST(Configuration, VarExpansionException) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConfWithEnv();
HBaseConfigurationLoader loader;
hbase::optional<Configuration> conf = loader.LoadDefaultResources();
ASSERT_TRUE(conf != none) << "No configuration object present.";
ASSERT_THROW((*conf).Get("foo.substs.exception", "foo-value").c_str(), std::runtime_error);
}
TEST(Configuration, GetInt) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConfWithEnv();
HBaseConfigurationLoader loader;
hbase::optional<Configuration> conf = loader.LoadDefaultResources();
ASSERT_TRUE(conf != none) << "No configuration object present.";
EXPECT_EQ(16000, (*conf).GetInt("int", 0));
EXPECT_EQ(2147483646, (*conf).GetInt("int.largevalue", 0));
}
TEST(Configuration, GetLong) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConfWithEnv();
HBaseConfigurationLoader loader;
hbase::optional<Configuration> conf = loader.LoadDefaultResources();
ASSERT_TRUE(conf != none) << "No configuration object present.";
EXPECT_EQ(2147483850, (*conf).GetLong("long", 0));
EXPECT_EQ(9223372036854775807, (*conf).GetLong("long.largevalue", 0));
}
TEST(Configuration, GetDouble) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConfWithEnv();
HBaseConfigurationLoader loader;
hbase::optional<Configuration> conf = loader.LoadDefaultResources();
ASSERT_TRUE(conf != none) << "No configuration object present.";
EXPECT_DOUBLE_EQ(17.9769e+100, (*conf).GetDouble("double", 0.0));
EXPECT_DOUBLE_EQ(170.769e+200, (*conf).GetDouble("double.largevalue", 0.0));
}
TEST(Configuration, GetBool) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConfWithEnv();
HBaseConfigurationLoader loader;
hbase::optional<Configuration> conf = loader.LoadDefaultResources();
ASSERT_TRUE(conf != none) << "No configuration object present.";
EXPECT_EQ(true, (*conf).GetBool("bool.true", true));
EXPECT_EQ(false, (*conf).GetBool("bool.false", false));
}
TEST(Configuration, GetIntException) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConfWithEnv();
HBaseConfigurationLoader loader;
hbase::optional<Configuration> conf = loader.LoadDefaultResources();
ASSERT_TRUE(conf != none) << "No configuration object present.";
ASSERT_THROW((*conf).GetInt("int.exception", 0), std::runtime_error);
}
TEST(Configuration, GetLongException) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConfWithEnv();
HBaseConfigurationLoader loader;
hbase::optional<Configuration> conf = loader.LoadDefaultResources();
ASSERT_TRUE(conf != none) << "No configuration object present.";
ASSERT_THROW((*conf).GetLong("long.exception", 0), std::runtime_error);
}
TEST(Configuration, GetDoubleException) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConfWithEnv();
HBaseConfigurationLoader loader;
hbase::optional<Configuration> conf = loader.LoadDefaultResources();
ASSERT_TRUE(conf != none) << "No configuration object present.";
ASSERT_THROW((*conf).GetDouble("double.exception", 0), std::runtime_error);
}
TEST(Configuration, GetBoolException) {
// Remove already configured env if present.
unsetenv("HBASE_CONF");
CreateHBaseConfWithEnv();
HBaseConfigurationLoader loader;
hbase::optional<Configuration> conf = loader.LoadDefaultResources();
ASSERT_TRUE(conf != none) << "No configuration object present.";
ASSERT_THROW((*conf).GetBool("bool.exception", false), std::runtime_error);
}
HBASE_TEST_MAIN()