From: Marcin Siodelski Date: Thu, 13 Jul 2017 11:12:03 +0000 (+0200) Subject: [5329] HooksManager now support functions for registering command handlers. X-Git-Tag: trac5124a_base~42^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bc01d351a660e00cec0fd60418ef78200a7aeb38;p=thirdparty%2Fkea.git [5329] HooksManager now support functions for registering command handlers. --- diff --git a/src/lib/hooks/callout_manager.h b/src/lib/hooks/callout_manager.h index bf68f974d4..b8c24df08b 100644 --- a/src/lib/hooks/callout_manager.h +++ b/src/lib/hooks/callout_manager.h @@ -205,6 +205,9 @@ public: /// @brief Checks if control command handlers are present for the /// specified command. /// + /// @param command_name Command name for which handlers' presence should + /// be checked. + /// /// @return true if there is a hook point associated with the specified /// command and callouts/command handlers are installed for this hook /// point, false otherwise. diff --git a/src/lib/hooks/hooks_manager.cc b/src/lib/hooks/hooks_manager.cc index 14c750103a..56db7b209e 100644 --- a/src/lib/hooks/hooks_manager.cc +++ b/src/lib/hooks/hooks_manager.cc @@ -48,6 +48,17 @@ HooksManager::calloutsPresent(int index) { return (getHooksManager().calloutsPresentInternal(index)); } +bool +HooksManager::commandHandlersPresentInternal(const std::string& command_name) { + conditionallyInitialize(); + return (callout_manager_->commandHandlersPresent(command_name)); +} + +bool +HooksManager::commandHandlersPresent(const std::string& command_name) { + return (getHooksManager().commandHandlersPresentInternal(command_name)); +} + // Call the callouts void @@ -61,6 +72,20 @@ HooksManager::callCallouts(int index, CalloutHandle& handle) { return (getHooksManager().callCalloutsInternal(index, handle)); } +void +HooksManager::callCommandHandlersInternal(const std::string& command_name, + CalloutHandle& handle) { + conditionallyInitialize(); + callout_manager_->callCommandHandlers(command_name, handle); +} + +void +HooksManager::callCommandHandlers(const std::string& command_name, + CalloutHandle& handle) { + getHooksManager().callCommandHandlersInternal(command_name, handle); +} + + // Load the libraries. This will delete the previously-loaded libraries // (if present) and load new ones. diff --git a/src/lib/hooks/hooks_manager.h b/src/lib/hooks/hooks_manager.h index bda0563b12..3eae0a95fb 100644 --- a/src/lib/hooks/hooks_manager.h +++ b/src/lib/hooks/hooks_manager.h @@ -90,6 +90,17 @@ public: /// @throw NoSuchHook Given index does not correspond to a valid hook. static bool calloutsPresent(int index); + /// @brief Checks if control command handlers are present for the + /// specified command. + /// + /// @param command_name Command name for which handlers' presence should + /// be checked. + /// + /// @return true if there is a hook point associated with the specified + /// command and callouts/command handlers are installed for this hook + /// point, false otherwise. + static bool commandHandlersPresent(const std::string& command_name); + /// @brief Calls the callouts for a given hook /// /// Iterates through the library handles and calls the callouts associated @@ -103,6 +114,22 @@ public: /// object being processed. static void callCallouts(int index, CalloutHandle& handle); + /// @brief Calls the callouts/command handlers for a given command name. + /// + /// Iterates through the library handles and calls the command handlers + /// associated with the given command. It expects that the hook point + /// for this command exists (with a name being a command_name prefixed + /// with a dollar sign and with hyphens replaced with underscores). + /// + /// @param command_name Command name for which handlers should be called. + /// @param handle Reference to the CalloutHandle object for the current + /// object being processed. + /// + /// @throw NoSuchHook if the hook point for the specified command does + /// not exist. + static void callCommandHandlers(const std::string& command_name, + CalloutHandle& handle); + /// @brief Return pre-callouts library handle /// /// Returns a library handle that can be used by the server to register @@ -253,6 +280,17 @@ private: /// @throw NoSuchHook Given index does not correspond to a valid hook. bool calloutsPresentInternal(int index); + /// @brief Checks if control command handlers are present for the + /// specified command. + /// + /// @param command_name Command name for which handlers' presence should + /// be checked. + /// + /// @return true if there is a hook point associated with the specified + /// command and callouts/command handlers are installed for this hook + /// point, false otherwise. + bool commandHandlersPresentInternal(const std::string& command_name); + /// @brief Calls the callouts for a given hook /// /// @param index Index of the hook to call. @@ -260,6 +298,17 @@ private: /// object being processed. void callCalloutsInternal(int index, CalloutHandle& handle); + /// @brief Calls the callouts/command handlers for a given command name. + /// + /// @param command_name Command name for which handlers should be called. + /// @param handle Reference to the CalloutHandle object for the current + /// object being processed. + /// + /// @throw NoSuchHook if the hook point for the specified command does + /// not exist. + void callCommandHandlersInternal(const std::string& command_name, + CalloutHandle& handle); + /// @brief Return callout handle /// /// @return Shared pointer to a CalloutHandle object. diff --git a/src/lib/hooks/tests/full_callout_library.cc b/src/lib/hooks/tests/full_callout_library.cc index 8aef81e187..50a34296c1 100644 --- a/src/lib/hooks/tests/full_callout_library.cc +++ b/src/lib/hooks/tests/full_callout_library.cc @@ -101,6 +101,38 @@ hook_nonstandard_three(CalloutHandle& handle) { return (0); } +// First command handler assigns data to a result. + +static int +command_handler_one(CalloutHandle& handle) { + int data; + handle.getArgument("data_1", data); + + int result; + handle.getArgument("result", result); + + result = data; + handle.setArgument("result", result); + + return (0); +} + +// Second command handler multiples the result by data by 10. + +static int +command_handler_two(CalloutHandle& handle) { + int data; + handle.getArgument("data_2", data); + + int result; + handle.getArgument("result", result); + + result *= data * 10; + handle.setArgument("result", result); + + return (0); +} + // Framework functions int @@ -118,6 +150,10 @@ load(LibraryHandle& handle) { handle.registerCallout("hookpt_two", hook_nonstandard_two); handle.registerCallout("hookpt_three", hook_nonstandard_three); + // Register command_handler_one as control command handler. + handle.registerCommandHandler("command-one", command_handler_one); + handle.registerCommandHandler("command-two", command_handler_two); + return (0); } diff --git a/src/lib/hooks/tests/hooks_manager_unittest.cc b/src/lib/hooks/tests/hooks_manager_unittest.cc index 952c67c542..55e8138b9d 100644 --- a/src/lib/hooks/tests/hooks_manager_unittest.cc +++ b/src/lib/hooks/tests/hooks_manager_unittest.cc @@ -93,6 +93,42 @@ public: EXPECT_EQ(r3, result) << "hookpt_three" << COMMON_TEXT; } + /// @brief Call command handlers test. + /// + /// This test is similar to @c executeCallCallouts but it uses + /// @ref HooksManager::callCommandHandlers to execute the command + /// handlers for the following commands: 'command-one' and 'command-two'. + /// + /// @param r1..r2, d1..d2 Data (dN) and expected results (rN). + void executeCallCommandHandlers(int d1, int r1, int d2, int r2) { + static const char* COMMON_TEXT = " command handler returned the wrong value"; + static const char* RESULT = "result"; + + int result; + + // Set up a callout handle for the calls. + CalloutHandlePtr handle = HooksManager::createCalloutHandle(); + + // Initialize the argument RESULT. This simplifies testing by + // eliminating the generation of an exception when we try the unload + // test. In that case, RESULT is unchanged. + handle->setArgument(RESULT, -1); + + // Perform the first calculation: it should assign the data to the + // result. + handle->setArgument("data_1", d1); + HooksManager::callCommandHandlers("command-one", *handle); + handle->getArgument(RESULT, result); + EXPECT_EQ(d1, result) << "command-one" << COMMON_TEXT; + + // Perform the second calculation: it should multiply the data by 10 + // and return in the result. + handle->setArgument("data_2", d2); + HooksManager::callCommandHandlers("command-two", *handle); + handle->getArgument(RESULT, result); + EXPECT_EQ(r2, result) << "command-two" << COMMON_TEXT; + } + private: /// To avoid unused variable errors std::string dummy(int i) { @@ -138,6 +174,12 @@ TEST_F(HooksManagerTest, LoadLibraries) { executeCallCallouts(10, 3, 33, 2, 62, 3, 183); } + // r2 = 5 * 7 * 10 + { + SCOPED_TRACE("Calculation using command handlers"); + executeCallCommandHandlers(5, 5, 7, 350); + } + // Try unloading the libraries. EXPECT_NO_THROW(HooksManager::unloadLibraries()); @@ -538,6 +580,8 @@ TEST_F(HooksManagerTest, NoLibrariesCalloutsPresent) { EXPECT_FALSE(HooksManager::calloutsPresent(hookpt_one_index_)); EXPECT_FALSE(HooksManager::calloutsPresent(hookpt_two_index_)); EXPECT_FALSE(HooksManager::calloutsPresent(hookpt_three_index_)); + EXPECT_FALSE(HooksManager::commandHandlersPresent("command-one")); + EXPECT_FALSE(HooksManager::commandHandlersPresent("command-two")); } TEST_F(HooksManagerTest, NoLibrariesCallCallouts) {