From: Francis Dupont Date: Sat, 20 Jul 2019 15:16:03 +0000 (+0200) Subject: [732-set-with-incorrect-tag-new-exception] Code done - new unit test to check message... X-Git-Tag: Kea-1.6.1~10^2~107^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6a2d3f9202f8428eacc0303f94b123ab91a8a75a;p=thirdparty%2Fkea.git [732-set-with-incorrect-tag-new-exception] Code done - new unit test to check message to do --- diff --git a/src/hooks/dhcp/mysql_cb/mysql_cb_impl.cc b/src/hooks/dhcp/mysql_cb/mysql_cb_impl.cc index 1453223220..d2ec66a266 100644 --- a/src/hooks/dhcp/mysql_cb/mysql_cb_impl.cc +++ b/src/hooks/dhcp/mysql_cb/mysql_cb_impl.cc @@ -906,7 +906,14 @@ MySqlConfigBackendImpl::attachElementToServers(const int index, MySqlBindingCollection in_server_bindings = { first_binding, in_bindings }; for (auto tag : server_selector.getTags()) { in_server_bindings.push_back(MySqlBinding::createString(tag.get())); - conn_.insertQuery(index, in_server_bindings); + // Handles the case where the server does not exists. + try { + conn_.insertQuery(index, in_server_bindings); + } catch (const NullKeyError&) { + // The message should give the tag value. + isc_throw(NullKeyError, + "server '" << tag.get() << "' does not exist"); + } in_server_bindings.pop_back(); } } diff --git a/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc b/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc index a0a93937d2..81b089389f 100644 --- a/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc +++ b/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc @@ -765,7 +765,7 @@ TEST_F(MySqlConfigBackendDHCPv4Test, globalParameters4WithServerTags) { // This should fail because the server must be inserted first. EXPECT_THROW(cbptr_->createUpdateGlobalParameter4(ServerSelector::ONE("server1"), global_parameter1), - DbOperationError); + NullKeyError); // Create two servers. EXPECT_NO_THROW(cbptr_->createUpdateServer4(test_servers_[1])); @@ -1102,7 +1102,7 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getSubnet4) { // An attempt to add a subnet to a non-existing server (server1) should fail. EXPECT_THROW(cbptr_->createUpdateSubnet4(ServerSelector::MULTIPLE({ "server1", "server2" }), subnet2), - DbOperationError); + NullKeyError); // The subnet shouldn't have been added, even though one of the servers exists. Subnet4Ptr returned_subnet; @@ -2128,7 +2128,7 @@ TEST_F(MySqlConfigBackendDHCPv4Test, createUpdateSharedNetwork4) { // An attempto insert the shared network for non-existing server should fail. EXPECT_THROW(cbptr_->createUpdateSharedNetwork4(ServerSelector::ONE("server1"), shared_network), - DbOperationError); + NullKeyError); // Insert the server1 into the database. EXPECT_NO_THROW(cbptr_->createUpdateServer4(test_servers_[0])); @@ -2880,7 +2880,7 @@ TEST_F(MySqlConfigBackendDHCPv4Test, optionDefs4WithServerTags) { // fail. EXPECT_THROW(cbptr_->createUpdateOptionDef4(ServerSelector::ONE("server1"), option1), - DbOperationError); + NullKeyError); // Create two servers. EXPECT_NO_THROW(cbptr_->createUpdateServer4(test_servers_[1])); @@ -3272,7 +3272,7 @@ TEST_F(MySqlConfigBackendDHCPv4Test, globalOptions4WithServerTags) { EXPECT_THROW(cbptr_->createUpdateOption4(ServerSelector::ONE("server1"), opt_boot_file_name1), - DbOperationError); + NullKeyError); // Create two servers. EXPECT_NO_THROW(cbptr_->createUpdateServer4(test_servers_[1])); diff --git a/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp6_unittest.cc b/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp6_unittest.cc index 2fe8317be7..3ae977a78d 100644 --- a/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp6_unittest.cc +++ b/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp6_unittest.cc @@ -796,6 +796,12 @@ TEST_F(MySqlConfigBackendDHCPv6Test, globalParameters6WithServerTags) { StampedValuePtr global_parameter2 = StampedValue::create("global", "value2"); StampedValuePtr global_parameter3 = StampedValue::create("global", "value3"); + // Try to insert one of them and associate with non-existing server. + // This should fail because the server must be inserted first. + EXPECT_THROW(cbptr_->createUpdateGlobalParameter6(ServerSelector::ONE("server1"), + global_parameter1), + NullKeyError); + // Create two servers. EXPECT_NO_THROW(cbptr_->createUpdateServer6(test_servers_[1])); { @@ -1131,7 +1137,7 @@ TEST_F(MySqlConfigBackendDHCPv6Test, getSubnet6) { // An attempt to add a subnet to a non-existing server (server1) should fail. EXPECT_THROW(cbptr_->createUpdateSubnet6(ServerSelector::MULTIPLE({ "server1", "server2" }), subnet2), - DbOperationError); + NullKeyError); // The subnet shouldn't have been added, even though one of the servers exists. Subnet6Ptr returned_subnet; @@ -2146,7 +2152,7 @@ TEST_F(MySqlConfigBackendDHCPv6Test, createUpdateSharedNetwork6) { // An attempto insert the shared network for non-existing server should fail. EXPECT_THROW(cbptr_->createUpdateSharedNetwork6(ServerSelector::ONE("server1"), shared_network), - DbOperationError); + NullKeyError); // Insert the server1 into the database. EXPECT_NO_THROW(cbptr_->createUpdateServer6(test_servers_[0])); @@ -2900,7 +2906,7 @@ TEST_F(MySqlConfigBackendDHCPv6Test, optionDefs6WithServerTags) { // fail. EXPECT_THROW(cbptr_->createUpdateOptionDef6(ServerSelector::ONE("server1"), option1), - DbOperationError); + NullKeyError); // Create two servers. EXPECT_NO_THROW(cbptr_->createUpdateServer6(test_servers_[1])); @@ -3296,7 +3302,7 @@ TEST_F(MySqlConfigBackendDHCPv6Test, globalOptions6WithServerTags) { EXPECT_THROW(cbptr_->createUpdateOption6(ServerSelector::ONE("server1"), opt_timezone1), - DbOperationError); + NullKeyError); // Create two servers. EXPECT_NO_THROW(cbptr_->createUpdateServer6(test_servers_[1])); diff --git a/src/lib/database/db_exceptions.h b/src/lib/database/db_exceptions.h index 21dd8fa5a6..1dd1c164f8 100644 --- a/src/lib/database/db_exceptions.h +++ b/src/lib/database/db_exceptions.h @@ -1,4 +1,4 @@ -// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -45,6 +45,13 @@ public: isc::Exception(file, line, what) {} }; +/// @brief Key is NULL but was specified NOT NULL +class NullKeyError : public Exception { +public: + NullKeyError(const char* file, size_t line, const char* what) : + isc::Exception(file, line, what) {} +}; + /// @brief Attempt to modify data in read-only database. class ReadOnlyDb : public Exception { public: diff --git a/src/lib/mysql/mysql_connection.h b/src/lib/mysql/mysql_connection.h index 714af49bb2..750bd59549 100644 --- a/src/lib/mysql/mysql_connection.h +++ b/src/lib/mysql/mysql_connection.h @@ -443,6 +443,10 @@ public: if (mysql_errno(mysql_) == ER_DUP_ENTRY) { isc_throw(DuplicateEntry, "Database duplicate entry error"); } + // Failure: check for the special case of WHERE returning NULL. + if (mysql_errno(mysql_) == ER_BAD_NULL_ERROR) { + isc_throw(NullKeyError, "Database bad NULL error"); + } checkError(status, index, "unable to execute"); } }