]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[2051] Implement the find wrapper
authorMichal 'vorner' Vaner <michal.vaner@nic.cz>
Tue, 17 Jul 2012 09:58:06 +0000 (11:58 +0200)
committerMichal 'vorner' Vaner <michal.vaner@nic.cz>
Tue, 17 Jul 2012 09:58:06 +0000 (11:58 +0200)
However, it still needs documentation and some stuff with object
lifetime management.

src/lib/python/isc/datasrc/client_python.cc
src/lib/python/isc/datasrc/client_python.h
src/lib/python/isc/datasrc/configurableclientlist_python.cc
src/lib/python/isc/datasrc/tests/clientlist_test.py

index c237115f897b5428c4252ce107e069788fcc6c7a..7754d799e03c345b02c555d34092f0dc2985193a 100644 (file)
@@ -348,6 +348,17 @@ PyTypeObject datasourceclient_type = {
     0                                   // tp_version_tag
 };
 
+PyObject*
+wrapDataSourceClient(DataSourceClient* client) {
+    // There aro no exceptions here, so this is safe
+    s_DataSourceClient *result =
+        static_cast<s_DataSourceClient*>(PyObject_New(s_DataSourceClient,
+                                                      &datasourceclient_type));
+    result->cppobj = NULL;
+    result->client = client;
+    return (result);
+}
+
 } // namespace python
 } // namespace datasrc
 } // namespace isc
index b20fb6b4c71878825814217296b3d16289489ffa..b30c0fb18eba3557eadf8f028736bbf0821da147 100644 (file)
@@ -25,6 +25,9 @@ namespace python {
 
 extern PyTypeObject datasourceclient_type;
 
+// TODO: Documentation, warning
+PyObject* wrapDataSourceClient(DataSourceClient* client);
+
 } // namespace python
 } // namespace datasrc
 } // namespace isc
index b77be24d2aa0eb6aa07b14c77ff6a57de2957ee7..ddca636825966debab37eb46452fc3ddb8ad2c51 100644 (file)
 #include <util/python/pycppwrapper_util.h>
 
 #include <dns/python/rrclass_python.h>
+#include <dns/python/name_python.h>
 
 #include <datasrc/client_list.h>
 
 #include "configurableclientlist_python.h"
 #include "datasrc.h"
 #include "configurableclientlist_inc.cc"
+#include "finder_python.h"
+#include "client_python.h"
 
 using namespace std;
 using namespace isc::util::python;
