summaryrefslogtreecommitdiffstats
path: root/src/lib/dns/tests/rdata_char_string_data_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dns/tests/rdata_char_string_data_unittest.cc')
-rw-r--r--src/lib/dns/tests/rdata_char_string_data_unittest.cc181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/lib/dns/tests/rdata_char_string_data_unittest.cc b/src/lib/dns/tests/rdata_char_string_data_unittest.cc
new file mode 100644
index 0000000..4ffeadb
--- /dev/null
+++ b/src/lib/dns/tests/rdata_char_string_data_unittest.cc
@@ -0,0 +1,181 @@
+// Copyright (C) 2014-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 <util/unittests/wiredata.h>
+
+#include <dns/exceptions.h>
+#include <dns/rdata.h>
+#include <dns/rdata/generic/detail/char_string.h>
+#include <util/buffer.h>
+
+#include <gtest/gtest.h>
+
+#include <string>
+#include <vector>
+
+using namespace isc::dns;
+using namespace isc::dns::rdata;
+using isc::dns::rdata::generic::detail::CharStringData;
+using isc::dns::rdata::generic::detail::stringToCharStringData;
+using isc::dns::rdata::generic::detail::charStringDataToString;
+using isc::dns::rdata::generic::detail::compareCharStringDatas;
+using isc::util::unittests::matchWireData;
+
+namespace {
+const uint8_t test_charstr[] = {
+ 'T', 'e', 's', 't', ' ', 'S', 't', 'r', 'i', 'n', 'g'
+};
+
+class CharStringDataTest : public ::testing::Test {
+protected:
+ CharStringDataTest() :
+ // char-string representation for test data using two types of escape
+ // ('r' = 114)
+ test_str("Test\\ St\\114ing")
+ {
+ str_region.beg = &test_str[0];
+ str_region.len = test_str.size();
+ }
+ CharStringData chstr; // place holder
+ const std::string test_str;
+ MasterToken::StringRegion str_region;
+};
+
+MasterToken::StringRegion
+createStringRegion(const std::string& str) {
+ MasterToken::StringRegion region;
+ region.beg = &str[0]; // note std ensures this works even if str is empty
+ region.len = str.size();
+ return (region);
+}
+
+TEST_F(CharStringDataTest, normalConversion) {
+ uint8_t tmp[3]; // placeholder for expected sequence
+
+ stringToCharStringData(str_region, chstr);
+ matchWireData(test_charstr, sizeof(test_charstr), &chstr[0], chstr.size());
+
+ // Empty string
+ chstr.clear();
+ stringToCharStringData(createStringRegion(""), chstr);
+ EXPECT_TRUE(chstr.empty());
+
+ // Possible largest char string
+ chstr.clear();
+ std::string long_str(255, 'x');
+ stringToCharStringData(createStringRegion(long_str), chstr);
+ std::vector<uint8_t> expected;
+ expected.insert(expected.end(), long_str.begin(), long_str.end());
+ matchWireData(&expected[0], expected.size(), &chstr[0], chstr.size());
+
+ // Escaped '\'
+ chstr.clear();
+ tmp[0] = '\\';
+ stringToCharStringData(createStringRegion("\\\\"), chstr);
+ matchWireData(tmp, 1, &chstr[0], chstr.size());
+
+ // Boundary values for \DDD
+ chstr.clear();
+ tmp[0] = 0;
+ stringToCharStringData(createStringRegion("\\000"), chstr);
+ matchWireData(tmp, 1, &chstr[0], chstr.size());
+
+ chstr.clear();
+ stringToCharStringData(createStringRegion("\\255"), chstr);
+ tmp[0] = 255;
+ matchWireData(tmp, 1, &chstr[0], chstr.size());
+
+ // Another digit follows DDD; it shouldn't cause confusion
+ chstr.clear();
+ stringToCharStringData(createStringRegion("\\2550"), chstr);
+ tmp[1] = '0';
+ matchWireData(tmp, 2, &chstr[0], chstr.size());
+}
+
+TEST_F(CharStringDataTest, badConversion) {
+ // input string ending with (non escaped) '\'
+ chstr.clear();
+ EXPECT_THROW(stringToCharStringData(createStringRegion("foo\\"), chstr),
+ InvalidRdataText);
+}
+
+TEST_F(CharStringDataTest, badDDD) {
+ // Check various type of bad form of \DDD
+
+ // Not a number
+ EXPECT_THROW(stringToCharStringData(createStringRegion("\\1a2"), chstr),
+ InvalidRdataText);
+ EXPECT_THROW(stringToCharStringData(createStringRegion("\\12a"), chstr),
+ InvalidRdataText);
+
+ // Not in the range of uint8_t
+ EXPECT_THROW(stringToCharStringData(createStringRegion("\\256"), chstr),
+ InvalidRdataText);
+
+ // Short buffer
+ EXPECT_THROW(stringToCharStringData(createStringRegion("\\42"), chstr),
+ InvalidRdataText);
+}
+
+const struct TestData {
+ const char *data;
+ const char *expected;
+} conversion_data[] = {
+ {"Test\"Test", "Test\\\"Test"},
+ {"Test;Test", "Test\\;Test"},
+ {"Test\\Test", "Test\\\\Test"},
+ {"Test\x1fTest", "Test\\031Test"},
+ {"Test ~ Test", "Test ~ Test"},
+ {"Test\x7fTest", "Test\\127Test"},
+ {NULL, NULL}
+};
+
+TEST_F(CharStringDataTest, charStringDataToString) {
+ for (const TestData* cur = conversion_data; cur->data != NULL; ++cur) {
+ uint8_t idata[32];
+ size_t length = std::strlen(cur->data);
+ ASSERT_LT(length, sizeof(idata));
+ std::memcpy(idata, cur->data, length);
+ const CharStringData test_data(idata, idata + length);
+ EXPECT_EQ(cur->expected, charStringDataToString(test_data));
+ }
+}
+
+TEST_F(CharStringDataTest, compareCharStringData) {
+ CharStringData charstr;
+ CharStringData charstr2;
+ CharStringData charstr_small1;
+ CharStringData charstr_small2;
+ CharStringData charstr_large1;
+ CharStringData charstr_large2;
+ CharStringData charstr_empty;
+
+ stringToCharStringData(createStringRegion("test string"), charstr);
+ stringToCharStringData(createStringRegion("test string"), charstr2);
+ stringToCharStringData(createStringRegion("test strin"), charstr_small1);
+ stringToCharStringData(createStringRegion("test strina"), charstr_small2);
+ stringToCharStringData(createStringRegion("test stringa"), charstr_large1);
+ stringToCharStringData(createStringRegion("test strinz"), charstr_large2);
+
+ EXPECT_EQ(0, compareCharStringDatas(charstr, charstr2));
+ EXPECT_EQ(0, compareCharStringDatas(charstr2, charstr));
+ EXPECT_EQ(1, compareCharStringDatas(charstr, charstr_small1));
+ EXPECT_EQ(1, compareCharStringDatas(charstr, charstr_small2));
+ EXPECT_EQ(-1, compareCharStringDatas(charstr, charstr_large1));
+ EXPECT_EQ(-1, compareCharStringDatas(charstr, charstr_large2));
+ EXPECT_EQ(-1, compareCharStringDatas(charstr_small1, charstr));
+ EXPECT_EQ(-1, compareCharStringDatas(charstr_small2, charstr));
+ EXPECT_EQ(1, compareCharStringDatas(charstr_large1, charstr));
+ EXPECT_EQ(1, compareCharStringDatas(charstr_large2, charstr));
+
+ EXPECT_EQ(-1, compareCharStringDatas(charstr_empty, charstr));
+ EXPECT_EQ(1, compareCharStringDatas(charstr, charstr_empty));
+ EXPECT_EQ(0, compareCharStringDatas(charstr_empty, charstr_empty));
+}
+
+} // unnamed namespace