summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal 'vorner' Vaner <michal.vaner@nic.cz>2012-07-17 11:58:06 +0200
committerMichal 'vorner' Vaner <michal.vaner@nic.cz>2012-07-17 11:58:06 +0200
commitcf2ea3f88a6f6610c6fc3ac709ce05540dcef111 (patch)
treef6901a5706e06cde07d21f1c9f3f5753ac41c109
parent[2051] Change the internals of DataSourceClient wrapper (diff)
downloadkea-cf2ea3f88a6f6610c6fc3ac709ce05540dcef111.tar.xz
kea-cf2ea3f88a6f6610c6fc3ac709ce05540dcef111.zip
[2051] Implement the find wrapper
However, it still needs documentation and some stuff with object lifetime management.
-rw-r--r--src/lib/python/isc/datasrc/client_python.cc11
-rw-r--r--src/lib/python/isc/datasrc/client_python.h3
-rw-r--r--src/lib/python/isc/datasrc/configurableclientlist_python.cc53
-rw-r--r--src/lib/python/isc/datasrc/tests/clientlist_test.py61
4 files changed, 125 insertions, 3 deletions
diff --git a/src/lib/python/isc/datasrc/client_python.cc b/src/lib/python/isc/datasrc/client_python.cc
index c237115f89..7754d799e0 100644
--- a/src/lib/python/isc/datasrc/client_python.cc
+++ b/src/lib/python/isc/datasrc/client_python.cc
@@ -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
diff --git a/src/lib/python/isc/datasrc/client_python.h b/src/lib/python/isc/datasrc/client_python.h
index b20fb6b4c7..b30c0fb18e 100644
--- a/src/lib/python/isc/datasrc/client_python.h
+++ b/src/lib/python/isc/datasrc/client_python.h
@@ -25,6 +25,9 @@ namespace python {
extern PyTypeObject datasourceclient_type;
+// TODO: Documentation, warning
+PyObject* wrapDataSourceClient(DataSourceClient* client);
+
} // namespace python
} // namespace datasrc
} // namespace isc
diff --git a/src/lib/python/isc/datasrc/configurableclientlist_python.cc b/src/lib/python/isc/datasrc/configurableclientlist_python.cc
index b77be24d2a..ddca636825 100644
--- a/src/lib/python/isc/datasrc/configurableclientlist_python.cc
+++ b/src/lib/python/isc/datasrc/configurableclientlist_python.cc
@@ -26,12 +26,15 @@
#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
diff --git a/src/lib/python/isc/datasrc/tests/clientlist_test.py b/src/lib/python/isc/datasrc/tests/clientlist_test.py
index e7219e9b27..334042ffaf 100644
--- a/src/lib/python/isc/datasrc/tests/clientlist_test.py
+++ b/src/lib/python/isc/datasrc/tests/clientlist_test.py
@@ -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()