Commit fa17460c authored by Jelte Jansen's avatar Jelte Jansen
Browse files

sync with trunk


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac327@3901 e5f2f494-b856-4b98-b285-d166d9295462
parents 4c538c51 f9ccf457
......@@ -12,6 +12,34 @@
It has "listen_on" and "forward_addresses" options.
(Trac #389, r3448)
131. [func] feng, jerry
src/lib/datasrc: Introduced two template classes RBTree and RBNode
to provide the generic map with domain name as key and anything as
the value. Because of some unresolved design issue, the new classes
are only intended to be used by memory zone and zone table.
(Trac #397, svn r3890)
130. [func] jerry
src/lib/datasrc: Introduced a new class MemoryDataSrc to provide
the general interface for memory data source. For the initial
implementation, we don't make it a derived class of AbstractDataSrc
because the interface is so different(we'll eventually consider this
as part of the generalization work).
(Trac #422, svn r3866)
129. [func] jinmei
src/lib/dns: Added new functions masterLoad() for loading master
zone files. The initial implementation can only parse a limited
form of master files, but BIND 9's named-compilezone can convert
any valid zone file into the acceptable form.
(Trac #423, svn r3857)
128. [build] vorner
Test for query name = '.', type = DS to authoritative nameserver
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.
......
......@@ -195,17 +195,50 @@ fi
# specify the default warning flags in CXXFLAGS and let specific modules
# "override" the default.
# This may be used to try linker flags.
AC_DEFUN([BIND10_CXX_TRY_FLAG], [
AC_MSG_CHECKING([whether $CXX supports $1])
bind10_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $1"
AC_LINK_IFELSE([int main(void){ return 0;} ],
[bind10_cxx_flag=yes], [bind10_cxx_flag=no])
CXXFLAGS="$bind10_save_CXXFLAGS"
if test "x$bind10_cxx_flag" = "xyes"; then
ifelse([$2], , :, [$2])
else
ifelse([$3], , :, [$3])
fi
AC_MSG_RESULT([$bind10_cxx_flag])
])
werror_ok=0
# SunStudio compiler requires special compiler options for boost
# (http://blogs.sun.com/sga/entry/boost_mini_howto)
if test "$SUNCXX" = "yes"; then
CXXFLAGS="$CXXFLAGS -library=stlport4 -features=tmplife -features=tmplrefstatic"
MULTITHREADING_FLAG="-mt"
fi
BIND10_CXX_TRY_FLAG(-Wno-missing-field-initializers,
[WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG="-Wno-missing-field-initializers"])
AC_SUBST(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
# gcc specific settings:
if test "X$GXX" = "Xyes"; then
B10_CXXFLAGS="-Wall -Wextra -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare"
case "$host" in
*-solaris*)
MULTITHREADING_FLAG=-pthreads
;;
*)
MULTITHREADING_FLAG=-pthread
;;
esac
# Certain versions of gcc (g++) have a bug that incorrectly warns about
# the use of anonymous name spaces even if they're closed in a single
......@@ -323,6 +356,62 @@ AC_CHECK_HEADERS([boost/shared_ptr.hpp boost/foreach.hpp boost/interprocess/sync
CPPFLAGS="$CPPFLAGS_SAVES"
AC_SUBST(BOOST_INCLUDES)
# Using boost::mutex can result in requiring libboost_thread with older
# versions of Boost. We'd like to avoid relying on a compiled Boost library
# whenever possible, so we need to check for it step by step.
#
# NOTE: another fix of this problem is to simply require newer versions of
# boost. If we choose that solution we should simplify the following tricky
# checks accordingly and all Makefile.am's that refer to NEED_LIBBOOST_THREAD.
AC_MSG_CHECKING(for boost::mutex)
CPPFLAGS_SAVES="$CPPFLAGS"
LIBS_SAVES="$LIBS"
CPPFLAGS="$BOOST_INCLUDES $CPPFLAGS $MULTITHREADING_FLAG"
need_libboost_thread=0
need_sunpro_workaround=0
AC_TRY_LINK([
#include <boost/thread.hpp>
],[
boost::mutex m;
],
[ AC_MSG_RESULT(yes (without libboost_thread)) ],
# there is one specific problem with SunStudio 5.10
# where including boost/thread causes a compilation failure
# There is a workaround in boost but it checks the version not being 5.10
# This will probably be fixed in the future, in which case this
# is only a temporary workaround
[ AC_TRY_LINK([
#if defined(__SUNPRO_CC) && __SUNPRO_CC == 0x5100
#undef __SUNPRO_CC
#define __SUNPRO_CC 0x5090
#endif
#include <boost/thread.hpp>
],[
boost::mutex m;
],
[ AC_MSG_RESULT(yes (with SUNOS workaround))
need_sunpro_workaround=1 ],
[ LIBS=" $LIBS -lboost_thread"
AC_TRY_LINK([
#include <boost/thread.hpp>
],[
boost::mutex m;
],
[ AC_MSG_RESULT(yes (with libboost_thread))
need_libboost_thread=1 ],
[ AC_MSG_RESULT(no)
AC_MSG_ERROR([boost::mutex cannot be linked in this build environment.
Perhaps you are using an older version of Boost that requires libboost_thread for the mutex support, which does not appear to be available.
You may want to check the availability of the library or to upgrade Boost.])
])])])
CPPFLAGS="$CPPFLAGS_SAVES"
LIBS="$LIBS_SAVES"
AM_CONDITIONAL(NEED_LIBBOOST_THREAD, test $need_libboost_thread = 1)
if test $need_sunpro_workaround = 1; then
AC_DEFINE([NEED_SUNPRO_WORKAROUND], [], [Need boost sunstudio workaround])
fi
#
# Check availability of gtest, which will be used for unit tests.
#
......@@ -388,6 +477,8 @@ PTHREAD_LDFLAGS=
AC_CHECK_LIB(pthread, pthread_create,[ PTHREAD_LDFLAGS=-lpthread ], [])
AC_SUBST(PTHREAD_LDFLAGS)
AC_SUBST(MULTITHREADING_FLAG)
#
# ASIO: we extensively use it as the C++ event management module.
#
......
......@@ -26,10 +26,10 @@ namespace isc {
namespace auth {
void
Query::process() const {
const ZoneTable::FindResult result = zone_table_.find(qname_);
const ZoneTable::FindResult result = zone_table_.findZone(qname_);
if (result.code != ZoneTable::SUCCESS &&
result.code != ZoneTable::PARTIALMATCH) {
if (result.code != isc::datasrc::result::SUCCESS &&
result.code != isc::datasrc::result::PARTIALMATCH) {
response_.setRcode(Rcode::SERVFAIL());
return;
}
......
......@@ -55,7 +55,7 @@ TEST_F(QueryTest, noZone) {
TEST_F(QueryTest, matchZone) {
// add a matching zone. since the zone is empty right now, the response
// should have NXDOMAIN.
zone_table.add(ZonePtr(new MemoryZone(qclass, Name("example.com"))));
zone_table.addZone(ZonePtr(new MemoryZone(qclass, Name("example.com"))));
query.process();
EXPECT_EQ(Rcode::NXDOMAIN(), response.getRcode());
}
......@@ -63,7 +63,7 @@ TEST_F(QueryTest, matchZone) {
TEST_F(QueryTest, noMatchZone) {
// there's a zone in the table but it doesn't match the qname. should
// result in SERVFAIL.
zone_table.add(ZonePtr(new MemoryZone(qclass, Name("example.org"))));
zone_table.addZone(ZonePtr(new MemoryZone(qclass, Name("example.org"))));
query.process();
EXPECT_EQ(Rcode::SERVFAIL(), response.getRcode());
}
......
......@@ -15,4 +15,6 @@ libdatasrc_la_SOURCES += static_datasrc.h static_datasrc.cc
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 += zonetable.h zonetable.cc
libdatasrc_la_SOURCES += memory_datasrc.h memory_datasrc.cc
// Copyright (C) 2010 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.
#include <dns/name.h>
#include <datasrc/memory_datasrc.h>
using namespace std;
using namespace isc::dns;
namespace isc {
namespace datasrc {
/// Implementation details for \c MemoryDataSrc hidden from the public
/// interface.
///
/// For now, \c MemoryDataSrc only contains a \c ZoneTable object, which
/// consists of (pointers to) \c MemoryZone objects, we may add more
/// member variables later for new features.
struct MemoryDataSrc::MemoryDataSrcImpl {
ZoneTable zone_table;
};
MemoryDataSrc::MemoryDataSrc() : impl_(new MemoryDataSrcImpl)
{}
MemoryDataSrc::~MemoryDataSrc() {
delete impl_;
}
result::Result
MemoryDataSrc::addZone(ZonePtr zone) {
if (!zone) {
isc_throw(InvalidParameter,
"Null pointer is passed to MemoryDataSrc::addZone()");
}
return (impl_->zone_table.addZone(zone));
}
MemoryDataSrc::FindResult
MemoryDataSrc::findZone(const isc::dns::Name& name) const {
return (FindResult(impl_->zone_table.findZone(name).code,
impl_->zone_table.findZone(name).zone));
}
} // end of namespace datasrc
} // end of namespace dns
// Copyright (C) 2010 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 __MEMORY_DATA_SOURCE_H
#define __MEMORY_DATA_SOURCE_H 1
#include <datasrc/zonetable.h>
namespace isc {
namespace dns {
class Name;
};
namespace datasrc {
/// \brief A data source that uses in memory dedicated backend.
///
/// The \c MemoryDataSrc class represents a data source and provides a
/// basic interface to help DNS lookup processing. For a given domain
/// name, its \c findZone() method searches the in memory dedicated backend
/// for the zone that gives a longest match against that name.
///
/// The in memory dedicated backend are assumed to be of the same RR class,
/// but the \c MemoryDataSrc class does not enforce the assumption through
/// its interface.
/// For example, the \c addZone() method does not check if the new zone is of
/// the same RR class as that of the others already in the dedicated backend.
/// It is caller's responsibility to ensure this assumption.
///
/// <b>Notes to developer:</b>
///
/// For now, we don't make it a derived class of AbstractDataSrc because the
/// interface is so different (we'll eventually consider this as part of the
/// generalization work).
///
/// The addZone() method takes a (Boost) shared pointer because it would be
/// inconvenient to require the caller to maintain the ownership of zones,
/// while it wouldn't be safe to delete unnecessary zones inside the dedicated
/// backend.
///
/// The findZone() method takes a domain name and returns the best matching \c
/// MemoryZone in the form of (Boost) shared pointer, so that it can provide
/// the general interface for all data sources.
///
/// Currently, \c FindResult::zone is immutable for safety.
/// In future versions we may want to make it changeable. For example,
/// we may want to allow configuration update on an existing zone.
class MemoryDataSrc {
public:
/// \brief A helper structure to represent the search result of
/// <code>MemoryDataSrc::find()</code>.
///
/// This is a straightforward pair of the result code and a share pointer
/// to the found zone to represent the result of \c find().
/// 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 with no internal state, so for
/// convenience we allow the applications to refer to the members
/// directly.
///
/// See the description of \c find() for the semantics of the member
/// variables.
struct FindResult {
FindResult(result::Result param_code, const ConstZonePtr param_zone) :
code(param_code), zone(param_zone)
{}
const result::Result code;
const ConstZonePtr 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:
MemoryDataSrc(const MemoryDataSrc& source);
MemoryDataSrc& operator=(const MemoryDataSrc& source);
public:
/// Default constructor.
///
/// This constructor internally involves resource allocation, and if
/// it fails, a corresponding standard exception will be thrown.
/// It never throws an exception otherwise.
MemoryDataSrc();
/// The destructor.
~MemoryDataSrc();
//@}
/// Add a \c Zone to the \c MemoryDataSrc.
///
/// \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 memory data source.
/// \return \c result::EXIST The memory data source already
/// stores a zone that has the same origin.
result::Result addZone(ZonePtr zone);
/// Find a \c Zone that best matches the given name in the \c MemoryDataSrc.
///
/// 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:
struct MemoryDataSrcImpl;
MemoryDataSrcImpl* impl_;
};
}
}
#endif // __DATA_SOURCE_MEMORY_H
// Local Variables:
// mode: c++
// End:
This diff is collapsed.
......@@ -24,12 +24,14 @@ run_unittests_SOURCES += static_unittest.cc
run_unittests_SOURCES += query_unittest.cc
run_unittests_SOURCES += cache_unittest.cc
run_unittests_SOURCES += test_datasrc.h test_datasrc.cc
run_unittests_SOURCES += rbtree_unittest.cc
run_unittests_SOURCES += zonetable_unittest.cc
run_unittests_SOURCES += memory_datasrc_unittest.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
run_unittests_LDADD = $(GTEST_LDADD)
run_unittests_LDADD += $(SQLITE_LIBS)
run_unittests_LDADD += $(top_builddir)/src/lib/datasrc/libdatasrc.la
run_unittests_LDADD += $(top_builddir)/src/lib/datasrc/libdatasrc.la
run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
......
// Copyright (C) 2010 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.
#include <exceptions/exceptions.h>
#include <dns/name.h>
#include <dns/rrclass.h>
#include <datasrc/zonetable.h>
#include <datasrc/memory_datasrc.h>
#include <gtest/gtest.h>
using namespace isc::dns;
using namespace isc::datasrc;
namespace {
class MemoryDataSrcTest : public ::testing::Test {
protected:
MemoryDataSrcTest()
{}
MemoryDataSrc memory_datasrc;
};
TEST_F(MemoryDataSrcTest, add_find_Zone) {
// test add zone
// Bogus zone (NULL)
EXPECT_THROW(memory_datasrc.addZone(ZonePtr()), isc::InvalidParameter);
// add zones with different names one by one
EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
ZonePtr(new MemoryZone(RRClass::IN(), Name("a")))));
EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
ZonePtr(new MemoryZone(RRClass::CH(), Name("b")))));
EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
ZonePtr(new MemoryZone(RRClass::IN(), Name("c")))));
// add zones with the same name suffix
EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
ZonePtr(new MemoryZone(RRClass::CH(),
Name("x.d.e.f")))));
EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
ZonePtr(new MemoryZone(RRClass::CH(),
Name("o.w.y.d.e.f")))));
EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
ZonePtr(new MemoryZone(RRClass::CH(),
Name("p.w.y.d.e.f")))));
EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
ZonePtr(new MemoryZone(RRClass::IN(),
Name("q.w.y.d.e.f")))));
// add super zone and its subzone
EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
ZonePtr(new MemoryZone(RRClass::CH(), Name("g.h")))));
EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
ZonePtr(new MemoryZone(RRClass::IN(), Name("i.g.h")))));
EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
ZonePtr(new MemoryZone(RRClass::IN(),
Name("z.d.e.f")))));
EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
ZonePtr(new MemoryZone(RRClass::IN(),
Name("j.z.d.e.f")))));
// different zone class isn't allowed.
EXPECT_EQ(result::EXIST, memory_datasrc.addZone(
ZonePtr(new MemoryZone(RRClass::CH(),
Name("q.w.y.d.e.f")))));
// names are compared in a case insensitive manner.
EXPECT_EQ(result::EXIST, memory_datasrc.addZone(
ZonePtr(new MemoryZone(RRClass::IN(),
Name("Q.W.Y.d.E.f")))));
// test find zone
EXPECT_EQ(result::SUCCESS, memory_datasrc.findZone(Name("a")).code);
EXPECT_EQ(Name("a"),
memory_datasrc.findZone(Name("a")).zone->getOrigin());
EXPECT_EQ(result::SUCCESS,
memory_datasrc.findZone(Name("j.z.d.e.f")).code);
EXPECT_EQ(Name("j.z.d.e.f"),
memory_datasrc.findZone(Name("j.z.d.e.f")).zone->getOrigin());
// NOTFOUND
EXPECT_EQ(result::NOTFOUND, memory_datasrc.findZone(Name("d.e.f")).code);
EXPECT_EQ(ConstZonePtr(), memory_datasrc.findZone(Name("d.e.f")).zone);
EXPECT_EQ(result::NOTFOUND,
memory_datasrc.findZone(Name("w.y.d.e.f")).code);
EXPECT_EQ(ConstZonePtr(),
memory_datasrc.findZone(Name("w.y.d.e.f")).zone);
// there's no exact match. the result should be the longest match,
// and the code should be PARTIALMATCH.
EXPECT_EQ(result::PARTIALMATCH,
memory_datasrc.findZone(Name("j.g.h")).code);
EXPECT_EQ(Name("g.h"),
memory_datasrc.findZone(Name("g.h")).zone->getOrigin());
EXPECT_EQ(result::PARTIALMATCH,
memory_datasrc.findZone(Name("z.i.g.h")).code);
EXPECT_EQ(Name("i.g.h"),
memory_datasrc.findZone(Name("z.i.g.h")).zone->getOrigin());
}
}
// Copyright (C) 2010 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.
#include <gtest/gtest.h>
#include <dns/name.h>
#include <dns/rrclass.h>
#include <dns/rrset.h>
#include <dns/rrtype.h>
#include <dns/rrttl.h>
#include <datasrc/rbtree.h>
#include <dns/tests/unittest_util.h>
using namespace std;
using namespace isc::dns;
using isc::UnitTestUtil;
using namespace isc::datasrc;
/* The initial structure of rbtree
*
* b
* / \
* a d.e.f
* / | \
* c | g.h
* | |
* w.y i
* / | \
* x | z
* | |
* p j
* / \
* o q
*/
namespace {
class RBTreeTest : public::testing::Test {
protected:
RBTreeTest() : rbtree() {
rbtree.insert(Name("c"), &rbtnode);
rbtnode->setData(RBNode<int>::NodeDataPtr(new int(1)));
rbtree.insert(Name("b"), &rbtnode);
rbtnode->setData(RBNode<int>::NodeDataPtr(new int(2)));
rbtree.insert(Name("a"), &rbtnode);
rbtnode->setData(RBNode<int>::NodeDataPtr(new int(3)));
rbtree.insert(Name("x.d.e.f"), &rbtnode);
rbtnode->setData(RBNode<int>::NodeDataPtr(new int(4)));
rbtree.insert(Name("z.d.e.f"), &rbtnode);
rbtnode->setData(RBNode<int>::NodeDataPtr(new int(5)));
rbtree.insert(Name("g.h"), &rbtnode);
rbtnode->setData(RBNode<int>::NodeDataPtr(new int(6)));
rbtree.insert(Name("i.g.h"), &rbtnode);
rbtnode->setData(RBNode<int>::NodeDataPtr(new int(7)));
rbtree.insert(Name("o.w.y.d.e.f"), &rbtnode);
rbtnode->setData(RBNode<int>::NodeDataPtr(new int(8)));
rbtree.insert(Name("j.z.d.e.f"), &rbtnode);
rbtnode->setData(RBNode<int>::NodeDataPtr(new int(9)));
rbtree.insert(Name("p.w.y.d.e.f"), &rbtnode);
rbtnode->setData(RBNode<int>::NodeDataPtr(new int(10)));
rbtree.insert(Name("q.w.y.d.e.f"), &rbtnode);
rbtnode->setData(RBNode<int>::NodeDataPtr(new int(11)));