Browse Source

Merge branch 'trac2947_2'

Mukund Sivaraman 12 years ago
parent
commit
9a3ddf1e2b

+ 0 - 9
src/bin/cfgmgr/plugins/tests/datasrc_test.py

@@ -96,15 +96,6 @@ class DatasrcTest(unittest.TestCase):
             "params": {}
             "params": {}
         }]})
         }]})
 
 
-    def test_dstype_bad(self):
-        """
-        The configuration is correct by the spec, but it would be rejected
-        by the client list. Check we reject it.
-        """
-        self.reject({"IN": [{
-            "type": "No such type"
-        }]})
-
     def test_invalid_mem_params(self):
     def test_invalid_mem_params(self):
         """
         """
         The client list skips in-memory sources. So we check it locally that
         The client list skips in-memory sources. So we check it locally that

+ 14 - 6
src/lib/datasrc/client_list.cc

@@ -110,12 +110,20 @@ ConfigurableClientList::configure(const ConstElementPtr& config,
                           << datasrc_name);
                           << datasrc_name);
             }
             }
 
 
-            // Create a client for the underling data source via factory.
-            // If it's our internal type of data source, this is essentially
-            // no-op.  In the latter case, it's of no use unless cache is
-            // allowed; we simply skip building it in that case.
-            const DataSourcePair dsrc_pair = getDataSourceClient(type,
-                                                                 param_conf);
+            DataSourcePair dsrc_pair;
+            try {
+                // Create a client for the underling data source via
+                // factory.  If it's our internal type of data source,
+                // this is essentially no-op.  In the latter case, it's
+                // of no use unless cache is allowed; we simply skip
+                // building it in that case.
+                dsrc_pair = getDataSourceClient(type, param_conf);
+            } catch (const DataSourceLibraryError& ex) {
+                LOG_ERROR(logger, DATASRC_LIBRARY_ERROR).
+                    arg(datasrc_name).arg(rrclass_).arg(ex.what());
+                continue;
+            }
+
             if (!allow_cache && !dsrc_pair.first) {
             if (!allow_cache && !dsrc_pair.first) {
                 LOG_WARN(logger, DATASRC_LIST_NOT_CACHED).
                 LOG_WARN(logger, DATASRC_LIST_NOT_CACHED).
                     arg(datasrc_name).arg(rrclass_);
                     arg(datasrc_name).arg(rrclass_);

+ 5 - 0
src/lib/datasrc/datasrc_messages.mes

@@ -370,6 +370,11 @@ Therefore, the entire data source will not be available for this process. If
 this is a problem, you should configure the zones of that data source to some
 this is a problem, you should configure the zones of that data source to some
 database backend (sqlite3, for example) and use it from there.
 database backend (sqlite3, for example) and use it from there.
 
 
+% DATASRC_LIBRARY_ERROR failure loading %1 datasource library for class %2: %3
+There was a problem loading the dynamic library for a data source. This
+backend is hence not available, and any data sources that use this
+backend will not be available.
+
 % DATASRC_LOAD_ZONE_ERROR Error loading zone %1/%2 on data source '%3': %4
 % DATASRC_LOAD_ZONE_ERROR Error loading zone %1/%2 on data source '%3': %4
 During data source configuration, an error was found in the zone data
 During data source configuration, an error was found in the zone data
 when it was being loaded in to memory on the shown data source.  This
 when it was being loaded in to memory on the shown data source.  This

+ 2 - 2
src/lib/datasrc/factory.cc

@@ -83,8 +83,8 @@ LibraryContainer::LibraryContainer(const std::string& name) {
     if (ds_lib_ == NULL) {
     if (ds_lib_ == NULL) {
         // This may cause the filename to appear twice in the actual
         // This may cause the filename to appear twice in the actual
         // error, but the output of dlerror is implementation-dependent
         // error, but the output of dlerror is implementation-dependent
-        isc_throw(DataSourceLibraryError, "dlopen failed for " << name << 
-                                          ": " << dlerror());
+        isc_throw(DataSourceLibraryOpenError,
+                  "dlopen failed for " << name << ": " << dlerror());
     }
     }
 }
 }
 
 

+ 12 - 3
src/lib/datasrc/factory.h

@@ -27,7 +27,7 @@ namespace isc {
 namespace datasrc {
 namespace datasrc {
 
 
 
 
-/// \brief Raised if there is an error loading the datasource implementation
+/// \brief Raised if there is an error in the datasource implementation
 ///        library
 ///        library
 class DataSourceLibraryError : public DataSourceError {
 class DataSourceLibraryError : public DataSourceError {
 public:
 public:
@@ -35,13 +35,22 @@ public:
         DataSourceError(file, line, what) {}
         DataSourceError(file, line, what) {}
 };
 };
 
 
+/// \brief Raised if there is an error opening the the datasource
+///        implementation library
+class DataSourceLibraryOpenError : public DataSourceLibraryError {
+public:
+    DataSourceLibraryOpenError(const char* file, size_t line,
+                               const char* what) :
+        DataSourceLibraryError(file, line, what) {}
+};
+
 /// \brief Raised if there is an error reading a symbol from the datasource
 /// \brief Raised if there is an error reading a symbol from the datasource
 ///        implementation library
 ///        implementation library
-class DataSourceLibrarySymbolError : public DataSourceError {
+class DataSourceLibrarySymbolError : public DataSourceLibraryError {
 public:
 public:
     DataSourceLibrarySymbolError(const char* file, size_t line,
     DataSourceLibrarySymbolError(const char* file, size_t line,
                                  const char* what) :
                                  const char* what) :
-        DataSourceError(file, line, what) {}
+        DataSourceLibraryError(file, line, what) {}
 };
 };
 
 
 typedef DataSourceClient* ds_creator(isc::data::ConstElementPtr config,
 typedef DataSourceClient* ds_creator(isc::data::ConstElementPtr config,

+ 34 - 0
src/lib/datasrc/tests/client_list_unittest.cc

@@ -16,6 +16,7 @@
 
 
 #include <datasrc/client_list.h>
 #include <datasrc/client_list.h>
 #include <datasrc/client.h>
 #include <datasrc/client.h>
+#include <datasrc/factory.h>
 #include <datasrc/cache_config.h>
 #include <datasrc/cache_config.h>
 #include <datasrc/zone_iterator.h>
 #include <datasrc/zone_iterator.h>
 #include <datasrc/exceptions.h>
 #include <datasrc/exceptions.h>
@@ -71,6 +72,10 @@ public:
         if (type == "error") {
         if (type == "error") {
             isc_throw(DataSourceError, "The error data source type");
             isc_throw(DataSourceError, "The error data source type");
         }
         }
+        if (type == "library_error") {
+            isc_throw(DataSourceLibraryError,
+                      "The library error data source type");
+        }
         if (type == "MasterFiles") {
         if (type == "MasterFiles") {
             return (DataSourcePair(0, DataSourceClientContainerPtr()));
             return (DataSourcePair(0, DataSourceClientContainerPtr()));
         }
         }
@@ -705,6 +710,35 @@ TEST_P(ListTest, dataSrcError) {
     checkDS(0, "test_type", "{}", false);
     checkDS(0, "test_type", "{}", false);
 }
 }
 
 
+// In case of library errors, the rest of the data sources should be
+// unaffected.
+TEST_P(ListTest, dataSrcLibraryError) {
+    EXPECT_EQ(0, list_->getDataSources().size());
+    const ConstElementPtr elem(Element::fromJSON("["
+        "{"
+        "   \"type\": \"type1\","
+        "   \"cache-enable\": false,"
+        "   \"params\": {}"
+        "},"
+        "{"
+        "   \"type\": \"library_error\","
+        "   \"cache-enable\": false,"
+        "   \"params\": {}"
+        "},"
+        "{"
+        "   \"type\": \"type2\","
+        "   \"cache-enable\": false,"
+        "   \"params\": {}"
+        "}]"
+    ));
+    list_->configure(elem, true);
+    EXPECT_EQ(2, list_->getDataSources().size());
+    checkDS(0, "type1", "{}", false);
+    checkDS(1, "type2", "{}", false);
+    // Check the exact configuration is preserved
+    EXPECT_EQ(elem, list_->getConfiguration());
+}
+
 // Check we can get the cache
 // Check we can get the cache
 TEST_P(ListTest, configureCacheEmpty) {
 TEST_P(ListTest, configureCacheEmpty) {
     const ConstElementPtr elem(Element::fromJSON("["
     const ConstElementPtr elem(Element::fromJSON("["

+ 0 - 3
src/lib/python/isc/datasrc/tests/clientlist_test.py

@@ -102,9 +102,6 @@ class ClientListTest(unittest.TestCase):
         self.assertRaises(isc.datasrc.Error, self.clist.configure,
         self.assertRaises(isc.datasrc.Error, self.clist.configure,
                           '"bad type"', True)
                           '"bad type"', True)
         self.assertRaises(isc.datasrc.Error, self.clist.configure, '''[{
         self.assertRaises(isc.datasrc.Error, self.clist.configure, '''[{
-            "type": "bad type"
-        }]''', True)
-        self.assertRaises(isc.datasrc.Error, self.clist.configure, '''[{
             bad JSON,
             bad JSON,
         }]''', True)
         }]''', True)
         self.assertRaises(TypeError, self.clist.configure, [], True)
         self.assertRaises(TypeError, self.clist.configure, [], True)

+ 6 - 0
tests/lettuce/configurations/example.org.inmem.config

@@ -22,6 +22,12 @@
                     "params": {
                     "params": {
                         "example.org": "data/example.org"
                         "example.org": "data/example.org"
                     }
                     }
+                },
+                {
+                    "type": "broken_libraries_should_be_skipped",
+                    "cache-enable": false,
+                    "params": {
+                    }
                 }
                 }
             ]
             ]
         }
         }

+ 1 - 0
tests/lettuce/features/queries.feature

@@ -53,6 +53,7 @@ Feature: Querying feature
         And wait for bind10 stderr message BIND10_STARTED_CC
         And wait for bind10 stderr message BIND10_STARTED_CC
         And wait for bind10 stderr message CMDCTL_STARTED
         And wait for bind10 stderr message CMDCTL_STARTED
         And wait for bind10 stderr message AUTH_SERVER_STARTED
         And wait for bind10 stderr message AUTH_SERVER_STARTED
+        And wait for bind10 stderr message DATASRC_LIBRARY_ERROR
         And wait for bind10 stderr message STATS_STARTING
         And wait for bind10 stderr message STATS_STARTING
 
 
         bind10 module Auth should be running
         bind10 module Auth should be running