1 // Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 
9 #include <dhcp/libdhcp++.h>
10 #include <dhcp/option_vendor.h>
11 #include <dhcpsrv/testutils/generic_backend_unittest.h>
12 #include <util/buffer.h>
13 #include <typeinfo>
14 
15 using namespace isc::data;
16 
17 namespace isc {
18 namespace dhcp {
19 namespace test {
20 
GenericBackendTest()21 GenericBackendTest::GenericBackendTest() {
22     LibDHCP::clearRuntimeOptionDefs();
23 }
24 
~GenericBackendTest()25 GenericBackendTest::~GenericBackendTest() {
26     LibDHCP::clearRuntimeOptionDefs();
27 }
28 
29 OptionDescriptor
createEmptyOption(const Option::Universe & universe,const uint16_t option_type,const bool persist) const30 GenericBackendTest::createEmptyOption(const Option::Universe& universe,
31                                       const uint16_t option_type,
32                                       const bool persist) const {
33     OptionPtr option(new Option(universe, option_type));
34     OptionDescriptor desc(option, persist);
35     return (desc);
36 }
37 
38 OptionDescriptor
createVendorOption(const Option::Universe & universe,const bool persist,const bool formatted,const uint32_t vendor_id) const39 GenericBackendTest::createVendorOption(const Option::Universe& universe,
40                                        const bool persist,
41                                        const bool formatted,
42                                        const uint32_t vendor_id) const {
43     OptionVendorPtr option(new OptionVendor(universe, vendor_id));
44 
45     std::ostringstream s;
46     if (formatted) {
47         // Vendor id comprises vendor-id field, for which we need to
48         // assign a value in the textual (formatted) format.
49         s << vendor_id;
50     }
51 
52     OptionDescriptor desc(option, persist, s.str());
53     return (desc);
54 }
55 
56 void
testOptionsEquivalent(const OptionDescriptor & ref_option,const OptionDescriptor & tested_option) const57 GenericBackendTest::testOptionsEquivalent(const OptionDescriptor& ref_option,
58                                           const OptionDescriptor& tested_option) const {
59     // Make sure that all pointers are non-null.
60     ASSERT_TRUE(ref_option.option_);
61     ASSERT_TRUE(tested_option.option_);
62 
63     // Get the reference to the tested option. Make should it has
64     // generic type.
65     Option& tested_option_reference = *tested_option.option_;
66     EXPECT_TRUE(typeid(tested_option_reference) == typeid(Option));
67 
68     // Only test the binary data if the formatted value is not provided.
69     if (tested_option.formatted_value_.empty()) {
70 
71         // Prepare on-wire data of the option under test.
72         isc::util::OutputBuffer tested_option_buf(1);
73         tested_option.option_->pack(tested_option_buf);
74         const uint8_t* tested_option_buf_data = static_cast<const uint8_t*>
75             (tested_option_buf.getData());
76         std::vector<uint8_t> tested_option_buf_vec(tested_option_buf_data,
77                                                    tested_option_buf_data + tested_option_buf.getLength());
78 
79         // Prepare on-wire data of the reference option.
80         isc::util::OutputBuffer ref_option_buf(1);
81         ref_option.option_->pack(ref_option_buf);
82         const uint8_t* ref_option_buf_data = static_cast<const uint8_t*>
83             (ref_option_buf.getData());
84         std::vector<uint8_t> ref_option_buf_vec(ref_option_buf_data,
85                                                 ref_option_buf_data + ref_option_buf.getLength());
86 
87         // Compare the on-wire data.
88         EXPECT_EQ(ref_option_buf_vec, tested_option_buf_vec);
89 
90     } else {
91         // If the formatted value is non-empty the buffer should be empty.
92         EXPECT_TRUE(tested_option.option_->getData().empty());
93     }
94 
95     // Compare other members of the @c OptionDescriptor, e.g. the
96     // tested option may contain formatted option data which can be
97     // later used to turn this option instance into a formatted
98     // option when an option definition is available.
99     EXPECT_EQ(ref_option.formatted_value_, tested_option.formatted_value_);
100     EXPECT_EQ(ref_option.persistent_, tested_option.persistent_);
101     EXPECT_EQ(ref_option.space_name_, tested_option.space_name_);
102 }
103 
104 void
checkConfiguredGlobal(const SrvConfigPtr & srv_cfg,const std::string & name,ConstElementPtr exp_value)105 GenericBackendTest::checkConfiguredGlobal(const SrvConfigPtr& srv_cfg,
106                                           const std::string &name,
107                                           ConstElementPtr exp_value) {
108     ConstElementPtr globals = srv_cfg->getConfiguredGlobals();
109     ConstElementPtr found_global = globals->get(name);
110     ASSERT_TRUE(found_global) << "expected global: "
111                               << name << " not found";
112 
113     ASSERT_EQ(exp_value->getType(), found_global->getType())
114         << "expected global: " << name << " has wrong type";
115 
116     ASSERT_EQ(*exp_value, *found_global)
117         << "expected global: " << name << " has wrong value";
118 }
119 
120 void
checkConfiguredGlobal(const SrvConfigPtr & srv_cfg,StampedValuePtr & exp_global)121 GenericBackendTest::checkConfiguredGlobal(const SrvConfigPtr& srv_cfg,
122                                           StampedValuePtr& exp_global) {
123     checkConfiguredGlobal(srv_cfg, exp_global->getName(), exp_global->getElementValue());
124 }
125 
126 
127 } // end of namespace isc::dhcp::test
128 } // end of namespace isc::dhcp
129 } // end of namespace isc
130