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

[master] Merge branch 'trac1792' with fixing conflicts.

This commit is contained in:
JINMEI Tatuya 2012-04-16 13:47:51 -07:00
commit 93f11d2a96
16 changed files with 251 additions and 22 deletions

View File

@ -12,14 +12,6 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <set>
#include <string>
#include <utility>
#include <vector>
#include <boost/foreach.hpp>
#include <boost/shared_ptr.hpp>
#include <dns/name.h>
#include <dns/rrclass.h>
@ -27,6 +19,7 @@
#include <datasrc/memory_datasrc.h>
#include <datasrc/zonetable.h>
#include <datasrc/factory.h>
#include <auth/auth_srv.h>
#include <auth/auth_config.h>
@ -34,6 +27,15 @@
#include <server_common/portconfig.h>
#include <boost/foreach.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <set>
#include <string>
#include <utility>
#include <vector>
using namespace std;
using namespace isc::dns;
using namespace isc::data;
@ -165,10 +167,21 @@ MemoryDatasourceConfig::build(ConstElementPtr config_value) {
isc_throw(AuthConfigError, "Missing zone file for zone: "
<< origin_txt);
}
// We support the traditional text type and SQLite3 backend. For the
// latter we create a client for the underlying SQLite3 data source,
// and build the in-memory zone using an iterator of the underlying
// zone.
ConstElementPtr filetype = zone_config->get("filetype");
const string filetype_txt = filetype ? filetype->stringValue() :
"text";
if (filetype_txt != "text") {
boost::scoped_ptr<DataSourceClientContainer> container;
if (filetype_txt == "sqlite3") {
container.reset(new DataSourceClientContainer(
"sqlite3",
Element::fromJSON("{\"database_file\": \"" +
file_txt + "\"}")));
} else if (filetype_txt != "text") {
isc_throw(AuthConfigError, "Invalid filetype for zone "
<< origin_txt << ": " << filetype_txt);
}
@ -198,7 +211,12 @@ MemoryDatasourceConfig::build(ConstElementPtr config_value) {
* need the load method to be split into some kind of build and
* commit/abort parts.
*/
if (filetype_txt == "text") {
zone_finder->load(file_txt);
} else {
zone_finder->load(*container->getInstance().getIterator(
Name(origin_txt)));
}
}
}

View File

@ -12,6 +12,9 @@ AM_CXXFLAGS = $(B10_CXXFLAGS)
if USE_STATIC_LINK
AM_LDFLAGS = -static
# Some test cases cannot work with static link. To selectively disable such
# tests we signal it via a definition.
AM_CPPFLAGS += -DUSE_STATIC_LINK=1
endif
CLEANFILES = *.gcno *.gcda
@ -29,6 +32,7 @@ run_unittests_SOURCES += ../auth_config.h ../auth_config.cc
run_unittests_SOURCES += ../command.h ../command.cc
run_unittests_SOURCES += ../common.h ../common.cc
run_unittests_SOURCES += ../statistics.h ../statistics.cc
run_unittests_SOURCES += datasrc_util.h datasrc_util.cc
run_unittests_SOURCES += auth_srv_unittest.cc
run_unittests_SOURCES += config_unittest.cc
run_unittests_SOURCES += config_syntax_unittest.cc

View File

