Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
7197d4f5
Commit
7197d4f5
authored
Jul 05, 2012
by
Michal 'vorner' Vaner
Browse files
Merge
#2044
parents
1fc2b06b
afddf882
Changes
5
Hide whitespace changes
Inline
Side-by-side
src/lib/datasrc/Makefile.am
View file @
7197d4f5
...
...
@@ -36,6 +36,7 @@ libdatasrc_la_SOURCES += client.h iterator.h
libdatasrc_la_SOURCES
+=
database.h database.cc
libdatasrc_la_SOURCES
+=
factory.h factory.cc
libdatasrc_la_SOURCES
+=
client_list.h client_list.cc
libdatasrc_la_SOURCES
+=
memory_datasrc.h memory_datasrc.cc
nodist_libdatasrc_la_SOURCES
=
datasrc_messages.h datasrc_messages.cc
libdatasrc_la_LDFLAGS
=
-no-undefined
-version-info
1:0:1
...
...
@@ -49,14 +50,12 @@ sqlite3_ds_la_LIBADD = $(top_builddir)/src/lib/exceptions/libexceptions.la
sqlite3_ds_la_LIBADD
+=
libdatasrc.la
sqlite3_ds_la_LIBADD
+=
$(SQLITE_LIBS)
memory_ds_la_SOURCES
=
memory_datasrc.h memory_datasrc.cc
memory_ds_la_SOURCES
+=
memory_datasrc_link.cc
memory_ds_la_SOURCES
=
memory_datasrc_link.cc
memory_ds_la_LDFLAGS
=
-module
-avoid-version
memory_ds_la_LIBADD
=
$(top_builddir)
/src/lib/exceptions/libexceptions.la
memory_ds_la_LIBADD
+=
libdatasrc.la
static_ds_la_SOURCES
=
memory_datasrc.h memory_datasrc.cc
static_ds_la_SOURCES
+=
static_datasrc_link.cc
static_ds_la_SOURCES
=
static_datasrc_link.cc
static_ds_la_LDFLAGS
=
-module
-avoid-version
static_ds_la_LIBADD
=
$(top_builddir)
/src/lib/exceptions/libexceptions.la
static_ds_la_LIBADD
+=
libdatasrc.la
...
...
src/lib/datasrc/client_list.cc
View file @
7197d4f5
...
...
@@ -15,19 +15,32 @@
#include "client_list.h"
#include "client.h"
#include "factory.h"
#include "memory_datasrc.h"
#include <memory>
#include <boost/foreach.hpp>
using
namespace
isc
::
data
;
using
namespace
isc
::
dns
;
using
namespace
std
;
using
namespace
boost
;
namespace
isc
{
namespace
datasrc
{
ConfigurableClientList
::
DataSourceInfo
::
DataSourceInfo
(
DataSourceClient
*
data_src_client
,
const
DataSourceClientContainerPtr
&
container
,
bool
hasCache
)
:
data_src_client_
(
data_src_client
),
container_
(
container
)
{
if
(
hasCache
)
{
cache_
.
reset
(
new
InMemoryClient
);
}
}
void
ConfigurableClientList
::
configure
(
const
Element
&
config
,
bool
)
{
// TODO: Implement the cache
ConfigurableClientList
::
configure
(
const
Element
&
config
,
bool
allow_cache
)
{
// TODO: Implement recycling from the old configuration.
size_t
i
(
0
);
// Outside of the try to be able to access it in the catch
try
{
...
...
@@ -49,8 +62,48 @@ ConfigurableClientList::configure(const Element& config, bool) {
// Ask the factory to create the data source for us
const
DataSourcePair
ds
(
this
->
getDataSourceClient
(
type
,
paramConf
));
const
bool
want_cache
(
allow_cache
&&
dconf
->
contains
(
"cache-enable"
)
&&
dconf
->
get
(
"cache-enable"
)
->
boolValue
());
// And put it into the vector
new_data_sources
.
push_back
(
DataSourceInfo
(
ds
.
first
,
ds
.
second
));
new_data_sources
.
push_back
(
DataSourceInfo
(
ds
.
first
,
ds
.
second
,
want_cache
));
if
(
want_cache
)
{
if
(
!
dconf
->
contains
(
"cache-zones"
))
{
isc_throw
(
isc
::
NotImplemented
,
"Auto-detection of zones "
"to cache is not yet implemented, supply "
"cache-zones parameter"
);
// TODO: Auto-detect list of all zones in the
// data source.
}
const
ConstElementPtr
zones
(
dconf
->
get
(
"cache-zones"
));
const
shared_ptr
<
InMemoryClient
>
cache
(
new_data_sources
.
back
().
cache_
);
const
DataSourceClient
*
const
client
(
new_data_sources
.
back
().
data_src_client_
);
for
(
size_t
i
(
0
);
i
<
zones
->
size
();
++
i
)
{
const
Name
origin
(
zones
->
get
(
i
)
->
stringValue
());
const
DataSourceClient
::
FindResult
zone
(
client
->
findZone
(
origin
));
if
(
zone
.
code
!=
result
::
SUCCESS
)
{
// The data source does not contain the zone, it can't
// be cached.
isc_throw
(
ConfigurationError
,
"Unable to cache "
"non-existent zone "
<<
origin
);
}
shared_ptr
<
InMemoryZoneFinder
>
finder
(
new
InMemoryZoneFinder
(
zone
.
zone_finder
->
getClass
(),
origin
));
ZoneIteratorPtr
iterator
(
client
->
getIterator
(
origin
));
if
(
!
iterator
)
{
isc_throw
(
isc
::
Unexpected
,
"Got NULL iterator for "
"zone "
<<
origin
);
}
finder
->
load
(
*
iterator
);
cache
->
addZone
(
finder
);
}
}
}
// If everything is OK up until now, we have the new configuration
// ready. So just put it there and let the old one die when we exit
...
...
@@ -88,14 +141,11 @@ ConfigurableClientList::find(const dns::Name& name, bool want_exact_match,
}
candidate
;
BOOST_FOREACH
(
const
DataSourceInfo
&
info
,
data_sources_
)
{
// TODO: Once we have support for the caches, consider them too here
// somehow. This would probably get replaced by a function, that
// checks if there's a cache available, if it is, checks the loaded
// zones and zones expected to be in the real data source. If it is
// the cached one, provide the cached one. If it is in the external
// data source, use the datasource and don't provide the finder yet.
const
DataSourceClient
::
FindResult
result
(
info
.
data_src_client_
->
findZone
(
name
));
DataSourceClient
*
client
(
info
.
cache_
?
info
.
cache_
.
get
()
:
info
.
data_src_client_
);
const
DataSourceClient
::
FindResult
result
(
client
->
findZone
(
name
));
// TODO: Once we mark the zones that are not loaded, but are present
// in the data source somehow, check them too.
switch
(
result
.
code
)
{
case
result
::
SUCCESS
:
// If we found an exact match, we have no hope to getting
...
...
@@ -103,7 +153,7 @@ ConfigurableClientList::find(const dns::Name& name, bool want_exact_match,
// TODO: In case we have only the datasource and not the finder
// and the need_updater parameter is true, get the zone there.
return
(
FindResult
(
info
.
data_src_
client
_
,
result
.
zone_finder
,
return
(
FindResult
(
client
,
result
.
zone_finder
,
true
));
case
result
::
PARTIALMATCH
:
if
(
!
want_exact_match
)
{
...
...
@@ -124,7 +174,7 @@ ConfigurableClientList::find(const dns::Name& name, bool want_exact_match,
if
(
labels
>
candidate
.
matched_labels
||
!
candidate
.
matched
)
{
// This one is strictly better. Replace it.
candidate
.
datasrc_client
=
info
.
data_src_
client
_
;
candidate
.
datasrc_client
=
client
;
candidate
.
finder
=
result
.
zone_finder
;
candidate
.
matched_labels
=
labels
;
candidate
.
matched
=
true
;
...
...
src/lib/datasrc/client_list.h
View file @
7197d4f5
...
...
@@ -33,6 +33,7 @@ typedef boost::shared_ptr<DataSourceClient> DataSourceClientPtr;
class
DataSourceClientContainer
;
typedef
boost
::
shared_ptr
<
DataSourceClientContainer
>
DataSourceClientContainerPtr
;
class
InMemoryClient
;
/// \brief The list of data source clients.
///
...
...
@@ -212,6 +213,11 @@ public:
/// client.
/// \throw ConfigurationError if the configuration is invalid in some
/// sense.
/// \throw Unexpected if something misbehaves (like the data source
/// returning NULL iterator).
/// \throw NotImplemented if the auto-detection of list of zones is
/// needed.
/// \throw Whatever is propagated from within the data source.
void
configure
(
const
data
::
Element
&
configuration
,
bool
allow_cache
);
/// \brief Implementation of the ClientList::find.
...
...
@@ -231,12 +237,11 @@ public:
data_src_client_
(
NULL
)
{}
DataSourceInfo
(
DataSourceClient
*
data_src_client
,
const
DataSourceClientContainerPtr
&
container
)
:
data_src_client_
(
data_src_client
),
container_
(
container
)
{}
const
DataSourceClientContainerPtr
&
container
,
bool
hasCache
);
DataSourceClient
*
data_src_client_
;
DataSourceClientContainerPtr
container_
;
boost
::
shared_ptr
<
InMemoryClient
>
cache_
;
};
/// \brief The collection of data sources.
...
...
src/lib/datasrc/tests/Makefile.am
View file @
7197d4f5
...
...
@@ -67,7 +67,6 @@ run_unittests_SOURCES += client_list_unittest.cc
# We need the actual module implementation in the tests (they are not part
# of libdatasrc)
run_unittests_SOURCES
+=
$(top_srcdir)
/src/lib/datasrc/sqlite3_accessor.cc
run_unittests_SOURCES
+=
$(top_srcdir)
/src/lib/datasrc/memory_datasrc.cc
run_unittests_CPPFLAGS
=
$(AM_CPPFLAGS)
$(GTEST_INCLUDES)
run_unittests_LDFLAGS
=
$(AM_LDFLAGS)
$(GTEST_LDFLAGS)
...
...
src/lib/datasrc/tests/client_list_unittest.cc
View file @
7197d4f5
...
...
@@ -14,9 +14,13 @@
#include <datasrc/client_list.h>
#include <datasrc/client.h>
#include <datasrc/iterator.h>
#include <datasrc/data_source.h>
#include <datasrc/memory_datasrc.h>
#include <dns/rrclass.h>
#include <dns/rrttl.h>
#include <dns/rdataclass.h>
#include <gtest/gtest.h>
...
...
@@ -41,7 +45,7 @@ public:
Name
getOrigin
()
const
{
return
(
origin_
);
}
// The rest is not to be called, so just have them
RRClass
getClass
()
const
{
isc_throw
(
isc
::
NotImplemented
,
"Not implemented"
);
return
(
RRClass
::
IN
()
);
}
shared_ptr
<
Context
>
find
(
const
Name
&
,
const
RRType
&
,
const
FindOptions
)
...
...
@@ -60,6 +64,35 @@ public:
private:
Name
origin_
;
};
class
Iterator
:
public
ZoneIterator
{
public:
Iterator
(
const
Name
&
origin
)
:
origin_
(
origin
),
finished_
(
false
),
soa_
(
new
RRset
(
origin_
,
RRClass
::
IN
(),
RRType
::
SOA
(),
RRTTL
(
3600
)))
{
// The RData here is bogus, but it is not used to anything. There
// just needs to be some.
soa_
->
addRdata
(
rdata
::
generic
::
SOA
(
Name
::
ROOT_NAME
(),
Name
::
ROOT_NAME
(),
0
,
0
,
0
,
0
,
0
));
}
virtual
isc
::
dns
::
ConstRRsetPtr
getNextRRset
()
{
if
(
finished_
)
{
return
(
ConstRRsetPtr
());
}
else
{
finished_
=
true
;
return
(
soa_
);
}
}
virtual
isc
::
dns
::
ConstRRsetPtr
getSOA
()
const
{
return
(
soa_
);
}
private:
const
Name
origin_
;
bool
finished_
;
const
isc
::
dns
::
RRsetPtr
soa_
;
};
// Constructor from a list of zones.
MockDataSourceClient
(
const
char
*
zone_names
[])
{
for
(
const
char
**
zone
(
zone_names
);
*
zone
;
++
zone
)
{
...
...
@@ -72,7 +105,13 @@ public:
const
ConstElementPtr
&
configuration
)
:
type_
(
type
),
configuration_
(
configuration
)
{}
{
if
(
configuration_
->
getType
()
==
Element
::
list
)
{
for
(
size_t
i
(
0
);
i
<
configuration_
->
size
();
++
i
)
{
zones
.
insert
(
Name
(
configuration_
->
get
(
i
)
->
stringValue
()));
}
}
}
virtual
FindResult
findZone
(
const
Name
&
name
)
const
{
if
(
zones
.
empty
())
{
return
(
FindResult
(
result
::
NOTFOUND
,
ZoneFinderPtr
()));
...
...
@@ -103,6 +142,15 @@ public:
{
isc_throw
(
isc
::
NotImplemented
,
"Not implemented"
);
}
virtual
ZoneIteratorPtr
getIterator
(
const
Name
&
name
,
bool
)
const
{
if
(
name
==
Name
(
"noiter.org"
))
{
isc_throw
(
isc
::
NotImplemented
,
"Asked not to be implemented"
);
}
else
if
(
name
==
Name
(
"null.org"
))
{
return
(
ZoneIteratorPtr
());
}
else
{
return
(
ZoneIteratorPtr
(
new
Iterator
(
name
)));
}
}
const
string
type_
;
const
ConstElementPtr
configuration_
;
private:
...
...
@@ -166,7 +214,6 @@ public:
config_elem_
(
Element
::
fromJSON
(
"["
"{"
"
\"
type
\"
:
\"
test_type
\"
,"
"
\"
cache
\"
:
\"
off
\"
,"
"
\"
params
\"
: {}"
"}]"
))
{
...
...
@@ -175,20 +222,28 @@ public:
ds
(
new
MockDataSourceClient
(
ds_zones
[
i
]));
ds_
.
push_back
(
ds
);
ds_info_
.
push_back
(
ConfigurableClientList
::
DataSourceInfo
(
ds
.
get
(),
DataSourceClientContainerPtr
()));
DataSourceClientContainerPtr
()
,
false
));
}
}
// Check the positive result is as we expect it.
void
positiveResult
(
const
ClientList
::
FindResult
&
result
,
const
shared_ptr
<
MockDataSourceClient
>&
dsrc
,
const
Name
&
name
,
bool
exact
,
const
char
*
test
)
const
char
*
test
,
bool
from_cache
=
false
)
{
SCOPED_TRACE
(
test
);
EXPECT_EQ
(
dsrc
.
get
(),
result
.
dsrc_client_
);
ASSERT_NE
(
ZoneFinderPtr
(),
result
.
finder_
);
EXPECT_EQ
(
name
,
result
.
finder_
->
getOrigin
());
EXPECT_EQ
(
exact
,
result
.
exact_match_
);
if
(
from_cache
)
{
EXPECT_NE
(
shared_ptr
<
InMemoryZoneFinder
>
(),
dynamic_pointer_cast
<
InMemoryZoneFinder
>
(
result
.
finder_
))
<<
"Finder is not from cache"
;
EXPECT_TRUE
(
NULL
!=
dynamic_cast
<
InMemoryClient
*>
(
result
.
dsrc_client_
));
}
else
{
EXPECT_EQ
(
dsrc
.
get
(),
result
.
dsrc_client_
);
}
}
// Configure the list with multiple data sources, according to
// some configuration. It uses the index as parameter, to be able to
...
...
@@ -220,7 +275,8 @@ public:
FAIL
()
<<
"Unknown configuration index "
<<
index
;
}
}
void
checkDS
(
size_t
index
,
const
string
&
type
,
const
string
&
params
)
const
void
checkDS
(
size_t
index
,
const
string
&
type
,
const
string
&
params
,
bool
cache
)
const
{
ASSERT_GT
(
list_
->
getDataSources
().
size
(),
index
);
MockDataSourceClient
*
ds
(
dynamic_cast
<
MockDataSourceClient
*>
(
...
...
@@ -230,6 +286,8 @@ public:
ASSERT_NE
(
ds
,
static_cast
<
const
MockDataSourceClient
*>
(
NULL
));
EXPECT_EQ
(
type
,
ds
->
type_
);
EXPECT_TRUE
(
Element
::
fromJSON
(
params
)
->
equals
(
*
ds
->
configuration_
));
EXPECT_EQ
(
cache
,
list_
->
getDataSources
()[
index
].
cache_
!=
shared_ptr
<
InMemoryClient
>
());
}
shared_ptr
<
TestedList
>
list_
;
const
ClientList
::
FindResult
negativeResult_
;
...
...
@@ -349,14 +407,14 @@ TEST_F(ListTest, multiBestMatch) {
// Check the configuration is empty when the list is empty
TEST_F
(
ListTest
,
configureEmpty
)
{
ConstElementPtr
elem
(
new
ListElement
);
const
ConstElementPtr
elem
(
new
ListElement
);
list_
->
configure
(
*
elem
,
true
);
EXPECT_TRUE
(
list_
->
getDataSources
().
empty
());
}
// Check we can get multiple data sources and they are in the right order.
TEST_F
(
ListTest
,
configureMulti
)
{
ConstElementPtr
elem
(
Element
::
fromJSON
(
"["
const
ConstElementPtr
elem
(
Element
::
fromJSON
(
"["
"{"
"
\"
type
\"
:
\"
type1
\"
,"
"
\"
cache
\"
:
\"
off
\"
,"
...
...
@@ -370,8 +428,8 @@ TEST_F(ListTest, configureMulti) {
));
list_
->
configure
(
*
elem
,
true
);
EXPECT_EQ
(
2
,
list_
->
getDataSources
().
size
());
checkDS
(
0
,
"type1"
,
"{}"
);
checkDS
(
1
,
"type2"
,
"{}"
);
checkDS
(
0
,
"type1"
,
"{}"
,
false
);
checkDS
(
1
,
"type2"
,
"{}"
,
false
);
}
// Check we can pass whatever we want to the params
...
...
@@ -396,7 +454,7 @@ TEST_F(ListTest, configureParams) {
"}]"
));
list_
->
configure
(
*
elem
,
true
);
EXPECT_EQ
(
1
,
list_
->
getDataSources
().
size
());
checkDS
(
0
,
"t"
,
*
param
);
checkDS
(
0
,
"t"
,
*
param
,
false
);
}
}
...
...
@@ -418,55 +476,198 @@ TEST_F(ListTest, wrongConfig) {
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, {
\"
type
\"
: null}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, {
\"
type
\"
: []}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, {
\"
type
\"
: {}}]"
,
// TODO: Once cache is supported, add some invalid cache values
// Bad type of cache-enable
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
x
\"
,
\"
cache-enable
\"
: 13,
\"
cache-zones
\"
: []}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
x
\"
,
\"
cache-enable
\"
:
\"
xx
\"
,
\"
cache-zones
\"
: []}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
x
\"
,
\"
cache-enable
\"
: [],
\"
cache-zones
\"
: []}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
x
\"
,
\"
cache-enable
\"
: {},
\"
cache-zones
\"
: []}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
x
\"
,
\"
cache-enable
\"
: null,
\"
cache-zones
\"
: []}]"
,
// Bad type of cache-zones
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
x
\"
,
\"
cache-enable
\"
: true,
\"
cache-zones
\"
:
\"
x
\"
}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
x
\"
,
\"
cache-enable
\"
: true,
\"
cache-zones
\"
: true}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
x
\"
,
\"
cache-enable
\"
: true,
\"
cache-zones
\"
: null}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
x
\"
,
\"
cache-enable
\"
: true,
\"
cache-zones
\"
: 13}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
x
\"
,
\"
cache-enable
\"
: true,
\"
cache-zones
\"
: {}}]"
,
NULL
};
// Put something inside to see it survives the exception
list_
->
configure
(
*
config_elem_
,
true
);
checkDS
(
0
,
"test_type"
,
"{}"
);
checkDS
(
0
,
"test_type"
,
"{}"
,
false
);
for
(
const
char
**
config
(
configs
);
*
config
;
++
config
)
{
SCOPED_TRACE
(
*
config
);
ConstElementPtr
elem
(
Element
::
fromJSON
(
*
config
));
EXPECT_THROW
(
list_
->
configure
(
*
elem
,
true
),
ConfigurableClientList
::
ConfigurationError
);
// Still untouched
checkDS
(
0
,
"test_type"
,
"{}"
);
checkDS
(
0
,
"test_type"
,
"{}"
,
false
);
EXPECT_EQ
(
1
,
list_
->
getDataSources
().
size
());
}
}
// The param thing defaults to null. Cache is not used yet.
TEST_F
(
ListTest
,
defaults
)
{
ConstElementPtr
elem
(
Element
::
fromJSON
(
"["
const
ConstElementPtr
elem
(
Element
::
fromJSON
(
"["
"{"
"
\"
type
\"
:
\"
type1
\"
"
"}]"
));
list_
->
configure
(
*
elem
,
true
);
EXPECT_EQ
(
1
,
list_
->
getDataSources
().
size
());
checkDS
(
0
,
"type1"
,
"null"
);
checkDS
(
0
,
"type1"
,
"null"
,
false
);
}
// Check we can call the configure multiple times, to change the configuration
TEST_F
(
ListTest
,
reconfigure
)
{
ConstElementPtr
empty
(
new
ListElement
);
const
ConstElementPtr
empty
(
new
ListElement
);
list_
->
configure
(
*
config_elem_
,
true
);
checkDS
(
0
,
"test_type"
,
"{}"
);
checkDS
(
0
,
"test_type"
,
"{}"
,
false
);
list_
->
configure
(
*
empty
,
true
);
EXPECT_TRUE
(
list_
->
getDataSources
().
empty
());
list_
->
configure
(
*
config_elem_
,
true
);
checkDS
(
0
,
"test_type"
,
"{}"
);
checkDS
(
0
,
"test_type"
,
"{}"
,
false
);
}
// Make sure the data source error exception from the factory is propagated
TEST_F
(
ListTest
,
dataSrcError
)
{
ConstElementPtr
elem
(
Element
::
fromJSON
(
"["
const
ConstElementPtr
elem
(
Element
::
fromJSON
(
"["
"{"
"
\"
type
\"
:
\"
error
\"
"
"}]"
));
list_
->
configure
(
*
config_elem_
,
true
);
checkDS
(
0
,
"test_type"
,
"{}"
);
checkDS
(
0
,
"test_type"
,
"{}"
,
false
);
EXPECT_THROW
(
list_
->
configure
(
*
elem
,
true
),
DataSourceError
);
checkDS
(
0
,
"test_type"
,
"{}"
);
checkDS
(
0
,
"test_type"
,
"{}"
,
false
);
}
// Check we can get the cache
TEST_F
(
ListTest
,
configureCacheEmpty
)
{
const
ConstElementPtr
elem
(
Element
::
fromJSON
(
"["
"{"
"
\"
type
\"
:
\"
type1
\"
,"
"
\"
cache-enable
\"
: true,"
"
\"
cache-zones
\"
: [],"
"
\"
params
\"
: {}"
"},"
"{"
"
\"
type
\"
:
\"
type2
\"
,"
"
\"
cache-enable
\"
: false,"
"
\"
cache-zones
\"
: [],"
"
\"
params
\"
: {}"
"}]"
));
list_
->
configure
(
*
elem
,
true
);
EXPECT_EQ
(
2
,
list_
->
getDataSources
().
size
());
checkDS
(
0
,
"type1"
,
"{}"
,
true
);
checkDS
(
1
,
"type2"
,
"{}"
,
false
);
}
// But no cache if we disallow it globally
TEST_F
(
ListTest
,
configureCacheDisabled
)
{
const
ConstElementPtr
elem
(
Element
::
fromJSON
(
"["
"{"
"
\"
type
\"
:
\"
type1
\"
,"
"
\"
cache-enable
\"
: true,"
"
\"
cache-zones
\"
: [],"
"
\"
params
\"
: {}"
"},"
"{"
"
\"
type
\"
:
\"
type2
\"
,"
"
\"
cache-enable
\"
: false,"
"
\"
cache-zones
\"
: [],"
"
\"
params
\"
: {}"
"}]"
));
list_
->
configure
(
*
elem
,
false
);
EXPECT_EQ
(
2
,
list_
->
getDataSources
().
size
());
checkDS
(
0
,
"type1"
,
"{}"
,
false
);
checkDS
(
1
,
"type2"
,
"{}"
,
false
);
}
// Put some zones into the cache
TEST_F
(
ListTest
,
cacheZones
)
{
const
ConstElementPtr
elem
(
Element
::
fromJSON
(
"["
"{"
"
\"
type
\"
:
\"
type1
\"
,"
"
\"
cache-enable
\"
: true,"
"
\"
cache-zones
\"
: [
\"
example.org
\"
,
\"
example.com
\"
],"
"
\"
params
\"
: [
\"
example.org
\"
,
\"
example.com
\"
,
\"
exmaple.cz
\"
]"
"}]"
));
list_
->
configure
(
*
elem
,
true
);
checkDS
(
0
,
"type1"
,
"[
\"
example.org
\"
,
\"
example.com
\"
,
\"
exmaple.cz
\"
]"
,
true
);
const
shared_ptr
<
InMemoryClient
>
cache
(
list_
->
getDataSources
()[
0
].
cache_
);
EXPECT_EQ
(
2
,
cache
->
getZoneCount
());
EXPECT_EQ
(
result
::
SUCCESS
,
cache
->
findZone
(
Name
(
"example.org"
)).
code
);
EXPECT_EQ
(
result
::
SUCCESS
,
cache
->
findZone
(
Name
(
"example.com"
)).
code
);
EXPECT_EQ
(
result
::
NOTFOUND
,
cache
->
findZone
(
Name
(
"example.cz"
)).
code
);
// These are cached and answered from the cache
positiveResult
(
list_
->
find
(
Name
(
"example.com."
)),
ds_
[
0
],
Name
(
"example.com."
),
true
,
"com"
,
true
);
positiveResult
(
list_
->
find
(
Name
(
"example.org."
)),
ds_
[
0
],
Name
(
"example.org."
),
true
,
"org"
,
true
);
positiveResult
(
list_
->
find
(
Name
(
"sub.example.com."
)),
ds_
[
0
],
Name
(
"example.com."
),
false
,
"Subdomain of com"
,
true
);
// For now, the ones not cached are ignored.
EXPECT_TRUE
(
negativeResult_
==
list_
->
find
(
Name
(
"example.cz."
)));
}
// Check the caching handles misbehaviour from the data source and
// misconfiguration gracefully
TEST_F
(
ListTest
,
badCache
)
{
list_
->
configure
(
*
config_elem_
,
true
);
checkDS
(
0
,
"test_type"
,
"{}"
,
false
);
// First, the zone is not in the data source
const
ConstElementPtr
elem1
(
Element
::
fromJSON
(
"["
"{"
"
\"
type
\"
:
\"
type1
\"
,"
"
\"
cache-enable
\"
: true,"
"
\"
cache-zones
\"
: [
\"
example.org
\"
],"
"
\"
params
\"
: []"
"}]"
));
EXPECT_THROW
(
list_
->
configure
(
*
elem1
,
true
),
ConfigurableClientList
::
ConfigurationError
);
checkDS
(
0
,
"test_type"
,
"{}"
,
false
);
// Now, the zone doesn't give an iterator
const
ConstElementPtr
elem2
(
Element
::
fromJSON
(
"["
"{"
"
\"
type
\"
:
\"
type1
\"
,"
"
\"
cache-enable
\"
: true,"
"
\"
cache-zones
\"
: [
\"
noiter.org
\"
],"
"
\"
params
\"
: [
\"
noiter.org
\"
]"
"}]"
));
EXPECT_THROW
(
list_
->
configure
(
*
elem2
,
true
),
isc
::
NotImplemented
);
checkDS
(
0
,
"test_type"
,
"{}"
,
false
);
// Now, the zone returns NULL iterator
const
ConstElementPtr
elem3
(
Element
::
fromJSON
(
"["
"{"
"
\"
type
\"
:
\"
type1
\"
,"
"
\"
cache-enable
\"
: true,"
"
\"
cache-zones
\"
: [
\"
null.org
\"
],"
"
\"
params
\"
: [
\"
null.org
\"
]"
"}]"
));
EXPECT_THROW
(
list_
->
configure
(
*
elem3
,
true
),
isc
::
Unexpected
);
checkDS
(
0
,
"test_type"
,
"{}"
,
false
);
// The autodetection of zones is not enabled
const
ConstElementPtr
elem4
(
Element
::
fromJSON
(
"["
"{"
"
\"
type
\"
:
\"
type1
\"
,"
"
\"
cache-enable
\"
: true,"
"
\"
params
\"
: [
\"
example.org
\"
]"
"}]"
));
EXPECT_THROW
(
list_
->
configure
(
*
elem4
,
true
),
isc
::
NotImplemented
);
checkDS
(
0
,
"test_type"
,
"{}"
,
false
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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