mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 21:45:37 +00:00
[#939] Adding more unit tests
Also removing OutOfRange check from OptionOpaqueDataTuples#unpack(begin, end). Also updating AUTHORS and the ChangeLog.
This commit is contained in:
2
AUTHORS
2
AUTHORS
@@ -31,7 +31,7 @@ Primary developers:
|
||||
- Slawek Figiel (documentation)
|
||||
- Dan Theisen (documentation, option handling, shell scripts)
|
||||
- Marcin Godzina (documentation, release engineering, testing)
|
||||
- Piotrek Zadroga (documentation)
|
||||
- Piotrek Zadroga (documentation, options handling)
|
||||
|
||||
Former developers who are no longer active:
|
||||
- Stephen Morris (Hooks, MySQL)
|
||||
|
@@ -1,3 +1,8 @@
|
||||
2116. [func] piotrek
|
||||
Added support of Secure Zero Touch Provisioning options as per
|
||||
RFC8572. Kea can now handle DHCPv4 Option code #143 and DHCPv6
|
||||
Option code #136.
|
||||
|
||||
2115. [func] tmark
|
||||
Added the parameter, offer-lifetime, to kea-dhcp4. When
|
||||
greater than zero, the server temporarily allocates and
|
||||
|
@@ -55,10 +55,9 @@ OptionOpaqueDataTuples::pack(isc::util::OutputBuffer& buf, bool check) const {
|
||||
void
|
||||
OptionOpaqueDataTuples::unpack(OptionBufferConstIter begin,
|
||||
OptionBufferConstIter end) {
|
||||
if (std::distance(begin, end) < getMinimalLength() - getHeaderLen()) {
|
||||
isc_throw(OutOfRange, "parsed data tuples option data truncated to"
|
||||
" size " << std::distance(begin, end));
|
||||
}
|
||||
// We are skipping typical OutOfRange check for Option#unpack(begin, end),
|
||||
// since empty collection of tuples is also a valid case where
|
||||
// std::distance(begin, end) = 0
|
||||
|
||||
// Start reading opaque data.
|
||||
size_t offset = 0;
|
||||
|
@@ -149,13 +149,6 @@ private:
|
||||
/// @brief length of the field which holds he size of the tuple.
|
||||
OpaqueDataTuple::LengthFieldType length_field_type_;
|
||||
|
||||
/// @brief Returns minimal length of the option for the given universe.
|
||||
/// Currently this class is only used for a DHCPv6 option it may be expanded
|
||||
/// for DHCPv4 in the future.
|
||||
uint16_t getMinimalLength() const {
|
||||
return (4);
|
||||
}
|
||||
|
||||
/// @brief Collection of opaque data tuples carried by the option.
|
||||
TuplesCollection tuples_;
|
||||
|
||||
|
@@ -17,6 +17,16 @@ using namespace isc::util;
|
||||
|
||||
namespace {
|
||||
|
||||
// This test checks that the DHCPv4 option constructor sets the default
|
||||
// properties to the expected values.
|
||||
TEST(OptionOpaqueDataTuples, constructor4) {
|
||||
OptionOpaqueDataTuples data_tuple(Option::V4, 200);
|
||||
// Option length is 1 byte for option code + 1 byte for option size
|
||||
EXPECT_EQ(2, data_tuple.len());
|
||||
// There should be no tuples.
|
||||
EXPECT_EQ(0, data_tuple.getTuplesNum());
|
||||
}
|
||||
|
||||
// This test checks that the DHCPv6 option constructor sets the default
|
||||
// properties to the expected values.
|
||||
TEST(OptionOpaqueDataTuples, constructor6) {
|
||||
@@ -98,6 +108,23 @@ TEST(OptionOpaqueDataTuples, setTuple) {
|
||||
EXPECT_THROW(data_tuple.setTuple(2, tuple), isc::OutOfRange);
|
||||
}
|
||||
|
||||
// Check that the returned length of the DHCPv4 option is correct.
|
||||
TEST(OptionOpaqueDataTuples, len4) {
|
||||
OptionOpaqueDataTuples data_tuple(Option::V4, 200);
|
||||
ASSERT_EQ(2, data_tuple.len());
|
||||
// Add first tuple.
|
||||
OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_1_BYTE);
|
||||
tuple = "xyz";
|
||||
ASSERT_NO_THROW(data_tuple.addTuple(tuple));
|
||||
// The total length grows by 1 byte of the length field and 3 bytes
|
||||
// consumed by 'xyz'.
|
||||
EXPECT_EQ(6, data_tuple.len());
|
||||
// Add another tuple and check that the total size gets increased.
|
||||
tuple = "abc";
|
||||
data_tuple.addTuple(tuple);
|
||||
EXPECT_EQ(10, data_tuple.len());
|
||||
}
|
||||
|
||||
// Check that the returned length of the DHCPv4 option is correct when
|
||||
// LTF is passed explicitly in constructor.
|
||||
TEST(OptionOpaqueDataTuples, len4_constructor_with_ltf) {
|
||||
@@ -134,6 +161,71 @@ TEST(OptionOpaqueDataTuples, len6) {
|
||||
EXPECT_EQ(14, data_tuple.len());
|
||||
}
|
||||
|
||||
// Check that the DHCPv4 option is rendered to the buffer in wire format.
|
||||
TEST(OptionOpaqueDataTuples, pack4) {
|
||||
OptionOpaqueDataTuples data_tuple(Option::V4, 200);
|
||||
ASSERT_EQ(0, data_tuple.getTuplesNum());
|
||||
// Add tuple.
|
||||
OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_1_BYTE);
|
||||
tuple = "Hello world";
|
||||
data_tuple.addTuple(tuple);
|
||||
// And add another tuple so as resulting option is a bit more complex.
|
||||
tuple = "foo";
|
||||
data_tuple.addTuple(tuple);
|
||||
|
||||
// Render the data to the buffer.
|
||||
OutputBuffer buf(10);
|
||||
ASSERT_NO_THROW(data_tuple.pack(buf));
|
||||
ASSERT_EQ(18, buf.getLength());
|
||||
|
||||
// Prepare reference data.
|
||||
const uint8_t ref[] = {
|
||||
0xC8, 0x10, // option 200, length 16
|
||||
0x0B, // tuple length is 11
|
||||
0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, // Hello<space>
|
||||
0x77, 0x6F, 0x72, 0x6C, 0x64, // world
|
||||
0x03, // tuple length is 3
|
||||
0x66, 0x6F, 0x6F // foo
|
||||
};
|
||||
// Compare the buffer with reference data.
|
||||
EXPECT_EQ(0, memcmp(static_cast<const void*>(ref),
|
||||
static_cast<const void*>(buf.getData()),
|
||||
buf.getLength()));
|
||||
}
|
||||
|
||||
// Check that the DHCPv4 option is rendered to the buffer in wire format,
|
||||
// when tuple's length field is coded on 2 octets.
|
||||
TEST(OptionOpaqueDataTuples, pack4_with_ltf) {
|
||||
OptionOpaqueDataTuples data_tuple(Option::V4, 143, OpaqueDataTuple::LENGTH_2_BYTES);
|
||||
ASSERT_EQ(0, data_tuple.getTuplesNum());
|
||||
// Add tuple.
|
||||
OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
|
||||
tuple = "Hello world";
|
||||
data_tuple.addTuple(tuple);
|
||||
// And add another tuple so as resulting option is a bit more complex.
|
||||
tuple = "foo";
|
||||
data_tuple.addTuple(tuple);
|
||||
|
||||
// Render the data to the buffer.
|
||||
OutputBuffer buf(10);
|
||||
ASSERT_NO_THROW(data_tuple.pack(buf));
|
||||
ASSERT_EQ(20, buf.getLength());
|
||||
|
||||
// Prepare reference data.
|
||||
const uint8_t ref[] = {
|
||||
0x8F, 0x12, // option 143, length 18
|
||||
0x00, 0x0B, // tuple length is 11
|
||||
0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, // Hello<space>
|
||||
0x77, 0x6F, 0x72, 0x6C, 0x64, // world
|
||||
0x00, 0x03, // tuple length is 3
|
||||
0x66, 0x6F, 0x6F // foo
|
||||
};
|
||||
// Compare the buffer with reference data.
|
||||
EXPECT_EQ(0, memcmp(static_cast<const void*>(ref),
|
||||
static_cast<const void*>(buf.getData()),
|
||||
buf.getLength()));
|
||||
}
|
||||
|
||||
// Check that the DHCPv6 option is rendered to the buffer in wire format.
|
||||
TEST(OptionOpaqueDataTuples, pack6) {
|
||||
OptionOpaqueDataTuples data_tuple(Option::V6, 60);
|
||||
@@ -166,6 +258,33 @@ TEST(OptionOpaqueDataTuples, pack6) {
|
||||
buf.getLength()));
|
||||
}
|
||||
|
||||
// This function checks that the DHCPv4 option with two opaque data tuples
|
||||
// is parsed correctly.
|
||||
TEST(OptionOpaqueDataTuples, unpack4) {
|
||||
// Prepare data to decode.
|
||||
const uint8_t buf_data[] = {
|
||||
0x0B, // tuple length is 11
|
||||
0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, // Hello<space>
|
||||
0x77, 0x6F, 0x72, 0x6C, 0x64, // world
|
||||
0x03, // tuple length is 3
|
||||
0x66, 0x6F, 0x6F // foo
|
||||
};
|
||||
OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
|
||||
|
||||
OptionOpaqueDataTuplesPtr data_tuple;
|
||||
ASSERT_NO_THROW(
|
||||
data_tuple = OptionOpaqueDataTuplesPtr(
|
||||
new OptionOpaqueDataTuples(Option::V4,
|
||||
143,
|
||||
buf.begin(),
|
||||
buf.end()));
|
||||
);
|
||||
EXPECT_EQ(DHO_V4_SZTP_REDIRECT, data_tuple->getType());
|
||||
ASSERT_EQ(2, data_tuple->getTuplesNum());
|
||||
EXPECT_EQ("Hello world", data_tuple->getTuple(0).getText());
|
||||
EXPECT_EQ("foo", data_tuple->getTuple(1).getText());
|
||||
}
|
||||
|
||||
// This function checks that the DHCPv4 option with two opaque data tuples
|
||||
// is parsed correctly. Tuple's LTF is passed explicitly in constructor.
|
||||
TEST(OptionOpaqueDataTuples, unpack4_constructor_with_ltf) {
|
||||
@@ -220,6 +339,46 @@ TEST(OptionOpaqueDataTuples, unpack6) {
|
||||
EXPECT_EQ("foo", data_tuple->getTuple(1).getText());
|
||||
}
|
||||
|
||||
// This test checks that the DHCPv4 option with opaque data of size 0
|
||||
// is correctly parsed.
|
||||
TEST(OptionOpaqueDataTuples, unpack4EmptyTuple) {
|
||||
// Prepare data to decode.
|
||||
const uint8_t buf_data[] = {0x00}; // tuple length is 0
|
||||
OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
|
||||
|
||||
OptionOpaqueDataTuplesPtr data_tuple;
|
||||
ASSERT_NO_THROW(
|
||||
data_tuple = OptionOpaqueDataTuplesPtr(new OptionOpaqueDataTuples(Option::V4,
|
||||
124,
|
||||
buf.begin(),
|
||||
buf.end()));
|
||||
);
|
||||
EXPECT_EQ(DHO_VIVCO_SUBOPTIONS, data_tuple->getType());
|
||||
ASSERT_EQ(1, data_tuple->getTuplesNum());
|
||||
EXPECT_TRUE(data_tuple->getTuple(0).getText().empty());
|
||||
}
|
||||
|
||||
// This test checks that the DHCPv4 option with opaque data of size 0
|
||||
// is correctly parsed. Tuple's LTF is passed explicitly in constructor.
|
||||
TEST(OptionOpaqueDataTuples, unpack4EmptyTuple_constructor_with_ltf) {
|
||||
// Prepare data to decode.
|
||||
const uint8_t buf_data[] = {0x00, 0x00}; // tuple length is 0
|
||||
OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
|
||||
|
||||
OptionOpaqueDataTuplesPtr data_tuple;
|
||||
ASSERT_NO_THROW(
|
||||
data_tuple = OptionOpaqueDataTuplesPtr(
|
||||
new OptionOpaqueDataTuples(Option::V4,
|
||||
143,
|
||||
buf.begin(),
|
||||
buf.end(),
|
||||
OpaqueDataTuple::LENGTH_2_BYTES));
|
||||
);
|
||||
EXPECT_EQ(DHO_V4_SZTP_REDIRECT, data_tuple->getType());
|
||||
ASSERT_EQ(1, data_tuple->getTuplesNum());
|
||||
EXPECT_TRUE(data_tuple->getTuple(0).getText().empty());
|
||||
}
|
||||
|
||||
// This test checks that the DHCPv6 option with opaque data of size 0
|
||||
// is correctly parsed.
|
||||
TEST(OptionOpaqueDataTuples, unpack6EmptyTuple) {
|
||||
@@ -239,6 +398,39 @@ TEST(OptionOpaqueDataTuples, unpack6EmptyTuple) {
|
||||
EXPECT_TRUE(data_tuple->getTuple(0).getText().empty());
|
||||
}
|
||||
|
||||
// This test checks that exception is thrown when parsing truncated DHCPv4 option
|
||||
TEST(OptionOpaqueDataTuples, unpack4Truncated) {
|
||||
// Prepare data to decode.
|
||||
const uint8_t buf_data[] = {
|
||||
0x0B, // tuple length is 11
|
||||
0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, // Hello<space>
|
||||
0x77, 0x6F, 0x72, 0x6C // worl (truncated d!)
|
||||
};
|
||||
OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
|
||||
|
||||
EXPECT_THROW(OptionOpaqueDataTuples (Option::V4, 200, buf.begin(), buf.end()),
|
||||
isc::dhcp::OpaqueDataTupleError);
|
||||
}
|
||||
|
||||
// This test checks that exception is thrown when parsing truncated DHCPv4 option,
|
||||
// when tuple's length field is coded on 2 octets.
|
||||
TEST(OptionOpaqueDataTuples, unpack4Truncated_with_ltf) {
|
||||
// Prepare data to decode.
|
||||
const uint8_t buf_data[] = {
|
||||
0x00, 0x0B, // tuple length is 11
|
||||
0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, // Hello<space>
|
||||
0x77, 0x6F, 0x72, 0x6C // worl (truncated d!)
|
||||
};
|
||||
OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
|
||||
|
||||
EXPECT_THROW(OptionOpaqueDataTuples (Option::V4,
|
||||
143,
|
||||
buf.begin(),
|
||||
buf.end(),
|
||||
OpaqueDataTuple::LENGTH_2_BYTES),
|
||||
isc::dhcp::OpaqueDataTupleError);
|
||||
}
|
||||
|
||||
// This test checks that exception is thrown when parsing truncated DHCPv6
|
||||
// bootfile-param option
|
||||
TEST(OptionOpaqueDataTuples, unpack6Truncated) {
|
||||
@@ -254,6 +446,27 @@ TEST(OptionOpaqueDataTuples, unpack6Truncated) {
|
||||
isc::dhcp::OpaqueDataTupleError);
|
||||
}
|
||||
|
||||
// This test checks that the DHCPv4 option containing no opaque
|
||||
// data is parsed correctly.
|
||||
TEST(OptionOpaqueDataTuples, unpack4NoTuple) {
|
||||
// Prepare data to decode.
|
||||
const uint8_t buf_data[] = {
|
||||
};
|
||||
OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
|
||||
|
||||
OptionOpaqueDataTuplesPtr data_tuple;
|
||||
ASSERT_NO_THROW(
|
||||
data_tuple = OptionOpaqueDataTuplesPtr(
|
||||
new OptionOpaqueDataTuples(Option::V4,
|
||||
143,
|
||||
buf.begin(),
|
||||
buf.end(),
|
||||
OpaqueDataTuple::LENGTH_2_BYTES));
|
||||
);
|
||||
EXPECT_EQ(DHO_V4_SZTP_REDIRECT, data_tuple->getType());
|
||||
EXPECT_EQ(0, data_tuple->getTuplesNum());
|
||||
}
|
||||
|
||||
// This test checks that the DHCPv6 bootfile-param option containing no opaque
|
||||
// data is parsed correctly.
|
||||
TEST(OptionOpaqueDataTuples, unpack6NoTuple) {
|
||||
@@ -273,6 +486,30 @@ TEST(OptionOpaqueDataTuples, unpack6NoTuple) {
|
||||
EXPECT_EQ(0, data_tuple->getTuplesNum());
|
||||
}
|
||||
|
||||
// Verifies correctness of the text representation of the DHCPv4 option.
|
||||
TEST(OptionOpaqueDataTuples, toText4) {
|
||||
OptionOpaqueDataTuples data_tuple(Option::V4, 143, OpaqueDataTuple::LENGTH_2_BYTES);
|
||||
ASSERT_EQ(0, data_tuple.getTuplesNum());
|
||||
// Lets add a tuple
|
||||
OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
|
||||
tuple = "Hello world";
|
||||
data_tuple.addTuple(tuple);
|
||||
// And add another tuple so as resulting option is a bit more complex.
|
||||
tuple = "foo";
|
||||
data_tuple.addTuple(tuple);
|
||||
// Check that the text representation of the option is as expected.
|
||||
EXPECT_EQ("type=143, len=18,"
|
||||
" data-len0=11, data0='Hello world',"
|
||||
" data-len1=3, data1='foo'",
|
||||
data_tuple.toText());
|
||||
|
||||
// Check that indentation works.
|
||||
EXPECT_EQ(" type=143, len=18,"
|
||||
" data-len0=11, data0='Hello world',"
|
||||
" data-len1=3, data1='foo'",
|
||||
data_tuple.toText(2));
|
||||
}
|
||||
|
||||
// Verifies correctness of the text representation of the DHCPv6 option.
|
||||
TEST(OptionOpaqueDataTuples, toText6) {
|
||||
OptionOpaqueDataTuples data_tuple(Option::V6, 60);
|
||||
|
Reference in New Issue
Block a user