@ -21,6 +21,7 @@
#include <cc/data.h>
#include <datasrc/data_source.h>
#include <datasrc/memory_datasrc.h>
#include <xfr/xfrout_client.h>
@ -29,14 +30,20 @@
#include <auth/auth_config.h>
#include <auth/common.h>
#include "datasrc_util.h"
#include <testutils/mockups.h>
#include <testutils/portconfig.h>
#include <testutils/socket_request.h>
#include <sstream>
using namespace std;
using namespace isc::dns;
using namespace isc::data;
using namespace isc::datasrc;
using namespace isc::asiodns;
using namespace isc::auth::unittest;
using namespace isc::testutils;
namespace {
@ -201,17 +208,44 @@ TEST_F(MemoryDatasrcConfigTest, addOneZone) {
RRType::A())->code);
}
TEST_F(MemoryDatasrcConfigTest, addOneWithFiletype) {
// Until #1792 is completed, only "text" filetype is allowed.
// This test uses dynamic load of a data source module, and won't work when
// statically linked.
TEST_F(MemoryDatasrcConfigTest,
#ifdef USE_STATIC_LINK
DISABLED_addOneWithFiletypeSQLite3
#else
addOneWithFiletypeSQLite3
#endif
)
{
const string test_db = TEST_DATA_BUILDDIR "/auth_test.sqlite3.copied";
stringstream ss("example.org. 3600 IN SOA . . 0 0 0 0 0\n");
createSQLite3DB(rrclass, Name("example.org"), test_db.c_str(), ss);
// In-memory with an SQLite3 data source as the backend.
parser->build(Element::fromJSON(
"[{\"type\": \"memory\","
" \"zones\": [{\"origin\": \"example.org\","
" \"file\": \""
+ test_db + "\","
" \"filetype\": \"sqlite3\"}]}]"));
parser->commit();
EXPECT_EQ(1, server.getInMemoryClient(rrclass)->getZoneCount());
// Failure case: the specified zone doesn't exist in the DB file.
delete parser;
parser = createAuthConfigParser(server, "datasources");
EXPECT_THROW(parser->build(
Element::fromJSON(
"[{\"type\": \"memory\","
" \"zones\": [{\"origin\": \"example.com\","
" \"file\": \""
TEST_DATA_DIR "/example.zone\","
+ test_db + "\","
" \"filetype\": \"sqlite3\"}]}]")),
AuthConfigError);
DataSourceError);
}
TEST_F(MemoryDatasrcConfigTest, addOneWithFiletypeText) {
// Explicitly specifying "text" is okay.
parser->build(Element::fromJSON(
"[{\"type\": \"memory\","

View File

@ -0,0 +1,77 @@
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <exceptions/exceptions.h>
#include <dns/masterload.h>
#include <dns/name.h>
#include <dns/rrclass.h>
#include <cc/data.h>
#include <datasrc/client.h>
#include <datasrc/zone.h>
#include <datasrc/factory.h>
#include "datasrc_util.h"
#include <boost/bind.hpp>
#include <istream>
#include <cstdlib>
using namespace std;
using namespace isc::dns;
using namespace isc::data;
using namespace isc::datasrc;
namespace isc {
namespace auth {
namespace unittest {
namespace {
void
addRRset(ZoneUpdaterPtr updater, ConstRRsetPtr rrset) {
updater->addRRset(*rrset);
}
}
void
createSQLite3DB(RRClass zclass, const Name& zname,
const char* const db_file, istream& rr_stream)
{
// We always begin with an empty template SQLite3 DB file and install
// the zone data from the zone file.
const char* const install_cmd_prefix = INSTALL_PROG " " TEST_DATA_DIR
"/rwtest.sqlite3 ";
const string install_cmd = string(install_cmd_prefix) + db_file;
if (system(install_cmd.c_str()) != 0) {
isc_throw(isc::Unexpected,
"Error setting up; command failed: " << install_cmd);
}
DataSourceClientContainer container("sqlite3",
Element::fromJSON(
"{\"database_file\": \"" +
string(db_file) + "\"}"));
ZoneUpdaterPtr updater = container.getInstance().getUpdater(zname, true);
masterLoad(rr_stream, zname, zclass, boost::bind(addRRset, updater, _1));
updater->commit();
}
} // end of unittest
} // end of auth
} // end of isc

View File

@ -0,0 +1,61 @@
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef __AUTH_DATA_SOURCE_UTIL_H
#define __AUTH_DATA_SOURCE_UTIL_H 1
#include <dns/name.h>
#include <dns/rrclass.h>
#include <istream>
namespace isc {
namespace auth {
namespace unittest {
// Here we define utility modules for the convenience of tests that create
// a data source client according to the specified conditions.
/// \brief Create an SQLite3 data source client from a stream.
///
/// This function creates an SQLite3 DB file for the specified zone
/// with specified content. The zone will be created in the given
/// SQLite3 database file. The database file does not have to exist;
/// this function will automatically create a new file for the test
/// based on a template that only contains the necessary schema. If
/// the given file already exists this function overrides the content
/// (so basically the file must be an ephemeral one only for that test
/// case).
///
/// The input stream must produce strings as the corresponding
/// \c dns::masterLoad() function expects.
///
/// \param zclass The RR class of the zone
/// \param zname The origin name of the zone
/// \param db_file The SQLite3 data base file in which the zone data should be
/// installed.
/// \param rr_stream An input stream that produces zone data.
void
createSQLite3DB(dns::RRClass zclass, const dns::Name& zname,
const char* const db_file, std::istream& rr_stream);
} // end of unittest
} // end of auth
} // end of isc
#endif // __AUTH_DATA_SOURCE_UTIL_H
// Local Variables:
// mode: c++
// End:

View File

@ -163,7 +163,7 @@ public:
///
/// \return Reference to the DataSourceClient instance contained in this
/// container.
DataSourceClient& getInstance() { return *instance_; }
DataSourceClient& getInstance() { return (*instance_); }
private:
DataSourceClient* instance_;

View File

@ -82,13 +82,15 @@ createInstance(isc::data::ConstElementPtr config, std::string& error) {
error = "Configuration error: " + errors->str();
return (NULL);
}
std::string dbfile = config->get(CONFIG_ITEM_DATABASE_FILE)->stringValue();
const std::string dbfile =
config->get(CONFIG_ITEM_DATABASE_FILE)->stringValue();
try {
boost::shared_ptr<DatabaseAccessor> sqlite3_accessor(
new SQLite3Accessor(dbfile, "IN")); // XXX: avoid hardcode RR class
return (new DatabaseClient(isc::dns::RRClass::IN(), sqlite3_accessor));
} catch (const std::exception& exc) {
error = std::string("Error creating sqlite3 datasource: ") + exc.what();
error = std::string("Error creating sqlite3 datasource: ") +
exc.what();
return (NULL);
} catch (...) {
error = std::string("Error creating sqlite3 datasource, "

View File

@ -107,7 +107,6 @@ EXTRA_DIST += testdata/mkbrokendb.c
EXTRA_DIST += testdata/root.zone
EXTRA_DIST += testdata/rrset_toWire1
EXTRA_DIST += testdata/rrset_toWire2
EXTRA_DIST += testdata/rwtest.sqlite3
EXTRA_DIST += testdata/sql1.example.com.signed
EXTRA_DIST += testdata/sql2.example.com.signed
EXTRA_DIST += testdata/test-root.sqlite3

View File

@ -1099,7 +1099,7 @@ public:
// probably move this to some specialized templated method specific
// to SQLite3 (or for even a longer term we should add an API to
// purge the diffs table).
const char* const install_cmd = INSTALL_PROG " " TEST_DATA_DIR
const char* const install_cmd = INSTALL_PROG " " TEST_DATA_COMMONDIR
"/rwtest.sqlite3 " TEST_DATA_BUILDDIR
"/rwtest.sqlite3.copied";
if (system(install_cmd) != 0) {

View File

@ -65,9 +65,9 @@ createSQLite3Client(RRClass zclass, const Name& zname,
const char* const db_file, istream& rr_stream)
{
// We always begin with an empty template SQLite3 DB file and install
// the zone data from the zone file to ensure that the data source contains
// the exact given data, and only that data.
const char* const install_cmd_prefix = INSTALL_PROG " " TEST_DATA_DIR
// the zone data from the zone file to ensure both cases have the
// same test data.
const char* const install_cmd_prefix = INSTALL_PROG " " TEST_DATA_COMMONDIR
"/rwtest.sqlite3 ";
const string install_cmd = string(install_cmd_prefix) + db_file;
if (system(install_cmd.c_str()) != 0) {

View File

@ -27,6 +27,7 @@ EXTRA_DIST += rfc5155-example.zone.signed
EXTRA_DIST += example.com
EXTRA_DIST += example.sqlite3
EXTRA_DIST += rwtest.sqlite3 # SQLite3 DB file as a template data source
EXTRA_DIST += test1.zone.in
EXTRA_DIST += test1-new.zone.in

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,24 @@
{
"version": 2,
"Logging": {
"loggers": [ {
"debuglevel": 99,
"severity": "DEBUG",
"name": "auth"
} ]
},
"Auth": {
"datasources": [ {
"type": "memory",
"zones": [ {
"origin": "example.org",
"file": "data/example.org.sqlite3",
"filetype": "sqlite3"
} ]
} ],
"listen_on": [ {
"port": 47806,
"address": "127.0.0.1"
} ]
}
}

View File

@ -0,0 +1,9 @@
Feature: In-memory zone using SQLite3 backend
This feature tests the authoritative server configured with an in-memory
data source that uses the SQLite3 data source as the backend, and tests
scenarios that update the zone via incoming zone transfers.
Scenario: Load and response
Given I have bind10 running with configuration inmemory_over_sqlite3/secondary.conf
A query for www.example.org should have rcode NOERROR
The SOA serial for example.org should be 1234