Commit 0caae46e authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[trac878] Implemented gtest tests for recently added dhcpv6 classes:

Addr6, Pkt6, IfaceMgr, Dhcpv6Srv. Interface detection is still not
implemented, so some parts of the tests are stubbed.
parent 70d50df5
......@@ -19,9 +19,7 @@ TESTS =
if HAVE_GTEST
TESTS += run_unittests
run_unittests_SOURCES = $(top_srcdir)/src/lib/dns/tests/unittest_util.h
run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
run_unittests_SOURCES += ../auth_srv.h ../auth_srv.cc
run_unittests_SOURCES = ../auth_srv.h ../auth_srv.cc
run_unittests_SOURCES += ../auth_log.h ../auth_log.cc
run_unittests_SOURCES += ../query.h ../query.cc
run_unittests_SOURCES += ../change_user.h ../change_user.cc
......
......@@ -24,6 +24,10 @@ Dhcpv6Srv::Dhcpv6Srv() {
cout << "Initialization" << endl;
}
Dhcpv6Srv::~Dhcpv6Srv() {
cout << "DHCPv6 Srv shutdown." << endl;
}
bool Dhcpv6Srv::run() {
while (true) {
Pkt6 * pkt;
......
......@@ -45,10 +45,6 @@ namespace isc {
};
typedef std::list<Iface> IfaceLst;
private:
IfaceMgr(); // don't create IfaceMgr directly, use instance() method
~IfaceMgr();
public:
static IfaceMgr& instance();
static void instanceCreate();
......@@ -67,17 +63,21 @@ namespace isc {
bool send(Pkt6 &pkt);
Pkt6 * receive();
// don't use private, we need derived classes in tests
protected:
IfaceMgr(); // don't create IfaceMgr directly, use instance() method
~IfaceMgr();
void detectIfaces();
// XXX: having 2 maps (ifindex->iface and ifname->iface would)
// probably be better for performance reasons
IfaceLst ifaces_;
private:
static IfaceMgr * instance_;
int recvsock_; // XXX: should be fd_set eventually, but we 2 sockets
int sendsock_; // will do for until next release
int recvsock_; // XXX: should be fd_set eventually, but we have only
int sendsock_; // 2 sockets for now. Will do for until next release
char * control_buf_;
int control_buf_len_;
......
......@@ -18,20 +18,28 @@
namespace isc {
/**
* constructor.
*
* Note: Pkt6 will take ownership of any data passed
*
* @param data
* @param dataLen
*/
Pkt6::Pkt6(char * data, int dataLen) {
data_ = data;
dataLen_ = dataLen;
data_ = data;
dataLen_ = dataLen;
}
Pkt6::Pkt6(int dataLen) {
data_ = new char[dataLen];
dataLen_ = dataLen;
data_ = new char[dataLen];
dataLen_ = dataLen;
}
Pkt6::~Pkt6() {
if (data_) {
delete [] data_;
}
if (data_) {
delete [] data_;
}
}
......
......@@ -40,24 +40,27 @@ endif
TESTS =
if HAVE_GTEST
TESTS += run_unittests
run_unittests_SOURCES = ../addr6.h ../addr6.cc
run_unittests_SOURCES += ../pkt6.h ../pkt6.cc
run_unittests_SOURCES += ../iface_mgr.h ../iface_mgr.cc
run_unittests_SOURCES += ../dhcp6_srv.h ../dhcp6_srv.cc
run_unittests_SOURCES += addr6_unittest.cc
run_unittests_SOURCES += run_unittests.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
run_unittests_LDADD = $(GTEST_LDADD)
run_unittests_LDADD += $(SQLITE_LIBS)
run_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
run_unittests_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
TESTS += dhcp6_unittests
dhcp6_unittests_SOURCES = ../addr6.h ../addr6.cc
dhcp6_unittests_SOURCES += ../pkt6.h ../pkt6.cc
dhcp6_unittests_SOURCES += ../iface_mgr.h ../iface_mgr.cc
dhcp6_unittests_SOURCES += ../dhcp6_srv.h ../dhcp6_srv.cc
dhcp6_unittests_SOURCES += dhcp6_unittests.cc
dhcp6_unittests_SOURCES += addr6_unittest.cc
dhcp6_unittests_SOURCES += pkt6_unittest.cc
dhcp6_unittests_SOURCES += iface_mgr_unittest.cc
dhcp6_unittests_SOURCES += dhcp6_srv_unittest.cc
dhcp6_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
dhcp6_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
dhcp6_unittests_LDADD = $(GTEST_LDADD)
dhcp6_unittests_LDADD += $(SQLITE_LIBS)
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
endif
noinst_PROGRAMS = $(TESTS)
......@@ -25,13 +25,13 @@
using namespace std;
using namespace isc;
// empty class for now, but may be extended once Addr6 becomes bigger
class Addr6Test : public ::testing::Test {
public:
Addr6Test() {
}
};
TEST_F(Addr6Test, constructor) {
char buf[16];
......@@ -56,14 +56,14 @@ TEST_F(Addr6Test, mcast_linklocal) {
Addr6 global("2001:db8:1::dead:beef", true);
Addr6 local("fe80::face:b00c", true);
EXPECT_EQ(mcast.multicast(), true);
EXPECT_EQ(mcast.linkLocal(), false);
EXPECT_TRUE(mcast.multicast());
EXPECT_FALSE(mcast.linkLocal());
EXPECT_EQ(global.multicast(), false);
EXPECT_EQ(global.linkLocal(), false);
EXPECT_FALSE(global.multicast());
EXPECT_FALSE(global.linkLocal());
EXPECT_EQ(local.multicast(), false);
EXPECT_EQ(local.linkLocal(), true);
EXPECT_FALSE(local.multicast());
EXPECT_TRUE(local.linkLocal());
}
TEST_F(Addr6Test, equal) {
......@@ -72,8 +72,8 @@ TEST_F(Addr6Test, equal) {
Addr6 two("2001:db8:1::abcd");
Addr6 three("2001:db8:1::4321");
EXPECT_EQ( (one==two), true);
EXPECT_EQ( (one==three), false);
EXPECT_TRUE( one==two );
EXPECT_FALSE( one==three );
}
TEST_F(Addr6Test, stream) {
......@@ -84,5 +84,5 @@ TEST_F(Addr6Test, stream) {
stringstream tmp;
tmp << addr;
EXPECT_EQ( tmp.str(), plain);
EXPECT_STREQ( tmp.str().c_str(), plain.c_str() );
}
// Copyright (C) 2011 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
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <config.h>
#include <iostream>
#include <sstream>
#include <arpa/inet.h>
#include <gtest/gtest.h>
#include "dhcp6/dhcp6_srv.h"
using namespace std;
using namespace isc;
class Dhcpv6SrvTest : public ::testing::Test {
public:
Dhcpv6SrvTest() {
}
};
TEST_F(Dhcpv6SrvTest, basic) {
// there's almost no code now. What's there provides echo capability
// that is just a proof of concept and will be removed soon
// No need to thoroughly test it
EXPECT_NO_THROW( {
Dhcpv6Srv * srv = new Dhcpv6Srv();
delete srv;
});
}
// Copyright (C) 2011 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
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <config.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <arpa/inet.h>
#include <gtest/gtest.h>
#include "dhcp6/addr6.h"
#include "dhcp6/pkt6.h"
#include "dhcp6/iface_mgr.h"
using namespace std;
using namespace isc;
class NakedIfaceMgr: public IfaceMgr {
// "naked" Interface Manager, exposes internal fields
public:
NakedIfaceMgr() { }
IfaceLst & getIfacesLst() { return ifaces_; }
void setSendSock(int sock) { sendsock_ = sock; }
void setRecvSock(int sock) { recvsock_ = sock; }
};
// dummy class for now, but this will be expanded when needed
class IfaceMgrTest : public ::testing::Test {
public:
IfaceMgrTest() {
}
};
TEST_F(IfaceMgrTest, basic) {
// checks that IfaceManager can be instantiated
IfaceMgr & ifacemgr = IfaceMgr::instance();
ASSERT_TRUE(&ifacemgr != 0);
}
TEST_F(IfaceMgrTest, ifaceClass) {
// basic tests for Iface inner class
IfaceMgr::Iface * iface = new IfaceMgr::Iface("eth5", 7);
EXPECT_STREQ("eth5/7", iface->getFullName().c_str());
delete iface;
}
TEST_F(IfaceMgrTest, getIface) {
cout << "Interface checks. Please ignore socket binding errors." << endl;
NakedIfaceMgr * ifacemgr = new NakedIfaceMgr();
// interface name, ifindex
IfaceMgr::Iface iface1("lo", 1);
IfaceMgr::Iface iface2("eth5", 2);
IfaceMgr::Iface iface3("en3", 5);
IfaceMgr::Iface iface4("e1000g0", 3);
ifacemgr->getIfacesLst().push_back(iface1);
ifacemgr->getIfacesLst().push_back(iface2);
ifacemgr->getIfacesLst().push_back(iface3);
ifacemgr->getIfacesLst().push_back(iface4);
// check that interface can be retrieved by ifindex
IfaceMgr::Iface * tmp = ifacemgr->getIface(5);
// ASSERT_NE(NULL, tmp); is not supported. hmmmm.
ASSERT_TRUE( tmp != NULL );
EXPECT_STREQ( "en3", tmp->name_.c_str() );
EXPECT_EQ(5, tmp->ifindex_);
// check that interface can be retrieved by name
tmp = ifacemgr->getIface("lo");
ASSERT_TRUE( tmp != NULL );
EXPECT_STREQ( "lo", tmp->name_.c_str() );
EXPECT_EQ(1, tmp->ifindex_);
// check that non-existing interfaces are not returned
EXPECT_EQ(0, ifacemgr->getIface("wifi0") );
delete ifacemgr;
}
TEST_F(IfaceMgrTest, detectIfaces) {
// test detects that interfaces can be detected
// there is no code for that now, but interfaces are
// read from file
fstream fakeifaces("interfaces.txt", ios::out);
fakeifaces << "eth0 fe80::1234";
fakeifaces.close();
// this is not usable on systems that don't have eth0
// interfaces. Nevertheless, this fake interface should
// be on list, but if_nametoindex() will fail.
IfaceMgr & ifacemgr = IfaceMgr::instance();
ASSERT_TRUE( ifacemgr.getIface("eth0") != NULL );
IfaceMgr::Iface * eth0 = ifacemgr.getIface("eth0");
// there should be one address
EXPECT_EQ(1, eth0->addrs_.size());
Addr6 * addr = &(*eth0->addrs_.begin());
ASSERT_TRUE( addr != NULL );
EXPECT_STREQ( "fe80::1234", addr->getPlain().c_str() );
}
TEST_F(IfaceMgrTest, sockets) {
// testing socket operation in a portable way is tricky
// without interface detection implemented
IfaceMgr & ifacemgr = IfaceMgr::instance();
Addr6 loAddr("::1", true);
// bind multicast socket to port 10547
int socket1 = ifacemgr.openSocket("lo", loAddr, 10547, true);
EXPECT_GT(socket1, 0); // socket > 0
// bind unicast socket to port 10548
int socket2 = ifacemgr.openSocket("lo", loAddr, 10548, false);
EXPECT_GT(socket2, 0);
// good to check that both sockets can be opened at once
close(socket1);
close(socket2);
}
TEST_F(IfaceMgrTest, sendReceive) {
// testing socket operation in a portable way is tricky
// without interface detection implemented
NakedIfaceMgr * ifacemgr = new NakedIfaceMgr();
// let's assume that every supported OS have lo interface
Addr6 loAddr("::1", true);
int socket1 = ifacemgr->openSocket("lo", loAddr, 10547, true);
int socket2 = ifacemgr->openSocket("lo", loAddr, 10546, false);
ifacemgr->setSendSock(socket2);
ifacemgr->setRecvSock(socket1);
Pkt6 sendPkt(128);
// prepare dummy payload
for (int i=0;i<128; i++) {
sendPkt.data_[i] = i;
}
sendPkt.remotePort = 10547;
sendPkt.remoteAddr = Addr6("::1", true);
sendPkt.ifindex = 1;
sendPkt.iface = "lo";
Pkt6 * rcvPkt;
EXPECT_EQ(true, ifacemgr->send(sendPkt));
rcvPkt = ifacemgr->receive();
ASSERT_TRUE( rcvPkt != NULL ); // received our own packet
// let's check that we received what was sent
EXPECT_EQ(sendPkt.dataLen_, rcvPkt->dataLen_);
EXPECT_EQ(0, memcmp(sendPkt.data_, rcvPkt->data_, rcvPkt->dataLen_) );
EXPECT_EQ(sendPkt.remoteAddr, rcvPkt->remoteAddr);
EXPECT_EQ(rcvPkt->remotePort, 10546);
delete rcvPkt;
delete ifacemgr;
}
// Copyright (C) 2011 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
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <config.h>
#include <iostream>
#include <sstream>
#include <arpa/inet.h>
#include <gtest/gtest.h>
#include "dhcp6/pkt6.h"
using namespace std;
using namespace isc;
// empty class for now, but may be extended once Addr6 becomes bigger
class Pkt6Test : public ::testing::Test {
public:
Pkt6Test() {
}
};
TEST_F(Pkt6Test, constructor) {
Pkt6 * pkt1 = new Pkt6(17);
ASSERT_EQ(pkt1->dataLen_, 17);
char * buf = new char[23];
// can't use char buf[23], as Pkt6 takes ownership of the data
Pkt6 * pkt2 = new Pkt6(buf, 23);
ASSERT_EQ(pkt2->dataLen_, 23);
ASSERT_EQ(pkt2->data_, buf);
delete pkt1;
delete pkt2;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment