[svn] commit: r1947 - in /experiments/python-binding/src/lib/dns/python: ./ tests/

BIND 10 source code commits bind10-changes at lists.isc.org
Thu May 27 12:59:51 UTC 2010


Author: jelte
Date: Thu May 27 12:59:51 2010
New Revision: 1947

Log:
We need tests. Lots of tests.
Not complete yet, but getting there

Added:
    experiments/python-binding/src/lib/dns/python/tests/messagerenderer_python_test.py
    experiments/python-binding/src/lib/dns/python/tests/name_python_test.py
    experiments/python-binding/src/lib/dns/python/tests/rdata_python_test.py
    experiments/python-binding/src/lib/dns/python/tests/rrclass_python_test.py
    experiments/python-binding/src/lib/dns/python/tests/rrttl_python_test.py
Modified:
    experiments/python-binding/src/lib/dns/python/TODO
    experiments/python-binding/src/lib/dns/python/libdns_python.cc
    experiments/python-binding/src/lib/dns/python/message_python.cc
    experiments/python-binding/src/lib/dns/python/name_python.cc
    experiments/python-binding/src/lib/dns/python/rrclass_python.cc
    experiments/python-binding/src/lib/dns/python/tests/Makefile.am
    experiments/python-binding/src/lib/dns/python/tests/message_python_test.py
    experiments/python-binding/src/lib/dns/python/tests/question_python_test.py

Modified: experiments/python-binding/src/lib/dns/python/TODO
==============================================================================
--- experiments/python-binding/src/lib/dns/python/TODO (original)
+++ experiments/python-binding/src/lib/dns/python/TODO Thu May 27 12:59:51 2010
@@ -5,6 +5,9 @@
 same for RRType? (xfrout.py.in line 256)
 
 __str__ for name, question, everything with to_text()
+rich compare for name (at least so we can have ==)
+
+should Name.downcase() return a ref to itself?
 
 All constructors based on buffers need an optional position
 argument (like question_python has now)
@@ -13,3 +16,15 @@
 value seems correct, while i'd like in-place addition if possible)
 
 creating a render message and not setting opcode/rcode results in a segfault later (nullpointer)
+
+
+The function set wrapped is not complete; for instance, in
+MessageRenderer, we really only provide the high-level readout
+functions. Do we need access to the writers? (there is one set() right
+now).
+
+All constants are now added named in the base module, while they should
+be added as class constants. Dunno how though.
+
+
+segfault when comparing with bad type like int (at least for Name and Rcode, but probably for the rest too)

Modified: experiments/python-binding/src/lib/dns/python/libdns_python.cc
==============================================================================
--- experiments/python-binding/src/lib/dns/python/libdns_python.cc (original)
+++ experiments/python-binding/src/lib/dns/python/libdns_python.cc Thu May 27 12:59:51 2010
@@ -27,8 +27,8 @@
 
 //#include "buffer_python.cc"
 // order is important here! (TODO: document dependencies)
+#include "messagerenderer_python.cc"
 #include "name_python.cc"
-#include "messagerenderer_python.cc"
 #include "rrclass_python.cc"
 #include "rrtype_python.cc"
 #include "rrttl_python.cc"

