changeset 745:903415e8ee2e

Tests: add error tests in irccdctl
author David Demelier <markand@malikania.fr>
date Wed, 01 Aug 2018 12:43:16 +0200
parents 484e8b8afb6d
children fe3d80412701
files irccdctl/main.cpp irccdctl/rule_add_cli.cpp irccdctl/rule_edit_cli.cpp irccdctl/rule_info_cli.cpp irccdctl/rule_move_cli.cpp irccdctl/rule_remove_cli.cpp libirccd/irccd/daemon/plugin.cpp libirccd/irccd/daemon/rule.cpp libirccd/irccd/daemon/server.cpp tests/src/irccdctl/CMakeLists.txt tests/src/irccdctl/cli-plugin-config/main.cpp tests/src/irccdctl/cli-plugin-info/main.cpp tests/src/irccdctl/cli-rule-add/main.cpp tests/src/irccdctl/cli-rule-edit/main.cpp tests/src/irccdctl/cli-rule-info/main.cpp tests/src/irccdctl/cli-rule-move/main.cpp tests/src/irccdctl/cli-rule-remove/main.cpp tests/src/irccdctl/cli-server-disconnect/CMakeLists.txt tests/src/irccdctl/cli-server-disconnect/main.cpp tests/src/irccdctl/cli-server-info/CMakeLists.txt tests/src/irccdctl/cli-server-info/main.cpp tests/src/irccdctl/cli-server-invite/CMakeLists.txt tests/src/irccdctl/cli-server-invite/main.cpp tests/src/irccdctl/cli-server-join/CMakeLists.txt tests/src/irccdctl/cli-server-join/main.cpp tests/src/irccdctl/cli-server-kick/main.cpp tests/src/irccdctl/cli-server-list/CMakeLists.txt tests/src/irccdctl/cli-server-me/CMakeLists.txt tests/src/irccdctl/cli-server-me/main.cpp tests/src/irccdctl/cli-server-message/CMakeLists.txt tests/src/irccdctl/cli-server-message/main.cpp tests/src/irccdctl/cli-server-mode/CMakeLists.txt tests/src/irccdctl/cli-server-mode/main.cpp tests/src/irccdctl/cli-server-nick/CMakeLists.txt tests/src/irccdctl/cli-server-nick/main.cpp tests/src/irccdctl/cli-server-notice/CMakeLists.txt tests/src/irccdctl/cli-server-notice/main.cpp tests/src/irccdctl/cli-server-part/CMakeLists.txt tests/src/irccdctl/cli-server-part/main.cpp tests/src/irccdctl/cli-server-reconnect/CMakeLists.txt tests/src/irccdctl/cli-server-reconnect/main.cpp tests/src/irccdctl/cli-server-topic/CMakeLists.txt tests/src/irccdctl/cli-server-topic/main.cpp
diffstat 43 files changed, 777 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/irccdctl/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/irccdctl/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -619,7 +619,9 @@
         irccd::ctl::do_exec(argc, argv);
     } catch (const std::system_error& ex) {
         std::cerr << "abort: " << ex.code().message() << std::endl;
+        return 1;
     } catch (const std::exception& ex) {
         std::cerr << "abort: " << ex.what() << std::endl;
+        return 1;
     }
 }
--- a/irccdctl/rule_add_cli.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/irccdctl/rule_add_cli.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -16,16 +16,11 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <boost/format.hpp>
-
 #include <irccd/options.hpp>
 #include <irccd/string_util.hpp>
 
 #include "rule_add_cli.hpp"
 
