diff options
author | Tomek Mrugalski <tomasz@isc.org> | 2015-06-19 19:41:18 +0200 |
---|---|---|
committer | Tomek Mrugalski <tomasz@isc.org> | 2015-06-19 19:41:18 +0200 |
commit | 7616e3b3b8dfc7bb4d95665651acd0056cd66408 (patch) | |
tree | 7813fbbc520af4b6935ae5201745e09c9f93a810 /src/bin/dhcp6/tests | |
parent | [master] Forgotten cleanup for 3800: remove tabs. (diff) | |
parent | [3795] Changes after review: (diff) | |
download | kea-7616e3b3b8dfc7bb4d95665651acd0056cd66408.tar.xz kea-7616e3b3b8dfc7bb4d95665651acd0056cd66408.zip |
[master] Merge branch 'trac3795' (DHCPv6 statistics)
Conflicts:
doc/guide/dhcp4-srv.xml
Diffstat (limited to 'src/bin/dhcp6/tests')
-rw-r--r-- | src/bin/dhcp6/tests/dhcp6_client.cc | 9 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/dhcp6_client.h | 14 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/dhcp6_srv_unittest.cc | 85 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/dhcp6_test_utils.cc | 85 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/dhcp6_test_utils.h | 49 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/infrequest_unittest.cc | 58 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/sarr_unittest.cc | 148 |
7 files changed, 409 insertions, 39 deletions
diff --git a/src/bin/dhcp6/tests/dhcp6_client.cc b/src/bin/dhcp6/tests/dhcp6_client.cc index 1fc120a9be..9de4755c8b 100644 --- a/src/bin/dhcp6/tests/dhcp6_client.cc +++ b/src/bin/dhcp6/tests/dhcp6_client.cc @@ -295,6 +295,9 @@ Dhcp6Client::doSARR() { void Dhcp6Client::doSolicit() { context_.query_ = createMsg(DHCPV6_SOLICIT); + if (forced_server_id_) { + context_.query_->addOption(forced_server_id_); + } if (use_na_) { context_.query_->addOption(Option6IAPtr(new Option6IA(D6O_IA_NA, 1234))); @@ -327,7 +330,11 @@ Dhcp6Client::doSolicit() { void Dhcp6Client::doRequest() { Pkt6Ptr query = createMsg(DHCPV6_REQUEST); - query->addOption(context_.response_->getOption(D6O_SERVERID)); + if (!forced_server_id_) { + query->addOption(context_.response_->getOption(D6O_SERVERID)); + } else { + query->addOption(forced_server_id_); + } copyIAs(context_.response_, query); // Add Client FQDN if configured. diff --git a/src/bin/dhcp6/tests/dhcp6_client.h b/src/bin/dhcp6/tests/dhcp6_client.h index 98091db61e..35462321ce 100644 --- a/src/bin/dhcp6/tests/dhcp6_client.h +++ b/src/bin/dhcp6/tests/dhcp6_client.h @@ -448,6 +448,17 @@ public: use_rapid_commit_ = rapid_commit; } + /// @brief Specifies server-id to be used in send messages + /// + /// Overrides the server-id to be sent when server-id is expected to be + /// sent. May be NULL, which means use proper server-id sent in Advertise + /// (which is a normal client behavior). + /// + /// @param server_id server-id to be sent + void useServerId(const OptionPtr& server_id) { + forced_server_id_ = server_id; + } + /// @brief Creates an instance of the Client FQDN option to be included /// in the client's message. /// @@ -614,6 +625,9 @@ private: /// to true. See @ref sendORO for details. std::vector<uint16_t> oro_; + /// @brief forced (Overridden) value of the server-id option (may be NULL) + OptionPtr forced_server_id_; + /// @brief FQDN requested by the client. Option6ClientFqdnPtr fqdn_; }; diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc index eb308e711a..b587becb4f 100644 --- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc @@ -37,7 +37,7 @@ #include <dhcpsrv/utils.h> #include <util/buffer.h> #include <util/range_utilities.h> -#include <hooks/server_hooks.h> +#include <stats/stats_mgr.h> #include <dhcp6/tests/dhcp6_test_utils.h> #include <dhcp6/tests/dhcp6_client.h> @@ -58,7 +58,6 @@ using namespace isc::asiolink; using namespace isc::dhcp; using namespace isc::dhcp::test; using namespace isc::util; -using namespace isc::hooks; using namespace std; namespace { @@ -2326,6 +2325,88 @@ TEST_F(Dhcpv6SrvTest, rsooOverride) { ASSERT_EQ(1, opt->getData().size()); } +// Test checks if pkt6-advertise-received is bumped up correctly. +// Note that in properly configured network the server never receives Advertise +// messages. +TEST_F(Dhcpv6SrvTest, receiveAdvertiseStat) { + testReceiveStats(DHCPV6_ADVERTISE, "pkt6-advertise-received"); +} + +// Test checks if pkt6-reply-received is bumped up correctly. +// Note that in properly configured network the server never receives Reply +// messages. +TEST_F(Dhcpv6SrvTest, receiveReplyStat) { + testReceiveStats(DHCPV6_REPLY, "pkt6-reply-received"); +} + +// Test checks if pkt6-unknown-received is bumped up correctly. +TEST_F(Dhcpv6SrvTest, receiveUnknownStat) { + testReceiveStats(123, "pkt6-unknown-received"); +} + +// Test checks if pkt6-renew-received is bumped up correctly. +TEST_F(Dhcpv6SrvTest, receiveRenewStat) { + testReceiveStats(DHCPV6_RENEW, "pkt6-renew-received"); +} + +// Test checks if pkt6-rebind-received is bumped up correctly. +TEST_F(Dhcpv6SrvTest, receiveRebindStat) { + testReceiveStats(DHCPV6_REBIND, "pkt6-rebind-received"); +} + +// Test checks if pkt6-release-received is bumped up correctly. +TEST_F(Dhcpv6SrvTest, receiveReleaseStat) { + testReceiveStats(DHCPV6_RELEASE, "pkt6-release-received"); +} + +// Test checks if pkt6-decline-received is bumped up correctly. +TEST_F(Dhcpv6SrvTest, receiveDeclineStat) { + testReceiveStats(DHCPV6_DECLINE, "pkt6-decline-received"); +} + +// Test checks if reception of a malformed packet increases pkt-parse-failed +// and pkt6-receive-drop +TEST_F(Dhcpv6SrvTest, receiveParseFailedStat) { + using namespace isc::stats; + StatsMgr& mgr = StatsMgr::instance(); + NakedDhcpv6Srv srv(0); + + // Let's get a simple SOLICIT... + Pkt6Ptr pkt = PktCaptures::captureSimpleSolicit(); + + // And pretend it's packet is only 3 bytes long. + pkt->data_.resize(3); + + // Check that those statistics are not set before the test + ObservationPtr pkt6_rcvd = mgr.getObservation("pkt6-received"); + ObservationPtr parse_fail = mgr.getObservation("pkt6-parse-failed"); + ObservationPtr recv_drop = mgr.getObservation("pkt6-receive-drop"); + EXPECT_FALSE(pkt6_rcvd); + EXPECT_FALSE(parse_fail); + EXPECT_FALSE(recv_drop); + + // Simulate that we have received that traffic + srv.fakeReceive(pkt); + + // 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() + srv.run(); + + // All expected statstics must be present. + pkt6_rcvd = mgr.getObservation("pkt6-received"); + parse_fail = mgr.getObservation("pkt6-parse-failed"); + recv_drop = mgr.getObservation("pkt6-receive-drop"); + ASSERT_TRUE(pkt6_rcvd); + ASSERT_TRUE(parse_fail); + ASSERT_TRUE(recv_drop); + + // They also must have expected values. + EXPECT_EQ(1, pkt6_rcvd->getInteger().first); + EXPECT_EQ(1, parse_fail->getInteger().first); + EXPECT_EQ(1, recv_drop->getInteger().first); +} + /// @todo: Add more negative tests for processX(), e.g. extend sanityCheck() test /// to call processX() methods. diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.cc b/src/bin/dhcp6/tests/dhcp6_test_utils.cc index 550fb5244c..dd40b049b9 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.cc +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.cc @@ -17,8 +17,10 @@ #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 <util/pointer_util.h> #include <cc/command_interpreter.h> +#include <stats/stats_mgr.h> #include <string.h> using namespace isc::data; @@ -28,6 +30,8 @@ using namespace isc::asiolink; namespace isc { namespace test { +const char* NakedDhcpv6SrvTest::DUID_FILE = "server-id-test.txt"; + Dhcpv6SrvTest::Dhcpv6SrvTest() :srv_(0) { subnet_ = isc::dhcp::Subnet6Ptr @@ -742,6 +746,44 @@ Dhcpv6SrvTest::testReleaseReject(Lease::Type type, const IOAddress& addr) { } void +Dhcpv6SrvTest::testReceiveStats(uint8_t pkt_type, const std::string& stat_name) { + + using namespace isc::stats; + StatsMgr& mgr = StatsMgr::instance(); + NakedDhcpv6Srv srv(0); + + // Let's get a simple SOLICIT... + Pkt6Ptr pkt = PktCaptures::captureSimpleSolicit(); + + // And pretend it's packet of a different type + pkt->data_[0] = pkt_type; + + // Check that those statistics are not set before the test + ObservationPtr pkt6_rcvd = mgr.getObservation("pkt6-received"); + ObservationPtr tested_stat = mgr.getObservation(stat_name); + EXPECT_FALSE(pkt6_rcvd); + EXPECT_FALSE(tested_stat); + + // Simulate that we have received that traffic + srv.fakeReceive(pkt); + + // 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() + srv.run(); + + // All expected statstics must be present. + pkt6_rcvd = mgr.getObservation("pkt6-received"); + tested_stat = mgr.getObservation(stat_name); + ASSERT_TRUE(pkt6_rcvd); + ASSERT_TRUE(tested_stat); + + // They also must have expected values. + EXPECT_EQ(1, pkt6_rcvd->getInteger().first); + EXPECT_EQ(1, tested_stat->getInteger().first); +} + +void Dhcpv6SrvTest::configure(const std::string& config) { configure(config, srv_); } @@ -761,6 +803,48 @@ Dhcpv6SrvTest::configure(const std::string& config, NakedDhcpv6Srv& srv) { CfgMgr::instance().commit(); } +NakedDhcpv6SrvTest::NakedDhcpv6SrvTest() +: rcode_(-1) { + // it's ok if that fails. There should not be such a file anyway + unlink(DUID_FILE); + + const isc::dhcp::IfaceMgr::IfaceCollection& ifaces = + isc::dhcp::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(); + + // Let's wipe all existing statistics. + isc::stats::StatsMgr::instance().removeAll(); +} + +NakedDhcpv6SrvTest::~NakedDhcpv6SrvTest() { + // Let's wipe all existing statistics. + isc::stats::StatsMgr::instance().removeAll(); + + // Let's clean up if there is such a file. + unlink(DUID_FILE); + isc::hooks::HooksManager::preCalloutsLibraryHandle() + .deregisterAllCallouts("buffer6_receive"); + isc::hooks::HooksManager::preCalloutsLibraryHandle() + .deregisterAllCallouts("buffer6_send"); + isc::hooks::HooksManager::preCalloutsLibraryHandle() + .deregisterAllCallouts("lease6_renew"); + isc::hooks::HooksManager::preCalloutsLibraryHandle() + .deregisterAllCallouts("lease6_release"); + isc::hooks::HooksManager::preCalloutsLibraryHandle() + .deregisterAllCallouts("pkt6_receive"); + isc::hooks::HooksManager::preCalloutsLibraryHandle() + .deregisterAllCallouts("pkt6_send"); + isc::hooks::HooksManager::preCalloutsLibraryHandle() + .deregisterAllCallouts("subnet6_select"); +} + // Generate IA_NA option with specified parameters boost::shared_ptr<Option6IA> NakedDhcpv6SrvTest::generateIA(uint16_t type, uint32_t iaid, uint32_t t1, @@ -855,5 +939,6 @@ NakedDhcpv6SrvTest::checkIA_NAStatusCode( } } + }; // end of isc::test namespace }; // end of isc namespace diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.h b/src/bin/dhcp6/tests/dhcp6_test_utils.h index 7f0b4a5a4b..d4e48319c6 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.h +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.h @@ -127,28 +127,16 @@ public: std::list<isc::dhcp::Pkt6Ptr> fake_sent_; }; -static const char* DUID_FILE = "server-id-test.txt"; - -// test fixture for any tests requiring blank/empty configuration -// serves as base class for additional tests +/// @brief Test fixture for any tests requiring blank/empty configuration +/// serves as base class for additional tests class NakedDhcpv6SrvTest : public ::testing::Test { public: - NakedDhcpv6SrvTest() : rcode_(-1) { - // it's ok if that fails. There should not be such a file anyway - unlink(DUID_FILE); - - const isc::dhcp::IfaceMgr::IfaceCollection& ifaces = - isc::dhcp::IfaceMgr::instance().getIfaces(); - - // There must be some interface detected - if (ifaces.empty()) { - // We can't use ASSERT in constructor - ADD_FAILURE() << "No interfaces detected."; - } + /// @brief Constructor + NakedDhcpv6SrvTest(); - valid_iface_ = (*ifaces.begin())->getName(); - } + /// @brief Location of a test DUID file + static const char* DUID_FILE; // Generate IA_NA or IA_PD option with specified parameters boost::shared_ptr<isc::dhcp::Option6IA> generateIA @@ -286,24 +274,7 @@ public: EXPECT_EQ(expected_transid, rsp->getTransid()); } - virtual ~NakedDhcpv6SrvTest() { - // Let's clean up if there is such a file. - unlink(DUID_FILE); - isc::hooks::HooksManager::preCalloutsLibraryHandle() - .deregisterAllCallouts("buffer6_receive"); - isc::hooks::HooksManager::preCalloutsLibraryHandle() - .deregisterAllCallouts("buffer6_send"); - isc::hooks::HooksManager::preCalloutsLibraryHandle() - .deregisterAllCallouts("lease6_renew"); - isc::hooks::HooksManager::preCalloutsLibraryHandle() - .deregisterAllCallouts("lease6_release"); - isc::hooks::HooksManager::preCalloutsLibraryHandle() - .deregisterAllCallouts("pkt6_receive"); - isc::hooks::HooksManager::preCalloutsLibraryHandle() - .deregisterAllCallouts("pkt6_send"); - isc::hooks::HooksManager::preCalloutsLibraryHandle() - .deregisterAllCallouts("subnet6_select"); - }; + virtual ~NakedDhcpv6SrvTest(); // A DUID used in most tests (typically as client-id) isc::dhcp::DuidPtr duid_; @@ -539,6 +510,12 @@ public: testReleaseReject(isc::dhcp::Lease::Type type, const isc::asiolink::IOAddress& addr); + /// @brief simulates reception of a packet of specified type and checks statistic + /// + /// @param pkt_type reception of a packet of this type will be simulated + /// @param stat_name this statistic is expected to be set to 1 + void testReceiveStats(uint8_t pkt_type, const std::string& stat_name); + /// A subnet used in most tests isc::dhcp::Subnet6Ptr subnet_; diff --git a/src/bin/dhcp6/tests/infrequest_unittest.cc b/src/bin/dhcp6/tests/infrequest_unittest.cc index ead363642d..8b15f7fb6e 100644 --- a/src/bin/dhcp6/tests/infrequest_unittest.cc +++ b/src/bin/dhcp6/tests/infrequest_unittest.cc @@ -18,6 +18,7 @@ #include <dhcp6/tests/dhcp6_client.h> #include <dhcp/option6_addrlst.h> #include <dhcp/option6_client_fqdn.h> +#include <stats/stats_mgr.h> using namespace isc; using namespace isc::dhcp; @@ -126,6 +127,17 @@ public: InfRequestTest() : Dhcpv6SrvTest(), iface_mgr_test_config_(true) { + + // Let's wipe all existing statistics. + isc::stats::StatsMgr::instance().removeAll(); + } + + /// @brief Destructor. + /// + /// Removes any statistics that may have been set. + ~InfRequestTest() { + // Let's wipe all existing statistics. + isc::stats::StatsMgr::instance().removeAll(); } /// @brief Interface Manager's fake configuration control. @@ -301,7 +313,53 @@ TEST_F(InfRequestTest, infRequestNoSubnets) { EXPECT_EQ("2001:db8::2", addrs[1].toText()); } +/// Check that server processes correctly an incoming inf-request in a +/// typical subnet that has also address and prefix pools. +TEST_F(InfRequestTest, infRequestStats) { + Dhcp6Client client; + // Configure client to request IA_PD. + configure(CONFIGS[0], *client.getServer()); + // Make sure we ended-up having expected number of subnets configured. + const Subnet6Collection* subnets = CfgMgr::instance().getCurrentCfg()-> + getCfgSubnets6()->getAll(); + ASSERT_EQ(1, subnets->size()); + + // Ok, let's check the statistics. None should be present. + using namespace isc::stats; + StatsMgr& mgr = StatsMgr::instance(); + ObservationPtr pkt6_rcvd = mgr.getObservation("pkt6-received"); + ObservationPtr pkt6_infreq_rcvd = mgr.getObservation("pkt6-infrequest-received"); + ObservationPtr pkt6_reply_sent = mgr.getObservation("pkt6-reply-sent"); + ObservationPtr pkt6_sent = mgr.getObservation("pkt6-sent"); + EXPECT_FALSE(pkt6_rcvd); + EXPECT_FALSE(pkt6_infreq_rcvd); + EXPECT_FALSE(pkt6_reply_sent); + EXPECT_FALSE(pkt6_sent); + + // Perform 2-way exchange (Inf-request/reply) + client.requestOption(D6O_NAME_SERVERS); + ASSERT_NO_THROW(client.doInfRequest()); + // Confirm that there's a response + Pkt6Ptr response = client.getContext().response_; + ASSERT_TRUE(response); + + pkt6_rcvd = mgr.getObservation("pkt6-received"); + pkt6_infreq_rcvd = mgr.getObservation("pkt6-infrequest-received"); + pkt6_reply_sent = mgr.getObservation("pkt6-reply-sent"); + pkt6_sent = mgr.getObservation("pkt6-sent"); + + ASSERT_TRUE(pkt6_rcvd); + ASSERT_TRUE(pkt6_infreq_rcvd); + ASSERT_TRUE(pkt6_reply_sent); + ASSERT_TRUE(pkt6_sent); + + // They also must have expected values. + EXPECT_EQ(1, pkt6_rcvd->getInteger().first); + EXPECT_EQ(1, pkt6_infreq_rcvd->getInteger().first); + EXPECT_EQ(1, pkt6_reply_sent->getInteger().first); + EXPECT_EQ(1, pkt6_sent->getInteger().first); +} } // end of anonymous namespace diff --git a/src/bin/dhcp6/tests/sarr_unittest.cc b/src/bin/dhcp6/tests/sarr_unittest.cc index 2035521383..71eb3e96d1 100644 --- a/src/bin/dhcp6/tests/sarr_unittest.cc +++ b/src/bin/dhcp6/tests/sarr_unittest.cc @@ -19,6 +19,8 @@ #include <dhcp6/tests/dhcp6_client.h> #include <dhcpsrv/cfgmgr.h> #include <dhcpsrv/d2_client_mgr.h> +#include <asiolink/io_address.h> +#include <stats/stats_mgr.h> using namespace isc; using namespace isc::dhcp; @@ -101,6 +103,8 @@ public: SARRTest() : Dhcpv6SrvTest(), iface_mgr_test_config_(true) { + // Let's wipe all existing statistics. + isc::stats::StatsMgr::instance().removeAll(); } /// @brief Destructor. @@ -109,6 +113,9 @@ public: virtual ~SARRTest() { D2ClientConfigPtr cfg(new D2ClientConfig()); CfgMgr::instance().setD2ClientConfig(cfg); + + // Let's wipe all existing statistics. + isc::stats::StatsMgr::instance().removeAll(); } /// @brief Interface Manager's fake configuration control. @@ -276,5 +283,146 @@ TEST_F(SARRTest, rapidCommitDisable) { 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) { + + // Let's use one of the existing configurations and tell the client to + // ask for an address. + Dhcp6Client client; + configure(CONFIGS[1], *client.getServer()); + client.setInterface("eth1"); + client.useNA(); + + // Make sure we ended-up having expected number of subnets configured. + const Subnet6Collection* subnets = CfgMgr::instance().getCurrentCfg()-> + getCfgSubnets6()->getAll(); + ASSERT_EQ(2, subnets->size()); + + // Ok, let's check the statistics. None should be present. + using namespace isc::stats; + StatsMgr& mgr = StatsMgr::instance(); + ObservationPtr pkt6_rcvd = mgr.getObservation("pkt6-received"); + ObservationPtr pkt6_solicit_rcvd = mgr.getObservation("pkt6-solicit-received"); + ObservationPtr pkt6_adv_sent = mgr.getObservation("pkt6-advertise-sent"); + ObservationPtr pkt6_request_rcvd = mgr.getObservation("pkt6-request-received"); + ObservationPtr pkt6_reply_sent = mgr.getObservation("pkt6-reply-sent"); + ObservationPtr pkt6_sent = mgr.getObservation("pkt6-sent"); + EXPECT_FALSE(pkt6_rcvd); + EXPECT_FALSE(pkt6_solicit_rcvd); + EXPECT_FALSE(pkt6_adv_sent); + EXPECT_FALSE(pkt6_request_rcvd); + EXPECT_FALSE(pkt6_reply_sent); + EXPECT_FALSE(pkt6_sent); + + // Perform 4-way exchange. + ASSERT_NO_THROW(client.doSARR()); + // Server should have assigned a prefix. + ASSERT_EQ(1, client.getLeaseNum()); + + // All expected statstics must be present now. + pkt6_rcvd = mgr.getObservation("pkt6-received"); + pkt6_solicit_rcvd = mgr.getObservation("pkt6-solicit-received"); + pkt6_adv_sent = mgr.getObservation("pkt6-advertise-sent"); + pkt6_request_rcvd = mgr.getObservation("pkt6-request-received"); + pkt6_reply_sent = mgr.getObservation("pkt6-reply-sent"); + pkt6_sent = mgr.getObservation("pkt6-sent"); + ASSERT_TRUE(pkt6_rcvd); + ASSERT_TRUE(pkt6_solicit_rcvd); + ASSERT_TRUE(pkt6_adv_sent); + ASSERT_TRUE(pkt6_request_rcvd); + ASSERT_TRUE(pkt6_reply_sent); + ASSERT_TRUE(pkt6_sent); + + // They also must have expected values. + EXPECT_EQ(2, pkt6_rcvd->getInteger().first); + EXPECT_EQ(1, pkt6_solicit_rcvd->getInteger().first); + EXPECT_EQ(1, pkt6_adv_sent->getInteger().first); + EXPECT_EQ(1, pkt6_request_rcvd->getInteger().first); + EXPECT_EQ(1, pkt6_reply_sent->getInteger().first); + 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) { + + // Dummy server-id (0xff repeated 10 times) + std::vector<uint8_t> data(10, 0xff); + OptionPtr bogus_srv_id(new Option(Option::V6, D6O_SERVERID, data)); + + // Let's use one of the existing configurations and tell the client to + // ask for an address. + Dhcp6Client client; + configure(CONFIGS[1], *client.getServer()); + client.setInterface("eth1"); + client.useNA(); + + client.doSolicit(); + client.useServerId(bogus_srv_id); + client.doRequest(); + + // Ok, let's check the statistic. pkt6-receive-drop should be set to 1. + using namespace isc::stats; + StatsMgr& mgr = StatsMgr::instance(); + + ObservationPtr pkt6_recv_drop = mgr.getObservation("pkt6-receive-drop"); + ASSERT_TRUE(pkt6_recv_drop); + + 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) { + + // Let's use one of the existing configurations and tell the client to + // ask for an address. + Dhcp6Client client; + configure(CONFIGS[1], *client.getServer()); + client.setInterface("eth1"); + client.useNA(); + + client.setDestAddress(asiolink::IOAddress("2001:db8::1")); // Pretend it's unicast + client.doSolicit(); + + // Ok, let's check the statistic. pkt6-receive-drop should be set to 1. + using namespace isc::stats; + StatsMgr& mgr = StatsMgr::instance(); + + ObservationPtr pkt6_recv_drop = mgr.getObservation("pkt6-receive-drop"); + ASSERT_TRUE(pkt6_recv_drop); + + 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) { + + // Let's use one of the existing configurations and tell the client to + // ask for an address. + Dhcp6Client client; + configure(CONFIGS[1], *client.getServer()); + client.setInterface("eth1"); + client.useNA(); + + // Let's send our client-id as server-id. That will result in the + // packet containing the client-id twice. That should cause RFCViolation + // exception. + client.useServerId(client.getClientId()); + client.doSolicit(); + + // Ok, let's check the statistic. pkt6-receive-drop should be set to 1. + using namespace isc::stats; + StatsMgr& mgr = StatsMgr::instance(); + + ObservationPtr pkt6_recv_drop = mgr.getObservation("pkt6-receive-drop"); + ASSERT_TRUE(pkt6_recv_drop); + + EXPECT_EQ(1, pkt6_recv_drop->getInteger().first); +} + } // end of anonymous namespace |