Modified: experiments/python-binding/src/lib/dns/python/message_python.cc
==============================================================================
--- experiments/python-binding/src/lib/dns/python/message_python.cc (original)
+++ experiments/python-binding/src/lib/dns/python/message_python.cc Thu May 27 12:59:51 2010
@@ -627,7 +627,7 @@
 static PyObject* 
 Opcode_richcmp(s_Opcode* self, s_Opcode* other, int op)
 {
-    bool c;
+    bool c = false;
 
     // Only equals and not equals here, unorderable type
     switch (op) {
@@ -653,8 +653,6 @@
         PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
         return NULL;
         break;
-    default:
-        assert(0);              // XXX: should trigger an exception
     }
     if (c)
         Py_RETURN_TRUE;

Modified: experiments/python-binding/src/lib/dns/python/name_python.cc
==============================================================================
--- experiments/python-binding/src/lib/dns/python/name_python.cc (original)
+++ experiments/python-binding/src/lib/dns/python/name_python.cc Thu May 27 12:59:51 2010
@@ -76,9 +76,9 @@
 static PyObject* NameComparisonResult_getRelation(s_NameComparisonResult* self);
 
 static PyMethodDef NameComparisonResult_methods[] = {
-    { "getOrder", (PyCFunction)NameComparisonResult_getOrder, METH_NOARGS, "Return the order" },
-    { "getCommonLabels", (PyCFunction)NameComparisonResult_getCommonLabels, METH_NOARGS, "Return the number of common labels" },
-    { "getRelation", (PyCFunction)NameComparisonResult_getRelation, METH_NOARGS, "Return the relation" },
+    { "get_order", (PyCFunction)NameComparisonResult_getOrder, METH_NOARGS, "Return the order" },
+    { "get_common_labels", (PyCFunction)NameComparisonResult_getCommonLabels, METH_NOARGS, "Return the number of common labels" },
+    { "get_relation", (PyCFunction)NameComparisonResult_getRelation, METH_NOARGS, "Return the relation" },
     { NULL, NULL, 0, NULL }
 };
 
@@ -176,7 +176,7 @@
 static int Name_init(s_Name* self, PyObject* args);
 static void Name_destroy(s_Name* self);
 
-static PyObject* Name_toWire(s_Name* self);
+static PyObject* Name_toWire(s_Name* self, PyObject* args);
 static PyObject* Name_toText(s_Name* self);
 static PyObject* Name_getLabelCount(s_Name* self);
 static PyObject* Name_at(s_Name* self, PyObject* args);
@@ -197,7 +197,7 @@
     { "get_length", (PyCFunction)Name_getLength, METH_NOARGS, "Return the length" },
     { "get_labelcount", (PyCFunction)Name_getLabelCount, METH_NOARGS, "Return the number of labels" },
     { "to_text", (PyCFunction)Name_toText, METH_NOARGS, "Return the string representation" },
-    { "to_wire", (PyCFunction)Name_toWire, METH_NOARGS, "Return the wire format" },
+    { "to_wire", (PyCFunction)Name_toWire, METH_VARARGS, "Return the wire format" },
     { "compare", (PyCFunction)Name_compare, METH_VARARGS, "Compare" },
     { "equals", (PyCFunction)Name_equals, METH_VARARGS, "Equals" },
     { "split", (PyCFunction)Name_split, METH_VARARGS, "split" },
@@ -305,15 +305,17 @@
     }
     PyErr_Clear();
 
-    const char* b;
+    PyObject* bytes_obj;
+    const char* bytes;
     Py_ssize_t len;
-    unsigned int position;
+    unsigned int position = 0;
 
     /* fromWire */
-    if (PyArg_ParseTuple(args, "y#I|O!", &b, &len, &position,
-                         &PyBool_Type, &downcase)) {
+    if (PyArg_ParseTuple(args, "O|IO!", &bytes_obj, &position,
+                         &PyBool_Type, &downcase) &&
+                         PyObject_AsCharBuffer(bytes_obj, &bytes, &len) != -1) {
         try {
-            InputBuffer buffer(b, len);
+            InputBuffer buffer(bytes, len);
 
             buffer.setPosition(position);
             self->name = new Name(buffer, downcase == Py_True);
@@ -322,23 +324,9 @@
             PyErr_SetString(po_InvalidBufferPosition,
                             "InvalidBufferPosition");
             return -1;
-        } catch (TooLongName) {
-            PyErr_SetString(po_TooLongName, "TooLongName");
-            return -1;
-        } catch (BadLabelType) {
-            PyErr_SetString(po_BadLabelType, "BadLabelType");
-            return -1;
         } catch (DNSMessageFORMERR) {
             PyErr_SetString(po_DNSMessageFORMERR, "DNSMessageFORMERR");
             return -1;
-        } catch (IncompleteName) {
-            PyErr_SetString(po_IncompleteName, "IncompleteName");
-            return -1;
-#ifdef CATCHMEMERR
-        } catch (std::bad_alloc) {
-            PyErr_NoMemory();
-            return -1;
-#endif
         } catch (...) {
             PyErr_SetString(po_IscException, "Unexpected?!");
             return -1;
@@ -348,7 +336,7 @@
 
     PyErr_Clear();
     PyErr_SetString(PyExc_TypeError,
-                    "fromText and fromWire Name constructors don't match");
+                    "No valid types in Name constructor (should be string or sequence and offset");
     return -1;
 }
 
@@ -394,15 +382,33 @@
     return Py_BuildValue("s", self->name->toText().c_str());
 }
 
