Browse Source

[1651] Implemented command tests for DHCPv4

Tomek Mrugalski 13 years ago
parent
commit
327e505ad6

+ 16 - 6
src/bin/dhcp4/ctrl_dhcp4_srv.cc

@@ -59,7 +59,7 @@ namespace dhcp {
 ControlledDhcpv4Srv* ControlledDhcpv4Srv::server_ = NULL;
 
 ConstElementPtr
-dhcp4_config_handler(ConstElementPtr new_config) {
+ControlledDhcpv4Srv::dhcp4ConfigHandler(ConstElementPtr new_config) {
     cout << "b10-dhcp4: Received new config:" << new_config->str() << endl;
     ConstElementPtr answer = isc::config::createAnswer(0,
                              "Thank you for sending config.");
@@ -67,7 +67,7 @@ dhcp4_config_handler(ConstElementPtr new_config) {
 }
 
 ConstElementPtr
-dhcp4_command_handler(const string& command, ConstElementPtr args) {
+ControlledDhcpv4Srv::dhcp4CommandHandler(const string& command, ConstElementPtr args) {
     cout << "b10-dhcp4: Received new command: [" << command << "], args="
          << args->str() << endl;
     if (command == "shutdown") {
@@ -110,8 +110,8 @@ void ControlledDhcpv4Srv::establishSession() {
     cc_session_ = new Session(io_service_.get_io_service());
 
     config_session_ = new ModuleCCSession(specfile, *cc_session_,
-                                          dhcp4_config_handler,
-                                          dhcp4_command_handler, false);
+                                          dhcp4ConfigHandler,
+                                          dhcp4CommandHandler, false);
     config_session_->start();
 
     int ctrl_socket = cc_session_->getSocketDesc();
@@ -142,8 +142,6 @@ ControlledDhcpv4Srv::ControlledDhcpv4Srv(uint16_t port /*= DHCP4_SERVER_PORT*/,
                          (verbose ? isc::log::DEBUG : isc::log::INFO),
                          isc::log::MAX_DEBUG_LEVEL, NULL);
     server_ = this; // remember this instance for use in callback
-    
-    establishSession();
 }
 
 void ControlledDhcpv4Srv::shutdown() {
@@ -158,5 +156,17 @@ ControlledDhcpv4Srv::~ControlledDhcpv4Srv() {
                     // at this stage anyway.
 }
 
+isc::data::ConstElementPtr
+ControlledDhcpv4Srv::execDhcpv4ServerCommand(const std::string& command_id,
+                                             isc::data::ConstElementPtr args) {
+    try {
+        return dhcp4CommandHandler(command_id, args);
+    } catch (const Exception& ex) {
+        ConstElementPtr answer = isc::config::createAnswer(1, ex.what());
+        return (answer);
+    }
+}
+
+
 };
 };

+ 37 - 1
src/bin/dhcp4/ctrl_dhcp4_srv.h

@@ -19,6 +19,7 @@
 #include <asiolink/asiolink.h>
 #include <cc/session.h>
 #include <config/ccsession.h>
+#include <cc/data.h>
 
 namespace isc {
 namespace dhcp {
@@ -36,6 +37,11 @@ namespace dhcp {
 /// Dhcpv4Srv and other classes, see \ref dhcpv4Session.
 class ControlledDhcpv4Srv : public isc::dhcp::Dhcpv4Srv {
 public:
+
+    /// @brief Constructor
+    ///
+    /// @param port UDP port to be opened for DHCP traffic
+    /// @param verbose should server print out additional commands?
     ControlledDhcpv4Srv(uint16_t port = DHCP4_SERVER_PORT,
                         bool verbose = false);
 
@@ -59,9 +65,40 @@ public:
 
     ~ControlledDhcpv4Srv();
 
+    /// @brief Session callback, processes received commands.
+    ///
+    /// @param command_id text represenation of the command (e.g. "shutdown")
+    /// @param args optional parameters
+    ///
+    /// @return status of the command
+    static isc::data::ConstElementPtr
+    execDhcpv4ServerCommand(const std::string& command,
+                            isc::data::ConstElementPtr args);
+
+    /// @brief Static pointer to the sole instance of the DHCP server.
+    ///
+    /// This is required for config and command handlers to gain access to
+    /// the server
     static ControlledDhcpv4Srv* server_;
 protected:
 
+    /// @brief A callback for handling incoming configuration updates.
+    ///
+    /// @param new_config textual representation of the new configuration
+    ///
+    /// @return status of the config update
+    static isc::data::ConstElementPtr
+    dhcp4ConfigHandler(isc::data::ConstElementPtr new_config);
+
+    /// @brief A callback for handling incoming commands.
+    ///
+    /// @param command textual representation of the command
+    /// @param args parameters of the command
+    ///
+    /// @return status of the processed command
+    static isc::data::ConstElementPtr
+    dhcp4CommandHandler(const std::string& command, isc::data::ConstElementPtr args);
+
     /// @brief callback that will be called from iface_mgr when command/config arrives
     ///
     /// This static callback method is called from IfaceMgr::receive4() method,
@@ -76,7 +113,6 @@ protected:
 
     /// @brief Session that receives configuation and commands
     isc::config::ModuleCCSession* config_session_;
-
 };
 
 }; // namespace isc::dhcp

+ 28 - 1
src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc

@@ -22,11 +22,14 @@
 
 #include <dhcp/dhcp4.h>
 #include <dhcp4/ctrl_dhcp4_srv.h>
+#include <config/ccsession.h>
 
 using namespace std;
 using namespace isc;
 using namespace isc::dhcp;
 using namespace isc::asiolink;
+using namespace isc::data;
+using namespace isc::config;
 
 namespace {
 
@@ -45,13 +48,37 @@ public:
     };
 };
 
-TEST_F(CtrlDhcpv4SrvTest, basic) {
+TEST_F(CtrlDhcpv4SrvTest, commands) {
 
     ControlledDhcpv4Srv* srv = NULL;
     ASSERT_NO_THROW({
         srv = new ControlledDhcpv4Srv(DHCP4_SERVER_PORT + 10000);
     });
 
+    // use empty parameters list
+    ElementPtr params(new isc::data::MapElement());
+    int rcode = -1;
+
+    // case 1: send bogus command
+    ConstElementPtr result = ControlledDhcpv4Srv::execDhcpv4ServerCommand("blah", params);
+    ConstElementPtr comment = parseAnswer(rcode, result);
+    EXPECT_EQ(1, rcode); // expect failure (no such command as blah)
+
+    // case 1: send shutdown command without any parameters
+    result = ControlledDhcpv4Srv::execDhcpv4ServerCommand("shutdown", params);
+    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 2: send shutdown command with 1 parameter: pid
+    result = ControlledDhcpv4Srv::execDhcpv4ServerCommand("shutdown", params);
+    comment = parseAnswer(rcode, result);
+    EXPECT_EQ(0, rcode); // expect success
+
+
     delete srv;
 }