]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#4144] Fix tests failing due to socket name too long
authorAndrei Pavel <andrei@isc.org>
Wed, 5 Nov 2025 11:29:33 +0000 (13:29 +0200)
committerAndrei Pavel <andrei@isc.org>
Fri, 14 Nov 2025 13:04:44 +0000 (15:04 +0200)
- kea-config-tests
- kea-agent-tests
- kea-d2-tests
- kea-dhcp4-tests
- kea-dhcp6-tests

15 files changed:
src/bin/agent/tests/ca_command_mgr_unittests.cc
src/bin/d2/tests/d2_command_unittest.cc
src/bin/dhcp4/tests/config_parser_unittest.cc
src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc
src/bin/dhcp4/tests/get_config_unittest.cc
src/bin/dhcp4/tests/get_config_unittest.cc.skel
src/bin/dhcp6/tests/config_parser_unittest.cc
src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc
src/bin/dhcp6/tests/get_config_unittest.cc
src/bin/dhcp6/tests/get_config_unittest.cc.skel
src/bin/netconf/tests/control_socket_unittests.cc
src/bin/netconf/tests/netconf_unittests.cc
src/lib/config/tests/unix_command_config_unittests.cc
src/lib/config/tests/unix_command_mgr_unittests.cc
src/lib/config/testutils/socket_test.h [new file with mode: 0644]

index 0c99d3578a60a052a75bed9f4378349d50a5a254..b8b5c5db8f75fdab67ed0f24e8077a7eea2a6c2f 100644 (file)
@@ -5,6 +5,7 @@
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 #include <config.h>
+
 #include <agent/ca_cfg_mgr.h>
 #include <agent/ca_command_mgr.h>
 #include <agent/ca_controller.h>
 #include <asiolink/testutils/test_server_unix_socket.h>
 #include <cc/command_interpreter.h>
 #include <cc/data.h>
+#include <config/testutils/socket_test.h>
 #include <config/unix_command_config.h>
 #include <process/testutils/d_test_stubs.h>
+#include <testutils/gtest_utils.h>
 #include <util/filesystem.h>
-#include <boost/pointer_cast.hpp>
-#include <gtest/gtest.h>
-#include <testutils/sandbox.h>
+
 #include <cstdlib>
 #include <functional>
-#include <vector>
 #include <thread>
+#include <vector>
+
+#include <boost/pointer_cast.hpp>
+
+#include <gtest/gtest.h>
 
 using namespace isc::agent;
 using namespace isc::asiolink;
+using namespace isc::asiolink::test;
+using namespace isc::config::test;
 using namespace isc::data;
 using namespace isc::process;
 using namespace isc::config;
