Browse Source

[2491] Test that appropriate std options are returned.

Marcin Siodelski 12 years ago
parent
commit
ac111116c5

+ 1 - 1
src/lib/dhcp/libdhcp++.cc

@@ -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);

+ 44 - 32
src/lib/dhcp/option_definition.cc

@@ -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());

+ 143 - 21
src/lib/dhcp/tests/libdhcp++_unittest.cc

@@ -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));
 }
 

+ 2 - 1
src/lib/dhcp/tests/option_definition_unittest.cc

@@ -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());