From: Michal 'vorner' Vaner Date: Fri, 7 Dec 2012 14:52:24 +0000 (+0100) Subject: [2377] Provide MasterLoader constructor from stream X-Git-Tag: bind10-1.0.0-beta-release~24^2~40 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e5fb484fbabf454dc0fea14ed4564061555af275;p=thirdparty%2Fkea.git [2377] Provide MasterLoader constructor from stream Instead of file name. And use it for some of the tests, to avoid juggling with files. --- diff --git a/src/lib/dns/master_loader.cc b/src/lib/dns/master_loader.cc index 581640b566..c4c5bc9964 100644 --- a/src/lib/dns/master_loader.cc +++ b/src/lib/dns/master_loader.cc @@ -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_; } diff --git a/src/lib/dns/master_loader.h b/src/lib/dns/master_loader.h index bbe4ac1800..c527c8ab1d 100644 --- a/src/lib/dns/master_loader.h +++ b/src/lib/dns/master_loader.h @@ -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(); diff --git a/src/lib/dns/tests/master_loader_unittest.cc b/src/lib/dns/tests/master_loader_unittest.cc index 8598b473a7..2156acdec6 100644 --- a/src/lib/dns/tests/master_loader_unittest.cc +++ b/src/lib/dns/tests/master_loader_unittest.cc @@ -26,13 +26,13 @@ #include #include #include -#include +#include 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.