Add tests for configuration parsing.

This commit is contained in:
Kishore Nallan 2019-04-29 18:55:45 +05:30
parent 374ab9789b
commit 51169bf6b6
6 changed files with 116 additions and 20 deletions

View File

@ -90,7 +90,7 @@ add_executable(benchmark ${SRC_FILES} src/main/benchmark.cpp)
add_executable(typesense-test ${SRC_FILES} test/main.cpp test/array_test.cpp test/sorted_array_test.cpp test/art_test.cpp
test/collection_test.cpp test/collection_manager_test.cpp
test/topster_test.cpp test/match_score_test.cpp test/store_test.cpp test/array_utils_test.cpp
test/string_utils_test.cpp)
test/string_utils_test.cpp test/config_test.cpp)
add_library(typesense-core STATIC ${SRC_FILES})

View File

@ -97,6 +97,7 @@
- ~~Have a LOG(ERROR) level~~
- ~~Handle SIGTERM which is sent when process is killed~~
- ~~Use snappy compression for storage~~
- API for optimizing on disk storage
- Jemalloc
- Exact search
- NOT operator support

View File

@ -32,23 +32,23 @@ public:
// setters
void set_data_dir(std::string & data_dir) {
void set_data_dir(const std::string & data_dir) {
this->data_dir = data_dir;
}
void set_log_dir(std::string & log_dir) {
void set_log_dir(const std::string & log_dir) {
this->log_dir = log_dir;
}
void set_api_key(std::string & api_key) {
void set_api_key(const std::string & api_key) {
this->api_key = api_key;
}
void set_search_only_api_key(std::string & search_only_api_key) {
void set_search_only_api_key(const std::string & search_only_api_key) {
this->search_only_api_key = search_only_api_key;
}
void set_listen_address(std::string & listen_address) {
void set_listen_address(const std::string & listen_address) {
this->listen_address = listen_address;
}
@ -56,15 +56,15 @@ public:
this->listen_port = listen_port;
}
void set_master(std::string & master) {
void set_master(const std::string & master) {
this->master = master;
}
void set_ssl_cert(std::string & ssl_cert) {
void set_ssl_cert(const std::string & ssl_cert) {
this->ssl_certificate = ssl_cert;
}
void set_ssl_cert_key(std::string & ssl_cert_key) {
void set_ssl_cert_key(const std::string & ssl_cert_key) {
this->ssl_certificate_key = ssl_cert_key;
}
@ -149,11 +149,12 @@ public:
}
void load_config_cmd_args(cmdline::parser & options) {
this->data_dir = options.get<std::string>("data-dir");
this->log_dir = options.get<std::string>("log-dir");
this->api_key = options.get<std::string>("api-key");
this->data_dir = options.exist("data-dir") ? options.get<std::string>("data-dir") : "";
this->log_dir = options.exist("log-dir") ? options.get<std::string>("log-dir") : "";
this->api_key = options.exist("api-key") ? options.get<std::string>("api-key") : "";
this->search_only_api_key = options.get<std::string>("search-only-api-key");
this->search_only_api_key = options.exist("search-only-api-key") ?
options.get<std::string>("search-only-api-key") : "";
if(options.exist("listen-address")) {
this->listen_address = options.get<std::string>("listen-address");
@ -163,9 +164,11 @@ public:
this->listen_port = options.get<uint32_t>("listen-port");
}
this->master = options.get<std::string>("master");
this->ssl_certificate = options.get<std::string>("ssl-certificate");
this->ssl_certificate_key = options.get<std::string>("ssl-certificate-key");
this->master = options.exist("master") ? options.get<std::string>("master") : "";
this->ssl_certificate = options.exist("ssl-certificate") ?
options.get<std::string>("ssl-certificate") : "";
this->ssl_certificate_key = options.exist("ssl-certificate-key") ?
options.get<std::string>("ssl-certificate-key") : "";
this->enable_cors = options.exist("enable-cors");
}
@ -183,5 +186,4 @@ public:
return Option<bool>(true);
}
};
};

View File

@ -57,6 +57,8 @@ int main(int argc, char **argv) {
if(!config_validitation.ok()) {
std::cerr << "Invalid configuration: " << config_validitation.error() << std::endl;
std::cerr << "Command line " << options.usage() << std::endl;
std::cerr << "You can also pass these arguments as environment variables such as "
<< "DATA_DIR, API_KEY, etc." << std::endl;
exit(1);
}

View File

@ -24,8 +24,9 @@ void init_cmdline_options(cmdline::parser & options, int argc, char **argv) {
options.add<std::string>("listen-address", 'h', "Address to which Typesense server binds.", false, "0.0.0.0");
options.add<uint32_t>("listen-port", 'p', "Port on which Typesense server listens.", false, 8108);
options.add<std::string>("master", 'm', "Provide the master's address in http(s)://<master_address>:<master_port> "
"format to start the server as a read-only replica.", false, "");
options.add<std::string>("master", 'm', "To start the server as read-only replica, "
"provide the master's address in http(s)://<master_address>:<master_port> format.",
false, "");
options.add<std::string>("ssl-certificate", 'c', "Path to the SSL certificate file.", false, "");
options.add<std::string>("ssl-certificate-key", 'k', "Path to the SSL certificate key file.", false, "");

90
test/config_test.cpp Normal file
View File

@ -0,0 +1,90 @@
#include <gtest/gtest.h>
#include <stdlib.h>
#include <cmdline.h>
#include "typesense_server_utils.h"
#include "config.h"
std::vector<char*> get_argv(std::vector<std::string> & args) {
std::vector<char*> argv;
for (const auto& arg : args)
argv.push_back((char*)arg.data());
argv.push_back(nullptr);
return argv;
}
TEST(ConfigTest, LoadCmdLineArguments) {
cmdline::parser options;
std::vector<std::string> args = {
"./typesense-server",
"--data-dir=/tmp/data",
"--api-key=abcd",
"--listen-port=8080",
};
std::vector<char*> argv = get_argv(args);
init_cmdline_options(options, argv.size() - 1, argv.data());
options.parse(argv.size() - 1, argv.data());
Config config;
config.load_config_cmd_args(options);
ASSERT_EQ("abcd", config.get_api_key());
ASSERT_EQ(8080, config.get_listen_port());
ASSERT_EQ("/tmp/data", config.get_data_dir());
}
TEST(ConfigTest, LoadEnvVars) {
cmdline::parser options;
putenv((char*)"TYPESENSE_DATA_DIR=/tmp/ts");
putenv((char*)"TYPESENSE_LISTEN_PORT=9090");
Config config;
config.load_config_env();
ASSERT_EQ("/tmp/ts", config.get_data_dir());
ASSERT_EQ(9090, config.get_listen_port());
}
TEST(ConfigTest, CmdLineArgsOverrideEnvVars) {
cmdline::parser options;
std::vector<std::string> args = {
"./typesense-server",
"--data-dir=/tmp/data",
"--api-key=abcd"
};
putenv((char*)"TYPESENSE_DATA_DIR=/tmp/ts");
putenv((char*)"TYPESENSE_LISTEN_PORT=9090");
std::vector<char*> argv = get_argv(args);
init_cmdline_options(options, argv.size() - 1, argv.data());
options.parse(argv.size() - 1, argv.data());
Config config;
config.load_config_env();
config.load_config_cmd_args(options);
ASSERT_EQ("abcd", config.get_api_key());
ASSERT_EQ("/tmp/data", config.get_data_dir());
ASSERT_EQ(9090, config.get_listen_port());
}
TEST(ConfigTest, BadConfigurationReturnsError) {
Config config1;
config1.set_api_key("abcd");
auto validation = config1.is_valid();
ASSERT_EQ(false, validation.ok());
ASSERT_EQ("Data directory is not specified.", validation.error());
Config config2;
config2.set_data_dir("/tmp/ts");
validation = config2.is_valid();
ASSERT_EQ(false, validation.ok());
ASSERT_EQ("API key is not specified.", validation.error());
}