// 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;
/// 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();
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.
/// @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);
}
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);
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
/// 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);
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,
/// 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(),
TEST_F(CtrlAgentCommandMgrTest, forwardListCommands) {
// Configure client side socket.
configureControlSocket("dhcp4");
+ SKIP_IF(skipped_);
// Create server side socket.
bindServerSocket("{ \"result\" : 3 }", true);
#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;
/// @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_;
/// @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);
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();
// 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);
// 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);
// 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);
// to shutdown command.
TEST_F(CtrlChannelD2Test, shutdownExitValue) {
EXPECT_NO_THROW(createUnixChannelServer());
+ SKIP_IF(skipped_);
string response;
sendUnixCommand("{ \"command\": \"shutdown\", "
// 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.
// 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);
// 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;
// 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);
// config-hash-get.
TEST_F(CtrlChannelD2Test, configHashGet) {
EXPECT_NO_THROW(createUnixChannelServer());
+ SKIP_IF(skipped_);
string response;
sendUnixCommand("{ \"command\": \"config-hash-get\" }", response);
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:
<< "}}";
// 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\" }",
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:
<< "}}";
// 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"
// 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.
// 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.
// 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.
// 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.
// 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.
// 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
// 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
// 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
/// 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);
);
createUnixChannelServer();
+ SKIP_IF(skipped_);
string response;
std::thread th([this, &response, &command]() {
);
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
// 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.
// 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.
#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>
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;
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;
}
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);
#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>
#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"
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;
/// @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_;
/// @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();
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();
// via ControlChannel
TEST_F(CtrlChannelDhcpv4SrvTest, controlChannelNegative) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
sendUnixCommand("{ \"command\": \"bogus\" }", response);
// via ControlChannel
TEST_F(CtrlChannelDhcpv4SrvTest, controlChannelShutdown) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
sendUnixCommand("{ \"command\": \"shutdown\" }", response);
// test of Dhcpv4 statistics.
TEST_F(CtrlChannelDhcpv4SrvTest, controlChannelStats) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
// Check statistic-get
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)
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)
// 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);
// config-hash-get.
TEST_F(CtrlChannelDhcpv4SrvTest, configHashGet) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
sendUnixCommand("{ \"command\": \"config-hash-get\" }", response);
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)
// 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\" ] } }";
// 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\" ] } }";
// This test verifies that the DHCP server handles version-get commands
TEST_F(CtrlChannelDhcpv4SrvTest, getVersion) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
// 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;
// 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);
TEST_F(CtrlChannelDhcpv4SrvTest, noManagers) {
// Send the status-get command.
createUnixChannelServer();
+ SKIP_IF(skipped_);
LeaseMgrFactory::destroy();
HostMgr::create();
string response_text;
// Send the status-get command.
createUnixChannelServer();
+ SKIP_IF(skipped_);
string response_text;
sendUnixCommand(R"({ "command": "status-get" })", response_text);
ConstElementPtr response;
// Send the status-get command.
createUnixChannelServer();
+ SKIP_IF(skipped_);
string response_text;
sendUnixCommand(R"({ "command": "status-get" })", response_text);
ConstElementPtr response;
// 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;
// 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).
// 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).
// via ControlChannel
TEST_F(CtrlChannelDhcpv4SrvTest, listCommands) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
sendUnixCommand("{ \"command\": \"list-commands\" }", response);
// 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.
// 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.
// 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.
// 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.
// 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.
// 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
// 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
// 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
// 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
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
// parameters.
TEST_F(CtrlChannelDhcpv4SrvTest, dhcpDisableBadParam) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
sendUnixCommand("{"
// 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);
// the origin-id.
TEST_F(CtrlChannelDhcpv4SrvTest, dhcpDisableOriginId) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
EXPECT_TRUE(server_->network_state_->isServiceEnabled());
// 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.
// parameters.
TEST_F(CtrlChannelDhcpv4SrvTest, dhcpEnableBadParam) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
ConstElementPtr rsp;
// 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);
// the origin-id.
TEST_F(CtrlChannelDhcpv4SrvTest, dhcpEnableOriginId) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
ConstElementPtr rsp;
// 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;
// relay link select address.
TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestRAILinkSelect) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
// subnet select address.
TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestSubnetSelect) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
// relay address.
TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestRelayAddress) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
// gateway address.
TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestGateway) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
// client address.
TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestClient) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
// remote/source address.
TEST_F(CtrlChannelDhcpv4SrvTest, subnet4SelectTestRemote) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
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"),
// 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"),
// 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;
// remote/source address.
TEST_F(CtrlChannelDhcpv4SrvTest, subnet4o6SelectTestRemote) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
// relay interface id.
TEST_F(CtrlChannelDhcpv4SrvTest, subnet4o6SelectTestRelayInterfaceId) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
// incoming interface.
TEST_F(CtrlChannelDhcpv4SrvTest, subnet4o6SelectTestIface) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
auto subnet = Subnet4::create(IOAddress("192.0.2.0"),
/// 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);
/// connections.
TEST_F(CtrlChannelDhcpv4SrvTest, concurrentConnections) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
boost::scoped_ptr<UnixControlClient> client1(new UnixControlClient());
ASSERT_TRUE(client1);
);
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
std::thread th([this, &response, &command]() {
);
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
// 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.
// 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.
#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>
#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;
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"
#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>
#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;
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"
#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>
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;
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;
}
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);
#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>
#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"
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;
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_;
/// @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,
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();
// via ControlChannel
TEST_F(CtrlChannelDhcpv6SrvTest, controlChannelNegative) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
sendUnixCommand("{ \"command\": \"bogus\" }", response);
// via ControlChannel
TEST_F(CtrlChannelDhcpv6SrvTest, controlChannelShutdown) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
sendUnixCommand("{ \"command\": \"shutdown\" }", response);
// test of Dhcpv6 statistics.
TEST_F(CtrlChannelDhcpv6SrvTest, controlChannelStats) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
// Check statistic-get
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)
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)
// 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);
// config-hash-get.
TEST_F(CtrlChannelDhcpv6SrvTest, configHashGet) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
sendUnixCommand("{ \"command\": \"config-hash-get\" }", response);
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)
// 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\" ] } }";
// This test verifies that the DHCP server handles version-get commands
TEST_F(CtrlChannelDhcpv6SrvTest, getVersion) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
// 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;
// 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);
TEST_F(CtrlChannelDhcpv6SrvTest, noManagers) {
// Send the status-get command.
createUnixChannelServer();
+ SKIP_IF(skipped_);
LeaseMgrFactory::destroy();
HostMgr::create();
string response_text;
// Send the status-get command.
createUnixChannelServer();
+ SKIP_IF(skipped_);
string response_text;
sendUnixCommand(R"({ "command": "status-get" })", response_text);
ConstElementPtr response;
// Send the status-get command.
createUnixChannelServer();
+ SKIP_IF(skipped_);
string response_text;
sendUnixCommand(R"({ "command": "status-get" })", response_text);
ConstElementPtr response;
// 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;
// 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).
// 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).
// via ControlChannel
TEST_F(CtrlChannelDhcpv6SrvTest, listCommands) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
sendUnixCommand("{ \"command\": \"list-commands\" }", response);
// 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.
// 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.
// 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.
// 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.
// 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.
// 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
// 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
// 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
// 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
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
// parameters.
TEST_F(CtrlChannelDhcpv6SrvTest, dhcpDisableBadParam) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
sendUnixCommand("{"
// 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);
// the origin-id.
TEST_F(CtrlChannelDhcpv6SrvTest, dhcpDisableOriginId) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
EXPECT_TRUE(server_->network_state_->isServiceEnabled());
// 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.
// parameters.
TEST_F(CtrlChannelDhcpv6SrvTest, dhcpEnableBadParam) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
ConstElementPtr rsp;
// 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);
// the origin-id.
TEST_F(CtrlChannelDhcpv6SrvTest, dhcpEnableOriginId) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
ConstElementPtr rsp;
// 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;
// remote/source address.
TEST_F(CtrlChannelDhcpv6SrvTest, subnet6SelectTestAddr) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
auto subnet = Subnet6::create(IOAddress("2001:db8:1::"),
// incoming interface.
TEST_F(CtrlChannelDhcpv6SrvTest, subnet6SelectTestIface) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
auto subnet = Subnet6::create(IOAddress("2001:db8:1::"),
// relay link address.
TEST_F(CtrlChannelDhcpv6SrvTest, subnet6SelectTestRelayLinkaddr) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
auto subnet = Subnet6::create(IOAddress("2001:db8:1::"),
// relay interface id.
TEST_F(CtrlChannelDhcpv6SrvTest, subnet6SelectTestRelayInterfaceId) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
auto subnet = Subnet6::create(IOAddress("2001:db8:1::"),
// 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::"),
/// 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);
/// connections.
TEST_F(CtrlChannelDhcpv6SrvTest, concurrentConnections) {
createUnixChannelServer();
+ SKIP_IF(skipped_);
boost::scoped_ptr<UnixControlClient> client1(new UnixControlClient());
ASSERT_TRUE(client1);
);
createUnixChannelServer();
+ SKIP_IF(skipped_);
std::string response;
std::thread th([this, &response, &command]() {
);
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
// 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.
// 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.
#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>
#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;
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"
#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>
#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;
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"
#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>
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;
// 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));
// 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));
// 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));
// 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));
#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>
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;
// 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"
" }\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;
// 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",
" }\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;
// 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"
" }\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;
// 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",
" }\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;
// 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",
" }\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;
// 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",
" }\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;
#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>
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;
#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;
// Test class for Unix Command Manager
class UnixCommandMgrTest : public ::testing::Test {
public:
- isc::test::Sandbox sandbox;
-
/// Default constructor
UnixCommandMgrTest() : io_service_(new IOService()) {
resetSocketPath();
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);
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();
--- /dev/null
+// 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