rdata_minfo_unittest.cc 8.44 KB
Newer Older
1
// Copyright (C) 2011-2013  Internet Systems Consortium, Inc. ("ISC")
2
//
3
// Permission to use, copy, modify, and/or distribute this software for any
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 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.

#include <util/buffer.h>
#include <dns/exceptions.h>
#include <dns/messagerenderer.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>

#include <gtest/gtest.h>

#include <dns/tests/unittest_util.h>
#include <dns/tests/rdata_unittest.h>

using isc::UnitTestUtil;
using namespace std;
using namespace isc::util;
31
using namespace isc::dns;
32
33
34
using namespace isc::dns::rdata;

// minfo text
35
const char* const minfo_txt = "rmailbox.example.com. emailbox.example.com.";
36
const char* const minfo_txt2 = "root.example.com. emailbox.example.com.";
37
const char* const too_long_label = "01234567890123456789012345678901234567"
38
                                   "89012345678901234567890123.";
39

40
41
namespace {
class Rdata_MINFO_Test : public RdataTest {
Paul Selkirk's avatar
Paul Selkirk committed
42
protected:
43
44
45
    Rdata_MINFO_Test():
        rdata_minfo(string(minfo_txt)), rdata_minfo2(string(minfo_txt2)) {}

Paul Selkirk's avatar
Paul Selkirk committed
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    void checkFromText_None(const string& rdata_str) {
        checkFromText<generic::MINFO, isc::Exception, isc::Exception>(
            rdata_str, rdata_minfo, false, false);
    }

    void checkFromText_LexerError(const string& rdata_str) {
        checkFromText
            <generic::MINFO, InvalidRdataText, MasterLexer::LexerError>(
                rdata_str, rdata_minfo, true, true);
    }

    void checkFromText_TooLongLabel(const string& rdata_str) {
        checkFromText<generic::MINFO, TooLongLabel, TooLongLabel>(
            rdata_str, rdata_minfo, true, true);
    }

62
63
64
65
    const generic::MINFO rdata_minfo;
    const generic::MINFO rdata_minfo2;
};

66
67

TEST_F(Rdata_MINFO_Test, createFromText) {
68
69
    EXPECT_EQ(Name("rmailbox.example.com."), rdata_minfo.getRmailbox());
    EXPECT_EQ(Name("emailbox.example.com."), rdata_minfo.getEmailbox());
70
71
72

    EXPECT_EQ(Name("root.example.com."), rdata_minfo2.getRmailbox());
    EXPECT_EQ(Name("emailbox.example.com."), rdata_minfo2.getEmailbox());
Paul Selkirk's avatar
Paul Selkirk committed
73
74

    checkFromText_None(minfo_txt);
75
76
77
78
}

TEST_F(Rdata_MINFO_Test, badText) {
    // incomplete text
Paul Selkirk's avatar
Paul Selkirk committed
79
    checkFromText_LexerError("root.example.com.");
80
    // number of fields (must be 2) is incorrect
81
    EXPECT_THROW(generic::MINFO("root.example.com. emailbox.example.com. "
82
83
84
                                "example.com."),
                 InvalidRdataText);
    // bad rmailbox name
Paul Selkirk's avatar
Paul Selkirk committed
85
86
    checkFromText_TooLongLabel("root.example.com. emailbox.example.com." +
                               string(too_long_label));
87
    // bad emailbox name
Paul Selkirk's avatar
Paul Selkirk committed
88
89
    checkFromText_TooLongLabel("root.example.com."  + string(too_long_label) +
                               " emailbox.example.com.");
90
91
92
}

TEST_F(Rdata_MINFO_Test, createFromWire) {
93
    // uncompressed names
94
    EXPECT_EQ(0, rdata_minfo.compare(
95
                  *rdataFactoryFromFile(RRType::MINFO(), RRClass::IN(),
96
97
                                     "rdata_minfo_fromWire1.wire")));
    // compressed names
98
    EXPECT_EQ(0, rdata_minfo.compare(
99
100
                  *rdataFactoryFromFile(RRType::MINFO(), RRClass::IN(),
                                     "rdata_minfo_fromWire2.wire", 15)));
101
    // RDLENGTH is too short
102
    EXPECT_THROW(rdataFactoryFromFile(RRType::MINFO(), RRClass::IN(),
103
                                     "rdata_minfo_fromWire3.wire"),
104
105
                 InvalidRdataLength);
    // RDLENGTH is too long
106
    EXPECT_THROW(rdataFactoryFromFile(RRType::MINFO(), RRClass::IN(),
107
                                      "rdata_minfo_fromWire4.wire"),
108
                 InvalidRdataLength);
109
110
111
112
113
114
115
116
117
    // bogus rmailbox name, the error should be detected in the name
    // constructor
    EXPECT_THROW(rdataFactoryFromFile(RRType::MINFO(), RRClass::IN(),
                                      "rdata_minfo_fromWire5.wire"),
                 DNSMessageFORMERR);
    // bogus emailbox name, the error should be detected in the name
    // constructor
    EXPECT_THROW(rdataFactoryFromFile(RRType::MINFO(), RRClass::IN(),
                                      "rdata_minfo_fromWire6.wire"),
118
119
120
                 DNSMessageFORMERR);
}

121
122
123
124
TEST_F(Rdata_MINFO_Test, createFromLexer) {
    EXPECT_EQ(0, rdata_minfo.compare(
        *test::createRdataUsingLexer(RRType::MINFO(), RRClass::IN(),
                                     minfo_txt)));
Paul Selkirk's avatar
Paul Selkirk committed
125
126
127
128
129
130
131
132
133

    // test::createRdataUsingLexer() constructs relative to
    // "example.org." origin.
    EXPECT_EQ(0, generic::MINFO("r.example.org. e.example.org.").compare(
        *test::createRdataUsingLexer(RRType::MINFO(), RRClass::IN(), "r e")));

    // Extra text at end of line
    EXPECT_FALSE(test::createRdataUsingLexer(RRType::MINFO(), RRClass::IN(),
             "rmailbox.example.com. emailbox.example.com. extra.example.com."));
134
135
}

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
TEST_F(Rdata_MINFO_Test, assignment) {
    generic::MINFO copy((string(minfo_txt2)));
    copy = rdata_minfo;
    EXPECT_EQ(0, copy.compare(rdata_minfo));

    // Check if the copied data is valid even after the original is deleted
    generic::MINFO* copy2 = new generic::MINFO(rdata_minfo);
    generic::MINFO copy3((string(minfo_txt2)));
    copy3 = *copy2;
    delete copy2;
    EXPECT_EQ(0, copy3.compare(rdata_minfo));

    // Self assignment
    copy = copy;
    EXPECT_EQ(0, copy.compare(rdata_minfo));
}

153
154
TEST_F(Rdata_MINFO_Test, toWireBuffer) {
    rdata_minfo.toWire(obuffer);
155
    vector<unsigned char> data;
156
    UnitTestUtil::readWireData("rdata_minfo_toWireUncompressed1.wire", data);
157
    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
158
159
160
161
162
163
164
165
166
167
                        static_cast<const uint8_t *>(obuffer.getData()),
                        obuffer.getLength(), &data[0], data.size());

