Commit 0878c77b authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[1332] [1332] implement a bit more complete version of getNextDiff() with more

detailed tests.  The MockAccessor was updated to have workable getDiffs().
parent efeb506e
......@@ -1095,26 +1095,57 @@ DatabaseClient::getUpdater(const isc::dns::Name& name, bool replace,
// source.
//
class DatabaseJournalReader : public ZoneJournalReader {
private:
// A shortcut typedef to keep the code concise.
typedef DatabaseAccessor Accessor;
public:
DatabaseJournalReader() {}
DatabaseJournalReader(shared_ptr<Accessor> accessor, const Name& zone,
const RRClass& rrclass, uint32_t begin,
uint32_t end) :
accessor_(accessor), rrclass_(rrclass)
{
const pair<bool, int> zoneinfo(accessor_->getZone(zone.toText()));
if (!zoneinfo.first) {
// No such zone, can't continue
isc_throw(DataSourceError, "Zone " << zone << "/"
<< rrclass << " doesn't exist in database: " <<
accessor_->getDBName());
}
context_ = accessor_->getDiffs(zoneinfo.second, begin, end);
}
virtual ~DatabaseJournalReader() {}
virtual ConstRRsetPtr getNextDiff() {
return (ConstRRsetPtr());
// TBD: check read after completion
string data[Accessor::COLUMN_COUNT];
if (!context_->getNext(data)) {
return (ConstRRsetPtr());
}
RRsetPtr rrset(new RRset(Name(data[Accessor::NAME_COLUMN]), rrclass_,
RRType(data[Accessor::TYPE_COLUMN]),
RRTTL(data[Accessor::TTL_COLUMN])));
rrset->addRdata(rdata::createRdata(rrset->getType(), rrclass_,
data[Accessor::RDATA_COLUMN]));
return (rrset);
}
private:
shared_ptr<Accessor> accessor_;
const RRClass rrclass_;
Accessor::IteratorContextPtr context_;
};
// The JournalReader factory
ZoneJournalReaderPtr
DatabaseClient::getJournalReader(const isc::dns::Name& zone,
uint32_t, uint32_t) const
uint32_t begin_serial,
uint32_t end_serial) const
{
const pair<bool, int> zoneinfo(accessor_->getZone(zone.toText()));
if (!zoneinfo.first) {
// No such zone, can't continue
isc_throw(DataSourceError, "Zone " << zone << "/" << rrclass_ <<
" doesn't exist in database: " + accessor_->getDBName());
}
return (ZoneJournalReaderPtr(new DatabaseJournalReader()));
return (ZoneJournalReaderPtr(new DatabaseJournalReader(accessor_, zone,
rrclass_,
begin_serial,
end_serial)));
}
}
}
......@@ -33,6 +33,7 @@
#include <testutils/dnsmessage_test.h>
#include <map>
#include <vector>
using namespace isc::datasrc;
using namespace std;
......@@ -261,7 +262,7 @@ public:
virtual IteratorContextPtr getDiffs(int, uint32_t, uint32_t) const {
isc_throw(isc::NotImplemented,
"This database datasource can't be iterated");
"This database datasource doesn't support diffs");
}
virtual std::string findPreviousName(int, const std::string&) const {
......@@ -550,6 +551,29 @@ private:
}
}
};
class MockDiffIteratorContext : public IteratorContext {
const vector<JournalEntry> diffs_;
vector<JournalEntry>::const_iterator it_;
public:
MockDiffIteratorContext(const vector<JournalEntry>& diffs) :
diffs_(diffs), it_(diffs_.begin())
{}
virtual bool getNext(string (&data)[COLUMN_COUNT]) {
if (it_ == diffs_.end()) {
return (false);
}
data[DatabaseAccessor::NAME_COLUMN] =
(*it_).data_[DatabaseAccessor::DIFF_NAME];
data[DatabaseAccessor::TYPE_COLUMN] =
(*it_).data_[DatabaseAccessor::DIFF_TYPE];
data[DatabaseAccessor::TTL_COLUMN] =
(*it_).data_[DatabaseAccessor::DIFF_TTL];
data[DatabaseAccessor::RDATA_COLUMN] =
(*it_).data_[DatabaseAccessor::DIFF_RDATA];
++it_;
return (true);
}
};
public:
virtual IteratorContextPtr getAllRecords(int id) const {
if (id == READONLY_ZONE_ID) {
......@@ -733,6 +757,26 @@ public:
}
}
virtual IteratorContextPtr getDiffs(int id, uint32_t start,
uint32_t end) const
{
vector<JournalEntry> selected_jnl;
for (vector<JournalEntry>::const_iterator it =
journal_entries_->begin();
it != journal_entries_->end(); ++it)
{
// For simplicity we don't take into account serial number
// arithmetic; compare serials as bare unsigned integers.
if (id != READONLY_ZONE_ID || (*it).serial_ < start ||
(*it).serial_ > end) {
continue;
}
selected_jnl.push_back(*it);
}
return (IteratorContextPtr(new MockDiffIteratorContext(selected_jnl)));
}
// Check the journal is as expected and clear the journal
void checkJournal(const std::vector<JournalEntry> &expected) const {
std::vector<JournalEntry> journal;
......@@ -3009,11 +3053,36 @@ TEST_F(MockDatabaseClientTest, journalException) {
EXPECT_THROW(updater_->deleteRRset(*soa_), DataSourceError);
}
TYPED_TEST(DatabaseClientTest, getJournalReader) {
//
// Tests for the ZoneJournalReader
//
TYPED_TEST(DatabaseClientTest, journalReader) {
// Check a simple, normal scenario: making an update from one SOA to
// another, and retrieve the corresponding diffs.
this->updater_ = this->client_->getUpdater(this->zname_, false, true);
this->updater_->deleteRRset(*this->soa_);
RRsetPtr soa_end(new RRset(this->zname_, this->qclass_, RRType::SOA(),
this->rrttl_));
soa_end->addRdata(rdata::createRdata(RRType::SOA(), this->qclass_,
"ns1.example.org. admin.example.org. "
"1235 3600 1800 2419200 7200"));
this->updater_->addRRset(*soa_end);
this->updater_->commit();
ZoneJournalReaderPtr jnl_reader(this->client_->getJournalReader(
this->zname_, 0, 1));
EXPECT_FALSE(jnl_reader->getNextDiff());
this->zname_, 1234, 1235));
ConstRRsetPtr rrset = jnl_reader->getNextDiff();
ASSERT_TRUE(rrset);
isc::testutils::rrsetCheck(this->soa_, rrset);
rrset = jnl_reader->getNextDiff();
ASSERT_TRUE(rrset);
isc::testutils::rrsetCheck(soa_end, rrset);
rrset = jnl_reader->getNextDiff();
ASSERT_FALSE(rrset);
}
TYPED_TEST(DatabaseClientTest, journalReaderForNXZone) {
EXPECT_THROW(this->client_->getJournalReader(Name("nosuchzone"), 0, 1),
DataSourceError);
}
......
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