option6_status_code_unittest.cc 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // Copyright (C) 2015 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/dhcp6.h>
  16. #include <dhcp/option.h>
  17. #include <dhcp/option6_status_code.h>
  18. #include <gtest/gtest.h>
  19. #include <cstring>
  20. using namespace isc;
  21. using namespace isc::dhcp;
  22. namespace {
  23. // This test verifies that the option can be created and that the
  24. // accessor methods return correct values used for the object
  25. // construction.
  26. TEST(Option6StatusCodeTest, accessors) {
  27. Option6StatusCode status1(STATUS_NoAddrsAvail, "Sorry, NoAddrsAvail");
  28. EXPECT_EQ(STATUS_NoAddrsAvail, status1.getStatusCode());
  29. EXPECT_EQ("Sorry, NoAddrsAvail", status1.getStatusMessage());
  30. Option6StatusCode status2(STATUS_NoBinding, "There is NoBinding");
  31. EXPECT_EQ(STATUS_NoBinding, status2.getStatusCode());
  32. EXPECT_EQ("There is NoBinding", status2.getStatusMessage());
  33. }
  34. // This test verifies that the status code and status message may
  35. // be modified.
  36. TEST(Option6StatusCodeTest, modifiers) {
  37. Option6StatusCode status(STATUS_NoAddrsAvail, "Sorry, NoAddrsAvail");
  38. ASSERT_EQ(STATUS_NoAddrsAvail, status.getStatusCode());
  39. ASSERT_EQ("Sorry, NoAddrsAvail", status.getStatusMessage());
  40. ASSERT_NO_THROW(status.setStatusCode(STATUS_Success));
  41. ASSERT_NO_THROW(status.setStatusMessage("Success"));
  42. EXPECT_EQ(STATUS_Success, status.getStatusCode());
  43. EXPECT_EQ("Success", status.getStatusMessage());
  44. }
  45. // This test verifies that the option returns its length correctly.
  46. TEST(Option6StatusCodeTest, length) {
  47. Option6StatusCode status(STATUS_Success, "");
  48. EXPECT_EQ(6, status.len());
  49. ASSERT_NO_THROW(status.setStatusMessage("non-empty message"));
  50. EXPECT_EQ(23, status.len());
  51. }
  52. // This test verifies that the option can be encoded into the wire
  53. // format.
  54. TEST(Option6StatusCodeTest, pack) {
  55. Option6StatusCode status(STATUS_NoBinding, "text");
  56. util::OutputBuffer buf(10);
  57. ASSERT_NO_THROW(status.pack(buf));
  58. const uint8_t ref[] = {
  59. 0, 13, // Option code is 13
  60. 0, 6, // Length is 6
  61. 0, 3, // NoBinding
  62. 't', 'e', 'x', 't'
  63. };
  64. ASSERT_EQ(sizeof(ref), buf.getLength());
  65. const void* packed = buf.getData();
  66. EXPECT_EQ(0, memcmp(static_cast<const void*>(ref), packed, sizeof(ref)));
  67. }
  68. // This test verifies that the option can be encoded into the
  69. // wire format when the status message is empty.
  70. TEST(Option6StatusCodeTest, packEmptyStatusMessage) {
  71. Option6StatusCode status(STATUS_NoAddrsAvail, "");
  72. util::OutputBuffer buf(10);
  73. ASSERT_NO_THROW(status.pack(buf));
  74. const uint8_t ref[] = {
  75. 0, 13, // Option code is 13
  76. 0, 2, // Length is 2
  77. 0, 2, // NoAddrsAvail
  78. };
  79. ASSERT_EQ(sizeof(ref), buf.getLength());
  80. const void* packed = buf.getData();
  81. EXPECT_EQ(0, memcmp(static_cast<const void*>(ref), packed, sizeof(ref)));
  82. }
  83. // This test verifies that the option can be parsed from the wire
  84. // format.
  85. TEST(Option6StatusCodeTest, unpack) {
  86. const uint8_t wire_data[] = {
  87. 0, 1, // status code = UnspecFail
  88. 'x', 'y', 'z', // short text: xyz
  89. };
  90. OptionBuffer buf(wire_data, wire_data + sizeof(wire_data));
  91. // Create option from buffer.
  92. Option6StatusCodePtr status;
  93. ASSERT_NO_THROW(status.reset(new Option6StatusCode(buf.begin(), buf.end())));
  94. // Verify that the data was parsed correctly.
  95. EXPECT_EQ(STATUS_UnspecFail, status->getStatusCode());
  96. EXPECT_EQ("xyz", status->getStatusMessage());
  97. // Remove the status message and leave only the status code.
  98. buf.resize(2);
  99. // Modify the status code.
  100. buf[1] = 0;
  101. ASSERT_NO_THROW(status.reset(new Option6StatusCode(buf.begin(), buf.end())));
  102. EXPECT_EQ(STATUS_Success, status->getStatusCode());
  103. EXPECT_TRUE(status->getStatusMessage().empty());
  104. }
  105. // This test verifies that the option data can be presented
  106. // in the textual form.
  107. TEST(Option6StatusCodeTest, dataToText) {
  108. Option6StatusCode status(STATUS_NoBinding, "Sorry, no binding");
  109. EXPECT_EQ("NoBinding(3) \"Sorry, no binding\"",
  110. status.dataToText());
  111. }
  112. // This test verifies that the option can be presented in the
  113. // textual form.
  114. TEST(Option6StatusCodeTest, toText) {
  115. Option6StatusCode status(STATUS_NoAddrsAvail, "Sorry, no address");
  116. EXPECT_EQ("type=00013, len=00019: NoAddrsAvail(2) \"Sorry, no address\"",
  117. status.toText());
  118. Option6StatusCode status_empty(STATUS_NoBinding, "");
  119. EXPECT_EQ("type=00013, len=00002: NoBinding(3) (no status message)",
  120. status_empty.toText());
  121. }
  122. /// @brief Test that the status code name is returned correctly.
  123. ///
  124. /// @param expected_name Expected name.
  125. /// @param status_code Status code for which test is performed.
  126. void testStatusName(const std::string& expected_name,
  127. const uint16_t status_code) {
  128. Option6StatusCode status(status_code, "some text");
  129. EXPECT_EQ(expected_name, status.getStatusCodeName());
  130. }
  131. // This test verifies that the status code name is
  132. // returned correctly.
  133. TEST(Option6StatusCodeTest, getStatusCodeName) {
  134. testStatusName("Success", STATUS_Success);
  135. testStatusName("UnspecFail", STATUS_UnspecFail);
  136. testStatusName("NoAddrsAvail", STATUS_NoAddrsAvail);
  137. testStatusName("NoBinding", STATUS_NoBinding);
  138. testStatusName("NotOnLink", STATUS_NotOnLink);
  139. testStatusName("UseMulticast", STATUS_UseMulticast);
  140. testStatusName("NoPrefixAvail", STATUS_NoPrefixAvail);
  141. testStatusName("UnknownQueryType", STATUS_UnknownQueryType);
  142. testStatusName("MalformedQuery", STATUS_MalformedQuery);
  143. testStatusName("NotConfigured", STATUS_NotConfigured);
  144. testStatusName("NotAllowed", STATUS_NotAllowed);
  145. testStatusName("(unknown status code)", 1234);
  146. }
  147. } // anonymous namespace