Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
a407cb3d
Commit
a407cb3d
authored
May 13, 2011
by
Michal 'vorner' Vaner
Browse files
Merge branch 'master' of
ssh://bind10.isc.org/var/bind10/git/bind10
parents
1cccbc68
081891b3
Changes
21
Hide whitespace changes
Inline
Side-by-side
configure.ac
View file @
a407cb3d
...
...
@@ -842,6 +842,7 @@ AC_OUTPUT([doc/version.ent
src/lib/cc/session_config.h.pre
src/lib/cc/tests/session_unittests_config.h
src/lib/log/tests/run_time_init_test.sh
src/lib/util/python/mkpywrapper.py
tests/system/conf.sh
tests/system/glue/setup.sh
tests/system/glue/nsx1/b10-config.db
...
...
@@ -867,6 +868,7 @@ AC_OUTPUT([doc/version.ent
chmod +x src/lib/dns/gen-rdatacode.py
chmod +x src/lib/dns/tests/testdata/gen-wiredata.py
chmod +x src/lib/log/tests/run_time_init_test.sh
chmod +x src/lib/util/python/mkpywrapper.py
chmod +x tests/system/conf.sh
])
AC_OUTPUT
...
...
doc/Doxyfile
View file @
a407cb3d
...
...
@@ -1140,7 +1140,7 @@ MAN_LINKS = NO
# generate an XML file that captures the structure of
# the code including all documentation.
GENERATE_XML =
NO
GENERATE_XML =
YES
# The XML_OUTPUT tag is used to specify where the XML pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
...
...
@@ -1165,7 +1165,7 @@ XML_DTD =
# and cross-referencing information) to the XML output. Note that
# enabling this will significantly increase the size of the XML output.
XML_PROGRAMLISTING =
YES
XML_PROGRAMLISTING =
NO
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
...
...
src/lib/dns/python/Makefile.am
View file @
a407cb3d
...
...
@@ -6,6 +6,8 @@ AM_CXXFLAGS = $(B10_CXXFLAGS)
pyexec_LTLIBRARIES
=
pydnspp.la
pydnspp_la_SOURCES
=
pydnspp.cc pydnspp_common.cc
pydnspp_la_SOURCES
+=
rcode_python.cc rcode_python.h
pydnspp_la_SOURCES
+=
tsigerror_python.cc tsigerror_python.h
pydnspp_la_CPPFLAGS
=
$(AM_CPPFLAGS)
$(PYTHON_INCLUDES)
pydnspp_la_LDFLAGS
=
$(PYTHON_LDFLAGS)
...
...
src/lib/dns/python/message_python.cc
View file @
a407cb3d
...
...
@@ -336,15 +336,15 @@ Message_getRcode(s_Message* self) {
rcode
=
static_cast
<
s_Rcode
*>
(
rcode_type
.
tp_alloc
(
&
rcode_type
,
0
));
if
(
rcode
!=
NULL
)
{
rcode
->
rcode
=
NULL
;
rcode
->
cppobj
=
NULL
;
try
{
rcode
->
rcode
=
new
Rcode
(
self
->
message
->
getRcode
());
rcode
->
cppobj
=
new
Rcode
(
self
->
message
->
getRcode
());
}
catch
(
const
InvalidMessageOperation
&
imo
)
{
PyErr_SetString
(
po_InvalidMessageOperation
,
imo
.
what
());
}
catch
(...)
{
PyErr_SetString
(
po_IscException
,
"Unexpected exception"
);
}
if
(
rcode
->
rcode
==
NULL
)
{
if
(
rcode
->
cppobj
==
NULL
)
{
Py_DECREF
(
rcode
);
return
(
NULL
);
}
...
...
@@ -360,7 +360,7 @@ Message_setRcode(s_Message* self, PyObject* args) {
return
(
NULL
);
}
try
{
self
->
message
->
setRcode
(
*
rcode
->
rcode
);
self
->
message
->
setRcode
(
*
rcode
->
cppobj
);
Py_RETURN_NONE
;
}
catch
(
const
InvalidMessageOperation
&
imo
)
{
PyErr_SetString
(
po_InvalidMessageOperation
,
imo
.
what
());
...
...
src/lib/dns/python/pydnspp.cc
View file @
a407cb3d
...
...
@@ -32,20 +32,32 @@
#include <exceptions/exceptions.h>
#include <util/buffer.h>
#include <dns/exceptions.h>
#include <dns/name.h>
#include <dns/messagerenderer.h>
#include
<dns/python/
pydnspp_common.h
>
#include
"
pydnspp_common.h
"
namespace
isc
{
namespace
dns
{
namespace
python
{
// For our 'general' isc::Exceptions
static
PyObject
*
po_IscException
;
static
PyObject
*
po_InvalidParameter
;
PyObject
*
po_IscException
;
PyObject
*
po_InvalidParameter
;
// For our own isc::dns::Exception
static
PyObject
*
po_DNSMessageBADVERS
;
PyObject
*
po_DNSMessageBADVERS
;
}
}
}
#include "rcode_python.h"
#include "tsigerror_python.h"
// order is important here!
using
namespace
isc
::
dns
::
python
;
#include <dns/python/messagerenderer_python.cc>
#include <dns/python/name_python.cc> // needs Messagerenderer
#include <dns/python/rrclass_python.cc> // needs Messagerenderer
...
...
@@ -58,14 +70,14 @@ static PyObject* po_DNSMessageBADVERS;
#include <dns/python/tsigkey_python.cc> // needs Name
#include <dns/python/tsig_python.cc> // needs tsigkey
#include <dns/python/opcode_python.cc>
#include <dns/python/rcode_python.cc>
#include <dns/python/edns_python.cc> // needs Messagerenderer, Rcode
#include <dns/python/message_python.cc> // needs RRset, Question
//
// Definition of the module
//
static
PyModuleDef
pydnspp
=
{
namespace
{
PyModuleDef
pydnspp
=
{
{
PyObject_HEAD_INIT
(
NULL
)
NULL
,
0
,
NULL
},
"pydnspp"
,
"Python bindings for the classes in the isc::dns namespace.
\n\n
"
...
...
@@ -80,10 +92,11 @@ static PyModuleDef pydnspp = {
NULL
,
NULL
};
}
PyMODINIT_FUNC
PyInit_pydnspp
(
void
)
{
PyObject
*
mod
=
PyModule_Create
(
&
pydnspp
);
PyObject
*
mod
=
PyModule_Create
(
&
pydnspp
);
if
(
mod
==
NULL
)
{
return
(
NULL
);
}
...
...
@@ -154,6 +167,10 @@ PyInit_pydnspp(void) {
return
(
NULL
);
}
if
(
!
initModulePart_TSIGError
(
mod
))
{
return
(
NULL
);
}
if
(
!
initModulePart_TSIGContext
(
mod
))
{
return
(
NULL
);
}
...
...
src/lib/dns/python/pydnspp_common.cc
View file @
a407cb3d
...
...
@@ -15,6 +15,9 @@
#include <Python.h>
#include <pydnspp_common.h>
namespace
isc
{
namespace
dns
{
namespace
python
{
int
readDataFromSequence
(
uint8_t
*
data
,
size_t
len
,
PyObject
*
sequence
)
{
PyObject
*
el
=
NULL
;
...
...
@@ -44,8 +47,15 @@ readDataFromSequence(uint8_t *data, size_t len, PyObject* sequence) {
}
void
addClassVariable
(
PyTypeObject
&
c
,
const
char
*
name
,
PyObject
*
obj
)
{
PyDict_SetItemString
(
c
.
tp_dict
,
name
,
obj
);
int
addClassVariable
(
PyTypeObject
&
c
,
const
char
*
name
,
PyObject
*
obj
)
{
if
(
obj
==
NULL
)
{
PyErr_SetString
(
PyExc_ValueError
,
"NULL object is specified for a class variable"
);
return
(
-
1
);
}
return
(
PyDict_SetItemString
(
c
.
tp_dict
,
name
,
obj
));
}
}
}
}
src/lib/dns/python/pydnspp_common.h
View file @
a407cb3d
...
...
@@ -15,9 +15,22 @@
#ifndef __LIBDNS_PYTHON_COMMON_H
#define __LIBDNS_PYTHON_COMMON_H 1
//
// Shared functions for python/c API
//
#include <Python.h>
#include <stdexcept>
#include <string>
#include <util/python/pycppwrapper_util.h>
namespace
isc
{
namespace
dns
{
namespace
python
{
// For our 'general' isc::Exceptions
extern
PyObject
*
po_IscException
;
extern
PyObject
*
po_InvalidParameter
;
// For our own isc::dns::Exception
extern
PyObject
*
po_DNSMessageBADVERS
;
// This function reads 'bytes' from a sequence
// This sequence can be anything that implements the Sequence interface,
...
...
@@ -31,6 +44,12 @@
// case nothing is removed
int
readDataFromSequence
(
uint8_t
*
data
,
size_t
len
,
PyObject
*
sequence
);
void
addClassVariable
(
PyTypeObject
&
c
,
const
char
*
name
,
PyObject
*
obj
);
int
addClassVariable
(
PyTypeObject
&
c
,
const
char
*
name
,
PyObject
*
obj
);
}
// namespace python
}
// namespace dns
}
// namespace isc
#endif // __LIBDNS_PYTHON_COMMON_H
// Local Variables:
// mode: c++
// End:
src/lib/dns/python/rcode_python.cc
View file @
a407cb3d
...
...
@@ -12,9 +12,15 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <exceptions/exceptions.h>
#include <dns/rcode.h>
#include "pydnspp_common.h"
#include "rcode_python.h"
using
namespace
isc
::
dns
;
using
namespace
isc
::
dns
::
python
;
//
// Declaration of the custom exceptions (None for this class)
...
...
@@ -27,25 +33,14 @@ using namespace isc::dns;
// and static wrappers around the methods we export), a list of methods,
// and a type description
namespace
{
//
// Rcode
//
// We added a helper variable static_code here
// Since we can create Rcodes dynamically with Rcode(int), but also
// use the static globals (Rcode::NOERROR() etc), we use this
// variable to see if the code came from one of the latter, in which
// case Rcode_destroy should not free it (the other option is to
// allocate new Rcodes for every use of the static ones, but this
// seems more efficient).
class
s_Rcode
:
public
PyObject
{
public:
s_Rcode
()
:
rcode
(
NULL
),
static_code
(
false
)
{}
const
Rcode
*
rcode
;
bool
static_code
;
};
// Trivial constructor.
s_Rcode
::
s_Rcode
()
:
cppobj
(
NULL
),
static_code
(
false
)
{}
namespace
{
int
Rcode_init
(
s_Rcode
*
const
self
,
PyObject
*
args
);
void
Rcode_destroy
(
s_Rcode
*
const
self
);
...
...
@@ -118,57 +113,6 @@ PyMethodDef Rcode_methods[] = {
{
NULL
,
NULL
,
0
,
NULL
}
};
PyTypeObject
rcode_type
=
{
PyVarObject_HEAD_INIT
(
NULL
,
0
)
"pydnspp.Rcode"
,
sizeof
(
s_Rcode
),
// tp_basicsize
0
,
// tp_itemsize
(
destructor
)
Rcode_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
Rcode_str
,
// tp_str
NULL
,
// tp_getattro
NULL
,
// tp_setattro
NULL
,
// tp_as_buffer
Py_TPFLAGS_DEFAULT
,
// tp_flags
"The Rcode class objects represent standard RCODEs"
"of the header section of DNS messages."
,
NULL
,
// tp_traverse
NULL
,
// tp_clear
(
richcmpfunc
)
Rcode_richcmp
,
// tp_richcompare
0
,
// tp_weaklistoffset
NULL
,
// tp_iter
NULL
,
// tp_iternext
Rcode_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
(
initproc
)
Rcode_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
};
int
Rcode_init
(
s_Rcode
*
const
self
,
PyObject
*
args
)
{
long
code
=
0
;
...
...
@@ -193,9 +137,9 @@ Rcode_init(s_Rcode* const self, PyObject* args) {
}
try
{
if
(
ext_code
==
-
1
)
{
self
->
rcode
=
new
Rcode
(
code
);
self
->
cppobj
=
new
Rcode
(
code
);
}
else
{
self
->
rcode
=
new
Rcode
(
code
,
ext_code
);
self
->
cppobj
=
new
Rcode
(
code
,
ext_code
);
}
self
->
static_code
=
false
;
}
catch
(
const
isc
::
OutOfRange
&
ex
)
{
...
...
@@ -211,27 +155,27 @@ Rcode_init(s_Rcode* const self, PyObject* args) {
void
Rcode_destroy
(
s_Rcode
*
const
self
)
{
// Depending on whether we created the rcode or are referring
// to a global one, we do or do not delete self->
rcode
here
// to a global one, we do or do not delete self->
cppobj
here
if
(
!
self
->
static_code
)
{
delete
self
->
rcode
;
delete
self
->
cppobj
;
}
self
->
rcode
=
NULL
;
self
->
cppobj
=
NULL
;
Py_TYPE
(
self
)
->
tp_free
(
self
);
}
PyObject
*
Rcode_getCode
(
const
s_Rcode
*
const
self
)
{
return
(
Py_BuildValue
(
"I"
,
self
->
rcode
->
getCode
()));
return
(
Py_BuildValue
(
"I"
,
self
->
cppobj
->
getCode
()));
}
PyObject
*
Rcode_getExtendedCode
(
const
s_Rcode
*
const
self
)
{
return
(
Py_BuildValue
(
"I"
,
self
->
rcode
->
getExtendedCode
()));
return
(
Py_BuildValue
(
"I"
,
self
->
cppobj
->
getExtendedCode
()));
}
PyObject
*
Rcode_toText
(
const
s_Rcode
*
const
self
)
{
return
(
Py_BuildValue
(
"s"
,
self
->
rcode
->
toText
().
c_str
()));
return
(
Py_BuildValue
(
"s"
,
self
->
cppobj
->
toText
().
c_str
()));
}
PyObject
*
...
...
@@ -245,7 +189,7 @@ PyObject*
Rcode_createStatic
(
const
Rcode
&
rcode
)
{
s_Rcode
*
ret
=
PyObject_New
(
s_Rcode
,
&
rcode_type
);
if
(
ret
!=
NULL
)
{
ret
->
rcode
=
&
rcode
;
ret
->
cppobj
=
&
rcode
;
ret
->
static_code
=
true
;
}
return
(
ret
);
...
...
@@ -357,10 +301,10 @@ Rcode_richcmp(const s_Rcode* const self, const s_Rcode* const other,
PyErr_SetString
(
PyExc_TypeError
,
"Unorderable type; Rcode"
);
return
(
NULL
);
case
Py_EQ
:
c
=
(
*
self
->
rcode
==
*
other
->
rcode
);
c
=
(
*
self
->
cppobj
==
*
other
->
cppobj
);
break
;
case
Py_NE
:
c
=
(
*
self
->
rcode
!=
*
other
->
rcode
);
c
=
(
*
self
->
cppobj
!=
*
other
->
cppobj
);
break
;
case
Py_GT
:
PyErr_SetString
(
PyExc_TypeError
,
"Unorderable type; Rcode"
);
...
...
@@ -374,6 +318,61 @@ Rcode_richcmp(const s_Rcode* const self, const s_Rcode* const other,
else
Py_RETURN_FALSE
;
}
}
// end of unnamed namespace
namespace
isc
{
namespace
dns
{
namespace
python
{
PyTypeObject
rcode_type
=
{
PyVarObject_HEAD_INIT
(
NULL
,
0
)
"pydnspp.Rcode"
,
sizeof
(
s_Rcode
),
// tp_basicsize
0
,
// tp_itemsize
(
destructor
)
Rcode_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
Rcode_str
,
// tp_str
NULL
,
// tp_getattro
NULL
,
// tp_setattro
NULL
,
// tp_as_buffer
Py_TPFLAGS_DEFAULT
,
// tp_flags
"The Rcode class objects represent standard RCODEs"
"of the header section of DNS messages."
,
NULL
,
// tp_traverse
NULL
,
// tp_clear
reinterpret_cast
<
richcmpfunc
>
(
Rcode_richcmp
),
// tp_richcompare
0
,
// tp_weaklistoffset
NULL
,
// tp_iter
NULL
,
// tp_iternext
Rcode_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
(
initproc
)
Rcode_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
};
// Module Initialization, all statics are initialized here
bool
...
...
@@ -428,4 +427,6 @@ initModulePart_Rcode(PyObject* mod) {
return
(
true
);
}
}
// end of unnamed namespace
}
// namespace python
}
// namespace dns
}
// namespace isc
src/lib/dns/python/rcode_python.h
0 → 100644
View file @
a407cb3d
// Copyright (C) 2011 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_RCODE_H
#define __PYTHON_RCODE_H 1
#include <Python.h>
namespace
isc
{
namespace
dns
{
class
Rcode
;
namespace
python
{
// The s_* Class simply covers one instantiation of the object.
//
// We added a helper variable static_code here
// Since we can create Rcodes dynamically with Rcode(int), but also
// use the static globals (Rcode::NOERROR() etc), we use this
// variable to see if the code came from one of the latter, in which
// case Rcode_destroy should not free it (the other option is to
// allocate new Rcodes for every use of the static ones, but this
// seems more efficient).
//
// Follow-up note: we don't have to use the proxy function in the python lib;
// we can just define class specific constants directly (see TSIGError).
// We should make this cleanup later.
class
s_Rcode
:
public
PyObject
{
public:
s_Rcode
();
const
Rcode
*
cppobj
;
bool
static_code
;
};
extern
PyTypeObject
rcode_type
;
bool
initModulePart_Rcode
(
PyObject
*
mod
);
}
// namespace python
}
// namespace dns
}
// namespace isc
#endif // __PYTHON_RCODE_H
// Local Variables:
// mode: c++
// End:
src/lib/dns/python/tests/Makefile.am
View file @
a407cb3d
...
...
@@ -12,6 +12,7 @@ PYTESTS += rrset_python_test.py
PYTESTS
+=
rrttl_python_test.py
PYTESTS
+=
rrtype_python_test.py
PYTESTS
+=
tsig_python_test.py
PYTESTS
+=
tsigerror_python_test.py
PYTESTS
+=
tsigkey_python_test.py
EXTRA_DIST
=
$(PYTESTS)
...
...
src/lib/dns/python/tests/tsigerror_python_test.py
0 → 100644
View file @
a407cb3d
# Copyright (C) 2011 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
unittest
import
sys
from
pydnspp
import
*
class
TSIGErrorTest
(
unittest
.
TestCase
):
def
test_from_code
(
self
):
self
.
assertEqual
(
0
,
TSIGError
(
0
).
get_code
())
self
.
assertEqual
(
18
,
TSIGError
(
18
).
get_code
())
self
.
assertEqual
(
65535
,
TSIGError
(
65535
).
get_code
())
self
.
assertRaises
(
ValueError
,
TSIGError
,
65536
)
self
.
assertRaises
(
ValueError
,
TSIGError
,
-
1
)
self
.
assertRaises
(
TypeError
,
TSIGError
,
"not yet supported"
)
def
test_from_rcode
(
self
):
# We use RCODE for code values from 0-15.
self
.
assertEqual
(
0
,
TSIGError
(
Rcode
.
NOERROR
()).
get_code
())
self
.
assertEqual
(
15
,
TSIGError
(
Rcode
(
15
)).
get_code
())
# From error code 16 TSIG errors define a separate space, so passing
# corresponding RCODE for such code values should be prohibited.
self
.
assertRaises
(
ValueError
,
TSIGError
,
Rcode
(
16
))
def
test_constants
(
self
):
# We'll only test arbitrarily chosen subsets of the codes.
# This class is quite simple, so it should be suffice.
self
.
assertEqual
(
TSIGError
.
BAD_SIG_CODE
,
TSIGError
(
16
).
get_code
())
self
.
assertEqual
(
TSIGError
.
BAD_KEY_CODE
,
TSIGError
(
17
).
get_code
())
self
.
assertEqual
(
TSIGError
.
BAD_TIME_CODE
,
TSIGError
(
18
).
get_code
())
self
.
assertEqual
(
0
,
TSIGError
.
NOERROR
.
get_code
())
self
.
assertEqual
(
9
,
TSIGError
.
NOTAUTH
.
get_code
())
self
.
assertEqual
(
14
,
TSIGError
.
RESERVED14
.
get_code
())
self
.
assertEqual
(
TSIGError
.
BAD_SIG_CODE
,
TSIGError
.
BAD_SIG
.
get_code
())
self
.
assertEqual
(
TSIGError
.
BAD_KEY_CODE
,
TSIGError
.
BAD_KEY
.
get_code
())
self
.
assertEqual
(
TSIGError
.
BAD_TIME_CODE
,
TSIGError
.
BAD_TIME
.
get_code
())
def
test_equal
(
self
):
self
.
assertTrue
(
TSIGError
.
NOERROR
==
TSIGError
(
Rcode
.
NOERROR
()))
self
.
assertTrue
(
TSIGError
(
Rcode
.
NOERROR
())
==
TSIGError
.
NOERROR
)
self
.
assertTrue
(
TSIGError
.
BAD_SIG
==
TSIGError
(
16
))
self
.
assertTrue
(
TSIGError
(
16
)
==
TSIGError
.
BAD_SIG
)
def
test_nequal
(
self
):
self
.
assertTrue
(
TSIGError
.
BAD_KEY
!=
TSIGError
(
Rcode
.
NOERROR
()))
self
.
assertTrue
(
TSIGError
(
Rcode
.
NOERROR
())
!=
TSIGError
.
BAD_KEY
)
def
test_to_text
(
self
):
# TSIGError derived from the standard Rcode
self
.
assertEqual
(
"NOERROR"
,
TSIGError
(
Rcode
.
NOERROR
()).
to_text
())
# Well known TSIG errors
self
.
assertEqual
(
"BADSIG"
,
TSIGError
.
BAD_SIG
.
to_text
())
self
.
assertEqual
(
"BADKEY"
,
TSIGError
.
BAD_KEY
.
to_text
())
self
.
assertEqual
(
"BADTIME"
,
TSIGError
.
BAD_TIME
.
to_text
())
# Unknown (or not yet supported) codes. Simply converted as numeric.
self
.
assertEqual
(
"19"
,
TSIGError
(
19
).
to_text
());
self
.
assertEqual
(
"65535"
,
TSIGError
(
65535
).
to_text
());
# also check str() works same way
self
.
assertEqual
(
"NOERROR"
,
str
(
TSIGError
(
Rcode
.
NOERROR
())))
self
.
assertEqual
(
"BADSIG"
,
str
(
TSIGError
.
BAD_SIG
))
def
test_to_rcode
(
self
):
# TSIGError derived from the standard Rcode
self
.
assertEqual
(
Rcode
.
NOERROR
(),
TSIGError
(
Rcode
.
NOERROR
()).
to_rcode
())
# Well known TSIG errors
self
.
assertEqual
(
Rcode
.
NOTAUTH
(),
TSIGError
.
BAD_SIG
.
to_rcode
())
self
.
assertEqual
(
Rcode
.
NOTAUTH
(),
TSIGError
.
BAD_KEY
.
to_rcode
())
self
.
assertEqual
(
Rcode
.
NOTAUTH
(),
TSIGError
.
BAD_TIME
.
to_rcode
())
# Unknown (or not yet supported) codes are treated as SERVFAIL.
self
.
assertEqual
(
Rcode
.
SERVFAIL