Skip to content
GitLab
Projects
Groups
Snippets
/
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
2a98f3d1
Commit
2a98f3d1
authored
Dec 04, 2012
by
Jelte Jansen
Browse files
[2379] Add more tests and catches
And update doc and do a bit of style cleanup
parent
ce492ecf
Changes
11
Hide whitespace changes
Inline
Side-by-side
src/lib/python/isc/datasrc/Makefile.am
View file @
2a98f3d1
...
...
@@ -20,6 +20,7 @@ datasrc_la_SOURCES += updater_python.cc updater_python.h
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)
...
...
src/lib/python/isc/datasrc/__init__.py
View file @
2a98f3d1
...
...
@@ -2,7 +2,7 @@ import sys
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
...
...
@@ -31,5 +31,4 @@ else:
sys
.
setdlopenflags
(
flags
)
from
isc.datasrc.sqlite3_ds
import
*
from
isc.datasrc.master
import
*
src/lib/python/isc/datasrc/client_python.cc
View file @
2a98f3d1
...
...
@@ -374,6 +374,16 @@ wrapDataSourceClient(DataSourceClient* client,
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
src/lib/python/isc/datasrc/client_python.h
View file @
2a98f3d1
...
...
@@ -44,6 +44,9 @@ wrapDataSourceClient(DataSourceClient* client,
LifeKeeper
>&
life_keeper
=
boost
::
shared_ptr
<
ClientList
::
FindResult
::
LifeKeeper
>
());
DataSourceClient
&
PyDataSourceClient_ToDataSourceClient
(
PyObject
*
client_obj
);
}
// namespace python
}
// namespace datasrc
}
// namespace isc
...
...
src/lib/python/isc/datasrc/datasrc.cc
View file @
2a98f3d1
...
...
@@ -29,6 +29,7 @@
#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>
...
...
@@ -180,6 +181,24 @@ initModulePart_ZoneIterator(PyObject* mod) {
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(),
...
...
@@ -234,8 +253,9 @@ initModulePart_ZoneJournalReader(PyObject* mod) {
}
PyObject
*
po_DataSourceError
;
PyObject
*
po_
OutOfZone
;
PyObject
*
po_
MasterFileError
;
PyObject
*
po_NotImplemented
;
PyObject
*
po_OutOfZone
;
PyModuleDef
iscDataSrc
=
{
{
PyObject_HEAD_INIT
(
NULL
)
NULL
,
0
,
NULL
},
...
...
@@ -260,6 +280,26 @@ PyInit_datasrc(void) {
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
);
...
...
@@ -290,17 +330,7 @@ PyInit_datasrc(void) {
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
);
}
...
...
src/lib/python/isc/datasrc/master.py
View file @
2a98f3d1
...
...
@@ -182,7 +182,7 @@ def records(input):
if
paren
==
1
or
not
record
:
continue
ret
=
' '
.
join
(
record
)
record
=
[]
oldsize
=
size
...
...
src/lib/python/isc/datasrc/tests/Makefile.am
View file @
2a98f3d1
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
...
...
src/lib/python/isc/datasrc/tests/zone_loader_test.py
0 → 100644
View file @
2a98f3d1
# 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
()
src/lib/python/isc/datasrc/zone_loader_inc.cc
0 → 100644
View file @
2a98f3d1
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
src/lib/python/isc/datasrc/zone_loader_python.cc
0 → 100644
View file @
2a98f3d1
// 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
src/lib/python/isc/datasrc/zone_loader_python.h
0 → 100644
View file @
2a98f3d1
// 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:
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment