command_options_unittest.cc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. // Copyright (C) 2011 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 <cstddef>
  15. #include <stdint.h>
  16. #include <string>
  17. #include <gtest/gtest.h>
  18. #include "../command_options.h"
  19. #include "exceptions/exceptions.h"
  20. using namespace std;
  21. using namespace isc;
  22. using namespace isc::perfdhcp;
  23. /// \brief Test Fixture Class
  24. class CommandOptionsTest : public virtual ::testing::Test,
  25. public virtual CommandOptions
  26. {
  27. public:
  28. /// \brief Default Constructor
  29. CommandOptionsTest() : CommandOptions() { }
  30. protected:
  31. /// \brief Parse command line and cleanup
  32. ///
  33. /// Tokenizes command line to array of C-strings,
  34. /// parses arguments and de-allocates C-strings
  35. ///
  36. /// \param s Command line to parse
  37. /// \return non-zero if parsing failed
  38. void process(const std::string& s) {
  39. int argc = 0;
  40. char** argv = tokenizeString(s, &argc);
  41. parse(argc, argv, true);
  42. for(int i = 0; i < argc; ++i) {
  43. free(argv[i]);
  44. argv[i] = NULL;
  45. }
  46. free(argv);
  47. }
  48. /// \brief Check initialized values
  49. ///
  50. /// Check if initialized values are correct
  51. void checkDefaults() {
  52. EXPECT_EQ(4, getIpVersion());
  53. EXPECT_EQ(DORR_SARR, getExchangeMode());
  54. EXPECT_EQ(0, getRate());
  55. EXPECT_EQ(0, getReportDelay());
  56. EXPECT_EQ(0, getRandomRange());
  57. // EXPECT_EQ(0, max_random_);
  58. // TODO MAC and DUID checks
  59. EXPECT_EQ(0, getBase().size());
  60. EXPECT_EQ(0, getNumRequests().size());
  61. EXPECT_EQ(0, getPeriod());
  62. for (int i = 0; i < getLostTime().size(); ++i) {
  63. EXPECT_DOUBLE_EQ(1, getLostTime()[i]);
  64. }
  65. ASSERT_EQ(getMaxDrop().size(), getMaxDropPercentage().size());
  66. for (int i = 0; i < getMaxDrop().size(); ++i) {
  67. EXPECT_EQ(0, getMaxDrop()[i]);
  68. EXPECT_EQ(0, getMaxDropPercentage()[i]);
  69. }
  70. EXPECT_EQ("", getLocalName());
  71. EXPECT_FALSE(isInterface());
  72. EXPECT_EQ(0, getPreload());
  73. EXPECT_EQ(1, getAggressivity());
  74. EXPECT_EQ(0, getLocalPort());
  75. EXPECT_FALSE(isSeeded());
  76. EXPECT_EQ(0, getSeed());
  77. EXPECT_FALSE(isBroadcast());
  78. EXPECT_FALSE(isRapidCommit());
  79. EXPECT_FALSE(isUseFirst());
  80. EXPECT_EQ(0, getTemplateFiles().size());
  81. EXPECT_EQ(0, getXidOffset().size());
  82. EXPECT_EQ(0, getRndOffset().size());
  83. EXPECT_GT(0, getElpOffset());
  84. EXPECT_GT(0, getSidOffset());
  85. EXPECT_GT(0, getRipOffset());
  86. EXPECT_EQ("", getDiags());
  87. EXPECT_EQ("", getWrapped());
  88. EXPECT_EQ("", getServerName());
  89. }
  90. /// \brief Split string to array of C-strings
  91. ///
  92. /// \param s String to split (tokenize)
  93. /// \param num Number of tokens returned
  94. /// \return array of C-strings (tokens)
  95. char** tokenizeString(const std::string& s, int* num) const {
  96. char** results = NULL;
  97. std::stringstream ss(s);
  98. std::istream_iterator<std::string> sit(ss);
  99. std::istream_iterator<std::string> send;
  100. std::vector<std::string> tokens(sit, send);
  101. if (tokens.size() > 0) {
  102. results = static_cast<char**>(malloc(tokens.size() * sizeof(char*)));
  103. if (results == NULL) {
  104. throw std::bad_alloc();
  105. }
  106. for (int i = 0; i < tokens.size(); ++i) {
  107. char* cs = static_cast<char*>(malloc(tokens[i].length() + 1));
  108. strcpy(cs, tokens[i].c_str());
  109. results[i] = cs;
  110. }
  111. if (num != NULL) {
  112. *num = tokens.size();
  113. }
  114. }
  115. return results;
  116. }
  117. };
  118. TEST_F(CommandOptionsTest, Defaults) {
  119. process("perfdhcp");
  120. checkDefaults();
  121. }
  122. TEST_F(CommandOptionsTest, UseFirst) {
  123. process("perfdhcp -l ethx -1 -B");
  124. EXPECT_TRUE(isUseFirst());
  125. }
  126. TEST_F(CommandOptionsTest, IpVersion) {
  127. process("perfdhcp -6 -l ethx -c -i");
  128. EXPECT_EQ(6, getIpVersion());
  129. EXPECT_EQ("ethx", getLocalName());
  130. EXPECT_TRUE(isRapidCommit());
  131. EXPECT_FALSE(isBroadcast());
  132. process("perfdhcp -4 -B -l ethx");
  133. EXPECT_EQ(4, getIpVersion());
  134. EXPECT_TRUE(isBroadcast());
  135. EXPECT_FALSE(isRapidCommit());
  136. EXPECT_THROW(process("perfdhcp -6 -B -l ethx"), isc::InvalidParameter);
  137. EXPECT_THROW(process("perfdhcp -c -l ethx"), isc::InvalidParameter);
  138. }
  139. TEST_F(CommandOptionsTest, Rate) {
  140. process("perfdhcp -4 -r 10 -l ethx");
  141. EXPECT_EQ(10, getRate());
  142. EXPECT_THROW(process("perfdhcp -4 -r 0 -l ethx"), isc::InvalidParameter);
  143. EXPECT_THROW(process("perfdhcp -6 -t 5 -l ethx"), isc::InvalidParameter);
  144. EXPECT_THROW(process("perfdhcp -4 -n 150 -l ethx"), isc::InvalidParameter);
  145. EXPECT_THROW(process("perfdhcp -6 -p 120 -l ethx"), isc::InvalidParameter);
  146. EXPECT_THROW(process("perfdhcp -4 -D 1400 -l ethx"), isc::InvalidParameter);
  147. }
  148. TEST_F(CommandOptionsTest, ReportDelay) {
  149. process("perfdhcp -r 100 -t 17 -l ethx");
  150. EXPECT_EQ(17, getReportDelay());
  151. }
  152. TEST_F(CommandOptionsTest, RandomRange) {
  153. process("perfdhcp -R 200 -l ethx");
  154. EXPECT_EQ(200, getRandomRange());
  155. }
  156. TEST_F(CommandOptionsTest, Base) {
  157. process("perfdhcp -6 -b MAC=10::20::30::40::50::60 -l ethx -b duiD=1AB7F5670901FF");
  158. uint8_t mac[6] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60 };
  159. uint8_t duid[7] = { 0x1A, 0xB7, 0xF5, 0x67, 0x09, 0x01, 0xFF };
  160. std::vector<uint8_t> v1(mac, mac + 6);
  161. std::vector<uint8_t> v2(duid, duid + 7);
  162. EXPECT_EQ(v1, getMacPrefix());
  163. EXPECT_EQ(v2, getDuidPrefix());
  164. }
  165. TEST_F(CommandOptionsTest, DropTime) {
  166. process("perfdhcp -l ethx -d 12");
  167. ASSERT_EQ(2, getLostTime().size());
  168. EXPECT_DOUBLE_EQ(12, getLostTime()[0]);
  169. EXPECT_DOUBLE_EQ(1, getLostTime()[1]);
  170. process("perfdhcp -l ethx -d 2 -d 4.7");
  171. ASSERT_EQ(2, getLostTime().size());
  172. EXPECT_DOUBLE_EQ(2, getLostTime()[0]);
  173. EXPECT_DOUBLE_EQ(4.7, getLostTime()[1]);
  174. }
  175. TEST_F(CommandOptionsTest, TimeOffset) {
  176. process("perfdhcp -l ethx -T file1.x -T file2.x -E 4");
  177. EXPECT_EQ(4, getElpOffset());
  178. EXPECT_THROW(process("perfdhcp -l ethx -E 3 -i"), isc::InvalidParameter);
  179. }
  180. TEST_F(CommandOptionsTest, ExchangeMode) {
  181. process("perfdhcp -l ethx -i");
  182. EXPECT_EQ(CommandOptions::DO_SA, getExchangeMode());
  183. EXPECT_THROW(process("perfdhcp -i -l ethx -X 3"), isc::InvalidParameter);
  184. EXPECT_THROW(process("perfdhcp -i -l ethx -O 2"), isc::InvalidParameter);
  185. EXPECT_THROW(process("perfdhcp -i -l ethx -E 3"), isc::InvalidParameter);
  186. EXPECT_THROW(process("perfdhcp -i -l ethx -S 1"), isc::InvalidParameter);
  187. EXPECT_THROW(process("perfdhcp -i -l ethx -I 2"), isc::InvalidParameter);
  188. }
  189. TEST_F(CommandOptionsTest, Offsets) {
  190. process("perfdhcp -E5 -4 -I 2 -S3 -O 30 -X7 -l ethx -X3 -T file1.x -T file2.x");
  191. EXPECT_EQ(2, getRipOffset());
  192. EXPECT_EQ(5, getElpOffset());
  193. EXPECT_EQ(3, getSidOffset());
  194. ASSERT_EQ(2, getRndOffset().size());
  195. EXPECT_EQ(30, getRndOffset()[0]);
  196. EXPECT_EQ(30, getRndOffset()[1]);
  197. ASSERT_EQ(2, getXidOffset().size());
  198. EXPECT_EQ(7, getXidOffset()[0]);
  199. EXPECT_EQ(3, getXidOffset()[1]);
  200. EXPECT_THROW(process("perfdhcp -6 -I 0 -l ethx"), isc::InvalidParameter);
  201. EXPECT_THROW(process("perfdhcp -6 -I -4 -l ethx"), isc::InvalidParameter);
  202. // TODO - other negative cases
  203. }
  204. TEST_F(CommandOptionsTest, LocalPort) {
  205. process("perfdhcp -l ethx -L 2000");
  206. EXPECT_EQ(2000, getLocalPort());
  207. }
  208. TEST_F(CommandOptionsTest, Preload) {
  209. process("perfdhcp -1 -P 3 -l ethx");
  210. EXPECT_EQ(3, getPreload());
  211. EXPECT_THROW(process("perfdhcp -P -1 -l ethx"), isc::InvalidParameter);
  212. }
  213. TEST_F(CommandOptionsTest, Seed) {
  214. process("perfdhcp -6 -P 2 -s 23 -l ethx");
  215. EXPECT_EQ(23, getSeed());
  216. EXPECT_TRUE(isSeeded());
  217. }
  218. TEST_F(CommandOptionsTest, TemplateFiles) {
  219. process("perfdhcp -T file1.x -l ethx");
  220. ASSERT_EQ(1, getTemplateFiles().size());
  221. EXPECT_EQ("file1.x", getTemplateFiles()[0]);
  222. process("perfdhcp -T file1.x -s 12 -w start -T file2.x -4 -l ethx");
  223. ASSERT_EQ(2, getTemplateFiles().size());
  224. EXPECT_EQ("file1.x", getTemplateFiles()[0]);
  225. EXPECT_EQ("file2.x", getTemplateFiles()[1]);
  226. }
  227. TEST_F(CommandOptionsTest, Wrapped) {
  228. process("perfdhcp -B -w start -i -l ethx");
  229. EXPECT_EQ("start", getWrapped());
  230. }
  231. TEST_F(CommandOptionsTest, Diagnostics) {
  232. process("perfdhcp -l ethx -i -x asTe");
  233. EXPECT_EQ("asTe", getDiags());
  234. }