-using boost::format;
-using boost::str;
-
 using irccd::string_util::to_uint;
 
 namespace irccd {
@@ -89,10 +84,6 @@
     if (index)
         json["index"] = *index;
 
-    // And action.
-    if (copy[0] != "accept" && copy[0] != "drop")
-        throw std::runtime_error(str(format("invalid action '%1%'") % copy[0]));
-
     json["action"] = copy[0];
 
     request(ctl, json);
--- a/irccdctl/rule_edit_cli.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/irccdctl/rule_edit_cli.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -19,6 +19,8 @@
 #include <irccd/options.hpp>
 #include <irccd/string_util.hpp>
 
+#include <irccd/daemon/service/rule_service.hpp>
+
 #include "rule_edit_cli.hpp"
 
 namespace irccd {
@@ -97,7 +99,7 @@
     const auto index = string_util::to_uint(copy[0]);
 
     if (!index)
-        throw std::invalid_argument("invalid index argument");
+        throw rule_error(rule_error::invalid_index);
 
     json["index"] = *index;
 
--- a/irccdctl/rule_info_cli.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/irccdctl/rule_info_cli.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -18,6 +18,10 @@
 
 #include <iostream>
 
+#include <irccd/string_util.hpp>
+
+#include <irccd/daemon/service/rule_service.hpp>
+
 #include "rule_info_cli.hpp"
 
 namespace irccd {
@@ -28,7 +32,7 @@
 {
     assert(json.is_object());
 
-    auto unjoin = [] (auto array) {
+    const auto unjoin = [] (auto array) {
         std::ostringstream oss;
 
         for (auto it = array.begin(); it != array.end(); ++it) {
@@ -40,7 +44,7 @@
 
         return oss.str();
     };
-    auto unstr = [] (auto action) {
+    const auto unstr = [] (auto action) {
         if (action.is_string() && action == "accept")
             return "accept";
         else
@@ -66,21 +70,18 @@
     if (args.size() < 1)
         throw std::invalid_argument("rule-info requires 1 argument");
 
-    int index = 0;
+    const auto index = string_util::to_int(args[0]);
 
-    try {
-        index = std::stoi(args[0]);
-    } catch (...) {
-        throw std::invalid_argument("invalid number '" + args[0] + "'");
-    }
+    if (!index)
+        throw rule_error(rule_error::invalid_index);
 
-    auto json = nlohmann::json::object({
+    const auto json = nlohmann::json::object({
         { "command",    "rule-info" },
-        { "index",      index       }
+        { "index",      *index      }
     });
 
-    request(ctl, std::move(json), [index] (auto result) {
-        print(result, index);
+    request(ctl, json, [index] (auto result) {
+        print(result, *index);
     });
 }
 
--- a/irccdctl/rule_move_cli.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/irccdctl/rule_move_cli.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -18,6 +18,8 @@
 
 #include <irccd/string_util.hpp>
 
+#include <irccd/daemon/service/rule_service.hpp>
+
 #include "rule_move_cli.hpp"
 
 namespace irccd {
@@ -38,9 +40,9 @@
     const auto to = string_util::to_int<int>(args[1]);
 
     if (!from)
-        throw std::invalid_argument("invalid source argument");
+        throw rule_error(rule_error::invalid_index);
     if (!to)
-        throw std::invalid_argument("invalid destination argument");
+        throw rule_error(rule_error::invalid_index);
 
     request(ctl, {
         { "command",    "rule-move" },
--- a/irccdctl/rule_remove_cli.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/irccdctl/rule_remove_cli.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -16,6 +16,10 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <irccd/string_util.hpp>
+
+#include <irccd/daemon/service/rule_service.hpp>
+
 #include "rule_remove_cli.hpp"
 
 namespace irccd {
@@ -32,17 +36,14 @@
     if (args.size() < 1)
         throw std::invalid_argument("rule-remove requires 1 argument");
 
-    int index = 0;
+    const auto index = string_util::to_int(args[0]);
 
-    try {
-        index = std::stoi(args[0]);
-    } catch (...) {
-        throw std::invalid_argument("invalid number '" + args[0] + "'");
-    }
+    if (!index)
+        throw rule_error(rule_error::invalid_index);
 
     request(ctl, {
         { "command",    "rule-remove"   },
-        { "index",      index           }
+        { "index",      *index          }
     });
 }
 
--- a/libirccd/irccd/daemon/plugin.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/libirccd/irccd/daemon/plugin.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -241,7 +241,7 @@
             case plugin_error::not_found:
                 return "plugin not found";
             case plugin_error::invalid_identifier:
-                return "invalid identifier";
+                return "invalid plugin identifier";
             case plugin_error::exec_error:
                 return "plugin exec error";
             case plugin_error::already_exists:
--- a/libirccd/irccd/daemon/rule.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/libirccd/irccd/daemon/rule.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -70,9 +70,9 @@
         {
             switch (static_cast<rule_error::error>(e)) {
             case rule_error::invalid_action:
-                return "invalid action given";
+                return "invalid rule action";
             case rule_error::invalid_index:
-                return "invalid index";
+                return "invalid rule index";
             default:
                 return "no error";
             }
--- a/libirccd/irccd/daemon/server.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/libirccd/irccd/daemon/server.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -805,7 +805,7 @@
             case server_error::not_found:
                 return "server not found";
             case server_error::invalid_identifier:
-                return "invalid identifier";
+                return "invalid server identifier";
             case server_error::not_connected:
                 return "server is not connected";
             case server_error::already_connected:
--- a/tests/src/irccdctl/CMakeLists.txt	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/CMakeLists.txt	Wed Aug 01 12:43:16 2018 +0200
@@ -41,7 +41,7 @@
 add_subdirectory(cli-server-me)
 add_subdirectory(cli-server-message)
 add_subdirectory(cli-server-mode)
-#add_subdirectory(cli-server-nick)
+add_subdirectory(cli-server-nick)
 add_subdirectory(cli-server-notice)
 add_subdirectory(cli-server-part)
 add_subdirectory(cli-server-reconnect)
--- a/tests/src/irccdctl/cli-plugin-config/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-plugin-config/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -83,6 +83,34 @@
     BOOST_TEST(out[1] == "v2               : 456");
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_identifier)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "plugin-config", "+++" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid plugin identifier");
+}
+
+BOOST_AUTO_TEST_CASE(not_found)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "plugin-config", "unknown" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: plugin not found");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-plugin-info/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-plugin-info/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -44,6 +44,34 @@
     BOOST_TEST(out[3] == "Version        : 1.0");
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_identifier)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "plugin-info", "+++" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid plugin identifier");
+}
+
+BOOST_AUTO_TEST_CASE(not_found)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "plugin-info", "unknown" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: plugin not found");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-rule-add/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-rule-add/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -168,6 +168,22 @@
     }
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_action)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "rule-add", "-p p1", "--add-plugin p2", "break" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid rule action");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-rule-edit/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-rule-edit/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -219,6 +219,46 @@
     }
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_index_1)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "rule-edit", "-p p1", "100" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid rule index");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_index_2)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "rule-edit", "-p p1", "notaint" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid rule index");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_action)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "rule-edit", "--action break", "0" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid rule action");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-rule-info/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-rule-info/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -52,6 +52,34 @@
     BOOST_TEST(out[5]  == "action:      drop");
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_index_1)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "rule-info", "100" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid rule index");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_index_2)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "rule-info", "notaint" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid rule index");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-rule-move/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-rule-move/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -184,6 +184,46 @@
     }
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_index_1_from)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "rule-move", "100", "0" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid rule index");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_index_2_from)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "rule-move", "notaint", "0" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid rule index");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_index_to)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "rule-move", "0", "notaint" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid rule index");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-rule-remove/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-rule-remove/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -93,6 +93,34 @@
     }
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_index_1)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "rule-remove", "100" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid rule index");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_index_2)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "rule-remove", "notaint" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid rule index");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-server-disconnect/CMakeLists.txt	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-disconnect/CMakeLists.txt	Wed Aug 01 12:43:16 2018 +0200
@@ -20,5 +20,5 @@
     NAME cli-server-disconnect
     SOURCES main.cpp
     LIBRARIES libirccd-core
