command_options_unittest.cc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  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. // Test fixture class
  23. class CommandOptionsTest : public virtual ::testing::Test,
  24. public virtual CommandOptions
  25. {
  26. public:
  27. CommandOptionsTest() {}
  28. };
  29. // Check that the getRange() method works
  30. TEST_F(CommandOptionsTest, processOptionValue) {
  31. uint32_t result[2];
  32. // Check valid data
  33. processOptionValue("1", result, 0, 1);
  34. EXPECT_EQ(1, result[0]);
  35. EXPECT_EQ(1, result[1]);
  36. processOptionValue("0-2", result, 0, 5);
  37. EXPECT_EQ(0, result[0]);
  38. EXPECT_EQ(2, result[1]);
  39. processOptionValue("4-8", result, 0, 10);
  40. EXPECT_EQ(4, result[0]);
  41. EXPECT_EQ(8, result[1]);
  42. processOptionValue("172-103", result, 0, 200);
  43. EXPECT_EQ(103, result[0]);
  44. EXPECT_EQ(172, result[1]);
  45. // Check coercion is as expected
  46. processOptionValue("1", result, 3, 4); // Single value below range
  47. EXPECT_EQ(3, result[0]);
  48. EXPECT_EQ(3, result[1]);
  49. processOptionValue("7", result, 3, 6); // Single value above range
  50. EXPECT_EQ(6, result[0]);
  51. EXPECT_EQ(6, result[1]);
  52. processOptionValue("2-6", result, 5, 10); // Range overlaps valid range on low side
  53. EXPECT_EQ(5, result[0]);
  54. EXPECT_EQ(6, result[1]);
  55. processOptionValue("4-7", result, 5, 9); // Range overlaps valid range on high side
  56. EXPECT_EQ(5, result[0]);
  57. EXPECT_EQ(7, result[1]);
  58. processOptionValue("9-1", result, 4, 8); // Range overlaps valid range
  59. EXPECT_EQ(4, result[0]);
  60. EXPECT_EQ(8, result[1]);
  61. processOptionValue("4-8", result, 1, 9); // Range inside valid range
  62. EXPECT_EQ(4, result[0]);
  63. EXPECT_EQ(8, result[1]);
  64. // Now the invalid ones.
  65. EXPECT_ANY_THROW(processOptionValue("", result, 0, 1));
  66. EXPECT_ANY_THROW(processOptionValue(" ", result, 0, 1));
  67. EXPECT_ANY_THROW(processOptionValue("abc", result, 0, 1));
  68. EXPECT_ANY_THROW(processOptionValue("xyz-def", result, 0, 1));
  69. EXPECT_ANY_THROW(processOptionValue("0.7", result, 0, 1));
  70. EXPECT_ANY_THROW(processOptionValue("0.7-2.3", result, 0, 1));
  71. }
  72. // Checks the minimum and maximum values specified for a flag
  73. void
  74. checkValuePair(const uint32_t value[2], uint32_t minval = 0,
  75. uint32_t maxval = 0)
  76. {
  77. EXPECT_EQ(minval, value[0]);
  78. EXPECT_EQ(maxval, value[1]);
  79. }
  80. // Checks that all flag values in the command values are zero
  81. void
  82. checkDefaultFlagValues(const CommandOptions::FlagValues& values) {
  83. checkValuePair(values.qr);
  84. checkValuePair(values.op);
  85. checkValuePair(values.aa);
  86. checkValuePair(values.tc);
  87. checkValuePair(values.z);
  88. checkValuePair(values.ad);
  89. checkValuePair(values.cd);
  90. checkValuePair(values.rc);
  91. }
  92. // Checks non-flag options are set to defaults.
  93. void
  94. checkDefaultOtherValues(CommandOptions& options) {
  95. EXPECT_EQ("127.0.0.1", options.getAddress());
  96. EXPECT_EQ(53, options.getPort());
  97. EXPECT_EQ(500, options.getTimeout());
  98. EXPECT_EQ("www.example.com", options.getQname());
  99. }
  100. // Check that each of the options will be recognised
  101. TEST_F(CommandOptionsTest, address) {
  102. const char* argv[] = {"badpacket", "--address", "192.0.2.1"};
  103. int argc = sizeof(argv) / sizeof(const char*);
  104. // The conversion is ugly but it simplifies the process of entering the
  105. // string constant. The cast throws away the "const"ness of the pointed-to
  106. // strings in order to conform to the function signature; however, the
  107. // called functions all treat the strings as const.
  108. parse(argc, const_cast<char**>(argv));
  109. EXPECT_EQ("192.0.2.1", getAddress());
  110. EXPECT_EQ(53, getPort());
  111. EXPECT_EQ(500, getTimeout());
  112. EXPECT_EQ("www.example.com", getQname());
  113. checkDefaultFlagValues(getFlagValues());
  114. }
  115. TEST_F(CommandOptionsTest, port) {
  116. const char* argv[] = {"badpacket", "--port", "153"};
  117. int argc = sizeof(argv) / sizeof(const char*);
  118. parse(argc, const_cast<char**>(argv));
  119. EXPECT_EQ("127.0.0.1", getAddress());
  120. EXPECT_EQ(153, getPort());
  121. EXPECT_EQ(500, getTimeout());
  122. EXPECT_EQ("www.example.com", getQname());
  123. checkDefaultFlagValues(getFlagValues());
  124. }
  125. TEST_F(CommandOptionsTest, timeout) {
  126. const char* argv[] = {"badpacket", "--timeout", "250"};
  127. int argc = sizeof(argv) / sizeof(const char*);
  128. parse(argc, const_cast<char**>(argv));
  129. EXPECT_EQ("127.0.0.1", getAddress());
  130. EXPECT_EQ(53, getPort());
  131. EXPECT_EQ(250, getTimeout());
  132. EXPECT_EQ("www.example.com", getQname());
  133. checkDefaultFlagValues(getFlagValues());
  134. }
  135. TEST_F(CommandOptionsTest, parameter) {
  136. const char* argv[] = {"badpacket", "ftp.example.net"};
  137. int argc = sizeof(argv) / sizeof(const char*);
  138. parse(argc, const_cast<char**>(argv));
  139. EXPECT_EQ("127.0.0.1", getAddress());
  140. EXPECT_EQ(53, getPort());
  141. EXPECT_EQ(500, getTimeout());
  142. EXPECT_EQ("ftp.example.net", getQname());
  143. checkDefaultFlagValues(getFlagValues());
  144. }
  145. // The various tests of the different flags
  146. TEST_F(CommandOptionsTest, qr) {
  147. // Specifying a value of zero, we expect all flag values to be zero
  148. const char* argv1[] = {"badpacket", "--qr", "0"};
  149. int argc1 = sizeof(argv1) / sizeof(const char*);
  150. parse(argc1, const_cast<char**>(argv1));
  151. checkDefaultOtherValues(*this);
  152. FlagValues values = getFlagValues();
  153. checkDefaultFlagValues(values);
  154. // Check that a value of 1 is accepted
  155. const char* argv2[] = {"badpacket", "--qr", "1"};
  156. int argc2 = sizeof(argv2) / sizeof(const char*);
  157. parse(argc2, const_cast<char**>(argv2));
  158. checkDefaultOtherValues(*this);
  159. values = getFlagValues();
  160. checkValuePair(values.qr, 1, 1);
  161. checkValuePair(values.op);
  162. checkValuePair(values.aa);
  163. checkValuePair(values.tc);
  164. checkValuePair(values.z);
  165. checkValuePair(values.ad);
  166. checkValuePair(values.cd);
  167. checkValuePair(values.rc);
  168. // Check that a range is accepted (in this case, specified backwards)
  169. const char* argv3[] = {"badpacket", "--qr", "1-0"};
  170. int argc3 = sizeof(argv3) / sizeof(const char*);
  171. parse(argc3, const_cast<char**>(argv3));
  172. checkDefaultOtherValues(*this);
  173. values = getFlagValues();
  174. checkValuePair(values.qr, 0, 1);
  175. checkValuePair(values.op);
  176. checkValuePair(values.aa);
  177. checkValuePair(values.tc);
  178. checkValuePair(values.z);
  179. checkValuePair(values.ad);
  180. checkValuePair(values.cd);
  181. checkValuePair(values.rc);
  182. }
  183. // The following are cut-and-pasted from the "qr" test. (It is awkward to put
  184. // the test into a general function because of differing string values and
  185. // variables.)
  186. TEST_F(CommandOptionsTest, op) {
  187. // Specifying a value of zero, we expect all flag values to be zero
  188. const char* argv1[] = {"badpacket", "--op", "0"};
  189. int argc1 = sizeof(argv1) / sizeof(const char*);
  190. parse(argc1, const_cast<char**>(argv1));
  191. checkDefaultOtherValues(*this);
  192. FlagValues values = getFlagValues();
  193. checkDefaultFlagValues(values);
  194. // Check that a value of 1 is accepted
  195. const char* argv2[] = {"badpacket", "--op", "8"};
  196. int argc2 = sizeof(argv2) / sizeof(const char*);
  197. parse(argc2, const_cast<char**>(argv2));
  198. checkDefaultOtherValues(*this);
  199. values = getFlagValues();
  200. checkValuePair(values.qr);
  201. checkValuePair(values.op, 8, 8);
  202. checkValuePair(values.aa);
  203. checkValuePair(values.tc);
  204. checkValuePair(values.z);
  205. checkValuePair(values.ad);
  206. checkValuePair(values.cd);
  207. checkValuePair(values.rc);
  208. // Check that a range is accepted (in this case, specified backwards and
  209. // outside the range - so it should be truncated).
  210. const char* argv3[] = {"badpacket", "--op", "21-0"};
  211. int argc3 = sizeof(argv3) / sizeof(const char*);
  212. parse(argc3, const_cast<char**>(argv3));
  213. checkDefaultOtherValues(*this);
  214. values = getFlagValues();
  215. checkValuePair(values.qr);
  216. checkValuePair(values.op, 0, 15);
  217. checkValuePair(values.aa);
  218. checkValuePair(values.tc);
  219. checkValuePair(values.z);
  220. checkValuePair(values.ad);
  221. checkValuePair(values.cd);
  222. checkValuePair(values.rc);
  223. }
  224. TEST_F(CommandOptionsTest, aa) {
  225. // Specifying a value of zero, we expect all flag values to be zero
  226. const char* argv1[] = {"badpacket", "--aa", "0"};
  227. int argc1 = sizeof(argv1) / sizeof(const char*);
  228. parse(argc1, const_cast<char**>(argv1));
  229. checkDefaultOtherValues(*this);
  230. FlagValues values = getFlagValues();
  231. checkDefaultFlagValues(values);
  232. // Check that a value of 1 is accepted
  233. const char* argv2[] = {"badpacket", "--aa", "1"};
  234. int argc2 = sizeof(argv2) / sizeof(const char*);
  235. parse(argc2, const_cast<char**>(argv2));
  236. checkDefaultOtherValues(*this);
  237. values = getFlagValues();
  238. checkValuePair(values.qr);
  239. checkValuePair(values.op);
  240. checkValuePair(values.aa, 1, 1);
  241. checkValuePair(values.tc);
  242. checkValuePair(values.z);
  243. checkValuePair(values.ad);
  244. checkValuePair(values.cd);
  245. checkValuePair(values.rc);
  246. // Check that a range is accepted (in this case, specified backwards and
  247. // outside the range - so it should be truncated).
  248. const char* argv3[] = {"badpacket", "--aa", "21-0"};
  249. int argc3 = sizeof(argv3) / sizeof(const char*);
  250. parse(argc3, const_cast<char**>(argv3));
  251. checkDefaultOtherValues(*this);
  252. values = getFlagValues();
  253. checkValuePair(values.qr);
  254. checkValuePair(values.op);
  255. checkValuePair(values.aa, 0, 1);
  256. checkValuePair(values.tc);
  257. checkValuePair(values.z);
  258. checkValuePair(values.ad);
  259. checkValuePair(values.cd);
  260. checkValuePair(values.rc);
  261. }
  262. TEST_F(CommandOptionsTest, tc) {
  263. // Specifying a value of zero, we expect all flag values to be zero
  264. const char* argv1[] = {"badpacket", "--tc", "0"};
  265. int argc1 = sizeof(argv1) / sizeof(const char*);
  266. parse(argc1, const_cast<char**>(argv1));
  267. checkDefaultOtherValues(*this);
  268. FlagValues values = getFlagValues();
  269. checkDefaultFlagValues(values);
  270. // Check that a value of 1 is accepted
  271. const char* argv2[] = {"badpacket", "--tc", "1"};
  272. int argc2 = sizeof(argv2) / sizeof(const char*);
  273. parse(argc2, const_cast<char**>(argv2));
  274. checkDefaultOtherValues(*this);
  275. values = getFlagValues();
  276. checkValuePair(values.qr);
  277. checkValuePair(values.op);
  278. checkValuePair(values.aa);
  279. checkValuePair(values.tc, 1, 1);
  280. checkValuePair(values.z);
  281. checkValuePair(values.ad);
  282. checkValuePair(values.cd);
  283. checkValuePair(values.rc);
  284. // Check that a range is accepted (in this case, specified backwards and
  285. // outside the range - so it should be truncated).
  286. const char* argv3[] = {"badpacket", "--tc", "21-0"};
  287. int argc3 = sizeof(argv3) / sizeof(const char*);
  288. parse(argc3, const_cast<char**>(argv3));
  289. checkDefaultOtherValues(*this);
  290. values = getFlagValues();
  291. checkValuePair(values.qr);
  292. checkValuePair(values.op);
  293. checkValuePair(values.aa);
  294. checkValuePair(values.tc, 0, 1);
  295. checkValuePair(values.z);
  296. checkValuePair(values.ad);
  297. checkValuePair(values.cd);
  298. checkValuePair(values.rc);
  299. }
  300. TEST_F(CommandOptionsTest, z) {
  301. // Specifying a value of zero, we expect all flag values to be zero
  302. const char* argv1[] = {"badpacket", "--z", "0"};
  303. int argc1 = sizeof(argv1) / sizeof(const char*);
  304. parse(argc1, const_cast<char**>(argv1));
  305. checkDefaultOtherValues(*this);
  306. FlagValues values = getFlagValues();
  307. checkDefaultFlagValues(values);
  308. // Check that a value of 1 is accepted
  309. const char* argv2[] = {"badpacket", "--z", "1"};
  310. int argc2 = sizeof(argv2) / sizeof(const char*);
  311. parse(argc2, const_cast<char**>(argv2));
  312. checkDefaultOtherValues(*this);
  313. values = getFlagValues();
  314. checkValuePair(values.qr);
  315. checkValuePair(values.op);
  316. checkValuePair(values.aa);
  317. checkValuePair(values.tc);
  318. checkValuePair(values.z, 1, 1);
  319. checkValuePair(values.ad);
  320. checkValuePair(values.cd);
  321. checkValuePair(values.rc);
  322. // Check that a range is accepted (in this case, specified backwards and
  323. // outside the range - so it should be truncated).
  324. const char* argv3[] = {"badpacket", "--z", "21-0"};
  325. int argc3 = sizeof(argv3) / sizeof(const char*);
  326. parse(argc3, const_cast<char**>(argv3));
  327. checkDefaultOtherValues(*this);
  328. values = getFlagValues();
  329. checkValuePair(values.qr);
  330. checkValuePair(values.op);
  331. checkValuePair(values.aa);
  332. checkValuePair(values.tc);
  333. checkValuePair(values.z, 0, 1);
  334. checkValuePair(values.ad);
  335. checkValuePair(values.cd);
  336. checkValuePair(values.rc);
  337. }
  338. TEST_F(CommandOptionsTest, ad) {
  339. // Specifying a value of zero, we expect all flag values to be zero
  340. const char* argv1[] = {"badpacket", "--ad", "0"};
  341. int argc1 = sizeof(argv1) / sizeof(const char*);
  342. parse(argc1, const_cast<char**>(argv1));
  343. checkDefaultOtherValues(*this);
  344. FlagValues values = getFlagValues();
  345. checkDefaultFlagValues(values);
  346. // Check that a value of 1 is accepted
  347. const char* argv2[] = {"badpacket", "--ad", "1"};
  348. int argc2 = sizeof(argv2) / sizeof(const char*);
  349. parse(argc2, const_cast<char**>(argv2));
  350. checkDefaultOtherValues(*this);
  351. values = getFlagValues();
  352. checkValuePair(values.qr);
  353. checkValuePair(values.op);
  354. checkValuePair(values.aa);
  355. checkValuePair(values.tc);
  356. checkValuePair(values.z);
  357. checkValuePair(values.ad, 1, 1);
  358. checkValuePair(values.cd);
  359. checkValuePair(values.rc);
  360. // Check that a range is accepted (in this case, specified backwards and
  361. // outside the range - so it should be truncated).
  362. const char* argv3[] = {"badpacket", "--ad", "21-0"};
  363. int argc3 = sizeof(argv3) / sizeof(const char*);
  364. parse(argc3, const_cast<char**>(argv3));
  365. checkDefaultOtherValues(*this);
  366. values = getFlagValues();
  367. checkValuePair(values.qr);
  368. checkValuePair(values.op);
  369. checkValuePair(values.aa);
  370. checkValuePair(values.tc);
  371. checkValuePair(values.z);
  372. checkValuePair(values.ad, 0, 1);
  373. checkValuePair(values.cd);
  374. checkValuePair(values.rc);
  375. }
  376. TEST_F(CommandOptionsTest, cd) {
  377. // Specifying a value of zero, we expect all flag values to be zero
  378. const char* argv1[] = {"badpacket", "--cd", "0"};
  379. int argc1 = sizeof(argv1) / sizeof(const char*);
  380. parse(argc1, const_cast<char**>(argv1));
  381. checkDefaultOtherValues(*this);
  382. FlagValues values = getFlagValues();
  383. checkDefaultFlagValues(values);
  384. // Check that a value of 1 is accepted
  385. const char* argv2[] = {"badpacket", "--cd", "1"};
  386. int argc2 = sizeof(argv2) / sizeof(const char*);
  387. parse(argc2, const_cast<char**>(argv2));
  388. checkDefaultOtherValues(*this);
  389. values = getFlagValues();
  390. checkValuePair(values.qr);
  391. checkValuePair(values.op);
  392. checkValuePair(values.aa);
  393. checkValuePair(values.tc);
  394. checkValuePair(values.z);
  395. checkValuePair(values.ad);
  396. checkValuePair(values.cd, 1, 1);
  397. checkValuePair(values.rc);
  398. // Check that a range is accepted (in this case, specified backwards and
  399. // outside the range - so it should be truncated).
  400. const char* argv3[] = {"badpacket", "--cd", "21-0"};
  401. int argc3 = sizeof(argv3) / sizeof(const char*);
  402. parse(argc3, const_cast<char**>(argv3));
  403. checkDefaultOtherValues(*this);
  404. values = getFlagValues();
  405. checkValuePair(values.qr);
  406. checkValuePair(values.op);
  407. checkValuePair(values.aa);
  408. checkValuePair(values.tc);
  409. checkValuePair(values.z);
  410. checkValuePair(values.ad);
  411. checkValuePair(values.cd, 0, 1);
  412. checkValuePair(values.rc);
  413. }
  414. TEST_F(CommandOptionsTest, rc) {
  415. // Specifying a value of zero, we expect all flag values to be zero
  416. const char* argv1[] = {"badpacket", "--rc", "0"};
  417. int argc1 = sizeof(argv1) / sizeof(const char*);
  418. parse(argc1, const_cast<char**>(argv1));
  419. checkDefaultOtherValues(*this);
  420. FlagValues values = getFlagValues();
  421. checkDefaultFlagValues(values);
  422. // Check that a value of 1 is accepted
  423. const char* argv2[] = {"badpacket", "--rc", "21"};
  424. int argc2 = sizeof(argv2) / sizeof(const char*);
  425. parse(argc2, const_cast<char**>(argv2));
  426. checkDefaultOtherValues(*this);
  427. values = getFlagValues();
  428. checkValuePair(values.qr);
  429. checkValuePair(values.op);
  430. checkValuePair(values.aa);
  431. checkValuePair(values.tc);
  432. checkValuePair(values.z);
  433. checkValuePair(values.ad);
  434. checkValuePair(values.cd);
  435. checkValuePair(values.rc, 15, 15);
  436. // Check that a range is accepted (in this case, specified backwards and
  437. // outside the range - so it should be truncated).
  438. const char* argv3[] = {"badpacket", "--rc", "21-0"};
  439. int argc3 = sizeof(argv3) / sizeof(const char*);
  440. parse(argc3, const_cast<char**>(argv3));
  441. checkDefaultOtherValues(*this);
  442. values = getFlagValues();
  443. checkValuePair(values.qr);
  444. checkValuePair(values.op);
  445. checkValuePair(values.aa);
  446. checkValuePair(values.tc);
  447. checkValuePair(values.z);
  448. checkValuePair(values.ad);
  449. checkValuePair(values.cd);
  450. checkValuePair(values.rc, 0, 15);
  451. }
  452. // Check that the other flags work