Browse Source

[2490] Option is created by calling to OptionDefinition::optionFactory.

Marcin Siodelski 12 years ago
parent
commit
b4b3814079

+ 1 - 4
src/bin/dhcp6/config_parser.cc

@@ -698,11 +698,8 @@ private:
             // We have exactly one option definition for the particular option code
             // use it to create the option instance.
             const OptionDefinitionPtr& def = *(range.first);
-            // getFactory should never return NULL pointer.
-            Option::Factory* factory = def->getFactory();
-            assert(factory != NULL);
             try {
-                OptionPtr option = factory(Option::V6, option_code, binary);
+                OptionPtr option = def->optionFactory(Option::V6, option_code, binary);
                 Subnet::OptionDescriptor desc(option, false);
                 option_descriptor_.option = option;
                 option_descriptor_.persistent = false;

+ 47 - 42
src/lib/dhcp/option_definition.cc

@@ -96,51 +96,50 @@ OptionDefinition::addRecordField(const DataType data_type) {
     record_fields_.push_back(data_type);
 }
 
-Option::Factory*
-OptionDefinition::getFactory() const {
+OptionPtr
+OptionDefinition::optionFactory(Option::Universe u, uint16_t type,
+                                OptionBufferConstIter begin,
+                                OptionBufferConstIter end) {
     validate();
 
-    // @todo This function must be extended to return more factory
-    // functions that create instances of more specialized options.
-    // This requires us to first implement those more specialized
-    // options that will be derived from Option class.
     if (type_ == BINARY_TYPE) {
-        return (factoryGeneric);
+        return (factoryGeneric(u, type, begin, end));
     } else if (type_ == IPV6_ADDRESS_TYPE && array_type_) {
-        return (factoryAddrList6);
+        return (factoryAddrList6(u, type, begin, end));
     } else if (type_ == IPV4_ADDRESS_TYPE && array_type_) {
-        return (factoryAddrList4);
+        return (factoryAddrList4(u, type, begin, end));
     } else if (type_ == EMPTY_TYPE) {
-        return (factoryEmpty);
+        return (factoryEmpty(u, type, begin, end));
     } else if (code_ == D6O_IA_NA && haveIA6Format()) {
-        return (factoryIA6);
+        return (factoryIA6(u, type, begin, end));
     } else if (code_ == D6O_IAADDR && haveIAAddr6Format()) {
-        return (factoryIAAddr6);
+        return (factoryIAAddr6(u, type, begin, end));
     } else if (type_ == UINT8_TYPE) {
         if (array_type_) {
-            return (factoryGeneric);
+            return (factoryGeneric(u, type, begin, end));
         } else {
-            return (factoryInteger<uint8_t>);
+            return (factoryInteger<uint8_t>(u, type, begin, end));
         }
     } else if (type_ == UINT16_TYPE) {
         if (array_type_) {
-            return (factoryIntegerArray<uint16_t>);
+            return (factoryIntegerArray<uint16_t>(u, type, begin, end));
         } else {
-            return (factoryInteger<uint16_t>);
+            return (factoryInteger<uint16_t>(u, type, begin, end));
         }
     } else if (type_ == UINT32_TYPE) {
         if (array_type_) {
-            return (factoryIntegerArray<uint32_t>);
+            return (factoryIntegerArray<uint32_t>(u, type, begin, end));
         } else {
-            return (factoryInteger<uint32_t>);
+            return (factoryInteger<uint32_t>(u, type, begin, end));
         }
     }
-    // Factory generic returns instance of Option class. However, once we
-    // implement CustomOption class we may want to return factory function
-    // that will create instance of CustomOption rather than Option.
-    // CustomOption will allow to access particular data fields within the
-    // option rather than raw data buffer.
-    return (factoryGeneric);
+    return (factoryGeneric(u, type, begin, end));
+}
+
+OptionPtr
+OptionDefinition::optionFactory(Option::Universe u, uint16_t type,
+                                const OptionBuffer& buf) {
+    return (optionFactory(u, type, buf.begin(), buf.end()));
 }
 
 void
@@ -195,26 +194,28 @@ OptionDefinition::haveIAAddr6Format() const {
 
 OptionPtr
 OptionDefinition::factoryAddrList4(Option::Universe u, uint16_t type,
-                                   const OptionBuffer& buf) {
+                                  OptionBufferConstIter begin,
+                                  OptionBufferConstIter end) {
     sanityCheckUniverse(u, Option::V4);
-    boost::shared_ptr<Option4AddrLst> option(new Option4AddrLst(type, buf.begin(),
-                                                                buf.begin() + buf.size()));
+    boost::shared_ptr<Option4AddrLst> option(new Option4AddrLst(type, begin, end));
     return (option);
 }
 
 OptionPtr
 OptionDefinition::factoryAddrList6(Option::Universe u, uint16_t type,
-                                   const OptionBuffer& buf) {
+                                   OptionBufferConstIter begin,
+                                   OptionBufferConstIter end) {
     sanityCheckUniverse(u, Option::V6);
-    boost::shared_ptr<Option6AddrLst> option(new Option6AddrLst(type, buf.begin(),
-                                                                buf.begin() + buf.size()));
+    boost::shared_ptr<Option6AddrLst> option(new Option6AddrLst(type, begin, end));
     return (option);
 }
 
 
 OptionPtr
-OptionDefinition::factoryEmpty(Option::Universe u, uint16_t type, const OptionBuffer& buf) {
-    if (buf.size() > 0) {
+OptionDefinition::factoryEmpty(Option::Universe u, uint16_t type,
+                               OptionBufferConstIter begin,
+                               OptionBufferConstIter end) {
+    if (std::distance(begin, end) > 0) {
         isc_throw(isc::BadValue, "input option buffer must be empty"
                   " when creating empty option instance");
     }
@@ -223,32 +224,36 @@ OptionDefinition::factoryEmpty(Option::Universe u, uint16_t type, const OptionBu
 }
 
 OptionPtr
-OptionDefinition::factoryGeneric(Option::Universe u, uint16_t type, const OptionBuffer& buf) {
-    OptionPtr option(new Option(u, type, buf));
+OptionDefinition::factoryGeneric(Option::Universe u, uint16_t type,
+                                 OptionBufferConstIter begin,
+                                 OptionBufferConstIter end) {
+    OptionPtr option(new Option(u, type, begin, end));
     return (option);
 }
 
 OptionPtr
-OptionDefinition::factoryIA6(Option::Universe u, uint16_t type, const OptionBuffer& buf) {
+OptionDefinition::factoryIA6(Option::Universe u, uint16_t type,
+                             OptionBufferConstIter begin,
+                             OptionBufferConstIter end) {
     sanityCheckUniverse(u, Option::V6);
-    if (buf.size() != Option6IA::OPTION6_IA_LEN) {
+    if (std::distance(begin, end) != Option6IA::OPTION6_IA_LEN) {
         isc_throw(isc::OutOfRange, "input option buffer has invalid size, expeted "
                   << Option6IA::OPTION6_IA_LEN << " bytes");
     }
-    boost::shared_ptr<Option6IA> option(new Option6IA(type, buf.begin(),
-                                                      buf.begin() + buf.size()));
+    boost::shared_ptr<Option6IA> option(new Option6IA(type, begin, end));
     return (option);
 }
 
 OptionPtr
-OptionDefinition::factoryIAAddr6(Option::Universe u, uint16_t type, const OptionBuffer& buf) {
+OptionDefinition::factoryIAAddr6(Option::Universe u, uint16_t type,
+                                 OptionBufferConstIter begin,
+                                 OptionBufferConstIter end) {
     sanityCheckUniverse(u, Option::V6);
-    if (buf.size() != Option6IAAddr::OPTION6_IAADDR_LEN) {
+    if (std::distance(begin, end) != Option6IAAddr::OPTION6_IAADDR_LEN) {
         isc_throw(isc::OutOfRange, "input option buffer has invalid size, expeted "
                   << Option6IAAddr::OPTION6_IAADDR_LEN << " bytes");
     }
-    boost::shared_ptr<Option6IAAddr> option(new Option6IAAddr(type, buf.begin(),
-                                                      buf.begin() + buf.size()));
+    boost::shared_ptr<Option6IAAddr> option(new Option6IAAddr(type, begin, end));
     return (option);
 }
 

+ 55 - 22
src/lib/dhcp/option_definition.h

@@ -231,13 +231,6 @@ public:
     /// @return option code.
     uint16_t getCode() const { return (code_); }
 
-    /// @brief Return factory function for the given definition.
-    ///
-    /// @throw isc::OutOfRange if \ref validate returns it.
-    /// @throw isc::BadValue if \ref validate returns it.
-    /// @return pointer to a factory function.
-    Option::Factory* getFactory() const;
-
     /// @brief Return option name.
     ///
     /// @return option name.
@@ -270,6 +263,36 @@ public:
     /// @return true if specified format is IAADDR option format.
     bool haveIAAddr6Format() const;
 
+    /// @brief Option factory.
+    ///
+    /// This function creates an instance of DHCP option using
+    /// provided chunk of buffer. This function may be used to
+    /// create option which is to be sent in the outgoing packet.
+    ///
+    /// @param universe option universe (V4 or V6).
+    /// @param type option type.
+    /// @param begin beginning of the option buffer.
+    /// @param end end of the option buffer.
+    ///
+    /// @return instance of the DHCP option.
+    OptionPtr optionFactory(Option::Universe u, uint16_t type,
+                            OptionBufferConstIter begin,
+                            OptionBufferConstIter end);
+
+    /// @brief Option factory.
+    ///
+    /// This function creates an instance of DHCP option using
+    /// whole provided buffer. This function may be used to
+    /// create option which is to be sent in the outgoing packet.
+    ///
+    /// @param universe option universe (V4 or V6).
+    /// @param type option type.
+    /// @param buf option buffer.
+    ///
+    /// @return instance of the DHCP option.
+    OptionPtr optionFactory(Option::Universe u, uint16_t type,
+                            const OptionBuffer& buf);
+
     /// @brief Factory to create option with address list.
     ///
     /// @param u universe (must be V4).
@@ -279,7 +302,8 @@ public:
     /// @throw isc::OutOfRange if length of the provided option buffer
     /// is not multiple of IPV4 address length.
     static OptionPtr factoryAddrList4(Option::Universe u, uint16_t type,
-                                      const OptionBuffer& buf);
+                                      OptionBufferConstIter begin,
+                                      OptionBufferConstIter end);
 
     /// @brief Factory to create option with address list.
     ///
@@ -290,7 +314,8 @@ public:
     /// @throw isc::OutOfaRange if length of provided option buffer
     /// is not multiple of IPV6 address length.
     static OptionPtr factoryAddrList6(Option::Universe u, uint16_t type,
-                                      const OptionBuffer& buf);
+                                      OptionBufferConstIter begin,
+                                      OptionBufferConstIter end);
 
     /// @brief Empty option factory.
     ///
@@ -298,7 +323,8 @@ public:
     /// @param type option type.
     /// @param buf option buffer (must be empty).
     static OptionPtr factoryEmpty(Option::Universe u, uint16_t type,
-                                  const OptionBuffer& buf);
+                                  OptionBufferConstIter begin,
+                                  OptionBufferConstIter end);
 
     /// @brief Factory to create generic option.
     ///
@@ -306,7 +332,8 @@ public:
     /// @param type option type.
     /// @param buf option buffer.
     static OptionPtr factoryGeneric(Option::Universe u, uint16_t type,
-                                    const OptionBuffer& buf);
+                                    OptionBufferConstIter begin,
+                                    OptionBufferConstIter end);
 
     /// @brief Factory for IA-type of option.
     ///
@@ -318,7 +345,8 @@ public:
     /// too long. Expected size is 12 bytes.
     /// @throw isc::BadValue if specified universe value is not V6.
     static OptionPtr factoryIA6(Option::Universe u, uint16_t type,
-                                const OptionBuffer& buf);
+                                OptionBufferConstIter begin,
+                                OptionBufferConstIter end);
 
     /// @brief Factory for IAADDR-type of option.
     ///
@@ -330,7 +358,8 @@ public:
     /// too long. Expected size is 24 bytes.
     /// @throw isc::BadValue if specified universe value is not V6.
     static OptionPtr factoryIAAddr6(Option::Universe u, uint16_t type,
-                                const OptionBuffer& buf);
+                                    OptionBufferConstIter begin,
+                                    OptionBufferConstIter end);
 
     /// @brief Factory function to create option with integer value.
     ///
@@ -340,12 +369,14 @@ public:
     ///
     /// @throw isc::OutOfRange if provided option buffer length is invalid.
     template<typename T>
-    static OptionPtr factoryInteger(Option::Universe, uint16_t type, const OptionBuffer& buf) {
-        if (buf.size() > sizeof(T)) {
+    static OptionPtr factoryInteger(Option::Universe, uint16_t type,
+                                    OptionBufferConstIter begin,
+                                    OptionBufferConstIter end) {
+        if (std::distance(begin, end) > sizeof(T)) {
             isc_throw(isc::OutOfRange, "provided option buffer is too large, expected: "
                       << sizeof(T) << " bytes");
         }
-        OptionPtr option(new Option6Int<T>(type, buf.begin(), buf.end()));
+        OptionPtr option(new Option6Int<T>(type, begin, end));
         return (option);
     }
 
@@ -357,14 +388,16 @@ public:
     ///
     /// @throw isc::OutOfRange if provided option buffer length is invalid.
     template<typename T>
-    static OptionPtr factoryIntegerArray(Option::Universe, uint16_t type, const OptionBuffer& buf) {
-        if (buf.size() == 0) {
+    static OptionPtr factoryIntegerArray(Option::Universe, uint16_t type,
+                                         OptionBufferConstIter begin,
+                                         OptionBufferConstIter end) {
+        if (std::distance(begin, end) == 0) {
             isc_throw(isc::OutOfRange, "option buffer length must be greater than zero");
-        } else if (buf.size() % OptionDataTypes<T>::len != 0) {
+        } else if (std::distance(begin, end) % OptionDataTypes<T>::len != 0) {
             isc_throw(isc::OutOfRange, "option buffer length must be multiple of "
                       << OptionDataTypes<T>::len << " bytes");
         }
-        OptionPtr option(new Option6IntArray<T>(type, buf.begin(), buf.end()));
+        OptionPtr option(new Option6IntArray<T>(type, begin, end));
         return (option);
     }
 
@@ -395,7 +428,7 @@ private:
     ///
     /// @throw isc::BadValue if expected universe and actual universe don't match.
    static inline void sanityCheckUniverse(const Option::Universe expected_universe,
-                                          const Option::Universe actual_universe); 
+                                          const Option::Universe actual_universe);
 
     /// Option name.
     std::string name_;
@@ -421,7 +454,7 @@ private:
 /// Note that this container can hold multiple options with the
 /// same code. For this reason, the latter index can be used to
 /// obtain a range of options for a particular option code.
-/// 
+///
 /// @todo: need an index to search options using option space name
 /// once option spaces are implemented.
 typedef boost::multi_index_container<

+ 1 - 6
src/lib/dhcp/tests/libdhcp++_unittest.cc

@@ -90,14 +90,9 @@ public:
         ASSERT_TRUE(def);
         // Check that option definition is valid.
         ASSERT_NO_THROW(def->validate());
-        // Get the factory function for the particular option
-        // definition. We will use this factory function to
-        // create option instance.
-        Option::Factory* factory = NULL;
-        ASSERT_NO_THROW(factory = def->getFactory());
         OptionPtr option;
         // Create the option.
-        ASSERT_NO_THROW(option = factory(Option::V6, code, buf));
+        ASSERT_NO_THROW(option = def->optionFactory(Option::V6, code, buf));
         // Make sure it is not NULL.
         ASSERT_TRUE(option);
         // And the actual object type is the one that we expect.

+ 39 - 67
src/lib/dhcp/tests/option_definition_unittest.cc

@@ -151,9 +151,6 @@ TEST_F(OptionDefinitionTest, validate) {
 TEST_F(OptionDefinitionTest, factoryAddrList6) {
     OptionDefinition opt_def("OPTION_NIS_SERVERS", D6O_NIS_SERVERS,
                              "ipv6-address", true);
-    Option::Factory* factory(NULL);
-    EXPECT_NO_THROW(factory = opt_def.getFactory());
-    ASSERT_TRUE(factory != NULL);
 
     // Create a list of some V6 addresses.
     std::vector<asiolink::IOAddress> addrs;
@@ -176,7 +173,7 @@ TEST_F(OptionDefinitionTest, factoryAddrList6) {
     // the provided buffer.
     OptionPtr option_v6;
     ASSERT_NO_THROW(
-        option_v6 = factory(Option::V6, D6O_NIS_SERVERS, buf);
+        option_v6 = opt_def.optionFactory(Option::V6, D6O_NIS_SERVERS, buf);
     );
     ASSERT_TRUE(typeid(*option_v6) == typeid(Option6AddrLst));
     boost::shared_ptr<Option6AddrLst> option_cast_v6 =
@@ -195,7 +192,7 @@ TEST_F(OptionDefinitionTest, factoryAddrList6) {
     buf.insert(buf.end(), 1, 1);
     // It should throw exception then.
     EXPECT_THROW(
-        factory(Option::V6, D6O_NIS_SERVERS, buf),
+        opt_def.optionFactory(Option::V6, D6O_NIS_SERVERS, buf),
         isc::OutOfRange
     );
 }
@@ -203,9 +200,6 @@ TEST_F(OptionDefinitionTest, factoryAddrList6) {
 TEST_F(OptionDefinitionTest, factoryAddrList4) {
     OptionDefinition opt_def("OPTION_NAME_SERVERS", D6O_NIS_SERVERS,
                              "ipv4-address", true);
-    Option::Factory* factory(NULL);
-    EXPECT_NO_THROW(factory = opt_def.getFactory());
-    ASSERT_TRUE(factory != NULL);
 
     // Create a list of some V6 addresses.
     std::vector<asiolink::IOAddress> addrs;
@@ -228,7 +222,7 @@ TEST_F(OptionDefinitionTest, factoryAddrList4) {
     // the provided buffer.
     OptionPtr option_v4;
     ASSERT_NO_THROW(
-        option_v4 = factory(Option::V4, DHO_NAME_SERVERS, buf)
+        option_v4 = opt_def.optionFactory(Option::V4, DHO_NAME_SERVERS, buf)
     );
     ASSERT_TRUE(typeid(*option_v4) == typeid(Option4AddrLst));
     // Get the list of parsed addresses from the option object.
@@ -245,19 +239,17 @@ TEST_F(OptionDefinitionTest, factoryAddrList4) {
     // fulfilled anymore.
     buf.insert(buf.end(), 1, 1);
     // It should throw exception then.
-    EXPECT_THROW(factory(Option::V4, DHO_NIS_SERVERS, buf), isc::OutOfRange);
+    EXPECT_THROW(opt_def.optionFactory(Option::V4, DHO_NIS_SERVERS, buf),
+                 isc::OutOfRange);
 }
 
 TEST_F(OptionDefinitionTest, factoryEmpty) {
     OptionDefinition opt_def("OPTION_RAPID_COMMIT", D6O_RAPID_COMMIT, "empty");
-    Option::Factory* factory(NULL);
-    EXPECT_NO_THROW(factory = opt_def.getFactory());
-    ASSERT_TRUE(factory != NULL);
 
     // Create option instance and provide empty buffer as expected.
     OptionPtr option_v6;
     ASSERT_NO_THROW(
-        option_v6 = factory(Option::V6, D6O_RAPID_COMMIT, OptionBuffer())
+        option_v6 = opt_def.optionFactory(Option::V6, D6O_RAPID_COMMIT, OptionBuffer())
     );
     ASSERT_TRUE(typeid(*option_v6) == typeid(Option));
     // Expect 'empty' DHCPv6 option.
@@ -266,10 +258,11 @@ TEST_F(OptionDefinitionTest, factoryEmpty) {
     EXPECT_EQ(0, option_v6->getData().size());
 
     // Repeat the same test scenario for DHCPv4 option.
-    EXPECT_THROW(factory(Option::V4, 214, OptionBuffer(2)),isc::BadValue);
+    EXPECT_THROW(opt_def.optionFactory(Option::V4, 214, OptionBuffer(2)),
+                 isc::BadValue);
 
     OptionPtr option_v4;
-    ASSERT_NO_THROW(option_v4 = factory(Option::V4, 214, OptionBuffer()));
+    ASSERT_NO_THROW(option_v4 = opt_def.optionFactory(Option::V4, 214, OptionBuffer()));
     // Expect 'empty' DHCPv4 option.
     EXPECT_EQ(Option::V4, option_v4->getUniverse());
     EXPECT_EQ(2, option_v4->getHeaderLen());
@@ -278,7 +271,8 @@ TEST_F(OptionDefinitionTest, factoryEmpty) {
     // This factory produces empty option (consisting of option type
     // and length). Attempt to provide some data in the buffer should
     // result in exception.
-    EXPECT_THROW(factory(Option::V6, D6O_RAPID_COMMIT,OptionBuffer(2)),isc::BadValue);
+    EXPECT_THROW(opt_def.optionFactory(Option::V6, D6O_RAPID_COMMIT, OptionBuffer(2)),
+                 isc::BadValue);
 }
 
 TEST_F(OptionDefinitionTest, factoryBinary) {
@@ -288,9 +282,6 @@ TEST_F(OptionDefinitionTest, factoryBinary) {
     // option consists of the option code, length and binary data so
     // this one was picked for this test.
     OptionDefinition opt_def("OPTION_SERVERID", D6O_SERVERID, "binary");
-    Option::Factory* factory(NULL);
-    EXPECT_NO_THROW(factory = opt_def.getFactory());
-    ASSERT_TRUE(factory != NULL);
 
     // Prepare some dummy data (serverid): 0, 1, 2 etc.
     OptionBuffer buf(14);
@@ -302,7 +293,7 @@ TEST_F(OptionDefinitionTest, factoryBinary) {
     // object of the type Option should be returned.
     OptionPtr option_v6;
     ASSERT_NO_THROW(
-        option_v6 = factory(Option::V6, D6O_SERVERID, buf);
+        option_v6 = opt_def.optionFactory(Option::V6, D6O_SERVERID, buf);
     );
     // Expect base option type returned.
     ASSERT_TRUE(typeid(*option_v6) == typeid(Option));
@@ -320,7 +311,7 @@ TEST_F(OptionDefinitionTest, factoryBinary) {
 
     // Repeat the same test scenario for DHCPv4 option.
     OptionPtr option_v4;
-    ASSERT_NO_THROW(option_v4 = factory(Option::V4, 214, buf));
+    ASSERT_NO_THROW(option_v4 = opt_def.optionFactory(Option::V4, 214, buf));
     // Expect 'empty' DHCPv4 option.
     EXPECT_EQ(Option::V4, option_v4->getUniverse());
     EXPECT_EQ(2, option_v4->getHeaderLen());
@@ -341,9 +332,6 @@ TEST_F(OptionDefinitionTest, factoryIA6) {
     for (int i = 0; i < 3; ++i) {
         EXPECT_NO_THROW(opt_def.addRecordField("uint32"));
     }
-    Option::Factory* factory(NULL);
-    EXPECT_NO_THROW(factory = opt_def.getFactory());
-    ASSERT_TRUE(factory != NULL);
 
     // Check the positive scenario.
     OptionBuffer buf(12);
@@ -351,7 +339,7 @@ TEST_F(OptionDefinitionTest, factoryIA6) {
         buf[i] = i;
     }
     OptionPtr option_v6;
-    ASSERT_NO_THROW(option_v6 = factory(Option::V6, D6O_IA_NA, buf));
+    ASSERT_NO_THROW(option_v6 = opt_def.optionFactory(Option::V6, D6O_IA_NA, buf));
     ASSERT_TRUE(typeid(*option_v6) == typeid(Option6IA));
     boost::shared_ptr<Option6IA> option_cast_v6 =
         boost::static_pointer_cast<Option6IA>(option_v6);
@@ -361,18 +349,18 @@ TEST_F(OptionDefinitionTest, factoryIA6) {
 
     // This should work for DHCPv6 only, try passing invalid universe value.
     EXPECT_THROW(
-        factory(Option::V4, D6O_IA_NA, OptionBuffer(option6_ia_len)),
+        opt_def.optionFactory(Option::V4, D6O_IA_NA, OptionBuffer(option6_ia_len)),
         isc::BadValue
     );
     // The length of the buffer must be 12 bytes.
     // Check too short buffer.
     EXPECT_THROW(
-        factory(Option::V6, D6O_IA_NA, OptionBuffer(option6_ia_len - 1)),
+        opt_def.optionFactory(Option::V6, D6O_IA_NA, OptionBuffer(option6_ia_len - 1)),
         isc::OutOfRange
      );
     // Check too long buffer.
     EXPECT_THROW(
-        factory(Option::V6, D6O_IA_NA, OptionBuffer(option6_ia_len + 1)),
+        opt_def.optionFactory(Option::V6, D6O_IA_NA, OptionBuffer(option6_ia_len + 1)),
         isc::OutOfRange
     );
 }
@@ -386,9 +374,6 @@ TEST_F(OptionDefinitionTest, factoryIAAddr6) {
     ASSERT_NO_THROW(opt_def.addRecordField("ipv6-address"));
     ASSERT_NO_THROW(opt_def.addRecordField("uint32"));
     ASSERT_NO_THROW(opt_def.addRecordField("uint32"));
-    Option::Factory* factory(NULL);
-    EXPECT_NO_THROW(factory = opt_def.getFactory());
-    ASSERT_TRUE(factory != NULL);
 
     // Check the positive scenario.
     OptionPtr option_v6;
@@ -403,7 +388,7 @@ TEST_F(OptionDefinitionTest, factoryIAAddr6) {
     for (int i = 0; i < option6_iaaddr_len - asiolink::V6ADDRESS_LEN; ++i) {
         buf.push_back(i);
     }
-    ASSERT_NO_THROW(option_v6 = factory(Option::V6, D6O_IAADDR, buf));
+    ASSERT_NO_THROW(option_v6 = opt_def.optionFactory(Option::V6, D6O_IAADDR, buf));
     ASSERT_TRUE(typeid(*option_v6) == typeid(Option6IAAddr));
     boost::shared_ptr<Option6IAAddr> option_cast_v6 =
         boost::static_pointer_cast<Option6IAAddr>(option_v6);
@@ -413,18 +398,18 @@ TEST_F(OptionDefinitionTest, factoryIAAddr6) {
 
     // This should work for DHCPv6 only, try passing invalid universe value.
     EXPECT_THROW(
-        factory(Option::V4, D6O_IAADDR, OptionBuffer(option6_iaaddr_len)),
+        opt_def.optionFactory(Option::V4, D6O_IAADDR, OptionBuffer(option6_iaaddr_len)),
         isc::BadValue
     );
     // The length of the buffer must be 12 bytes.
     // Check too short buffer.
     EXPECT_THROW(
-        factory(Option::V6, D6O_IAADDR, OptionBuffer(option6_iaaddr_len - 1)),
+        opt_def.optionFactory(Option::V6, D6O_IAADDR, OptionBuffer(option6_iaaddr_len - 1)),
         isc::OutOfRange
      );
     // Check too long buffer.
     EXPECT_THROW(
-        factory(Option::V6, D6O_IAADDR, OptionBuffer(option6_iaaddr_len + 1)),
+        opt_def.optionFactory(Option::V6, D6O_IAADDR, OptionBuffer(option6_iaaddr_len + 1)),
         isc::OutOfRange
     );
 }
@@ -433,22 +418,21 @@ TEST_F(OptionDefinitionTest, factoryIntegerInvalidType) {
     // The template function factoryInteger<> accepts integer values only
     // as template typename. Here we try passing different type and
     // see if it rejects it.
+    OptionBuffer buf(1);
     EXPECT_THROW(
-        OptionDefinition::factoryInteger<bool>(Option::V6, D6O_PREFERENCE, OptionBuffer(1)),
+        OptionDefinition::factoryInteger<bool>(Option::V6, D6O_PREFERENCE,
+                                               buf.begin(), buf.end()),
         isc::dhcp::InvalidDataType
     );
 }
 
 TEST_F(OptionDefinitionTest, factoryUint8) {
     OptionDefinition opt_def("OPTION_PREFERENCE", D6O_PREFERENCE, "uint8");
-    Option::Factory* factory(NULL);
-    EXPECT_NO_THROW(factory = opt_def.getFactory());
-    ASSERT_TRUE(factory != NULL);
 
     OptionPtr option_v6;
     // Try to use correct buffer length = 1 byte.
     ASSERT_NO_THROW(
-        option_v6 = factory(Option::V6, D6O_PREFERENCE, OptionBuffer(1, 1));
+        option_v6 = opt_def.optionFactory(Option::V6, D6O_PREFERENCE, OptionBuffer(1, 1));
     );
     ASSERT_TRUE(typeid(*option_v6) == typeid(Option6Int<uint8_t>));
     // Validate the value.
@@ -458,13 +442,13 @@ TEST_F(OptionDefinitionTest, factoryUint8) {
 
     // Try to provide too large buffer. Expect exception.
     EXPECT_THROW(
-        option_v6 = factory(Option::V6, D6O_PREFERENCE, OptionBuffer(3)),
+        option_v6 = opt_def.optionFactory(Option::V6, D6O_PREFERENCE, OptionBuffer(3)),
         isc::OutOfRange
     );
 
     // Try to provide zero-length buffer. Expect exception.
     EXPECT_THROW(
-        option_v6 = factory(Option::V6, D6O_PREFERENCE, OptionBuffer()),
+        option_v6 = opt_def.optionFactory(Option::V6, D6O_PREFERENCE, OptionBuffer()),
         isc::OutOfRange
     );
 
@@ -473,9 +457,6 @@ TEST_F(OptionDefinitionTest, factoryUint8) {
 
 TEST_F(OptionDefinitionTest, factoryUint16) {
     OptionDefinition opt_def("OPTION_ELAPSED_TIME", D6O_ELAPSED_TIME, "uint16");
-    Option::Factory* factory(NULL);
-    EXPECT_NO_THROW(factory = opt_def.getFactory());
-    ASSERT_TRUE(factory != NULL);
 
     OptionPtr option_v6;
     // Try to use correct buffer length = 2 bytes.
@@ -483,7 +464,7 @@ TEST_F(OptionDefinitionTest, factoryUint16) {
     buf.push_back(1);
     buf.push_back(2);
     ASSERT_NO_THROW(
-        option_v6 = factory(Option::V6, D6O_ELAPSED_TIME, buf);
+        option_v6 = opt_def.optionFactory(Option::V6, D6O_ELAPSED_TIME, buf);
     );
     ASSERT_TRUE(typeid(*option_v6) == typeid(Option6Int<uint16_t>));
     // Validate the value.
@@ -493,12 +474,12 @@ TEST_F(OptionDefinitionTest, factoryUint16) {
 
     // Try to provide too large buffer. Expect exception.
     EXPECT_THROW(
-        option_v6 = factory(Option::V6, D6O_ELAPSED_TIME, OptionBuffer(3)),
+        option_v6 = opt_def.optionFactory(Option::V6, D6O_ELAPSED_TIME, OptionBuffer(3)),
         isc::OutOfRange
     );
     // Try to provide zero-length buffer. Expect exception.
     EXPECT_THROW(
-        option_v6 = factory(Option::V6, D6O_ELAPSED_TIME, OptionBuffer(1)),
+        option_v6 = opt_def.optionFactory(Option::V6, D6O_ELAPSED_TIME, OptionBuffer(1)),
         isc::OutOfRange
     );
 
@@ -507,9 +488,6 @@ TEST_F(OptionDefinitionTest, factoryUint16) {
 
 TEST_F(OptionDefinitionTest, factoryUint32) {
     OptionDefinition opt_def("OPTION_CLT_TIME", D6O_CLT_TIME, "uint32");
-    Option::Factory* factory(NULL);
-    EXPECT_NO_THROW(factory = opt_def.getFactory());
-    ASSERT_TRUE(factory != NULL);
 
     OptionPtr option_v6;
     OptionBuffer buf;
@@ -518,7 +496,7 @@ TEST_F(OptionDefinitionTest, factoryUint32) {
     buf.push_back(3);
     buf.push_back(4);
     ASSERT_NO_THROW(
-        option_v6 = factory(Option::V6, D6O_CLT_TIME, buf);
+        option_v6 = opt_def.optionFactory(Option::V6, D6O_CLT_TIME, buf);
     );
     ASSERT_TRUE(typeid(*option_v6) == typeid(Option6Int<uint32_t>));
     // Validate the value.
@@ -528,12 +506,12 @@ TEST_F(OptionDefinitionTest, factoryUint32) {
 
     // Try to provide too large buffer. Expect exception.
     EXPECT_THROW(
-        option_v6 = factory(Option::V6, D6O_CLT_TIME, OptionBuffer(5)),
+        option_v6 = opt_def.optionFactory(Option::V6, D6O_CLT_TIME, OptionBuffer(5)),
         isc::OutOfRange
     );
     // Try to provide zero-length buffer. Expect exception.
     EXPECT_THROW(
-        option_v6 = factory(Option::V6, D6O_CLT_TIME, OptionBuffer(2)),
+        option_v6 = opt_def.optionFactory(Option::V6, D6O_CLT_TIME, OptionBuffer(2)),
         isc::OutOfRange
     );
 
@@ -544,9 +522,6 @@ TEST_F(OptionDefinitionTest, factoryUint16Array) {
     // Let's define some dummy option.
     const uint16_t opt_code = 79;
     OptionDefinition opt_def("OPTION_UINT16_ARRAY", opt_code, "uint16", true);
-    Option::Factory* factory(NULL);
-    EXPECT_NO_THROW(factory = opt_def.getFactory());
-    ASSERT_TRUE(factory != NULL);
 
     OptionPtr option_v6;
     // Positive scenario, initiate the buffer with length being
@@ -558,7 +533,7 @@ TEST_F(OptionDefinitionTest, factoryUint16Array) {
     }
     // Constructor should succeed because buffer has correct size.
     EXPECT_NO_THROW(
-        option_v6 = factory(Option::V6, opt_code, buf);
+        option_v6 = opt_def.optionFactory(Option::V6, opt_code, buf);
     );
     ASSERT_TRUE(typeid(*option_v6) == typeid(Option6IntArray<uint16_t>));
     boost::shared_ptr<Option6IntArray<uint16_t> > option_cast_v6 =
@@ -576,12 +551,12 @@ TEST_F(OptionDefinitionTest, factoryUint16Array) {
     // Provided buffer size must be greater than zero. Check if we
     // get exception if we provide zero-length buffer.
     EXPECT_THROW(
-        option_v6 = factory(Option::V6, opt_code, OptionBuffer()),
+        option_v6 = opt_def.optionFactory(Option::V6, opt_code, OptionBuffer()),
         isc::OutOfRange
     );
     // Buffer length must be multiple of data type size.
     EXPECT_THROW(
-        option_v6 = factory(Option::V6, opt_code, OptionBuffer(5)),
+        option_v6 = opt_def.optionFactory(Option::V6, opt_code, OptionBuffer(5)),
         isc::OutOfRange
     );
 }
@@ -591,9 +566,6 @@ TEST_F(OptionDefinitionTest, factoryUint32Array) {
     const uint16_t opt_code = 80;
 
     OptionDefinition opt_def("OPTION_UINT32_ARRAY", opt_code, "uint32", true);
-    Option::Factory* factory(NULL);
-    EXPECT_NO_THROW(factory = opt_def.getFactory());
-    ASSERT_TRUE(factory != NULL);
 
     OptionPtr option_v6;
     // Positive scenario, initiate the buffer with length being
@@ -605,7 +577,7 @@ TEST_F(OptionDefinitionTest, factoryUint32Array) {
     }
     // Constructor should succeed because buffer has correct size.
     EXPECT_NO_THROW(
-        option_v6 = factory(Option::V6, opt_code, buf);
+        option_v6 = opt_def.optionFactory(Option::V6, opt_code, buf);
     );
     ASSERT_TRUE(typeid(*option_v6) == typeid(Option6IntArray<uint32_t>));
     boost::shared_ptr<Option6IntArray<uint32_t> > option_cast_v6 =
@@ -623,12 +595,12 @@ TEST_F(OptionDefinitionTest, factoryUint32Array) {
     // Provided buffer size must be greater than zero. Check if we
     // get exception if we provide zero-length buffer.
     EXPECT_THROW(
-        option_v6 = factory(Option::V6, opt_code, OptionBuffer()),
+        option_v6 = opt_def.optionFactory(Option::V6, opt_code, OptionBuffer()),
         isc::OutOfRange
     );
     // Buffer length must be multiple of data type size.
     EXPECT_THROW(
-        option_v6 = factory(Option::V6, opt_code, OptionBuffer(5)),
+        option_v6 = opt_def.optionFactory(Option::V6, opt_code, OptionBuffer(5)),
         isc::OutOfRange
     );
 }