[svn] commit: r2859 - in /branches/trac232/src/lib/datasrc/python: libdata_source_python.cc tests/data_source_python_test.py

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Sep 8 10:18:41 UTC 2010


Author: jelte
Date: Wed Sep  8 10:18:41 2010
New Revision: 2859

Log:
findRRset()
also added a number of conversion functions, which should probably be moved to a more general location

Modified:
    branches/trac232/src/lib/datasrc/python/libdata_source_python.cc
    branches/trac232/src/lib/datasrc/python/tests/data_source_python_test.py

Modified: branches/trac232/src/lib/datasrc/python/libdata_source_python.cc
==============================================================================
--- branches/trac232/src/lib/datasrc/python/libdata_source_python.cc (original)
+++ branches/trac232/src/lib/datasrc/python/libdata_source_python.cc Wed Sep  8 10:18:41 2010
@@ -22,6 +22,10 @@
 
 #include <datasrc/data_source.h>
 #include <datasrc/sqlite3_datasrc.h>
+#include <dns/rrsetlist.h>
+#include <dns/rrset.h>
+
+#include <boost/foreach.hpp>
 
 using namespace isc::datasrc;
 
@@ -69,6 +73,7 @@
 static PyObject* DataSrc_getClass(s_DataSrc* self);
 static PyObject* DataSrc_init(s_DataSrc* self, PyObject *args);
 static PyObject* DataSrc_close(s_DataSrc* self);
+static PyObject* DataSrc_findRRset(s_DataSrc* self, PyObject* args);
 static PyObject* DataSrc_startTransaction(s_DataSrc* self, PyObject* args);
 static PyObject* DataSrc_commitTransaction(s_DataSrc* self, PyObject* args);
 static PyObject* DataSrc_rollbackTransaction(s_DataSrc* self, PyObject* args);
@@ -80,6 +85,8 @@
       "Initializes the data source" },
     { "close", reinterpret_cast<PyCFunction>(DataSrc_close), METH_NOARGS,
       "Closes the data source" },
+    { "find_rrset", reinterpret_cast<PyCFunction>(DataSrc_findRRset), METH_VARARGS,
+      "Searches the datasource for an RRset" },
     { "start_transaction", reinterpret_cast<PyCFunction>(DataSrc_startTransaction), METH_VARARGS,
       "Start a transaction" },
     { "commit_transaction", reinterpret_cast<PyCFunction>(DataSrc_commitTransaction), METH_VARARGS,
@@ -244,6 +251,160 @@
     Py_TYPE(self)->tp_free(self);
 }
 