-// XX TODO: renderer and direct versions
-static PyObject*
-Name_toWire(s_Name* self)
-{
-    OutputBuffer buffer(255);
-
-    self->name->toWire(buffer);
-    return Py_BuildValue("y#", buffer.getData(),
-                         (Py_ssize_t) buffer.getLength());
+static PyObject*
+Name_toWire(s_Name* self, PyObject* args)
+{
+    PyObject* bytes;
+    s_MessageRenderer* mr;
+    
+    if (PyArg_ParseTuple(args, "O", &bytes) && PySequence_Check(bytes)) {
+        PyObject* bytes_o = bytes;
+        
+        OutputBuffer buffer(255);
+        self->name->toWire(buffer);
+        PyObject* n = PyBytes_FromStringAndSize((const char*) buffer.getData(), buffer.getLength());
+        PyObject* result = PySequence_InPlaceConcat(bytes_o, n);
+        // We need to release the object we temporarily created here
+        // to prevent memory leak
+        Py_DECREF(n);
+        return result;
+    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+        self->name->toWire(*mr->messagerenderer);
+        // If we return NULL it is seen as an error, so use this for
+        // None returns
+        Py_RETURN_NONE;
+    }
+    PyErr_Clear();
+    PyErr_SetString(PyExc_TypeError,
+                    "toWire argument must be a sequence object or a MessageRenderer");
+    return NULL;
 }
 
 static PyObject*
@@ -525,7 +531,7 @@
         try {
             ret->name = new Name(self->name->concatenate(*other->name));
         } catch (isc::dns::TooLongName tln) {
-            PyErr_SetString(PyExc_IndexError, tln.what());
+            PyErr_SetString(po_TooLongName, tln.what());
             ret->name = NULL;
         }
         if (ret->name == NULL) {

Modified: experiments/python-binding/src/lib/dns/python/rrclass_python.cc
==============================================================================
--- experiments/python-binding/src/lib/dns/python/rrclass_python.cc (original)
+++ experiments/python-binding/src/lib/dns/python/rrclass_python.cc Thu May 27 12:59:51 2010
@@ -165,15 +165,8 @@
             PyErr_Clear();
             return 0;
         }
-    } catch (IncompleteRRClass icc) {
-        // Ok so one of our functions has thrown a C++ exception.
-        // We need to translate that to a Python Exception
-        // First clear any existing error that was set
-        PyErr_Clear();
-        // Now set our own exception
-        PyErr_SetString(po_InvalidRRClass, icc.what());
-        // And return negative
-        return -1;
+    /* Incomplete is never thrown, a type error would have already been raised
+     * when we try to read the 2 bytes above */
     } catch (InvalidRRClass ic) {
         PyErr_Clear();
         PyErr_SetString(po_InvalidRRClass, ic.what());

Modified: experiments/python-binding/src/lib/dns/python/tests/Makefile.am
==============================================================================
--- experiments/python-binding/src/lib/dns/python/tests/Makefile.am (original)
+++ experiments/python-binding/src/lib/dns/python/tests/Makefile.am Thu May 27 12:59:51 2010
@@ -1,6 +1,11 @@
 PYTESTS = message_python_test.py
+PYTESTS += messagerenderer_python_test.py
+PYTESTS += name_python_test.py
 PYTESTS += question_python_test.py
+PYTESTS += rdata_python_test.py
+PYTESTS += rrclass_python_test.py
 PYTESTS += rrset_python_test.py
+PYTESTS += rrttl_python_test.py
 PYTESTS += rrtype_python_test.py
 
 EXTRA_DIST = $(PYTESTS)

Modified: experiments/python-binding/src/lib/dns/python/tests/message_python_test.py
==============================================================================
--- experiments/python-binding/src/lib/dns/python/tests/message_python_test.py (original)
+++ experiments/python-binding/src/lib/dns/python/tests/message_python_test.py Thu May 27 12:59:51 2010
@@ -21,6 +21,251 @@
 import os
 from libdns_python import *
 
+
+class MessageFlagTest(unittest.TestCase):
+    def test_init(self):
+        self.assertRaises(NotImplementedError, MessageFlag)
+
+    def test_get_bit(self):
+        self.assertEqual(0x8000, MessageFlag.QR().get_bit())
+        self.assertEqual(0x0400, MessageFlag.AA().get_bit())
+        self.assertEqual(0x0200, MessageFlag.TC().get_bit())
+        self.assertEqual(0x0100, MessageFlag.RD().get_bit())
+        self.assertEqual(0x0080, MessageFlag.RA().get_bit())
+        self.assertEqual(0x0020, MessageFlag.AD().get_bit())
+        self.assertEqual(0x0010, MessageFlag.CD().get_bit())
+
+class OpcodeTest(unittest.TestCase):
+    def test_init(self):
+        self.assertRaises(NotImplementedError, Opcode)
+
+    def test_get_code(self):
+        self.assertEqual(0, Opcode.QUERY().get_code())
+        self.assertEqual(1, Opcode.IQUERY().get_code())
+        self.assertEqual(2, Opcode.STATUS().get_code())
+        self.assertEqual(3, Opcode.RESERVED3().get_code())
+        self.assertEqual(4, Opcode.NOTIFY().get_code())
+        self.assertEqual(5, Opcode.UPDATE().get_code())
+        self.assertEqual(6, Opcode.RESERVED6().get_code())
+        self.assertEqual(7, Opcode.RESERVED7().get_code())
+        self.assertEqual(8, Opcode.RESERVED8().get_code())
+        self.assertEqual(9, Opcode.RESERVED9().get_code())
+        self.assertEqual(10, Opcode.RESERVED10().get_code())
+        self.assertEqual(11, Opcode.RESERVED11().get_code())
+        self.assertEqual(12, Opcode.RESERVED12().get_code())
+        self.assertEqual(13, Opcode.RESERVED13().get_code())
+        self.assertEqual(14, Opcode.RESERVED14().get_code())
+        self.assertEqual(15, Opcode.RESERVED15().get_code())
+
+    def test_to_text(self):
+        self.assertEqual("QUERY", Opcode.QUERY().to_text())
+        self.assertEqual("QUERY", Opcode.QUERY().__str__())
+        self.assertEqual("IQUERY", Opcode.IQUERY().to_text())
+        self.assertEqual("STATUS", Opcode.STATUS().to_text())
+        self.assertEqual("RESERVED3", Opcode.RESERVED3().to_text())
+        self.assertEqual("NOTIFY", Opcode.NOTIFY().to_text())
+        self.assertEqual("UPDATE", Opcode.UPDATE().to_text())
+        self.assertEqual("RESERVED6", Opcode.RESERVED6().to_text())
+        self.assertEqual("RESERVED7", Opcode.RESERVED7().to_text())
+        self.assertEqual("RESERVED8", Opcode.RESERVED8().to_text())
+        self.assertEqual("RESERVED9", Opcode.RESERVED9().to_text())
+        self.assertEqual("RESERVED10", Opcode.RESERVED10().to_text())
+        self.assertEqual("RESERVED11", Opcode.RESERVED11().to_text())
+        self.assertEqual("RESERVED12", Opcode.RESERVED12().to_text())
+        self.assertEqual("RESERVED13", Opcode.RESERVED13().to_text())
+        self.assertEqual("RESERVED14", Opcode.RESERVED14().to_text())
+        self.assertEqual("RESERVED15", Opcode.RESERVED15().to_text())
+
+    def test_richcmp(self):
+        o1 = Opcode.QUERY()
+        o2 = Opcode.NOTIFY()
+        o3 = Opcode.NOTIFY()
+        self.assertTrue(o2 == o3)
+        self.assertTrue(o1 != o2)
+        # can't use assertRaises here...
+        try:
+            o1 < o2
+        except Exception as err:
+            self.assertEqual(TypeError, type(err))
+        try:
+            o1 <= o2
+        except Exception as err:
+            self.assertEqual(TypeError, type(err))
+        try:
+            o1 > o2
+        except Exception as err:
+            self.assertEqual(TypeError, type(err))
+        try:
+            o1 >= o2
+        except Exception as err:
+            self.assertEqual(TypeError, type(err))
+
+class RcodeTest(unittest.TestCase):
+    def test_init(self):
+        self.assertRaises(TypeError, Rcode, "wrong")
+        self.assertRaises(OverflowError, Rcode, 65536)
+
+    def test_get_code(self):
+        self.assertEqual(0, Rcode.NOERROR().get_code())
+        self.assertEqual(1, Rcode.FORMERR().get_code())
+        self.assertEqual(2, Rcode.SERVFAIL().get_code())
+        self.assertEqual(3, Rcode.NXDOMAIN().get_code())
+        self.assertEqual(4, Rcode.NOTIMP().get_code())
+        self.assertEqual(5, Rcode.REFUSED().get_code())
+        self.assertEqual(6, Rcode.YXDOMAIN().get_code())
+        self.assertEqual(7, Rcode.YXRRSET().get_code())
+        self.assertEqual(8, Rcode.NXRRSET().get_code())
+        self.assertEqual(9, Rcode.NOTAUTH().get_code())
+        self.assertEqual(10, Rcode.NOTZONE().get_code())
+        self.assertEqual(11, Rcode.RESERVED11().get_code())
+        self.assertEqual(12, Rcode.RESERVED12().get_code())
+        self.assertEqual(13, Rcode.RESERVED13().get_code())
+        self.assertEqual(14, Rcode.RESERVED14().get_code())
+        self.assertEqual(15, Rcode.RESERVED15().get_code())
+
+    def test_to_text(self):
+        self.assertEqual("NOERROR", Rcode(0).to_text())
+        self.assertEqual("NOERROR", Rcode(0).__str__())
+        self.assertEqual("FORMERR", Rcode(1).to_text())
+        self.assertEqual("SERVFAIL", Rcode(2).to_text())
+        self.assertEqual("NXDOMAIN", Rcode(3).to_text())
+        self.assertEqual("NOTIMP", Rcode(4).to_text())
+        self.assertEqual("REFUSED", Rcode(5).to_text())
+        self.assertEqual("YXDOMAIN", Rcode(6).to_text())
+        self.assertEqual("YXRRSET", Rcode(7).to_text())
+        self.assertEqual("NXRRSET", Rcode(8).to_text())
+        self.assertEqual("NOTAUTH", Rcode(9).to_text())
+        self.assertEqual("NOTZONE", Rcode(10).to_text())
+        self.assertEqual("RESERVED11", Rcode(11).to_text())
+        self.assertEqual("RESERVED12", Rcode(12).to_text())
+        self.assertEqual("RESERVED13", Rcode(13).to_text())
+        self.assertEqual("RESERVED14", Rcode(14).to_text())
+        self.assertEqual("RESERVED15", Rcode(15).to_text())
+        
+    def test_richcmp(self):
+        r1 = Rcode.NOERROR()
+        r2 = Rcode.FORMERR()
+        r3 = Rcode.FORMERR()
+        self.assertTrue(r2 == r3)
+        self.assertTrue(r1 != r2)
+        # can't use assertRaises here...
+        try:
+            r1 < r2
+        except Exception as err:
+            self.assertEqual(TypeError, type(err))
+        try:
+            r1 <= r2
+        except Exception as err:
+            self.assertEqual(TypeError, type(err))
+        try:
+            r1 > r2
+        except Exception as err:
+            self.assertEqual(TypeError, type(err))
+        try:
+            r1 >= r2
+        except Exception as err:
+            self.assertEqual(TypeError, type(err))
+
+class SectionTest(unittest.TestCase):
+
+    def test_init(self):
+        self.assertRaises(NotImplementedError, Section)
+
+    def test_get_code(self):
+        self.assertEqual(0, Section.QUESTION().get_code())
+        self.assertEqual(1, Section.ANSWER().get_code())
+        self.assertEqual(2, Section.AUTHORITY().get_code())
+        self.assertEqual(3, Section.ADDITIONAL().get_code())
+
+    def test_richcmp(self):
+        s1 = Section.QUESTION()
+        s2 = Section.ANSWER()
+        s3 = Section.ANSWER()
+        self.assertTrue(s2 == s3)
+        self.assertTrue(s1 != s2)
+        # can't use assertRaises here...
+        try:
+            s1 < s2
+        except Exception as err:
+            self.assertEqual(TypeError, type(err))
+        try:
+            s1 <= s2
+        except Exception as err:
+            self.assertEqual(TypeError, type(err))
+        try:
+            s1 > s2
+        except Exception as err:
+            self.assertEqual(TypeError, type(err))
+        try:
+            s1 >= s2
+        except Exception as err:
+            self.assertEqual(TypeError, type(err))
+        
+
+class MessageTest(unittest.TestCase):
+
+    def setUp(self):
+        self.p = Message(PARSE)
+        self.r = Message(RENDER)
+        
+    def test_init(self):
+        self.assertRaises(TypeError, Message, 3)
+        self.assertRaises(TypeError, Message, "wrong")
+
+    def test_get_header_flag(self):
+        self.assertRaises(TypeError, self.p.get_header_flag, "wrong")
+        self.assertFalse(self.p.get_header_flag(MessageFlag.AA()))
+
+    def test_set_header_flag(self):
+        self.assertRaises(TypeError, self.r.set_header_flag, "wrong")
+        self.assertRaises(TypeError, self.r.clear_header_flag, "wrong")
+
+        self.assertFalse(self.r.get_header_flag(MessageFlag.AA()))
+        self.r.set_header_flag(MessageFlag.AA())
+        self.assertTrue(self.r.get_header_flag(MessageFlag.AA()))
+        self.r.clear_header_flag(MessageFlag.AA())
+        self.assertFalse(self.r.get_header_flag(MessageFlag.AA()))
+
+    def test_set_DNSSEC_supported(self):
+        self.assertRaises(TypeError, self.r.set_dnssec_supported, "wrong")
+
+        self.assertFalse(self.r.is_dnssec_supported())
+        self.r.set_dnssec_supported(True)
+        self.assertTrue(self.r.is_dnssec_supported())
+        self.r.set_dnssec_supported(False)
+        self.assertFalse(self.r.is_dnssec_supported())
+
+    def test_set_udp_size(self):
+        self.assertRaises(TypeError, self.r.set_udp_size, "wrong")
+
+    def test_set_qid(self):
+        self.assertRaises(TypeError, self.r.set_qid, "wrong")
+
+    def test_set_rcode(self):
+        self.assertRaises(TypeError, self.r.set_rcode, "wrong")
+
+    def test_set_opcode(self):
+        self.assertRaises(TypeError, self.r.set_opcode, "wrong")
+
+    def test_get_section(self):
+        self.assertRaises(TypeError, self.r.get_section, "wrong")
+
+    def test_add_rrset(self):
+        self.assertRaises(TypeError, self.r.add_rrset, "wrong")
+
+    def test_clear(self):
+        self.assertEqual(None, self.r.clear(PARSE))
+        self.assertEqual(None, self.r.clear(RENDER))
+        self.assertRaises(TypeError, self.r.clear, "wrong")
+        self.assertRaises(TypeError, self.r.clear, 3)
+
+    def test_to_wire(self):
+        self.assertRaises(TypeError, self.r.to_wire, 1)
+
+    def test_from_wire(self):
+        self.assertRaises(TypeError, self.r.from_wire, 1)
+
+# helper functions for tests taken from c++ unittests
 if "TESTDATA_PATH" in os.environ:
     testdata_path = os.environ["TESTDATA_PATH"]
 else:
@@ -44,8 +289,9 @@
     message.from_wire(data)
     pass
 
-class MessageTest(unittest.TestCase):
-    
+class ConvertedUnittests(unittest.TestCase):
+    
+    # tests below based on c++ unit tests
     def test_RcodeConstruct(self):
         # normal cases
         self.assertEqual(0, Rcode(0).get_code())
@@ -220,7 +466,7 @@
                           message_parse,
                           "message_fromWire9")
     
