messagerenderer_unittest.cc 6.77 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

// $Id$

#include <vector>

19 20 21
#include <dns/buffer.h>
#include <dns/name.h>
#include <dns/messagerenderer.h>
22

23
#include <dns/tests/unittest_util.h>
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51

#include <gtest/gtest.h>

using isc::UnitTestUtil;
using isc::dns::OutputBuffer;
using isc::dns::Name;
using isc::dns::MessageRenderer;

namespace {
class MessageRendererTest : public ::testing::Test {
protected:
    MessageRendererTest() : expected_size(0), buffer(0), renderer(buffer)
    {
        data16 = (2 << 8) | 3;
        data32 = (4 << 24) | (5 << 16) | (6 << 8) | 7;
    }
    size_t expected_size;
    uint16_t data16;
    uint32_t data32;
    OutputBuffer buffer;
    MessageRenderer renderer;
    std::vector<unsigned char> data;
    static const uint8_t testdata[5];
};

const uint8_t MessageRendererTest::testdata[5] = {1, 2, 3, 4, 5};

// The test cases are borrowed from those for the OutputBuffer class.
52
TEST_F(MessageRendererTest, writeIntger) {
53 54 55 56 57 58 59
    renderer.writeUint16(data16);
    expected_size += sizeof(data16);

    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
                        renderer.getLength(), &testdata[1], sizeof(data16));
}

60
TEST_F(MessageRendererTest, writeName) {
61
    UnitTestUtil::readWireData("name_toWire1", data);
62 63 64 65 66 67 68
    renderer.writeName(Name("a.example.com."));
    renderer.writeName(Name("b.example.com."));
    renderer.writeName(Name("a.example.org."));
    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
                        buffer.getLength(), &data[0], data.size());
}

69
TEST_F(MessageRendererTest, writeNameInLargeBuffer) {
70 71 72
    size_t offset = 0x3fff;
    buffer.skip(offset);

73
    UnitTestUtil::readWireData("name_toWire2", data);
74 75 76 77 78 79 80 81 82
    renderer.writeName(Name("a.example.com."));
    renderer.writeName(Name("a.example.com."));
    renderer.writeName(Name("b.example.com."));
    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                        static_cast<const uint8_t*>(buffer.getData()) + offset,
                        buffer.getLength() - offset,
                        &data[0], data.size());
}

83
TEST_F(MessageRendererTest, writeNameWithUncompressed) {
84
    UnitTestUtil::readWireData("name_toWire3", data);
85 86 87 88 89 90 91
    renderer.writeName(Name("a.example.com."));
    renderer.writeName(Name("b.example.com."), false);
    renderer.writeName(Name("b.example.com."));
    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
                        buffer.getLength(), &data[0], data.size());
}

92
TEST_F(MessageRendererTest, writeNamePointerChain) {
93
    UnitTestUtil::readWireData("name_toWire4", data);
94 95 96 97 98 99 100
    renderer.writeName(Name("a.example.com."));
    renderer.writeName(Name("b.example.com."));
    renderer.writeName(Name("b.example.com."));
    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
                        buffer.getLength(), &data[0], data.size());
}

101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
TEST_F(MessageRendererTest, compressMode) {
    // By default the render performs case insensitive compression.
    EXPECT_EQ(MessageRenderer::CASE_INSENSITIVE, renderer.getCompressMode());

    // The mode can be explicitly changed.
    renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE);
    EXPECT_EQ(MessageRenderer::CASE_SENSITIVE, renderer.getCompressMode());
    renderer.setCompressMode(MessageRenderer::CASE_INSENSITIVE);
    EXPECT_EQ(MessageRenderer::CASE_INSENSITIVE, renderer.getCompressMode());

    // The clear() method resets the mode to the default.
    renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE);
    renderer.clear();
    EXPECT_EQ(MessageRenderer::CASE_INSENSITIVE, renderer.getCompressMode());
}

117
TEST_F(MessageRendererTest, writeNameCaseCompress) {
118 119
    // By default MessageRenderer performs case insensitive compression.

120
    UnitTestUtil::readWireData("name_toWire1", data);
121 122 123 124 125 126 127
    renderer.writeName(Name("a.example.com."));
    // this should match the first name in terms of compression:
    renderer.writeName(Name("b.exAmple.CoM."));
    renderer.writeName(Name("a.example.org."));
    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
                        buffer.getLength(), &data[0], data.size());
}
128

129 130 131 132
TEST_F(MessageRendererTest, writeNameCaseSensitiveCompress) {
    // name compression in case sensitive manner.  See the data file
    // description for details.
    renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE);
133
    UnitTestUtil::readWireData("name_toWire5", data);
134 135 136 137 138 139 140 141 142
    renderer.writeName(Name("a.example.com."));
    renderer.writeName(Name("b.eXample.com."));
    renderer.writeName(Name("c.eXample.com."));
    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
                        buffer.getLength(), &data[0], data.size());
}

TEST_F(MessageRendererTest, writeNameMixedCaseCompress) {
    renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE);
143
    UnitTestUtil::readWireData("name_toWire6", data);
144 145 146 147 148 149 150 151 152 153 154 155
    renderer.writeName(Name("a.example.com."));
    renderer.writeName(Name("b.eXample.com."));

    // Change the compression mode in the middle of rendering.  This is an
    // unusual operation and is unlikely to happen in practice, but is still
    // allowed in this API.
    renderer.setCompressMode(MessageRenderer::CASE_INSENSITIVE);
    renderer.writeName(Name("c.b.EXAMPLE.com."));
    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
                        buffer.getLength(), &data[0], data.size());
}

156
TEST_F(MessageRendererTest, writeRootName) {
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
    // root name is special: it never causes compression or can (reasonably)
    // be a compression pointer.  So it makes sense to check this case
    // explicitly.
    Name example_name = Name("www.example.com");

    OutputBuffer expected(0);
    expected.writeUint8(0);     // root name
    example_name.toWire(expected);

    renderer.writeName(Name("."));
    renderer.writeName(example_name);
    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                        static_cast<const uint8_t*>(buffer.getData()),
                        buffer.getLength(),
                        static_cast<const uint8_t*>(expected.getData()),
                        expected.getLength());
}
174
}