+/* conversion functions, also usable by other modules
+ * (TODO: move to separate file)
+ */
+isc::dns::Name
+pyName_AsName(PyObject* name_obj)
+{
+    PyObject* name_obj_str = PyObject_CallMethod(name_obj, "to_text", NULL);
+    const char* name_str = PyBytes_AS_STRING(PyUnicode_AsUTF8String(name_obj_str));
+    return isc::dns::Name(name_str);
+}
+
+// do we need this one?
+/*
+const char *
+pyName_AsString(PyObject* name_obj)
+{
+    PyObject* name_obj_str = PyObject_CallMethod(name_obj, "to_text", NULL);
+    return PyBytes_AS_STRING(PyUnicode_AsUTF8String(name_obj_str));
+}
+*/
+
+PyObject*
+pyName_FromString(const char* name_str)
+{
+    PyObject* name_class = PyObject_GetAttrString(po_DNS_module, "Name");
+    PyObject* name = PyObject_CallObject(name_class, Py_BuildValue("(s)", name_str));
+    Py_DECREF(name_class);
+    return name;
+}
+
+PyObject*
+pyName_FromName(const isc::dns::Name& name)
+{
+    return pyName_FromString(name.toText().c_str());
+}
+
+isc::dns::RRClass
+pyRRClass_AsRRClass(PyObject* rrclass_obj)
+{
+    PyObject* rrclass_obj_str = PyObject_CallMethod(rrclass_obj, "to_text", NULL);
+    const char* rrclass_str = PyBytes_AS_STRING(PyUnicode_AsUTF8String(rrclass_obj_str));
+    return isc::dns::RRClass(rrclass_str);
+}
+
+PyObject*
+pyRRClass_FromString(const char* rrclass_str)
+{
+    PyObject* rrclass_class = PyObject_GetAttrString(po_DNS_module, "RRClass");
+    PyObject* rrclass = PyObject_CallObject(rrclass_class, Py_BuildValue("(s)", rrclass_str));
+    Py_DECREF(rrclass_class);
+    return rrclass;
+}
+
+PyObject*
+pyRRClass_FromRRClass(const isc::dns::RRClass& rrclass)
+{
+    return pyRRClass_FromString(rrclass.toText().c_str());
+}
+
+PyObject*
+pyRRType_FromString(const char* rrtype_str)
+{
+    PyObject* rrtype_class = PyObject_GetAttrString(po_DNS_module, "RRType");
+    PyObject* rrtype = PyObject_CallObject(rrtype_class, Py_BuildValue("(s)", rrtype_str));
+    Py_DECREF(rrtype_class);
+    return rrtype;
+}
+
+PyObject*
+pyRRType_FromRRType(const isc::dns::RRType& rrtype)
+{
+    return pyRRType_FromString(rrtype.toText().c_str());
+}
+
+isc::dns::RRType
+pyRRType_AsRRType(PyObject* rrtype_obj)
+{
+    PyObject* rrtype_obj_str = PyObject_CallMethod(rrtype_obj, "to_text", NULL);
+    const char* rrtype_str = PyBytes_AS_STRING(PyUnicode_AsUTF8String(rrtype_obj_str));
+    return isc::dns::RRType(rrtype_str);
+}
+
+PyObject*
+pyRRTTL_FromString(const char* rrttl_str)
+{
+    PyObject* rrttl_class = PyObject_GetAttrString(po_DNS_module, "RRTTL");
+    PyObject* rrttl = PyObject_CallObject(rrttl_class, Py_BuildValue("(s)", rrttl_str));
+    Py_DECREF(rrttl_class);
+    return rrttl;
+}
+
+PyObject*
+pyRRTTL_FromRRTTL(const isc::dns::RRTTL& rrttl)
+{
+    return pyRRTTL_FromString(rrttl.toText().c_str());
+}
+
+isc::dns::RRTTL
+pyRRTTL_AsRRTTL(PyObject* rrttl_obj)
+{
+    PyObject* rrttl_obj_str = PyObject_CallMethod(rrttl_obj, "to_text", NULL);
+    const char* rrttl_str = PyBytes_AS_STRING(PyUnicode_AsUTF8String(rrttl_obj_str));
+    return isc::dns::RRTTL(rrttl_str);
+}
+
+PyObject*
+pyRdata_createRdata(const isc::dns::RRType& rrtype, const isc::dns::RRClass& rrclass, const isc::dns::rdata::Rdata& rdata) {
+    PyObject* rdata_class = PyObject_GetAttrString(po_DNS_module, "Rdata");
+    PyObject* type_obj = pyRRType_FromRRType(rrtype);
+    PyObject* class_obj = pyRRClass_FromRRClass(rrclass);
+    PyObject* rdata_obj = PyObject_CallObject(rdata_class,
+                                   Py_BuildValue("(OOs)",
+                                                 type_obj,
+                                                 class_obj,
+                                                 rdata.toText().c_str()));
+    Py_DECREF(rdata_class);
+    Py_DECREF(type_obj);
+    Py_DECREF(class_obj);
+    return rdata_obj;
+}
+
+PyObject*
+pyRRset_FromRRset(const isc::dns::RRset& rrset)
+{
+    PyObject* rrset_class = PyObject_GetAttrString(po_DNS_module, "RRset");
+    PyObject* name_obj = pyName_FromName(rrset.getName());
+    PyObject* rrclass_obj = pyRRClass_FromRRClass(rrset.getClass());
+    PyObject* rrtype_obj = pyRRType_FromRRType(rrset.getType());
+    PyObject* rrttl_obj = pyRRTTL_FromRRTTL(rrset.getTTL());
+    
+    PyObject* rrset_obj = PyObject_CallObject(rrset_class,
+                                              Py_BuildValue("OOOO",
+                                              name_obj,
+                                              rrclass_obj,
+                                              rrtype_obj,
+                                              rrttl_obj));
+
+    Py_DECREF(rrset_class);
+    Py_DECREF(name_obj);
+    Py_DECREF(rrclass_obj);
+    Py_DECREF(rrtype_obj);
+    Py_DECREF(rrttl_obj);
+
+    isc::dns::RdataIteratorPtr it = rrset.getRdataIterator();
+    for (it->first(); !it->isLast(); it->next()) {
+        PyObject* rdata_obj = pyRdata_createRdata(rrset.getType(), rrset.getClass(), it->getCurrent());
+        PyObject_CallMethod(rrset_obj, "add_rdata", "O", rdata_obj);
+        Py_DECREF(rdata_obj);
+    }
+    return rrset_obj;
+}
+
+/* end of conversion functions */
+
 static PyObject*
 DataSrc_init(s_DataSrc* self, PyObject* args)
 {
@@ -278,6 +439,51 @@
         return (Py_BuildValue("I", self->datasrc->close()));
     } catch (DataSourceError dse) {
         PyErr_SetString(po_DataSrcError, dse.what());
+        return (NULL);
+    }
+}
+
+static PyObject*
+DataSrc_findRRset(s_DataSrc* self, PyObject* args) {
+    PyObject* name_class = PyObject_GetAttrString(po_DNS_module, "Name");
+    PyObject* rrclass_class = PyObject_GetAttrString(po_DNS_module, "RRClass");
+    PyObject* rrtype_class = PyObject_GetAttrString(po_DNS_module, "RRType");
+    PyObject *name_obj, *class_obj, *type_obj, *result_list_obj, *zone_name_obj;
+    uint32_t flags;
+    int args_check = PyArg_ParseTuple(args, "O!O!O!OIO!",
+                         name_class, &name_obj,
+                         rrclass_class, &class_obj,
+                         rrtype_class, &type_obj,
+                         &result_list_obj,
+                         &flags,
+                         name_class, &zone_name_obj);
+    Py_DECREF(name_class);
+    Py_DECREF(rrclass_class);
+    Py_DECREF(rrtype_class);
+       
+    if (args_check) {
+        if (!PyList_Check(result_list_obj)) {
+            PyErr_SetString(PyExc_TypeError,
+                            "argument 4 of find_rrset is not a List");
+            return (NULL);
+        }
+        isc::dns::Name n = pyName_AsName(name_obj);
+        isc::dns::RRClass c = pyRRClass_AsRRClass(class_obj);
+        isc::dns::RRType t = pyRRType_AsRRType(type_obj);
+        isc::dns::Name zone_name = pyName_AsName(zone_name_obj);
+        
+        isc::dns::RRsetList result_list;
+        isc::datasrc::DataSrc::Result result =
+                self->datasrc->findRRset(n, c, t, result_list,
+                                         flags, &zone_name);
+
+        BOOST_FOREACH(isc::dns::RRsetPtr rrs, result_list) {
+            PyObject *rrset_obj = pyRRset_FromRRset(*rrs);
+            PyList_Append(result_list_obj, rrset_obj);
+            Py_DECREF(rrset_obj);
+        }
+        return Py_BuildValue("I", result);
+    } else {
         return (NULL);
     }
 }

