RFCViolation);
}
-// Checks if received relay agent info option is echoed back to the client
-TEST_F(Dhcpv4SrvTest, relayAgentInfoEcho) {
+} // end of anonymous namespace
+
+namespace isc {
+namespace dhcp {
+namespace test {
+
+void
+Dhcpv4SrvTest::relayAgentInfoEcho() {
IfaceMgrTestConfig test_config(true);
NakedDhcpv4Srv srv(0);
EXPECT_TRUE(rai_response->equals(rai_query));
}
-// Checks if received bad relay agent info option is not echoed back
-// to the client
-TEST_F(Dhcpv4SrvTest, badRelayAgentInfoEcho) {
+void
+Dhcpv4SrvTest::badRelayAgentInfoEcho() {
IfaceMgrTestConfig test_config(true);
NakedDhcpv4Srv srv(0);
ASSERT_FALSE(rai_response);
}
-// Checks if client port can be overridden in packets being sent.
-TEST_F(Dhcpv4SrvTest, portsClientPort) {
+void
+Dhcpv4SrvTest::portsClientPort() {
IfaceMgrTestConfig test_config(true);
NakedDhcpv4Srv srv(0);
EXPECT_EQ(srv.client_port_, offer->getRemotePort());
}
-// Checks if server port can be overridden in packets being sent.
-TEST_F(Dhcpv4SrvTest, portsServerPort) {
+void
+Dhcpv4SrvTest::portsServerPort() {
IfaceMgrTestConfig test_config(true);
// Do not use DHCP4_SERVER_PORT here as 0 means don't open sockets.
EXPECT_EQ(srv.server_port_, offer->getLocalPort());
}
+} // end of isc::dhcp::test namespace
+} // end of isc::dhcp namespace
+} // end of isc namespace
+
+namespace {
+
+TEST_F(Dhcpv4SrvTest, relayAgentInfoEcho) {
+ Dhcpv4SrvMTTestGuard guard(*this, false);
+ relayAgentInfoEcho();
+}
+
+TEST_F(Dhcpv4SrvTest, relayAgentInfoEchoMultiThreading) {
+ Dhcpv4SrvMTTestGuard guard(*this, true);
+ relayAgentInfoEcho();
+}
+
+TEST_F(Dhcpv4SrvTest, badRelayAgentInfoEcho) {
+ Dhcpv4SrvMTTestGuard guard(*this, false);
+ badRelayAgentInfoEcho();
+}
+
+TEST_F(Dhcpv4SrvTest, badRelayAgentInfoEchoMultiThreading) {
+ Dhcpv4SrvMTTestGuard guard(*this, true);
+ badRelayAgentInfoEcho();
+}
+
+TEST_F(Dhcpv4SrvTest, portsClientPort) {
+ Dhcpv4SrvMTTestGuard guard(*this, false);
+ portsClientPort();
+}
+
+TEST_F(Dhcpv4SrvTest, portsClientPortMultiThreading) {
+ Dhcpv4SrvMTTestGuard guard(*this, true);
+ portsClientPort();
+}
+
+TEST_F(Dhcpv4SrvTest, portsServerPort) {
+ Dhcpv4SrvMTTestGuard guard(*this, false);
+ portsServerPort();
+}
+
+TEST_F(Dhcpv4SrvTest, portsServerPortMultiTHreading) {
+ Dhcpv4SrvMTTestGuard guard(*this, true);
+ portsServerPort();
+}
+
/// @todo Implement tests for subnetSelect See tests in dhcp6_srv_unittest.cc:
/// selectSubnetAddr, selectSubnetIface, selectSubnetRelayLinkaddr,
/// selectSubnetRelayInterfaceId. Note that the concept of interface-id is not
<< " class after the test. Exception has been caught: "
<< ex.what();
}
-
- setMultiThreading(false);
}
void
}
}
+ /// @brief fake receive packet from server
+ ///
+ /// The client uses this packet as a reply from the server.
+ ///
+ /// @return The received packet.
Pkt4Ptr receiveOneMsg() {
if (isc::util::MultiThreadingMgr::instance().getMode()) {
std::lock_guard<std::mutex> lk(mutex_);
}
}
+ /// @brief fake receive packet from server
+ ///
+ /// The client uses this packet as a reply from the server.
+ /// This function should be called in a thread safe context.
+ ///
+ /// @return The received packet.
Pkt4Ptr receiveOneMsgInternal() {
// Return empty pointer if server hasn't responded.
if (fake_sent_.empty()) {
processRelease(release, context);
}
- /// @brief Runs processing DHCPDECLINE
+ /// @brief Runs processing DHCPDECLINE.
///
/// @param decline message received from client
void processDecline(Pkt4Ptr& decline) {
/// @brief Dummy server identifier option used by various tests.
OptionPtr server_id_;
- /// @brief packets we pretend to receive
+ /// @brief packets we pretend to receive.
///
/// Instead of setting up sockets on interfaces that change between OSes, it
/// is much easier to fake packet reception. This is a list of packets that
/// using fakeReceive() and NakedDhcpv4Srv::receivePacket() methods.
std::list<Pkt4Ptr> fake_received_;
- /// @brief packets we pretend to send
+ /// @brief packets we pretend to send.
std::list<Pkt4Ptr> fake_sent_;
using Dhcpv4Srv::adjustIfaceData;
ExpectedResult expected_result);
/// @brief Checks if received relay agent info option is echoed back to the
- /// client
+ /// client.
void relayAgentInfoEcho();
+ /// @brief Checks if received bad relay agent info option is not echoed back
+ /// to the client.
+ void badRelayAgentInfoEcho();
+
+ /// @brief Checks if client port can be overridden in packets being sent.
+ void portsClientPort();
+
+ /// @brief Checks if server port can be overridden in packets being sent.
+ void portsServerPort();
+
/// @brief This function cleans up after the test.
virtual void TearDown();
multi_threading_ = enabled;
}
- /// @brief A subnet used in most tests
+ /// @brief A subnet used in most tests.
Subnet4Ptr subnet_;
- /// @brief A pool used in most tests
+ /// @brief A pool used in most tests.
Pool4Ptr pool_;
- /// @brief A client-id used in most tests
+ /// @brief A client-id used in most tests.
ClientIdPtr client_id_;
/// @brief Return code
int rcode_;
- /// @brief Comment
+ /// @brief Comment received from configuration.
isc::data::ConstElementPtr comment_;
/// @brief Server object under test.
NakedDhcpv4Srv srv_;
- /// @brief The multi-threading flag
+ /// @brief The multi-threading flag.
bool multi_threading_;
};
#include <dhcpsrv/pool.h>
#include <dhcp6/tests/dhcp6_client.h>
#include <util/buffer.h>
+#include <util/multi_threading_mgr.h>
#include <boost/foreach.hpp>
#include <boost/pointer_cast.hpp>
#include <algorithm>
using namespace isc::asiolink;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
+using namespace isc::util;
namespace {
}
}
-
void
Dhcp6Client::generateIAFromLeases(const Pkt6Ptr& query,
const bool include_address) {
}
bool
-Dhcp6Client::
-hasLeaseWithZeroLifetimeForAddress(const asiolink::IOAddress& address) const {
+Dhcp6Client::hasLeaseWithZeroLifetimeForAddress(const asiolink::IOAddress& address) const {
std::vector<Lease6> leases = getLeasesByAddress(address);
BOOST_FOREACH(const Lease6& lease, leases) {
if ((lease.preferred_lft_ == 0) && (lease.valid_lft_ == 0)) {
Pkt6Ptr
Dhcp6Client::receiveOneMsg() {
- // Return empty pointer if server hasn't responded.
- if (srv_->fake_sent_.empty()) {
- return (Pkt6Ptr());
- }
- Pkt6Ptr msg = srv_->fake_sent_.front();
- srv_->fake_sent_.pop_front();
- return (msg);
+ return (srv_->receiveOneMsg());
}
void
} catch (...) {
// Suppress errors, as the DHCPv6 server does.
}
+
+ // Make sure the server processed all packets in MT.
+ isc::util::MultiThreadingMgr::instance().getThreadPool().wait();
}
void
#include <config.h>
#include <gtest/gtest.h>
+#include <cc/command_interpreter.h>
#include <dhcp/option6_status_code.h>
#include <dhcp6/tests/dhcp6_test_utils.h>
#include <dhcp6/json_config_parser.h>
#include <dhcp/tests/pkt_captures.h>
#include <log/logger_support.h>
+#include <dhcpsrv/cfg_multi_threading.h>
#include <util/pointer_util.h>
-#include <cc/command_interpreter.h>
#include <stats/stats_mgr.h>
#include <cstdio>
#include <sstream>
using namespace isc::dhcp;
using namespace isc::asiolink;
using namespace isc::stats;
+using namespace isc::util;
namespace isc {
namespace dhcp {
}
Dhcpv6SrvTest::Dhcpv6SrvTest()
- : NakedDhcpv6SrvTest(), srv_(0) {
- subnet_ = isc::dhcp::Subnet6Ptr
- (new isc::dhcp::Subnet6(isc::asiolink::IOAddress("2001:db8:1::"),
- 48, 1000, 2000, 3000, 4000));
+ : NakedDhcpv6SrvTest(), srv_(0), multi_threading_(false) {
+ subnet_ = isc::dhcp::Subnet6Ptr(new isc::dhcp::Subnet6(isc::asiolink::IOAddress("2001:db8:1::"),
+ 48, 1000, 2000, 3000, 4000));
subnet_->setIface("eth0");
- pool_ = isc::dhcp::Pool6Ptr
- (new isc::dhcp::Pool6(isc::dhcp::Lease::TYPE_NA,
- isc::asiolink::IOAddress("2001:db8:1:1::"),
- 64));
+ pool_ = isc::dhcp::Pool6Ptr(new isc::dhcp::Pool6(isc::dhcp::Lease::TYPE_NA,
+ isc::asiolink::IOAddress("2001:db8:1:1::"),
+ 64));
subnet_->addPool(pool_);
isc::dhcp::CfgMgr::instance().clear();
isc::dhcp::CfgMgr::instance().commit();
// configure PD pool
- pd_pool_ = isc::dhcp::Pool6Ptr
- (new isc::dhcp::Pool6(isc::dhcp::Lease::TYPE_PD,
- isc::asiolink::IOAddress("2001:db8:1:2::"),
- 64, 80));
+ pd_pool_ = isc::dhcp::Pool6Ptr(new isc::dhcp::Pool6(isc::dhcp::Lease::TYPE_PD,
+ isc::asiolink::IOAddress("2001:db8:1:2::"),
+ 64, 80));
subnet_->addPool(pd_pool_);
}
void
Dhcpv6SrvTest::configure(const std::string& config, NakedDhcpv6Srv& srv) {
+ MultiThreadingCriticalSection cs;
ConstElementPtr json;
try {
json = parseJSON(config);
// Disable the re-detect flag
disableIfacesReDetect(json);
+ // Set up multi-threading
+ configureMultiThreading(multi_threading_, json);
+
// Configure the server and make sure the config is accepted
EXPECT_NO_THROW(status = configureDhcp6Server(srv, json));
ASSERT_TRUE(status);
ASSERT_EQ(0, rcode) << "configuration failed, test is broken: "
<< comment->str();
+ try {
+ CfgMultiThreading::apply(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading());
+ } catch (const std::exception& ex) {
+ ADD_FAILURE() << "Error applying multi threading settings: "
+ << ex.what();
+ }
+
CfgMgr::instance().commit();
}
NakedDhcpv6SrvTest::NakedDhcpv6SrvTest()
-: rcode_(-1) {
+ : rcode_(-1) {
// it's ok if that fails. There should not be such a file anyway
static_cast<void>(remove(DUID_FILE));
#include <dhcp6/dhcp6_srv.h>
#include <dhcp6/parser_context.h>
#include <hooks/hooks_manager.h>
+#include <util/multi_threading_mgr.h>
#include <list>
return (pkt);
}
+ // Make sure the server processed all packets in MT.
+ isc::util::MultiThreadingMgr::instance().getThreadPool().wait();
+
// If not, just trigger shutdown and
// return immediately
shutdown();
/// it in fake_send_ list where test can later inspect
/// server's response.
virtual void sendPacket(const isc::dhcp::Pkt6Ptr& pkt) {
- fake_sent_.push_back(pkt);
+ if (isc::util::MultiThreadingMgr::instance().getMode()) {
+ std::lock_guard<std::mutex> lk(mutex_);
+ fake_sent_.push_back(pkt);
+ } else {
+ fake_sent_.push_back(pkt);
+ }
+ }
+
+ /// @brief fake receive packet from server
+ ///
+ /// The client uses this packet as a reply from the server.
+ ///
+ /// @return The received packet.
+ Pkt6Ptr receiveOneMsg() {
+ if (isc::util::MultiThreadingMgr::instance().getMode()) {
+ std::lock_guard<std::mutex> lk(mutex_);
+ return (receiveOneMsgInternal());
+ } else {
+ return (receiveOneMsgInternal());
+ }
+ }
+
+ /// @brief fake receive packet from server
+ ///
+ /// The client uses this packet as a reply from the server.
+ /// This function should be called in a thread safe context.
+ ///
+ /// @return The received packet.
+ Pkt6Ptr receiveOneMsgInternal() {
+ // Return empty pointer if server hasn't responded.
+ if (fake_sent_.empty()) {
+ return (Pkt6Ptr());
+ }
+ Pkt6Ptr msg = fake_sent_.front();
+ fake_sent_.pop_front();
+ return (msg);
}
/// @brief adds a packet to fake receive queue
using Dhcpv6Srv::server_port_;
using Dhcpv6Srv::client_port_;
- /// @brief packets we pretend to receive
+ /// @brief packets we pretend to receive.
///
/// Instead of setting up sockets on interfaces that change between
/// OSes, it is much easier to fake packet reception. This is a list
/// NakedDhcpv6Srv::receivePacket() methods.
std::list<isc::dhcp::Pkt6Ptr> fake_received_;
+ /// @brief packets we pretend to send.
std::list<isc::dhcp::Pkt6Ptr> fake_sent_;
+
+ /// @brief Mutex to protect the packet buffers.
+ std::mutex mutex_;
};
/// @brief Test fixture for any tests requiring blank/empty configuration
NO_IA // Client will not send IA_NA at all
};
+ class Dhcpv6SrvMTTestGuard {
+ public:
+ Dhcpv6SrvMTTestGuard(Dhcpv6SrvTest& test, bool mt_enabled) : test_(test) {
+ test_.setMultiThreading(mt_enabled);
+ }
+ ~Dhcpv6SrvMTTestGuard() {
+ test_.setMultiThreading(false);
+ }
+ Dhcpv6SrvTest& test_;
+ };
+
/// @brief Constructor that initializes a simple default configuration
///
/// Sets up a single subnet6 with one pool for addresses and second
// Checks if the lease sent to client is present in the database
// and is valid when checked against the configured subnet
- isc::dhcp::Lease6Ptr checkLease
- (const isc::dhcp::DuidPtr& duid, const isc::dhcp::OptionPtr& ia_na,
- boost::shared_ptr<isc::dhcp::Option6IAAddr> addr);
+ isc::dhcp::Lease6Ptr
+ checkLease(const isc::dhcp::DuidPtr& duid,
+ const isc::dhcp::OptionPtr& ia_na,
+ boost::shared_ptr<isc::dhcp::Option6IAAddr> addr);
/// @brief Check if the specified lease is present in the data base.
///
/// @param ia_pd IA_PD option that contains the IAPRefix option
/// @param prefix pointer to the IAPREFIX option
/// @return corresponding IPv6 lease (if found)
- isc::dhcp::Lease6Ptr checkPdLease
- (const isc::dhcp::DuidPtr& duid, const isc::dhcp::OptionPtr& ia_pd,
- boost::shared_ptr<isc::dhcp::Option6IAPrefix> prefix);
+ isc::dhcp::Lease6Ptr
+ checkPdLease(const isc::dhcp::DuidPtr& duid,
+ const isc::dhcp::OptionPtr& ia_pd,
+ boost::shared_ptr<isc::dhcp::Option6IAPrefix> prefix);
/// @brief Creates a message with specified IA
///
/// @param stat_name this statistic is expected to be set to 1
void testReceiveStats(uint8_t pkt_type, const std::string& stat_name);
+ /// @brief Set multi-threading mode.
+ void setMultiThreading(bool enabled) {
+ multi_threading_ = enabled;
+ }
- /// A subnet used in most tests
+ /// A subnet used in most tests.
isc::dhcp::Subnet6Ptr subnet_;
- /// A normal, non-temporary pool used in most tests
+ /// A normal, non-temporary pool used in most tests.
isc::dhcp::Pool6Ptr pool_;
- /// A prefix pool used in most tests
+ /// A prefix pool used in most tests.
isc::dhcp::Pool6Ptr pd_pool_;
/// @brief Server object under test.
NakedDhcpv6Srv srv_;
+
+ /// @brief The multi-threading flag.
+ bool multi_threading_;
};
/// @brief Patch the server config to add interface-config/re-detect=false
}
}
+/// @brief Patch the server config to add multi-threading/enable-multi-threading
+/// @param json the server config
+inline void
+configureMultiThreading(bool enabled, isc::data::ConstElementPtr json) {
+ isc::data::ConstElementPtr multi_threading = json->get("multi-threading");
+ if (!multi_threading) {
+ isc::data::ElementPtr mutable_cfg =
+ boost::const_pointer_cast<isc::data::Element>(json);
+ multi_threading = isc::data::Element::createMap();
+ mutable_cfg->set("multi-threading", multi_threading);
+ }
+
+ isc::data::ElementPtr mutable_cfg =
+ boost::const_pointer_cast<isc::data::Element>(multi_threading);
+ if (enabled) {
+ mutable_cfg->set("enable-multi-threading", isc::data::Element::create(true));
+ mutable_cfg->set("thread-pool-size", isc::data::Element::create(4));
+ mutable_cfg->set("packet-queue-size", isc::data::Element::create(4));
+ } else {
+ mutable_cfg->set("enable-multi-threading", isc::data::Element::create(false));
+ }
+}
+
/// @brief Runs parser in JSON mode, useful for parser testing
///
/// @param in string to be parsed
/// @return ElementPtr structure representing parsed JSON
inline isc::data::ElementPtr
-parseJSON(const std::string& in)
-{
+parseJSON(const std::string& in) {
isc::dhcp::Parser6Context ctx;
return (ctx.parseString(in, isc::dhcp::Parser6Context::PARSER_JSON));
}
/// @param verbose display the exception message when it fails
/// @return ElementPtr structure representing parsed JSON
inline isc::data::ElementPtr
-parseDHCP6(const std::string& in, bool verbose = false)
-{
+parseDHCP6(const std::string& in, bool verbose = false) {
try {
isc::dhcp::Parser6Context ctx;
isc::data::ElementPtr json;
/// @param verbose display the exception message when it fails
/// @return ElementPtr structure representing parsed JSON
inline isc::data::ElementPtr
-parseOPTION_DEFS(const std::string& in, bool verbose = false)
-{
+parseOPTION_DEFS(const std::string& in, bool verbose = false) {
try {
isc::dhcp::Parser6Context ctx;
return (ctx.parseString(in, isc::dhcp::Parser6Context::PARSER_OPTION_DEFS));
}
}
-}; // end of isc::dhcp::test namespace
-}; // end of isc::dhcp namespace
-}; // end of isc namespace
+} // end of isc::dhcp::test namespace
+} // end of isc::dhcp namespace
+} // end of isc namespace
#endif // DHCP6_TEST_UTILS_H
isc::stats::StatsMgr::instance().removeAll();
}
+ /// @brief Check that server processes correctly a prefix hint sent by the
+ /// client. This test checks that the server doesn't allocate colliding
+ /// prefixes as a result of receiving hints from two clients which set the
+ /// non-significant bytes of the prefix in their hints. The server should
+ /// zero the non-significant bytes of the hint and allocate the prefix of
+ /// the correct (configured) length.
+ void directClientPrefixHint();
+
+ /// @brief This test verifies that the same options can be specified on the
+ /// global level, subnet level and pool level. The options associated with
+ /// pools are used when the lease is handed out from these pools.
+ void optionsInheritance();
+
+ /// @brief This test verifies that it is possible to specify an excluded
+ /// prefix (RFC 6603) and send it back to the client requesting prefix
+ /// delegation.
+ void directClientExcludedPrefix();
+
+ /// @brief Check that when the client includes the Rapid Commit option in
+ /// its Solicit, the server responds with Reply and commits the lease.
+ void rapidCommitEnable();
+
+ /// @brief Check that the server responds with Advertise if the client
+ /// hasn't included the Rapid Commit option in the Solicit.
+ void rapidCommitNoOption();
+
+ /// @brief Check that when the Rapid Commit support is disabled for the
+ /// subnet the server replies with an Advertise and ignores the Rapid Commit
+ /// option sent by the client.
+ void rapidCommitDisable();
+
+ /// @brief This test verifies that regular Solicit/Adv/Request/Reply
+ /// exchange will result in appropriately set statistics.
+ void sarrStats();
+
+ /// @brief This test verifies that pkt6-receive-drop is increased properly
+ /// when the client's packet is rejected due to mismatched server-id value.
+ void pkt6ReceiveDropStat1();
+
+ /// @brief This test verifies that pkt6-receive-drop is increased properly
+ /// when the client's packet is rejected due to being unicast communication.
+ void pkt6ReceiveDropStat2();
+
+ /// @brief This test verifies that pkt6-receive-drop is increased properly
+ /// when the client's packet is rejected due to having too many client-id
+ /// options (exactly one is expected).
+ void pkt6ReceiveDropStat3();
+
+ /// @brief This test verifies that in pool reservations are ignored when the
+ /// reservations-out-of-pool flag is set to true.
+ void reservationModeOutOfPool();
+
+ /// @brief This test verifies that the in-pool reservation can be assigned
+ /// to a client not owning this reservation when the
+ /// reservations-out-of-pool flag is set to true.
+ void reservationIgnoredInOutOfPoolMode();
+
/// @brief Interface Manager's fake configuration control.
IfaceMgrTestConfig iface_mgr_test_config_;
};
-/// Check that server processes correctly a prefix hint sent by the client.
-/// This test checks that the server doesn't allocate colliding prefixes
-/// as a result of receiving hints from two clients which set the
-/// non-significant bytes of the prefix in their hints. The server should zero
-/// the non-significant bytes of the hint and allocate the prefix of the
-/// correct (configured) length.
-TEST_F(SARRTest, directClientPrefixHint) {
+void
+SARRTest::directClientPrefixHint() {
Dhcp6Client client;
// Configure client to request IA_PD.
client.requestPrefix();
ASSERT_TRUE(lease_server);
}
-// This test verifies that the same options can be specified on the global
-// level, subnet level and pool level. The options associated with pools
-// are used when the lease is handed out from these pools.
-TEST_F(SARRTest, optionsInheritance) {
+TEST_F(SARRTest, directClientPrefixHint) {
+ Dhcpv6SrvMTTestGuard guard(*this, false);
+ directClientPrefixHint();
+}
+
+TEST_F(SARRTest, directClientPrefixHintMultiThreading) {
+ Dhcpv6SrvMTTestGuard guard(*this, true);
+ directClientPrefixHint();
+}
+
+void
+SARRTest::optionsInheritance() {
Dhcp6Client client;
// Request a single address and single prefix.
ASSERT_NO_THROW(client.requestPrefix(0xabac, 64, IOAddress("2001:db8:4::")));
ASSERT_TRUE(client.hasOptionWithAddress(D6O_SNTP_SERVERS, "3000:2::2"));
}
-/// This test verifies that it is possible to specify an excluded prefix
-/// (RFC 6603) and send it back to the client requesting prefix delegation.
-TEST_F(SARRTest, directClientExcludedPrefix) {
+TEST_F(SARRTest, optionsInheritance) {
+ Dhcpv6SrvMTTestGuard guard(*this, false);
+ optionsInheritance();
+}
+
+TEST_F(SARRTest, optionsInheritanceMultiThreading) {
+ Dhcpv6SrvMTTestGuard guard(*this, true);
+ optionsInheritance();
+}
+
+void
+SARRTest::directClientExcludedPrefix() {
Dhcp6Client client;
// Configure client to request IA_PD.
client.requestPrefix();
EXPECT_EQ(120, static_cast<unsigned>(pd_exclude->getExcludedPrefixLength()));
}
-// Check that when the client includes the Rapid Commit option in its
-// Solicit, the server responds with Reply and commits the lease.
-TEST_F(SARRTest, rapidCommitEnable) {
+TEST_F(SARRTest, directClientExcludedPrefix) {
+ Dhcpv6SrvMTTestGuard guard(*this, false);
+ directClientExcludedPrefix();
+}
+
+TEST_F(SARRTest, directClientExcludedPrefixMultiThreading) {
+ Dhcpv6SrvMTTestGuard guard(*this, true);
+ directClientExcludedPrefix();
+}
+
+void
+SARRTest::rapidCommitEnable() {
Dhcp6Client client;
// Configure client to request IA_NA
client.requestAddress();
EXPECT_EQ(1, CfgMgr::instance().getD2ClientMgr().getQueueSize());
}
-// Check that the server responds with Advertise if the client hasn't
-// included the Rapid Commit option in the Solicit.
-TEST_F(SARRTest, rapidCommitNoOption) {
+TEST_F(SARRTest, rapidCommitEnable) {
+ Dhcpv6SrvMTTestGuard guard(*this, false);
+ rapidCommitEnable();
+}
+
+TEST_F(SARRTest, rapidCommitEnableMultiThreading) {
+ Dhcpv6SrvMTTestGuard guard(*this, true);
+ rapidCommitEnable();
+}
+
+void
+SARRTest::rapidCommitNoOption() {
Dhcp6Client client;
// Configure client to request IA_NA
client.requestAddress();
EXPECT_EQ(0, CfgMgr::instance().getD2ClientMgr().getQueueSize());
}
-// Check that when the Rapid Commit support is disabled for the subnet
-// the server replies with an Advertise and ignores the Rapid Commit
-// option sent by the client.
-TEST_F(SARRTest, rapidCommitDisable) {
+TEST_F(SARRTest, rapidCommitNoOption) {
+ Dhcpv6SrvMTTestGuard guard(*this, false);
+ rapidCommitNoOption();
+}
+
+TEST_F(SARRTest, rapidCommitNoOptionMultiThreading) {
+ Dhcpv6SrvMTTestGuard guard(*this, true);
+ rapidCommitNoOption();
+}
+
+void
+SARRTest::rapidCommitDisable() {
Dhcp6Client client;
// The subnet assigned to eth1 has Rapid Commit disabled.
client.setInterface("eth1");
EXPECT_EQ(0, CfgMgr::instance().getD2ClientMgr().getQueueSize());
}
-// This test verifies that regular Solicit/Adv/Request/Reply exchange will
-// result in appropriately set statistics.
-TEST_F(SARRTest, sarrStats) {
+TEST_F(SARRTest, rapidCommitDisable) {
+ Dhcpv6SrvMTTestGuard guard(*this, false);
+ rapidCommitDisable();
+}
+
+TEST_F(SARRTest, rapidCommitDisableMultiThreading) {
+ Dhcpv6SrvMTTestGuard guard(*this, true);
+ rapidCommitDisable();
+}
+
+void
+SARRTest::sarrStats() {
// Let's use one of the existing configurations and tell the client to
// ask for an address.
EXPECT_EQ(2, pkt6_sent->getInteger().first);
}
-// This test verifies that pkt6-receive-drop is increased properly when the
-// client's packet is rejected due to mismatched server-id value.
-TEST_F(SARRTest, pkt6ReceiveDropStat1) {
+TEST_F(SARRTest, sarrStats) {
+ Dhcpv6SrvMTTestGuard guard(*this, false);
+ sarrStats();
+}
+
+TEST_F(SARRTest, sarrStatsMultiThreading) {
+ Dhcpv6SrvMTTestGuard guard(*this, true);
+ sarrStats();
+}
+
+void
+SARRTest::pkt6ReceiveDropStat1() {
// Dummy server-id (0xff repeated 10 times)
std::vector<uint8_t> data(10, 0xff);
EXPECT_EQ(1, pkt6_recv_drop->getInteger().first);
}
-// This test verifies that pkt6-receive-drop is increased properly when the
-// client's packet is rejected due to being unicast communication.
-TEST_F(SARRTest, pkt6ReceiveDropStat2) {
+TEST_F(SARRTest, pkt6ReceiveDropStat1) {
+ Dhcpv6SrvMTTestGuard guard(*this, false);
+ pkt6ReceiveDropStat1();
+}
+
+TEST_F(SARRTest, pkt6ReceiveDropStat1MultiThreading) {
+ Dhcpv6SrvMTTestGuard guard(*this, true);
+ pkt6ReceiveDropStat1();
+}
+
+void
+SARRTest::pkt6ReceiveDropStat2() {
// Let's use one of the existing configurations and tell the client to
// ask for an address.
EXPECT_EQ(1, pkt6_recv_drop->getInteger().first);
}
-// This test verifies that pkt6-receive-drop is increased properly when the
-// client's packet is rejected due to having too many client-id options
-// (exactly one is expected).
-TEST_F(SARRTest, pkt6ReceiveDropStat3) {
+TEST_F(SARRTest, pkt6ReceiveDropStat2) {
+ Dhcpv6SrvMTTestGuard guard(*this, false);
+ pkt6ReceiveDropStat2();
+}
+
+TEST_F(SARRTest, pkt6ReceiveDropStat2MultiThreading) {
+ Dhcpv6SrvMTTestGuard guard(*this, true);
+ pkt6ReceiveDropStat2();
+}
+
+void
+SARRTest::pkt6ReceiveDropStat3() {
// Let's use one of the existing configurations and tell the client to
// ask for an address.
EXPECT_EQ(1, pkt6_recv_drop->getInteger().first);
}
-// This test verifies that in pool reservations are ignored when the
-// reservations-out-of-pool flag is set to true.
-TEST_F(SARRTest, reservationModeOutOfPool) {
+TEST_F(SARRTest, pkt6ReceiveDropStat3) {
+ Dhcpv6SrvMTTestGuard guard(*this, false);
+ pkt6ReceiveDropStat3();
+}
+
+TEST_F(SARRTest, pkt6ReceiveDropStat3MultiThreading) {
+ Dhcpv6SrvMTTestGuard guard(*this, true);
+ pkt6ReceiveDropStat3();
+}
+
+void
+SARRTest::reservationModeOutOfPool() {
// Create the first client for which we have a reservation out of the
// dynamic pool.
Dhcp6Client client;
ASSERT_EQ("2001:db8:1::3", lease.addr_.toText());
}
-// This test verifies that the in-pool reservation can be assigned to a client
-// not owning this reservation when the reservations-out-of-pool flag is set to
-// true.
-TEST_F(SARRTest, reservationIgnoredInOutOfPoolMode) {
+TEST_F(SARRTest, reservationModeOutOfPool) {
+ Dhcpv6SrvMTTestGuard guard(*this, false);
+ reservationModeOutOfPool();
+}
+
+TEST_F(SARRTest, reservationModeOutOfPoolMultiThreading) {
+ Dhcpv6SrvMTTestGuard guard(*this, true);
+ reservationModeOutOfPool();
+}
+
+void
+SARRTest::reservationIgnoredInOutOfPoolMode() {
// Create the first client for which we have a reservation out of the
// dynamic pool.
Dhcp6Client client;
ASSERT_EQ("2001:db8:1::5", lease.addr_.toText());
}
+TEST_F(SARRTest, reservationIgnoredInOutOfPoolMode) {
+ Dhcpv6SrvMTTestGuard guard(*this, false);
+ reservationIgnoredInOutOfPoolMode();
+}
+
+TEST_F(SARRTest, reservationIgnoredInOutOfPoolModeMultiThreading) {
+ Dhcpv6SrvMTTestGuard guard(*this, true);
+ reservationIgnoredInOutOfPoolMode();
+}
+
} // end of anonymous namespace