Mercurial > irccd
changeset 870:2b335166e641
tests: add rule-service test, continue #742
author | David Demelier <markand@malikania.fr> |
---|---|
date | Fri, 26 Jul 2019 11:20:19 +0000 |
parents | c885cb16540d |
children | dbd611105f57 |
files | libirccd-daemon/irccd/daemon/rule.cpp libirccd-daemon/irccd/daemon/rule.hpp tests/src/libirccd-daemon/CMakeLists.txt tests/src/libirccd-daemon/rule-service/CMakeLists.txt tests/src/libirccd-daemon/rule-service/main.cpp tests/src/libirccd-daemon/rules/CMakeLists.txt tests/src/libirccd-daemon/rules/main.cpp |
diffstat | 7 files changed, 390 insertions(+), 307 deletions(-) [+] |
line wrap: on
line diff
--- a/libirccd-daemon/irccd/daemon/rule.cpp Fri Jul 26 21:10:00 2019 +0000 +++ b/libirccd-daemon/irccd/daemon/rule.cpp Fri Jul 26 11:20:19 2019 +0000 @@ -49,6 +49,21 @@ match_set(events, std::string(event)); } +auto operator==(const rule& lhs, const rule& rhs) noexcept -> bool +{ + return lhs.servers == rhs.servers && + lhs.channels == rhs.channels && + lhs.origins == rhs.origins && + lhs.plugins == rhs.plugins && + lhs.events == rhs.events && + lhs.action == rhs.action; +} + +auto operator!=(const rule& lhs, const rule& rhs) noexcept -> bool +{ + return !(lhs == rhs); +} + auto rule_category() -> const std::error_category& { static const class category : public std::error_category {
--- a/libirccd-daemon/irccd/daemon/rule.hpp Fri Jul 26 21:10:00 2019 +0000 +++ b/libirccd-daemon/irccd/daemon/rule.hpp Fri Jul 26 11:20:19 2019 +0000 @@ -50,11 +50,11 @@ drop //!< The event is dropped }; - set servers; //!< The list of servers - set channels; //!< The list of channels - set origins; //!< The list of originators - set plugins; //!< The list of plugins - set events; //!< The list of events + set servers{}; //!< The list of servers + set channels{}; //!< The list of channels + set origins{}; //!< The list of originators + set plugins{}; //!< The list of plugins + set events{}; //!< The list of events /** * The action. @@ -89,6 +89,24 @@ }; /** + * Equality operator. + * + * \param lhs the left side + * \param rhs the right side + * \return true if they equals + */ +auto operator==(const rule& lhs, const rule& rhs) noexcept -> bool; + +/** + * Equality operator. + * + * \param lhs the left side + * \param rhs the right side + * \return false if they equals + */ +auto operator!=(const rule& lhs, const rule& rhs) noexcept -> bool; + +/** * \brief Rule error. */ class rule_error : public std::system_error {
--- a/tests/src/libirccd-daemon/CMakeLists.txt Fri Jul 26 21:10:00 2019 +0000 +++ b/tests/src/libirccd-daemon/CMakeLists.txt Fri Jul 26 11:20:19 2019 +0000 @@ -47,9 +47,9 @@ add_subdirectory(dynlib-plugin) add_subdirectory(irc) add_subdirectory(logger) -add_subdirectory(rules) add_subdirectory(rule-util) add_subdirectory(server) add_subdirectory(server-util) add_subdirectory(server-service) +add_subdirectory(rule-service) add_subdirectory(transports)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/src/libirccd-daemon/rule-service/CMakeLists.txt Fri Jul 26 11:20:19 2019 +0000 @@ -0,0 +1,23 @@ +# +# CMakeLists.txt -- CMake build system for irccd +# +# Copyright (c) 2013-2019 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 rule-service + SOURCES main.cpp + LIBRARIES libirccd-daemon +)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/src/libirccd-daemon/rule-service/main.cpp Fri Jul 26 11:20:19 2019 +0000 @@ -0,0 +1,328 @@ +/* + * main.cpp -- test rule_service object + * + * Copyright (c) 2013-2019 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 "rule_service" +#include <boost/test/unit_test.hpp> + +#include <irccd/daemon/logger.hpp> +#include <irccd/daemon/rule_service.hpp> + +#include <irccd/test/irccd_fixture.hpp> + +namespace test = irccd::test; + +BOOST_TEST_DONT_PRINT_LOG_VALUE(irccd::daemon::rule) + +namespace irccd::daemon { + +namespace { + +BOOST_FIXTURE_TEST_SUITE(rule_service_test_suite, test::irccd_fixture) + +BOOST_AUTO_TEST_CASE(add) +{ + rule r1{{"s1"}}; + rule r2{{"s2"}}; + + bot_.get_rules().add(r1); + bot_.get_rules().add(r2); + + BOOST_TEST(bot_.get_rules().list().size() == 2U); + BOOST_TEST(bot_.get_rules().list()[0] == r1); + BOOST_TEST(bot_.get_rules().list()[1] == r2); +} + +BOOST_AUTO_TEST_CASE(insert) +{ + rule r1{{"s1"}}; + rule r2{{"s2"}}; + + bot_.get_rules().insert(r1, 0); + bot_.get_rules().insert(r2, 0); + + BOOST_TEST(bot_.get_rules().list().size() == 2U); + BOOST_TEST(bot_.get_rules().list()[0] == r2); + BOOST_TEST(bot_.get_rules().list()[1] == r1); +} + +BOOST_AUTO_TEST_CASE(remove) +{ + rule r1{{"s1"}}; + rule r2{{"s2"}}; + + bot_.get_rules().add(r1); + bot_.get_rules().add(r2); + bot_.get_rules().remove(1); + + BOOST_TEST(bot_.get_rules().list().size() == 1U); + BOOST_TEST(bot_.get_rules().list()[0] == r1); +} + +BOOST_AUTO_TEST_CASE(require) +{ + rule r1{{"s1"}}; + rule r2{{"s2"}}; + + bot_.get_rules().add(r1); + bot_.get_rules().add(r2); + + BOOST_TEST(bot_.get_rules().require(0) == r1); + BOOST_TEST(bot_.get_rules().require(1) == r2); + BOOST_REQUIRE_THROW(bot_.get_rules().require(500), rule_error); +} + +BOOST_AUTO_TEST_SUITE_END() + +/* + * Simulate the following rules configuration: + * + * # + * # On all servers, each channel #staff can't use the onCommand event, + * # everything else is allowed. + * # + * [rule] #1 + * servers = "" + * channels = "#staff" + * events = "onCommand" + * action = drop + * + * # + * # However, the same onCommand on #staff is allowed on server "unsafe" + * # + * [rule] #2 + * servers = "unsafe" + * channels = "#staff" + * events = "onCommand" + * action = accept + * + * # + * # Plugin game is only allowed on server "malikania" and "localhost", + * # channel "#games" and events "onMessage, onCommand". + * # + * # The first rule #3-1 disable the plugin game for every server, it is + * # reenabled again with the #3-2. + * # + * [rule] #3-1 + * plugins = "game" + * action = drop + * + * [rule] #3-2 + * servers = "malikania localhost" + * channels = "#games" + * plugins = "game" + * events = "onMessage onCommand" + * action = accept + */ +class solving_test : public test::irccd_fixture { +protected: + solving_test() + { + bot_.set_log(std::make_unique<logger::silent_sink>()); + + // #1 + { + bot_.get_rules().add({ + rule::set{ }, // Servers + rule::set{ "#staff" }, // Channels + rule::set{ }, // Origins + rule::set{ }, // Plugins + rule::set{ "onCommand" }, // Events + rule::action_type::drop + }); + } + + // #2 + { + bot_.get_rules().add({ + rule::set{ "unsafe" }, + rule::set{ "#staff" }, + rule::set{ }, + rule::set{ }, + rule::set{ "onCommand" }, + rule::action_type::accept + }); + } + + // #3-1 + { + bot_.get_rules().add({ + rule::set{}, + rule::set{}, + rule::set{}, + rule::set{"game"}, + rule::set{}, + rule::action_type::drop + }); + } + + // #3-2 + { + bot_.get_rules().add({ + rule::set{ "malikania", "localhost" }, + rule::set{ "#games" }, + rule::set{ }, + rule::set{ "game" }, + rule::set{ "onCommand", "onMessage" }, + rule::action_type::accept + }); + } + } +}; + +BOOST_FIXTURE_TEST_SUITE(solving_test_suite, solving_test) + +BOOST_AUTO_TEST_CASE(basic_match1) +{ + rule m; + + /* + * [rule] + */ + BOOST_TEST(m.match("freenode", "#test", "a", "", "")); + BOOST_TEST(m.match("", "", "", "", "")); +} + +BOOST_AUTO_TEST_CASE(basic_match2) +{ + rule m{rule::set{"freenode"}}; + + /* + * [rule] + * servers = "freenode" + */ + + BOOST_TEST(m.match("freenode", "#test", "a", "", "")); + BOOST_TEST(!m.match("malikania", "#test", "a", "", "")); + BOOST_TEST(m.match("freenode", "", "jean", "", "onMessage")); +} + +BOOST_AUTO_TEST_CASE(basic_match3) +{ + rule m{rule::set{"freenode"}, rule::set{"#staff"}}; + + /* + * [rule] + * servers = "freenode" + * channels = "#staff" + */ + + BOOST_TEST(m.match("freenode", "#staff", "a", "", "")); + BOOST_TEST(!m.match("freenode", "#test", "a", "", "")); + BOOST_TEST(!m.match("malikania", "#staff", "a", "", "")); +} + +BOOST_AUTO_TEST_CASE(basic_match4) +{ + rule m{rule::set{"malikania"}, rule::set{"#staff"}, rule::set{"a"}}; + + /* + * [rule] + * servers = "malikania" + * channels = "#staff" + * plugins = "a" + */ + + BOOST_TEST(m.match("malikania", "#staff", "a", "","")); + BOOST_TEST(!m.match("malikania", "#staff", "b", "", "")); + BOOST_TEST(!m.match("freenode", "#staff", "a", "", "")); +} + +BOOST_AUTO_TEST_CASE(complex_match1) +{ + rule m{rule::set{"malikania", "freenode"}}; + + /* + * [rule] + * servers = "malikania freenode" + */ + + BOOST_TEST(m.match("malikania", "", "", "", "")); + BOOST_TEST(m.match("freenode", "", "", "", "")); + BOOST_TEST(!m.match("no", "", "", "", "")); +} + +BOOST_AUTO_TEST_CASE(origin_match) +{ + rule m{ + rule::set{"malikania"}, + rule::set{}, + rule::set{"markand"}, + rule::set{}, + rule::set{}, + rule::action_type::accept + }; + + /* + * [rule] + * servers = "malikania" + * origins = "markand" + */ + BOOST_TEST(m.match("malikania", "#staff", "markand", "system", "onCommand")); + BOOST_TEST(!m.match("malikania", "#staff", "", "system", "onNames")); + BOOST_TEST(!m.match("malikania", "#staff", "jean", "system", "onMessage")); +} + +BOOST_AUTO_TEST_CASE(basic_solve) +{ + /* Allowed */ + BOOST_TEST(bot_.get_rules().solve("malikania", "#staff", "", "a", "onMessage")); + + /* Allowed */ + BOOST_TEST(bot_.get_rules().solve("freenode", "#staff", "", "b", "onTopic")); + + /* Not allowed */ + BOOST_TEST(!bot_.get_rules().solve("malikania", "#staff", "", "", "onCommand")); + + /* Not allowed */ + BOOST_TEST(!bot_.get_rules().solve("freenode", "#staff", "", "c", "onCommand")); + + /* Allowed */ + BOOST_TEST(bot_.get_rules().solve("unsafe", "#staff", "", "c", "onCommand")); +} + +BOOST_AUTO_TEST_CASE(games_solve) +{ + /* Allowed */ + BOOST_TEST(bot_.get_rules().solve("malikania", "#games", "", "game", "onMessage")); + + /* Allowed */ + BOOST_TEST(bot_.get_rules().solve("localhost", "#games", "", "game", "onMessage")); + + /* Allowed */ + BOOST_TEST(bot_.get_rules().solve("malikania", "#games", "", "game", "onCommand")); + + /* Not allowed */ + BOOST_TEST(!bot_.get_rules().solve("malikania", "#games", "", "game", "onQuery")); + + /* Not allowed */ + BOOST_TEST(!bot_.get_rules().solve("freenode", "#no", "", "game", "onMessage")); + + /* Not allowed */ + BOOST_TEST(!bot_.get_rules().solve("malikania", "#test", "", "game", "onMessage")); +} + +BOOST_AUTO_TEST_CASE(fix_645) +{ + BOOST_TEST(!bot_.get_rules().solve("MALIKANIA", "#STAFF", "", "SYSTEM", "onCommand")); +} + +BOOST_AUTO_TEST_SUITE_END() + +} // !namespace + +} // !irccd::daemon
--- a/tests/src/libirccd-daemon/rules/CMakeLists.txt Fri Jul 26 21:10:00 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -# -# CMakeLists.txt -- CMake build system for irccd -# -# Copyright (c) 2013-2019 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 rules - SOURCES main.cpp - LIBRARIES libirccd -)
--- a/tests/src/libirccd-daemon/rules/main.cpp Fri Jul 26 21:10:00 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,278 +0,0 @@ -/* - * main.cpp -- test irccd rules - * - * Copyright (c) 2013-2019 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 "Rules" -#include <boost/test/unit_test.hpp> - -#include <irccd/daemon/bot.hpp> -#include <irccd/daemon/logger.hpp> -#include <irccd/daemon/rule_service.hpp> - -using boost::asio::io_context; - -using irccd::daemon::bot; -using irccd::daemon::logger::silent_sink; -using irccd::daemon::rule; -using irccd::daemon::rule_service; - -namespace irccd { - -namespace { - -/* - * Simulate the following rules configuration: - * - * # - * # On all servers, each channel #staff can't use the onCommand event, - * # everything else is allowed. - * # - * [rule] #1 - * servers = "" - * channels = "#staff" - * events = "onCommand" - * action = drop - * - * # - * # However, the same onCommand on #staff is allowed on server "unsafe" - * # - * [rule] #2 - * servers = "unsafe" - * channels = "#staff" - * events = "onCommand" - * action = accept - * - * # - * # Plugin game is only allowed on server "malikania" and "localhost", - * # channel "#games" and events "onMessage, onCommand". - * # - * # The first rule #3-1 disable the plugin game for every server, it is - * # reenabled again with the #3-2. - * # - * [rule] #3-1 - * plugins = "game" - * action = drop - * - * [rule] #3-2 - * servers = "malikania localhost" - * channels = "#games" - * plugins = "game" - * events = "onMessage onCommand" - * action = accept - */ -class rules_test { -protected: - io_context service_; - bot bot_{service_}; - rule_service rules_{bot_}; - - rules_test() - { - bot_.set_log(std::make_unique<silent_sink>()); - - // #1 - { - rules_.add({ - rule::set{ }, // Servers - rule::set{ "#staff" }, // Channels - rule::set{ }, // Origins - rule::set{ }, // Plugins - rule::set{ "onCommand" }, // Events - rule::action_type::drop - }); - } - - // #2 - { - rules_.add({ - rule::set{ "unsafe" }, - rule::set{ "#staff" }, - rule::set{ }, - rule::set{ }, - rule::set{ "onCommand" }, - rule::action_type::accept - }); - } - - // #3-1 - { - rules_.add({ - rule::set{}, - rule::set{}, - rule::set{}, - rule::set{"game"}, - rule::set{}, - rule::action_type::drop - }); - } - - // #3-2 - { - rules_.add({ - rule::set{ "malikania", "localhost" }, - rule::set{ "#games" }, - rule::set{ }, - rule::set{ "game" }, - rule::set{ "onCommand", "onMessage" }, - rule::action_type::accept - }); - } - } -}; - -BOOST_FIXTURE_TEST_SUITE(rules_test_suite, rules_test) - -BOOST_AUTO_TEST_CASE(basic_match1) -{ - rule m; - - /* - * [rule] - */ - BOOST_TEST(m.match("freenode", "#test", "a", "", "")); - BOOST_TEST(m.match("", "", "", "", "")); -} - -BOOST_AUTO_TEST_CASE(basic_match2) -{ - rule m{rule::set{"freenode"}}; - - /* - * [rule] - * servers = "freenode" - */ - - BOOST_TEST(m.match("freenode", "#test", "a", "", "")); - BOOST_TEST(!m.match("malikania", "#test", "a", "", "")); - BOOST_TEST(m.match("freenode", "", "jean", "", "onMessage")); -} - -BOOST_AUTO_TEST_CASE(basic_match3) -{ - rule m{rule::set{"freenode"}, rule::set{"#staff"}}; - - /* - * [rule] - * servers = "freenode" - * channels = "#staff" - */ - - BOOST_TEST(m.match("freenode", "#staff", "a", "", "")); - BOOST_TEST(!m.match("freenode", "#test", "a", "", "")); - BOOST_TEST(!m.match("malikania", "#staff", "a", "", "")); -} - -BOOST_AUTO_TEST_CASE(basic_match4) -{ - rule m{rule::set{"malikania"}, rule::set{"#staff"}, rule::set{"a"}}; - - /* - * [rule] - * servers = "malikania" - * channels = "#staff" - * plugins = "a" - */ - - BOOST_TEST(m.match("malikania", "#staff", "a", "","")); - BOOST_TEST(!m.match("malikania", "#staff", "b", "", "")); - BOOST_TEST(!m.match("freenode", "#staff", "a", "", "")); -} - -BOOST_AUTO_TEST_CASE(complex_match1) -{ - rule m{rule::set{"malikania", "freenode"}}; - - /* - * [rule] - * servers = "malikania freenode" - */ - - BOOST_TEST(m.match("malikania", "", "", "", "")); - BOOST_TEST(m.match("freenode", "", "", "", "")); - BOOST_TEST(!m.match("no", "", "", "", "")); -} - -BOOST_AUTO_TEST_CASE(origin_match) -{ - rule m{ - rule::set{"malikania"}, - rule::set{}, - rule::set{"markand"}, - rule::set{}, - rule::set{}, - rule::action_type::accept - }; - - /* - * [rule] - * servers = "malikania" - * origins = "markand" - */ - BOOST_TEST(m.match("malikania", "#staff", "markand", "system", "onCommand")); - BOOST_TEST(!m.match("malikania", "#staff", "", "system", "onNames")); - BOOST_TEST(!m.match("malikania", "#staff", "jean", "system", "onMessage")); -} - -BOOST_AUTO_TEST_CASE(basic_solve) -{ - /* Allowed */ - BOOST_TEST(rules_.solve("malikania", "#staff", "", "a", "onMessage")); - - /* Allowed */ - BOOST_TEST(rules_.solve("freenode", "#staff", "", "b", "onTopic")); - - /* Not allowed */ - BOOST_TEST(!rules_.solve("malikania", "#staff", "", "", "onCommand")); - - /* Not allowed */ - BOOST_TEST(!rules_.solve("freenode", "#staff", "", "c", "onCommand")); - - /* Allowed */ - BOOST_TEST(rules_.solve("unsafe", "#staff", "", "c", "onCommand")); -} - -BOOST_AUTO_TEST_CASE(games_solve) -{ - /* Allowed */ - BOOST_TEST(rules_.solve("malikania", "#games", "", "game", "onMessage")); - - /* Allowed */ - BOOST_TEST(rules_.solve("localhost", "#games", "", "game", "onMessage")); - - /* Allowed */ - BOOST_TEST(rules_.solve("malikania", "#games", "", "game", "onCommand")); - - /* Not allowed */ - BOOST_TEST(!rules_.solve("malikania", "#games", "", "game", "onQuery")); - - /* Not allowed */ - BOOST_TEST(!rules_.solve("freenode", "#no", "", "game", "onMessage")); - - /* Not allowed */ - BOOST_TEST(!rules_.solve("malikania", "#test", "", "game", "onMessage")); -} - -BOOST_AUTO_TEST_CASE(fix_645) -{ - BOOST_TEST(!rules_.solve("MALIKANIA", "#STAFF", "", "SYSTEM", "onCommand")); -} - -BOOST_AUTO_TEST_SUITE_END() - -} // !namespace - -} // !irccd