Modified: branches/trac232/src/lib/datasrc/python/tests/data_source_python_test.py
==============================================================================
--- branches/trac232/src/lib/datasrc/python/tests/data_source_python_test.py (original)
+++ branches/trac232/src/lib/datasrc/python/tests/data_source_python_test.py Wed Sep  8 10:18:41 2010
@@ -21,42 +21,91 @@
 import sys
 import os
 from libdata_source_python import *
-from libdns_python import Name, RRClass
+from libdns_python import *
 
 class DataSourceTest(unittest.TestCase):
+    def setUp(self):
+        self.ds = DataSrc()
+        
     def test_init_close(self):
-        ds = DataSrc()
-        self.assertRaises(DataSrcError, ds.close)
-        self.assertRaises(TypeError, ds.close, 1)
+        self.assertRaises(DataSrcError, self.ds.close)
+        self.assertRaises(TypeError, self.ds.close, 1)
         print(testdata_path)
-        self.assertRaises(DataSrcError, ds.init, 1)
-        self.assertRaises(DataSrcError, ds.init, "{")
-        self.assertRaises(DataSrcError, ds.init, "{ \"database_file\": \"/ badfilename /\" }")
-        self.assertRaises(DataSrcError, ds.init, "{ \"database_file\": \"/brokendb.sqlite3\" }")
-        ds.init("{ \"database_file\": \""+ testdata_path + "/example2.com.sqlite3\" }")
-        self.assertEqual(0, ds.close())
+        self.assertRaises(DataSrcError, self.ds.init, 1)
+        self.assertRaises(DataSrcError, self.ds.init, "{")
+        self.assertRaises(DataSrcError, self.ds.init, "{ \"database_file\": \"/ badfilename /\" }")
+        self.assertRaises(DataSrcError, self.ds.init, "{ \"database_file\": \"/brokendb.sqlite3\" }")
+        self.ds.init("{ \"database_file\": \""+ testdata_path + "/example.org.sqlite3\" }")
+        self.assertEqual(0, self.ds.close())
 
     def test_get_class(self):
-        ds = DataSrc()
-        self.assertEqual(RRClass("IN"), ds.get_class())
+        self.assertEqual(RRClass("IN"), self.ds.get_class())
+
+    def test_find_rrset(self):
+        self.ds.init("{ \"database_file\": \""+ testdata_path + "/example.org.sqlite3\" }")
+        result = []
+        n = self.ds.find_rrset(Name("www.example.org"), RRClass.IN(), RRType.A(), result, 0, Name("example.org"))
+        self.assertEqual(DataSrc.SUCCESS, n);
+        self.assertEqual(1, len(result))
+        self.assertEqual("www.example.org. 3600 IN A 192.0.2.1\n", str(result[0]))
+
+        result = []
+        n = self.ds.find_rrset(Name("doesnotexist.example.org"), RRClass.IN(), RRType.A(), result, 0, Name("example.org"))
+        self.assertEqual(DataSrc.SUCCESS, n);
+        self.assertEqual(0, len(result))
+
+        result = []
+        n = self.ds.find_rrset(Name("www.doesnotexist.org"), RRClass.IN(), RRType.A(), result, 0, Name("doesnotexist.org"))
+        self.assertEqual(DataSrc.SUCCESS, n);
+        self.assertEqual(0, len(result))
+
+        self.assertRaises(TypeError, self.ds.find_rrset);
+        self.assertRaises(TypeError, self.ds.find_rrset,
+                                     Name("www.doesnotexist.org"),
+                                     RRClass.IN(), RRType.A(), 0,
+                                     0, Name("doesnotexist.org"));
+
+class DataSourceWriteTest(unittest.TestCase):
+    def setUp(self):
+        install_writable_database()
+        self.ds = DataSrc()
+        self.ds.init("{ \"database_file\": \""+ testdata_out_path + "/write_test.sqlite3\" }")
 
     def test_transaction(self):
-        install_writable_database()
         
-        ds = DataSrc()
-        ds.init("{ \"database_file\": \""+ testdata_out_path + "/write_test.sqlite3\" }")
+        self.assertRaises(TypeError, self.ds.start_transaction)
+        self.assertRaises(TypeError, self.ds.start_transaction, 1)
+        self.assertRaises(TypeError, self.ds.start_transaction, 1, RRClass.IN())
+        self.assertRaises(TypeError, self.ds.start_transaction, Name("example.com"), 1)
+
+        transaction = DataSrcTransaction(self.ds, Name("example.com"), RRClass.IN())
+        self.assertEqual(DataSrcTransaction.INIT, transaction.get_state())
+
+        result = self.ds.start_transaction(transaction)
+        self.assertEqual(DataSrc.T_SUCCESS, result)
+        self.assertEqual(DataSrcTransaction.RUNNING, transaction.get_state())
+
+        self.ds.rollback_transaction(transaction)
+        self.assertEqual(DataSrcTransaction.DONE, transaction.get_state())
+
+        transaction = DataSrcTransaction(self.ds, Name("doesnotexist.com"), RRClass.IN())
+        result = self.ds.start_transaction(transaction)
+        self.assertEqual(DataSrc.T_NO_SUCH_ZONE, result)
+        self.assertEqual(DataSrcTransaction.INIT, transaction.get_state())
+
+    def test_add_rrset(self):
+        rrset = RRset(Name("pythontest.example.com"), RRClass.IN(), RRType.A(), RRTTL(3600))
         
-        self.assertRaises(TypeError, ds.start_transaction)
-        self.assertRaises(TypeError, ds.start_transaction, 1)
+        transaction = DataSrcTransaction(self.ds, Name("example.com"), RRClass.IN())
+        self.assertEqual(DataSrcTransaction.INIT, transaction.get_state())
 
-        transaction1 = DataSrcTransaction(ds, Name("example.com"), RRClass.IN())
-        self.assertEqual(DataSrcTransaction.INIT, transaction1.get_state())
+        result = self.ds.start_transaction(transaction)
+        self.assertEqual(DataSrc.T_SUCCESS, result)
 
-        ds.start_transaction(transaction1)
-        self.assertEqual(DataSrcTransaction.RUNNING, transaction1.get_state())
+        #result = self.ds.add_rrset(transaction, rrset)
+        self.assertEqual(DataSrc.T_SUCCESS, result)
 
-        ds.rollback_transaction(transaction1)
-        self.assertEqual(DataSrcTransaction.DONE, transaction1.get_state())
+        self.ds.rollback_transaction(transaction)
 
 
 # helper functions for tests taken from c++ unittests




More information about the bind10-changes mailing list