void addFromLoad(const ConstRRsetPtr& rrset,
const Name& zone_name, ZoneData* zone_data)
{
+ // If we see a new name, flush the temporary holders, adding the
+ // pairs of RRsets and RRSIGs of the previous name to the zone.
if ((!node_rrsets_.empty() || !node_rrsigsets_.empty()) &&
getCurrentName() != rrset->getName()) {
flushNodeRRsets(zone_name, zone_data);
}
- if (rrset->getType() == RRType::RRSIG()) {
- node_rrsigsets_.insert(NodeRRsetsVal(getCoveredType(rrset),
- rrset));
- } else {
- if (!node_rrsets_.insert(NodeRRsetsVal(rrset->getType(),
- rrset)).second) {
- isc_throw(AddError,
- "Duplicate add of the same type of RRset: "
- << rrset->getName() << "/" << rrset->getType());
- }
+
+ // Store this RRset until it can be added to the zone. The current
+ // implementation requires RRs of the same RRset should be added at
+ // once, so we check the "duplicate" here.
+ const bool is_rrsig = rrset->getType() == RRType::RRSIG();
+ NodeRRsets& node_rrsets = is_rrsig ? node_rrsigsets_ : node_rrsets_;
+ const RRType& rrtype = is_rrsig ?
+ getCoveredType(rrset) : rrset->getType();
+ if (!node_rrsets.insert(NodeRRsetsVal(rrtype, rrset)).second) {
+ isc_throw(AddError,
+ "Duplicate add of the same type of"
+ << (is_rrsig ? " RRSIG" : "") << " RRset: "
+ << rrset->getName() << "/" << rrtype);
}
}
void flushNodeRRsets(const Name& zone_name, ZoneData* zone_data) {
NULL
};
-// Similar to the previous, but RRs of the same RRset are separated.
+// RRsets that emulate the "separate RRs" mode.
const char* rrset_data_separated[] = {
+ "example.org. 3600 IN SOA ns1.example.org. bugs.x.w.example.org. "
+ "68 3600 300 3600000 3600",
+ "a.example.org. 3600 IN A 192.168.0.1", // these two belong to the same
+ "a.example.org. 3600 IN A 192.168.0.2", // RRset, but are separated.
+ NULL
+};
+
+// Similar to the previous one, but with separated RRSIGs
+const char* rrset_data_sigseparated[] = {
"example.org. 3600 IN SOA ns1.example.org. bugs.x.w.example.org. "
"68 3600 300 3600000 3600",
"a.example.org. 3600 IN A 192.168.0.1",
- "a.example.org. 3600 IN A 192.168.0.2",
-// This will trigger a bug in the implementation
-// "a.example.org. 3600 IN RRSIG A 5 3 3600 20150420235959 20051021000000 "
-// "40430 example.org. FAKEFAKE",
- "a.example.org. 3600 IN MX 10 mail.example.org.",
- "a.example.org. 3600 IN RRSIG MX 5 3 3600 20150420235959 20051021000000 "
- "40430 example.org. FAKEFAKEFAKE",
+ "a.example.org. 3600 IN RRSIG A 5 3 3600 20150420235959 20051021000000 "
+ "40430 example.org. FAKEFAKE",
+ "a.example.org. 3600 IN RRSIG A 5 3 3600 20150420235959 20051021000000 "
+ "53535 example.org. FAKEFAKE",
NULL
};
class MockIterator : public ZoneIterator {
private:
- MockIterator(bool separate_rrs) :
- rrset_data_ptr_(separate_rrs ? rrset_data_separated : rrset_data)
+ MockIterator(const char** rrset_data_ptr) :
+ rrset_data_ptr_(rrset_data_ptr)
{
}
isc_throw(isc::NotImplemented, "Not implemented");
}
- static ZoneIteratorPtr makeIterator(bool separate_rrs = false) {
- return (ZoneIteratorPtr(new MockIterator(separate_rrs)));
+ static ZoneIteratorPtr makeIterator(const char** rrset_data_ptr) {
+ return (ZoneIteratorPtr(new MockIterator(rrset_data_ptr)));
}
};
}
TEST_F(MemoryClientTest, loadFromIterator) {
- client_->load(Name("example.org"), *MockIterator::makeIterator());
+ client_->load(Name("example.org"),
+ *MockIterator::makeIterator(rrset_data));
ZoneIteratorPtr iterator(client_->getIterator(Name("example.org")));
// will fail because the resulting sequence doesn't meet assumptions of
// the (current) in-memory implementation.
EXPECT_THROW(client_->load(Name("example.org"),
- *MockIterator::makeIterator(true)),
+ *MockIterator::makeIterator(
+ rrset_data_separated)),
+ InMemoryClient::AddError);
+
+ // Similar to the previous case, but with separated RRSIGs.
+ EXPECT_THROW(client_->load(Name("example.org"),
+ *MockIterator::makeIterator(
+ rrset_data_sigseparated)),
InMemoryClient::AddError);
}