From: Thomas Markwalder Date: Fri, 24 May 2013 19:29:36 +0000 (-0400) Subject: [2955] Addressed review comments. Most notably, renamed DProcess X-Git-Tag: bind10-1.2.0beta1-release~411^2~8^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d7fe718898c7a8d1fbcebd4a4d47548d08ae1d98;p=thirdparty%2Fkea.git [2955] Addressed review comments. Most notably, renamed DProcess to DProcessBase. --- diff --git a/src/bin/d2/Makefile.am b/src/bin/d2/Makefile.am index 9ab8891f2d..201b4a8e44 100644 --- a/src/bin/d2/Makefile.am +++ b/src/bin/d2/Makefile.am @@ -48,7 +48,8 @@ pkglibexec_PROGRAMS = b10-d2 b10_d2_SOURCES = main.cc b10_d2_SOURCES += d2_log.cc d2_log.h -b10_d2_SOURCES += d2_process.cc d2_process.h d_process.h +b10_d2_SOURCES += d2_process.h +b10_d2_SOURCES += d2_process.cc d2_process.h nodist_b10_d2_SOURCES = d2_messages.h d2_messages.cc EXTRA_DIST += d2_messages.mes diff --git a/src/bin/d2/d2_messages.mes b/src/bin/d2/d2_messages.mes index 2f886596b9..804b2cb25c 100644 --- a/src/bin/d2/d2_messages.mes +++ b/src/bin/d2/d2_messages.mes @@ -14,39 +14,35 @@ $NAMESPACE isc::d2 -% D2_STARTING : service starting -This is a debug message issued during a D2 service startup. +% D2CTL_STARTING DHCP-DDNS controller starting, pid: %1 +This is an informational message issued when controller for DHCP-DDNS +service first starts. -% D2_START_INFO pid: %1, verbose: %2, standalone: %3 -This is a debug message issued during the D2 service startup. -It lists some information about the parameters with which the -process is running. +% D2CTL_STOPPING DHCP-DDNS controller is exiting +This is an informational message issued when the controller is exiting +following a shut down (normal or otherwise) of the DDHCP-DDNS process. -% D2_SHUTDOWN : service is performing a normal shutting down -This is a debug message issued when the D2 service shuts down -normally in response to command to stop. +% D2PRC_SHUTDOWN DHCP-DDNS process is performing a normal shut down +This is a debug message issued when the service process has been instructed +to shut down by the controller. -% D2PRC_SHUTDOWN : process is performing a normal shutting down -This is a debug message issued when the D2 process shuts down -normally in response to service directive to stop. - -% D2PRC_RUN_ENTER : process has entered the event loop. +% D2PRC_RUN_ENTER process has entered the event loop This is a debug message issued when the D2 process enters it's run method. -% D2PRC_RUN_EXIT : process is exiting the event loop. +% D2PRC_RUN_EXIT process is exiting the event loop This is a debug message issued when the D2 process exits the in event loop. -% D2PRC_FAILED : process experienced a fatal error. +% D2PRC_FAILED process experienced a fatal error: %1 This is a debug message issued when the D2 process encounters an unrecoverable error from within the event loop. -% D2PRC_CONFIGURE : new configuration received: %1 +% D2PRC_CONFIGURE new configuration received: %1 This is a debug message issued when the D2 process configure method has been invoked. -% D2PRC_COMMAND : command directive received, command: %1 - args: %2 +% D2PRC_COMMAND command directive received, command: %1 - args: %2 This is a debug message issued when the D2 process command method has been invoked. diff --git a/src/bin/d2/d2_process.cc b/src/bin/d2/d2_process.cc index 8fdb6a62ee..e12f0bce6b 100644 --- a/src/bin/d2/d2_process.cc +++ b/src/bin/d2/d2_process.cc @@ -22,7 +22,7 @@ namespace isc { namespace d2 { D2Process::D2Process(const char* name, IOServicePtr io_service) - : DProcess(name, io_service) { + : DProcessBase(name, io_service) { }; void @@ -38,9 +38,10 @@ D2Process::run() { // or the call to run will continue to block, and shutdown will not // occur. LOG_DEBUG(d2_logger, DBGLVL_START_SHUT, D2PRC_RUN_ENTER); - while (!shut_down_) { + IOServicePtr& io_service = getIoService(); + while (!shouldShutDown()) { try { - io_service_->run_one(); + io_service->run_one(); } catch (const std::exception& ex) { LOG_FATAL(d2_logger, D2PRC_FAILED).arg(ex.what()); return (EXIT_FAILURE); @@ -54,7 +55,7 @@ D2Process::run() { int D2Process::shutdown() { LOG_DEBUG(d2_logger, DBGLVL_START_SHUT, D2PRC_SHUTDOWN); - shut_down_ = true; + setShutdownFlag(true); return (0); } diff --git a/src/bin/d2/d2_process.h b/src/bin/d2/d2_process.h index 2f36de1208..4d6d36b1d1 100644 --- a/src/bin/d2/d2_process.h +++ b/src/bin/d2/d2_process.h @@ -25,10 +25,10 @@ namespace d2 { /// D2Process provides the top level application logic for DHCP-driven DDNS /// update processing. It provides the asynchronous event processing required /// to receive DNS mapping change requests and carry them out. -/// It implements the DProcess interface, which structures it such that it +/// It implements the DProcessBase interface, which structures it such that it /// is a managed "application", controlled by a management layer. -class D2Process : public DProcess { +class D2Process : public DProcessBase { public: /// @brief Constructor /// @@ -37,7 +37,7 @@ public: /// @param io_service is the io_service used by the caller for /// asynchronous event handling. /// - /// @throw DProcessError is io_service is NULL. + /// @throw DProcessBaseError is io_service is NULL. D2Process(const char* name, IOServicePtr io_service); /// @brief Will be used after instantiation to perform initialization diff --git a/src/bin/d2/d_process.h b/src/bin/d2/d_process.h index 7398fa29a6..4de50aabc1 100644 --- a/src/bin/d2/d_process.h +++ b/src/bin/d2/d_process.h @@ -27,25 +27,25 @@ namespace isc { namespace d2 { /// @brief Exception thrown if the process encountered an operational error. -class DProcessError : public isc::Exception { +class DProcessBaseError : public isc::Exception { public: - DProcessError(const char* file, size_t line, const char* what) : + DProcessBaseError(const char* file, size_t line, const char* what) : isc::Exception(file, line, what) { }; }; /// @brief Application Process Interface /// -/// DProcess is an abstract class represents the primary "application" level -/// object in a "managed" asyncrhonous application. It provides a uniform +/// DProcessBase is an abstract class represents the primary "application" +/// level object in a "managed" asynchronous application. It provides a uniform /// interface such that a managing layer can construct, intialize, and start /// the application's event loop. The event processing is centered around the /// use of isc::asiolink::io_service. The io_service is shared between the -/// the managing layer and the DProcess. This allows management layer IO +/// the managing layer and the DProcessBase. This allows management layer IO /// such as directives to be sensed and handled, as well as processing IO -/// activity specific to the application. In terms fo management layer IO, +/// activity specific to the application. In terms of management layer IO, /// there are methods shutdown, configuration updates, and commands unique /// to the application. -class DProcess { +class DProcessBase { public: /// @brief Constructor /// @@ -54,12 +54,12 @@ public: /// @param io_service is the io_service used by the caller for /// asynchronous event handling. /// - /// @throw DProcessError is io_service is NULL. - DProcess(const char* name, IOServicePtr io_service) : name_(name), - io_service_(io_service), shut_down_(false) { + /// @throw DProcessBaseError is io_service is NULL. + DProcessBase(const char* name, IOServicePtr io_service) : name_(name), + io_service_(io_service), shut_down_flag(false) { if (!io_service_) { - isc_throw (DProcessError, "IO Service cannot be null"); + isc_throw (DProcessBaseError, "IO Service cannot be null"); } }; @@ -112,9 +112,25 @@ public: const std::string& command, isc::data::ConstElementPtr args) = 0; /// @brief Destructor - virtual ~DProcess(){}; + virtual ~DProcessBase(){}; -protected: + bool shouldShutDown() { + return shut_down_flag; + } + + void setShutdownFlag(bool value) { + shut_down_flag = value; + } + + const std::string& getName() { + return (name_); + } + + IOServicePtr& getIoService() { + return (io_service_); + } + +private: /// @brief Text label for the process. Generally used in log statements, /// but otherwise can be arbitrary. std::string name_; @@ -123,11 +139,11 @@ protected: IOServicePtr io_service_; /// @brief Boolean flag set when shutdown has been requested. - bool shut_down_; + bool shut_down_flag; }; -/// @brief Defines a shared pointer to DProcess. -typedef boost::shared_ptr DProcessPtr; +/// @brief Defines a shared pointer to DProcessBase. +typedef boost::shared_ptr DProcessBasePtr; }; // namespace isc::d2 }; // namespace isc diff --git a/src/bin/d2/main.cc b/src/bin/d2/main.cc index 7ef300b907..5658a8aec8 100644 --- a/src/bin/d2/main.cc +++ b/src/bin/d2/main.cc @@ -82,16 +82,14 @@ main(int argc, char* argv[]) { ((verbose_mode && stand_alone) ? isc::log::DEBUG : isc::log::INFO), isc::log::MAX_DEBUG_LEVEL, NULL, !stand_alone); - LOG_INFO(d2_logger, D2_STARTING); - LOG_DEBUG(d2_logger, DBGLVL_START_SHUT, D2_START_INFO) - .arg(getpid()).arg(verbose_mode ? "yes" : "no") - .arg(stand_alone ? "yes" : "no" ); + + LOG_INFO(d2_logger, D2CTL_STARTING); // For now we will sleep awhile to simulate doing something. // Without at least a sleep, the process will start, exit and be // restarted by Bind10/Init endlessley in a rapid succession. sleep(1000); - LOG_INFO(d2_logger, D2_SHUTDOWN); + LOG_INFO(d2_logger, D2CTL_STOPPING); return (EXIT_SUCCESS); } diff --git a/src/bin/d2/tests/Makefile.am b/src/bin/d2/tests/Makefile.am index aea12c0397..de8db08d09 100644 --- a/src/bin/d2/tests/Makefile.am +++ b/src/bin/d2/tests/Makefile.am @@ -52,6 +52,7 @@ if HAVE_GTEST TESTS += d2_unittests d2_unittests_SOURCES = ../d2_log.h ../d2_log.cc +d2_unittests_SOURCES += ../d2_process.h d2_unittests_SOURCES += ../d2_process.cc ../d2_process.h ../d_process.h d2_unittests_SOURCES += d2_unittests.cc d2_unittests_SOURCES += d2_process_unittests.cc diff --git a/src/bin/d2/tests/d2_process_unittests.cc b/src/bin/d2/tests/d2_process_unittests.cc index 9e6f852841..2dc0d3d966 100644 --- a/src/bin/d2/tests/d2_process_unittests.cc +++ b/src/bin/d2/tests/d2_process_unittests.cc @@ -35,7 +35,7 @@ class D2ProcessTest : public ::testing::Test { public: /// @brief Static instance accessible via test callbacks. - static DProcessPtr process_; + static DProcessBasePtr process_; /// @brief Constructor D2ProcessTest() { @@ -56,7 +56,7 @@ public: /// @brief Callback that throws an exception. static void genFatalErrorCallback() { - isc_throw (DProcessError, "simulated fatal error"); + isc_throw (DProcessBaseError, "simulated fatal error"); } /// @brief IOService for event processing. Fills in for IOservice @@ -65,7 +65,7 @@ public: }; // Define the static process instance -DProcessPtr D2ProcessTest::process_; +DProcessBasePtr D2ProcessTest::process_; /// @brief Verifies D2Process constructor behavior. @@ -75,7 +75,7 @@ TEST(D2Process, construction) { // Verify that the constructor will fail if given an empty // io service. IOServicePtr lcl_io_service; - EXPECT_THROW (D2Process("TestProcess", lcl_io_service), DProcessError); + EXPECT_THROW (D2Process("TestProcess", lcl_io_service), DProcessBaseError); // Verify that the constructor succeeds with a valid io_service lcl_io_service.reset(new isc::asiolink::IOService()); @@ -115,16 +115,16 @@ TEST_F(D2ProcessTest, command) { /// the run method to exit gracefully with a return value of EXIT_SUCCESS. TEST_F(D2ProcessTest, normalShutdown) { // Use an asiolink IntervalTimer and callback to generate the - // shutdown invocation. + // shutdown invocation. (Note IntervalTimer setup is in milliseconds). isc::asiolink::IntervalTimer timer(*io_service_); - timer.setup(genShutdownCallback, 2*1000); + timer.setup(genShutdownCallback, 2 * 1000); // Record start time, and invoke run(). - ptime start = second_clock::universal_time(); + ptime start = microsec_clock::universal_time(); int rcode = process_->run(); // Record stop time. - ptime stop = second_clock::universal_time(); + ptime stop = microsec_clock::universal_time(); // Verify normal shutdown status. EXPECT_EQ(EXIT_SUCCESS, rcode); @@ -133,23 +133,24 @@ TEST_F(D2ProcessTest, normalShutdown) { // timer duration. This demonstrates that the shutdown was driven // by an io_service event and callback. time_duration elapsed = stop - start; - EXPECT_EQ(2L, elapsed.seconds()); + EXPECT_TRUE(elapsed.total_milliseconds() >= 1900 && + elapsed.total_milliseconds() <= 2100); } /// @brief Verifies that an "uncaught" exception thrown during event loop /// processing is treated as a fatal error. TEST_F(D2ProcessTest, fatalErrorShutdown) { // Use an asiolink IntervalTimer and callback to generate the - // the exception. + // the exception. (Note IntervalTimer setup is in milliseconds). isc::asiolink::IntervalTimer timer(*io_service_); - timer.setup(genFatalErrorCallback, 2*1000); + timer.setup(genFatalErrorCallback, 2 * 1000); // Record start time, and invoke run(). - ptime start = second_clock::universal_time(); + ptime start = microsec_clock::universal_time(); int rcode = process_->run(); // Record stop time. - ptime stop = second_clock::universal_time(); + ptime stop = microsec_clock::universal_time(); // Verify failure status. EXPECT_EQ(EXIT_FAILURE, rcode); @@ -158,7 +159,8 @@ TEST_F(D2ProcessTest, fatalErrorShutdown) { // timer duration. This demonstrates that the anomaly occurred // during io callback processing. time_duration elapsed = stop - start; - EXPECT_EQ(2L, elapsed.seconds()); + EXPECT_TRUE(elapsed.total_milliseconds() >= 1900 && + elapsed.total_milliseconds() <= 2100); } } // end of anonymous namespace diff --git a/src/bin/d2/tests/d2_test.py b/src/bin/d2/tests/d2_test.py index ce7bdc3cac..032aaa463d 100644 --- a/src/bin/d2/tests/d2_test.py +++ b/src/bin/d2/tests/d2_test.py @@ -161,7 +161,7 @@ class TestD2Daemon(unittest.TestCase): # soon enough to catch it. (returncode, output, error) = self.runCommand(["../b10-d2", "-s"]) output_text = str(output) + str(error) - self.assertEqual(output_text.count("D2_STARTING"), 1) + self.assertEqual(output_text.count("D2CTL_STARTING"), 1) if __name__ == '__main__': unittest.main()