"www.example.com. 3600 IN RRSIG AAAA 5 2"
" 3600 20120814220826 20120715220826 "
"4321 example.com. FAKE\n")),
+ txt_rrsig_rrset_(textToRRset("www.example.com. 3600 IN RRSIG TXT 5 2"
+ " 3600 20120814220826 20120715220826 "
+ "1234 example.com. FAKE\n")),
zone_data_(NULL)
{}
void SetUp() {
aaaa_rdataset_ = RdataSet::create(mem_sgmt_, encoder_, aaaa_rrset_,
aaaa_rrsig_rrset_);
a_rdataset_->next = aaaa_rdataset_;
+
+ // A rare (half broken) case of RRSIG-only set
+ rrsig_only_rdataset_ = RdataSet::create(mem_sgmt_, encoder_,
+ ConstRRsetPtr(),
+ txt_rrsig_rrset_);
+ aaaa_rdataset_->next = rrsig_only_rdataset_;
}
void TearDown() {
ZoneData::destroy(mem_sgmt_, zone_data_, rrclass_);
RdataEncoder encoder_;
MessageRenderer renderer_, renderer_expected_;
ConstRRsetPtr ns_rrset_, a_rrset_, aaaa_rrset_, dname_rrset_,
- a_rrsig_rrset_, aaaa_rrsig_rrset_;
+ a_rrsig_rrset_, aaaa_rrsig_rrset_, txt_rrsig_rrset_;
ZoneData* zone_data_;
ZoneNode* origin_node_;
ZoneNode* www_node_;
RdataSet* dname_rdataset_;
RdataSet* a_rdataset_;
RdataSet* aaaa_rdataset_;
+ RdataSet* rrsig_only_rdataset_;
};
// Check some trivial fields of a constructed TreeNodeRRset (passed as
checkBasicFields(TreeNodeRRset(rrclass_, origin_node_, ns_rdataset_,
false),
origin_name_, rrclass_, RRType::NS(), 1, 0);
+ // RRSIG-only case (note the RRset's type is covered type)
+ checkBasicFields(TreeNodeRRset(rrclass_, www_node_, rrsig_only_rdataset_,
+ true),
+ www_name_, rrclass_, RRType::TXT(), 0, 1);
+ // RRSIG-only case (note the RRset's type is covered type), but it's
+ // invisible
+ checkBasicFields(TreeNodeRRset(rrclass_, www_node_, rrsig_only_rdataset_,
+ false),
+ www_name_, rrclass_, RRType::TXT(), 0, 0);
}
// Templated if and when we support OutputBuffer version of toWire().
// Prepare "actual" rendered data. We prepend a name to confirm the
// owner name should be compressed in both cases.
prepended_name.toWire(actual_output);
+ const size_t rdata_count = rrset ? rrset->getRdataCount() : 0;
const int expected_ret = (dnssec_ok && rrsig_rrset) ?
- rrset->getRdataCount() + rrsig_rrset->getRdataCount() :
- rrset->getRdataCount();
+ rdata_count + rrsig_rrset->getRdataCount() : rdata_count;
EXPECT_EQ(expected_ret, actual_rrset.toWire(actual_output));
// Prepare "expected" data.
prepended_name.toWire(expected_output);
- rrset->toWire(expected_output);
+ if (rrset) {
+ rrset->toWire(expected_output);
+ }
if (dnssec_ok && rrsig_rrset) {
rrsig_rrset->toWire(expected_output);
}
Name("example.org"), dname_rrset_, ConstRRsetPtr(),
false);
}
+
+ {
+ // Very unusual case: the set only contains RRSIG (already rare)
+ // and it's requested to be dumped to wire (can only happen in
+ // ANY or type-RRSIG queries, which are rare also). But can still
+ // happen.
+ SCOPED_TRACE("RRSIG only, DNSSEC OK");
+ const TreeNodeRRset rrset6(rrclass_, www_node_, rrsig_only_rdataset_,
+ true);
+ checkToWireResult(expected_renderer, actual_renderer, rrset6,
+ www_name_, ConstRRsetPtr(), txt_rrsig_rrset_,true);
+ }
+
+ {
+ // Similar to the previous case, but DNSSEC records aren't requested.
+ // In practice this case wouldn't happen, but API-wise possible, so
+ // we test it explicitly.
+ SCOPED_TRACE("RRSIG only, DNSSEC not OK");
+ const TreeNodeRRset rrset7(rrclass_, www_node_, rrsig_only_rdataset_,
+ false);
+ checkToWireResult(expected_renderer, actual_renderer, rrset7,
+ www_name_, ConstRRsetPtr(), txt_rrsig_rrset_,false);
+ }
}
void
EXPECT_TRUE(actual_renderer.isTruncated()); // always true in this test
expected_renderer.setLengthLimit(len_limit);
- rrset->toWire(expected_renderer);
+ if (rrset) {
+ rrset->toWire(expected_renderer);
+ }
if (!expected_renderer.isTruncated() && dnssec_ok && rrsig_rrset) {
rrsig_rrset->toWire(expected_renderer);
}
true),
aaaa_rrset_, aaaa_rrsig_rrset_, true, limit_len,
2); // 1 main RR, 1 RRSIG
+
+ // RRSIG only case. Render length limit being 1, so it won't fit,
+ // and will cause truncation.
+ checkTruncationResult(expected_renderer, actual_renderer,
+ TreeNodeRRset(rrclass_, www_node_,
+ rrsig_only_rdataset_, true),
+ ConstRRsetPtr(), txt_rrsig_rrset_, true, 1,
+ 0); // no RR
}
void
// move to the first RDATA again, and check the value.
rit->first();
- EXPECT_EQ(expected[0], rit->getCurrent().toText());
+ if (!expected.empty()) {
+ EXPECT_EQ(expected[0], rit->getCurrent().toText());
+ } else {
+ EXPECT_TRUE(rit->isLast());
+ }
}
TEST_F(TreeNodeRRsetTest, getRdataIterator) {
checkRdataIterator(expected,
TreeNodeRRset(rrclass_, origin_node_, ns_rdataset_,
false).getRdataIterator());
+
+ // RRSIG only. Iterator will be empty and shouldn't cause any disruption.
+ expected.clear();
+ checkRdataIterator(expected,
+ TreeNodeRRset(rrclass_, www_node_, rrsig_only_rdataset_,
+ true).getRdataIterator());
}
void
// Constructed without RRSIG, and it should be visible
checkToText(TreeNodeRRset(rrclass_, origin_node_, ns_rdataset_, false),
ns_rrset_, ConstRRsetPtr());
+ // RRSIG case
+ checkToText(TreeNodeRRset(rrclass_, www_node_, rrsig_only_rdataset_,
+ true),
+ ConstRRsetPtr(), txt_rrsig_rrset_);
+ // Similar to the previous case, but completely empty.
+ checkToText(TreeNodeRRset(rrclass_, www_node_, rrsig_only_rdataset_,
+ false),
+ ConstRRsetPtr(), ConstRRsetPtr());
}
}