diff options
author | Michal 'vorner' Vaner <michal.vaner@nic.cz> | 2012-07-17 11:58:06 +0200 |
---|---|---|
committer | Michal 'vorner' Vaner <michal.vaner@nic.cz> | 2012-07-17 11:58:06 +0200 |
commit | cf2ea3f88a6f6610c6fc3ac709ce05540dcef111 (patch) | |
tree | f6901a5706e06cde07d21f1c9f3f5753ac41c109 | |
parent | [2051] Change the internals of DataSourceClient wrapper (diff) | |
download | kea-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.cc | 11 | ||||
-rw-r--r-- | src/lib/python/isc/datasrc/client_python.h | 3 | ||||
-rw-r--r-- | src/lib/python/isc/datasrc/configurableclientlist_python.cc | 53 | ||||
-rw-r--r-- | src/lib/python/isc/datasrc/tests/clientlist_test.py | 61 |
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() |