summaryrefslogtreecommitdiffstats
path: root/src/lib/dns/tests/question_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dns/tests/question_unittest.cc')
-rw-r--r--src/lib/dns/tests/question_unittest.cc196
1 files changed, 196 insertions, 0 deletions
diff --git a/src/lib/dns/tests/question_unittest.cc b/src/lib/dns/tests/question_unittest.cc
new file mode 100644
index 0000000..03d31b1
--- /dev/null
+++ b/src/lib/dns/tests/question_unittest.cc
@@ -0,0 +1,196 @@
+// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <config.h>
+
+#include <vector>
+#include <sstream>
+
+#include <exceptions/exceptions.h>
+
+#include <util/buffer.h>
+#include <dns/exceptions.h>
+#include <dns/messagerenderer.h>
+#include <dns/name.h>
+#include <dns/question.h>
+#include <dns/rrclass.h>
+#include <dns/rrtype.h>
+
+#include <gtest/gtest.h>
+
+#include <dns/tests/unittest_util.h>
+#include <util/unittests/wiredata.h>
+
+using namespace std;
+using namespace isc::dns;
+using namespace isc::util;
+using isc::UnitTestUtil;
+using isc::util::unittests::matchWireData;
+
+namespace {
+class QuestionTest : public ::testing::Test {
+protected:
+ QuestionTest() : obuffer(0),
+ example_name1(Name("foo.example.com")),
+ example_name2(Name("bar.example.com")),
+ test_question1(example_name1, RRClass::IN(),
+ RRType::NS()),
+ test_question2(example_name2, RRClass::CH(),
+ RRType::A())
+ {}
+ OutputBuffer obuffer;
+ MessageRenderer renderer;
+ Name example_name1;
+ Name example_name2;
+ Question test_question1;
+ Question test_question2;
+ vector<unsigned char> wiredata;
+};
+
+Question
+questionFromWire(const char* datafile, size_t position = 0) {
+ vector<unsigned char> data;
+ UnitTestUtil::readWireData(datafile, data);
+
+ InputBuffer buffer(&data[0], data.size());
+ buffer.setPosition(position);
+
+ return (Question(buffer));
+}
+
+TEST_F(QuestionTest, fromWire) {
+ Question q = questionFromWire("question_fromWire");
+
+ EXPECT_EQ(example_name1, q.getName());
+ EXPECT_EQ(RRClass::IN(), q.getClass());
+ EXPECT_EQ(RRType::NS(), q.getType());
+
+ // owner name of the second Question is compressed. It's uncommon
+ // (to have multiple questions), but isn't prohibited by the protocol.
+ q = questionFromWire("question_fromWire", 21);
+ EXPECT_EQ(example_name2, q.getName());
+ EXPECT_EQ(RRClass::CH(), q.getClass());
+ EXPECT_EQ(RRType::A(), q.getType());
+
+ // Pathological cases: Corresponding exceptions will be thrown from
+ // the underlying parser.
+ EXPECT_THROW(questionFromWire("question_fromWire", 31), DNSMessageFORMERR);
+ EXPECT_THROW(questionFromWire("question_fromWire", 36), IncompleteRRClass);
+}
+
+TEST_F(QuestionTest, toText) {
+ EXPECT_EQ("foo.example.com. IN NS", test_question1.toText());
+ EXPECT_EQ("bar.example.com. CH A", test_question2.toText());
+
+ EXPECT_EQ("foo.example.com. IN NS", test_question1.toText(false));
+ EXPECT_EQ("bar.example.com. CH A", test_question2.toText(false));
+
+ EXPECT_EQ("foo.example.com. IN NS\n", test_question1.toText(true));
+ EXPECT_EQ("bar.example.com. CH A\n", test_question2.toText(true));
+}
+
+TEST_F(QuestionTest, toWireBuffer) {
+ test_question1.toWire(obuffer);
+ test_question2.toWire(obuffer);
+ UnitTestUtil::readWireData("question_toWire1", wiredata);
+ matchWireData(&wiredata[0], wiredata.size(),
+ obuffer.getData(), obuffer.getLength());
+}
+
+TEST_F(QuestionTest, toWireRenderer) {
+ test_question1.toWire(renderer);
+ test_question2.toWire(renderer);
+ UnitTestUtil::readWireData("question_toWire2", wiredata);
+ matchWireData(&wiredata[0], wiredata.size(),
+ renderer.getData(), renderer.getLength());
+}
+
+TEST_F(QuestionTest, toWireTruncated) {
+ // If the available length in the renderer is too small, it would require
+ // truncation. This won't happen in normal cases, but protocol wise it
+ // could still happen if and when we support some (possibly future) opcode
+ // that allows multiple questions.
+
+ // Set the length limit to the qname length so that the whole question
+ // would request truncated
+ renderer.setLengthLimit(example_name1.getLength());
+
+ EXPECT_FALSE(renderer.isTruncated()); // check pre-render condition
+ EXPECT_EQ(0, test_question1.toWire(renderer));
+ EXPECT_TRUE(renderer.isTruncated());
+ EXPECT_EQ(0, renderer.getLength()); // renderer shouldn't have any data
+}
+
+// test operator<<. We simply confirm it appends the result of toText().
+TEST_F(QuestionTest, LeftShiftOperator) {
+ ostringstream oss;
+ oss << test_question1;
+ EXPECT_EQ(test_question1.toText(), oss.str());
+}
+
+TEST_F(QuestionTest, comparison) {
+ const Name a("a"), b("b");
+ const RRClass in(RRClass::IN()), ch(RRClass::CH());
+ const RRType ns(RRType::NS()), aaaa(RRType::AAAA());
+
+ EXPECT_TRUE(Question(a, in, ns) < Question(a, in, aaaa));
+ EXPECT_FALSE(Question(a, in, aaaa) < Question(a, in, ns));
+
+ EXPECT_TRUE(Question(a, in, ns) < Question(a, ch, ns));
+ EXPECT_FALSE(Question(a, ch, ns) < Question(a, in, ns));
+
+ EXPECT_TRUE(Question(a, in, ns) < Question(a, ch, aaaa));
+ EXPECT_FALSE(Question(a, ch, aaaa) < Question(a, in, ns));
+
+ EXPECT_TRUE(Question(a, in, ns) < Question(b, in, ns));
+ EXPECT_FALSE(Question(a, in, ns) < Question(a, in, ns));
+
+ EXPECT_TRUE(Question(a, in, ns) < Question(b, ch, ns));
+ EXPECT_FALSE(Question(b, ch, ns) < Question(a, in, ns));
+
+ EXPECT_TRUE(Question(a, in, ns) < Question(b, ch, aaaa));
+ EXPECT_FALSE(Question(b, ch, aaaa) < Question(a, in, ns));
+
+ EXPECT_FALSE(Question(a, in, ns) < Question(a, in, ns));
+ EXPECT_FALSE(Question(a, ch, ns) < Question(a, ch, ns));
+ EXPECT_FALSE(Question(b, in, ns) < Question(b, in, ns));
+ EXPECT_FALSE(Question(b, in, aaaa) < Question(b, in, aaaa));
+
+ // Identical questions are equal
+
+ EXPECT_TRUE(Question(a, in, ns) == Question(a, in, ns));
+ EXPECT_FALSE(Question(a, in, ns) != Question(a, in, ns));
+
+ // Components differing by one component are unequal...
+
+ EXPECT_FALSE(Question(b, in, ns) == Question(a, in, ns));
+ EXPECT_TRUE(Question(b, in, ns) != Question(a, in, ns));
+
+ EXPECT_FALSE(Question(a, ch, ns) == Question(a, in, ns));
+ EXPECT_TRUE(Question(a, ch, ns) != Question(a, in, ns));
+
+ EXPECT_FALSE(Question(a, in, aaaa) == Question(a, in, ns));
+ EXPECT_TRUE(Question(a, in, aaaa) != Question(a, in, ns));
+
+ // ... as are those differing by two components
+
+ EXPECT_FALSE(Question(b, ch, ns) == Question(a, in, ns));
+ EXPECT_TRUE(Question(b, ch, ns) != Question(a, in, ns));
+
+ EXPECT_FALSE(Question(b, in, aaaa) == Question(a, in, ns));
+ EXPECT_TRUE(Question(b, in, aaaa) != Question(a, in, ns));
+
+ EXPECT_FALSE(Question(a, ch, aaaa) == Question(a, in, ns));
+ EXPECT_TRUE(Question(a, ch, aaaa) != Question(a, in, ns));
+
+ // ... and question differing by all three
+
+ EXPECT_FALSE(Question(b, ch, aaaa) == Question(a, in, ns));
+ EXPECT_TRUE(Question(b, ch, aaaa) != Question(a, in, ns));
+
+}
+
+}