BIND 10 trac2379_2, updated. ca8707b6528b0779ce9cc6de42169d53af561b8a [2379] Add separate initializer for NameComparisonResult type

BIND 10 source code commits bind10-changes at lists.isc.org
Mon Dec 17 14:02:12 UTC 2012


The branch, trac2379_2 has been updated
       via  ca8707b6528b0779ce9cc6de42169d53af561b8a (commit)
       via  5a34019b3d874b4e8d1209d47d38592281b971ca (commit)
       via  45596b6bd556fd78555930c4e883a5025912ec4d (commit)
      from  3fb09910a4c862fef0e8f3dc631df0fba49c8107 (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 ca8707b6528b0779ce9cc6de42169d53af561b8a
Author: Jelte Jansen <jelte at isc.org>
Date:   Mon Dec 17 14:57:52 2012 +0100

    [2379] Add separate initializer for NameComparisonResult type

commit 5a34019b3d874b4e8d1209d47d38592281b971ca
Author: Jelte Jansen <jelte at isc.org>
Date:   Mon Dec 17 14:50:12 2012 +0100

    [2379] catch errors when using PyObjectContainer

commit 45596b6bd556fd78555930c4e883a5025912ec4d
Author: Jelte Jansen <jelte at isc.org>
Date:   Mon Dec 17 14:28:32 2012 +0100

    [2379] Add reference count checks to tests

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

Summary of changes:
 src/lib/dns/python/pydnspp.cc                      |  270 +++++++++++++-------
 src/lib/dns/python/pydnspp_common.cc               |    4 +-
 .../python/isc/datasrc/tests/zone_loader_test.py   |   57 +++--
 3 files changed, 215 insertions(+), 116 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/dns/python/pydnspp.cc b/src/lib/dns/python/pydnspp.cc
index 44a3785..443a21a 100644
--- a/src/lib/dns/python/pydnspp.cc
+++ b/src/lib/dns/python/pydnspp.cc
@@ -187,11 +187,7 @@ initModulePart_MessageRenderer(PyObject* mod) {
 }
 
 bool
-initModulePart_Name(PyObject* mod) {
-
-    //
-    // NameComparisonResult
-    //
+initModulePart_NameComparisonResult(PyObject* mod) {
     if (!initClass(name_comparison_result_type,
                    "NameComparisonResult", mod)) {
         return (false);
@@ -215,10 +211,11 @@ initModulePart_Name(PyObject* mod) {
     addClassVariable(name_comparison_result_type, "COMMONANCESTOR",
                      Py_BuildValue("I", NameComparisonResult::COMMONANCESTOR));
 
+    return (true);
+}
 
-    //
-    // Name
-    //
+bool
+initModulePart_Name(PyObject* mod) {
     if (!initClass(name_type, "Name", mod)) {
         return (false);
     }
@@ -240,39 +237,49 @@ initModulePart_Name(PyObject* mod) {
     addClassVariable(name_type, "ROOT_NAME",
                      createNameObject(Name::ROOT_NAME()));
 
-
-
     // Add the exceptions to the module
-    po_EmptyLabel = PyErr_NewException("pydnspp.EmptyLabel", NULL, NULL);
-    PyObjectContainer(po_EmptyLabel).installToModule(mod, "EmptyLabel");
+    try {
+        po_EmptyLabel = PyErr_NewException("pydnspp.EmptyLabel", NULL, NULL);
+        PyObjectContainer(po_EmptyLabel).installToModule(mod, "EmptyLabel");
 
-    po_TooLongName = PyErr_NewException("pydnspp.TooLongName", NULL, NULL);
-    PyObjectContainer(po_TooLongName).installToModule(mod, "TooLongName");
+        po_TooLongName = PyErr_NewException("pydnspp.TooLongName", NULL, NULL);
+        PyObjectContainer(po_TooLongName).installToModule(mod, "TooLongName");
 
-    po_TooLongLabel = PyErr_NewException("pydnspp.TooLongLabel", NULL, NULL);
-    PyObjectContainer(po_TooLongLabel).installToModule(mod, "TooLongLabel");
+        po_TooLongLabel = PyErr_NewException("pydnspp.TooLongLabel", NULL, NULL);
+        PyObjectContainer(po_TooLongLabel).installToModule(mod, "TooLongLabel");
 
-    po_BadLabelType = PyErr_NewException("pydnspp.BadLabelType", NULL, NULL);
-    PyObjectContainer(po_BadLabelType).installToModule(mod, "BadLabelType");
+        po_BadLabelType = PyErr_NewException("pydnspp.BadLabelType", NULL, NULL);
+        PyObjectContainer(po_BadLabelType).installToModule(mod, "BadLabelType");
 
-    po_BadEscape = PyErr_NewException("pydnspp.BadEscape", NULL, NULL);
-    PyObjectContainer(po_BadEscape).installToModule(mod, "BadEscape");
+        po_BadEscape = PyErr_NewException("pydnspp.BadEscape", NULL, NULL);
+        PyObjectContainer(po_BadEscape).installToModule(mod, "BadEscape");
 
-    po_IncompleteName = PyErr_NewException("pydnspp.IncompleteName", NULL,
-                                           NULL);
-    PyObjectContainer(po_IncompleteName).installToModule(mod, "IncompleteName");
+        po_IncompleteName = PyErr_NewException("pydnspp.IncompleteName", NULL,
+                                               NULL);
+        PyObjectContainer(po_IncompleteName).installToModule(mod, "IncompleteName");
 
-    po_InvalidBufferPosition =
-        PyErr_NewException("pydnspp.InvalidBufferPosition", NULL, NULL);
-    PyObjectContainer(po_InvalidBufferPosition).installToModule(
-        mod, "InvalidBufferPosition");
+        po_InvalidBufferPosition =
+            PyErr_NewException("pydnspp.InvalidBufferPosition", NULL, NULL);
+        PyObjectContainer(po_InvalidBufferPosition).installToModule(
+            mod, "InvalidBufferPosition");
 
-    // This one could have gone into the message_python.cc file, but is
-    // already needed here.
-    po_DNSMessageFORMERR = PyErr_NewException("pydnspp.DNSMessageFORMERR",
-                                              NULL, NULL);
-    PyObjectContainer(po_DNSMessageFORMERR).installToModule(
-        mod, "DNSMessageFORMERR");
+        // This one could have gone into the message_python.cc file, but is
+        // already needed here.
+        po_DNSMessageFORMERR = PyErr_NewException("pydnspp.DNSMessageFORMERR",
+                                                  NULL, NULL);
+        PyObjectContainer(po_DNSMessageFORMERR).installToModule(
+            mod, "DNSMessageFORMERR");
+    } catch (const std::exception& ex) {
+        const std::string ex_what =
+            "Unexpected failure in Name initialization: " +
+            std::string(ex.what());
+        PyErr_SetString(po_IscException, ex_what.c_str());
+        return (false);
+    } catch (...) {
+        PyErr_SetString(PyExc_SystemError,
+                        "Unexpected failure in Name initialization");
+        return (false);
+    }
 
     return (true);
 }
@@ -321,12 +328,7 @@ initModulePart_Opcode(PyObject* mod) {
 
 bool
 initModulePart_Question(PyObject* mod) {
-    if (!initClass(question_type, "Question", mod)) {
-        return (false);
-    }
-
-    Py_INCREF(&question_type);
-    return (true);
+    return (initClass(question_type, "Question", mod));
 }
 
 bool
@@ -380,20 +382,32 @@ initModulePart_Rdata(PyObject* mod) {
     }
 
     // Add the exceptions to the class
-    po_InvalidRdataLength = PyErr_NewException("pydnspp.InvalidRdataLength",
-                                               NULL, NULL);
-    PyObjectContainer(po_InvalidRdataLength).installToModule(
-        mod, "InvalidRdataLength");
-
-    po_InvalidRdataText = PyErr_NewException("pydnspp.InvalidRdataText",
-                                             NULL, NULL);
-    PyObjectContainer(po_InvalidRdataText).installToModule(
-        mod, "InvalidRdataText");
-
-    po_CharStringTooLong = PyErr_NewException("pydnspp.CharStringTooLong",
-                                              NULL, NULL);
-    PyObjectContainer(po_CharStringTooLong).installToModule(
-        mod, "CharStringTooLong");
+    try {
+        po_InvalidRdataLength = PyErr_NewException("pydnspp.InvalidRdataLength",
+                                                   NULL, NULL);
+        PyObjectContainer(po_InvalidRdataLength).installToModule(
+            mod, "InvalidRdataLength");
+
+        po_InvalidRdataText = PyErr_NewException("pydnspp.InvalidRdataText",
+                                                 NULL, NULL);
+        PyObjectContainer(po_InvalidRdataText).installToModule(
+            mod, "InvalidRdataText");
+
+        po_CharStringTooLong = PyErr_NewException("pydnspp.CharStringTooLong",
+                                                  NULL, NULL);
+        PyObjectContainer(po_CharStringTooLong).installToModule(
+            mod, "CharStringTooLong");
+    } catch (const std::exception& ex) {
+        const std::string ex_what =
+            "Unexpected failure in Rdata initialization: " +
+            std::string(ex.what());
+        PyErr_SetString(po_IscException, ex_what.c_str());
+        return (false);
+    } catch (...) {
+        PyErr_SetString(PyExc_SystemError,
+                        "Unexpected failure in Rdata initialization");
+        return (false);
+    }
 
     return (true);
 }
@@ -404,15 +418,27 @@ initModulePart_RRClass(PyObject* mod) {
         return (false);
     }
 
-    po_InvalidRRClass = PyErr_NewException("pydnspp.InvalidRRClass",
-                                           NULL, NULL);
-    PyObjectContainer(po_InvalidRRClass).installToModule(
-        mod, "InvalidRRClass");
+    try {
+        po_InvalidRRClass = PyErr_NewException("pydnspp.InvalidRRClass",
+                                               NULL, NULL);
+        PyObjectContainer(po_InvalidRRClass).installToModule(
+            mod, "InvalidRRClass");
 
-    po_IncompleteRRClass = PyErr_NewException("pydnspp.IncompleteRRClass",
-                                              NULL, NULL);
-    PyObjectContainer(po_IncompleteRRClass).installToModule(
-        mod, "IncompleteRRClass");
+        po_IncompleteRRClass = PyErr_NewException("pydnspp.IncompleteRRClass",
+                                                  NULL, NULL);
+        PyObjectContainer(po_IncompleteRRClass).installToModule(
+            mod, "IncompleteRRClass");
+    } catch (const std::exception& ex) {
+        const std::string ex_what =
+            "Unexpected failure in RRClass initialization: " +
+            std::string(ex.what());
+        PyErr_SetString(po_IscException, ex_what.c_str());
+        return (false);
+    } catch (...) {
+        PyErr_SetString(PyExc_SystemError,
+                        "Unexpected failure in RRClass initialization");
+        return (false);
+    }
 
     return (true);
 }
@@ -423,8 +449,20 @@ initModulePart_RRset(PyObject* mod) {
         return (false);
     }
 
-    po_EmptyRRset = PyErr_NewException("pydnspp.EmptyRRset", NULL, NULL);
-    PyObjectContainer(po_EmptyRRset).installToModule(mod, "EmptyRRset");
+    try {
+        po_EmptyRRset = PyErr_NewException("pydnspp.EmptyRRset", NULL, NULL);
+        PyObjectContainer(po_EmptyRRset).installToModule(mod, "EmptyRRset");
+    } catch (const std::exception& ex) {
+        const std::string ex_what =
+            "Unexpected failure in RRset initialization: " +
+            std::string(ex.what());
+        PyErr_SetString(po_IscException, ex_what.c_str());
+        return (false);
+    } catch (...) {
+        PyErr_SetString(PyExc_SystemError,
+                        "Unexpected failure in RRset initialization");
+        return (false);
+    }
 
     return (true);
 }
@@ -435,13 +473,27 @@ initModulePart_RRTTL(PyObject* mod) {
         return (false);
     }
 
-    po_InvalidRRTTL = PyErr_NewException("pydnspp.InvalidRRTTL", NULL, NULL);
-    PyObjectContainer(po_InvalidRRTTL).installToModule(mod, "InvalidRRTTL");
+    try {
+        po_InvalidRRTTL = PyErr_NewException("pydnspp.InvalidRRTTL",
+                                             NULL, NULL);
+        PyObjectContainer(po_InvalidRRTTL).installToModule(mod,
+                                                           "InvalidRRTTL");
 
-    po_IncompleteRRTTL = PyErr_NewException("pydnspp.IncompleteRRTTL",
-                                            NULL, NULL);
-    PyObjectContainer(po_IncompleteRRTTL).installToModule(
-        mod, "IncompleteRRTTL");
+        po_IncompleteRRTTL = PyErr_NewException("pydnspp.IncompleteRRTTL",
+                                                NULL, NULL);
+        PyObjectContainer(po_IncompleteRRTTL).installToModule(
+            mod, "IncompleteRRTTL");
+    } catch (const std::exception& ex) {
+        const std::string ex_what =
+            "Unexpected failure in RRTTL initialization: " +
+            std::string(ex.what());
+        PyErr_SetString(po_IscException, ex_what.c_str());
+        return (false);
+    } catch (...) {
+        PyErr_SetString(PyExc_SystemError,
+                        "Unexpected failure in RRTTL initialization");
+        return (false);
+    }
 
     return (true);
 }
@@ -452,24 +504,34 @@ initModulePart_RRType(PyObject* mod) {
         return (false);
     }
 
-    po_InvalidRRType = PyErr_NewException("pydnspp.InvalidRRType", NULL, NULL);
-    PyObjectContainer(po_InvalidRRType).installToModule(mod, "InvalidRRType");
+    try {
+        po_InvalidRRType = PyErr_NewException("pydnspp.InvalidRRType",
+                                              NULL, NULL);
+        PyObjectContainer(po_InvalidRRType).installToModule(mod,
+                                                            "InvalidRRType");
 
-    po_IncompleteRRType = PyErr_NewException("pydnspp.IncompleteRRType",
-                                             NULL, NULL);
-    PyObjectContainer(po_IncompleteRRType).installToModule(
-        mod, "IncompleteRRType");
+        po_IncompleteRRType = PyErr_NewException("pydnspp.IncompleteRRType",
+                                                 NULL, NULL);
+        PyObjectContainer(po_IncompleteRRType).installToModule(
+            mod, "IncompleteRRType");
+    } catch (const std::exception& ex) {
+        const std::string ex_what =
+            "Unexpected failure in RRType initialization: " +
+            std::string(ex.what());
+        PyErr_SetString(po_IscException, ex_what.c_str());
+        return (false);
+    } catch (...) {
+        PyErr_SetString(PyExc_SystemError,
+                        "Unexpected failure in RRType initialization");
+        return (false);
+    }
 
     return (true);
 }
 
 bool
 initModulePart_Serial(PyObject* mod) {
-    if (!initClass(serial_type, "Serial", mod)) {
-        return (false);
-    }
-
-    return (true);
+    return (initClass(serial_type, "Serial", mod));
 }
 
 bool
@@ -638,11 +700,7 @@ initModulePart_TSIGContext(PyObject* mod) {
 
 bool
 initModulePart_TSIG(PyObject* mod) {
-    if (!initClass(tsig_type, "TSIG", mod)) {
-        return (false);
-    }
-
-    return (true);
+    return (initClass(tsig_type, "TSIG", mod));
 }
 
 bool
@@ -694,22 +752,38 @@ PyInit_pydnspp(void) {
         return (NULL);
     }
 
-    // Add the exceptions to the class
-    po_IscException = PyErr_NewException("pydnspp.IscException", NULL, NULL);
-    PyObjectContainer(po_IscException).installToModule(mod, "IscException");
-
-    po_InvalidOperation = PyErr_NewException("pydnspp.InvalidOperation",
-                                             NULL, NULL);
-    PyObjectContainer(po_InvalidOperation).installToModule(
-        mod, "InvalidOperation");
-
-    po_InvalidParameter = PyErr_NewException("pydnspp.InvalidParameter",
-                                             NULL, NULL);
-    PyObjectContainer(po_InvalidParameter).installToModule(
-        mod, "InvalidParameter");
+    try {
+        // Add the exceptions to the class
+        po_IscException = PyErr_NewException("pydnspp.IscException", NULL, NULL);
+        PyObjectContainer(po_IscException).installToModule(mod, "IscException");
+
+        po_InvalidOperation = PyErr_NewException("pydnspp.InvalidOperation",
+                                                 NULL, NULL);
+        PyObjectContainer(po_InvalidOperation).installToModule(
+            mod, "InvalidOperation");
+
+        po_InvalidParameter = PyErr_NewException("pydnspp.InvalidParameter",
+                                                 NULL, NULL);
+        PyObjectContainer(po_InvalidParameter).installToModule(
+            mod, "InvalidParameter");
+    } catch (const std::exception& ex) {
+        const std::string ex_what =
+            "Unexpected failure in pydnspp initialization: " +
+            std::string(ex.what());
+        PyErr_SetString(po_IscException, ex_what.c_str());
+        return (NULL);
+    } catch (...) {
+        PyErr_SetString(PyExc_SystemError,
+                        "Unexpected failure in pydnspp initialization");
+        return (NULL);
+    }
 
     // for each part included above, we call its specific initializer
 
+    if (!initModulePart_NameComparisonResult(mod)) {
+        return (NULL);
+    }
+
     if (!initModulePart_Name(mod)) {
         return (NULL);
     }
diff --git a/src/lib/dns/python/pydnspp_common.cc b/src/lib/dns/python/pydnspp_common.cc
index 6213a4a..e9d62e0 100644
--- a/src/lib/dns/python/pydnspp_common.cc
+++ b/src/lib/dns/python/pydnspp_common.cc
@@ -99,9 +99,9 @@ initClass(PyTypeObject& type, const char* name, PyObject* mod) {
     // then add it to the module. This is not just a check! (leaving
     // this out results in segmentation faults)
     //
+    void* p = &type;
     if (PyType_Ready(&type) < 0 ||
-        PyModule_AddObject(mod, name,
-                           reinterpret_cast<PyObject*>(&type)) < 0) {
+        PyModule_AddObject(mod, name, static_cast<PyObject*>(p)) < 0) {
         return (false);
     }
     Py_INCREF(&type);
diff --git a/src/lib/python/isc/datasrc/tests/zone_loader_test.py b/src/lib/python/isc/datasrc/tests/zone_loader_test.py
index a8095ba..c044fd5 100644
--- a/src/lib/python/isc/datasrc/tests/zone_loader_test.py
+++ b/src/lib/python/isc/datasrc/tests/zone_loader_test.py
@@ -19,6 +19,7 @@ import isc.dns
 import os
 import unittest
 import shutil
+import sys
 
 # Constants and common data used in tests
 
@@ -46,14 +47,37 @@ class ZoneLoaderTests(unittest.TestCase):
         self.client = isc.datasrc.DataSourceClient("sqlite3", DB_CLIENT_CONFIG)
         # Make a fresh copy of the database
         shutil.copy(ORIG_DB_FILE, DB_FILE)
+        # Some tests set source client; if so, check refcount in
+        # tearDown, since most tests don't, set it to None by default.
+        self.source_client = None
+        self.loader = None
+        self.assertEqual(2, sys.getrefcount(self.test_name))
+        self.assertEqual(2, sys.getrefcount(self.client))
 
     def tearDown(self):
         # We can only create 1 loader at a time (it locks the db), and it
         # may not be destroyed immediately if there is an exception in a
         # test. So the tests that do create one should put it in self, and
         # we make sure to invalidate it here.
+
+        # We can also use this to check reference counts; if a loader
+        # exists, the client and source client (if any) should have
+        # an increased reference count (but the name should not, this
+        # is only used in the initializer)
+        if self.loader is not None:
+            self.assertEqual(2, sys.getrefcount(self.test_name))
+            self.assertEqual(3, sys.getrefcount(self.client))
+            if (self.source_client is not None):
+                self.assertEqual(3, sys.getrefcount(self.source_client))
         self.loader = None
 
+        # Now that the loader has been destroyed, the refcounts
+        # of its arguments should be back to their originals
+        self.assertEqual(2, sys.getrefcount(self.test_name))
+        self.assertEqual(2, sys.getrefcount(self.client))
+        if (self.source_client is not None):
+            self.assertEqual(2, sys.getrefcount(self.source_client))
+
     def test_bad_constructor(self):
         self.assertRaises(TypeError, isc.datasrc.ZoneLoader)
         self.assertRaises(TypeError, isc.datasrc.ZoneLoader, 1)
@@ -90,13 +114,13 @@ class ZoneLoaderTests(unittest.TestCase):
         self.check_load()
 
     def test_load_from_client(self):
-        source_client = isc.datasrc.DataSourceClient('sqlite3',
-                                                     DB_SOURCE_CLIENT_CONFIG)
+        self.source_client = isc.datasrc.DataSourceClient('sqlite3',
+                                    DB_SOURCE_CLIENT_CONFIG)
         self.loader = isc.datasrc.ZoneLoader(self.client, self.test_name,
-                                             source_client)
+                                             self.source_client)
         self.check_load()
 
-    def test_load_from_file_checkrefs(self):
+    def Xtest_load_from_file_checkrefs(self):
         # A test to see the refcount is increased properly
         self.loader = isc.datasrc.ZoneLoader(self.client, self.test_name,
                                              self.test_file)
@@ -109,7 +133,7 @@ class ZoneLoaderTests(unittest.TestCase):
         self.test_file = None
         self.loader.load()
 
-    def test_load_from_client_checkrefs(self):
+    def Xtest_load_from_client_checkrefs(self):
         # A test to see the refcount is increased properly
         source_client = isc.datasrc.DataSourceClient('sqlite3',
                                                      DB_SOURCE_CLIENT_CONFIG)
@@ -146,10 +170,10 @@ class ZoneLoaderTests(unittest.TestCase):
         self.check_load_incremental()
 
     def test_load_from_client_incremental(self):
-        source_client = isc.datasrc.DataSourceClient('sqlite3',
-                                                     DB_SOURCE_CLIENT_CONFIG)
+        self.source_client = isc.datasrc.DataSourceClient('sqlite3',
+                                            DB_SOURCE_CLIENT_CONFIG)
         self.loader = isc.datasrc.ZoneLoader(self.client, self.test_name,
-                                             source_client)
+                                             self.source_client)
         self.check_load_incremental()
 
     def test_bad_file(self):
@@ -175,18 +199,18 @@ class ZoneLoaderTests(unittest.TestCase):
     def test_no_such_zone_in_source(self):
         # Reuse a zone that exists in target but not in source
         zone_name = isc.dns.Name("sql1.example.com")
-        source_client = isc.datasrc.DataSourceClient('sqlite3',
-                                                     DB_SOURCE_CLIENT_CONFIG)
+        self.source_client = isc.datasrc.DataSourceClient('sqlite3',
+                                            DB_SOURCE_CLIENT_CONFIG)
 
         # make sure the zone exists in the target
         found, _ = self.client.find_zone(zone_name)
         self.assertEqual(self.client.SUCCESS, found)
         # And that it does not in the source
-        found, _ = source_client.find_zone(zone_name)
-        self.assertNotEqual(source_client.SUCCESS, found)
+        found, _ = self.source_client.find_zone(zone_name)
+        self.assertNotEqual(self.source_client.SUCCESS, found)
 
         self.assertRaises(isc.datasrc.Error, isc.datasrc.ZoneLoader,
-                          self.client, zone_name, source_client)
+                          self.client, zone_name, self.source_client)
 
     def test_no_ds_load_support(self):
         # This may change in the future, but atm, the in-mem ds does
@@ -209,10 +233,11 @@ class ZoneLoaderTests(unittest.TestCase):
         clientlist = isc.datasrc.ConfigurableClientList(isc.dns.RRClass.CH())
         clientlist.configure('[ { "type": "static", "params": "' +
                              STATIC_ZONE_FILE +'" } ]', False)
-        source_client, _, _ = clientlist.find(isc.dns.Name("bind."),
-                                              False, False)
+        self.source_client, _, _ = clientlist.find(isc.dns.Name("bind."),
+                                                   False, False)
         self.assertRaises(isc.dns.InvalidParameter, isc.datasrc.ZoneLoader,
-                          self.client, isc.dns.Name("bind."), source_client)
+                          self.client, isc.dns.Name("bind."),
+                          self.source_client)
 
     def test_exception(self):
         # Just check if masterfileerror is subclass of datasrc.Error



More information about the bind10-changes mailing list