Commit e5fb484f authored by Michal 'vorner' Vaner's avatar Michal 'vorner' Vaner
Browse files

[2377] Provide MasterLoader constructor from stream

Instead of file name. And use it for some of the tests, to avoid
juggling with files.
parent 03911f10
......@@ -51,6 +51,12 @@ public:
ok_ = false;
callbacks_.error("", 0, error);
}
initialized_ = true;
}
void pushStreamSource(std::istream& stream) {
lexer_.pushSource(stream);
initialized_ = true;
}
// Get a string token. Handle it as error if it is not string.
......@@ -65,7 +71,6 @@ public:
}
if (!initialized_) {
pushSource(master_file_);
initialized_ = true;
}
size_t count = 0;
while (ok_ && count < count_limit) {
......@@ -184,6 +189,21 @@ MasterLoader::MasterLoader(const char* master_file,
zone_class, callbacks, add_callback, options);
}
MasterLoader::MasterLoader(std::istream& stream,
const Name& zone_origin,
const RRClass& zone_class,
const MasterLoaderCallbacks& callbacks,
const AddRRCallback& add_callback,
Options options)
{
if (add_callback.empty()) {
isc_throw(isc::InvalidParameter, "Empty add RR callback");
}
impl_ = new MasterLoaderImpl("", zone_origin, zone_class, callbacks,
add_callback, options);
impl_->pushStreamSource(stream);
}
MasterLoader::~MasterLoader() {
delete impl_;
}
......
......@@ -71,6 +71,20 @@ public:
const AddRRCallback& add_callback,
Options options = DEFAULT);
/// \brief Constructor from a stream
///
/// This is a constructor very similar to the previous one. The only
/// difference is it doesn't take a filename, but an input stream
/// to read the data from. It is expected to be mostly used in tests,
/// but it is public as it may possibly be useful for other currently
/// unknown purposes.
MasterLoader(std::istream& input,
const Name& zone_origin,
const RRClass& zone_class,
const MasterLoaderCallbacks& callbacks,
const AddRRCallback& add_callback,
Options options = DEFAULT);
/// \brief Destructor
~MasterLoader();
......
......@@ -26,13 +26,13 @@
#include <string>
#include <vector>
#include <list>
#include <fstream>
#include <sstream>
using namespace isc::dns;
using std::vector;
using std::string;
using std::list;
using std::ofstream;
using std::stringstream;
using std::endl;
namespace {
......@@ -67,8 +67,8 @@ public:
rrsets_.push_back(rrset);
}
void setLoader(const char* file, const Name& origin, const RRClass rrclass,
const MasterLoader::Options options)
void setLoader(const char* file, const Name& origin,
const RRClass& rrclass, const MasterLoader::Options options)
{
loader_.reset(new MasterLoader(file, origin, rrclass, callbacks_,
boost::bind(&MasterLoaderTest::addRRset,
......@@ -76,15 +76,22 @@ public:
options));
}
void prepareBrokenZone(const string& filename, const string& line) {
ofstream out(filename.c_str(),
std::ios_base::out | std::ios_base::trunc);
ASSERT_FALSE(out.fail());
out << "example.org. 3600 IN SOA ns1.example.org. "
"admin.example.org. 1234 3600 1800 2419200 7200" << endl;
out << line << endl;
out << "correct 3600 IN A 192.0.2.2" << endl;
out.close();
void setLoader(std::istream& stream, const Name& origin,
const RRClass& rrclass, const MasterLoader::Options options)
{
loader_.reset(new MasterLoader(stream, origin, rrclass, callbacks_,
boost::bind(&MasterLoaderTest::addRRset,
this, _1, _2, _3, _4, _5),
options));
}
string prepareZone(const string& line) {
string result;
result += "example.org. 3600 IN SOA ns1.example.org. "
"admin.example.org. 1234 3600 1800 2419200 7200\n";
result += line + "\n";
result += "correct 3600 IN A 192.0.2.2\n";
return (result);
}
void clear() {
......@@ -131,6 +138,21 @@ TEST_F(MasterLoaderTest, basicLoad) {
checkRR("www.example.org", RRType::A(), "192.0.2.1");
}
// Check it works the same when created based on a stream, not filename
TEST_F(MasterLoaderTest, streamConstructor) {
stringstream zone_stream(prepareZone(""));
setLoader(zone_stream, Name("example.org."), RRClass::IN(),
MasterLoader::MANY_ERRORS);
loader_->load();
EXPECT_TRUE(errors_.empty());
EXPECT_TRUE(warnings_.empty());
checkRR("example.org", RRType::SOA(), "ns1.example.org. "
"admin.example.org. 1234 3600 1800 2419200 7200");
checkRR("correct.example.org", RRType::A(), "192.0.2.2");
}
// Try loading data incrementally.
TEST_F(MasterLoaderTest, incrementalLoad) {
setLoader(TEST_DATA_SRCDIR "/example.org", Name("example.org."),
......@@ -193,15 +215,15 @@ struct ErrorCase {
// Test a broken zone is handled properly. We test several problems,
// both in strict and lenient mode.
TEST_F(MasterLoaderTest, brokenZone) {
const string filename(TEST_DATA_BUILDDIR "/broken.zone");
for (const ErrorCase* ec = error_cases; ec->line != NULL; ++ec) {
SCOPED_TRACE(ec->problem);
prepareBrokenZone(filename, ec->line);
const string zone(prepareZone(ec->line));
{
SCOPED_TRACE("Strict mode");
clear();
setLoader(filename.c_str(), Name("example.org."), RRClass::IN(),
stringstream zone_stream(zone);
setLoader(zone_stream, Name("example.org."), RRClass::IN(),
MasterLoader::DEFAULT);
loader_->load();
EXPECT_EQ(1, errors_.size());
......@@ -217,7 +239,8 @@ TEST_F(MasterLoaderTest, brokenZone) {
{
SCOPED_TRACE("Lenient mode");
clear();
setLoader(filename.c_str(), Name("example.org."), RRClass::IN(),
stringstream zone_stream(zone);
setLoader(zone_stream, Name("example.org."), RRClass::IN(),
MasterLoader::MANY_ERRORS);
loader_->load();
EXPECT_EQ(1, errors_.size());
......@@ -236,6 +259,11 @@ TEST_F(MasterLoaderTest, emptyCallback) {
EXPECT_THROW(MasterLoader(TEST_DATA_SRCDIR "/example.org",
Name("example.org"), RRClass::IN(), callbacks_,
AddRRCallback()), isc::InvalidParameter);
// And the same with the second constructor
stringstream ss("");
EXPECT_THROW(MasterLoader(ss, Name("example.org"), RRClass::IN(),
callbacks_, AddRRCallback()),
isc::InvalidParameter);
}
// Check it throws when we try to load after loading was complete.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment