// reasons, see memset() above
// dhcp4_client_classes : VARCHAR(255) NULL
- // TODO this should probably be converted in some way... Don't know how yet,
- // also size method might be wrong
bind_[7].buffer_type = MYSQL_TYPE_STRING;
- //bind_[7].buffer = reinterpret_cast<char*>(host_->getClientClasses4());
- bind_[7].buffer_length = sizeof(host_->getClientClasses4());
- // bind_[7].is_null = &MLM_FALSE; // commented out for performance
- // reasons, see memset() above
+ string classes4_txt = classesToString(host_->getClientClasses4());
+ strncpy(dhcp4_client_classes_, classes4_txt.c_str(), CLIENT_CLASSES_MAX_LEN - 1);
+ bind_[7].buffer = dhcp4_client_classes_;
+ bind_[7].buffer_length = classes4_txt.length();
// dhcp6_client_classes : VARCHAR(255) NULL
bind_[8].buffer_type = MYSQL_TYPE_STRING;
- //bind_[8].buffer = reinterpret_cast<char*>(host_->getClientClasses6());
+ string classes6_txt = classesToString(host->getClientClasses6());
+ strncpy(dhcp6_client_classes_, classes6_txt.c_str(), CLIENT_CLASSES_MAX_LEN - 1);
+ bind_[8].buffer = dhcp6_client_classes_;
+ bind_[8].buffer_length = classes6_txt.length();
bind_[8].buffer_length = sizeof(host_->getClientClasses6());
- // bind_[8].is_null = &MLM_FALSE; // commented out for performance
- // reasons, see memset() above
-
} catch (const std::exception& ex) {
isc_throw(DbOperationError,
return (getColumnsInError(error_, columns_, HOST_COLUMNS));
}
+ std::string classesToString(const ClientClasses& classes) {
+ string txt;
+ bool first = true;
+ for (ClientClasses::const_iterator it = classes.begin();
+ it != classes.end(); ++it) {
+ if (!first) {
+ txt += ",";
+ }
+ txt += (*it);
+
+ first = false;
+ }
+
+ return (txt);
+ }
+
private:
uint32_t host_id_; /// Host unique identifier
std::vector<uint8_t> dhcp_identifier_; /// HW address (0) / DUID (1)
void
MySqlHostDataSource::addHost(StatementIndex stindex,
- std::vector<MYSQL_BIND>& bind) {
+ std::vector<MYSQL_BIND>& bind) {
// Bind the parameters to the statement
int status = mysql_stmt_bind_param(conn_.statements_[stindex],
GenericHostDataSourceTest::~GenericHostDataSourceTest() {
}
+std::string
+GenericHostDataSourceTest::generateHWAddr() {
+ /// @todo: Make this code return different hwaddress every time.
+ return ("01:02:03:04:05:06");
+}
+
+std::string
+GenericHostDataSourceTest::generateDuid() {
+ /// @todo: Make this code return different duid every time.
+ return ("010203040506abcd");
+}
+
+HostPtr GenericHostDataSourceTest::initializeHost4(std::string address,
+ bool hwaddr) {
+ string ident;
+ string ident_type;
+
+ if (hwaddr) {
+ ident = generateHWAddr();
+ ident_type = "hw-address";
+ } else {
+ ident = generateDuid();
+ ident_type = "duid";
+ }
+
+ // Let's create ever increasing subnet-ids. Let's keep those different,
+ // so subnet4 != subnet6. Useful for catching cases if the code confuses
+ // subnet4 with subnet6.
+ static SubnetID subnet4 = 0;
+ static SubnetID subnet6 = 100;
+ subnet4++;
+ subnet6++;
+
+ IOAddress addr(address);
+ HostPtr host(new Host(ident, ident_type, subnet4, subnet6, addr));
+
+ return (host);
+}
+
+HostPtr GenericHostDataSourceTest::initializeHost6(std::string address,
+ bool hwaddr, bool prefix) {
+ string ident;
+ string ident_type;
+
+ if (hwaddr) {
+ ident = generateHWAddr();
+ ident_type = "hw-address";
+ } else {
+ ident = generateDuid();
+ ident_type = "duid";
+ }
+
+ // Let's create ever increasing subnet-ids. Let's keep those different,
+ // so subnet4 != subnet6. Useful for catching cases if the code confuses
+ // subnet4 with subnet6.
+ static SubnetID subnet4 = 0;
+ static SubnetID subnet6 = 100;
+ subnet4++;
+ subnet6++;
+ HostPtr host(new Host(ident, ident_type, subnet4, subnet6, IOAddress("0.0.0.0")));
+ if (!prefix) {
+ // Create IPv6 reservation (for an address)
+ IPv6Resrv resv(IPv6Resrv::TYPE_NA, IOAddress(address), 128);
+ host->addReservation(resv);
+ } else {
+ // Create IPv6 reservation for a /64 prefix
+ IPv6Resrv resv(IPv6Resrv::TYPE_PD, IOAddress(address), 64);
+ host->addReservation(resv);
+ }
+ return (host);
+}
+
+void GenericHostDataSourceTest::compareHosts(const ConstHostPtr& host1,
+ const ConstHostPtr& host2) {
+ ASSERT_TRUE(host1);
+ ASSERT_TRUE(host2);
+
+ // Compare if both have or have not HWaddress set.
+ ASSERT_EQ(host1->getHWAddress(), host2->getHWAddress());
+ if (host1->getHWAddress()) {
+ // Compare the actual address if they match.
+ EXPECT_EQ(*host1->getHWAddress(), *host2->getHWAddress());
+ }
+
+ /// @todo: Compare other fields
+}
+
+void GenericHostDataSourceTest::testBasic4() {
+ // Make sure we have the pointer to the host data source.
+ ASSERT_TRUE(hdsptr_);
+
+ // Create a host reservation.
+ HostPtr host = initializeHost4("192.0.2.1", true);
+ ASSERT_TRUE(host); // Make sure the host is generate properly.
+ SubnetID subnet = host->getIPv4SubnetID();
+
+ // Try to add it to the host data source.
+ ASSERT_NO_THROW(hdsptr_->add(host));
+
+ // And then retrive it.
+ ConstHostPtr from_hds = hdsptr_->get4(subnet, IOAddress("192.0.2.1"));
+
+ // Make sure we got something back.
+ ASSERT_TRUE(from_hds);
+
+ // Finally, let's check if what we got makes any sense.
+ compareHosts(host, from_hds);
+}
}; // namespace test
}; // namespace dhcp
/// @brief Virtual destructor.
virtual ~GenericHostDataSourceTest();
+ /// @brief Creates a host reservation for specified IPv4 address.
+ ///
+ /// @param address IPv4 address to be set
+ /// @param hwaddr type of identifier (true = hwaddr, false = client-id)
+ ///
+ /// @return generated Host object
+ HostPtr initializeHost4(std::string address, bool hwaddr);
+
+ /// @brief Creates a host reservation for specified IPv4 address.
+ ///
+ /// @param address IPv6 address to be reserved
+ /// @param hwaddr type of identifier (true = hwaddr, false = client-id)
+ /// @param prefix reservation type (true = prefix, false = address)
+ ///
+ /// @return generated Host object
+ HostPtr initializeHost6(std::string address, bool hwaddr, bool prefix);
+
+ /// @brief Generates a hardware address in text version.
+ ///
+ /// @return HW address in textual form acceptable by Host constructor
+ std::string generateHWAddr();
+
+ /// @brief Generates a hardware address in text version.
+ /// @return DUID in textual form acceptable by Host constructor
+ std::string generateDuid();
+
+ /// @brief Compares two hosts
+ ///
+ /// This method uses gtest macros to signal errors.
+ ///
+ /// @param host1 first host to compare
+ /// @param host2 second host to compare
+ void compareHosts(const ConstHostPtr& host1, const ConstHostPtr& host2);
+
/// @brief Pointer to the host data source
BaseHostDataSource* hdsptr_;
+
+ /// @brief Test that checks that simple host with IPv4 reservation
+ /// can be inserted and later retrieved.
+ ///
+ /// Uses gtest macros to report failures.
+ void testBasic4();
};
}; // namespace test
// Test verifies if a host reservation can be added and later retrieved by IPv4
// address.
TEST_F(MySqlHostDataSourceTest, basic4) {
- /// @todo: basic - add host reserveration, retrieve it by address and
- /// confirm that all fields have correct value.
+ testBasic4();
}
// Test verifies if a host reservation can be added and later retrieved by
"DROP TABLE hosts",
"DROP TABLE dhcp4_options",
"DROP TABLE dhcp6_options",
+
+ "DROP TRIGGER host_BDEL",
NULL
};