// will need to reset all members many times to perform unit tests
ipversion_ = 0;
exchange_mode_ = DORA_SARR;
+ lease_type_ = ADDRESS_ONLY;
rate_ = 0;
report_delay_ = 0;
clients_num_ = 0;
// In this section we collect argument values from command line
// they will be tuned and validated elsewhere
while((opt = getopt(argc, argv, "hv46r:t:R:b:n:p:d:D:l:P:a:L:"
- "s:iBc1T:X:O:E:S:I:x:w:")) != -1) {
+ "s:iBc1T:X:O:E:S:I:x:w:e:")) != -1) {
stream << " -" << static_cast<char>(opt);
if (optarg) {
stream << " " << optarg;
}
break;
+ case 'e':
+ initLeaseType();
+ break;
+
case 'E':
elp_offset_ = nonNegativeInteger("value of time-offset: -E<value>"
" must not be a negative integer");
"-6 (IPv6) must be set to use -c");
check((getExchangeMode() == DO_SA) && (getNumRequests().size() > 1),
"second -n<num-request> is not compatible with -i");
+ check((getIpVersion() == 4) && (getLeaseType() != ADDRESS_ONLY),
+ "-6 option must be used if lease type other than '-e address-only'"
+ " is specified");
+ check(!getTemplateFiles().empty() && (getLeaseType() != ADDRESS_ONLY),
+ "template files may be only used with '-e address-only'");
check((getExchangeMode() == DO_SA) && (getDropTime()[1] != 1.),
"second -d<drop-time> is not compatible with -i");
check((getExchangeMode() == DO_SA) &&
return sarg;
}
+void
+CommandOptions::initLeaseType() {
+ std::string lease_type_arg = optarg;
+ if (lease_type_arg == "address-only") {
+ lease_type_ = ADDRESS_ONLY;
+
+ } else if (lease_type_arg == "prefix-only") {
+ lease_type_ = PREFIX_ONLY;
+
+ } else {
+ isc_throw(isc::InvalidParameter, "value of lease-type: -e<lease-type>,"
+ " must be one of the following: 'address-only' or"
+ " 'prefix-only'");
+ }
+}
+
void
CommandOptions::printCommandLine() const {
std::cout << "IPv" << static_cast<int>(ipversion_) << std::endl;
void
CommandOptions::usage() const {
std::cout <<
- "perfdhcp [-hv] [-4|-6] [-r<rate>] [-t<report>] [-R<range>] [-b<base>]\n"
- " [-n<num-request>] [-p<test-period>] [-d<drop-time>] [-D<max-drop>]\n"
- " [-l<local-addr|interface>] [-P<preload>] [-a<aggressivity>]\n"
- " [-L<local-port>] [-s<seed>] [-i] [-B] [-c] [-1]\n"
- " [-T<template-file>] [-X<xid-offset>] [-O<random-offset]\n"
- " [-E<time-offset>] [-S<srvid-offset>] [-I<ip-offset>]\n"
- " [-x<diagnostic-selector>] [-w<wrapped>] [server]\n"
+ "perfdhcp [-hv] [-4|-6] [-e<lease-type>] [-r<rate>] [-t<report>]\n"
+ " [-R<range>] [-b<base>] [-n<num-request>] [-p<test-period>]\n"
+ " [-d<drop-time>] [-D<max-drop>] [-l<local-addr|interface>]\n"
+ " [-P<preload>] [-a<aggressivity>] [-L<local-port>] [-s<seed>]\n"
+ " [-i] [-B] [-c] [-1] [-T<template-file>] [-X<xid-offset>]\n"
+ " [-O<random-offset] [-E<time-offset>] [-S<srvid-offset>]\n"
+ " [-I<ip-offset>] [-x<diagnostic-selector>] [-w<wrapped>] [server]\n"
"\n"
"The [server] argument is the name/address of the DHCP server to\n"
"contact. For DHCPv4 operation, exchanges are initiated by\n"
"-d<drop-time>: Specify the time after which a requeqst is treated as\n"
" having been lost. The value is given in seconds and may contain a\n"
" fractional component. The default is 1 second.\n"
+ "-e<lease-type>: A type of lease being requested from the server. It\n"
+ " may be one of the following: address-only or prefix-only. The\n"
+ " former indicates that the regular IP (v4 or v6) will be requested,\n"
+ " the latter indicates that the IPv6 prefixes will be requested. The\n"
+ " '-e prefix-only' must not be used with -4.\n"
"-E<time-offset>: Offset of the (DHCPv4) secs field / (DHCPv6)\n"
" elapsed-time option in the (second/request) template.\n"
" The value 0 disables it.\n"
DORA_SARR
};
+ /// @brief A type of lease being requested by the client.
+ ///
+ /// Currently it indicates whether perfdhcp is simulating the requests
+ /// for IPv6 addresses or prefixes (Prefix Delegation). Note that
+ /// prefixes can be only requested when IPv6 mode is selected.
+ enum LeaseType {
+ ADDRESS_ONLY,
+ PREFIX_ONLY
+ };
+
/// CommandOptions is a singleton class. This method returns reference
/// to its sole instance.
///
/// \return packet exchange mode.
ExchangeMode getExchangeMode() const { return exchange_mode_; }
+ /// \ brief Returns the type of lease being requested.
+ ///
+ /// \return type of lease being requested by perfdhcp.
+ LeaseType getLeaseType() const { return (lease_type_); }
+
/// \brief Returns echange rate.
///
/// \return exchange rate per second.
/// \throw InvalidParameter if string is empty.
std::string nonEmptyString(const std::string& errmsg) const;
+ /// \brief Decodes the lease type requested by perfdhcp from optarg.
+ ///
+ /// \throw InvalidParameter if lease type value specified is invalid.
+ void initLeaseType();
+
/// \brief Set number of clients.
///
/// Interprets the getopt() "opt" global variable as the number of clients
uint8_t ipversion_;
/// Packet exchange mode (e.g. DORA/SARR)
ExchangeMode exchange_mode_;
+ /// Lease Type to be obtained: address only, IPv6 prefix only.
+ LeaseType lease_type_;
/// Rate in exchange per second
int rate_;
/// Delay between generation of two consecutive
-// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
EXPECT_NO_THROW(process("perfdhcp 192.168.0.1"));
EXPECT_EQ(4, opt.getIpVersion());
EXPECT_EQ(CommandOptions::DORA_SARR, opt.getExchangeMode());
+ EXPECT_EQ(CommandOptions::ADDRESS_ONLY, opt.getLeaseType());
EXPECT_EQ(0, opt.getRate());
EXPECT_EQ(0, opt.getReportDelay());
EXPECT_EQ(0, opt.getClientsNum());
EXPECT_THROW(process("perfdhcp -c -l ethx all"), isc::InvalidParameter);
}
+TEST_F(CommandOptionsTest, LeaseType) {
+ CommandOptions& opt = CommandOptions::instance();
+ // Check that the -e address-only works for IPv6.
+ ASSERT_NO_THROW(process("perfdhcp -6 -l etx -e address-only all"));
+ EXPECT_EQ(6, opt.getIpVersion());
+ EXPECT_EQ("etx", opt.getLocalName());
+ EXPECT_EQ(CommandOptions::ADDRESS_ONLY, opt.getLeaseType());
+ // Check that the -e address-only works for IPv4.
+ ASSERT_NO_THROW(process("perfdhcp -4 -l etx -e address-only all"));
+ EXPECT_EQ(4, opt.getIpVersion());
+ EXPECT_EQ("etx", opt.getLocalName());
+ EXPECT_EQ(CommandOptions::ADDRESS_ONLY, opt.getLeaseType());
+ // Check that the -e prefix-only works.
+ ASSERT_NO_THROW(process("perfdhcp -6 -l etx -e prefix-only all"));
+ EXPECT_EQ(6, opt.getIpVersion());
+ EXPECT_EQ("etx", opt.getLocalName());
+ EXPECT_EQ(CommandOptions::PREFIX_ONLY, opt.getLeaseType());
+ // Check that -e prefix-only must not coexist with -4 option.
+ EXPECT_THROW(process("perfdhcp -4 -l ethx -e prefix-only all"),
+ InvalidParameter);
+ // Check that -e prefix-only must not coexist with -T options.
+ EXPECT_THROW(process("perfdhcp -6 -l ethx -e prefix-only -T file1.hex"
+ " -T file2.hex -E 4 all"), InvalidParameter);
+
+}
+
TEST_F(CommandOptionsTest, Rate) {
CommandOptions& opt = CommandOptions::instance();
EXPECT_NO_THROW(process("perfdhcp -4 -r 10 -l ethx all"));