diff options
author | Thomas Markwalder <tmark@isc.org> | 2020-02-28 22:04:28 +0100 |
---|---|---|
committer | Thomas Markwalder <tmark@isc.org> | 2020-03-04 12:59:52 +0100 |
commit | 17580ffc984d264181e177b9d86edfa518f09066 (patch) | |
tree | 4314315f9c4fdfa6757b48cfcee17c99025b33a3 /src/bin | |
parent | [#1088] updated ChangeLog (diff) | |
download | kea-17580ffc984d264181e177b9d86edfa518f09066.tar.xz kea-17580ffc984d264181e177b9d86edfa518f09066.zip |
[#1115] shutdown command exit-value arg, exit w/failure on db loss
Added exit-value argument to shutdown command.
kea-dhcpX servers now exit with EXIT_FAILURE status on db loss
src/lib/process/daemon.*
Daemon::exit_value_, new member with getter/setter
src/lib/process/d_controller.*
DControllerBase::launch() - now returns getExitValue()
DControllerBase::shutdownHandler() - uses exit-value argument to set exit
value
src/lib/process/tests/daemon_unittest.cc
TEST_F(DaemonTest, exitValue) - new test
src/bin/agent/main.cc
Use launch() return value for exit value.
src/bin/agent/tests/ca_controller_unittests.cc
TEST_F(CtrlAgentControllerTest, shutdownExitValue) - new test
src/bin/d2/main.cc
Use launch() return value for exit value.
src/bin/d2/tests/d2_command_unittest.cc
TEST_F(CtrlChannelD2Test, shutdownExitValue) - new test
src/bin/dhcp4/ctrl_dhcp4_srv.*
ControlledDhcpv4Srv::
commandShutdownHandler() - handle exit-value argument
shutdown(int exit_value) - added exit_value parameter
dbReconnect() - call shutdown(EXIT_FAILURE)
dbLostCallback() - call shutdown(EXIT_FAILURE)
src/bin/dhcp4/dhcp4_srv.*
Dhcp4Srv::run() - returns int Daemon::exit_value instead of bool
src/bin/dhcp4/main.cc
Use run() return value for exit value.
src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc
TEST_F(CtrlChannelDhcpv4SrvTest, commands) - revamped test
src/bin/dhcp6/ctrl_dhcp6_srv.*
ControlledDhcpv6Srv::
commandShutdownHandler() - use exit-value argument to set exit value
shutdown(int exit_value) - added exit_value parameter
dbReconnect() - call shutdown(EXIT_FAILURE)
dbLostCallback() - call shutdown(EXIT_FAILURE)
src/bin/dhcp6/dhcp6_srv.*
Dhcp6Srv::run() - returns int Daemon::exit_value instead of bool
src/bin/dhcp6/main.cc
Use run() return value for exit value.
src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc
TEST_F(CtrlDhcpv6SrvTest, commands) - revamped test
Diffstat (limited to 'src/bin')
-rw-r--r-- | src/bin/agent/main.cc | 2 | ||||
-rw-r--r-- | src/bin/agent/tests/ca_controller_unittests.cc | 52 | ||||
-rw-r--r-- | src/bin/d2/main.cc | 2 | ||||
-rw-r--r-- | src/bin/d2/tests/d2_command_unittest.cc | 21 | ||||
-rw-r--r-- | src/bin/dhcp4/ctrl_dhcp4_srv.cc | 49 | ||||
-rw-r--r-- | src/bin/dhcp4/ctrl_dhcp4_srv.h | 3 | ||||
-rw-r--r-- | src/bin/dhcp4/dhcp4_srv.cc | 4 | ||||
-rw-r--r-- | src/bin/dhcp4/dhcp4_srv.h | 5 | ||||
-rw-r--r-- | src/bin/dhcp4/main.cc | 2 | ||||
-rw-r--r-- | src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc | 12 | ||||
-rw-r--r-- | src/bin/dhcp6/ctrl_dhcp6_srv.cc | 46 | ||||
-rw-r--r-- | src/bin/dhcp6/ctrl_dhcp6_srv.h | 3 | ||||
-rw-r--r-- | src/bin/dhcp6/dhcp6_srv.cc | 4 | ||||
-rw-r--r-- | src/bin/dhcp6/dhcp6_srv.h | 4 | ||||
-rw-r--r-- | src/bin/dhcp6/main.cc | 2 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc | 12 |
16 files changed, 167 insertions, 56 deletions
diff --git a/src/bin/agent/main.cc b/src/bin/agent/main.cc index be43065b29..42117e5c3a 100644 --- a/src/bin/agent/main.cc +++ b/src/bin/agent/main.cc @@ -23,7 +23,7 @@ int main(int argc, char* argv[]) { DControllerBasePtr& controller = CtrlAgentController::instance(); // 'false' value disables test mode. - controller->launch(argc, argv, false); + ret = controller->launch(argc, argv, false); } catch (const VersionMessage& ex) { std::string msg(ex.what()); if (!msg.empty()) { diff --git a/src/bin/agent/tests/ca_controller_unittests.cc b/src/bin/agent/tests/ca_controller_unittests.cc index dcda359c97..0c084daf9a 100644 --- a/src/bin/agent/tests/ca_controller_unittests.cc +++ b/src/bin/agent/tests/ca_controller_unittests.cc @@ -697,4 +697,56 @@ TEST_F(CtrlAgentControllerTest, statusGet) { EXPECT_GE(found_reload->intValue(), 0); } +TEST_F(CtrlAgentControllerTest, shutdownExitValue) { + ASSERT_NO_THROW(initProcess()); + EXPECT_TRUE(checkProcess()); + + // The framework available makes it very difficult to test the actual + // code as CtrlAgentController is not initialized the same way it is + // in production code. In particular, the way CtrlAgentController + // is initialized in tests does not call registerCommands(). + // This is a crude workaround for this problem. Proper solution should + // be developed sooner rather than later. + const DControllerBasePtr& base = getController(); + const CtrlAgentControllerPtr& ctrl + = boost::dynamic_pointer_cast<CtrlAgentController>(base); + ASSERT_TRUE(ctrl); + // Now clean up after ourselves. + ctrl->registerCommands(); + + // This is normally set to whatever value is passed to -c when the server is + // started, but we're not starting it that way, so need to set it by hand. + getController()->setConfigFile("testvalid.json"); + + // Ok, enough fooling around. Let's create a valid config. + ofstream f("testvalid.json", ios::trunc); + f << "{ \"Control-agent\": " + << string(valid_agent_config) + << " }" << endl; + f.close(); + + // Build and execute the command. + + ConstElementPtr cmd = Element::fromJSON("{ \"command\": \"shutdown\"}"); + ConstElementPtr params = Element::fromJSON("{ \"exit-value\": 77 }"); + ConstElementPtr answer; + answer = CtrlAgentCommandMgr::instance().handleCommand("shutdown", + params, cmd); + + // Verify the reload was successful. + string expected = "[ { \"result\": 0, \"text\": " + "\"Control Agent is shutting down\" } ]"; + + EXPECT_EQ(expected, answer->str()); + + int exit_value = ctrl->getExitValue(); + EXPECT_EQ(77, exit_value); + + // Remove the file. + ::remove("testvalid.json"); + + // Now clean up after ourselves. + ctrl->deregisterCommands(); +} + } diff --git a/src/bin/d2/main.cc b/src/bin/d2/main.cc index 7eb704467b..1f896fcb83 100644 --- a/src/bin/d2/main.cc +++ b/src/bin/d2/main.cc @@ -32,7 +32,7 @@ int main(int argc, char* argv[]) { DControllerBasePtr& controller = D2Controller::instance(); // 'false' value disables test mode. - controller->launch(argc, argv, false); + ret = controller->launch(argc, argv, false); } catch (const VersionMessage& ex) { std::string msg(ex.what()); if (!msg.empty()) { diff --git a/src/bin/d2/tests/d2_command_unittest.cc b/src/bin/d2/tests/d2_command_unittest.cc index c6690d75e2..e0eceafacb 100644 --- a/src/bin/d2/tests/d2_command_unittest.cc +++ b/src/bin/d2/tests/d2_command_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2018-2020 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 @@ -565,7 +565,7 @@ TEST_F(CtrlChannelD2Test, invalid) { response); } -// Tests that the server properly responds to shtudown command. +// Tests that the server properly responds to shutdown command. TEST_F(CtrlChannelD2Test, shutdown) { EXPECT_NO_THROW(createUnixChannelServer()); string response; @@ -573,6 +573,23 @@ TEST_F(CtrlChannelD2Test, shutdown) { sendUnixCommand("{ \"command\": \"shutdown\" }", response); EXPECT_EQ("{ \"result\": 0, \"text\": \"Shutdown initiated, type is: normal\" }", response); + EXPECT_EQ(EXIT_SUCCESS, server_->getExitValue()); +} + +// Tests that the server sets exit value supplied as argument +// to shutdown command. +TEST_F(CtrlChannelD2Test, shutdownExitValue) { + EXPECT_NO_THROW(createUnixChannelServer()); + string response; + + sendUnixCommand("{ \"command\": \"shutdown\", " + "\"arguments\": { \"exit-value\": 77 }}" + , response); + + EXPECT_EQ("{ \"result\": 0, \"text\": \"Shutdown initiated, type is: normal\" }", + response); + + EXPECT_EQ(77, server_->getExitValue()); } // This test verifies that the DHCP server handles version-get commands. diff --git a/src/bin/dhcp4/ctrl_dhcp4_srv.cc b/src/bin/dhcp4/ctrl_dhcp4_srv.cc index 2b298dfbf6..8e00344e7a 100644 --- a/src/bin/dhcp4/ctrl_dhcp4_srv.cc +++ b/src/bin/dhcp4/ctrl_dhcp4_srv.cc @@ -202,17 +202,32 @@ ControlledDhcpv4Srv::loadConfigFile(const std::string& file_name) { } ConstElementPtr -ControlledDhcpv4Srv::commandShutdownHandler(const string&, ConstElementPtr) { - if (ControlledDhcpv4Srv::getInstance()) { - ControlledDhcpv4Srv::getInstance()->shutdown(); - } else { +ControlledDhcpv4Srv::commandShutdownHandler(const string&, ConstElementPtr args) { + if (!ControlledDhcpv4Srv::getInstance()) { LOG_WARN(dhcp4_logger, DHCP4_NOT_RUNNING); - ConstElementPtr answer = isc::config::createAnswer(1, - "Shutdown failure."); - return (answer); + return(createAnswer(CONTROL_RESULT_ERROR, "Shutdown failure.")); } - ConstElementPtr answer = isc::config::createAnswer(0, "Shutting down."); - return (answer); + + int exit_value = 0; + if (args) { + // @todo Should we go ahead and shutdown even if the args are invalid? + if (args->getType() != Element::map) { + return (createAnswer(CONTROL_RESULT_ERROR, "Argument must be a map")); + } + + ConstElementPtr param = args->get("exit-value"); + if (param) { + if (param->getType() != Element::integer) { + return (createAnswer(CONTROL_RESULT_ERROR, + "parameter 'exit-value' is not an integer")); + } + + exit_value = param->intValue(); + } + } + + ControlledDhcpv4Srv::getInstance()->shutdown(exit_value); + return(createAnswer(CONTROL_RESULT_SUCCESS, "Shutting down.")); } ConstElementPtr @@ -957,9 +972,10 @@ ControlledDhcpv4Srv::ControlledDhcpv4Srv(uint16_t server_port /*= DHCP4_SERVER_P boost::bind(&StatsMgr::statisticSetMaxSampleCountAllHandler, _1, _2)); } -void ControlledDhcpv4Srv::shutdown() { - io_service_.stop(); // Stop ASIO transmissions - Dhcpv4Srv::shutdown(); // Initiate DHCPv4 shutdown procedure. +void ControlledDhcpv4Srv::shutdown(int exit_value) { + setExitValue(exit_value); + io_service_.stop(); // Stop ASIO transmissions + Dhcpv4Srv::shutdown(); // Initiate DHCPv4 shutdown procedure. } ControlledDhcpv4Srv::~ControlledDhcpv4Srv() { @@ -1065,9 +1081,10 @@ ControlledDhcpv4Srv::dbReconnect(ReconnectCtlPtr db_reconnect_ctl) { db_reconnect_ctl.reset(); } else { if (!db_reconnect_ctl->checkRetries()) { + // We're out of retries, log it and initiate shutdown. LOG_ERROR(dhcp4_logger, DHCP4_DB_RECONNECT_RETRIES_EXHAUSTED) .arg(db_reconnect_ctl->maxRetries()); - shutdown(); + shutdown(EXIT_FAILURE); return; } @@ -1099,14 +1116,14 @@ ControlledDhcpv4Srv::dbLostCallback(ReconnectCtlPtr db_reconnect_ctl) { return (false); } - // If reconnect isn't enabled or we're out of retries, - // log it, schedule a shutdown, and return false + // If reconnect isn't enabled log it, + // initiate a shutdown and return false. if (!db_reconnect_ctl->retriesLeft() || !db_reconnect_ctl->retryInterval()) { LOG_INFO(dhcp4_logger, DHCP4_DB_RECONNECT_DISABLED) .arg(db_reconnect_ctl->retriesLeft()) .arg(db_reconnect_ctl->retryInterval()); - ControlledDhcpv4Srv::processCommand("shutdown", ConstElementPtr()); + shutdown(EXIT_FAILURE); return(false); } diff --git a/src/bin/dhcp4/ctrl_dhcp4_srv.h b/src/bin/dhcp4/ctrl_dhcp4_srv.h index b50479681a..d1f8107751 100644 --- a/src/bin/dhcp4/ctrl_dhcp4_srv.h +++ b/src/bin/dhcp4/ctrl_dhcp4_srv.h @@ -63,7 +63,8 @@ public: void cleanup(); /// @brief Initiates shutdown procedure for the whole DHCPv4 server. - void shutdown(); + /// @param exit_value integer value to the process should exit with. + void shutdown(int exit_value); /// @brief Command processor /// diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index d5b2c34846..6d20213631 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -771,7 +771,7 @@ Dhcpv4Srv::sendPacket(const Pkt4Ptr& packet) { IfaceMgr::instance().send(packet); } -bool +int Dhcpv4Srv::run() { #ifdef ENABLE_AFL // Set up structures needed for fuzzing. @@ -805,7 +805,7 @@ Dhcpv4Srv::run() { // destroying the thread pool MultiThreadingMgr::instance().apply(false, 0); - return (true); + return (getExitValue()); } void diff --git a/src/bin/dhcp4/dhcp4_srv.h b/src/bin/dhcp4/dhcp4_srv.h index 3af4f97eb5..4ade966691 100644 --- a/src/bin/dhcp4/dhcp4_srv.h +++ b/src/bin/dhcp4/dhcp4_srv.h @@ -272,8 +272,8 @@ public: /// Main server processing loop. Call the processing step routine /// until shut down. /// - /// @return true, if being shut down gracefully, never fail. - bool run(); + /// @return The value returned by @c Daemon::getExitValue(). + int run(); /// @brief Main server processing step. /// @@ -319,7 +319,6 @@ public: void processPacket(Pkt4Ptr& query, Pkt4Ptr& rsp, bool allow_packet_park = true); - /// @brief Instructs the server to shut down. void shutdown(); diff --git a/src/bin/dhcp4/main.cc b/src/bin/dhcp4/main.cc index b8cd9a5205..9d72cebaab 100644 --- a/src/bin/dhcp4/main.cc +++ b/src/bin/dhcp4/main.cc @@ -269,7 +269,7 @@ main(int argc, char* argv[]) { LOG_INFO(dhcp4_logger, DHCP4_STARTED).arg(VERSION); // And run the main loop of the server. - server.run(); + ret = server.run(); LOG_INFO(dhcp4_logger, DHCP4_SHUTDOWN); diff --git a/src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc index 8930bc2aec..b3533d99c9 100644 --- a/src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc @@ -401,15 +401,19 @@ TEST_F(CtrlChannelDhcpv4SrvTest, commands) { result = ControlledDhcpv4Srv::processCommand("shutdown", params); comment = parseAnswer(rcode, result); EXPECT_EQ(0, rcode); // expect success + // Exit value should default to 0. + EXPECT_EQ(0, server_->getExitValue()); - const pid_t pid(getpid()); - ConstElementPtr x(new isc::data::IntElement(pid)); - params->set("pid", x); + // Case 3: send shutdown command with exit-value parameter. + ConstElementPtr x(new isc::data::IntElement(77)); + params->set("exit-value", x); - // Case 3: send shutdown command with 1 parameter: pid result = ControlledDhcpv4Srv::processCommand("shutdown", params); comment = parseAnswer(rcode, result); EXPECT_EQ(0, rcode); // expect success + + // Exit value should match. + EXPECT_EQ(77, server_->getExitValue()); } // Check that the "libreload" command will reload libraries diff --git a/src/bin/dhcp6/ctrl_dhcp6_srv.cc b/src/bin/dhcp6/ctrl_dhcp6_srv.cc index 69cce5d4f0..e8bb15af05 100644 --- a/src/bin/dhcp6/ctrl_dhcp6_srv.cc +++ b/src/bin/dhcp6/ctrl_dhcp6_srv.cc @@ -205,16 +205,33 @@ void ControlledDhcpv6Srv::cleanup() { } ConstElementPtr -ControlledDhcpv6Srv::commandShutdownHandler(const string&, ConstElementPtr) { - if (ControlledDhcpv6Srv::getInstance()) { - ControlledDhcpv6Srv::getInstance()->shutdown(); - } else { +ControlledDhcpv6Srv::commandShutdownHandler(const string&, ConstElementPtr args) { + + if (!ControlledDhcpv6Srv::getInstance()) { LOG_WARN(dhcp6_logger, DHCP6_NOT_RUNNING); - ConstElementPtr answer = isc::config::createAnswer(1, "Shutdown failure."); - return (answer); + return(createAnswer(CONTROL_RESULT_ERROR, "Shutdown failure.")); } - ConstElementPtr answer = isc::config::createAnswer(0, "Shutting down."); - return (answer); + + int exit_value = 0; + if (args) { + // @todo Should we go ahead and shutdown even if the args are invalid? + if (args->getType() != Element::map) { + return (createAnswer(CONTROL_RESULT_ERROR, "Argument must be a map")); + } + + ConstElementPtr param = args->get("exit-value"); + if (param) { + if (param->getType() != Element::integer) { + return (createAnswer(CONTROL_RESULT_ERROR, + "parameter 'exit-value' is not an integer")); + } + + exit_value = param->intValue(); + } + } + + ControlledDhcpv6Srv::getInstance()->shutdown(exit_value); + return(createAnswer(CONTROL_RESULT_SUCCESS, "Shutting down.")); } ConstElementPtr @@ -977,8 +994,9 @@ ControlledDhcpv6Srv::ControlledDhcpv6Srv(uint16_t server_port, boost::bind(&StatsMgr::statisticSetMaxSampleCountAllHandler, _1, _2)); } -void ControlledDhcpv6Srv::shutdown() { - io_service_.stop(); // Stop ASIO transmissions +void ControlledDhcpv6Srv::shutdown(int exit_value) { + setExitValue(exit_value); + io_service_.stop(); // Stop ASIO transmissions Dhcpv6Srv::shutdown(); // Initiate DHCPv6 shutdown procedure. } @@ -1085,9 +1103,10 @@ ControlledDhcpv6Srv::dbReconnect(ReconnectCtlPtr db_reconnect_ctl) { db_reconnect_ctl.reset(); } else { if (!db_reconnect_ctl->checkRetries()) { + // We're out of retries, log it and initiate shutdown. LOG_ERROR(dhcp6_logger, DHCP6_DB_RECONNECT_RETRIES_EXHAUSTED) .arg(db_reconnect_ctl->maxRetries()); - shutdown(); + shutdown(EXIT_FAILURE); return; } @@ -1119,14 +1138,13 @@ ControlledDhcpv6Srv::dbLostCallback(ReconnectCtlPtr db_reconnect_ctl) { return (false); } - // If reconnect isn't enabled or we're out of retries, - // log it, schedule a shutdown, and return false + // If reconnect isn't enabled log it and initiate a shutdown. if (!db_reconnect_ctl->retriesLeft() || !db_reconnect_ctl->retryInterval()) { LOG_INFO(dhcp6_logger, DHCP6_DB_RECONNECT_DISABLED) .arg(db_reconnect_ctl->retriesLeft()) .arg(db_reconnect_ctl->retryInterval()); - ControlledDhcpv6Srv::processCommand("shutdown", ConstElementPtr()); + shutdown(EXIT_FAILURE); return(false); } diff --git a/src/bin/dhcp6/ctrl_dhcp6_srv.h b/src/bin/dhcp6/ctrl_dhcp6_srv.h index 6061630b33..911eb01908 100644 --- a/src/bin/dhcp6/ctrl_dhcp6_srv.h +++ b/src/bin/dhcp6/ctrl_dhcp6_srv.h @@ -63,7 +63,8 @@ public: void cleanup(); /// @brief Initiates shutdown procedure for the whole DHCPv6 server. - void shutdown(); + /// @param exit_value integer value to the process should exit with. + virtual void shutdown(int exit_value); /// @brief Command processor /// diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index 1f28dd4a12..5aa4321e39 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -442,7 +442,7 @@ Dhcpv6Srv::initContext(const Pkt6Ptr& pkt, evaluateClasses(pkt, true); } -bool Dhcpv6Srv::run() { +int Dhcpv6Srv::run() { #ifdef ENABLE_AFL // Set up structures needed for fuzzing. Fuzz fuzzer(6, server_port_); @@ -475,7 +475,7 @@ bool Dhcpv6Srv::run() { // destroying the thread pool MultiThreadingMgr::instance().apply(false, 0); - return (true); + return (getExitValue()); } void Dhcpv6Srv::run_one() { diff --git a/src/bin/dhcp6/dhcp6_srv.h b/src/bin/dhcp6/dhcp6_srv.h index 59fa57f13d..b1716340ac 100644 --- a/src/bin/dhcp6/dhcp6_srv.h +++ b/src/bin/dhcp6/dhcp6_srv.h @@ -139,8 +139,8 @@ public: /// Main server processing loop. Call the processing step routine /// until shut down. /// - /// @return true, if being shut down gracefully, never fail. - bool run(); + /// @return The value returned by @c Daemon::getExitValue(). + int run(); /// @brief Main server processing step. /// diff --git a/src/bin/dhcp6/main.cc b/src/bin/dhcp6/main.cc index 893107d84f..b4fde4cbd4 100644 --- a/src/bin/dhcp6/main.cc +++ b/src/bin/dhcp6/main.cc @@ -269,7 +269,7 @@ main(int argc, char* argv[]) { LOG_INFO(dhcp6_logger, DHCP6_STARTED).arg(VERSION); // And run the main loop of the server. - server.run(); + ret = server.run(); LOG_INFO(dhcp6_logger, DHCP6_SHUTDOWN); diff --git a/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc index e81065716f..3a9259e4a5 100644 --- a/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2012-2019 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2012-2020 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 @@ -419,14 +419,16 @@ TEST_F(CtrlDhcpv6SrvTest, commands) { comment = parseAnswer(rcode, result); EXPECT_EQ(0, rcode); // expect success - const pid_t pid(getpid()); - ConstElementPtr x(new isc::data::IntElement(pid)); - params->set("pid", x); + // Case 3: send shutdown command with exit-value parameter. + ConstElementPtr x(new isc::data::IntElement(77)); + params->set("exit-value", x); - // Case 3: send shutdown command with 1 parameter: pid result = ControlledDhcpv6Srv::processCommand("shutdown", params); comment = parseAnswer(rcode, result); EXPECT_EQ(0, rcode); // expect success + + // Exit value should match. + EXPECT_EQ(77, srv->getExitValue()); } // Check that the "libreload" command will reload libraries |