-    DEPENDS irccd
+    DEPENDS irccd irccdctl
 )
--- a/tests/src/irccdctl/cli-server-disconnect/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-disconnect/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -69,6 +69,34 @@
     BOOST_TEST(s2->find("disconnect").size() == 1U);
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_identifier)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-disconnect", "+++" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid server identifier");
+}
+
+BOOST_AUTO_TEST_CASE(not_found)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-disconnect", "unknown" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: server not found");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-server-info/CMakeLists.txt	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-info/CMakeLists.txt	Wed Aug 01 12:43:16 2018 +0200
@@ -20,5 +20,5 @@
     NAME cli-server-info
     SOURCES main.cpp
     LIBRARIES libirccd-core
-    DEPENDS irccd
+    DEPENDS irccd irccdctl
 )
--- a/tests/src/irccdctl/cli-server-info/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-info/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -50,6 +50,34 @@
     BOOST_TEST(out[9] == "Real name      : IRC Client Daemon");
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_identifier)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-info", "+++" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid server identifier");
+}
+
+BOOST_AUTO_TEST_CASE(not_found)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-info", "unknown" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: server not found");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-server-invite/CMakeLists.txt	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-invite/CMakeLists.txt	Wed Aug 01 12:43:16 2018 +0200
@@ -20,5 +20,5 @@
     NAME cli-server-invite
     SOURCES main.cpp
     LIBRARIES libirccd-core
-    DEPENDS irccd
+    DEPENDS irccd irccdctl
 )
--- a/tests/src/irccdctl/cli-server-invite/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-invite/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -44,6 +44,58 @@
     BOOST_TEST(std::any_cast<std::string>(cmd[0][1]) == "#staff");
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_identifier_1)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-invite", "+++", "francis", "#staff" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid server identifier");
+}
+
+BOOST_AUTO_TEST_CASE(not_found)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-invite", "unknown", "francis", "#staff" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: server not found");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_nickname)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-invite", "test", "\"\"", "#staff" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid nickname");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_channel)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-invite", "test", "francis", "\"\"" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid or empty channel");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-server-join/CMakeLists.txt	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-join/CMakeLists.txt	Wed Aug 01 12:43:16 2018 +0200
@@ -20,5 +20,5 @@
     NAME cli-server-join
     SOURCES main.cpp
     LIBRARIES libirccd-core