@@ -47,9 +50,6 @@ s_ConfigurableClientList::s_ConfigurableClientList() : cppobj(NULL) {
 }
 
 namespace {
-// Shortcut type which would be convenient for adding class variables safely.
-typedef CPPPyObjectContainer<s_ConfigurableClientList, ConfigurableClientList>
-    ConfigurableClientListContainer;
 
 int
 ConfigurableClientList_init(PyObject* po_self, PyObject* args, PyObject*) {
@@ -111,6 +111,52 @@ ConfigurableClientList_configure(PyObject* po_self, PyObject* args) {
     }
 }
 
+PyObject*
+ConfigurableClientList_find(PyObject* po_self, PyObject* args) {
+    s_ConfigurableClientList* self =
+        static_cast<s_ConfigurableClientList*>(po_self);
+    try {
+        PyObject* name_obj;
+        int want_exact_match = 0;
+        int want_finder = 1;
+        if (PyArg_ParseTuple(args, "O!|ii", &isc::dns::python::name_type,
+                             &name_obj, &want_exact_match, &want_finder)) {
+            const isc::dns::Name
+                name(isc::dns::python::PyName_ToName(name_obj));
+            const ClientList::FindResult
+                result(self->cppobj->find(name, want_exact_match,
+                                          want_finder));
+            PyObjectContainer dsrc;
+            if (result.dsrc_client_ == NULL) {
+                // Use the Py_BuildValue, as it takes care of the
+                // reference counts correctly.
+                dsrc.reset(Py_BuildValue(""));
+            } else {
+                dsrc.reset(wrapDataSourceClient(result.dsrc_client_));
+            }
+            PyObjectContainer finder;
+            if (result.finder_ == NULL) {
+                finder.reset(Py_BuildValue(""));
+            } else {
+                finder.reset(createZoneFinderObject(result.finder_));
+            }
+            PyObjectContainer exact(PyBool_FromLong(result.exact_match_));
+
+            return (Py_BuildValue("OOO", dsrc.get(), finder.get(),
+                                  exact.get()));
+        } else {
+            return (NULL);
+        }
+    } catch (const std::exception& exc) {
+        PyErr_SetString(getDataSourceException("Error"), exc.what());
+        return (NULL);
+    } catch (...) {
+        PyErr_SetString(getDataSourceException("Error"),
+                        "Unknown C++ exception");
+        return (NULL);
+    }
+}
+
 // This list contains the actual set of functions we have in
 // python. Each entry has
 // 1. Python method name
@@ -120,6 +166,7 @@ ConfigurableClientList_configure(PyObject* po_self, PyObject* args) {
 PyMethodDef ConfigurableClientList_methods[] = {
     { "configure", ConfigurableClientList_configure, METH_VARARGS,
         "TODO: Docs" },
+    { "find", ConfigurableClientList_find, METH_VARARGS, "TODO: Docs" },
     { NULL, NULL, 0, NULL }
 };
 } // end of unnamed namespace
index e7219e9b27eb5204ea1157dc448055161fbc10a7..334042ffafef882ac5e1d00568ffab51686078e7 100644 (file)
@@ -52,6 +52,11 @@ class ClientListTest(unittest.TestCase):
         clist = isc.datasrc.ConfigurableClientList(isc.dns.RRClass.IN())
         # This should be NOP now
         clist.configure("[]", True)
+        # Check the zone is not there yet
+        dsrc, finder, exact = clist.find(isc.dns.Name("example.org"))
+        self.assertIsNone(dsrc)
+        self.assertIsNone(finder)
+        self.assertFalse(exact)
         # We can use this type, as it is not loaded dynamically.
         clist.configure('''[{
             "type": "MasterFiles",
@@ -60,6 +65,14 @@ class ClientListTest(unittest.TestCase):
             },
             "cache-enable": true
         }]''', True)
+        # Check the zone is there now. Proper tests of find are in other
+        # test methods.
+        dsrc, finder, exact = clist.find(isc.dns.Name("example.org"))
+        self.assertIsNotNone(dsrc)
+        self.assertTrue(isinstance(dsrc, isc.datasrc.DataSourceClient))
+        self.assertIsNotNone(finder)
+        self.assertTrue(isinstance(finder, isc.datasrc.ZoneFinder))
+        self.assertTrue(exact)
         self.assertRaises(isc.datasrc.Error, clist.configure, '"bad type"',
                           True)
         self.assertRaises(isc.datasrc.Error, clist.configure, '''[{
@@ -72,6 +85,54 @@ class ClientListTest(unittest.TestCase):
         self.assertRaises(TypeError, clist.configure, "[]")
         self.assertRaises(TypeError, clist.configure, "[]", "true")
 
+    def test_find(self):
+        """
+        Test the find accepts the right arguments, some of them can be omitted,
+        etc.
+        """
+        clist = isc.datasrc.ConfigurableClientList(isc.dns.RRClass.IN())
+        clist.configure('''[{
+            "type": "MasterFiles",
+            "params": {
+                "example.org": "''' + TESTDATA_PATH + '''example.org.zone"
+            },
+            "cache-enable": true
+        }]''', True)
+        dsrc, finder, exact = clist.find(isc.dns.Name("sub.example.org"))
+        self.assertIsNotNone(dsrc)
+        self.assertTrue(isinstance(dsrc, isc.datasrc.DataSourceClient))
+        self.assertIsNotNone(finder)
+        self.assertTrue(isinstance(finder, isc.datasrc.ZoneFinder))
+        # We check an exact match in test_configure already
+        self.assertFalse(exact)
+        dsrc, finder, exact = clist.find(isc.dns.Name("sub.example.org"),
+                                         False)
+        self.assertIsNotNone(dsrc)
+        self.assertTrue(isinstance(dsrc, isc.datasrc.DataSourceClient))
+        self.assertIsNotNone(finder)
+        self.assertTrue(isinstance(finder, isc.datasrc.ZoneFinder))
+        self.assertFalse(exact)
+        dsrc, finder, exact = clist.find(isc.dns.Name("sub.example.org"),
+                                         True)
+        self.assertIsNone(dsrc)
+        self.assertIsNone(finder)
+        self.assertFalse(exact)
+        dsrc, finder, exact = clist.find(isc.dns.Name("sub.example.org"),
+                                         False, False)
+        self.assertIsNotNone(dsrc)
+        self.assertTrue(isinstance(dsrc, isc.datasrc.DataSourceClient))
+        self.assertIsNotNone(finder)
+        self.assertTrue(isinstance(finder, isc.datasrc.ZoneFinder))
+        self.assertFalse(exact)
+        dsrc, finder, exact = clist.find(isc.dns.Name("sub.example.org"),
+                                         True, False)
+        self.assertIsNone(dsrc)
+        self.assertIsNone(finder)
+        self.assertFalse(exact)
+        # Some invalid inputs
+        self.assertRaises(TypeError, clist.find, "example.org")
+        self.assertRaises(TypeError, clist.find)
+
 if __name__ == "__main__":
     isc.log.init("bind10")
     isc.log.resetUnitTestRootLogger()