123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790 |
- // Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
- //
- // This Source Code Form is subject to the terms of the Mozilla Public
- // License, v. 2.0. If a copy of the MPL was not distributed with this
- // file, You can obtain one at http://mozilla.org/MPL/2.0/.
- #include <config.h>
- #include <asiolink/io_address.h>
- #include <dhcp/dhcp6.h>
- #include <dhcp/opaque_data_tuple.h>
- #include <dhcp/option.h>
- #include <dhcp/option_custom.h>
- #include <dhcp/option_definition.h>
- #include <dhcp/option_int.h>
- #include <dhcp/option_int_array.h>
- #include <dhcp/option_opaque_data_tuples.h>
- #include <dhcp/option_string.h>
- #include <dhcp/option_vendor.h>
- #include <dhcp/option_vendor_class.h>
- #include <dhcp/option4_addrlst.h>
- #include <dhcp/option4_client_fqdn.h>
- #include <dhcp/option6_addrlst.h>
- #include <dhcp/option6_client_fqdn.h>
- #include <dhcp/option6_ia.h>
- #include <dhcp/option6_iaaddr.h>
- #include <dhcp/option6_iaprefix.h>
- #include <dhcp/option6_status_code.h>
- #include <util/buffer.h>
- #include <boost/pointer_cast.hpp>
- #include <gtest/gtest.h>
- using namespace std;
- using namespace isc;
- using namespace isc::asiolink;
- using namespace isc::dhcp;
- using namespace isc::util;
- namespace {
- /// @brief Type of the "copy" operation to be performed in a test.
- ///
- /// Possible operations are:
- /// - copy construction,
- /// - cloning with Option::clone,
- /// - assignment.
- enum OpType {
- COPY,
- CLONE,
- ASSIGN
- };
- /// @brief Generic test for deep copy of an option.
- ///
- /// This test can use one of the three supported operations to deep copy
- /// an option: copy construction, cloning or assignment.
- ///
- /// After copying the option the following parameters checked if they
- /// have been copied (copied by the Option class):
- /// - universe,
- /// - option type,
- /// - encapsulated space,
- /// - data.
- ///
- /// This test also checks that the sub options have been copied by checking
- /// that:
- /// - options' types match,
- /// - binary representations are equal,
- /// - pointers to the options are unequal (to make sure that the option has
- /// been copied, rather than the pointer).
- ///
- /// @param op_type Copy operation to be performed.
- /// @param option Source option.
- /// @param option_copy Destination option. Note that this option may be
- /// initially set to a non-null value. For the "copy" and "clone" operations
- /// the pointer will be reset, so there is no sense to initialize this
- /// object to a non-null value. However, for the assignment testing it is
- /// recommended to initialize the option_copy to point to an option having
- /// different parameters to verify that all parameters have been overridden
- /// by the assignment operation.
- template<typename OptionType>
- void testCopyAssign(const OpType& op_type,
- boost::shared_ptr<OptionType>& option,
- boost::shared_ptr<OptionType>& option_copy) {
- // Set the encapsulated to 'foo' because tests usually don't set that
- // value.
- option->setEncapsulatedSpace("foo");
- // Create two sub options of different types to later check that they
- // are copied.
- OptionUint16Ptr sub1 = OptionUint16Ptr(new OptionUint16(Option::V4, 10, 234));
- Option4AddrLstPtr sub2 =
- Option4AddrLstPtr(new Option4AddrLst(11, IOAddress("192.0.2.3")));
- option->addOption(sub1);
- option->addOption(sub2);
- // Copy option by copy construction, cloning or assignment.
- switch (op_type) {
- case COPY:
- option_copy.reset(new OptionType(*option));
- break;
- case CLONE:
- option_copy = boost::dynamic_pointer_cast<OptionType>(option->clone());
- ASSERT_TRUE(option_copy);
- break;
- case ASSIGN:
- option_copy->setEncapsulatedSpace("bar");
- *option_copy = *option;
- break;
- default:
- ADD_FAILURE() << "unsupported operation";
- return;
- }
- // Verify that basic parameters have been copied.
- EXPECT_EQ(option->getUniverse(), option_copy->getUniverse());
- EXPECT_EQ(option->getType(), option_copy->getType());
- EXPECT_EQ(option->len(), option_copy->len());
- EXPECT_EQ(option->getEncapsulatedSpace(), option_copy->getEncapsulatedSpace());
- EXPECT_TRUE(std::equal(option->getData().begin(), option->getData().end(),
- option_copy->getData().begin()));
- // Retrieve sub options so as they can be compared.
- const OptionCollection& option_subs = option->getOptions();
- const OptionCollection& option_copy_subs = option_copy->getOptions();
- ASSERT_EQ(option_subs.size(), option_copy_subs.size());
- // Iterate over source options.
- OptionCollection::const_iterator it_copy = option_copy_subs.begin();
- for (OptionCollection::const_iterator it = option_subs.begin();
- it != option_subs.end(); ++it, ++it_copy) {
- // The option codes should be equal in both containers.
- EXPECT_EQ(it->first, it_copy->first);
- // Pointers must be unequal because the expectation is that options
- // are copied, rather than pointers.
- EXPECT_NE(it->second, it_copy->second);
- Option* opt_ptr = it->second.get();
- Option* opt_copy_ptr = it_copy->second.get();
- // The C++ types must match.
- EXPECT_TRUE(typeid(*opt_ptr) == typeid(*opt_copy_ptr));
- }
- // Final check is to compare their binary representations.
- std::vector<uint8_t> buf = option->toBinary(true);
- std::vector<uint8_t> buf_copy = option_copy->toBinary(true);
- ASSERT_EQ(buf.size(), buf_copy.size());
- EXPECT_TRUE(std::equal(buf_copy.begin(), buf_copy.end(), buf.begin()));
- }
- // **************************** Option ***************************
- /// @brief Test deep copy of option encapsulated by Option type.
- ///
- /// @param op_type Copy operation type.
- void testOption(const OpType& op_type) {
- OptionBuffer buf(10, 1);
- OptionPtr option(new Option(Option::V4, 1, buf));
- OptionPtr option_copy(new Option(Option::V6, 1000));
- ASSERT_NO_FATAL_FAILURE(testCopyAssign(op_type, option, option_copy));
- // Save binary representation of the original option. We will
- // be later comparing it with a copied option to make sure that
- // modification of the original option doesn't affect the copy.
- std::vector<uint8_t> binary_copy = option_copy->toBinary(true);
- // Modify the original option.
- OptionBuffer buf_modified(10, 2);
- option->setData(buf_modified.begin(), buf_modified.end());
- // Retrieve the binary representation of the copy to verify that
- // it hasn't been modified.
- std::vector<uint8_t> binary_copy_after = option_copy->toBinary(true);
- ASSERT_EQ(binary_copy.size(), binary_copy_after.size());
- EXPECT_TRUE(std::equal(binary_copy_after.begin(), binary_copy_after.end(),
- binary_copy.begin()));
- }
- TEST(OptionCopyTest, optionConstructor) {
- testOption(COPY);
- }
- TEST(OptionCopyTest, optionClone) {
- testOption(CLONE);
- }
- TEST(OptionCopyTest, optionAssignment) {
- testOption(ASSIGN);
- }
- // **************************** OptionInt ***************************
- /// @brief Test deep copy of option encapsulated by OptionInt type.
- ///
- /// @param op_type Copy operation type.
- void testOptionInt(const OpType& op_type) {
- OptionUint16Ptr option(new OptionUint16(Option::V4, 1, 12345));
- OptionUint16Ptr option_copy(new OptionUint16(Option::V6, 10, 11111));
- ASSERT_NO_FATAL_FAILURE(testCopyAssign(op_type, option, option_copy));
- // Modify value in the original option.
- option->setValue(9);
- // The value in the copy should not be affected.
- EXPECT_EQ(12345, option_copy->getValue());
- }
- TEST(OptionCopyTest, optionIntConstructor) {
- testOptionInt(COPY);
- }
- TEST(OptionCopyTest, optionIntClone) {
- testOptionInt(CLONE);
- }
- TEST(OptionCopyTest, optionIntAssignment) {
- testOptionInt(ASSIGN);
- }
- // ************************* OptionIntArray ***************************
- /// @brief Test deep copy of option encapsulated by OptionIntArray type.
- ///
- /// @param op_type Copy operation type.
- void testOptionIntArray(const OpType& op_type) {
- OptionUint32ArrayPtr option(new OptionUint32Array(Option::V4, 1));;
- option->addValue(2345);
- option->addValue(3456);
- OptionUint32ArrayPtr option_copy(new OptionUint32Array(Option::V6, 10));
- option_copy->addValue(5678);
- option_copy->addValue(6789);
- ASSERT_NO_FATAL_FAILURE(testCopyAssign(op_type, option, option_copy));
- // Modify the values in the original option.
- option->setValues(std::vector<uint32_t>(2, 7));
- // The values in the copy should not be affected.
- std::vector<uint32_t> values_copy = option_copy->getValues();
- ASSERT_EQ(2, values_copy.size());
- EXPECT_EQ(2345, values_copy[0]);
- EXPECT_EQ(3456, values_copy[1]);
- }
- TEST(OptionCopyTest, optionIntArrayConstructor) {
- testOptionIntArray(COPY);
- }
- TEST(OptionCopyTest, optionIntArrayClone) {
- testOptionIntArray(CLONE);
- }
- TEST(OptionCopyTest, optionIntArrayAssignment) {
- testOptionIntArray(ASSIGN);
- }
- // ************************* Option4AddrLst ***************************
- /// @brief Test deep copy of option encapsulated by Option4AddrLst or
- /// Option6AddrLst type.
- ///
- /// @param op_type Copy operation type.
- /// @param option_address Address carried in the source option.
- /// @param option_copy_address Address carried in the destination option.
- /// @param option_modified_address Address to which the original address
- /// is modified to check that this modification doesn't affect option
- /// copy.
- /// @tparam OptionType Option4AddrLst or Option6AddrLst.
- template<typename OptionType>
- void testOptionAddrLst(const OpType& op_type,
- const IOAddress& option_address,
- const IOAddress& option_copy_address,
- const IOAddress& option_modified_address) {
- typedef boost::shared_ptr<OptionType> OptionTypePtr;
- OptionTypePtr option(new OptionType(1, option_address));
- OptionTypePtr option_copy(new OptionType(10, option_copy_address));
- ASSERT_NO_FATAL_FAILURE(testCopyAssign(op_type, option, option_copy));
- // Modify the address in the original option.
- option->setAddress(option_modified_address);
- // The address in the copy should not be affected.
- typename OptionType::AddressContainer addrs_copy = option_copy->getAddresses();
- ASSERT_EQ(1, addrs_copy.size());
- EXPECT_EQ(option_address.toText(), addrs_copy[0].toText());
- }
- /// @brief Test deep copy of option encapsulated by Option4AddrLst type.
- ///
- /// @param op_type Copy operation type.
- void testOption4AddrLst(const OpType& op_type) {
- testOptionAddrLst<Option4AddrLst>(op_type,
- IOAddress("127.0.0.1"),
- IOAddress("192.0.2.111"),
- IOAddress("127.0.0.1"));
- }
- TEST(OptionCopyTest, option4AddrLstConstructor) {
- testOption4AddrLst(COPY);
- }
- TEST(OptionCopyTest, option4AddrLstClone) {
- testOption4AddrLst(CLONE);
- }
- TEST(OptionCopyTest, option4AddrLstAssignment) {
- testOption4AddrLst(ASSIGN);
- }
- // ************************* Option6AddrLst ***************************
- /// @brief Test deep copy of option encapsulated by Option6AddrLst type.
- ///
- /// @param op_type Copy operation type.
- void testOption6AddrLst(const OpType& op_type) {
- testOptionAddrLst<Option6AddrLst>(op_type,
- IOAddress("2001:db8:1::2"),
- IOAddress("3001::cafe"),
- IOAddress("3000:1::1"));
- }
- TEST(OptionCopyTest, option6AddrLstConstructor) {
- testOption6AddrLst(COPY);
- }
- TEST(OptionCopyTest, option6AddrLstClone) {
- testOption6AddrLst(CLONE);
- }
- TEST(OptionCopyTest, option6AddrLstAssignment) {
- testOption6AddrLst(ASSIGN);
- }
- // *************************** Option6IA ***************************
- /// @brief Test deep copy of option encapsulated by Option6IA type.
- ///
- /// @param op_type Copy operation type.
- void testOption6IA(const OpType& op_type) {
- Option6IAPtr option(new Option6IA(D6O_IA_NA, 1234));
- option->setT1(1000);
- option->setT2(2000);
- Option6IAPtr option_copy(new Option6IA(D6O_IA_PD, 5678));
- ASSERT_NO_FATAL_FAILURE(testCopyAssign(op_type, option, option_copy));
- // Modify the values in the original option.
- option->setT1(3000);
- option->setT2(4000);
- option->setIAID(5678);
- // The values in the copy should not be affected.
- EXPECT_EQ(1000, option_copy->getT1());
- EXPECT_EQ(2000, option_copy->getT2());
- EXPECT_EQ(1234, option_copy->getIAID());
- }
- TEST(OptionCopyTest, option6IAConstructor) {
- testOption6IA(COPY);
- }
- TEST(OptionCopyTest, option6IAClone) {
- testOption6IA(CLONE);
- }
- TEST(OptionCopyTest, option6IAAssignment) {
- testOption6IA(ASSIGN);
- }
- // *************************** Option6IAAddr ***************************
- /// @brief Test deep copy of option encapsulated by Option6IAAddr type.
- ///
- /// @param op_type Copy operation type.
- void testOption6IAAddr(const OpType& op_type) {
- Option6IAAddrPtr option(new Option6IAAddr(D6O_IAADDR,
- IOAddress("2001:db8:1::1"),
- 60, 90));
- Option6IAAddrPtr option_copy(new Option6IAAddr(D6O_IAADDR,
- IOAddress("2001:db8:1::2"),
- 50, 80));
- ASSERT_NO_FATAL_FAILURE(testCopyAssign(op_type, option, option_copy));
- // Modify the values in the original option.
- option->setAddress(IOAddress("2001:db8:1::3"));
- option->setPreferred(1000);
- option->setValid(2000);
- // The values in the copy should not be affected.
- EXPECT_EQ("2001:db8:1::1", option_copy->getAddress().toText());
- EXPECT_EQ(60, option_copy->getPreferred());
- EXPECT_EQ(90, option_copy->getValid());
- }
- TEST(OptionCopyTest, option6IAAddrConstructor) {
- testOption6IAAddr(COPY);
- }
- TEST(OptionCopyTest, option6IAAddrClone) {
- testOption6IAAddr(CLONE);
- }
- TEST(OptionCopyTest, option6IAAddrAssignment) {
- testOption6IAAddr(ASSIGN);
- }
- // *************************** Option6IAPrefix ***************************
- /// @brief Test deep copy of option encapsulated by Option6IAPrefix type.
- ///
- /// @param op_type Copy operation type.
- void testOption6IAPrefix(const OpType& op_type) {
- Option6IAPrefixPtr option(new Option6IAPrefix(D6O_IAPREFIX,
- IOAddress("3000::"),
- 64, 60, 90));
- Option6IAPrefixPtr option_copy(new Option6IAPrefix(D6O_IAPREFIX,
- IOAddress("3001::"),
- 48, 50, 80));
- ASSERT_NO_FATAL_FAILURE(testCopyAssign(op_type, option, option_copy));
- // Modify the values in the original option.
- option->setPrefix(IOAddress("3002::"), 32);
- option->setPreferred(1000);
- option->setValid(2000);
- // The values in the copy should not be affected.
- EXPECT_EQ("3000::", option_copy->getAddress().toText());
- EXPECT_EQ(64, option_copy->getLength());
- EXPECT_EQ(60, option_copy->getPreferred());
- EXPECT_EQ(90, option_copy->getValid());
- }
- TEST(OptionCopyTest, option6IAPrefixConstructor) {
- testOption6IAPrefix(COPY);
- }
- TEST(OptionCopyTest, option6IAPrefixClone) {
- testOption6IAPrefix(CLONE);
- }
- TEST(OptionCopyTest, option6IAPrefixAssignment) {
- testOption6IAPrefix(ASSIGN);
- }
- // *************************** Option6StatusCode ***************************
- /// @brief Test deep copy of option encapsulated by Option6StatusCode type.
- ///
- /// @param op_type Copy operation type.
- void testOption6StatusCode(const OpType& op_type) {
- Option6StatusCodePtr option(new Option6StatusCode(STATUS_NoBinding,
- "no binding"));
- Option6StatusCodePtr option_copy(new Option6StatusCode(STATUS_Success,
- "success"));
- ASSERT_NO_FATAL_FAILURE(testCopyAssign(op_type, option, option_copy));
- // Modify the values in the original option.
- option->setStatusCode(STATUS_NoAddrsAvail);
- option->setStatusMessage("foo");
- // The values in the copy should not be affected.
- EXPECT_EQ(STATUS_NoBinding, option_copy->getStatusCode());
- EXPECT_EQ("no binding", option_copy->getStatusMessage());
- }
- TEST(OptionCopyTest, option6StatusCodeConstructor) {
- testOption6StatusCode(COPY);
- }
- TEST(OptionCopyTest, option6StatusCodeClone) {
- testOption6StatusCode(CLONE);
- }
- TEST(OptionCopyTest, option6StatusCodeAssignment) {
- testOption6StatusCode(ASSIGN);
- }
- // *************************** OptionString ***************************
- /// @brief Test deep copy of option encapsulated by OptionString type.
- ///
- /// @param op_type Copy operation type.
- void testOptionString(const OpType& op_type) {
- OptionStringPtr option(new OptionString(Option::V4, 1, "option value"));
- OptionStringPtr option_copy(new OptionString(Option::V6, 10,
- "another value"));
- ASSERT_NO_FATAL_FAILURE(testCopyAssign(op_type, option, option_copy));
- // Modify the string in the original option.
- option->setValue("foo");
- // The string in the copy should not be affected.
- EXPECT_EQ("option value", option_copy->getValue());
- }
- TEST(OptionCopyTest, optionStringConstructor) {
- testOptionString(COPY);
- }
- TEST(OptionCopyTest, optionStringClone) {
- testOptionString(CLONE);
- }
- TEST(OptionCopyTest, optionStringAssignment) {
- testOptionString(ASSIGN);
- }
- // *************************** OptionVendor ***************************
- /// @brief Test deep copy of option encapsulated by OptionVendor type.
- ///
- /// @param op_type Copy operation type.
- void testOptionVendor(const OpType& op_type) {
- OptionVendorPtr option(new OptionVendor(Option::V4, 2986));
- OptionVendorPtr option_copy(new OptionVendor(Option::V6, 1111));
- ASSERT_NO_FATAL_FAILURE(testCopyAssign(op_type, option, option_copy));
- // Modify the vendor id in the original option.
- option->setVendorId(2222);
- // The vendor id in the copy should not be affected.
- EXPECT_EQ(2986, option_copy->getVendorId());
- }
- TEST(OptionCopyTest, optionVendorConstructor) {
- testOptionVendor(COPY);
- }
- TEST(OptionCopyTest, optionVendorClone) {
- testOptionVendor(CLONE);
- }
- TEST(OptionCopyTest, optionVendorAssignment) {
- testOptionVendor(ASSIGN);
- }
- // *********************** OptionVendorClass ***************************
- /// @brief Test deep copy of option encapsulated by OptionVendorClass type.
- ///
- /// @param op_type Copy operation type.
- void testOptionVendorClass(const OpType& op_type) {
- // Create a DHCPv4 option with a single tuple.
- OptionVendorClassPtr option(new OptionVendorClass(Option::V4, 2986));
- OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_1_BYTE);
- tuple = "vendor-class-value";
- option->setTuple(0, tuple);
- // Create a DHCPv6 option with a single tuple.
- OptionVendorClassPtr option_copy(new OptionVendorClass(Option::V6,
- 1111));
- OpaqueDataTuple tuple_copy(OpaqueDataTuple::LENGTH_2_BYTES);
- tuple = "vendor-class-assigned";
- option_copy->addTuple(tuple_copy);
- ASSERT_NO_FATAL_FAILURE(testCopyAssign(op_type, option, option_copy));
- // Modify the tuple in the original option and add one more tuple.
- tuple = "modified-vendor-class-value";
- option->setTuple(0, tuple);
- tuple = "another-modified-vendor-class-value";
- option->addTuple(tuple);
- // That change shouldn't affect the original option. It should still
- // contain a single tuple with the original value.
- ASSERT_EQ(1, option_copy->getTuplesNum());
- tuple = option_copy->getTuple(0);
- EXPECT_TRUE(tuple.equals("vendor-class-value"));
- }
- TEST(OptionCopyTest, optionVendorClassConstructor) {
- testOptionVendorClass(COPY);
- }
- TEST(OptionCopyTest, optionVendorClassClone) {
- testOptionVendorClass(CLONE);
- }
- TEST(OptionCopyTest, optionVendorClassAssignment) {
- testOptionVendorClass(ASSIGN);
- }
- // ************************** Option4ClientFqdn ***************************
- /// @brief Test deep copy of option encapsulated by Option4ClientFqdn or
- /// Option6ClientFqdn type.
- ///
- /// @param op_type Copy operation type.
- /// @param option Option to be copied.
- /// @param option_copy Destination option. Note that this option may be
- /// initially set to a non-null value. For the "copy" and "clone" operations
- /// the pointer will be reset, so there is no sense to initialize this
- /// object to a non-null value. However, for the assignment testing it is
- /// recommended to initialize the option_copy to point to an option having
- /// different parameters to verify that all parameters have been overridden
- /// by the assignment operation.
- ///
- /// @tparam OptionType Option4ClientFqdn or Option6ClientFqdn.
- template<typename OptionType>
- void testOptionClientFqdn(const OpType& op_type,
- boost::shared_ptr<OptionType>& option,
- boost::shared_ptr<OptionType>& option_copy) {
- ASSERT_NO_FATAL_FAILURE(testCopyAssign(op_type, option, option_copy));
- // Modify the values in the original option.
- option->setDomainName("newname", OptionType::PARTIAL);
- option->setFlag(OptionType::FLAG_S, false);
- option->setFlag(OptionType::FLAG_N, true);
- // Rcode is carried on the in the DHCPv4 Client FQDN option.
- // If the OptionType is pointing to a DHCPv6 option the dynamic
- // cast will result in NULL pointer and we'll not check the
- // RCODE.
- Option4ClientFqdnPtr option4 =
- boost::dynamic_pointer_cast<Option4ClientFqdn>(option);
- if (option4) {
- option4->setRcode(64);
- }
- // Verify that common parameters haven't been modified in the
- // copied option by the change in the original option.
- EXPECT_EQ("myname.example.org.", option_copy->getDomainName());
- EXPECT_EQ(OptionType::FULL, option_copy->getDomainNameType());
- EXPECT_TRUE(option_copy->getFlag(OptionType::FLAG_S));
- EXPECT_FALSE(option_copy->getFlag(OptionType::FLAG_N));
- // If we're dealing with DHCPv4 Client FQDN, we also need to
- // test RCODE.
- Option4ClientFqdnPtr option_copy4 =
- boost::dynamic_pointer_cast<Option4ClientFqdn>(option_copy);
- if (option_copy4) {
- EXPECT_EQ(255, option_copy4->getRcode().first.getCode());
- EXPECT_EQ(255, option_copy4->getRcode().second.getCode());
- }
- }
- /// @brief Test deep copy of option encapsulated by Option4ClientFqdn type.
- ///
- /// @param op_type Copy operation type.
- void testOption4ClientFqdn(const OpType& op_type) {
- Option4ClientFqdnPtr
- option(new Option4ClientFqdn(Option4ClientFqdn::FLAG_S,
- Option4ClientFqdn::Rcode(255),
- "myname.example.org"));
- Option4ClientFqdnPtr
- option_copy(new Option4ClientFqdn(Option4ClientFqdn::FLAG_O,
- Option4ClientFqdn::Rcode(0),
- "other.example.org"));
- ASSERT_NO_FATAL_FAILURE(testOptionClientFqdn<Option4ClientFqdn>(op_type, option,
- option_copy));
- }
- TEST(OptionCopyTest, option4ClientFqdnConstructor) {
- testOption4ClientFqdn(COPY);
- }
- TEST(OptionCopyTest, option4ClientFqdnClone) {
- testOption4ClientFqdn(CLONE);
- }
- TEST(OptionCopyTest, option4ClientFqdnAssignment) {
- testOption4ClientFqdn(ASSIGN);
- }
- // ************************** Option6ClientFqdn ***************************
- /// @brief Test deep copy of option encapsulated by Option6ClientFqdn type.
- ///
- /// @param op_type Copy operation type.
- void testOption6ClientFqdn(const OpType& op_type) {
- Option6ClientFqdnPtr
- option(new Option6ClientFqdn(Option6ClientFqdn::FLAG_S,
- "myname.example.org"));
- Option6ClientFqdnPtr
- option_copy(new Option6ClientFqdn(Option6ClientFqdn::FLAG_O,
- "other.example.org"));
- ASSERT_NO_FATAL_FAILURE(testOptionClientFqdn<Option6ClientFqdn>(op_type, option,
- option_copy));
- }
- TEST(OptionCopyTest, option6ClientFqdnConstructor) {
- testOption6ClientFqdn(COPY);
- }
- TEST(OptionCopyTest, option6ClientFqdnClone) {
- testOption6ClientFqdn(CLONE);
- }
- TEST(OptionCopyTest, option6ClientFqdnAssignment) {
- testOption6ClientFqdn(ASSIGN);
- }
- // **************************** OptionCustom ***************************
- /// @brief Test deep copy of option encapsulated by OptionCustom type.
- ///
- /// @param op_type Copy operation type.
- void testOptionCustom(const OpType& op_type) {
- // Create option with a single field carrying 16-bits integer.
- OptionDefinition def("foo", 1, "uint16", true);
- OptionCustomPtr option(new OptionCustom(def, Option::V4));
- option->addArrayDataField<uint16_t>(5555);
- // Create option with two fields carrying IPv4 address and 32-bit
- // integer.
- OptionDefinition def_copy("bar", 10, "record");
- def_copy.addRecordField("ipv4-address");
- def_copy.addRecordField("uint32");
- OptionCustomPtr option_copy(new OptionCustom(def_copy, Option::V6));
- option_copy->writeAddress(IOAddress("192.0.0.2"));
- option_copy->writeInteger<uint32_t>(12, 1);
- ASSERT_NO_FATAL_FAILURE(testCopyAssign(op_type, option, option_copy));
- // Modify the original option value.
- option->writeInteger<uint16_t>(1000);
- // The copied option should not be affected.
- ASSERT_EQ(1, option_copy->getDataFieldsNum());
- EXPECT_EQ(5555, option_copy->readInteger<uint16_t>());
- }
- TEST(OptionCopyTest, optionCustomConstructor) {
- testOptionCustom(COPY);
- }
- TEST(OptionCopyTest, optionCustomClone) {
- testOptionCustom(CLONE);
- }
- TEST(OptionCopyTest, optionCustomAssignment) {
- testOptionCustom(ASSIGN);
- }
- // ************************ OptionOpaqueDataTuples ***********************
- /// @brief Test deep copy of option encapsulated by OptionOpaqueDataTuples type.
- ///
- /// @param op_type Copy operation type.
- void testOptionOpaqueDataTuples(const OpType& op_type) {
- OptionOpaqueDataTuplesPtr option(new OptionOpaqueDataTuples(Option::V4, 1));
- OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_1_BYTE);
- tuple = "a string";
- option->addTuple(tuple);
- tuple = "another string";
- option->addTuple(tuple);
- OptionOpaqueDataTuplesPtr option_copy(new OptionOpaqueDataTuples(Option::V6, 10));
- OpaqueDataTuple tuple_copy(OpaqueDataTuple::LENGTH_2_BYTES);
- tuple_copy = "copy string";
- option_copy->addTuple(tuple_copy);
- ASSERT_NO_FATAL_FAILURE(testCopyAssign(op_type, option, option_copy));
- // Modify the value in the first tuple and add one more tuple.
- tuple = "modified-first-tuple";
- option->setTuple(0, tuple);
- tuple = "modified-second-tuple";
- option->setTuple(1, tuple);
- // This should not affect the values in the original option.
- ASSERT_EQ(2, option_copy->getTuplesNum());
- EXPECT_TRUE(option_copy->getTuple(0).equals("a string"));
- EXPECT_TRUE(option_copy->getTuple(1).equals("another string"));
- }
- TEST(OptionCopyTest, optionOpaqueDataTuplesConstructor) {
- testOptionOpaqueDataTuples(COPY);
- }
- TEST(OptionCopyTest, optionOpaqueDataTuplesClone) {
- testOptionOpaqueDataTuples(CLONE);
- }
- TEST(OptionCopyTest, optionOpaqueDataTuplesAssign) {
- testOptionOpaqueDataTuples(ASSIGN);
- }
- }
|