Commit ac111116 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[2491] Test that appropriate std options are returned.

parent 84e441c7
......@@ -356,7 +356,7 @@ LibDHCP::initStdOptionDefs6() {
case D6O_GEOCONF_CIVIC:
definition->addRecordField(OPT_UINT8_TYPE);
definition->addRecordField(OPT_UINT16_TYPE);
definition->addRecordField(OPT_STRING_TYPE);
definition->addRecordField(OPT_BINARY_TYPE);
break;
case D6O_REMOTE_ID:
definition->addRecordField(OPT_UINT32_TYPE);
......
......@@ -19,6 +19,7 @@
#include <dhcp/option6_iaaddr.h>
#include <dhcp/option6_int.h>
#include <dhcp/option6_int_array.h>
#include <dhcp/option_custom.h>
#include <dhcp/option_definition.h>
#include <util/encode/hex.h>
......@@ -78,53 +79,64 @@ OptionDefinition::optionFactory(Option::Universe u, uint16_t type,
OptionBufferConstIter begin,
OptionBufferConstIter end) const {
validate();
try {
if (type_ == OPT_BINARY_TYPE) {
switch(type_) {
case OPT_EMPTY_TYPE:
return (factoryEmpty(u, type));
case OPT_BINARY_TYPE:
return (factoryGeneric(u, type, begin, end));
} else if (type_ == OPT_IPV6_ADDRESS_TYPE && array_type_) {
return (factoryAddrList6(type, begin, end));
case OPT_UINT8_TYPE:
return (array_type_ ? factoryGeneric(u, type, begin, end) :
factoryInteger<uint8_t>(u, type, begin, end));;
} else if (type_ == OPT_IPV4_ADDRESS_TYPE && array_type_) {
return (factoryAddrList4(type, begin, end));
case OPT_INT8_TYPE:
return (array_type_ ? factoryGeneric(u, type, begin, end) :
factoryInteger<int8_t>(u, type, begin, end));
} else if (type_ == OPT_EMPTY_TYPE) {
return (factoryEmpty(u, type));
case OPT_UINT16_TYPE:
return (array_type_ ? factoryIntegerArray<uint16_t>(type, begin, end) :
factoryInteger<uint16_t>(u, type, begin, end));
} else if (u == Option::V6 &&
code_ == D6O_IA_NA &&
haveIA6Format()) {
return (factoryIA6(type, begin, end));
case OPT_INT16_TYPE:
return (array_type_ ? factoryIntegerArray<uint16_t>(type, begin, end) :
factoryInteger<int16_t>(u, type, begin, end));
} else if (u == Option::V6 &&
code_ == D6O_IAADDR &&
haveIAAddr6Format()) {
return (factoryIAAddr6(type, begin, end));
case OPT_UINT32_TYPE:
return (array_type_ ? factoryIntegerArray<uint32_t>(type, begin, end) :
factoryInteger<uint32_t>(u, type, begin, end));
} else if (type_ == OPT_UINT8_TYPE) {
if (array_type_) {
return (factoryGeneric(u, type, begin, end));
} else {
return (factoryInteger<uint8_t>(u, type, begin, end));
}
case OPT_INT32_TYPE:
return (array_type_ ? factoryIntegerArray<uint32_t>(type, begin, end) :
factoryInteger<int32_t>(u, type, begin, end));
} else if (type_ == OPT_UINT16_TYPE) {
case OPT_IPV4_ADDRESS_TYPE:
if (array_type_) {
return (factoryIntegerArray<uint16_t>(type, begin, end));
} else {
return (factoryInteger<uint16_t>(u, type, begin, end));
return (factoryAddrList4(type, begin, end));
}
break;
} else if (type_ == OPT_UINT32_TYPE) {
case OPT_IPV6_ADDRESS_TYPE:
if (array_type_) {
return (factoryIntegerArray<uint32_t>(type, begin, end));
} else {
return (factoryInteger<uint32_t>(u, type, begin, end));
return (factoryAddrList6(type, begin, end));
}
break;
default:
if (u == Option::V6 &&
(code_ == D6O_IA_NA || code_ == D6O_IA_PD) &&
haveIA6Format()) {
return (factoryIA6(type, begin, end));
} else if (u == Option::V6 &&
code_ == D6O_IAADDR &&
haveIAAddr6Format()) {
return (factoryIAAddr6(type, begin, end));
}
}
return (factoryGeneric(u, type, begin, end));
return (OptionPtr(new OptionCustom(*this, u, begin, end)));
} catch (const Exception& ex) {
isc_throw(InvalidOptionValue, ex.what());
......
......@@ -22,6 +22,7 @@
#include <dhcp/option6_iaaddr.h>
#include <dhcp/option6_int.h>
#include <dhcp/option6_int_array.h>
#include <dhcp/option_custom.h>
#include <util/buffer.h>
#include <gtest/gtest.h>
......@@ -90,13 +91,15 @@ public:
ASSERT_NO_THROW(def->validate());
OptionPtr option;
// Create the option.
ASSERT_NO_THROW(option = def->optionFactory(Option::V6, code, buf));
ASSERT_NO_THROW(option = def->optionFactory(Option::V6, code, buf))
<< "Option creation failed to option code " << code;
// Make sure it is not NULL.
ASSERT_TRUE(option);
// And the actual object type is the one that we expect.
// Note that for many options there are dedicated classes
// derived from Option class to represent them.
EXPECT_TRUE(typeid(*option) == expected_type);
EXPECT_TRUE(typeid(*option) == expected_type)
<< "Invalid class returned for option code " << code;
}
};
......@@ -399,29 +402,148 @@ TEST_F(LibDhcpTest, unpackOptions4) {
// This test have to be extended once all option definitions are
// created.
TEST_F(LibDhcpTest, stdOptionDefs6) {
LibDhcpTest::testStdOptionDefs6(D6O_CLIENTID, OptionBuffer(14, 1),
typeid(Option));
LibDhcpTest::testStdOptionDefs6(D6O_SERVERID, OptionBuffer(14, 1),
typeid(Option));
LibDhcpTest::testStdOptionDefs6(D6O_IA_NA, OptionBuffer(12, 1),
typeid(Option6IA));
LibDhcpTest::testStdOptionDefs6(D6O_IA_TA, OptionBuffer(4, 1),
// Create a buffer that holds dummy option data.
// It will be used to create most of the options.
std::vector<uint8_t> buf(48, 1);
// Prepare buffer holding an array of FQDNs.
const char data[] = {
8, 109, 121, 100, 111, 109, 97, 105, 110, // "mydomain"
7, 101, 120, 97, 109, 112, 108, 101, // "example"
3, 99, 111, 109, // "com"
0,
7, 101, 120, 97, 109, 112, 108, 101, // "example"
3, 99, 111, 109, // "com"
0
};
// Initialize a vector with the FQDN data.
std::vector<uint8_t> fqdn_buf(data, data + sizeof(data));
// The CLIENT_FQDN holds a uint8_t value and FQDN. We have
// to add the uint8_t value to it and then append the buffer
// holding some valid FQDN.
std::vector<uint8_t> client_fqdn_buf(1);
client_fqdn_buf.insert(client_fqdn_buf.end(), fqdn_buf.begin(),
fqdn_buf.end());
// The actual test starts here for all supported option codes.
LibDhcpTest::testStdOptionDefs6(D6O_CLIENTID, buf, typeid(Option));
LibDhcpTest::testStdOptionDefs6(D6O_SERVERID, buf, typeid(Option));
LibDhcpTest::testStdOptionDefs6(D6O_IA_NA, buf, typeid(Option6IA));
LibDhcpTest::testStdOptionDefs6(D6O_IA_TA, buf,
typeid(Option6Int<uint32_t>));
LibDhcpTest::testStdOptionDefs6(D6O_IAADDR, OptionBuffer(24, 1),
typeid(Option6IAAddr));
LibDhcpTest::testStdOptionDefs6(D6O_ORO, OptionBuffer(10, 1),
LibDhcpTest::testStdOptionDefs6(D6O_IAADDR, buf, typeid(Option6IAAddr));
LibDhcpTest::testStdOptionDefs6(D6O_ORO, buf,
typeid(Option6IntArray<uint16_t>));
LibDhcpTest::testStdOptionDefs6(D6O_PREFERENCE, OptionBuffer(1, 1),
LibDhcpTest::testStdOptionDefs6(D6O_PREFERENCE, buf,
typeid(Option6Int<uint8_t>));
LibDhcpTest::testStdOptionDefs6(D6O_ELAPSED_TIME, OptionBuffer(2, 1),
LibDhcpTest::testStdOptionDefs6(D6O_ELAPSED_TIME, buf,
typeid(Option6Int<uint16_t>));
LibDhcpTest::testStdOptionDefs6(D6O_RELAY_MSG, OptionBuffer(30, 1),
typeid(Option));
LibDhcpTest::testStdOptionDefs6(D6O_STATUS_CODE, OptionBuffer(10, 1),
typeid(Option));
LibDhcpTest::testStdOptionDefs6(D6O_RAPID_COMMIT, OptionBuffer(),
typeid(Option));
LibDhcpTest::testStdOptionDefs6(D6O_NAME_SERVERS, OptionBuffer(32, 1),
LibDhcpTest::testStdOptionDefs6(D6O_RELAY_MSG, buf, typeid(Option));
LibDhcpTest::testStdOptionDefs6(D6O_STATUS_CODE, buf, typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_RAPID_COMMIT, buf, typeid(Option));
LibDhcpTest::testStdOptionDefs6(D6O_USER_CLASS, buf, typeid(Option));
LibDhcpTest::testStdOptionDefs6(D6O_VENDOR_CLASS, buf,
typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_VENDOR_OPTS, buf, typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_INTERFACE_ID, buf, typeid(Option));
LibDhcpTest::testStdOptionDefs6(D6O_RECONF_MSG, buf,
typeid(Option6Int<uint8_t>));
LibDhcpTest::testStdOptionDefs6(D6O_RECONF_ACCEPT, buf, typeid(Option));
LibDhcpTest::testStdOptionDefs6(D6O_SIP_SERVERS_DNS, fqdn_buf,
typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_SIP_SERVERS_ADDR, buf,
typeid(Option6AddrLst));
LibDhcpTest::testStdOptionDefs6(D6O_NAME_SERVERS, buf,
typeid(Option6AddrLst));
LibDhcpTest::testStdOptionDefs6(D6O_DOMAIN_SEARCH, fqdn_buf,
typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_IA_PD, buf, typeid(Option6IA));
LibDhcpTest::testStdOptionDefs6(D6O_IAPREFIX, buf, typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_NIS_SERVERS, buf,
typeid(Option6AddrLst));
LibDhcpTest::testStdOptionDefs6(D6O_NISP_SERVERS, buf,
typeid(Option6AddrLst));
LibDhcpTest::testStdOptionDefs6(D6O_NIS_DOMAIN_NAME, fqdn_buf,
typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_NISP_DOMAIN_NAME, fqdn_buf,
typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_SNTP_SERVERS, buf,
typeid(Option6AddrLst));
LibDhcpTest::testStdOptionDefs6(D6O_INFORMATION_REFRESH_TIME,
buf, typeid(Option6Int<uint32_t>));
LibDhcpTest::testStdOptionDefs6(D6O_BCMCS_SERVER_D, fqdn_buf,
typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_BCMCS_SERVER_A, buf,
typeid(Option6AddrLst));
LibDhcpTest::testStdOptionDefs6(D6O_GEOCONF_CIVIC, buf,
typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_REMOTE_ID, buf, typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_SUBSCRIBER_ID, buf,typeid(Option));
LibDhcpTest::testStdOptionDefs6(D6O_CLIENT_FQDN, client_fqdn_buf,
typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_PANA_AGENT, buf,
typeid(Option6AddrLst));
LibDhcpTest::testStdOptionDefs6(D6O_PANA_AGENT, buf,
typeid(Option6AddrLst));
LibDhcpTest::testStdOptionDefs6(D6O_NEW_POSIX_TIMEZONE, buf,
typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_NEW_TZDB_TIMEZONE, buf,
typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_ERO, buf,
typeid(Option6IntArray<uint16_t>));
LibDhcpTest::testStdOptionDefs6(D6O_LQ_QUERY, buf, typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_CLIENT_DATA, buf, typeid(Option));
LibDhcpTest::testStdOptionDefs6(D6O_CLT_TIME, buf,
typeid(Option6Int<uint32_t>));
LibDhcpTest::testStdOptionDefs6(D6O_LQ_RELAY_DATA, buf,
typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_LQ_CLIENT_LINK, buf,
typeid(Option6AddrLst));
}
......
......@@ -23,6 +23,7 @@
#include <dhcp/option6_iaaddr.h>
#include <dhcp/option6_int.h>
#include <dhcp/option6_int_array.h>
#include <dhcp/option_custom.h>
#include <dhcp/option_definition.h>
#include <exceptions/exceptions.h>
......@@ -883,7 +884,7 @@ TEST_F(OptionDefinitionTest, utf8StringTokenized) {
option_v6 = opt_def.optionFactory(Option::V6, opt_code, values);
);
ASSERT_TRUE(option_v6);
ASSERT_TRUE(typeid(*option_v6) == typeid(Option));
ASSERT_TRUE(typeid(*option_v6) == typeid(OptionCustom));
std::vector<uint8_t> data = option_v6->getData();
std::vector<uint8_t> ref_data(values[0].c_str(), values[0].c_str()
+ values[0].length());
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment