cfg_duid_unittest.cc 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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/dhcp4.h>
  16. #include <dhcp/duid.h>
  17. #include <dhcpsrv/cfg_duid.h>
  18. #include <exceptions/exceptions.h>
  19. #include <testutils/io_utils.h>
  20. #include <util/encode/hex.h>
  21. #include <gtest/gtest.h>
  22. #include <stdint.h>
  23. #include <stdio.h>
  24. #include <sstream>
  25. #include <string>
  26. #include <vector>
  27. using namespace isc;
  28. using namespace isc::dhcp;
  29. namespace {
  30. /// @brief Specifies file name holding DUID.
  31. const std::string DUID_FILE_NAME = "test.duid";
  32. /// @brief Test fixture class for @c CfgDUID.
  33. class CfgDUIDTest : public ::testing::Test {
  34. public:
  35. /// @brief Constructor.
  36. ///
  37. /// Removes DUID file if present.
  38. CfgDUIDTest() {
  39. static_cast<void>(remove(absolutePath(DUID_FILE_NAME).c_str()));
  40. }
  41. /// @brief Destructor.
  42. ///
  43. /// Removes DUID file if present.
  44. virtual ~CfgDUIDTest() {
  45. static_cast<void>(remove(absolutePath(DUID_FILE_NAME).c_str()));
  46. }
  47. /// @brief Returns absolute path to a file used by tests.
  48. ///
  49. /// @param filename File name.
  50. std::string absolutePath(const std::string& filename) const;
  51. /// @brief Converts vector to string of hexadecimal digits.
  52. ///
  53. /// @param vec Input vector.
  54. /// @return String of hexadecimal digits converted from vector.
  55. std::string toString(const std::vector<uint8_t>& vec) const;
  56. };
  57. std::string
  58. CfgDUIDTest::absolutePath(const std::string& filename) const {
  59. std::ostringstream s;
  60. s << DHCP_DATA_DIR << "/" << filename;
  61. return (s.str());
  62. }
  63. /// @brief Converts vector to string of hexadecimal digits.
  64. ///
  65. /// @param vec Input vector.
  66. /// @return String of hexadecimal digits converted from vector.
  67. std::string
  68. CfgDUIDTest::toString(const std::vector<uint8_t>& vec) const {
  69. try {
  70. return (util::encode::encodeHex(vec));
  71. } catch (...) {
  72. ADD_FAILURE() << "toString: unable to encode vector to"
  73. " hexadecimal string";
  74. }
  75. return ("");
  76. }
  77. // This test verifies default values of the DUID configuration.
  78. TEST_F(CfgDUIDTest, defaults) {
  79. CfgDUID cfg_duid;
  80. EXPECT_EQ(DUID::DUID_LLT, cfg_duid.getType());
  81. EXPECT_TRUE(cfg_duid.getIdentifier().empty())
  82. << "expected empty identifier, found: "
  83. << toString(cfg_duid.getIdentifier());
  84. EXPECT_EQ(0, cfg_duid.getHType());
  85. EXPECT_EQ(0, cfg_duid.getTime());
  86. EXPECT_EQ(0, cfg_duid.getEnterpriseId());
  87. EXPECT_TRUE(cfg_duid.persist());
  88. }
  89. // This test verifies that it is possible to set values for the CfgDUID.
  90. TEST_F(CfgDUIDTest, setValues) {
  91. CfgDUID cfg_duid;
  92. // Set values.
  93. ASSERT_NO_THROW(cfg_duid.setType(DUID::DUID_EN));
  94. ASSERT_NO_THROW(cfg_duid.setIdentifier("ABCDEF"));
  95. ASSERT_NO_THROW(cfg_duid.setHType(100));
  96. ASSERT_NO_THROW(cfg_duid.setTime(32100));
  97. ASSERT_NO_THROW(cfg_duid.setEnterpriseId(10));
  98. ASSERT_NO_THROW(cfg_duid.setPersist(false));
  99. // Check that values have been set correctly.
  100. EXPECT_EQ(DUID::DUID_EN, cfg_duid.getType());
  101. EXPECT_EQ("ABCDEF", toString(cfg_duid.getIdentifier()));
  102. EXPECT_EQ(100, cfg_duid.getHType());
  103. EXPECT_EQ(32100, cfg_duid.getTime());
  104. EXPECT_EQ(10, cfg_duid.getEnterpriseId());
  105. EXPECT_FALSE(cfg_duid.persist());
  106. }
  107. // This test checks positive scenarios for setIdentifier.
  108. TEST_F(CfgDUIDTest, setIdentifier) {
  109. CfgDUID cfg_duid;
  110. // Check that hexadecimal characters may be lower case.
  111. ASSERT_NO_THROW(cfg_duid.setIdentifier("a1b2c3"));
  112. EXPECT_EQ("A1B2C3", toString(cfg_duid.getIdentifier()));
  113. // Check that whitespaces are allowed.
  114. ASSERT_NO_THROW(cfg_duid.setIdentifier(" ABC DEF "));
  115. EXPECT_EQ("ABCDEF", toString(cfg_duid.getIdentifier()));
  116. // Check that identifier including only whitespaces is ignored.
  117. ASSERT_NO_THROW(cfg_duid.setIdentifier(" "));
  118. EXPECT_TRUE(cfg_duid.getIdentifier().empty())
  119. << "expected empty identifier, found: "
  120. << toString(cfg_duid.getIdentifier());
  121. }
  122. // This test verifies that the invalid identifier is rejected and
  123. // exception is thrown.
  124. TEST_F(CfgDUIDTest, setInvalidIdentifier) {
  125. CfgDUID cfg_duid;
  126. // Check that hexadecimal characters may be lower case.
  127. ASSERT_NO_THROW(cfg_duid.setIdentifier("a1b2c3"));
  128. EXPECT_EQ("A1B2C3", toString(cfg_duid.getIdentifier()));
  129. // Try to set invalid value. This should not modify original
  130. // value.
  131. ASSERT_THROW(cfg_duid.setIdentifier("hola!"), isc::BadValue);
  132. EXPECT_EQ("A1B2C3", toString(cfg_duid.getIdentifier()));
  133. }
  134. // This method checks that the DUID-LLT can be created from the
  135. // specified configuration.
  136. TEST_F(CfgDUIDTest, createLLT) {
  137. CfgDUID cfg;
  138. ASSERT_NO_THROW(cfg.setType(DUID::DUID_LLT));
  139. ASSERT_NO_THROW(cfg.setTime(0x1123));
  140. ASSERT_NO_THROW(cfg.setHType(8));
  141. ASSERT_NO_THROW(cfg.setIdentifier("12564325A63F"));
  142. // Generate DUID from this configuration.
  143. DuidPtr duid;
  144. ASSERT_NO_THROW(duid = cfg.create(absolutePath(DUID_FILE_NAME)));
  145. ASSERT_TRUE(duid);
  146. // Verify if the DUID is correct.
  147. EXPECT_EQ("00:01:00:08:00:00:11:23:12:56:43:25:a6:3f",
  148. duid->toText());
  149. // Verify that the DUID file has been created.
  150. EXPECT_TRUE(dhcp::test::fileExists(absolutePath(DUID_FILE_NAME)));
  151. }
  152. // This method checks that the DUID-EN can be created from the
  153. // specified configuration.
  154. TEST_F(CfgDUIDTest, createEN) {
  155. CfgDUID cfg;
  156. ASSERT_NO_THROW(cfg.setType(DUID::DUID_EN));
  157. ASSERT_NO_THROW(cfg.setIdentifier("250F3E26A762"));
  158. ASSERT_NO_THROW(cfg.setEnterpriseId(0x1010));
  159. // Generate DUID from this configuration.
  160. DuidPtr duid;
  161. ASSERT_NO_THROW(duid = cfg.create(absolutePath(DUID_FILE_NAME)));
  162. ASSERT_TRUE(duid);
  163. // Verify if the DUID is correct.
  164. EXPECT_EQ("00:02:00:00:10:10:25:0f:3e:26:a7:62", duid->toText());
  165. // Verify that the DUID file has been created.
  166. EXPECT_TRUE(dhcp::test::fileExists(absolutePath(DUID_FILE_NAME)));
  167. }
  168. // This method checks that the DUID-LL can be created from the
  169. // specified configuration.
  170. TEST_F(CfgDUIDTest, createLL) {
  171. CfgDUID cfg;
  172. ASSERT_NO_THROW(cfg.setType(DUID::DUID_LL));
  173. ASSERT_NO_THROW(cfg.setIdentifier("124134A4B367"));
  174. ASSERT_NO_THROW(cfg.setHType(2));
  175. // Generate DUID from this configuration.
  176. DuidPtr duid;
  177. ASSERT_NO_THROW(duid = cfg.create(absolutePath(DUID_FILE_NAME)));
  178. ASSERT_TRUE(duid);
  179. // Verify if the DUID is correct.
  180. EXPECT_EQ("00:03:00:02:12:41:34:a4:b3:67", duid->toText());
  181. // Verify that the DUID file has been created.
  182. EXPECT_TRUE(dhcp::test::fileExists(absolutePath(DUID_FILE_NAME)));
  183. }
  184. // This test verifies that it is possible to disable storing
  185. // generated DUID on a hard drive.
  186. TEST_F(CfgDUIDTest, createDisableWrite) {
  187. CfgDUID cfg;
  188. ASSERT_NO_THROW(cfg.setType(DUID::DUID_EN));
  189. ASSERT_NO_THROW(cfg.setIdentifier("250F3E26A762"));
  190. ASSERT_NO_THROW(cfg.setEnterpriseId(0x1010));
  191. ASSERT_NO_THROW(cfg.setPersist(false));
  192. // Generate DUID from this configuration.
  193. DuidPtr duid;
  194. ASSERT_NO_THROW(duid = cfg.create(absolutePath(DUID_FILE_NAME)));
  195. ASSERT_TRUE(duid);
  196. // Verify if the DUID is correct.
  197. EXPECT_EQ("00:02:00:00:10:10:25:0f:3e:26:a7:62", duid->toText());
  198. // DUID persistence is disabled so there should be no DUID file.
  199. EXPECT_FALSE(dhcp::test::fileExists(absolutePath(DUID_FILE_NAME)));
  200. }
  201. } // end of anonymous namespace