diff --git a/source/clientserver/makeRequestBlock.cpp b/source/clientserver/makeRequestBlock.cpp index 93569b4d..d0e1bbbc 100644 --- a/source/clientserver/makeRequestBlock.cpp +++ b/source/clientserver/makeRequestBlock.cpp @@ -1464,16 +1464,13 @@ void parse_name_value(const char* pair, NameValue* nameValue, unsigned short str nameValue->name = (char*)malloc(lstr * sizeof(char)); if (copy[0] == '/') { strcpy(nameValue->name, ©[1]); // Ignore leader forward slash - lstr = 5; - nameValue->value = (char*)malloc(lstr * sizeof(char)); - strcpy(nameValue->value, "true"); - UDA_LOG(UDA_LOG_DEBUG, "Placeholder name: {}, value: {}", nameValue->name, nameValue->value) } else { strcpy(nameValue->name, copy); - nameValue->value = (char*)malloc(lstr * sizeof(char)); - strcpy(nameValue->value, copy); - UDA_LOG(UDA_LOG_DEBUG, "Placeholder value: {}", nameValue->name); } + lstr = 5; + nameValue->value = (char*)malloc(lstr * sizeof(char)); + strcpy(nameValue->value, "true"); + UDA_LOG(UDA_LOG_DEBUG, "Placeholder name: {}, value: {}", nameValue->name, nameValue->value) } left_trim_string(nameValue->name); left_trim_string(nameValue->value); diff --git a/source/logging/logging.h b/source/logging/logging.h index 52d78075..e9dafb7d 100644 --- a/source/logging/logging.h +++ b/source/logging/logging.h @@ -34,8 +34,13 @@ void set_log_stdout(LogLevel mode); void set_log_file(LogLevel mode, const std::string& file_name, const std::string& open_mode); template -void log(LogLevel mode, const char* file, int line, const std::string& fmt, Args &&...args) +void log(LogLevel mode, const char* file, int line, const std::string_view fmt, Args &&...args) { + auto log_level = spdlog::get_level(); + if (log_level == spdlog::level::off) { + return; + } + std::shared_ptr logger; spdlog::level::level_enum level; @@ -74,7 +79,7 @@ void log(LogLevel mode, const char* file, int line, const std::string& fmt, Args if (mode == LogLevel::UDA_LOG_ERROR) { spdlog::get("debug")->log(loc, level, fmt, args...); } - logger->flush(); +// logger->flush(); } } // namespace uda::logging diff --git a/source/plugins/help/help_plugin.cpp b/source/plugins/help/help_plugin.cpp index 0dd9f875..9d2b4bcc 100644 --- a/source/plugins/help/help_plugin.cpp +++ b/source/plugins/help/help_plugin.cpp @@ -33,7 +33,7 @@ class HelpPlugin : public UDAPluginBase }; HelpPlugin::HelpPlugin() - : UDAPluginBase("HELP", 1, "read", boost::filesystem::path(__FILE__).parent_path().append("help.txt").string()) + : UDAPluginBase("HELP", 1, "ping", boost::filesystem::path(__FILE__).parent_path().append("help.txt").string()) { register_method("ping", static_cast(&HelpPlugin::ping)); register_method("services", static_cast(&HelpPlugin::services)); diff --git a/source/server2/plugins.hpp b/source/server2/plugins.hpp index 7631e217..52a41a5e 100644 --- a/source/server2/plugins.hpp +++ b/source/server2/plugins.hpp @@ -54,6 +54,10 @@ class Plugins [[nodiscard]] std::pair> find_by_name(const std::string& name) const; [[nodiscard]] boost::optional find_by_id(size_t id) const; +#if UDA_TEST + void add_plugin(client_server::PluginData&& plugin) { _plugins.emplace_back(std::move(plugin)); } +#endif + private: const config::Config& _config; std::vector _plugins; diff --git a/source/server2/server.hpp b/source/server2/server.hpp index f08455ca..19664bd8 100644 --- a/source/server2/server.hpp +++ b/source/server2/server.hpp @@ -35,7 +35,7 @@ class Server LIBRARY_API Server(config::Config config); LIBRARY_API void run(); - private: + protected: void shutdown(); void initialise(); void connect(int socket_fd); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6bc548d4..f1b63ede 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -86,6 +86,20 @@ if( ( WIN32 AND MINGW ) OR NOT WIN32 ) set( LINK_M m ) endif() +add_executable( server_tests server_tests.cpp ) +target_include_directories( server_tests PRIVATE + ${CMAKE_SOURCE_DIR}/source + ${CMAKE_SOURCE_DIR}/source/include + ${CMAKE_BINARY_DIR}/include +) +target_link_libraries( server_tests PRIVATE + Boost::boost + OpenSSL::SSL + ${LIBRARIES} + server2-static +) +target_compile_definitions( server_tests PRIVATE UDA_TEST ) + macro( BUILD_TEST NAME SOURCE ) set( LINK_PROJECT ${PROJECT_NAME}_cpp-static ) if( BUILD_SHARED_LIBS ) diff --git a/test/server_tests.cpp b/test/server_tests.cpp new file mode 100644 index 00000000..8b7585fe --- /dev/null +++ b/test/server_tests.cpp @@ -0,0 +1,172 @@ +#define CATCH_CONFIG_MAIN +#include "catch.hpp" + +#include +#include + +#include "server2/server.hpp" +#include "clientserver/makeRequestBlock.h" + +int entry_func(UDA_PLUGIN_INTERFACE* plugin_interface) +{ + std::string function = boost::to_lower_copy(udaPluginFunction(plugin_interface)); + + if (function == "help") { + udaPluginReturnDataStringScalar(plugin_interface, "test data", "test description"); + return 0; + } + + return -1; +} + +int no_op(void*) { return 0; } + +class TestServer : public uda::server::Server { +public: + TestServer() : Server(uda::config::Config{}) { + std::filesystem::path path{ __FILE__ }; + auto config_path = path.parent_path() / "test_server.toml"; + _config.load(config_path.string()); + uda::logging::init_logging(); + uda::logging::set_log_level(uda::logging::LogLevel::UDA_LOG_NONE); + + uda::client_server::PluginData plugin; + plugin.name = "test"; + plugin.entry_func = entry_func; + plugin.type = UdaPluginClass::UDA_PLUGIN_CLASS_FUNCTION; + plugin.handle = {this, no_op}; + + _plugins.add_plugin(std::move(plugin)); + } + + uda::client_server::RequestData make_request(const std::string& request) + { + uda::client_server::RequestData request_data = {}; + + strcpy(request_data.signal, request.c_str()); + + uda::client_server::make_request_data(_config, &request_data, _plugins.plugin_list()); + + return request_data; + } + + int get(const std::string& request, uda::client_server::DataBlock& data_block) + { + int depth = 0; + + uda::client_server::RequestData request_data = make_request(request); + strcpy(_metadata_block.data_source.format, "test"); + + return get_data(&depth, &request_data, &data_block, TestServer::ServerVersion); + } + +}; + +TEST_CASE( "Test create server", "[server]" ) +{ + uda::config::Config config; + TestServer server; +} + +TEST_CASE( "Test make request", "[server]" ) +{ + uda::config::Config config; + TestServer server; + + SECTION( "Test plugin function with no args" ) { + auto request= server.make_request("TEST::HELP()"); + REQUIRE( std::string{ request.api_delim } == "::" ); + REQUIRE( std::string{ request.signal } == "HELP()" ); + REQUIRE( std::string{ request.archive } == "TEST" ); + REQUIRE( std::string{ request.function } == "HELP" ); + REQUIRE( std::string{ request.format } == "test" ); + REQUIRE( request.request == 0 ); + REQUIRE( request.nameValueList.listSize == 0 ); + } + + SECTION( "Test plugin function with one arg" ) { + auto request= server.make_request("TEST::HELP(foo=1)"); + REQUIRE( std::string{ request.api_delim } == "::" ); + REQUIRE( std::string{ request.signal } == "HELP(foo=1)" ); + REQUIRE( std::string{ request.archive } == "TEST" ); + REQUIRE( std::string{ request.function } == "HELP" ); + REQUIRE( std::string{ request.format } == "test" ); + REQUIRE( request.request == 0 ); + REQUIRE( request.nameValueList.pairCount == 1 ); + REQUIRE( std::string{ request.nameValueList.nameValue[0].name } == "foo" ); + REQUIRE( std::string{ request.nameValueList.nameValue[0].value } == "1" ); + } + + SECTION( "Test plugin function with two args" ) { + auto request= server.make_request("TEST::HELP(foo=1, bar=zog)"); + REQUIRE( std::string{ request.api_delim } == "::" ); + REQUIRE( std::string{ request.signal } == "HELP(foo=1, bar=zog)" ); + REQUIRE( std::string{ request.archive } == "TEST" ); + REQUIRE( std::string{ request.function } == "HELP" ); + REQUIRE( std::string{ request.format } == "test" ); + REQUIRE( request.request == 0 ); + REQUIRE( request.nameValueList.pairCount == 2 ); + REQUIRE( std::string{ request.nameValueList.nameValue[0].name } == "foo" ); + REQUIRE( std::string{ request.nameValueList.nameValue[0].value } == "1" ); + REQUIRE( std::string{ request.nameValueList.nameValue[1].name } == "bar" ); + REQUIRE( std::string{ request.nameValueList.nameValue[1].value } == "zog" ); + } + + SECTION( "Test plugin function with flag arg" ) { + auto request= server.make_request("TEST::HELP(foo)"); + REQUIRE( std::string{ request.api_delim } == "::" ); + REQUIRE( std::string{ request.signal } == "HELP(foo)" ); + REQUIRE( std::string{ request.archive } == "TEST" ); + REQUIRE( std::string{ request.function } == "HELP" ); + REQUIRE( std::string{ request.format } == "test" ); + REQUIRE( request.request == 0 ); + REQUIRE( request.nameValueList.pairCount == 1 ); + REQUIRE( std::string{ request.nameValueList.nameValue[0].name } == "foo" ); + REQUIRE( std::string{ request.nameValueList.nameValue[0].value } == "true" ); + } + + SECTION( "Test plugin function with IDL style flag arg" ) { + auto request= server.make_request("TEST::HELP(/foo)"); + REQUIRE( std::string{ request.api_delim } == "::" ); + REQUIRE( std::string{ request.signal } == "HELP(/foo)" ); + REQUIRE( std::string{ request.archive } == "TEST" ); + REQUIRE( std::string{ request.function } == "HELP" ); + REQUIRE( std::string{ request.format } == "test" ); + REQUIRE( request.request == 0 ); + REQUIRE( request.nameValueList.pairCount == 1 ); + REQUIRE( std::string{ request.nameValueList.nameValue[0].name } == "foo" ); + REQUIRE( std::string{ request.nameValueList.nameValue[0].value } == "true" ); + } + + SECTION( "Test plugin function with mix of arg types" ) { + auto request= server.make_request("TEST::HELP(foo=1, /bar)"); + REQUIRE( std::string{ request.api_delim } == "::" ); + REQUIRE( std::string{ request.signal } == "HELP(foo=1, /bar)" ); + REQUIRE( std::string{ request.archive } == "TEST" ); + REQUIRE( std::string{ request.function } == "HELP" ); + REQUIRE( std::string{ request.format } == "test" ); + REQUIRE( request.request == 0 ); + REQUIRE( request.nameValueList.pairCount == 2 ); + REQUIRE( std::string{ request.nameValueList.nameValue[0].name } == "foo" ); + REQUIRE( std::string{ request.nameValueList.nameValue[0].value } == "1" ); + REQUIRE( std::string{ request.nameValueList.nameValue[1].name } == "bar" ); + REQUIRE( std::string{ request.nameValueList.nameValue[1].value } == "true" ); + } +} + +TEST_CASE( "Test get data", "[server]" ) +{ + uda::config::Config config; + TestServer server; + + uda::client_server::DataBlock data_block; + + SECTION( "Testing help method" ) { + int rc = server.get("TEST::HELP()", data_block); + REQUIRE( rc == 0 ); + REQUIRE( data_block.data_type == UDA_TYPE_STRING ); + REQUIRE( std::string{ data_block.data } == "test data" ); + REQUIRE( std::string{ data_block.data_desc } == "test description" ); + } + +} \ No newline at end of file diff --git a/test/test_server.toml b/test/test_server.toml new file mode 100644 index 00000000..2499834f --- /dev/null +++ b/test/test_server.toml @@ -0,0 +1,5 @@ +[request] +delim = "::" + +[logging] +level = 6 \ No newline at end of file