BIND 10 master, updated. 4efd3d6cab93018b850da07a8f51433c248d615f Changelog

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Dec 22 08:18:00 UTC 2011


The branch, master has been updated
       via  4efd3d6cab93018b850da07a8f51433c248d615f (commit)
       via  0020456f8d118c9f3fd6fc585757c822b79a96f6 (commit)
       via  6969f47777586b17c909b5f75f4f79699bc8ce1d (commit)
       via  f59e0c5bab84c830f6922c5982c0ae61f028597e (commit)
       via  d907907c7dfaeca2ace318cb67d70c4445974b6f (commit)
       via  a1b7e0e81d17c607fdf1f3c4c9b3bc578b9269eb (commit)
       via  3e851b72d4869bd4e7ede881aac0470da39aef3a (commit)
       via  d2f1ad06d2beb7ab5f51357bf191a9aaf56ddb2f (commit)
       via  137405d030cfdcdec5b1a247e42dd8c4ec83e538 (commit)
       via  321a37a11088881f57df5088571f9ac7c919daf7 (commit)
       via  0938b2fb80685e2b91fafcc3bf75dba718c72de0 (commit)
       via  855f42784d0e9e5f86a3dfb6988da3987cda2200 (commit)
      from  2858ffa9471778539dabf7cbf5204296d464351d (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 4efd3d6cab93018b850da07a8f51433c248d615f
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Thu Dec 22 09:16:03 2011 +0100

    Changelog

commit 0020456f8d118c9f3fd6fc585757c822b79a96f6
Merge: 2858ffa9471778539dabf7cbf5204296d464351d 6969f47777586b17c909b5f75f4f79699bc8ce1d
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Thu Dec 22 09:10:32 2011 +0100

    Merge branch #1484

commit 6969f47777586b17c909b5f75f4f79699bc8ce1d
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Thu Dec 22 09:10:12 2011 +0100

    [1484] Remove unreachable code

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                        |    7 ++
 src/bin/xfrin/tests/xfrin_test.py                |    2 +-
 src/bin/xfrin/xfrin.py.in                        |    3 +-
 src/bin/xfrout/tests/xfrout_test.py.in           |    2 +-
 src/bin/xfrout/xfrout.py.in                      |    3 +-
 src/lib/datasrc/zone.h                           |    4 -
 src/lib/python/isc/datasrc/finder_inc.cc         |   32 ++++--
 src/lib/python/isc/datasrc/finder_python.cc      |   82 ++++++++++++---
 src/lib/python/isc/datasrc/tests/datasrc_test.py |  121 ++++++++++++++--------
 src/lib/python/isc/datasrc/updater_python.cc     |   34 ++++--
 10 files changed, 201 insertions(+), 89 deletions(-)

-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index 2dbb5e4..ca35397 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+359.	[func]*		vorner
+	The target parameter of ZoneFinder::find is no longer present, as the
+	interface was awkward. To get all the RRsets of a single domain, use
+	the new findAll method (the same applies to python version, the method
+	is named find_all).
+	(Trac #1483,#1484, git 0020456f8d118c9f3fd6fc585757c822b79a96f6)
+
 349.	[bug]		dvv
 	resolver: If an upstream server responds with FORMERR to an EDNS query,
 	try querying it without EDNS.
diff --git a/src/bin/xfrin/tests/xfrin_test.py b/src/bin/xfrin/tests/xfrin_test.py
index eb2c747..497ecd1 100644
--- a/src/bin/xfrin/tests/xfrin_test.py
+++ b/src/bin/xfrin/tests/xfrin_test.py
@@ -158,7 +158,7 @@ class MockDataSourceClient():
             return (DataSourceClient.PARTIALMATCH, self)
         raise ValueError('Unexpected input to mock client: bug in test case?')
 
-    def find(self, name, rrtype, target=None, options=ZoneFinder.FIND_DEFAULT):
+    def find(self, name, rrtype, options=ZoneFinder.FIND_DEFAULT):
         '''Mock ZoneFinder.find().
 
         It returns the predefined SOA RRset to queries for SOA of the common
diff --git a/src/bin/xfrin/xfrin.py.in b/src/bin/xfrin/xfrin.py.in
index 1167bef..7b70b52 100755
--- a/src/bin/xfrin/xfrin.py.in
+++ b/src/bin/xfrin/xfrin.py.in
@@ -583,8 +583,7 @@ class XfrinConnection(asyncore.dispatcher):
             result, finder = self._datasrc_client.find_zone(self._zone_name)
         if result != DataSourceClient.SUCCESS:
             return None
-        result, soa_rrset = finder.find(self._zone_name, RRType.SOA(),
-                                        None, ZoneFinder.FIND_DEFAULT)
+        result, soa_rrset = finder.find(self._zone_name, RRType.SOA())
         if result != ZoneFinder.SUCCESS:
             logger.info(XFRIN_ZONE_NO_SOA, self.zone_str())
             return None
diff --git a/src/bin/xfrout/tests/xfrout_test.py.in b/src/bin/xfrout/tests/xfrout_test.py.in
index ea4de27..2c7fab8 100644
--- a/src/bin/xfrout/tests/xfrout_test.py.in
+++ b/src/bin/xfrout/tests/xfrout_test.py.in
@@ -95,7 +95,7 @@ class MockDataSrcClient:
             return (isc.datasrc.DataSourceClient.NOTFOUND, None)
         return (isc.datasrc.DataSourceClient.SUCCESS, self)
 
-    def find(self, name, rrtype, target=None, options=ZoneFinder.FIND_DEFAULT):
+    def find(self, name, rrtype, options=ZoneFinder.FIND_DEFAULT):
         '''Mock ZoneFinder.find().
 
         (At the moment) this method only handles query for type SOA.
diff --git a/src/bin/xfrout/xfrout.py.in b/src/bin/xfrout/xfrout.py.in
index 691c7db..a59fc8a 100755
--- a/src/bin/xfrout/xfrout.py.in
+++ b/src/bin/xfrout/xfrout.py.in
@@ -336,8 +336,7 @@ class XfroutSession():
         result, finder = self._datasrc_client.find_zone(zone_name)
         if result != DataSourceClient.SUCCESS:
             return (Rcode.NOTAUTH(), None)
-        result, soa_rrset = finder.find(zone_name, RRType.SOA(), None,
-                                        ZoneFinder.FIND_DEFAULT)
+        result, soa_rrset = finder.find(zone_name, RRType.SOA())
         if result != ZoneFinder.SUCCESS:
             return (Rcode.SERVFAIL(), None)
         # Especially for database-based zones, a working zone may be in
diff --git a/src/lib/datasrc/zone.h b/src/lib/datasrc/zone.h
index 77e1148..d8734d3 100644
--- a/src/lib/datasrc/zone.h
+++ b/src/lib/datasrc/zone.h
@@ -238,10 +238,6 @@ public:
     /// - If the search name matches a delegation point of DNAME, it returns
     ///   the code of \c DNAME and that DNAME RR.
     ///
-    /// \note This behavior is controversial as we discussed in
-    /// https://lists.isc.org/pipermail/bind10-dev/2011-January/001918.html
-    /// We should revisit the interface before we heavily rely on it.
-    ///
     /// The \c options parameter specifies customized behavior of the search.
     /// Their semantics is as follows (they are or bit-field):
     ///
diff --git a/src/lib/python/isc/datasrc/finder_inc.cc b/src/lib/python/isc/datasrc/finder_inc.cc
index 82c5fdc..22fabfa 100644
--- a/src/lib/python/isc/datasrc/finder_inc.cc
+++ b/src/lib/python/isc/datasrc/finder_inc.cc
@@ -46,9 +46,8 @@ Return the RR class of the zone.\n\
 // - Return type: use tuple instead of the dedicated FindResult type
 // - NULL->None
 // - exceptions
-// - description of the 'target' parameter (must be None for now)
 const char* const ZoneFinder_find_doc = "\
-find(name, type, target=None, options=FIND_DEFAULT) -> (integer, RRset)\n\
+find(name, type, options=FIND_DEFAULT) -> (integer, RRset)\n\
 \n\
 Search the zone for a given pair of domain name and RR type.\n\
 \n\
@@ -72,14 +71,6 @@ answer for the search key. Specifically,\n\
   and the code of SUCCESS will be returned.\n\
 - If the search name matches a delegation point of DNAME, it returns\n\
   the code of DNAME and that DNAME RR.\n\
-- If the target isn't None, all RRsets under the domain are inserted\n\
-  there and SUCCESS (or NXDOMAIN, in case of empty domain) is returned\n\
-  instead of normall processing. This is intended to handle ANY query.\n\
-  (Note: the Python version doesn't support this feature yet)\n\
-\n\
-Note: This behavior is controversial as we discussed in\n\
-https://lists.isc.org/pipermail/bind10-dev/2011-January/001918.html We\n\
-should revisit the interface before we heavily rely on it.\n\
 \n\
 The options parameter specifies customized behavior of the search.\n\
 Their semantics is as follows (they are or bit-field):\n\
@@ -107,13 +98,32 @@ internal error in the datasource.\n\
 Parameters:\n\
   name       The domain name to be searched for.\n\
   type       The RR type to be searched for.\n\
-  target     Must be None.\n\
   options    The search options.\n\
 \n\
 Return Value(s): A tuple of a result code (integer) and an RRset object\n\
 enclosing the search result (see above).\n\
 ";
 
+const char* const ZoneFinder_find_all_doc = "\
+find_all(isc.dns.Name, options=FIND_DEFAULT) -> (integer, RRset) | (integer, [RRset])\
+\n\
+This acts mostly the same as the find method. The main difference is,\n\
+when the lookup is successful (eg. the first part of the result is either\n\
+SUCCESS or WILDCARD), the second part is list of all RRsets in the given name\n\
+instead of a single RRset as in case of find.\n\
+\n\
+This method raises an isc.datasrc.Error exception if there is an\n\
+internal error in the datasource.\n\
+\n\
+Parameters:\n\
+  name       The domain name to be searched for.\n\
+  options    The search options.\n\
+\n\
+Return Value(s): A tuple of a result code (integer) and an either RRset object,\n\
+for cases where the result is some kind of delegation, CNAME or similar, or list\n\
+of RRset objects, containing all the results.\n\
+";
+
 const char* const ZoneFinder_find_previous_name_doc = "\
 find_previous_name(isc.dns.Name) -> isc.dns.Name\n\
 \n\
diff --git a/src/lib/python/isc/datasrc/finder_python.cc b/src/lib/python/isc/datasrc/finder_python.cc
index 5aa9c3e..5df944f 100644
--- a/src/lib/python/isc/datasrc/finder_python.cc
+++ b/src/lib/python/isc/datasrc/finder_python.cc
@@ -59,17 +59,11 @@ PyObject* ZoneFinder_helper(ZoneFinder* finder, PyObject* args) {
     }
     PyObject* name;
     PyObject* rrtype;
-    PyObject* target = Py_None;
     unsigned int options_int = ZoneFinder::FIND_DEFAULT;
-    if (PyArg_ParseTuple(args, "O!O!|OI", &name_type, &name,
+    if (PyArg_ParseTuple(args, "O!O!|I", &name_type, &name,
                                          &rrtype_type, &rrtype,
-                                         &target, &options_int)) {
+                                         &options_int)) {
         try {
-            if (target != Py_None) {
-                PyErr_SetString(PyExc_TypeError,
-                                "find(): target must be None in this version");
-                return (NULL);
-            }
             ZoneFinder::FindOptions options =
                 static_cast<ZoneFinder::FindOptions>(options_int);
             const ZoneFinder::FindResult find_result(
@@ -97,7 +91,60 @@ PyObject* ZoneFinder_helper(ZoneFinder* finder, PyObject* args) {
     } else {
         return (NULL);
     }
-    return Py_BuildValue("I", 1);
+}
+
+PyObject* ZoneFinder_helper_all(ZoneFinder* finder, PyObject* args) {
+    if (finder == NULL) {
+        PyErr_SetString(getDataSourceException("Error"),
+                        "Internal error in find_all() wrapper; "
+                        "finder object NULL");
+        return (NULL);
+    }
+    PyObject* name;
+    const unsigned int options_int = ZoneFinder::FIND_DEFAULT;
+    if (PyArg_ParseTuple(args, "O!|I", &name_type, &name, &options_int)) {
+        try {
+            ZoneFinder::FindOptions options =
+                static_cast<ZoneFinder::FindOptions>(options_int);
+            std::vector<isc::dns::ConstRRsetPtr> target;
+            const ZoneFinder::FindResult find_result(
+                finder->findAll(PyName_ToName(name), target, options));
+            const ZoneFinder::Result r = find_result.code;
+            isc::dns::ConstRRsetPtr rrsp = find_result.rrset;
+            if (r == ZoneFinder::SUCCESS || r == ZoneFinder::WILDCARD) {
+                // Copy all the RRsets to the result list
+                PyObjectContainer list_container(PyList_New(target.size()));
+                for (size_t i(0); i < target.size(); ++i) {
+                    PyList_SET_ITEM(list_container.get(), i,
+                                    createRRsetObject(*target[i]));
+                }
+                // Construct the result with the list. The Py_BuildValue
+                // increases the refcount and the container decreases it
+                // later. This way, it feels safer in case the build function
+                // would fail.
+                return (Py_BuildValue("IO", r, list_container.get()));
+            } else {
+                if (rrsp) {
+                    // Use N instead of O so the refcount isn't increased twice
+                    return (Py_BuildValue("IN", r, createRRsetObject(*rrsp)));
+                } else {
+                    return (Py_BuildValue("IO", r, Py_None));
+                }
+            }
+        } catch (const DataSourceError& dse) {
+            PyErr_SetString(getDataSourceException("Error"), dse.what());
+            return (NULL);
+        } catch (const std::exception& exc) {
+            PyErr_SetString(getDataSourceException("Error"), exc.what());
+            return (NULL);
+        } catch (...) {
+            PyErr_SetString(getDataSourceException("Error"),
+                            "Unexpected exception");
+            return (NULL);
+        }
+    } else {
+        return (NULL);
+    }
 }
 
 } // end namespace internal
@@ -121,7 +168,7 @@ typedef CPPPyObjectContainer<s_ZoneFinder, ZoneFinder> ZoneFinderContainer;
 
 // General creation and destruction
 int
-ZoneFinder_init(s_ZoneFinder* self, PyObject* args) {
+ZoneFinder_init(PyObject*, PyObject*, PyObject*) {
     // can't be called directly
     PyErr_SetString(PyExc_TypeError,
                     "ZoneFinder cannot be constructed directly");
@@ -130,7 +177,8 @@ ZoneFinder_init(s_ZoneFinder* self, PyObject* args) {
 }
 
 void
-ZoneFinder_destroy(s_ZoneFinder* const self) {
+ZoneFinder_destroy(PyObject* po_self) {
+    s_ZoneFinder* self = static_cast<s_ZoneFinder*>(po_self);
     // cppobj is a shared ptr, but to make sure things are not destroyed in
     // the wrong order, we reset it here.
     self->cppobj.reset();
@@ -173,6 +221,13 @@ ZoneFinder_find(PyObject* po_self, PyObject* args) {
 }
 
 PyObject*
+ZoneFinder_find_all(PyObject* po_self, PyObject* args) {
+    s_ZoneFinder* const self = static_cast<s_ZoneFinder*>(po_self);
+    return (isc_datasrc_internal::ZoneFinder_helper_all(self->cppobj.get(),
+                                                        args));
+}
+
+PyObject*
 ZoneFinder_findPreviousName(PyObject* po_self, PyObject* args) {
     s_ZoneFinder* const self = static_cast<s_ZoneFinder*>(po_self);
     PyObject* name_obj;
@@ -208,6 +263,7 @@ PyMethodDef ZoneFinder_methods[] = {
        ZoneFinder_getOrigin_doc },
     { "get_class", ZoneFinder_getClass, METH_NOARGS, ZoneFinder_getClass_doc },
     { "find", ZoneFinder_find, METH_VARARGS, ZoneFinder_find_doc },
+    { "find_all", ZoneFinder_find_all, METH_VARARGS, ZoneFinder_find_all_doc },
     { "find_previous_name", ZoneFinder_findPreviousName, METH_VARARGS,
       ZoneFinder_find_previous_name_doc },
     { NULL, NULL, 0, NULL }
@@ -224,7 +280,7 @@ PyTypeObject zonefinder_type = {
     "datasrc.ZoneFinder",
     sizeof(s_ZoneFinder),               // tp_basicsize
     0,                                  // tp_itemsize
-    reinterpret_cast<destructor>(ZoneFinder_destroy),// tp_dealloc
+    ZoneFinder_destroy,                 // tp_dealloc
     NULL,                               // tp_print
     NULL,                               // tp_getattr
     NULL,                               // tp_setattr
@@ -255,7 +311,7 @@ PyTypeObject zonefinder_type = {
     NULL,                               // tp_descr_get
     NULL,                               // tp_descr_set
     0,                                  // tp_dictoffset
-    reinterpret_cast<initproc>(ZoneFinder_init),// tp_init
+    ZoneFinder_init,                    // tp_init
     NULL,                               // tp_alloc
     PyType_GenericNew,                  // tp_new
     NULL,                               // tp_free
diff --git a/src/lib/python/isc/datasrc/tests/datasrc_test.py b/src/lib/python/isc/datasrc/tests/datasrc_test.py
index 3e4a1d7..8b2a8c5 100644
--- a/src/lib/python/isc/datasrc/tests/datasrc_test.py
+++ b/src/lib/python/isc/datasrc/tests/datasrc_test.py
@@ -57,6 +57,61 @@ def create_soa(serial):
                         str(serial) + ' 3600 1800 2419200 7200'))
     return soa
 
+def test_findall_common(self, tested):
+    """
+    Common part of the find_all test. It tests a find_all method on the passed
+    object.
+    """
+    # Some "failure" responses
+    result, rrset = tested.find_all(isc.dns.Name("www.sql1.example.com"),
+                                    ZoneFinder.FIND_DEFAULT)
+    self.assertEqual(ZoneFinder.DELEGATION, result)
+    expected = RRset(Name('sql1.example.com.'), RRClass.IN(), RRType.NS(),
+                     RRTTL(3600))
+    expected.add_rdata(Rdata(RRType.NS(), RRClass.IN(),
+                             'dns01.example.com.'))
+    expected.add_rdata(Rdata(RRType.NS(), RRClass.IN(),
+                             'dns02.example.com.'))
+    expected.add_rdata(Rdata(RRType.NS(), RRClass.IN(),
+                             'dns03.example.com.'))
+    self.assertTrue(rrsets_equal(expected, rrset))
+
+    result, rrset = tested.find_all(isc.dns.Name("nxdomain.example.com"),
+                                     ZoneFinder.FIND_DEFAULT)
+    self.assertEqual(ZoneFinder.NXDOMAIN, result)
+    self.assertIsNone(None, rrset)
+
+    # A success. It should return the list now.
+    # This also tests we can ommit the options parameter
+    result, rrsets = tested.find_all(isc.dns.Name("mix.example.com."))
+    self.assertEqual(ZoneFinder.SUCCESS, result)
+    self.assertEqual(2, len(rrsets))
+    rrsets.sort(key=lambda rrset: rrset.get_type().to_text())
+    expected = [
+        RRset(Name('mix.example.com.'), RRClass.IN(), RRType.A(),
+              RRTTL(3600)),
+        RRset(Name('mix.example.com.'), RRClass.IN(), RRType.AAAA(),
+              RRTTL(3600))
+    ]
+    expected[0].add_rdata(Rdata(RRType.A(), RRClass.IN(), "192.0.2.1"))
+    expected[0].add_rdata(Rdata(RRType.A(), RRClass.IN(), "192.0.2.2"))
+    expected[1].add_rdata(Rdata(RRType.AAAA(), RRClass.IN(),
+                                "2001:db8::1"))
+    expected[1].add_rdata(Rdata(RRType.AAAA(), RRClass.IN(),
+                                "2001:db8::2"))
+    for (rrset, exp) in zip(rrsets, expected):
+        self.assertTrue(rrsets_equal(exp, rrset))
+
+    # Check the reference counts on them. The getrefcount returns one more,
+    # as for the reference in its own parameter - see its docs.
+
+    # Two - one for the variable, one for parameter
+    self.assertEqual(2, sys.getrefcount(rrsets))
+    for rrset in rrsets:
+        # 3 - one as the element of list, one for the rrset variable
+        # and one for the parameter.
+        self.assertEqual(3, sys.getrefcount(rrset))
+
 class DataSrcClient(unittest.TestCase):
 
     def test_(self):
@@ -269,6 +324,19 @@ class DataSrcClient(unittest.TestCase):
         self.assertNotEqual(ZoneFinder.WILDCARD_CNAME,
                             ZoneFinder.WILDCARD_NXRRSET)
 
+    def test_findall(self):
+        """
+        A test for the find_all method.
+        """
+        dsc = isc.datasrc.DataSourceClient("sqlite3", READ_ZONE_DB_CONFIG)
+        result, finder = dsc.find_zone(isc.dns.Name("example.com"))
+
+        self.assertEqual(finder.SUCCESS, result)
+        self.assertEqual(isc.dns.RRClass.IN(), finder.get_class())
+        self.assertEqual("example.com.", finder.get_origin().to_text())
+
+        test_findall_common(self, finder)
+
     def test_find(self):
         dsc = isc.datasrc.DataSourceClient("sqlite3", READ_ZONE_DB_CONFIG)
 
@@ -279,7 +347,6 @@ class DataSrcClient(unittest.TestCase):
 
         result, rrset = finder.find(isc.dns.Name("www.example.com"),
                                     isc.dns.RRType.A(),
-                                    None,
                                     finder.FIND_DEFAULT)
         self.assertEqual(finder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
@@ -292,20 +359,8 @@ class DataSrcClient(unittest.TestCase):
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
                          rrset.to_text())
 
-        result, rrset = finder.find(isc.dns.Name("www.example.com"),
-                                    isc.dns.RRType.A(), None)
-        self.assertEqual(finder.SUCCESS, result)
-        self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
-                         rrset.to_text())
-
-        # Invalid value for the "target"
-        self.assertRaises(TypeError, finder.find,
-                          isc.dns.Name("www.example.com"),
-                          isc.dns.RRType.A(), True)
-
         result, rrset = finder.find(isc.dns.Name("www.sql1.example.com"),
                                     isc.dns.RRType.A(),
-                                    None,
                                     finder.FIND_DEFAULT)
         self.assertEqual(finder.DELEGATION, result)
         self.assertEqual("sql1.example.com. 3600 IN NS dns01.example.com.\n" +
@@ -315,28 +370,24 @@ class DataSrcClient(unittest.TestCase):
 
         result, rrset = finder.find(isc.dns.Name("doesnotexist.example.com"),
                                     isc.dns.RRType.A(),
-                                    None,
                                     finder.FIND_DEFAULT)
         self.assertEqual(finder.NXDOMAIN, result)
         self.assertEqual(None, rrset)
 
         result, rrset = finder.find(isc.dns.Name("www.some.other.domain"),
                                     isc.dns.RRType.A(),
-                                    None,
                                     finder.FIND_DEFAULT)
         self.assertEqual(finder.NXDOMAIN, result)
         self.assertEqual(None, rrset)
 
         result, rrset = finder.find(isc.dns.Name("www.example.com"),
                                     isc.dns.RRType.TXT(),
-                                    None,
                                     finder.FIND_DEFAULT)
         self.assertEqual(finder.NXRRSET, result)
         self.assertEqual(None, rrset)
 
         result, rrset = finder.find(isc.dns.Name("cname-ext.example.com"),
                                     isc.dns.RRType.A(),
-                                    None,
                                     finder.FIND_DEFAULT)
         self.assertEqual(finder.CNAME, result)
         self.assertEqual(
@@ -345,7 +396,6 @@ class DataSrcClient(unittest.TestCase):
 
         result, rrset = finder.find(isc.dns.Name("foo.wild.example.com"),
                                     isc.dns.RRType.A(),
-                                    None,
                                     finder.FIND_DEFAULT)
         self.assertEqual(finder.WILDCARD, result)
         self.assertEqual("foo.wild.example.com. 3600 IN A 192.0.2.255\n",
@@ -353,7 +403,6 @@ class DataSrcClient(unittest.TestCase):
 
         result, rrset = finder.find(isc.dns.Name("foo.wild.example.com"),
                                     isc.dns.RRType.TXT(),
-                                    None,
                                     finder.FIND_DEFAULT)
         self.assertEqual(finder.WILDCARD_NXRRSET, result)
         self.assertEqual(None, rrset)
@@ -361,17 +410,14 @@ class DataSrcClient(unittest.TestCase):
         self.assertRaises(TypeError, finder.find,
                           "foo",
                           isc.dns.RRType.A(),
-                          None,
                           finder.FIND_DEFAULT)
         self.assertRaises(TypeError, finder.find,
                           isc.dns.Name("cname-ext.example.com"),
                           "foo",
-                          None,
                           finder.FIND_DEFAULT)
         self.assertRaises(TypeError, finder.find,
                           isc.dns.Name("cname-ext.example.com"),
                           isc.dns.RRType.A(),
-                          None,
                           "foo")
 
     def test_find_previous(self):
@@ -399,6 +445,16 @@ class DataSrcUpdater(unittest.TestCase):
         # Make a fresh copy of the writable database with all original content
         shutil.copyfile(READ_ZONE_DB_FILE, WRITE_ZONE_DB_FILE)
 
+    def test_findall(self):
+        """
+        The same test as DataSrcClient.test_findall, but on an updater
+        instead of a finder.
+        """
+        dsc = isc.datasrc.DataSourceClient("sqlite3", WRITE_ZONE_DB_CONFIG)
+        updater = dsc.get_updater(isc.dns.Name("example.com"), False)
+
+        test_findall_common(self, updater)
+
     def test_construct(self):
         # can't construct directly
         self.assertRaises(TypeError, isc.datasrc.ZoneUpdater)
@@ -409,7 +465,6 @@ class DataSrcUpdater(unittest.TestCase):
         updater = dsc.get_updater(isc.dns.Name("example.com"), False)
         result, rrset = updater.find(isc.dns.Name("www.example.com"),
                                      isc.dns.RRType.A(),
-                                     None,
                                      ZoneFinder.FIND_DEFAULT)
         self.assertEqual(ZoneFinder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
@@ -422,17 +477,6 @@ class DataSrcUpdater(unittest.TestCase):
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
                          rrset.to_text())
 
-        result, rrset = updater.find(isc.dns.Name("www.example.com"),
-                                     isc.dns.RRType.A(), None)
-        self.assertEqual(ZoneFinder.SUCCESS, result)
-        self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
-                         rrset.to_text())
-
-        # Invalid value for 'target'
-        self.assertRaises(TypeError, updater.find,
-                          isc.dns.Name("www.example.com"),
-                          isc.dns.RRType.A(), 1)
-
     def test_update_delete_commit(self):
 
         dsc = isc.datasrc.DataSourceClient("sqlite3", WRITE_ZONE_DB_CONFIG)
@@ -445,7 +489,6 @@ class DataSrcUpdater(unittest.TestCase):
 
         result, rrset = finder.find(isc.dns.Name("www.example.com"),
                                     isc.dns.RRType.A(),
-                                    None,
                                     finder.FIND_DEFAULT)
         self.assertEqual(finder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
@@ -467,14 +510,12 @@ class DataSrcUpdater(unittest.TestCase):
         # finder (since we have not committed)
         result, rrset = updater.find(isc.dns.Name("www.example.com"),
                                      isc.dns.RRType.A(),
-                                     None,
                                      finder.FIND_DEFAULT)
         self.assertEqual(finder.NXDOMAIN, result)
         self.assertEqual(None, rrset)
 
         result, rrset = finder.find(isc.dns.Name("www.example.com"),
                                     isc.dns.RRType.A(),
-                                    None,
                                     finder.FIND_DEFAULT)
         self.assertEqual(finder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
@@ -487,7 +528,6 @@ class DataSrcUpdater(unittest.TestCase):
         # the record should be gone now in the 'real' finder as well
         result, rrset = finder.find(isc.dns.Name("www.example.com"),
                                     isc.dns.RRType.A(),
-                                    None,
                                     finder.FIND_DEFAULT)
         self.assertEqual(finder.NXDOMAIN, result)
         self.assertEqual(None, rrset)
@@ -502,7 +542,6 @@ class DataSrcUpdater(unittest.TestCase):
 
         result, rrset = finder.find(isc.dns.Name("www.example.com"),
                                     isc.dns.RRType.A(),
-                                    None,
                                     finder.FIND_DEFAULT)
         self.assertEqual(finder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
@@ -527,7 +566,6 @@ class DataSrcUpdater(unittest.TestCase):
         self.assertEqual("example.com.", finder.get_origin().to_text())
         result, rrset = finder.find(isc.dns.Name("www.example.com"),
                                     isc.dns.RRType.A(),
-                                    None,
                                     finder.FIND_DEFAULT)
         self.assertEqual(finder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
@@ -551,7 +589,6 @@ class DataSrcUpdater(unittest.TestCase):
 
         result, rrset = finder.find(isc.dns.Name("www.example.com"),
                                     isc.dns.RRType.A(),
-                                    None,
                                     finder.FIND_DEFAULT)
         self.assertEqual(finder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
@@ -573,7 +610,6 @@ class DataSrcUpdater(unittest.TestCase):
         # finder (since we have not committed)
         result, rrset = updater.find(isc.dns.Name("www.example.com"),
                                      isc.dns.RRType.A(),
-                                     None,
                                      finder.FIND_DEFAULT)
         self.assertEqual(finder.NXDOMAIN, result)
         self.assertEqual(None, rrset)
@@ -584,7 +620,6 @@ class DataSrcUpdater(unittest.TestCase):
         # the record should still be available in the 'real' finder as well
         result, rrset = finder.find(isc.dns.Name("www.example.com"),
                                     isc.dns.RRType.A(),
-                                    None,
                                     finder.FIND_DEFAULT)
         self.assertEqual(finder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
diff --git a/src/lib/python/isc/datasrc/updater_python.cc b/src/lib/python/isc/datasrc/updater_python.cc
index 29d2ffe..c528a0c 100644
--- a/src/lib/python/isc/datasrc/updater_python.cc
+++ b/src/lib/python/isc/datasrc/updater_python.cc
@@ -48,6 +48,7 @@ using namespace isc::datasrc::python;
 namespace isc_datasrc_internal {
 // See finder_python.cc
 PyObject* ZoneFinder_helper(ZoneFinder* finder, PyObject* args);
+PyObject* ZoneFinder_helper_all(ZoneFinder* finder, PyObject* args);
 }
 
 namespace {
@@ -74,7 +75,7 @@ typedef CPPPyObjectContainer<s_ZoneUpdater, ZoneUpdater> ZoneUpdaterContainer;
 
 // General creation and destruction
 int
-ZoneUpdater_init(s_ZoneUpdater* self, PyObject* args) {
+ZoneUpdater_init(PyObject*, PyObject*, PyObject*) {
     // can't be called directly
     PyErr_SetString(PyExc_TypeError,
                     "ZoneUpdater cannot be constructed directly");
@@ -83,7 +84,9 @@ ZoneUpdater_init(s_ZoneUpdater* self, PyObject* args) {
 }
 
 void
-ZoneUpdater_destroy(s_ZoneUpdater* const self) {
+ZoneUpdater_destroy(PyObject* po_self) {
+    s_ZoneUpdater* const self = static_cast<s_ZoneUpdater*>(po_self);
+
     // cppobj is a shared ptr, but to make sure things are not destroyed in
     // the wrong order, we reset it here.
     self->cppobj.reset();
@@ -185,6 +188,13 @@ ZoneUpdater_find(PyObject* po_self, PyObject* args) {
                                                     args));
 }
 
+PyObject*
+ZoneUpdater_find_all(PyObject* po_self, PyObject* args) {
+    s_ZoneUpdater* const self = static_cast<s_ZoneUpdater*>(po_self);
+    return (isc_datasrc_internal::ZoneFinder_helper_all(
+        &self->cppobj->getFinder(), args));
+}
+
 // This list contains the actual set of functions we have in
 // python. Each entry has
 // 1. Python method name
@@ -192,22 +202,22 @@ ZoneUpdater_find(PyObject* po_self, PyObject* args) {
 // 3. Argument type
 // 4. Documentation
 PyMethodDef ZoneUpdater_methods[] = {
-    { "add_rrset", reinterpret_cast<PyCFunction>(ZoneUpdater_addRRset),
+    { "add_rrset", ZoneUpdater_addRRset,
       METH_VARARGS, ZoneUpdater_addRRset_doc },
-    { "delete_rrset", reinterpret_cast<PyCFunction>(ZoneUpdater_deleteRRset),
+    { "delete_rrset", ZoneUpdater_deleteRRset,
       METH_VARARGS, ZoneUpdater_deleteRRset_doc },
-    { "commit", reinterpret_cast<PyCFunction>(ZoneUpdater_commit), METH_NOARGS,
-      ZoneUpdater_commit_doc },
+    { "commit", ZoneUpdater_commit, METH_NOARGS, ZoneUpdater_commit_doc },
     // Instead of a getFinder, we implement the finder functionality directly
     // This is because ZoneFinder is non-copyable, and we should not create
     // a ZoneFinder object from a reference only (which is what is returned
     // by getFinder(). Apart from that
-    { "get_origin", reinterpret_cast<PyCFunction>(ZoneUpdater_getOrigin),
+    { "get_origin", ZoneUpdater_getOrigin,
       METH_NOARGS, ZoneFinder_getOrigin_doc },
-    { "get_class", reinterpret_cast<PyCFunction>(ZoneUpdater_getClass),
+    { "get_class", ZoneUpdater_getClass,
       METH_NOARGS, ZoneFinder_getClass_doc },
-    { "find", reinterpret_cast<PyCFunction>(ZoneUpdater_find), METH_VARARGS,
-      ZoneFinder_find_doc },
+    { "find", ZoneUpdater_find, METH_VARARGS, ZoneFinder_find_doc },
+    { "find_all", ZoneUpdater_find_all, METH_VARARGS,
+      ZoneFinder_find_all_doc },
     { NULL, NULL, 0, NULL }
 };
 
@@ -221,7 +231,7 @@ PyTypeObject zoneupdater_type = {
     "datasrc.ZoneUpdater",
     sizeof(s_ZoneUpdater),              // tp_basicsize
     0,                                  // tp_itemsize
-    reinterpret_cast<destructor>(ZoneUpdater_destroy),// tp_dealloc
+    ZoneUpdater_destroy,                // tp_dealloc
     NULL,                               // tp_print
     NULL,                               // tp_getattr
     NULL,                               // tp_setattr
@@ -252,7 +262,7 @@ PyTypeObject zoneupdater_type = {
     NULL,                               // tp_descr_get
     NULL,                               // tp_descr_set
     0,                                  // tp_dictoffset
-    reinterpret_cast<initproc>(ZoneUpdater_init),// tp_init
+    ZoneUpdater_init,                   // tp_init
     NULL,                               // tp_alloc
     PyType_GenericNew,                  // tp_new
     NULL,                               // tp_free




More information about the bind10-changes mailing list