-    DEPENDS irccd
+    DEPENDS irccd irccdctl
 )
--- a/tests/src/irccdctl/cli-server-join/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-join/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -61,6 +61,46 @@
     BOOST_TEST(std::any_cast<std::string>(cmd[0][1]) == "secret");
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_identifier_1)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-join", "+++", "#staff" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid server identifier");
+}
+
+BOOST_AUTO_TEST_CASE(not_found)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-join", "unknown", "#staff" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: server not found");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_channel)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-join", "test", "\"\"" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid or empty channel");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-server-kick/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-kick/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -63,6 +63,58 @@
     BOOST_TEST(std::any_cast<std::string>(cmd[0][2]) == "shhh");
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_identifier_1)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-kick", "+++", "francis", "#staff" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid server identifier");
+}
+
+BOOST_AUTO_TEST_CASE(not_found)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-kick", "unknown", "francis", "#staff" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: server not found");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_nickname)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-kick", "test", "\"\"", "#staff" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid nickname");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_channel)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-kick", "test", "francis", "\"\"" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid or empty channel");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-server-list/CMakeLists.txt	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-list/CMakeLists.txt	Wed Aug 01 12:43:16 2018 +0200
@@ -20,5 +20,5 @@
     NAME cli-server-list
     SOURCES main.cpp
     LIBRARIES libirccd-core
-    DEPENDS irccd
+    DEPENDS irccd irccdctl
 )
--- a/tests/src/irccdctl/cli-server-me/CMakeLists.txt	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-me/CMakeLists.txt	Wed Aug 01 12:43:16 2018 +0200
@@ -20,5 +20,5 @@
     NAME cli-server-me
     SOURCES main.cpp
     LIBRARIES libirccd-core
-    DEPENDS irccd
+    DEPENDS irccd irccdctl
 )
--- a/tests/src/irccdctl/cli-server-me/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-me/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -44,6 +44,46 @@
     BOOST_TEST(std::any_cast<std::string>(cmd[0][1]) == "hi");
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_identifier_1)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-me", "+++", "#staff", "hello" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid server identifier");
+}
+
+BOOST_AUTO_TEST_CASE(not_found)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-me", "unknown", "#staff", "hello" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: server not found");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_channel)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-me", "test", "\"\"", "hello" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid or empty channel");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-server-message/CMakeLists.txt	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-message/CMakeLists.txt	Wed Aug 01 12:43:16 2018 +0200
@@ -20,5 +20,5 @@
     NAME cli-server-message
     SOURCES main.cpp
     LIBRARIES libirccd-core
-    DEPENDS irccd
+    DEPENDS irccd irccdctl
 )
--- a/tests/src/irccdctl/cli-server-message/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-message/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -44,6 +44,46 @@
     BOOST_TEST(std::any_cast<std::string>(cmd[0][1]) == "hi");
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_identifier_1)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-message", "+++", "#staff", "hello" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid server identifier");
+}
+
+BOOST_AUTO_TEST_CASE(not_found)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-message", "unknown", "#staff", "hello" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: server not found");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_channel)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-message", "test", "\"\"", "hello" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid or empty channel");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-server-mode/CMakeLists.txt	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-mode/CMakeLists.txt	Wed Aug 01 12:43:16 2018 +0200
@@ -20,5 +20,5 @@
     NAME cli-server-mode
     SOURCES main.cpp
     LIBRARIES libirccd-core
-    DEPENDS irccd
+    DEPENDS irccd irccdctl
 )
--- a/tests/src/irccdctl/cli-server-mode/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-mode/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -67,6 +67,58 @@
     BOOST_TEST(std::any_cast<std::string>(cmd[0][4]) == "");
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_identifier_1)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-mode", "+++", "#staff", "+t" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid server identifier");
+}
+
+BOOST_AUTO_TEST_CASE(not_found)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-mode", "unknown", "#staff", "+t" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: server not found");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_channel)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-mode", "test", "\"\"", "+t" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid or empty channel");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_mode)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-mode", "test", "#staff", "\"\"" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid or empty mode");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-server-nick/CMakeLists.txt	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-nick/CMakeLists.txt	Wed Aug 01 12:43:16 2018 +0200
@@ -20,5 +20,5 @@
     NAME cli-server-nick
     SOURCES main.cpp
     LIBRARIES libirccd-core
