Commit 8525babb authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[2984] Tests implemented for buffer6_receive, buffer6_send now pass

parent 4b090641
......@@ -277,6 +277,14 @@ public:
virtual ~NakedDhcpv6SrvTest() {
// Let's clean up if there is such a file.
unlink(DUID_FILE);
HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts(
"buffer6_receive");
HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts(
"buffer6_send");
HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts(
"lease6_renew");
HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts(
"lease6_release");
HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts(
"pkt6_receive");
HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts(
......
......@@ -56,11 +56,23 @@ TEST_F(Dhcpv6SrvTest, Hooks) {
NakedDhcpv6Srv srv(0);
// check if appropriate hooks are registered
int hook_index_buffer6_receive = -1;
int hook_index_buffer6_send = -1;
int hook_index_lease6_renew = -1;
int hook_index_lease6_release = -1;
int hook_index_pkt6_received = -1;
int hook_index_select_subnet = -1;
int hook_index_pkt6_send = -1;
// check if appropriate indexes are set
EXPECT_NO_THROW(hook_index_buffer6_receive = ServerHooks::getServerHooks()
.getIndex("buffer6_receive"));
EXPECT_NO_THROW(hook_index_buffer6_send = ServerHooks::getServerHooks()
.getIndex("buffer6_send"));
EXPECT_NO_THROW(hook_index_lease6_renew = ServerHooks::getServerHooks()
.getIndex("lease6_renew"));
EXPECT_NO_THROW(hook_index_lease6_release = ServerHooks::getServerHooks()
.getIndex("lease6_release"));
EXPECT_NO_THROW(hook_index_pkt6_received = ServerHooks::getServerHooks()
.getIndex("pkt6_receive"));
EXPECT_NO_THROW(hook_index_select_subnet = ServerHooks::getServerHooks()
......@@ -71,6 +83,10 @@ TEST_F(Dhcpv6SrvTest, Hooks) {
EXPECT_TRUE(hook_index_pkt6_received > 0);
EXPECT_TRUE(hook_index_select_subnet > 0);
EXPECT_TRUE(hook_index_pkt6_send > 0);
EXPECT_TRUE(hook_index_buffer6_receive > 0);
EXPECT_TRUE(hook_index_buffer6_send > 0);
EXPECT_TRUE(hook_index_lease6_renew > 0);
EXPECT_TRUE(hook_index_lease6_release > 0);
}
// This function returns buffer for very simple Solicit
......@@ -208,6 +224,80 @@ public:
return pkt6_receive_callout(callout_handle);
}
/// test callback that stores received callout name and pkt6 value
/// @param callout_handle handle passed by the hooks framework
/// @return always 0
static int
buffer6_receive_callout(CalloutHandle& callout_handle) {
callback_name_ = string("buffer6_receive");
callout_handle.getArgument("query6", callback_pkt6_);
callback_argument_names_ = callout_handle.getArgumentNames();
return (0);
}
/// test callback that changes first byte of client-id value
/// @param callout_handle handle passed by the hooks framework
/// @return always 0
static int
buffer6_receive_change_clientid(CalloutHandle& callout_handle) {
Pkt6Ptr pkt;
callout_handle.getArgument("query6", pkt);
// If there is at least one option with data
if (pkt->data_.size()>Pkt6::DHCPV6_PKT_HDR_LEN + Option::OPTION6_HDR_LEN) {
pkt->data_[8] = 0xff;
}
// carry on as usual
return buffer6_receive_callout(callout_handle);
}
/// test callback that deletes client-id
/// @param callout_handle handle passed by the hooks framework
/// @return always 0
static int
buffer6_receive_delete_clientid(CalloutHandle& callout_handle) {
Pkt6Ptr pkt;
callout_handle.getArgument("query6", pkt);
// this is modified SOLICIT (with missing mandatory client-id)
uint8_t data[] = {
1, // type 1 = SOLICIT
0xca, 0xfe, 0x01, // trans-id = 0xcafe01
0, 3, // option type 3 (IA_NA)
0, 12, // option length 12
0, 0, 0, 1, // iaid = 1
0, 0, 0, 0, // T1 = 0
0, 0, 0, 0 // T2 = 0
};
OptionBuffer modifiedMsg(data, data + sizeof(data));
pkt->data_ = modifiedMsg;
// carry on as usual
return buffer6_receive_callout(callout_handle);
}
/// test callback that sets skip flag
/// @param callout_handle handle passed by the hooks framework
/// @return always 0
static int
buffer6_receive_skip(CalloutHandle& callout_handle) {
Pkt6Ptr pkt;
callout_handle.getArgument("query6", pkt);
callout_handle.setSkip(true);
// carry on as usual
return buffer6_receive_callout(callout_handle);
}
/// Test callback that stores received callout name and pkt6 value
/// @param callout_handle handle passed by the hooks framework
/// @return always 0
......@@ -348,7 +438,128 @@ const Subnet6Collection* HooksDhcpv6SrvTest::callback_subnet6collection_;
vector<string> HooksDhcpv6SrvTest::callback_argument_names_;
// Checks if callouts installed on pkt6_received are indeed called and the
// Checks if callouts installed on pkt6_receive are indeed called and the
// all necessary parameters are passed.
//
// Note that the test name does not follow test naming convention,
// but the proper hook name is "buffer6_receive".
TEST_F(HooksDhcpv6SrvTest, simple_buffer6_receive) {
// Install pkt6_receive_callout
EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
"buffer6_receive", buffer6_receive_callout));
// Let's create a simple SOLICIT
Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
// Simulate that we have received that traffic
srv_->fakeReceive(sol);
// Server will now process to run its normal loop, but instead of calling
// IfaceMgr::receive6(), it will read all packets from the list set by
// fakeReceive()
// In particular, it should call registered pkt6_receive callback.
srv_->run();
// check that the callback called is indeed the one we installed
EXPECT_EQ("buffer6_receive", callback_name_);
// check that pkt6 argument passing was successful and returned proper value
EXPECT_TRUE(callback_pkt6_.get() == sol.get());
// Check that all expected parameters are there
vector<string> expected_argument_names;
expected_argument_names.push_back(string("query6"));
EXPECT_TRUE(expected_argument_names == callback_argument_names_);
}
// Checks if callouts installed on pkt6_received is able to change
// the values and the parameters are indeed used by the server.
TEST_F(HooksDhcpv6SrvTest, valueChange_buffer6_receive) {
// Install pkt6_receive_callout
EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
"buffer6_receive", buffer6_receive_change_clientid));
// Let's create a simple SOLICIT
Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
// Simulate that we have received that traffic
srv_->fakeReceive(sol);
// Server will now process to run its normal loop, but instead of calling
// IfaceMgr::receive6(), it will read all packets from the list set by
// fakeReceive()
// In particular, it should call registered pkt6_receive callback.
srv_->run();
// check that the server did send a reposonce
ASSERT_EQ(1, srv_->fake_sent_.size());
// Make sure that we received a response
Pkt6Ptr adv = srv_->fake_sent_.front();
ASSERT_TRUE(adv);
// Get client-id...
OptionPtr clientid = adv->getOption(D6O_CLIENTID);
ASSERT_TRUE(clientid);
// ... and check if it is the modified value
EXPECT_EQ(0xff, clientid->getData()[0]);
}
// Checks if callouts installed on buffer6_receive is able to delete
// existing options and that change impacts server processing (mandatory
// client-id option is deleted, so the packet is expected to be dropped)
TEST_F(HooksDhcpv6SrvTest, deleteClientId_buffer6_receive) {
// Install pkt6_receive_callout
EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
"buffer6_receive", buffer6_receive_delete_clientid));
// Let's create a simple SOLICIT
Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
// Simulate that we have received that traffic
srv_->fakeReceive(sol);
// Server will now process to run its normal loop, but instead of calling
// IfaceMgr::receive6(), it will read all packets from the list set by
// fakeReceive()
// In particular, it should call registered pkt6_receive callback.
srv_->run();
// Check that the server dropped the packet and did not send a response
ASSERT_EQ(0, srv_->fake_sent_.size());
}
// Checks if callouts installed on buffer6_received is able to set skip flag that
// will cause the server to not process the packet (drop), even though it is valid.
TEST_F(HooksDhcpv6SrvTest, skip_buffer6_receive) {
// Install pkt6_receive_callout
EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
"buffer6_receive", buffer6_receive_skip));
// Let's create a simple SOLICIT
Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
// Simulate that we have received that traffic
srv_->fakeReceive(sol);
// Server will now process to run its normal loop, but instead of calling
// IfaceMgr::receive6(), it will read all packets from the list set by
// fakeReceive()
// In particular, it should call registered pkt6_receive callback.
srv_->run();
// check that the server dropped the packet and did not produce any response
ASSERT_EQ(0, srv_->fake_sent_.size());
}
// Checks if callouts installed on pkt6_receive are indeed called and the
// all necessary parameters are passed.
//
// Note that the test name does not follow test naming convention,
......
......@@ -142,7 +142,7 @@ public:
/// @brief Returns reference to input buffer.
///
/// @return reference to input buffer
const OptionBuffer& getData() const { return(data_); }
/// const OptionBuffer& getData() const { return(data_); }
/// @brief Returns protocol of this packet (UDP or TCP).
///
......@@ -410,6 +410,18 @@ public:
/// to be impossible). Therefore public field is considered the best
/// (or least bad) solution.
std::vector<RelayInfo> relay_info_;
/// unparsed data (in received packets)
///
/// @warning This public member is accessed by derived
/// classes directly. One of such derived classes is
/// @ref perfdhcp::PerfPkt6. The impact on derived clasess'
/// behavior must be taken into consideration before making
/// changes to this member such as access scope restriction or
/// data format change etc.
OptionBuffer data_;
protected:
/// Builds on wire packet for TCP transmission.
///
......@@ -492,16 +504,6 @@ protected:
/// DHCPv6 transaction-id
uint32_t transid_;
/// unparsed data (in received packets)
///
/// @warning This protected member is accessed by derived
/// classes directly. One of such derived classes is
/// @ref perfdhcp::PerfPkt6. The impact on derived clasess'
/// behavior must be taken into consideration before making
/// changes to this member such as access scope restriction or
/// data format change etc.
OptionBuffer data_;
/// name of the network interface the packet was received/to be sent over
std::string iface_;
......
......@@ -766,9 +766,9 @@ TEST_F(IfaceMgrTest, sendReceive6) {
ASSERT_TRUE(rcvPkt); // received our own packet
// let's check that we received what was sent
ASSERT_EQ(sendPkt->getData().size(), rcvPkt->getData().size());
EXPECT_EQ(0, memcmp(&sendPkt->getData()[0], &rcvPkt->getData()[0],
rcvPkt->getData().size()));
ASSERT_EQ(sendPkt->data_.size(), rcvPkt->data_.size());
EXPECT_EQ(0, memcmp(&sendPkt->data_[0], &rcvPkt->data_[0],
rcvPkt->data_.size()));
EXPECT_EQ(sendPkt->getRemoteAddr().toText(), rcvPkt->getRemoteAddr().toText());
......
......@@ -64,8 +64,8 @@ TEST_F(Pkt6Test, constructor) {
uint8_t data[] = { 0, 1, 2, 3, 4, 5 };
scoped_ptr<Pkt6> pkt1(new Pkt6(data, sizeof(data)));
EXPECT_EQ(6, pkt1->getData().size());
EXPECT_EQ(0, memcmp( &pkt1->getData()[0], data, sizeof(data)));
EXPECT_EQ(6, pkt1->data_.size());
EXPECT_EQ(0, memcmp( &pkt1->data_[0], data, sizeof(data)));
}
/// @brief returns captured actual SOLICIT packet
......
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