    obuffer.clear();
    rdata_minfo2.toWire(obuffer);
    vector<unsigned char> data2;
    UnitTestUtil::readWireData("rdata_minfo_toWireUncompressed2.wire", data2);
    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                        static_cast<const uint8_t *>(obuffer.getData()),
                        obuffer.getLength(), &data2[0], data2.size());
168
169
170
171
}

TEST_F(Rdata_MINFO_Test, toWireRenderer) {
    rdata_minfo.toWire(renderer);
172
    vector<unsigned char> data;
173
174
    UnitTestUtil::readWireData("rdata_minfo_toWire1.wire", data);
    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
175
176
                        static_cast<const uint8_t *>(renderer.getData()),
                        renderer.getLength(), &data[0], data.size());
177
178
179
180
    renderer.clear();
    rdata_minfo2.toWire(renderer);
    vector<unsigned char> data2;
    UnitTestUtil::readWireData("rdata_minfo_toWire2.wire", data2);
181
    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
182
183
                        static_cast<const uint8_t *>(renderer.getData()),
                        renderer.getLength(), &data2[0], data2.size());
184
185
186
187
}

TEST_F(Rdata_MINFO_Test, toText) {
    EXPECT_EQ(minfo_txt, rdata_minfo.toText());
188
    EXPECT_EQ(minfo_txt2, rdata_minfo2.toText());
189
190
191
192
193
194
195
}

TEST_F(Rdata_MINFO_Test, compare) {
    // check reflexivity
    EXPECT_EQ(0, rdata_minfo.compare(rdata_minfo));

    // names must be compared in case-insensitive manner
196
197
    EXPECT_EQ(0, rdata_minfo.compare(generic::MINFO("RMAILBOX.example.com. "
                                                  "emailbox.EXAMPLE.com.")));
198
199

    // another MINFO whose rmailbox name is larger than that of rdata_minfo.
200
    const generic::MINFO large1_minfo("zzzzzzzz.example.com. "
201
202
203
204
205
                                      "emailbox.example.com.");
    EXPECT_GT(0, rdata_minfo.compare(large1_minfo));
    EXPECT_LT(0, large1_minfo.compare(rdata_minfo));

    // another MINFO whose emailbox name is larger than that of rdata_minfo.
206
207
    const generic::MINFO large2_minfo("rmailbox.example.com. "
                                      "zzzzzzzzzzz.example.com.");
208
209
210
211
212
213
214
    EXPECT_GT(0, rdata_minfo.compare(large2_minfo));
    EXPECT_LT(0, large2_minfo.compare(rdata_minfo));

    // comparison attempt between incompatible RR types should be rejected
    EXPECT_THROW(rdata_minfo.compare(*RdataTest::rdata_nomatch), bad_cast);
}
}