command_options_unittest.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. // Copyright (C) 2012 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 <boost/date_time/posix_time/posix_time.hpp>
  19. #include <dhcp/iface_mgr.h>
  20. #include <exceptions/exceptions.h>
  21. #include "command_options_helper.h"
  22. using namespace std;
  23. using namespace isc;
  24. using namespace isc::perfdhcp;
  25. using namespace boost::posix_time;
  26. /// \brief Test Fixture Class
  27. ///
  28. /// This test fixture class is used to perform
  29. /// unit tests on perfdhcp CommandOptions class.
  30. class CommandOptionsTest : public virtual ::testing::Test
  31. {
  32. public:
  33. /// \brief Default Constructor
  34. CommandOptionsTest() { }
  35. protected:
  36. /// \brief Parse command line and cleanup
  37. ///
  38. /// The method tokenizes command line to array of C-strings,
  39. /// parses arguments using CommandOptions class to set
  40. /// its data members and de-allocates array of C-strings.
  41. ///
  42. /// \param cmdline Command line to parse.
  43. /// \throws std::bad allocation if tokenization failed.
  44. /// \return true if program has been run in help or version mode ('h' or 'v' flag).
  45. bool process(const std::string& cmdline) {
  46. return (CommandOptionsHelper::process(cmdline));
  47. }
  48. /// \brief Check default initialized values
  49. ///
  50. /// Check if initialized values are correct
  51. void checkDefaults() {
  52. CommandOptions& opt = CommandOptions::instance();
  53. EXPECT_NO_THROW(process("perfdhcp 192.168.0.1"));
  54. EXPECT_EQ(4, opt.getIpVersion());
  55. EXPECT_EQ(CommandOptions::DORA_SARR, opt.getExchangeMode());
  56. EXPECT_EQ(0, opt.getRate());
  57. EXPECT_EQ(0, opt.getReportDelay());
  58. EXPECT_EQ(0, opt.getClientsNum());
  59. // default mac
  60. const uint8_t mac[6] = { 0x00, 0x0C, 0x01, 0x02, 0x03, 0x04 };
  61. std::vector<uint8_t> v1 = opt.getMacTemplate();
  62. ASSERT_EQ(6, v1.size());
  63. EXPECT_TRUE(std::equal(v1.begin(), v1.end(), mac));
  64. // Check if DUID is initialized. The DUID-LLT is expected
  65. // to start with DUID_LLT value of 1 and hardware ethernet
  66. // type equal to 1 (HWETHER_TYPE).
  67. const uint8_t duid_llt_and_hw[4] = { 0x0, 0x1, 0x0, 0x1 };
  68. // We assume DUID-LLT length 14. This includes 4 octets of
  69. // DUID_LLT value, two octets of hardware type, 4 octets
  70. // of time value and 6 octets of variable link layer (MAC)
  71. // address.
  72. const int duid_llt_size = 14;
  73. // DUID is not given from the command line but it is supposed
  74. // to be initialized by the CommandOptions private method
  75. // generateDuidTemplate().
  76. std::vector<uint8_t> v2 = opt.getDuidTemplate();
  77. ASSERT_EQ(duid_llt_size, opt.getDuidTemplate().size());
  78. EXPECT_TRUE(std::equal(v2.begin(), v2.begin() + 4,
  79. duid_llt_and_hw));
  80. // Check time field contents.
  81. ptime now = microsec_clock::universal_time();
  82. ptime duid_epoch(from_iso_string("20000101T000000"));
  83. time_period period(duid_epoch, now);
  84. uint32_t duration_sec = period.length().total_seconds();
  85. // Read time from the template generated.
  86. uint32_t duration_from_template = 0;
  87. memcpy(&duration_from_template, &v2[4], 4);
  88. duration_from_template = htonl(duration_from_template);
  89. // In special cases, we may have overflow in time field
  90. // so we give ourselves the margin of 10 seconds here.
  91. // If time value has been set more then 10 seconds back
  92. // it is safe to compare it with the time value generated
  93. // from now.
  94. if (duration_from_template > 10) {
  95. EXPECT_GE(duration_sec, duration_from_template);
  96. }
  97. EXPECT_EQ(0, opt.getBase().size());
  98. EXPECT_EQ(0, opt.getNumRequests().size());
  99. EXPECT_EQ(0, opt.getPeriod());
  100. for (int i = 0; i < opt.getDropTime().size(); ++i) {
  101. EXPECT_DOUBLE_EQ(1, opt.getDropTime()[i]);
  102. }
  103. ASSERT_EQ(opt.getMaxDrop().size(), opt.getMaxDropPercentage().size());
  104. for (int i = 0; i < opt.getMaxDrop().size(); ++i) {
  105. EXPECT_EQ(0, opt.getMaxDrop()[i]);
  106. EXPECT_EQ(0, opt.getMaxDropPercentage()[i]);
  107. }
  108. EXPECT_EQ("", opt.getLocalName());
  109. EXPECT_FALSE(opt.isInterface());
  110. EXPECT_EQ(0, opt.getPreload());
  111. EXPECT_EQ(1, opt.getAggressivity());
  112. EXPECT_EQ(0, opt.getLocalPort());
  113. EXPECT_FALSE(opt.isSeeded());
  114. EXPECT_EQ(0, opt.getSeed());
  115. EXPECT_FALSE(opt.isBroadcast());
  116. EXPECT_FALSE(opt.isRapidCommit());
  117. EXPECT_FALSE(opt.isUseFirst());
  118. EXPECT_EQ(0, opt.getTemplateFiles().size());
  119. EXPECT_EQ(0, opt.getTransactionIdOffset().size());
  120. EXPECT_EQ(0, opt.getRandomOffset().size());
  121. EXPECT_GT(0, opt.getElapsedTimeOffset());
  122. EXPECT_GT(0, opt.getServerIdOffset());
  123. EXPECT_GT(0, opt.getRequestedIpOffset());
  124. EXPECT_EQ("", opt.getDiags());
  125. EXPECT_EQ("", opt.getWrapped());
  126. EXPECT_EQ("192.168.0.1", opt.getServerName());
  127. }
  128. };
  129. TEST_F(CommandOptionsTest, Defaults) {
  130. EXPECT_NO_THROW(process("perfdhcp all"));
  131. checkDefaults();
  132. }
  133. TEST_F(CommandOptionsTest, HelpVersion) {
  134. // The parser is supposed to return true if 'h' or 'v' options
  135. // are specified.
  136. EXPECT_TRUE(process("perfdhcp -h"));
  137. EXPECT_TRUE(process("perfdhcp -v"));
  138. EXPECT_TRUE(process("perfdhcp -h -v"));
  139. EXPECT_TRUE(process("perfdhcp -6 -l ethx -h all"));
  140. EXPECT_TRUE(process("perfdhcp -l ethx -v all"));
  141. // No 'h' or 'v' option specified. The false value
  142. // should be returned.
  143. EXPECT_FALSE(process("perfdhcp -l ethx all"));
  144. }
  145. TEST_F(CommandOptionsTest, UseFirst) {
  146. CommandOptions& opt = CommandOptions::instance();
  147. EXPECT_NO_THROW(process("perfdhcp -1 -B -l ethx all"));
  148. EXPECT_TRUE(opt.isUseFirst());
  149. }
  150. TEST_F(CommandOptionsTest, IpVersion) {
  151. CommandOptions& opt = CommandOptions::instance();
  152. EXPECT_NO_THROW(process("perfdhcp -6 -l ethx -c -i all"));
  153. EXPECT_EQ(6, opt.getIpVersion());
  154. EXPECT_EQ("ethx", opt.getLocalName());
  155. EXPECT_TRUE(opt.isRapidCommit());
  156. EXPECT_FALSE(opt.isBroadcast());
  157. process("perfdhcp -4 -B -l ethx all");
  158. EXPECT_EQ(4, opt.getIpVersion());
  159. EXPECT_TRUE(opt.isBroadcast());
  160. EXPECT_FALSE(opt.isRapidCommit());
  161. // Negative test cases
  162. // -4 and -6 must not coexist
  163. EXPECT_THROW(process("perfdhcp -4 -6 -l ethx all"), isc::InvalidParameter);
  164. // -6 and -B must not coexist
  165. EXPECT_THROW(process("perfdhcp -6 -B -l ethx all"), isc::InvalidParameter);
  166. // -c and -4 (default) must not coexist
  167. EXPECT_THROW(process("perfdhcp -c -l ethx all"), isc::InvalidParameter);
  168. }
  169. TEST_F(CommandOptionsTest, Rate) {
  170. CommandOptions& opt = CommandOptions::instance();
  171. EXPECT_NO_THROW(process("perfdhcp -4 -r 10 -l ethx all"));
  172. EXPECT_EQ(10, opt.getRate());
  173. // Negative test cases
  174. // Rate must not be 0
  175. EXPECT_THROW(process("perfdhcp -4 -r 0 -l ethx all"),
  176. isc::InvalidParameter);
  177. // -r must be specified to use -n, -p and -D
  178. EXPECT_THROW(process("perfdhcp -6 -t 5 -l ethx all"),
  179. isc::InvalidParameter);
  180. EXPECT_THROW(process("perfdhcp -4 -n 150 -l ethx all"),
  181. isc::InvalidParameter);
  182. EXPECT_THROW(process("perfdhcp -6 -p 120 -l ethx all"),
  183. isc::InvalidParameter);
  184. EXPECT_THROW(process("perfdhcp -4 -D 1400 -l ethx all"),
  185. isc::InvalidParameter);
  186. }
  187. TEST_F(CommandOptionsTest, ReportDelay) {
  188. CommandOptions& opt = CommandOptions::instance();
  189. EXPECT_NO_THROW(process("perfdhcp -r 100 -t 17 -l ethx all"));
  190. EXPECT_EQ(17, opt.getReportDelay());
  191. // Negative test cases
  192. // -t must be positive integer
  193. EXPECT_THROW(process("perfdhcp -r 10 -t -8 -l ethx all"),
  194. isc::InvalidParameter);
  195. EXPECT_THROW(process("perfdhcp -r 10 -t 0 -l ethx all"),
  196. isc::InvalidParameter);
  197. EXPECT_THROW(process("perfdhcp -r 10 -t s -l ethx all"),
  198. isc::InvalidParameter);
  199. }
  200. TEST_F(CommandOptionsTest, ClientsNum) {
  201. CommandOptions& opt = CommandOptions::instance();
  202. EXPECT_NO_THROW(process("perfdhcp -R 200 -l ethx all"));
  203. EXPECT_EQ(200, opt.getClientsNum());
  204. process("perfdhcp -R 0 -l ethx all");
  205. EXPECT_EQ(0, opt.getClientsNum());
  206. // Negative test cases
  207. // Number of clients must be non-negative integer
  208. EXPECT_THROW(process("perfdhcp -R -5 -l ethx all"),
  209. isc::InvalidParameter);
  210. EXPECT_THROW(process("perfdhcp -R gs -l ethx all"),
  211. isc::InvalidParameter);
  212. }
  213. TEST_F(CommandOptionsTest, Base) {
  214. CommandOptions& opt = CommandOptions::instance();
  215. uint8_t mac[6] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60 };
  216. uint8_t duid[14] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  217. 0x01, 0x01, 0x01, 0x10, 0x11, 0x1F, 0x14 };
  218. // Test DUID and MAC together.
  219. EXPECT_NO_THROW(process("perfdhcp -b DUID=0101010101010101010110111F14"
  220. " -b MAC=10::20::30::40::50::60"
  221. " -l 127.0.0.1 all"));
  222. std::vector<uint8_t> v1 = opt.getMacTemplate();
  223. std::vector<uint8_t> v2 = opt.getDuidTemplate();
  224. v2 = opt.getDuidTemplate();
  225. EXPECT_TRUE(std::equal(v1.begin(), v1.end(), mac));
  226. EXPECT_TRUE(std::equal(v2.begin(), v2.end(), duid));
  227. // Test valid DUID.
  228. EXPECT_NO_THROW(
  229. process("perfdhcp -b duid=0101010101010101010110111F14 -l 127.0.0.1 all")
  230. );
  231. ASSERT_EQ(sizeof(duid) / sizeof(uint8_t), v2.size());
  232. EXPECT_TRUE(std::equal(v2.begin(), v2.end(), duid));
  233. // Test mix of upper/lower case letters.
  234. EXPECT_NO_THROW(process("perfdhcp -b DuiD=0101010101010101010110111F14"
  235. " -b Mac=10::20::30::40::50::60"
  236. " -l 127.0.0.1 all"));
  237. v1 = opt.getMacTemplate();
  238. v2 = opt.getDuidTemplate();
  239. EXPECT_TRUE(std::equal(v1.begin(), v1.end(), mac));
  240. EXPECT_TRUE(std::equal(v2.begin(), v2.end(), duid));
  241. // Use "ether" instead of "mac".
  242. EXPECT_NO_THROW(process("perfdhcp -b ether=10::20::30::40::50::60"
  243. " -l 127.0.0.1 all"));
  244. v1 = opt.getMacTemplate();
  245. EXPECT_TRUE(std::equal(v1.begin(), v1.end(), mac));
  246. // Use "ETHER" in upper case.
  247. EXPECT_NO_THROW(process("perfdhcp -b ETHER=10::20::30::40::50::60"
  248. " -l 127.0.0.1 all"));
  249. v1 = opt.getMacTemplate();
  250. EXPECT_TRUE(std::equal(v1.begin(), v1.end(), mac));
  251. // "t" is invalid character in DUID
  252. EXPECT_THROW(process("perfdhcp -6 -l ethx -b "
  253. "duid=010101010101010101t110111F14 all"),
  254. isc::InvalidParameter);
  255. // "3x" is invalid value in MAC address
  256. EXPECT_THROW(process("perfdhcp -b mac=10::2::3x::4::5::6 -l ethx all"),
  257. isc::InvalidParameter);
  258. // Base is not specified
  259. EXPECT_THROW(process("perfdhcp -b -l ethx all"),
  260. isc::InvalidParameter);
  261. // Typo: should be mac= instead of mc=
  262. EXPECT_THROW(process("perfdhcp -l ethx -b mc=00:01:02:03::04:05 all"),
  263. isc::InvalidParameter);
  264. // Too short DUID (< 6).
  265. EXPECT_THROW(process("perfdhcp -l ethx -b duid=00010203 all"),
  266. isc::InvalidParameter);
  267. // Odd number of digits.
  268. EXPECT_THROW(process("perfdhcp -l ethx -b duid=000102030405060 all"),
  269. isc::InvalidParameter);
  270. // Too short MAC (!= 6).
  271. EXPECT_THROW(process("perfdhcp -l ethx -b mac=00:01:02:04 all"),
  272. isc::InvalidParameter);
  273. }
  274. TEST_F(CommandOptionsTest, DropTime) {
  275. CommandOptions& opt = CommandOptions::instance();
  276. EXPECT_NO_THROW(process("perfdhcp -l ethx -d 12 all"));
  277. ASSERT_EQ(2, opt.getDropTime().size());
  278. EXPECT_DOUBLE_EQ(12, opt.getDropTime()[0]);
  279. EXPECT_DOUBLE_EQ(1, opt.getDropTime()[1]);
  280. EXPECT_NO_THROW(process("perfdhcp -l ethx -d 2 -d 4.7 all"));
  281. ASSERT_EQ(2, opt.getDropTime().size());
  282. EXPECT_DOUBLE_EQ(2, opt.getDropTime()[0]);
  283. EXPECT_DOUBLE_EQ(4.7, opt.getDropTime()[1]);
  284. // Negative test cases
  285. // Drop time must not be negative
  286. EXPECT_THROW(process("perfdhcp -l ethx -d -2 -d 4.7 all"),
  287. isc::InvalidParameter);
  288. EXPECT_THROW(process("perfdhcp -l ethx -d -9.1 -d 0 all"),
  289. isc::InvalidParameter);
  290. }
  291. TEST_F(CommandOptionsTest, TimeOffset) {
  292. CommandOptions& opt = CommandOptions::instance();
  293. EXPECT_NO_THROW(process("perfdhcp -l ethx -T file1.x -T file2.x -E 4 all"));
  294. EXPECT_EQ(4, opt.getElapsedTimeOffset());
  295. // Negative test cases
  296. // Argument -E must be used with -T
  297. EXPECT_THROW(process("perfdhcp -l ethx -E 3 -i all"),
  298. isc::InvalidParameter);
  299. // Value in -E not specified
  300. EXPECT_THROW(process("perfdhcp -l ethx -T file.x -E -i all"),
  301. isc::InvalidParameter);
  302. // Value for -E must not be negative
  303. EXPECT_THROW(process("perfdhcp -l ethx -E -3 -T file.x all"),
  304. isc::InvalidParameter);
  305. }
  306. TEST_F(CommandOptionsTest, ExchangeMode) {
  307. CommandOptions& opt = CommandOptions::instance();
  308. process("perfdhcp -l ethx -i all");
  309. EXPECT_EQ(CommandOptions::DO_SA, opt.getExchangeMode());
  310. // Negative test cases
  311. // No template file specified
  312. EXPECT_THROW(process("perfdhcp -i -l ethx -X 3 all"),
  313. isc::InvalidParameter);
  314. // Offsets can't be used in simple exchanges (-i)
  315. EXPECT_THROW(process("perfdhcp -i -l ethx -O 2 -T file.x all"),
  316. isc::InvalidParameter);
  317. EXPECT_THROW(process("perfdhcp -i -l ethx -E 3 -T file.x all"),
  318. isc::InvalidParameter);
  319. EXPECT_THROW(process("perfdhcp -i -l ethx -S 1 -T file.x all"),
  320. isc::InvalidParameter);
  321. EXPECT_THROW(process("perfdhcp -i -l ethx -I 2 -T file.x all"),
  322. isc::InvalidParameter);
  323. }
  324. TEST_F(CommandOptionsTest, Offsets) {
  325. CommandOptions& opt = CommandOptions::instance();
  326. EXPECT_NO_THROW(process("perfdhcp -E5 -4 -I 2 -S3 -O 30 -X7 -l ethx "
  327. "-X3 -T file1.x -T file2.x all"));
  328. EXPECT_EQ(2, opt.getRequestedIpOffset());
  329. EXPECT_EQ(5, opt.getElapsedTimeOffset());
  330. EXPECT_EQ(3, opt.getServerIdOffset());
  331. ASSERT_EQ(2, opt.getRandomOffset().size());
  332. EXPECT_EQ(30, opt.getRandomOffset()[0]);
  333. EXPECT_EQ(30, opt.getRandomOffset()[1]);
  334. ASSERT_EQ(2, opt.getTransactionIdOffset().size());
  335. EXPECT_EQ(7, opt.getTransactionIdOffset()[0]);
  336. EXPECT_EQ(3, opt.getTransactionIdOffset()[1]);
  337. // Negative test cases
  338. // IP offset/IA_NA offset must be positive
  339. EXPECT_THROW(process("perfdhcp -6 -I 0 -l ethx all"),
  340. isc::InvalidParameter);
  341. EXPECT_THROW(process("perfdhcp -6 -I -4 -l ethx all"),
  342. isc::InvalidParameter);
  343. // TODO - other negative cases
  344. }
  345. TEST_F(CommandOptionsTest, LocalPort) {
  346. CommandOptions& opt = CommandOptions::instance();
  347. EXPECT_NO_THROW(process("perfdhcp -l ethx -L 2000 all"));
  348. EXPECT_EQ(2000, opt.getLocalPort());
  349. // Negative test cases
  350. // Local port must be between 0..65535
  351. EXPECT_THROW(process("perfdhcp -l ethx -L -2 all"),
  352. isc::InvalidParameter);
  353. EXPECT_THROW(process("perfdhcp -l ethx -L all"),
  354. isc::InvalidParameter);
  355. EXPECT_THROW(process("perfdhcp -l ethx -L 65540 all"),
  356. isc::InvalidParameter);
  357. }
  358. TEST_F(CommandOptionsTest, Preload) {
  359. CommandOptions& opt = CommandOptions::instance();
  360. EXPECT_NO_THROW(process("perfdhcp -1 -P 3 -l ethx all"));
  361. EXPECT_EQ(3, opt.getPreload());
  362. // Negative test cases
  363. // Number of preload packages must not be negative integer
  364. EXPECT_THROW(process("perfdhcp -P -1 -l ethx all"),
  365. isc::InvalidParameter);
  366. EXPECT_THROW(process("perfdhcp -P -3 -l ethx all"),
  367. isc::InvalidParameter);
  368. }
  369. TEST_F(CommandOptionsTest, Seed) {
  370. CommandOptions& opt = CommandOptions::instance();
  371. EXPECT_NO_THROW(process("perfdhcp -6 -P 2 -s 23 -l ethx all"));
  372. EXPECT_EQ(23, opt.getSeed());
  373. EXPECT_TRUE(opt.isSeeded());
  374. EXPECT_NO_THROW(process("perfdhcp -6 -P 2 -s 0 -l ethx all"));
  375. EXPECT_EQ(0, opt.getSeed());
  376. EXPECT_FALSE(opt.isSeeded());
  377. // Negtaive test cases
  378. // Seed must be non-negative integer
  379. EXPECT_THROW(process("perfdhcp -6 -P 2 -s -5 -l ethx all"),
  380. isc::InvalidParameter);
  381. EXPECT_THROW(process("perfdhcp -6 -P 2 -s -l ethx all"),
  382. isc::InvalidParameter);
  383. }
  384. TEST_F(CommandOptionsTest, TemplateFiles) {
  385. CommandOptions& opt = CommandOptions::instance();
  386. EXPECT_NO_THROW(process("perfdhcp -T file1.x -l ethx all"));
  387. ASSERT_EQ(1, opt.getTemplateFiles().size());
  388. EXPECT_EQ("file1.x", opt.getTemplateFiles()[0]);
  389. EXPECT_NO_THROW(process("perfdhcp -T file1.x -s 12 -w start -T file2.x -4 -l ethx all"));
  390. ASSERT_EQ(2, opt.getTemplateFiles().size());
  391. EXPECT_EQ("file1.x", opt.getTemplateFiles()[0]);
  392. EXPECT_EQ("file2.x", opt.getTemplateFiles()[1]);
  393. // Negative test cases
  394. // No template file specified
  395. EXPECT_THROW(process("perfdhcp -s 12 -T -l ethx all"),
  396. isc::InvalidParameter);
  397. // Too many template files specified
  398. EXPECT_THROW(process("perfdhcp -s 12 -l ethx -T file.x "
  399. "-T file.x -T file.x all"),
  400. isc::InvalidParameter);
  401. }
  402. TEST_F(CommandOptionsTest, Wrapped) {
  403. CommandOptions& opt = CommandOptions::instance();
  404. EXPECT_NO_THROW(process("perfdhcp -B -w start -i -l ethx all"));
  405. EXPECT_EQ("start", opt.getWrapped());
  406. // Negative test cases
  407. // Missing command after -w, expected start/stop
  408. EXPECT_THROW(process("perfdhcp -B -i -l ethx -w all"),
  409. isc::InvalidParameter);
  410. }
  411. TEST_F(CommandOptionsTest, Diagnostics) {
  412. CommandOptions& opt = CommandOptions::instance();
  413. EXPECT_NO_THROW(process("perfdhcp -l ethx -i -x asTe all"));
  414. EXPECT_EQ("asTe", opt.getDiags());
  415. // Negative test cases
  416. // No diagnostics string specified
  417. EXPECT_THROW(process("perfdhcp -l ethx -i -x all"),
  418. isc::InvalidParameter);
  419. }
  420. TEST_F(CommandOptionsTest, Aggressivity) {
  421. CommandOptions& opt = CommandOptions::instance();
  422. process("perfdhcp -a 10 -l 192.168.0.1 all");
  423. EXPECT_EQ(10, opt.getAggressivity());
  424. // Negative test cases
  425. // Aggressivity must be non negative integer
  426. EXPECT_THROW(process("perfdhcp -l ethx -a 0 all"),
  427. isc::InvalidParameter);
  428. EXPECT_THROW(process("perfdhcp -l ethx -a all"),
  429. isc::InvalidParameter);
  430. EXPECT_THROW(process("perfdhcp -a -2 -l ethx -a 3 all"),
  431. isc::InvalidParameter);
  432. }
  433. TEST_F(CommandOptionsTest, MaxDrop) {
  434. CommandOptions& opt = CommandOptions::instance();
  435. EXPECT_NO_THROW(process("perfdhcp -D 25 -l ethx -r 10 all"));
  436. EXPECT_EQ(25, opt.getMaxDrop()[0]);
  437. EXPECT_NO_THROW(process("perfdhcp -D 25 -l ethx -D 15 -r 10 all"));
  438. EXPECT_EQ(25, opt.getMaxDrop()[0]);
  439. EXPECT_EQ(15, opt.getMaxDrop()[1]);
  440. EXPECT_NO_THROW(process("perfdhcp -D 15% -l ethx -r 10 all"));
  441. EXPECT_EQ(15, opt.getMaxDropPercentage()[0]);
  442. EXPECT_NO_THROW(process("perfdhcp -D 15% -D25% -l ethx -r 10 all"));
  443. EXPECT_EQ(15, opt.getMaxDropPercentage()[0]);
  444. EXPECT_EQ(25, opt.getMaxDropPercentage()[1]);
  445. EXPECT_NO_THROW(process("perfdhcp -D 1% -D 99% -l ethx -r 10 all"));
  446. EXPECT_EQ(1, opt.getMaxDropPercentage()[0]);
  447. EXPECT_EQ(99, opt.getMaxDropPercentage()[1]);
  448. // Negative test cases
  449. // Too many -D<value> options
  450. EXPECT_THROW(process("perfdhcp -D 0% -D 1 -l ethx -r20 -D 3 all"),
  451. isc::InvalidParameter);
  452. // Too many -D<value%> options
  453. EXPECT_THROW(process("perfdhcp -D 99% -D 13% -l ethx -r20 -D 10% all"),
  454. isc::InvalidParameter);
  455. // Percentage is out of bounds
  456. EXPECT_THROW(process("perfdhcp -D101% -D 13% -l ethx -r20 all"),
  457. isc::InvalidParameter);
  458. EXPECT_THROW(process("perfdhcp -D0% -D 13% -l ethx -r20 all"),
  459. isc::InvalidParameter);
  460. }
  461. TEST_F(CommandOptionsTest, NumRequest) {
  462. CommandOptions& opt = CommandOptions::instance();
  463. EXPECT_NO_THROW(process("perfdhcp -n 1000 -r 10 -l ethx all"));
  464. EXPECT_EQ(1000, opt.getNumRequests()[0]);
  465. EXPECT_NO_THROW(process("perfdhcp -n 5 -r 10 -n 500 -l ethx all"));
  466. EXPECT_EQ(5, opt.getNumRequests()[0]);
  467. EXPECT_EQ(500, opt.getNumRequests()[1]);
  468. // Negative test cases
  469. // Too many -n<value> parameters, expected maximum 2
  470. EXPECT_THROW(process("perfdhcp -n 1 -n 2 -l ethx -n3 -r 20 all"),
  471. isc::InvalidParameter);
  472. // Num request must be positive integer
  473. EXPECT_THROW(process("perfdhcp -n 1 -n -22 -l ethx -r 10 all"),
  474. isc::InvalidParameter);
  475. EXPECT_THROW(process("perfdhcp -n 0 -l ethx -r 10 all"),
  476. isc::InvalidParameter);
  477. }
  478. TEST_F(CommandOptionsTest, Period) {
  479. CommandOptions& opt = CommandOptions::instance();
  480. EXPECT_NO_THROW(process("perfdhcp -p 120 -l ethx -r 100 all"));
  481. EXPECT_EQ(120, opt.getPeriod());
  482. // Negative test cases
  483. // Test period must be positive integer
  484. EXPECT_THROW(process("perfdhcp -p 0 -l ethx -r 50 all"),
  485. isc::InvalidParameter);
  486. EXPECT_THROW(process("perfdhcp -p -3 -l ethx -r 50 all"),
  487. isc::InvalidParameter);
  488. }
  489. TEST_F(CommandOptionsTest, Interface) {
  490. // In order to make this test portable we need to know
  491. // at least one interface name on OS where test is run.
  492. // Interface Manager has ability to detect interfaces.
  493. // Altough we don't call initIsInterface explicitely
  494. // here it is called by CommandOptions object interally
  495. // so this function is covered by the test.
  496. dhcp::IfaceMgr& iface_mgr = dhcp::IfaceMgr::instance();
  497. const dhcp::IfaceMgr::IfaceCollection& ifaces = iface_mgr.getIfaces();
  498. std::string iface_name;
  499. CommandOptions& opt = CommandOptions::instance();
  500. // The local loopback interface should be available.
  501. // If no interface have been found for any reason we should
  502. // not fail this test.
  503. if (ifaces.size() > 0) {
  504. // Get the name of the interface we detected.
  505. iface_name = ifaces.begin()->getName();
  506. // Use the name in the command parser.
  507. ASSERT_NO_THROW(process("perfdhcp -4 -l " + iface_name + " abc"));
  508. // We expect that command parser will detect that argument
  509. // specified along with '-l' is the interface name.
  510. EXPECT_TRUE(opt.isInterface());
  511. // If neither interface nor server is specified then
  512. // exception is expected to be thrown.
  513. EXPECT_THROW(process("perfdhcp -4"), isc::InvalidParameter);
  514. }
  515. }
  516. TEST_F(CommandOptionsTest, Server) {
  517. CommandOptions& opt = CommandOptions::instance();
  518. // There is at least server parameter needed. If server is not
  519. // specified the local interface must be specified.
  520. // The server value equal to 'all' means use broadcast.
  521. ASSERT_NO_THROW(process("perfdhcp all"));
  522. // Once command line is parsed we expect that server name is
  523. // set to broadcast address because 'all' was specified.
  524. EXPECT_TRUE(opt.isBroadcast());
  525. // The broadcast address is 255.255.255.255.
  526. EXPECT_EQ(DHCP_IPV4_BROADCAST_ADDRESS, opt.getServerName());
  527. // When all is specified for DHCPv6 mode we expect
  528. // FF02::1:2 as a server name which means All DHCP
  529. // servers and relay agents in local network segment
  530. ASSERT_NO_THROW(process("perfdhcp -6 all"));
  531. EXPECT_EQ(ALL_DHCP_RELAY_AGENTS_AND_SERVERS, opt.getServerName());
  532. // When server='servers' in DHCPv6 mode we expect
  533. // FF05::1:3 as server name which means All DHCP
  534. // servers in local network.
  535. ASSERT_NO_THROW(process("perfdhcp -6 servers"));
  536. EXPECT_EQ(ALL_DHCP_SERVERS, opt.getServerName());
  537. // If server name is neither 'all' nor 'servers'
  538. // the given argument value is expected to be
  539. // returned.
  540. ASSERT_NO_THROW(process("perfdhcp -6 abc"));
  541. EXPECT_EQ("abc", opt.getServerName());
  542. }