From: JINMEI Tatuya Date: Fri, 19 Oct 2012 21:46:21 +0000 (-0700) Subject: [2211] added reconfigure() for DataSrcClientsMgr X-Git-Tag: trac2402_base~3^2~21 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=eb90dff94fbb2df0632f51982fc2c512af6e9c65;p=thirdparty%2Fkea.git [2211] added reconfigure() for DataSrcClientsMgr --- diff --git a/src/bin/auth/datasrc_clients_mgr.h b/src/bin/auth/datasrc_clients_mgr.h index 8fa7d344f1..c81b50e09a 100644 --- a/src/bin/auth/datasrc_clients_mgr.h +++ b/src/bin/auth/datasrc_clients_mgr.h @@ -142,6 +142,24 @@ public: cleanup(); // see below } + /// \brief Handle new full configuration for data source clients. + /// + /// This method simply passes the new configuration to the builder + /// and immediately returns. This method is basically exception free + /// as long as the caller a non NULL value for \c config_arg; it doesn't + /// validate the argument further. + /// + /// \brief isc::InvalidParameter config_arg is NULL. + /// \brief std::bad_alloc + /// + /// \param config_arg The new data source configuration. Must not be NULL. + void reconfigure(data::ConstElementPtr config_arg) { + if (!config_arg) { + isc_throw(InvalidParameter, "Invalid null config argument"); + } + sendCommand(datasrc_clientmgr_internal::RECONFIGURE, config_arg); + } + private: // This is expected to be called at the end of the destructor. It // actually does nothing, but provides a customization point for diff --git a/src/bin/auth/tests/datasrc_clients_mgr_unittest.cc b/src/bin/auth/tests/datasrc_clients_mgr_unittest.cc index 5ad76b83b4..cc4d99d578 100644 --- a/src/bin/auth/tests/datasrc_clients_mgr_unittest.cc +++ b/src/bin/auth/tests/datasrc_clients_mgr_unittest.cc @@ -12,6 +12,8 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. +#include + #include #include @@ -21,6 +23,7 @@ #include +using namespace isc::data; using namespace isc::auth; using namespace isc::auth::datasrc_clientmgr_internal; @@ -41,6 +44,30 @@ shutdownCheck() { EXPECT_TRUE(FakeDataSrcClientsBuilder::thread_waited); } +// Commonly used patter of checking member variables shared between the +// manager and builder. +void +checkSharedMembers(size_t expected_queue_lock_count, + size_t expected_queue_unlock_count, + size_t expected_map_lock_count, + size_t expected_map_unlock_count, + size_t expected_cond_signal_count, + size_t expected_command_queue_size) +{ + EXPECT_EQ(expected_queue_lock_count, + FakeDataSrcClientsBuilder::queue_mutex->lock_count); + EXPECT_EQ(expected_queue_unlock_count, + FakeDataSrcClientsBuilder::queue_mutex->unlock_count); + EXPECT_EQ(expected_map_lock_count, + FakeDataSrcClientsBuilder::map_mutex->lock_count); + EXPECT_EQ(expected_map_unlock_count, + FakeDataSrcClientsBuilder::map_mutex->unlock_count); + EXPECT_EQ(expected_cond_signal_count, + FakeDataSrcClientsBuilder::cond->signal_count); + EXPECT_EQ(expected_command_queue_size, + FakeDataSrcClientsBuilder::command_queue->size()); +} + TEST(DataSrcClientsMgrTest, start) { // When we create a manager, builder's run() method should be called. FakeDataSrcClientsBuilder::started = false; @@ -77,6 +104,44 @@ TEST(DataSrcClientsMgrTest, shutdownWithException) { }); } +TEST(DataSrcClientsMgrTest, reconfigure) { + TestDataSrcClientsMgr mgr; + + // Check pre-command condition + checkSharedMembers(0, 0, 0, 0, 0, 0); + + // A valid reconfigure argument + ConstElementPtr reconfigure_arg = Element::fromJSON( + "{" "\"IN\": [{\"type\": \"MasterFiles\", \"params\": {}," + " \"cache-enable\": true}]}"); + + // On reconfigure(), it just send the RECONFIGURE command to the builder + // thread with the given argument intact. + mgr.reconfigure(reconfigure_arg); + + // The manager should have acquired the queue lock, send RECONFIGURE + // command with the arg, wake up the builder thread by signal. It doesn't + // touch or refer to the map, so it shouldn't acquire the map lock. + checkSharedMembers(1, 1, 0, 0, 1, 1); + const Command& cmd1 = FakeDataSrcClientsBuilder::command_queue->front(); + EXPECT_EQ(RECONFIGURE, cmd1.first); + EXPECT_EQ(reconfigure_arg, cmd1.second); + + // Non-null, but semantically invalid argument. The manager doesn't do + // this check, so it should result in the same effect. + FakeDataSrcClientsBuilder::command_queue->clear(); + reconfigure_arg = isc::data::Element::create("{ \"foo\": \"bar\" }"); + mgr.reconfigure(reconfigure_arg); + checkSharedMembers(2, 2, 0, 0, 2, 1); + const Command& cmd2 = FakeDataSrcClientsBuilder::command_queue->front(); + EXPECT_EQ(RECONFIGURE, cmd2.first); + EXPECT_EQ(reconfigure_arg, cmd2.second); + + // Passing NULL argument is immediately rejected + EXPECT_THROW(mgr.reconfigure(ConstElementPtr()), isc::InvalidParameter); + checkSharedMembers(2, 2, 0, 0, 2, 1); // no state change +} + TEST(DataSrcClientsMgrTest, realThread) { // Using the non-test definition with a real thread. Just checking // no disruption happens.