From: Marcin Siodelski Date: Tue, 7 Aug 2012 12:45:06 +0000 (+0200) Subject: [1959] Enable broadcast addresses for perfdhcp's DHCPv4 mode. X-Git-Tag: trac2351_base~47^2~11^2~31 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9dc528fb9ce46478f415722abfb9068d264154ce;p=thirdparty%2Fkea.git [1959] Enable broadcast addresses for perfdhcp's DHCPv4 mode. --- diff --git a/tests/tools/perfdhcp/command_options.cc b/tests/tools/perfdhcp/command_options.cc index 09393bbc3d..55380d086b 100644 --- a/tests/tools/perfdhcp/command_options.cc +++ b/tests/tools/perfdhcp/command_options.cc @@ -21,8 +21,8 @@ #include #include -#include "exceptions/exceptions.h" - +#include +#include #include "command_options.h" using namespace std; @@ -219,6 +219,7 @@ CommandOptions::initialize(int argc, char** argv) { case 'l': localname_ = std::string(optarg); + initIsInterface(); break; case 'L': @@ -351,7 +352,21 @@ CommandOptions::initialize(int argc, char** argv) { } } - // TODO handle -l option with IfaceManager when it is created + // Handle the local '-l' address/interface + if (!localname_.empty()) { + if (server_name_.empty()) { + if (is_interface_ && (ipversion_ == 4)) { + broadcast_ = 1; + server_name_ = "255.255.255.255"; + } else if (is_interface_ && (ipversion_ == 6)) { + server_name_ = "FF02::1:2"; + } + } + } + if (server_name_.empty()) { + isc_throw(InvalidParameter, + "without an inteface server is required"); + } } void @@ -376,6 +391,17 @@ CommandOptions::initClientsNum() { } } +void +CommandOptions::initIsInterface() { + is_interface_ = false; + if (!localname_.empty()) { + dhcp::IfaceMgr& iface_mgr = dhcp::IfaceMgr::instance(); + if (iface_mgr.getIface(localname_) != NULL) { + is_interface_ = true; + } + } +} + void CommandOptions::decodeBase(const std::string& base) { std::string b(base); diff --git a/tests/tools/perfdhcp/command_options.h b/tests/tools/perfdhcp/command_options.h index 9196857d7c..459efa598b 100644 --- a/tests/tools/perfdhcp/command_options.h +++ b/tests/tools/perfdhcp/command_options.h @@ -301,6 +301,13 @@ private: /// \throw InvalidParameter if -R is wrong void initClientsNum(); + /// \brief Sets value indicating if interface name was given. + /// + /// Method checks if the command line argument given with + /// '-l' option is the interface name. The is_interface_ member + /// is set accordingly. + void initIsInterface(); + /// \brief Decodes base provided with -b /// /// Function decodes argument of -b switch, which diff --git a/tests/tools/perfdhcp/test_control.cc b/tests/tools/perfdhcp/test_control.cc index 6e793cd578..c050c9f0a6 100644 --- a/tests/tools/perfdhcp/test_control.cc +++ b/tests/tools/perfdhcp/test_control.cc @@ -208,27 +208,24 @@ TestControl::openSocket() const { family = AF_INET6; port = 547; } + // Local name is specified along with '-l' option. + // It may point to interface name or local address. if (!localname.empty()) { - bool is_interface = false;; - try { + // CommandOptions should be already aware wether local name + // is interface name or address because it uses IfaceMgr to + // scan interfaces and get's their names. + if (options.isInterface()) { sock = IfaceMgr::instance().openSocketFromIface(localname, port, family); - is_interface = true; - } catch (...) { - // This is not fatal error. It may be the case that - // parameter given from command line is not interface - // name but local IP address. - } - if (!is_interface) { + } else { IOAddress localaddr(localname); - // We don't catch exception here because parameter given - // must be either interface name or local address. If - // both attempts failed, we want exception to be emited. sock = IfaceMgr::instance().openSocketFromAddress(localaddr, port); } } else if (!servername.empty()) { + // If only server name is given we will need to try to resolve + // the local address to bind socket to based on remote address. IOAddress remoteaddr(servername); sock = IfaceMgr::instance().openSocketFromRemoteAddress(remoteaddr, port); @@ -237,6 +234,20 @@ TestControl::openSocket() const { isc_throw(BadValue, "unable to open socket to communicate with " "DHCP server"); } + + // IfaceMgr does not set broadcast option on the socket. We rely + // on CommandOptions object to find out if socket has to have + // broadcast enabled. + if ((options.getIpVersion() == 4) && options.isBroadcast()) { + int broadcast_enable = 1; + int ret = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, + &broadcast_enable, sizeof(broadcast_enable)); + if (ret < 0) { + isc_throw(InvalidOperation, + "unable to set broadcast option on the socket"); + } + } + return(sock); } @@ -362,7 +373,7 @@ TestControl::setDefaults4(const TestControlSocket &socket, void TestControl::updateSendDue() { // If default constructor was called, this should not happen but - // if somebody has cw/e August 3, 2012hanged default constructor it is better to + // if somebody has changed default constructor it is better to // keep this check. if (last_sent_.is_not_a_date_time()) { isc_throw(Unexpected, "time of last sent packet not initialized"); diff --git a/tests/tools/perfdhcp/test_control.h b/tests/tools/perfdhcp/test_control.h index 8d6c4f3c81..bb1f283712 100644 --- a/tests/tools/perfdhcp/test_control.h +++ b/tests/tools/perfdhcp/test_control.h @@ -209,7 +209,10 @@ private: /// from the command line). If socket can't be created for any /// reason, exception is thrown. /// - /// \throw isc::BadValue if socket can't be created. + /// \throw isc::BadValue if socket can't be created for given + /// interface, local address or remote address. + /// \throw isc::InvalidOperation if broadcast option can't be + /// set for the socket. /// \return socket descriptor. int openSocket() const; diff --git a/tests/tools/perfdhcp/tests/command_options_unittest.cc b/tests/tools/perfdhcp/tests/command_options_unittest.cc index 8e1053dc30..669d792bb5 100644 --- a/tests/tools/perfdhcp/tests/command_options_unittest.cc +++ b/tests/tools/perfdhcp/tests/command_options_unittest.cc @@ -17,9 +17,10 @@ #include #include -#include "../command_options.h" +#include +#include -#include "exceptions/exceptions.h" +#include "../command_options.h" using namespace std; using namespace isc; @@ -62,7 +63,7 @@ protected: /// Check if initialized values are correct void checkDefaults() { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp"); + process("perfdhcp 192.168.0.1"); EXPECT_EQ(4, opt.getIpVersion()); EXPECT_EQ(CommandOptions::DORA_SARR, opt.getExchangeMode()); EXPECT_EQ(0, opt.getRate()); @@ -104,7 +105,7 @@ protected: EXPECT_GT(0, opt.getRequestedIpOffset()); EXPECT_EQ("", opt.getDiags()); EXPECT_EQ("", opt.getWrapped()); - EXPECT_EQ("", opt.getServerName()); + EXPECT_EQ("192.168.0.1", opt.getServerName()); } /// \brief Split string to array of C-strings @@ -145,79 +146,90 @@ protected: }; TEST_F(CommandOptionsTest, Defaults) { - process("perfdhcp"); + process("perfdhcp all"); checkDefaults(); } TEST_F(CommandOptionsTest, UseFirst) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -1 -B -l ethx"); + process("perfdhcp -1 -B -l ethx all"); EXPECT_TRUE(opt.isUseFirst()); } TEST_F(CommandOptionsTest, IpVersion) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -6 -l ethx -c -i"); + process("perfdhcp -6 -l ethx -c -i all"); EXPECT_EQ(6, opt.getIpVersion()); EXPECT_EQ("ethx", opt.getLocalName()); EXPECT_TRUE(opt.isRapidCommit()); EXPECT_FALSE(opt.isBroadcast()); - process("perfdhcp -4 -B -l ethx"); + process("perfdhcp -4 -B -l ethx all"); EXPECT_EQ(4, opt.getIpVersion()); EXPECT_TRUE(opt.isBroadcast()); EXPECT_FALSE(opt.isRapidCommit()); // Negative test cases // -4 and -6 must not coexist - EXPECT_THROW(process("perfdhcp -4 -6 -l ethx"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -4 -6 -l ethx all"), isc::InvalidParameter); // -6 and -B must not coexist - EXPECT_THROW(process("perfdhcp -6 -B -l ethx"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -6 -B -l ethx all"), isc::InvalidParameter); // -c and -4 (default) must not coexist - EXPECT_THROW(process("perfdhcp -c -l ethx"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -c -l ethx all"), isc::InvalidParameter); } TEST_F(CommandOptionsTest, Rate) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -4 -r 10 -l ethx"); + process("perfdhcp -4 -r 10 -l ethx all"); EXPECT_EQ(10, opt.getRate()); // Negative test cases // Rate must not be 0 - EXPECT_THROW(process("perfdhcp -4 -r 0 -l ethx"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -4 -r 0 -l ethx all"), + isc::InvalidParameter); // -r must be specified to use -n, -p and -D - EXPECT_THROW(process("perfdhcp -6 -t 5 -l ethx"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -4 -n 150 -l ethx"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -6 -p 120 -l ethx"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -4 -D 1400 -l ethx"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -6 -t 5 -l ethx all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -4 -n 150 -l ethx all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -6 -p 120 -l ethx all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -4 -D 1400 -l ethx all"), + isc::InvalidParameter); } TEST_F(CommandOptionsTest, ReportDelay) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -r 100 -t 17 -l ethx"); + process("perfdhcp -r 100 -t 17 -l ethx all"); EXPECT_EQ(17, opt.getReportDelay()); // Negative test cases // -t must be positive integer - EXPECT_THROW(process("perfdhcp -r 10 -t -8 -l ethx"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -r 10 -t 0 -l ethx"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -r 10 -t s -l ethx"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -r 10 -t -8 -l ethx all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -r 10 -t 0 -l ethx all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -r 10 -t s -l ethx all"), + isc::InvalidParameter); } TEST_F(CommandOptionsTest, ClientsNum) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -R 200 -l ethx"); + process("perfdhcp -R 200 -l ethx all"); EXPECT_EQ(200, opt.getClientsNum()); - process("perfdhcp -R 0 -l ethx"); + process("perfdhcp -R 0 -l ethx all"); EXPECT_EQ(0, opt.getClientsNum()); // Negative test cases // Number of clients must be non-negative integer - EXPECT_THROW(process("perfdhcp -R -5 -l ethx"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -R gs -l ethx"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -R -5 -l ethx all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -R gs -l ethx all"), + isc::InvalidParameter); } TEST_F(CommandOptionsTest, Base) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -6 -b MAC=10::20::30::40::50::60 -l ethx -b duiD=1AB7F5670901FF"); + process("perfdhcp -6 -b MAC=10::20::30::40::50::60 " + "-l ethx -b duiD=1AB7F5670901FF all"); uint8_t mac[6] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60 }; uint8_t duid[7] = { 0x1A, 0xB7, 0xF5, 0x67, 0x09, 0x01, 0xFF }; @@ -226,72 +238,87 @@ TEST_F(CommandOptionsTest, Base) { ASSERT_EQ(6, v1.size()); EXPECT_TRUE(std::equal(v1.begin(), v1.end(), mac)); // "3x" is invalid value in MAC address - EXPECT_THROW(process("perfdhcp -b mac=10::2::3x::4::5::6 -l ethx"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -b mac=10::2::3x::4::5::6 -l ethx all"), + isc::InvalidParameter); // Test DUID std::vector v2 = opt.getDuidPrefix(); ASSERT_EQ(sizeof(duid) / sizeof(uint8_t), v2.size()); EXPECT_TRUE(std::equal(v2.begin(), v2.end(), duid)); // "t" is invalid digit in DUID - EXPECT_THROW(process("perfdhcp -6 -l ethx -b duiD=1AB7Ft670901FF"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -6 -l ethx -b duiD=1AB7Ft670901FF all"), + isc::InvalidParameter); // Some more negative test cases // Base is not specified - EXPECT_THROW(process("perfdhcp -b -l ethx"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -b -l ethx all"), + isc::InvalidParameter); // Typo: should be mac= instead of mc= - EXPECT_THROW(process("perfdhcp -l ethx -b mc=00:01:02:03::04:05"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -l ethx -b mc=00:01:02:03::04:05 all"), + isc::InvalidParameter); } TEST_F(CommandOptionsTest, DropTime) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -l ethx -d 12"); + process("perfdhcp -l ethx -d 12 all"); ASSERT_EQ(2, opt.getDropTime().size()); EXPECT_DOUBLE_EQ(12, opt.getDropTime()[0]); EXPECT_DOUBLE_EQ(1, opt.getDropTime()[1]); - process("perfdhcp -l ethx -d 2 -d 4.7"); + process("perfdhcp -l ethx -d 2 -d 4.7 all"); ASSERT_EQ(2, opt.getDropTime().size()); EXPECT_DOUBLE_EQ(2, opt.getDropTime()[0]); EXPECT_DOUBLE_EQ(4.7, opt.getDropTime()[1]); // Negative test cases // Drop time must not be negative - EXPECT_THROW(process("perfdhcp -l ethx -d -2 -d 4.7"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -l ethx -d -9.1 -d 0"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -l ethx -d -2 -d 4.7 all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -l ethx -d -9.1 -d 0 all"), + isc::InvalidParameter); } TEST_F(CommandOptionsTest, TimeOffset) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -l ethx -T file1.x -T file2.x -E 4"); + process("perfdhcp -l ethx -T file1.x -T file2.x -E 4 all"); EXPECT_EQ(4, opt.getElapsedTimeOffset()); // Negative test cases // Argument -E must be used with -T - EXPECT_THROW(process("perfdhcp -l ethx -E 3 -i"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -l ethx -E 3 -i all"), + isc::InvalidParameter); // Value in -E not specified - EXPECT_THROW(process("perfdhcp -l ethx -T file.x -E -i"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -l ethx -T file.x -E -i all"), + isc::InvalidParameter); // Value for -E must not be negative - EXPECT_THROW(process("perfdhcp -l ethx -E -3 -T file.x"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -l ethx -E -3 -T file.x all"), + isc::InvalidParameter); } TEST_F(CommandOptionsTest, ExchangeMode) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -l ethx -i"); + process("perfdhcp -l ethx -i all"); EXPECT_EQ(CommandOptions::DO_SA, opt.getExchangeMode()); // Negative test cases // No template file specified - EXPECT_THROW(process("perfdhcp -i -l ethx -X 3"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -i -l ethx -X 3 all"), + isc::InvalidParameter); // Offsets can't be used in simple exchanges (-i) - EXPECT_THROW(process("perfdhcp -i -l ethx -O 2 -T file.x"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -i -l ethx -E 3 -T file.x"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -i -l ethx -S 1 -T file.x"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -i -l ethx -I 2 -T file.x"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -i -l ethx -O 2 -T file.x all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -i -l ethx -E 3 -T file.x all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -i -l ethx -S 1 -T file.x all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -i -l ethx -I 2 -T file.x all"), + isc::InvalidParameter); } TEST_F(CommandOptionsTest, Offsets) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -E5 -4 -I 2 -S3 -O 30 -X7 -l ethx -X3 -T file1.x -T file2.x"); + process("perfdhcp -E5 -4 -I 2 -S3 -O 30 -X7 -l ethx " + "-X3 -T file1.x -T file2.x all"); EXPECT_EQ(2, opt.getRequestedIpOffset()); EXPECT_EQ(5, opt.getElapsedTimeOffset()); EXPECT_EQ(3, opt.getServerIdOffset()); @@ -304,151 +331,234 @@ TEST_F(CommandOptionsTest, Offsets) { // Negative test cases // IP offset/IA_NA offset must be positive - EXPECT_THROW(process("perfdhcp -6 -I 0 -l ethx"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -6 -I -4 -l ethx"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -6 -I 0 -l ethx all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -6 -I -4 -l ethx all"), + isc::InvalidParameter); // TODO - other negative cases } TEST_F(CommandOptionsTest, LocalPort) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -l ethx -L 2000"); + process("perfdhcp -l ethx -L 2000 all"); EXPECT_EQ(2000, opt.getLocalPort()); // Negative test cases // Local port must be between 0..65535 - EXPECT_THROW(process("perfdhcp -l ethx -L -2"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -l ethx -L"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -l ethx -L 65540"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -l ethx -L -2 all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -l ethx -L all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -l ethx -L 65540 all"), + isc::InvalidParameter); } TEST_F(CommandOptionsTest, Preload) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -1 -P 3 -l ethx"); + process("perfdhcp -1 -P 3 -l ethx all"); EXPECT_EQ(3, opt.getPreload()); // Negative test cases // Number of preload packages must not be negative integer - EXPECT_THROW(process("perfdhcp -P -1 -l ethx"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -P -3 -l ethx"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -P -1 -l ethx all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -P -3 -l ethx all"), + isc::InvalidParameter); } TEST_F(CommandOptionsTest, Seed) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -6 -P 2 -s 23 -l ethx"); + process("perfdhcp -6 -P 2 -s 23 -l ethx all"); EXPECT_EQ(23, opt.getSeed()); EXPECT_TRUE(opt.isSeeded()); - process("perfdhcp -6 -P 2 -s 0 -l ethx"); + process("perfdhcp -6 -P 2 -s 0 -l ethx all"); EXPECT_EQ(0, opt.getSeed()); EXPECT_FALSE(opt.isSeeded()); // Negtaive test cases // Seed must be non-negative integer - EXPECT_THROW(process("perfdhcp -6 -P 2 -s -5 -l ethx"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -6 -P 2 -s -l ethx"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -6 -P 2 -s -5 -l ethx all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -6 -P 2 -s -l ethx all"), + isc::InvalidParameter); } TEST_F(CommandOptionsTest, TemplateFiles) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -T file1.x -l ethx"); + process("perfdhcp -T file1.x -l ethx all"); ASSERT_EQ(1, opt.getTemplateFiles().size()); EXPECT_EQ("file1.x", opt.getTemplateFiles()[0]); - process("perfdhcp -T file1.x -s 12 -w start -T file2.x -4 -l ethx"); + process("perfdhcp -T file1.x -s 12 -w start -T file2.x -4 -l ethx all"); ASSERT_EQ(2, opt.getTemplateFiles().size()); EXPECT_EQ("file1.x", opt.getTemplateFiles()[0]); EXPECT_EQ("file2.x", opt.getTemplateFiles()[1]); // Negative test cases // No template file specified - EXPECT_THROW(process("perfdhcp -s 12 -l ethx -T"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -s 12 -T -l ethx all"), + isc::InvalidParameter); // Too many template files specified - EXPECT_THROW(process("perfdhcp -s 12 -l ethx -T file.x -T file.x -T file.x"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -s 12 -l ethx -T file.x " + "-T file.x -T file.x all"), + isc::InvalidParameter); } TEST_F(CommandOptionsTest, Wrapped) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -B -w start -i -l ethx"); + process("perfdhcp -B -w start -i -l ethx all"); EXPECT_EQ("start", opt.getWrapped()); // Negative test cases // Missing command after -w, expected start/stop - EXPECT_THROW(process("perfdhcp -B -i -l ethx -w"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -B -i -l ethx -w all"), + isc::InvalidParameter); } TEST_F(CommandOptionsTest, Diagnostics) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -l ethx -i -x asTe"); + process("perfdhcp -l ethx -i -x asTe all"); EXPECT_EQ("asTe", opt.getDiags()); // Negative test cases // No diagnostics string specified - EXPECT_THROW(process("perfdhcp -l ethx -i -x"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -l ethx -i -x all"), + isc::InvalidParameter); } TEST_F(CommandOptionsTest, Aggressivity) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -a 10 -l 192.168.0.1"); + process("perfdhcp -a 10 -l 192.168.0.1 all"); EXPECT_EQ(10, opt.getAggressivity()); // Negative test cases // Aggressivity must be non negative integer - EXPECT_THROW(process("perfdhcp -l ethx -a 0"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -l ethx -a"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -a -2 -l ethx -a 3"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -l ethx -a 0 all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -l ethx -a all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -a -2 -l ethx -a 3 all"), + isc::InvalidParameter); } TEST_F(CommandOptionsTest, MaxDrop) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -D 25 -l ethx -r 10"); + process("perfdhcp -D 25 -l ethx -r 10 all"); EXPECT_EQ(25, opt.getMaxDrop()[0]); - process("perfdhcp -D 25 -l ethx -D 15 -r 10"); + process("perfdhcp -D 25 -l ethx -D 15 -r 10 all"); EXPECT_EQ(25, opt.getMaxDrop()[0]); EXPECT_EQ(15, opt.getMaxDrop()[1]); - process("perfdhcp -D 15% -l ethx -r 10"); + process("perfdhcp -D 15% -l ethx -r 10 all"); EXPECT_EQ(15, opt.getMaxDropPercentage()[0]); - process("perfdhcp -D 15% -D25% -l ethx -r 10"); + process("perfdhcp -D 15% -D25% -l ethx -r 10 all"); EXPECT_EQ(15, opt.getMaxDropPercentage()[0]); EXPECT_EQ(25, opt.getMaxDropPercentage()[1]); - process("perfdhcp -D 1% -D 99% -l ethx -r 10"); + process("perfdhcp -D 1% -D 99% -l ethx -r 10 all"); EXPECT_EQ(1, opt.getMaxDropPercentage()[0]); EXPECT_EQ(99, opt.getMaxDropPercentage()[1]); // Negative test cases // Too many -D options - EXPECT_THROW(process("perfdhcp -D 0% -D 1 -l ethx -r20 -D 3"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -D 0% -D 1 -l ethx -r20 -D 3 all"), + isc::InvalidParameter); // Too many -D options - EXPECT_THROW(process("perfdhcp -D 99% -D 13% -l ethx -r20 -D 10%"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -D 99% -D 13% -l ethx -r20 -D 10% all"), + isc::InvalidParameter); // Percentage is out of bounds - EXPECT_THROW(process("perfdhcp -D101% -D 13% -l ethx -r20"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -D0% -D 13% -l ethx -r20"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -D101% -D 13% -l ethx -r20 all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -D0% -D 13% -l ethx -r20 all"), + isc::InvalidParameter); } TEST_F(CommandOptionsTest, NumRequest) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -n 1000 -r 10 -l ethx"); + process("perfdhcp -n 1000 -r 10 -l ethx all"); EXPECT_EQ(1000, opt.getNumRequests()[0]); - process("perfdhcp -n 5 -r 10 -n 500 -l ethx"); + process("perfdhcp -n 5 -r 10 -n 500 -l ethx all"); EXPECT_EQ(5, opt.getNumRequests()[0]); EXPECT_EQ(500, opt.getNumRequests()[1]); // Negative test cases // Too many -n parameters, expected maximum 2 - EXPECT_THROW(process("perfdhcp -n 1 -n 2 -l ethx -n3 -r 20"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -n 1 -n 2 -l ethx -n3 -r 20 all"), + isc::InvalidParameter); // Num request must be positive integer - EXPECT_THROW(process("perfdhcp -n 1 -n -22 -l ethx -r 10"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -n 0 -l ethx -r 10"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -n 1 -n -22 -l ethx -r 10 all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -n 0 -l ethx -r 10 all"), + isc::InvalidParameter); } TEST_F(CommandOptionsTest, Period) { CommandOptions& opt = CommandOptions::instance(); - process("perfdhcp -p 120 -l ethx -r 100"); + process("perfdhcp -p 120 -l ethx -r 100 all"); EXPECT_EQ(120, opt.getPeriod()); // Negative test cases // Test period must be positive integer - EXPECT_THROW(process("perfdhcp -p 0 -l ethx -r 50"), isc::InvalidParameter); - EXPECT_THROW(process("perfdhcp -p -3 -l ethx -r 50"), isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -p 0 -l ethx -r 50 all"), + isc::InvalidParameter); + EXPECT_THROW(process("perfdhcp -p -3 -l ethx -r 50 all"), + isc::InvalidParameter); +} + +TEST_F(CommandOptionsTest, Interface) { + // In order to make this test portable we need to know + // at least one interface name on OS where test is run. + // Interface Manager has ability to detect interfaces. + dhcp::IfaceMgr& iface_mgr = dhcp::IfaceMgr::instance(); + const dhcp::IfaceMgr::IfaceCollection& ifaces = iface_mgr.getIfaces(); + std::string iface_name; + CommandOptions& opt = CommandOptions::instance(); + // The local loopback interface should be available. + // If no interface have been found for any reason we should + // not fail this test. + if (ifaces.size() > 0) { + // Get the name of the interface we detected. + iface_name = ifaces.begin()->getName(); + // Use the name in the command parser. + ASSERT_NO_THROW(process("perfdhcp -4 -l " + iface_name + " abc")); + // We expect that command parser will detect that argument + // specified along with '-l' is the interface name. + EXPECT_TRUE(opt.isInterface()); + + // If neither interface nor server is specified then + // exception is expected to be thrown. + EXPECT_THROW(process("perfdhcp -4"), isc::InvalidParameter); + } +} + +TEST_F(CommandOptionsTest, Server) { + CommandOptions& opt = CommandOptions::instance(); + // There is at least server parameter needed. If server is not + // specified the local interface must be specified. + // The server value equal to 'all' means use broadcast. + ASSERT_NO_THROW(process("perfdhcp all")); + // Once command line is parsed we expect that server name is + // set to broadcast address because 'all' was specified. + EXPECT_TRUE(opt.isBroadcast()); + // The broadcast address is 255.255.255.255. + EXPECT_EQ("255.255.255.255", opt.getServerName()); + + // When all is specified for DHCPv6 mode we expect + // FF02::1:2 as a server name which means All DHCP + // servers and relay agents in local network segment + ASSERT_NO_THROW(process("perfdhcp -6 all")); + EXPECT_EQ("FF02::1:2", opt.getServerName()); + + // When server='servers' in DHCPv6 mode we expect + // FF05::1:3 as server name which means All DHCP + // servers in local network. + ASSERT_NO_THROW(process("perfdhcp -6 servers")); + EXPECT_EQ("FF05::1:3", opt.getServerName()); + + // If server name is neither 'all' nor 'servers' + // the given argument value is expected to be + // returned. + ASSERT_NO_THROW(process("perfdhcp -6 abc")); + EXPECT_EQ("abc", opt.getServerName()); }