Commit c4824042 authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[2429] handled various corner cases.

parent 334ffd13
......@@ -182,10 +182,14 @@ private:
// and the default TTL for subsequent RRs.
const RRTTL& getCurrentTTL(bool explicit_ttl, const RRType& rrtype,
const rdata::ConstRdataPtr& rdata) {
// We've completed parsing the full of RR, and the lexer is already
// positioned at the next line. If we need to call callback,
// we need to adjust the line number.
const size_t current_line = lexer_.getSourceLine() - 1;
if (!current_ttl_ && !default_ttl_) {
if (rrtype == RRType::SOA()) {
callbacks_.warning(lexer_.getSourceName(),
lexer_.getSourceLine(),
callbacks_.warning(lexer_.getSourceName(), current_line,
"no TTL specified; "
"using SOA MINTTL instead");
const uint32_t ttl_val =
......@@ -193,14 +197,19 @@ private:
getMinimum();
setDefaultTTL(RRTTL(ttl_val));
setCurrentTTL(*default_ttl_);
} else {
// On catching the exception we'll try to reach EOL again,
// so we need to unget it now.
lexer_.ungetToken();
throw InternalException(__FILE__, __LINE__,
"no TTL specified; load rejected");
}
} else if (!explicit_ttl && default_ttl_) {
setCurrentTTL(*default_ttl_);
} else if (!explicit_ttl && warn_rfc1035_ttl_) {
// Omitted (class and) TTL values are default to the last
// explicitly stated values (RFC 1035, Sec. 5.1).
callbacks_.warning(lexer_.getSourceName(),
lexer_.getSourceLine(),
callbacks_.warning(lexer_.getSourceName(), current_line,
"using RFC1035 TTL semantics");
warn_rfc1035_ttl_ = false; // we only warn about this once
}
......@@ -231,7 +240,7 @@ private:
case MasterToken::END_OF_FILE:
callbacks_.warning(lexer_.getSourceName(),
lexer_.getSourceLine(),
"Unexpected end ond of file");
"Unexpected end end of file");
// We don't pop here. The End of file will stay there,
// and we'll handle it in the next iteration of
// loadIncremental properly.
......
......@@ -22,7 +22,9 @@
#include <dns/rdata.h>
#include <gtest/gtest.h>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/scoped_ptr.hpp>
#include <string>
......@@ -36,6 +38,7 @@ using std::string;
using std::list;
using std::stringstream;
using std::endl;
using boost::lexical_cast;
namespace {
class MasterLoaderTest : public ::testing::Test {
......@@ -407,6 +410,18 @@ TEST_F(MasterLoaderTest, ttlDirective) {
checkRR("a2.example.org", RRType::A(), "192.0.2.3", RRTTL(3600));
}
// A commonly used helper to check callback message.
void
checkCallbackMessage(const string& actual_msg, const string& expected_msg,
size_t expected_line) {
// The actual message should begin with the expected message.
EXPECT_EQ(0, actual_msg.find(expected_msg));
// and it should end with "...:<line_num>]"
const string line_desc = ":" + lexical_cast<string>(expected_line) + "]";
EXPECT_EQ(actual_msg.size() - line_desc.size(), actual_msg.find(line_desc));
}
TEST_F(MasterLoaderTest, ttlFromSOA) {
// No $TTL, and the SOA doesn't have an explicit TTL field. Its minimum
// TTL field will be used as the RR's TTL, and it'll be used as the
......@@ -422,10 +437,11 @@ TEST_F(MasterLoaderTest, ttlFromSOA) {
// The use of SOA minimum TTL should have caused a warning.
EXPECT_EQ(1, warnings_.size());
EXPECT_EQ(0, warnings_.at(0).find(
"no TTL specified; using SOA MINTTL instead"));
checkCallbackMessage(warnings_.at(0),
"no TTL specified; using SOA MINTTL instead", 1);
}
TEST_F(MasterLoaderTest, ttlFromPrevious) {
// No available default TTL. 2nd and 3rd RR will use the TTL of the
// 1st RR. This will result in a warning, but only for the first time.
......@@ -441,7 +457,66 @@ TEST_F(MasterLoaderTest, ttlFromPrevious) {
checkRR("c.example.org", RRType::A(), "192.0.2.3", RRTTL(1800));
EXPECT_EQ(1, warnings_.size());
EXPECT_EQ(0, warnings_.at(0).find("using RFC1035 TTL semantics"));
checkCallbackMessage(warnings_.at(0), "using RFC1035 TTL semantics", 2);
}
TEST_F(MasterLoaderTest, ttlFromPreviousSOA) {
// Mixture of the previous two cases: SOA has explicit TTL, followed by
// an RR without an explicit TTL. In this case the minimum TTL won't be
// recognized as the "default TTL".
stringstream zone_stream("example.org. 100 IN SOA . . 0 0 0 0 1800\n"
"a.example.org. IN A 192.0.2.1\n");
setLoader(zone_stream, Name("example.org."), RRClass::IN(),
MasterLoader::DEFAULT);
loader_->load();
EXPECT_TRUE(loader_->loadedSucessfully());
checkRR("example.org", RRType::SOA(), ". . 0 0 0 0 1800", RRTTL(100));
checkRR("a.example.org", RRType::A(), "192.0.2.1", RRTTL(100));
EXPECT_EQ(1, warnings_.size());
checkCallbackMessage(warnings_.at(0), "using RFC1035 TTL semantics", 2);
}
TEST_F(MasterLoaderTest, ttlUnknown) {
// No available TTL is known for the first RR.
stringstream zone_stream("a.example.org. IN A 192.0.2.1\n");
setLoader(zone_stream, Name("example.org."), RRClass::IN(),
MasterLoader::DEFAULT);
EXPECT_THROW(loader_->load(), MasterLoaderError);
}
TEST_F(MasterLoaderTest, ttlUnknownAndContinue) {
stringstream zone_stream("a.example.org. IN A 192.0.2.1\n"
"b.example.org. 1800 IN A 192.0.2.2\n");
setLoader(zone_stream, Name("example.org."), RRClass::IN(),
MasterLoader::MANY_ERRORS);
loader_->load();
EXPECT_FALSE(loader_->loadedSucessfully());
checkRR("b.example.org", RRType::A(), "192.0.2.2", RRTTL(1800));
EXPECT_TRUE(warnings_.empty());
EXPECT_EQ(1, errors_.size());
checkCallbackMessage(errors_.at(0), "no TTL specified; load rejected", 1);
}
TEST_F(MasterLoaderTest, ttlUnknownAndEOF) {
// Similar to the previous case, but the input will be abruptly terminated
// after the offending RR. This will cause an additional warning.
stringstream zone_stream("a.example.org. IN A 192.0.2.1");
setLoader(zone_stream, Name("example.org."), RRClass::IN(),
MasterLoader::MANY_ERRORS);
loader_->load();
EXPECT_FALSE(loader_->loadedSucessfully());
EXPECT_TRUE(rrsets_.empty());
EXPECT_EQ(1, errors_.size());
checkCallbackMessage(errors_.at(0), "no TTL specified; load rejected", 1);
// RDATA implementation can complain about it, too. To be independent of
// its details, we focus on the very last warning.
EXPECT_FALSE(warnings_.empty());
checkCallbackMessage(*warnings_.rbegin(), "Unexpected end end of file", 1);
}
// Test the constructor rejects empty add callback.
......
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