changeset 779:317c66a131be

Irccd: merge [identity] with [server], closes #905 @2h While here, also add some tests for server_util, #779
author David Demelier <markand@malikania.fr>
date Thu, 01 Nov 2018 10:34:21 +0100
parents 3ff081c72250
children 560b62f6b0a7
files CHANGES.md MIGRATING.md doc/examples/irccd.conf.sample libirccd/irccd/daemon/server.hpp libirccd/irccd/daemon/server_service.cpp libirccd/irccd/daemon/server_util.cpp libirccd/irccd/daemon/server_util.hpp tests/src/libirccd/CMakeLists.txt tests/src/libirccd/server-util/CMakeLists.txt tests/src/libirccd/server-util/full.conf tests/src/libirccd/server-util/full.json tests/src/libirccd/server-util/main.cpp tests/src/libirccd/server-util/ssl.conf
diffstat 13 files changed, 286 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES.md	Wed Oct 31 20:14:00 2018 +0100
+++ b/CHANGES.md	Thu Nov 01 10:34:21 2018 +0100
@@ -12,6 +12,7 @@
   standard paths for both irccd and plugins (#611),
 - If Mercurial is found, the version is bundled in `irccd --version`,
 - Irccd no longer supports uid, gid, pid and daemon features (#846).
+- Sections `[identity]` and `[server]` have been merged (#905).
 
 Irccd test:
 
--- a/MIGRATING.md	Wed Oct 31 20:14:00 2018 +0100
+++ b/MIGRATING.md	Thu Nov 01 10:34:21 2018 +0100
@@ -83,3 +83,5 @@
 - The option `reconnect-tries` has been removed from `[server]` section, use
   `auto-reconnect` boolean option instead.
 - The option `reconnect-timeout` has been renamed to `auto-reconnect-delay`.
+- The section `[identity]` has been removed, instead move those values inside
+  each server in their `[server]` section.
--- a/doc/examples/irccd.conf.sample	Wed Oct 31 20:14:00 2018 +0100
+++ b/doc/examples/irccd.conf.sample	Thu Nov 01 10:34:21 2018 +0100
@@ -9,23 +9,6 @@
 # abc = ""                      # This will search for abc
 # ask = /tmp/ask.js             # This use /tmp/ask.js to load the plugin
 
-# Section identities:
-#    This describe identities, you can add any number you want they are used with servers so you can reuse an
-#    identity for one or more servers if you want.
-#
-# [identity]
-# name = "id"                   # (id) the identity unique id,
-# nickname = "foo"              # (string) the nickname (Optional, default: irccd),
-# username = "bar"              # (string) the realname (Optional, default: IRC Client daemon),
-# realname = "Jean"             # (string) the username name (Optional, default: irccd),
-# ctcp-version = "irccd"        # (string) what version to respond to CTCP VERSION (Optional, default: IRC Client Daemon),
-
-[identity]
-name = "default"
-nickname = "superbot"
-username = "superbot"
-realname = "Superbot"
-
 # Section transport:
 #    You can use transport to wait for any input you want. Unix and internet sockets are supported. Unix are used
 #    for file based socket while internet bind to standard address plus a specific port.
@@ -59,7 +42,10 @@
 # name = "id"                   # (id) the unique id,
 # host = "chat.foo.com"         # (string) the server address,
 # port = "4321"                 # (int) the server port (Optional, default: 6667),
-# identity = "default"          # (string) an identity to use (Optional, default: irccd's default),
+# nickname = "foo"              # (string) the nickname (Optional, default: irccd),
+# username = "bar"              # (string) the realname (Optional, default: IRC Client daemon),
+# realname = "Jean"             # (string) the username name (Optional, default: irccd),
+# ctcp-version = "irccd"        # (string) what version to respond to CTCP VERSION (Optional, default: IRC Client Daemon),
 # password = "secret"           # (string) an optional password (Optional, default: none),
 # auto-rejoin = false           # (bool) auto rejoin a channel after being kicked (Optional, default: false),
 # join-invite = false           # (bool) join channels upon invitation (Optional, default: false),
--- a/libirccd/irccd/daemon/server.hpp	Wed Oct 31 20:14:00 2018 +0100
+++ b/libirccd/irccd/daemon/server.hpp	Thu Nov 01 10:34:21 2018 +0100
@@ -268,6 +268,7 @@
 		identifying,                    //!< sending nick, user and password commands,
 		connected                       //!< ready for use.
 	};
+
 protected:
 	/*
 	 * \brief Server state.
@@ -433,7 +434,7 @@
 	 *
 	 * \param nickname the nickname
 	 */
-	virtual void set_nickname(std::string nickname);
+	void set_nickname(std::string nickname);
 
 	/**
 	 * Get the username.
--- a/libirccd/irccd/daemon/server_service.cpp	Wed Oct 31 20:14:00 2018 +0100
+++ b/libirccd/irccd/daemon/server_service.cpp	Thu Nov 01 10:34:21 2018 +0100
@@ -224,7 +224,7 @@
 				ev.message,
 				ev.server->get_command_char(),
 				plugin.get_id()
-			).type == server_util::message_type::type::command ? "onCommand" : "onMessage";
+			).type == server_util::message_type::is_command ? "onCommand" : "onMessage";
 		},
 		[=] (plugin& plugin) mutable {
 			auto copy = ev;
@@ -236,7 +236,7 @@
 
 			copy.message = pack.message;
 
-			if (pack.type == server_util::message_type::type::command)
+			if (pack.type == server_util::message_type::is_command)
 				plugin.handle_command(irccd_, copy);
 			else
 				plugin.handle_message(irccd_, copy);
@@ -462,7 +462,6 @@
 	assert(server);
 
 	irccd_.get_log().warning(*server) << code.message() << std::endl;
-
 	irccd_.get_log().warning(*server) << int(server->get_options()) << std::endl;
 
 	if ((server->get_options() & server::options::auto_reconnect) != server::options::auto_reconnect)
@@ -661,7 +660,7 @@
 		const auto id = section.get("name").get_value();
 
 		try {
-			auto server = server_util::from_config(irccd_.get_service(), cfg, section);
+			auto server = server_util::from_config(irccd_.get_service(), section);
 
 			if (has(server->get_id()))
 				throw server_error(server_error::already_exists);
--- a/libirccd/irccd/daemon/server_util.cpp	Wed Oct 31 20:14:00 2018 +0100
+++ b/libirccd/irccd/daemon/server_util.cpp	Thu Nov 01 10:34:21 2018 +0100
@@ -26,9 +26,9 @@
 #include "server.hpp"
 #include "server_util.hpp"
 
-namespace irccd::server_util {
+using irccd::json_util::deserializer;
 
-using json_util::deserializer;
+namespace irccd::server_util {
 
 namespace {
 
@@ -187,7 +187,7 @@
 	auto result = std::string(message);
 	auto cc = std::string(cchar);
 	auto name = std::string(plugin);
-	auto iscommand = false;
+	auto type = is_message;
 
 	// handle special commands "!<plugin> command"
 	if (cc.length() > 0) {
@@ -201,11 +201,11 @@
 		 * typing "!foo123123" will trigger foo plugin.
 		 */
 		if (pos == std::string::npos)
-			iscommand = result == fullcommand;
-		else
-			iscommand = result.length() >= fullcommand.length() && result.compare(0, pos, fullcommand) == 0;
+			type = result == fullcommand ? is_command : is_message;
+		else if (result.length() >= fullcommand.length() && result.compare(0, pos, fullcommand) == 0)
+			type = is_command;
 
-		if (iscommand) {
+		if (type == is_command) {
 			/*
 			 * If no space is found we just set the message to "" otherwise
 			 * the plugin name will be passed through onCommand
@@ -217,10 +217,7 @@
 		}
 	}
 
-	return {
-		iscommand ? message_type::type::command : message_type::type::message,
-		result
-	};
+	return {type, result};
 }
 
 auto from_json(boost::asio::io_service& service, const nlohmann::json& object) -> std::shared_ptr<server>
@@ -244,7 +241,6 @@
 }
 
 auto from_config(boost::asio::io_service& service,
-                 const config& cfg,
                  const ini::section& sc) -> std::shared_ptr<server>
 {
 	// Mandatory parameters.
@@ -262,21 +258,7 @@
 	from_config_load_flags(*sv, sc);
 	from_config_load_numeric_parameters(*sv, sc);
 	from_config_load_options(*sv, sc);
-
-	// Identity is in a separate section
-	const auto identity = sc.get("identity");
-
-	if (identity.get_value().size() > 0) {
-		const auto it = std::find_if(cfg.begin(), cfg.end(), [&] (const auto& i) {
-			if (i.get_key() != "identity")
-				return false;
-
-			return i.get("name").get_value() == identity.get_value();
-		});
-
-		if (it != cfg.end())
-			from_config_load_identity(*sv, *it);
-	}
+	from_config_load_identity(*sv, sc);
 
 	return sv;
 }
--- a/libirccd/irccd/daemon/server_util.hpp	Wed Oct 31 20:14:00 2018 +0100
+++ b/libirccd/irccd/daemon/server_util.hpp	Thu Nov 01 10:34:21 2018 +0100
@@ -60,9 +60,9 @@
 	/**
 	 * \brief Describe which type of message has been received
 	 */
-	enum class type {
-		command,        //!< special command
-		message         //!< standard message
+	enum kind {
+		is_command,     //!< special command
+		is_message      //!< standard message
 	} type;
 
 	/**
@@ -107,7 +107,6 @@
  * \throw server_error on errors
  */
 auto from_config(boost::asio::io_service& service,
-                 const config& cfg,
                  const ini::section& sc) -> std::shared_ptr<server>;
 
 } // !server_util
--- a/tests/src/libirccd/CMakeLists.txt	Wed Oct 31 20:14:00 2018 +0100
+++ b/tests/src/libirccd/CMakeLists.txt	Thu Nov 01 10:34:21 2018 +0100
@@ -49,3 +49,4 @@
 add_subdirectory(logger)
 add_subdirectory(rules)
 add_subdirectory(rule-util)
+add_subdirectory(server-util)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/src/libirccd/server-util/CMakeLists.txt	Thu Nov 01 10:34:21 2018 +0100
@@ -0,0 +1,23 @@
+#
+# CMakeLists.txt -- CMake build system for irccd
+#
+# Copyright (c) 2013-2018 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+irccd_define_test(
+	NAME server-util
+	SOURCES main.cpp
+	LIBRARIES libirccd
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/src/libirccd/server-util/full.conf	Thu Nov 01 10:34:21 2018 +0100
@@ -0,0 +1,13 @@
+[server]
+name = "localhost"
+hostname = "irc.localhost"
+channels = ( "#staff", "#test" )
+port = 3344
+password = "secret"
+reconnect-timeout = 60
+nickname = "superbot"
+username = "sp"
+realname = "SuperBot 2000 NT"
+join-invite = true
+auto-rejoin = true
+auto-reconnect = true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/src/libirccd/server-util/full.json	Thu Nov 01 10:34:21 2018 +0100
@@ -0,0 +1,9 @@
+{
+	"name": "localhost",
+	"host": "irc.localhost",
+	"port": 3344,
+	"password": "secret",
+	"nickname": "superbot",
+	"username": "sp",
+	"realname": "SuperBot 2000 NT"
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/src/libirccd/server-util/main.cpp	Thu Nov 01 10:34:21 2018 +0100
@@ -0,0 +1,202 @@
+/*
+ * main.cpp -- test server_util functions
+ *
+ * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define BOOST_TEST_MODULE "server_util"
+#include <boost/test/unit_test.hpp>
+#include <boost/filesystem.hpp>
+
+#include <irccd/ini.hpp>
+
+#include <irccd/daemon/server.hpp>
+#include <irccd/daemon/server_util.hpp>
+
+using nlohmann::json;
+
+using irccd::server_util::from_config;
+using irccd::server_util::from_json;
+using irccd::server_util::message_type;
+
+namespace irccd {
+
+namespace server_util {
+
+auto operator<<(std::ostream& out, message_type::kind kind) -> std::ostream&
+{
+	if (kind == message_type::is_command)
+		out << "command";
+	else
+		out << "message";
+
+	return out;
+}
+
+} // !server_util
+
+namespace {
+
+class fixture {
+protected:
+	boost::asio::io_service ctx_;
+};
+
+auto open_config(const std::string& config) -> ini::document
+{
+	boost::filesystem::path path;
+
+	path /= CMAKE_CURRENT_SOURCE_DIR;
+	path /= config;
+
+	return ini::read_file(path.string());
+}
+
+auto open_json(const std::string& file) -> json
+{
+	boost::filesystem::path path;
+
+	path /= CMAKE_CURRENT_SOURCE_DIR;
+	path /= file;
+
+	std::ifstream input(path.string());
+
+	if (!input)
+		throw std::runtime_error(std::strerror(errno));
+
+	return json::parse(std::string(std::istreambuf_iterator<char>(input.rdbuf()), {}));
+}
+
+BOOST_FIXTURE_TEST_SUITE(from_config, fixture)
+
+BOOST_AUTO_TEST_SUITE(valid)
+
+BOOST_AUTO_TEST_CASE(full)
+{
+	const auto sv = server_util::from_config(ctx_, open_config("full.conf")[0]);
+
+	BOOST_TEST(sv->get_id() == "localhost");
+	BOOST_TEST(sv->get_host() == "irc.localhost");
+	BOOST_TEST(sv->get_port() == 3344U);
+	BOOST_TEST(sv->get_password() == "secret");
+	BOOST_TEST(sv->get_nickname() == "superbot");
+	BOOST_TEST(sv->get_username() == "sp");
+	BOOST_TEST(sv->get_realname() == "SuperBot 2000 NT");
+	BOOST_TEST(static_cast<bool>(sv->get_options() & server::options::join_invite));
+	BOOST_TEST(static_cast<bool>(sv->get_options() & server::options::auto_rejoin));
+	BOOST_TEST(static_cast<bool>(sv->get_options() & server::options::auto_reconnect));
+}
+
+#if defined(IRCCD_HAVE_SSL)
+
+BOOST_AUTO_TEST_CASE(ssl)
+{
+	const auto sv = server_util::from_config(ctx_, open_config("ssl.conf")[0]);
+
+	BOOST_TEST(sv->get_id() == "localhost");
+	BOOST_TEST(sv->get_host() == "irc.localhost");
+	BOOST_TEST(sv->get_port() == 6697U);
+	BOOST_TEST(sv->get_password() == "secret");
+	BOOST_TEST(sv->get_nickname() == "secure");
+	BOOST_TEST(sv->get_username() == "sc");
+	BOOST_TEST(sv->get_realname() == "SuperBot 2000 NT SSL");
+	BOOST_TEST(static_cast<bool>(sv->get_options() & server::options::ssl));
+	BOOST_TEST(static_cast<bool>(sv->get_options() & server::options::join_invite));
+	BOOST_TEST(static_cast<bool>(sv->get_options() & server::options::auto_rejoin));
+	BOOST_TEST(static_cast<bool>(sv->get_options() & server::options::auto_reconnect));
+}
+
+#endif // !IRCCD_HAVE_SSL
+
+BOOST_AUTO_TEST_SUITE_END()
+
+BOOST_AUTO_TEST_SUITE_END()
+
+BOOST_FIXTURE_TEST_SUITE(from_json, fixture)
+
+BOOST_AUTO_TEST_SUITE(valid)
+
+BOOST_AUTO_TEST_CASE(full)
+{
+	const auto sv = server_util::from_json(ctx_, open_json("full.json"));
+
+	BOOST_TEST(sv->get_id() == "localhost");
+	BOOST_TEST(sv->get_host() == "irc.localhost");
+	BOOST_TEST(sv->get_port() == 3344U);
+	BOOST_TEST(sv->get_password() == "secret");
+	BOOST_TEST(sv->get_nickname() == "superbot");
+	BOOST_TEST(sv->get_username() == "sp");
+	BOOST_TEST(sv->get_realname() == "SuperBot 2000 NT");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+BOOST_AUTO_TEST_SUITE_END()
+
+BOOST_AUTO_TEST_SUITE(message)
+
+BOOST_AUTO_TEST_CASE(valid_short)
+{
+	const auto m = message_type::parse("!hello", "!", "hello");
+
+	BOOST_TEST(m.type == message_type::is_command);
+	BOOST_TEST(m.message == "");
+}
+
+BOOST_AUTO_TEST_CASE(valid_arguments)
+{
+	const auto m = message_type::parse("!hello world", "!", "hello");
+
+	BOOST_TEST(m.type == message_type::is_command);
+	BOOST_TEST(m.message == "world");
+}
+
+BOOST_AUTO_TEST_CASE(cchar_with_message_short)
+{
+	const auto m = message_type::parse("!hello", "!", "hangman");
+
+	BOOST_TEST(m.type == message_type::is_message);
+	BOOST_TEST(m.message == "!hello");
+}
+
+BOOST_AUTO_TEST_CASE(cchar_with_message_arguments)
+{
+	const auto m = message_type::parse("!hello world", "!", "hangman");
+
+	BOOST_TEST(m.type == message_type::is_message);
+	BOOST_TEST(m.message == "!hello world");
+}
+
+BOOST_AUTO_TEST_CASE(command_with_different_cchar_short)
+{
+	const auto m = message_type::parse("!hello", ">", "hello");
+
+	BOOST_TEST(m.type == message_type::is_message);
+	BOOST_TEST(m.message == "!hello");
+}
+
+BOOST_AUTO_TEST_CASE(command_with_different_cchar_arguments)
+{
+	const auto m = message_type::parse("!hello", ">", "hello");
+
+	BOOST_TEST(m.type == message_type::is_message);
+	BOOST_TEST(m.message == "!hello");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // !namespace
+
+} // !irccd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/src/libirccd/server-util/ssl.conf	Thu Nov 01 10:34:21 2018 +0100
@@ -0,0 +1,14 @@
+[server]
+name = "localhost"
+hostname = "irc.localhost"
+port = 6697
+ssl = true
+ssl-verify = false
+password = "secret"
+reconnect-timeout = 60
+nickname = "secure"
+username = "sc"
+realname = "SuperBot 2000 NT SSL"
+join-invite = true
+auto-rejoin = true
+auto-reconnect = true