return (controller_ptr);
}
- virtual ~NakedD2Controller() { deregisterCommands(); }
+ virtual ~NakedD2Controller() {
+ deregisterCommands();
+ }
using DControllerBase::getIOService;
using DControllerBase::initProcess;
NakedD2Controller() { }
};
-}; // namespace isc::d2
-}; // namespace isc
+} // namespace isc::d2
+} // namespace isc
namespace {
/// @brief Returns pointer to the server's IO service.
///
/// @return Pointer to the server's IO service or null pointer if the
- /// hasn't been created server.
+ /// server hasn't been created.
IOServicePtr getIOService() {
return (server_ ? d2Controller()->getIOService() : IOServicePtr());
}
/// @brief Check if the answer for config-write command is correct.
///
- /// @param response_txt response in text form.
- /// (as read from the control socket)
- /// @param exp_status expected status.
- /// (0 success, 1 failure)
+ /// @param response_txt response in text form (as read from
+ /// the control socket).
+ /// @param exp_status expected status (0 success, 1 failure).
/// @param exp_txt for success cases this defines the expected filename,
- /// for failure cases this defines the expected error message.
+ /// for failure cases this defines the expected error message.
void checkConfigWrite(const string& response_txt, int exp_status,
const string& exp_txt = "") {
EXPECT_EQ(77, server_->getExitValue());
}
-// This test verifies that the DHCP server handles version-get commands.
+// This test verifies that the D2 server handles version-get commands.
TEST_F(CtrlChannelD2Test, getversion) {
EXPECT_NO_THROW(createUnixChannelServer());
string response;
checkListCommands(rsp, "version-get");
}
-// This test verifies that the D2 server handles status-get commands
+// This test verifies that the D2 server handles status-get commands.
TEST_F(CtrlChannelD2Test, statusGet) {
EXPECT_NO_THROW(createUnixChannelServer());
std::string response_txt;
- // Send the version-get command
+ // Send the status-get command.
sendUnixCommand("{ \"command\": \"status-get\" }", response_txt);
ConstElementPtr response;
ASSERT_NO_THROW(response = Element::fromJSON(response_txt));
ASSERT_GT(CommandMgr::instance().getControlSocketFD(), -1);
- // Create a config with malformed subnet that should fail to parse.
+ // Create a config with invalid content that should fail to parse.
os.str("");
os << config_test_txt << ","
<< args_txt
ASSERT_GT(CommandMgr::instance().getControlSocketFD(), -1);
- // Create a config with malformed subnet that should fail to parse.
+ // Create a config with invalid content that should fail to parse.
os.str("");
os << config_set_txt << ","
<< args_txt
sendUnixCommand("{ \"command\": \"config-write\", "
"\"arguments\": { \"filename\": \"test2.json\" } }",
response);
+
checkConfigWrite(response, CONTROL_RESULT_SUCCESS, "test2.json");
::remove("test2.json");
}
// Tell the server to reload its configuration. It should attempt to load
// testbad.json (and fail, because the file is not valid JSON).
- // does-not-exist.json (and fail, because the file is not there).
sendUnixCommand("{ \"command\": \"config-reload\" }", response);
// Verify the reload was rejected.
}
// Tests if config-reload attempts to reload a file and reports that the
-// file is missing.
+// file is loaded correctly.
TEST_F(CtrlChannelD2Test, configReloadFileValid) {
EXPECT_NO_THROW(createUnixChannelServer());
string response;
return (controller_ptr);
}
- virtual ~NakedD2Controller() { deregisterCommands(); }
+ virtual ~NakedD2Controller() {
+ deregisterCommands();
+ }
using DControllerBase::getIOService;
using DControllerBase::initProcess;
NakedD2Controller() { }
};
-}; // namespace isc::d2
-}; // namespace isc
+} // namespace isc::d2
+} // namespace isc
namespace {
/// @brief Returns pointer to the server's IO service.
///
/// @return Pointer to the server's IO service or null pointer if the
- /// hasn't been created server.
+ /// server hasn't been created.
IOServicePtr getIOService() {
return (server_ ? d2Controller()->getIOService() : IOServicePtr());
}
/// @param response_str a string containing the whole HTTP
/// response received.
///
- /// @return An HttpResponse constructed from by parsing the
- /// response string.
+ /// @return An HttpResponse constructed by parsing the response string.
HttpResponsePtr parseResponse(const std::string response_str) {
HttpResponsePtr hr(new HttpResponse());
HttpResponseParser parser(*hr);
/// @brief Parse list answer.
///
/// Clone of parseAnswer but taking the answer as a list and
- /// decapulating it.
+ /// decapsulating it.
///
/// @param rcode Return code.
/// @param msg_list The message to parse.
/// @brief Check if the answer for config-write command is correct.
///
- /// @param response_txt response in text form.
- /// (as read from the control socket)
- /// @param exp_status expected status.
- /// (0 success, 1 failure)
+ /// @param response_txt response in text form (as read from
+ /// the control socket).
+ /// @param exp_status expected status (0 success, 1 failure).
/// @param exp_txt for success cases this defines the expected filename,
- /// for failure cases this defines the expected error message.
+ /// for failure cases this defines the expected error message.
void checkConfigWrite(const string& response_txt, int exp_status,
const string& exp_txt = "") {
// let's parse expected_command back to JSON to guarantee that
// both structures are built using the same order.
EXPECT_EQ(Element::fromJSON(expected_command)->str(),
- entire_command->str());
+ entire_command->str());
return (createAnswer(CONTROL_RESULT_SUCCESS, "long command received ok"));
}
EXPECT_EQ(77, server_->getExitValue());
}
-// This test verifies that the DHCP server handles version-get commands.
+// This test verifies that the D2 server handles version-get commands.
TEST_F(HttpCtrlChannelD2Test, getversion) {
EXPECT_NO_THROW(createHttpChannelServer());
string response;
checkListCommands(rsp, "version-get");
}
-// This test verifies that the D2 server handles status-get commands
+// This test verifies that the D2 server handles status-get commands.
TEST_F(HttpCtrlChannelD2Test, statusGet) {
EXPECT_NO_THROW(createHttpChannelServer());
std::string response_txt;
- // Send the version-get command
+ // Send the status-get command.
sendHttpCommand("{ \"command\": \"status-get\" }", response_txt);
ConstElementPtr response_list;
ASSERT_NO_THROW(response_list = Element::fromJSON(response_txt));
int status;
ConstElementPtr args = parseListAnswer(status, rsp);
EXPECT_EQ(CONTROL_RESULT_SUCCESS, status);
- // the parseListAnswer is trying to be smart with ignoring hash.
+ // The parseListAnswer is trying to be smart with ignoring hash.
// But this time we really want to see the hash, so we'll retrieve
// the arguments manually.
ASSERT_NO_THROW(args = rsp->get(0)->get(CONTROL_ARGUMENTS));
ASSERT_TRUE(HttpCommandMgr::instance().getHttpListener());
- // Create a config with malformed subnet that should fail to parse.
+ // Create a config with invalid content that should fail to parse.
string config_test_txt =
"{ \"command\": \"config-test\", \n"
" \"arguments\": { \n"
ASSERT_TRUE(HttpCommandMgr::instance().getHttpListener());
- // Create a config with malformed subnet that should fail to parse.
+ // Create a config with invalid content that should fail to parse.
string config_test_txt =
"{ \"command\": \"config-set\", \n"
" \"arguments\": { \n"
sendHttpCommand("{ \"command\": \"config-write\", "
"\"arguments\": { \"filename\": \"test2.json\" } }",
response);
+
checkConfigWrite(response, CONTROL_RESULT_SUCCESS, "test2.json");
::remove("test2.json");
}
// Tell the server to reload its configuration. It should attempt to load
// testbad.json (and fail, because the file is not valid JSON).
- // does-not-exist.json (and fail, because the file is not there).
sendHttpCommand("{ \"command\": \"config-reload\" }", response);
// Verify the reload was rejected.
}
// Tests if config-reload attempts to reload a file and reports that the
-// file is missing.
+// file is loaded correctly.
TEST_F(HttpCtrlChannelD2Test, configReloadFileValid) {
EXPECT_NO_THROW(createHttpChannelServer());
string response;
createHttpChannelServer();
- // The entire response should be received but anayway check it.
+ // The entire response should be received but anyway check it.
ConstElementPtr raw_response =
longResponseHandler("foo", ConstElementPtr());
ElementPtr json_response = Element::createList();
///
/// This method connects to the given server over the given socket path.
/// If successful, it then sends the given command and retrieves the
- /// server's response. Note that it calls the server's receivePacket()
- /// method where needed to cause the server to process IO events on
- /// control channel the control channel sockets.
+ /// server's response. Note that it polls the server's I/O service
+ /// where needed to cause the server to process IO events on
+ /// the control channel sockets.
///
/// @param command the command text to execute in JSON form
/// @param response variable into which the received response should be
"v4-lease-reuses",
};
- // preparing the schema which check if all statistics are set to zero
std::ostringstream s;
s << "{ \"arguments\": { ";
bool first = true;
ASSERT_FALSE(lease1);
}
-// Tests that the server properly responds to shutdown command sent
+// Tests that the server properly responds to list-commands command sent
// via ControlChannel
TEST_F(CtrlChannelDhcpv4SrvTest, listCommands) {
createUnixChannelServer();
/// @param response_str a string containing the whole HTTP
/// response received.
///
- /// @return An HttpResponse constructed from by parsing the
- /// response string.
+ /// @return An HttpResponse constructed from parsing the response string.
HttpResponsePtr parseResponse(const std::string response_str) {
HttpResponsePtr hr(new HttpResponse());
HttpResponseParser parser(*hr);
return (hr);
}
- /// @brief Conducts a command/response exchange via HttpCommandSocket
+ /// @brief Conducts a command/response exchange via HttpCommandSocket.
///
/// This method connects to the given server over the given address/port.
/// If successful, it then sends the given command and retrieves the
- /// server's response. Note that it calls the server's receivePacket()
- /// method where needed to cause the server to process IO events on
- /// control channel the control channel sockets.
+ /// server's response. Note that it polls the server's I/O service
+ /// where needed to cause the server to process IO events on
+ /// the control channel sockets.
///
/// @param command the command text to execute in JSON form.
/// @param response variable into which the received response should be
ASSERT_TRUE(client);
// Send the command. This will trigger server's handler which receives
- // data over the unix domain socket. The server will start sending
+ // data over the HTTP socket. The server will start sending
// response to the client.
ASSERT_NO_THROW(client->startRequest(buildPostStr(command)));
runIOService();
/// @brief Parse list answer.
///
/// Clone of parseAnswer but taking the answer as a list and
- /// decapulating it.
+ /// decapsulating it.
///
/// @param rcode Return code.
/// @param msg_list The message to parse.
return (msg->get(CONTROL_TEXT));
}
- /// @brief Checks response for list-commands
+ /// @brief Checks response for list-commands.
///
/// This method checks if the list-commands response is generally sane
/// and whether specified command is mentioned in the response.
///
- /// @param rsp response sent back by the server
+ /// @param rsp response sent back by the server.
/// @param command command expected to be on the list.
void checkListCommands(const ConstElementPtr& rsp, const std::string& command) {
ConstElementPtr params;
for (size_t i = 0; i < params->size(); ++i) {
string tmp = params->get(i)->stringValue();
if (tmp == command) {
- // Command found, but that's not enough. Need to continue working
- // through the list to see if there are no duplicates.
+ // Command found, but that's not enough.
+ // Need to continue working through the list to see
+ // if there are no duplicates.
cnt++;
}
}
EXPECT_EQ(1, cnt) << "Command " << command << " not found";
}
- /// @brief Check if the answer for write-config command is correct
+ /// @brief Check if the answer for write-config command is correct.
///
/// @param response_txt response in text form (as read from the control socket)
/// @param exp_status expected status (0 success, 1 failure)
/// This handler generates a large response (over 4kB). It includes
/// a list of randomly generated strings to make sure that the test
/// can catch out of order delivery.
- static ConstElementPtr longResponseHandler(const std::string&,
- const ConstElementPtr&) {
+ static ConstElementPtr
+ longResponseHandler(const std::string&, const ConstElementPtr&) {
ElementPtr arguments = Element::createList();
for (unsigned i = 0; i < 800; ++i) { // was 80000 (400kB).
std::ostringstream s;
sendHttpCommand("{ \"command\": \"shutdown\" }", response);
EXPECT_EQ("[ { \"result\": 0, \"text\": \"Shutting down.\" } ]",
response);
+
+ EXPECT_EQ(EXIT_SUCCESS, server_->getExitValue());
}
// Tests that the server properly responds to statistics commands. Note this
"v4-lease-reuses",
};
- // preparing the schema which check if all statistics are set to zero
std::ostringstream s;
s << "[ { \"arguments\": { ";
bool first = true;
int status;
ConstElementPtr args = parseListAnswer(status, rsp);
EXPECT_EQ(CONTROL_RESULT_SUCCESS, status);
- // the parseListAnswer is trying to be smart with ignoring hash.
+ // The parseListAnswer is trying to be smart with ignoring hash.
// But this time we really want to see the hash, so we'll retrieve
// the arguments manually.
args = rsp->get(0)->get(CONTROL_ARGUMENTS);
// Clean up after the test.
CfgMgr::instance().clear();
}
+
// This test verifies that the DHCP server handles version-get commands
TEST_F(HttpCtrlChannelDhcpv4Test, getVersion) {
createHttpChannelServer();
ASSERT_FALSE(lease1);
}
-// Tests that the server properly responds to shutdown command sent
+// Tests that the server properly responds to list-commands command sent
// via ControlChannel
TEST_F(HttpCtrlChannelDhcpv4Test, listCommands) {
createHttpChannelServer();
createHttpChannelServer();
- // The entire response should be received but anayway check it.
+ // The entire response should be received but anyway check it.
ConstElementPtr raw_response =
longResponseHandler("foo", ConstElementPtr());
ElementPtr json_response = Element::createList();
///
/// This method connects to the given server over the given socket path.
/// If successful, it then sends the given command and retrieves the
- /// server's response. Note that it calls the server's receivePacket()
- /// method where needed to cause the server to process IO events on
- /// control channel the control channel sockets.
+ /// server's response. Note that it polls the server's I/O service
+ /// where needed to cause the server to process IO events on
+ /// the control channel sockets.
///
/// @param command the command text to execute in JSON form
/// @param response variable into which the received response should be
response);
}
-// Tests that the server properly responds to shutdown command sent
+// Tests that the server properly responds to list-commands command sent
// via ControlChannel
TEST_F(CtrlChannelDhcpv6SrvTest, listCommands) {
createUnixChannelServer();
// Get rid of any marker files.
static_cast<void>(remove(LOAD_MARKER_FILE));
static_cast<void>(remove(UNLOAD_MARKER_FILE));
+
IfaceMgr::instance().deleteAllExternalSockets();
CfgMgr::instance().clear();
}
HttpCommandMgr::instance().close();
}
CommandMgr::instance().deregisterAll();
- CommandMgr::instance().setConnectionTimeout(TIMEOUT_DHCP_SERVER_RECEIVE_COMMAND);
+ HttpCommandMgr::instance().setConnectionTimeout(TIMEOUT_DHCP_SERVER_RECEIVE_COMMAND);
server_.reset();
reset();
/// @param response_str a string containing the whole HTTP
/// response received.
///
- /// @return An HttpResponse constructed from by parsing the
- /// response string.
+ /// @return An HttpResponse constructed by parsing the response string.
HttpResponsePtr parseResponse(const std::string response_str) {
HttpResponsePtr hr(new HttpResponse());
HttpResponseParser parser(*hr);
return (hr);
}
- /// @brief Conducts a command/response exchange via HttpCommandSocket
+ /// @brief Conducts a command/response exchange via HttpCommandSocket.
///
/// This method connects to the given server over the given address/port.
/// If successful, it then sends the given command and retrieves the
- /// server's response. Note that it calls the server's receivePacket()
- /// method where needed to cause the server to process IO events on
- /// control channel the control channel sockets.
+ /// server's response. Note that it polls the server's I/O service
+ /// where needed to cause the server to process IO events on
+ /// the control channel sockets.
///
/// @param command the command text to execute in JSON form.
/// @param response variable into which the received response should be
ASSERT_TRUE(client);
// Send the command. This will trigger server's handler which receives
- // data over the unix domain socket. The server will start sending
+ // data over the HTTP domain socket. The server will start sending
// response to the client.
ASSERT_NO_THROW(client->startRequest(buildPostStr(command)));
runIOService();
/// @brief Parse list answer.
///
/// Clone of parseAnswer but taking the answer as a list and
- /// decapulating it.
+ /// decapsulating it.
///
/// @param rcode Return code.
/// @param msg_list The message to parse.
return (msg->get(CONTROL_TEXT));
}
- /// @brief Checks response for list-commands
+ /// @brief Checks response for list-commands.
///
/// This method checks if the list-commands response is generally sane
/// and whether specified command is mentioned in the response.
///
- /// @param rsp response sent back by the server
+ /// @param rsp response sent back by the server.
/// @param command command expected to be on the list.
void checkListCommands(const ConstElementPtr& rsp, const std::string& command) {
ConstElementPtr params;
for (size_t i = 0; i < params->size(); ++i) {
string tmp = params->get(i)->stringValue();
if (tmp == command) {
- // Command found, but that's not enough. Need to continue working
- // through the list to see if there are no duplicates.
+ // Command found, but that's not enough.
+ // Need to continue working through the list to see
+ // if there are no duplicates.
cnt++;
}
}
EXPECT_EQ(1, cnt) << "Command " << command << " not found";
}
- /// @brief Check if the answer for write-config command is correct
+ /// @brief Check if the answer for write-config command is correct.
///
/// @param response_txt response in text form (as read from the control socket)
/// @param exp_status expected status (0 success, 1 failure)
/// This handler generates a large response (over 4kB). It includes
/// a list of randomly generated strings to make sure that the test
/// can catch out of order delivery.
- static ConstElementPtr longResponseHandler(const std::string&,
- const ConstElementPtr&) {
+ static ConstElementPtr
+ longResponseHandler(const std::string&, const ConstElementPtr&) {
ElementPtr arguments = Element::createList();
for (unsigned i = 0; i < 800; ++i) { // was 80000 (400kB).
std::ostringstream s;
std::string response;
sendHttpCommand("{ \"command\": \"shutdown\" }", response);
- EXPECT_EQ("[ { \"result\": 0, \"text\": \"Shutting down.\" } ]",response);
+ EXPECT_EQ("[ { \"result\": 0, \"text\": \"Shutting down.\" } ]", response);
+
+ EXPECT_EQ(EXIT_SUCCESS, server_->getExitValue());
}
// Check that the "config-set" command will replace current configuration
// Send the config-set command
std::string response;
sendHttpCommand(os.str(), response);
-
EXPECT_EQ("[ { \"arguments\": { \"hash\": \"BCE3D0CC68CBBB49C3F5967E3FFCB4E44E55CBFB53814761B12ADB5C7CD95C1F\" }, \"result\": 0, \"text\": \"Configuration successful.\" } ]",
response);
ASSERT_NO_THROW(HttpCommandMgr::instance().garbageCollectListeners());
EXPECT_FALSE(HttpCommandMgr::instance().getHttpListener());
+ // With no command channel, should still receive the response.
EXPECT_EQ("[ { \"arguments\": { \"hash\": \"48035E8F9CC25FC1F6175B78CCC6B8A673CACBA9E956C0ED3079C478BF1F2D1A\" }, \"result\": 0, \"text\": \"Configuration successful.\" } ]",
response);
response);
}
-// Tests that the server properly responds to shutdown command sent
+// Tests that the server properly responds to list-commands command sent
// via ControlChannel
TEST_F(HttpCtrlChannelDhcpv6Test, listCommands) {
createHttpChannelServer();
std::string response;
sendHttpCommand("{ \"command\": \"config-write\", "
- "\"arguments\": { \"filename\": \"test2.json\" } }", response);
+ "\"arguments\": { \"filename\": \"test2.json\" } }",
+ response);
checkConfigWrite(response, CONTROL_RESULT_SUCCESS, "test2.json");
::remove("test2.json");
EXPECT_EQ("[ { \"arguments\": { \"hash\": \"2D97C398AFE8414A818D9F04C9ADB62D493861EDD3689015D081880D6A85A3C3\" }, \"result\": 0, \"text\": \"Configuration successful.\" } ]",
response);
- EXPECT_NE(response.find("\"result\": 0"), std::string::npos);
- EXPECT_NE(response.find("\"text\": \"Configuration successful.\""), std::string::npos);
// Check that the config was indeed applied.
const Subnet6Collection* subnets =
createHttpChannelServer();
- // The entire response should be received but anayway check it.
+ // The entire response should be received but anyway check it.
ConstElementPtr raw_response =
longResponseHandler("foo", ConstElementPtr());
ElementPtr json_response = Element::createList();
/// @param response_str a string containing the whole HTTP
/// response received.
///
- /// @return An HttpResponse constructed from by parsing the
- /// response string.
+ /// @return An HttpResponse constructed by parsing the response string.
HttpResponsePtr parseResponse(const std::string response_str) {
HttpResponsePtr hr(new HttpResponse());
HttpResponseParser parser(*hr);
/// @param response_str a string containing the whole HTTP
/// response received.
///
- /// @return An HttpResponse constructed from by parsing the
- /// response string.
+ /// @return An HttpResponse constructed by parsing the response string.
HttpResponsePtr parseResponse(const std::string response_str) {
HttpResponsePtr hr(new HttpResponse());
HttpResponseParser parser(*hr);
/// @brief Sets information about the UNIX control socket
///
- /// @param ontrol_socket UNIX control socket config
+ /// @param control_socket UNIX control socket config
void setControlSocketInfo(const isc::data::ConstElementPtr& control_socket) {
unix_control_socket_ = control_socket;
}