command_unittest.cc 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <config.h>
  15. #include "datasrc_util.h"
  16. #include <auth/auth_srv.h>
  17. #include <auth/command.h>
  18. #include <auth/datasrc_config.h>
  19. #include <dns/name.h>
  20. #include <dns/rrclass.h>
  21. #include <dns/rrtype.h>
  22. #include <dns/rrttl.h>
  23. #include <cc/data.h>
  24. #include <config/ccsession.h>
  25. #include <datasrc/memory_datasrc.h>
  26. #include <asiolink/asiolink.h>
  27. #include <util/unittests/mock_socketsession.h>
  28. #include <testutils/mockups.h>
  29. #include <cassert>
  30. #include <cstdlib>
  31. #include <string>
  32. #include <stdexcept>
  33. #include <boost/bind.hpp>
  34. #include <gtest/gtest.h>
  35. #include <sys/types.h>
  36. #include <unistd.h>
  37. using namespace std;
  38. using namespace isc::dns;
  39. using namespace isc::data;
  40. using namespace isc::datasrc;
  41. using namespace isc::config;
  42. using namespace isc::util::unittests;
  43. using namespace isc::testutils;
  44. using namespace isc::auth;
  45. using namespace isc::auth::unittest;
  46. namespace {
  47. class AuthCommandTest : public ::testing::Test {
  48. protected:
  49. AuthCommandTest() :
  50. server_(xfrout_, ddns_forwarder_),
  51. rcode_(-1),
  52. expect_rcode_(0),
  53. itimer_(server_.getIOService())
  54. {}
  55. void checkAnswer(const int expected_code, const char* name = "") {
  56. SCOPED_TRACE(name);
  57. parseAnswer(rcode_, result_);
  58. EXPECT_EQ(expected_code, rcode_) << result_->str();
  59. }
  60. MockXfroutClient xfrout_;
  61. MockSocketSessionForwarder ddns_forwarder_;
  62. AuthSrv server_;
  63. ConstElementPtr result_;
  64. // The shutdown command parameter
  65. ConstElementPtr param_;
  66. int rcode_, expect_rcode_;
  67. isc::asiolink::IntervalTimer itimer_;
  68. public:
  69. void stopServer(); // need to be public for boost::bind
  70. void dontStopServer(); // need to be public for boost::bind
  71. };
  72. TEST_F(AuthCommandTest, unknownCommand) {
  73. result_ = execAuthServerCommand(server_, "no_such_command",
  74. ConstElementPtr());
  75. parseAnswer(rcode_, result_);
  76. EXPECT_EQ(1, rcode_);
  77. }
  78. TEST_F(AuthCommandTest, DISABLED_unexpectedException) {
  79. // execAuthServerCommand() won't catch standard exceptions.
  80. // Skip this test for now: ModuleCCSession doesn't seem to validate
  81. // commands.
  82. EXPECT_THROW(execAuthServerCommand(server_, "_throw_exception",
  83. ConstElementPtr()),
  84. runtime_error);
  85. }
  86. void
  87. AuthCommandTest::stopServer() {
  88. result_ = execAuthServerCommand(server_, "shutdown", param_);
  89. parseAnswer(rcode_, result_);
  90. assert(rcode_ == 0); // make sure the test stops when something is wrong
  91. }
  92. TEST_F(AuthCommandTest, shutdown) {
  93. // Param defaults to empty/null pointer on creation
  94. itimer_.setup(boost::bind(&AuthCommandTest::stopServer, this), 1);
  95. server_.getIOService().run();
  96. EXPECT_EQ(0, rcode_);
  97. }
  98. TEST_F(AuthCommandTest, shutdownCorrectPID) {
  99. // Put the pid parameter there
  100. const pid_t pid(getpid());
  101. ElementPtr param(new isc::data::MapElement());
  102. param->set("pid", ConstElementPtr(new isc::data::IntElement(pid)));
  103. param_ = param;
  104. // With the correct PID, it should act exactly the same as in case
  105. // of no parameter
  106. itimer_.setup(boost::bind(&AuthCommandTest::stopServer, this), 1);
  107. server_.getIOService().run();
  108. EXPECT_EQ(0, rcode_);
  109. }
  110. // This is like stopServer, but the server should not stop after the
  111. // command, it should be running
  112. void
  113. AuthCommandTest::dontStopServer() {
  114. result_ = execAuthServerCommand(server_, "shutdown", param_);
  115. parseAnswer(rcode_, result_);
  116. EXPECT_EQ(expect_rcode_, rcode_);
  117. rcode_ = -1;
  118. // We run the stopServer now, to really stop the server.
  119. // If it had stopped already, it won't be run and the rcode -1 will
  120. // be left here.
  121. param_ = ConstElementPtr();
  122. itimer_.cancel();
  123. itimer_.setup(boost::bind(&AuthCommandTest::stopServer, this), 1);
  124. }
  125. // If we provide something not an int, the PID is not really specified, so
  126. // act as if nothing came.
  127. TEST_F(AuthCommandTest, shutdownNotInt) {
  128. // Put the pid parameter there
  129. ElementPtr param(new isc::data::MapElement());
  130. param->set("pid", ConstElementPtr(new isc::data::StringElement("pid")));
  131. param_ = param;
  132. expect_rcode_ = 1;
  133. // It should reject to stop if the PID is not an int.
  134. itimer_.setup(boost::bind(&AuthCommandTest::dontStopServer, this), 1);
  135. server_.getIOService().run();
  136. EXPECT_EQ(0, rcode_);
  137. }
  138. TEST_F(AuthCommandTest, shutdownIncorrectPID) {
  139. // The PID = 0 should be taken by init, so we are not init and the
  140. // PID should be different
  141. param_ = Element::fromJSON("{\"pid\": 0}");
  142. itimer_.setup(boost::bind(&AuthCommandTest::dontStopServer, this), 1);
  143. server_.getIOService().run();
  144. EXPECT_EQ(0, rcode_);
  145. }
  146. TEST_F(AuthCommandTest, getStats) {
  147. result_ = execAuthServerCommand(server_, "getstats", ConstElementPtr());
  148. parseAnswer(rcode_, result_);
  149. // Just check the command execution succeeded. Detailed tests specific to
  150. // statistics are done in its own tests.
  151. EXPECT_EQ(0, rcode_);
  152. }
  153. }