#include "common.hh" #include "config.hh" #include "file_test.hh" #include "logger.hh" #include "unique_fd.hh" #include #include namespace { class ConfigTest : public FileTest { protected: ConfigTest() : logger_(Logger::create_null()) {} Logger* logger() const { return logger_.get(); } private: std::unique_ptr logger_; }; } // namespace TEST(Config, empty) { auto cfg = Config::create_empty(); EXPECT_EQ("bar", cfg->get("foo", std::string_view("bar"))); EXPECT_STREQ("bar", cfg->get("foo", "bar")); EXPECT_EQ(1000, cfg->get("foo", 1000)); EXPECT_EQ(0, cfg->get_size("foo", 0)); EXPECT_EQ(0.0, cfg->get_duration("foo", 0.0)); EXPECT_TRUE(cfg->get_path("foo", "").empty()); EXPECT_EQ("bar", cfg->get_path("foo", "bar")); } TEST_F(ConfigTest, empty_file) { write(""); auto cfg = Config::create(logger(), path()); ASSERT_TRUE(cfg); EXPECT_EQ("bar", cfg->get("foo", std::string_view("bar"))); EXPECT_STREQ("bar", cfg->get("foo", "bar")); EXPECT_EQ(1000, cfg->get("foo", 1000)); EXPECT_EQ(0, cfg->get_size("foo", 0)); EXPECT_TRUE(cfg->get_path("foo", "").empty()); } TEST_F(ConfigTest, sanity) { write("# comment\n" "str = bar\n" "uint = 1000\n" "size = 1M\n" "path = /root\n"); auto cfg = Config::create(logger(), path()); ASSERT_TRUE(cfg); EXPECT_EQ("bar", cfg->get("str", std::string_view())); EXPECT_STREQ("bar", cfg->get("str", "")); EXPECT_EQ(1000, cfg->get("uint", static_cast(0))); EXPECT_EQ(1024 * 1024, cfg->get_size("size", 0)); EXPECT_EQ("/root", cfg->get_path("path", "")); } TEST_F(ConfigTest, missing_equal) { write("bad file\n"); auto cfg = Config::create(logger(), path()); EXPECT_FALSE(cfg); } TEST_F(ConfigTest, missing_key) { write("= arg\n"); auto cfg = Config::create(logger(), path()); EXPECT_FALSE(cfg); } TEST_F(ConfigTest, sizes) { write("bytes1 = 12\n" "bytes2 = 12b\n" "bytes3 = 12B\n" "kilo1 = 1.2k\n" "kilo2 = 1.2K\n" "kilo3 = 1.2Kb\n" "mega1 = 1.2m\n" "mega2 = 1.2M\n" "mega3 = 1.2MB\n" "giga1 = .2g\n" "giga2 = .2G\n" "terra1 = 2.t\n" "terra2 = 2.T\n" "unknown = 4X\n" "nan = X\n"); auto cfg = Config::create(logger(), path()); ASSERT_TRUE(cfg); EXPECT_EQ(12, cfg->get_size("bytes1", 0)); EXPECT_EQ(12, cfg->get_size("bytes2", 0)); EXPECT_EQ(12, cfg->get_size("bytes3", 0)); EXPECT_EQ(1228, cfg->get_size("kilo1", 0)); EXPECT_EQ(1228, cfg->get_size("kilo2", 0)); EXPECT_EQ(1228, cfg->get_size("kilo3", 0)); EXPECT_EQ(1258291, cfg->get_size("mega1", 0)); EXPECT_EQ(1258291, cfg->get_size("mega2", 0)); EXPECT_EQ(1258291, cfg->get_size("mega3", 0)); EXPECT_EQ(static_cast(214748364), cfg->get_size("giga1", 0)); EXPECT_EQ(static_cast(214748364), cfg->get_size("giga2", 0)); EXPECT_EQ(static_cast(2) * 1024 * 1024 * 1024 * 1024, cfg->get_size("terra1", 0)); EXPECT_EQ(static_cast(2) * 1024 * 1024 * 1024 * 1024, cfg->get_size("terra2", 0)); EXPECT_FALSE(cfg->get_size("unknown", 0).has_value()); EXPECT_FALSE(cfg->get_size("nan", 0).has_value()); } TEST_F(ConfigTest, durations) { write("seconds1 = 1.2\n" "seconds2 = 1.2s\n" "seconds3 = 1.2S\n" "min1 = .5m\n" "min2 = .5M\n" "hour1 = 12.1h\n" "hour2 = 12.1H\n" "milli1 = 100ms\n" "milli2 = 100MS\n" "nano1 = 20000ns\n" "nano2 = 20000NS\n" "unknown = 4X\n" "nan = X\n"); auto cfg = Config::create(logger(), path()); ASSERT_TRUE(cfg); EXPECT_EQ(1.2, cfg->get_duration("seconds1", 0)); EXPECT_EQ(1.2, cfg->get_duration("seconds2", 0)); EXPECT_EQ(1.2, cfg->get_duration("seconds3", 0)); EXPECT_EQ(30., cfg->get_duration("min1", 0)); EXPECT_EQ(30., cfg->get_duration("min2", 0)); EXPECT_EQ(43560., cfg->get_duration("hour1", 0)); EXPECT_EQ(43560., cfg->get_duration("hour2", 0)); EXPECT_EQ(.1, cfg->get_duration("milli1", 0)); EXPECT_EQ(.1, cfg->get_duration("milli2", 0)); EXPECT_EQ(.02, cfg->get_duration("nano1", 0)); EXPECT_EQ(.02, cfg->get_duration("nano2", 0)); EXPECT_FALSE(cfg->get_duration("unknown", 0).has_value()); EXPECT_FALSE(cfg->get_duration("nan", 0).has_value()); } TEST_F(ConfigTest, uint64) { write("max = 18446744073709551615\n" "hex = 0xffffffffffffffff\n" "negative = -10\n" "suffix = 100X\n" "nan = X\n"); auto cfg = Config::create(logger(), path()); ASSERT_TRUE(cfg); EXPECT_EQ(0xffffffffffffffff, cfg->get("max", static_cast(0))); EXPECT_FALSE(cfg->get("hex", static_cast(0)).has_value()); EXPECT_FALSE(cfg->get("negative", static_cast(0)).has_value()); EXPECT_FALSE(cfg->get("suffix", static_cast(0)).has_value()); EXPECT_FALSE(cfg->get("nan", static_cast(0)).has_value()); } TEST_F(ConfigTest, path) { write("absolute = /file\n" "relative = file\n"); auto cfg = Config::create(logger(), path()); ASSERT_TRUE(cfg); EXPECT_EQ("/file", cfg->get_path("absolute", "")); EXPECT_EQ(path().parent_path() / "file", cfg->get_path("relative", "")); }