From: Thomas Markwalder Date: Thu, 19 Mar 2015 20:08:19 +0000 (-0400) Subject: [3689] Added host renew and rebind tests X-Git-Tag: kea-0.9.1~8^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2d290633dbfd4a5c5cf3f7f0e6a914822e6577ea;p=thirdparty%2Fkea.git [3689] Added host renew and rebind tests tests/dhcp6_client.cc tests/dhcp6_client.h added Dhcp6Client::doRenew() tests/host_unittest.cc added TEST_F(HostTest, sarrAndRenew) added TEST_F(HostTest, sarrAndRebind) --- diff --git a/src/bin/dhcp6/tests/dhcp6_client.cc b/src/bin/dhcp6/tests/dhcp6_client.cc index 8f445ec882..330037bb83 100644 --- a/src/bin/dhcp6/tests/dhcp6_client.cc +++ b/src/bin/dhcp6/tests/dhcp6_client.cc @@ -338,6 +338,20 @@ Dhcp6Client::doInfRequest() { context_.response_ = receiveOneMsg(); } +void +Dhcp6Client::doRenew() { + Pkt6Ptr query = createMsg(DHCPV6_RENEW); + query->addOption(context_.response_->getOption(D6O_SERVERID)); + copyIAsFromLeases(query); + context_.query_ = query; + sendMsg(context_.query_); + context_.response_ = receiveOneMsg(); + // Apply configuration only if the server has responded. + if (context_.response_) { + applyRcvdConfiguration(context_.response_); + } +} + void Dhcp6Client::doRebind() { Pkt6Ptr query = createMsg(DHCPV6_REBIND); diff --git a/src/bin/dhcp6/tests/dhcp6_client.h b/src/bin/dhcp6/tests/dhcp6_client.h index 319cc23461..03d69f2d97 100644 --- a/src/bin/dhcp6/tests/dhcp6_client.h +++ b/src/bin/dhcp6/tests/dhcp6_client.h @@ -182,6 +182,21 @@ public: /// @todo Perform sanity checks on returned messages. void doSolicit(); + /// @brief Sends a Renew to the server and receives the Reply. + /// + /// This function simulates sending the Renew message to the server and + /// receiving server's response (if any). The client uses existing leases + /// (either address or prefixes) and places them in the Renew message. + /// If the server responds to the Renew (and extends the lease lifetimes) + /// the current lease configuration is updated. + /// + /// @throw This function doesn't throw exceptions on its own, but it calls + /// functions that are not exception safe, so it may throw exceptions if + /// error occurs. + /// + /// @todo Perform sanity checks on returned messages. + void doRenew(); + /// @brief Sends a Rebind to the server and receives the Reply. /// /// This function simulates sending the Rebind message to the server and @@ -305,9 +320,11 @@ public: /// @brief Sets the client's DUID from a string value /// /// Replaces the client's DUID with one constructed from the given - /// string. The string is expected to hexadecimal digits with or + /// string. The string is expected to contain hexadecimal digits with or /// without ":" separators. /// + /// @param str The string of digits from which to create the DUID + /// /// The DUID modification affects the value returned by the /// @c Dhcp6Client::getClientId void setDUID(const std::string& duid_str); diff --git a/src/bin/dhcp6/tests/host_unittest.cc b/src/bin/dhcp6/tests/host_unittest.cc index 341c7f594a..e7541b7006 100644 --- a/src/bin/dhcp6/tests/host_unittest.cc +++ b/src/bin/dhcp6/tests/host_unittest.cc @@ -26,10 +26,10 @@ namespace { /// @brief Set of JSON configurations used by the Host reservation unit tests. /// -/// - Configuration 0: +/// - Configuration 0: /// Single subnet with two reservations, one with a hostname, one without const char* CONFIGS[] = { - // Configuration 0: + // Configuration 0: "{ " "\"interfaces-config\": {" " \"interfaces\": [ \"*\" ]" @@ -72,11 +72,23 @@ public: IfaceMgrTestConfig iface_mgr_test_config_; }; -TEST_F(HostTest, basicSARRs) { +// Test basic SARR scenarios against a server configured with one subnet +// containing two reservations. One reservation with a hostname, one +// without a hostname. Scenarios: +// +// - Verify that a client when matched to a host reservation with a hostname +// gets that reservation and the lease hostname matches the reserved hostname +// +// - Verify that a client when matched to a host reservation without a hostname +// gets that reservation and the lease hostname is blank +// +// - Verify that a client that does not match a host reservation gets a dynamic +// lease and the hostname for the lease is blank. +// +TEST_F(HostTest, basicSarrs) { Dhcp6Client client; 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()); @@ -90,13 +102,13 @@ TEST_F(HostTest, basicSARRs) { // Perform 4-way exchange. ASSERT_NO_THROW(client.doSARR()); - // Verify that the client we got the reserved address + // Verify that the client we got the reserved address ASSERT_EQ(1, client.getLeaseNum()); Lease6 lease_client = client.getLease(0); EXPECT_EQ("2001:db8:1:1::babe", lease_client.addr_.toText()); // Check that the server recorded the lease. - // and lease has reserved hostname + // and lease has reserved hostname Lease6Ptr lease_server = checkLease(lease_client); ASSERT_TRUE(lease_server); EXPECT_EQ("alice", lease_server->hostname_); @@ -110,19 +122,19 @@ TEST_F(HostTest, basicSARRs) { // Perform 4-way exchange. ASSERT_NO_THROW(client.doSARR()); - // Verify that the client we got the reserved address + // Verify that the client we got the reserved address ASSERT_EQ(1, client.getLeaseNum()); lease_client = client.getLease(0); EXPECT_EQ("2001:db8:1:1::babf", lease_client.addr_.toText()); // Check that the server recorded the lease. - // and that the server lease has NO hostname + // and that the server lease has NO hostname lease_server = checkLease(lease_client); ASSERT_TRUE(lease_server); EXPECT_EQ("", lease_server->hostname_); // Now redo the client with yet another DUID and verify that - // we get a dynamic address. + // we get a dynamic address. client.clearConfig(); client.modifyDUID(); client.useNA(); @@ -137,10 +149,110 @@ TEST_F(HostTest, basicSARRs) { EXPECT_EQ("2001:db8:1:1::", lease_client.addr_.toText()); // Check that the server recorded the lease. - // and that the server lease has NO hostname + // and that the server lease has NO hostname lease_server = checkLease(lease_client); ASSERT_TRUE(lease_server); EXPECT_EQ("", lease_server->hostname_); } +// Test basic SARR and renew situation with a client that matches a host +// reservation +TEST_F(HostTest, sarrAndRenew) { + Dhcp6Client client; + + configure(CONFIGS[0], *client.getServer()); + + // Configure client to request IA_NA. + client.useNA(); + + const Subnet6Collection* subnets = CfgMgr::instance().getCurrentCfg()-> + getCfgSubnets6()->getAll(); + ASSERT_EQ(1, subnets->size()); + + // Configure client to request IA_NA and aAppend IA_NA option + // to the client's message. + client.setDUID("01:02:03:04"); + client.useNA(); + ASSERT_NO_THROW(client.useHint(100, 200, 64, "2001:db8:1:1::dead:beef")); + + // Perform 4-way exchange. + ASSERT_NO_THROW(client.doSARR()); + + // Now play with time + client.fastFwdTime(1000); + + // Verify that the client we got the reserved address + ASSERT_EQ(1, client.getLeaseNum()); + Lease6 lease_client = client.getLease(0); + EXPECT_EQ("2001:db8:1:1::babe", lease_client.addr_.toText()); + + // Send Renew message to the server. + ASSERT_NO_THROW(client.doRenew()); + + // Verify that we got an extended lease back + ASSERT_EQ(1, client.getLeaseNum()); + Lease6 lease_client2 = client.getLease(0); + EXPECT_EQ("2001:db8:1:1::babe", lease_client2.addr_.toText()); + + // The client's lease should have been extended. The client will + // update the cltt to current time when the lease gets extended. + ASSERT_GE(lease_client2.cltt_ - lease_client.cltt_, 1000); + + // Make sure, that the client's lease matches the lease held by the + // server and that we have the reserved host name. + Lease6Ptr lease_server2 = checkLease(lease_client2); + EXPECT_TRUE(lease_server2); + EXPECT_EQ("alice", lease_server2->hostname_); +} + +// Test basic SARR and rebind situation with a client that matches a host +// reservation. +TEST_F(HostTest, sarrAndRebind) { + Dhcp6Client client; + + configure(CONFIGS[0], *client.getServer()); + + // Configure client to request IA_NA. + client.useNA(); + + const Subnet6Collection* subnets = CfgMgr::instance().getCurrentCfg()-> + getCfgSubnets6()->getAll(); + ASSERT_EQ(1, subnets->size()); + + // Configure client to request IA_NA and aAppend IA_NA option + // to the client's message. + client.setDUID("01:02:03:04"); + client.useNA(); + ASSERT_NO_THROW(client.useHint(100, 200, 64, "2001:db8:1:1::dead:beef")); + + // Perform 4-way exchange. + ASSERT_NO_THROW(client.doSARR()); + + // Now play with time + client.fastFwdTime(1000); + + // Verify that the client we got the reserved address + ASSERT_EQ(1, client.getLeaseNum()); + Lease6 lease_client = client.getLease(0); + EXPECT_EQ("2001:db8:1:1::babe", lease_client.addr_.toText()); + + // Send Rebind message to the server. + ASSERT_NO_THROW(client.doRebind()); + + // Verify that we got an extended lease back + ASSERT_EQ(1, client.getLeaseNum()); + Lease6 lease_client2 = client.getLease(0); + EXPECT_EQ("2001:db8:1:1::babe", lease_client2.addr_.toText()); + + // The client's lease should have been extended. The client will + // update the cltt to current time when the lease gets extended. + ASSERT_GE(lease_client2.cltt_ - lease_client.cltt_, 1000); + + // Make sure, that the client's lease matches the lease held by the + // server and that we have the reserved host name. + Lease6Ptr lease_server2 = checkLease(lease_client2); + EXPECT_TRUE(lease_server2); + EXPECT_EQ("alice", lease_server2->hostname_); +} + } // end of anonymous namespace