callout_handle_store_unittest.cc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Copyright (C) 2012-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 <config.h>
  15. #include <dhcp/dhcp4.h>
  16. #include <dhcp/dhcp6.h>
  17. #include <dhcp/pkt4.h>
  18. #include <dhcpsrv/callout_handle_store.h>
  19. #include "test_get_callout_handle.h"
  20. #include <gtest/gtest.h>
  21. using namespace isc;
  22. using namespace isc::dhcp;
  23. using namespace isc::hooks;
  24. namespace {
  25. TEST(CalloutHandleStoreTest, StoreRetrieve) {
  26. // Create two DHCP4 packets during tests. The constructor arguments are
  27. // arbitrary.
  28. Pkt4Ptr pktptr_1(new Pkt4(DHCPDISCOVER, 1234));
  29. Pkt4Ptr pktptr_2(new Pkt4(DHCPDISCOVER, 5678));
  30. // Check that the pointers point to objects that are different, and that
  31. // the pointers are the only pointers pointing to the packets.
  32. ASSERT_TRUE(pktptr_1);
  33. ASSERT_TRUE(pktptr_2);
  34. ASSERT_TRUE(pktptr_1 != pktptr_2);
  35. EXPECT_EQ(1, pktptr_1.use_count());
  36. EXPECT_EQ(1, pktptr_2.use_count());
  37. // Get the CalloutHandle for the first packet.
  38. CalloutHandlePtr chptr_1 = getCalloutHandle(pktptr_1);
  39. ASSERT_TRUE(chptr_1);
  40. // Reference counts on both the callout handle and the packet should have
  41. // been incremented because of the stored data. The reference count on the
  42. // other Pkt4 object should not have changed.
  43. EXPECT_EQ(2, chptr_1.use_count());
  44. EXPECT_EQ(2, pktptr_1.use_count());
  45. EXPECT_EQ(1, pktptr_2.use_count());
  46. // Try getting another pointer for the same packet. Use a different
  47. // pointer object to check that the function returns a handle based on the
  48. // pointed-to data and not the pointer. (Clear the temporary pointer after
  49. // use to avoid complicating reference counts.)
  50. Pkt4Ptr pktptr_temp = pktptr_1;
  51. CalloutHandlePtr chptr_2 = getCalloutHandle(pktptr_temp);
  52. pktptr_temp.reset();
  53. ASSERT_TRUE(chptr_2);
  54. EXPECT_TRUE(chptr_1 == chptr_2);
  55. // Reference count is now 3 on the callout handle - two for pointers here,
  56. // one for the static pointer in the function. The count is 2 for the]
  57. // object pointed to by pktptr_1 - one for that pointer and one for the
  58. // pointer in the function.
  59. EXPECT_EQ(3, chptr_1.use_count());
  60. EXPECT_EQ(3, chptr_2.use_count());
  61. EXPECT_EQ(2, pktptr_1.use_count());
  62. EXPECT_EQ(1, pktptr_2.use_count());
  63. // Now ask for a CalloutHandle for a different object. This should return
  64. // a different CalloutHandle.
  65. chptr_2 = getCalloutHandle(pktptr_2);
  66. EXPECT_FALSE(chptr_1 == chptr_2);
  67. // Check reference counts. The getCalloutHandle function should be storing
  68. // pointers to the objects poiunted to by chptr_2 and pktptr_2.
  69. EXPECT_EQ(1, chptr_1.use_count());
  70. EXPECT_EQ(1, pktptr_1.use_count());
  71. EXPECT_EQ(2, chptr_2.use_count());
  72. EXPECT_EQ(2, pktptr_2.use_count());
  73. // Now try clearing the stored pointers.
  74. Pkt4Ptr pktptr_empty;
  75. ASSERT_FALSE(pktptr_empty);
  76. CalloutHandlePtr chptr_empty = getCalloutHandle(pktptr_empty);
  77. EXPECT_FALSE(chptr_empty);
  78. // Reference counts should be back to 1 for the CalloutHandles and the
  79. // Packet pointers.
  80. EXPECT_EQ(1, chptr_1.use_count());
  81. EXPECT_EQ(1, pktptr_1.use_count());
  82. EXPECT_EQ(1, chptr_2.use_count());
  83. EXPECT_EQ(1, pktptr_2.use_count());
  84. }
  85. // The followings is a trival test to check that if the template function
  86. // is referred to in a separate compilation unit, only one copy of the static
  87. // objects stored in it are returned. (For a change, we'll use a Pkt6 as the
  88. // packet object.)
  89. TEST(CalloutHandleStoreTest, SeparateCompilationUnit) {
  90. // Access the template function here.
  91. Pkt6Ptr pktptr_1(new Pkt6(DHCPV6_ADVERTISE, 4321));
  92. CalloutHandlePtr chptr_1 = getCalloutHandle(pktptr_1);
  93. ASSERT_TRUE(chptr_1);
  94. // Access it from within another compilation unit.
  95. CalloutHandlePtr chptr_2 = isc::dhcp::test::testGetCalloutHandle(pktptr_1);
  96. EXPECT_TRUE(chptr_1 == chptr_2);
  97. }
  98. } // Anonymous namespace