library_manager_unittest.cc 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. // Copyright (C) 2013 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 <hooks/callout_handle.h>
  15. #include <hooks/callout_manager.h>
  16. #include <hooks/library_manager.h>
  17. #include <hooks/server_hooks.h>
  18. #include <gtest/gtest.h>
  19. #include <algorithm>
  20. #include <string>
  21. #include <vector>
  22. using namespace isc;
  23. using namespace isc::hooks;
  24. using namespace std;
  25. /// @brief Library manager test class
  26. class LibraryManagerTest : public ::testing::Test {
  27. public:
  28. /// @brief Constructor
  29. ///
  30. /// Sets up a collection of three LibraryHandle objects to use in the test.
  31. LibraryManagerTest() {
  32. // Set up the server hooks. There is sone singleton for all tests,
  33. // so reset it and explicitly set up the hooks for the test.
  34. ServerHooks& hooks = ServerHooks::getServerHooks();
  35. hooks.reset();
  36. alpha_index_ = hooks.registerHook("alpha");
  37. beta_index_ = hooks.registerHook("beta");
  38. gamma_index_ = hooks.registerHook("gamma");
  39. // Set up the callout manager with these hooks. Assume a maximum of
  40. // four libraries.
  41. callout_manager_.reset(new CalloutManager(1));
  42. // Set up the callout handle.
  43. callout_handle_.reset(new CalloutHandle(callout_manager_));
  44. }
  45. /// @brief Return the callout handle
  46. CalloutHandle& getCalloutHandle() {
  47. return (*callout_handle_);
  48. }
  49. /// @brief Return the callout manager
  50. boost::shared_ptr<CalloutManager> getCalloutManager() {
  51. return (callout_manager_);
  52. }
  53. /// Hook indexes. These are somewhat ubiquitous, so are made public for
  54. /// ease of reference instead of being accessible by a function.
  55. int alpha_index_;
  56. int beta_index_;
  57. int gamma_index_;
  58. private:
  59. /// Callout handle used in calls
  60. boost::shared_ptr<CalloutHandle> callout_handle_;
  61. /// Callout manager used for the test
  62. boost::shared_ptr<CalloutManager> callout_manager_;
  63. };
  64. /// @brief Library manager class
  65. ///
  66. /// This is an instance of the LibraryManager class but with the protected
  67. /// methods made public for test purposes.
  68. class PublicLibraryManager : public isc::hooks::LibraryManager {
  69. public:
  70. /// @brief Constructor
  71. ///
  72. /// Stores the library name. The actual loading is done in loadLibrary().
  73. ///
  74. /// @param name Name of the library to load. This should be an absolute
  75. /// path name.
  76. /// @param index Index of this library
  77. /// @param manager CalloutManager object
  78. PublicLibraryManager(const std::string& name, int index,
  79. const boost::shared_ptr<CalloutManager>& manager)
  80. : LibraryManager(name, index, manager)
  81. {}
  82. /// Public methods that call protected methods on the superclass
  83. //@{
  84. /// @brief Open library
  85. ///
  86. /// Opens the library associated with this LibraryManager. A message is
  87. /// logged on an error.
  88. ///
  89. /// @return true if the library opened successfully, false otherwise.
  90. bool openLibrary() {
  91. return (LibraryManager::openLibrary());
  92. }
  93. /// @brief Close library
  94. ///
  95. /// Closes the library associated with this LibraryManager. A message is
  96. /// logged on an error.
  97. ///
  98. /// @return true if the library closed successfully, false otherwise.
  99. bool closeLibrary() {
  100. return (LibraryManager::closeLibrary());
  101. }
  102. /// @brief Check library version
  103. ///
  104. /// With the library open, accesses the "version()" function and, if
  105. /// present, checks the returned value against the hooks version symbol
  106. /// for the currently running BIND 10.
  107. ///
  108. /// If there is no version() function, or if there is a mismatch in
  109. /// version number, a message logged.
  110. ///
  111. /// @return bool true if the check succeeded
  112. bool checkVersion() const {
  113. return (LibraryManager::checkVersion());
  114. }
  115. //@}
  116. };
  117. // Names of the libraries used in these tests. These libraries are built using
  118. // libtool, so we need to look in the hidden ".libs" directory to locate the
  119. // .so file. Note that we access the .so file - libtool creates this as a
  120. // like to the real shared library.
  121. static const char* NOT_PRESENT_LIBRARY = "/home/stephen/bind10/src/lib/hooks/tests/.libs/libnothere.so";
  122. static const char* NO_VERSION_LIBRARY = "/home/stephen/bind10/src/lib/hooks/tests/.libs/libnv.so";
  123. static const char* INCORRECT_VERSION_LIBRARY = "/home/stephen/bind10/src/lib/hooks/tests/.libs/libiv.so";
  124. static const char* BASIC_CALLOUT_LIBRARY = "/home/stephen/bind10/src/lib/hooks/tests/.libs/libbco.so";
  125. namespace {
  126. // Tests that OpenLibrary reports an error for an unknown library.
  127. TEST_F(LibraryManagerTest, NonExistentLibrary) {
  128. // Check that opening a non-existent library fails.
  129. PublicLibraryManager lib_manager(std::string(NOT_PRESENT_LIBRARY),
  130. 0, getCalloutManager());
  131. EXPECT_FALSE(lib_manager.openLibrary());
  132. }
  133. // Tests that OpenLibrary handles the case of no version present.
  134. TEST_F(LibraryManagerTest, NoVersionFunction) {
  135. PublicLibraryManager lib_manager(std::string(NO_VERSION_LIBRARY),
  136. 0, getCalloutManager());
  137. // Open should succeed.
  138. EXPECT_TRUE(lib_manager.openLibrary());
  139. // Version check should fail.
  140. EXPECT_FALSE(lib_manager.checkVersion());
  141. // Tidy up.
  142. EXPECT_TRUE(lib_manager.closeLibrary());
  143. }
  144. // Tests that OpenLibrary reports an error for an unknown library.
  145. TEST_F(LibraryManagerTest, IncorrectVersionReturned) {
  146. PublicLibraryManager lib_manager(std::string(INCORRECT_VERSION_LIBRARY),
  147. 0, getCalloutManager());
  148. // Open should succeed.
  149. EXPECT_TRUE(lib_manager.openLibrary());
  150. // Version check should fail.
  151. EXPECT_FALSE(lib_manager.checkVersion());
  152. // Tidy up.
  153. EXPECT_TRUE(lib_manager.closeLibrary());
  154. }
  155. // Tests that the openLibrary() and closeLibrary() methods work.
  156. TEST_F(LibraryManagerTest, OpenClose) {
  157. // Create the library manager.
  158. PublicLibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
  159. 0, getCalloutManager());
  160. // Open and close the library
  161. EXPECT_TRUE(lib_manager.openLibrary());
  162. EXPECT_TRUE(lib_manager.closeLibrary());
  163. // Check that closing an already closed library causes no problems.
  164. EXPECT_TRUE(lib_manager.closeLibrary());
  165. }
  166. // Checks the basic functionality - loads a library where the callouts are
  167. // named after the hooks, calls the callouts and checks the results.
  168. TEST_F(LibraryManagerTest, BasicCalloutTest) {
  169. // Load the only library, specifying the index of 0 as it's the only
  170. // library. This should load all callouts.
  171. LibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
  172. 0, getCalloutManager());
  173. EXPECT_NO_THROW(lib_manager.loadLibrary());
  174. // Set up abbreviations...
  175. boost::shared_ptr<CalloutManager> co_manager = getCalloutManager();
  176. CalloutHandle& callout_handle = getCalloutHandle();
  177. // Now execute the callouts in the order expected. context_create
  178. // always comes first. This sets the context value to 10.
  179. co_manager->callCallouts(ServerHooks::CONTEXT_CREATE, callout_handle);
  180. // First callout adds 5 to the context value.
  181. callout_handle.setArgument("data_1", static_cast<int>(5));
  182. co_manager->callCallouts(alpha_index_, callout_handle);
  183. // Second callout multiples the context value by 7
  184. callout_handle.setArgument("data_2", static_cast<int>(7));
  185. co_manager->callCallouts(beta_index_, callout_handle);
  186. // Third callour retrieves the context value.
  187. co_manager->callCallouts(gamma_index_, callout_handle);
  188. int result;
  189. callout_handle.getArgument("result", result);
  190. EXPECT_EQ(105, result);
  191. }
  192. } // Anonymous namespace