-    def test_toWire(self):
+    def test_to_text_and_wire(self):
         message_render = Message(RENDER)
         message_render.set_qid(0x1035)
         message_render.set_opcode(Opcode.QUERY())
@@ -228,25 +474,35 @@
         message_render.set_header_flag(MessageFlag.QR())
         message_render.set_header_flag(MessageFlag.RD())
         message_render.set_header_flag(MessageFlag.AA())
-        #message_render.addQuestion(Question(Name("test.example.com"), RRClass.IN(),
-                                            #RRType.A()))
+        message_render.add_question(Question(Name("test.example.com"), RRClass("IN"), RRType("A")))
         rrset = RRset(Name("test.example.com"), RRClass("IN"),
                                             RRType("A"), RRTTL(3600))
-        #rrset.add_rdata(in.A("192.0.2.1"))
-        #rrset.addRdata(in.A("192.0.2.2"))
-        #message_render.addRRset(Section.ANSWER(), rrset)
-    
-        #self.assertEqual(1, message_render.get_rr_count(Section.QUESTION()))
-        #self.assertEqual(2, message_render.get_rr_count(Section.ANSWER()))
+        rrset.add_rdata(Rdata(RRType("A"), RRClass("IN"), "192.0.2.1"))
+        rrset.add_rdata(Rdata(RRType("A"), RRClass("IN"), "192.0.2.2"))
+        message_render.add_rrset(Section.ANSWER(), rrset)
+    
+        self.assertEqual(1, message_render.get_rr_count(Section.QUESTION()))
+        self.assertEqual(2, message_render.get_rr_count(Section.ANSWER()))
         self.assertEqual(0, message_render.get_rr_count(Section.AUTHORITY()))
         self.assertEqual(0, message_render.get_rr_count(Section.ADDITIONAL()))
 
         renderer = MessageRenderer()
         message_render.to_wire(renderer)