-    DEPENDS irccd
+    DEPENDS irccd irccdctl
 )
--- a/tests/src/irccdctl/cli-server-nick/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-nick/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -29,12 +29,53 @@
 
 BOOST_AUTO_TEST_CASE(basic)
 {
+    start();
     /*
      * TODO: we will make server::set_nickname call raw() instead of being
      * virtual.
      */
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_identifier_1)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-nick", "+++", "francis" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid server identifier");
+}
+
+BOOST_AUTO_TEST_CASE(not_found)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-nick", "unknown", "francis" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: server not found");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_nickname)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-nick", "test", "\"\"" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid nickname");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-server-notice/CMakeLists.txt	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-notice/CMakeLists.txt	Wed Aug 01 12:43:16 2018 +0200
@@ -20,5 +20,5 @@
     NAME cli-server-notice
     SOURCES main.cpp
     LIBRARIES libirccd-core
-    DEPENDS irccd
+    DEPENDS irccd irccdctl
 )
--- a/tests/src/irccdctl/cli-server-notice/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-notice/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -44,6 +44,46 @@
     BOOST_TEST(std::any_cast<std::string>(cmd[0][1]) == "hi");
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_identifier_1)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-notice", "+++", "#staff", "hello" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid server identifier");
+}
+
+BOOST_AUTO_TEST_CASE(not_found)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-notice", "unknown", "#staff", "hello" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: server not found");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_channel)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-notice", "test", "\"\"", "hello" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid or empty channel");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-server-part/CMakeLists.txt	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-part/CMakeLists.txt	Wed Aug 01 12:43:16 2018 +0200
@@ -20,5 +20,5 @@
     NAME cli-server-part
     SOURCES main.cpp
     LIBRARIES libirccd-core
-    DEPENDS irccd
+    DEPENDS irccd irccdctl
 )
--- a/tests/src/irccdctl/cli-server-part/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-part/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -61,6 +61,46 @@
     BOOST_TEST(std::any_cast<std::string>(cmd[0][1]) == "sick");
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_identifier_1)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-part", "+++", "#staff" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid server identifier");
+}
+
+BOOST_AUTO_TEST_CASE(not_found)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-part", "unknown", "#staff" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: server not found");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_channel)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-part", "test", "\"\"" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid or empty channel");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-server-reconnect/CMakeLists.txt	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-reconnect/CMakeLists.txt	Wed Aug 01 12:43:16 2018 +0200
@@ -20,5 +20,5 @@
     NAME cli-server-reconnect
     SOURCES main.cpp
     LIBRARIES libirccd-core
-    DEPENDS irccd
+    DEPENDS irccd irccdctl
 )
--- a/tests/src/irccdctl/cli-server-reconnect/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-reconnect/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -75,6 +75,34 @@
     BOOST_TEST(s2->find("connect").size() == 1U);
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_identifier)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-reconnect", "+++" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid server identifier");
+}
+
+BOOST_AUTO_TEST_CASE(not_found)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-reconnect", "unknown" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: server not found");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace
--- a/tests/src/irccdctl/cli-server-topic/CMakeLists.txt	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-topic/CMakeLists.txt	Wed Aug 01 12:43:16 2018 +0200
@@ -20,5 +20,5 @@
     NAME cli-server-topic
     SOURCES main.cpp
     LIBRARIES libirccd-core
-    DEPENDS irccd
+    DEPENDS irccd irccdctl
 )
--- a/tests/src/irccdctl/cli-server-topic/main.cpp	Fri Jul 27 08:29:06 2018 +0200
+++ b/tests/src/irccdctl/cli-server-topic/main.cpp	Wed Aug 01 12:43:16 2018 +0200
@@ -44,6 +44,46 @@
     BOOST_TEST(std::any_cast<std::string>(cmd[0][1]) == "welcome");
 }
 
+BOOST_AUTO_TEST_SUITE(errors)
+
+BOOST_AUTO_TEST_CASE(invalid_identifier_1)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-topic", "+++", "#staff", "hello" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid server identifier");
+}
+
+BOOST_AUTO_TEST_CASE(not_found)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-topic", "unknown", "#staff", "hello" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: server not found");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_channel)
+{
+    start();
+
+    const auto [code, out, err] = exec({ "server-topic", "test", "\"\"", "hello" });
+
+    BOOST_TEST(code);
+    BOOST_TEST(out.size() == 0U);
+    BOOST_TEST(err.size() == 1U);
+    BOOST_TEST(err[0] == "abort: invalid or empty channel");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // !namespace