datasrc_la_SOURCES += journal_reader_python.cc journal_reader_python.h
datasrc_la_SOURCES += configurableclientlist_python.cc
datasrc_la_SOURCES += configurableclientlist_python.h
+datasrc_la_SOURCES += zone_loader_python.cc zone_loader_python.h
datasrc_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
datasrc_la_CXXFLAGS = $(AM_CXXFLAGS) $(PYTHON_CXXFLAGS)
import os
# The datasource factory loader uses dlopen, as does python
-# for its modules. Some dynamic linkers do not play nice if
+# for its modules. Some dynamic linkers do not play nice if
# modules are not loaded with RTLD_GLOBAL, a symptom of which
# is that exceptions are not recognized by type. So to make
# sure this doesn't happen, we temporarily set RTLD_GLOBAL
sys.setdlopenflags(flags)
from isc.datasrc.sqlite3_ds import *
-from isc.datasrc.master import *
return (container.release());
}
+DataSourceClient&
+PyDataSourceClient_ToDataSourceClient(PyObject* client_obj) {
+ if (client_obj == NULL) {
+ isc_throw(PyCPPWrapperException,
+ "obj argument NULL in Name PyObject conversion");
+ }
+ const s_DataSourceClient* client = static_cast<const s_DataSourceClient*>(client_obj);
+ return (*client->client);
+}
+
} // namespace python
} // namespace datasrc
} // namespace isc
LifeKeeper>& life_keeper = boost::shared_ptr<ClientList::
FindResult::LifeKeeper>());
+DataSourceClient&
+PyDataSourceClient_ToDataSourceClient(PyObject* client_obj);
+
} // namespace python
} // namespace datasrc
} // namespace isc
#include "updater_python.h"
#include "journal_reader_python.h"
#include "configurableclientlist_python.h"
+#include "zone_loader_python.h"
#include <util/python/pycppwrapper_util.h>
#include <dns/python/pydnspp_common.h>
return (true);
}
+bool
+initModulePart_ZoneLoader(PyObject* mod) {
+ // We initialize the static description object with PyType_Ready(),
+ // then add it to the module. This is not just a check! (leaving
+ // this out results in segmentation faults)
+ if (PyType_Ready(&zone_loader_type) < 0) {
+ return (false);
+ }
+ void* p = &zone_loader_type;
+ if (PyModule_AddObject(mod, "ZoneLoader",
+ static_cast<PyObject*>(p)) < 0) {
+ return (false);
+ }
+ Py_INCREF(&zone_loader_type);
+
+ return (true);
+}
+
bool
initModulePart_ZoneUpdater(PyObject* mod) {
// We initialize the static description object with PyType_Ready(),
}
PyObject* po_DataSourceError;
-PyObject* po_OutOfZone;
+PyObject* po_MasterFileError;
PyObject* po_NotImplemented;
+PyObject* po_OutOfZone;
PyModuleDef iscDataSrc = {
{ PyObject_HEAD_INIT(NULL) NULL, 0, NULL},
return (NULL);
}
+ try {
+ po_DataSourceError = PyErr_NewException("isc.datasrc.Error", NULL,
+ NULL);
+ PyObjectContainer(po_DataSourceError).installToModule(mod, "Error");
+ po_MasterFileError = PyErr_NewException("isc.datasrc.MasterFileError",
+ po_DataSourceError, NULL);
+ PyObjectContainer(po_MasterFileError).installToModule(mod,
+ "MasterFileError");
+ po_OutOfZone = PyErr_NewException("isc.datasrc.OutOfZone", NULL, NULL);
+ PyObjectContainer(po_OutOfZone).installToModule(mod, "OutOfZone");
+ po_NotImplemented = PyErr_NewException("isc.datasrc.NotImplemented",
+ NULL, NULL);
+ PyObjectContainer(po_NotImplemented).installToModule(mod,
+ "NotImplemented");
+
+ } catch (...) {
+ Py_DECREF(mod);
+ return (NULL);
+ }
+
if (!initModulePart_DataSourceClient(mod)) {
Py_DECREF(mod);
return (NULL);
return (NULL);
}
- try {
- po_DataSourceError = PyErr_NewException("isc.datasrc.Error", NULL,
- NULL);
- PyObjectContainer(po_DataSourceError).installToModule(mod, "Error");
- po_OutOfZone = PyErr_NewException("isc.datasrc.OutOfZone", NULL, NULL);
- PyObjectContainer(po_OutOfZone).installToModule(mod, "OutOfZone");
- po_NotImplemented = PyErr_NewException("isc.datasrc.NotImplemented",
- NULL, NULL);
- PyObjectContainer(po_NotImplemented).installToModule(mod,
- "NotImplemented");
- } catch (...) {
+ if (!initModulePart_ZoneLoader(mod)) {
Py_DECREF(mod);
return (NULL);
}
if paren == 1 or not record:
continue
-
+
ret = ' '.join(record)
record = []
oldsize = size
PYCOVERAGE_RUN = @PYCOVERAGE_RUN@
# old tests, TODO remove or change to use new API?
#PYTESTS = master_test.py
-PYTESTS = datasrc_test.py sqlite3_ds_test.py clientlist_test.py
+PYTESTS = datasrc_test.py sqlite3_ds_test.py
+PYTESTS += clientlist_test.py zone_loader_test.py
EXTRA_DIST = $(PYTESTS)
EXTRA_DIST += testdata/brokendb.sqlite3
--- /dev/null
+# Copyright (C) 2012 Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import isc.datasrc
+import isc.dns
+
+import os
+import unittest
+
+TESTDATA_PATH = os.environ['TESTDATA_PATH'] + os.sep
+TESTDATA_WRITE_PATH = os.environ['TESTDATA_WRITE_PATH'] + os.sep
+
+READ_ZONE_DB_FILE = TESTDATA_PATH + "example.com.sqlite3"
+WRITE_ZONE_DB_FILE = TESTDATA_WRITE_PATH + "rwtest.sqlite3.copied"
+
+READ_ZONE_DB_CONFIG = "{ \"database_file\": \"" + READ_ZONE_DB_FILE + "\" }"
+WRITE_ZONE_DB_CONFIG = "{ \"database_file\": \"" + WRITE_ZONE_DB_FILE + "\"}"
+
+class ZoneLoaderTests(unittest.TestCase):
+ def setUp(self):
+ self.test_name = isc.dns.Name("example.com")
+ self.test_file = "foo.txt"
+ self.client = isc.datasrc.DataSourceClient("sqlite3", WRITE_ZONE_DB_CONFIG)
+
+ def test_bad_constructor(self):
+ self.assertRaises(TypeError, isc.datasrc.ZoneLoader)
+ self.assertRaises(TypeError, isc.datasrc.ZoneLoader, 1)
+ self.assertRaises(TypeError, isc.datasrc.ZoneLoader,
+ None, self.test_name, self.test_file)
+ self.assertRaises(TypeError, isc.datasrc.ZoneLoader,
+ self.client, None, self.test_file)
+ self.assertRaises(TypeError, isc.datasrc.ZoneLoader,
+ self.client, self.test_name, None)
+ self.assertRaises(TypeError, isc.datasrc.ZoneLoader,
+ self.client, self.test_name, self.test_file, 1)
+
+ def test_load_file(self):
+ #self.assertRaises(TypeError, isc.datasrc.ZoneLoader());
+ loader = isc.datasrc.ZoneLoader(self.client, self.test_name, self.test_file)
+ # This would currently loop
+ #loader.load()
+
+ def test_bad_file(self):
+ #self.assertRaises(TypeError, isc.datasrc.ZoneLoader());
+ loader = isc.datasrc.ZoneLoader(self.client, self.test_name, "no such file")
+ # This would currently loop
+ #loader.load()
+
+ def test_exception(self):
+ # Just check if masterfileerror is subclass of datasrc.Error
+ self.assertTrue(issubclass(isc.datasrc.MasterFileError,
+ isc.datasrc.Error))
+
+if __name__ == "__main__":
+ isc.log.init("bind10")
+ isc.log.resetUnitTestRootLogger()
+ unittest.main()
--- /dev/null
+namespace {
+const char* const ZoneLoader_doc = "\
+\n\
+\n\
+";
+
+const char* const ZoneLoader_loadIncremental_doc = "\
+\n\
+\n\
+";
+
+const char* const ZoneLoader_load_doc = "\
+\n\
+\n\
+";
+
+} // unnamed namespace
--- /dev/null
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+// Enable this if you use s# variants with PyArg_ParseTuple(), see
+// http://docs.python.org/py3k/c-api/arg.html#strings-and-buffers
+//#define PY_SSIZE_T_CLEAN
+
+// Python.h needs to be placed at the head of the program file, see:
+// http://docs.python.org/py3k/extending/extending.html#a-simple-example
+#include <Python.h>
+
+#include <util/python/pycppwrapper_util.h>
+
+#include <datasrc/client.h>
+#include <datasrc/database.h>
+#include <datasrc/data_source.h>
+#include <datasrc/sqlite3_accessor.h>
+#include <datasrc/iterator.h>
+#include <datasrc/zone.h>
+#include <datasrc/zone_loader.h>
+
+#include <dns/python/name_python.h>
+//#include <dns/python/rrset_python.h>
+//#include <dns/python/rrclass_python.h>
+//#include <dns/python/rrtype_python.h>
+#include <dns/python/pydnspp_common.h>
+
+#include "client_python.h"
+#include "datasrc.h"
+#include "zone_loader_inc.cc"
+
+using namespace std;
+using namespace isc::util::python;
+using namespace isc::dns::python;
+using namespace isc::datasrc;
+using namespace isc::datasrc::python;
+
+namespace {
+// The s_* Class simply covers one instantiation of the object
+class s_ZoneLoader : public PyObject {
+public:
+ s_ZoneLoader() : cppobj(NULL) {};
+ ZoneLoader* cppobj;
+};
+
+// Shortcut type which would be convenient for adding class variables safely.
+typedef CPPPyObjectContainer<s_ZoneLoader, ZoneLoader> ZoneLoaderContainer;
+
+// General creation and destruction
+int
+ZoneLoader_init(PyObject* po_self, PyObject* args, PyObject*) {
+ s_ZoneLoader* self = static_cast<s_ZoneLoader*>(po_self);
+ PyObject *po_ds_client;
+ PyObject *po_name;
+ char* master_file;
+ if (PyArg_ParseTuple(args, "O!O!s", &datasourceclient_type, &po_ds_client, &name_type, &po_name, &master_file)) {
+ try {
+ self->cppobj = new ZoneLoader(PyDataSourceClient_ToDataSourceClient(po_ds_client), PyName_ToName(po_name), master_file);
+ return (0);
+ } catch (const isc::datasrc::MasterFileError& mfe) {
+ PyErr_SetString(getDataSourceException("MasterFileError"), mfe.what());
+ } catch (const isc::datasrc::DataSourceError& dse) {
+ PyErr_SetString(getDataSourceException("Error"), dse.what());
+ } catch (const isc::NotImplemented& ni) {
+ PyErr_SetString(getDataSourceException("NotImplemented"), ni.what());
+ } catch (const std::exception& stde) {
+ PyErr_SetString(getDataSourceException("Error"), stde.what());
+ } catch (...) {
+ PyErr_SetString(getDataSourceException("Error"),
+ "Unexpected exception");
+ }
+ }
+ return (-1);
+}
+
+void
+ZoneLoader_destroy(PyObject* po_self) {
+ s_ZoneLoader* self = static_cast<s_ZoneLoader*>(po_self);
+ delete self->cppobj;
+ self->cppobj = NULL;
+ Py_TYPE(self)->tp_free(self);
+}
+
+PyObject* ZoneLoader_load(PyObject* po_self, PyObject*) {
+ s_ZoneLoader* self = static_cast<s_ZoneLoader*>(po_self);
+ try {
+ self->cppobj->load();
+ Py_RETURN_NONE;
+ } catch (const isc::datasrc::MasterFileError& mfe) {
+ PyErr_SetString(getDataSourceException("MasterFileError"), mfe.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);
+ }
+}
+
+// This list contains the actual set of functions we have in
+// python. Each entry has
+// 1. Python method name
+// 2. Our static function here
+// 3. Argument type
+// 4. Documentation
+PyMethodDef ZoneLoader_methods[] = {
+/*
+ { "get_origin", ZoneLoader_getOrigin, METH_NOARGS,
+ ZoneLoader_getOrigin_doc },
+ { "get_class", ZoneLoader_getClass, METH_NOARGS, ZoneLoader_getClass_doc },
+ { "find", ZoneLoader_find, METH_VARARGS, ZoneLoader_find_doc },
+ { "find_all", ZoneLoader_find_all, METH_VARARGS, ZoneLoader_findAll_doc },
+*/
+ { "load", ZoneLoader_load, METH_NOARGS, ZoneLoader_load_doc },
+ { NULL, NULL, 0, NULL }
+};
+
+} // end of unnamed namespace
+
+namespace isc {
+namespace datasrc {
+namespace python {
+
+PyTypeObject zone_loader_type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "datasrc.ZoneLoader",
+ sizeof(s_ZoneLoader), // tp_basicsize
+ 0, // tp_itemsize
+ ZoneLoader_destroy, // tp_dealloc
+ NULL, // tp_print
+ NULL, // tp_getattr
+ NULL, // tp_setattr
+ NULL, // tp_reserved
+ NULL, // tp_repr
+ NULL, // tp_as_number
+ NULL, // tp_as_sequence
+ NULL, // tp_as_mapping
+ NULL, // tp_hash
+ NULL, // tp_call
+ NULL, // tp_str
+ NULL, // tp_getattro
+ NULL, // tp_setattro
+ NULL, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
+ ZoneLoader_doc,
+ NULL, // tp_traverse
+ NULL, // tp_clear
+ NULL, // tp_richcompare
+ 0, // tp_weaklistoffset
+ NULL, // tp_iter
+ NULL, // tp_iternext
+ ZoneLoader_methods, // tp_methods
+ NULL, // tp_members
+ NULL, // tp_getset
+ NULL, // tp_base
+ NULL, // tp_dict
+ NULL, // tp_descr_get
+ NULL, // tp_descr_set
+ 0, // tp_dictoffset
+ ZoneLoader_init, // tp_init
+ NULL, // tp_alloc
+ PyType_GenericNew, // tp_new
+ NULL, // tp_free
+ NULL, // tp_is_gc
+ NULL, // tp_bases
+ NULL, // tp_mro
+ NULL, // tp_cache
+ NULL, // tp_subclasses
+ NULL, // tp_weaklist
+ NULL, // tp_del
+ 0 // tp_version_tag
+};
+
+PyObject* po_MasterFileError;
+
+} // namespace python
+} // namespace datasrc
+} // namespace isc
+
--- /dev/null
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef PYTHON_DATASRC_ZONE_LOADER_H
+#define PYTHON_DATASRC_ZONE_LOADER_H 1
+
+#include <Python.h>
+
+namespace isc {
+namespace datasrc {
+
+namespace python {
+
+extern PyTypeObject zone_loader_type;
+
+} // namespace python
+} // namespace datasrc
+} // namespace isc
+#endif // PYTHON_DATASRC_ZONE_LOADER_H
+
+// Local Variables:
+// mode: c++
+// End: