[svn] commit: r3997 - in /branches/trac446: ./ src/bin/auth/tests/ src/bin/bind10/ src/bin/bindctl/ src/bin/cmdctl/ src/bin/loadzone/ src/bin/msgq/ src/bin/stats/ src/bin/stats/tests/isc/util/ src/bin/usermgr/ src/bin/xfrin/ src/bin/xfrout/ src/bin/zonemgr/ src/lib/config/ src/lib/config/tests/ src/lib/config/tests/testdata/ src/lib/datasrc/ src/lib/datasrc/tests/ src/lib/python/isc/config/ src/lib/python/isc/config/tests/
BIND 10 source code commits
bind10-changes at lists.isc.org
Thu Dec 23 23:18:19 UTC 2010
Author: jinmei
Date: Thu Dec 23 23:18:18 2010
New Revision: 3997
Log:
sync with trunk, resolving a conflict.
Added:
branches/trac446/src/lib/config/tests/testdata/data22_9.data
- copied unchanged from r3996, trunk/src/lib/config/tests/testdata/data22_9.data
branches/trac446/src/lib/datasrc/result.h
- copied unchanged from r3996, trunk/src/lib/datasrc/result.h
branches/trac446/src/lib/datasrc/zone.h
- copied unchanged from r3996, trunk/src/lib/datasrc/zone.h
Modified:
branches/trac446/ (props changed)
branches/trac446/ChangeLog
branches/trac446/src/bin/auth/tests/query_unittest.cc
branches/trac446/src/bin/bind10/bind10.py.in (props changed)
branches/trac446/src/bin/bind10/run_bind10.sh.in
branches/trac446/src/bin/bindctl/run_bindctl.sh.in
branches/trac446/src/bin/cmdctl/run_b10-cmdctl.sh.in
branches/trac446/src/bin/loadzone/run_loadzone.sh.in
branches/trac446/src/bin/msgq/run_msgq.sh.in
branches/trac446/src/bin/stats/run_b10-stats.sh.in
branches/trac446/src/bin/stats/run_b10-stats_stub.sh.in
branches/trac446/src/bin/stats/tests/isc/util/ (props changed)
branches/trac446/src/bin/usermgr/run_b10-cmdctl-usermgr.sh.in
branches/trac446/src/bin/xfrin/run_b10-xfrin.sh.in
branches/trac446/src/bin/xfrout/run_b10-xfrout.sh.in
branches/trac446/src/bin/zonemgr/run_b10-zonemgr.sh.in
branches/trac446/src/lib/config/module_spec.cc
branches/trac446/src/lib/config/tests/module_spec_unittests.cc
branches/trac446/src/lib/config/tests/testdata/Makefile.am
branches/trac446/src/lib/config/tests/testdata/data22_8.data
branches/trac446/src/lib/datasrc/Makefile.am
branches/trac446/src/lib/datasrc/memory_datasrc.cc
branches/trac446/src/lib/datasrc/memory_datasrc.h
branches/trac446/src/lib/datasrc/tests/memory_datasrc_unittest.cc
branches/trac446/src/lib/datasrc/tests/zonetable_unittest.cc
branches/trac446/src/lib/datasrc/zonetable.cc
branches/trac446/src/lib/datasrc/zonetable.h
branches/trac446/src/lib/python/isc/config/ccsession.py
branches/trac446/src/lib/python/isc/config/config_data.py
branches/trac446/src/lib/python/isc/config/module_spec.py
branches/trac446/src/lib/python/isc/config/tests/ccsession_test.py
branches/trac446/src/lib/python/isc/config/tests/config_data_test.py
branches/trac446/src/lib/python/isc/config/tests/module_spec_test.py
Modified: branches/trac446/ChangeLog
==============================================================================
--- branches/trac446/ChangeLog (original)
+++ branches/trac446/ChangeLog Thu Dec 23 23:18:18 2010
@@ -1,3 +1,20 @@
+ 137. [bug] jreed
+ Fix run_*.sh scripts that are used for development testing
+ so they use a msgq socket file in the build tree.
+ (Trac #226, svn r3989)
+
+ 136. [bug] jelte
+ bindctl (and the configuration manager in general) now no longer
+ accepts 'unknown' data; i.e. data for modules that it does not know
+ about, or configuration items that are not specified in the .spec
+ files.
+ (Trac #202, svn r3967)
+
+ 135. [func] each
+ Add b10-recurse. This is an example recursive server that
+ currently does forwarding only and no caching.
+ (Trac #327, svn r3903)
+
134. [func] vorner
b10-recurse supports timeouts and retries in forwarder mode.
(Trac #401, svn r3660)
@@ -8,7 +25,7 @@
(Trac #393, r3602)
132. [func] vorner
- The b10-recursive is configured through config manager.
+ The b10-recurse is configured through config manager.
It has "listen_on" and "forward_addresses" options.
(Trac #389, r3448)
@@ -39,7 +56,6 @@
for root zone was added.
(Trac #85, svn r3836)
->>>>>>> .merge-right.r3894
127. [bug] stephen
During normal operation process termination and resurrection messages
are now output regardless of the state of the verbose flag.
Modified: branches/trac446/src/bin/auth/tests/query_unittest.cc
==============================================================================
--- branches/trac446/src/bin/auth/tests/query_unittest.cc (original)
+++ branches/trac446/src/bin/auth/tests/query_unittest.cc Thu Dec 23 23:18:18 2010
@@ -18,6 +18,7 @@
#include <dns/rrtype.h>
#include <datasrc/zonetable.h>
+#include <datasrc/memory_datasrc.h>
#include <auth/query.h>
Modified: branches/trac446/src/bin/bind10/run_bind10.sh.in
==============================================================================
--- branches/trac446/src/bin/bind10/run_bind10.sh.in (original)
+++ branches/trac446/src/bin/bind10/run_bind10.sh.in Thu Dec 23 23:18:18 2010
@@ -46,5 +46,5 @@
export BIND10_MSGQ_SOCKET_FILE
cd ${BIND10_PATH}
-exec ${PYTHON_EXEC} -O bind10 $*
+exec ${PYTHON_EXEC} -O bind10 "$@"
Modified: branches/trac446/src/bin/bindctl/run_bindctl.sh.in
==============================================================================
--- branches/trac446/src/bin/bindctl/run_bindctl.sh.in (original)
+++ branches/trac446/src/bin/bindctl/run_bindctl.sh.in Thu Dec 23 23:18:18 2010
@@ -26,5 +26,8 @@
B10_FROM_SOURCE=@abs_top_srcdir@
export B10_FROM_SOURCE
+BIND10_MSGQ_SOCKET_FILE=@abs_top_builddir@/msgq_socket
+export BIND10_MSGQ_SOCKET_FILE
+
cd ${BINDCTL_PATH}
-exec ${PYTHON_EXEC} -O bindctl $*
+exec ${PYTHON_EXEC} -O bindctl "$@"
Modified: branches/trac446/src/bin/cmdctl/run_b10-cmdctl.sh.in
==============================================================================
--- branches/trac446/src/bin/cmdctl/run_b10-cmdctl.sh.in (original)
+++ branches/trac446/src/bin/cmdctl/run_b10-cmdctl.sh.in Thu Dec 23 23:18:18 2010
@@ -22,6 +22,8 @@
PYTHONPATH=@abs_top_srcdir@/src/lib/python
export PYTHONPATH
+BIND10_MSGQ_SOCKET_FILE=@abs_top_builddir@/msgq_socket
+export BIND10_MSGQ_SOCKET_FILE
+
cd ${CMD_CTRLD_PATH}
-${PYTHON_EXEC} b10-cmdctl
-
+exec ${PYTHON_EXEC} b10-cmdctl "$@"
Modified: branches/trac446/src/bin/loadzone/run_loadzone.sh.in
==============================================================================
--- branches/trac446/src/bin/loadzone/run_loadzone.sh.in (original)
+++ branches/trac446/src/bin/loadzone/run_loadzone.sh.in Thu Dec 23 23:18:18 2010
@@ -21,5 +21,8 @@
PYTHONPATH=@abs_top_builddir@/src/lib/python
export PYTHONPATH
+BIND10_MSGQ_SOCKET_FILE=@abs_top_builddir@/msgq_socket
+export BIND10_MSGQ_SOCKET_FILE
+
LOADZONE_PATH=@abs_top_builddir@/src/bin/loadzone
-exec ${LOADZONE_PATH}/b10-loadzone $*
+exec ${LOADZONE_PATH}/b10-loadzone "$@"
Modified: branches/trac446/src/bin/msgq/run_msgq.sh.in
==============================================================================
--- branches/trac446/src/bin/msgq/run_msgq.sh.in (original)
+++ branches/trac446/src/bin/msgq/run_msgq.sh.in Thu Dec 23 23:18:18 2010
@@ -23,5 +23,8 @@
PYTHONPATH=@abs_top_srcdir@/src/lib/python
export PYTHONPATH
+BIND10_MSGQ_SOCKET_FILE=@abs_top_builddir@/msgq_socket
+export BIND10_MSGQ_SOCKET_FILE
+
cd ${MYPATH_PATH}
-exec ${PYTHON_EXEC} -O b10-msgq $*
+exec ${PYTHON_EXEC} -O b10-msgq "$@"
Modified: branches/trac446/src/bin/stats/run_b10-stats.sh.in
==============================================================================
--- branches/trac446/src/bin/stats/run_b10-stats.sh.in (original)
+++ branches/trac446/src/bin/stats/run_b10-stats.sh.in Thu Dec 23 23:18:18 2010
@@ -21,10 +21,13 @@
PYTHONPATH=@abs_top_builddir@/src/lib/python
export PYTHONPATH
+BIND10_MSGQ_SOCKET_FILE=@abs_top_builddir@/msgq_socket
+export BIND10_MSGQ_SOCKET_FILE
+
B10_FROM_BUILD=@abs_top_builddir@
export B10_FROM_BUILD
STATS_PATH=@abs_top_builddir@/src/bin/stats
cd ${STATS_PATH}
-exec ${PYTHON_EXEC} -O b10-stats $*
+exec ${PYTHON_EXEC} -O b10-stats "$@"
Modified: branches/trac446/src/bin/stats/run_b10-stats_stub.sh.in
==============================================================================
--- branches/trac446/src/bin/stats/run_b10-stats_stub.sh.in (original)
+++ branches/trac446/src/bin/stats/run_b10-stats_stub.sh.in Thu Dec 23 23:18:18 2010
@@ -24,7 +24,10 @@
B10_FROM_BUILD=@abs_top_srcdir@
export B10_FROM_BUILD
+BIND10_MSGQ_SOCKET_FILE=@abs_top_builddir@/msgq_socket
+export BIND10_MSGQ_SOCKET_FILE
+
STATS_PATH=@abs_top_builddir@/src/bin/stats
cd ${STATS_PATH}
-exec ${PYTHON_EXEC} -O b10-stats_stub $*
+exec ${PYTHON_EXEC} -O b10-stats_stub "$@"
Modified: branches/trac446/src/bin/usermgr/run_b10-cmdctl-usermgr.sh.in
==============================================================================
--- branches/trac446/src/bin/usermgr/run_b10-cmdctl-usermgr.sh.in (original)
+++ branches/trac446/src/bin/usermgr/run_b10-cmdctl-usermgr.sh.in Thu Dec 23 23:18:18 2010
@@ -20,6 +20,8 @@
MYPATH_PATH=@abs_top_builddir@/src/bin/usermgr
+BIND10_MSGQ_SOCKET_FILE=@abs_top_builddir@/msgq_socket
+export BIND10_MSGQ_SOCKET_FILE
+
cd ${MYPATH_PATH}
-${PYTHON_EXEC} b10-cmdctl-usermgr
-
+exec ${PYTHON_EXEC} b10-cmdctl-usermgr "$@"
Modified: branches/trac446/src/bin/xfrin/run_b10-xfrin.sh.in
==============================================================================
--- branches/trac446/src/bin/xfrin/run_b10-xfrin.sh.in (original)
+++ branches/trac446/src/bin/xfrin/run_b10-xfrin.sh.in Thu Dec 23 23:18:18 2010
@@ -22,6 +22,8 @@
PYTHONPATH=@abs_top_srcdir@/src/lib/python:@abs_top_builddir@/src/lib/dns/.libs
export PYTHONPATH
+BIND10_MSGQ_SOCKET_FILE=@abs_top_builddir@/msgq_socket
+export BIND10_MSGQ_SOCKET_FILE
+
cd ${MYPATH_PATH}
-${PYTHON_EXEC} b10-xfrin
-
+exec ${PYTHON_EXEC} b10-xfrin "$@"
Modified: branches/trac446/src/bin/xfrout/run_b10-xfrout.sh.in
==============================================================================
--- branches/trac446/src/bin/xfrout/run_b10-xfrout.sh.in (original)
+++ branches/trac446/src/bin/xfrout/run_b10-xfrout.sh.in Thu Dec 23 23:18:18 2010
@@ -22,6 +22,8 @@
PYTHONPATH=@abs_top_srcdir@/src/lib/python:@abs_top_builddir@/src/lib/xfr/.libs:@abs_top_builddir@/src/lib/dns/python/.libs
export PYTHONPATH
+BIND10_MSGQ_SOCKET_FILE=@abs_top_builddir@/msgq_socket
+export BIND10_MSGQ_SOCKET_FILE
+
cd ${MYPATH_PATH}
-${PYTHON_EXEC} b10-xfrout
-
+exec ${PYTHON_EXEC} b10-xfrout "$@"
Modified: branches/trac446/src/bin/zonemgr/run_b10-zonemgr.sh.in
==============================================================================
--- branches/trac446/src/bin/zonemgr/run_b10-zonemgr.sh.in (original)
+++ branches/trac446/src/bin/zonemgr/run_b10-zonemgr.sh.in Thu Dec 23 23:18:18 2010
@@ -22,6 +22,8 @@
PYTHONPATH=@abs_top_srcdir@/src/lib/python:@abs_top_builddir@/src/lib/dns/.libs
export PYTHONPATH
+BIND10_MSGQ_SOCKET_FILE=@abs_top_builddir@/msgq_socket
+export BIND10_MSGQ_SOCKET_FILE
+
cd ${MYPATH_PATH}
-${PYTHON_EXEC} b10-zonemgr
-
+exec ${PYTHON_EXEC} b10-zonemgr "$@"
Modified: branches/trac446/src/lib/config/module_spec.cc
==============================================================================
--- branches/trac446/src/lib/config/module_spec.cc (original)
+++ branches/trac446/src/lib/config/module_spec.cc Thu Dec 23 23:18:18 2010
@@ -330,14 +330,33 @@
ModuleSpec::validate_spec_list(ConstElementPtr spec, ConstElementPtr data,
const bool full, ElementPtr errors) const
{
+ bool validated = true;
std::string cur_item_name;
BOOST_FOREACH(ConstElementPtr cur_spec_el, spec->listValue()) {
if (!validate_spec(cur_spec_el, data, full, errors)) {
- return (false);
- }
- }
- return (true);
-}
-
-}
-}
+ validated = false;
+ }
+ }
+
+ typedef std::pair<std::string, ConstElementPtr> maptype;
+
+ BOOST_FOREACH(maptype m, data->mapValue()) {
+ bool found = false;
+ BOOST_FOREACH(ConstElementPtr cur_spec_el, spec->listValue()) {
+ if (cur_spec_el->get("item_name")->stringValue().compare(m.first) == 0) {
+ found = true;
+ }
+ }
+ if (!found) {
+ validated = false;
+ if (errors) {
+ errors->add(Element::create("Unknown item " + m.first));
+ }
+ }
+ }
+
+ return (validated);
+}
+
+}
+}
Modified: branches/trac446/src/lib/config/tests/module_spec_unittests.cc
==============================================================================
--- branches/trac446/src/lib/config/tests/module_spec_unittests.cc (original)
+++ branches/trac446/src/lib/config/tests/module_spec_unittests.cc Thu Dec 23 23:18:18 2010
@@ -166,8 +166,13 @@
EXPECT_TRUE(data_test(dd, "data22_6.data"));
EXPECT_TRUE(data_test(dd, "data22_7.data"));
EXPECT_FALSE(data_test(dd, "data22_8.data"));
+ EXPECT_FALSE(data_test(dd, "data22_9.data"));
ElementPtr errors = Element::createList();
EXPECT_FALSE(data_test_with_errors(dd, "data22_8.data", errors));
EXPECT_EQ("[ \"Type mismatch\" ]", errors->str());
+
+ errors = Element::createList();
+ EXPECT_FALSE(data_test_with_errors(dd, "data22_9.data", errors));
+ EXPECT_EQ("[ \"Unknown item value_does_not_exist\" ]", errors->str());
}
Modified: branches/trac446/src/lib/config/tests/testdata/Makefile.am
==============================================================================
--- branches/trac446/src/lib/config/tests/testdata/Makefile.am (original)
+++ branches/trac446/src/lib/config/tests/testdata/Makefile.am Thu Dec 23 23:18:18 2010
@@ -20,6 +20,7 @@
EXTRA_DIST += data22_6.data
EXTRA_DIST += data22_7.data
EXTRA_DIST += data22_8.data
+EXTRA_DIST += data22_9.data
EXTRA_DIST += spec1.spec
EXTRA_DIST += spec2.spec
EXTRA_DIST += spec3.spec
Modified: branches/trac446/src/lib/config/tests/testdata/data22_8.data
==============================================================================
--- branches/trac446/src/lib/config/tests/testdata/data22_8.data (original)
+++ branches/trac446/src/lib/config/tests/testdata/data22_8.data Thu Dec 23 23:18:18 2010
@@ -5,5 +5,6 @@
"value4": "foo",
"value5": [ 1, 2, 3 ],
"value6": { "v61": "bar", "v62": true },
- "value8": [ { "a": "d" }, { "a": 1 } ]
+ "value8": [ { "a": "d" }, { "a": 1 } ],
+ "value9": { "v91": "hi", "v92": { "v92a": "Hi", "v92b": 3 } }
}
Modified: branches/trac446/src/lib/datasrc/Makefile.am
==============================================================================
--- branches/trac446/src/lib/datasrc/Makefile.am (original)
+++ branches/trac446/src/lib/datasrc/Makefile.am Thu Dec 23 23:18:18 2010
@@ -15,6 +15,8 @@
libdatasrc_la_SOURCES += sqlite3_datasrc.h sqlite3_datasrc.cc
libdatasrc_la_SOURCES += query.h query.cc
libdatasrc_la_SOURCES += cache.h cache.cc
-libdatasrc_la_SOURCES += rbtree.h
+libdatasrc_la_SOURCES += rbtree.h
libdatasrc_la_SOURCES += zonetable.h zonetable.cc
libdatasrc_la_SOURCES += memory_datasrc.h memory_datasrc.cc
+libdatasrc_la_SOURCES += zone.h
+libdatasrc_la_SOURCES += result.h
Modified: branches/trac446/src/lib/datasrc/memory_datasrc.cc
==============================================================================
--- branches/trac446/src/lib/datasrc/memory_datasrc.cc (original)
+++ branches/trac446/src/lib/datasrc/memory_datasrc.cc Thu Dec 23 23:18:18 2010
@@ -12,14 +12,77 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include <map>
+#include <boost/shared_ptr.hpp>
+
#include <dns/name.h>
+#include <dns/rrclass.h>
+
#include <datasrc/memory_datasrc.h>
+#include <datasrc/rbtree.h>
using namespace std;
using namespace isc::dns;
namespace isc {
namespace datasrc {
+
+// Private data and hidden methods of MemoryZone
+struct MemoryZone::MemoryZoneImpl {
+ // Constructor
+ MemoryZoneImpl(const RRClass& zone_class, const Name& origin) :
+ zone_class_(zone_class), origin_(origin)
+ {}
+
+ // Information about the zone
+ RRClass zone_class_;
+ Name origin_;
+
+ // Some type aliases
+ /*
+ * Each domain consists of some RRsets. They will be looked up by the
+ * RRType.
+ *
+ * The use of map is questionable with regard to performance - there'll
+ * be usually only few RRsets in the domain, so the log n benefit isn't
+ * much and a vector/array might be faster due to its simplicity and
+ * continuous memory location. But this is unlikely to be a performance
+ * critical place and map has better interface for the lookups, so we use
+ * that.
+ */
+ typedef map<RRType, ConstRRsetPtr> Domain;
+ typedef boost::shared_ptr<Domain> DomainPtr;
+ // The tree stores domains
+ typedef RBTree<Domain> DomainTree;
+ typedef RBNode<Domain> DomainNode;
+ // The actual zone data
+ DomainTree domains_;
+};
+
+MemoryZone::MemoryZone(const RRClass& zone_class, const Name& origin) :
+ impl_(new MemoryZoneImpl(zone_class, origin))
+{
+}
+
+MemoryZone::~MemoryZone() {
+ delete impl_;
+}
+
+const Name&
+MemoryZone::getOrigin() const {
+ return (impl_->origin_);
+}
+
+const RRClass&
+MemoryZone::getClass() const {
+ return (impl_->zone_class_);
+}
+
+Zone::FindResult
+MemoryZone::find(const Name&, const RRType&) const {
+ // This is a tentative implementation that always returns NXDOMAIN.
+ return (FindResult(NXDOMAIN, RRsetPtr()));
+}
/// Implementation details for \c MemoryDataSrc hidden from the public
/// interface.
Modified: branches/trac446/src/lib/datasrc/memory_datasrc.h
==============================================================================
--- branches/trac446/src/lib/datasrc/memory_datasrc.h (original)
+++ branches/trac446/src/lib/datasrc/memory_datasrc.h Thu Dec 23 23:18:18 2010
@@ -24,6 +24,51 @@
namespace datasrc {
+/// A derived zone class intended to be used with the memory data source.
+class MemoryZone : public Zone {
+ ///
+ /// \name Constructors and Destructor.
+ ///
+ /// \b Note:
+ /// The copy constructor and the assignment operator are intentionally
+ /// defined as private, making this class non copyable.
+ //@{
+private:
+ MemoryZone(const MemoryZone& source);
+ MemoryZone& operator=(const MemoryZone& source);
+public:
+ /// \brief Constructor from zone parameters.
+ ///
+ /// This constructor internally involves resource allocation, and if
+ /// it fails, a corresponding standard exception will be thrown.
+ /// It never throws an exception otherwise.
+ ///
+ /// \param rrclass The RR class of the zone.
+ /// \param origin The origin name of the zone.
+ MemoryZone(const isc::dns::RRClass& rrclass, const isc::dns::Name& origin);
+
+ /// The destructor.
+ virtual ~MemoryZone();
+ //@}
+
+ /// \brief Returns the origin of the zone.
+ virtual const isc::dns::Name& getOrigin() const;
+ /// \brief Returns the class of the zone.
+ virtual const isc::dns::RRClass& getClass() const;
+ /// \brief Looks up an RRset in the zone.
+ ///
+ /// See documentation in \c Zone.
+ virtual FindResult find(const isc::dns::Name& name,
+ const isc::dns::RRType& type) const;
+
+private:
+ /// \name Hidden private data
+ //@{
+ struct MemoryZoneImpl;
+ MemoryZoneImpl* impl_;
+ //@}
+};
+
/// \brief A data source that uses in memory dedicated backend.
///
/// The \c MemoryDataSrc class represents a data source and provides a
Modified: branches/trac446/src/lib/datasrc/tests/memory_datasrc_unittest.cc
==============================================================================
--- branches/trac446/src/lib/datasrc/tests/memory_datasrc_unittest.cc (original)
+++ branches/trac446/src/lib/datasrc/tests/memory_datasrc_unittest.cc Thu Dec 23 23:18:18 2010
@@ -17,7 +17,6 @@
#include <dns/name.h>
#include <dns/rrclass.h>
-#include <datasrc/zonetable.h>
#include <datasrc/memory_datasrc.h>
#include <gtest/gtest.h>
@@ -114,7 +113,6 @@
memory_datasrc.findZone(Name("z.i.g.h")).zone->getOrigin());
}
-
TEST_F(MemoryDataSrcTest, getZoneCount) {
EXPECT_EQ(0, memory_datasrc.getZoneCount());
memory_datasrc.addZone(
@@ -131,4 +129,30 @@
ZonePtr(new MemoryZone(rrclass, Name("example.org"))));
EXPECT_EQ(2, memory_datasrc.getZoneCount());
}
+
+/// \brief Test fixture for the MemoryZone class
+class MemoryZoneTest : public ::testing::Test {
+public:
+ MemoryZoneTest() :
+ class_(RRClass::IN()),
+ origin_("example.org"),
+ zone_(class_, origin_)
+ { }
+ // Some data to test with
+ RRClass class_;
+ Name origin_;
+ // The zone to torture by tests
+ MemoryZone zone_;
+};
+
+/**
+ * \brief Test MemoryZone::MemoryZone constructor.
+ *
+ * Takes the created zone and checks its properties they are the same
+ * as passed parameters.
+ */
+TEST_F(MemoryZoneTest, Constructor) {
+ ASSERT_EQ(class_, zone_.getClass());
+ ASSERT_EQ(origin_, zone_.getOrigin());
}
+}
Modified: branches/trac446/src/lib/datasrc/tests/zonetable_unittest.cc
==============================================================================
--- branches/trac446/src/lib/datasrc/tests/zonetable_unittest.cc (original)
+++ branches/trac446/src/lib/datasrc/tests/zonetable_unittest.cc Thu Dec 23 23:18:18 2010
@@ -18,6 +18,8 @@
#include <dns/rrclass.h>
#include <datasrc/zonetable.h>
+// We use MemoryZone to put something into the table
+#include <datasrc/memory_datasrc.h>
#include <gtest/gtest.h>
@@ -73,7 +75,7 @@
EXPECT_THROW(zone_table.addZone(ZonePtr()), isc::InvalidParameter);
}
-TEST_F(ZoneTableTest, removeZone) {
+TEST_F(ZoneTableTest, DISABLED_removeZone) {
EXPECT_EQ(result::SUCCESS, zone_table.addZone(zone1));
EXPECT_EQ(result::SUCCESS, zone_table.addZone(zone2));
EXPECT_EQ(result::SUCCESS, zone_table.addZone(zone3));
Modified: branches/trac446/src/lib/datasrc/zonetable.cc
==============================================================================
--- branches/trac446/src/lib/datasrc/zonetable.cc (original)
+++ branches/trac446/src/lib/datasrc/zonetable.cc Thu Dec 23 23:18:18 2010
@@ -12,15 +12,12 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-// Note: map and utility (for 'pair') are for temporary workaround.
-// we'll soon replace them with built-in intelligent backend structure.
-#include <map>
-#include <utility>
+#include <cassert>
#include <dns/name.h>
-#include <dns/rrclass.h>
#include <datasrc/zonetable.h>
+#include <datasrc/rbtree.h>
using namespace std;
using namespace isc::dns;
@@ -28,46 +25,77 @@
namespace isc {
namespace datasrc {
-struct MemoryZone::MemoryZoneImpl {
- MemoryZoneImpl(const RRClass& zone_class, const Name& origin) :
- zone_class_(zone_class), origin_(origin)
- {}
- RRClass zone_class_;
- Name origin_;
-};
+/// \short Private data and implementation of ZoneTable
+struct ZoneTable::ZoneTableImpl {
+ // Type aliases to make it shorter
+ typedef RBTree<Zone> ZoneTree;
+ typedef RBNode<Zone> ZoneNode;
+ // The actual storage
+ ZoneTree zones_;
-MemoryZone::MemoryZone(const RRClass& zone_class, const Name& origin) :
- impl_(new MemoryZoneImpl(zone_class, origin))
-{
-}
+ /*
+ * The implementation methods are here and just wrap-called in the
+ * ZoneTable. We have variables locally (without impl_->), have
+ * type aliases, etc. And they will get inlined anyway.
+ */
-MemoryZone::~MemoryZone() {
- delete impl_;
-}
+ // Implementation of ZoneTable::addZone
+ result::Result addZone(ZonePtr zone) {
+ // Sanity check
+ if (!zone) {
+ isc_throw(InvalidParameter,
+ "Null pointer is passed to ZoneTable::addZone()");
+ }
-const Name&
-MemoryZone::getOrigin() const {
- return (impl_->origin_);
-}
+ // Get the node where we put the zone
+ ZoneNode* node(NULL);
+ switch (zones_.insert(zone->getOrigin(), &node)) {
+ // This is OK
+ case ZoneTree::SUCCEED:
+ case ZoneTree::ALREADYEXIST:
+ break;
+ // Can Not Happen
+ default:
+ assert(0);
+ }
+ // Can Not Happen
+ assert(node);
-const RRClass&
-MemoryZone::getClass() const {
- return (impl_->zone_class_);
-}
+ // Is it empty? We either just created it or it might be nonterminal
+ if (node->isEmpty()) {
+ node->setData(zone);
+ return (result::SUCCESS);
+ } else { // There's something there already
+ return (result::EXIST);
+ }
+ }
-Zone::FindResult
-MemoryZone::find(const Name&, const RRType&) const {
- // This is a tentative implementation that always returns NXDOMAIN.
- return (FindResult(NXDOMAIN, RRsetPtr()));
-}
+ // Implementation of ZoneTable::findZone
+ ZoneTable::FindResult findZone(const Name& name) const {
+ ZoneNode *node(NULL);
+ result::Result my_result;
-// This is a temporary, inefficient implementation using std::map and handmade
-// iteration to realize longest match.
+ // Translate the return codes
+ switch (zones_.find(name, &node)) {
+ case ZoneTree::EXACTMATCH:
+ my_result = result::SUCCESS;
+ break;
+ case ZoneTree::PARTIALMATCH:
+ my_result = result::PARTIALMATCH;
+ break;
+ // We have no data there, so translate the pointer to NULL as well
+ case ZoneTree::NOTFOUND:
+ return (FindResult(result::NOTFOUND, ConstZonePtr()));
+ // Can Not Happen
+ default:
+ assert(0);
+ }
-struct ZoneTable::ZoneTableImpl {
- typedef map<Name, ZonePtr> ZoneMap;
- typedef pair<Name, ZonePtr> NameAndZone;
- ZoneMap zones;
+ // Can Not Happen (remember, NOTFOUND is handled)
+ assert(node);
+
+ return (FindResult(my_result, node->getData()));
+ }
};
ZoneTable::ZoneTable() : impl_(new ZoneTableImpl)
@@ -79,40 +107,21 @@
result::Result
ZoneTable::addZone(ZonePtr zone) {
- if (!zone) {
- isc_throw(InvalidParameter,
- "Null pointer is passed to ZoneTable::addZone()");
- }
-
- if (impl_->zones.insert(
- ZoneTableImpl::NameAndZone(zone->getOrigin(), zone)).second
- == true) {
- return (result::SUCCESS);
- } else {
- return (result::EXIST);
- }
+ return (impl_->addZone(zone));
}
result::Result
-ZoneTable::removeZone(const Name& origin) {
- return (impl_->zones.erase(origin) == 1 ? result::SUCCESS :
- result::NOTFOUND);
+ZoneTable::removeZone(const Name&) {
+ // TODO Implement
+ assert(0);
+ // This should not ever be returned, the assert should kill us by now
+ return (result::SUCCESS);
}
ZoneTable::FindResult
ZoneTable::findZone(const Name& name) const {
- // Inefficient internal loop to find a longest match.
- // This will be replaced with a single call to more intelligent backend.
- for (int i = 0; i < name.getLabelCount(); ++i) {
- Name matchname(name.split(i));
- ZoneTableImpl::ZoneMap::const_iterator found =
- impl_->zones.find(matchname);
- if (found != impl_->zones.end()) {
- return (FindResult(i == 0 ? result::SUCCESS :
- result::PARTIALMATCH, (*found).second));
- }
- }
- return (FindResult(result::NOTFOUND, ConstZonePtr()));
+ return (impl_->findZone(name));
}
+
} // end of namespace datasrc
} // end of namespace isc
Modified: branches/trac446/src/lib/datasrc/zonetable.h
==============================================================================
--- branches/trac446/src/lib/datasrc/zonetable.h (original)
+++ branches/trac446/src/lib/datasrc/zonetable.h Thu Dec 23 23:18:18 2010
@@ -19,6 +19,8 @@
#include <dns/rrset.h>
+#include <datasrc/zone.h>
+
namespace isc {
namespace dns {
class Name;
@@ -26,215 +28,6 @@
};
namespace datasrc {
-namespace result {
-/// Result codes of various public methods of in memory data source
-///
-/// The detailed semantics may differ in different methods.
-/// See the description of specific methods for more details.
-///
-/// Note: this is intended to be used from other data sources eventually,
-/// but for now it's specific to in memory data source and its backend.
-enum Result {
- SUCCESS, ///< The operation is successful.
- EXIST, ///< The search key is already stored.
- NOTFOUND, ///< The specified object is not found.
- PARTIALMATCH ///< \c Only a partial match is found.
-};
-}
-
-/// \brief The base class for a single authoritative zone
-///
-/// The \c Zone class is an abstract base class for representing
-/// a DNS zone as part of data source.
-///
-/// At the moment this is provided mainly for making the \c ZoneTable class
-/// and the authoritative query logic testable, and only provides a minimal
-/// set of features.
-/// This is why this class is defined in the same header file, but it may
-/// have to move to a separate header file when we understand what is
-/// necessary for this class for actual operation.
-///
-/// The idea is to provide a specific derived zone class for each data
-/// source, beginning with in memory one. At that point the derived classes
-/// will have more specific features. For example, they will maintain
-/// information about the location of a zone file, whether it's loaded in
-/// memory, etc.
-///
-/// It's not yet clear how the derived zone classes work with various other
-/// data sources when we integrate these components, but one possibility is
-/// something like this:
-/// - If the underlying database such as some variant of SQL doesn't have an
-/// explicit representation of zones (as part of public interface), we can
-/// probably use a "default" zone class that simply encapsulates the
-/// corresponding data source and calls a common "find" like method.
-/// - Some data source may want to specialize it by inheritance as an
-/// optimization. For example, in the current schema design of the sqlite3
-/// data source, its (derived) zone class would contain the information of
-/// the "zone ID".
-///
-/// <b>Note:</b> Unlike some other abstract base classes we don't name the
-/// class beginning with "Abstract". This is because we want to have
-/// commonly used definitions such as \c Result and \c ZonePtr, and we want
-/// to make them look more intuitive.
-class Zone {
-public:
- /// Result codes of the \c find() method.
- ///
- /// Note: the codes are tentative. We may need more, or we may find
- /// some of them unnecessary as we implement more details.
- enum Result {
- SUCCESS, ///< An exact match is found.
- DELEGATION, ///< The search encounters a zone cut.
- NXDOMAIN, ///< There is no domain name that matches the search name
- NXRRSET, ///< There is a matching name but no RRset of the search type
- CNAME, ///< The search encounters and returns a CNAME RR
- DNAME ///< The search encounters and returns a DNAME RR
- };
-
- /// A helper structure to represent the search result of \c find().
- ///
- /// This is a straightforward tuple of the result code and a pointer
- /// to the found RRset to represent the result of \c find()
- /// (there will be more members in the future - see the class
- /// description).
- /// We use this in order to avoid overloading the return value for both
- /// the result code ("success" or "not found") and the found object,
- /// i.e., avoid using \c NULL to mean "not found", etc.
- ///
- /// This is a simple value class whose internal state never changes,
- /// so for convenience we allow the applications to refer to the members
- /// directly.
- ///
- /// Note: we should eventually include a notion of "zone node", which
- /// corresponds to a particular domain name of the zone, so that we can
- /// find RRsets of a different RR type for that name (e.g. for type ANY
- /// query or to include DS RRs with delegation).
- ///
- /// Note: we may also want to include the closest enclosure "node" to
- /// optimize including the NSEC for no-wildcard proof (FWIW NSD does that).
- struct FindResult {
- FindResult(Result param_code,
- const isc::dns::ConstRRsetPtr param_rrset) :
- code(param_code), rrset(param_rrset)
- {}
- const Result code;
- const isc::dns::ConstRRsetPtr rrset;
- };
-
- ///
- /// \name Constructors and Destructor.
- ///
- //@{
-protected:
- /// The default constructor.
- ///
- /// This is intentionally defined as \c protected as this base class should
- /// never be instantiated (except as part of a derived class).
- Zone() {}
-public:
- /// The destructor.
- virtual ~Zone() {}
- //@}
-
- ///
- /// \name Getter Methods
- ///
- /// These methods should never throw an exception.
- //@{
- /// Return the origin name of the zone.
- virtual const isc::dns::Name& getOrigin() const = 0;
-
- /// Return the RR class of the zone.
- virtual const isc::dns::RRClass& getClass() const = 0;
- //@}
-
- ///
- /// \name Search Method
- ///
- //@{
- /// Search the zone for a given pair of domain name and RR type.
- ///
- /// Each derived version of this method searches the underlying backend
- /// for the data that best matches the given name and type.
- /// This method is expected to be "intelligent", and identifies the
- /// best possible answer for the search key. Specifically,
- /// - If the search name belongs under a zone cut, it returns the code
- /// of \c DELEGATION and the NS RRset at the zone cut.
- /// - If there is no matching name, it returns the code of \c NXDOMAIN,
- /// and, if DNSSEC is requested, the NSEC RRset that proves the
- /// non-existence.
- /// - If there is a matching name but no RRset of the search type, it
- /// returns the code of \c NXRRSET, and, if DNSSEC is required,
- /// the NSEC RRset for that name.
- /// - If there is a matching name with CNAME, it returns the code of
- /// \c CNAME and that CNAME RR.
- /// - If the search name matches a delegation point of DNAME, it returns
- /// the code of \c DNAME and that DNAME RR.
- ///
- /// A derived version of this method may involve internal resource
- /// allocation, especially for constructing the resulting RRset, and may
- /// throw an exception if it fails.
- /// It should not throw other types of exceptions.
- ///
- /// Note: It's quite likely that we'll need to specify search options.
- /// For example, we should be able to specify whether to allow returning
- /// glue records at or under a zone cut. We leave this interface open
- /// at this moment.
- ///
- /// \param name The domain name to be searched for.
- /// \param type The RR type to be searched for.
- /// \return A \c FindResult object enclosing the search result (see above).
- virtual FindResult find(const isc::dns::Name& name,
- const isc::dns::RRType& type) const = 0;
- //@}
-};
-
-/// \brief A pointer-like type pointing to a \c Zone object.
-typedef boost::shared_ptr<Zone> ZonePtr;
-
-/// \brief A pointer-like type pointing to a \c Zone object.
-typedef boost::shared_ptr<const Zone> ConstZonePtr;
-
-/// A derived zone class intended to be used with the memory data source.
-///
-/// Currently this is almost empty and is only used for testing the
-/// \c ZoneTable class. It will be substantially expanded, and will probably
-/// moved to a separate header file.
-class MemoryZone : public Zone {
- ///
- /// \name Constructors and Destructor.
- ///
- /// \b Note:
- /// The copy constructor and the assignment operator are intentionally
- /// defined as private, making this class non copyable.
- //@{
-private:
- MemoryZone(const MemoryZone& source);
- MemoryZone& operator=(const MemoryZone& source);
-public:
- /// \brief Constructor from zone parameters.
- ///
- /// This constructor internally involves resource allocation, and if
- /// it fails, a corresponding standard exception will be thrown.
- /// It never throws an exception otherwise.
- ///
- /// \param rrclass The RR class of the zone.
- /// \param origin The origin name of the zone.
- MemoryZone(const isc::dns::RRClass& rrclass, const isc::dns::Name& origin);
-
- /// The destructor.
- virtual ~MemoryZone();
- //@}
-
- virtual const isc::dns::Name& getOrigin() const;
- virtual const isc::dns::RRClass& getClass() const;
- virtual FindResult find(const isc::dns::Name& name,
- const isc::dns::RRType& type) const;
-
-private:
- struct MemoryZoneImpl;
- MemoryZoneImpl* impl_;
-};
/// \brief A set of authoritative zones.
///
@@ -278,8 +71,18 @@
//@}
/// Add a \c Zone to the \c ZoneTable.
- /// See the description of <code>MemoryDataSrc::addZone()</code> for more
- /// details.
+ ///
+ /// \c Zone must not be associated with a NULL pointer; otherwise
+ /// an exception of class \c InvalidParameter will be thrown.
+ /// If internal resource allocation fails, a corresponding standard
+ /// exception will be thrown.
+ /// This method never throws an exception otherwise.
+ ///
+ /// \param zone A \c Zone object to be added.
+ /// \return \c result::SUCCESS If the zone is successfully
+ /// added to the zone table.
+ /// \return \c result::EXIST The zone table already contains
+ /// zone of the same origin.
result::Result addZone(ZonePtr zone);
/// Remove a \c Zone of the given origin name from the \c ZoneTable.
@@ -294,8 +97,23 @@
result::Result removeZone(const isc::dns::Name& origin);
/// Find a \c Zone that best matches the given name in the \c ZoneTable.
- /// See the description of <code>MemoryDataSrc::findZone()</code> for more
- /// details.
+ ///
+ /// It searches the internal storage for a \c Zone that gives the
+ /// longest match against \c name, and returns the result in the
+ /// form of a \c FindResult object as follows:
+ /// - \c code: The result code of the operation.
+ /// - \c result::SUCCESS: A zone that gives an exact match
+ /// is found
+ /// - \c result::PARTIALMATCH: A zone whose origin is a
+ /// super domain of \c name is found (but there is no exact match)
+ /// - \c result::NOTFOUND: For all other cases.
+ /// - \c zone: A <Boost> shared pointer to the found \c Zone object if one
+ /// is found; otherwise \c NULL.
+ ///
+ /// This method never throws an exception.
+ ///
+ /// \param name A domain name for which the search is performed.
+ /// \return A \c FindResult object enclosing the search result (see above).
FindResult findZone(const isc::dns::Name& name) const;
private:
Modified: branches/trac446/src/lib/python/isc/config/ccsession.py
==============================================================================
--- branches/trac446/src/lib/python/isc/config/ccsession.py (original)
+++ branches/trac446/src/lib/python/isc/config/ccsession.py Thu Dec 23 23:18:18 2010
@@ -224,7 +224,7 @@
if not self._config_handler:
answer = create_answer(2, self._module_name + " has no config handler")
elif not self.get_module_spec().validate_config(False, new_config, errors):
- answer = create_answer(1, " ".join(errors))
+ answer = create_answer(1, ", ".join(errors))
else:
isc.cc.data.remove_identical(new_config, self.get_local_config())
answer = self._config_handler(new_config)
@@ -422,7 +422,16 @@
"""Commit all local changes, send them through b10-cmdctl to
the configuration manager"""
if self.get_local_changes():
- self._conn.send_POST('/ConfigManager/set_config', [ self.get_local_changes() ])
- # todo: check result
- self.request_current_config()
- self.clear_local_changes()
+ response = self._conn.send_POST('/ConfigManager/set_config',
+ [ self.get_local_changes() ])
+ answer = isc.cc.data.parse_value_str(response.read().decode())
+ # answer is either an empty dict (on success), or one
+ # containing errors
+ if answer == {}:
+ self.request_current_config()
+ self.clear_local_changes()
+ elif "error" in answer:
+ print("Error: " + answer["error"])
+ print("Configuration not committed")
+ else:
+ raise ModuleCCSessionError("Unknown format of answer in commit(): " + str(answer))
Modified: branches/trac446/src/lib/python/isc/config/config_data.py
==============================================================================
--- branches/trac446/src/lib/python/isc/config/config_data.py (original)
+++ branches/trac446/src/lib/python/isc/config/config_data.py Thu Dec 23 23:18:18 2010
@@ -464,12 +464,15 @@
there is a specification for the given identifier, the type
is checked."""
spec_part = self.find_spec_part(identifier)
- if spec_part is not None and value is not None:
- id, list_indices = isc.cc.data.split_identifier_list_indices(identifier)
- if list_indices is not None \
- and spec_part['item_type'] == 'list':
- spec_part = spec_part['list_item_spec']
- check_type(spec_part, value)
+ if spec_part is not None:
+ if value is not None:
+ id, list_indices = isc.cc.data.split_identifier_list_indices(identifier)
+ if list_indices is not None \
+ and spec_part['item_type'] == 'list':
+ spec_part = spec_part['list_item_spec']
+ check_type(spec_part, value)
+ else:
+ raise isc.cc.data.DataNotFoundError(identifier)
# Since we do not support list diffs (yet?), we need to
# copy the currently set list of items to _local_changes
Modified: branches/trac446/src/lib/python/isc/config/module_spec.py
==============================================================================
--- branches/trac446/src/lib/python/isc/config/module_spec.py (original)
+++ branches/trac446/src/lib/python/isc/config/module_spec.py Thu Dec 23 23:18:18 2010
@@ -328,7 +328,24 @@
return True
def _validate_spec_list(module_spec, full, data, errors):
+ # we do not return immediately, there may be more errors
+ # so we keep a boolean to keep track if we found errors
+ validated = True
+
+ # check if the known items are correct
for spec_item in module_spec:
if not _validate_spec(spec_item, full, data, errors):
- return False
- return True
+ validated = False
+
+ # check if there are items in our data that are not in the
+ # specification
+ for item_name in data:
+ found = False
+ for spec_item in module_spec:
+ if spec_item["item_name"] == item_name:
+ found = True
+ if not found:
+ if errors != None:
+ errors.append("unknown item " + item_name)
+ validated = False
+ return validated
Modified: branches/trac446/src/lib/python/isc/config/tests/ccsession_test.py
==============================================================================
--- branches/trac446/src/lib/python/isc/config/tests/ccsession_test.py (original)
+++ branches/trac446/src/lib/python/isc/config/tests/ccsession_test.py Thu Dec 23 23:18:18 2010
@@ -290,7 +290,7 @@
mccs = self.create_session("spec2.spec", None, None, fake_session)
mccs.set_config_handler(self.my_config_handler_ok)
self.assertEqual(len(fake_session.message_queue), 0)
- cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'Spec2': { 'item1': 2 }})
+ cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'item1': 2 })
fake_session.group_sendmsg(cmd, 'Spec2')
self.assertEqual(len(fake_session.message_queue), 1)
mccs.check_command()
@@ -303,12 +303,12 @@
mccs = self.create_session("spec2.spec", None, None, fake_session)
mccs.set_config_handler(self.my_config_handler_err)
self.assertEqual(len(fake_session.message_queue), 0)
- cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'Spec2': { 'item1': 'aaa' }})
+ cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'item1': 'aaa' })
fake_session.group_sendmsg(cmd, 'Spec2')
self.assertEqual(len(fake_session.message_queue), 1)
mccs.check_command()
self.assertEqual(len(fake_session.message_queue), 1)
- self.assertEqual({'result': [1, 'just an error']},
+ self.assertEqual({'result': [1, 'aaa should be an integer']},
fake_session.get_message('Spec2', None))
def test_check_command5(self):
@@ -316,12 +316,12 @@
mccs = self.create_session("spec2.spec", None, None, fake_session)
mccs.set_config_handler(self.my_config_handler_exc)
self.assertEqual(len(fake_session.message_queue), 0)
- cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'Spec2': { 'item1': 'aaa' }})
+ cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'item1': 'aaa' })
fake_session.group_sendmsg(cmd, 'Spec2')
self.assertEqual(len(fake_session.message_queue), 1)
mccs.check_command()
self.assertEqual(len(fake_session.message_queue), 1)
- self.assertEqual({'result': [1, 'just an exception']},
+ self.assertEqual({'result': [1, 'aaa should be an integer']},
fake_session.get_message('Spec2', None))
def test_check_command6(self):
@@ -416,7 +416,7 @@
mccs = self.create_session("spec2.spec", None, None, fake_session)
mccs.set_config_handler(self.my_config_handler_ok)
self.assertEqual(len(fake_session.message_queue), 0)
- cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'Spec2': { 'item1': 2 }})
+ cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'item1': 2 })
self.assertEqual(len(fake_session.message_queue), 0)
env = { 'group':'Spec2', 'from':None }
mccs.check_command_without_recvmsg(cmd, env)
@@ -559,6 +559,14 @@
mccs.check_command()
self.assertEqual(len(fake_session.message_queue), 0)
+
+class fakeData:
+ def decode(self):
+ return "{}";
+
+class fakeAnswer:
+ def read(self):
+ return fakeData();
class fakeUIConn():
def __init__(self):
@@ -581,7 +589,7 @@
if name in self.post_answers:
return self.post_answers[name]
else:
- return None
+ return fakeAnswer()
class TestUIModuleCCSession(unittest.TestCase):
Modified: branches/trac446/src/lib/python/isc/config/tests/config_data_test.py
==============================================================================
--- branches/trac446/src/lib/python/isc/config/tests/config_data_test.py (original)
+++ branches/trac446/src/lib/python/isc/config/tests/config_data_test.py Thu Dec 23 23:18:18 2010
@@ -335,6 +335,8 @@
pass
def test_get_local_value(self):
+ module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
+ self.mcd.set_specification(module_spec)
value = self.mcd.get_local_value("Spec2/item1")
self.assertEqual(None, value)
self.mcd.set_value("Spec2/item1", 2)
@@ -464,12 +466,11 @@
module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
self.mcd.set_specification(module_spec)
self.mcd.set_value("Spec2/item1", 2)
- self.assertRaises(isc.cc.data.DataTypeError, self.mcd.set_value, "Spec2/item1", "asdf")
-
- self.mcd.set_value("Spec2/no_such_item", 4)
- value, status = self.mcd.get_value("Spec2/no_such_item")
- self.assertEqual(value, 4)
- self.assertEqual(MultiConfigData.LOCAL, status)
+ self.assertRaises(isc.cc.data.DataTypeError,
+ self.mcd.set_value, "Spec2/item1", "asdf")
+
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self.mcd.set_value, "Spec2/no_such_item", 4)
self.mcd.set_value("Spec2/item5[0]", "c")
value, status = self.mcd.get_value("Spec2/item5[0]")
Modified: branches/trac446/src/lib/python/isc/config/tests/module_spec_test.py
==============================================================================
--- branches/trac446/src/lib/python/isc/config/tests/module_spec_test.py (original)
+++ branches/trac446/src/lib/python/isc/config/tests/module_spec_test.py Thu Dec 23 23:18:18 2010
@@ -312,6 +312,18 @@
self.assertEqual(False, isc.config.module_spec._validate_spec(spec, True, {}, None))
self.assertEqual(False, isc.config.module_spec._validate_spec(spec, True, {}, errors))
self.assertEqual(['non-optional item an_item missing'], errors)
+
+ def test_validate_unknown_items(self):
+ spec = [{ 'item_name': "an_item",
+ 'item_type': "string",
+ 'item_optional': True,
+ 'item_default': "asdf"
+ }]
+
+ errors = []
+ self.assertEqual(False, isc.config.module_spec._validate_spec_list(spec, True, { 'does_not_exist': 1 }, None))
+ self.assertEqual(False, isc.config.module_spec._validate_spec_list(spec, True, { 'does_not_exist': 1 }, errors))
+ self.assertEqual(['unknown item does_not_exist'], errors)
More information about the bind10-changes
mailing list