option_string_unittest.cc 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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 <config.h>
  15. #include <dhcp/option_string.h>
  16. #include <boost/scoped_ptr.hpp>
  17. #include <gtest/gtest.h>
  18. using namespace isc;
  19. using namespace isc::dhcp;
  20. using namespace isc::util;
  21. namespace {
  22. /// @brief OptionString test class.
  23. class OptionStringTest : public ::testing::Test {
  24. public:
  25. /// @brief Constructor.
  26. ///
  27. /// Initializes the test buffer with some data.
  28. OptionStringTest() {
  29. std::string test_string("This is a test string");
  30. buf_.assign(test_string.begin(), test_string.end());
  31. }
  32. OptionBuffer buf_;
  33. };
  34. // This test verifies that the constructor which creates an option instance
  35. // from a string value will create it properly.
  36. TEST_F(OptionStringTest, constructorFromString) {
  37. const std::string optv4_value = "some option";
  38. OptionString optv4(Option::V4, 123, optv4_value);
  39. EXPECT_EQ(Option::V4, optv4.getUniverse());
  40. EXPECT_EQ(123, optv4.getType());
  41. EXPECT_EQ(optv4_value, optv4.getValue());
  42. EXPECT_EQ(Option::OPTION4_HDR_LEN + optv4_value.size(), optv4.len());
  43. // Do another test with the same constructor to make sure that
  44. // different set of parameters would initialize the class members
  45. // to different values.
  46. const std::string optv6_value = "other option";
  47. OptionString optv6(Option::V6, 234, optv6_value);
  48. EXPECT_EQ(Option::V6, optv6.getUniverse());
  49. EXPECT_EQ(234, optv6.getType());
  50. EXPECT_EQ("other option", optv6.getValue());
  51. EXPECT_EQ(Option::OPTION6_HDR_LEN + optv6_value.size(), optv6.len());
  52. // Check that an attempt to use empty string in the constructor
  53. // will result in an exception.
  54. EXPECT_THROW(OptionString(Option::V6, 123, ""), isc::OutOfRange);
  55. }
  56. // This test verifies that the constructor which creates an option instance
  57. // from a buffer, holding option payload, will create it properly.
  58. // This function calls unpack() internally thus test test is considered
  59. // to cover testing of unpack() functionality.
  60. TEST_F(OptionStringTest, constructorFromBuffer) {
  61. // Attempt to create an option using empty buffer should result in
  62. // an exception.
  63. EXPECT_THROW(
  64. OptionString(Option::V4, 234, buf_.begin(), buf_.begin()),
  65. isc::OutOfRange
  66. );
  67. // Declare option as a scoped pointer here so as its scope is
  68. // function wide. The initialization (constructor invocation)
  69. // is pushed to the ASSERT_NO_THROW macro below, as it may
  70. // throw exception if buffer is truncated.
  71. boost::scoped_ptr<OptionString> optv4;
  72. ASSERT_NO_THROW(
  73. optv4.reset(new OptionString(Option::V4, 234, buf_.begin(), buf_.end()));
  74. );
  75. // Make sure that it has been initialized to non-NULL value.
  76. ASSERT_TRUE(optv4);
  77. // Test the instance of the created option.
  78. const std::string optv4_value = "This is a test string";
  79. EXPECT_EQ(Option::V4, optv4->getUniverse());
  80. EXPECT_EQ(234, optv4->getType());
  81. EXPECT_EQ(Option::OPTION4_HDR_LEN + buf_.size(), optv4->len());
  82. EXPECT_EQ(optv4_value, optv4->getValue());
  83. // Do the same test for V6 option.
  84. boost::scoped_ptr<OptionString> optv6;
  85. ASSERT_NO_THROW(
  86. // Let's reduce the size of the buffer by one byte and see if our option
  87. // will absorb this little change.
  88. optv6.reset(new OptionString(Option::V6, 123, buf_.begin(), buf_.end() - 1));
  89. );
  90. // Make sure that it has been initialized to non-NULL value.
  91. ASSERT_TRUE(optv6);
  92. // Test the instance of the created option.
  93. const std::string optv6_value = "This is a test strin";
  94. EXPECT_EQ(Option::V6, optv6->getUniverse());
  95. EXPECT_EQ(123, optv6->getType());
  96. EXPECT_EQ(Option::OPTION6_HDR_LEN + buf_.size() - 1, optv6->len());
  97. EXPECT_EQ(optv6_value, optv6->getValue());
  98. }
  99. // This test verifies that the current option value can be overriden
  100. // with new value, using setValue method.
  101. TEST_F(OptionStringTest, setValue) {
  102. // Create an instance of the option and set some initial value.
  103. OptionString optv4(Option::V4, 123, "some option");
  104. EXPECT_EQ("some option", optv4.getValue());
  105. // Replace the value with the new one, and make sure it has
  106. // been successful.
  107. EXPECT_NO_THROW(optv4.setValue("new option value"));
  108. EXPECT_EQ("new option value", optv4.getValue());
  109. // Try to set to an empty string. It should throw exception.
  110. EXPECT_THROW(optv4.setValue(""), isc::OutOfRange);
  111. }
  112. // This test verifies that the pack function encodes the option in
  113. // a on-wire format properly.
  114. TEST_F(OptionStringTest, pack) {
  115. // Create an instance of the option.
  116. std::string option_value("sample option value");
  117. OptionString optv4(Option::V4, 123, option_value);
  118. // Encode the option in on-wire format.
  119. OutputBuffer buf(Option::OPTION4_HDR_LEN);
  120. EXPECT_NO_THROW(optv4.pack(buf));
  121. // Sanity check the length of the buffer.
  122. ASSERT_EQ(Option::OPTION4_HDR_LEN + option_value.length(),
  123. buf.getLength());
  124. // Copy the contents of the OutputBuffer to InputBuffer because
  125. // the latter has API to read data from it.
  126. InputBuffer test_buf(buf.getData(), buf.getLength());
  127. // First byte holds option code.
  128. EXPECT_EQ(123, test_buf.readUint8());
  129. // Second byte holds option length.
  130. EXPECT_EQ(option_value.size(), test_buf.readUint8());
  131. // Read the option data.
  132. std::vector<uint8_t> data;
  133. test_buf.readVector(data, test_buf.getLength() - test_buf.getPosition());
  134. // And create a string from it.
  135. std::string test_string(data.begin(), data.end());
  136. // This string should be equal to the string used to create
  137. // option's instance.
  138. EXPECT_TRUE(option_value == test_string);
  139. }
  140. } // anonymous namespace