callout_manager_unittest.cc 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  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 <exceptions/exceptions.h>
  15. #include <hooks/callout_handle.h>
  16. #include <hooks/callout_manager.h>
  17. #include <hooks/library_handle.h>
  18. #include <hooks/server_hooks.h>
  19. #include <boost/scoped_ptr.hpp>
  20. #include <gtest/gtest.h>
  21. #include <algorithm>
  22. #include <climits>
  23. #include <string>
  24. #include <vector>
  25. /// @file
  26. /// @brief CalloutManager and LibraryHandle tests
  27. ///
  28. /// These set of tests check the CalloutManager and LibraryHandle. They are
  29. /// together in the same file because the LibraryHandle is little more than a
  30. /// restricted interface to the CalloutManager, and a lot of the support
  31. /// structure for the tests is common.
  32. using namespace isc;
  33. using namespace isc::hooks;
  34. using namespace std;
  35. namespace {
  36. class CalloutManagerTest : public ::testing::Test {
  37. public:
  38. /// @brief Constructor
  39. ///
  40. /// Sets up a collection of three LibraryHandle objects to use in the test.
  41. CalloutManagerTest() {
  42. // Set up the server hooks. There is one singleton for all tests,
  43. // so reset it and explicitly set up the hooks for the test.
  44. ServerHooks& hooks = ServerHooks::getServerHooks();
  45. hooks.reset();
  46. alpha_index_ = hooks.registerHook("alpha");
  47. beta_index_ = hooks.registerHook("beta");
  48. gamma_index_ = hooks.registerHook("gamma");
  49. delta_index_ = hooks.registerHook("delta");
  50. // Set up the callout manager with these hooks. Assume a maximum of
  51. // four libraries.
  52. callout_manager_.reset(new CalloutManager(10));
  53. // Set up the callout handle.
  54. callout_handle_.reset(new CalloutHandle(callout_manager_));
  55. // Initialize the static variable.
  56. callout_value_ = 0;
  57. }
  58. /// @brief Return the callout handle
  59. CalloutHandle& getCalloutHandle() {
  60. return (*callout_handle_);
  61. }
  62. /// @brief Return the callout manager
  63. boost::shared_ptr<CalloutManager> getCalloutManager() {
  64. return (callout_manager_);
  65. }
  66. /// Static variable used for accumulating information
  67. static int callout_value_;
  68. /// Hook indexes. These are somewhat ubiquitous, so are made public for
  69. /// ease of reference instead of being accessible by a function.
  70. int alpha_index_;
  71. int beta_index_;
  72. int gamma_index_;
  73. int delta_index_;
  74. private:
  75. /// Callout handle used in calls
  76. boost::shared_ptr<CalloutHandle> callout_handle_;
  77. /// Callout manager used for the test
  78. boost::shared_ptr<CalloutManager> callout_manager_;
  79. };
  80. // Definition of the static variable.
  81. int CalloutManagerTest::callout_value_ = 0;
  82. // Callout definitions
  83. //
  84. // The callouts defined here are structured in such a way that it is possible
  85. // to determine the order in which they are called and whether they are called
  86. // at all. The method used is simple - after a sequence of callouts, the digits
  87. // in the value, reading left to right, determines the order of the callouts
  88. // called. For example, callout one followed by two followed by three followed
  89. // by two followed by one results in a value of 12321.
  90. //
  91. // Functions return a zero to indicate success.
  92. extern "C" {
  93. int callout_general(int number) {
  94. CalloutManagerTest::callout_value_ =
  95. 10 * CalloutManagerTest::callout_value_ + number;
  96. return (0);
  97. }
  98. int callout_one(CalloutHandle&) {
  99. return (callout_general(1));
  100. }
  101. int callout_two(CalloutHandle&) {
  102. return (callout_general(2));
  103. }
  104. int callout_three(CalloutHandle&) {
  105. return (callout_general(3));
  106. }
  107. int callout_four(CalloutHandle&) {
  108. return (callout_general(4));
  109. }
  110. int callout_five(CalloutHandle&) {
  111. return (callout_general(5));
  112. }
  113. int callout_six(CalloutHandle&) {
  114. return (callout_general(6));
  115. }
  116. int callout_seven(CalloutHandle&) {
  117. return (callout_general(7));
  118. }
  119. // The next functions are duplicates of some of the above, but return an error.
  120. int callout_one_error(CalloutHandle& handle) {
  121. (void) callout_one(handle);
  122. return (1);
  123. }
  124. int callout_two_error(CalloutHandle& handle) {
  125. (void) callout_two(handle);
  126. return (1);
  127. }
  128. int callout_three_error(CalloutHandle& handle) {
  129. (void) callout_three(handle);
  130. return (1);
  131. }
  132. int callout_four_error(CalloutHandle& handle) {
  133. (void) callout_four(handle);
  134. return (1);
  135. }
  136. }; // extern "C"
  137. // *** Callout Tests ***
  138. //
  139. // The next set of tests check that callouts can be called.
  140. // Constructor - check that we trap bad parameters.
  141. TEST_F(CalloutManagerTest, BadConstructorParameters) {
  142. boost::scoped_ptr<CalloutManager> cm;
  143. // Invalid number of libraries
  144. EXPECT_THROW(cm.reset(new CalloutManager(-1)), BadValue);
  145. }
  146. // Check the number of libraries is reported successfully.
  147. TEST_F(CalloutManagerTest, NumberOfLibraries) {
  148. boost::scoped_ptr<CalloutManager> cm;
  149. // Check two valid values of number of libraries to ensure that the
  150. // GetNumLibraries() returns the value set.
  151. EXPECT_NO_THROW(cm.reset(new CalloutManager()));
  152. EXPECT_EQ(0, cm->getNumLibraries());
  153. EXPECT_NO_THROW(cm.reset(new CalloutManager(0)));
  154. EXPECT_EQ(0, cm->getNumLibraries());
  155. EXPECT_NO_THROW(cm.reset(new CalloutManager(4)));
  156. EXPECT_EQ(4, cm->getNumLibraries());
  157. EXPECT_NO_THROW(cm.reset(new CalloutManager(42)));
  158. EXPECT_EQ(42, cm->getNumLibraries());
  159. }
  160. // Check that we can only set the current library index to the correct values.
  161. TEST_F(CalloutManagerTest, CheckLibraryIndex) {
  162. // Check valid indexes. As the callout manager is sized for 10 libraries,
  163. // we expect:
  164. //
  165. // -1 to be valid as it is the standard "invalid" value.
  166. // 0 to be valid for the pre-user library callouts
  167. // 1-10 to be valid for the user-library callouts
  168. // INT_MAX to be valid for the post-user library callouts
  169. //
  170. // All other values to be invalid.
  171. for (int i = -1; i < 11; ++i) {
  172. EXPECT_NO_THROW(getCalloutManager()->setLibraryIndex(i));
  173. EXPECT_EQ(i, getCalloutManager()->getLibraryIndex());
  174. }
  175. EXPECT_NO_THROW(getCalloutManager()->setLibraryIndex(INT_MAX));
  176. EXPECT_EQ(INT_MAX, getCalloutManager()->getLibraryIndex());
  177. // Check invalid ones
  178. EXPECT_THROW(getCalloutManager()->setLibraryIndex(-2), NoSuchLibrary);
  179. EXPECT_THROW(getCalloutManager()->setLibraryIndex(11), NoSuchLibrary);
  180. }
  181. // Check that we can only register callouts on valid hook names.
  182. TEST_F(CalloutManagerTest, ValidHookNames) {
  183. getCalloutManager()->setLibraryIndex(0);
  184. EXPECT_NO_THROW(getCalloutManager()->registerCallout("alpha", callout_one));
  185. EXPECT_THROW(getCalloutManager()->registerCallout("unknown", callout_one),
  186. NoSuchHook);
  187. }
  188. // Check we can register callouts appropriately.
  189. TEST_F(CalloutManagerTest, RegisterCallout) {
  190. // Ensure that no callouts are attached to any of the hooks.
  191. EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
  192. EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
  193. // Set up so that hooks "alpha" and "beta" have callouts attached from a
  194. // different libraries.
  195. getCalloutManager()->setLibraryIndex(0);
  196. getCalloutManager()->registerCallout("alpha", callout_one);
  197. getCalloutManager()->setLibraryIndex(1);
  198. getCalloutManager()->registerCallout("beta", callout_two);
  199. // Check all is as expected.
  200. EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
  201. EXPECT_TRUE(getCalloutManager()->calloutsPresent(beta_index_));
  202. EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
  203. EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
  204. // Check that calling the callouts returns as expected. (This is also a
  205. // test of the callCallouts method.)
  206. callout_value_ = 0;
  207. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  208. EXPECT_EQ(1, callout_value_);
  209. callout_value_ = 0;
  210. getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
  211. EXPECT_EQ(2, callout_value_);
  212. // Register some more callouts from different libraries on hook "alpha".
  213. getCalloutManager()->setLibraryIndex(2);
  214. getCalloutManager()->registerCallout("alpha", callout_three);
  215. getCalloutManager()->registerCallout("alpha", callout_four);
  216. getCalloutManager()->setLibraryIndex(3);
  217. getCalloutManager()->registerCallout("alpha", callout_five);
  218. // Check it is as expected.
  219. callout_value_ = 0;
  220. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  221. EXPECT_EQ(1345, callout_value_);
  222. // ... and check the additional callouts were not registered on the "beta"
  223. // hook.
  224. callout_value_ = 0;
  225. getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
  226. EXPECT_EQ(2, callout_value_);
  227. // Add another callout to hook "alpha" from library index 2 - this should
  228. // appear at the end of the callout list for that library.
  229. getCalloutManager()->setLibraryIndex(2);
  230. getCalloutManager()->registerCallout("alpha", callout_six);
  231. callout_value_ = 0;
  232. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  233. EXPECT_EQ(13465, callout_value_);
  234. // Add a callout from library index 1 - this should appear between the
  235. // callouts from library index 0 and library index 2.
  236. getCalloutManager()->setLibraryIndex(1);
  237. getCalloutManager()->registerCallout("alpha", callout_seven);
  238. callout_value_ = 0;
  239. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  240. EXPECT_EQ(173465, callout_value_);
  241. }
  242. // Check the "calloutsPresent()" method.
  243. TEST_F(CalloutManagerTest, CalloutsPresent) {
  244. // Ensure that no callouts are attached to any of the hooks.
  245. EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
  246. EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
  247. EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
  248. EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
  249. // Set up so that hooks "alpha", "beta" and "delta" have callouts attached
  250. // to them, and callout "gamma" does not. (In the statements below, the
  251. // exact callouts attached to a hook are not relevant - only the fact
  252. // that some callouts are). Chose the libraries for which the callouts
  253. // are registered randomly.
  254. getCalloutManager()->setLibraryIndex(0);
  255. getCalloutManager()->registerCallout("alpha", callout_one);
  256. getCalloutManager()->setLibraryIndex(1);
  257. getCalloutManager()->registerCallout("alpha", callout_two);
  258. getCalloutManager()->registerCallout("beta", callout_two);
  259. getCalloutManager()->setLibraryIndex(3);
  260. getCalloutManager()->registerCallout("alpha", callout_three);
  261. getCalloutManager()->registerCallout("delta", callout_four);
  262. // Check all is as expected.
  263. EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
  264. EXPECT_TRUE(getCalloutManager()->calloutsPresent(beta_index_));
  265. EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
  266. EXPECT_TRUE(getCalloutManager()->calloutsPresent(delta_index_));
  267. // Check we fail on an invalid hook index.
  268. EXPECT_THROW(getCalloutManager()->calloutsPresent(42), NoSuchHook);
  269. EXPECT_THROW(getCalloutManager()->calloutsPresent(-1), NoSuchHook);
  270. }
  271. // Test that calling a hook with no callouts on it returns success.
  272. TEST_F(CalloutManagerTest, CallNoCallouts) {
  273. // Ensure that no callouts are attached to any of the hooks.
  274. EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
  275. EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
  276. EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
  277. EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
  278. // Call the callouts on an arbitrary hook and ensure that nothing happens.
  279. callout_value_ = 475;
  280. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  281. EXPECT_EQ(475, callout_value_); // Unchanged
  282. }
  283. // Test that the callouts are called in the correct order (i.e. the callouts
  284. // from the first library in the order they were registered, then the callouts
  285. // from the second library in the order they were registered etc.)
  286. TEST_F(CalloutManagerTest, CallCalloutsSuccess) {
  287. // Ensure that no callouts are attached to any of the hooks.
  288. EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
  289. EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
  290. EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
  291. EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
  292. // Each library contributes one callout on hook "alpha".
  293. callout_value_ = 0;
  294. getCalloutManager()->setLibraryIndex(1);
  295. getCalloutManager()->registerCallout("alpha", callout_one);
  296. getCalloutManager()->setLibraryIndex(1);
  297. getCalloutManager()->registerCallout("alpha", callout_two);
  298. getCalloutManager()->setLibraryIndex(2);
  299. getCalloutManager()->registerCallout("alpha", callout_three);
  300. getCalloutManager()->setLibraryIndex(3);
  301. getCalloutManager()->registerCallout("alpha", callout_four);
  302. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  303. EXPECT_EQ(1234, callout_value_);
  304. // Do a random selection of callouts on hook "beta".
  305. callout_value_ = 0;
  306. getCalloutManager()->setLibraryIndex(0);
  307. getCalloutManager()->registerCallout("beta", callout_one);
  308. getCalloutManager()->registerCallout("beta", callout_three);
  309. getCalloutManager()->setLibraryIndex(1);
  310. getCalloutManager()->registerCallout("beta", callout_two);
  311. getCalloutManager()->setLibraryIndex(3);
  312. getCalloutManager()->registerCallout("beta", callout_four);
  313. getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
  314. EXPECT_EQ(1324, callout_value_);
  315. // Ensure that calling the callouts on a hook with no callouts works.
  316. callout_value_ = 0;
  317. getCalloutManager()->callCallouts(gamma_index_, getCalloutHandle());
  318. EXPECT_EQ(0, callout_value_);
  319. }
  320. // Test that the callouts are called in order, but that callouts occurring
  321. // after a callout that returns an error are not called.
  322. //
  323. // (Note: in this test, the callouts that return an error set the value of
  324. // callout_value_ before they return the error code.)
  325. TEST_F(CalloutManagerTest, CallCalloutsError) {
  326. // Ensure that no callouts are attached to any of the hooks.
  327. EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
  328. EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
  329. EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
  330. EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
  331. // Each library contributing one callout on hook "alpha". The first callout
  332. // returns an error (after adding its value to the result).
  333. callout_value_ = 0;
  334. getCalloutManager()->setLibraryIndex(0);
  335. getCalloutManager()->registerCallout("alpha", callout_one_error);
  336. getCalloutManager()->setLibraryIndex(1);
  337. getCalloutManager()->registerCallout("alpha", callout_two);
  338. getCalloutManager()->setLibraryIndex(2);
  339. getCalloutManager()->registerCallout("alpha", callout_three);
  340. getCalloutManager()->setLibraryIndex(3);
  341. getCalloutManager()->registerCallout("alpha", callout_four);
  342. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  343. EXPECT_EQ(1234, callout_value_);
  344. // Each library contributing multiple callouts on hook "beta". The last
  345. // callout on the first library returns an error.
  346. callout_value_ = 0;
  347. getCalloutManager()->setLibraryIndex(0);
  348. getCalloutManager()->registerCallout("beta", callout_one);
  349. getCalloutManager()->registerCallout("beta", callout_one_error);
  350. getCalloutManager()->setLibraryIndex(1);
  351. getCalloutManager()->registerCallout("beta", callout_two);
  352. getCalloutManager()->registerCallout("beta", callout_two);
  353. getCalloutManager()->registerCallout("beta", callout_three);
  354. getCalloutManager()->registerCallout("beta", callout_three);
  355. getCalloutManager()->setLibraryIndex(3);
  356. getCalloutManager()->registerCallout("beta", callout_four);
  357. getCalloutManager()->registerCallout("beta", callout_four);
  358. getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
  359. EXPECT_EQ(11223344, callout_value_);
  360. // A callout in a random position in the callout list returns an error.
  361. callout_value_ = 0;
  362. getCalloutManager()->setLibraryIndex(0);
  363. getCalloutManager()->registerCallout("gamma", callout_one);
  364. getCalloutManager()->registerCallout("gamma", callout_one);
  365. getCalloutManager()->setLibraryIndex(1);
  366. getCalloutManager()->registerCallout("gamma", callout_two);
  367. getCalloutManager()->registerCallout("gamma", callout_two);
  368. getCalloutManager()->setLibraryIndex(3);
  369. getCalloutManager()->registerCallout("gamma", callout_four_error);
  370. getCalloutManager()->registerCallout("gamma", callout_four);
  371. getCalloutManager()->callCallouts(gamma_index_, getCalloutHandle());
  372. EXPECT_EQ(112244, callout_value_);
  373. // The last callout on a hook returns an error.
  374. callout_value_ = 0;
  375. getCalloutManager()->setLibraryIndex(0);
  376. getCalloutManager()->registerCallout("delta", callout_one);
  377. getCalloutManager()->registerCallout("delta", callout_one);
  378. getCalloutManager()->setLibraryIndex(1);
  379. getCalloutManager()->registerCallout("delta", callout_two);
  380. getCalloutManager()->registerCallout("delta", callout_two);
  381. getCalloutManager()->setLibraryIndex(2);
  382. getCalloutManager()->registerCallout("delta", callout_three);
  383. getCalloutManager()->registerCallout("delta", callout_three);
  384. getCalloutManager()->setLibraryIndex(3);
  385. getCalloutManager()->registerCallout("delta", callout_four);
  386. getCalloutManager()->registerCallout("delta", callout_four_error);
  387. getCalloutManager()->callCallouts(delta_index_, getCalloutHandle());
  388. EXPECT_EQ(11223344, callout_value_);
  389. }
  390. // Now test that we can deregister a single callout on a hook.
  391. TEST_F(CalloutManagerTest, DeregisterSingleCallout) {
  392. // Ensure that no callouts are attached to any of the hooks.
  393. EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
  394. EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
  395. EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
  396. EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
  397. // Add a callout to hook "alpha" and check it is added correctly.
  398. callout_value_ = 0;
  399. getCalloutManager()->setLibraryIndex(0);
  400. getCalloutManager()->registerCallout("alpha", callout_two);
  401. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  402. EXPECT_EQ(2, callout_value_);
  403. // Remove it and check that the no callouts are present. We have to reset
  404. // the current library index here as it was invalidated by the call
  405. // to callCallouts().
  406. getCalloutManager()->setLibraryIndex(0);
  407. EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
  408. EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
  409. EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
  410. }
  411. // Now test that we can deregister a single callout on a hook that has multiple
  412. // callouts from the same library.
  413. TEST_F(CalloutManagerTest, DeregisterSingleCalloutSameLibrary) {
  414. // Ensure that no callouts are attached to any of the hooks.
  415. EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
  416. EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
  417. EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
  418. EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
  419. // Add multiple callouts to hook "alpha".
  420. callout_value_ = 0;
  421. getCalloutManager()->setLibraryIndex(0);
  422. getCalloutManager()->registerCallout("alpha", callout_one);
  423. getCalloutManager()->registerCallout("alpha", callout_two);
  424. getCalloutManager()->registerCallout("alpha", callout_three);
  425. getCalloutManager()->registerCallout("alpha", callout_four);
  426. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  427. EXPECT_EQ(1234, callout_value_);
  428. // Remove the callout_two callout. We have to reset the current library
  429. // index here as it was invalidated by the call to callCallouts().
  430. getCalloutManager()->setLibraryIndex(0);
  431. EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
  432. callout_value_ = 0;
  433. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  434. EXPECT_EQ(134, callout_value_);
  435. // Try removing it again.
  436. getCalloutManager()->setLibraryIndex(0);
  437. EXPECT_FALSE(getCalloutManager()->deregisterCallout("alpha", callout_two));
  438. callout_value_ = 0;
  439. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  440. EXPECT_EQ(134, callout_value_);
  441. }
  442. // Check we can deregister multiple callouts from the same library.
  443. TEST_F(CalloutManagerTest, DeregisterMultipleCalloutsSameLibrary) {
  444. // Ensure that no callouts are attached to any of the hooks.
  445. EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
  446. EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
  447. EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
  448. EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
  449. // Each library contributes one callout on hook "alpha".
  450. callout_value_ = 0;
  451. getCalloutManager()->setLibraryIndex(0);
  452. getCalloutManager()->registerCallout("alpha", callout_one);
  453. getCalloutManager()->registerCallout("alpha", callout_two);
  454. getCalloutManager()->registerCallout("alpha", callout_one);
  455. getCalloutManager()->registerCallout("alpha", callout_two);
  456. getCalloutManager()->registerCallout("alpha", callout_three);
  457. getCalloutManager()->registerCallout("alpha", callout_four);
  458. getCalloutManager()->registerCallout("alpha", callout_three);
  459. getCalloutManager()->registerCallout("alpha", callout_four);
  460. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  461. EXPECT_EQ(12123434, callout_value_);
  462. // Remove the callout_two callouts. We have to reset the current library
  463. // index here as it was invalidated by the call to callCallouts().
  464. getCalloutManager()->setLibraryIndex(0);
  465. EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
  466. callout_value_ = 0;
  467. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  468. EXPECT_EQ(113434, callout_value_);
  469. // Try removing multiple callouts that includes one at the end of the
  470. // list of callouts.
  471. getCalloutManager()->setLibraryIndex(0);
  472. EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_four));
  473. callout_value_ = 0;
  474. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  475. EXPECT_EQ(1133, callout_value_);
  476. // ... and from the start.
  477. getCalloutManager()->setLibraryIndex(0);
  478. EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_one));
  479. callout_value_ = 0;
  480. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  481. EXPECT_EQ(33, callout_value_);
  482. // ... and the remaining callouts.
  483. getCalloutManager()->setLibraryIndex(0);
  484. EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_three));
  485. callout_value_ = 0;
  486. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  487. EXPECT_EQ(0, callout_value_);
  488. EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
  489. }
  490. // Check we can deregister multiple callouts from multiple libraries.
  491. TEST_F(CalloutManagerTest, DeregisterMultipleCalloutsMultipleLibraries) {
  492. // Ensure that no callouts are attached to any of the hooks.
  493. EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
  494. EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
  495. EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
  496. EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
  497. // Each library contributes two callouts to hook "alpha".
  498. callout_value_ = 0;
  499. getCalloutManager()->setLibraryIndex(0);
  500. getCalloutManager()->registerCallout("alpha", callout_one);
  501. getCalloutManager()->registerCallout("alpha", callout_two);
  502. getCalloutManager()->setLibraryIndex(1);
  503. getCalloutManager()->registerCallout("alpha", callout_three);
  504. getCalloutManager()->registerCallout("alpha", callout_four);
  505. getCalloutManager()->setLibraryIndex(2);
  506. getCalloutManager()->registerCallout("alpha", callout_five);
  507. getCalloutManager()->registerCallout("alpha", callout_two);
  508. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  509. EXPECT_EQ(123452, callout_value_);
  510. // Remove the callout_two callout from library 0. It should not affect
  511. // the second callout_two callout registered by library 2.
  512. getCalloutManager()->setLibraryIndex(0);
  513. EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
  514. callout_value_ = 0;
  515. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  516. EXPECT_EQ(13452, callout_value_);
  517. }
  518. // Check we can deregister all callouts from a single library.
  519. TEST_F(CalloutManagerTest, DeregisterAllCallouts) {
  520. // Ensure that no callouts are attached to hook one.
  521. EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
  522. // Each library contributes two callouts to hook "alpha".
  523. callout_value_ = 0;
  524. getCalloutManager()->setLibraryIndex(0);
  525. getCalloutManager()->registerCallout("alpha", callout_one);
  526. getCalloutManager()->registerCallout("alpha", callout_two);
  527. getCalloutManager()->setLibraryIndex(1);
  528. getCalloutManager()->registerCallout("alpha", callout_three);
  529. getCalloutManager()->registerCallout("alpha", callout_four);
  530. getCalloutManager()->setLibraryIndex(2);
  531. getCalloutManager()->registerCallout("alpha", callout_five);
  532. getCalloutManager()->registerCallout("alpha", callout_six);
  533. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  534. EXPECT_EQ(123456, callout_value_);
  535. // Remove all callouts from library index 1.
  536. getCalloutManager()->setLibraryIndex(1);
  537. EXPECT_TRUE(getCalloutManager()->deregisterAllCallouts("alpha"));
  538. callout_value_ = 0;
  539. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  540. EXPECT_EQ(1256, callout_value_);
  541. // Remove all callouts from library index 2.
  542. getCalloutManager()->setLibraryIndex(2);
  543. EXPECT_TRUE(getCalloutManager()->deregisterAllCallouts("alpha"));
  544. callout_value_ = 0;
  545. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  546. EXPECT_EQ(12, callout_value_);
  547. }
  548. // Check that we can register/deregister callouts on different libraries
  549. // and different hooks, and that the callout instances are regarded as
  550. // unique and do not affect one another.
  551. TEST_F(CalloutManagerTest, MultipleCalloutsLibrariesHooks) {
  552. // Ensure that no callouts are attached to any of the hooks.
  553. EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
  554. EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
  555. EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
  556. EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
  557. // Register callouts on the alpha hook.
  558. callout_value_ = 0;
  559. getCalloutManager()->setLibraryIndex(0);
  560. getCalloutManager()->registerCallout("alpha", callout_one);
  561. getCalloutManager()->registerCallout("alpha", callout_two);
  562. getCalloutManager()->setLibraryIndex(1);
  563. getCalloutManager()->registerCallout("alpha", callout_three);
  564. getCalloutManager()->registerCallout("alpha", callout_four);
  565. getCalloutManager()->setLibraryIndex(2);
  566. getCalloutManager()->registerCallout("alpha", callout_five);
  567. getCalloutManager()->registerCallout("alpha", callout_two);
  568. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  569. EXPECT_EQ(123452, callout_value_);
  570. // Register the same callouts on the beta hook, and check that those
  571. // on the alpha hook are not affected.
  572. callout_value_ = 0;
  573. getCalloutManager()->setLibraryIndex(0);
  574. getCalloutManager()->registerCallout("beta", callout_five);
  575. getCalloutManager()->registerCallout("beta", callout_one);
  576. getCalloutManager()->setLibraryIndex(2);
  577. getCalloutManager()->registerCallout("beta", callout_four);
  578. getCalloutManager()->registerCallout("beta", callout_three);
  579. getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
  580. EXPECT_EQ(5143, callout_value_);
  581. // Check that the order of callouts on the alpha hook has not been affected.
  582. callout_value_ = 0;
  583. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  584. EXPECT_EQ(123452, callout_value_);
  585. // Remove callout four from beta and check that alpha is not affected.
  586. getCalloutManager()->setLibraryIndex(2);
  587. EXPECT_TRUE(getCalloutManager()->deregisterCallout("beta", callout_four));
  588. callout_value_ = 0;
  589. getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
  590. EXPECT_EQ(513, callout_value_);
  591. callout_value_ = 0;
  592. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  593. EXPECT_EQ(123452, callout_value_);
  594. }
  595. // Library handle tests. As by inspection the LibraryHandle can be seen to be
  596. // little more than shell around CalloutManager, only a basic set of tests
  597. // is done concerning registration and deregistration of functions.
  598. //
  599. // More extensive tests (i.e. checking that when a callout is called it can
  600. // only register and deregister callouts within its library) require that
  601. // the CalloutHandle object pass the appropriate LibraryHandle to the
  602. // callout. These tests are done in the handles_unittest tests.
  603. TEST_F(CalloutManagerTest, LibraryHandleRegistration) {
  604. // Ensure that no callouts are attached to any of the hooks.
  605. EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
  606. // Set up so that hooks "alpha" and "beta" have callouts attached from a
  607. // different libraries.
  608. getCalloutManager()->setLibraryIndex(0);
  609. getCalloutManager()->getLibraryHandle().registerCallout("alpha",
  610. callout_one);
  611. getCalloutManager()->getLibraryHandle().registerCallout("alpha",
  612. callout_two);
  613. getCalloutManager()->setLibraryIndex(1);
  614. getCalloutManager()->getLibraryHandle().registerCallout("alpha",
  615. callout_three);
  616. getCalloutManager()->getLibraryHandle().registerCallout("alpha",
  617. callout_four);
  618. // Check all is as expected.
  619. EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
  620. EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
  621. EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
  622. EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
  623. // Check that calling the callouts returns as expected. (This is also a
  624. // test of the callCallouts method.)
  625. callout_value_ = 0;
  626. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  627. EXPECT_EQ(1234, callout_value_);
  628. // Deregister a callout on library index 0 (after we check we can't
  629. // deregister it through library index 1).
  630. getCalloutManager()->setLibraryIndex(1);
  631. EXPECT_FALSE(getCalloutManager()->deregisterCallout("alpha", callout_two));
  632. callout_value_ = 0;
  633. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  634. EXPECT_EQ(1234, callout_value_);
  635. getCalloutManager()->setLibraryIndex(0);
  636. EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
  637. callout_value_ = 0;
  638. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  639. EXPECT_EQ(134, callout_value_);
  640. // Deregister all callouts on library index 1.
  641. getCalloutManager()->setLibraryIndex(1);
  642. EXPECT_TRUE(getCalloutManager()->deregisterAllCallouts("alpha"));
  643. callout_value_ = 0;
  644. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  645. EXPECT_EQ(1, callout_value_);
  646. }
  647. // A repeat of the test above, but using the alternate constructor for the
  648. // LibraryHandle.
  649. TEST_F(CalloutManagerTest, LibraryHandleAlternateConstructor) {
  650. // Ensure that no callouts are attached to any of the hooks.
  651. EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
  652. // Set up so that hooks "alpha" and "beta" have callouts attached from a
  653. // different libraries.
  654. LibraryHandle lh0(getCalloutManager().get(), 0);
  655. lh0.registerCallout("alpha", callout_one);
  656. lh0.registerCallout("alpha", callout_two);
  657. LibraryHandle lh1(getCalloutManager().get(), 1);
  658. lh1.registerCallout("alpha", callout_three);
  659. lh1.registerCallout("alpha", callout_four);
  660. // Check all is as expected.
  661. EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
  662. EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
  663. EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
  664. EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
  665. // Check that calling the callouts returns as expected. (This is also a
  666. // test of the callCallouts method.)
  667. callout_value_ = 0;
  668. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  669. EXPECT_EQ(1234, callout_value_);
  670. // Deregister a callout on library index 0 (after we check we can't
  671. // deregister it through library index 1).
  672. EXPECT_FALSE(lh1.deregisterCallout("alpha", callout_two));
  673. callout_value_ = 0;
  674. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  675. EXPECT_EQ(1234, callout_value_);
  676. EXPECT_TRUE(lh0.deregisterCallout("alpha", callout_two));
  677. callout_value_ = 0;
  678. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  679. EXPECT_EQ(134, callout_value_);
  680. // Deregister all callouts on library index 1.
  681. EXPECT_TRUE(lh1.deregisterAllCallouts("alpha"));
  682. callout_value_ = 0;
  683. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  684. EXPECT_EQ(1, callout_value_);
  685. }
  686. // Check that the pre- and post- user callout library handles work
  687. // appropriately with no user libraries.
  688. TEST_F(CalloutManagerTest, LibraryHandlePrePostNoLibraries) {
  689. // Create a local callout manager and callout handle to reflect no libraries
  690. // being loaded.
  691. boost::shared_ptr<CalloutManager> manager(new CalloutManager(0));
  692. CalloutHandle handle(manager);
  693. // Ensure that no callouts are attached to any of the hooks.
  694. EXPECT_FALSE(manager->calloutsPresent(alpha_index_));
  695. // Setup the pre-and post callouts.
  696. manager->getPostLibraryHandle().registerCallout("alpha", callout_four);
  697. manager->getPreLibraryHandle().registerCallout("alpha", callout_one);
  698. // Check all is as expected.
  699. EXPECT_TRUE(manager->calloutsPresent(alpha_index_));
  700. EXPECT_FALSE(manager->calloutsPresent(beta_index_));
  701. EXPECT_FALSE(manager->calloutsPresent(gamma_index_));
  702. EXPECT_FALSE(manager->calloutsPresent(delta_index_));
  703. // Check that calling the callouts returns as expected.
  704. callout_value_ = 0;
  705. manager->callCallouts(alpha_index_, handle);
  706. EXPECT_EQ(14, callout_value_);
  707. // Deregister the pre- library callout.
  708. EXPECT_TRUE(manager->getPreLibraryHandle().deregisterAllCallouts("alpha"));
  709. callout_value_ = 0;
  710. manager->callCallouts(alpha_index_, handle);
  711. EXPECT_EQ(4, callout_value_);
  712. }
  713. // Repeat the tests with one user library.
  714. TEST_F(CalloutManagerTest, LibraryHandlePrePostUserLibrary) {
  715. // Setup the pre-, library and post callouts.
  716. getCalloutManager()->getPostLibraryHandle().registerCallout("alpha",
  717. callout_four);
  718. getCalloutManager()->getPreLibraryHandle().registerCallout("alpha",
  719. callout_one);
  720. // ... and set up a callout in between, on library number 2.
  721. LibraryHandle lh1(getCalloutManager().get(), 2);
  722. lh1.registerCallout("alpha", callout_five);
  723. // Check all is as expected.
  724. EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
  725. EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
  726. EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
  727. EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
  728. // Check that calling the callouts returns as expected.
  729. callout_value_ = 0;
  730. getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
  731. EXPECT_EQ(154, callout_value_);
  732. }
  733. // The setting of the hook index is checked in the handles_unittest
  734. // set of tests, as access restrictions mean it is not easily tested
  735. // on its own.
  736. } // Anonymous namespace