2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-29 13:07:50 +00:00

Merge branch 'trac2993'

This commit is contained in:
Mukund Sivaraman 2013-06-30 20:55:12 +05:30
commit dc6150ca4d
12 changed files with 136 additions and 29 deletions

View File

@ -1257,6 +1257,7 @@ AC_CONFIG_FILES([Makefile
src/lib/python/isc/util/cio/tests/Makefile
src/lib/python/isc/datasrc/Makefile
src/lib/python/isc/datasrc/tests/Makefile
src/lib/python/isc/datasrc/tests/testdata/Makefile
src/lib/python/isc/dns/Makefile
src/lib/python/isc/cc/Makefile
src/lib/python/isc/cc/cc_generated/Makefile

View File

@ -623,7 +623,7 @@ DataSrcClientsBuilderBase<MutexType, CondVarType>::getZoneWriter(
datasrc::ConfigurableClientList::ZoneWriterPair writerpair;
{
typename MutexType::Locker locker(*map_mutex_);
writerpair = client_list.getCachedZoneWriter(origin);
writerpair = client_list.getCachedZoneWriter(origin, false);
}
switch (writerpair.first) {

View File

@ -347,6 +347,7 @@ ConfigurableClientList::resetMemorySegment
ConfigurableClientList::ZoneWriterPair
ConfigurableClientList::getCachedZoneWriter(const Name& name,
bool catch_load_error,
const std::string& datasrc_name)
{
if (!allow_cache_) {
@ -385,7 +386,8 @@ ConfigurableClientList::getCachedZoneWriter(const Name& name,
ZoneWriterPtr(
new memory::ZoneWriter(
*info.ztable_segment_,
load_action, name, rrclass_, false))));
load_action, name, rrclass_,
catch_load_error))));
}
// We can't find the specified zone. If a specific data source was

View File

@ -432,6 +432,8 @@ public:
/// of the pair.
///
/// \param zone The origin of the zone to load.
/// \param catch_load_errors Whether to make the zone writer catch
/// load errors (see \c ZoneWriter constructor documentation).
/// \param datasrc_name If not empty, the name of the data source
/// to be used for loading the zone (see above).
/// \return The result has two parts. The first one is a status indicating
@ -442,6 +444,7 @@ public:
/// \throw DataSourceError or anything else that the data source
/// containing the zone might throw is propagated.
ZoneWriterPair getCachedZoneWriter(const dns::Name& zone,
bool catch_load_error,
const std::string& datasrc_name = "");
/// \brief Implementation of the ClientList::find.

View File

@ -210,7 +210,7 @@ public:
config_ztable_segment);
const ConfigurableClientList::ZoneWriterPair result =
list_->getCachedZoneWriter(zone, dsrc_info.name_);
list_->getCachedZoneWriter(zone, false, dsrc_info.name_);
ASSERT_EQ(ConfigurableClientList::ZONE_SUCCESS, result.first);
result.second->load();
@ -1023,7 +1023,7 @@ TEST_P(ListTest, BadMasterFile) {
ConfigurableClientList::CacheStatus
ListTest::doReload(const Name& origin, const string& datasrc_name) {
ConfigurableClientList::ZoneWriterPair
result(list_->getCachedZoneWriter(origin, datasrc_name));
result(list_->getCachedZoneWriter(origin, false, datasrc_name));
if (result.first == ConfigurableClientList::ZONE_SUCCESS) {
// Can't use ASSERT_NE here, it would want to return(), which
// it can't in non-void function.
@ -1041,6 +1041,59 @@ ListTest::doReload(const Name& origin, const string& datasrc_name) {
return (result.first);
}
// Check that ZoneWriter doesn't throw when asked not to
TEST_P(ListTest, checkZoneWriterCatchesExceptions) {
const ConstElementPtr config_elem_zones_(Element::fromJSON("["
"{"
" \"type\": \"MasterFiles\","
" \"params\": {"
" \"example.edu\": \"" TEST_DATA_DIR "example.edu-broken\""
" },"
" \"cache-enable\": true"
"}]"));
list_->configure(config_elem_zones_, true);
ConfigurableClientList::ZoneWriterPair
result(list_->getCachedZoneWriter(Name("example.edu"), true));
ASSERT_EQ(ConfigurableClientList::ZONE_SUCCESS, result.first);
ASSERT_TRUE(result.second);
std::string error_msg;
// Because of the way we called getCachedZoneWriter() with
// catch_load_error=true, the following should not throw and must
// return an error message in error_msg.
EXPECT_NO_THROW(result.second->load(&error_msg));
EXPECT_FALSE(error_msg.empty());
result.second->cleanup();
}
// Check that ZoneWriter throws when asked to
TEST_P(ListTest, checkZoneWriterThrows) {
const ConstElementPtr config_elem_zones_(Element::fromJSON("["
"{"
" \"type\": \"MasterFiles\","
" \"params\": {"
" \"example.edu\": \"" TEST_DATA_DIR "example.edu-broken\""
" },"
" \"cache-enable\": true"
"}]"));
list_->configure(config_elem_zones_, true);
ConfigurableClientList::ZoneWriterPair
result(list_->getCachedZoneWriter(Name("example.edu"), false));
ASSERT_EQ(ConfigurableClientList::ZONE_SUCCESS, result.first);
ASSERT_TRUE(result.second);
std::string error_msg;
// Because of the way we called getCachedZoneWriter() with
// catch_load_error=false, the following should throw and must not
// modify error_msg.
EXPECT_THROW(result.second->load(&error_msg),
isc::datasrc::ZoneLoaderException);
EXPECT_TRUE(error_msg.empty());
result.second->cleanup();
}
// Test we can reload a zone
TEST_P(ListTest, reloadSuccess) {
list_->configure(config_elem_zones_, true);
@ -1315,9 +1368,9 @@ ListTest::accessorIterate(const ConstZoneTableAccessorPtr& accessor,
bool found = false;
int i;
for (i = 0; !it->isLast(); ++i, it->next()) {
if (Name(zoneName) == it->getCurrent().origin) {
found = true;
}
if (Name(zoneName) == it->getCurrent().origin) {
found = true;
}
}
EXPECT_EQ(i, numZones);
if (numZones > 0) {

View File

@ -65,7 +65,7 @@ Parameters:\n\
";
const char* const ConfigurableClientList_get_cached_zone_writer_doc = "\
get_cached_zone_writer(zone, datasrc_name) -> status, zone_writer\n\
get_cached_zone_writer(zone, catch_load_error, datasrc_name) -> status, zone_writer\n\
\n\
This method returns a ZoneWriter that can be used to (re)load a zone.\n\
\n\
@ -89,6 +89,7 @@ the status is anything else, the second element is None.\n\
\n\
Parameters:\n\
zone The origin of the zone to (re)load.\n\
catch_load_error Whether to catch load errors, or to raise them as exceptions.\n\
datasrc_name The name of the data source where the zone is to be loaded (optional).\n\
";

View File

@ -163,15 +163,17 @@ ConfigurableClientList_getCachedZoneWriter(PyObject* po_self, PyObject* args) {
static_cast<s_ConfigurableClientList*>(po_self);
try {
PyObject* name_obj;
int catch_load_error;
const char* datasrc_name_p = "";
if (PyArg_ParseTuple(args, "O!|s", &isc::dns::python::name_type,
&name_obj, &datasrc_name_p)) {
if (PyArg_ParseTuple(args, "O!p|s", &isc::dns::python::name_type,
&name_obj, &catch_load_error, &datasrc_name_p)) {
const isc::dns::Name&
name(isc::dns::python::PyName_ToName(name_obj));
const std::string datasrc_name(datasrc_name_p);
const ConfigurableClientList::ZoneWriterPair result =
self->cppobj->getCachedZoneWriter(name, datasrc_name);
self->cppobj->getCachedZoneWriter(name, catch_load_error,
datasrc_name);
PyObjectContainer writer;
if (!result.second) {

View File

@ -1,17 +1,10 @@
SUBDIRS = testdata
PYCOVERAGE_RUN = @PYCOVERAGE_RUN@
PYTESTS = datasrc_test.py sqlite3_ds_test.py
PYTESTS += clientlist_test.py zone_loader_test.py
EXTRA_DIST = $(PYTESTS)
EXTRA_DIST += testdata/brokendb.sqlite3
EXTRA_DIST += testdata/example.com.sqlite3
EXTRA_DIST += testdata/example.com.source.sqlite3
EXTRA_DIST += testdata/newschema.sqlite3
EXTRA_DIST += testdata/oldschema.sqlite3
EXTRA_DIST += testdata/new_minor_schema.sqlite3
EXTRA_DIST += testdata/example.com
EXTRA_DIST += testdata/example.com.ch
EXTRA_DIST += testdata/static.zone
CLEANFILES = $(abs_builddir)/rwtest.sqlite3.copied
CLEANFILES += $(abs_builddir)/zoneloadertest.sqlite3

View File

@ -253,7 +253,9 @@ class ClientListTest(unittest.TestCase):
self.clist.reset_memory_segment("MasterFiles",
isc.datasrc.ConfigurableClientList.CREATE,
map_params)
result, self.__zone_writer = self.clist.get_cached_zone_writer(isc.dns.Name("example.com"))
result, self.__zone_writer = \
self.clist.get_cached_zone_writer(isc.dns.Name("example.com"),
False)
self.assertEqual(isc.datasrc.ConfigurableClientList.CACHE_STATUS_ZONE_SUCCESS,
result)
err_msg = self.__zone_writer.load()
@ -264,7 +266,9 @@ class ClientListTest(unittest.TestCase):
self.clist.reset_memory_segment("MasterFiles",
isc.datasrc.ConfigurableClientList.READ_ONLY,
map_params)
result, self.__zone_writer = self.clist.get_cached_zone_writer(isc.dns.Name("example.com"))
result, self.__zone_writer = \
self.clist.get_cached_zone_writer(isc.dns.Name("example.com"),
False)
self.assertEqual(isc.datasrc.ConfigurableClientList.CACHE_STATUS_CACHE_NOT_WRITABLE,
result)
@ -280,7 +284,9 @@ class ClientListTest(unittest.TestCase):
self.clist = isc.datasrc.ConfigurableClientList(isc.dns.RRClass.IN)
self.configure_helper()
result, self.__zone_writer = self.clist.get_cached_zone_writer(isc.dns.Name("example.com"))
result, self.__zone_writer = \
self.clist.get_cached_zone_writer(isc.dns.Name("example.com"),
False)
self.assertEqual(isc.datasrc.ConfigurableClientList.CACHE_STATUS_ZONE_SUCCESS,
result)
err_msg = self.__zone_writer.load()
@ -288,6 +294,30 @@ class ClientListTest(unittest.TestCase):
self.assertRaises(isc.datasrc.Error, self.__zone_writer.load)
self.__zone_writer.cleanup()
def test_zone_writer_load_without_raise(self):
"""
Test that the zone writer does not throw when asked not to.
"""
self.clist = isc.datasrc.ConfigurableClientList(isc.dns.RRClass.IN)
self.clist.configure('''[{
"type": "MasterFiles",
"params": {
"example.com": "''' + TESTDATA_PATH + '''example.com-broken.zone"
},
"cache-enable": true
}]''', True)
result, self.__zone_writer = \
self.clist.get_cached_zone_writer(isc.dns.Name("example.com"),
True)
self.assertEqual(isc.datasrc.ConfigurableClientList.CACHE_STATUS_ZONE_SUCCESS,
result)
err_msg = self.__zone_writer.load()
self.assertIsNotNone(err_msg)
self.assertTrue('Errors found when validating zone' in err_msg)
self.__zone_writer.cleanup()
def test_zone_writer_install_without_load(self):
"""
Test that the zone writer throws when install() is called
@ -297,7 +327,9 @@ class ClientListTest(unittest.TestCase):
self.clist = isc.datasrc.ConfigurableClientList(isc.dns.RRClass.IN)
self.configure_helper()
result, self.__zone_writer = self.clist.get_cached_zone_writer(isc.dns.Name("example.com"))
result, self.__zone_writer = \
self.clist.get_cached_zone_writer(isc.dns.Name("example.com"),
False)
self.assertEqual(isc.datasrc.ConfigurableClientList.CACHE_STATUS_ZONE_SUCCESS,
result)
self.assertRaises(isc.datasrc.Error, self.__zone_writer.install)

View File

@ -0,0 +1,12 @@
EXTRA_DIST = \
brokendb.sqlite3 \
example.com \
example.com-broken.zone \
example.com.ch \
example.com.source.sqlite3 \
example.com.sqlite3 \
Makefile.am \
new_minor_schema.sqlite3 \
newschema.sqlite3 \
oldschema.sqlite3 \
static.zone

View File

@ -0,0 +1,6 @@
; This zone is broken (contains no NS records).
example.com. 1000 IN SOA a.dns.example.com. mail.example.com. 2 1 1 1 1
a.dns.example.com. 1000 IN A 1.1.1.1
b.dns.example.com. 1000 IN A 3.3.3.3
b.dns.example.com. 1000 IN AAAA 4:4::4:4
b.dns.example.com. 1000 IN AAAA 5:5::5:5

View File

@ -46,11 +46,13 @@ the data actually served, it only prepares them for future use.\n\
This is the first method you should call on the object. Never call it\n\
multiple times.\n\
\n\
Depending on how the ZoneWriter was constructed, in case a load error\n\
happens, a string with the error message may be returned. When\n\
ZoneWriter is not constructed to do that, in case of a load error, a\n\
DataSourceError exception is raised. In all other cases, this method\n\
returns None.\n\
If the zone loads successfully, this method returns None. In the case of\n\
a load error, if the ZoneWriter was constructed with the\n\
catch_load_error option (see\n\
ConfigurableClientList.get_cached_zone_writer()), this method will\n\
return an error message string; if it was created without the\n\
catch_load_error option, this method will raise a DataSourceError\n\
exception.\n\
\n\
Exceptions:\n\
isc.InvalidOperation if called second time.\n\