-        #vector<unsigned char> data;
-        #UnitTestUtil.readWireData("testdata/message_toWire1", data)
-        #EXPECT_PRED_FORMAT4(UnitTestUtil.matchWireData, obuffer.getData(),
-                            #obuffer.getLength(), &data[0], data.size())
+        self.assertEqual(b'\x105\x85\x00\x00\x01\x00\x02\x00\x00\x00\x00\x04test\x07example\x03com\x00\x00\x01\x00\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x04\xc0\x00\x02\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x04\xc0\x00\x02\x02',
+                         renderer.get_data())
+        msg_str =\
+""";; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4149
+;; flags: qr aa rd ; QUESTION: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
+
+;; QUESTION SECTION:
+;test.example.com. IN A
+
+;; ANSWER SECTION:
+test.example.com. 3600 IN A 192.0.2.1
+test.example.com. 3600 IN A 192.0.2.2
+"""
+        self.assertEqual(msg_str, message_render.to_text())
+        self.assertEqual(msg_str, message_render.__str__())
 
 if __name__ == '__main__':
     unittest.main()

Modified: experiments/python-binding/src/lib/dns/python/tests/question_python_test.py
==============================================================================
--- experiments/python-binding/src/lib/dns/python/tests/question_python_test.py (original)
+++ experiments/python-binding/src/lib/dns/python/tests/question_python_test.py Thu May 27 12:59:51 2010
@@ -51,6 +51,10 @@
         self.test_question1 = Question(self.example_name1, RRClass("IN"), RRType("NS"))
         self.test_question2 = Question(self.example_name2, RRClass("CH"), RRType("A"))
 
+    def test_init(self):
+        self.assertRaises(TypeError, Question, "wrong")
+
+    # tests below based on cpp unit tests
     def test_QuestionTest_fromWire(self):
         
         q = question_from_wire("question_fromWire")
@@ -79,6 +83,7 @@
     def test_QuestionTest_to_text(self):
     
         self.assertEqual("foo.example.com. IN NS\n", self.test_question1.to_text())
+        self.assertEqual("foo.example.com. IN NS\n", self.test_question1.__str__())
         self.assertEqual("bar.example.com. CH A\n", self.test_question2.to_text())
     
     
@@ -96,6 +101,7 @@
         self.test_question2.to_wire(renderer)
         wiredata = read_wire_data("question_toWire2")
         self.assertEqual(renderer.get_data(), wiredata)
+        self.assertRaises(TypeError, self.test_question1.to_wire, 1)
     
 
 if __name__ == '__main__':




More information about the bind10-changes mailing list