Commit 94ca32cb authored by Michal 'vorner' Vaner's avatar Michal 'vorner' Vaner
Browse files

[1596] Handle pid parameter in auth

parent 3d7ea0c3
......@@ -97,7 +97,13 @@
{
"command_name": "shutdown",
"command_description": "Shut down authoritative DNS server",
"command_args": []
"command_args": [
{
"item_name": "pid",
"item_type": "integer",
"item_optional": true
}
]
},
{
"command_name": "sendstats",
......
......@@ -343,7 +343,7 @@ public:
///
/// \param type Type of a counter to get the value of
///
/// \return the value of the counter.
uint64_t getCounter(const AuthCounters::ServerCounterType type) const;
/// \brief Get the value of per Opcode counter in the Auth Counters.
......
......@@ -12,10 +12,9 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <string>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <auth/command.h>
#include <auth/auth_log.h>
#include <auth/auth_srv.h>
#include <exceptions/exceptions.h>
......@@ -27,9 +26,13 @@
#include <config/ccsession.h>
#include <auth/auth_log.h>
#include <auth/auth_srv.h>
#include <auth/command.h>
#include <string>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <sys/types.h>
#include <unistd.h>
using boost::scoped_ptr;
using namespace isc::auth;
......@@ -104,10 +107,22 @@ public:
virtual void exec(AuthSrv& server, isc::data::ConstElementPtr args) = 0;
};
// Handle the "shutdown" command. No argument is assumed.
// Handle the "shutdown" command. An optional parameter "pid" is used to
// see if it is really for our instance.
class ShutdownCommand : public AuthCommand {
public:
virtual void exec(AuthSrv& server, isc::data::ConstElementPtr) {
virtual void exec(AuthSrv& server, isc::data::ConstElementPtr args) {
// Is the pid argument provided?
if (args && args->getType() ==
isc::data::Element::map && args->contains("pid")) {
// If it is, we check it is the same as our PID
int pid(args->get("pid")->intValue());
pid_t my_pid(getpid());
if (my_pid != pid) {
// It is not for us
return;
}
}
server.stop();
}
};
......
......@@ -14,14 +14,9 @@
#include <config.h>
#include <cassert>
#include <cstdlib>
#include <string>
#include <stdexcept>
#include <boost/bind.hpp>
#include <gtest/gtest.h>
#include <auth/auth_srv.h>
#include <auth/auth_config.h>
#include <auth/command.h>
#include <dns/name.h>
#include <dns/rrclass.h>
......@@ -33,14 +28,22 @@
#include <datasrc/memory_datasrc.h>
#include <auth/auth_srv.h>
#include <auth/auth_config.h>
#include <auth/command.h>
#include <asiolink/asiolink.h>
#include <testutils/mockups.h>
#include <cassert>
#include <cstdlib>
#include <string>
#include <stdexcept>
#include <boost/bind.hpp>
#include <gtest/gtest.h>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
using namespace isc::dns;
using namespace isc::data;
......@@ -50,7 +53,11 @@ using namespace isc::config;
namespace {
class AuthCommandTest : public ::testing::Test {
protected:
AuthCommandTest() : server(false, xfrout), rcode(-1) {
AuthCommandTest() :
server(false, xfrout),
rcode(-1),
itimer_(server.getIOService())
{
server.setStatisticsSession(&statistics_session);
}
void checkAnswer(const int expected_code) {
......@@ -61,9 +68,13 @@ protected:
MockXfroutClient xfrout;
AuthSrv server;
ConstElementPtr result;
// The shutdown command parameter
ConstElementPtr param;
int rcode;
isc::asiolink::IntervalTimer itimer_;
public:
void stopServer(); // need to be public for boost::bind
void dontStopServer(); // need to be public for boost::bind
};
TEST_F(AuthCommandTest, unknownCommand) {
......@@ -92,14 +103,52 @@ TEST_F(AuthCommandTest, sendStatistics) {
void
AuthCommandTest::stopServer() {
result = execAuthServerCommand(server, "shutdown", ConstElementPtr());
result = execAuthServerCommand(server, "shutdown", param);
parseAnswer(rcode, result);
assert(rcode == 0); // make sure the test stops when something is wrong
}
TEST_F(AuthCommandTest, shutdown) {
isc::asiolink::IntervalTimer itimer(server.getIOService());
itimer.setup(boost::bind(&AuthCommandTest::stopServer, this), 1);
// Param defaults to empty/null pointer on creation
itimer_.setup(boost::bind(&AuthCommandTest::stopServer, this), 1);
server.getIOService().run();
EXPECT_EQ(0, rcode);
}
TEST_F(AuthCommandTest, shutdownCorrectPID) {
// Put the pid parameter there
pid_t pid(getpid());
ElementPtr param(new isc::data::MapElement());
param->set("pid", ConstElementPtr(new isc::data::IntElement(pid)));
this->param = param;
// With the correct PID, it should act exactly the same as in case
// of no parameter
itimer_.setup(boost::bind(&AuthCommandTest::stopServer, this), 1);
server.getIOService().run();
EXPECT_EQ(0, rcode);
}
// This is like stopServer, but the server should not stop after the
// command, it should be running
void
AuthCommandTest::dontStopServer() {
result = execAuthServerCommand(server, "shutdown", param);
parseAnswer(rcode, result);
EXPECT_EQ(0, rcode);
rcode = -1;
// We run the stopServer now, to really stop the server.
// If it had stopped already, it won't be run and the rcode -1 will
// be left here.
param = ConstElementPtr();
itimer_.cancel();
itimer_.setup(boost::bind(&AuthCommandTest::stopServer, this), 1);
}
TEST_F(AuthCommandTest, shutdownIncorrectPID) {
// The PID = 0 should be taken by init, so we are not init and the
// PID should be different
param = Element::fromJSON("{\"pid\": 0}");
itimer_.setup(boost::bind(&AuthCommandTest::dontStopServer, this), 1);
server.getIOService().run();
EXPECT_EQ(0, rcode);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment