command_options_unittest.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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 <string>
  16. #include <gtest/gtest.h>
  17. #include "../command_options.h"
  18. #include "exceptions/exceptions.h"
  19. using namespace std;
  20. using namespace isc;
  21. using namespace isc::badpacket;
  22. /// \brief Test Fixture Class
  23. class CommandOptionsTest : public virtual ::testing::Test,
  24. public virtual CommandOptions
  25. {
  26. public:
  27. /// \brief Default Constructor
  28. CommandOptionsTest()
  29. {}
  30. /// \brief Check Non-Limit Options
  31. ///
  32. /// Checks that the options that are NOT related to the message are set to
  33. /// their default values.
  34. void checkDefaultOtherValues() {
  35. EXPECT_EQ("127.0.0.1", getAddress());
  36. EXPECT_EQ(53, getPort());
  37. EXPECT_EQ(500, getTimeout());
  38. EXPECT_EQ("www.example.com", getQname());
  39. }
  40. /// \brief Checks the minimum and maximum value specified for an option
  41. ///
  42. /// Checks the values for one of the options whose values are stored in the
  43. /// class's options_ array.
  44. ///
  45. /// \param index Index of the option in the limits_ array
  46. /// \param minval Expected minimum value
  47. /// \param maxval Expected maximum value
  48. void checkValuePair(int index, uint32_t minval = 0, uint32_t maxval = 0) {
  49. EXPECT_EQ(minimum(index), minval);
  50. EXPECT_EQ(maximum(index), maxval);
  51. }
  52. /// \brief Checks that all options are at default values
  53. ///
  54. /// Checks that all options have both their maximum and minimum set to the
  55. /// default values.
  56. ///
  57. /// \param except Index not to check. (This allows options not being tested
  58. /// to be checked to see that they are at the default value.) As all
  59. /// index values are positive, a negative value means check
  60. /// everything.
  61. void checkDefaultLimitsValues(int except = -1) {
  62. for (int i = 0; i < OptionInfo::SIZE; ++i) {
  63. if (i != except) {
  64. checkValuePair(i, OptionInfo::defval(i),
  65. OptionInfo::defval(i));
  66. }
  67. }
  68. }
  69. /// \brief Check valid command option
  70. ///
  71. /// Checks that the command line specification of one of the options taking
  72. /// a value correctly processes the option.
  73. ///
  74. /// \param index Option index
  75. /// \param optflag Option flag (in the form '--option')
  76. /// \param optval Value to be passed to the option.
  77. /// \param minval Expected minimum value
  78. /// \param maxval Expected maximum value
  79. void checkCommandValid(int index, const char* optflag, const char* optval,
  80. uint32_t minval, uint32_t maxval) {
  81. // Set up the command line and parse it.
  82. const char* argv[] = {"badpacket", NULL, NULL};
  83. argv[1] = optflag;
  84. argv[2] = optval;
  85. int argc = 3;
  86. parse(argc, const_cast<char**>(argv));
  87. // Check the results. Everything should be at the defaults except for
  88. // the specified option, where the minimum and maximum should be as
  89. // specified.
  90. checkDefaultOtherValues();
  91. checkDefaultLimitsValues(index);
  92. checkValuePair(index, minval, maxval);
  93. }
  94. /// \brief Check invalid command option
  95. ///
  96. /// Passed a command with an invalid value, checks that the parsing throws
  97. /// a BadValue exception.
  98. ///
  99. /// \param optflag Option flag (in the form '--option')
  100. /// \param optval Value to be passed to the option.
  101. void checkCommandInvalid(const char* optflag, const char* optval) {
  102. // Set up the command line and parse it.
  103. const char* argv[] = {"badpacket", NULL, NULL};
  104. argv[1] = optflag;
  105. argv[2] = optval;
  106. int argc = 3;
  107. EXPECT_THROW(parse(argc, const_cast<char**>(argv)), isc::BadValue);
  108. }
  109. /// \brief Check one-bit field
  110. ///
  111. /// Explicitly for those fields in the flags word that are one bit wide,
  112. /// perform a series of tests to check that they accept valid values and
  113. /// reject invalid ones.
  114. ///
  115. /// \param index Option index
  116. /// \param optflag Option flag (in the form '--option')
  117. void checkOneBitField(int index, const char* optflag) {
  118. checkCommandValid(index, optflag, "0", 0, 0);
  119. checkCommandValid(index, optflag, "1", 1, 1);
  120. checkCommandValid(index, optflag, "0-1", 0, 1);
  121. checkCommandValid(index, optflag, "1-0", 0, 1);
  122. checkCommandInvalid(optflag, "0-3");
  123. checkCommandInvalid(optflag, "4");
  124. checkCommandInvalid(optflag, "xyz");
  125. }
  126. /// \brief Check four-bit field
  127. ///
  128. /// Explicitly for those fields in the flags word that are four bits wide,
  129. /// perform a series of tests to check that they accept valid values and
  130. /// reject invalid ones.
  131. ///
  132. /// \param index Option index
  133. /// \param optflag Option flag (in the form '--option')
  134. void checkFourBitField(int index, const char* optflag) {
  135. checkCommandValid(index, optflag, "0", 0, 0);
  136. checkCommandValid(index, optflag, "15", 15, 15);
  137. checkCommandValid(index, optflag, "0-15", 0, 15);
  138. checkCommandValid(index, optflag, "15-0", 0, 15);
  139. checkCommandInvalid(optflag, "0-17");
  140. checkCommandInvalid(optflag, "24");
  141. checkCommandInvalid(optflag, "xyz");
  142. }
  143. /// \brief Check sixteen-bit field
  144. ///
  145. /// Explicitly test the parsing of the fields that can take a 16-bit
  146. /// value ranging from 0 to 65535.
  147. ///
  148. /// \param index Option index
  149. /// \param optflag Option flag (in the form '--option')
  150. void checkSixteenBitField(int index, const char* optflag) {
  151. checkCommandValid(index, optflag, "0", 0, 0);
  152. checkCommandValid(index, optflag, "65535", 65535, 65535);
  153. checkCommandValid(index, optflag, "0-65535", 0, 65535);
  154. checkCommandValid(index, optflag, "65535-0", 0, 65535);
  155. checkCommandInvalid(optflag, "0-65536");
  156. checkCommandInvalid(optflag, "65537");
  157. checkCommandInvalid(optflag, "xyz");
  158. }
  159. };
  160. // Check that each of the non-message options will be recognised
  161. TEST_F(CommandOptionsTest, address) {
  162. const char* argv[] = {"badpacket", "--address", "192.0.2.1"};
  163. int argc = sizeof(argv) / sizeof(const char*);
  164. // The conversion is ugly but it simplifies the process of entering the
  165. // string constant. The cast throws away the "const"ness of the pointed-to
  166. // strings in order to conform to the function signature; however, the
  167. // called functions all treat the strings as const.
  168. parse(argc, const_cast<char**>(argv));
  169. EXPECT_EQ("192.0.2.1", getAddress());
  170. EXPECT_EQ(53, getPort());
  171. EXPECT_EQ(500, getTimeout());
  172. EXPECT_EQ("www.example.com", getQname());
  173. checkDefaultLimitsValues();
  174. }
  175. TEST_F(CommandOptionsTest, port) {
  176. const char* argv[] = {"badpacket", "--port", "153"};
  177. int argc = sizeof(argv) / sizeof(const char*);
  178. parse(argc, const_cast<char**>(argv));
  179. EXPECT_EQ("127.0.0.1", getAddress());
  180. EXPECT_EQ(153, getPort());
  181. EXPECT_EQ(500, getTimeout());
  182. EXPECT_EQ("www.example.com", getQname());
  183. checkDefaultLimitsValues();
  184. }
  185. TEST_F(CommandOptionsTest, timeout) {
  186. const char* argv[] = {"badpacket", "--timeout", "250"};
  187. int argc = sizeof(argv) / sizeof(const char*);
  188. parse(argc, const_cast<char**>(argv));
  189. EXPECT_EQ("127.0.0.1", getAddress());
  190. EXPECT_EQ(53, getPort());
  191. EXPECT_EQ(250, getTimeout());
  192. EXPECT_EQ("www.example.com", getQname());
  193. checkDefaultLimitsValues();
  194. }
  195. TEST_F(CommandOptionsTest, parameter) {
  196. const char* argv[] = {"badpacket", "ftp.example.net"};
  197. int argc = sizeof(argv) / sizeof(const char*);
  198. parse(argc, const_cast<char**>(argv));
  199. EXPECT_EQ("127.0.0.1", getAddress());
  200. EXPECT_EQ(53, getPort());
  201. EXPECT_EQ(500, getTimeout());
  202. EXPECT_EQ("ftp.example.net", getQname());
  203. checkDefaultLimitsValues();
  204. }
  205. // Test options representing the flags fields.
  206. TEST_F(CommandOptionsTest, qr) {
  207. checkOneBitField(OptionInfo::QR, "--qr");
  208. }
  209. TEST_F(CommandOptionsTest, op) {
  210. checkFourBitField(OptionInfo::OP, "--op");
  211. }
  212. TEST_F(CommandOptionsTest, aa) {
  213. checkOneBitField(OptionInfo::AA, "--aa");
  214. }
  215. TEST_F(CommandOptionsTest, tc) {
  216. checkOneBitField(OptionInfo::TC, "--tc");
  217. }
  218. TEST_F(CommandOptionsTest, z) {
  219. checkOneBitField(OptionInfo::Z, "--z");
  220. }
  221. TEST_F(CommandOptionsTest, ad) {
  222. checkOneBitField(OptionInfo::AD, "--ad");
  223. }
  224. TEST_F(CommandOptionsTest, cd) {
  225. checkOneBitField(OptionInfo::CD, "--cd");
  226. }
  227. TEST_F(CommandOptionsTest, rc) {
  228. checkFourBitField(OptionInfo::RC, "--rc");
  229. }
  230. // Section count options
  231. TEST_F(CommandOptionsTest, qc) {
  232. checkSixteenBitField(OptionInfo::QC, "--qc");
  233. }
  234. TEST_F(CommandOptionsTest, ac) {
  235. checkSixteenBitField(OptionInfo::AC, "--ac");
  236. }
  237. TEST_F(CommandOptionsTest, uc) {
  238. checkSixteenBitField(OptionInfo::UC, "--uc");
  239. }
  240. TEST_F(CommandOptionsTest, dc) {
  241. checkSixteenBitField(OptionInfo::DC, "--dc");
  242. }
  243. // ... and the message size option
  244. TEST_F(CommandOptionsTest, ms) {
  245. int index = OptionInfo::MS;
  246. const char* optflag = "--ms";
  247. checkCommandValid(index, optflag, "1", 1, 1);
  248. checkCommandValid(index, optflag, "65536", 65536, 65536);
  249. checkCommandValid(index, optflag, "1-65536", 1, 65536);
  250. checkCommandValid(index, optflag, "65536-1", 1, 65536);
  251. checkCommandInvalid(optflag, "0");
  252. checkCommandInvalid(optflag, "1-65537");
  253. checkCommandInvalid(optflag, "65538");
  254. checkCommandInvalid(optflag, "xyz");
  255. }