/// dummy server-id file location
const char* SRVID_FILE = "server-id-test.txt";
-// Sanity check. Verifies that both Dhcpv4Srv and its derived
-// class NakedDhcpv4Srv can be instantiated and destroyed.
-TEST_F(Dhcpv4SrvTest, basic) {
-
- // Check that the base class can be instantiated
- boost::scoped_ptr<Dhcpv4Srv> srv;
- ASSERT_NO_THROW(srv.reset(new Dhcpv4Srv(DHCP4_SERVER_PORT + 10000, "type=memfile",
- false, false)));
- srv.reset();
- // We have to close open sockets because further in this test we will
- // call the Dhcpv4Srv constructor again. This constructor will try to
- // set the appropriate packet filter class for IfaceMgr. This requires
- // that all sockets are closed.
- IfaceMgr::instance().closeSockets();
-
- // Check that the derived class can be instantiated
- boost::scoped_ptr<NakedDhcpv4Srv> naked_srv;
- ASSERT_NO_THROW(
- naked_srv.reset(new NakedDhcpv4Srv(DHCP4_SERVER_PORT + 10000)));
- EXPECT_TRUE(naked_srv->getServerID());
- // Close sockets again for the next test.
- IfaceMgr::instance().closeSockets();
-
- ASSERT_NO_THROW(naked_srv.reset(new NakedDhcpv4Srv(0)));
- EXPECT_TRUE(naked_srv->getServerID());
-}
-
-// This test verifies that exception is not thrown when an error occurs during
-// opening sockets. This test forces an error by adding a fictious interface
-// to the IfaceMgr. An attempt to open socket on this interface must always
-// fail. The DHCPv4 installs the error handler function to prevent exceptions
-// being thrown from the openSockets4 function.
-// @todo The server tests for socket should be extended but currently the
-// ability to unit test the sockets code is somewhat limited.
-TEST_F(Dhcpv4SrvTest, openActiveSockets) {
- ASSERT_NO_THROW(CfgMgr::instance().activateAllIfaces());
-
- Iface iface("bogusiface", 255);
- iface.flag_loopback_ = false;
- iface.flag_up_ = true;
- iface.flag_running_ = true;
- iface.inactive4_ = false;
- iface.addAddress(IOAddress("192.0.0.0"));
- IfaceMgr::instance().addInterface(iface);
- ASSERT_NO_THROW(Dhcpv4Srv::openActiveSockets(DHCP4_SERVER_PORT, false));
-}
-
// This test verifies that the destination address of the response
// message is set to giaddr, when giaddr is set to non-zero address
// in the received message.
EXPECT_EQ("255.255.255.255", resp->getRemoteAddr().toText());
}
+// Sanity check. Verifies that both Dhcpv4Srv and its derived
+// class NakedDhcpv4Srv can be instantiated and destroyed.
+TEST_F(Dhcpv4SrvTest, basic) {
+
+ // Check that the base class can be instantiated
+ boost::scoped_ptr<Dhcpv4Srv> srv;
+ ASSERT_NO_THROW(srv.reset(new Dhcpv4Srv(DHCP4_SERVER_PORT + 10000, "type=memfile",
+ false, false)));
+ srv.reset();
+ // We have to close open sockets because further in this test we will
+ // call the Dhcpv4Srv constructor again. This constructor will try to
+ // set the appropriate packet filter class for IfaceMgr. This requires
+ // that all sockets are closed.
+ IfaceMgr::instance().closeSockets();
+
+ // Check that the derived class can be instantiated
+ boost::scoped_ptr<NakedDhcpv4Srv> naked_srv;
+ ASSERT_NO_THROW(
+ naked_srv.reset(new NakedDhcpv4Srv(DHCP4_SERVER_PORT + 10000)));
+ EXPECT_TRUE(naked_srv->getServerID());
+ // Close sockets again for the next test.
+ IfaceMgr::instance().closeSockets();
+
+ ASSERT_NO_THROW(naked_srv.reset(new NakedDhcpv4Srv(0)));
+ EXPECT_TRUE(naked_srv->getServerID());
+}
+
+// This test verifies that exception is not thrown when an error occurs during
+// opening sockets. This test forces an error by adding a fictious interface
+// to the IfaceMgr. An attempt to open socket on this interface must always
+// fail. The DHCPv4 installs the error handler function to prevent exceptions
+// being thrown from the openSockets4 function.
+// @todo The server tests for socket should be extended but currently the
+// ability to unit test the sockets code is somewhat limited.
+TEST_F(Dhcpv4SrvTest, openActiveSockets) {
+ ASSERT_NO_THROW(CfgMgr::instance().activateAllIfaces());
+
+ Iface iface("bogusiface", 255);
+ iface.flag_loopback_ = false;
+ iface.flag_up_ = true;
+ iface.flag_running_ = true;
+ iface.inactive4_ = false;
+ iface.addAddress(IOAddress("192.0.0.0"));
+ IfaceMgr::instance().addInterface(iface);
+ ASSERT_NO_THROW(Dhcpv4Srv::openActiveSockets(DHCP4_SERVER_PORT, false));
+}
+
// Verifies that DISCOVER message can be processed correctly,
// that the OFFER message generated in response is valid and
// contains necessary options.
// are other tests that verify correctness of the allocation
// engine. See DiscoverBasic, DiscoverHint, DiscoverNoClientId
// and DiscoverInvalidHint.
-TEST_F(Dhcpv4SrvTest, processDiscover) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, processDiscover) {
testDiscoverRequest(DHCPDISCOVER);
}
// are other tests that verify correctness of the allocation
// engine. See DiscoverBasic, DiscoverHint, DiscoverNoClientId
// and DiscoverInvalidHint.
-TEST_F(Dhcpv4SrvTest, processRequest) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, processRequest) {
testDiscoverRequest(DHCPREQUEST);
}
-TEST_F(Dhcpv4SrvTest, processRelease) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, processRelease) {
NakedDhcpv4Srv srv;
Pkt4Ptr pkt(new Pkt4(DHCPRELEASE, 1234));
EXPECT_NO_THROW(srv.processRelease(pkt));
}
-TEST_F(Dhcpv4SrvTest, processDecline) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, processDecline) {
NakedDhcpv4Srv srv;
Pkt4Ptr pkt(new Pkt4(DHCPDECLINE, 1234));
EXPECT_NO_THROW(srv.processDecline(pkt));
}
-TEST_F(Dhcpv4SrvTest, processInform) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, processInform) {
NakedDhcpv4Srv srv;
Pkt4Ptr pkt(new Pkt4(DHCPINFORM, 1234));
// - copy of client-id
// - server-id
// - offered address
-TEST_F(Dhcpv4SrvTest, DiscoverBasic) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, DiscoverBasic) {
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
dis->setRemoteAddr(IOAddress("192.0.2.1"));
OptionPtr clientid = generateClientId();
dis->addOption(clientid);
+ dis->setIface("eth0");
// Pass it to the server and get an offer
Pkt4Ptr offer = srv->processDiscover(dis);
// - copy of client-id
// - server-id
// - offered address
-TEST_F(Dhcpv4SrvTest, DiscoverHint) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, DiscoverHint) {
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
IOAddress hint("192.0.2.107");
OptionPtr clientid = generateClientId();
dis->addOption(clientid);
dis->setYiaddr(hint);
+ dis->setIface("eth0");
// Pass it to the server and get an offer
Pkt4Ptr offer = srv->processDiscover(dis);
// - copy of client-id
// - server-id
// - offered address
-TEST_F(Dhcpv4SrvTest, DiscoverNoClientId) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, DiscoverNoClientId) {
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
IOAddress hint("192.0.2.107");
dis->setRemoteAddr(IOAddress("192.0.2.1"));
dis->setYiaddr(hint);
dis->setHWAddr(generateHWAddr(6));
+ dis->setIface("eth0");
// Pass it to the server and get an offer
Pkt4Ptr offer = srv->processDiscover(dis);
// - copy of client-id
// - server-id
// - offered address (!= hint)
-TEST_F(Dhcpv4SrvTest, DiscoverInvalidHint) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, DiscoverInvalidHint) {
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
IOAddress hint("10.1.2.3");
OptionPtr clientid = generateClientId();
dis->addOption(clientid);
dis->setYiaddr(hint);
+ dis->setIface("eth0");
// Pass it to the server and get an offer
Pkt4Ptr offer = srv->processDiscover(dis);
// and this is a correct behavior. It is REQUEST that will fail for the third
// client. OFFER is basically saying "if you send me a request, you will
// probably get an address like this" (there are no guarantees).
-TEST_F(Dhcpv4SrvTest, ManyDiscovers) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, ManyDiscovers) {
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
dis2->setRemoteAddr(IOAddress("192.0.2.2"));
dis3->setRemoteAddr(IOAddress("192.0.2.3"));
+ // Assign interfaces
+ dis1->setIface("eth0");
+ dis2->setIface("eth0");
+ dis3->setIface("eth0");
+
// Different client-id sizes
OptionPtr clientid1 = generateClientId(4); // length 4
OptionPtr clientid2 = generateClientId(5); // length 5
// - assigned address
//
// Test verifies that the lease is actually in the database.
-TEST_F(Dhcpv4SrvTest, RequestBasic) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, RequestBasic) {
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
OptionPtr clientid = generateClientId();
req->addOption(clientid);
req->setYiaddr(hint);
+ req->setIface("eth0");
// Pass it to the server and get an advertise
Pkt4Ptr ack = srv->processRequest(req);
// - copy of client-id
// - server-id
// - assigned address (different for each client)
-TEST_F(Dhcpv4SrvTest, ManyRequests) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, ManyRequests) {
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
req2->setRemoteAddr(relay);
req3->setRemoteAddr(relay);
+ // Assign interfaces
+ req1->setIface("eth0");
+ req2->setIface("eth0");
+ req3->setIface("eth0");
+
req1->setYiaddr(req_addr1);
req2->setYiaddr(req_addr2);
req3->setYiaddr(req_addr3);
// - returned REPLY message has server-id
// - returned REPLY message has IA that includes IAADDR
// - lease is actually renewed in LeaseMgr
-TEST_F(Dhcpv4SrvTest, RenewBasic) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, RenewBasic) {
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
req->setRemoteAddr(IOAddress(addr));
req->setYiaddr(addr);
req->setCiaddr(addr); // client's address
+ req->setIface("eth0");
req->addOption(clientid);
req->addOption(srv->getServerID());
// @todo: Implement tests for rejecting renewals
// This test verifies if the sanityCheck() really checks options presence.
-TEST_F(Dhcpv4SrvTest, sanityCheck) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, sanityCheck) {
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
// This test verifies that incoming (positive) RELEASE can be handled properly.
// As there is no REPLY in DHCPv4, the only thing to verify here is that
// the lease is indeed removed from the database.
-TEST_F(Dhcpv4SrvTest, ReleaseBasic) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, ReleaseBasic) {
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
rel->addOption(clientid);
rel->addOption(srv->getServerID());
rel->setHWAddr(hw);
+ rel->setIface("eth0");
// Pass it to the server and hope for a REPLY
// Note: this is no response to RELEASE in DHCPv4
// 1. there is no such lease at all
// 2. there is such a lease, but it is assigned to a different IAID
// 3. there is such a lease, but it belongs to a different client
-TEST_F(Dhcpv4SrvTest, ReleaseReject) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, ReleaseReject) {
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
rel->addOption(clientid);
rel->addOption(srv->getServerID());
rel->setHWAddr(bogus_hw);
+ rel->setIface("eth0");
// Case 1: No lease known to server
SCOPED_TRACE("CASE 1: Lease is not known to the server");
// This test verifies if the server-id disk operations (read, write) are
// working properly.
-TEST_F(Dhcpv4SrvTest, ServerID) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, ServerID) {
NakedDhcpv4Srv srv(0);
string srvid_text = "192.0.2.100";
}
// Checks if received relay agent info option is echoed back to the client
-TEST_F(Dhcpv4SrvTest, relayAgentInfoEcho) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, relayAgentInfoEcho) {
NakedDhcpv4Srv srv(0);
// Checks if vendor options are parsed correctly and requested vendor options
// are echoed back.
-TEST_F(Dhcpv4SrvTest, vendorOptionsDocsis) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, vendorOptionsDocsis) {
NakedDhcpv4Srv srv(0);
" \"rebind-timer\": 2000, "
" \"renew-timer\": 1000, "
" \"valid-lifetime\": 4000,"
- " \"interface\": \"" + valid_iface_ + "\" "
+ " \"interface\": \"eth0\" "
" } ],"
"\"valid-lifetime\": 4000 }";
// Checks whether the server uses default (0.0.0.0) siaddr value, unless
// explicitly specified
-TEST_F(Dhcpv4SrvTest, siaddrDefault) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, siaddrDefault) {
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
IOAddress hint("192.0.2.107");
OptionPtr clientid = generateClientId();
dis->addOption(clientid);
dis->setYiaddr(hint);
+ dis->setIface("eth0");
// Pass it to the server and get an offer
Pkt4Ptr offer = srv->processDiscover(dis);
}
// Checks whether the server uses specified siaddr value
-TEST_F(Dhcpv4SrvTest, siaddr) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, siaddr) {
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
subnet_->setSiaddr(IOAddress("192.0.2.123"));
Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
dis->setRemoteAddr(IOAddress("192.0.2.1"));
+ dis->setIface("eth0");
OptionPtr clientid = generateClientId();
dis->addOption(clientid);
// specific value and returned in server messages. There's also similar test for
// checking parser only configuration, see Dhcp4ParserTest.nextServerOverride in
// config_parser_unittest.cc.
-TEST_F(Dhcpv4SrvTest, nextServerOverride) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, nextServerOverride) {
NakedDhcpv4Srv srv(0);
Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
dis->setRemoteAddr(IOAddress("192.0.2.1"));
+ dis->setIface("eth0");
OptionPtr clientid = generateClientId();
dis->addOption(clientid);
// when there is no specific value defined in subnet and returned to the client
// properly. There's also similar test for checking parser only configuration,
// see Dhcp4ParserTest.nextServerGlobal in config_parser_unittest.cc.
-TEST_F(Dhcpv4SrvTest, nextServerGlobal) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, nextServerGlobal) {
NakedDhcpv4Srv srv(0);
Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
dis->setRemoteAddr(IOAddress("192.0.2.1"));
+ dis->setIface("eth0");
OptionPtr clientid = generateClientId();
dis->addOption(clientid);
/// can't modify non-static members (for obvious reasons), so many
/// fields are declared static. It is still better to keep them as
/// one class rather than unrelated collection of global objects.
-class HooksDhcpv4SrvTest : public Dhcpv4SrvTest {
+class HooksDhcpv4SrvTest : public Dhcpv4SrvFakeIfaceTest {
public:
// Checks if callouts installed on buffer4_receive is able to change
// the values and the parameters are indeed used by the server.
-TEST_F(HooksDhcpv4SrvTest, buffer4RreceiveValueChange) {
+TEST_F(HooksDhcpv4SrvTest, buffer4ReceiveValueChange) {
// Install callback that modifies MAC addr of incoming packet
EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
"\"subnet4\": [ { "
" \"pool\": [ \"192.0.2.0/25\" ],"
" \"subnet\": \"192.0.2.0/24\", "
- " \"interface\": \"" + valid_iface_ + "\" "
+ " \"interface\": \"eth0\" "
" }, {"
" \"pool\": [ \"192.0.3.0/25\" ],"
" \"subnet\": \"192.0.3.0/24\" "
// Prepare discover packet. Server should select first subnet for it
Pkt4Ptr sol = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
sol->setRemoteAddr(IOAddress("192.0.2.1"));
- sol->setIface(valid_iface_);
+ sol->setIface("eth0");
OptionPtr clientid = generateClientId();
sol->addOption(clientid);
"\"subnet4\": [ { "
" \"pool\": [ \"192.0.2.0/25\" ],"
" \"subnet\": \"192.0.2.0/24\", "
- " \"interface\": \"" + valid_iface_ + "\" "
+ " \"interface\": \"eth0\" "
" }, {"
" \"pool\": [ \"192.0.3.0/25\" ],"
" \"subnet\": \"192.0.3.0/24\" "
// Prepare discover packet. Server should select first subnet for it
Pkt4Ptr sol = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
sol->setRemoteAddr(IOAddress("192.0.2.1"));
- sol->setIface(valid_iface_);
+ sol->setIface("eth0");
OptionPtr clientid = generateClientId();
sol->addOption(clientid);
req->setRemoteAddr(IOAddress(addr));
req->setYiaddr(addr);
req->setCiaddr(addr); // client's address
+ req->setIface("eth0");
req->addOption(clientid);
req->addOption(srv_->getServerID());
req->setRemoteAddr(IOAddress(addr));
req->setYiaddr(addr);
req->setCiaddr(addr); // client's address
+ req->setIface("eth0");
req->addOption(clientid);
req->addOption(srv_->getServerID());
}
// Checks if server is able to handle a relayed traffic from DOCSIS3.0 modems
-TEST_F(Dhcpv4SrvTest, docsisVendorOptionsParse) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, docsisVendorOptionsParse) {
// Let's get a traffic capture from DOCSIS3.0 modem
Pkt4Ptr dis = captureRelayedDiscover();
}
// Checks if server is able to parse incoming docsis option and extract suboption 1 (docsis ORO)
-TEST_F(Dhcpv4SrvTest, docsisVendorORO) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, docsisVendorORO) {
// Let's get a traffic capture from DOCSIS3.0 modem
Pkt4Ptr dis = captureRelayedDiscover();
// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491)
// vendor options is parsed correctly and the requested options are actually assigned.
-TEST_F(Dhcpv4SrvTest, vendorOptionsORO) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, vendorOptionsORO) {
NakedDhcpv4Srv srv(0);
" \"rebind-timer\": 2000, "
" \"renew-timer\": 1000, "
" \"valid-lifetime\": 4000,"
- " \"interface\": \"" + valid_iface_ + "\" "
+ " \"interface\": \"eth0\" "
" } ],"
"\"valid-lifetime\": 4000 }";
dis->setGiaddr(IOAddress("192.0.2.1"));
OptionPtr clientid = generateClientId();
dis->addOption(clientid);
+ // Set interface. It is required by the server to generate server id.
+ dis->setIface("eth0");
// Pass it to the server and get an advertise
Pkt4Ptr offer = srv.processDiscover(dis);
// Test checks whether it is possible to use option definitions defined in
// src/lib/dhcp/docsis3_option_defs.h.
-TEST_F(Dhcpv4SrvTest, vendorOptionsDocsisDefinitions) {
+TEST_F(Dhcpv4SrvFakeIfaceTest, vendorOptionsDocsisDefinitions) {
ConstElementPtr x;
string config_prefix = "{ \"interfaces\": [ \"all\" ],"
"\"rebind-timer\": 2000, "
// it's ok if that fails. There should not be such a file anyway
unlink(SRVID_FILE);
-
- const IfaceMgr::IfaceCollection& ifaces = IfaceMgr::instance().getIfaces();
-
- // There must be some interface detected
- if (ifaces.empty()) {
- // We can't use ASSERT in constructor
- ADD_FAILURE() << "No interfaces detected.";
- }
-
- valid_iface_ = ifaces.begin()->getName();
}
void Dhcpv4SrvTest::addPrlOption(Pkt4Ptr& pkt) {
return (lease);
}
-/// @brief Checks if server response (OFFER, ACK, NAK) includes proper server-id
-/// @param rsp response packet to be validated
-/// @param expected_srvid expected value of server-id
void Dhcpv4SrvTest::checkServerId(const Pkt4Ptr& rsp, const OptionPtr& expected_srvid) {
// Check that server included its server-id
OptionPtr opt = rsp->getOption(DHO_DHCP_SERVER_IDENTIFIER);
return (::testing::AssertionSuccess());
}
+void Dhcpv4SrvTest::TearDown() {
+
+ CfgMgr::instance().deleteSubnets4();
+
+ // Let's clean up if there is such a file.
+ unlink(SRVID_FILE);
+
+ // Close all open sockets.
+ IfaceMgr::instance().closeSockets();
+
+ // Some unit tests override the default packet filtering class, used
+ // by the IfaceMgr. The dummy class, called PktFilterTest, reports the
+ // capability to directly respond to the clients without IP address
+ // assigned. This capability is not supported by the default packet
+ // filtering class: PktFilterInet. Therefore setting the dummy class
+ // allows to test scenarios, when server responds to the broadcast address
+ // on client's request, despite having support for direct response.
+ // The following call restores the use of original packet filtering class
+ // after the test.
+ try {
+ IfaceMgr::instance().setPacketFilter(PktFilterPtr(new PktFilterInet()));
+
+ } catch (const Exception& ex) {
+ FAIL() << "Failed to restore the default (PktFilterInet) packet filtering"
+ << " class after the test. Exception has been caught: "
+ << ex.what();
+ }
+
+}
+
+Dhcpv4SrvFakeIfaceTest::Dhcpv4SrvFakeIfaceTest()
+: Dhcpv4SrvTest() {
+ // Remove current interface configuration. Instead we want to add
+ // a couple of fake interfaces.
+ IfaceMgr& ifacemgr = IfaceMgr::instance();
+ ifacemgr.closeSockets();
+ ifacemgr.clearIfaces();
+
+ // Add fake interfaces.
+ ifacemgr.addInterface(createIface("lo", 0, "127.0.0.1"));
+ ifacemgr.addInterface(createIface("eth0", 1, "192.0.3.1"));
+ ifacemgr.addInterface(createIface("eth1", 2, "10.0.0.1"));
+
+ // In order to use fake interfaces we have to supply the custom
+ // packet filtering class, which can mimic opening sockets on
+ // fake interafaces.
+ ifacemgr.setPacketFilter(PktFilterPtr(new PktFilterTest()));
+ ifacemgr.openSockets4();
+}
+
+void
+Dhcpv4SrvFakeIfaceTest::TearDown() {
+ // The base class function restores the original packet filtering class.
+ Dhcpv4SrvTest::TearDown();
+ // The base class however, doesn't re-detect real interfaces.
+ try {
+ IfaceMgr::instance().clearIfaces();
+ IfaceMgr::instance().detectIfaces();
+
+ } catch (const Exception& ex) {
+ FAIL() << "Failed to restore interface configuration after using"
+ " fake interfaces";
+ }
+}
+
+Iface
+Dhcpv4SrvFakeIfaceTest::createIface(const std::string& name, const int ifindex,
+ const std::string& addr) {
+ Iface iface(name, ifindex);
+ iface.addAddress(IOAddress(addr));
+ if (name == "lo") {
+ iface.flag_loopback_ = true;
+ }
+ iface.flag_up_ = true;
+ iface.flag_running_ = true;
+ iface.inactive4_ = false;
+ return (iface);
+}
-void Dhcpv4SrvTest::testDiscoverRequest(const uint8_t msg_type) {
+void
+Dhcpv4SrvFakeIfaceTest::testDiscoverRequest(const uint8_t msg_type) {
// Create an instance of the tested class.
boost::scoped_ptr<NakedDhcpv4Srv> srv(new NakedDhcpv4Srv(0));
// which was parsed from its wire format.
Pkt4Ptr received;
ASSERT_TRUE(createPacketFromBuffer(req, received));
+ // Set interface. It is required for the server to generate server id.
+ received->setIface("eth0");
if (msg_type == DHCPDISCOVER) {
ASSERT_NO_THROW(
rsp = srv->processDiscover(received);
ASSERT_TRUE(createPacketFromBuffer(req, received));
ASSERT_TRUE(received->getOption(DHO_DHCP_PARAMETER_REQUEST_LIST));
+ // Set interface. It is required for the server to generate server id.
+ received->setIface("eth0");
+
if (msg_type == DHCPDISCOVER) {
ASSERT_NO_THROW(rsp = srv->processDiscover(received));
ASSERT_TRUE(createPacketFromBuffer(req, received));
ASSERT_TRUE(received->getOption(DHO_DHCP_PARAMETER_REQUEST_LIST));
+ // Set interface. It is required for the server to generate server id.
+ received->setIface("eth0");
+
if (msg_type == DHCPDISCOVER) {
ASSERT_NO_THROW(rsp = srv->processDiscover(received));
// Should return non-NULL packet.
EXPECT_TRUE(noBasicOptions(rsp));
}
-/// @brief This function cleans up after the test.
-void Dhcpv4SrvTest::TearDown() {
-
- CfgMgr::instance().deleteSubnets4();
-
- // Let's clean up if there is such a file.
- unlink(SRVID_FILE);
-
- // Close all open sockets.
- IfaceMgr::instance().closeSockets();
-
- // Some unit tests override the default packet filtering class, used
- // by the IfaceMgr. The dummy class, called PktFilterTest, reports the
- // capability to directly respond to the clients without IP address
- // assigned. This capability is not supported by the default packet
- // filtering class: PktFilterInet. Therefore setting the dummy class
- // allows to test scenarios, when server responds to the broadcast address
- // on client's request, despite having support for direct response.
- // The following call restores the use of original packet filtering class
- // after the test.
- try {
- IfaceMgr::instance().setPacketFilter(PktFilterPtr(new PktFilterInet()));
-
- } catch (const Exception& ex) {
- FAIL() << "Failed to restore the default (PktFilterInet) packet filtering"
- << " class after the test. Exception has been caught: "
- << ex.what();
- }
-}
-
-Dhcpv4SrvFakeIfaceTest::Dhcpv4SrvFakeIfaceTest() : Dhcpv4SrvTest() {
- IfaceMgr& ifacemgr = IfaceMgr::instance();
- ifacemgr.clearIfaces();
-
- ifacemgr.addInterface(createIface("lo", 0, "127.0.0.1"));
- ifacemgr.addInterface(createIface("eth0", 0, "192.0.3.1"));
- ifacemgr.addInterface(createIface("eth1", 0, "10.0.0.1"));
-}
-
-Dhcpv4SrvFakeIfaceTest::~Dhcpv4SrvFakeIfaceTest() {
- IfaceMgr& ifacemgr = IfaceMgr::instance();
- ifacemgr.setPacketFilter(PktFilterPtr(new PktFilterInet()));
- ifacemgr.clearIfaces();
- ifacemgr.detectIfaces();
-}
-
-Iface
-Dhcpv4SrvFakeIfaceTest::createIface(const std::string& name, const int ifindex,
- const std::string& addr) {
- Iface iface(name, ifindex);
- iface.addAddress(IOAddress(addr));
- if (name == "lo") {
- iface.flag_loopback_ = true;
- }
- iface.flag_up_ = true;
- iface.flag_running_ = true;
- iface.inactive4_ = false;
- return (iface);
-}
-
}; // end of isc::dhcp::test namespace
}; // end of isc::dhcp namespace
}; // end of isc namespace