[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