// ----------------------------------------------------------------------
// File: configuration.cc
// Author: Georgios Bitzes - CERN
// ----------------------------------------------------------------------
/************************************************************************
* quarkdb - a redis-like highly available key-value store *
* Copyright (C) 2016 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see .*
************************************************************************/
#include "Configuration.hh"
#include "config/ConfigurationReader.hh"
#include
using namespace quarkdb;
TEST(ConfigurationReader, BasicSanity) {
ConfigurationReader cr(
"if exec xrootd\n"
"xrd.protocol redis:7776 libXrdQuarkDB.so\n"
"redis.mode raft\n"
" redis.database /home/user/mydb\n"
"redis.myself server1:7776\n"
"redis.trace debug\n"
"redis.write_ahead_log true\n"
"redis.password_file /tmp/quarkdb-tests/password-file\n"
"redis.require_password_for_localhost true\n"
"fi\n");
ASSERT_FALSE(cr.eof());
ASSERT_EQ(cr.getCurrentWord(), "if");
cr.advanceWord();
ASSERT_EQ(cr.getCurrentWord(), "exec");
ASSERT_EQ(cr.getCurrentWord(), "exec");
cr.advanceWord();
ASSERT_EQ(cr.getCurrentWord(), "xrootd");
cr.advanceWord();
ASSERT_EQ(cr.getCurrentWord(), "xrd.protocol");
cr.advanceWord();
ASSERT_EQ(cr.getCurrentWord(), "redis:7776");
cr.advanceWord();
ASSERT_EQ(cr.getCurrentWord(), "libXrdQuarkDB.so");
cr.advanceWord();
ASSERT_EQ(cr.getCurrentWord(), "redis.mode");
cr.advanceWord();
ASSERT_EQ(cr.getCurrentWord(), "raft");
cr.advanceLine();
ASSERT_EQ(cr.getCurrentWord(), "redis.database");
cr.advanceLine();
ASSERT_EQ(cr.getCurrentWord(), "redis.myself");
cr.advanceLine();
ASSERT_EQ(cr.getCurrentWord(), "redis.trace");
cr.advanceLine();
ASSERT_EQ(cr.getCurrentWord(), "redis.write_ahead_log");
cr.advanceLine();
ASSERT_EQ(cr.getCurrentWord(), "redis.password_file");
cr.advanceLine();
ASSERT_EQ(cr.getCurrentWord(), "redis.require_password_for_localhost");
cr.advanceLine();
ASSERT_FALSE(cr.eof());
ASSERT_EQ(cr.getCurrentWord(), "fi");
cr.advanceLine();
ASSERT_TRUE(cr.eof());
}
TEST(Configuration, T1) {
Configuration config;
std::string c;
c = "if exec xrootd\n"
"fi\n";
ASSERT_FALSE(Configuration::fromString(c, config));
}
TEST(Configuration, T2) {
Configuration config;
std::string c;
c = "if exec xrootd\n"
"xrd.protocol redis:7776 libXrdQuarkDB.so\n"
"redis.mode raft\n"
"redis.database /home/user/mydb\n"
"redis.myself server1:7776\n"
"redis.trace debug\n"
"redis.write_ahead_log true\n"
"redis.password_file /tmp/quarkdb-tests/password-file\n"
"redis.require_password_for_localhost true\n"
"fi\n";
ASSERT_TRUE(Configuration::fromString(c, config));
ASSERT_EQ(config.getMode(), Mode::raft);
ASSERT_EQ(config.getDatabase(), "/home/user/mydb");
ASSERT_EQ(config.getMyself(), RaftServer("server1", 7776) );
ASSERT_EQ(config.getTraceLevel(), TraceLevel::debug);
ASSERT_EQ(config.getWriteAheadLog(), true);
ASSERT_EQ(config.getPassword(), "");
ASSERT_EQ(config.getPasswordFilePath(), "/tmp/quarkdb-tests/password-file");
ASSERT_TRUE(config.getRequirePasswordForLocalhost());
ASSERT_THROW(config.extractPasswordOrDie(), FatalException); // file does not exist
ASSERT_EQ(system("echo 'pickles\n \n' > /tmp/quarkdb-tests/password-file"), 0);
ASSERT_EQ(system("chmod 700 /tmp/quarkdb-tests/password-file"), 0);
ASSERT_THROW(config.extractPasswordOrDie(), FatalException); // bad permissions
ASSERT_EQ(system("chmod 400 /tmp/quarkdb-tests/password-file"), 0);
ASSERT_EQ(config.extractPasswordOrDie(), "pickles");
ASSERT_EQ(system("chmod 700 /tmp/quarkdb-tests/password-file"), 0);
ASSERT_EQ(system("rm -f /tmp/quarkdb-tests/password-file"), 0);
}
TEST(Configuration, NoPassword) {
Configuration config;
std::string c;
c = "if exec xrootd\n"
"xrd.protocol redis:7776 libXrdQuarkDB.so\n"
"redis.mode raft\n"
"redis.database /home/user/mydb\n"
"redis.myself server1:7776\n"
"redis.trace debug\n"
"redis.write_ahead_log true\n"
"fi\n";
ASSERT_TRUE(Configuration::fromString(c, config));
ASSERT_EQ(config.getMode(), Mode::raft);
ASSERT_EQ(config.getDatabase(), "/home/user/mydb");
ASSERT_EQ(config.getMyself(), RaftServer("server1", 7776) );
ASSERT_EQ(config.getTraceLevel(), TraceLevel::debug);
ASSERT_EQ(config.getWriteAheadLog(), true);
ASSERT_EQ(config.getPassword(), "");
ASSERT_EQ(config.getPasswordFilePath(), "");
ASSERT_EQ(config.extractPasswordOrDie(), "");
}
TEST(Configuration, NoPasswordButRequireForLocalhost) {
Configuration config;
std::string c;
c = "if exec xrootd\n"
"xrd.protocol redis:7776 libXrdQuarkDB.so\n"
"redis.mode raft\n"
"redis.database /home/user/mydb\n"
"redis.myself server1:7776\n"
"redis.trace debug\n"
"redis.write_ahead_log true\n"
"redis.require_password_for_localhost true\n"
"fi\n";
ASSERT_FALSE(Configuration::fromString(c, config));
}
TEST(Configuration, PasswordAndPasswordPath) {
Configuration config;
std::string c;
c = "if exec xrootd\n"
"xrd.protocol redis:7776 libXrdQuarkDB.so\n"
"redis.mode raft\n"
"redis.database /home/user/mydb\n"
"redis.myself server1:7776\n"
"redis.trace debug\n"
"redis.write_ahead_log true\n"
"redis.password_file /etc/super.secure\n"
"redis.password hunter2\n"
"fi\n";
ASSERT_FALSE(Configuration::fromString(c, config));
}
TEST(Configuration, T3) {
Configuration config;
std::string c;
// specifying a raft-only directive when standalone
c = "if exec xrootd\n"
"xrd.protocol redis:7776 libXrdQuarkDB.so\n"
"redis.mode standalone\n"
"redis.database /home/user/mydb\n"
"redis.myself server1:7776\n"
"fi\n";
ASSERT_FALSE(Configuration::fromString(c, config));
}
TEST(Configuration, T4) {
Configuration config;
std::string c;
c = "if exec xrootd\n"
"xrd.protocol redis:7776 libXrdQuarkDB.so\n"
"redis.mode standalone\n"
"redis.database /home/user/mydb\n"
"redis.trace info\n"
"redis.write_ahead_log false\n"
"redis.password hunter2\n"
"fi\n";
ASSERT_TRUE(Configuration::fromString(c, config));
ASSERT_EQ(config.getMode(), Mode::standalone);
ASSERT_EQ(config.getDatabase(), "/home/user/mydb");
ASSERT_EQ(config.getTraceLevel(), TraceLevel::info);
ASSERT_EQ(config.getWriteAheadLog(), false);
ASSERT_EQ(config.getPassword(), "hunter2");
ASSERT_EQ(config.getPasswordFilePath(), "");
ASSERT_EQ(config.extractPasswordOrDie(), "hunter2");
}
TEST(Configuration, T5) {
Configuration config;
std::string c;
// missing database
c = "if exec xrootd\n"
"xrd.protocol redis:7776 libXrdQuarkDB.so\n"
"redis.mode standalone\n"
"fi\n";
ASSERT_FALSE(Configuration::fromString(c, config));
}
TEST(Configuration, T6) {
Configuration config;
std::string c;
// unknown mode
c = "if exec xrootd\n"
"xrd.protocol redis:7776 libXrdQuarkDB.so\n"
"redis.mode something_something\n"
"redis.database /home/user/mydb\n"
"fi\n";
ASSERT_FALSE(Configuration::fromString(c, config));
}
TEST(Configuration, T7) {
Configuration config;
std::string c;
// unknown directive
c = "if exec xrootd\n"
"xrd.protocol redis:7776 libXrdQuarkDB.so\n"
"redis.mode standalone\n"
"redis.database /home/user/mydb\n"
"redis.blublu something\n"
"fi\n";
ASSERT_FALSE(Configuration::fromString(c, config));
}
TEST(Configuration, T8) {
Configuration config;
std::string c;
// unknown trace level
c = "if exec xrootd\n"
"xrd.protocol redis:7776 libXrdQuarkDB.so\n"
"redis.mode standalone\n"
"redis.database /home/user/mydb\n"
"redis.trace wrong\n"
"fi\n";
ASSERT_FALSE(Configuration::fromString(c, config));
}
TEST(Configuration, T9) {
Configuration config;
std::string c;
c = "if exec xrootd\n"
"xrd.protocol redis:7776 libXrdQuarkDB.so\n"
"redis.mode standalone\n"
"redis.database /home/user/mydb/\n"
"redis.trace info\n"
"fi\n";
// no trailing slashes in redis.database
ASSERT_FALSE(Configuration::fromString(c, config));
}
TEST(Configuration, T10) {
Configuration config;
std::string c;
c = "if exec xrootd\n"
"xrd.protocol redis:7776 libXrdQuarkDB.so\n"
"redis.mode standalone\n"
"redis.database /home/user/mydb\n"
"redis.write_ahead_log qadsfadf\n"
"fi\n";
ASSERT_FALSE(Configuration::fromString(c, config));
}