@@ -45,14 +52,12 @@ const long TEST_TIMEOUT = 10000;
 /// Meanwhile, this is just a placeholder for the tests.
 class CtrlAgentCommandMgrTest : public DControllerTest {
 public:
-    isc::test::Sandbox sandbox;
-
     /// @brief Constructor.
     ///
     /// Deregisters all commands except 'list-commands'.
     CtrlAgentCommandMgrTest()
-        : DControllerTest(CtrlAgentController::instance),
-          mgr_(CtrlAgentCommandMgr::instance()) {
+        : DControllerTest(CtrlAgentController::instance), mgr_(CtrlAgentCommandMgr::instance()),
+          skipped_(false) {
         mgr_.deregisterAll();
         setSocketTestPath();
         removeUnixSocketFile();
@@ -167,9 +172,15 @@ public:
         ASSERT_TRUE(ctx);
 
         ElementPtr control_socket = Element::createMap();
-        control_socket->set("validated-socket-name",
-                            Element::create(unixSocketFilePath()));
+        std::string const socket_path(unixSocketFilePath());
+        control_socket->set("validated-socket-name", Element::create(socket_path));
         ctx->setControlSocketInfo(control_socket, service);
+
+        bool const too_long(SocketName::isTooLong(socket_path));
+        if (too_long) {
+            skipped_ = true;
+            SKIP_IF("Socket name too long.");
+        }
     }
 
     /// @brief Create and bind server side socket.
@@ -179,9 +190,9 @@ public:
     /// @param use_thread Indicates if the IO service will be ran in thread.
     void bindServerSocket(const std::string& response,
                           const bool use_thread = false) {
-        server_socket_.reset(new test::TestServerUnixSocket(getIOService(),
-                                                            unixSocketFilePath(),
-                                                            response));
+        server_socket_.reset(new TestServerUnixSocket(getIOService(),
+                                                      unixSocketFilePath(),
+                                                      response));
         server_socket_->startTimer(TEST_TIMEOUT);
         server_socket_->bindServerSocket(use_thread);
     }
@@ -230,6 +241,7 @@ public:
                      const std::string& server_response = "{ \"result\": 0 }") {
         // Configure client side socket.
         configureControlSocket(configured_service);
+        SKIP_IF(skipped_);
         // Create server side socket.
         bindServerSocket(server_response, true);
 
@@ -267,7 +279,10 @@ public:
     CtrlAgentCommandMgr& mgr_;
 
     /// @brief Pointer to the test server unix socket.
-    test::TestServerUnixSocketPtr server_socket_;
+    TestServerUnixSocketPtr server_socket_;
+
+    /// @brief Whether the current test was skipped.
+    bool skipped_;
 };
 
 /// Just a basic test checking that non-existent command is handled
@@ -317,6 +332,7 @@ TEST_F(CtrlAgentCommandMgrTest, forwardToD2Server) {
 /// Check that the same command is forwarded to multiple servers.
 TEST_F(CtrlAgentCommandMgrTest, forwardToBothDHCPServers) {
     configureControlSocket("dhcp6");
+    SKIP_IF(skipped_);
 
     testForward("dhcp4", "dhcp4,dhcp6", isc::config::CONTROL_RESULT_SUCCESS,
                 isc::config::CONTROL_RESULT_SUCCESS, -1, 2);
@@ -326,6 +342,7 @@ TEST_F(CtrlAgentCommandMgrTest, forwardToBothDHCPServers) {
 TEST_F(CtrlAgentCommandMgrTest, forwardToAllServers) {
     configureControlSocket("dhcp6");
     configureControlSocket("d2");
+    SKIP_IF(skipped_);
 
     testForward("dhcp4", "dhcp4,dhcp6,d2", isc::config::CONTROL_RESULT_SUCCESS,
                 isc::config::CONTROL_RESULT_SUCCESS,
@@ -381,6 +398,7 @@ TEST_F(CtrlAgentCommandMgrTest, noClientSocket) {
 /// which the control command is to be forwarded is not available.
 TEST_F(CtrlAgentCommandMgrTest, noServerSocket) {
     configureControlSocket("dhcp6");
+    SKIP_IF(skipped_);
 
     ConstElementPtr command = createCommand("foo", "dhcp6");
     ConstElementPtr answer = mgr_.handleCommand("foo", ConstElementPtr(),
@@ -394,6 +412,7 @@ TEST_F(CtrlAgentCommandMgrTest, noServerSocket) {
 TEST_F(CtrlAgentCommandMgrTest, forwardListCommands) {
     // Configure client side socket.
     configureControlSocket("dhcp4");
+    SKIP_IF(skipped_);
     // Create server side socket.
     bindServerSocket("{ \"result\" : 3 }", true);
 
index 68786c44a918461d5d3eed1c855d7580c91807b9..d2aa835ad50238ffa206cfcea8e2abe1145caf7e 100644 (file)
 #include <asiolink/io_service.h>
 #include <cc/command_interpreter.h>
 #include <config/command_mgr.h>
+#include <config/testutils/socket_test.h>
 #include <config/timeouts.h>
 #include <config/unix_command_mgr.h>
-#include <testutils/io_utils.h>
-#include <testutils/unix_control_client.h>
 #include <d2/d2_controller.h>
 #include <d2/d2_process.h>
 #include <d2/parser_context.h>
+#include <testutils/gtest_utils.h>
+#include <testutils/io_utils.h>
+#include <testutils/unix_control_client.h>
 #include <util/filesystem.h>
-#include <gtest/gtest.h>
-#include <testutils/sandbox.h>
-#include <boost/pointer_cast.hpp>
+
 #include <fstream>
 #include <iostream>
 #include <sstream>
 #include <thread>
+
+#include <boost/pointer_cast.hpp>
+
+#include <gtest/gtest.h>
 #include <unistd.h>
 
 using namespace std;
 using namespace isc;
 using namespace isc::asiolink;
 using namespace isc::config;
+using namespace isc::config::test;
 using namespace isc::d2;
 using namespace isc::data;
 using namespace isc::dhcp::test;
 using namespace isc::process;
+using namespace isc::test;
 using namespace isc::util;
 using namespace boost::asio;
 namespace ph = std::placeholders;
@@ -106,8 +112,6 @@ private:
 /// @brief Fixture class intended for testing control channel in D2.
 class CtrlChannelD2Test : public ::testing::Test {
 public:
-    isc::test::Sandbox sandbox;
-
     /// @brief Path to the UNIX socket being used to communicate with the server.
     string socket_path_;
 
@@ -122,11 +126,13 @@ public:
     /// @brief Configuration file.
     static const char* CFG_TEST_FILE;
 
+    /// @brief Whether the current test was skipped.
+    bool skipped_;
+
     /// @brief Default constructor.
     ///
     /// Sets socket path to its default value.
-    CtrlChannelD2Test()
-        : server_(NakedD2Controller::instance()) {
+    CtrlChannelD2Test() : server_(NakedD2Controller::instance()), skipped_(false) {
         setSocketTestPath();
         ::remove(socket_path_.c_str());
         file::PathChecker::enableEnforcement(false);
@@ -230,6 +236,13 @@ public:
 
         int status = 0;
         ConstElementPtr txt = parseAnswer(status, answer);
+
+        bool const too_long(SocketName::isTooLong(socket_path_));
+        if (too_long) {
+            skipped_ = true;
+            SKIP_IF("Socket name too long.");
+        }
+
         // This should succeed. If not, print the error message.
         ASSERT_EQ(0, status) << txt->str();
 
@@ -518,6 +531,7 @@ TEST_F(CtrlChannelD2Test, commandsRegistration) {
 
     // Created server should register several additional commands.
     EXPECT_NO_THROW(createUnixChannelServer());
+    SKIP_IF(skipped_);
 
     EXPECT_NO_THROW(answer = CommandMgr::instance().processCommand(list_cmds));
     ASSERT_TRUE(answer);
@@ -553,6 +567,7 @@ TEST_F(CtrlChannelD2Test, commandsRegistration) {
 // Tests that the server properly responds to invalid commands.
 TEST_F(CtrlChannelD2Test, invalid) {
     EXPECT_NO_THROW(createUnixChannelServer());
+    SKIP_IF(skipped_);
     string response;
 
     sendUnixCommand("{ \"command\": \"bogus\" }", response);
@@ -567,6 +582,7 @@ TEST_F(CtrlChannelD2Test, invalid) {
 // Tests that the server properly responds to shutdown command.
 TEST_F(CtrlChannelD2Test, shutdown) {
     EXPECT_NO_THROW(createUnixChannelServer());
+    SKIP_IF(skipped_);
     string response;
 
     sendUnixCommand("{ \"command\": \"shutdown\" }", response);
@@ -579,6 +595,7 @@ TEST_F(CtrlChannelD2Test, shutdown) {
 // to shutdown command.
 TEST_F(CtrlChannelD2Test, shutdownExitValue) {
     EXPECT_NO_THROW(createUnixChannelServer());
+    SKIP_IF(skipped_);
     string response;
 
     sendUnixCommand("{ \"command\": \"shutdown\", "
@@ -594,6 +611,7 @@ TEST_F(CtrlChannelD2Test, shutdownExitValue) {
 // This test verifies that the D2 server handles version-get commands.
 TEST_F(CtrlChannelD2Test, getversion) {
     EXPECT_NO_THROW(createUnixChannelServer());
+    SKIP_IF(skipped_);
     string response;
 
     // Send the version-get command.
@@ -611,6 +629,7 @@ TEST_F(CtrlChannelD2Test, getversion) {
 // Tests that the server properly responds to list-commands command.
 TEST_F(CtrlChannelD2Test, listCommands) {
     EXPECT_NO_THROW(createUnixChannelServer());
+    SKIP_IF(skipped_);
     string response;
 
     sendUnixCommand("{ \"command\": \"list-commands\" }", response);
@@ -639,6 +658,7 @@ TEST_F(CtrlChannelD2Test, listCommands) {
 // This test verifies that the D2 server handles status-get commands.
 TEST_F(CtrlChannelD2Test, statusGet) {
     EXPECT_NO_THROW(createUnixChannelServer());
+    SKIP_IF(skipped_);
 
     std::string response_txt;
 
@@ -680,6 +700,7 @@ TEST_F(CtrlChannelD2Test, statusGet) {
 // config-get handler are actually converting the configuration correctly.
 TEST_F(CtrlChannelD2Test, configGet) {
     EXPECT_NO_THROW(createUnixChannelServer());
+    SKIP_IF(skipped_);
     string response;
 
     sendUnixCommand("{ \"command\": \"config-get\" }", response);
@@ -703,6 +724,7 @@ TEST_F(CtrlChannelD2Test, configGet) {
 // config-hash-get.
 TEST_F(CtrlChannelD2Test, configHashGet) {
     EXPECT_NO_THROW(createUnixChannelServer());
+    SKIP_IF(skipped_);
     string response;
 
     sendUnixCommand("{ \"command\": \"config-hash-get\" }", response);
@@ -787,6 +809,13 @@ TEST_F(CtrlChannelD2Test, configTest) {
     ASSERT_TRUE(proc);
     ConstElementPtr answer = proc->configure(config, false);
     ASSERT_TRUE(answer);
+
+    bool const too_long(SocketName::isTooLong(socket_path_));
+    if (too_long) {
+        skipped_ = true;
+        SKIP_IF("Socket name too long.");
+    }
+
     // The config contains random
     // socket name (/tmp/kea-<value-changing-each-time>/kea6.sock), so the
     // hash will be different each time. As such, we can do simplified checks:
@@ -849,13 +878,13 @@ TEST_F(CtrlChannelD2Test, configTest) {
        << "}}";
 
     // Verify the control channel socket exists.
-    ASSERT_TRUE(test::fileExists(socket_path_));
+    ASSERT_TRUE(fileExists(socket_path_));
 
     // Send the config-test command.
     sendUnixCommand(os.str(), response);
 
     // Verify the control channel socket still exists.
-    EXPECT_TRUE(test::fileExists(socket_path_));
+    EXPECT_TRUE(fileExists(socket_path_));
 
     // Verify the configuration was successful.
     EXPECT_EQ("{ \"result\": 0, \"text\": \"Configuration check successful\" }",
@@ -925,6 +954,13 @@ TEST_F(CtrlChannelD2Test, configSet) {
     ASSERT_TRUE(proc);
     ConstElementPtr answer = proc->configure(config, false);
     ASSERT_TRUE(answer);
+
+    bool const too_long(SocketName::isTooLong(socket_path_));
+    if (too_long) {
+        skipped_ = true;
+        SKIP_IF("Socket name too long.");
+    }
+
     // The config contains random
     // socket name (/tmp/kea-<value-changing-each-time>/kea6.sock), so the
     // hash will be different each time. As such, we can do simplified checks:
@@ -988,13 +1024,13 @@ TEST_F(CtrlChannelD2Test, configSet) {
        << "}}";
 
     // Verify the control channel socket exists.
-    ASSERT_TRUE(test::fileExists(socket_path_));
+    ASSERT_TRUE(fileExists(socket_path_));
 
     // Send the config-set command.
     sendUnixCommand(os.str(), response);
 
     // Verify the control channel socket no longer exists.
-    EXPECT_FALSE(test::fileExists(socket_path_));
+    EXPECT_FALSE(fileExists(socket_path_));
 
     // Verify the configuration was successful.
     EXPECT_EQ("{ \"arguments\": { \"hash\": \"5206A1BEC7E3C6ADD5E97C5983861F97739EA05CFEAD823CBBC4"
@@ -1011,6 +1047,7 @@ TEST_F(CtrlChannelD2Test, configSet) {
 // Tests if config-write can be called without any parameters.
 TEST_F(CtrlChannelD2Test, writeConfigNoFilename) {
     EXPECT_NO_THROW(createUnixChannelServer());
+    SKIP_IF(skipped_);
     string response;
 
     // This is normally set by the command line -c parameter.
@@ -1027,6 +1064,7 @@ TEST_F(CtrlChannelD2Test, writeConfigNoFilename) {
 // Tests if config-write can be called with a valid filename as parameter.
 TEST_F(CtrlChannelD2Test, writeConfigFilename) {
     EXPECT_NO_THROW(createUnixChannelServer());
+    SKIP_IF(skipped_);
     string response;
 
     // This is normally set by the command line -c parameter.
@@ -1043,6 +1081,7 @@ TEST_F(CtrlChannelD2Test, writeConfigFilename) {
 // Tests if config-write can be called with a valid full path as parameter.
 TEST_F(CtrlChannelD2Test, configWriteFullPath) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set by the command line -c parameter.
@@ -1059,6 +1098,7 @@ TEST_F(CtrlChannelD2Test, configWriteFullPath) {
 // Tests if config-write raises an error with invalid path as parameter.
 TEST_F(CtrlChannelD2Test, configWriteBadPath) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set by the command line -c parameter.
@@ -1078,6 +1118,7 @@ TEST_F(CtrlChannelD2Test, configWriteBadPath) {
 // Tests if config-write raises an error with invalid full path as parameter.
 TEST_F(CtrlChannelD2Test, configWriteBadFullPath) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set by the command line -c parameter.
@@ -1098,6 +1139,7 @@ TEST_F(CtrlChannelD2Test, configWriteBadFullPath) {
 // file is missing.
 TEST_F(CtrlChannelD2Test, configReloadMissingFile) {
     EXPECT_NO_THROW(createUnixChannelServer());
+    SKIP_IF(skipped_);
     string response;
 
     // This is normally set to whatever value is passed to -c when the server is
@@ -1119,6 +1161,7 @@ TEST_F(CtrlChannelD2Test, configReloadMissingFile) {
 // file is not a valid JSON.
 TEST_F(CtrlChannelD2Test, configReloadBrokenFile) {
     EXPECT_NO_THROW(createUnixChannelServer());
+    SKIP_IF(skipped_);
     string response;
 
     // This is normally set to whatever value is passed to -c when the server is
@@ -1149,6 +1192,7 @@ TEST_F(CtrlChannelD2Test, configReloadBrokenFile) {
 // file is loaded correctly.
 TEST_F(CtrlChannelD2Test, configReloadFileValid) {
     EXPECT_NO_THROW(createUnixChannelServer());
+    SKIP_IF(skipped_);
     string response;
 
     // This is normally set to whatever value is passed to -c when the server is
@@ -1199,6 +1243,7 @@ TEST_F(CtrlChannelD2Test, configReloadFileValid) {
 /// established. (@todo change when response will be sent in multiple chunks)
 TEST_F(CtrlChannelD2Test, concurrentConnections) {
     EXPECT_NO_THROW(createUnixChannelServer());
+    SKIP_IF(skipped_);
 
     boost::scoped_ptr<UnixControlClient> client1(new UnixControlClient());
     ASSERT_TRUE(client1);
@@ -1270,6 +1315,7 @@ TEST_F(CtrlChannelD2Test, longCommand) {
     );
 
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     string response;
     std::thread th([this, &response, &command]() {
@@ -1328,6 +1374,7 @@ TEST_F(CtrlChannelD2Test, longResponse) {
     );
 
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // The UnixControlClient doesn't have any means to check that the entire
     // response has been received. What we want to do is to generate a
@@ -1387,6 +1434,7 @@ TEST_F(CtrlChannelD2Test, longResponse) {
 // takes too long, after receiving a partial command
 TEST_F(CtrlChannelD2Test, connectionTimeoutPartialCommand) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // Set connection timeout to 2s to prevent long waiting time for the
     // timeout during this test.
@@ -1440,6 +1488,7 @@ TEST_F(CtrlChannelD2Test, connectionTimeoutPartialCommand) {
 // takes too long, having received no data from the client.
 TEST_F(CtrlChannelD2Test, connectionTimeoutNoData) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // Set connection timeout to 2s to prevent long waiting time for the
     // timeout during this test.
index 3c21bfb07ac97901e62c23880d93106ff656c7c2..bf91ec50b0a3579595839fb12b7c829ae46f7988 100644 (file)
@@ -9,6 +9,7 @@
 #include <asiolink/addr_utilities.h>
 #include <cc/command_interpreter.h>
 #include <config/http_command_config.h>
+#include <config/testutils/socket_test.h>
 #include <dhcp/classify.h>
 #include <dhcp/docsis3_option_defs.h>
 #include <dhcp/iface_mgr.h>
@@ -59,6 +60,7 @@
 using namespace isc;
 using namespace isc::asiolink;
 using namespace isc::config;
+using namespace isc::config::test;
 using namespace isc::data;
 using namespace isc::dhcp;
 using namespace isc::dhcp::test;
@@ -409,12 +411,21 @@ public:
 
         int rcode;
         ConstElementPtr comment = parseAnswerText(rcode, status);
-        EXPECT_EQ(expected_code, rcode);
 
         string text;
         ASSERT_TRUE(comment);
         ASSERT_NO_THROW(text = comment->stringValue());
 
+        // Socket name too long?
+        bool const too_long(SocketName::isTooLongFromConfig(json));
+        if (too_long) {
+            EXPECT_EQ(CONTROL_RESULT_ERROR, rcode);
+            exp_error = "name too long";
+            EXPECT_NE(std::string::npos, text.find(exp_error));
+            return;
+        }
+
+        EXPECT_EQ(expected_code, rcode);
         if (expected_code != rcode) {
             std::cout << "Reported status: " << text << std::endl;
         }
@@ -6950,6 +6961,13 @@ TEST_F(Dhcp4ParserTest, comments) {
     ASSERT_TRUE(ctx_iface->get("comment"));
     EXPECT_EQ("\"Use wildcard\"", ctx_iface->get("comment")->str());
 
+    ConstElementPtr json;
+    ASSERT_NO_THROW_LOG(json = parseDHCP4(config, true));
+    bool const too_long(SocketName::isTooLongFromConfig(json));
+    if (too_long) {
+        return;
+    }
+
     // There is a global option definition.
     const OptionDefinitionPtr& opt_def =
         LibDHCP::getRuntimeOptionDef("isc", 100);
index 6a435f045479e86392e4cd973946444a1867dbac..09c22b0434404bcc91d03d682dd14a119a1f512e 100644 (file)
@@ -10,6 +10,7 @@
 #include <asiolink/io_service.h>
 #include <cc/command_interpreter.h>
 #include <config/command_mgr.h>
+#include <config/testutils/socket_test.h>
 #include <config/timeouts.h>
 #include <database/database_connection.h>
 #include <config/unix_command_mgr.h>
@@ -29,9 +30,9 @@
 #include <stats/stats_mgr.h>
 #include <util/multi_threading_mgr.h>
 #include <util/chrono_time_utils.h>
+#include <testutils/gtest_utils.h>
 #include <testutils/io_utils.h>
 #include <testutils/unix_control_client.h>
-#include <testutils/sandbox.h>
 
 #include "marker_file.h"
 
@@ -50,6 +51,7 @@ using namespace std;
 using namespace isc;
 using namespace isc::asiolink;
 using namespace isc::config;
+using namespace isc::config::test;
 using namespace isc::data;
 using namespace isc::db;
 using namespace isc::dhcp;
@@ -107,8 +109,6 @@ public:
 /// @brief Fixture class intended for testing control channel in the DHCPv4Srv
 class CtrlChannelDhcpv4SrvTest : public BaseServerTest {
 public:
-    isc::test::Sandbox sandbox;
-
     /// @brief Path to the UNIX socket being used to communicate with the server
     std::string socket_path_;
 
@@ -121,10 +121,13 @@ public:
     /// @brief Asynchronous timer service to detect timeouts.
     IntervalTimerPtr test_timer_;
 
+    /// @brief Whether the current test was skipped.
+    bool skipped_;
+
     /// @brief Default constructor
     ///
     /// Sets socket path to its default value.
-    CtrlChannelDhcpv4SrvTest() : interfaces_("\"*\"") {
+    CtrlChannelDhcpv4SrvTest() : interfaces_("\"*\""), skipped_(false) {
         resetLogPath();
         setSocketTestPath();
         reset();
@@ -261,6 +264,13 @@ public:
 
         int status = 0;
         ConstElementPtr txt = isc::config::parseAnswer(status, answer);
+
+        bool const too_long(SocketName::isTooLong(socket_path_));
+        if (too_long) {
+            skipped_ = true;
+            SKIP_IF("Socket name too long.");
+        }
+
         // This should succeed. If not, print the error message.
         ASSERT_EQ(0, status) << txt->str();
 
@@ -573,6 +583,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, commandsRegistration) {
 // via ControlChannel
 TEST_F(CtrlChannelDhcpv4SrvTest, controlChannelNegative) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{ \"command\": \"bogus\" }", response);
@@ -589,6 +600,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, controlChannelNegative) {
 // via ControlChannel
 TEST_F(CtrlChannelDhcpv4SrvTest, controlChannelShutdown) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{ \"command\": \"shutdown\" }", response);
@@ -601,6 +613,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, controlChannelShutdown) {
 // test of Dhcpv4 statistics.
 TEST_F(CtrlChannelDhcpv4SrvTest, controlChannelStats) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // Check statistic-get
@@ -726,6 +739,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, controlChannelStats) {
 TEST_F(CtrlChannelDhcpv4SrvTest, configSet) {
     setLogTestPath("/dev");
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // Define strings to permutate the config arguments
     // (Note the line feeds makes errors easy to find)
@@ -909,6 +923,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configSet) {
 TEST_F(CtrlChannelDhcpv4SrvTest, configSetLFCRunning) {
     setLogTestPath("/dev");
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // Define strings to permutate the config arguments
     // (Note the line feeds makes errors easy to find)
@@ -1064,6 +1079,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configSetLFCRunning) {
 // config-get handler are actually converting the configuration correctly.
 TEST_F(CtrlChannelDhcpv4SrvTest, configGet) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{ \"command\": \"config-get\" }", response);
@@ -1088,6 +1104,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configGet) {
 // config-hash-get.
 TEST_F(CtrlChannelDhcpv4SrvTest, configHashGet) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{ \"command\": \"config-hash-get\" }", response);
@@ -1119,6 +1136,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configHashGet) {
 TEST_F(CtrlChannelDhcpv4SrvTest, configTest) {
     setLogTestPath("/dev");
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // Define strings to permutate the config arguments
     // (Note the line feeds makes errors easy to find)
@@ -1267,6 +1285,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configTest) {
 // Verify that the "subnet4-select-test" command will do what we expect.
 TEST_F(CtrlChannelDhcpv4SrvTest, subnetSelectTest) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     string command_txt = "{ \"command\": \"subnet4-select-test\", \"arguments\": { \"classes\": [ \"foo\" ] } }";
 
@@ -1281,6 +1300,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, subnetSelectTest) {
 // Verify that the "subnet4o6-select-test" command will do what we expect.
 TEST_F(CtrlChannelDhcpv4SrvTest, subnet4o6SelectTest) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     string command_txt = "{ \"command\": \"subnet4o6-select-test\", \"arguments\": { \"classes\": [ \"foo\" ] } }";
 
@@ -1295,6 +1315,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, subnet4o6SelectTest) {
 // This test verifies that the DHCP server handles version-get commands
 TEST_F(CtrlChannelDhcpv4SrvTest, getVersion) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     std::string response;
 
@@ -1313,6 +1334,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, getVersion) {
 // This test verifies that the DHCP server handles server-tag-get command
 TEST_F(CtrlChannelDhcpv4SrvTest, serverTagGet) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     std::string response;
     std::string expected;
@@ -1334,6 +1356,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, serverTagGet) {
 // This test verifies that the DHCP server handles status-get commands
 TEST_F(CtrlChannelDhcpv4SrvTest, statusGet) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // start_ is initialized by init.
     ASSERT_THROW(server_->init("/no/such/file"), BadValue);
@@ -1445,6 +1468,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, statusGet) {
 TEST_F(CtrlChannelDhcpv4SrvTest, noManagers) {
     // Send the status-get command.
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     LeaseMgrFactory::destroy();
     HostMgr::create();
     string response_text;
@@ -1469,6 +1493,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, statusGetSockets) {
 
     // Send the status-get command.
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     string response_text;
     sendUnixCommand(R"({ "command": "status-get" })", response_text);
     ConstElementPtr response;
@@ -1508,6 +1533,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, statusGetSocketsErrors) {
 
     // Send the status-get command.
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     string response_text;
     sendUnixCommand(R"({ "command": "status-get" })", response_text);
     ConstElementPtr response;
@@ -1551,6 +1577,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, statusGetSocketsErrors) {
 // This test verifies that the DHCP server handles config-backend-pull command
 TEST_F(CtrlChannelDhcpv4SrvTest, configBackendPull) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     std::string response;
     std::string expected;
@@ -1565,6 +1592,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configBackendPull) {
 // leases on leases-reclaim command
 TEST_F(CtrlChannelDhcpv4SrvTest, controlLeasesReclaim) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // Create expired leases. Leases are expired by 40 seconds ago
     // (valid lifetime = 60, cltt = now - 100).
@@ -1623,6 +1651,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, controlLeasesReclaim) {
 // leases on leases-reclaim command with remove = true
 TEST_F(CtrlChannelDhcpv4SrvTest, controlLeasesReclaimRemove) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // Create expired leases. Leases are expired by 40 seconds ago
     // (valid lifetime = 60, cltt = now - 100).
@@ -1662,6 +1691,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, controlLeasesReclaimRemove) {
 // via ControlChannel
 TEST_F(CtrlChannelDhcpv4SrvTest, listCommands) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{ \"command\": \"list-commands\" }", response);
@@ -1700,6 +1730,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, listCommands) {
 // Tests if config-write can be called without any parameters.
 TEST_F(CtrlChannelDhcpv4SrvTest, configWriteNoFilename) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set by the command line -c parameter.
@@ -1716,6 +1747,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configWriteNoFilename) {
 // Tests if config-write can be called with a valid filename as parameter.
 TEST_F(CtrlChannelDhcpv4SrvTest, configWriteFilename) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set by the command line -c parameter.
@@ -1731,6 +1763,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configWriteFilename) {
 // Tests if config-write can be called with a valid full path as parameter.
 TEST_F(CtrlChannelDhcpv4SrvTest, configWriteFullPath) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set by the command line -c parameter.
@@ -1746,6 +1779,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configWriteFullPath) {
 // Tests if config-write raises an error with invalid path as parameter.
 TEST_F(CtrlChannelDhcpv4SrvTest, configWriteBadPath) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set by the command line -c parameter.
@@ -1764,6 +1798,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configWriteBadPath) {
 // Tests if config-write raises an error with invalid full path as parameter.
 TEST_F(CtrlChannelDhcpv4SrvTest, configWriteBadFullPath) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set by the command line -c parameter.
@@ -1783,6 +1818,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configWriteBadFullPath) {
 // file is missing.
 TEST_F(CtrlChannelDhcpv4SrvTest, configReloadMissingFile) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set to whatever value is passed to -c when the server is
@@ -1804,6 +1840,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configReloadMissingFile) {
 // file is not a valid JSON.
 TEST_F(CtrlChannelDhcpv4SrvTest, configReloadBrokenFile) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set to whatever value is passed to -c when the server is
@@ -1831,6 +1868,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configReloadBrokenFile) {
 // Check that the "config-reload" fails when LFC is running.
 TEST_F(CtrlChannelDhcpv4SrvTest, configReloadLFCRunning) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set to whatever value is passed to -c when the server is
@@ -1887,6 +1925,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configReloadLFCRunning) {
 // file is loaded correctly.
 TEST_F(CtrlChannelDhcpv4SrvTest, configReloadValid) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set to whatever value is passed to -c when the server is
@@ -1950,6 +1989,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configReloadDetectInterfaces) {
     IfaceMgr::instance().closeSockets();
     IfaceMgr::instance().detectIfaces();
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set to whatever value is passed to -c when the server is
@@ -2010,6 +2050,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configReloadDetectInterfaces) {
 // parameters.
 TEST_F(CtrlChannelDhcpv4SrvTest, dhcpDisableBadParam) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{"
@@ -2085,6 +2126,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, dhcpDisableBadParam) {
 // This test verifies if it is possible to disable DHCP service via command.
 TEST_F(CtrlChannelDhcpv4SrvTest, dhcpDisable) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{ \"command\": \"dhcp-disable\" }", response);
@@ -2169,6 +2211,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, dhcpDisable) {
 // the origin-id.
 TEST_F(CtrlChannelDhcpv4SrvTest, dhcpDisableOriginId) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     EXPECT_TRUE(server_->network_state_->isServiceEnabled());
@@ -2202,6 +2245,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, dhcpDisableOriginId) {
 // period of time, after which the service is automatically enabled.
 TEST_F(CtrlChannelDhcpv4SrvTest, dhcpDisableTemporarily) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // Send a command to disable DHCP service for 3 seconds.
@@ -2232,6 +2276,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, dhcpDisableTemporarily) {
 // parameters.
 TEST_F(CtrlChannelDhcpv4SrvTest, dhcpEnableBadParam) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
     ConstElementPtr rsp;
 
@@ -2293,6 +2338,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, dhcpEnableBadParam) {
 // This test verifies if it is possible to enable DHCP service via command.
 TEST_F(CtrlChannelDhcpv4SrvTest, dhcpEnable) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{ \"command\": \"dhcp-enable\" }", response);
@@ -2373,6 +2419,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, dhcpEnable) {
 // the origin-id.
 TEST_F(CtrlChannelDhcpv4SrvTest, dhcpEnableOriginId) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     ConstElementPtr rsp;
@@ -2427,6 +2474,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, dhcpEnableOriginId) {
 // This test verifies that subnet4-select-test command performs sanity check parameters.
 TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestBadParam) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
     ConstElementPtr rsp;
 
@@ -2700,6 +2748,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestBadParam) {
 // relay link select address.
 TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestRAILinkSelect) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
@@ -2751,6 +2800,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestRAILinkSelect) {
 // subnet select address.
 TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestSubnetSelect) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
@@ -2802,6 +2852,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestSubnetSelect) {
 // relay address.
 TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestRelayAddress) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
@@ -2854,6 +2905,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestRelayAddress) {
 // gateway address.
 TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestGateway) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
@@ -2905,6 +2957,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestGateway) {
 // client address.
 TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestClient) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
@@ -2956,6 +3009,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestClient) {
 // remote/source address.
 TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestRemote) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
@@ -3008,6 +3062,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestRemote) {
 TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestIface) {
     isc::dhcp::test::IfaceMgrTestConfig test_config(true);
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
@@ -3060,6 +3115,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestIface) {
 // This test verifies if subnet4-select-test command returns proper guarded subnet.
 TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestClass) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
@@ -3113,6 +3169,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestClass) {
 // This test verifies that subnet4o6-select-test command performs sanity check parameters.
 TEST_F(CtrlChannelDhcpv4SrvTest, subnet4o6SelectTestBadParam) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
     ConstElementPtr rsp;
 
@@ -3419,6 +3476,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, subnet4o6SelectTestBadParam) {
 // remote/source address.
 TEST_F(CtrlChannelDhcpv4SrvTest, subnet4o6SelectTestRemote) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
@@ -3471,6 +3529,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, subnet4o6SelectTestRemote) {
 // relay interface id.
 TEST_F(CtrlChannelDhcpv4SrvTest, subnet4o6SelectTestRelayInterfaceId) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
@@ -3526,6 +3585,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, subnet4o6SelectTestRelayInterfaceId) {
 // incoming interface.
 TEST_F(CtrlChannelDhcpv4SrvTest, subnet4o6SelectTestIface) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
@@ -3588,6 +3648,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, keaLfcStartNoBackend) {
 /// Verify that kea-lfc-start requires persist true.
 TEST_F(CtrlChannelDhcpv4SrvTest, keaLfcStartPersistFalse) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{ \"command\" : \"kea-lfc-start\" }", response);
@@ -3606,6 +3667,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, keaLfcStartPersistFalse) {
 /// connections.
 TEST_F(CtrlChannelDhcpv4SrvTest, concurrentConnections) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     boost::scoped_ptr<UnixControlClient> client1(new UnixControlClient());
     ASSERT_TRUE(client1);
@@ -3677,6 +3739,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, longCommand) {
     );
 
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     std::string response;
     std::thread th([this, &response, &command]() {
@@ -3735,6 +3798,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, longResponse) {
     );
 
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // The UnixControlClient doesn't have any means to check that the entire
     // response has been received. What we want to do is to generate a
@@ -3794,6 +3858,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, longResponse) {
 // takes too long, having received a partial command.
 TEST_F(CtrlChannelDhcpv4SrvTest, connectionTimeoutPartialCommand) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // Set connection timeout to 2s to prevent long waiting time for the
     // timeout during this test.
@@ -3848,6 +3913,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, connectionTimeoutPartialCommand) {
 // takes too long, having received no data from the client.
 TEST_F(CtrlChannelDhcpv4SrvTest, connectionTimeoutNoData) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // Set connection timeout to 2s to prevent long waiting time for the
     // timeout during this test.
index a1bba1580205e13b5ffa04429ee3475291f3794e..b386d402fd3cd202bde3a3a281f7d830d0665b05 100644 (file)
@@ -9,6 +9,7 @@
 #include <cc/command_interpreter.h>
 #include <cc/data.h>
 #include <cc/simple_parser.h>
+#include <config/testutils/socket_test.h>
 #include <dhcp/testutils/iface_mgr_test_config.h>
 #include <dhcp4/ctrl_dhcp4_srv.h>
 #include <dhcp4/dhcp4_srv.h>
@@ -30,6 +31,7 @@
 #include <gtest/gtest.h>
 
 using namespace isc::config;
+using namespace isc::config::test;
 using namespace isc::data;
 using namespace isc::dhcp;
 using namespace isc::dhcp::test;
@@ -14650,6 +14652,16 @@ public:
             if (comment_) {
                 reason = string(" (") + comment_->stringValue() + string(")");
             }
+
+            bool const too_long(SocketName::isTooLongFromConfig(json));
+            if (too_long) {
+                EXPECT_EQ(CONTROL_RESULT_ERROR, rcode_);
+                string const exp_error("name too long");
+                string const error(comment_->stringValue());
+                EXPECT_NE(std::string::npos, error.find(exp_error));
+                return (true);
+            }
+
             ADD_FAILURE() << "configure for " << operation
                           << " returned error code "
                           << rcode_ << reason << " on\n"
index 6db931d256d65a52d09411389643d19c935e62b0..635840fb7be6cb647030c7fb88776cdf5d7896da 100644 (file)
@@ -9,6 +9,7 @@
 #include <cc/command_interpreter.h>
 #include <cc/data.h>
 #include <cc/simple_parser.h>
+#include <config/testutils/socket_test.h>
 #include <dhcp/testutils/iface_mgr_test_config.h>
 #include <dhcp4/ctrl_dhcp4_srv.h>
 #include <dhcp4/dhcp4_srv.h>
@@ -30,6 +31,7 @@
 #include <gtest/gtest.h>
 
 using namespace isc::config;
+using namespace isc::config::test;
 using namespace isc::data;
 using namespace isc::dhcp;
 using namespace isc::dhcp::test;
@@ -248,6 +250,16 @@ public:
             if (comment_) {
                 reason = string(" (") + comment_->stringValue() + string(")");
             }
+
+            bool const too_long(SocketName::isTooLongFromConfig(json));
+            if (too_long) {
+                EXPECT_EQ(CONTROL_RESULT_ERROR, rcode_);
+                string const exp_error("name too long");
+                string const error(comment_->stringValue());
+                EXPECT_NE(std::string::npos, error.find(exp_error));
+                return (true);
+            }
+
             ADD_FAILURE() << "configure for " << operation
                           << " returned error code "
                           << rcode_ << reason << " on\n"
index 548c63fe92638b26be170acec0eb6ca0702b7c4f..a2e4b7081337865d9c1da0061e3cfe3170bf5022 100644 (file)
@@ -9,6 +9,7 @@
 #include <asiolink/addr_utilities.h>
 #include <cc/command_interpreter.h>
 #include <config/http_command_config.h>
+#include <config/testutils/socket_test.h>
 #include <dhcp/classify.h>
 #include <dhcp/docsis3_option_defs.h>
 #include <dhcp/iface_mgr.h>
@@ -60,6 +61,7 @@
 using namespace isc;
 using namespace isc::asiolink;
 using namespace isc::config;
+using namespace isc::config::test;
 using namespace isc::data;
 using namespace isc::dhcp;
 using namespace isc::dhcp::test;
@@ -495,12 +497,21 @@ public:
 
         int rcode;
         ConstElementPtr comment = parseAnswerText(rcode, status);
-        EXPECT_EQ(expected_code, rcode);
 
         string text;
         ASSERT_TRUE(comment);
         ASSERT_NO_THROW(text = comment->stringValue());
 
+        // Socket name too long?
+        bool const too_long(SocketName::isTooLongFromConfig(json));
+        if (too_long) {
+            EXPECT_EQ(CONTROL_RESULT_ERROR, rcode);
+            exp_error = "name too long";
+            EXPECT_NE(std::string::npos, text.find(exp_error));
+            return;
+        }
+
+        EXPECT_EQ(expected_code, rcode);
         if (expected_code != rcode) {
             std::cout << "Reported status: " << text << std::endl;
         }
@@ -7740,6 +7751,13 @@ TEST_F(Dhcp6ParserTest, comments) {
     ASSERT_TRUE(ctx_iface->get("comment"));
     EXPECT_EQ("\"Use wildcard\"", ctx_iface->get("comment")->str());
 
+    ConstElementPtr json;
+    ASSERT_NO_THROW_LOG(json = parseDHCP6(config, true));
+    bool const too_long(SocketName::isTooLongFromConfig(json));
+    if (too_long) {
+        return;
+    }
+
     // There is a global option definition.
     const OptionDefinitionPtr& opt_def =
         LibDHCP::getRuntimeOptionDef("isc", 100);
index a247071fe31cc2e4ad42d7a0723a4d565ee4cd5f..25619fd932e948bccc21393f2e94c4cc4a0418d7 100644 (file)
@@ -9,6 +9,7 @@
 #include <asiolink/io_address.h>
 #include <cc/command_interpreter.h>
 #include <config/command_mgr.h>
+#include <config/testutils/socket_test.h>
 #include <config/timeouts.h>
 #include <database/database_connection.h>
 #include <config/unix_command_mgr.h>
@@ -27,9 +28,9 @@
 #include <stats/stats_mgr.h>
 #include <util/multi_threading_mgr.h>
 #include <util/chrono_time_utils.h>
+#include <testutils/gtest_utils.h>
 #include <testutils/io_utils.h>
 #include <testutils/unix_control_client.h>
-#include <testutils/sandbox.h>
 
 #include "marker_file.h"
 
@@ -49,6 +50,7 @@ using namespace std;
 using namespace isc;
 using namespace isc::asiolink;
 using namespace isc::config;
+using namespace isc::config::test;
 using namespace isc::data;
 using namespace isc::db;
 using namespace isc::dhcp;
@@ -140,8 +142,6 @@ public:
 
 class CtrlChannelDhcpv6SrvTest : public CtrlDhcpv6SrvTest {
 public:
-    isc::test::Sandbox sandbox;
-
     /// @brief Path to the UNIX socket being used to communicate with the server
     std::string socket_path_;
 
@@ -154,10 +154,13 @@ public:
     /// @brief Asynchronous timer service to detect timeouts.
     IntervalTimerPtr test_timer_;
 
+    /// @brief Whether the current test was skipped.
+    bool skipped_;
+
     /// @brief Default constructor
     ///
     /// Sets socket path to its default value.
-    CtrlChannelDhcpv6SrvTest() : interfaces_("\"*\"") {
+    CtrlChannelDhcpv6SrvTest() : interfaces_("\"*\""), skipped_(false) {
         reset();
         IfaceMgr::instance().setTestMode(false);
         IfaceMgr::instance().setDetectCallback(std::bind(&IfaceMgr::checkDetectIfaces,
@@ -273,6 +276,13 @@ public:
 
         int status = 0;
         ConstElementPtr txt = isc::config::parseAnswer(status, answer);
+
+        bool const too_long(SocketName::isTooLong(socket_path_));
+        if (too_long) {
+            skipped_ = true;
+            SKIP_IF("Socket name too long.");
+        }
+
         // This should succeed. If not, print the error message.
         ASSERT_EQ(0, status) << txt->str();
 
@@ -575,6 +585,7 @@ TEST_F(CtrlDhcpv6SrvTest, commandsRegistration) {
 // via ControlChannel
 TEST_F(CtrlChannelDhcpv6SrvTest, controlChannelNegative) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{ \"command\": \"bogus\" }", response);
@@ -591,6 +602,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, controlChannelNegative) {
 // via ControlChannel
 TEST_F(CtrlChannelDhcpv6SrvTest, controlChannelShutdown) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{ \"command\": \"shutdown\" }", response);
@@ -603,6 +615,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, controlChannelShutdown) {
 // test of Dhcpv6 statistics.
 TEST_F(CtrlChannelDhcpv6SrvTest, controlChannelStats) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // Check statistic-get
@@ -734,6 +747,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, controlChannelStats) {
 TEST_F(CtrlChannelDhcpv6SrvTest, configSet) {
     setLogTestPath("/dev");
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // Define strings to permutate the config arguments
     // (Note the line feeds makes errors easy to find)
@@ -918,6 +932,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configSet) {
 TEST_F(CtrlChannelDhcpv6SrvTest, configSetLFCRunning) {
     setLogTestPath("/dev");
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // Define strings to permutate the config arguments
     // (Note the line feeds makes errors easy to find)
@@ -1074,6 +1089,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configSetLFCRunning) {
 // config-get handler are actually converting the configuration correctly.
 TEST_F(CtrlChannelDhcpv6SrvTest, configGet) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{ \"command\": \"config-get\" }", response);
@@ -1098,6 +1114,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configGet) {
 // config-hash-get.
 TEST_F(CtrlChannelDhcpv6SrvTest, configHashGet) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{ \"command\": \"config-hash-get\" }", response);
@@ -1129,6 +1146,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configHashGet) {
 TEST_F(CtrlChannelDhcpv6SrvTest, configTest) {
     setLogTestPath("/dev");
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // Define strings to permutate the config arguments
     // (Note the line feeds makes errors easy to find)
@@ -1278,6 +1296,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configTest) {
 // Verify that the "subnet6-select-test" command will do what we expect.
 TEST_F(CtrlChannelDhcpv6SrvTest, subnetSelectTest) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     string command_txt = "{ \"command\": \"subnet6-select-test\", \"arguments\": { \"classes\": [ \"foo\" ] } }";
 
@@ -1292,6 +1311,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, subnetSelectTest) {
 // This test verifies that the DHCP server handles version-get commands
 TEST_F(CtrlChannelDhcpv6SrvTest, getVersion) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     std::string response;
 
@@ -1310,6 +1330,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, getVersion) {
 // This test verifies that the DHCP server handles server-tag-get command
 TEST_F(CtrlChannelDhcpv6SrvTest, serverTagGet) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     std::string response;
     std::string expected;
@@ -1331,6 +1352,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, serverTagGet) {
 // This test verifies that the DHCP server handles status-get commands
 TEST_F(CtrlChannelDhcpv6SrvTest, statusGet) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // start_ is initialized by init.
     ASSERT_THROW(server_->init("/no/such/file"), BadValue);
@@ -1446,6 +1468,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, statusGet) {
 TEST_F(CtrlChannelDhcpv6SrvTest, noManagers) {
     // Send the status-get command.
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     LeaseMgrFactory::destroy();
     HostMgr::create();
     string response_text;
@@ -1470,6 +1493,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, statusGetSockets) {
 
     // Send the status-get command.
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     string response_text;
     sendUnixCommand(R"({ "command": "status-get" })", response_text);
     ConstElementPtr response;
@@ -1508,6 +1532,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, statusGetSocketsErrors) {
 
     // Send the status-get command.
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     string response_text;
     sendUnixCommand(R"({ "command": "status-get" })", response_text);
     ConstElementPtr response;
@@ -1545,6 +1570,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, statusGetSocketsErrors) {
 // This test verifies that the DHCP server handles config-backend-pull command
 TEST_F(CtrlChannelDhcpv6SrvTest, configBackendPull) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     std::string response;
     std::string expected;
@@ -1559,6 +1585,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configBackendPull) {
 // leases on leases-reclaim command
 TEST_F(CtrlChannelDhcpv6SrvTest, controlLeasesReclaim) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // Create expired leases. Leases are expired by 40 seconds ago
     // (valid lifetime = 60, cltt = now - 100).
@@ -1621,6 +1648,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, controlLeasesReclaim) {
 // leases on leases-reclaim command with remove = true
 TEST_F(CtrlChannelDhcpv6SrvTest, controlLeasesReclaimRemove) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // Create expired leases. Leases are expired by 40 seconds ago
     // (valid lifetime = 60, cltt = now - 100).
@@ -1664,6 +1692,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, controlLeasesReclaimRemove) {
 // via ControlChannel
 TEST_F(CtrlChannelDhcpv6SrvTest, listCommands) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{ \"command\": \"list-commands\" }", response);
@@ -1702,6 +1731,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, listCommands) {
 // Tests if config-write can be called without any parameters.
 TEST_F(CtrlChannelDhcpv6SrvTest, configWriteNoFilename) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set by the command line -c parameter.
@@ -1718,6 +1748,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configWriteNoFilename) {
 // Tests if config-write can be called with a valid filename as parameter.
 TEST_F(CtrlChannelDhcpv6SrvTest, configWriteFilename) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set by the command line -c parameter.
@@ -1733,6 +1764,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configWriteFilename) {
 // Tests if config-write can be called with a valid full path as parameter.
 TEST_F(CtrlChannelDhcpv6SrvTest, configWriteFullPath) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set by the command line -c parameter.
@@ -1748,6 +1780,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configWriteFullPath) {
 // Tests if config-write raises an error with invalid path as parameter.
 TEST_F(CtrlChannelDhcpv6SrvTest, configWriteBadPath) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set by the command line -c parameter.
@@ -1766,6 +1799,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configWriteBadPath) {
 // Tests if config-write raises an error with invalid full path as parameter.
 TEST_F(CtrlChannelDhcpv6SrvTest, configWriteBadFullPath) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set by the command line -c parameter.
@@ -1785,6 +1819,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configWriteBadFullPath) {
 // file is missing.
 TEST_F(CtrlChannelDhcpv6SrvTest, configReloadMissingFile) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set to whatever value is passed to -c when the server is
@@ -1806,6 +1841,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configReloadMissingFile) {
 // file is not a valid JSON.
 TEST_F(CtrlChannelDhcpv6SrvTest, configReloadBrokenFile) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set to whatever value is passed to -c when the server is
@@ -1833,6 +1869,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configReloadBrokenFile) {
 // Check that the "config-reload" fails when LFC is running.
 TEST_F(CtrlChannelDhcpv6SrvTest, configReloadLFCRunning) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set to whatever value is passed to -c when the server is
@@ -1888,6 +1925,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configReloadLFCRunning) {
 // file is loaded correctly.
 TEST_F(CtrlChannelDhcpv6SrvTest, configReloadValid) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set to whatever value is passed to -c when the server is
@@ -1950,6 +1988,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configReloadDetectInterfaces) {
     IfaceMgr::instance().closeSockets();
     IfaceMgr::instance().detectIfaces();
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // This is normally set to whatever value is passed to -c when the server is
@@ -2009,6 +2048,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configReloadDetectInterfaces) {
 // parameters.
 TEST_F(CtrlChannelDhcpv6SrvTest, dhcpDisableBadParam) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{"
@@ -2084,6 +2124,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, dhcpDisableBadParam) {
 // This test verifies if it is possible to disable DHCP service via command.
 TEST_F(CtrlChannelDhcpv6SrvTest, dhcpDisable) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{ \"command\": \"dhcp-disable\" }", response);
@@ -2168,6 +2209,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, dhcpDisable) {
 // the origin-id.
 TEST_F(CtrlChannelDhcpv6SrvTest, dhcpDisableOriginId) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     EXPECT_TRUE(server_->network_state_->isServiceEnabled());
@@ -2201,6 +2243,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, dhcpDisableOriginId) {
 // period of time, after which the service is automatically enabled.
 TEST_F(CtrlChannelDhcpv6SrvTest, dhcpDisableTemporarily) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     // Send a command to disable DHCP service for 3 seconds.
@@ -2231,6 +2274,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, dhcpDisableTemporarily) {
 // parameters.
 TEST_F(CtrlChannelDhcpv6SrvTest, dhcpEnableBadParam) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
     ConstElementPtr rsp;
 
@@ -2292,6 +2336,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, dhcpEnableBadParam) {
 // This test verifies if it is possible to enable DHCP service via command.
 TEST_F(CtrlChannelDhcpv6SrvTest, dhcpEnable) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{ \"command\": \"dhcp-enable\" }", response);
@@ -2372,6 +2417,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, dhcpEnable) {
 // the origin-id.
 TEST_F(CtrlChannelDhcpv6SrvTest, dhcpEnableOriginId) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     ConstElementPtr rsp;
@@ -2426,6 +2472,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, dhcpEnableOriginId) {
 // This test verifies that subnet6-select-test command performs sanity check parameters.
 TEST_F(CtrlChannelDhcpv6SrvTest, subnet6SelectTestBadParam) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
     ConstElementPtr rsp;
 
@@ -2596,6 +2643,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, subnet6SelectTestBadParam) {
 // remote/source address.
 TEST_F(CtrlChannelDhcpv6SrvTest, subnet6SelectTestAddr) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     auto subnet = Subnet6::create(IOAddress("2001:db8:1::"),
@@ -2647,6 +2695,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, subnet6SelectTestAddr) {
 // incoming interface.
 TEST_F(CtrlChannelDhcpv6SrvTest, subnet6SelectTestIface) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     auto subnet = Subnet6::create(IOAddress("2001:db8:1::"),
@@ -2699,6 +2748,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, subnet6SelectTestIface) {
 // relay link address.
 TEST_F(CtrlChannelDhcpv6SrvTest, subnet6SelectTestRelayLinkaddr) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     auto subnet = Subnet6::create(IOAddress("2001:db8:1::"),
@@ -2750,6 +2800,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, subnet6SelectTestRelayLinkaddr) {
 // relay interface id.
 TEST_F(CtrlChannelDhcpv6SrvTest, subnet6SelectTestRelayInterfaceId) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     auto subnet = Subnet6::create(IOAddress("2001:db8:1::"),
@@ -2809,6 +2860,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, subnet6SelectTestRelayInterfaceId) {
 // This test verifies if subnet6-select-test command returns proper guarded subnet.
 TEST_F(CtrlChannelDhcpv6SrvTest, subnet6SelectTestClass) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     auto subnet = Subnet6::create(IOAddress("2001:db8:1::"),
@@ -2873,6 +2925,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, keaLfcStartNoBackend) {
 /// Verify that kea-lfc-start requires persist true.
 TEST_F(CtrlChannelDhcpv6SrvTest, keaLfcStartPersistFalse) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
     std::string response;
 
     sendUnixCommand("{ \"command\" : \"kea-lfc-start\" }", response);
@@ -2891,6 +2944,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, keaLfcStartPersistFalse) {
 /// connections.
 TEST_F(CtrlChannelDhcpv6SrvTest, concurrentConnections) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     boost::scoped_ptr<UnixControlClient> client1(new UnixControlClient());
     ASSERT_TRUE(client1);
@@ -2962,6 +3016,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, longCommand) {
     );
 
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     std::string response;
     std::thread th([this, &response, &command]() {
@@ -3020,6 +3075,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, longResponse) {
     );
 
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // The UnixControlClient doesn't have any means to check that the entire
     // response has been received. What we want to do is to generate a
@@ -3079,6 +3135,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, longResponse) {
 // takes too long, having received a partial command.
 TEST_F(CtrlChannelDhcpv6SrvTest, connectionTimeoutPartialCommand) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // Set connection timeout to 2s to prevent long waiting time for the
     // timeout during this test.
@@ -3133,6 +3190,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, connectionTimeoutPartialCommand) {
 // takes too long, having received no data from the client.
 TEST_F(CtrlChannelDhcpv6SrvTest, connectionTimeoutNoData) {
     createUnixChannelServer();
+    SKIP_IF(skipped_);
 
     // Set connection timeout to 2s to prevent long waiting time for the
     // timeout during this test.
index 2bc46be15b6327bb1f4d785af0f545aa426ab13c..5ac1b56c22abd986ed594002c981c99d0d1ecb36 100644 (file)
@@ -9,6 +9,7 @@
 #include <cc/command_interpreter.h>
 #include <cc/data.h>
 #include <cc/simple_parser.h>
+#include <config/testutils/socket_test.h>
 #include <dhcp/testutils/iface_mgr_test_config.h>
 #include <dhcp6/ctrl_dhcp6_srv.h>
 #include <dhcp6/dhcp6_srv.h>
@@ -30,6 +31,7 @@
 #include <gtest/gtest.h>
 
 using namespace isc::config;
+using namespace isc::config::test;
 using namespace isc::data;
 using namespace isc::dhcp;
 using namespace isc::dhcp::test;
@@ -14968,6 +14970,16 @@ public:
             if (comment_) {
                 reason = string(" (") + comment_->stringValue() + string(")");
             }
+
+            bool const too_long(SocketName::isTooLongFromConfig(json));
+            if (too_long) {
+                EXPECT_EQ(CONTROL_RESULT_ERROR, rcode_);
+                string const exp_error("name too long");
+                string const error(comment_->stringValue());
+                EXPECT_NE(std::string::npos, error.find(exp_error));
+                return (true);
+            }
+
             ADD_FAILURE() << "configure for " << operation
                           << " returned error code "
                           << rcode_ << reason << " on\n"
index ac7fd8182ba7c1ded9c50bc7165dfa741eec8664..6753aa21427414d5e203360538e0f40726ab1430 100644 (file)
@@ -9,6 +9,7 @@
 #include <cc/command_interpreter.h>
 #include <cc/data.h>
 #include <cc/simple_parser.h>
+#include <config/testutils/socket_test.h>
 #include <dhcp/testutils/iface_mgr_test_config.h>
 #include <dhcp6/ctrl_dhcp6_srv.h>
 #include <dhcp6/dhcp6_srv.h>
@@ -30,6 +31,7 @@
 #include <gtest/gtest.h>
 
 using namespace isc::config;
+using namespace isc::config::test;
 using namespace isc::data;
 using namespace isc::dhcp;
 using namespace isc::dhcp::test;
@@ -248,6 +250,17 @@ public:
             if (comment_) {
                 reason = string(" (") + comment_->stringValue() + string(")");
             }
+
+            bool const too_long(SocketName::isTooLongFromConfig(json));
+            if (too_long) {
+                EXPECT_EQ(CONTROL_RESULT_ERROR, rcode_);
+
+                string const exp_error("name too long");
+                string const error(comment_->stringValue());
+                EXPECT_NE(std::string::npos, error.find(exp_error));
+                return (true);
+            }
+
             ADD_FAILURE() << "configure for " << operation
                           << " returned error code "
                           << rcode_ << reason << " on\n"
index b40efcaeb69122d8580156740235be8e9654b5b8..3b8a736c0ffb61c9a19d2c8b3accc3fa75e5b7cc 100644 (file)
@@ -9,6 +9,7 @@
 #include <asiolink/asio_wrapper.h>
 #include <asiolink/interval_timer.h>
 #include <asiolink/io_service.h>
+#include <config/testutils/socket_test.h>
 #include <config/unix_command_config.h>
 #include <http/listener.h>
 #include <http/post_request_json.h>
@@ -34,6 +35,7 @@ using namespace isc;
 using namespace isc::netconf;
 using namespace isc::asiolink;
 using namespace isc::config;
+using namespace isc::config::test;
 using namespace isc::data;
 using namespace isc::http;
 using namespace isc::http::test;
@@ -321,6 +323,8 @@ TEST_F(UnixControlSocketTest, createControlSocket) {
 
 // Verifies that unix control sockets handle configGet() as expected.
 TEST_F(UnixControlSocketTest, configGet) {
+    bool const socket_name_too_long(SocketName::isTooLong(unixSocketFilePath()));
+    SKIP_IF(socket_name_too_long);
     CfgControlSocketPtr cfg = createCfgControlSocket();
     ASSERT_TRUE(cfg);
     UnixControlSocketPtr ucs(new UnixControlSocket(cfg));
@@ -345,6 +349,8 @@ TEST_F(UnixControlSocketTest, configGet) {
 
 // Verifies that unix control sockets handle configTest() as expected.
 TEST_F(UnixControlSocketTest, configTest) {
+    bool const socket_name_too_long(SocketName::isTooLong(unixSocketFilePath()));
+    SKIP_IF(socket_name_too_long);
     CfgControlSocketPtr cfg = createCfgControlSocket();
     ASSERT_TRUE(cfg);
     UnixControlSocketPtr ucs(new UnixControlSocket(cfg));
@@ -372,6 +378,8 @@ TEST_F(UnixControlSocketTest, configTest) {
 
 // Verifies that unix control sockets handle configSet() as expected.
 TEST_F(UnixControlSocketTest, configSet) {
+    bool const socket_name_too_long(SocketName::isTooLong(unixSocketFilePath()));
+    SKIP_IF(socket_name_too_long);
     CfgControlSocketPtr cfg = createCfgControlSocket();
     ASSERT_TRUE(cfg);
     UnixControlSocketPtr ucs(new UnixControlSocket(cfg));
@@ -399,6 +407,8 @@ TEST_F(UnixControlSocketTest, configSet) {
 
 // Verifies that unix control sockets handle timeouts.
 TEST_F(UnixControlSocketTest, timeout) {
+    bool const socket_name_too_long(SocketName::isTooLong(unixSocketFilePath()));
+    SKIP_IF(socket_name_too_long);
     CfgControlSocketPtr cfg = createCfgControlSocket();
     ASSERT_TRUE(cfg);
     UnixControlSocketPtr ucs(new UnixControlSocket(cfg));
index 59f10a7d0d3b481b11cf50f25c6eaa6406af069a..ead96913b53f99b52013f81d14302f66576dd04a 100644 (file)
@@ -11,6 +11,7 @@
 #include <asiolink/io_service.h>
 #include <cc/command_interpreter.h>
 #include <config/unix_command_config.h>
+#include <config/testutils/socket_test.h>
 #include <netconf/netconf.h>
 #include <netconf/netconf_process.h>
 #include <netconf/parser_context.h>
@@ -39,6 +40,7 @@ using namespace isc;
 using namespace isc::netconf;
 using namespace isc::asiolink;
 using namespace isc::config;
+using namespace isc::config::test;
 using namespace isc::data;
 using namespace isc::http;
 using namespace isc::test;
@@ -587,6 +589,10 @@ TEST_F(NetconfAgentLogTest, logChanges2) {
 
 // Verifies that the keaConfig method works as expected.
 TEST_F(NetconfAgentTest, keaConfig) {
+    string const socket_path(unixSocketFilePath());
+    bool const socket_name_too_long(SocketName::isTooLong(socket_path));
+    SKIP_IF(socket_name_too_long);
+
     // Netconf configuration.
     string config_prefix = "{\n"
         "  \"Netconf\": {\n"
@@ -601,7 +607,7 @@ TEST_F(NetconfAgentTest, keaConfig) {
         "    }\n"
         "  }\n"
         "}";
-    string config = config_prefix + unixSocketFilePath() + config_trailer;
+    string config = config_prefix + socket_path + config_trailer;
     NetconfConfigPtr ctx(new NetconfConfig());
     ElementPtr json;
     ParserContext parser_context;
@@ -668,6 +674,10 @@ TEST_F(NetconfAgentTest, keaConfig) {
 // Verifies that the yangConfig method works as expected: apply YANG config
 // to the server.
 TEST_F(NetconfAgentTest, yangConfig) {
+    string const socket_path(unixSocketFilePath());
+    bool const socket_name_too_long(SocketName::isTooLong(socket_path));
+    SKIP_IF(socket_name_too_long);
+
     // YANG configuration.
     const YRTree tree = YangRepr::buildTreeFromVector({
         { "/kea-dhcp4-server:config/subnet4[id='1']/id",
@@ -698,7 +708,7 @@ TEST_F(NetconfAgentTest, yangConfig) {
         "    }\n"
         "  }\n"
         "}";
-    string config = config_prefix + unixSocketFilePath() + config_trailer;
+    string config = config_prefix + socket_path + config_trailer;
     NetconfConfigPtr ctx(new NetconfConfig());
     ElementPtr json;
     ParserContext parser_context;
@@ -776,6 +786,10 @@ TEST_F(NetconfAgentTest, yangConfig) {
 
 // Verifies that the subscribeToDataChanges method works as expected.
 TEST_F(NetconfAgentTest, subscribeToDataChanges) {
+    string const socket_path(unixSocketFilePath());
+    bool const socket_name_too_long(SocketName::isTooLong(socket_path));
+    SKIP_IF(socket_name_too_long);
+
     // Netconf configuration.
     string config_prefix = "{\n"
         "  \"Netconf\": {\n"
@@ -790,7 +804,7 @@ TEST_F(NetconfAgentTest, subscribeToDataChanges) {
         "    }\n"
         "  }\n"
         "}";
-    string config = config_prefix + unixSocketFilePath() + config_trailer;
+    string config = config_prefix + socket_path + config_trailer;
     NetconfConfigPtr ctx(new NetconfConfig());
     ElementPtr json;
     ParserContext parser_context;
@@ -827,6 +841,10 @@ TEST_F(NetconfAgentTest, subscribeToDataChanges) {
 // Verifies that the update method works as expected: apply new YANG configuration
 // to the server. Note it is called by the subscription callback.
 TEST_F(NetconfAgentTest, update) {
+    string const socket_path(unixSocketFilePath());
+    bool const socket_name_too_long(SocketName::isTooLong(socket_path));
+    SKIP_IF(socket_name_too_long);
+
     // Initial YANG configuration.
     const YRTree tree0 = YangRepr::buildTreeFromVector({
         { "/kea-dhcp4-server:config/subnet4[id='1']/id",
@@ -859,7 +877,7 @@ TEST_F(NetconfAgentTest, update) {
         "    }\n"
         "  }\n"
         "}";
-    string config = config_prefix + unixSocketFilePath() + config_trailer;
+    string config = config_prefix + socket_path + config_trailer;
     NetconfConfigPtr ctx(new NetconfConfig());
     ElementPtr json;
     ParserContext parser_context;
@@ -954,6 +972,10 @@ TEST_F(NetconfAgentTest, update) {
 // with the server. Note it is called by the subscription callback and
 // update is called after.
 TEST_F(NetconfAgentTest, validate) {
+    string const socket_path(unixSocketFilePath());
+    bool const socket_name_too_long(SocketName::isTooLong(socket_path));
+    SKIP_IF(socket_name_too_long);
+
     // Initial YANG configuration.
     const YRTree tree0 = YangRepr::buildTreeFromVector({
         { "/kea-dhcp4-server:config/subnet4[id='1']/id",
@@ -984,7 +1006,7 @@ TEST_F(NetconfAgentTest, validate) {
         "    }\n"
         "  }\n"
         "}";
-    string config = config_prefix + unixSocketFilePath() + config_trailer;
+    string config = config_prefix + socket_path + config_trailer;
     NetconfConfigPtr ctx(new NetconfConfig());
     ElementPtr json;
     ParserContext parser_context;
@@ -1116,6 +1138,10 @@ TEST_F(NetconfAgentTest, validate) {
 
 // Verifies what happens when the validate method returns an error.
 TEST_F(NetconfAgentTest, noValidate) {
+    string const socket_path(unixSocketFilePath());
+    bool const socket_name_too_long(SocketName::isTooLong(socket_path));
+    SKIP_IF(socket_name_too_long);
+
     // Initial YANG configuration.
     const YRTree tree0 = YangRepr::buildTreeFromVector({
         { "/kea-dhcp4-server:config/subnet4[id='1']/id",
@@ -1142,7 +1168,7 @@ TEST_F(NetconfAgentTest, noValidate) {
         "    }\n"
         "  }\n"
         "}";
-    string config = config_prefix + unixSocketFilePath() + config_trailer;
+    string config = config_prefix + socket_path + config_trailer;
     NetconfConfigPtr ctx(new NetconfConfig());
     ElementPtr json;
     ParserContext parser_context;
index 59d2b9da52fe2874fab0b831bd8acff9adff67cd..218df576089bdeed393fd2b21dc763cc2ac7c871 100644 (file)
@@ -7,6 +7,7 @@
 #include <config.h>
 
 #include <config/command_mgr.h>
+#include <config/testutils/socket_test.h>
 #include <config/unix_command_config.h>
 #include <http/basic_auth_config.h>
 #include <util/filesystem.h>
@@ -18,6 +19,7 @@
 using namespace isc;
 using namespace isc::asiolink;
 using namespace isc::config;
+using namespace isc::config::test;
 using namespace isc::data;
 using namespace isc::dhcp;
 using namespace isc::http;
index 36276a55e2662dbf3522daa1531cb42337513af6..fbcb9629ee67778dda8de9d3c6d75090fc33811b 100644 (file)
@@ -6,18 +6,21 @@
 
 #include <config.h>
 
-#include <gtest/gtest.h>
-
-#include <testutils/sandbox.h>
 #include <asiolink/io_service.h>
 #include <cc/dhcp_config_error.h>
 #include <config/command_mgr.h>
+#include <config/testutils/socket_test.h>
 #include <config/unix_command_mgr.h>
+#include <testutils/gtest_utils.h>
 #include <util/filesystem.h>
+
 #include <string>
 
+#include <gtest/gtest.h>
+
 using namespace isc::asiolink;
 using namespace isc::config;
+using namespace isc::config::test;
 using namespace isc::data;
 using namespace isc::dhcp;
 using namespace isc::util;
@@ -26,8 +29,6 @@ using namespace std;
 // Test class for Unix Command Manager
 class UnixCommandMgrTest : public ::testing::Test {
 public:
-    isc::test::Sandbox sandbox;
-
     /// Default constructor
     UnixCommandMgrTest() : io_service_(new IOService()) {
         resetSocketPath();
@@ -86,6 +87,15 @@ TEST_F(UnixCommandMgrTest, unixCreate) {
                  DhcpConfigError);
 
     socket_info->set("socket-name", Element::create("test_socket"));
+
+    bool const too_long(SocketName::isTooLong("test_socket"));
+    if (too_long) {
+        // "File name too long"
+        EXPECT_THROW(UnixCommandMgr::instance().openCommandSocket(socket_info), SocketError);
+        EXPECT_EQ(UnixCommandMgr::instance().getControlSocketFD(), -1);
+        return;
+    }
+
     EXPECT_NO_THROW(UnixCommandMgr::instance().openCommandSocket(socket_info));
     EXPECT_GE(UnixCommandMgr::instance().getControlSocketFD(), 0);
 
@@ -116,6 +126,14 @@ TEST_F(UnixCommandMgrTest, exclusiveOpen) {
     socket_info->set("socket-type", Element::create("unix"));
     socket_info->set("socket-name", Element::create("test_socket"));
 
+    bool const too_long(SocketName::isTooLong("test_socket"));
+    if (too_long) {
+        // "File name too long"
+        EXPECT_THROW(UnixCommandMgr::instance().openCommandSocket(socket_info), SocketError);
+        EXPECT_EQ(UnixCommandMgr::instance().getControlSocketFD(), -1);
+        return;
+    }
+
     EXPECT_NO_THROW(UnixCommandMgr::instance().openCommandSocket(socket_info));
     EXPECT_GE(UnixCommandMgr::instance().getControlSocketFD(), 0);
     int fd = UnixCommandMgr::instance().getControlSocketFD();
diff --git a/src/lib/config/testutils/socket_test.h b/src/lib/config/testutils/socket_test.h
new file mode 100644 (file)
index 0000000..55d983b
--- /dev/null
@@ -0,0 +1,84 @@
+// Copyright (C) 2021-2025 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef ISC_CONFIG_TESTUTILS_SOCKET_TEST_H
+#define ISC_CONFIG_TESTUTILS_SOCKET_TEST_H
+
+#include <asiolink/asio_wrapper.h>
+#include <asiolink/unix_domain_socket_endpoint.h>
+#include <cc/data.h>
+#include <config/unix_command_config.h>
+#include <exceptions/exceptions.h>
+
+#include <exception>
+#include <string>
+
+namespace isc {
+namespace config {
+namespace test {
+
+/// @brief Struct exists only to avoid ODR violation of inline functions.
+struct SocketName {
+    /// @brief Check if socket name is too long.
+    ///
+    /// @param socket_name Socket name
+    ///
+    /// @return whether the socket name is too long
+    static bool isTooLong(std::string const& socket_name) {
+        try {
+            std::string const validated_socket_name(UnixCommandConfig::validatePath(socket_name));
+            isc::asiolink::UnixDomainSocketEndpoint endpoint(validated_socket_name);
+        } catch (std::exception const& e) {
+            // Check if it starts with it.
+            std::string const search_for("name too long");
+            if (std::string::npos != std::string(e.what()).find(search_for)) {
+                return true;
+            }
+            // Alternative:
+            // std::unordered_set<std::string> expected_errors {
+            //     "File name too long",  // on some Linuxes: Debian, RHEL, Ubuntu
+            //     "File name too long [system:36]",  // on some Linuxes: Arch, Fedora
+            //     "File name too long [system:63]",  // on BSD
+            //     "Filename too long [system:36]",  // on some Linuxes: Alpine
+            // };
+            // return (expected_errors.count(e.what()));
+        }
+        return false;
+    }
+
+    /// @brief Takes socket information from config and checks if its name is too long.
+    ///
+    /// @param config config without the top level entry
+    ///
+    /// @return whether the socket name is too long
+    static bool isTooLongFromConfig(isc::data::ConstElementPtr const& config) {
+        using isc::data::ConstElementPtr;
+        using isc::data::Element;
+
+        // Socket name too long?
+        ConstElementPtr control_sockets(config->get("control-sockets"));
+        bool too_long(false);
+        if (control_sockets) {
+            for (ConstElementPtr control_socket : control_sockets->listValue()) {
+                ConstElementPtr socket_name(control_socket->get("socket-name"));
+                ConstElementPtr socket_type(control_socket->get("socket-type"));
+                if (socket_name && socket_name->getType() == Element::string && socket_type &&
+                    socket_type->getType() == Element::string &&
+                    socket_type->stringValue() == "unix") {
+                    std::string const name(socket_name->stringValue());
+                    too_long |= isTooLong(name);
+                }
+            }
+        }
+        return too_long;
+    }
+};
+
+}  // namespace test
+}  // namespace config
+}  // namespace isc
+
+#endif  // ISC_CONFIG_TESTUTILS_SOCKET_TEST_H