Bug Summary

File:usr/src/googletest/googletest/include/gtest/gtest-assertion-result.h
Warning:line 161, column 18
Assigned value is uninitialized

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name config_parser_unittest.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/fedora/workspace/kea-dev/clang-static-analyzer/build/meson-private/tmpk3qwau10 -fcoverage-compilation-dir=/home/fedora/workspace/kea-dev/clang-static-analyzer/build/meson-private/tmpk3qwau10 -resource-dir /usr/bin/../lib/clang/22 -I src/bin/dhcp4/tests/kea-dhcp4-tests.p -I src/bin/dhcp4/tests -I ../../../src/bin/dhcp4/tests -I . -I ../../.. -I src -I ../../../src -I src/bin -I ../../../src/bin -I src/lib -I ../../../src/lib -I /usr/src/googletest/googletest -I /usr/src/googletest/googletest/include -I /usr/include/mysql -I /usr/include/mysql/mysql -I /usr/include -D _GLIBCXX_ASSERTIONS=1 -D _FILE_OFFSET_BITS=64 -D BOOST_ALL_NO_LIB -D TEST_DATA_BUILDDIR="/home/fedora/workspace/kea-dev/clang-static-analyzer/build/meson-private/tmpk3qwau10/src/bin/dhcp4/tests" -D CFG_EXAMPLES="/home/fedora/workspace/kea-dev/clang-static-analyzer/doc/examples/kea4" -D DHCP_DATA_DIR="/usr/local/var/lib/kea" -D SYNTAX_FILE="/home/fedora/workspace/kea-dev/clang-static-analyzer/src/bin/dhcp4/tests/../dhcp4_parser.yy" -D KEA_LFC_EXECUTABLE="/home/fedora/workspace/kea-dev/clang-static-analyzer/build/meson-private/tmpk3qwau10/src/bin/lfc/kea-lfc" -D TEST_CA_DIR="/home/fedora/workspace/kea-dev/clang-static-analyzer/src/lib/asiolink/testutils/ca" -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/backward -internal-isystem /usr/bin/../lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-missing-field-initializers -fdeprecated-macro -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /home/fedora/workspace/kea-dev/clang-static-analyzer/build/meson-logs/scanbuild/2026-09-28-125224-4737-1 -x c++ ../../../src/bin/dhcp4/tests/config_parser_unittest.cc

../../../src/bin/dhcp4/tests/config_parser_unittest.cc

→
1// Copyright (C) 2012-2026 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 <asiolink/addr_utilities.h>
10#include <cc/command_interpreter.h>
11#include <config/http_command_config.h>
12#include <config/testutils/socket_path.h>
13#include <dhcp/classify.h>
14#include <dhcp/docsis3_option_defs.h>
15#include <dhcp/iface_mgr.h>
16#include <dhcp/libdhcp++.h>
17#include <dhcp/option4_addrlst.h>
18#include <dhcp/option_custom.h>
19#include <dhcp/option_int.h>
20#include <dhcp/testutils/iface_mgr_test_config.h>
21#include <dhcp4/ctrl_dhcp4_srv.h>
22#include <dhcp4/dhcp4_srv.h>
23#include <dhcp4/json_config_parser.h>
24#include <dhcp4/tests/dhcp4_test_utils.h>
25#include <dhcp4/tests/get_config_unittest.h>
26#include <dhcp4/tests/marker_file.h>
27#include <dhcp4/tests/test_libraries.h>
28#include <dhcpsrv/cfg_expiration.h>
29#include <dhcpsrv/cfg_hosts.h>
30#include <dhcpsrv/cfg_subnets4.h>
31#include <dhcpsrv/cfgmgr.h>
32#include <dhcpsrv/parsers/simple_parser4.h>
33#include <dhcpsrv/subnet.h>
34#include <dhcpsrv/subnet_selector.h>
35#include <dhcpsrv/testutils/config_result_check.h>
36#include <dhcpsrv/testutils/test_config_backend_dhcp4.h>
37#include <hooks/hooks_manager.h>
38#include <hooks/hooks_parser.h>
39#include <process/config_ctl_info.h>
40#include <stats/stats_mgr.h>
41#include <testutils/gtest_utils.h>
42#include <testutils/log_utils.h>
43#include <testutils/test_to_element.h>
44#include <util/chrono_time_utils.h>
45#include <util/doubles.h>
46#include <util/filesystem.h>
47
48#include <iostream>
49#include <sstream>
50#include <string>
51#include <vector>
52
53#include <boost/scoped_ptr.hpp>
54#include <gtest/gtest.h>
55
56#include <arpa/inet.h>
57#include <unistd.h>
58
59using namespace isc;
60using namespace isc::asiolink;
61using namespace isc::config;
62using namespace isc::config::test;
63using namespace isc::data;
64using namespace isc::dhcp;
65using namespace isc::dhcp::test;
66using namespace isc::hooks;
67using namespace isc::test;
68using namespace isc::util;
69using namespace std;
70
71namespace {
72
73const char* PARSER_CONFIGS[] = {
74 // Configuration 0: one subnet with one pool, no user contexts
75 "{"
76 " \"interfaces-config\": {"
77 " \"interfaces\": [\"*\" ]"
78 " },"
79 " \"valid-lifetime\": 4000,"
80 " \"rebind-timer\": 2000,"
81 " \"renew-timer\": 1000,"
82 " \"subnet4\": [ {"
83 " \"pools\": [ "
84 " { \"pool\": \"192.0.2.0/28\" }"
85 " ],"
86 " \"id\": 1,"
87 " \"subnet\": \"192.0.2.0/24\""
88 " } ]"
89 "}",
90
91 // Configuration 1: one pool with empty user context
92 "{"
93 " \"interfaces-config\": {"
94 " \"interfaces\": [\"*\" ]"
95 " },"
96 " \"valid-lifetime\": 4000,"
97 " \"rebind-timer\": 2000,"
98 " \"renew-timer\": 1000,"
99 " \"subnet4\": [ {"
100 " \"pools\": [ "
101 " { \"pool\": \"192.0.2.0/28\","
102 " \"user-context\": {"
103 " }"
104 " }"
105 " ],"
106 " \"id\": 1,"
107 " \"subnet\": \"192.0.2.0/24\""
108 " } ]"
109 "}",
110
111 // Configuration 2: one pool with user context containing lw4over6 parameters
112 "{"
113 " \"interfaces-config\": {"
114 " \"interfaces\": [\"*\" ]"
115 " },"
116 " \"valid-lifetime\": 4000,"
117 " \"rebind-timer\": 2000,"
118 " \"renew-timer\": 1000,"
119 " \"subnet4\": [ {"
120 " \"pools\": [ "
121 " { \"pool\": \"192.0.2.0/28\","
122 " \"user-context\": {"
123 " \"integer-param\": 42,"
124 " \"string-param\": \"Sagittarius\","
125 " \"bool-param\": true"
126 " }"
127 " }"
128 " ],"
129 " \"id\": 1,"
130 " \"subnet\": \"192.0.2.0/24\""
131 " } ]"
132 "}",
133
134 // Configuration 3: one min-max pool with user context containing lw4over6 parameters
135 "{"
136 " \"interfaces-config\": {"
137 " \"interfaces\": [\"*\" ]"
138 " },"
139 " \"valid-lifetime\": 4000,"
140 " \"rebind-timer\": 2000,"
141 " \"renew-timer\": 1000,"
142 " \"subnet4\": [ {"
143 " \"pools\": [ "
144 " { \"pool\": \"192.0.2.0 - 192.0.2.15\","
145 " \"user-context\": {"
146 " \"integer-param\": 42,"
147 " \"string-param\": \"Sagittarius\","
148 " \"bool-param\": true"
149 " }"
150 " }"
151 " ],"
152 " \"id\": 1,"
153 " \"subnet\": \"192.0.2.0/24\""
154 " } ]"
155 "}",
156
157 // Configuration 4: two host databases
158 "{"
159 " \"interfaces-config\": {"
160 " \"interfaces\": [\"*\" ]"
161 " },"
162 " \"valid-lifetime\": 4000,"
163 " \"rebind-timer\": 2000,"
164 " \"renew-timer\": 1000,"
165 " \"hosts-databases\": [ {"
166 " \"type\": \"mysql\","
167 " \"name\": \"keatest1\","
168 " \"user\": \"keatest\","
169 " \"password\": \"keatest\""
170 " },{"
171 " \"type\": \"mysql\","
172 " \"name\": \"keatest2\","
173 " \"user\": \"keatest\","
174 " \"retry-on-startup\": true,"
175 " \"password\": \"keatest\""
176 " }"
177 " ]"
178 "}",
179
180 // Configuration 5: config databases
181 "{ \n"
182 " \"interfaces-config\": { \n"
183 " \"interfaces\": [\"*\" ] \n"
184 " }, \n"
185 " \"valid-lifetime\": 4000, \n"
186 " \"rebind-timer\": 2000, \n"
187 " \"renew-timer\": 1000, \n"
188 " \"config-control\": { \n"
189 " \"config-fetch-wait-time\": 10, \n"
190 " \"config-databases\": [ { \n"
191 " \"type\": \"mysql\", \n"
192 " \"name\": \"keatest1\", \n"
193 " \"user\": \"keatest\", \n"
194 " \"password\": \"keatest\" \n"
195 " },{ \n"
196 " \"type\": \"mysql\", \n"
197 " \"name\": \"keatest2\", \n"
198 " \"user\": \"keatest\", \n"
199 " \"retry-on-startup\": true, \n"
200 " \"password\": \"keatest\" \n"
201 " } \n"
202 " ] \n"
203 " } \n"
204 "} \n",
205
206 // Configuration 6 for comments
207 "{"
208 " \"comment\": \"A DHCPv4 server\","
209 " \"interfaces-config\": {"
210 " \"comment\": \"Use wildcard\","
211 " \"interfaces\": [ \"*\" ] },"
212 " \"option-def\": [ {"
213 " \"comment\": \"An option definition\","
214 " \"name\": \"foo\","
215 " \"code\": 100,"
216 " \"type\": \"ipv4-address\","
217 " \"space\": \"isc\""
218 " } ],"
219 " \"option-data\": [ {"
220 " \"comment\": \"Set option value\","
221 " \"name\": \"dhcp-message\","
222 " \"data\": \"ABCDEF0105\","
223 " \"csv-format\": false"
224 " } ],"
225 " \"client-classes\": ["
226 " {"
227 " \"comment\": \"match all\","
228 " \"name\": \"all\","
229 " \"test\": \"'' == ''\""
230 " },"
231 " {"
232 " \"name\": \"none\""
233 " },"
234 " {"
235 " \"comment\": \"a comment\","
236 " \"name\": \"both\","
237 " \"user-context\": {"
238 " \"version\": 1"
239 " }"
240 " }"
241 " ],"
242 " \"control-sockets\": ["
243 " {"
244 " \"socket-type\": \"unix\","
245 " \"socket-name\": \"kea4-ctrl-socket\","
246 " \"user-context\": { \"comment\": \"Indirect comment\" }"
247 " },"
248 " {"
249 " \"comment\": \"HTTP control socket\","
250 " \"socket-type\": \"http\","
251 " \"socket-address\": \"::1\","
252 " \"socket-port\": 8000,"
253 " \"http-headers\": [ {"
254 " \"comment\": \"HSTS header\","
255 " \"name\": \"Strict-Transport-Security\","
256 " \"value\": \"max-age=31536000\""
257 " } ],"
258 " \"authentication\": {"
259 " \"comment\": \"basic HTTP authentication\","
260 " \"type\": \"basic\","
261 " \"clients\": [ {"
262 " \"comment\": \"admin is authorized\","
263 " \"user\": \"admin\","
264 " \"password\": \"foobar\""
265 " } ]"
266 " }"
267 " }"
268 " ],"
269 " \"shared-networks\": [ {"
270 " \"comment\": \"A shared network\","
271 " \"name\": \"foo\","
272 " \"subnet4\": ["
273 " { "
274 " \"comment\": \"A subnet\","
275 " \"subnet\": \"192.0.1.0/24\","
276 " \"id\": 100,"
277 " \"pools\": ["
278 " {"
279 " \"comment\": \"A pool\","
280 " \"pool\": \"192.0.1.1-192.0.1.10\""
281 " }"
282 " ],"
283 " \"reservations\": ["
284 " {"
285 " \"comment\": \"A host reservation\","
286 " \"hw-address\": \"AA:BB:CC:DD:EE:FF\","
287 " \"hostname\": \"foo.example.com\","
288 " \"option-data\": [ {"
289 " \"comment\": \"An option in a reservation\","
290 " \"name\": \"domain-name\","
291 " \"data\": \"example.com\""
292 " } ]"
293 " }"
294 " ]"
295 " }"
296 " ]"
297 " } ],"
298 " \"dhcp-ddns\": {"
299 " \"comment\": \"No dynamic DNS\","
300 " \"enable-updates\": false"
301 " }"
302 "}"
303};
304
305class Dhcp4ParserTest : public LogContentTest {
306protected:
307 // Check that no hooks libraries are loaded. This is a pre-condition for
308 // a number of tests, so is checked in one place. As this uses an
309 // ASSERT call - and it is not clear from the documentation that Gtest
310 // predicates can be used in a constructor - the check is placed in SetUp.
311 virtual void SetUp() {
312 std::vector<std::string> libraries = HooksManager::getLibraryNames();
313 ASSERT_TRUE(libraries.empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(libraries.empty())) ;
else return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 313, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "libraries.empty()", "false", "true") .c_str()) = ::testing
::Message()
;
314 }
315
316public:
317 Dhcp4ParserTest() : rcode_(-1) {
318 // Open port 0 means to not open any sockets. We don't want to
319 // deal with sockets here, just check if configuration handling
320 // is sane.
321 srv_.reset(new ControlledDhcpv4Srv(0));
322
323 const IfaceCollection& ifaces = IfaceMgr::instance().getIfaces();
324
325 // There must be some interface detected
326 if (ifaces.empty()) {
327 // We can't use ASSERT in constructor
328 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 328, "Failed") = ::testing::Message()
<< "No interfaces detected.";
329 }
330
331 valid_iface_ = (*ifaces.begin())->getName();
332 bogus_iface_ = "nonexisting0";
333
334 if (IfaceMgr::instance().getIface(bogus_iface_)) {
335 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 335, "Failed") = ::testing::Message()
<< "The '" << bogus_iface_ << "' exists on this system"
336 << " while the test assumes that it doesn't, to execute"
337 << " some negative scenarios. Can't continue this test.";
338 }
339 // Reset configuration for each test.
340 resetConfiguration();
341
342 resetHooksPath();
343 Dhcpv4SrvTest::resetSocketPath();
344 file::PathChecker::enableEnforcement(true);
345 }
346
347 ~Dhcp4ParserTest() {
348 // Reset configuration database after each test.
349 resetConfiguration();
350
351 // ... and delete the hooks library marker files if present
352 static_cast<void>(remove(LOAD_MARKER_FILE));
353 static_cast<void>(remove(UNLOAD_MARKER_FILE));
354
355 resetHooksPath();
356 Dhcpv4SrvTest::resetSocketPath();
357 file::PathChecker::enableEnforcement(true);
358 };
359
360 /// @brief Sets the Hooks path from which hooks can be loaded.
361 /// @param explicit_path path to use as the hooks path.
362 void setHooksTestPath(const std::string explicit_path = "") {
363 HooksLibrariesParser::getHooksPath(true,
364 (!explicit_path.empty() ?
365 explicit_path : DHCP4_HOOKS_TEST_PATH));
366 }
367
368 /// @brief Resets the hooks path to DEFAULT_HOOKS_PATH.
369 void resetHooksPath() {
370 HooksLibrariesParser::getHooksPath(true);
371 }
372
373 // Checks if the result of DHCP server configuration has
374 // expected code (0 for success, other for failures).
375 // Also stores result in rcode_ and comment_.
376 void checkResult(ConstElementPtr status, int expected_code) {
377 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 377, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
378 comment_ = parseAnswerText(rcode_, status);
379 EXPECT_EQ(expected_code, rcode_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("expected_code"
, "rcode_", expected_code, rcode_))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 379, gtest_ar.failure_message()) = ::testing::Message()
<< "error text:" << comment_->stringValue();
380 }
381
382 // Checks if the result of DHCP server configuration has
383 // expected code (0 for success, other for failures) and
384 // the text part. Also stores result in rcode_ and comment_.
385 void checkResult(ConstElementPtr status, int expected_code,
386 string expected_txt) {
387 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 387, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
388 comment_ = parseAnswerText(rcode_, status);
389 EXPECT_EQ(expected_code, rcode_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("expected_code"
, "rcode_", expected_code, rcode_))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 389, gtest_ar.failure_message()) = ::testing::Message()
<< "error text:" << comment_->stringValue();
390 ASSERT_TRUE(comment_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(comment_)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 390, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "comment_", "false", "true") .c_str()) = ::testing::Message
()
;
391 ASSERT_EQ(Element::string, comment_->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("Element::string"
, "comment_->getType()", Element::string, comment_->getType
()))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 391, gtest_ar.failure_message()) = ::testing::Message()
;
392 EXPECT_EQ(expected_txt, comment_->stringValue())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("expected_txt"
, "comment_->stringValue()", expected_txt, comment_->stringValue
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 392, gtest_ar.failure_message()) = ::testing::Message()
;
393 }
394
395 /// @brief Convenience method for running configuration
396 ///
397 /// This method does not throw, but signals errors using gtest macros.
398 ///
399 /// @param config text to be parsed as JSON
400 /// @param expected_code expected code (see cc/command_interpreter.h)
401 /// @param exp_error expected text error (check skipped if empty)
402 void configure(std::string config, int expected_code,
403 std::string exp_error = "") {
404 ConstElementPtr json;
405 ASSERT_NO_THROW_LOG(json = parseDHCP4(config, true)){ try { json = parseDHCP4(config, true); } catch (const std::
exception& ex) { return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 405, "Failed") = ::testing::Message() << "json = parseDHCP4(config, true)"
<< " threw type: " << typeid(ex).name() <<
", what: " << ex.what(); } catch (...) { return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 405
, "Failed") = ::testing::Message() << "json = parseDHCP4(config, true)"
<< " threw non-std::exception"; } }
;
406
407 ConstElementPtr status;
408 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_408; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_408; } } else gtest_label_testnothrow_408
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 408, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
409 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 409, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
410
411 int rcode;
412 ConstElementPtr comment = parseAnswerText(rcode, status);
413
414 string text;
415 ASSERT_TRUE(comment)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(comment)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 415, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "comment", "false", "true") .c_str()) = ::testing::Message(
)
;
416 ASSERT_NO_THROW(text = comment->stringValue())switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
text = comment->stringValue(); } else static_assert(true,
""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_416
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_416
; } } else gtest_label_testnothrow_416 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 416, ("Expected: " "text = comment->stringValue()" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
417
418 // Socket name too long?
419 bool const too_long(SocketPath::isTooLongFromConfig(json));
420 if (too_long) {
421 EXPECT_EQ(CONTROL_RESULT_FATAL_ERROR, rcode)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("CONTROL_RESULT_FATAL_ERROR"
, "rcode", CONTROL_RESULT_FATAL_ERROR, rcode))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 421
, gtest_ar.failure_message()) = ::testing::Message()
;
422 exp_error = "name too long";
423 EXPECT_NE(std::string::npos, text.find(exp_error))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::CmpHelperNE("std::string::npos"
, "text.find(exp_error)", std::string::npos, text.find(exp_error
)))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 423, gtest_ar.failure_message()) = ::testing::Message()
;
424 return;
425 }
426
427 EXPECT_EQ(expected_code, rcode)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("expected_code"
, "rcode", expected_code, rcode))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 427, gtest_ar.failure_message()) = ::testing::Message()
;
428 if (expected_code != rcode) {
429 std::cout << "Reported status: " << text << std::endl;
430 }
431
432 if ((rcode != 0)) {
433 if (!exp_error.empty()) {
434 EXPECT_EQ(exp_error, text)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("exp_error"
, "text", exp_error, text))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 434, gtest_ar.failure_message()) = ::testing::Message()
;
435 }
436 }
437 }
438
439 /// @brief Returns an interface configuration used by the most of the
440 /// unit tests.
441 std::string genIfaceConfig() const {
442 return ("\"interfaces-config\": {"
443 " \"interfaces\": [ \"*\" ]"
444 "}");
445 }
446
447 /// @brief Create the simple configuration with single option.
448 ///
449 /// This function allows to set one of the parameters that configure
450 /// option value. These parameters are: "name", "code", "data",
451 /// "csv-format" and "space".
452 ///
453 /// @param param_value string holding option parameter value to be
454 /// injected into the configuration string.
455 /// @param parameter name of the parameter to be configured with
456 /// param value.
457 /// @return configuration string containing custom values of parameters
458 /// describing an option.
459 std::string createConfigWithOption(const std::string& param_value,
460 const std::string& parameter) {
461 std::map<std::string, std::string> params;
462 if (parameter == "name") {
463 params["name"] = param_value;
464 params["space"] = DHCP4_OPTION_SPACE"dhcp4";
465 params["code"] = "56";
466 params["data"] = "ABCDEF0105";
467 params["csv-format"] = "false";
468 } else if (parameter == "space") {
469 params["name"] = "dhcp-message";
470 params["space"] = param_value;
471 params["code"] = "56";
472 params["data"] = "ABCDEF0105";
473 params["csv-format"] = "false";
474 } else if (parameter == "code") {
475 params["name"] = "dhcp-message";
476 params["space"] = DHCP4_OPTION_SPACE"dhcp4";
477 params["code"] = param_value;
478 params["data"] = "ABCDEF0105";
479 params["csv-format"] = "false";
480 } else if (parameter == "data") {
481 params["name"] = "dhcp-message";
482 params["space"] = DHCP4_OPTION_SPACE"dhcp4";
483 params["code"] = "56";
484 params["data"] = param_value;
485 params["csv-format"] = "false";
486 } else if (parameter == "csv-format") {
487 params["name"] = "dhcp-message";
488 params["space"] = DHCP4_OPTION_SPACE"dhcp4";
489 params["code"] = "56";
490 params["data"] = "ABCDEF0105";
491 params["csv-format"] = param_value;
492 }
493 return (createConfigWithOption(params));
494 }
495
496 /// @brief Create simple configuration with single option.
497 ///
498 /// This function creates a configuration for a single option with
499 /// custom values for all parameters that describe the option.
500 ///
501 /// @params params map holding parameters and their values.
502 /// @return configuration string containing custom values of parameters
503 /// describing an option.
504 std::string createConfigWithOption(const std::map<std::string,
505 std::string>& params) {
506 std::ostringstream stream;
507 stream << "{ " << genIfaceConfig() << "," <<
508 "\"rebind-timer\": 2000, "
509 "\"renew-timer\": 1000, "
510 "\"subnet4\": [ { "
511 " \"id\": 1,"
512 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
513 " \"subnet\": \"192.0.2.0/24\", "
514 " \"option-data\": [ {";
515 bool first = true;
516 for (auto const& param : params) {
517 if (!first) {
518 stream << ", ";
519 } else {
520 // cppcheck-suppress unreadVariable
521 first = false;
522 }
523 if (param.first == "name") {
524 stream << "\"name\": \"" << param.second << "\"";
525 } else if (param.first == "space") {
526 stream << "\"space\": \"" << param.second << "\"";
527 } else if (param.first == "code") {
528 stream << "\"code\": " << param.second;
529 } else if (param.first == "data") {
530 stream << "\"data\": \"" << param.second << "\"";
531 } else if (param.first == "csv-format") {
532 stream << "\"csv-format\": " << param.second;
533 }
534 }
535 stream <<
536 " } ]"
537 " } ],"
538 "\"valid-lifetime\": 4000 }";
539 return (stream.str());
540 }
541
542 /// @brief Returns an option from the subnet.
543 ///
544 /// This function returns an option from a subnet to which the
545 /// specified subnet address belongs. The option is identified
546 /// by its code.
547 ///
548 /// @param subnet_address Address which belongs to the subnet from
549 /// which the option is to be returned.
550 /// @param option_code Code of the option to be returned.
551 /// @param expected_options_count Expected number of options in
552 /// the particular subnet.
553 ///
554 /// @return Descriptor of the option. If the descriptor holds a
555 /// NULL option pointer, it means that there was no such option
556 /// in the subnet.
557 OptionDescriptor
558 getOptionFromSubnet(const IOAddress& subnet_address,
559 const uint16_t option_code,
560 const uint16_t expected_options_count = 1) {
561 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
562 getCfgSubnets4()->selectSubnet(subnet_address);
563 if (!subnet) {
564 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 564, "Failed") = ::testing::Message()
<< "A subnet for the specified address "
565 << subnet_address
566 << " does not exist in Config Manager";
567 return (OptionDescriptor(false, false));
568 }
569 OptionContainerPtr options =
570 subnet->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
571 if (expected_options_count != options->size()) {
572 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 572, "Failed") = ::testing::Message()
<< "The number of options in the subnet '"
573 << subnet_address.toText() << "' is different "
574 " than expected number of options '"
575 << expected_options_count << "'";
576 }
577
578 // Get the search index. Index #1 is to search using option code.
579 const OptionContainerTypeIndex& idx = options->get<1>();
580
581 // Get the options for specified index. Expecting one option to be
582 // returned but in theory we may have multiple options with the same
583 // code so we get the range.
584 std::pair<OptionContainerTypeIndex::const_iterator,
585 OptionContainerTypeIndex::const_iterator> range =
586 idx.equal_range(option_code);
587 if (std::distance(range.first, range.second) > 1) {
588 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 588, "Failed") = ::testing::Message()
<< "There is more than one option having the"
589 " option code '" << option_code << "' in a subnet '"
590 << subnet_address.toText() << "'. Expected "
591 " at most one option";
592 } else if (std::distance(range.first, range.second) == 0) {
593 return (OptionDescriptor(OptionPtr(), false, false));
594 }
595
596 return (*range.first);
597 }
598
599 /// @brief Test invalid option parameter value.
600 ///
601 /// This test function constructs the simple configuration
602 /// string and injects invalid option configuration into it.
603 /// It expects that parser will fail with provided option code.
604 ///
605 /// @param param_value string holding invalid option parameter value
606 /// to be injected into configuration string.
607 /// @param parameter name of the parameter to be configured with
608 /// param_value (can be any of "name", "code", "data")
609 void testInvalidOptionParam(const std::string& param_value,
610 const std::string& parameter) {
611 ConstElementPtr x;
612 std::string config = createConfigWithOption(param_value, parameter);
613 ConstElementPtr json = parseDHCP4(config);
614 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_614; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_614; } } else gtest_label_testnothrow_614
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 614, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
615 checkResult(x, CONTROL_RESULT_ERROR);
616 EXPECT_TRUE(errorContainsPosition(x, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(x, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 616, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(x, \"<string>\")", "false", "true"
) .c_str()) = ::testing::Message()
;
617 CfgMgr::instance().clear();
618 }
619
620 /// @brief Test invalid option parameter value.
621 ///
622 /// This test function constructs the simple configuration
623 /// string and injects invalid option configuration into it.
624 /// It expects that parser will fail with provided option code.
625 ///
626 /// @param params Map of parameters defining an option.
627 void
628 testInvalidOptionParam(const std::map<std::string, std::string>& params) {
629 ConstElementPtr x;
630 std::string config = createConfigWithOption(params);
631 ConstElementPtr json = parseDHCP4(config);
632 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_632; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_632; } } else gtest_label_testnothrow_632
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 632, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
633 checkResult(x, CONTROL_RESULT_ERROR);
634 EXPECT_TRUE(errorContainsPosition(x, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(x, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 634, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(x, \"<string>\")", "false", "true"
) .c_str()) = ::testing::Message()
;
635 CfgMgr::instance().clear();
636 }
637
638 /// @brief Test option against given code and data.
639 ///
640 /// @param option_desc option descriptor that carries the option to
641 /// be tested.
642 /// @param expected_code expected code of the option.
643 /// @param expected_data expected data in the option.
644 /// @param expected_data_len length of the reference data.
645 /// @param extra_data if true extra data is allowed in an option
646 /// after tested data.
647 void testOption(const OptionDescriptor& option_desc,
648 uint16_t expected_code, const uint8_t* expected_data,
649 size_t expected_data_len,
650 bool extra_data = false) {
651 // Check if option descriptor contains valid option pointer.
652 ASSERT_TRUE(option_desc.option_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(option_desc.option_))
; else return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 652, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option_desc.option_", "false", "true") .c_str()) = ::testing
::Message()
;
653 // Verify option type.
654 EXPECT_EQ(expected_code, option_desc.option_->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("expected_code"
, "option_desc.option_->getType()", expected_code, option_desc
.option_->getType()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 654, gtest_ar.failure_message()) = ::testing::Message()
;
655 // We may have many different option types being created. Some of them
656 // have dedicated classes derived from Option class. In such case if
657 // we want to verify the option contents against expected_data we have
658 // to prepare raw buffer with the contents of the option. The easiest
659 // way is to call pack() which will prepare on-wire data.
660 util::OutputBuffer buf(option_desc.option_->getData().size());
661 option_desc.option_->pack(buf);
662 if (extra_data) {
663 // The length of the buffer must be at least equal to size of the
664 // reference data but it can sometimes be greater than that. This is
665 // because some options carry suboptions that increase the overall
666 // length.
667 ASSERT_GE(buf.getLength() - option_desc.option_->getHeaderLen(),switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::CmpHelperGE("buf.getLength() - option_desc.option_->getHeaderLen()"
, "expected_data_len", buf.getLength() - option_desc.option_->
getHeaderLen(), expected_data_len))) ; else return ::testing::
internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 668
, gtest_ar.failure_message()) = ::testing::Message()
668 expected_data_len)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::CmpHelperGE("buf.getLength() - option_desc.option_->getHeaderLen()"
, "expected_data_len", buf.getLength() - option_desc.option_->
getHeaderLen(), expected_data_len))) ; else return ::testing::
internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 668
, gtest_ar.failure_message()) = ::testing::Message()
;
669 } else {
670 ASSERT_EQ(buf.getLength() - option_desc.option_->getHeaderLen(),switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("buf.getLength() - option_desc.option_->getHeaderLen()"
, "expected_data_len", buf.getLength() - option_desc.option_->
getHeaderLen(), expected_data_len))) ; else return ::testing::
internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 671
, gtest_ar.failure_message()) = ::testing::Message()
671 expected_data_len)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("buf.getLength() - option_desc.option_->getHeaderLen()"
, "expected_data_len", buf.getLength() - option_desc.option_->
getHeaderLen(), expected_data_len))) ; else return ::testing::
internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 671
, gtest_ar.failure_message()) = ::testing::Message()
;
672 }
673 // Verify that the data is correct. Do not verify suboptions and a header.
674 const uint8_t* data = buf.getData();
675 EXPECT_EQ(0, memcmp(expected_data,switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("0", "memcmp(expected_data, data + option_desc.option_->getHeaderLen(), expected_data_len)"
, 0, memcmp(expected_data, data + option_desc.option_->getHeaderLen
(), expected_data_len)))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 677, gtest_ar.failure_message()) = ::testing::Message()
676 data + option_desc.option_->getHeaderLen(),switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("0", "memcmp(expected_data, data + option_desc.option_->getHeaderLen(), expected_data_len)"
, 0, memcmp(expected_data, data + option_desc.option_->getHeaderLen
(), expected_data_len)))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 677, gtest_ar.failure_message()) = ::testing::Message()
677 expected_data_len))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("0", "memcmp(expected_data, data + option_desc.option_->getHeaderLen(), expected_data_len)"
, 0, memcmp(expected_data, data + option_desc.option_->getHeaderLen
(), expected_data_len)))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 677, gtest_ar.failure_message()) = ::testing::Message()
;
678 }
679
680 /// @brief Test option configuration.
681 ///
682 /// This function creates a configuration for a specified option using
683 /// a map of parameters specified as the argument. The map holds
684 /// name/value pairs which identifies option's configuration parameters:
685 /// - name
686 /// - space
687 /// - code
688 /// - data
689 /// - csv-format.
690 /// This function applies a new server configuration and checks that the
691 /// option being configured is inserted into CfgMgr. The raw contents of
692 /// this option are compared with the binary data specified as expected
693 /// data passed to this function.
694 ///
695 /// @param params Map of parameters defining an option.
696 /// @param option_code Option code.
697 /// @param expected_data Array containing binary data expected to be stored
698 /// in the configured option.
699 /// @param expected_data_len Length of the array holding reference data.
700 void testConfiguration(const std::map<std::string, std::string>& params,
701 const uint16_t option_code,
702 const uint8_t* expected_data,
703 const size_t expected_data_len) {
704 CfgMgr::instance().clear();
705
706 std::string config = createConfigWithOption(params);
707 ASSERT_TRUE(executeConfiguration(config, "parse option configuration"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(executeConfiguration(
config, "parse option configuration"))) ; else return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 707
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "executeConfiguration(config, \"parse option configuration\")"
, "false", "true") .c_str()) = ::testing::Message()
;
708
709 // The subnet should now hold one option with the specified option code.
710 OptionDescriptor desc =
711 getOptionFromSubnet(IOAddress("192.0.2.24"), option_code);
712 ASSERT_TRUE(desc.option_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(desc.option_)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 712, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc.option_", "false", "true") .c_str()) = ::testing::Message
()
;
713 testOption(desc, option_code, expected_data, expected_data_len);
714 CfgMgr::instance().clear();
715 }
716
717 /// @brief Parse and Execute configuration
718 ///
719 /// Parses a configuration and executes a configuration of the server.
720 /// If the operation fails, the current test will register a failure.
721 ///
722 /// @param config Configuration to parse
723 /// @param operation Operation being performed. In the case of an error,
724 /// the error text will include the string "unable to <operation>.".
725 ///
726 /// @return true if the configuration succeeded, false if not. In the
727 /// latter case, a failure will have been added to the current test.
728 bool
729 executeConfiguration(const std::string& config, const char* operation) {
730 CfgMgr::instance().clear();
731 ConstElementPtr json;
732 ConstElementPtr status;
733 try {
734 json = parseJSON(config);
735 status = Dhcpv4SrvTest::configure(*srv_, json);
736 } catch (const std::exception& ex) {
737 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 737, "Failed") = ::testing::Message()
<< "Unable to " << operation << ". "
738 << "The following configuration was used: " << std::endl
739 << config << std::endl
740 << " and the following error message was returned:"
741 << ex.what() << std::endl;
742 return (false);
743 }
744
745 // The status object must not be NULL
746 if (!status) {
747 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 747, "Failed") = ::testing::Message()
<< "Unable to " << operation << ". "
748 << "The configuration function returned a null pointer.";
749 return (false);
750 }
751
752 // Store the answer if we need it.
753
754 // Returned value should be 0 (configuration success)
755 comment_ = parseAnswerText(rcode_, status);
756 if (rcode_ != 0) {
757 string reason = "";
758 if (comment_) {
759 reason = string(" (") + comment_->stringValue() + string(")");
760 }
761 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 761, "Failed") = ::testing::Message()
<< "Unable to " << operation << ". "
762 << "The configuration function returned error code "
763 << rcode_ << reason;
764 return (false);
765 }
766
767 return (true);
768 }
769
770 /// @brief Reset configuration database.
771 ///
772 /// This function resets configuration data base by removing all subnets
773 /// option-data, and hooks libraries. The reset must be performed after each
774 /// test to make sure that contents of the database do not affect the
775 /// results of subsequent tests.
776 void resetConfiguration() {
777 // The default setting is to listen on all interfaces. In order to
778 // properly test interface configuration we disable listening on
779 // all interfaces before each test and later check that this setting
780 // has been overridden by the configuration used in the test.
781 CfgMgr::instance().clear();
782 string config = "{ \"interfaces-config\": {"
783 " \"interfaces\": [ ]"
784 "},"
785 "\"hooks-libraries\": [ ],"
786 "\"rebind-timer\": 2000, "
787 "\"renew-timer\": 1000, "
788 "\"valid-lifetime\": 4000, "
789 "\"subnet4\": [ ], "
790 "\"dhcp-ddns\": { \"enable-updates\" : false }, "
791 "\"option-def\": [ ], "
792 "\"option-data\": [ ] }";
793 static_cast<void>(executeConfiguration(config,
794 "reset configuration database"));
795 CfgMgr::instance().clearStagingConfiguration();
796 }
797
798 /// @brief Retrieve an option associated with a host.
799 ///
800 /// The option is retrieved from the "dhcp4" option space.
801 ///
802 /// @param host Reference to a host for which an option should be retrieved.
803 /// @param option_code Option code.
804 /// @tparam ReturnType Type of the pointer object returned.
805 ///
806 /// @return Pointer to an option or NULL pointer if not found.
807 template<typename ReturnType>
808 ReturnType
809 retrieveOption(const Host& host, const uint16_t option_code) const {
810 return (retrieveOption<ReturnType>(host, DHCP4_OPTION_SPACE"dhcp4", option_code));
811 }
812
813 /// @brief Retrieve an option associated with a host.
814 ///
815 /// @param host Reference to a host for which an option should be retrieved.
816 /// @param space Option space from which option should be retrieved.
817 /// @param option_code Option code.
818 /// @tparam ReturnType Type of the pointer object returned.
819 ///
820 /// @return Pointer to an option or NULL pointer if not found.
821 template<typename ReturnType>
822 ReturnType
823 retrieveOption(const Host& host, const std::string& space,
824 const uint16_t option_code) const {
825 ConstCfgOptionPtr cfg_option = host.getCfgOption4();
826 if (cfg_option) {
827 OptionDescriptor opt_desc = cfg_option->get(space, option_code);
828 if (opt_desc.option_) {
829 return (boost::dynamic_pointer_cast<
830 typename ReturnType::element_type>(opt_desc.option_));
831 }
832 }
833 return (ReturnType());
834 }
835
836 /// @brief Checks if specified subnet is part of the collection
837 ///
838 /// @tparam CollectionType type of subnet4 collections i.e.
839 /// either Subnet4SimpleCollection or Subnet4Collection
840 /// @param col collection of subnets to be inspected
841 /// @param subnet text notation (e.g. 192.0.2.0/24)
842 /// @param t1 expected renew-timer value
843 /// @param t2 expected rebind-timer value
844 /// @param valid expected valid-lifetime value
845 /// @param min_valid expected min-valid-lifetime value
846 /// (0 (default) means same as valid)
847 /// @param max_valid expected max-valid-lifetime value
848 /// (0 (default) means same as valid)
849 /// @return the subnet that was examined
850 template <typename CollectionType>
851 Subnet4Ptr
852 checkSubnet(const CollectionType& col, std::string subnet,
853 uint32_t t1, uint32_t t2, uint32_t valid,
854 uint32_t min_valid = 0, uint32_t max_valid = 0) {
855 auto const& index = col.template get<SubnetPrefixIndexTag>();
856 auto subnet_it = index.find(subnet);
857 if (subnet_it == index.cend()) {
858 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 858, "Failed") = ::testing::Message()
<< "Unable to find expected subnet " << subnet;
859 return (Subnet4Ptr());
860 }
861 Subnet4Ptr s = *subnet_it;
862
863 EXPECT_EQ(t1, s->getT1().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("t1", "s->getT1().get()"
, t1, s->getT1().get()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 863, gtest_ar.failure_message()) = ::testing::Message()
;
864 EXPECT_EQ(t2, s->getT2().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("t2", "s->getT2().get()"
, t2, s->getT2().get()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 864, gtest_ar.failure_message()) = ::testing::Message()
;
865 EXPECT_EQ(valid, s->getValid().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("valid", "s->getValid().get()"
, valid, s->getValid().get()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 865, gtest_ar.failure_message()) = ::testing::Message()
;
866 EXPECT_EQ(min_valid ? min_valid : valid, s->getValid().getMin())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("min_valid ? min_valid : valid"
, "s->getValid().getMin()", min_valid ? min_valid : valid,
s->getValid().getMin()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 866, gtest_ar.failure_message()) = ::testing::Message()
;
867 EXPECT_EQ(max_valid ? max_valid : valid, s->getValid().getMax())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("max_valid ? max_valid : valid"
, "s->getValid().getMax()", max_valid ? max_valid : valid,
s->getValid().getMax()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 867, gtest_ar.failure_message()) = ::testing::Message()
;
868
869 return (s);
870 }
871
872 /// @brief This utility method attempts to configure using specified
873 /// config and then returns requested pool from requested subnet
874 ///
875 /// @param config configuration to be applied
876 /// @param subnet_index index of the subnet to be returned (0 - the first subnet)
877 /// @param pool_index index of the pool within a subnet (0 - the first pool)
878 /// @param pool [out] Pool pointer will be stored here (if found)
879 void getPool(const std::string& config, size_t subnet_index,
880 size_t pool_index, PoolPtr& pool) {
881 ConstElementPtr status;
882 ConstElementPtr json;
883
884 EXPECT_NO_THROW(json = parseDHCP4(config, true))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config, true); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_884
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_884
; } } else gtest_label_testnothrow_884 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 884, ("Expected: " "json = parseDHCP4(config, true)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
885 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_885; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_885; } } else gtest_label_testnothrow_885
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 885, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
886 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 886, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
887 checkResult(status, 0);
888
889 ConstCfgSubnets4Ptr subnets4 = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
890 ASSERT_TRUE(subnets4)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnets4)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 890, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets4", "false", "true") .c_str()) = ::testing::Message
()
;
891
892 const Subnet4Collection* subnets = subnets4->getAll();
893 ASSERT_TRUE(subnets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnets)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 893, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
894 ASSERT_GE(subnets->size(), subnet_index + 1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::CmpHelperGE("subnets->size()"
, "subnet_index + 1", subnets->size(), subnet_index + 1)))
; else return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 894, gtest_ar.failure_message()) = ::testing::Message()
;
895
896 auto subnet = subnets->begin();
897 // std::advance is not available for subnets iterators.
898 for (size_t i = 0; i < subnet_index; ++i) {
899 subnet = std::next(subnet);
900 }
901 const PoolCollection pools = (*subnet)->getPools(Lease::TYPE_V4);
902 ASSERT_GE(pools.size(), pool_index + 1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::CmpHelperGE("pools.size()",
"pool_index + 1", pools.size(), pool_index + 1))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 902, gtest_ar.failure_message()) = ::testing::Message()
;
903
904 pool = pools.at(pool_index);
905 EXPECT_TRUE(pool)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool)) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 905
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
906 }
907
908 /// @brief Tests if the current config has a given global parameter value
909 /// @param name name of the global parameter expected to exist
910 /// @param value expected value of the global parameter
911 template <typename ValueType>
912 void checkGlobal(const std::string name, ValueType value) {
913 ConstElementPtr param;
914 ConstElementPtr exp_value;
915 param = CfgMgr::instance().getStagingCfg()->getConfiguredGlobal(name);
916 ASSERT_TRUE(param)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(param)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 916, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "param", "false", "true") .c_str()) = ::testing::Message()
<< "global: " << name << ", expected but not found";
917 ASSERT_NO_THROW(exp_value = Element::create(value))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
exp_value = Element::create(value); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_917
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_917
; } } else gtest_label_testnothrow_917 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 917, ("Expected: " "exp_value = Element::create(value)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
918 EXPECT_TRUE(param->equals(*exp_value))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(param->equals(*exp_value
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 918, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "param->equals(*exp_value)", "false", "true") .c_str()) =
::testing::Message()
<< "global: " << name
919 << isc::data::prettyPrint(param)
920 << " does not match expected: "
921 << isc::data::prettyPrint(exp_value);
922 }
923
924 int rcode_; ///< Return code from element parsing
925 boost::scoped_ptr<Dhcpv4Srv> srv_; ///< Instance of the Dhcpv4Srv used during tests
926 ConstElementPtr comment_; ///< Comment (see @ref isc::config::parseAnswer)
927 string valid_iface_; ///< Valid network interface name (present in system)
928 string bogus_iface_; ///< invalid network interface name (not in system)
929 isc::dhcp::ClientClasses classify_; ///< used in client classification
930};
931
932/// The goal of this test is to verify that the code accepts only
933/// valid commands and malformed or unsupported parameters are rejected.
934TEST_F(Dhcp4ParserTest, bogusCommand)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("bogusCommand") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_bogusCommand_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_bogusCommand_Test() = default; ~Dhcp4ParserTest_bogusCommand_Test
() override = default; Dhcp4ParserTest_bogusCommand_Test (const
Dhcp4ParserTest_bogusCommand_Test &) = delete; Dhcp4ParserTest_bogusCommand_Test
& operator=( const Dhcp4ParserTest_bogusCommand_Test &
) = delete; Dhcp4ParserTest_bogusCommand_Test (Dhcp4ParserTest_bogusCommand_Test
&&) noexcept = delete; Dhcp4ParserTest_bogusCommand_Test
& operator=( Dhcp4ParserTest_bogusCommand_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_bogusCommand_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "bogusCommand", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 934
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 934), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 934), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_bogusCommand_Test
>); void Dhcp4ParserTest_bogusCommand_Test::TestBody()
{
935
936 ConstElementPtr x;
937
938 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_,switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, parseJSON("{\"bogus\": 5}"
)); } else static_assert(true, ""); } catch (std::exception const
& e) { gtest_msg.value = "it throws "; gtest_msg.value +=
::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testnothrow_939; } catch (...
) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_939
; } } else gtest_label_testnothrow_939 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 939, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, parseJSON(\"{\\\"bogus\\\": 5}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
939 parseJSON("{\"bogus\": 5}")))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, parseJSON("{\"bogus\": 5}"
)); } else static_assert(true, ""); } catch (std::exception const
& e) { gtest_msg.value = "it throws "; gtest_msg.value +=
::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testnothrow_939; } catch (...
) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_939
; } } else gtest_label_testnothrow_939 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 939, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, parseJSON(\"{\\\"bogus\\\": 5}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
940
941 // returned value must be 1 (configuration parse error)
942 checkResult(x, CONTROL_RESULT_ERROR);
943
944 // it should be refused by syntax too
945 EXPECT_THROW(parseDHCP4("{\"bogus\": 5}"), Dhcp4ParseError)switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { bool gtest_caught_expected = false; try { if (
::testing::internal::AlwaysTrue()) { parseDHCP4("{\"bogus\": 5}"
); } else static_assert(true, ""); } catch (Dhcp4ParseError const
&) { gtest_caught_expected = true; } catch (typename std::
conditional< std::is_same<typename std::remove_cv<typename
std::remove_reference< Dhcp4ParseError>::type>::type
, std::exception>::value, const ::testing::internal::NeverThrown
&, const std::exception&>::type e) { gtest_msg.value
= "Expected: " "parseDHCP4(\"{\\\"bogus\\\": 5}\")" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws "; gtest_msg.value
+= ::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testthrow_945; } catch (...
) { gtest_msg.value = "Expected: " "parseDHCP4(\"{\\\"bogus\\\": 5}\")"
" throws an exception of type " "Dhcp4ParseError" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_945; } if (!gtest_caught_expected
) { gtest_msg.value = "Expected: " "parseDHCP4(\"{\\\"bogus\\\": 5}\")"
" throws an exception of type " "Dhcp4ParseError" ".\n Actual: it throws nothing."
; goto gtest_label_testthrow_945; } } else gtest_label_testthrow_945
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 945, gtest_msg.value.c_str()) = ::testing::Message()
;
946}
947
948/// The goal of this test is to verify empty interface-config is accepted.
949TEST_F(Dhcp4ParserTest, emptyInterfaceConfig)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("emptyInterfaceConfig") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_emptyInterfaceConfig_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_emptyInterfaceConfig_Test() = default
; ~Dhcp4ParserTest_emptyInterfaceConfig_Test() override = default
; Dhcp4ParserTest_emptyInterfaceConfig_Test (const Dhcp4ParserTest_emptyInterfaceConfig_Test
&) = delete; Dhcp4ParserTest_emptyInterfaceConfig_Test &
operator=( const Dhcp4ParserTest_emptyInterfaceConfig_Test &
) = delete; Dhcp4ParserTest_emptyInterfaceConfig_Test (Dhcp4ParserTest_emptyInterfaceConfig_Test
&&) noexcept = delete; Dhcp4ParserTest_emptyInterfaceConfig_Test
& operator=( Dhcp4ParserTest_emptyInterfaceConfig_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_emptyInterfaceConfig_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "emptyInterfaceConfig", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 949), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 949), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 949), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_emptyInterfaceConfig_Test
>); void Dhcp4ParserTest_emptyInterfaceConfig_Test::TestBody
()
{
950
951 ConstElementPtr json;
952 EXPECT_NO_THROW(json = parseDHCP4("{ "switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4("{ " "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, "
"\"valid-lifetime\": 4000 }"); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_955
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_955
; } } else gtest_label_testnothrow_955 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 955, ("Expected: " "json = parseDHCP4(\"{ \" \"\\\"rebind-timer\\\": 2000, \" \"\\\"renew-timer\\\": 1000, \" \"\\\"valid-lifetime\\\": 4000 }\")"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
953 "\"rebind-timer\": 2000, "switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4("{ " "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, "
"\"valid-lifetime\": 4000 }"); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_955
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_955
; } } else gtest_label_testnothrow_955 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 955, ("Expected: " "json = parseDHCP4(\"{ \" \"\\\"rebind-timer\\\": 2000, \" \"\\\"renew-timer\\\": 1000, \" \"\\\"valid-lifetime\\\": 4000 }\")"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
954 "\"renew-timer\": 1000, "switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4("{ " "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, "
"\"valid-lifetime\": 4000 }"); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_955
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_955
; } } else gtest_label_testnothrow_955 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 955, ("Expected: " "json = parseDHCP4(\"{ \" \"\\\"rebind-timer\\\": 2000, \" \"\\\"renew-timer\\\": 1000, \" \"\\\"valid-lifetime\\\": 4000 }\")"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
955 "\"valid-lifetime\": 4000 }"))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4("{ " "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, "
"\"valid-lifetime\": 4000 }"); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_955
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_955
; } } else gtest_label_testnothrow_955 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 955, ("Expected: " "json = parseDHCP4(\"{ \" \"\\\"rebind-timer\\\": 2000, \" \"\\\"renew-timer\\\": 1000, \" \"\\\"valid-lifetime\\\": 4000 }\")"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
956
957 ConstElementPtr status;
958 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_958; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_958; } } else gtest_label_testnothrow_958
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 958, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
959
960 // returned value should be 0 (success)
961 checkResult(status, 0);
962}
963
964/// Check that valid-lifetime must be between min-valid-lifetime and
965/// max-valid-lifetime when a bound is specified, *AND* a subnet is
966/// specified (boundary check is done when lifetimes are applied).
967TEST_F(Dhcp4ParserTest, outBoundValidLifetime)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("outBoundValidLifetime") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_outBoundValidLifetime_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_outBoundValidLifetime_Test() = default
; ~Dhcp4ParserTest_outBoundValidLifetime_Test() override = default
; Dhcp4ParserTest_outBoundValidLifetime_Test (const Dhcp4ParserTest_outBoundValidLifetime_Test
&) = delete; Dhcp4ParserTest_outBoundValidLifetime_Test &
operator=( const Dhcp4ParserTest_outBoundValidLifetime_Test &
) = delete; Dhcp4ParserTest_outBoundValidLifetime_Test (Dhcp4ParserTest_outBoundValidLifetime_Test
&&) noexcept = delete; Dhcp4ParserTest_outBoundValidLifetime_Test
& operator=( Dhcp4ParserTest_outBoundValidLifetime_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_outBoundValidLifetime_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "outBoundValidLifetime", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 967), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 967), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 967), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_outBoundValidLifetime_Test
>); void Dhcp4ParserTest_outBoundValidLifetime_Test::TestBody
()
{
968
969 string too_small = "{ " + genIfaceConfig() + ","
970 "\"subnet4\": [ { "
971 " \"id\": 1,"
972 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
973 " \"subnet\": \"192.0.2.0/24\" } ],"
974 "\"valid-lifetime\": 1000, \"min-valid-lifetime\": 2000 }";
975
976 ConstElementPtr json;
977 ASSERT_NO_THROW(json = parseDHCP4(too_small))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(too_small); } else static_assert(true, "")
; } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_977
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_977
; } } else gtest_label_testnothrow_977 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 977, ("Expected: " "json = parseDHCP4(too_small)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
978
979 ConstElementPtr status;
980 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_980; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_980; } } else gtest_label_testnothrow_980
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 980, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
981 string expected = "subnet configuration failed: "
982 "the value of min-valid-lifetime (2000) is not "
983 "less than (default) valid-lifetime (1000)";
984 checkResult(status, CONTROL_RESULT_ERROR, expected);
985 resetConfiguration();
986
987 string too_large = "{ " + genIfaceConfig() + ","
988 "\"subnet4\": [ { "
989 " \"id\": 1,"
990 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
991 " \"subnet\": \"192.0.2.0/24\" } ],"
992 "\"valid-lifetime\": 2000, \"max-valid-lifetime\": 1000 }";
993
994 ASSERT_NO_THROW(json = parseDHCP4(too_large))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(too_large); } else static_assert(true, "")
; } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_994
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_994
; } } else gtest_label_testnothrow_994 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 994, ("Expected: " "json = parseDHCP4(too_large)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
995 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_995; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_995; } } else gtest_label_testnothrow_995
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 995, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
996 expected = "subnet configuration failed: "
997 "the value of (default) valid-lifetime (2000) is not "
998 "less than max-valid-lifetime (1000)";
999 checkResult(status, CONTROL_RESULT_ERROR, expected);
1000 resetConfiguration();
1001
1002 string before = "{ " + genIfaceConfig() + ","
1003 "\"subnet4\": [ { "
1004 " \"id\": 1,"
1005 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1006 " \"subnet\": \"192.0.2.0/24\" } ],"
1007 "\"valid-lifetime\": 1000, \"min-valid-lifetime\": 2000, "
1008 "\"max-valid-lifetime\": 4000 }";
1009
1010 ASSERT_NO_THROW(json = parseDHCP4(before))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(before); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1010
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1010
; } } else gtest_label_testnothrow_1010 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1010, ("Expected: " "json = parseDHCP4(before)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1011 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1011; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1011; } } else gtest_label_testnothrow_1011
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1011, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1012 expected = "subnet configuration failed: "
1013 "the value of (default) valid-lifetime (1000) is not "
1014 "between min-valid-lifetime (2000) and max-valid-lifetime (4000)";
1015 checkResult(status, CONTROL_RESULT_ERROR, expected);
1016 resetConfiguration();
1017
1018 string after = "{ " + genIfaceConfig() + ","
1019 "\"subnet4\": [ { "
1020 " \"id\": 1,"
1021 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1022 " \"subnet\": \"192.0.2.0/24\" } ],"
1023 "\"valid-lifetime\": 5000, \"min-valid-lifetime\": 1000, "
1024 "\"max-valid-lifetime\": 4000 }";
1025
1026 ASSERT_NO_THROW(json = parseDHCP4(after))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(after); } else static_assert(true, ""); } catch
(std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1026
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1026
; } } else gtest_label_testnothrow_1026 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1026, ("Expected: " "json = parseDHCP4(after)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1027 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1027; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1027; } } else gtest_label_testnothrow_1027
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1027, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1028 expected = "subnet configuration failed: "
1029 "the value of (default) valid-lifetime (5000) is not "
1030 "between min-valid-lifetime (1000) and max-valid-lifetime (4000)";
1031 checkResult(status, CONTROL_RESULT_ERROR, expected);
1032 resetConfiguration();
1033
1034 string crossed = "{ " + genIfaceConfig() + ","
1035 "\"subnet4\": [ { "
1036 " \"id\": 1,"
1037 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1038 " \"subnet\": \"192.0.2.0/24\" } ],"
1039 "\"valid-lifetime\": 1500, \"min-valid-lifetime\": 2000, "
1040 "\"max-valid-lifetime\": 1000 }";
1041
1042 ASSERT_NO_THROW(json = parseDHCP4(crossed))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(crossed); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1042
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1042
; } } else gtest_label_testnothrow_1042 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1042, ("Expected: " "json = parseDHCP4(crossed)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1043 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1043; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1043; } } else gtest_label_testnothrow_1043
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1043, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1044 expected = "subnet configuration failed: "
1045 "the value of min-valid-lifetime (2000) is not "
1046 "less than max-valid-lifetime (1000)";
1047 checkResult(status, CONTROL_RESULT_ERROR, expected);
1048}
1049
1050/// Check that valid-lifetime must be between min-valid-lifetime and
1051/// max-valid-lifetime when a bound is specified. Check on global
1052/// parameters only.
1053TEST_F(Dhcp4ParserTest, outBoundGlobalValidLifetime)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("outBoundGlobalValidLifetime") > 1
, "test_name must not be empty"); class Dhcp4ParserTest_outBoundGlobalValidLifetime_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_outBoundGlobalValidLifetime_Test
() = default; ~Dhcp4ParserTest_outBoundGlobalValidLifetime_Test
() override = default; Dhcp4ParserTest_outBoundGlobalValidLifetime_Test
(const Dhcp4ParserTest_outBoundGlobalValidLifetime_Test &
) = delete; Dhcp4ParserTest_outBoundGlobalValidLifetime_Test &
operator=( const Dhcp4ParserTest_outBoundGlobalValidLifetime_Test
&) = delete; Dhcp4ParserTest_outBoundGlobalValidLifetime_Test
(Dhcp4ParserTest_outBoundGlobalValidLifetime_Test &&
) noexcept = delete; Dhcp4ParserTest_outBoundGlobalValidLifetime_Test
& operator=( Dhcp4ParserTest_outBoundGlobalValidLifetime_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_outBoundGlobalValidLifetime_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "outBoundGlobalValidLifetime", nullptr, nullptr, ::testing::
internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1053), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1053), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1053), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_outBoundGlobalValidLifetime_Test
>); void Dhcp4ParserTest_outBoundGlobalValidLifetime_Test::
TestBody()
{
1054
1055 string too_small = "{ " + genIfaceConfig() + ","
1056 "\"valid-lifetime\": 1000, \"min-valid-lifetime\": 2000 }";
1057
1058 ConstElementPtr json;
1059 ASSERT_NO_THROW(json = parseDHCP4(too_small))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(too_small); } else static_assert(true, "")
; } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1059
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1059
; } } else gtest_label_testnothrow_1059 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1059, ("Expected: " "json = parseDHCP4(too_small)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1060
1061 ConstElementPtr status;
1062 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1062; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1062; } } else gtest_label_testnothrow_1062
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1062, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1063 string expected =
1064 "the value of min-valid-lifetime (2000) is not "
1065 "less than (default) valid-lifetime (1000)";
1066 checkResult(status, CONTROL_RESULT_ERROR, expected);
1067 resetConfiguration();
1068
1069 string too_large = "{ " + genIfaceConfig() + ","
1070 "\"valid-lifetime\": 2000, \"max-valid-lifetime\": 1000 }";
1071
1072 ASSERT_NO_THROW(json = parseDHCP4(too_large))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(too_large); } else static_assert(true, "")
; } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1072
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1072
; } } else gtest_label_testnothrow_1072 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1072, ("Expected: " "json = parseDHCP4(too_large)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1073 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1073; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1073; } } else gtest_label_testnothrow_1073
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1073, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1074 expected =
1075 "the value of (default) valid-lifetime (2000) is not "
1076 "less than max-valid-lifetime (1000)";
1077 checkResult(status, CONTROL_RESULT_ERROR, expected);
1078 resetConfiguration();
1079
1080 string before = "{ " + genIfaceConfig() + ","
1081 "\"valid-lifetime\": 1000, \"min-valid-lifetime\": 2000, "
1082 "\"max-valid-lifetime\": 4000 }";
1083
1084 ASSERT_NO_THROW(json = parseDHCP4(before))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(before); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1084
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1084
; } } else gtest_label_testnothrow_1084 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1084, ("Expected: " "json = parseDHCP4(before)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1085 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1085; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1085; } } else gtest_label_testnothrow_1085
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1085, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1086 expected =
1087 "the value of (default) valid-lifetime (1000) is not "
1088 "between min-valid-lifetime (2000) and max-valid-lifetime (4000)";
1089 checkResult(status, CONTROL_RESULT_ERROR, expected);
1090 resetConfiguration();
1091
1092 string after = "{ " + genIfaceConfig() + ","
1093 "\"valid-lifetime\": 5000, \"min-valid-lifetime\": 1000, "
1094 "\"max-valid-lifetime\": 4000 }";
1095
1096 ASSERT_NO_THROW(json = parseDHCP4(after))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(after); } else static_assert(true, ""); } catch
(std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1096
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1096
; } } else gtest_label_testnothrow_1096 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1096, ("Expected: " "json = parseDHCP4(after)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1097 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1097; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1097; } } else gtest_label_testnothrow_1097
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1097, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1098 expected =
1099 "the value of (default) valid-lifetime (5000) is not "
1100 "between min-valid-lifetime (1000) and max-valid-lifetime (4000)";
1101 checkResult(status, CONTROL_RESULT_ERROR, expected);
1102 resetConfiguration();
1103
1104 string crossed = "{ " + genIfaceConfig() + ","
1105 "\"valid-lifetime\": 1500, \"min-valid-lifetime\": 2000, "
1106 "\"max-valid-lifetime\": 1000 }";
1107
1108 ASSERT_NO_THROW(json = parseDHCP4(crossed))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(crossed); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1108
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1108
; } } else gtest_label_testnothrow_1108 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1108, ("Expected: " "json = parseDHCP4(crossed)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1109 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1109; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1109; } } else gtest_label_testnothrow_1109
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1109, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1110 expected =
1111 "the value of min-valid-lifetime (2000) is not "
1112 "less than max-valid-lifetime (1000)";
1113 checkResult(status, CONTROL_RESULT_ERROR, expected);
1114}
1115
1116/// Check that the renew-timer doesn't have to be specified, in which case
1117/// it is marked unspecified in the Subnet.
1118TEST_F(Dhcp4ParserTest, unspecifiedRenewTimer)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("unspecifiedRenewTimer") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_unspecifiedRenewTimer_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_unspecifiedRenewTimer_Test() = default
; ~Dhcp4ParserTest_unspecifiedRenewTimer_Test() override = default
; Dhcp4ParserTest_unspecifiedRenewTimer_Test (const Dhcp4ParserTest_unspecifiedRenewTimer_Test
&) = delete; Dhcp4ParserTest_unspecifiedRenewTimer_Test &
operator=( const Dhcp4ParserTest_unspecifiedRenewTimer_Test &
) = delete; Dhcp4ParserTest_unspecifiedRenewTimer_Test (Dhcp4ParserTest_unspecifiedRenewTimer_Test
&&) noexcept = delete; Dhcp4ParserTest_unspecifiedRenewTimer_Test
& operator=( Dhcp4ParserTest_unspecifiedRenewTimer_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_unspecifiedRenewTimer_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "unspecifiedRenewTimer", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1118), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1118), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1118), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_unspecifiedRenewTimer_Test
>); void Dhcp4ParserTest_unspecifiedRenewTimer_Test::TestBody
()
{
1119
1120 string config = "{ " + genIfaceConfig() + ","
1121 "\"rebind-timer\": 2000, "
1122 "\"subnet4\": [ { "
1123 " \"id\": 1,"
1124 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1125 " \"subnet\": \"192.0.2.0/24\" } ],"
1126 "\"valid-lifetime\": 4000 }";
1127
1128 ConstElementPtr json;
1129 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1129
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1129
; } } else gtest_label_testnothrow_1129 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1129, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1130 extractConfig(config);
1131
1132 ConstElementPtr status;
1133 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1133; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1133; } } else gtest_label_testnothrow_1133
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1133, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1134
1135 // returned value should be 0 (success)
1136 checkResult(status, 0);
1137
1138 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
1139 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
1140 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1140, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
1141
1142 EXPECT_TRUE(subnet->getT1().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->getT1().unspecified
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1142, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getT1().unspecified()", "false", "true") .c_str
()) = ::testing::Message()
;
1143 EXPECT_FALSE(subnet->getT2().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getT2().
unspecified()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1143, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getT2().unspecified()", "true", "false") .c_str
()) = ::testing::Message()
;
1144 EXPECT_EQ(2000U, subnet->getT2().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2000U", "subnet->getT2().get()"
, 2000U, subnet->getT2().get()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1144, gtest_ar.failure_message()) = ::testing::Message()
;
1145 EXPECT_EQ(4000U, subnet->getValid().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("4000U", "subnet->getValid().get()"
, 4000U, subnet->getValid().get()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1145, gtest_ar.failure_message()) = ::testing::Message()
;
1146
1147 // Check that subnet-id is 1
1148 EXPECT_EQ(1U, subnet->getID())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "subnet->getID()"
, 1U, subnet->getID()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1148, gtest_ar.failure_message()) = ::testing::Message()
;
1149}
1150
1151/// Check that the rebind-timer doesn't have to be specified, in which case
1152/// it is marked unspecified in the Subnet.
1153TEST_F(Dhcp4ParserTest, unspecifiedRebindTimer)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("unspecifiedRebindTimer") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_unspecifiedRebindTimer_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_unspecifiedRebindTimer_Test
() = default; ~Dhcp4ParserTest_unspecifiedRebindTimer_Test() override
= default; Dhcp4ParserTest_unspecifiedRebindTimer_Test (const
Dhcp4ParserTest_unspecifiedRebindTimer_Test &) = delete;
Dhcp4ParserTest_unspecifiedRebindTimer_Test & operator=(
const Dhcp4ParserTest_unspecifiedRebindTimer_Test &) = delete
; Dhcp4ParserTest_unspecifiedRebindTimer_Test (Dhcp4ParserTest_unspecifiedRebindTimer_Test
&&) noexcept = delete; Dhcp4ParserTest_unspecifiedRebindTimer_Test
& operator=( Dhcp4ParserTest_unspecifiedRebindTimer_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_unspecifiedRebindTimer_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "unspecifiedRebindTimer", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1153), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1153), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1153), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_unspecifiedRebindTimer_Test
>); void Dhcp4ParserTest_unspecifiedRebindTimer_Test::TestBody
()
{
1154
1155 string config = "{ " + genIfaceConfig() + ","
1156 "\"renew-timer\": 1000, "
1157 "\"subnet4\": [ { "
1158 " \"id\": 1,"
1159 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1160 " \"subnet\": \"192.0.2.0/24\" } ],"
1161 "\"valid-lifetime\": 4000 }";
1162
1163 ConstElementPtr json;
1164 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1164
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1164
; } } else gtest_label_testnothrow_1164 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1164, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1165 extractConfig(config);
1166
1167 ConstElementPtr status;
1168 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1168; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1168; } } else gtest_label_testnothrow_1168
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1168, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1169
1170 // returned value should be 0 (success)
1171 checkResult(status, 0);
1172
1173 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
1174 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
1175 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1175, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
1176 EXPECT_FALSE(subnet->getT1().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getT1().
unspecified()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1176, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getT1().unspecified()", "true", "false") .c_str
()) = ::testing::Message()
;
1177 EXPECT_EQ(1000U, subnet->getT1().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1000U", "subnet->getT1().get()"
, 1000U, subnet->getT1().get()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1177, gtest_ar.failure_message()) = ::testing::Message()
;
1178 EXPECT_TRUE(subnet->getT2().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->getT2().unspecified
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1178, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getT2().unspecified()", "false", "true") .c_str
()) = ::testing::Message()
;
1179 EXPECT_EQ(4000U, subnet->getValid().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("4000U", "subnet->getValid().get()"
, 4000U, subnet->getValid().get()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1179, gtest_ar.failure_message()) = ::testing::Message()
;
1180
1181 // Check that subnet-id is 1
1182 EXPECT_EQ(1U, subnet->getID())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "subnet->getID()"
, 1U, subnet->getID()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1182, gtest_ar.failure_message()) = ::testing::Message()
;
1183}
1184
1185/// The goal of this test is to verify if configuration without any
1186/// subnets defined can be accepted.
1187TEST_F(Dhcp4ParserTest, emptySubnet)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("emptySubnet") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_emptySubnet_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_emptySubnet_Test() = default; ~Dhcp4ParserTest_emptySubnet_Test
() override = default; Dhcp4ParserTest_emptySubnet_Test (const
Dhcp4ParserTest_emptySubnet_Test &) = delete; Dhcp4ParserTest_emptySubnet_Test
& operator=( const Dhcp4ParserTest_emptySubnet_Test &
) = delete; Dhcp4ParserTest_emptySubnet_Test (Dhcp4ParserTest_emptySubnet_Test
&&) noexcept = delete; Dhcp4ParserTest_emptySubnet_Test
& operator=( Dhcp4ParserTest_emptySubnet_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_emptySubnet_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "emptySubnet", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 1187
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1187), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1187), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_emptySubnet_Test
>); void Dhcp4ParserTest_emptySubnet_Test::TestBody()
{
1188
1189 string config = "{ " + genIfaceConfig() + ","
1190 "\"rebind-timer\": 2000, "
1191 "\"renew-timer\": 1000, "
1192 "\"subnet4\": [ ], "
1193 "\"valid-lifetime\": 4000 }";
1194
1195 ConstElementPtr json;
1196 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1196
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1196
; } } else gtest_label_testnothrow_1196 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1196, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1197 extractConfig(config);
1198
1199 ConstElementPtr status;
1200 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1200; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1200; } } else gtest_label_testnothrow_1200
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1200, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1201
1202 // returned value should be 0 (success)
1203 checkResult(status, 0);
1204}
1205
1206/// The goal of this test is to verify if defined subnet uses global
1207/// parameter timer definitions.
1208TEST_F(Dhcp4ParserTest, subnetGlobalDefaults)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("subnetGlobalDefaults") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_subnetGlobalDefaults_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_subnetGlobalDefaults_Test() = default
; ~Dhcp4ParserTest_subnetGlobalDefaults_Test() override = default
; Dhcp4ParserTest_subnetGlobalDefaults_Test (const Dhcp4ParserTest_subnetGlobalDefaults_Test
&) = delete; Dhcp4ParserTest_subnetGlobalDefaults_Test &
operator=( const Dhcp4ParserTest_subnetGlobalDefaults_Test &
) = delete; Dhcp4ParserTest_subnetGlobalDefaults_Test (Dhcp4ParserTest_subnetGlobalDefaults_Test
&&) noexcept = delete; Dhcp4ParserTest_subnetGlobalDefaults_Test
& operator=( Dhcp4ParserTest_subnetGlobalDefaults_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_subnetGlobalDefaults_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "subnetGlobalDefaults", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1208), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1208), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1208), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_subnetGlobalDefaults_Test
>); void Dhcp4ParserTest_subnetGlobalDefaults_Test::TestBody
()
{
1209
1210 string config = "{ " + genIfaceConfig() + ","
1211 "\"rebind-timer\": 2000, "
1212 "\"renew-timer\": 1000, "
1213 "\"subnet4\": [ { "
1214 " \"id\": 1,"
1215 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1216 " \"subnet\": \"192.0.2.0/24\" } ],"
1217 "\"valid-lifetime\": 4000,"
1218 "\"min-valid-lifetime\": 3000,"
1219 "\"max-valid-lifetime\": 5000 }";
1220
1221 ConstElementPtr json;
1222 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1222
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1222
; } } else gtest_label_testnothrow_1222 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1222, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1223 extractConfig(config);
1224
1225 ConstElementPtr status;
1226 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1226; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1226; } } else gtest_label_testnothrow_1226
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1226, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1227
1228 // check if returned status is OK
1229 checkResult(status, 0);
1230
1231 // Now check if the configuration was indeed handled and we have
1232 // expected pool configured.
1233 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
1234 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
1235 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1235, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
1236 EXPECT_EQ(1000U, subnet->getT1().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1000U", "subnet->getT1().get()"
, 1000U, subnet->getT1().get()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1236, gtest_ar.failure_message()) = ::testing::Message()
;
1237 EXPECT_EQ(2000U, subnet->getT2().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2000U", "subnet->getT2().get()"
, 2000U, subnet->getT2().get()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1237, gtest_ar.failure_message()) = ::testing::Message()
;
1238 EXPECT_EQ(4000U, subnet->getValid().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("4000U", "subnet->getValid().get()"
, 4000U, subnet->getValid().get()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1238, gtest_ar.failure_message()) = ::testing::Message()
;
1239 EXPECT_EQ(3000U, subnet->getValid().getMin())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("3000U", "subnet->getValid().getMin()"
, 3000U, subnet->getValid().getMin()))) ; else ::testing::
internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 1239
, gtest_ar.failure_message()) = ::testing::Message()
;
1240 EXPECT_EQ(5000U, subnet->getValid().getMax())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("5000U", "subnet->getValid().getMax()"
, 5000U, subnet->getValid().getMax()))) ; else ::testing::
internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 1240
, gtest_ar.failure_message()) = ::testing::Message()
;
1241
1242 // Check that subnet-id is 1
1243 EXPECT_EQ(1U, subnet->getID())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "subnet->getID()"
, 1U, subnet->getID()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1243, gtest_ar.failure_message()) = ::testing::Message()
;
1244}
1245
1246// This test checks that it is possible to assign arbitrary ids for subnets.
1247TEST_F(Dhcp4ParserTest, multipleSubnetsExplicitIDs)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("multipleSubnetsExplicitIDs") > 1,
"test_name must not be empty"); class Dhcp4ParserTest_multipleSubnetsExplicitIDs_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_multipleSubnetsExplicitIDs_Test
() = default; ~Dhcp4ParserTest_multipleSubnetsExplicitIDs_Test
() override = default; Dhcp4ParserTest_multipleSubnetsExplicitIDs_Test
(const Dhcp4ParserTest_multipleSubnetsExplicitIDs_Test &
) = delete; Dhcp4ParserTest_multipleSubnetsExplicitIDs_Test &
operator=( const Dhcp4ParserTest_multipleSubnetsExplicitIDs_Test
&) = delete; Dhcp4ParserTest_multipleSubnetsExplicitIDs_Test
(Dhcp4ParserTest_multipleSubnetsExplicitIDs_Test &&)
noexcept = delete; Dhcp4ParserTest_multipleSubnetsExplicitIDs_Test
& operator=( Dhcp4ParserTest_multipleSubnetsExplicitIDs_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_multipleSubnetsExplicitIDs_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "multipleSubnetsExplicitIDs", nullptr, nullptr, ::testing::
internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1247), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1247), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1247), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_multipleSubnetsExplicitIDs_Test
>); void Dhcp4ParserTest_multipleSubnetsExplicitIDs_Test::
TestBody()
{
1248 ConstElementPtr x;
1249 // Four subnets with arbitrary subnet ids.
1250 string config = "{ " + genIfaceConfig() + ","
1251 "\"rebind-timer\": 2000, "
1252 "\"renew-timer\": 1000, "
1253 "\"subnet4\": [ { "
1254 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1255 " \"subnet\": \"192.0.2.0/24\", "
1256 " \"id\": 1024"
1257 " },"
1258 " {"
1259 " \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
1260 " \"subnet\": \"192.0.3.0/24\", "
1261 " \"id\": 100"
1262 " },"
1263 " {"
1264 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
1265 " \"subnet\": \"192.0.4.0/24\", "
1266 " \"id\": 1"
1267 " },"
1268 " {"
1269 " \"pools\": [ { \"pool\": \"192.0.5.101 - 192.0.5.150\" } ],"
1270 " \"subnet\": \"192.0.5.0/24\", "
1271 " \"id\": 34"
1272 " } ],"
1273 "\"valid-lifetime\": 4000 }";
1274
1275 int cnt = 0; // Number of reconfigurations
1276
1277 ConstElementPtr json;
1278 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1278
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1278
; } } else gtest_label_testnothrow_1278 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1278, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1279 extractConfig(config);
1280
1281 do {
1282 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1282; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1282; } } else gtest_label_testnothrow_1282
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1282, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1283 checkResult(x, 0);
1284
1285 CfgMgr::instance().commit();
1286
1287 const Subnet4Collection* subnets =
1288 CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
1289 ASSERT_TRUE(subnets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnets)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1289, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
1290 ASSERT_EQ(4U, subnets->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("4U", "subnets->size()"
, 4U, subnets->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1290, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 4 subnets
1291
1292 // Verify that subnet ids are as expected.
1293 // Now the subnet order is the subnet id one.
1294 auto subnet = subnets->begin();
1295 EXPECT_EQ(1U, (*subnet)->getID())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "(*subnet)->getID()"
, 1U, (*subnet)->getID()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1295, gtest_ar.failure_message()) = ::testing::Message()
;
1296 EXPECT_EQ(34U, (*++subnet)->getID())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("34U", "(*++subnet)->getID()"
, 34U, (*++subnet)->getID()))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1296, gtest_ar.failure_message()) = ::testing::Message()
;
1297 EXPECT_EQ(100U, (*++subnet)->getID())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("100U", "(*++subnet)->getID()"
, 100U, (*++subnet)->getID()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1297, gtest_ar.failure_message()) = ::testing::Message()
;
1298 EXPECT_EQ(1024U, (*++subnet)->getID())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1024U", "(*++subnet)->getID()"
, 1024U, (*++subnet)->getID()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1298, gtest_ar.failure_message()) = ::testing::Message()
;
1299
1300 // Repeat reconfiguration process 10 times and check that the subnet-id
1301 // is set to the same value.
1302 } while (++cnt < 3);
1303}
1304
1305// Check that the configuration with two subnets having the same ID is rejected.
1306TEST_F(Dhcp4ParserTest, multipleSubnetsOverlappingIDs)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("multipleSubnetsOverlappingIDs") >
1, "test_name must not be empty"); class Dhcp4ParserTest_multipleSubnetsOverlappingIDs_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_multipleSubnetsOverlappingIDs_Test
() = default; ~Dhcp4ParserTest_multipleSubnetsOverlappingIDs_Test
() override = default; Dhcp4ParserTest_multipleSubnetsOverlappingIDs_Test
(const Dhcp4ParserTest_multipleSubnetsOverlappingIDs_Test &
) = delete; Dhcp4ParserTest_multipleSubnetsOverlappingIDs_Test
& operator=( const Dhcp4ParserTest_multipleSubnetsOverlappingIDs_Test
&) = delete; Dhcp4ParserTest_multipleSubnetsOverlappingIDs_Test
(Dhcp4ParserTest_multipleSubnetsOverlappingIDs_Test &&
) noexcept = delete; Dhcp4ParserTest_multipleSubnetsOverlappingIDs_Test
& operator=( Dhcp4ParserTest_multipleSubnetsOverlappingIDs_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_multipleSubnetsOverlappingIDs_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "multipleSubnetsOverlappingIDs", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1306), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1306), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1306), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_multipleSubnetsOverlappingIDs_Test
>); void Dhcp4ParserTest_multipleSubnetsOverlappingIDs_Test
::TestBody()
{
1307 ConstElementPtr x;
1308 // Four subnets, two of them have the same id.
1309 string config = "{ " + genIfaceConfig() + ","
1310 "\"rebind-timer\": 2000, "
1311 "\"renew-timer\": 1000, "
1312 "\"subnet4\": [ { "
1313 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1314 " \"subnet\": \"192.0.2.0/24\", "
1315 " \"id\": 1024"
1316 " },"
1317 " {"
1318 " \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
1319 " \"subnet\": \"192.0.3.0/24\", "
1320 " \"id\": 100"
1321 " },"
1322 " {"
1323 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
1324 " \"subnet\": \"192.0.4.0/24\", "
1325 " \"id\": 1024"
1326 " },"
1327 " {"
1328 " \"pools\": [ { \"pool\": \"192.0.5.101 - 192.0.5.150\" } ],"
1329 " \"subnet\": \"192.0.5.0/24\", "
1330 " \"id\": 34"
1331 " } ],"
1332 "\"valid-lifetime\": 4000 }";
1333
1334 ConstElementPtr json;
1335 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1335
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1335
; } } else gtest_label_testnothrow_1335 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1335, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1336
1337 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1337; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1337; } } else gtest_label_testnothrow_1337
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1337, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1338 checkResult(x, CONTROL_RESULT_ERROR);
1339 EXPECT_TRUE(errorContainsPosition(x, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(x, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1339, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(x, \"<string>\")", "false", "true"
) .c_str()) = ::testing::Message()
;
1340}
1341
1342// Goal of this test is to verify that a previously configured subnet can be
1343// deleted in subsequent reconfiguration.
1344TEST_F(Dhcp4ParserTest, reconfigureRemoveSubnet)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("reconfigureRemoveSubnet") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_reconfigureRemoveSubnet_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_reconfigureRemoveSubnet_Test
() = default; ~Dhcp4ParserTest_reconfigureRemoveSubnet_Test()
override = default; Dhcp4ParserTest_reconfigureRemoveSubnet_Test
(const Dhcp4ParserTest_reconfigureRemoveSubnet_Test &) =
delete; Dhcp4ParserTest_reconfigureRemoveSubnet_Test & operator
=( const Dhcp4ParserTest_reconfigureRemoveSubnet_Test &) =
delete; Dhcp4ParserTest_reconfigureRemoveSubnet_Test (Dhcp4ParserTest_reconfigureRemoveSubnet_Test
&&) noexcept = delete; Dhcp4ParserTest_reconfigureRemoveSubnet_Test
& operator=( Dhcp4ParserTest_reconfigureRemoveSubnet_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_reconfigureRemoveSubnet_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "reconfigureRemoveSubnet", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1344), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1344), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1344), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_reconfigureRemoveSubnet_Test
>); void Dhcp4ParserTest_reconfigureRemoveSubnet_Test::TestBody
()
{
1345 ConstElementPtr x;
1346
1347 // All four subnets
1348 string config4 = "{ " + genIfaceConfig() + ","
1349 "\"rebind-timer\": 2000, "
1350 "\"renew-timer\": 1000, "
1351 "\"subnet4\": [ { "
1352 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1353 " \"subnet\": \"192.0.2.0/24\", "
1354 " \"id\": 1"
1355 " },"
1356 " {"
1357 " \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
1358 " \"subnet\": \"192.0.3.0/24\", "
1359 " \"id\": 2"
1360 " },"
1361 " {"
1362 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
1363 " \"subnet\": \"192.0.4.0/24\", "
1364 " \"id\": 3"
1365 " },"
1366 " {"
1367 " \"pools\": [ { \"pool\": \"192.0.5.101 - 192.0.5.150\" } ],"
1368 " \"subnet\": \"192.0.5.0/24\", "
1369 " \"id\": 4"
1370 " } ],"
1371 "\"valid-lifetime\": 4000 }";
1372
1373 // Three subnets (the last one removed)
1374 string config_first3 = "{ " + genIfaceConfig() + ","
1375 "\"rebind-timer\": 2000, "
1376 "\"renew-timer\": 1000, "
1377 "\"subnet4\": [ { "
1378 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1379 " \"subnet\": \"192.0.2.0/24\", "
1380 " \"id\": 1"
1381 " },"
1382 " {"
1383 " \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
1384 " \"subnet\": \"192.0.3.0/24\", "
1385 " \"id\": 2"
1386 " },"
1387 " {"
1388 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
1389 " \"subnet\": \"192.0.4.0/24\", "
1390 " \"id\": 3"
1391 " } ],"
1392 "\"valid-lifetime\": 4000 }";
1393
1394 // Second subnet removed
1395 string config_second_removed = "{ " + genIfaceConfig() + ","
1396 "\"rebind-timer\": 2000, "
1397 "\"renew-timer\": 1000, "
1398 "\"subnet4\": [ { "
1399 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1400 " \"subnet\": \"192.0.2.0/24\", "
1401 " \"id\": 1"
1402 " },"
1403 " {"
1404 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
1405 " \"subnet\": \"192.0.4.0/24\", "
1406 " \"id\": 3"
1407 " },"
1408 " {"
1409 " \"pools\": [ { \"pool\": \"192.0.5.101 - 192.0.5.150\" } ],"
1410 " \"subnet\": \"192.0.5.0/24\", "
1411 " \"id\": 4"
1412 " } ],"
1413 "\"valid-lifetime\": 4000 }";
1414
1415 // CASE 1: Configure 4 subnets, then reconfigure and remove the
1416 // last one.
1417
1418 ConstElementPtr json;
1419 ASSERT_NO_THROW(json = parseDHCP4(config4))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config4); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1419
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1419
; } } else gtest_label_testnothrow_1419 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1419, ("Expected: " "json = parseDHCP4(config4)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1420 extractConfig(config4);
1421 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1421; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1421; } } else gtest_label_testnothrow_1421
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1421, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1422 checkResult(x, 0);
1423
1424 CfgMgr::instance().commit();
1425
1426 const Subnet4Collection* subnets =
1427 CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
1428 ASSERT_TRUE(subnets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnets)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1428, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
1429 ASSERT_EQ(4U, subnets->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("4U", "subnets->size()"
, 4U, subnets->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1429, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 4 subnets
1430
1431 CfgMgr::instance().clear();
1432
1433 // Do the reconfiguration (the last subnet is removed)
1434 ASSERT_NO_THROW(json = parseDHCP4(config_first3))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config_first3); } else static_assert(true,
""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1434
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1434
; } } else gtest_label_testnothrow_1434 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1434, ("Expected: " "json = parseDHCP4(config_first3)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1435 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1435; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1435; } } else gtest_label_testnothrow_1435
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1435, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1436 checkResult(x, 0);
1437
1438 CfgMgr::instance().commit();
1439
1440 subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
1441 ASSERT_TRUE(subnets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnets)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1441, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
1442 ASSERT_EQ(3U, subnets->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("3U", "subnets->size()"
, 3U, subnets->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1442, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 3 subnets now (4th is removed)
1443
1444 // Check subnet-ids of each subnet (it should be monotonously increasing)
1445 auto subnet = subnets->begin();
1446 EXPECT_EQ(1U, (*subnet)->getID())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "(*subnet)->getID()"
, 1U, (*subnet)->getID()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1446, gtest_ar.failure_message()) = ::testing::Message()
;
1447 EXPECT_EQ(2U, (*++subnet)->getID())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "(*++subnet)->getID()"
, 2U, (*++subnet)->getID()))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1447, gtest_ar.failure_message()) = ::testing::Message()
;
1448 EXPECT_EQ(3U, (*++subnet)->getID())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("3U", "(*++subnet)->getID()"
, 3U, (*++subnet)->getID()))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1448, gtest_ar.failure_message()) = ::testing::Message()
;
1449
1450 CfgMgr::instance().clear();
1451
1452 /// CASE 2: Configure 4 subnets, then reconfigure and remove one
1453 /// from in between (not first, not last)
1454 ASSERT_NO_THROW(json = parseDHCP4(config4))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config4); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1454
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1454
; } } else gtest_label_testnothrow_1454 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1454, ("Expected: " "json = parseDHCP4(config4)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1455 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1455; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1455; } } else gtest_label_testnothrow_1455
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1455, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1456 checkResult(x, 0);
1457
1458 CfgMgr::instance().commit();
1459
1460 // Do reconfiguration
1461 ASSERT_NO_THROW(json = parseDHCP4(config_second_removed))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config_second_removed); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1461; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1461; } } else gtest_label_testnothrow_1461
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1461, ("Expected: " "json = parseDHCP4(config_second_removed)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1462 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1462; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1462; } } else gtest_label_testnothrow_1462
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1462, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1463 checkResult(x, 0);
1464
1465 CfgMgr::instance().commit();
1466
1467 subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
1468 ASSERT_TRUE(subnets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnets)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1468, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
1469 ASSERT_EQ(3U, subnets->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("3U", "subnets->size()"
, 3U, subnets->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1469, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 4 subnets
1470
1471 subnet = subnets->begin();
1472 EXPECT_EQ(1U, (*subnet)->getID())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "(*subnet)->getID()"
, 1U, (*subnet)->getID()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1472, gtest_ar.failure_message()) = ::testing::Message()
;
1473 // The second subnet (with subnet-id = 2) is no longer there
1474 EXPECT_EQ(3U, (*++subnet)->getID())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("3U", "(*++subnet)->getID()"
, 3U, (*++subnet)->getID()))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1474, gtest_ar.failure_message()) = ::testing::Message()
;
1475 EXPECT_EQ(4U, (*++subnet)->getID())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("4U", "(*++subnet)->getID()"
, 4U, (*++subnet)->getID()))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1475, gtest_ar.failure_message()) = ::testing::Message()
;
1476}
1477
1478/// @todo: implement subnet removal test as part of #3281.
1479
1480// Checks if the next-server and other fixed BOOTP fields defined as
1481// global parameter are taken into consideration.
1482TEST_F(Dhcp4ParserTest, nextServerGlobal)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("nextServerGlobal") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_nextServerGlobal_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_nextServerGlobal_Test() = default;
~Dhcp4ParserTest_nextServerGlobal_Test() override = default;
Dhcp4ParserTest_nextServerGlobal_Test (const Dhcp4ParserTest_nextServerGlobal_Test
&) = delete; Dhcp4ParserTest_nextServerGlobal_Test &
operator=( const Dhcp4ParserTest_nextServerGlobal_Test &
) = delete; Dhcp4ParserTest_nextServerGlobal_Test (Dhcp4ParserTest_nextServerGlobal_Test
&&) noexcept = delete; Dhcp4ParserTest_nextServerGlobal_Test
& operator=( Dhcp4ParserTest_nextServerGlobal_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_nextServerGlobal_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "nextServerGlobal", nullptr, nullptr, ::testing::internal::
CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1482), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1482), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1482), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_nextServerGlobal_Test
>); void Dhcp4ParserTest_nextServerGlobal_Test::TestBody()
{
1483
1484 string config = "{ " + genIfaceConfig() + ","
1485 "\"rebind-timer\": 2000, "
1486 "\"renew-timer\": 1000, "
1487 "\"next-server\": \"1.2.3.4\", "
1488 "\"server-hostname\": \"foo\", "
1489 "\"boot-file-name\": \"bar\", "
1490 "\"subnet4\": [ { "
1491 " \"id\": 1,"
1492 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1493 " \"subnet\": \"192.0.2.0/24\" } ],"
1494 "\"valid-lifetime\": 4000 }";
1495
1496 ConstElementPtr json;
1497 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1497
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1497
; } } else gtest_label_testnothrow_1497 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1497, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1498 extractConfig(config);
1499
1500 ConstElementPtr status;
1501 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1501; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1501; } } else gtest_label_testnothrow_1501
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1501, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1502
1503 // check if returned status is OK
1504 checkResult(status, 0);
1505
1506 // Now check if the configuration was indeed handled and we have
1507 // expected pool configured.
1508 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
1509 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
1510 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1510, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
1511 // Reset the fetch global function to staging (vs current) config.
1512 Subnet4Ptr mutable_subnet = boost::const_pointer_cast<Subnet4>(subnet);
1513 mutable_subnet->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
1514 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
1515 });
1516 EXPECT_EQ("1.2.3.4", subnet->getSiaddr().get().toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"1.2.3.4\""
, "subnet->getSiaddr().get().toText()", "1.2.3.4", subnet->
getSiaddr().get().toText()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1516, gtest_ar.failure_message()) = ::testing::Message()
;
1517 EXPECT_EQ("foo", subnet->getSname().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"foo\""
, "subnet->getSname().get()", "foo", subnet->getSname()
.get()))) ; else ::testing::internal::AssertHelper(::testing::
TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1517, gtest_ar.failure_message()) = ::testing::Message()
;
1518 EXPECT_EQ("bar", subnet->getFilename().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"bar\""
, "subnet->getFilename().get()", "bar", subnet->getFilename
().get()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1518, gtest_ar.failure_message()) = ::testing::Message()
;
1519}
1520
1521// Checks if the next-server and other fixed BOOTP fields defined as
1522// subnet parameter are taken into consideration.
1523TEST_F(Dhcp4ParserTest, nextServerSubnet)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("nextServerSubnet") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_nextServerSubnet_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_nextServerSubnet_Test() = default;
~Dhcp4ParserTest_nextServerSubnet_Test() override = default;
Dhcp4ParserTest_nextServerSubnet_Test (const Dhcp4ParserTest_nextServerSubnet_Test
&) = delete; Dhcp4ParserTest_nextServerSubnet_Test &
operator=( const Dhcp4ParserTest_nextServerSubnet_Test &
) = delete; Dhcp4ParserTest_nextServerSubnet_Test (Dhcp4ParserTest_nextServerSubnet_Test
&&) noexcept = delete; Dhcp4ParserTest_nextServerSubnet_Test
& operator=( Dhcp4ParserTest_nextServerSubnet_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_nextServerSubnet_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "nextServerSubnet", nullptr, nullptr, ::testing::internal::
CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1523), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1523), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1523), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_nextServerSubnet_Test
>); void Dhcp4ParserTest_nextServerSubnet_Test::TestBody()
{
1524
1525 string config = "{ " + genIfaceConfig() + ","
1526 "\"rebind-timer\": 2000, "
1527 "\"renew-timer\": 1000, "
1528 "\"subnet4\": [ { "
1529 " \"id\": 1,"
1530 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1531 " \"next-server\": \"1.2.3.4\", "
1532 " \"server-hostname\": \"foo\", "
1533 " \"boot-file-name\": \"bar\", "
1534 " \"subnet\": \"192.0.2.0/24\" } ],"
1535 "\"valid-lifetime\": 4000 }";
1536
1537 ConstElementPtr json;
1538 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1538
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1538
; } } else gtest_label_testnothrow_1538 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1538, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1539 extractConfig(config);
1540
1541 ConstElementPtr status;
1542 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1542; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1542; } } else gtest_label_testnothrow_1542
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1542, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1543
1544 // check if returned status is OK
1545 checkResult(status, 0);
1546
1547 // Now check if the configuration was indeed handled and we have
1548 // expected pool configured.
1549 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
1550 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
1551 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1551, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
1552 EXPECT_EQ("1.2.3.4", subnet->getSiaddr().get().toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"1.2.3.4\""
, "subnet->getSiaddr().get().toText()", "1.2.3.4", subnet->
getSiaddr().get().toText()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1552, gtest_ar.failure_message()) = ::testing::Message()
;
1553 EXPECT_EQ("foo", subnet->getSname().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"foo\""
, "subnet->getSname().get()", "foo", subnet->getSname()
.get()))) ; else ::testing::internal::AssertHelper(::testing::
TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1553, gtest_ar.failure_message()) = ::testing::Message()
;
1554 EXPECT_EQ("bar", subnet->getFilename().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"bar\""
, "subnet->getFilename().get()", "bar", subnet->getFilename
().get()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1554, gtest_ar.failure_message()) = ::testing::Message()
;
1555}
1556
1557// Test checks several negative scenarios for next-server configuration: bogus
1558// address, IPv6 address and empty string.
1559TEST_F(Dhcp4ParserTest, nextServerNegative)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("nextServerNegative") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_nextServerNegative_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_nextServerNegative_Test() = default
; ~Dhcp4ParserTest_nextServerNegative_Test() override = default
; Dhcp4ParserTest_nextServerNegative_Test (const Dhcp4ParserTest_nextServerNegative_Test
&) = delete; Dhcp4ParserTest_nextServerNegative_Test &
operator=( const Dhcp4ParserTest_nextServerNegative_Test &
) = delete; Dhcp4ParserTest_nextServerNegative_Test (Dhcp4ParserTest_nextServerNegative_Test
&&) noexcept = delete; Dhcp4ParserTest_nextServerNegative_Test
& operator=( Dhcp4ParserTest_nextServerNegative_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_nextServerNegative_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "nextServerNegative", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1559), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1559), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1559), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_nextServerNegative_Test
>); void Dhcp4ParserTest_nextServerNegative_Test::TestBody
()
{
1560 IfaceMgrTestConfig test_config(true);
1561
1562 // Config with junk instead of next-server address
1563 string config_bogus1 = "{ " + genIfaceConfig() + ","
1564 "\"rebind-timer\": 2000, "
1565 "\"renew-timer\": 1000, "
1566 "\"subnet4\": [ { "
1567 " \"id\": 1,"
1568 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1569 " \"rebind-timer\": 2000, "
1570 " \"renew-timer\": 1000, "
1571 " \"next-server\": \"a.b.c.d\", "
1572 " \"subnet\": \"192.0.2.0/24\" } ],"
1573 "\"valid-lifetime\": 4000 }";
1574
1575 // Config with IPv6 next server address
1576 string config_bogus2 = "{ " + genIfaceConfig() + ","
1577 "\"rebind-timer\": 2000, "
1578 "\"renew-timer\": 1000, "
1579 "\"subnet4\": [ { "
1580 " \"id\": 1,"
1581 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1582 " \"rebind-timer\": 2000, "
1583 " \"renew-timer\": 1000, "
1584 " \"next-server\": \"2001:db8::1\", "
1585 " \"subnet\": \"192.0.2.0/24\" } ],"
1586 "\"valid-lifetime\": 4000 }";
1587
1588 // Config with empty next server address
1589 string config_bogus3 = "{ " + genIfaceConfig() + ","
1590 "\"rebind-timer\": 2000, "
1591 "\"renew-timer\": 1000, "
1592 "\"subnet4\": [ { "
1593 " \"id\": 1,"
1594 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1595 " \"rebind-timer\": 2000, "
1596 " \"renew-timer\": 1000, "
1597 " \"next-server\": \"\", "
1598 " \"subnet\": \"192.0.2.0/24\" } ],"
1599 "\"valid-lifetime\": 4000 }";
1600
1601 // Config with too large server-hostname
1602 string bigsname(Pkt4::MAX_SNAME_LEN + 1, ' ');
1603 string config_bogus4 = "{ " + genIfaceConfig() + ","
1604 "\"rebind-timer\": 2000, "
1605 "\"renew-timer\": 1000, "
1606 "\"subnet4\": [ { "
1607 " \"id\": 1,"
1608 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1609 " \"rebind-timer\": 2000, "
1610 " \"renew-timer\": 1000, "
1611 " \"server-hostname\": \"" + bigsname + "\", " +
1612 " \"subnet\": \"192.0.2.0/24\" } ],"
1613 "\"valid-lifetime\": 4000 }";
1614
1615 // Config with too large boot-file-hostname
1616 string bigfilename(Pkt4::MAX_FILE_LEN + 1, ' ');
1617 string config_bogus5 = "{ " + genIfaceConfig() + ","
1618 "\"rebind-timer\": 2000, "
1619 "\"renew-timer\": 1000, "
1620 "\"subnet4\": [ { "
1621 " \"id\": 1,"
1622 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1623 " \"rebind-timer\": 2000, "
1624 " \"renew-timer\": 1000, "
1625 " \"boot-file-name\": \"" + bigfilename + "\", " +
1626 " \"subnet\": \"192.0.2.0/24\" } ],"
1627 "\"valid-lifetime\": 4000 }";
1628
1629 ConstElementPtr json1;
1630 ASSERT_NO_THROW(json1 = parseDHCP4(config_bogus1))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json1 = parseDHCP4(config_bogus1); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1630
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1630
; } } else gtest_label_testnothrow_1630 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1630, ("Expected: " "json1 = parseDHCP4(config_bogus1)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1631 ConstElementPtr json2;
1632 ASSERT_NO_THROW(json2 = parseDHCP4(config_bogus2))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json2 = parseDHCP4(config_bogus2); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1632
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1632
; } } else gtest_label_testnothrow_1632 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1632, ("Expected: " "json2 = parseDHCP4(config_bogus2)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1633 ConstElementPtr json3;
1634 ASSERT_NO_THROW(json3 = parseDHCP4(config_bogus3))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json3 = parseDHCP4(config_bogus3); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1634
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1634
; } } else gtest_label_testnothrow_1634 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1634, ("Expected: " "json3 = parseDHCP4(config_bogus3)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1635 ConstElementPtr json4;
1636 ASSERT_NO_THROW(json4 = parseDHCP4(config_bogus4))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json4 = parseDHCP4(config_bogus4); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1636
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1636
; } } else gtest_label_testnothrow_1636 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1636, ("Expected: " "json4 = parseDHCP4(config_bogus4)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1637 ConstElementPtr json5;
1638 ASSERT_NO_THROW(json5 = parseDHCP4(config_bogus5))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json5 = parseDHCP4(config_bogus5); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1638
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1638
; } } else gtest_label_testnothrow_1638 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1638, ("Expected: " "json5 = parseDHCP4(config_bogus5)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1639
1640 // check if returned status is always a failure
1641 ConstElementPtr status;
1642 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json1))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json1); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1642; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1642; } } else gtest_label_testnothrow_1642
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1642, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json1)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1643 checkResult(status, CONTROL_RESULT_ERROR);
1644 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1644, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
1645
1646 CfgMgr::instance().clear();
1647
1648 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json2))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json2); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1648; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1648; } } else gtest_label_testnothrow_1648
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1648, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json2)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1649 checkResult(status, CONTROL_RESULT_ERROR);
1650 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1650, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
1651
1652 CfgMgr::instance().clear();
1653
1654 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json3))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json3); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1654; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1654; } } else gtest_label_testnothrow_1654
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1654, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json3)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1655 checkResult(status, 0);
1656 EXPECT_FALSE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(errorContainsPosition
(status, "<string>")))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1656, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "true"
, "false") .c_str()) = ::testing::Message()
;
1657
1658 CfgMgr::instance().clear();
1659
1660 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json4))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json4); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1660; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1660; } } else gtest_label_testnothrow_1660
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1660, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json4)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1661 checkResult(status, CONTROL_RESULT_ERROR);
1662 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1662, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
1663
1664 CfgMgr::instance().clear();
1665
1666 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json5))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json5); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1666; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1666; } } else gtest_label_testnothrow_1666
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1666, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json5)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1667 checkResult(status, CONTROL_RESULT_ERROR);
1668 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1668, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
1669}
1670
1671// Checks if the next-server defined as global value is overridden by subnet
1672// specific value.
1673TEST_F(Dhcp4ParserTest, nextServerOverride)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("nextServerOverride") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_nextServerOverride_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_nextServerOverride_Test() = default
; ~Dhcp4ParserTest_nextServerOverride_Test() override = default
; Dhcp4ParserTest_nextServerOverride_Test (const Dhcp4ParserTest_nextServerOverride_Test
&) = delete; Dhcp4ParserTest_nextServerOverride_Test &
operator=( const Dhcp4ParserTest_nextServerOverride_Test &
) = delete; Dhcp4ParserTest_nextServerOverride_Test (Dhcp4ParserTest_nextServerOverride_Test
&&) noexcept = delete; Dhcp4ParserTest_nextServerOverride_Test
& operator=( Dhcp4ParserTest_nextServerOverride_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_nextServerOverride_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "nextServerOverride", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1673), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1673), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1673), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_nextServerOverride_Test
>); void Dhcp4ParserTest_nextServerOverride_Test::TestBody
()
{
1674
1675 string config = "{ " + genIfaceConfig() + ","
1676 "\"rebind-timer\": 2000, "
1677 "\"renew-timer\": 1000, "
1678 "\"next-server\": \"192.0.0.1\", "
1679 "\"server-hostname\": \"nohost\","
1680 "\"boot-file-name\": \"nofile\","
1681 "\"subnet4\": [ { "
1682 " \"id\": 1,"
1683 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1684 " \"next-server\": \"1.2.3.4\", "
1685 " \"server-hostname\": \"some-name.example.org\","
1686 " \"boot-file-name\": \"bootfile.efi\","
1687 " \"subnet\": \"192.0.2.0/24\" } ],"
1688 "\"valid-lifetime\": 4000 }";
1689
1690 ConstElementPtr json;
1691 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1691
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1691
; } } else gtest_label_testnothrow_1691 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1691, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1692 extractConfig(config);
1693
1694 ConstElementPtr status;
1695 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1695; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1695; } } else gtest_label_testnothrow_1695
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1695, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1696
1697 // check if returned status is OK
1698 checkResult(status, 0);
1699
1700 // Now check if the configuration was indeed handled and we have
1701 // expected pool configured.
1702 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
1703 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
1704 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1704, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
1705 EXPECT_EQ("1.2.3.4", subnet->getSiaddr().get().toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"1.2.3.4\""
, "subnet->getSiaddr().get().toText()", "1.2.3.4", subnet->
getSiaddr().get().toText()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1705, gtest_ar.failure_message()) = ::testing::Message()
;
1706 EXPECT_EQ("some-name.example.org", subnet->getSname().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"some-name.example.org\""
, "subnet->getSname().get()", "some-name.example.org", subnet
->getSname().get()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1706, gtest_ar.failure_message()) = ::testing::Message()
;
1707 EXPECT_EQ("bootfile.efi", subnet->getFilename().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"bootfile.efi\""
, "subnet->getFilename().get()", "bootfile.efi", subnet->
getFilename().get()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1707, gtest_ar.failure_message()) = ::testing::Message()
;
1708}
1709
1710// Check whether it is possible to configure echo-client-id
1711TEST_F(Dhcp4ParserTest, echoClientId)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("echoClientId") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_echoClientId_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_echoClientId_Test() = default; ~Dhcp4ParserTest_echoClientId_Test
() override = default; Dhcp4ParserTest_echoClientId_Test (const
Dhcp4ParserTest_echoClientId_Test &) = delete; Dhcp4ParserTest_echoClientId_Test
& operator=( const Dhcp4ParserTest_echoClientId_Test &
) = delete; Dhcp4ParserTest_echoClientId_Test (Dhcp4ParserTest_echoClientId_Test
&&) noexcept = delete; Dhcp4ParserTest_echoClientId_Test
& operator=( Dhcp4ParserTest_echoClientId_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_echoClientId_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "echoClientId", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 1711
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1711), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1711), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_echoClientId_Test
>); void Dhcp4ParserTest_echoClientId_Test::TestBody()
{
1712
1713 string config_false = "{ " + genIfaceConfig() + ","
1714 "\"rebind-timer\": 2000, "
1715 "\"renew-timer\": 1000, "
1716 "\"echo-client-id\": false,"
1717 "\"subnet4\": [ { "
1718 " \"id\": 1,"
1719 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1720 " \"subnet\": \"192.0.2.0/24\" } ],"
1721 "\"valid-lifetime\": 4000 }";
1722
1723 string config_true = "{ " + genIfaceConfig() + ","
1724 "\"rebind-timer\": 2000, "
1725 "\"renew-timer\": 1000, "
1726 "\"echo-client-id\": true,"
1727 "\"subnet4\": [ { "
1728 " \"id\": 1,"
1729 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1730 " \"subnet\": \"192.0.2.0/24\" } ],"
1731 "\"valid-lifetime\": 4000 }";
1732
1733 ConstElementPtr json_false;
1734 ASSERT_NO_THROW(json_false = parseDHCP4(config_false))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json_false = parseDHCP4(config_false); } else static_assert(
true, ""); } catch (std::exception const& e) { gtest_msg.
value = "it throws "; gtest_msg.value += ::testing::internal::
GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1734; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1734; } } else gtest_label_testnothrow_1734
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1734, ("Expected: " "json_false = parseDHCP4(config_false)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1735 extractConfig(config_false);
1736 ConstElementPtr json_true;
1737 ASSERT_NO_THROW(json_true = parseDHCP4(config_true))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json_true = parseDHCP4(config_true); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1737
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1737
; } } else gtest_label_testnothrow_1737 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1737, ("Expected: " "json_true = parseDHCP4(config_true)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1738 extractConfig(config_true);
1739
1740 // Let's check the default. It should be true
1741 ASSERT_TRUE(CfgMgr::instance().getStagingCfg()->getEchoClientId())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(CfgMgr::instance().getStagingCfg
()->getEchoClientId())) ; else return ::testing::internal::
AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1741, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getEchoClientId()",
"false", "true") .c_str()) = ::testing::Message()
;
1742
1743 // Now check that "false" configuration is really applied.
1744 ConstElementPtr status;
1745 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json_false))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json_false); } else
static_assert(true, ""); } catch (std::exception const& e
) { gtest_msg.value = "it throws "; gtest_msg.value += ::testing
::internal::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1745; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1745; } } else gtest_label_testnothrow_1745
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1745, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json_false)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1746 checkResult(status, 0);
1747 ASSERT_FALSE(CfgMgr::instance().getStagingCfg()->getEchoClientId())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(CfgMgr::instance().
getStagingCfg()->getEchoClientId()))) ; else return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 1747
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getEchoClientId()",
"true", "false") .c_str()) = ::testing::Message()
;
1748
1749 CfgMgr::instance().clear();
1750
1751 // Now check that "true" configuration is really applied.
1752 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json_true))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json_true); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1752; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1752; } } else gtest_label_testnothrow_1752
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1752, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json_true)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1753 checkResult(status, 0);
1754 ASSERT_TRUE(CfgMgr::instance().getStagingCfg()->getEchoClientId())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(CfgMgr::instance().getStagingCfg
()->getEchoClientId())) ; else return ::testing::internal::
AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1754, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getEchoClientId()",
"false", "true") .c_str()) = ::testing::Message()
;
1755
1756 // In any case revert back to the default value (true)
1757 CfgMgr::instance().getStagingCfg()->setEchoClientId(true);
1758}
1759
1760// Check whether it is possible to configure compatibility flags.
1761TEST_F(Dhcp4ParserTest, compatibility)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("compatibility") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_compatibility_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_compatibility_Test() = default; ~Dhcp4ParserTest_compatibility_Test
() override = default; Dhcp4ParserTest_compatibility_Test (const
Dhcp4ParserTest_compatibility_Test &) = delete; Dhcp4ParserTest_compatibility_Test
& operator=( const Dhcp4ParserTest_compatibility_Test &
) = delete; Dhcp4ParserTest_compatibility_Test (Dhcp4ParserTest_compatibility_Test
&&) noexcept = delete; Dhcp4ParserTest_compatibility_Test
& operator=( Dhcp4ParserTest_compatibility_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_compatibility_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "compatibility", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 1761
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1761), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1761), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_compatibility_Test
>); void Dhcp4ParserTest_compatibility_Test::TestBody()
{
1762 string config = "{ " + genIfaceConfig() + ","
1763 "\"rebind-timer\": 2000, "
1764 "\"renew-timer\": 1000, "
1765 "\"compatibility\": { "
1766 " \"lenient-option-parsing\": true,"
1767 " \"ignore-dhcp-server-identifier\": true,"
1768 " \"ignore-rai-link-selection\": true,"
1769 " \"exclude-first-last-24\": true"
1770 "},"
1771 "\"subnet4\": [ { "
1772 " \"id\": 1,"
1773 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1774 " \"subnet\": \"192.0.2.0/24\" } ],"
1775 "\"valid-lifetime\": 4000 }";
1776
1777 ConstElementPtr json;
1778 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1778
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1778
; } } else gtest_label_testnothrow_1778 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1778, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
<< "bad config: " << config;
1779 extractConfig(config);
1780
1781 // Check defaults: they should be false.
1782 EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getLenientOptionParsing())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(CfgMgr::instance().
getStagingCfg()->getLenientOptionParsing()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 1782
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getLenientOptionParsing()"
, "true", "false") .c_str()) = ::testing::Message()
;
1783 EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getIgnoreServerIdentifier())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(CfgMgr::instance().
getStagingCfg()->getIgnoreServerIdentifier()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 1783
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getIgnoreServerIdentifier()"
, "true", "false") .c_str()) = ::testing::Message()
;
1784 EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getIgnoreRAILinkSelection())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(CfgMgr::instance().
getStagingCfg()->getIgnoreRAILinkSelection()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 1784
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getIgnoreRAILinkSelection()"
, "true", "false") .c_str()) = ::testing::Message()
;
1785 EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getExcludeFirstLast24())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(CfgMgr::instance().
getStagingCfg()->getExcludeFirstLast24()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 1785
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getExcludeFirstLast24()"
, "true", "false") .c_str()) = ::testing::Message()
;
1786
1787 // Check the configuration was really applied.
1788 ConstElementPtr status;
1789 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1789; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1789; } } else gtest_label_testnothrow_1789
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1789, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1790 checkResult(status, 0);
1791
1792 EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getLenientOptionParsing())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(CfgMgr::instance().getStagingCfg
()->getLenientOptionParsing())) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1792, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getLenientOptionParsing()"
, "false", "true") .c_str()) = ::testing::Message()
;
1793 EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getIgnoreServerIdentifier())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(CfgMgr::instance().getStagingCfg
()->getIgnoreServerIdentifier())) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1793, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getIgnoreServerIdentifier()"
, "false", "true") .c_str()) = ::testing::Message()
;
1794 EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getIgnoreRAILinkSelection())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(CfgMgr::instance().getStagingCfg
()->getIgnoreRAILinkSelection())) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1794, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getIgnoreRAILinkSelection()"
, "false", "true") .c_str()) = ::testing::Message()
;
1795 EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getExcludeFirstLast24())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(CfgMgr::instance().getStagingCfg
()->getExcludeFirstLast24())) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1795, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getExcludeFirstLast24()"
, "false", "true") .c_str()) = ::testing::Message()
;
1796}
1797
1798// Check that unknown compatibility flag raises error.
1799TEST_F(Dhcp4ParserTest, compatibilityUnknown)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("compatibilityUnknown") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_compatibilityUnknown_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_compatibilityUnknown_Test() = default
; ~Dhcp4ParserTest_compatibilityUnknown_Test() override = default
; Dhcp4ParserTest_compatibilityUnknown_Test (const Dhcp4ParserTest_compatibilityUnknown_Test
&) = delete; Dhcp4ParserTest_compatibilityUnknown_Test &
operator=( const Dhcp4ParserTest_compatibilityUnknown_Test &
) = delete; Dhcp4ParserTest_compatibilityUnknown_Test (Dhcp4ParserTest_compatibilityUnknown_Test
&&) noexcept = delete; Dhcp4ParserTest_compatibilityUnknown_Test
& operator=( Dhcp4ParserTest_compatibilityUnknown_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_compatibilityUnknown_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "compatibilityUnknown", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1799), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1799), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1799), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_compatibilityUnknown_Test
>); void Dhcp4ParserTest_compatibilityUnknown_Test::TestBody
()
{
1800 string config = "{ " + genIfaceConfig() + ","
1801 "\"rebind-timer\": 2000, "
1802 "\"renew-timer\": 1000, "
1803 "\"compatibility\": { "
1804 " \"foo-bar\": true"
1805 "},"
1806 "\"subnet4\": [ { "
1807 " \"id\": 1,"
1808 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1809 " \"subnet\": \"192.0.2.0/24\" } ],"
1810 "\"valid-lifetime\": 4000 }";
1811
1812 // Syntax is incorrect.
1813 EXPECT_THROW(parseDHCP4(config), Dhcp4ParseError)switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { bool gtest_caught_expected = false; try { if (
::testing::internal::AlwaysTrue()) { parseDHCP4(config); } else
static_assert(true, ""); } catch (Dhcp4ParseError const&
) { gtest_caught_expected = true; } catch (typename std::conditional
< std::is_same<typename std::remove_cv<typename std::
remove_reference< Dhcp4ParseError>::type>::type, std
::exception>::value, const ::testing::internal::NeverThrown
&, const std::exception&>::type e) { gtest_msg.value
= "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws "; gtest_msg.value
+= ::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testthrow_1813; } catch (...
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_1813; } if (!gtest_caught_expected
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws nothing."; goto gtest_label_testthrow_1813
; } } else gtest_label_testthrow_1813 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1813, gtest_msg.value.c_str()) = ::testing::Message()
;
1814 ConstElementPtr json;
1815 EXPECT_NO_THROW(json = parseJSON(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseJSON(config); } else static_assert(true, ""); } catch
(std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1815
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1815
; } } else gtest_label_testnothrow_1815 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1815, ("Expected: " "json = parseJSON(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1816
1817 // Unknown keyword is detected.
1818 ConstElementPtr status;
1819 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1819; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1819; } } else gtest_label_testnothrow_1819
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1819, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1820 string expected = "unsupported compatibility parameter: ";
1821 expected += "foo-bar (<string>:1:127)";
1822 checkResult(status, CONTROL_RESULT_ERROR, expected);
1823}
1824
1825// Check that not boolean compatibility flag value raises error.
1826TEST_F(Dhcp4ParserTest, compatibilityNotBool)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("compatibilityNotBool") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_compatibilityNotBool_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_compatibilityNotBool_Test() = default
; ~Dhcp4ParserTest_compatibilityNotBool_Test() override = default
; Dhcp4ParserTest_compatibilityNotBool_Test (const Dhcp4ParserTest_compatibilityNotBool_Test
&) = delete; Dhcp4ParserTest_compatibilityNotBool_Test &
operator=( const Dhcp4ParserTest_compatibilityNotBool_Test &
) = delete; Dhcp4ParserTest_compatibilityNotBool_Test (Dhcp4ParserTest_compatibilityNotBool_Test
&&) noexcept = delete; Dhcp4ParserTest_compatibilityNotBool_Test
& operator=( Dhcp4ParserTest_compatibilityNotBool_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_compatibilityNotBool_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "compatibilityNotBool", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1826), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1826), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1826), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_compatibilityNotBool_Test
>); void Dhcp4ParserTest_compatibilityNotBool_Test::TestBody
()
{
1827 string config = "{ " + genIfaceConfig() + ","
1828 "\"rebind-timer\": 2000, "
1829 "\"renew-timer\": 1000, "
1830 "\"compatibility\": { "
1831 " \"lenient-option-parsing\": 1"
1832 "},"
1833 "\"subnet4\": [ { "
1834 " \"id\": 1,"
1835 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1836 " \"subnet\": \"192.0.2.0/24\" } ],"
1837 "\"valid-lifetime\": 4000 }";
1838
1839 // Syntax is incorrect.
1840 EXPECT_THROW(parseDHCP4(config), Dhcp4ParseError)switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { bool gtest_caught_expected = false; try { if (
::testing::internal::AlwaysTrue()) { parseDHCP4(config); } else
static_assert(true, ""); } catch (Dhcp4ParseError const&
) { gtest_caught_expected = true; } catch (typename std::conditional
< std::is_same<typename std::remove_cv<typename std::
remove_reference< Dhcp4ParseError>::type>::type, std
::exception>::value, const ::testing::internal::NeverThrown
&, const std::exception&>::type e) { gtest_msg.value
= "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws "; gtest_msg.value
+= ::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testthrow_1840; } catch (...
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_1840; } if (!gtest_caught_expected
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws nothing."; goto gtest_label_testthrow_1840
; } } else gtest_label_testthrow_1840 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1840, gtest_msg.value.c_str()) = ::testing::Message()
;
1841 ConstElementPtr json;
1842 EXPECT_NO_THROW(json = parseJSON(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseJSON(config); } else static_assert(true, ""); } catch
(std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1842
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1842
; } } else gtest_label_testnothrow_1842 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1842, ("Expected: " "json = parseJSON(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1843
1844 // Bad value type is detected.
1845 ConstElementPtr status;
1846 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1846; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1846; } } else gtest_label_testnothrow_1846
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1846, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1847 string expected = "compatibility parameter values must be boolean ";
1848 expected += "(lenient-option-parsing at <string>:1:142)";
1849 checkResult(status, CONTROL_RESULT_ERROR, expected);
1850}
1851
1852// This test checks that the global match-client-id parameter is optional
1853// and that values under the subnet are used.
1854TEST_F(Dhcp4ParserTest, matchClientIdNoGlobal)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("matchClientIdNoGlobal") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_matchClientIdNoGlobal_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_matchClientIdNoGlobal_Test() = default
; ~Dhcp4ParserTest_matchClientIdNoGlobal_Test() override = default
; Dhcp4ParserTest_matchClientIdNoGlobal_Test (const Dhcp4ParserTest_matchClientIdNoGlobal_Test
&) = delete; Dhcp4ParserTest_matchClientIdNoGlobal_Test &
operator=( const Dhcp4ParserTest_matchClientIdNoGlobal_Test &
) = delete; Dhcp4ParserTest_matchClientIdNoGlobal_Test (Dhcp4ParserTest_matchClientIdNoGlobal_Test
&&) noexcept = delete; Dhcp4ParserTest_matchClientIdNoGlobal_Test
& operator=( Dhcp4ParserTest_matchClientIdNoGlobal_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_matchClientIdNoGlobal_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "matchClientIdNoGlobal", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1854), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1854), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1854), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_matchClientIdNoGlobal_Test
>); void Dhcp4ParserTest_matchClientIdNoGlobal_Test::TestBody
()
{
1855 std::string config = "{ " + genIfaceConfig() + ","
1856 "\"rebind-timer\": 2000, "
1857 "\"renew-timer\": 1000, "
1858 "\"subnet4\": [ "
1859 "{"
1860 " \"id\": 1,"
1861 " \"match-client-id\": true,"
1862 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1863 " \"subnet\": \"192.0.2.0/24\""
1864 "},"
1865 "{"
1866 " \"id\": 2,"
1867 " \"match-client-id\": false,"
1868 " \"pools\": [ { \"pool\": \"192.0.3.1 - 192.0.3.100\" } ],"
1869 " \"subnet\": \"192.0.3.0/24\""
1870 "} ],"
1871 "\"valid-lifetime\": 4000 }";
1872
1873 ConstElementPtr json;
1874 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1874
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1874
; } } else gtest_label_testnothrow_1874 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1874, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1875 extractConfig(config);
1876
1877 ConstElementPtr status;
1878 ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1878; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1878; } } else gtest_label_testnothrow_1878
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1878, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1879 checkResult(status, 0);
1880
1881 CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
1882 ConstSubnet4Ptr subnet1 = cfg->selectSubnet(IOAddress("192.0.2.1"));
1883 ASSERT_TRUE(subnet1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet1)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1883, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1", "false", "true") .c_str()) = ::testing::Message(
)
;
1884 // Reset the fetch global function to staging (vs current) config.
1885 Subnet4Ptr mutable_subnet1 = boost::const_pointer_cast<Subnet4>(subnet1);
1886 mutable_subnet1->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
1887 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
1888 });
1889 EXPECT_TRUE(subnet1->getMatchClientId())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet1->getMatchClientId
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1889, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1->getMatchClientId()", "false", "true") .c_str()
) = ::testing::Message()
;
1890
1891 ConstSubnet4Ptr subnet2 = cfg->selectSubnet(IOAddress("192.0.3.1"));
1892 ASSERT_TRUE(subnet2)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet2)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1892, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2", "false", "true") .c_str()) = ::testing::Message(
)
;
1893 // Reset the fetch global function to staging (vs current) config.
1894 Subnet4Ptr mutable_subnet2 = boost::const_pointer_cast<Subnet4>(subnet2);
1895 mutable_subnet2->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
1896 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
1897 });
1898 EXPECT_FALSE(subnet2->getMatchClientId())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet2->getMatchClientId
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1898, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2->getMatchClientId()", "true", "false") .c_str()
) = ::testing::Message()
;
1899}
1900
1901// This test checks that the global match-client-id parameter is used
1902// when there is no such parameter under subnet and that the parameter
1903// specified for a subnet overrides the global setting.
1904TEST_F(Dhcp4ParserTest, matchClientIdGlobal)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("matchClientIdGlobal") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_matchClientIdGlobal_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_matchClientIdGlobal_Test() = default
; ~Dhcp4ParserTest_matchClientIdGlobal_Test() override = default
; Dhcp4ParserTest_matchClientIdGlobal_Test (const Dhcp4ParserTest_matchClientIdGlobal_Test
&) = delete; Dhcp4ParserTest_matchClientIdGlobal_Test &
operator=( const Dhcp4ParserTest_matchClientIdGlobal_Test &
) = delete; Dhcp4ParserTest_matchClientIdGlobal_Test (Dhcp4ParserTest_matchClientIdGlobal_Test
&&) noexcept = delete; Dhcp4ParserTest_matchClientIdGlobal_Test
& operator=( Dhcp4ParserTest_matchClientIdGlobal_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_matchClientIdGlobal_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "matchClientIdGlobal", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1904), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1904), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1904), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_matchClientIdGlobal_Test
>); void Dhcp4ParserTest_matchClientIdGlobal_Test::TestBody
()
{
1905 std::string config = "{ " + genIfaceConfig() + ","
1906 "\"rebind-timer\": 2000, "
1907 "\"renew-timer\": 1000, "
1908 "\"match-client-id\": true,"
1909 "\"subnet4\": [ "
1910 "{"
1911 " \"id\": 1,"
1912 " \"match-client-id\": false,"
1913 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1914 " \"subnet\": \"192.0.2.0/24\""
1915 "},"
1916 "{"
1917 " \"id\": 2,"
1918 " \"pools\": [ { \"pool\": \"192.0.3.1 - 192.0.3.100\" } ],"
1919 " \"subnet\": \"192.0.3.0/24\""
1920 "} ],"
1921 "\"valid-lifetime\": 4000 }";
1922
1923 ConstElementPtr json;
1924 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1924
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1924
; } } else gtest_label_testnothrow_1924 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1924, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1925 extractConfig(config);
1926
1927 ConstElementPtr status;
1928 ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1928; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1928; } } else gtest_label_testnothrow_1928
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1928, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1929 checkResult(status, 0);
1930
1931 CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
1932 ConstSubnet4Ptr subnet1 = cfg->selectSubnet(IOAddress("192.0.2.1"));
1933 ASSERT_TRUE(subnet1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet1)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1933, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1", "false", "true") .c_str()) = ::testing::Message(
)
;
1934 // Reset the fetch global function to staging (vs current) config.
1935 Subnet4Ptr mutable_subnet1 = boost::const_pointer_cast<Subnet4>(subnet1);
1936 mutable_subnet1->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
1937 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
1938 });
1939 EXPECT_FALSE(subnet1->getMatchClientId())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet1->getMatchClientId
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1939, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1->getMatchClientId()", "true", "false") .c_str()
) = ::testing::Message()
;
1940
1941 ConstSubnet4Ptr subnet2 = cfg->selectSubnet(IOAddress("192.0.3.1"));
1942 ASSERT_TRUE(subnet2)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet2)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1942, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2", "false", "true") .c_str()) = ::testing::Message(
)
;
1943 // Reset the fetch global function to staging (vs current) config.
1944 Subnet4Ptr mutable_subnet2 = boost::const_pointer_cast<Subnet4>(subnet2);
1945 mutable_subnet2->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
1946 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
1947 });
1948 EXPECT_TRUE(subnet2->getMatchClientId())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet2->getMatchClientId
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1948, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2->getMatchClientId()", "false", "true") .c_str()
) = ::testing::Message()
;
1949}
1950
1951// This test checks that the global authoritative parameter is optional
1952// and that values under the subnet are used.
1953TEST_F(Dhcp4ParserTest, authoritativeNoGlobal)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("authoritativeNoGlobal") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_authoritativeNoGlobal_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_authoritativeNoGlobal_Test() = default
; ~Dhcp4ParserTest_authoritativeNoGlobal_Test() override = default
; Dhcp4ParserTest_authoritativeNoGlobal_Test (const Dhcp4ParserTest_authoritativeNoGlobal_Test
&) = delete; Dhcp4ParserTest_authoritativeNoGlobal_Test &
operator=( const Dhcp4ParserTest_authoritativeNoGlobal_Test &
) = delete; Dhcp4ParserTest_authoritativeNoGlobal_Test (Dhcp4ParserTest_authoritativeNoGlobal_Test
&&) noexcept = delete; Dhcp4ParserTest_authoritativeNoGlobal_Test
& operator=( Dhcp4ParserTest_authoritativeNoGlobal_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_authoritativeNoGlobal_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "authoritativeNoGlobal", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1953), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1953), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1953), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_authoritativeNoGlobal_Test
>); void Dhcp4ParserTest_authoritativeNoGlobal_Test::TestBody
()
{
1954 std::string config = "{ " + genIfaceConfig() + ","
1955 "\"rebind-timer\": 2000, "
1956 "\"renew-timer\": 1000, "
1957 "\"subnet4\": [ "
1958 "{"
1959 " \"id\": 1,"
1960 " \"authoritative\": true,"
1961 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1962 " \"subnet\": \"192.0.2.0/24\""
1963 "},"
1964 "{"
1965 " \"id\": 2,"
1966 " \"authoritative\": false,"
1967 " \"pools\": [ { \"pool\": \"192.0.3.1 - 192.0.3.100\" } ],"
1968 " \"subnet\": \"192.0.3.0/24\""
1969 "} ],"
1970 "\"valid-lifetime\": 4000 }";
1971
1972 ConstElementPtr json;
1973 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1973
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1973
; } } else gtest_label_testnothrow_1973 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1973, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1974 extractConfig(config);
1975
1976 ConstElementPtr status;
1977 ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_1977; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1977; } } else gtest_label_testnothrow_1977
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1977, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1978 checkResult(status, 0);
1979
1980 CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
1981 ConstSubnet4Ptr subnet1 = cfg->selectSubnet(IOAddress("192.0.2.1"));
1982 ASSERT_TRUE(subnet1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet1)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1982, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1", "false", "true") .c_str()) = ::testing::Message(
)
;
1983 // Reset the fetch global function to staging (vs current) config.
1984 Subnet4Ptr mutable_subnet1 = boost::const_pointer_cast<Subnet4>(subnet1);
1985 mutable_subnet1->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
1986 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
1987 });
1988 EXPECT_TRUE(subnet1->getAuthoritative())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet1->getAuthoritative
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1988, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1->getAuthoritative()", "false", "true") .c_str()
) = ::testing::Message()
;
1989
1990 ConstSubnet4Ptr subnet2 = cfg->selectSubnet(IOAddress("192.0.3.1"));
1991 ASSERT_TRUE(subnet2)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet2)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1991, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2", "false", "true") .c_str()) = ::testing::Message(
)
;
1992 // Reset the fetch global function to staging (vs current) config.
1993 Subnet4Ptr mutable_subnet2 = boost::const_pointer_cast<Subnet4>(subnet2);
1994 mutable_subnet2->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
1995 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
1996 });
1997 EXPECT_FALSE(subnet2->getAuthoritative())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet2->getAuthoritative
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1997, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2->getAuthoritative()", "true", "false") .c_str()
) = ::testing::Message()
;
1998}
1999
2000// This test checks that the global authoritative parameter is used
2001// when there is no such parameter under subnet and that the parameter
2002// specified for a subnet overrides the global setting.
2003TEST_F(Dhcp4ParserTest, authoritativeGlobal)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("authoritativeGlobal") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_authoritativeGlobal_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_authoritativeGlobal_Test() = default
; ~Dhcp4ParserTest_authoritativeGlobal_Test() override = default
; Dhcp4ParserTest_authoritativeGlobal_Test (const Dhcp4ParserTest_authoritativeGlobal_Test
&) = delete; Dhcp4ParserTest_authoritativeGlobal_Test &
operator=( const Dhcp4ParserTest_authoritativeGlobal_Test &
) = delete; Dhcp4ParserTest_authoritativeGlobal_Test (Dhcp4ParserTest_authoritativeGlobal_Test
&&) noexcept = delete; Dhcp4ParserTest_authoritativeGlobal_Test
& operator=( Dhcp4ParserTest_authoritativeGlobal_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_authoritativeGlobal_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "authoritativeGlobal", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2003), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2003), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2003), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_authoritativeGlobal_Test
>); void Dhcp4ParserTest_authoritativeGlobal_Test::TestBody
()
{
2004 std::string config = "{ " + genIfaceConfig() + ","
2005 "\"rebind-timer\": 2000, "
2006 "\"renew-timer\": 1000, "
2007 "\"authoritative\": true,"
2008 "\"subnet4\": [ "
2009 "{"
2010 " \"id\": 1,"
2011 " \"authoritative\": false,"
2012 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
2013 " \"subnet\": \"192.0.2.0/24\""
2014 "},"
2015 "{"
2016 " \"id\": 2,"
2017 " \"pools\": [ { \"pool\": \"192.0.3.1 - 192.0.3.100\" } ],"
2018 " \"subnet\": \"192.0.3.0/24\""
2019 "} ],"
2020 "\"valid-lifetime\": 4000 }";
2021
2022 ConstElementPtr json;
2023 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2023
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2023
; } } else gtest_label_testnothrow_2023 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2023, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2024 extractConfig(config);
2025
2026 ConstElementPtr status;
2027 ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2027; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2027; } } else gtest_label_testnothrow_2027
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2027, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2028 checkResult(status, 0);
2029
2030 CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
2031 ConstSubnet4Ptr subnet1 = cfg->selectSubnet(IOAddress("192.0.2.1"));
2032 ASSERT_TRUE(subnet1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet1)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2032, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1", "false", "true") .c_str()) = ::testing::Message(
)
;
2033 // Reset the fetch global function to staging (vs current) config.
2034 Subnet4Ptr mutable_subnet1 = boost::const_pointer_cast<Subnet4>(subnet1);
2035 mutable_subnet1->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
2036 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
2037 });
2038 EXPECT_FALSE(subnet1->getAuthoritative())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet1->getAuthoritative
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2038, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1->getAuthoritative()", "true", "false") .c_str()
) = ::testing::Message()
;
2039
2040 ConstSubnet4Ptr subnet2 = cfg->selectSubnet(IOAddress("192.0.3.1"));
2041 ASSERT_TRUE(subnet2)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet2)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2041, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2", "false", "true") .c_str()) = ::testing::Message(
)
;
2042 // Reset the fetch global function to staging (vs current) config.
2043 Subnet4Ptr mutable_subnet2 = boost::const_pointer_cast<Subnet4>(subnet2);
2044 mutable_subnet2->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
2045 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
2046 });
2047 EXPECT_TRUE(subnet2->getAuthoritative())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet2->getAuthoritative
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2047, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2->getAuthoritative()", "false", "true") .c_str()
) = ::testing::Message()
;
2048}
2049
2050// This test checks if it is possible to override global values
2051// on a per subnet basis.
2052TEST_F(Dhcp4ParserTest, subnetLocal)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("subnetLocal") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_subnetLocal_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_subnetLocal_Test() = default; ~Dhcp4ParserTest_subnetLocal_Test
() override = default; Dhcp4ParserTest_subnetLocal_Test (const
Dhcp4ParserTest_subnetLocal_Test &) = delete; Dhcp4ParserTest_subnetLocal_Test
& operator=( const Dhcp4ParserTest_subnetLocal_Test &
) = delete; Dhcp4ParserTest_subnetLocal_Test (Dhcp4ParserTest_subnetLocal_Test
&&) noexcept = delete; Dhcp4ParserTest_subnetLocal_Test
& operator=( Dhcp4ParserTest_subnetLocal_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_subnetLocal_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "subnetLocal", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2052
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2052), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2052), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_subnetLocal_Test
>); void Dhcp4ParserTest_subnetLocal_Test::TestBody()
{
2053
2054 string config = "{ " + genIfaceConfig() + ","
2055 "\"rebind-timer\": 2000, "
2056 "\"renew-timer\": 1000, "
2057 "\"subnet4\": [ { "
2058 " \"id\": 1,"
2059 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
2060 " \"renew-timer\": 1, "
2061 " \"rebind-timer\": 2, "
2062 " \"valid-lifetime\": 4,"
2063 " \"min-valid-lifetime\": 3,"
2064 " \"max-valid-lifetime\": 5,"
2065 " \"subnet\": \"192.0.2.0/24\" } ],"
2066 "\"valid-lifetime\": 4000,"
2067 "\"min-valid-lifetime\": 3000,"
2068 "\"max-valid-lifetime\": 5000 }";
2069
2070 ConstElementPtr json;
2071 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2071
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2071
; } } else gtest_label_testnothrow_2071 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2071, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2072 extractConfig(config);
2073
2074 ConstElementPtr status;
2075 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2075; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2075; } } else gtest_label_testnothrow_2075
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2075, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2076
2077 // returned value should be 0 (configuration success)
2078 checkResult(status, 0);
2079
2080 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
2081 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
2082 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2082, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
2083 EXPECT_EQ(1U, subnet->getT1().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "subnet->getT1().get()"
, 1U, subnet->getT1().get()))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2083, gtest_ar.failure_message()) = ::testing::Message()
;
2084 EXPECT_EQ(2U, subnet->getT2().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "subnet->getT2().get()"
, 2U, subnet->getT2().get()))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2084, gtest_ar.failure_message()) = ::testing::Message()
;
2085 EXPECT_EQ(4U, subnet->getValid().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("4U", "subnet->getValid().get()"
, 4U, subnet->getValid().get()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2085, gtest_ar.failure_message()) = ::testing::Message()
;
2086 EXPECT_EQ(3U, subnet->getValid().getMin())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("3U", "subnet->getValid().getMin()"
, 3U, subnet->getValid().getMin()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2086, gtest_ar.failure_message()) = ::testing::Message()
;
2087 EXPECT_EQ(5U, subnet->getValid().getMax())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("5U", "subnet->getValid().getMax()"
, 5U, subnet->getValid().getMax()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2087, gtest_ar.failure_message()) = ::testing::Message()
;
2088}
2089
2090// This test checks if it is possible to define a subnet with an
2091// interface defined.
2092TEST_F(Dhcp4ParserTest, subnetInterface)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("subnetInterface") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_subnetInterface_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_subnetInterface_Test() = default; ~
Dhcp4ParserTest_subnetInterface_Test() override = default; Dhcp4ParserTest_subnetInterface_Test
(const Dhcp4ParserTest_subnetInterface_Test &) = delete;
Dhcp4ParserTest_subnetInterface_Test & operator=( const Dhcp4ParserTest_subnetInterface_Test
&) = delete; Dhcp4ParserTest_subnetInterface_Test (Dhcp4ParserTest_subnetInterface_Test
&&) noexcept = delete; Dhcp4ParserTest_subnetInterface_Test
& operator=( Dhcp4ParserTest_subnetInterface_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_subnetInterface_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "subnetInterface", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2092
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2092), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2092), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_subnetInterface_Test
>); void Dhcp4ParserTest_subnetInterface_Test::TestBody()
{
2093
2094 // There should be at least one interface
2095 // As far as I can tell, this is the first lambda in Kea code. Cool.
2096 auto config = [this](string iface) {
2097 return ("{ " + genIfaceConfig() + ","
2098 "\"rebind-timer\": 2000, "
2099 "\"renew-timer\": 1000, "
2100 "\"subnet4\": [ { "
2101 " \"id\": 1,"
2102 " \"pools\": [ { "
2103 " \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
2104 " \"interface\": \"" + iface + "\","
2105 " \"subnet\": \"192.0.2.0/24\" } ],"
2106 "\"valid-lifetime\": 4000 }"); };
2107 cout << config(valid_iface_) << endl;
2108
2109 ConstElementPtr json;
2110 ASSERT_NO_THROW(json = parseDHCP4(config(valid_iface_)))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config(valid_iface_)); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2110; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2110; } } else gtest_label_testnothrow_2110
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2110, ("Expected: " "json = parseDHCP4(config(valid_iface_))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2111 extractConfig(config("eth0"));
2112
2113 ConstElementPtr status;
2114 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2114; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2114; } } else gtest_label_testnothrow_2114
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2114, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2115
2116 // returned value should be 0 (configuration success)
2117 checkResult(status, 0);
2118
2119 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
2120 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"), classify_);
2121 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2121, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
2122 EXPECT_EQ(valid_iface_, subnet->getIface().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("valid_iface_"
, "subnet->getIface().get()", valid_iface_, subnet->getIface
().get()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2122, gtest_ar.failure_message()) = ::testing::Message()
;
2123}
2124
2125// This test checks if invalid interface name will be rejected in
2126// Subnet4 definition.
2127TEST_F(Dhcp4ParserTest, subnetInterfaceBogus)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("subnetInterfaceBogus") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_subnetInterfaceBogus_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_subnetInterfaceBogus_Test() = default
; ~Dhcp4ParserTest_subnetInterfaceBogus_Test() override = default
; Dhcp4ParserTest_subnetInterfaceBogus_Test (const Dhcp4ParserTest_subnetInterfaceBogus_Test
&) = delete; Dhcp4ParserTest_subnetInterfaceBogus_Test &
operator=( const Dhcp4ParserTest_subnetInterfaceBogus_Test &
) = delete; Dhcp4ParserTest_subnetInterfaceBogus_Test (Dhcp4ParserTest_subnetInterfaceBogus_Test
&&) noexcept = delete; Dhcp4ParserTest_subnetInterfaceBogus_Test
& operator=( Dhcp4ParserTest_subnetInterfaceBogus_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_subnetInterfaceBogus_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "subnetInterfaceBogus", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2127), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2127), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2127), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_subnetInterfaceBogus_Test
>); void Dhcp4ParserTest_subnetInterfaceBogus_Test::TestBody
()
{
2128
2129 // There should be at least one interface
2130
2131 string config = "{ " + genIfaceConfig() + ","
2132 "\"rebind-timer\": 2000, "
2133 "\"renew-timer\": 1000, "
2134 "\"subnet4\": [ { "
2135 " \"id\": 1,"
2136 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
2137 " \"interface\": \"" + bogus_iface_ + "\","
2138 " \"subnet\": \"192.0.2.0/24\" } ],"
2139 "\"valid-lifetime\": 4000 }";
2140 cout << config << endl;
2141
2142 ConstElementPtr json;
2143 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2143
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2143
; } } else gtest_label_testnothrow_2143 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2143, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2144
2145 ConstElementPtr status;
2146 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2146; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2146; } } else gtest_label_testnothrow_2146
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2146, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2147
2148 // returned value should be 1 (configuration error)
2149 checkResult(status, CONTROL_RESULT_ERROR);
2150 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2150, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2151
2152 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
2153 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"), classify_);
2154 EXPECT_FALSE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet))) ; else ::
testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2154
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "true", "false") .c_str()) = ::testing::Message()
;
2155}
2156
2157// This test checks if it is not allowed to define global interface
2158// parameter.
2159TEST_F(Dhcp4ParserTest, interfaceGlobal)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("interfaceGlobal") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_interfaceGlobal_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_interfaceGlobal_Test() = default; ~
Dhcp4ParserTest_interfaceGlobal_Test() override = default; Dhcp4ParserTest_interfaceGlobal_Test
(const Dhcp4ParserTest_interfaceGlobal_Test &) = delete;
Dhcp4ParserTest_interfaceGlobal_Test & operator=( const Dhcp4ParserTest_interfaceGlobal_Test
&) = delete; Dhcp4ParserTest_interfaceGlobal_Test (Dhcp4ParserTest_interfaceGlobal_Test
&&) noexcept = delete; Dhcp4ParserTest_interfaceGlobal_Test
& operator=( Dhcp4ParserTest_interfaceGlobal_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_interfaceGlobal_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "interfaceGlobal", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2159
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2159), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2159), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_interfaceGlobal_Test
>); void Dhcp4ParserTest_interfaceGlobal_Test::TestBody()
{
2160
2161 string config = "{ " + genIfaceConfig() + ","
2162 "\"rebind-timer\": 2000, "
2163 "\"renew-timer\": 1000, "
2164 "\"interface\": \"" + valid_iface_ + "\"," // Not valid. Can be defined in subnet only
2165 "\"subnet4\": [ { "
2166 " \"id\": 1,"
2167 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
2168 " \"subnet\": \"192.0.2.0/24\" } ],"
2169 "\"valid-lifetime\": 4000 }";
2170 cout << config << endl;
2171
2172 ConstElementPtr json = parseJSON(config);
2173
2174 ConstElementPtr status;
2175 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2175; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2175; } } else gtest_label_testnothrow_2175
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2175, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2176
2177 // returned value should be 1 (parse error)
2178 checkResult(status, CONTROL_RESULT_ERROR);
2179 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2179, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2180
2181 EXPECT_THROW(parseDHCP4(config), Dhcp4ParseError)switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { bool gtest_caught_expected = false; try { if (
::testing::internal::AlwaysTrue()) { parseDHCP4(config); } else
static_assert(true, ""); } catch (Dhcp4ParseError const&
) { gtest_caught_expected = true; } catch (typename std::conditional
< std::is_same<typename std::remove_cv<typename std::
remove_reference< Dhcp4ParseError>::type>::type, std
::exception>::value, const ::testing::internal::NeverThrown
&, const std::exception&>::type e) { gtest_msg.value
= "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws "; gtest_msg.value
+= ::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testthrow_2181; } catch (...
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_2181; } if (!gtest_caught_expected
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws nothing."; goto gtest_label_testthrow_2181
; } } else gtest_label_testthrow_2181 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2181, gtest_msg.value.c_str()) = ::testing::Message()
;
2182}
2183
2184// Goal of this test is to verify that invalid subnet fails to be parsed.
2185TEST_F(Dhcp4ParserTest, badSubnetValues)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("badSubnetValues") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_badSubnetValues_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_badSubnetValues_Test() = default; ~
Dhcp4ParserTest_badSubnetValues_Test() override = default; Dhcp4ParserTest_badSubnetValues_Test
(const Dhcp4ParserTest_badSubnetValues_Test &) = delete;
Dhcp4ParserTest_badSubnetValues_Test & operator=( const Dhcp4ParserTest_badSubnetValues_Test
&) = delete; Dhcp4ParserTest_badSubnetValues_Test (Dhcp4ParserTest_badSubnetValues_Test
&&) noexcept = delete; Dhcp4ParserTest_badSubnetValues_Test
& operator=( Dhcp4ParserTest_badSubnetValues_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_badSubnetValues_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "badSubnetValues", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2185
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2185), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2185), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_badSubnetValues_Test
>); void Dhcp4ParserTest_badSubnetValues_Test::TestBody()
{
2186
2187 // Contains parts needed for a single test scenario.
2188 struct Scenario {
2189 std::string description_;
2190 std::string config_json_;
2191 std::string exp_error_msg_;
2192 };
2193
2194 // Vector of scenarios.
2195 std::vector<Scenario> scenarios = {
2196 {
2197 "IP is not an address",
2198 "{ \"subnet4\": [ { "
2199 " \"subnet\": \"not an address/24\" } ],"
2200 "\"valid-lifetime\": 4000 }",
2201 "subnet configuration failed: "
2202 "Failed to convert string to address 'notanaddress': Invalid argument"
2203 },
2204 {
2205 "IP is Invalid",
2206 "{ \"subnet4\": [ { "
2207 " \"subnet\": \"256.16.1.0/24\" } ],"
2208 "\"valid-lifetime\": 4000 }",
2209 "subnet configuration failed: "
2210 "Failed to convert string to address '256.16.1.0': Invalid argument"
2211 },
2212 {
2213 "Missing prefix",
2214 "{ \"subnet4\": [ { "
2215 " \"subnet\": \"192.0.2.0\" } ],"
2216 "\"valid-lifetime\": 4000 }",
2217 "subnet configuration failed: "
2218 "Invalid subnet syntax (prefix/len expected):192.0.2.0 (<string>:1:32)"
2219 },
2220 {
2221 "Prefix not an integer (2 slashes)",
2222 "{ \"subnet4\": [ { "
2223 " \"subnet\": \"192.0.2.0//24\" } ],"
2224 "\"valid-lifetime\": 4000 }",
2225 "subnet configuration failed: "
2226 "prefix length: '/24' is not an integer (<string>:1:32)"
2227 },
2228 {
2229 "Prefix value is insane",
2230 "{ \"subnet4\": [ { "
2231 " \"subnet\": \"192.0.2.0/45938\" } ],"
2232 "\"valid-lifetime\": 4000 }",
2233 "subnet configuration failed: "
2234 "Invalid prefix length specified for subnet: 45938 (<string>:1:32)"
2235 }
2236 };
2237
2238 // Iterate over the list of scenarios. Each should fail to parse with
2239 // a specific error message.
2240 for (auto const& scenario : scenarios) {
2241 SCOPED_TRACE(scenario.description_)const ::testing::ScopedTrace gtest_trace_2241( "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2241, (scenario.description_))
;
2242 ConstElementPtr config;
2243 ASSERT_NO_THROW(config = parseDHCP4(scenario.config_json_))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
config = parseDHCP4(scenario.config_json_); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2243; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2243; } } else gtest_label_testnothrow_2243
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2243, ("Expected: " "config = parseDHCP4(scenario.config_json_)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
2244 << "invalid json, broken test";
2245 ConstElementPtr status;
2246 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, config); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2246; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2246; } } else gtest_label_testnothrow_2246
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2246, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, config)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2247 checkResult(status, CONTROL_RESULT_ERROR);
2248 ASSERT_TRUE(comment_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(comment_)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2248, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "comment_", "false", "true") .c_str()) = ::testing::Message
()
;
2249 EXPECT_EQ(comment_->stringValue(), scenario.exp_error_msg_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("comment_->stringValue()"
, "scenario.exp_error_msg_", comment_->stringValue(), scenario
.exp_error_msg_))) ; else ::testing::internal::AssertHelper(::
testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2249, gtest_ar.failure_message()) = ::testing::Message()
;
2250 }
2251}
2252
2253// This test checks that multiple pools can be defined and handled properly.
2254// The test defines 2 subnets, each with 2 pools.
2255TEST_F(Dhcp4ParserTest, multiplePools)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("multiplePools") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_multiplePools_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_multiplePools_Test() = default; ~Dhcp4ParserTest_multiplePools_Test
() override = default; Dhcp4ParserTest_multiplePools_Test (const
Dhcp4ParserTest_multiplePools_Test &) = delete; Dhcp4ParserTest_multiplePools_Test
& operator=( const Dhcp4ParserTest_multiplePools_Test &
) = delete; Dhcp4ParserTest_multiplePools_Test (Dhcp4ParserTest_multiplePools_Test
&&) noexcept = delete; Dhcp4ParserTest_multiplePools_Test
& operator=( Dhcp4ParserTest_multiplePools_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_multiplePools_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "multiplePools", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2255
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2255), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2255), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_multiplePools_Test
>); void Dhcp4ParserTest_multiplePools_Test::TestBody()
{
2256 // Collection with two subnets, each with 2 pools.
2257 string config = "{ " + genIfaceConfig() + ","
2258 "\"rebind-timer\": 2000, "
2259 "\"renew-timer\": 1000, "
2260 "\"subnet4\": [ { "
2261 " \"id\": 1,"
2262 " \"pools\": [ "
2263 " { \"pool\": \"192.0.2.0/28\" },"
2264 " { \"pool\": \"192.0.2.200-192.0.2.255\" }"
2265 " ],"
2266 " \"subnet\": \"192.0.2.0/24\" "
2267 " },"
2268 " {"
2269 " \"id\": 2,"
2270 " \"pools\": [ "
2271 " { \"pool\": \"192.0.3.0/25\" },"
2272 " { \"pool\": \"192.0.3.128/25\" }"
2273 " ],"
2274 " \"subnet\": \"192.0.3.0/24\""
2275 " } ],"
2276 "\"valid-lifetime\": 4000 }";
2277 ConstElementPtr json;
2278 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2278
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2278
; } } else gtest_label_testnothrow_2278 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2278, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2279 extractConfig(config);
2280
2281 ConstElementPtr status;
2282 ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2282; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2282; } } else gtest_label_testnothrow_2282
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2282, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2283 checkResult(status, 0);
2284
2285 const Subnet4Collection* subnets =
2286 CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
2287 ASSERT_TRUE(subnets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnets)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2287, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
2288 ASSERT_EQ(2U, subnets->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "subnets->size()"
, 2U, subnets->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2288, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 2 subnets
2289
2290 // Check the first subnet
2291 auto subnet = subnets->begin();
2292 const PoolCollection& pools1 = (*subnet)->getPools(Lease::TYPE_V4);
2293 ASSERT_EQ(2U, pools1.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "pools1.size()"
, 2U, pools1.size()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2293, gtest_ar.failure_message()) = ::testing::Message()
;
2294 EXPECT_EQ("type=V4, 192.0.2.0-192.0.2.15",switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"type=V4, 192.0.2.0-192.0.2.15\""
, "pools1[0]->toText()", "type=V4, 192.0.2.0-192.0.2.15", pools1
[0]->toText()))) ; else ::testing::internal::AssertHelper(
::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2295, gtest_ar.failure_message()) = ::testing::Message()
2295 pools1[0]->toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"type=V4, 192.0.2.0-192.0.2.15\""
, "pools1[0]->toText()", "type=V4, 192.0.2.0-192.0.2.15", pools1
[0]->toText()))) ; else ::testing::internal::AssertHelper(
::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2295, gtest_ar.failure_message()) = ::testing::Message()
;
2296 EXPECT_EQ("type=V4, 192.0.2.200-192.0.2.255",switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"type=V4, 192.0.2.200-192.0.2.255\""
, "pools1[1]->toText()", "type=V4, 192.0.2.200-192.0.2.255"
, pools1[1]->toText()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2297, gtest_ar.failure_message()) = ::testing::Message()
2297 pools1[1]->toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"type=V4, 192.0.2.200-192.0.2.255\""
, "pools1[1]->toText()", "type=V4, 192.0.2.200-192.0.2.255"
, pools1[1]->toText()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2297, gtest_ar.failure_message()) = ::testing::Message()
;
2298 // There shouldn't be any PD pools
2299 EXPECT_THROW((*subnet)->getPools(Lease::TYPE_PD), BadValue)switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { bool gtest_caught_expected = false; try { if (
::testing::internal::AlwaysTrue()) { (*subnet)->getPools(Lease
::TYPE_PD); } else static_assert(true, ""); } catch (BadValue
const&) { gtest_caught_expected = true; } catch (typename
std::conditional< std::is_same<typename std::remove_cv
<typename std::remove_reference< BadValue>::type>
::type, std::exception>::value, const ::testing::internal::
NeverThrown&, const std::exception&>::type e) { gtest_msg
.value = "Expected: " "(*subnet)->getPools(Lease::TYPE_PD)"
" throws an exception of type " "BadValue" ".\n Actual: it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testthrow_2299
; } catch (...) { gtest_msg.value = "Expected: " "(*subnet)->getPools(Lease::TYPE_PD)"
" throws an exception of type " "BadValue" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_2299; } if (!gtest_caught_expected
) { gtest_msg.value = "Expected: " "(*subnet)->getPools(Lease::TYPE_PD)"
" throws an exception of type " "BadValue" ".\n Actual: it throws nothing."
; goto gtest_label_testthrow_2299; } } else gtest_label_testthrow_2299
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2299, gtest_msg.value.c_str()) = ::testing::Message()
;
2300
2301 // Check the second subnet
2302 ++subnet;
2303 const PoolCollection& pools2 = (*subnet)->getPools(Lease::TYPE_V4);
2304 ASSERT_EQ(2U, pools2.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "pools2.size()"
, 2U, pools2.size()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2304, gtest_ar.failure_message()) = ::testing::Message()
;
2305 EXPECT_EQ("type=V4, 192.0.3.0-192.0.3.127",switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"type=V4, 192.0.3.0-192.0.3.127\""
, "pools2[0]->toText()", "type=V4, 192.0.3.0-192.0.3.127",
pools2[0]->toText()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2306, gtest_ar.failure_message()) = ::testing::Message()
2306 pools2[0]->toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"type=V4, 192.0.3.0-192.0.3.127\""
, "pools2[0]->toText()", "type=V4, 192.0.3.0-192.0.3.127",
pools2[0]->toText()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2306, gtest_ar.failure_message()) = ::testing::Message()
;
2307 EXPECT_EQ("type=V4, 192.0.3.128-192.0.3.255",switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"type=V4, 192.0.3.128-192.0.3.255\""
, "pools2[1]->toText()", "type=V4, 192.0.3.128-192.0.3.255"
, pools2[1]->toText()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2308, gtest_ar.failure_message()) = ::testing::Message()
2308 pools2[1]->toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"type=V4, 192.0.3.128-192.0.3.255\""
, "pools2[1]->toText()", "type=V4, 192.0.3.128-192.0.3.255"
, pools2[1]->toText()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2308, gtest_ar.failure_message()) = ::testing::Message()
;
2309 // There shouldn't be any PD pools
2310 EXPECT_THROW((*subnet)->getPools(Lease::TYPE_PD), BadValue)switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { bool gtest_caught_expected = false; try { if (
::testing::internal::AlwaysTrue()) { (*subnet)->getPools(Lease
::TYPE_PD); } else static_assert(true, ""); } catch (BadValue
const&) { gtest_caught_expected = true; } catch (typename
std::conditional< std::is_same<typename std::remove_cv
<typename std::remove_reference< BadValue>::type>
::type, std::exception>::value, const ::testing::internal::
NeverThrown&, const std::exception&>::type e) { gtest_msg
.value = "Expected: " "(*subnet)->getPools(Lease::TYPE_PD)"
" throws an exception of type " "BadValue" ".\n Actual: it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testthrow_2310
; } catch (...) { gtest_msg.value = "Expected: " "(*subnet)->getPools(Lease::TYPE_PD)"
" throws an exception of type " "BadValue" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_2310; } if (!gtest_caught_expected
) { gtest_msg.value = "Expected: " "(*subnet)->getPools(Lease::TYPE_PD)"
" throws an exception of type " "BadValue" ".\n Actual: it throws nothing."
; goto gtest_label_testthrow_2310; } } else gtest_label_testthrow_2310
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2310, gtest_msg.value.c_str()) = ::testing::Message()
;
2311}
2312
2313// Test verifies that a subnet with pool values that do not belong to that
2314// pool are rejected.
2315TEST_F(Dhcp4ParserTest, poolOutOfSubnet)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("poolOutOfSubnet") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_poolOutOfSubnet_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_poolOutOfSubnet_Test() = default; ~
Dhcp4ParserTest_poolOutOfSubnet_Test() override = default; Dhcp4ParserTest_poolOutOfSubnet_Test
(const Dhcp4ParserTest_poolOutOfSubnet_Test &) = delete;
Dhcp4ParserTest_poolOutOfSubnet_Test & operator=( const Dhcp4ParserTest_poolOutOfSubnet_Test
&) = delete; Dhcp4ParserTest_poolOutOfSubnet_Test (Dhcp4ParserTest_poolOutOfSubnet_Test
&&) noexcept = delete; Dhcp4ParserTest_poolOutOfSubnet_Test
& operator=( Dhcp4ParserTest_poolOutOfSubnet_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_poolOutOfSubnet_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "poolOutOfSubnet", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2315
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2315), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2315), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_poolOutOfSubnet_Test
>); void Dhcp4ParserTest_poolOutOfSubnet_Test::TestBody()
{
2316
2317 string config = "{ " + genIfaceConfig() + ","
2318 "\"rebind-timer\": 2000, "
2319 "\"renew-timer\": 1000, "
2320 "\"subnet4\": [ { "
2321 " \"id\": 1,"
2322 " \"pools\": [ { \"pool\": \"192.0.4.0/28\" } ],"
2323 " \"subnet\": \"192.0.2.0/24\" } ],"
2324 "\"valid-lifetime\": 4000 }";
2325
2326 ConstElementPtr json;
2327 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2327
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2327
; } } else gtest_label_testnothrow_2327 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2327, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2328
2329 ConstElementPtr status;
2330 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2330; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2330; } } else gtest_label_testnothrow_2330
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2330, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2331
2332 // returned value must be 1 (values error)
2333 // as the pool does not belong to that subnet
2334 checkResult(status, CONTROL_RESULT_ERROR);
2335 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2335, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2336}
2337
2338// Goal of this test is to verify if pools can be defined
2339// using prefix/length notation. There is no separate test for min-max
2340// notation as it was tested in several previous tests.
2341TEST_F(Dhcp4ParserTest, poolPrefixLen)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("poolPrefixLen") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_poolPrefixLen_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_poolPrefixLen_Test() = default; ~Dhcp4ParserTest_poolPrefixLen_Test
() override = default; Dhcp4ParserTest_poolPrefixLen_Test (const
Dhcp4ParserTest_poolPrefixLen_Test &) = delete; Dhcp4ParserTest_poolPrefixLen_Test
& operator=( const Dhcp4ParserTest_poolPrefixLen_Test &
) = delete; Dhcp4ParserTest_poolPrefixLen_Test (Dhcp4ParserTest_poolPrefixLen_Test
&&) noexcept = delete; Dhcp4ParserTest_poolPrefixLen_Test
& operator=( Dhcp4ParserTest_poolPrefixLen_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_poolPrefixLen_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "poolPrefixLen", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2341
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2341), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2341), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_poolPrefixLen_Test
>); void Dhcp4ParserTest_poolPrefixLen_Test::TestBody()
{
2342 string config = "{ " + genIfaceConfig() + ","
2343 "\"rebind-timer\": 2000, "
2344 "\"renew-timer\": 1000, "
2345 "\"subnet4\": [ { "
2346 " \"id\": 1,"
2347 " \"pools\": [ { \"pool\": \"192.0.2.128/28\" } ],"
2348 " \"subnet\": \"192.0.2.0/24\" } ],"
2349 "\"valid-lifetime\": 4000 }";
2350
2351 ConstElementPtr json;
2352 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2352
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2352
; } } else gtest_label_testnothrow_2352 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2352, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2353 extractConfig(config);
2354
2355 ConstElementPtr status;
2356 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2356; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2356; } } else gtest_label_testnothrow_2356
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2356, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2357
2358 // returned value must be 0 (configuration accepted)
2359 checkResult(status, 0);
2360
2361 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
2362 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
2363 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2363, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
2364 EXPECT_EQ(1000U, subnet->getT1().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1000U", "subnet->getT1().get()"
, 1000U, subnet->getT1().get()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2364, gtest_ar.failure_message()) = ::testing::Message()
;
2365 EXPECT_EQ(2000U, subnet->getT2().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2000U", "subnet->getT2().get()"
, 2000U, subnet->getT2().get()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2365, gtest_ar.failure_message()) = ::testing::Message()
;
2366 EXPECT_EQ(4000U, subnet->getValid().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("4000U", "subnet->getValid().get()"
, 4000U, subnet->getValid().get()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2366, gtest_ar.failure_message()) = ::testing::Message()
;
2367}
2368
2369// Goal of this test is to verify if invalid pool definitions
2370// return a location in the error message.
2371TEST_F(Dhcp4ParserTest, badPools)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("badPools") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_badPools_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_badPools_Test() = default; ~Dhcp4ParserTest_badPools_Test
() override = default; Dhcp4ParserTest_badPools_Test (const Dhcp4ParserTest_badPools_Test
&) = delete; Dhcp4ParserTest_badPools_Test & operator
=( const Dhcp4ParserTest_badPools_Test &) = delete; Dhcp4ParserTest_badPools_Test
(Dhcp4ParserTest_badPools_Test &&) noexcept = delete
; Dhcp4ParserTest_badPools_Test & operator=( Dhcp4ParserTest_badPools_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_badPools_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "badPools", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2371
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2371), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2371), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_badPools_Test
>); void Dhcp4ParserTest_badPools_Test::TestBody()
{
2372
2373 // not a prefix
2374 string config_bogus1 = "{ " + genIfaceConfig() + ","
2375 "\"rebind-timer\": 2000, "
2376 "\"renew-timer\": 1000, "
2377 "\"subnet4\": [ { "
2378 " \"id\": 1,"
2379 " \"pools\": [ { \"pool\": \"foo/28\" } ],"
2380 " \"subnet\": \"192.0.2.0/24\" } ],"
2381 "\"valid-lifetime\": 4000 }";
2382
2383 // not a length
2384 string config_bogus2 = "{ " + genIfaceConfig() + ","
2385 "\"rebind-timer\": 2000, "
2386 "\"renew-timer\": 1000, "
2387 "\"subnet4\": [ { "
2388 " \"id\": 1,"
2389 " \"pools\": [ { \"pool\": \"192.0.2.128/foo\" } ],"
2390 " \"subnet\": \"192.0.2.0/24\" } ],"
2391 "\"valid-lifetime\": 4000 }";
2392
2393 // invalid prefix length
2394 string config_bogus3 = "{ " + genIfaceConfig() + ","
2395 "\"rebind-timer\": 2000, "
2396 "\"renew-timer\": 1000, "
2397 "\"subnet4\": [ { "
2398 " \"id\": 1,"
2399 " \"pools\": [ { \"pool\": \"192.0.2.128/100\" } ],"
2400 " \"subnet\": \"192.0.2.0/24\" } ],"
2401 "\"valid-lifetime\": 4000 }";
2402
2403 // not a prefix nor a min-max
2404 string config_bogus4 = "{ " + genIfaceConfig() + ","
2405 "\"rebind-timer\": 2000, "
2406 "\"renew-timer\": 1000, "
2407 "\"subnet4\": [ { "
2408 " \"id\": 1,"
2409 " \"pools\": [ { \"pool\": \"foo\" } ],"
2410 " \"subnet\": \"192.0.2.0/24\" } ],"
2411 "\"valid-lifetime\": 4000 }";
2412
2413 // not an address
2414 string config_bogus5 = "{ " + genIfaceConfig() + ","
2415 "\"rebind-timer\": 2000, "
2416 "\"renew-timer\": 1000, "
2417 "\"subnet4\": [ { "
2418 " \"id\": 1,"
2419 " \"pools\": [ { \"pool\": \"foo - bar\" } ],"
2420 " \"subnet\": \"192.0.2.0/24\" } ],"
2421 "\"valid-lifetime\": 4000 }";
2422
2423 // min > max
2424 string config_bogus6 = "{ " + genIfaceConfig() + ","
2425 "\"rebind-timer\": 2000, "
2426 "\"renew-timer\": 1000, "
2427 "\"subnet4\": [ { "
2428 " \"id\": 1,"
2429 " \"pools\": [ { \"pool\": \"192.0.2.200 - 192.0.2.100\" } ],"
2430 " \"subnet\": \"192.0.2.0/24\" } ],"
2431 "\"valid-lifetime\": 4000 }";
2432
2433 // out of range prefix length (new check)
2434 string config_bogus7 = "{ " + genIfaceConfig() + ","
2435 "\"rebind-timer\": 2000, "
2436 "\"renew-timer\": 1000, "
2437 "\"subnet4\": [ { "
2438 " \"id\": 1,"
2439 " \"pools\": [ { \"pool\": \"192.0.2.128/1052\" } ],"
2440 " \"subnet\": \"192.0.2.0/24\" } ],"
2441 "\"valid-lifetime\": 4000 }";
2442
2443 ConstElementPtr json1;
2444 ASSERT_NO_THROW(json1 = parseDHCP4(config_bogus1))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json1 = parseDHCP4(config_bogus1); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2444
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2444
; } } else gtest_label_testnothrow_2444 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2444, ("Expected: " "json1 = parseDHCP4(config_bogus1)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2445 ConstElementPtr json2;
2446 ASSERT_NO_THROW(json2 = parseDHCP4(config_bogus2))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json2 = parseDHCP4(config_bogus2); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2446
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2446
; } } else gtest_label_testnothrow_2446 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2446, ("Expected: " "json2 = parseDHCP4(config_bogus2)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2447 ConstElementPtr json3;
2448 ASSERT_NO_THROW(json3 = parseDHCP4(config_bogus3))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json3 = parseDHCP4(config_bogus3); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2448
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2448
; } } else gtest_label_testnothrow_2448 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2448, ("Expected: " "json3 = parseDHCP4(config_bogus3)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2449 ConstElementPtr json4;
2450 ASSERT_NO_THROW(json4 = parseDHCP4(config_bogus4))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json4 = parseDHCP4(config_bogus4); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2450
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2450
; } } else gtest_label_testnothrow_2450 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2450, ("Expected: " "json4 = parseDHCP4(config_bogus4)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2451 ConstElementPtr json5;
2452 ASSERT_NO_THROW(json5 = parseDHCP4(config_bogus5))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json5 = parseDHCP4(config_bogus5); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2452
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2452
; } } else gtest_label_testnothrow_2452 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2452, ("Expected: " "json5 = parseDHCP4(config_bogus5)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2453 ConstElementPtr json6;
2454 ASSERT_NO_THROW(json6 = parseDHCP4(config_bogus6))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json6 = parseDHCP4(config_bogus6); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2454
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2454
; } } else gtest_label_testnothrow_2454 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2454, ("Expected: " "json6 = parseDHCP4(config_bogus6)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2455 ConstElementPtr json7;
2456 ASSERT_NO_THROW(json7 = parseDHCP4(config_bogus7))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json7 = parseDHCP4(config_bogus7); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2456
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2456
; } } else gtest_label_testnothrow_2456 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2456, ("Expected: " "json7 = parseDHCP4(config_bogus7)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2457
2458 ConstElementPtr status;
2459 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json1))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json1); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2459; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2459; } } else gtest_label_testnothrow_2459
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2459, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json1)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2460
2461 // check if returned status is always a failure
2462 checkResult(status, CONTROL_RESULT_ERROR);
2463 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2463, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2464
2465 CfgMgr::instance().clear();
2466
2467 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json2))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json2); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2467; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2467; } } else gtest_label_testnothrow_2467
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2467, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json2)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2468 checkResult(status, CONTROL_RESULT_ERROR);
2469 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2469, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2470
2471 CfgMgr::instance().clear();
2472
2473 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json3))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json3); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2473; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2473; } } else gtest_label_testnothrow_2473
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2473, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json3)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2474 checkResult(status, CONTROL_RESULT_ERROR);
2475 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2475, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2476
2477 CfgMgr::instance().clear();
2478
2479 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json4))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json4); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2479; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2479; } } else gtest_label_testnothrow_2479
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2479, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json4)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2480 checkResult(status, CONTROL_RESULT_ERROR);
2481 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2481, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2482
2483 CfgMgr::instance().clear();
2484
2485 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json5))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json5); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2485; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2485; } } else gtest_label_testnothrow_2485
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2485, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json5)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2486 checkResult(status, CONTROL_RESULT_ERROR);
2487 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2487, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2488
2489 CfgMgr::instance().clear();
2490
2491 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json6))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json6); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2491; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2491; } } else gtest_label_testnothrow_2491
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2491, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json6)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2492 checkResult(status, CONTROL_RESULT_ERROR);
2493 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2493, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2494
2495 CfgMgr::instance().clear();
2496
2497 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json7))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json7); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2497; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2497; } } else gtest_label_testnothrow_2497
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2497, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json7)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2498 checkResult(status, CONTROL_RESULT_ERROR);
2499 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2499, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2500}
2501
2502// Goal of this test is to verify no pool definitions is invalid
2503// and returns a location in the error message.
2504TEST_F(Dhcp4ParserTest, noPools)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("noPools") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_noPools_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_noPools_Test() = default; ~Dhcp4ParserTest_noPools_Test
() override = default; Dhcp4ParserTest_noPools_Test (const Dhcp4ParserTest_noPools_Test
&) = delete; Dhcp4ParserTest_noPools_Test & operator
=( const Dhcp4ParserTest_noPools_Test &) = delete; Dhcp4ParserTest_noPools_Test
(Dhcp4ParserTest_noPools_Test &&) noexcept = delete;
Dhcp4ParserTest_noPools_Test & operator=( Dhcp4ParserTest_noPools_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_noPools_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "noPools", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2504
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2504), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2504), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_noPools_Test
>); void Dhcp4ParserTest_noPools_Test::TestBody()
{
2505
2506 // Configuration string.
2507 string config = "{ " + genIfaceConfig() + ","
2508 "\"rebind-timer\": 2000, "
2509 "\"renew-timer\": 1000, "
2510 "\"subnet4\": [ { "
2511 " \"id\": 1,"
2512 " \"pools\": [ { \"user-context\": { } } ],"
2513 " \"subnet\": \"192.0.2.0/24\" } ],"
2514 "\"valid-lifetime\": 4000 }";
2515
2516 EXPECT_THROW(parseDHCP4(config, true), Dhcp4ParseError)switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { bool gtest_caught_expected = false; try { if (
::testing::internal::AlwaysTrue()) { parseDHCP4(config, true)
; } else static_assert(true, ""); } catch (Dhcp4ParseError const
&) { gtest_caught_expected = true; } catch (typename std::
conditional< std::is_same<typename std::remove_cv<typename
std::remove_reference< Dhcp4ParseError>::type>::type
, std::exception>::value, const ::testing::internal::NeverThrown
&, const std::exception&>::type e) { gtest_msg.value
= "Expected: " "parseDHCP4(config, true)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws "; gtest_msg.value
+= ::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testthrow_2516; } catch (...
) { gtest_msg.value = "Expected: " "parseDHCP4(config, true)"
" throws an exception of type " "Dhcp4ParseError" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_2516; } if (!gtest_caught_expected
) { gtest_msg.value = "Expected: " "parseDHCP4(config, true)"
" throws an exception of type " "Dhcp4ParseError" ".\n Actual: it throws nothing."
; goto gtest_label_testthrow_2516; } } else gtest_label_testthrow_2516
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2516, gtest_msg.value.c_str()) = ::testing::Message()
;
2517}
2518
2519
2520// Goal of this test is to verify that unknown interface fails
2521// to be parsed.
2522TEST_F(Dhcp4ParserTest, unknownInterface)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("unknownInterface") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_unknownInterface_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_unknownInterface_Test() = default;
~Dhcp4ParserTest_unknownInterface_Test() override = default;
Dhcp4ParserTest_unknownInterface_Test (const Dhcp4ParserTest_unknownInterface_Test
&) = delete; Dhcp4ParserTest_unknownInterface_Test &
operator=( const Dhcp4ParserTest_unknownInterface_Test &
) = delete; Dhcp4ParserTest_unknownInterface_Test (Dhcp4ParserTest_unknownInterface_Test
&&) noexcept = delete; Dhcp4ParserTest_unknownInterface_Test
& operator=( Dhcp4ParserTest_unknownInterface_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_unknownInterface_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "unknownInterface", nullptr, nullptr, ::testing::internal::
CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2522), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2522), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2522), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_unknownInterface_Test
>); void Dhcp4ParserTest_unknownInterface_Test::TestBody()
{
2523
2524 // Configuration string.
2525 string config = "{ " + genIfaceConfig() + ","
2526 "\"rebind-timer\": 2000, "
2527 "\"renew-timer\": 1000, "
2528 "\"subnet4\": [ { "
2529 " \"id\": 1,"
2530 " \"pools\": [ ],"
2531 " \"subnet\": \"192.0.2.0/24\","
2532 " \"interface\": \"ethX\" } ],"
2533 "\"valid-lifetime\": 4000 }";
2534
2535 ConstElementPtr json;
2536 ASSERT_NO_THROW(json = parseDHCP4(config, true))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config, true); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2536
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2536
; } } else gtest_label_testnothrow_2536 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2536, ("Expected: " "json = parseDHCP4(config, true)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2537 ConstElementPtr status;
2538 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2538; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2538; } } else gtest_label_testnothrow_2538
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2538, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2539 checkResult(status, CONTROL_RESULT_ERROR);
2540 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2540, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2541}
2542
2543// The goal of this test is to check whether an option definition
2544// that defines an option carrying an IPv4 address can be created.
2545TEST_F(Dhcp4ParserTest, optionDefIpv4Address)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDefIpv4Address") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionDefIpv4Address_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionDefIpv4Address_Test() = default
; ~Dhcp4ParserTest_optionDefIpv4Address_Test() override = default
; Dhcp4ParserTest_optionDefIpv4Address_Test (const Dhcp4ParserTest_optionDefIpv4Address_Test
&) = delete; Dhcp4ParserTest_optionDefIpv4Address_Test &
operator=( const Dhcp4ParserTest_optionDefIpv4Address_Test &
) = delete; Dhcp4ParserTest_optionDefIpv4Address_Test (Dhcp4ParserTest_optionDefIpv4Address_Test
&&) noexcept = delete; Dhcp4ParserTest_optionDefIpv4Address_Test
& operator=( Dhcp4ParserTest_optionDefIpv4Address_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionDefIpv4Address_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDefIpv4Address", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2545), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2545), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2545), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefIpv4Address_Test
>); void Dhcp4ParserTest_optionDefIpv4Address_Test::TestBody
()
{
2546
2547 // Configuration string.
2548 std::string config =
2549 "{ \"option-def\": [ {"
2550 " \"name\": \"foo\","
2551 " \"code\": 100,"
2552 " \"type\": \"ipv4-address\","
2553 " \"space\": \"isc\""
2554 " } ]"
2555 "}";
2556 ConstElementPtr json;
2557 ASSERT_NO_THROW(json = parseOPTION_DEFS(config, true))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseOPTION_DEFS(config, true); } else static_assert(
true, ""); } catch (std::exception const& e) { gtest_msg.
value = "it throws "; gtest_msg.value += ::testing::internal::
GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2557; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2557; } } else gtest_label_testnothrow_2557
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2557, ("Expected: " "json = parseOPTION_DEFS(config, true)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2558 extractConfig(config);
2559
2560 // Make sure that the particular option definition does not exist.
2561 OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
2562 getCfgOptionDef()->get("isc", 100);
2563 ASSERT_FALSE(def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(def))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2563, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "true", "false") .c_str()) = ::testing::Message()
;
2564
2565 // Use the configuration string to create new option definition.
2566 ConstElementPtr status;
2567 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2567; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2567; } } else gtest_label_testnothrow_2567
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2567, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2568 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2568, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2569 checkResult(status, 0);
2570
2571 // We need to commit option definitions because later in this test we
2572 // will be checking if they get removed when "option-def" parameter
2573 // is removed from a configuration.
2574 LibDHCP::commitRuntimeOptionDefs();
2575
2576 // The option definition should now be available in the CfgMgr.
2577 def = CfgMgr::instance().getStagingCfg()->getCfgOptionDef()->get("isc", 100);
2578 ASSERT_TRUE(def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2578
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "false", "true") .c_str()) = ::testing::Message()
;
2579
2580 // Verify that the option definition data is valid.
2581 EXPECT_EQ("foo", def->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"foo\""
, "def->getName()", "foo", def->getName()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2581
, gtest_ar.failure_message()) = ::testing::Message()
;
2582 EXPECT_EQ(100U, def->getCode())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("100U", "def->getCode()"
, 100U, def->getCode()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2582, gtest_ar.failure_message()) = ::testing::Message()
;
2583 EXPECT_FALSE(def->getArrayType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(def->getArrayType
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2583, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getArrayType()", "true", "false") .c_str()) = ::testing
::Message()
;
2584 EXPECT_EQ(OPT_IPV4_ADDRESS_TYPE, def->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("OPT_IPV4_ADDRESS_TYPE"
, "def->getType()", OPT_IPV4_ADDRESS_TYPE, def->getType
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2584, gtest_ar.failure_message()) = ::testing::Message()
;
2585 EXPECT_TRUE(def->getEncapsulatedSpace().empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def->getEncapsulatedSpace
().empty())) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2585, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getEncapsulatedSpace().empty()", "false", "true") .
c_str()) = ::testing::Message()
;
2586
2587 // The copy of the option definition should be available in the libdhcp++.
2588 OptionDefinitionPtr def_libdhcp = LibDHCP::getRuntimeOptionDef("isc", 100);
2589 ASSERT_TRUE(def_libdhcp)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def_libdhcp)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2589, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def_libdhcp", "false", "true") .c_str()) = ::testing::Message
()
;
2590
2591 // Both definitions should be held in distinct pointers but they should
2592 // be equal.
2593 EXPECT_TRUE(def_libdhcp != def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def_libdhcp != def)) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2593, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def_libdhcp != def", "false", "true") .c_str()) = ::testing
::Message()
;
2594 EXPECT_TRUE(*def_libdhcp == *def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(*def_libdhcp == *def)
) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2594, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "*def_libdhcp == *def", "false", "true") .c_str()) = ::testing
::Message()
;
2595
2596 // Let's apply empty configuration. This removes the option definitions
2597 // configuration and should result in removal of the option 100 from the
2598 // libdhcp++. Note DHCP4 or OPTION_DEFS parsers do not accept empty maps.
2599 json.reset(new MapElement());
2600 ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2600; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2600; } } else gtest_label_testnothrow_2600
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2600, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2601 checkResult(status, 0);
2602
2603 EXPECT_FALSE(LibDHCP::getRuntimeOptionDef("isc", 100))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(LibDHCP::getRuntimeOptionDef
("isc", 100)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2603, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "LibDHCP::getRuntimeOptionDef(\"isc\", 100)", "true", "false"
) .c_str()) = ::testing::Message()
;
2604}
2605
2606// The goal of this test is to check whether an option definition
2607// that defines an option carrying a record of data fields can
2608// be created.
2609TEST_F(Dhcp4ParserTest, optionDefRecord)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDefRecord") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionDefRecord_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionDefRecord_Test() = default; ~
Dhcp4ParserTest_optionDefRecord_Test() override = default; Dhcp4ParserTest_optionDefRecord_Test
(const Dhcp4ParserTest_optionDefRecord_Test &) = delete;
Dhcp4ParserTest_optionDefRecord_Test & operator=( const Dhcp4ParserTest_optionDefRecord_Test
&) = delete; Dhcp4ParserTest_optionDefRecord_Test (Dhcp4ParserTest_optionDefRecord_Test
&&) noexcept = delete; Dhcp4ParserTest_optionDefRecord_Test
& operator=( Dhcp4ParserTest_optionDefRecord_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionDefRecord_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDefRecord", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2609
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2609), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2609), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefRecord_Test
>); void Dhcp4ParserTest_optionDefRecord_Test::TestBody()
{
2610
2611 // Configuration string.
2612 std::string config =
2613 "{ \"option-def\": [ {"
2614 " \"name\": \"foo\","
2615 " \"code\": 100,"
2616 " \"type\": \"record\","
2617 " \"record-types\": \"uint16, ipv4-address, ipv6-address, string\","
2618 " \"space\": \"isc\""
2619 " } ]"
2620 "}";
2621 ConstElementPtr json;
2622 ASSERT_NO_THROW(json = parseOPTION_DEFS(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseOPTION_DEFS(config); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2622
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2622
; } } else gtest_label_testnothrow_2622 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2622, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2623 extractConfig(config);
2624
2625 // Make sure that the particular option definition does not exist.
2626 OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
2627 getCfgOptionDef()->get("isc", 100);
2628 ASSERT_FALSE(def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(def))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2628, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "true", "false") .c_str()) = ::testing::Message()
;
2629
2630 // Use the configuration string to create new option definition.
2631 ConstElementPtr status;
2632 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2632; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2632; } } else gtest_label_testnothrow_2632
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2632, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2633 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2633, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2634 checkResult(status, 0);
2635
2636 // The option definition should now be available in the CfgMgr.
2637 def = CfgMgr::instance().getStagingCfg()->getCfgOptionDef()->get("isc", 100);
2638 ASSERT_TRUE(def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2638
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "false", "true") .c_str()) = ::testing::Message()
;
2639
2640 // Check the option data.
2641 EXPECT_EQ("foo", def->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"foo\""
, "def->getName()", "foo", def->getName()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2641
, gtest_ar.failure_message()) = ::testing::Message()
;
2642 EXPECT_EQ(100U, def->getCode())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("100U", "def->getCode()"
, 100U, def->getCode()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2642, gtest_ar.failure_message()) = ::testing::Message()
;
2643 EXPECT_EQ(OPT_RECORD_TYPE, def->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("OPT_RECORD_TYPE"
, "def->getType()", OPT_RECORD_TYPE, def->getType()))) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2643, gtest_ar.failure_message()) = ::testing::Message()
;
2644 EXPECT_FALSE(def->getArrayType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(def->getArrayType
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2644, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getArrayType()", "true", "false") .c_str()) = ::testing
::Message()
;
2645 EXPECT_TRUE(def->getEncapsulatedSpace().empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def->getEncapsulatedSpace
().empty())) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2645, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getEncapsulatedSpace().empty()", "false", "true") .
c_str()) = ::testing::Message()
;
2646
2647 // The option comprises the record of data fields. Verify that all
2648 // fields are present and they are of the expected types.
2649 const OptionDefinition::RecordFieldsCollection& record_fields =
2650 def->getRecordFields();
2651 ASSERT_EQ(4U, record_fields.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("4U", "record_fields.size()"
, 4U, record_fields.size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2651, gtest_ar.failure_message()) = ::testing::Message()
;
2652 EXPECT_EQ(OPT_UINT16_TYPE, record_fields[0])switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("OPT_UINT16_TYPE"
, "record_fields[0]", OPT_UINT16_TYPE, record_fields[0]))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2652, gtest_ar.failure_message()) = ::testing::Message()
;
2653 EXPECT_EQ(OPT_IPV4_ADDRESS_TYPE, record_fields[1])switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("OPT_IPV4_ADDRESS_TYPE"
, "record_fields[1]", OPT_IPV4_ADDRESS_TYPE, record_fields[1]
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2653, gtest_ar.failure_message()) = ::testing::Message()
;
2654 EXPECT_EQ(OPT_IPV6_ADDRESS_TYPE, record_fields[2])switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("OPT_IPV6_ADDRESS_TYPE"
, "record_fields[2]", OPT_IPV6_ADDRESS_TYPE, record_fields[2]
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2654, gtest_ar.failure_message()) = ::testing::Message()
;
2655 EXPECT_EQ(OPT_STRING_TYPE, record_fields[3])switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("OPT_STRING_TYPE"
, "record_fields[3]", OPT_STRING_TYPE, record_fields[3]))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2655, gtest_ar.failure_message()) = ::testing::Message()
;
2656}
2657
2658// The goal of this test is to verify that multiple option definitions
2659// can be created.
2660TEST_F(Dhcp4ParserTest, optionDefMultiple)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDefMultiple") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionDefMultiple_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionDefMultiple_Test() = default
; ~Dhcp4ParserTest_optionDefMultiple_Test() override = default
; Dhcp4ParserTest_optionDefMultiple_Test (const Dhcp4ParserTest_optionDefMultiple_Test
&) = delete; Dhcp4ParserTest_optionDefMultiple_Test &
operator=( const Dhcp4ParserTest_optionDefMultiple_Test &
) = delete; Dhcp4ParserTest_optionDefMultiple_Test (Dhcp4ParserTest_optionDefMultiple_Test
&&) noexcept = delete; Dhcp4ParserTest_optionDefMultiple_Test
& operator=( Dhcp4ParserTest_optionDefMultiple_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionDefMultiple_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDefMultiple", nullptr, nullptr, ::testing::internal::
CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2660), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2660), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2660), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefMultiple_Test
>); void Dhcp4ParserTest_optionDefMultiple_Test::TestBody(
)
{
2661 // Configuration string.
2662 std::string config =
2663 "{ \"option-def\": [ {"
2664 " \"name\": \"foo\","
2665 " \"code\": 100,"
2666 " \"type\": \"uint32\","
2667 " \"space\": \"isc\""
2668 " },"
2669 " {"
2670 " \"name\": \"foo-2\","
2671 " \"code\": 101,"
2672 " \"type\": \"ipv4-address\","
2673 " \"space\": \"isc\""
2674 " } ]"
2675 "}";
2676 ConstElementPtr json;
2677 ASSERT_NO_THROW(json = parseOPTION_DEFS(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseOPTION_DEFS(config); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2677
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2677
; } } else gtest_label_testnothrow_2677 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2677, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2678 extractConfig(config);
2679
2680 // Make sure that the option definitions do not exist yet.
2681 ASSERT_FALSE(CfgMgr::instance().getStagingCfg()->switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(CfgMgr::instance().
getStagingCfg()-> getCfgOptionDef()->get("isc", 100))))
; else return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2682, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()-> getCfgOptionDef()->get(\"isc\", 100)"
, "true", "false") .c_str()) = ::testing::Message()
2682 getCfgOptionDef()->get("isc", 100))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(CfgMgr::instance().
getStagingCfg()-> getCfgOptionDef()->get("isc", 100))))
; else return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2682, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()-> getCfgOptionDef()->get(\"isc\", 100)"
, "true", "false") .c_str()) = ::testing::Message()
;
2683 ASSERT_FALSE(CfgMgr::instance().getStagingCfg()->switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(CfgMgr::instance().
getStagingCfg()-> getCfgOptionDef()->get("isc", 101))))
; else return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2684, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()-> getCfgOptionDef()->get(\"isc\", 101)"
, "true", "false") .c_str()) = ::testing::Message()
2684 getCfgOptionDef()->get("isc", 101))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(CfgMgr::instance().
getStagingCfg()-> getCfgOptionDef()->get("isc", 101))))
; else return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2684, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()-> getCfgOptionDef()->get(\"isc\", 101)"
, "true", "false") .c_str()) = ::testing::Message()
;
2685
2686 // Use the configuration string to create new option definitions.
2687 ConstElementPtr status;
2688 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2688; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2688; } } else gtest_label_testnothrow_2688
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2688, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2689 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2689, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2690 checkResult(status, 0);
2691
2692 // Check the first definition we have created.
2693 OptionDefinitionPtr def1 = CfgMgr::instance().getStagingCfg()->
2694 getCfgOptionDef()->get("isc", 100);
2695 ASSERT_TRUE(def1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def1)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2695
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def1", "false", "true") .c_str()) = ::testing::Message()
;
2696
2697 // Check the option data.
2698 EXPECT_EQ("foo", def1->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"foo\""
, "def1->getName()", "foo", def1->getName()))) ; else ::
testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2698
, gtest_ar.failure_message()) = ::testing::Message()
;
2699 EXPECT_EQ(100U, def1->getCode())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("100U", "def1->getCode()"
, 100U, def1->getCode()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2699, gtest_ar.failure_message()) = ::testing::Message()
;
2700 EXPECT_EQ(OPT_UINT32_TYPE, def1->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("OPT_UINT32_TYPE"
, "def1->getType()", OPT_UINT32_TYPE, def1->getType()))
) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2700, gtest_ar.failure_message()) = ::testing::Message()
;
2701 EXPECT_FALSE(def1->getArrayType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(def1->getArrayType
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2701, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def1->getArrayType()", "true", "false") .c_str()) = ::testing
::Message()
;
2702 EXPECT_TRUE(def1->getEncapsulatedSpace().empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def1->getEncapsulatedSpace
().empty())) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2702, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def1->getEncapsulatedSpace().empty()", "false", "true")
.c_str()) = ::testing::Message()
;
2703
2704 // Check the second option definition we have created.
2705 OptionDefinitionPtr def2 = CfgMgr::instance().getStagingCfg()->
2706 getCfgOptionDef()->get("isc", 101);
2707 ASSERT_TRUE(def2)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def2)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2707
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def2", "false", "true") .c_str()) = ::testing::Message()
;
2708
2709 // Check the option data.
2710 EXPECT_EQ("foo-2", def2->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"foo-2\""
, "def2->getName()", "foo-2", def2->getName()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2710, gtest_ar.failure_message()) = ::testing::Message()
;
2711 EXPECT_EQ(101U, def2->getCode())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("101U", "def2->getCode()"
, 101U, def2->getCode()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2711, gtest_ar.failure_message()) = ::testing::Message()
;
2712 EXPECT_EQ(OPT_IPV4_ADDRESS_TYPE, def2->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("OPT_IPV4_ADDRESS_TYPE"
, "def2->getType()", OPT_IPV4_ADDRESS_TYPE, def2->getType
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2712, gtest_ar.failure_message()) = ::testing::Message()
;
2713 EXPECT_FALSE(def2->getArrayType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(def2->getArrayType
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2713, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def2->getArrayType()", "true", "false") .c_str()) = ::testing
::Message()
;
2714 EXPECT_TRUE(def2->getEncapsulatedSpace().empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def2->getEncapsulatedSpace
().empty())) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2714, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def2->getEncapsulatedSpace().empty()", "false", "true")
.c_str()) = ::testing::Message()
;
2715}
2716
2717// The goal of this test is to verify that the duplicated option
2718// definition is not accepted.
2719TEST_F(Dhcp4ParserTest, optionDefDuplicate)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDefDuplicate") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionDefDuplicate_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionDefDuplicate_Test() = default
; ~Dhcp4ParserTest_optionDefDuplicate_Test() override = default
; Dhcp4ParserTest_optionDefDuplicate_Test (const Dhcp4ParserTest_optionDefDuplicate_Test
&) = delete; Dhcp4ParserTest_optionDefDuplicate_Test &
operator=( const Dhcp4ParserTest_optionDefDuplicate_Test &
) = delete; Dhcp4ParserTest_optionDefDuplicate_Test (Dhcp4ParserTest_optionDefDuplicate_Test
&&) noexcept = delete; Dhcp4ParserTest_optionDefDuplicate_Test
& operator=( Dhcp4ParserTest_optionDefDuplicate_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionDefDuplicate_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDefDuplicate", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2719), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2719), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2719), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefDuplicate_Test
>); void Dhcp4ParserTest_optionDefDuplicate_Test::TestBody
()
{
2720 // Preconfigure libdhcp++ with option definitions. The new configuration
2721 // should override it, but when the new configuration fails, it should
2722 // revert to this original configuration.
2723 OptionDefSpaceContainer defs;
2724 OptionDefinitionPtr def(new OptionDefinition("bar", 233, "isc", "string"));
2725 defs.addItem(def);
2726 LibDHCP::setRuntimeOptionDefs(defs);
2727 LibDHCP::commitRuntimeOptionDefs();
2728
2729 // Configuration string. Both option definitions have
2730 // the same code and belong to the same option space.
2731 // This configuration should not be accepted.
2732 std::string config =
2733 "{ \"option-def\": [ {"
2734 " \"name\": \"foo\","
2735 " \"code\": 100,"
2736 " \"type\": \"uint32\","
2737 " \"space\": \"isc\""
2738 " },"
2739 " {"
2740 " \"name\": \"foo-2\","
2741 " \"code\": 100,"
2742 " \"type\": \"ipv4-address\","
2743 " \"space\": \"isc\""
2744 " } ]"
2745 "}";
2746 ConstElementPtr json;
2747 ASSERT_NO_THROW(json = parseOPTION_DEFS(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseOPTION_DEFS(config); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2747
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2747
; } } else gtest_label_testnothrow_2747 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2747, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2748
2749 // Make sure that the option definition does not exist yet.
2750 ASSERT_FALSE(CfgMgr::instance().getStagingCfg()->switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(CfgMgr::instance().
getStagingCfg()-> getCfgOptionDef()->get("isc", 100))))
; else return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2751, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()-> getCfgOptionDef()->get(\"isc\", 100)"
, "true", "false") .c_str()) = ::testing::Message()
2751 getCfgOptionDef()->get("isc", 100))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(CfgMgr::instance().
getStagingCfg()-> getCfgOptionDef()->get("isc", 100))))
; else return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2751, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()-> getCfgOptionDef()->get(\"isc\", 100)"
, "true", "false") .c_str()) = ::testing::Message()
;
2752
2753 // Use the configuration string to create new option definitions.
2754 ConstElementPtr status;
2755 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2755; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2755; } } else gtest_label_testnothrow_2755
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2755, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2756 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2756, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2757 checkResult(status, CONTROL_RESULT_ERROR);
2758 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2758, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2759
2760 // Specific check for incorrect report using default config pair
2761 // as option-def is parsed first.
2762 string expected = "failed to create or run parser for configuration ";
2763 expected += "element option-def: option definition with code '100' ";
2764 expected += "already exists in option space 'isc'";
2765 EXPECT_EQ(1U, countFile(expected))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "countFile(expected)"
, 1U, countFile(expected)))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2765, gtest_ar.failure_message()) = ::testing::Message()
;
2766
2767 // The new configuration should have inserted option 100, but
2768 // once configuration failed (on the duplicate option definition)
2769 // the original configuration in libdhcp++ should be reverted.
2770 EXPECT_FALSE(LibDHCP::getRuntimeOptionDef("isc", 100))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(LibDHCP::getRuntimeOptionDef
("isc", 100)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2770, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "LibDHCP::getRuntimeOptionDef(\"isc\", 100)", "true", "false"
) .c_str()) = ::testing::Message()
;
2771 def = LibDHCP::getRuntimeOptionDef("isc", 233);
2772 ASSERT_TRUE(def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2772
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "false", "true") .c_str()) = ::testing::Message()
;
2773 EXPECT_EQ("bar", def->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"bar\""
, "def->getName()", "bar", def->getName()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2773
, gtest_ar.failure_message()) = ::testing::Message()
;
2774 EXPECT_EQ(233U, def->getCode())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("233U", "def->getCode()"
, 233U, def->getCode()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2774, gtest_ar.failure_message()) = ::testing::Message()
;
2775}
2776
2777// The goal of this test is to verify that the option definition
2778// comprising an array of uint32 values can be created.
2779TEST_F(Dhcp4ParserTest, optionDefArray)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDefArray") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionDefArray_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionDefArray_Test() = default; ~
Dhcp4ParserTest_optionDefArray_Test() override = default; Dhcp4ParserTest_optionDefArray_Test
(const Dhcp4ParserTest_optionDefArray_Test &) = delete; Dhcp4ParserTest_optionDefArray_Test
& operator=( const Dhcp4ParserTest_optionDefArray_Test &
) = delete; Dhcp4ParserTest_optionDefArray_Test (Dhcp4ParserTest_optionDefArray_Test
&&) noexcept = delete; Dhcp4ParserTest_optionDefArray_Test
& operator=( Dhcp4ParserTest_optionDefArray_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionDefArray_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDefArray", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2779
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2779), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2779), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefArray_Test
>); void Dhcp4ParserTest_optionDefArray_Test::TestBody()
{
2780
2781 // Configuration string. Created option definition should
2782 // comprise an array of uint32 values.
2783 std::string config =
2784 "{ \"option-def\": [ {"
2785 " \"name\": \"foo\","
2786 " \"code\": 100,"
2787 " \"type\": \"uint32\","
2788 " \"array\": true,"
2789 " \"space\": \"isc\""
2790 " } ]"
2791 "}";
2792 ConstElementPtr json;
2793 ASSERT_NO_THROW(json = parseOPTION_DEFS(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseOPTION_DEFS(config); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2793
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2793
; } } else gtest_label_testnothrow_2793 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2793, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2794 extractConfig(config);
2795
2796 // Make sure that the particular option definition does not exist.
2797 OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
2798 getCfgOptionDef()->get("isc", 100);
2799 ASSERT_FALSE(def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(def))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2799, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "true", "false") .c_str()) = ::testing::Message()
;
2800
2801 // Use the configuration string to create new option definition.
2802 ConstElementPtr status;
2803 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2803; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2803; } } else gtest_label_testnothrow_2803
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2803, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2804 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2804, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2805 checkResult(status, 0);
2806
2807 // The option definition should now be available in the CfgMgr.
2808 def = CfgMgr::instance().getStagingCfg()->
2809 getCfgOptionDef()->get("isc", 100);
2810 ASSERT_TRUE(def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2810
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "false", "true") .c_str()) = ::testing::Message()
;
2811
2812 // Check the option data.
2813 EXPECT_EQ("foo", def->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"foo\""
, "def->getName()", "foo", def->getName()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2813
, gtest_ar.failure_message()) = ::testing::Message()
;
2814 EXPECT_EQ(100U, def->getCode())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("100U", "def->getCode()"
, 100U, def->getCode()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2814, gtest_ar.failure_message()) = ::testing::Message()
;
2815 EXPECT_EQ(OPT_UINT32_TYPE, def->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("OPT_UINT32_TYPE"
, "def->getType()", OPT_UINT32_TYPE, def->getType()))) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2815, gtest_ar.failure_message()) = ::testing::Message()
;
2816 EXPECT_TRUE(def->getArrayType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def->getArrayType(
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2816, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getArrayType()", "false", "true") .c_str()) = ::testing
::Message()
;
2817 EXPECT_TRUE(def->getEncapsulatedSpace().empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def->getEncapsulatedSpace
().empty())) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2817, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getEncapsulatedSpace().empty()", "false", "true") .
c_str()) = ::testing::Message()
;
2818}
2819
2820// The purpose of this test to verify that encapsulated option
2821// space name may be specified.
2822TEST_F(Dhcp4ParserTest, optionDefEncapsulate)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDefEncapsulate") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionDefEncapsulate_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionDefEncapsulate_Test() = default
; ~Dhcp4ParserTest_optionDefEncapsulate_Test() override = default
; Dhcp4ParserTest_optionDefEncapsulate_Test (const Dhcp4ParserTest_optionDefEncapsulate_Test
&) = delete; Dhcp4ParserTest_optionDefEncapsulate_Test &
operator=( const Dhcp4ParserTest_optionDefEncapsulate_Test &
) = delete; Dhcp4ParserTest_optionDefEncapsulate_Test (Dhcp4ParserTest_optionDefEncapsulate_Test
&&) noexcept = delete; Dhcp4ParserTest_optionDefEncapsulate_Test
& operator=( Dhcp4ParserTest_optionDefEncapsulate_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionDefEncapsulate_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDefEncapsulate", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2822), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2822), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2822), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefEncapsulate_Test
>); void Dhcp4ParserTest_optionDefEncapsulate_Test::TestBody
()
{
2823
2824 // Configuration string. Included the encapsulated
2825 // option space name.
2826 std::string config =
2827 "{ \"option-def\": [ {"
2828 " \"name\": \"foo\","
2829 " \"code\": 100,"
2830 " \"type\": \"uint32\","
2831 " \"space\": \"isc\","
2832 " \"encapsulate\": \"sub-opts-space\""
2833 " } ]"
2834 "}";
2835 ConstElementPtr json;
2836 ASSERT_NO_THROW(json = parseOPTION_DEFS(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseOPTION_DEFS(config); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2836
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2836
; } } else gtest_label_testnothrow_2836 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2836, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2837 extractConfig(config);
2838
2839 // Make sure that the particular option definition does not exist.
2840 OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
2841 getCfgOptionDef()->get("isc", 100);
2842 ASSERT_FALSE(def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(def))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2842, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "true", "false") .c_str()) = ::testing::Message()
;
2843
2844 // Use the configuration string to create new option definition.
2845 ConstElementPtr status;
2846 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2846; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2846; } } else gtest_label_testnothrow_2846
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2846, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2847 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2847, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2848 checkResult(status, 0);
2849
2850 // The option definition should now be available in the CfgMgr.
2851 def = CfgMgr::instance().getStagingCfg()->
2852 getCfgOptionDef()->get("isc", 100);
2853 ASSERT_TRUE(def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2853
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "false", "true") .c_str()) = ::testing::Message()
;
2854
2855 // Check the option data.
2856 EXPECT_EQ("foo", def->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"foo\""
, "def->getName()", "foo", def->getName()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 2856
, gtest_ar.failure_message()) = ::testing::Message()
;
2857 EXPECT_EQ(100U, def->getCode())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("100U", "def->getCode()"
, 100U, def->getCode()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2857, gtest_ar.failure_message()) = ::testing::Message()
;
2858 EXPECT_EQ(OPT_UINT32_TYPE, def->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("OPT_UINT32_TYPE"
, "def->getType()", OPT_UINT32_TYPE, def->getType()))) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2858, gtest_ar.failure_message()) = ::testing::Message()
;
2859 EXPECT_FALSE(def->getArrayType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(def->getArrayType
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2859, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getArrayType()", "true", "false") .c_str()) = ::testing
::Message()
;
2860 EXPECT_EQ("sub-opts-space", def->getEncapsulatedSpace())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"sub-opts-space\""
, "def->getEncapsulatedSpace()", "sub-opts-space", def->
getEncapsulatedSpace()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2860, gtest_ar.failure_message()) = ::testing::Message()
;
2861}
2862
2863/// The purpose of this test is to verify that the option definition
2864/// with invalid name is not accepted.
2865TEST_F(Dhcp4ParserTest, optionDefInvalidName)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDefInvalidName") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionDefInvalidName_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionDefInvalidName_Test() = default
; ~Dhcp4ParserTest_optionDefInvalidName_Test() override = default
; Dhcp4ParserTest_optionDefInvalidName_Test (const Dhcp4ParserTest_optionDefInvalidName_Test
&) = delete; Dhcp4ParserTest_optionDefInvalidName_Test &
operator=( const Dhcp4ParserTest_optionDefInvalidName_Test &
) = delete; Dhcp4ParserTest_optionDefInvalidName_Test (Dhcp4ParserTest_optionDefInvalidName_Test
&&) noexcept = delete; Dhcp4ParserTest_optionDefInvalidName_Test
& operator=( Dhcp4ParserTest_optionDefInvalidName_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionDefInvalidName_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDefInvalidName", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2865), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2865), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2865), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefInvalidName_Test
>); void Dhcp4ParserTest_optionDefInvalidName_Test::TestBody
()
{
2866 // Configuration string. The option name is invalid as it
2867 // contains the % character.
2868 std::string config =
2869 "{ \"option-def\": [ {"
2870 " \"name\": \"invalid%name\","
2871 " \"code\": 100,"
2872 " \"type\": \"string\","
2873 " \"space\": \"isc\""
2874 " } ]"
2875 "}";
2876 ConstElementPtr json;
2877 ASSERT_NO_THROW(json = parseOPTION_DEFS(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseOPTION_DEFS(config); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2877
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2877
; } } else gtest_label_testnothrow_2877 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2877, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2878
2879 // Use the configuration string to create new option definition.
2880 ConstElementPtr status;
2881 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2881; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2881; } } else gtest_label_testnothrow_2881
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2881, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2882 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2882, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2883 // Expecting parsing error (error code 1).
2884 checkResult(status, CONTROL_RESULT_ERROR);
2885 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2885, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2886}
2887
2888/// The purpose of this test is to verify that the option definition
2889/// with invalid type is not accepted.
2890TEST_F(Dhcp4ParserTest, optionDefInvalidType)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDefInvalidType") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionDefInvalidType_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionDefInvalidType_Test() = default
; ~Dhcp4ParserTest_optionDefInvalidType_Test() override = default
; Dhcp4ParserTest_optionDefInvalidType_Test (const Dhcp4ParserTest_optionDefInvalidType_Test
&) = delete; Dhcp4ParserTest_optionDefInvalidType_Test &
operator=( const Dhcp4ParserTest_optionDefInvalidType_Test &
) = delete; Dhcp4ParserTest_optionDefInvalidType_Test (Dhcp4ParserTest_optionDefInvalidType_Test
&&) noexcept = delete; Dhcp4ParserTest_optionDefInvalidType_Test
& operator=( Dhcp4ParserTest_optionDefInvalidType_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionDefInvalidType_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDefInvalidType", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2890), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2890), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2890), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefInvalidType_Test
>); void Dhcp4ParserTest_optionDefInvalidType_Test::TestBody
()
{
2891 // Configuration string. The option type is invalid. It is
2892 // "sting" instead of "string".
2893 std::string config =
2894 "{ \"option-def\": [ {"
2895 " \"name\": \"foo\","
2896 " \"code\": 100,"
2897 " \"type\": \"sting\","
2898 " \"space\": \"isc\""
2899 " } ]"
2900 "}";
2901 ConstElementPtr json;
2902 ASSERT_NO_THROW(json = parseOPTION_DEFS(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseOPTION_DEFS(config); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2902
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2902
; } } else gtest_label_testnothrow_2902 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2902, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2903
2904 // Use the configuration string to create new option definition.
2905 ConstElementPtr status;
2906 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2906; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2906; } } else gtest_label_testnothrow_2906
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2906, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2907 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2907, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2908 // Expecting parsing error (error code 1).
2909 checkResult(status, CONTROL_RESULT_ERROR);
2910 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2910, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2911}
2912
2913/// The purpose of this test is to verify that the option definition
2914/// with invalid type is not accepted.
2915TEST_F(Dhcp4ParserTest, optionDefInvalidRecordType)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDefInvalidRecordType") > 1,
"test_name must not be empty"); class Dhcp4ParserTest_optionDefInvalidRecordType_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_optionDefInvalidRecordType_Test
() = default; ~Dhcp4ParserTest_optionDefInvalidRecordType_Test
() override = default; Dhcp4ParserTest_optionDefInvalidRecordType_Test
(const Dhcp4ParserTest_optionDefInvalidRecordType_Test &
) = delete; Dhcp4ParserTest_optionDefInvalidRecordType_Test &
operator=( const Dhcp4ParserTest_optionDefInvalidRecordType_Test
&) = delete; Dhcp4ParserTest_optionDefInvalidRecordType_Test
(Dhcp4ParserTest_optionDefInvalidRecordType_Test &&)
noexcept = delete; Dhcp4ParserTest_optionDefInvalidRecordType_Test
& operator=( Dhcp4ParserTest_optionDefInvalidRecordType_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_optionDefInvalidRecordType_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDefInvalidRecordType", nullptr, nullptr, ::testing::
internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2915), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2915), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2915), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefInvalidRecordType_Test
>); void Dhcp4ParserTest_optionDefInvalidRecordType_Test::
TestBody()
{
2916 // Configuration string. The third of the record fields
2917 // is invalid. It is "sting" instead of "string".
2918 std::string config =
2919 "{ \"option-def\": [ {"
2920 " \"name\": \"foo\","
2921 " \"code\": 100,"
2922 " \"type\": \"record\","
2923 " \"record-types\": \"uint32,uint8,sting\","
2924 " \"space\": \"isc\""
2925 " } ]"
2926 "}";
2927 ConstElementPtr json;
2928 ASSERT_NO_THROW(json = parseOPTION_DEFS(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseOPTION_DEFS(config); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2928
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2928
; } } else gtest_label_testnothrow_2928 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2928, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2929
2930 // Use the configuration string to create new option definition.
2931 ConstElementPtr status;
2932 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2932; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2932; } } else gtest_label_testnothrow_2932
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2932, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2933 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2933, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2934 // Expecting parsing error (error code 1).
2935 checkResult(status, CONTROL_RESULT_ERROR);
2936 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2936, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2937}
2938
2939/// The purpose of this test is to verify that various integer types
2940/// are supported.
2941TEST_F(Dhcp4ParserTest, optionIntegerTypes)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionIntegerTypes") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionIntegerTypes_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionIntegerTypes_Test() = default
; ~Dhcp4ParserTest_optionIntegerTypes_Test() override = default
; Dhcp4ParserTest_optionIntegerTypes_Test (const Dhcp4ParserTest_optionIntegerTypes_Test
&) = delete; Dhcp4ParserTest_optionIntegerTypes_Test &
operator=( const Dhcp4ParserTest_optionIntegerTypes_Test &
) = delete; Dhcp4ParserTest_optionIntegerTypes_Test (Dhcp4ParserTest_optionIntegerTypes_Test
&&) noexcept = delete; Dhcp4ParserTest_optionIntegerTypes_Test
& operator=( Dhcp4ParserTest_optionIntegerTypes_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionIntegerTypes_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionIntegerTypes", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2941), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2941), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2941), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionIntegerTypes_Test
>); void Dhcp4ParserTest_optionIntegerTypes_Test::TestBody
()
{
2942 // Configuration string. The third of the record fields
2943 // is invalid. It is "sting" instead of "string".
2944 std::string config =
2945 "{ \"option-def\": [ {"
2946 " \"name\": \"foo\","
2947 " \"code\": 100,"
2948 " \"type\": \"record\","
2949 " \"record-types\": \"uint8,uint16,uint32,int8,int16,int32\","
2950 " \"space\": \"isc\""
2951 " } ]"
2952 "}";
2953 ConstElementPtr json;
2954 ASSERT_NO_THROW(json = parseOPTION_DEFS(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseOPTION_DEFS(config); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2954
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2954
; } } else gtest_label_testnothrow_2954 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2954, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2955
2956 // Use the configuration string to create new option definition.
2957 ConstElementPtr status;
2958 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2958; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2958; } } else gtest_label_testnothrow_2958
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2958, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2959 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2959, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2960 // Expecting parsing error (error code 1).
2961 checkResult(status, 0);
2962}
2963
2964/// The goal of this test is to verify that the invalid encapsulated
2965/// option space name is not accepted.
2966TEST_F(Dhcp4ParserTest, optionDefInvalidEncapsulatedSpace)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDefInvalidEncapsulatedSpace") >
1, "test_name must not be empty"); class Dhcp4ParserTest_optionDefInvalidEncapsulatedSpace_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_optionDefInvalidEncapsulatedSpace_Test
() = default; ~Dhcp4ParserTest_optionDefInvalidEncapsulatedSpace_Test
() override = default; Dhcp4ParserTest_optionDefInvalidEncapsulatedSpace_Test
(const Dhcp4ParserTest_optionDefInvalidEncapsulatedSpace_Test
&) = delete; Dhcp4ParserTest_optionDefInvalidEncapsulatedSpace_Test
& operator=( const Dhcp4ParserTest_optionDefInvalidEncapsulatedSpace_Test
&) = delete; Dhcp4ParserTest_optionDefInvalidEncapsulatedSpace_Test
(Dhcp4ParserTest_optionDefInvalidEncapsulatedSpace_Test &&
) noexcept = delete; Dhcp4ParserTest_optionDefInvalidEncapsulatedSpace_Test
& operator=( Dhcp4ParserTest_optionDefInvalidEncapsulatedSpace_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_optionDefInvalidEncapsulatedSpace_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDefInvalidEncapsulatedSpace", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2966), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2966), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2966), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefInvalidEncapsulatedSpace_Test
>); void Dhcp4ParserTest_optionDefInvalidEncapsulatedSpace_Test
::TestBody()
{
2967 // Configuration string. The encapsulated option space
2968 // name is invalid (% character is not allowed).
2969 std::string config =
2970 "{ \"option-def\": [ {"
2971 " \"name\": \"foo\","
2972 " \"code\": 100,"
2973 " \"type\": \"uint32\","
2974 " \"space\": \"isc\","
2975 " \"encapsulate\": \"invalid%space%name\""
2976 " } ]"
2977 "}";
2978 ConstElementPtr json;
2979 ASSERT_NO_THROW(json = parseOPTION_DEFS(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseOPTION_DEFS(config); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_2979
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2979
; } } else gtest_label_testnothrow_2979 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2979, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2980
2981 // Use the configuration string to create new option definition.
2982 ConstElementPtr status;
2983 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_2983; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2983; } } else gtest_label_testnothrow_2983
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2983, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2984 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2984, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2985 // Expecting parsing error (error code 1).
2986 checkResult(status, CONTROL_RESULT_ERROR);
2987 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2987, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2988}
2989
2990/// The goal of this test is to verify that the encapsulated
2991/// option space name can't be specified for the option that
2992/// comprises an array of data fields.
2993TEST_F(Dhcp4ParserTest, optionDefEncapsulatedSpaceAndArray)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDefEncapsulatedSpaceAndArray")
> 1, "test_name must not be empty"); class Dhcp4ParserTest_optionDefEncapsulatedSpaceAndArray_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_optionDefEncapsulatedSpaceAndArray_Test
() = default; ~Dhcp4ParserTest_optionDefEncapsulatedSpaceAndArray_Test
() override = default; Dhcp4ParserTest_optionDefEncapsulatedSpaceAndArray_Test
(const Dhcp4ParserTest_optionDefEncapsulatedSpaceAndArray_Test
&) = delete; Dhcp4ParserTest_optionDefEncapsulatedSpaceAndArray_Test
& operator=( const Dhcp4ParserTest_optionDefEncapsulatedSpaceAndArray_Test
&) = delete; Dhcp4ParserTest_optionDefEncapsulatedSpaceAndArray_Test
(Dhcp4ParserTest_optionDefEncapsulatedSpaceAndArray_Test &&
) noexcept = delete; Dhcp4ParserTest_optionDefEncapsulatedSpaceAndArray_Test
& operator=( Dhcp4ParserTest_optionDefEncapsulatedSpaceAndArray_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_optionDefEncapsulatedSpaceAndArray_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDefEncapsulatedSpaceAndArray", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2993), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2993), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2993), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefEncapsulatedSpaceAndArray_Test
>); void Dhcp4ParserTest_optionDefEncapsulatedSpaceAndArray_Test
::TestBody()
{
2994 // Configuration string. The encapsulated option space
2995 // name is set to non-empty value and the array flag
2996 // is set.
2997 std::string config =
2998 "{ \"option-def\": [ {"
2999 " \"name\": \"foo\","
3000 " \"code\": 100,"
3001 " \"type\": \"uint32\","
3002 " \"array\": true,"
3003 " \"space\": \"isc\","
3004 " \"encapsulate\": \"valid-space-name\""
3005 " } ]"
3006 "}";
3007 ConstElementPtr json;
3008 ASSERT_NO_THROW(json = parseOPTION_DEFS(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseOPTION_DEFS(config); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_3008
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3008
; } } else gtest_label_testnothrow_3008 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3008, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3009
3010 // Use the configuration string to create new option definition.
3011 ConstElementPtr status;
3012 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_3012; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3012; } } else gtest_label_testnothrow_3012
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3012, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3013 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3013, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
3014 // Expecting parsing error (error code 1).
3015 checkResult(status, CONTROL_RESULT_ERROR);
3016 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3016, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
3017}
3018
3019/// The goal of this test is to verify that the option may not
3020/// encapsulate option space it belongs to.
3021TEST_F(Dhcp4ParserTest, optionDefEncapsulateOwnSpace)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDefEncapsulateOwnSpace") > 1
, "test_name must not be empty"); class Dhcp4ParserTest_optionDefEncapsulateOwnSpace_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_optionDefEncapsulateOwnSpace_Test
() = default; ~Dhcp4ParserTest_optionDefEncapsulateOwnSpace_Test
() override = default; Dhcp4ParserTest_optionDefEncapsulateOwnSpace_Test
(const Dhcp4ParserTest_optionDefEncapsulateOwnSpace_Test &
) = delete; Dhcp4ParserTest_optionDefEncapsulateOwnSpace_Test
& operator=( const Dhcp4ParserTest_optionDefEncapsulateOwnSpace_Test
&) = delete; Dhcp4ParserTest_optionDefEncapsulateOwnSpace_Test
(Dhcp4ParserTest_optionDefEncapsulateOwnSpace_Test &&
) noexcept = delete; Dhcp4ParserTest_optionDefEncapsulateOwnSpace_Test
& operator=( Dhcp4ParserTest_optionDefEncapsulateOwnSpace_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_optionDefEncapsulateOwnSpace_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDefEncapsulateOwnSpace", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3021), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3021), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3021), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefEncapsulateOwnSpace_Test
>); void Dhcp4ParserTest_optionDefEncapsulateOwnSpace_Test
::TestBody()
{
3022 // Configuration string. Option is set to encapsulate
3023 // option space it belongs to.
3024 std::string config =
3025 "{ \"option-def\": [ {"
3026 " \"name\": \"foo\","
3027 " \"code\": 100,"
3028 " \"type\": \"uint32\","
3029 " \"space\": \"isc\","
3030 " \"encapsulate\": \"isc\""
3031 " } ]"
3032 "}";
3033 ConstElementPtr json;
3034 ASSERT_NO_THROW(json = parseOPTION_DEFS(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseOPTION_DEFS(config); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_3034
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3034
; } } else gtest_label_testnothrow_3034 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3034, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3035
3036 // Use the configuration string to create new option definition.
3037 ConstElementPtr status;
3038 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_3038; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3038; } } else gtest_label_testnothrow_3038
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3038, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3039 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3039, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
3040 // Expecting parsing error (error code 1).
3041 checkResult(status, CONTROL_RESULT_ERROR);
3042 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3042, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
3043}
3044
3045/// The purpose of this test is to verify that it is not allowed
3046/// to override the standard option (that belongs to dhcp4 option
3047/// space and has its definition) and that it is allowed to define
3048/// option in the dhcp4 option space that has a code which is not
3049/// used by any of the standard options.
3050TEST_F(Dhcp4ParserTest, optionStandardDefOverride)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionStandardDefOverride") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionStandardDefOverride_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_optionStandardDefOverride_Test
() = default; ~Dhcp4ParserTest_optionStandardDefOverride_Test
() override = default; Dhcp4ParserTest_optionStandardDefOverride_Test
(const Dhcp4ParserTest_optionStandardDefOverride_Test &)
= delete; Dhcp4ParserTest_optionStandardDefOverride_Test &
operator=( const Dhcp4ParserTest_optionStandardDefOverride_Test
&) = delete; Dhcp4ParserTest_optionStandardDefOverride_Test
(Dhcp4ParserTest_optionStandardDefOverride_Test &&) noexcept
= delete; Dhcp4ParserTest_optionStandardDefOverride_Test &
operator=( Dhcp4ParserTest_optionStandardDefOverride_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionStandardDefOverride_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionStandardDefOverride", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3050), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3050), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3050), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionStandardDefOverride_Test
>); void Dhcp4ParserTest_optionStandardDefOverride_Test::TestBody
()
{
3051
3052 // Configuration string. The option code 109 is unassigned
3053 // so it can be used for a custom option definition in
3054 // dhcp4 option space.
3055 std::string config =
3056 "{ \"option-def\": [ {"
3057 " \"name\": \"foo\","
3058 " \"code\": 109,"
3059 " \"type\": \"string\","
3060 " \"space\": \"dhcp4\""
3061 " } ]"
3062 "}";
3063 ConstElementPtr json;
3064 ASSERT_NO_THROW(json = parseOPTION_DEFS(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseOPTION_DEFS(config); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_3064
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3064
; } } else gtest_label_testnothrow_3064 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3064, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3065 extractConfig(config);
3066
3067 OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
3068 getCfgOptionDef()->get(DHCP4_OPTION_SPACE"dhcp4", 109);
3069 ASSERT_FALSE(def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(def))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3069, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "true", "false") .c_str()) = ::testing::Message()
;
3070
3071 // Use the configuration string to create new option definition.
3072 ConstElementPtr status;
3073 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_3073; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3073; } } else gtest_label_testnothrow_3073
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3073, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3074 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3074, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
3075 checkResult(status, 0);
3076
3077 // The option definition should now be available in the CfgMgr.
3078 def = CfgMgr::instance().getStagingCfg()->
3079 getCfgOptionDef()->get(DHCP4_OPTION_SPACE"dhcp4", 109);
3080 ASSERT_TRUE(def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 3080
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "false", "true") .c_str()) = ::testing::Message()
;
3081
3082 // Check the option data.
3083 EXPECT_EQ("foo", def->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"foo\""
, "def->getName()", "foo", def->getName()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 3083
, gtest_ar.failure_message()) = ::testing::Message()
;
3084 EXPECT_EQ(109U, def->getCode())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("109U", "def->getCode()"
, 109U, def->getCode()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3084, gtest_ar.failure_message()) = ::testing::Message()
;
3085 EXPECT_EQ(OPT_STRING_TYPE, def->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("OPT_STRING_TYPE"
, "def->getType()", OPT_STRING_TYPE, def->getType()))) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3085, gtest_ar.failure_message()) = ::testing::Message()
;
3086 EXPECT_FALSE(def->getArrayType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(def->getArrayType
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3086, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getArrayType()", "true", "false") .c_str()) = ::testing
::Message()
;
3087
3088 // The combination of option space and code is invalid. The 'dhcp4'
3089 // option space groups standard options and the code 3 is reserved
3090 // for one of them.
3091 config =
3092 "{ \"option-def\": [ {"
3093 " \"name\": \"routers\","
3094 " \"code\": 3,"
3095 " \"type\": \"ipv4-address\","
3096 " \"space\": \"dhcp4\""
3097 " } ]"
3098 "}";
3099 ASSERT_NO_THROW(json = parseOPTION_DEFS(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseOPTION_DEFS(config); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_3099
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3099
; } } else gtest_label_testnothrow_3099 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3099, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3100
3101 // Use the configuration string to create new option definition.
3102 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_3102; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3102; } } else gtest_label_testnothrow_3102
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3102, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3103 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3103, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
3104 // Expecting parsing error (error code 1).
3105 checkResult(status, CONTROL_RESULT_ERROR);
3106 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3106, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
3107
3108 /// There is no definition for unassigned option 170.
3109 config =
3110 "{ \"option-def\": [ {"
3111 " \"name\": \"unassigned-option-170\","
3112 " \"code\": 170,"
3113 " \"type\": \"string\","
3114 " \"space\": \"dhcp4\""
3115 " } ]"
3116 "}";
3117 ASSERT_NO_THROW(json = parseOPTION_DEFS(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseOPTION_DEFS(config); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_3117
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3117
; } } else gtest_label_testnothrow_3117 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3117, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3118 extractConfig(config);
3119
3120 // Use the configuration string to create new option definition.
3121 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_3121; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3121; } } else gtest_label_testnothrow_3121
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3121, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3122 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3122, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
3123 // Expecting success.
3124 checkResult(status, 0);
3125
3126 def = CfgMgr::instance().getStagingCfg()->
3127 getCfgOptionDef()->get(DHCP4_OPTION_SPACE"dhcp4", 170);
3128 ASSERT_TRUE(def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(def)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 3128
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "false", "true") .c_str()) = ::testing::Message()
;
3129
3130 // Check the option data.
3131 EXPECT_EQ("unassigned-option-170", def->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"unassigned-option-170\""
, "def->getName()", "unassigned-option-170", def->getName
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3131, gtest_ar.failure_message()) = ::testing::Message()
;
3132 EXPECT_EQ(170U, def->getCode())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("170U", "def->getCode()"
, 170U, def->getCode()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3132, gtest_ar.failure_message()) = ::testing::Message()
;
3133 EXPECT_EQ(OPT_STRING_TYPE, def->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("OPT_STRING_TYPE"
, "def->getType()", OPT_STRING_TYPE, def->getType()))) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3133, gtest_ar.failure_message()) = ::testing::Message()
;
3134 EXPECT_FALSE(def->getArrayType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(def->getArrayType
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3134, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getArrayType()", "true", "false") .c_str()) = ::testing
::Message()
;
3135}
3136
3137// Goal of this test is to verify that global option data is configured
3138TEST_F(Dhcp4ParserTest, optionDataDefaultsGlobal)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDataDefaultsGlobal") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionDataDefaultsGlobal_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_optionDataDefaultsGlobal_Test
() = default; ~Dhcp4ParserTest_optionDataDefaultsGlobal_Test(
) override = default; Dhcp4ParserTest_optionDataDefaultsGlobal_Test
(const Dhcp4ParserTest_optionDataDefaultsGlobal_Test &) =
delete; Dhcp4ParserTest_optionDataDefaultsGlobal_Test & operator
=( const Dhcp4ParserTest_optionDataDefaultsGlobal_Test &)
= delete; Dhcp4ParserTest_optionDataDefaultsGlobal_Test (Dhcp4ParserTest_optionDataDefaultsGlobal_Test
&&) noexcept = delete; Dhcp4ParserTest_optionDataDefaultsGlobal_Test
& operator=( Dhcp4ParserTest_optionDataDefaultsGlobal_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_optionDataDefaultsGlobal_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDataDefaultsGlobal", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3138), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3138), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3138), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataDefaultsGlobal_Test
>); void Dhcp4ParserTest_optionDataDefaultsGlobal_Test::TestBody
()
{
3139 ConstElementPtr x;
3140 string config = "{ " + genIfaceConfig() + ","
3141 "\"rebind-timer\": 2000,"
3142 "\"renew-timer\": 1000,"
3143 "\"option-data\": [ {"
3144 " \"name\": \"dhcp-message\","
3145 " \"data\": \"ABCDEF0105\","
3146 " \"csv-format\": false"
3147 " },"
3148 " {"
3149 " \"name\": \"default-ip-ttl\","
3150 " \"data\": \"01\","
3151 " \"csv-format\": false"
3152 " } ],"
3153 "\"subnet4\": [ { "
3154 " \"id\": 1,"
3155 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
3156 " \"subnet\": \"192.0.2.0/24\""
3157 " } ],"
3158 "\"valid-lifetime\": 4000 }";
3159
3160 ConstElementPtr json;
3161 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_3161
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3161
; } } else gtest_label_testnothrow_3161 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3161, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3162 extractConfig(config);
3163
3164 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_3164; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3164; } } else gtest_label_testnothrow_3164
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3164, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3165 checkResult(x, 0);
3166
3167 // These options are global
3168 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
3169 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
3170 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3170, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
3171 OptionContainerPtr options = subnet->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3172 ASSERT_EQ(0U, options->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("0U", "options->size()"
, 0U, options->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3172, gtest_ar.failure_message()) = ::testing::Message()
;
3173
3174 options = CfgMgr::instance().getStagingCfg()->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3175 ASSERT_EQ(2U, options->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "options->size()"
, 2U, options->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3175, gtest_ar.failure_message()) = ::testing::Message()
;
3176
3177 // Get the search index. Index #1 is to search using option code.
3178 const OptionContainerTypeIndex& idx = options->get<1>();
3179
3180 // Get the options for specified index. Expecting one option to be
3181 // returned but in theory we may have multiple options with the same
3182 // code so we get the range.
3183 std::pair<OptionContainerTypeIndex::const_iterator,
3184 OptionContainerTypeIndex::const_iterator> range =
3185 idx.equal_range(56);
3186 // Expect single option with the code equal to 56.
3187 ASSERT_EQ(1, std::distance(range.first, range.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1", "std::distance(range.first, range.second)"
, 1, std::distance(range.first, range.second)))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3187, gtest_ar.failure_message()) = ::testing::Message()
;
3188 const uint8_t foo_expected[] = {
3189 0xAB, 0xCD, 0xEF, 0x01, 0x05
3190 };
3191 // Check if option is valid in terms of code and carried data.
3192 testOption(*range.first, 56, foo_expected, sizeof(foo_expected));
3193
3194 range = idx.equal_range(23);
3195 ASSERT_EQ(1, std::distance(range.first, range.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1", "std::distance(range.first, range.second)"
, 1, std::distance(range.first, range.second)))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3195, gtest_ar.failure_message()) = ::testing::Message()
;
3196 // Do another round of testing with second option.
3197 const uint8_t foo2_expected[] = {
3198 0x01
3199 };
3200 testOption(*range.first, 23, foo2_expected, sizeof(foo2_expected));
3201
3202 // Check that options with other option codes are not returned.
3203 for (uint8_t code = 24; code < 35; ++code) {
3204 range = idx.equal_range(code);
3205 EXPECT_EQ(0, std::distance(range.first, range.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("0", "std::distance(range.first, range.second)"
, 0, std::distance(range.first, range.second)))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 3205
, gtest_ar.failure_message()) = ::testing::Message()
;
3206 }
3207}
3208
3209// Goal of this test is to verify that subnet option data is configured
3210TEST_F(Dhcp4ParserTest, optionDataDefaultsSubnet)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDataDefaultsSubnet") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionDataDefaultsSubnet_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_optionDataDefaultsSubnet_Test
() = default; ~Dhcp4ParserTest_optionDataDefaultsSubnet_Test(
) override = default; Dhcp4ParserTest_optionDataDefaultsSubnet_Test
(const Dhcp4ParserTest_optionDataDefaultsSubnet_Test &) =
delete; Dhcp4ParserTest_optionDataDefaultsSubnet_Test & operator
=( const Dhcp4ParserTest_optionDataDefaultsSubnet_Test &)
= delete; Dhcp4ParserTest_optionDataDefaultsSubnet_Test (Dhcp4ParserTest_optionDataDefaultsSubnet_Test
&&) noexcept = delete; Dhcp4ParserTest_optionDataDefaultsSubnet_Test
& operator=( Dhcp4ParserTest_optionDataDefaultsSubnet_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_optionDataDefaultsSubnet_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDataDefaultsSubnet", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3210), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3210), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3210), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataDefaultsSubnet_Test
>); void Dhcp4ParserTest_optionDataDefaultsSubnet_Test::TestBody
()
{
3211 ConstElementPtr x;
3212 string config = "{ " + genIfaceConfig() + ","
3213 "\"rebind-timer\": 2000,"
3214 "\"renew-timer\": 1000,"
3215 "\"subnet4\": [ { "
3216 " \"id\": 1,"
3217 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
3218 " \"subnet\": \"192.0.2.0/24\","
3219 " \"option-data\": [ {"
3220 " \"name\": \"dhcp-message\","
3221 " \"data\": \"ABCDEF0105\","
3222 " \"csv-format\": false"
3223 " },"
3224 " {"
3225 " \"name\": \"default-ip-ttl\","
3226 " \"data\": \"01\","
3227 " \"csv-format\": false"
3228 " } ]"
3229 " } ],"
3230 "\"valid-lifetime\": 4000 }";
3231
3232 ConstElementPtr json;
3233 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_3233
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3233
; } } else gtest_label_testnothrow_3233 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3233, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3234 extractConfig(config);
3235
3236 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_3236; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3236; } } else gtest_label_testnothrow_3236
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3236, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3237 checkResult(x, 0);
3238
3239 // These options are subnet options
3240 OptionContainerPtr options =
3241 CfgMgr::instance().getStagingCfg()->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3242 ASSERT_EQ(0U, options->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("0U", "options->size()"
, 0U, options->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3242, gtest_ar.failure_message()) = ::testing::Message()
;
3243
3244 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
3245 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
3246 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3246, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
3247 options = subnet->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3248 ASSERT_EQ(2U, options->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "options->size()"
, 2U, options->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3248, gtest_ar.failure_message()) = ::testing::Message()
;
3249
3250 // Get the search index. Index #1 is to search using option code.
3251 const OptionContainerTypeIndex& idx = options->get<1>();
3252
3253 // Get the options for specified index. Expecting one option to be
3254 // returned but in theory we may have multiple options with the same
3255 // code so we get the range.
3256 std::pair<OptionContainerTypeIndex::const_iterator,
3257 OptionContainerTypeIndex::const_iterator> range =
3258 idx.equal_range(56);
3259 // Expect single option with the code equal to 56.
3260 ASSERT_EQ(1, std::distance(range.first, range.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1", "std::distance(range.first, range.second)"
, 1, std::distance(range.first, range.second)))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3260, gtest_ar.failure_message()) = ::testing::Message()
;
3261 const uint8_t foo_expected[] = {
3262 0xAB, 0xCD, 0xEF, 0x01, 0x05
3263 };
3264 // Check if option is valid in terms of code and carried data.
3265 testOption(*range.first, 56, foo_expected, sizeof(foo_expected));
3266
3267 range = idx.equal_range(23);
3268 ASSERT_EQ(1, std::distance(range.first, range.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1", "std::distance(range.first, range.second)"
, 1, std::distance(range.first, range.second)))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3268, gtest_ar.failure_message()) = ::testing::Message()
;
3269 // Do another round of testing with second option.
3270 const uint8_t foo2_expected[] = {
3271 0x01
3272 };
3273 testOption(*range.first, 23, foo2_expected, sizeof(foo2_expected));
3274}
3275
3276/// The goal of this test is to verify that two options having the same
3277/// option code can be added to different option spaces.
3278TEST_F(Dhcp4ParserTest, optionDataTwoSpaces)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDataTwoSpaces") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionDataTwoSpaces_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionDataTwoSpaces_Test() = default
; ~Dhcp4ParserTest_optionDataTwoSpaces_Test() override = default
; Dhcp4ParserTest_optionDataTwoSpaces_Test (const Dhcp4ParserTest_optionDataTwoSpaces_Test
&) = delete; Dhcp4ParserTest_optionDataTwoSpaces_Test &
operator=( const Dhcp4ParserTest_optionDataTwoSpaces_Test &
) = delete; Dhcp4ParserTest_optionDataTwoSpaces_Test (Dhcp4ParserTest_optionDataTwoSpaces_Test
&&) noexcept = delete; Dhcp4ParserTest_optionDataTwoSpaces_Test
& operator=( Dhcp4ParserTest_optionDataTwoSpaces_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionDataTwoSpaces_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDataTwoSpaces", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3278), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3278), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3278), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataTwoSpaces_Test
>); void Dhcp4ParserTest_optionDataTwoSpaces_Test::TestBody
()
{
3279
3280 // This configuration string is to configure two options
3281 // sharing the code 56 and having different definitions
3282 // and belonging to the different option spaces.
3283 // The option definition must be provided for the
3284 // option that belongs to the 'isc' option space.
3285 // The definition is not required for the option that
3286 // belongs to the 'dhcp4' option space as it is the
3287 // standard option.
3288 string config = "{ " + genIfaceConfig() + ","
3289 "\"valid-lifetime\": 4000,"
3290 "\"rebind-timer\": 2000,"
3291 "\"renew-timer\": 1000,"
3292 "\"option-data\": [ {"
3293 " \"name\": \"dhcp-message\","
3294 " \"data\": \"ABCDEF0105\","
3295 " \"csv-format\": false"
3296 " },"
3297 " {"
3298 " \"name\": \"foo\","
3299 " \"space\": \"isc\","
3300 " \"data\": \"1234\""
3301 " } ],"
3302 "\"option-def\": [ {"
3303 " \"name\": \"foo\","
3304 " \"code\": 56,"
3305 " \"type\": \"uint32\","
3306 " \"space\": \"isc\""
3307 " } ],"
3308 "\"subnet4\": [ { "
3309 " \"id\": 1,"
3310 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
3311 " \"subnet\": \"192.0.2.0/24\""
3312 " } ]"
3313 "}";
3314
3315 ConstElementPtr json;
3316 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_3316
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3316
; } } else gtest_label_testnothrow_3316 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3316, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3317 extractConfig(config);
3318
3319 ConstElementPtr status;
3320 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_3320; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3320; } } else gtest_label_testnothrow_3320
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3320, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3321 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3321, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
3322 checkResult(status, 0);
3323
3324 // Options should be now available
3325 // Try to get the option from the space dhcp4.
3326 OptionDescriptor desc1 =
3327 CfgMgr::instance().getStagingCfg()->getCfgOption()->get(DHCP4_OPTION_SPACE"dhcp4", 56);
3328 ASSERT_TRUE(desc1.option_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(desc1.option_)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3328, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc1.option_", "false", "true") .c_str()) = ::testing::Message
()
;
3329 EXPECT_EQ(56U, desc1.option_->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("56U", "desc1.option_->getType()"
, 56U, desc1.option_->getType()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3329, gtest_ar.failure_message()) = ::testing::Message()
;
3330 // Try to get the option from the space isc.
3331 OptionDescriptor desc2 =
3332 CfgMgr::instance().getStagingCfg()->getCfgOption()->get("isc", 56);
3333 ASSERT_TRUE(desc2.option_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(desc2.option_)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3333, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc2.option_", "false", "true") .c_str()) = ::testing::Message
()
;
3334 EXPECT_EQ(56U, desc1.option_->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("56U", "desc1.option_->getType()"
, 56U, desc1.option_->getType()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3334, gtest_ar.failure_message()) = ::testing::Message()
;
3335 // Try to get the non-existing option from the non-existing
3336 // option space and expect that option is not returned.
3337 OptionDescriptor desc3 = CfgMgr::instance().getStagingCfg()->
3338 getCfgOption()->get("non-existing", 56);
3339 ASSERT_FALSE(desc3.option_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(desc3.option_))) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3339, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc3.option_", "true", "false") .c_str()) = ::testing::Message
()
;
3340}
3341
3342// The goal of this test is to verify that it is possible to
3343// encapsulate option space containing some options with
3344// another option. In this test we create base option that
3345// encapsulates option space 'isc' that comprises two other
3346// options. Also, for all options their definitions are
3347// created.
3348TEST_F(Dhcp4ParserTest, optionDataEncapsulate)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDataEncapsulate") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionDataEncapsulate_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionDataEncapsulate_Test() = default
; ~Dhcp4ParserTest_optionDataEncapsulate_Test() override = default
; Dhcp4ParserTest_optionDataEncapsulate_Test (const Dhcp4ParserTest_optionDataEncapsulate_Test
&) = delete; Dhcp4ParserTest_optionDataEncapsulate_Test &
operator=( const Dhcp4ParserTest_optionDataEncapsulate_Test &
) = delete; Dhcp4ParserTest_optionDataEncapsulate_Test (Dhcp4ParserTest_optionDataEncapsulate_Test
&&) noexcept = delete; Dhcp4ParserTest_optionDataEncapsulate_Test
& operator=( Dhcp4ParserTest_optionDataEncapsulate_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionDataEncapsulate_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDataEncapsulate", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3348), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3348), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3348), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataEncapsulate_Test
>); void Dhcp4ParserTest_optionDataEncapsulate_Test::TestBody
()
{
3349
3350 // @todo DHCP configurations has many dependencies between
3351 // parameters. First of all, configuration for subnet is
3352 // inherited from the global values. Thus subnet has to be
3353 // configured when all global values have been configured.
3354 // Also, an option can encapsulate another option only
3355 // if the latter has been configured. For this reason in this
3356 // test we created two-stage configuration where first we
3357 // created options that belong to encapsulated option space.
3358 // In the second stage we add the base option. Also, the Subnet
3359 // object is configured in the second stage so it is created
3360 // at the very end (when all other parameters are configured).
3361
3362 // Starting stage 1. Configure sub-options and their definitions.
3363 string config = "{ " + genIfaceConfig() + ","
3364 "\"valid-lifetime\": 4000,"
3365 "\"rebind-timer\": 2000,"
3366 "\"renew-timer\": 1000,"
3367 "\"option-data\": [ {"
3368 " \"name\": \"foo\","
3369 " \"space\": \"isc\","
3370 " \"data\": \"1234\""
3371 " },"
3372 " {"
3373 " \"name\": \"foo2\","
3374 " \"space\": \"isc\","
3375 " \"data\": \"192.168.2.1\""
3376 " } ],"
3377 "\"option-def\": [ {"
3378 " \"name\": \"foo\","
3379 " \"code\": 1,"
3380 " \"type\": \"uint32\","
3381 " \"space\": \"isc\""
3382 " },"
3383 " {"
3384 " \"name\": \"foo2\","
3385 " \"code\": 2,"
3386 " \"type\": \"ipv4-address\","
3387 " \"space\": \"isc\""
3388 " } ]"
3389 "}";
3390
3391 ConstElementPtr json;
3392 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_3392
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3392
; } } else gtest_label_testnothrow_3392 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3392, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3393 extractConfig(config);
3394
3395 ConstElementPtr status;
3396 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_3396; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3396; } } else gtest_label_testnothrow_3396
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3396, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3397 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3397, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
3398 checkResult(status, 0);
3399
3400 CfgMgr::instance().clear();
3401
3402 // Stage 2. Configure base option and a subnet. Please note that
3403 // the configuration from the stage 2 is repeated because Kea
3404 // configuration manager sends whole configuration for the lists
3405 // where at least one element is being modified or added.
3406 config = "{ " + genIfaceConfig() + ","
3407 "\"valid-lifetime\": 3000,"
3408 "\"rebind-timer\": 2000,"
3409 "\"renew-timer\": 1000,"
3410 "\"option-data\": [ {"
3411 " \"name\": \"base-option\","
3412 " \"data\": \"11\""
3413 " },"
3414 " {"
3415 " \"name\": \"foo\","
3416 " \"space\": \"isc\","
3417 " \"data\": \"1234\""
3418 " },"
3419 " {"
3420 " \"name\": \"foo2\","
3421 " \"space\": \"isc\","
3422 " \"data\": \"192.168.2.1\""
3423 " } ],"
3424 "\"option-def\": [ {"
3425 " \"name\": \"base-option\","
3426 " \"code\": 222,"
3427 " \"type\": \"uint8\","
3428 " \"space\": \"dhcp4\","
3429 " \"encapsulate\": \"isc\""
3430 "},"
3431 "{"
3432 " \"name\": \"foo\","
3433 " \"code\": 1,"
3434 " \"type\": \"uint32\","
3435 " \"space\": \"isc\""
3436 " },"
3437 " {"
3438 " \"name\": \"foo2\","
3439 " \"code\": 2,"
3440 " \"type\": \"ipv4-address\","
3441 " \"space\": \"isc\""
3442 " } ],"
3443 "\"subnet4\": [ { "
3444 " \"id\": 1,"
3445 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
3446 " \"subnet\": \"192.0.2.0/24\""
3447 " } ]"
3448 "}";
3449
3450 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_3450
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3450
; } } else gtest_label_testnothrow_3450 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3450, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3451 extractConfig(config);
3452
3453 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_3453; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3453; } } else gtest_label_testnothrow_3453
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3453, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3454 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3454, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
3455 checkResult(status, 0);
3456
3457 // We should have one option available.
3458 OptionContainerPtr options =
3459 CfgMgr::instance().getStagingCfg()->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3460 ASSERT_TRUE(options)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(options)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3460, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "options", "false", "true") .c_str()) = ::testing::Message(
)
;
3461 ASSERT_EQ(1U, options->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "options->size()"
, 1U, options->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3461, gtest_ar.failure_message()) = ::testing::Message()
;
3462
3463 // Get the option.
3464 OptionDescriptor desc =
3465 CfgMgr::instance().getStagingCfg()->getCfgOption()->get(DHCP4_OPTION_SPACE"dhcp4", 222);
3466 EXPECT_TRUE(desc.option_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(desc.option_)) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3466, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc.option_", "false", "true") .c_str()) = ::testing::Message
()
;
3467 EXPECT_EQ(222U, desc.option_->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("222U", "desc.option_->getType()"
, 222U, desc.option_->getType()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3467, gtest_ar.failure_message()) = ::testing::Message()
;
3468
3469 // This option should comprise two sub-options.
3470 // One of them is 'foo' with code 1.
3471 OptionPtr option_foo = desc.option_->getOption(1);
3472 ASSERT_TRUE(option_foo)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(option_foo)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3472, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option_foo", "false", "true") .c_str()) = ::testing::Message
()
;
3473 EXPECT_EQ(1U, option_foo->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "option_foo->getType()"
, 1U, option_foo->getType()))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3473, gtest_ar.failure_message()) = ::testing::Message()
;
3474
3475 // ...another one 'foo2' with code 2.
3476 OptionPtr option_foo2 = desc.option_->getOption(2);
3477 ASSERT_TRUE(option_foo2)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(option_foo2)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3477, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option_foo2", "false", "true") .c_str()) = ::testing::Message
()
;
3478 EXPECT_EQ(2U, option_foo2->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "option_foo2->getType()"
, 2U, option_foo2->getType()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3478, gtest_ar.failure_message()) = ::testing::Message()
;
3479}
3480
3481// Goal of this test is to verify options configuration
3482// for a single subnet. In particular this test checks
3483// that local options configuration overrides global
3484// option setting.
3485TEST_F(Dhcp4ParserTest, optionDataInSingleSubnet)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDataInSingleSubnet") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionDataInSingleSubnet_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_optionDataInSingleSubnet_Test
() = default; ~Dhcp4ParserTest_optionDataInSingleSubnet_Test(
) override = default; Dhcp4ParserTest_optionDataInSingleSubnet_Test
(const Dhcp4ParserTest_optionDataInSingleSubnet_Test &) =
delete; Dhcp4ParserTest_optionDataInSingleSubnet_Test & operator
=( const Dhcp4ParserTest_optionDataInSingleSubnet_Test &)
= delete; Dhcp4ParserTest_optionDataInSingleSubnet_Test (Dhcp4ParserTest_optionDataInSingleSubnet_Test
&&) noexcept = delete; Dhcp4ParserTest_optionDataInSingleSubnet_Test
& operator=( Dhcp4ParserTest_optionDataInSingleSubnet_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_optionDataInSingleSubnet_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDataInSingleSubnet", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3485), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3485), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3485), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataInSingleSubnet_Test
>); void Dhcp4ParserTest_optionDataInSingleSubnet_Test::TestBody
()
{
3486 ConstElementPtr x;
3487 string config = "{ " + genIfaceConfig() + ","
3488 "\"rebind-timer\": 2000, "
3489 "\"renew-timer\": 1000, "
3490 "\"option-data\": [ {"
3491 " \"name\": \"dhcp-message\","
3492 " \"data\": \"AB\","
3493 " \"csv-format\": false"
3494 " } ],"
3495 "\"subnet4\": [ { "
3496 " \"id\": 1,"
3497 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
3498 " \"subnet\": \"192.0.2.0/24\", "
3499 " \"option-data\": [ {"
3500 " \"name\": \"dhcp-message\","
3501 " \"data\": \"ABCDEF0105\","
3502 " \"csv-format\": false"
3503 " },"
3504 " {"
3505 " \"name\": \"default-ip-ttl\","
3506 " \"data\": \"01\","
3507 " \"csv-format\": false"
3508 " } ]"
3509 " } ],"
3510 "\"valid-lifetime\": 4000 }";
3511
3512 ConstElementPtr json;
3513 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_3513
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3513
; } } else gtest_label_testnothrow_3513 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3513, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3514 extractConfig(config);
3515
3516 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_3516; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3516; } } else gtest_label_testnothrow_3516
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3516, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3517 checkResult(x, 0);
3518
3519 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
3520 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.24"));
3521 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3521, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
3522 OptionContainerPtr options = subnet->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3523 ASSERT_EQ(2U, options->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "options->size()"
, 2U, options->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3523, gtest_ar.failure_message()) = ::testing::Message()
;
3524
3525 // Get the search index. Index #1 is to search using option code.
3526 const OptionContainerTypeIndex& idx = options->get<1>();
3527
3528 // Get the options for specified index. Expecting one option to be
3529 // returned but in theory we may have multiple options with the same
3530 // code so we get the range.
3531 std::pair<OptionContainerTypeIndex::const_iterator,
3532 OptionContainerTypeIndex::const_iterator> range =
3533 idx.equal_range(56);
3534 // Expect single option with the code equal to 100.
3535 ASSERT_EQ(1, std::distance(range.first, range.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1", "std::distance(range.first, range.second)"
, 1, std::distance(range.first, range.second)))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3535, gtest_ar.failure_message()) = ::testing::Message()
;
3536 const uint8_t foo_expected[] = {
3537 0xAB, 0xCD, 0xEF, 0x01, 0x05
3538 };
3539 // Check if option is valid in terms of code and carried data.
3540 testOption(*range.first, 56, foo_expected, sizeof(foo_expected));
3541
3542 range = idx.equal_range(23);
3543 ASSERT_EQ(1, std::distance(range.first, range.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1", "std::distance(range.first, range.second)"
, 1, std::distance(range.first, range.second)))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3543, gtest_ar.failure_message()) = ::testing::Message()
;
3544 // Do another round of testing with second option.
3545 const uint8_t foo2_expected[] = {
3546 0x01
3547 };
3548 testOption(*range.first, 23, foo2_expected, sizeof(foo2_expected));
3549}
3550
3551// The goal of this test is to check that the option carrying a boolean
3552// value can be configured using one of the values: "true", "false", "0"
3553// or "1".
3554TEST_F(Dhcp4ParserTest, optionDataBoolean)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDataBoolean") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionDataBoolean_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionDataBoolean_Test() = default
; ~Dhcp4ParserTest_optionDataBoolean_Test() override = default
; Dhcp4ParserTest_optionDataBoolean_Test (const Dhcp4ParserTest_optionDataBoolean_Test
&) = delete; Dhcp4ParserTest_optionDataBoolean_Test &
operator=( const Dhcp4ParserTest_optionDataBoolean_Test &
) = delete; Dhcp4ParserTest_optionDataBoolean_Test (Dhcp4ParserTest_optionDataBoolean_Test
&&) noexcept = delete; Dhcp4ParserTest_optionDataBoolean_Test
& operator=( Dhcp4ParserTest_optionDataBoolean_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionDataBoolean_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDataBoolean", nullptr, nullptr, ::testing::internal::
CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3554), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3554), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3554), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataBoolean_Test
>); void Dhcp4ParserTest_optionDataBoolean_Test::TestBody(
)
{
3555 // Create configuration. Use standard option 19 (ip-forwarding).
3556 std::map<std::string, std::string> params;
3557 params["name"] = "ip-forwarding";
3558 params["space"] = DHCP4_OPTION_SPACE"dhcp4";
3559 params["code"] = "19";
3560 params["data"] = "true";
3561 params["csv-format"] = "true";
3562
3563 std::string config = createConfigWithOption(params);
3564 ASSERT_TRUE(executeConfiguration(config, "parse configuration with a"switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(executeConfiguration(
config, "parse configuration with a" " boolean value"))) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3565, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "executeConfiguration(config, \"parse configuration with a\" \" boolean value\")"
, "false", "true") .c_str()) = ::testing::Message()
3565 " boolean value"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(executeConfiguration(
config, "parse configuration with a" " boolean value"))) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3565, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "executeConfiguration(config, \"parse configuration with a\" \" boolean value\")"
, "false", "true") .c_str()) = ::testing::Message()
;
3566
3567 // The subnet should now hold one option with the code 19.
3568 OptionDescriptor desc = getOptionFromSubnet(IOAddress("192.0.2.24"), 19);
3569 ASSERT_TRUE(desc.option_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(desc.option_)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3569, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc.option_", "false", "true") .c_str()) = ::testing::Message
()
;
3570
3571 // This option should be set to "true", represented as 0x1 in the option
3572 // buffer.
3573 uint8_t expected_option_data[] = {
3574 0x1
3575 };
3576 testConfiguration(params, 19, expected_option_data,
3577 sizeof(expected_option_data));
3578
3579 // Configure the option with the "1" value. This should have the same
3580 // effect as if "true" was specified.
3581 params["data"] = "1";
3582 testConfiguration(params, 19, expected_option_data,
3583 sizeof(expected_option_data));
3584
3585 // The value of "1" with a few leading zeros should work too.
3586 params["data"] = "00001";
3587 testConfiguration(params, 19, expected_option_data,
3588 sizeof(expected_option_data));
3589
3590 // Configure the option with the "false" value.
3591 params["data"] = "false";
3592 // The option buffer should now hold the value of 0.
3593 expected_option_data[0] = 0;
3594 testConfiguration(params, 19, expected_option_data,
3595 sizeof(expected_option_data));
3596
3597 // Specifying "0" should have the same effect as "false".
3598 params["data"] = "0";
3599 testConfiguration(params, 19, expected_option_data,
3600 sizeof(expected_option_data));
3601
3602 // The same effect should be for multiple 0 chars.
3603 params["data"] = "00000";
3604 testConfiguration(params, 19, expected_option_data,
3605 sizeof(expected_option_data));
3606
3607 // Bogus values should not be accepted.
3608 params["data"] = "bogus";
3609 testInvalidOptionParam(params);
3610
3611 params["data"] = "2";
3612 testInvalidOptionParam(params);
3613
3614 // Now let's test that it is possible to use binary format.
3615 params["data"] = "0";
3616 params["csv-format"] = "false";
3617 testConfiguration(params, 19, expected_option_data,
3618 sizeof(expected_option_data));
3619
3620 // The binary 1 should work as well.
3621 params["data"] = "1";
3622 expected_option_data[0] = 1;
3623 testConfiguration(params, 19, expected_option_data,
3624 sizeof(expected_option_data));
3625
3626 // As well as an even number of digits.
3627 params["data"] = "01";
3628 testConfiguration(params, 19, expected_option_data,
3629 sizeof(expected_option_data));
3630}
3631
3632// Goal of this test is to verify options configuration
3633// for multiple subnets.
3634TEST_F(Dhcp4ParserTest, optionDataInMultipleSubnets)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDataInMultipleSubnets") > 1
, "test_name must not be empty"); class Dhcp4ParserTest_optionDataInMultipleSubnets_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_optionDataInMultipleSubnets_Test
() = default; ~Dhcp4ParserTest_optionDataInMultipleSubnets_Test
() override = default; Dhcp4ParserTest_optionDataInMultipleSubnets_Test
(const Dhcp4ParserTest_optionDataInMultipleSubnets_Test &
) = delete; Dhcp4ParserTest_optionDataInMultipleSubnets_Test &
operator=( const Dhcp4ParserTest_optionDataInMultipleSubnets_Test
&) = delete; Dhcp4ParserTest_optionDataInMultipleSubnets_Test
(Dhcp4ParserTest_optionDataInMultipleSubnets_Test &&
) noexcept = delete; Dhcp4ParserTest_optionDataInMultipleSubnets_Test
& operator=( Dhcp4ParserTest_optionDataInMultipleSubnets_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_optionDataInMultipleSubnets_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDataInMultipleSubnets", nullptr, nullptr, ::testing::
internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3634), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3634), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3634), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataInMultipleSubnets_Test
>); void Dhcp4ParserTest_optionDataInMultipleSubnets_Test::
TestBody()
{
3635 ConstElementPtr x;
3636 string config = "{ " + genIfaceConfig() + ","
3637 "\"rebind-timer\": 2000, "
3638 "\"renew-timer\": 1000, "
3639 "\"subnet4\": [ { "
3640 " \"id\": 1,"
3641 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
3642 " \"subnet\": \"192.0.2.0/24\", "
3643 " \"option-data\": [ {"
3644 " \"name\": \"dhcp-message\","
3645 " \"data\": \"0102030405060708090A\","
3646 " \"csv-format\": false"
3647 " } ]"
3648 " },"
3649 " {"
3650 " \"id\": 2,"
3651 " \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
3652 " \"subnet\": \"192.0.3.0/24\", "
3653 " \"option-data\": [ {"
3654 " \"name\": \"default-ip-ttl\","
3655 " \"data\": \"FF\","
3656 " \"csv-format\": false"
3657 " } ]"
3658 " } ],"
3659 "\"valid-lifetime\": 4000 }";
3660
3661 ConstElementPtr json;
3662 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_3662
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3662
; } } else gtest_label_testnothrow_3662 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3662, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3663 extractConfig(config);
3664
3665 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_3665; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3665; } } else gtest_label_testnothrow_3665
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3665, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3666 checkResult(x, 0);
3667
3668 ConstSubnet4Ptr subnet1 = CfgMgr::instance().getStagingCfg()->
3669 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.100"));
3670 ASSERT_TRUE(subnet1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet1)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3670, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1", "false", "true") .c_str()) = ::testing::Message(
)
;
3671 OptionContainerPtr options1 = subnet1->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3672 ASSERT_EQ(1U, options1->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "options1->size()"
, 1U, options1->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3672, gtest_ar.failure_message()) = ::testing::Message()
;
3673
3674 // Get the search index. Index #1 is to search using option code.
3675 const OptionContainerTypeIndex& idx1 = options1->get<1>();
3676
3677 // Get the options for specified index. Expecting one option to be
3678 // returned but in theory we may have multiple options with the same
3679 // code so we get the range.
3680 std::pair<OptionContainerTypeIndex::const_iterator,
3681 OptionContainerTypeIndex::const_iterator> range1 =
3682 idx1.equal_range(56);
3683 // Expect single option with the code equal to 56.
3684 ASSERT_EQ(1, std::distance(range1.first, range1.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1", "std::distance(range1.first, range1.second)"
, 1, std::distance(range1.first, range1.second)))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3684, gtest_ar.failure_message()) = ::testing::Message()
;
3685 const uint8_t foo_expected[] = {
3686 0x01, 0x02, 0x03, 0x04, 0x05,
3687 0x06, 0x07, 0x08, 0x09, 0x0A
3688 };
3689 // Check if option is valid in terms of code and carried data.
3690 testOption(*range1.first, 56, foo_expected, sizeof(foo_expected));
3691
3692 // Test another subnet in the same way.
3693 ConstSubnet4Ptr subnet2 = CfgMgr::instance().getStagingCfg()->
3694 getCfgSubnets4()->selectSubnet(IOAddress("192.0.3.102"));
3695 ASSERT_TRUE(subnet2)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet2)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3695, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2", "false", "true") .c_str()) = ::testing::Message(
)
;
3696 OptionContainerPtr options2 = subnet2->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3697 ASSERT_EQ(1U, options2->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "options2->size()"
, 1U, options2->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3697, gtest_ar.failure_message()) = ::testing::Message()
;
3698
3699 const OptionContainerTypeIndex& idx2 = options2->get<1>();
3700 std::pair<OptionContainerTypeIndex::const_iterator,
3701 OptionContainerTypeIndex::const_iterator> range2 =
3702 idx2.equal_range(23);
3703 ASSERT_EQ(1, std::distance(range2.first, range2.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1", "std::distance(range2.first, range2.second)"
, 1, std::distance(range2.first, range2.second)))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3703, gtest_ar.failure_message()) = ::testing::Message()
;
3704
3705 const uint8_t foo2_expected[] = { 0xFF };
3706 testOption(*range2.first, 23, foo2_expected, sizeof(foo2_expected));
3707}
3708
3709// This test verifies that it is possible to specify options on
3710// pool levels.
3711TEST_F(Dhcp4ParserTest, optionDataSinglePool)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDataSinglePool") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionDataSinglePool_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionDataSinglePool_Test() = default
; ~Dhcp4ParserTest_optionDataSinglePool_Test() override = default
; Dhcp4ParserTest_optionDataSinglePool_Test (const Dhcp4ParserTest_optionDataSinglePool_Test
&) = delete; Dhcp4ParserTest_optionDataSinglePool_Test &
operator=( const Dhcp4ParserTest_optionDataSinglePool_Test &
) = delete; Dhcp4ParserTest_optionDataSinglePool_Test (Dhcp4ParserTest_optionDataSinglePool_Test
&&) noexcept = delete; Dhcp4ParserTest_optionDataSinglePool_Test
& operator=( Dhcp4ParserTest_optionDataSinglePool_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionDataSinglePool_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDataSinglePool", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3711), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3711), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3711), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataSinglePool_Test
>); void Dhcp4ParserTest_optionDataSinglePool_Test::TestBody
()
{
3712 ConstElementPtr x;
3713 string config = "{ " + genIfaceConfig() + ","
3714 "\"rebind-timer\": 2000, "
3715 "\"renew-timer\": 1000, "
3716 "\"subnet4\": [ { "
3717 " \"id\": 1,"
3718 " \"pools\": [ { "
3719 " \"pool\": \"192.0.2.1 - 192.0.2.100\","
3720 " \"option-data\": [ {"
3721 " \"name\": \"dhcp-message\","
3722 " \"data\": \"ABCDEF0105\","
3723 " \"csv-format\": false"
3724 " },"
3725 " {"
3726 " \"name\": \"default-ip-ttl\","
3727 " \"data\": \"01\","
3728 " \"csv-format\": false"
3729 " } ]"
3730 " } ],"
3731 " \"subnet\": \"192.0.2.0/24\""
3732 " } ],"
3733 "\"valid-lifetime\": 4000 }";
3734
3735 ConstElementPtr json;
3736 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_3736
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3736
; } } else gtest_label_testnothrow_3736 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3736, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3737 extractConfig(config);
3738
3739 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_3739; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3739; } } else gtest_label_testnothrow_3739
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3739, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3740 checkResult(x, 0);
3741
3742 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
3743 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.24"), classify_);
3744 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3744, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
3745
3746 PoolPtr pool = subnet->getPool(Lease::TYPE_V4, IOAddress("192.0.2.24"), false);
3747 ASSERT_TRUE(pool)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 3747
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
3748 Pool4Ptr pool4 = boost::dynamic_pointer_cast<Pool4>(pool);
3749 ASSERT_TRUE(pool4)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool4)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3749, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool4", "false", "true") .c_str()) = ::testing::Message()
;
3750
3751 OptionContainerPtr options =
3752 pool4->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3753 ASSERT_EQ(2U, options->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "options->size()"
, 2U, options->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3753, gtest_ar.failure_message()) = ::testing::Message()
;
3754
3755 // Get the search index. Index #1 is to search using option code.
3756 const OptionContainerTypeIndex& idx = options->get<1>();
3757
3758 // Get the options for specified index. Expecting one option to be
3759 // returned but in theory we may have multiple options with the same
3760 // code so we get the range.
3761 std::pair<OptionContainerTypeIndex::const_iterator,
3762 OptionContainerTypeIndex::const_iterator> range =
3763 idx.equal_range(56);
3764 // Expect a single option with the code equal to 100.
3765 ASSERT_EQ(1, std::distance(range.first, range.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1", "std::distance(range.first, range.second)"
, 1, std::distance(range.first, range.second)))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3765, gtest_ar.failure_message()) = ::testing::Message()
;
3766 const uint8_t foo_expected[] = {
3767 0xAB, 0xCD, 0xEF, 0x01, 0x05
3768 };
3769 // Check if option is valid in terms of code and carried data.
3770 testOption(*range.first, 56, foo_expected, sizeof(foo_expected));
3771
3772 range = idx.equal_range(23);
3773 ASSERT_EQ(1, std::distance(range.first, range.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1", "std::distance(range.first, range.second)"
, 1, std::distance(range.first, range.second)))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3773, gtest_ar.failure_message()) = ::testing::Message()
;
3774 // Do another round of testing with second option.
3775
3776 const uint8_t foo2_expected[] = {
3777 0x01
3778 };
3779 testOption(*range.first, 23, foo2_expected, sizeof(foo2_expected));
3780}
3781
3782// This test verifies that it's possible to define different options in
3783// different pools and those options are not confused.
3784TEST_F(Dhcp4ParserTest, optionDataMultiplePools)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDataMultiplePools") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionDataMultiplePools_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_optionDataMultiplePools_Test
() = default; ~Dhcp4ParserTest_optionDataMultiplePools_Test()
override = default; Dhcp4ParserTest_optionDataMultiplePools_Test
(const Dhcp4ParserTest_optionDataMultiplePools_Test &) =
delete; Dhcp4ParserTest_optionDataMultiplePools_Test & operator
=( const Dhcp4ParserTest_optionDataMultiplePools_Test &) =
delete; Dhcp4ParserTest_optionDataMultiplePools_Test (Dhcp4ParserTest_optionDataMultiplePools_Test
&&) noexcept = delete; Dhcp4ParserTest_optionDataMultiplePools_Test
& operator=( Dhcp4ParserTest_optionDataMultiplePools_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_optionDataMultiplePools_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDataMultiplePools", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3784), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3784), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3784), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataMultiplePools_Test
>); void Dhcp4ParserTest_optionDataMultiplePools_Test::TestBody
()
{
3785 ConstElementPtr x;
3786 string config = "{ " + genIfaceConfig() + ","
3787 "\"rebind-timer\": 2000, "
3788 "\"renew-timer\": 1000, "
3789 "\"subnet4\": [ { "
3790 " \"id\": 1,"
3791 " \"pools\": [ { "
3792 " \"pool\": \"192.0.2.1 - 192.0.2.100\","
3793 " \"option-data\": [ {"
3794 " \"name\": \"dhcp-message\","
3795 " \"data\": \"ABCDEF0105\","
3796 " \"csv-format\": false"
3797 " } ]"
3798 " },"
3799 " {"
3800 " \"pool\": \"192.0.2.200 - 192.0.2.250\","
3801 " \"option-data\": [ {"
3802 " \"name\": \"default-ip-ttl\","
3803 " \"data\": \"01\","
3804 " \"csv-format\": false"
3805 " } ]"
3806 " } ],"
3807 " \"subnet\": \"192.0.2.0/24\""
3808 " } ],"
3809 "\"valid-lifetime\": 4000 }";
3810
3811 ConstElementPtr json;
3812 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_3812
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3812
; } } else gtest_label_testnothrow_3812 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3812, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3813 extractConfig(config);
3814
3815 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_3815; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3815; } } else gtest_label_testnothrow_3815
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3815, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3816 checkResult(x, 0);
3817
3818 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
3819 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.24"), classify_);
3820 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3820, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
3821
3822 PoolPtr pool1 = subnet->getPool(Lease::TYPE_V4, IOAddress("192.0.2.24"), false);
3823 ASSERT_TRUE(pool1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool1)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3823, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool1", "false", "true") .c_str()) = ::testing::Message()
;
3824 Pool4Ptr pool41 = boost::dynamic_pointer_cast<Pool4>(pool1);
3825 ASSERT_TRUE(pool41)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool41)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3825, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool41", "false", "true") .c_str()) = ::testing::Message()
;
3826
3827 OptionContainerPtr options1 =
3828 pool41->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3829 ASSERT_EQ(1U, options1->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "options1->size()"
, 1U, options1->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3829, gtest_ar.failure_message()) = ::testing::Message()
;
3830
3831 // Get the search index. Index #1 is to search using option code.
3832 const OptionContainerTypeIndex& idx1 = options1->get<1>();
3833
3834 // Get the options for specified index. Expecting one option to be
3835 // returned but in theory we may have multiple options with the same
3836 // code so we get the range.
3837 std::pair<OptionContainerTypeIndex::const_iterator,
3838 OptionContainerTypeIndex::const_iterator> range1 =
3839 idx1.equal_range(56);
3840 // Expect a single option with the code equal to 100.
3841 ASSERT_EQ(1, std::distance(range1.first, range1.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1", "std::distance(range1.first, range1.second)"
, 1, std::distance(range1.first, range1.second)))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3841, gtest_ar.failure_message()) = ::testing::Message()
;
3842 const uint8_t foo_expected[] = {
3843 0xAB, 0xCD, 0xEF, 0x01, 0x05
3844 };
3845 // Check if option is valid in terms of code and carried data.
3846 testOption(*range1.first, 56, foo_expected, sizeof(foo_expected));
3847
3848 // Test another pool in the same way.
3849 PoolPtr pool2 = subnet->getPool(Lease::TYPE_V4, IOAddress("192.0.2.240"), false);
3850 ASSERT_TRUE(pool2)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool2)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3850, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool2", "false", "true") .c_str()) = ::testing::Message()
;
3851 Pool4Ptr pool42 = boost::dynamic_pointer_cast<Pool4>(pool2);
3852 ASSERT_TRUE(pool42)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool42)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3852, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool42", "false", "true") .c_str()) = ::testing::Message()
;
3853
3854 OptionContainerPtr options2 =
3855 pool42->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3856 ASSERT_EQ(1U, options2->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "options2->size()"
, 1U, options2->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3856, gtest_ar.failure_message()) = ::testing::Message()
;
3857
3858 const OptionContainerTypeIndex& idx2 = options2->get<1>();
3859 std::pair<OptionContainerTypeIndex::const_iterator,
3860 OptionContainerTypeIndex::const_iterator> range2 =
3861 idx2.equal_range(23);
3862 ASSERT_EQ(1, std::distance(range2.first, range2.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1", "std::distance(range2.first, range2.second)"
, 1, std::distance(range2.first, range2.second)))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3862, gtest_ar.failure_message()) = ::testing::Message()
;
3863 const uint8_t foo2_expected[] = {
3864 0x01
3865 };
3866 testOption(*range2.first, 23, foo2_expected, sizeof(foo2_expected));
3867}
3868
3869// Verify that empty option name is rejected in the configuration.
3870TEST_F(Dhcp4ParserTest, optionNameEmpty)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionNameEmpty") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionNameEmpty_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionNameEmpty_Test() = default; ~
Dhcp4ParserTest_optionNameEmpty_Test() override = default; Dhcp4ParserTest_optionNameEmpty_Test
(const Dhcp4ParserTest_optionNameEmpty_Test &) = delete;
Dhcp4ParserTest_optionNameEmpty_Test & operator=( const Dhcp4ParserTest_optionNameEmpty_Test
&) = delete; Dhcp4ParserTest_optionNameEmpty_Test (Dhcp4ParserTest_optionNameEmpty_Test
&&) noexcept = delete; Dhcp4ParserTest_optionNameEmpty_Test
& operator=( Dhcp4ParserTest_optionNameEmpty_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionNameEmpty_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionNameEmpty", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 3870
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3870), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3870), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionNameEmpty_Test
>); void Dhcp4ParserTest_optionNameEmpty_Test::TestBody()
{
3871 // Empty option names not allowed.
3872 testInvalidOptionParam("", "name");
3873}
3874
3875// Verify that empty option name with spaces is rejected
3876// in the configuration.
3877TEST_F(Dhcp4ParserTest, optionNameSpaces)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionNameSpaces") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionNameSpaces_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionNameSpaces_Test() = default;
~Dhcp4ParserTest_optionNameSpaces_Test() override = default;
Dhcp4ParserTest_optionNameSpaces_Test (const Dhcp4ParserTest_optionNameSpaces_Test
&) = delete; Dhcp4ParserTest_optionNameSpaces_Test &
operator=( const Dhcp4ParserTest_optionNameSpaces_Test &
) = delete; Dhcp4ParserTest_optionNameSpaces_Test (Dhcp4ParserTest_optionNameSpaces_Test
&&) noexcept = delete; Dhcp4ParserTest_optionNameSpaces_Test
& operator=( Dhcp4ParserTest_optionNameSpaces_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionNameSpaces_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionNameSpaces", nullptr, nullptr, ::testing::internal::
CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3877), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3877), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3877), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionNameSpaces_Test
>); void Dhcp4ParserTest_optionNameSpaces_Test::TestBody()
{
3878 // Spaces in option names not allowed.
3879 testInvalidOptionParam("option foo", "name");
3880}
3881
3882// Verify that negative option code is rejected in the configuration.
3883TEST_F(Dhcp4ParserTest, optionCodeNegative)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionCodeNegative") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionCodeNegative_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionCodeNegative_Test() = default
; ~Dhcp4ParserTest_optionCodeNegative_Test() override = default
; Dhcp4ParserTest_optionCodeNegative_Test (const Dhcp4ParserTest_optionCodeNegative_Test
&) = delete; Dhcp4ParserTest_optionCodeNegative_Test &
operator=( const Dhcp4ParserTest_optionCodeNegative_Test &
) = delete; Dhcp4ParserTest_optionCodeNegative_Test (Dhcp4ParserTest_optionCodeNegative_Test
&&) noexcept = delete; Dhcp4ParserTest_optionCodeNegative_Test
& operator=( Dhcp4ParserTest_optionCodeNegative_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionCodeNegative_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionCodeNegative", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3883), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3883), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3883), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionCodeNegative_Test
>); void Dhcp4ParserTest_optionCodeNegative_Test::TestBody
()
{
3884 // Check negative option code -4. This should fail too.
3885 testInvalidOptionParam("-4", "code");
3886}
3887
3888// Verify that out of bounds option code is rejected in the configuration.
3889TEST_F(Dhcp4ParserTest, optionCodeNonUint8)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionCodeNonUint8") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionCodeNonUint8_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionCodeNonUint8_Test() = default
; ~Dhcp4ParserTest_optionCodeNonUint8_Test() override = default
; Dhcp4ParserTest_optionCodeNonUint8_Test (const Dhcp4ParserTest_optionCodeNonUint8_Test
&) = delete; Dhcp4ParserTest_optionCodeNonUint8_Test &
operator=( const Dhcp4ParserTest_optionCodeNonUint8_Test &
) = delete; Dhcp4ParserTest_optionCodeNonUint8_Test (Dhcp4ParserTest_optionCodeNonUint8_Test
&&) noexcept = delete; Dhcp4ParserTest_optionCodeNonUint8_Test
& operator=( Dhcp4ParserTest_optionCodeNonUint8_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionCodeNonUint8_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionCodeNonUint8", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3889), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3889), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3889), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionCodeNonUint8_Test
>); void Dhcp4ParserTest_optionCodeNonUint8_Test::TestBody
()
{
3890 // The valid option codes are uint8_t values so passing
3891 // uint8_t maximum value incremented by 1 should result
3892 // in failure.
3893 testInvalidOptionParam("257", "code");
3894}
3895
3896// Verify that out of bounds option code is rejected in the configuration.
3897TEST_F(Dhcp4ParserTest, optionCodeHighNonUint8)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionCodeHighNonUint8") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionCodeHighNonUint8_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_optionCodeHighNonUint8_Test
() = default; ~Dhcp4ParserTest_optionCodeHighNonUint8_Test() override
= default; Dhcp4ParserTest_optionCodeHighNonUint8_Test (const
Dhcp4ParserTest_optionCodeHighNonUint8_Test &) = delete;
Dhcp4ParserTest_optionCodeHighNonUint8_Test & operator=(
const Dhcp4ParserTest_optionCodeHighNonUint8_Test &) = delete
; Dhcp4ParserTest_optionCodeHighNonUint8_Test (Dhcp4ParserTest_optionCodeHighNonUint8_Test
&&) noexcept = delete; Dhcp4ParserTest_optionCodeHighNonUint8_Test
& operator=( Dhcp4ParserTest_optionCodeHighNonUint8_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_optionCodeHighNonUint8_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionCodeHighNonUint8", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3897), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3897), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3897), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionCodeHighNonUint8_Test
>); void Dhcp4ParserTest_optionCodeHighNonUint8_Test::TestBody
()
{
3898 // Another check for uint8_t overflow but this time
3899 // let's pass even greater option code value.
3900 testInvalidOptionParam("500", "code");
3901}
3902
3903// Verify that zero option code is rejected in the configuration.
3904TEST_F(Dhcp4ParserTest, optionCodeZero)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionCodeZero") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_optionCodeZero_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_optionCodeZero_Test() = default; ~
Dhcp4ParserTest_optionCodeZero_Test() override = default; Dhcp4ParserTest_optionCodeZero_Test
(const Dhcp4ParserTest_optionCodeZero_Test &) = delete; Dhcp4ParserTest_optionCodeZero_Test
& operator=( const Dhcp4ParserTest_optionCodeZero_Test &
) = delete; Dhcp4ParserTest_optionCodeZero_Test (Dhcp4ParserTest_optionCodeZero_Test
&&) noexcept = delete; Dhcp4ParserTest_optionCodeZero_Test
& operator=( Dhcp4ParserTest_optionCodeZero_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_optionCodeZero_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionCodeZero", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 3904
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3904), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3904), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionCodeZero_Test
>); void Dhcp4ParserTest_optionCodeZero_Test::TestBody()
{
3905 // Option code 0 is reserved and should not be accepted
3906 // by configuration parser.
3907 testInvalidOptionParam("0", "code");
3908}
3909
3910// Verify that invalid hex literals for option data are detected.
3911TEST_F(Dhcp4ParserTest, optionDataInvalidHexLiterals)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDataInvalidHexLiterals") > 1
, "test_name must not be empty"); class Dhcp4ParserTest_optionDataInvalidHexLiterals_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_optionDataInvalidHexLiterals_Test
() = default; ~Dhcp4ParserTest_optionDataInvalidHexLiterals_Test
() override = default; Dhcp4ParserTest_optionDataInvalidHexLiterals_Test
(const Dhcp4ParserTest_optionDataInvalidHexLiterals_Test &
) = delete; Dhcp4ParserTest_optionDataInvalidHexLiterals_Test
& operator=( const Dhcp4ParserTest_optionDataInvalidHexLiterals_Test
&) = delete; Dhcp4ParserTest_optionDataInvalidHexLiterals_Test
(Dhcp4ParserTest_optionDataInvalidHexLiterals_Test &&
) noexcept = delete; Dhcp4ParserTest_optionDataInvalidHexLiterals_Test
& operator=( Dhcp4ParserTest_optionDataInvalidHexLiterals_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_optionDataInvalidHexLiterals_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDataInvalidHexLiterals", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3911), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3911), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3911), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataInvalidHexLiterals_Test
>); void Dhcp4ParserTest_optionDataInvalidHexLiterals_Test
::TestBody()
{
3912 testInvalidOptionParam("01020R", "data"); // non hex digit
3913 testInvalidOptionParam("0x01:02", "data"); // 0x prefix with colon separator
3914 testInvalidOptionParam("0x01 02", "data"); // 0x prefix with space separator
3915 testInvalidOptionParam("0X0102", "data"); // 0X upper case X in prefix
3916 testInvalidOptionParam("01.02", "data"); // invalid separator
3917}
3918
3919// Verify the valid forms hex literals in option data are supported.
3920TEST_F(Dhcp4ParserTest, optionDataValidHexLiterals)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionDataValidHexLiterals") > 1,
"test_name must not be empty"); class Dhcp4ParserTest_optionDataValidHexLiterals_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_optionDataValidHexLiterals_Test
() = default; ~Dhcp4ParserTest_optionDataValidHexLiterals_Test
() override = default; Dhcp4ParserTest_optionDataValidHexLiterals_Test
(const Dhcp4ParserTest_optionDataValidHexLiterals_Test &
) = delete; Dhcp4ParserTest_optionDataValidHexLiterals_Test &
operator=( const Dhcp4ParserTest_optionDataValidHexLiterals_Test
&) = delete; Dhcp4ParserTest_optionDataValidHexLiterals_Test
(Dhcp4ParserTest_optionDataValidHexLiterals_Test &&)
noexcept = delete; Dhcp4ParserTest_optionDataValidHexLiterals_Test
& operator=( Dhcp4ParserTest_optionDataValidHexLiterals_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_optionDataValidHexLiterals_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionDataValidHexLiterals", nullptr, nullptr, ::testing::
internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3920), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3920), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3920), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataValidHexLiterals_Test
>); void Dhcp4ParserTest_optionDataValidHexLiterals_Test::
TestBody()
{
3921
3922 std::vector<std::string> valid_hexes =
3923 {
3924 "0a0b0C0D", // upper and lower case
3925 "0A:0B:0C:0D", // colon seperator
3926 "0A 0B 0C 0D", // space seperator
3927 "A0B0C0D", // odd number of digits
3928 "0xA0B0C0D" // 0x prefix
3929 };
3930
3931 for (auto const& valid_hex : valid_hexes) {
3932 ConstElementPtr x;
3933 std::string config = createConfigWithOption(valid_hex, "data");
3934 ConstElementPtr json;
3935 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_3935
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3935
; } } else gtest_label_testnothrow_3935 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3935, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3936
3937 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_3937; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3937; } } else gtest_label_testnothrow_3937
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3937, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3938 checkResult(x, 0);
3939
3940 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
3941 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.5"));
3942 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3942, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
3943 OptionContainerPtr options = subnet->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3944 ASSERT_EQ(1U, options->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "options->size()"
, 1U, options->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3944, gtest_ar.failure_message()) = ::testing::Message()
;
3945
3946 // Get the search index. Index #1 is to search using option code.
3947 const OptionContainerTypeIndex& idx = options->get<1>();
3948
3949 // Get the options for specified index. Expecting one option to be
3950 // returned but in theory we may have multiple options with the same
3951 // code so we get the range.
3952 std::pair<OptionContainerTypeIndex::const_iterator,
3953 OptionContainerTypeIndex::const_iterator> range =
3954 idx.equal_range(56);
3955
3956 // Expect single option with the code equal to 100.
3957 ASSERT_EQ(1, std::distance(range.first, range.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1", "std::distance(range.first, range.second)"
, 1, std::distance(range.first, range.second)))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3957, gtest_ar.failure_message()) = ::testing::Message()
;
3958 const uint8_t foo_expected[] = { 0x0A, 0x0B, 0x0C, 0x0D };
3959
3960 // Check if option is valid in terms of code and carried data.
3961 testOption(*range.first, 56, foo_expected, sizeof(foo_expected));
3962
3963 // Clear configuration for the next pass.
3964 resetConfiguration();
3965 }
3966}
3967
3968// Verify that specific option object is returned for standard
3969// option which has dedicated option class derived from Option.
3970TEST_F(Dhcp4ParserTest, stdOptionData)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("stdOptionData") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_stdOptionData_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_stdOptionData_Test() = default; ~Dhcp4ParserTest_stdOptionData_Test
() override = default; Dhcp4ParserTest_stdOptionData_Test (const
Dhcp4ParserTest_stdOptionData_Test &) = delete; Dhcp4ParserTest_stdOptionData_Test
& operator=( const Dhcp4ParserTest_stdOptionData_Test &
) = delete; Dhcp4ParserTest_stdOptionData_Test (Dhcp4ParserTest_stdOptionData_Test
&&) noexcept = delete; Dhcp4ParserTest_stdOptionData_Test
& operator=( Dhcp4ParserTest_stdOptionData_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_stdOptionData_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "stdOptionData", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 3970
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3970), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3970), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_stdOptionData_Test
>); void Dhcp4ParserTest_stdOptionData_Test::TestBody()
{
3971 ConstElementPtr x;
3972 std::map<std::string, std::string> params;
3973 params["name"] = "nis-servers";
3974 params["space"] = DHCP4_OPTION_SPACE"dhcp4";
3975 // Option code 41 means nis-servers.
3976 params["code"] = "41";
3977 // Specify option values in a CSV (user friendly) format.
3978 params["data"] = "192.0.2.10, 192.0.2.1, 192.0.2.3";
3979 params["csv-format"] = "true";
3980
3981 std::string config = createConfigWithOption(params);
3982 ConstElementPtr json;
3983 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_3983
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3983
; } } else gtest_label_testnothrow_3983 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3983, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3984
3985 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_3985; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3985; } } else gtest_label_testnothrow_3985
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3985, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3986 checkResult(x, 0);
3987
3988 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
3989 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.5"));
3990 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3990, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
3991 OptionContainerPtr options = subnet->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3992 ASSERT_TRUE(options)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(options)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3992, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "options", "false", "true") .c_str()) = ::testing::Message(
)
;
3993 ASSERT_EQ(1U, options->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "options->size()"
, 1U, options->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3993, gtest_ar.failure_message()) = ::testing::Message()
;
3994
3995 // Get the search index. Index #1 is to search using option code.
3996 const OptionContainerTypeIndex& idx = options->get<1>();
3997
3998 // Get the options for specified index. Expecting one option to be
3999 // returned but in theory we may have multiple options with the same
4000 // code so we get the range.
4001 std::pair<OptionContainerTypeIndex::const_iterator,
4002 OptionContainerTypeIndex::const_iterator> range =
4003 idx.equal_range(DHO_NIS_SERVERS);
4004 // Expect single option with the code equal to NIS_SERVERS option code.
4005 ASSERT_EQ(1, std::distance(range.first, range.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1", "std::distance(range.first, range.second)"
, 1, std::distance(range.first, range.second)))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4005, gtest_ar.failure_message()) = ::testing::Message()
;
4006 // The actual pointer to the option is held in the option field
4007 // in the structure returned.
4008 OptionPtr option = range.first->option_;
4009 ASSERT_TRUE(option)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(option)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4009, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option", "false", "true") .c_str()) = ::testing::Message()
;
4010 // Option object returned for here is expected to be Option4AddrLst
4011 // which is derived from Option. This class is dedicated to
4012 // represent standard option DHO_NIS_SERVERS.
4013 boost::shared_ptr<Option4AddrLst> option_addrs =
4014 boost::dynamic_pointer_cast<Option4AddrLst>(option);
4015 // If cast is unsuccessful than option returned was of a
4016 // different type than Option4AddrLst. This is wrong.
4017 ASSERT_TRUE(option_addrs)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(option_addrs)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4017, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option_addrs", "false", "true") .c_str()) = ::testing::Message
()
;
4018
4019 // Get addresses from the option.
4020 Option4AddrLst::AddressContainer addrs = option_addrs->getAddresses();
4021 // Verify that the addresses have been configured correctly.
4022 ASSERT_EQ(3U, addrs.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("3U", "addrs.size()"
, 3U, addrs.size()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4022, gtest_ar.failure_message()) = ::testing::Message()
;
4023 EXPECT_EQ("192.0.2.10", addrs[0].toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.0.2.10\""
, "addrs[0].toText()", "192.0.2.10", addrs[0].toText()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4023, gtest_ar.failure_message()) = ::testing::Message()
;
4024 EXPECT_EQ("192.0.2.1", addrs[1].toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.0.2.1\""
, "addrs[1].toText()", "192.0.2.1", addrs[1].toText()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4024, gtest_ar.failure_message()) = ::testing::Message()
;
4025 EXPECT_EQ("192.0.2.3", addrs[2].toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.0.2.3\""
, "addrs[2].toText()", "192.0.2.3", addrs[2].toText()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4025, gtest_ar.failure_message()) = ::testing::Message()
;
4026}
4027
4028/// This test checks if Uint32Parser can really parse the whole range
4029/// and properly err of out of range values. As we can't call Uint32Parser
4030/// directly, we are exploiting the fact that it is used to parse global
4031/// parameter renew-timer and the results are stored in uint32_defaults.
4032/// We get the uint32_defaults using a getUint32Defaults functions which
4033/// is defined only to access the values from this test.
4034TEST_F(Dhcp4ParserTest, DISABLED_Uint32Parser)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("DISABLED_Uint32Parser") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_DISABLED_Uint32Parser_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_DISABLED_Uint32Parser_Test() = default
; ~Dhcp4ParserTest_DISABLED_Uint32Parser_Test() override = default
; Dhcp4ParserTest_DISABLED_Uint32Parser_Test (const Dhcp4ParserTest_DISABLED_Uint32Parser_Test
&) = delete; Dhcp4ParserTest_DISABLED_Uint32Parser_Test &
operator=( const Dhcp4ParserTest_DISABLED_Uint32Parser_Test &
) = delete; Dhcp4ParserTest_DISABLED_Uint32Parser_Test (Dhcp4ParserTest_DISABLED_Uint32Parser_Test
&&) noexcept = delete; Dhcp4ParserTest_DISABLED_Uint32Parser_Test
& operator=( Dhcp4ParserTest_DISABLED_Uint32Parser_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_DISABLED_Uint32Parser_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "DISABLED_Uint32Parser", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4034), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4034), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4034), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_DISABLED_Uint32Parser_Test
>); void Dhcp4ParserTest_DISABLED_Uint32Parser_Test::TestBody
()
{
4035
4036 ConstElementPtr status;
4037
4038 // CASE 1: 0 - minimum value, should work
4039 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_,switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, parseDHCP4("{\"renew-timer\": 0}"
)); } else static_assert(true, ""); } catch (std::exception const
& e) { gtest_msg.value = "it throws "; gtest_msg.value +=
::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testnothrow_4040; } catch (
...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4040
; } } else gtest_label_testnothrow_4040 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4040, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, parseDHCP4(\"{\\\"renew-timer\\\": 0}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
4040 parseDHCP4("{\"renew-timer\": 0}")))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, parseDHCP4("{\"renew-timer\": 0}"
)); } else static_assert(true, ""); } catch (std::exception const
& e) { gtest_msg.value = "it throws "; gtest_msg.value +=
::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testnothrow_4040; } catch (
...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4040
; } } else gtest_label_testnothrow_4040 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4040, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, parseDHCP4(\"{\\\"renew-timer\\\": 0}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4041
4042 // returned value must be ok (0 is a proper value)
4043 checkResult(status, 0);
4044 /// @todo: check that the renew-timer is really 0
4045
4046 // CASE 2: 4294967295U (UINT_MAX) should work as well
4047 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_,switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, parseDHCP4("{\"renew-timer\": 4294967295}"
)); } else static_assert(true, ""); } catch (std::exception const
& e) { gtest_msg.value = "it throws "; gtest_msg.value +=
::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testnothrow_4048; } catch (
...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4048
; } } else gtest_label_testnothrow_4048 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4048, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, parseDHCP4(\"{\\\"renew-timer\\\": 4294967295}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
4048 parseDHCP4("{\"renew-timer\": 4294967295}")))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, parseDHCP4("{\"renew-timer\": 4294967295}"
)); } else static_assert(true, ""); } catch (std::exception const
& e) { gtest_msg.value = "it throws "; gtest_msg.value +=
::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testnothrow_4048; } catch (
...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4048
; } } else gtest_label_testnothrow_4048 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4048, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, parseDHCP4(\"{\\\"renew-timer\\\": 4294967295}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4049
4050 // returned value must be ok (0 is a proper value)
4051 checkResult(status, 0);
4052 /// @todo: check that the renew-timer is really 4294967295U
4053
4054 // CASE 3: 4294967296U (UINT_MAX + 1) should not work
4055 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_,switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, parseJSON("{\"renew-timer\": 4294967296}"
)); } else static_assert(true, ""); } catch (std::exception const
& e) { gtest_msg.value = "it throws "; gtest_msg.value +=
::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testnothrow_4056; } catch (
...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4056
; } } else gtest_label_testnothrow_4056 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4056, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, parseJSON(\"{\\\"renew-timer\\\": 4294967296}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
4056 parseJSON("{\"renew-timer\": 4294967296}")))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, parseJSON("{\"renew-timer\": 4294967296}"
)); } else static_assert(true, ""); } catch (std::exception const
& e) { gtest_msg.value = "it throws "; gtest_msg.value +=
::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testnothrow_4056; } catch (
...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4056
; } } else gtest_label_testnothrow_4056 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4056, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, parseJSON(\"{\\\"renew-timer\\\": 4294967296}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4057
4058 // returned value must be rejected (1 configuration error)
4059 checkResult(status, CONTROL_RESULT_ERROR);
4060 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4060, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
4061
4062 // CASE 4: -1 (UINT_MIN -1 ) should not work
4063 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_,switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, parseJSON("{\"renew-timer\": -1}"
)); } else static_assert(true, ""); } catch (std::exception const
& e) { gtest_msg.value = "it throws "; gtest_msg.value +=
::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testnothrow_4064; } catch (
...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4064
; } } else gtest_label_testnothrow_4064 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4064, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, parseJSON(\"{\\\"renew-timer\\\": -1}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
4064 parseJSON("{\"renew-timer\": -1}")))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, parseJSON("{\"renew-timer\": -1}"
)); } else static_assert(true, ""); } catch (std::exception const
& e) { gtest_msg.value = "it throws "; gtest_msg.value +=
::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testnothrow_4064; } catch (
...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4064
; } } else gtest_label_testnothrow_4064 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4064, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, parseJSON(\"{\\\"renew-timer\\\": -1}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4065
4066 // returned value must be rejected (1 configuration error)
4067 checkResult(status, CONTROL_RESULT_ERROR);
4068 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4068, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
4069}
4070
4071// The goal of this test is to verify that the domain-search option
4072// can be set using domain names
4073TEST_F(Dhcp4ParserTest, domainSearchOption)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("domainSearchOption") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_domainSearchOption_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_domainSearchOption_Test() = default
; ~Dhcp4ParserTest_domainSearchOption_Test() override = default
; Dhcp4ParserTest_domainSearchOption_Test (const Dhcp4ParserTest_domainSearchOption_Test
&) = delete; Dhcp4ParserTest_domainSearchOption_Test &
operator=( const Dhcp4ParserTest_domainSearchOption_Test &
) = delete; Dhcp4ParserTest_domainSearchOption_Test (Dhcp4ParserTest_domainSearchOption_Test
&&) noexcept = delete; Dhcp4ParserTest_domainSearchOption_Test
& operator=( Dhcp4ParserTest_domainSearchOption_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_domainSearchOption_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "domainSearchOption", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4073), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4073), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4073), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_domainSearchOption_Test
>); void Dhcp4ParserTest_domainSearchOption_Test::TestBody
()
{
4074 // Create configuration.
4075 std::map<std::string, std::string> params;
4076 params["name"] = "domain-search";
4077 params["space"] = DHCP4_OPTION_SPACE"dhcp4";
4078 params["code"] = "119"; // DHO_DOMAIN_SEARCH
4079 params["data"] = "mydomain.example.com, example.com";
4080 params["csv-format"] = "true";
4081
4082 std::string config = createConfigWithOption(params);
4083 EXPECT_TRUE(executeConfiguration(config, "parse configuration with a"switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(executeConfiguration(
config, "parse configuration with a" " domain-search option")
)) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4084, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "executeConfiguration(config, \"parse configuration with a\" \" domain-search option\")"
, "false", "true") .c_str()) = ::testing::Message()
4084 " domain-search option"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(executeConfiguration(
config, "parse configuration with a" " domain-search option")
)) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4084, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "executeConfiguration(config, \"parse configuration with a\" \" domain-search option\")"
, "false", "true") .c_str()) = ::testing::Message()
;
4085}
4086
4087// The goal of this test is to verify that the slp-directory-agent
4088// option can be set using a trailing array of addresses and
4089// slp-service-scope without option scope list
4090TEST_F(Dhcp4ParserTest, slpOptions)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("slpOptions") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_slpOptions_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_slpOptions_Test() = default; ~Dhcp4ParserTest_slpOptions_Test
() override = default; Dhcp4ParserTest_slpOptions_Test (const
Dhcp4ParserTest_slpOptions_Test &) = delete; Dhcp4ParserTest_slpOptions_Test
& operator=( const Dhcp4ParserTest_slpOptions_Test &
) = delete; Dhcp4ParserTest_slpOptions_Test (Dhcp4ParserTest_slpOptions_Test
&&) noexcept = delete; Dhcp4ParserTest_slpOptions_Test
& operator=( Dhcp4ParserTest_slpOptions_Test &&)
noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_slpOptions_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "slpOptions", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 4090
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4090), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4090), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_slpOptions_Test
>); void Dhcp4ParserTest_slpOptions_Test::TestBody()
{
4091 ConstElementPtr x;
4092 string config = "{ " + genIfaceConfig() + ","
4093 "\"rebind-timer\": 2000,"
4094 "\"renew-timer\": 1000,"
4095 "\"option-data\": [ {"
4096 " \"name\": \"slp-directory-agent\","
4097 " \"data\": \"true, 10.0.0.3, 127.0.0.1\""
4098 " },"
4099 " {"
4100 " \"name\": \"slp-service-scope\","
4101 " \"data\": \"false, \""
4102 " } ],"
4103 "\"subnet4\": [ { "
4104 " \"id\": 1,"
4105 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
4106 " \"subnet\": \"192.0.2.0/24\""
4107 " } ],"
4108 "\"valid-lifetime\": 4000 }";
4109
4110 ConstElementPtr json;
4111 ASSERT_NO_THROW(json = parseDHCP4(config, true))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config, true); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_4111
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4111
; } } else gtest_label_testnothrow_4111 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4111, ("Expected: " "json = parseDHCP4(config, true)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4112 extractConfig(config);
4113
4114 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_4114; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4114; } } else gtest_label_testnothrow_4114
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4114, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4115 checkResult(x, 0);
4116
4117 // Get options
4118 OptionContainerPtr options = CfgMgr::instance().getStagingCfg()->
4119 getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
4120 ASSERT_EQ(2U, options->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "options->size()"
, 2U, options->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4120, gtest_ar.failure_message()) = ::testing::Message()
;
4121
4122 // Get the search index. Index #1 is to search using option code.
4123 const OptionContainerTypeIndex& idx = options->get<1>();
4124
4125 // Get the options for specified index. Expecting one option to be
4126 // returned but in theory we may have multiple options with the same
4127 // code so we get the range.
4128 std::pair<OptionContainerTypeIndex::const_iterator,
4129 OptionContainerTypeIndex::const_iterator> range =
4130 idx.equal_range(DHO_DIRECTORY_AGENT);
4131 // Expect a single option with the code equal to 78.
4132 ASSERT_EQ(1, std::distance(range.first, range.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1", "std::distance(range.first, range.second)"
, 1, std::distance(range.first, range.second)))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4132, gtest_ar.failure_message()) = ::testing::Message()
;
4133 const uint8_t sda_expected[] = {
4134 0x01, 0x0a, 0x00, 0x00, 0x03, 0x7f, 0x00, 0x00, 0x01
4135 };
4136 // Check if option is valid in terms of code and carried data.
4137 testOption(*range.first, 78, sda_expected, sizeof(sda_expected));
4138
4139 range = idx.equal_range(DHO_SERVICE_SCOPE);
4140 ASSERT_EQ(1, std::distance(range.first, range.second))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1", "std::distance(range.first, range.second)"
, 1, std::distance(range.first, range.second)))) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4140, gtest_ar.failure_message()) = ::testing::Message()
;
4141 // Do another round of testing with second option.
4142 const uint8_t sss_expected[] = {
4143 0x00
4144 };
4145 testOption(*range.first, 79, sss_expected, sizeof(sss_expected));
4146}
4147
4148// The goal of this test is to verify that the standard option can
4149// be configured to encapsulate multiple other options.
4150TEST_F(Dhcp4ParserTest, stdOptionDataEncapsulate)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("stdOptionDataEncapsulate") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_stdOptionDataEncapsulate_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_stdOptionDataEncapsulate_Test
() = default; ~Dhcp4ParserTest_stdOptionDataEncapsulate_Test(
) override = default; Dhcp4ParserTest_stdOptionDataEncapsulate_Test
(const Dhcp4ParserTest_stdOptionDataEncapsulate_Test &) =
delete; Dhcp4ParserTest_stdOptionDataEncapsulate_Test & operator
=( const Dhcp4ParserTest_stdOptionDataEncapsulate_Test &)
= delete; Dhcp4ParserTest_stdOptionDataEncapsulate_Test (Dhcp4ParserTest_stdOptionDataEncapsulate_Test
&&) noexcept = delete; Dhcp4ParserTest_stdOptionDataEncapsulate_Test
& operator=( Dhcp4ParserTest_stdOptionDataEncapsulate_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_stdOptionDataEncapsulate_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "stdOptionDataEncapsulate", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4150), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4150), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4150), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_stdOptionDataEncapsulate_Test
>); void Dhcp4ParserTest_stdOptionDataEncapsulate_Test::TestBody
()
{
4151
4152 // The configuration is two stage process in this test.
4153 // In the first stage we create definitions of suboptions
4154 // that we will add to the base option.
4155 // Let's create some dummy options: foo and foo2.
4156 string config = "{ " + genIfaceConfig() + ","
4157 "\"valid-lifetime\": 4000,"
4158 "\"rebind-timer\": 2000,"
4159 "\"renew-timer\": 1000,"
4160 "\"option-data\": [ {"
4161 " \"name\": \"foo\","
4162 " \"space\": \"vendor-encapsulated-options-space\","
4163 " \"data\": \"1234\""
4164 " },"
4165 " {"
4166 " \"name\": \"foo2\","
4167 " \"space\": \"vendor-encapsulated-options-space\","
4168 " \"data\": \"192.168.2.1\""
4169 " } ],"
4170 "\"option-def\": [ {"
4171 " \"name\": \"foo\","
4172 " \"code\": 1,"
4173 " \"type\": \"uint32\","
4174 " \"space\": \"vendor-encapsulated-options-space\""
4175 " },"
4176 " {"
4177 " \"name\": \"foo2\","
4178 " \"code\": 2,"
4179 " \"type\": \"ipv4-address\","
4180 " \"space\": \"vendor-encapsulated-options-space\""
4181 " } ]"
4182 "}";
4183
4184 ConstElementPtr json;
4185 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_4185
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4185
; } } else gtest_label_testnothrow_4185 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4185, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4186 extractConfig(config);
4187
4188 ConstElementPtr status;
4189 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_4189; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4189; } } else gtest_label_testnothrow_4189
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4189, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4190 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4190, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4191 checkResult(status, 0);
4192
4193 CfgMgr::instance().clear();
4194
4195 // Once the definitions have been added we can configure the
4196 // standard option #43. This option comprises an enterprise
4197 // number and sub options. By convention (introduced in
4198 // std_option_defs.h) option named 'vendor-encapsulated-options'
4199 // encapsulates the option space named 'vendor-encapsulated-options-space'.
4200 // We add our dummy options to this option space and thus
4201 // they should be included as sub-options in the
4202 // 'vendor-encapsulated-options' option.
4203 config = "{ " + genIfaceConfig() + ","
4204 "\"valid-lifetime\": 3000,"
4205 "\"rebind-timer\": 2000,"
4206 "\"renew-timer\": 1000,"
4207 "\"option-data\": [ {"
4208 " \"name\": \"vendor-encapsulated-options\","
4209 " \"csv-format\": false"
4210 " },"
4211 " {"
4212 " \"name\": \"foo\","
4213 " \"space\": \"vendor-encapsulated-options-space\","
4214 " \"data\": \"1234\""
4215 " },"
4216 " {"
4217 " \"name\": \"foo2\","
4218 " \"space\": \"vendor-encapsulated-options-space\","
4219 " \"code\": 2,"
4220 " \"data\": \"192.168.2.1\","
4221 " \"csv-format\": true"
4222 " } ],"
4223 "\"option-def\": [ {"
4224 " \"name\": \"foo\","
4225 " \"code\": 1,"
4226 " \"type\": \"uint32\","
4227 " \"space\": \"vendor-encapsulated-options-space\""
4228 " },"
4229 " {"
4230 " \"name\": \"foo2\","
4231 " \"code\": 2,"
4232 " \"type\": \"ipv4-address\","
4233 " \"space\": \"vendor-encapsulated-options-space\""
4234 " } ],"
4235 "\"subnet4\": [ { "
4236 " \"id\": 1,"
4237 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
4238 " \"subnet\": \"192.0.2.0/24\""
4239 " } ]"
4240 "}";
4241
4242 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_4242
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4242
; } } else gtest_label_testnothrow_4242 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4242, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4243 extractConfig(config);
4244
4245 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_4245; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4245; } } else gtest_label_testnothrow_4245
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4245, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4246 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4246, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4247 checkResult(status, 0);
4248
4249 // We should have one option available.
4250 OptionContainerPtr options =
4251 CfgMgr::instance().getStagingCfg()->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
4252 ASSERT_TRUE(options)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(options)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4252, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "options", "false", "true") .c_str()) = ::testing::Message(
)
;
4253 ASSERT_EQ(1U, options->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "options->size()"
, 1U, options->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4253, gtest_ar.failure_message()) = ::testing::Message()
;
4254
4255 // Get the option.
4256 OptionDescriptor desc = CfgMgr::instance().getStagingCfg()->
4257 getCfgOption()->get(DHCP4_OPTION_SPACE"dhcp4", DHO_VENDOR_ENCAPSULATED_OPTIONS);
4258 EXPECT_TRUE(desc.option_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(desc.option_)) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4258, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc.option_", "false", "true") .c_str()) = ::testing::Message
()
;
4259 EXPECT_EQ(DHO_VENDOR_ENCAPSULATED_OPTIONS, desc.option_->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("DHO_VENDOR_ENCAPSULATED_OPTIONS"
, "desc.option_->getType()", DHO_VENDOR_ENCAPSULATED_OPTIONS
, desc.option_->getType()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4259, gtest_ar.failure_message()) = ::testing::Message()
;
4260
4261 // Option with the code 1 should be added as a sub-option.
4262 OptionPtr option_foo = desc.option_->getOption(1);
4263 ASSERT_TRUE(option_foo)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(option_foo)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4263, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option_foo", "false", "true") .c_str()) = ::testing::Message
()
;
4264 EXPECT_EQ(1U, option_foo->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "option_foo->getType()"
, 1U, option_foo->getType()))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4264, gtest_ar.failure_message()) = ::testing::Message()
;
4265 // This option comprises a single uint32_t value thus it is
4266 // represented by OptionInt<uint32_t> class. Let's get the
4267 // object of this type.
4268 boost::shared_ptr<OptionInt<uint32_t> > option_foo_uint32 =
4269 boost::dynamic_pointer_cast<OptionInt<uint32_t> >(option_foo);
4270 ASSERT_TRUE(option_foo_uint32)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(option_foo_uint32)) ;
else return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4270, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option_foo_uint32", "false", "true") .c_str()) = ::testing
::Message()
;
4271 // Validate the value according to the configuration.
4272 EXPECT_EQ(1234U, option_foo_uint32->getValue())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1234U", "option_foo_uint32->getValue()"
, 1234U, option_foo_uint32->getValue()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 4272
, gtest_ar.failure_message()) = ::testing::Message()
;
4273
4274 // Option with the code 2 should be added as a sub-option.
4275 OptionPtr option_foo2 = desc.option_->getOption(2);
4276 ASSERT_TRUE(option_foo2)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(option_foo2)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4276, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option_foo2", "false", "true") .c_str()) = ::testing::Message
()
;
4277 EXPECT_EQ(2U, option_foo2->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "option_foo2->getType()"
, 2U, option_foo2->getType()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4277, gtest_ar.failure_message()) = ::testing::Message()
;
4278 // This option comprises the IPV4 address. Such option is
4279 // represented by OptionCustom object.
4280 OptionCustomPtr option_foo2_v4 =
4281 boost::dynamic_pointer_cast<OptionCustom>(option_foo2);
4282 ASSERT_TRUE(option_foo2_v4)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(option_foo2_v4)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4282, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option_foo2_v4", "false", "true") .c_str()) = ::testing::Message
()
;
4283 // Get the IP address carried by this option and validate it.
4284 EXPECT_EQ("192.168.2.1", option_foo2_v4->readAddress().toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.168.2.1\""
, "option_foo2_v4->readAddress().toText()", "192.168.2.1",
option_foo2_v4->readAddress().toText()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 4284
, gtest_ar.failure_message()) = ::testing::Message()
;
4285
4286 // Option with the code 3 should not be added.
4287 EXPECT_FALSE(desc.option_->getOption(3))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(desc.option_->getOption
(3)))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4287, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc.option_->getOption(3)", "true", "false") .c_str())
= ::testing::Message()
;
4288}
4289
4290// This test checks if vendor options can be specified in the config file
4291// (in hex format), and later retrieved from configured subnet
4292TEST_F(Dhcp4ParserTest, vendorOptionsHex)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("vendorOptionsHex") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_vendorOptionsHex_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_vendorOptionsHex_Test() = default;
~Dhcp4ParserTest_vendorOptionsHex_Test() override = default;
Dhcp4ParserTest_vendorOptionsHex_Test (const Dhcp4ParserTest_vendorOptionsHex_Test
&) = delete; Dhcp4ParserTest_vendorOptionsHex_Test &
operator=( const Dhcp4ParserTest_vendorOptionsHex_Test &
) = delete; Dhcp4ParserTest_vendorOptionsHex_Test (Dhcp4ParserTest_vendorOptionsHex_Test
&&) noexcept = delete; Dhcp4ParserTest_vendorOptionsHex_Test
& operator=( Dhcp4ParserTest_vendorOptionsHex_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_vendorOptionsHex_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "vendorOptionsHex", nullptr, nullptr, ::testing::internal::
CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4292), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4292), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4292), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_vendorOptionsHex_Test
>); void Dhcp4ParserTest_vendorOptionsHex_Test::TestBody()
{
4293
4294 // This configuration string is to configure two options
4295 // sharing the code 1 and belonging to the different vendor spaces.
4296 // (different vendor-id values).
4297 string config = "{ " + genIfaceConfig() + ","
4298 "\"valid-lifetime\": 4000,"
4299 "\"rebind-timer\": 2000,"
4300 "\"renew-timer\": 1000,"
4301 "\"option-data\": [ {"
4302 " \"name\": \"option-one\","
4303 " \"space\": \"vendor-4491\"," // VENDOR_ID_CABLE_LABS = 4491
4304 " \"code\": 100," // just a random code
4305 " \"data\": \"ABCDEF0105\","
4306 " \"csv-format\": false"
4307 " },"
4308 " {"
4309 " \"name\": \"option-two\","
4310 " \"space\": \"vendor-1234\","
4311 " \"code\": 100,"
4312 " \"data\": \"1234\","
4313 " \"csv-format\": false"
4314 " } ],"
4315 "\"subnet4\": [ { "
4316 " \"id\": 1,"
4317 " \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\" } ],"
4318 " \"subnet\": \"192.0.2.0/24\""
4319 " } ]"
4320 "}";
4321
4322 ConstElementPtr json;
4323 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_4323
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4323
; } } else gtest_label_testnothrow_4323 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4323, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4324 extractConfig(config);
4325
4326 ConstElementPtr status;
4327 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_4327; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4327; } } else gtest_label_testnothrow_4327
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4327, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4328 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4328, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4329 checkResult(status, 0);
4330
4331 // Options should be now available
4332 // Try to get the option from the vendor space 4491
4333 OptionDescriptor desc1 = CfgMgr::instance().getStagingCfg()->
4334 getCfgOption()->get(VENDOR_ID_CABLE_LABS4491U, 100);
4335 ASSERT_TRUE(desc1.option_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(desc1.option_)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4335, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc1.option_", "false", "true") .c_str()) = ::testing::Message
()
;
4336 EXPECT_EQ(100U, desc1.option_->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("100U", "desc1.option_->getType()"
, 100U, desc1.option_->getType()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4336, gtest_ar.failure_message()) = ::testing::Message()
;
4337 // Try to get the option from the vendor space 1234
4338 OptionDescriptor desc2 =
4339 CfgMgr::instance().getStagingCfg()->getCfgOption()->get(1234, 100);
4340 ASSERT_TRUE(desc2.option_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(desc2.option_)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4340, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc2.option_", "false", "true") .c_str()) = ::testing::Message
()
;
4341 EXPECT_EQ(100U, desc1.option_->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("100U", "desc1.option_->getType()"
, 100U, desc1.option_->getType()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4341, gtest_ar.failure_message()) = ::testing::Message()
;
4342
4343 // Try to get the non-existing option from the non-existing
4344 // option space and expect that option is not returned.
4345 OptionDescriptor desc3 =
4346 CfgMgr::instance().getStagingCfg()->getCfgOption()->get(5678, 100);
4347 ASSERT_FALSE(desc3.option_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(desc3.option_))) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4347, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc3.option_", "true", "false") .c_str()) = ::testing::Message
()
;
4348}
4349
4350// This test checks if vendor options can be specified in the config file,
4351// (in csv format), and later retrieved from configured subnet
4352TEST_F(Dhcp4ParserTest, vendorOptionsCsv)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("vendorOptionsCsv") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_vendorOptionsCsv_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_vendorOptionsCsv_Test() = default;
~Dhcp4ParserTest_vendorOptionsCsv_Test() override = default;
Dhcp4ParserTest_vendorOptionsCsv_Test (const Dhcp4ParserTest_vendorOptionsCsv_Test
&) = delete; Dhcp4ParserTest_vendorOptionsCsv_Test &
operator=( const Dhcp4ParserTest_vendorOptionsCsv_Test &
) = delete; Dhcp4ParserTest_vendorOptionsCsv_Test (Dhcp4ParserTest_vendorOptionsCsv_Test
&&) noexcept = delete; Dhcp4ParserTest_vendorOptionsCsv_Test
& operator=( Dhcp4ParserTest_vendorOptionsCsv_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_vendorOptionsCsv_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "vendorOptionsCsv", nullptr, nullptr, ::testing::internal::
CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4352), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4352), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4352), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_vendorOptionsCsv_Test
>); void Dhcp4ParserTest_vendorOptionsCsv_Test::TestBody()
{
4353
4354 // This configuration string is to configure two options
4355 // sharing the code 1 and belonging to the different vendor spaces.
4356 // (different vendor-id values).
4357 string config = "{ " + genIfaceConfig() + ","
4358 "\"valid-lifetime\": 4000,"
4359 "\"rebind-timer\": 2000,"
4360 "\"renew-timer\": 1000,"
4361 "\"option-data\": [ {"
4362 " \"name\": \"foo\","
4363 " \"space\": \"vendor-4491\","
4364 " \"code\": 100,"
4365 " \"data\": \"this is a string vendor-opt\""
4366 " } ],"
4367 "\"option-def\": [ {"
4368 " \"name\": \"foo\","
4369 " \"code\": 100,"
4370 " \"type\": \"string\","
4371 " \"space\": \"vendor-4491\""
4372 " } ],"
4373 "\"subnet4\": [ { "
4374 " \"id\": 1,"
4375 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
4376 " \"subnet\": \"192.0.2.0/24\" "
4377 " } ]"
4378 "}";
4379
4380 ConstElementPtr status;
4381
4382 ConstElementPtr json;
4383 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_4383
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4383
; } } else gtest_label_testnothrow_4383 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4383, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4384 extractConfig(config);
4385
4386 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_4386; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4386; } } else gtest_label_testnothrow_4386
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4386, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4387 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4387, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4388 checkResult(status, 0);
4389
4390 // Options should be now available.
4391 // Try to get the option from the vendor space 4491
4392 OptionDescriptor desc1 = CfgMgr::instance().getStagingCfg()->
4393 getCfgOption()->get(VENDOR_ID_CABLE_LABS4491U, 100);
4394 ASSERT_TRUE(desc1.option_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(desc1.option_)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4394, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc1.option_", "false", "true") .c_str()) = ::testing::Message
()
;
4395 EXPECT_EQ(100U, desc1.option_->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("100U", "desc1.option_->getType()"
, 100U, desc1.option_->getType()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4395, gtest_ar.failure_message()) = ::testing::Message()
;
4396
4397 // Try to get the non-existing option from the non-existing
4398 // option space and expect that option is not returned.
4399 OptionDescriptor desc2 =
4400 CfgMgr::instance().getStagingCfg()->getCfgOption()->get(5678, 100);
4401 ASSERT_FALSE(desc2.option_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(desc2.option_))) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4401, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc2.option_", "true", "false") .c_str()) = ::testing::Message
()
;
4402}
4403
4404// Tests of the hooks libraries configuration. All tests have the pre-
4405// condition (checked in the test fixture's SetUp() method) that no hooks
4406// libraries are loaded at the start of the tests.
4407
4408// Helper function to return a configuration containing an arbitrary number
4409// of hooks libraries.
4410std::string
4411buildHooksLibrariesConfig(const std::vector<std::string>& libraries = {},
4412 bool multi_threading = true) {
4413 const string lbrace("{");
4414 const string rbrace("}");
4415 const string liblabel("\"library\": ");
4416 const string quote("\"");
4417
4418 // Create the first part of the configuration string.
4419 string config =
4420 "{ \"interfaces-config\": { \"interfaces\": [] },"
4421 "\"hooks-libraries\": [";
4422
4423 // Append the libraries (separated by commas if needed)
4424 for (unsigned int i = 0; i < libraries.size(); ++i) {
4425 if (i > 0) {
4426 config += string(", ");
4427 }
4428 config += (lbrace + liblabel + quote + libraries[i] + quote + rbrace);
4429 }
4430
4431 // Append the remainder of the configuration.
4432 config += string(
4433 "],"
4434 "\"valid-lifetime\": 4000,"
4435 "\"rebind-timer\": 2000,"
4436 "\"renew-timer\": 1000,"
4437 "\"option-data\": [ {"
4438 " \"name\": \"dhcp-message\","
4439 " \"data\": \"ABCDEF0105\","
4440 " \"csv-format\": false"
4441 " },"
4442 " {"
4443 " \"name\": \"foo\","
4444 " \"space\": \"isc\","
4445 " \"data\": \"1234\""
4446 " } ],"
4447 "\"option-def\": [ {"
4448 " \"name\": \"foo\","
4449 " \"code\": 56,"
4450 " \"type\": \"uint32\","
4451 " \"space\": \"isc\""
4452 " } ],"
4453 "\"subnet4\": [ { "
4454 " \"id\": 1,"
4455 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
4456 " \"subnet\": \"192.0.2.0/24\""
4457 " } ]");
4458
4459 config += R"(,
4460 "multi-threading": {
4461 "enable-multi-threading": )" +
4462 string(multi_threading ? "true" : "false") + R"(
4463 })";
4464
4465 config += string("}");
4466
4467 return (config);
4468}
4469
4470// The goal of this test is to verify the configuration of hooks libraries if
4471// none are specified.
4472TEST_F(Dhcp4ParserTest, NoHooksLibraries)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("NoHooksLibraries") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_NoHooksLibraries_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_NoHooksLibraries_Test() = default;
~Dhcp4ParserTest_NoHooksLibraries_Test() override = default;
Dhcp4ParserTest_NoHooksLibraries_Test (const Dhcp4ParserTest_NoHooksLibraries_Test
&) = delete; Dhcp4ParserTest_NoHooksLibraries_Test &
operator=( const Dhcp4ParserTest_NoHooksLibraries_Test &
) = delete; Dhcp4ParserTest_NoHooksLibraries_Test (Dhcp4ParserTest_NoHooksLibraries_Test
&&) noexcept = delete; Dhcp4ParserTest_NoHooksLibraries_Test
& operator=( Dhcp4ParserTest_NoHooksLibraries_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_NoHooksLibraries_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "NoHooksLibraries", nullptr, nullptr, ::testing::internal::
CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4472), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4472), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4472), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_NoHooksLibraries_Test
>); void Dhcp4ParserTest_NoHooksLibraries_Test::TestBody()
{
4473 // Parse a configuration containing no names.
4474 string config = buildHooksLibrariesConfig();
4475 if (!executeConfiguration(config,
4476 "set configuration with no hooks libraries")) {
4477 FAIL()return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4477, "Failed") = ::testing::Message()
<< "Unable to execute configuration";
4478
4479 } else {
4480 // No libraries should be loaded at the end of the test.
4481 std::vector<std::string> libraries = HooksManager::getLibraryNames();
4482 EXPECT_TRUE(libraries.empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(libraries.empty())) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4482, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "libraries.empty()", "false", "true") .c_str()) = ::testing
::Message()
;
4483 }
4484}
4485
4486// Verify parsing fails with one library that will fail validation.
4487TEST_F(Dhcp4ParserTest, InvalidLibrary)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("InvalidLibrary") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_InvalidLibrary_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_InvalidLibrary_Test() = default; ~
Dhcp4ParserTest_InvalidLibrary_Test() override = default; Dhcp4ParserTest_InvalidLibrary_Test
(const Dhcp4ParserTest_InvalidLibrary_Test &) = delete; Dhcp4ParserTest_InvalidLibrary_Test
& operator=( const Dhcp4ParserTest_InvalidLibrary_Test &
) = delete; Dhcp4ParserTest_InvalidLibrary_Test (Dhcp4ParserTest_InvalidLibrary_Test
&&) noexcept = delete; Dhcp4ParserTest_InvalidLibrary_Test
& operator=( Dhcp4ParserTest_InvalidLibrary_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_InvalidLibrary_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "InvalidLibrary", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 4487
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4487), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4487), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_InvalidLibrary_Test
>); void Dhcp4ParserTest_InvalidLibrary_Test::TestBody()
{
4488 // Parse a configuration containing a failing library.
4489 string config = buildHooksLibrariesConfig({NOT_PRESENT_LIBRARY});
4490
4491 ConstElementPtr json;
4492 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_4492
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4492
; } } else gtest_label_testnothrow_4492 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4492, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4493
4494 ConstElementPtr status;
4495 ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_4495; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4495; } } else gtest_label_testnothrow_4495
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4495, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4496
4497 // The status object must not be NULL
4498 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4498, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4499
4500 // Returned value should not be 0
4501 comment_ = parseAnswer(rcode_, status);
4502 EXPECT_NE(0, rcode_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::CmpHelperNE("0", "rcode_", 0
, rcode_))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4502, gtest_ar.failure_message()) = ::testing::Message()
;
4503}
4504
4505// Verify the configuration of hooks libraries with two being specified.
4506TEST_F(Dhcp4ParserTest, LibrariesSpecified)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("LibrariesSpecified") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_LibrariesSpecified_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_LibrariesSpecified_Test() = default
; ~Dhcp4ParserTest_LibrariesSpecified_Test() override = default
; Dhcp4ParserTest_LibrariesSpecified_Test (const Dhcp4ParserTest_LibrariesSpecified_Test
&) = delete; Dhcp4ParserTest_LibrariesSpecified_Test &
operator=( const Dhcp4ParserTest_LibrariesSpecified_Test &
) = delete; Dhcp4ParserTest_LibrariesSpecified_Test (Dhcp4ParserTest_LibrariesSpecified_Test
&&) noexcept = delete; Dhcp4ParserTest_LibrariesSpecified_Test
& operator=( Dhcp4ParserTest_LibrariesSpecified_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_LibrariesSpecified_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "LibrariesSpecified", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4506), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4506), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4506), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_LibrariesSpecified_Test
>); void Dhcp4ParserTest_LibrariesSpecified_Test::TestBody
()
{
4507 setHooksTestPath();
4508
4509 // Marker files should not be present.
4510 EXPECT_FALSE(checkMarkerFileExists(LOAD_MARKER_FILE))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(checkMarkerFileExists
(LOAD_MARKER_FILE)))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4510, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(LOAD_MARKER_FILE)", "true", "false")
.c_str()) = ::testing::Message()
;
4511 EXPECT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(checkMarkerFileExists
(UNLOAD_MARKER_FILE)))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4511, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(UNLOAD_MARKER_FILE)", "true", "false"
) .c_str()) = ::testing::Message()
;
4512
4513 // Set up the configuration with two libraries and load them.
4514 // Disable multi-threading since one of the libraries is single-threaded.
4515 string config = buildHooksLibrariesConfig({CALLOUT_LIBRARY_1, CALLOUT_LIBRARY_2},
4516 /* multi_threading = */ false);
4517 ASSERT_TRUE(executeConfiguration(config,switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(executeConfiguration(
config, "load two valid libraries"))) ; else return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 4518
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "executeConfiguration(config, \"load two valid libraries\")"
, "false", "true") .c_str()) = ::testing::Message()
4518 "load two valid libraries"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(executeConfiguration(
config, "load two valid libraries"))) ; else return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 4518
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "executeConfiguration(config, \"load two valid libraries\")"
, "false", "true") .c_str()) = ::testing::Message()
;
4519
4520 // Expect two libraries to be loaded in the correct order (load marker file
4521 // is present, no unload marker file).
4522 std::vector<std::string> libraries = HooksManager::getLibraryNames();
4523 ASSERT_EQ(2U, libraries.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "libraries.size()"
, 2U, libraries.size()))) ; else return ::testing::internal::
AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4523, gtest_ar.failure_message()) = ::testing::Message()
;
4524 EXPECT_TRUE(checkMarkerFile(LOAD_MARKER_FILE, "12"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(checkMarkerFile(LOAD_MARKER_FILE
, "12"))) ; else ::testing::internal::AssertHelper(::testing::
TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4524, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFile(LOAD_MARKER_FILE, \"12\")", "false", "true"
) .c_str()) = ::testing::Message()
;
4525 EXPECT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(checkMarkerFileExists
(UNLOAD_MARKER_FILE)))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4525, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(UNLOAD_MARKER_FILE)", "true", "false"
) .c_str()) = ::testing::Message()
;
4526
4527 // Commit the changes so as we get the fresh configuration for the
4528 // second part of this test.
4529 CfgMgr::instance().commit();
4530
4531 // Unload the libraries. The load file should not have changed, but
4532 // the unload one should indicate the unload() functions have been run.
4533 config = buildHooksLibrariesConfig();
4534 ASSERT_TRUE(executeConfiguration(config, "unloading libraries"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(executeConfiguration(
config, "unloading libraries"))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4534, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "executeConfiguration(config, \"unloading libraries\")", "false"
, "true") .c_str()) = ::testing::Message()
;
4535 EXPECT_TRUE(checkMarkerFile(LOAD_MARKER_FILE, "12"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(checkMarkerFile(LOAD_MARKER_FILE
, "12"))) ; else ::testing::internal::AssertHelper(::testing::
TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4535, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFile(LOAD_MARKER_FILE, \"12\")", "false", "true"
) .c_str()) = ::testing::Message()
;
4536 EXPECT_TRUE(checkMarkerFile(UNLOAD_MARKER_FILE, "21"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(checkMarkerFile(UNLOAD_MARKER_FILE
, "21"))) ; else ::testing::internal::AssertHelper(::testing::
TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4536, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFile(UNLOAD_MARKER_FILE, \"21\")", "false", "true"
) .c_str()) = ::testing::Message()
;
4537
4538 // Expect the hooks system to say that none are loaded.
4539 libraries = HooksManager::getLibraryNames();
4540 EXPECT_TRUE(libraries.empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(libraries.empty())) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4540, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "libraries.empty()", "false", "true") .c_str()) = ::testing
::Message()
;
4541}
4542
4543// Verify the configuration of hooks libraries which are not compatible with
4544// multi threading is rejected.
4545TEST_F(Dhcp4ParserTest, IncompatibleLibrary2Specified)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("IncompatibleLibrary2Specified") >
1, "test_name must not be empty"); class Dhcp4ParserTest_IncompatibleLibrary2Specified_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_IncompatibleLibrary2Specified_Test
() = default; ~Dhcp4ParserTest_IncompatibleLibrary2Specified_Test
() override = default; Dhcp4ParserTest_IncompatibleLibrary2Specified_Test
(const Dhcp4ParserTest_IncompatibleLibrary2Specified_Test &
) = delete; Dhcp4ParserTest_IncompatibleLibrary2Specified_Test
& operator=( const Dhcp4ParserTest_IncompatibleLibrary2Specified_Test
&) = delete; Dhcp4ParserTest_IncompatibleLibrary2Specified_Test
(Dhcp4ParserTest_IncompatibleLibrary2Specified_Test &&
) noexcept = delete; Dhcp4ParserTest_IncompatibleLibrary2Specified_Test
& operator=( Dhcp4ParserTest_IncompatibleLibrary2Specified_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_IncompatibleLibrary2Specified_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "IncompatibleLibrary2Specified", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4545), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4545), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4545), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_IncompatibleLibrary2Specified_Test
>); void Dhcp4ParserTest_IncompatibleLibrary2Specified_Test
::TestBody()
{
4546 // Marker files should not be present.
4547 EXPECT_FALSE(checkMarkerFileExists(LOAD_MARKER_FILE))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(checkMarkerFileExists
(LOAD_MARKER_FILE)))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4547, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(LOAD_MARKER_FILE)", "true", "false")
.c_str()) = ::testing::Message()
;
4548 EXPECT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(checkMarkerFileExists
(UNLOAD_MARKER_FILE)))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4548, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(UNLOAD_MARKER_FILE)", "true", "false"
) .c_str()) = ::testing::Message()
;
4549
4550 std::vector<std::string> libraries;
4551 libraries.push_back(string(CALLOUT_LIBRARY_2));
4552
4553 // Set up the configuration with two libraries and load them.
4554 string config = buildHooksLibrariesConfig(libraries, true);
4555 ConstElementPtr json;
4556 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_4556
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4556
; } } else gtest_label_testnothrow_4556 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4556, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4557 ConstElementPtr status;
4558 ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_4558; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4558; } } else gtest_label_testnothrow_4558
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4558, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4559
4560 // The status object must not be NULL
4561 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4561, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4562
4563 // Returned value should not be 0
4564 comment_ = parseAnswer(rcode_, status);
4565 EXPECT_NE(0, rcode_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::CmpHelperNE("0", "rcode_", 0
, rcode_))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4565, gtest_ar.failure_message()) = ::testing::Message()
;
4566
4567 // Expect the library to be rejected by the server (no load marker file, no
4568 // unload marker file).
4569 EXPECT_FALSE(checkMarkerFileExists(LOAD_MARKER_FILE))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(checkMarkerFileExists
(LOAD_MARKER_FILE)))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4569, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(LOAD_MARKER_FILE)", "true", "false")
.c_str()) = ::testing::Message()
;
4570 EXPECT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(checkMarkerFileExists
(UNLOAD_MARKER_FILE)))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4570, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(UNLOAD_MARKER_FILE)", "true", "false"
) .c_str()) = ::testing::Message()
;
4571
4572 // Expect the hooks system to say that none are loaded.
4573 libraries = HooksManager::getLibraryNames();
4574 EXPECT_TRUE(libraries.empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(libraries.empty())) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4574, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "libraries.empty()", "false", "true") .c_str()) = ::testing
::Message()
;
4575}
4576
4577// Verify the configuration of hooks libraries which are not compatible with
4578// multi threading is rejected.
4579TEST_F(Dhcp4ParserTest, IncompatibleLibrary3Specified)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("IncompatibleLibrary3Specified") >
1, "test_name must not be empty"); class Dhcp4ParserTest_IncompatibleLibrary3Specified_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_IncompatibleLibrary3Specified_Test
() = default; ~Dhcp4ParserTest_IncompatibleLibrary3Specified_Test
() override = default; Dhcp4ParserTest_IncompatibleLibrary3Specified_Test
(const Dhcp4ParserTest_IncompatibleLibrary3Specified_Test &
) = delete; Dhcp4ParserTest_IncompatibleLibrary3Specified_Test
& operator=( const Dhcp4ParserTest_IncompatibleLibrary3Specified_Test
&) = delete; Dhcp4ParserTest_IncompatibleLibrary3Specified_Test
(Dhcp4ParserTest_IncompatibleLibrary3Specified_Test &&
) noexcept = delete; Dhcp4ParserTest_IncompatibleLibrary3Specified_Test
& operator=( Dhcp4ParserTest_IncompatibleLibrary3Specified_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_IncompatibleLibrary3Specified_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "IncompatibleLibrary3Specified", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4579), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4579), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4579), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_IncompatibleLibrary3Specified_Test
>); void Dhcp4ParserTest_IncompatibleLibrary3Specified_Test
::TestBody()
{
4580 // Marker files should not be present.
4581 EXPECT_FALSE(checkMarkerFileExists(LOAD_MARKER_FILE))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(checkMarkerFileExists
(LOAD_MARKER_FILE)))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4581, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(LOAD_MARKER_FILE)", "true", "false")
.c_str()) = ::testing::Message()
;
4582 EXPECT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(checkMarkerFileExists
(UNLOAD_MARKER_FILE)))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4582, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(UNLOAD_MARKER_FILE)", "true", "false"
) .c_str()) = ::testing::Message()
;
4583
4584 std::vector<std::string> libraries;
4585 libraries.push_back(string(CALLOUT_LIBRARY_3));
4586
4587 // Set up the configuration with two libraries and load them.
4588 string config = buildHooksLibrariesConfig(libraries, true);
4589 ConstElementPtr json;
4590 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_4590
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4590
; } } else gtest_label_testnothrow_4590 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4590, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4591 ConstElementPtr status;
4592 ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_4592; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4592; } } else gtest_label_testnothrow_4592
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4592, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4593
4594 // The status object must not be NULL
4595 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4595, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4596
4597 // Returned value should not be 0
4598 comment_ = parseAnswer(rcode_, status);
4599 EXPECT_NE(0, rcode_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::CmpHelperNE("0", "rcode_", 0
, rcode_))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4599, gtest_ar.failure_message()) = ::testing::Message()
;
4600
4601 // Expect the library to be rejected by the server (no load marker file, no
4602 // unload marker file).
4603 EXPECT_FALSE(checkMarkerFileExists(LOAD_MARKER_FILE))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(checkMarkerFileExists
(LOAD_MARKER_FILE)))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4603, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(LOAD_MARKER_FILE)", "true", "false")
.c_str()) = ::testing::Message()
;
4604 EXPECT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(checkMarkerFileExists
(UNLOAD_MARKER_FILE)))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4604, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(UNLOAD_MARKER_FILE)", "true", "false"
) .c_str()) = ::testing::Message()
;
4605
4606 // Expect the hooks system to say that none are loaded.
4607 libraries = HooksManager::getLibraryNames();
4608 EXPECT_TRUE(libraries.empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(libraries.empty())) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4608, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "libraries.empty()", "false", "true") .c_str()) = ::testing
::Message()
;
4609}
4610
4611// This test verifies that it is possible to select subset of interfaces
4612// on which server should listen.
4613TEST_F(Dhcp4ParserTest, selectedInterfaces)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("selectedInterfaces") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_selectedInterfaces_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_selectedInterfaces_Test() = default
; ~Dhcp4ParserTest_selectedInterfaces_Test() override = default
; Dhcp4ParserTest_selectedInterfaces_Test (const Dhcp4ParserTest_selectedInterfaces_Test
&) = delete; Dhcp4ParserTest_selectedInterfaces_Test &
operator=( const Dhcp4ParserTest_selectedInterfaces_Test &
) = delete; Dhcp4ParserTest_selectedInterfaces_Test (Dhcp4ParserTest_selectedInterfaces_Test
&&) noexcept = delete; Dhcp4ParserTest_selectedInterfaces_Test
& operator=( Dhcp4ParserTest_selectedInterfaces_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_selectedInterfaces_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "selectedInterfaces", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4613), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4613), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4613), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_selectedInterfaces_Test
>); void Dhcp4ParserTest_selectedInterfaces_Test::TestBody
()
{
4614 IfaceMgrTestConfig test_config(true);
4615
4616 // Make sure the config manager is clean and there is no hanging
4617 // interface configuration.
4618 ASSERT_FALSE(test_config.socketOpen("eth0", AF_INET))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(test_config.socketOpen
("eth0", 2)))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4618, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth0\", 2)", "true", "false") .c_str
()) = ::testing::Message()
;
4619 ASSERT_FALSE(test_config.socketOpen("eth1", AF_INET))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(test_config.socketOpen
("eth1", 2)))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4619, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth1\", 2)", "true", "false") .c_str
()) = ::testing::Message()
;
4620
4621 string config = "{ \"interfaces-config\": {"
4622 " \"interfaces\": [ \"eth0\", \"eth1\" ]"
4623 "},"
4624 "\"rebind-timer\": 2000, "
4625 "\"renew-timer\": 1000, "
4626 "\"valid-lifetime\": 4000 }";
4627
4628 ConstElementPtr json;
4629 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_4629
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4629
; } } else gtest_label_testnothrow_4629 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4629, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4630 extractConfig(config);
4631
4632 ConstElementPtr status;
4633 // Apply configuration.
4634 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_4634; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4634; } } else gtest_label_testnothrow_4634
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4634, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4635 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4635, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4636 // returned value must be 0 (configuration accepted)
4637 checkResult(status, 0);
4638
4639 CfgMgr::instance().getStagingCfg()->getCfgIface()->openSockets(AF_INET2, 10000);
4640
4641 // eth0 and eth1 were explicitly selected. eth2 was not.
4642 EXPECT_TRUE(test_config.socketOpen("eth0", AF_INET))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(test_config.socketOpen
("eth0", 2))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4642, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth0\", 2)", "false", "true") .c_str
()) = ::testing::Message()
;
4643 EXPECT_TRUE(test_config.socketOpen("eth1", AF_INET))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(test_config.socketOpen
("eth1", 2))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4643, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth1\", 2)", "false", "true") .c_str
()) = ::testing::Message()
;
4644}
4645
4646// This test verifies that it is possible to configure the server in such a way
4647// that it listens on all interfaces.
4648TEST_F(Dhcp4ParserTest, allInterfaces)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("allInterfaces") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_allInterfaces_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_allInterfaces_Test() = default; ~Dhcp4ParserTest_allInterfaces_Test
() override = default; Dhcp4ParserTest_allInterfaces_Test (const
Dhcp4ParserTest_allInterfaces_Test &) = delete; Dhcp4ParserTest_allInterfaces_Test
& operator=( const Dhcp4ParserTest_allInterfaces_Test &
) = delete; Dhcp4ParserTest_allInterfaces_Test (Dhcp4ParserTest_allInterfaces_Test
&&) noexcept = delete; Dhcp4ParserTest_allInterfaces_Test
& operator=( Dhcp4ParserTest_allInterfaces_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_allInterfaces_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "allInterfaces", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 4648
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4648), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4648), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_allInterfaces_Test
>); void Dhcp4ParserTest_allInterfaces_Test::TestBody()
{
4649 IfaceMgrTestConfig test_config(true);
4650
4651 // Make sure there is no old configuration.
4652 ASSERT_FALSE(test_config.socketOpen("eth0", AF_INET))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(test_config.socketOpen
("eth0", 2)))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4652, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth0\", 2)", "true", "false") .c_str
()) = ::testing::Message()
;
4653 ASSERT_FALSE(test_config.socketOpen("eth1", AF_INET))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(test_config.socketOpen
("eth1", 2)))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4653, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth1\", 2)", "true", "false") .c_str
()) = ::testing::Message()
;
4654
4655 // This configuration specifies two interfaces on which server should listen
4656 // but it also includes asterisk. The asterisk switches server into the
4657 // mode when it listens on all interfaces regardless of what interface names
4658 // were specified in the "interfaces" parameter.
4659 string config = "{ \"interfaces-config\": {"
4660 " \"interfaces\": [ \"eth0\", \"*\", \"eth1\" ]"
4661 "},"
4662 "\"rebind-timer\": 2000, "
4663 "\"renew-timer\": 1000, "
4664 "\"valid-lifetime\": 4000 }";
4665
4666 ConstElementPtr json;
4667 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_4667
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4667
; } } else gtest_label_testnothrow_4667 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4667, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4668 extractConfig(config);
4669
4670 ConstElementPtr status;
4671
4672 // Apply configuration.
4673 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_4673; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4673; } } else gtest_label_testnothrow_4673
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4673, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4674 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4674, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4675 checkResult(status, 0);
4676
4677 CfgMgr::instance().getStagingCfg()->getCfgIface()->openSockets(AF_INET2, 10000);
4678
4679 // All interfaces should be now active.
4680 ASSERT_TRUE(test_config.socketOpen("eth0", AF_INET))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(test_config.socketOpen
("eth0", 2))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4680, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth0\", 2)", "false", "true") .c_str
()) = ::testing::Message()
;
4681 ASSERT_TRUE(test_config.socketOpen("eth1", AF_INET))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(test_config.socketOpen
("eth1", 2))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4681, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth1\", 2)", "false", "true") .c_str
()) = ::testing::Message()
;
4682}
4683
4684// This test verifies that it is possible to select subset of interfaces
4685// and addresses.
4686TEST_F(Dhcp4ParserTest, selectedInterfacesAndAddresses)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("selectedInterfacesAndAddresses") >
1, "test_name must not be empty"); class Dhcp4ParserTest_selectedInterfacesAndAddresses_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_selectedInterfacesAndAddresses_Test
() = default; ~Dhcp4ParserTest_selectedInterfacesAndAddresses_Test
() override = default; Dhcp4ParserTest_selectedInterfacesAndAddresses_Test
(const Dhcp4ParserTest_selectedInterfacesAndAddresses_Test &
) = delete; Dhcp4ParserTest_selectedInterfacesAndAddresses_Test
& operator=( const Dhcp4ParserTest_selectedInterfacesAndAddresses_Test
&) = delete; Dhcp4ParserTest_selectedInterfacesAndAddresses_Test
(Dhcp4ParserTest_selectedInterfacesAndAddresses_Test &&
) noexcept = delete; Dhcp4ParserTest_selectedInterfacesAndAddresses_Test
& operator=( Dhcp4ParserTest_selectedInterfacesAndAddresses_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_selectedInterfacesAndAddresses_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "selectedInterfacesAndAddresses", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4686), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4686), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4686), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_selectedInterfacesAndAddresses_Test
>); void Dhcp4ParserTest_selectedInterfacesAndAddresses_Test
::TestBody()
{
4687 IfaceMgrTestConfig test_config(true);
4688
4689 ConstElementPtr x;
4690 string config = "{ \"interfaces-config\": {"
4691 " \"interfaces\": [ \"eth0/10.0.0.1\", \"eth1/192.0.2.3\" ]"
4692 "},"
4693 "\"rebind-timer\": 2000, "
4694 "\"renew-timer\": 1000, "
4695 "\"valid-lifetime\": 4000 }";
4696
4697 ConstElementPtr json;
4698 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_4698
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4698
; } } else gtest_label_testnothrow_4698 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4698, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4699
4700 ConstElementPtr status;
4701
4702 // Make sure the config manager is clean and there is no hanging
4703 // interface configuration.
4704 ASSERT_FALSE(test_config.socketOpen("eth0", "10.0.0.1"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(test_config.socketOpen
("eth0", "10.0.0.1")))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4704, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth0\", \"10.0.0.1\")", "true", "false"
) .c_str()) = ::testing::Message()
;
4705 ASSERT_FALSE(test_config.socketOpen("eth1", "192.0.2.3"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(test_config.socketOpen
("eth1", "192.0.2.3")))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4705, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth1\", \"192.0.2.3\")", "true", "false"
) .c_str()) = ::testing::Message()
;
4706 ASSERT_FALSE(test_config.socketOpen("eth1", "192.0.2.5"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(test_config.socketOpen
("eth1", "192.0.2.5")))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4706, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth1\", \"192.0.2.5\")", "true", "false"
) .c_str()) = ::testing::Message()
;
4707
4708 // Apply configuration.
4709 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_4709; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4709; } } else gtest_label_testnothrow_4709
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4709, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4710 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4710, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4711 checkResult(status, 0);
4712
4713 CfgMgr::instance().getStagingCfg()->getCfgIface()->openSockets(AF_INET2, 10000);
4714
4715 // An address on eth0 was selected
4716 EXPECT_TRUE(test_config.socketOpen("eth0", "10.0.0.1"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(test_config.socketOpen
("eth0", "10.0.0.1"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4716, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth0\", \"10.0.0.1\")", "false", "true"
) .c_str()) = ::testing::Message()
;
4717 // The 192.0.2.3 address on eth1 was selected.
4718 EXPECT_TRUE(test_config.socketOpen("eth1", "192.0.2.3"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(test_config.socketOpen
("eth1", "192.0.2.3"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4718, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth1\", \"192.0.2.3\")", "false",
"true") .c_str()) = ::testing::Message()
;
4719 // The 192.0.2.5 was not selected, thus the socket should not
4720 // be bound to this address.
4721 EXPECT_FALSE(test_config.socketOpen("eth1", "192.0.2.5"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(test_config.socketOpen
("eth1", "192.0.2.5")))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4721, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth1\", \"192.0.2.5\")", "true", "false"
) .c_str()) = ::testing::Message()
;
4722}
4723
4724// This test checks if it is possible to specify relay information
4725TEST_F(Dhcp4ParserTest, subnetRelayInfo)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("subnetRelayInfo") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_subnetRelayInfo_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_subnetRelayInfo_Test() = default; ~
Dhcp4ParserTest_subnetRelayInfo_Test() override = default; Dhcp4ParserTest_subnetRelayInfo_Test
(const Dhcp4ParserTest_subnetRelayInfo_Test &) = delete;
Dhcp4ParserTest_subnetRelayInfo_Test & operator=( const Dhcp4ParserTest_subnetRelayInfo_Test
&) = delete; Dhcp4ParserTest_subnetRelayInfo_Test (Dhcp4ParserTest_subnetRelayInfo_Test
&&) noexcept = delete; Dhcp4ParserTest_subnetRelayInfo_Test
& operator=( Dhcp4ParserTest_subnetRelayInfo_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_subnetRelayInfo_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "subnetRelayInfo", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 4725
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4725), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4725), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_subnetRelayInfo_Test
>); void Dhcp4ParserTest_subnetRelayInfo_Test::TestBody()
{
4726
4727 // A config with relay information.
4728 string config = "{ " + genIfaceConfig() + ","
4729 "\"rebind-timer\": 2000, "
4730 "\"renew-timer\": 1000, "
4731 "\"subnet4\": [ { "
4732 " \"id\": 1,"
4733 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
4734 " \"renew-timer\": 1, "
4735 " \"rebind-timer\": 2, "
4736 " \"valid-lifetime\": 4,"
4737 " \"relay\": { "
4738 " \"ip-addresses\": [ \"192.0.2.123\" ]"
4739 " },"
4740 " \"subnet\": \"192.0.2.0/24\" } ],"
4741 "\"valid-lifetime\": 4000 }";
4742
4743 ConstElementPtr json;
4744 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_4744
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4744
; } } else gtest_label_testnothrow_4744 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4744, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4745 extractConfig(config);
4746
4747 ConstElementPtr status;
4748 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_4748; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4748; } } else gtest_label_testnothrow_4748
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4748, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4749
4750 // returned value should be 0 (configuration success)
4751 checkResult(status, 0);
4752
4753 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
4754 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
4755 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4755, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
4756
4757 EXPECT_TRUE(subnet->hasRelays())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->hasRelays(
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4757, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->hasRelays()", "false", "true") .c_str()) = ::testing
::Message()
;
4758 EXPECT_TRUE(subnet->hasRelayAddress(IOAddress("192.0.2.123")))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->hasRelayAddress
(IOAddress("192.0.2.123")))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4758, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->hasRelayAddress(IOAddress(\"192.0.2.123\"))", "false"
, "true") .c_str()) = ::testing::Message()
;
4759}
4760
4761// This test checks if it is possible to specify a list of relays
4762TEST_F(Dhcp4ParserTest, subnetRelayInfoList)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("subnetRelayInfoList") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_subnetRelayInfoList_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_subnetRelayInfoList_Test() = default
; ~Dhcp4ParserTest_subnetRelayInfoList_Test() override = default
; Dhcp4ParserTest_subnetRelayInfoList_Test (const Dhcp4ParserTest_subnetRelayInfoList_Test
&) = delete; Dhcp4ParserTest_subnetRelayInfoList_Test &
operator=( const Dhcp4ParserTest_subnetRelayInfoList_Test &
) = delete; Dhcp4ParserTest_subnetRelayInfoList_Test (Dhcp4ParserTest_subnetRelayInfoList_Test
&&) noexcept = delete; Dhcp4ParserTest_subnetRelayInfoList_Test
& operator=( Dhcp4ParserTest_subnetRelayInfoList_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_subnetRelayInfoList_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "subnetRelayInfoList", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4762), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4762), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4762), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_subnetRelayInfoList_Test
>); void Dhcp4ParserTest_subnetRelayInfoList_Test::TestBody
()
{
4763 // A config with relay information.
4764 string config = "{ " + genIfaceConfig() + ","
4765 "\"rebind-timer\": 2000, "
4766 "\"renew-timer\": 1000, "
4767 "\"subnet4\": [ { "
4768 " \"id\": 1,"
4769 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
4770 " \"renew-timer\": 1, "
4771 " \"rebind-timer\": 2, "
4772 " \"valid-lifetime\": 4,"
4773 " \"relay\": { "
4774 " \"ip-addresses\": [ \"192.0.3.123\", \"192.0.3.124\" ]"
4775 " },"
4776 " \"subnet\": \"192.0.2.0/24\" } ],"
4777 "\"valid-lifetime\": 4000 }";
4778
4779 ConstElementPtr json;
4780 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_4780
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4780
; } } else gtest_label_testnothrow_4780 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4780, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4781 extractConfig(config);
4782
4783 ConstElementPtr status;
4784 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_4784; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4784; } } else gtest_label_testnothrow_4784
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4784, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4785
4786 // returned value should be 0 (configuration success)
4787 checkResult(status, 0);
4788
4789 SubnetSelector selector;
4790 selector.giaddr_ = IOAddress("192.0.2.200");
4791
4792 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
4793 getCfgSubnets4()->selectSubnet(selector);
4794 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4794, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
4795
4796 EXPECT_TRUE(subnet->hasRelays())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->hasRelays(
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4796, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->hasRelays()", "false", "true") .c_str()) = ::testing
::Message()
;
4797 EXPECT_TRUE(subnet->hasRelayAddress(IOAddress("192.0.3.123")))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->hasRelayAddress
(IOAddress("192.0.3.123")))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4797, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->hasRelayAddress(IOAddress(\"192.0.3.123\"))", "false"
, "true") .c_str()) = ::testing::Message()
;
4798 EXPECT_TRUE(subnet->hasRelayAddress(IOAddress("192.0.3.124")))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->hasRelayAddress
(IOAddress("192.0.3.124")))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4798, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->hasRelayAddress(IOAddress(\"192.0.3.124\"))", "false"
, "true") .c_str()) = ::testing::Message()
;
4799}
4800
4801// Goal of this test is to verify that multiple subnets can be configured
4802// with defined client classes.
4803TEST_F(Dhcp4ParserTest, classifySubnets)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("classifySubnets") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_classifySubnets_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_classifySubnets_Test() = default; ~
Dhcp4ParserTest_classifySubnets_Test() override = default; Dhcp4ParserTest_classifySubnets_Test
(const Dhcp4ParserTest_classifySubnets_Test &) = delete;
Dhcp4ParserTest_classifySubnets_Test & operator=( const Dhcp4ParserTest_classifySubnets_Test
&) = delete; Dhcp4ParserTest_classifySubnets_Test (Dhcp4ParserTest_classifySubnets_Test
&&) noexcept = delete; Dhcp4ParserTest_classifySubnets_Test
& operator=( Dhcp4ParserTest_classifySubnets_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_classifySubnets_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "classifySubnets", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 4803
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4803), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4803), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_classifySubnets_Test
>); void Dhcp4ParserTest_classifySubnets_Test::TestBody()
{
4804 ConstElementPtr x;
4805 string config = "{ " + genIfaceConfig() + ","
4806 "\"rebind-timer\": 2000, "
4807 "\"renew-timer\": 1000, "
4808 "\"subnet4\": [ { "
4809 " \"id\": 1,"
4810 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
4811 " \"subnet\": \"192.0.2.0/24\", "
4812 " \"client-class\": \"alpha\" "
4813 " },"
4814 " {"
4815 " \"id\": 2,"
4816 " \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
4817 " \"subnet\": \"192.0.3.0/24\", "
4818 " \"client-class\": \"beta\" "
4819 " },"
4820 " {"
4821 " \"id\": 3,"
4822 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
4823 " \"subnet\": \"192.0.4.0/24\", "
4824 " \"client-classes\": [ \"gamma\" ] "
4825 " },"
4826 " {"
4827 " \"id\": 4,"
4828 " \"pools\": [ { \"pool\": \"192.0.5.101 - 192.0.5.150\" } ],"
4829 " \"subnet\": \"192.0.5.0/24\" "
4830 " } ],"
4831 "\"valid-lifetime\": 4000 }";
4832
4833 ConstElementPtr json;
4834 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_4834
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4834
; } } else gtest_label_testnothrow_4834 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4834, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4835 extractConfig(config);
4836
4837 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_4837; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4837; } } else gtest_label_testnothrow_4837
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4837, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4838 checkResult(x, 0);
4839
4840 const Subnet4Collection* subnets =
4841 CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
4842 ASSERT_TRUE(subnets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnets)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4842, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
4843 ASSERT_EQ(4U, subnets->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("4U", "subnets->size()"
, 4U, subnets->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4843, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 4 subnets
4844
4845 // Let's check if client belonging to alpha class is supported in subnet[0]
4846 // and not supported in any other subnet (except subnet[3], which allows
4847 // everyone).
4848 ClientClasses classes;
4849 classes.insert("alpha");
4850 auto subnet0 = subnets->begin();
4851 auto subnet1 = std::next(subnet0);
4852 auto subnet2 = std::next(subnet1);
4853 auto subnet3 = std::next(subnet2);
4854 EXPECT_TRUE ((*subnet0)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult((*subnet0)->clientSupported
(classes))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4854, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet0)->clientSupported(classes)", "false", "true")
.c_str()) = ::testing::Message()
;
4855 EXPECT_FALSE((*subnet1)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!((*subnet1)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4855, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet1)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4856 EXPECT_FALSE((*subnet2)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!((*subnet2)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4856, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet2)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4857 EXPECT_TRUE ((*subnet3)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult((*subnet3)->clientSupported
(classes))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4857, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet3)->clientSupported(classes)", "false", "true")
.c_str()) = ::testing::Message()
;
4858
4859 // Let's check if client belonging to beta class is supported in subnet[1]
4860 // and not supported in any other subnet (except subnet[3], which allows
4861 // everyone).
4862 classes.clear();
4863 classes.insert("beta");
4864 EXPECT_FALSE((*subnet0)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!((*subnet0)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4864, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet0)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4865 EXPECT_TRUE ((*subnet1)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult((*subnet1)->clientSupported
(classes))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4865, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet1)->clientSupported(classes)", "false", "true")
.c_str()) = ::testing::Message()
;
4866 EXPECT_FALSE((*subnet2)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!((*subnet2)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4866, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet2)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4867 EXPECT_TRUE ((*subnet3)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult((*subnet3)->clientSupported
(classes))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4867, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet3)->clientSupported(classes)", "false", "true")
.c_str()) = ::testing::Message()
;
4868
4869 // Let's check if client belonging to gamma class is supported in subnet[2]
4870 // and not supported in any other subnet (except subnet[3], which allows
4871 // everyone).
4872 classes.clear();
4873 classes.insert("gamma");
4874 EXPECT_FALSE((*subnet0)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!((*subnet0)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4874, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet0)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4875 EXPECT_FALSE((*subnet1)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!((*subnet1)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4875, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet1)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4876 EXPECT_TRUE ((*subnet2)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult((*subnet2)->clientSupported
(classes))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4876, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet2)->clientSupported(classes)", "false", "true")
.c_str()) = ::testing::Message()
;
4877 EXPECT_TRUE ((*subnet3)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult((*subnet3)->clientSupported
(classes))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4877, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet3)->clientSupported(classes)", "false", "true")
.c_str()) = ::testing::Message()
;
4878
4879 // Let's check if client belonging to some other class (not mentioned in
4880 // the config) is supported only in subnet[3], which allows everyone.
4881 classes.clear();
4882 classes.insert("delta");
4883 EXPECT_FALSE((*subnet0)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!((*subnet0)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4883, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet0)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4884 EXPECT_FALSE((*subnet1)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!((*subnet1)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4884, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet1)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4885 EXPECT_FALSE((*subnet2)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!((*subnet2)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4885, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet2)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4886 EXPECT_TRUE ((*subnet3)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult((*subnet3)->clientSupported
(classes))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4886, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet3)->clientSupported(classes)", "false", "true")
.c_str()) = ::testing::Message()
;
4887
4888 // Finally, let's check class-less client. He should be allowed only in
4889 // the last subnet, which does not have any class restrictions.
4890 classes.clear();
4891 EXPECT_FALSE((*subnet0)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!((*subnet0)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4891, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet0)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4892 EXPECT_FALSE((*subnet1)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!((*subnet1)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4892, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet1)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4893 EXPECT_FALSE((*subnet2)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!((*subnet2)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4893, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet2)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4894 EXPECT_TRUE ((*subnet3)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult((*subnet3)->clientSupported
(classes))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4894, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet3)->clientSupported(classes)", "false", "true")
.c_str()) = ::testing::Message()
;
4895}
4896
4897// Goal of this test is to verify that multiple pools can be configured
4898// with defined client classes.
4899TEST_F(Dhcp4ParserTest, classifyPools)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("classifyPools") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_classifyPools_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_classifyPools_Test() = default; ~Dhcp4ParserTest_classifyPools_Test
() override = default; Dhcp4ParserTest_classifyPools_Test (const
Dhcp4ParserTest_classifyPools_Test &) = delete; Dhcp4ParserTest_classifyPools_Test
& operator=( const Dhcp4ParserTest_classifyPools_Test &
) = delete; Dhcp4ParserTest_classifyPools_Test (Dhcp4ParserTest_classifyPools_Test
&&) noexcept = delete; Dhcp4ParserTest_classifyPools_Test
& operator=( Dhcp4ParserTest_classifyPools_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_classifyPools_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "classifyPools", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 4899
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4899), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4899), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_classifyPools_Test
>); void Dhcp4ParserTest_classifyPools_Test::TestBody()
{
4900 ConstElementPtr x;
4901 string config = "{ " + genIfaceConfig() + ","
4902 "\"rebind-timer\": 2000, "
4903 "\"renew-timer\": 1000, "
4904 "\"subnet4\": [ { "
4905 " \"id\": 1,"
4906 " \"pools\": [ { "
4907 " \"pool\": \"192.0.2.1 - 192.0.2.100\", "
4908 " \"client-classes\": [ \"alpha\" ]"
4909 " },"
4910 " {"
4911 " \"pool\": \"192.0.3.101 - 192.0.3.150\", "
4912 " \"client-classes\": [ \"beta\" ] "
4913 " },"
4914 " {"
4915 " \"pool\": \"192.0.4.101 - 192.0.4.150\", "
4916 " \"client-classes\": [ \"gamma\" ] "
4917 " },"
4918 " {"
4919 " \"pool\": \"192.0.5.101 - 192.0.5.150\" "
4920 " } ],"
4921 " \"subnet\": \"192.0.0.0/16\" "
4922 " } ],"
4923 "\"valid-lifetime\": 4000 }";
4924
4925 ConstElementPtr json;
4926 ASSERT_NO_THROW(json = parseDHCP4(config, true))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config, true); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_4926
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4926
; } } else gtest_label_testnothrow_4926 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4926, ("Expected: " "json = parseDHCP4(config, true)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4927 extractConfig(config);
4928
4929 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_4929; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4929; } } else gtest_label_testnothrow_4929
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4929, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4930 checkResult(x, 0);
4931
4932 const Subnet4Collection* subnets =
4933 CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
4934 ASSERT_TRUE(subnets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnets)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4934, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
4935 ASSERT_EQ(1U, subnets->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "subnets->size()"
, 1U, subnets->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4935, gtest_ar.failure_message()) = ::testing::Message()
;
4936 const PoolCollection& pools = (*subnets->begin())->getPools(Lease::TYPE_V4);
4937 ASSERT_EQ(4U, pools.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("4U", "pools.size()"
, 4U, pools.size()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4937, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 4 pools
4938
4939 // Let's check if client belonging to alpha class is supported in pool[0]
4940 // and not supported in any other pool (except pool[3], which allows
4941 // everyone).
4942 ClientClasses classes;
4943 classes.insert("alpha");
4944 EXPECT_TRUE(pools.at(0)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pools.at(0)->clientSupported
(classes))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4944, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(0)->clientSupported(classes)", "false", "true"
) .c_str()) = ::testing::Message()
;
4945 EXPECT_FALSE(pools.at(1)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pools.at(1)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4945, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(1)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4946 EXPECT_FALSE(pools.at(2)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pools.at(2)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4946, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(2)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4947 EXPECT_TRUE(pools.at(3)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pools.at(3)->clientSupported
(classes))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4947, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(3)->clientSupported(classes)", "false", "true"
) .c_str()) = ::testing::Message()
;
4948
4949 // Let's check if client belonging to beta class is supported in pool[1]
4950 // and not supported in any other pool (except pool[3], which allows
4951 // everyone).
4952 classes.clear();
4953 classes.insert("beta");
4954 EXPECT_FALSE(pools.at(0)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pools.at(0)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4954, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(0)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4955 EXPECT_TRUE(pools.at(1)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pools.at(1)->clientSupported
(classes))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4955, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(1)->clientSupported(classes)", "false", "true"
) .c_str()) = ::testing::Message()
;
4956 EXPECT_FALSE(pools.at(2)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pools.at(2)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4956, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(2)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4957 EXPECT_TRUE(pools.at(3)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pools.at(3)->clientSupported
(classes))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4957, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(3)->clientSupported(classes)", "false", "true"
) .c_str()) = ::testing::Message()
;
4958
4959 // Let's check if client belonging to gamma class is supported in pool[2]
4960 // and not supported in any other pool (except pool[3], which allows
4961 // everyone).
4962 classes.clear();
4963 classes.insert("gamma");
4964 EXPECT_FALSE(pools.at(0)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pools.at(0)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4964, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(0)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4965 EXPECT_FALSE(pools.at(1)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pools.at(1)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4965, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(1)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4966 EXPECT_TRUE(pools.at(2)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pools.at(2)->clientSupported
(classes))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4966, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(2)->clientSupported(classes)", "false", "true"
) .c_str()) = ::testing::Message()
;
4967 EXPECT_TRUE(pools.at(3)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pools.at(3)->clientSupported
(classes))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4967, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(3)->clientSupported(classes)", "false", "true"
) .c_str()) = ::testing::Message()
;
4968
4969 // Let's check if client belonging to some other class (not mentioned in
4970 // the config) is supported only in pool[3], which allows everyone.
4971 classes.clear();
4972 classes.insert("delta");
4973 EXPECT_FALSE(pools.at(0)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pools.at(0)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4973, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(0)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4974 EXPECT_FALSE(pools.at(1)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pools.at(1)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4974, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(1)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4975 EXPECT_FALSE(pools.at(2)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pools.at(2)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4975, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(2)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4976 EXPECT_TRUE(pools.at(3)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pools.at(3)->clientSupported
(classes))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4976, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(3)->clientSupported(classes)", "false", "true"
) .c_str()) = ::testing::Message()
;
4977
4978 // Finally, let's check class-less client. He should be allowed only in
4979 // the last pool, which does not have any class restrictions.
4980 classes.clear();
4981 EXPECT_FALSE(pools.at(0)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pools.at(0)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4981, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(0)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4982 EXPECT_FALSE(pools.at(1)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pools.at(1)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4982, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(1)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4983 EXPECT_FALSE(pools.at(2)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pools.at(2)->clientSupported
(classes)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4983, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(2)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4984 EXPECT_TRUE(pools.at(3)->clientSupported(classes))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pools.at(3)->clientSupported
(classes))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4984, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(3)->clientSupported(classes)", "false", "true"
) .c_str()) = ::testing::Message()
;
4985}
4986
4987// This test verifies that valid d2CliengConfig works correctly.
4988TEST_F(Dhcp4ParserTest, d2ClientConfigValid)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("d2ClientConfigValid") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_d2ClientConfigValid_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_d2ClientConfigValid_Test() = default
; ~Dhcp4ParserTest_d2ClientConfigValid_Test() override = default
; Dhcp4ParserTest_d2ClientConfigValid_Test (const Dhcp4ParserTest_d2ClientConfigValid_Test
&) = delete; Dhcp4ParserTest_d2ClientConfigValid_Test &
operator=( const Dhcp4ParserTest_d2ClientConfigValid_Test &
) = delete; Dhcp4ParserTest_d2ClientConfigValid_Test (Dhcp4ParserTest_d2ClientConfigValid_Test
&&) noexcept = delete; Dhcp4ParserTest_d2ClientConfigValid_Test
& operator=( Dhcp4ParserTest_d2ClientConfigValid_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_d2ClientConfigValid_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "d2ClientConfigValid", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4988), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4988), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4988), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_d2ClientConfigValid_Test
>); void Dhcp4ParserTest_d2ClientConfigValid_Test::TestBody
()
{
4989 // Verify that the D2 configuration can be fetched and is set to disabled.
4990 D2ClientConfigPtr d2_client_config = CfgMgr::instance().getD2ClientConfig();
4991 EXPECT_FALSE(d2_client_config->getEnableUpdates())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(d2_client_config->
getEnableUpdates()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4991, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "d2_client_config->getEnableUpdates()", "true", "false")
.c_str()) = ::testing::Message()
;
4992
4993 // Verify that the convenience method agrees.
4994 ASSERT_FALSE(CfgMgr::instance().ddnsEnabled())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(CfgMgr::instance().
ddnsEnabled()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4994, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().ddnsEnabled()", "true", "false") .c_str
()) = ::testing::Message()
;
4995
4996 string config_str = "{ " + genIfaceConfig() + ","
4997 "\"rebind-timer\": 2000, "
4998 "\"renew-timer\": 1000, "
4999 "\"subnet4\": [ { "
5000 " \"id\": 1,"
5001 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5002 " \"subnet\": \"192.0.2.0/24\" } ],"
5003 " \"dhcp-ddns\" : {"
5004 " \"enable-updates\" : true, "
5005 " \"server-ip\" : \"192.168.2.1\", "
5006 " \"server-port\" : 777, "
5007 " \"sender-ip\" : \"192.168.2.2\", "
5008 " \"sender-port\" : 778, "
5009 " \"max-queue-size\" : 2048, "
5010 " \"ncr-protocol\" : \"UDP\", "
5011 " \"ncr-format\" : \"JSON\"}, "
5012 "\"valid-lifetime\": 4000 }";
5013
5014 // Convert the JSON string to configuration elements.
5015 ConstElementPtr config;
5016 ASSERT_NO_THROW(config = parseDHCP4(config_str, true))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
config = parseDHCP4(config_str, true); } else static_assert(
true, ""); } catch (std::exception const& e) { gtest_msg.
value = "it throws "; gtest_msg.value += ::testing::internal::
GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5016; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5016; } } else gtest_label_testnothrow_5016
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5016, ("Expected: " "config = parseDHCP4(config_str, true)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5017 extractConfig(config_str);
5018
5019 // Pass the configuration in for parsing.
5020 ConstElementPtr status;
5021 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, config); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5021; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5021; } } else gtest_label_testnothrow_5021
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5021, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, config)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5022
5023 // check if returned status is OK
5024 checkResult(status, 0);
5025
5026 // Verify that DHCP-DDNS updating is enabled.
5027 EXPECT_TRUE(CfgMgr::instance().ddnsEnabled())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(CfgMgr::instance().ddnsEnabled
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5027, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().ddnsEnabled()", "false", "true") .c_str
()) = ::testing::Message()
;
5028
5029 // Verify that the D2 configuration can be retrieved.
5030 d2_client_config = CfgMgr::instance().getD2ClientConfig();
5031 ASSERT_TRUE(d2_client_config)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(d2_client_config)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5031, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "d2_client_config", "false", "true") .c_str()) = ::testing::
Message()
;
5032
5033 // Verify that the configuration values are correct.
5034 EXPECT_TRUE(d2_client_config->getEnableUpdates())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(d2_client_config->
getEnableUpdates())) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5034, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "d2_client_config->getEnableUpdates()", "false", "true")
.c_str()) = ::testing::Message()
;
5035 EXPECT_EQ("192.168.2.1", d2_client_config->getServerIp().toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.168.2.1\""
, "d2_client_config->getServerIp().toText()", "192.168.2.1"
, d2_client_config->getServerIp().toText()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5035
, gtest_ar.failure_message()) = ::testing::Message()
;
5036 EXPECT_EQ(777U, d2_client_config->getServerPort())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("777U", "d2_client_config->getServerPort()"
, 777U, d2_client_config->getServerPort()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5036
, gtest_ar.failure_message()) = ::testing::Message()
;
5037 EXPECT_EQ("192.168.2.2", d2_client_config->getSenderIp().toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.168.2.2\""
, "d2_client_config->getSenderIp().toText()", "192.168.2.2"
, d2_client_config->getSenderIp().toText()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5037
, gtest_ar.failure_message()) = ::testing::Message()
;
5038 EXPECT_EQ(778U, d2_client_config->getSenderPort())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("778U", "d2_client_config->getSenderPort()"
, 778U, d2_client_config->getSenderPort()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5038
, gtest_ar.failure_message()) = ::testing::Message()
;
5039 EXPECT_EQ(2048U, d2_client_config->getMaxQueueSize())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2048U", "d2_client_config->getMaxQueueSize()"
, 2048U, d2_client_config->getMaxQueueSize()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5039
, gtest_ar.failure_message()) = ::testing::Message()
;
5040 EXPECT_EQ(dhcp_ddns::NCR_UDP, d2_client_config->getNcrProtocol())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("dhcp_ddns::NCR_UDP"
, "d2_client_config->getNcrProtocol()", dhcp_ddns::NCR_UDP
, d2_client_config->getNcrProtocol()))) ; else ::testing::
internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5040
, gtest_ar.failure_message()) = ::testing::Message()
;
5041 EXPECT_EQ(dhcp_ddns::FMT_JSON, d2_client_config->getNcrFormat())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("dhcp_ddns::FMT_JSON"
, "d2_client_config->getNcrFormat()", dhcp_ddns::FMT_JSON,
d2_client_config->getNcrFormat()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5041, gtest_ar.failure_message()) = ::testing::Message()
;
5042
5043 // ddns-send-updates should be global default
5044 checkGlobal("ddns-send-updates", true);
5045 checkGlobal("ddns-conflict-resolution-mode", "check-with-dhcid");
5046
5047 // The following, deprecated dhcp-ddns parameters,
5048 // should all have global default values.
5049 checkGlobal("ddns-override-no-update", false);
5050 checkGlobal("ddns-override-client-update", false);
5051 checkGlobal("ddns-replace-client-name", "never");
5052 checkGlobal("ddns-generated-prefix", "myhost");
5053 checkGlobal("ddns-qualifying-suffix", "");
5054}
5055
5056// This test checks the ability of the server to handle a configuration
5057// containing an invalid dhcp-ddns (D2ClientConfig) entry.
5058TEST_F(Dhcp4ParserTest, invalidD2ClientConfig)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("invalidD2ClientConfig") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_invalidD2ClientConfig_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_invalidD2ClientConfig_Test() = default
; ~Dhcp4ParserTest_invalidD2ClientConfig_Test() override = default
; Dhcp4ParserTest_invalidD2ClientConfig_Test (const Dhcp4ParserTest_invalidD2ClientConfig_Test
&) = delete; Dhcp4ParserTest_invalidD2ClientConfig_Test &
operator=( const Dhcp4ParserTest_invalidD2ClientConfig_Test &
) = delete; Dhcp4ParserTest_invalidD2ClientConfig_Test (Dhcp4ParserTest_invalidD2ClientConfig_Test
&&) noexcept = delete; Dhcp4ParserTest_invalidD2ClientConfig_Test
& operator=( Dhcp4ParserTest_invalidD2ClientConfig_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_invalidD2ClientConfig_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "invalidD2ClientConfig", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5058), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5058), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5058), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_invalidD2ClientConfig_Test
>); void Dhcp4ParserTest_invalidD2ClientConfig_Test::TestBody
()
{
5059 // Configuration string with an invalid D2 client config,
5060 // "server-ip" is invalid.
5061 string config_str = "{ " + genIfaceConfig() + ","
5062 "\"rebind-timer\": 2000, "
5063 "\"renew-timer\": 1000, "
5064 "\"ddns-override-no-update\" : true, "
5065 "\"ddns-override-client-update\" : true, "
5066 "\"ddns-replace-client-name\" : \"when-present\", "
5067 "\"ddns-generated-prefix\" : \"test.prefix\", "
5068 "\"ddns-qualifying-suffix\" : \"test.suffix.\", "
5069 "\"subnet4\": [ { "
5070 " \"id\": 1,"
5071 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5072 " \"subnet\": \"192.0.2.0/24\" } ],"
5073 " \"dhcp-ddns\" : {"
5074 " \"enable-updates\" : true, "
5075 " \"server-ip\" : \"bogus-value\", "
5076 " \"server-port\" : 5301, "
5077 " \"ncr-protocol\" : \"UDP\", "
5078 " \"ncr-format\" : \"JSON\"},"
5079 "\"valid-lifetime\": 4000 }";
5080
5081 // Convert the JSON string to configuration elements.
5082 ConstElementPtr config;
5083 ASSERT_NO_THROW(config = parseDHCP4(config_str))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
config = parseDHCP4(config_str); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5083
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5083
; } } else gtest_label_testnothrow_5083 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5083, ("Expected: " "config = parseDHCP4(config_str)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5084
5085 // Configuration should not throw, but should fail.
5086 ConstElementPtr status;
5087 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, config); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5087; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5087; } } else gtest_label_testnothrow_5087
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5087, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, config)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5088
5089 // check if returned status is failed.
5090 checkResult(status, CONTROL_RESULT_ERROR);
5091 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5091, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
5092
5093 // Verify that the D2 configuration can be fetched and is set to disabled.
5094 D2ClientConfigPtr d2_client_config = CfgMgr::instance().getD2ClientConfig();
5095 EXPECT_FALSE(d2_client_config->getEnableUpdates())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(d2_client_config->
getEnableUpdates()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5095, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "d2_client_config->getEnableUpdates()", "true", "false")
.c_str()) = ::testing::Message()
;
5096
5097 // Verify that the convenience method agrees.
5098 ASSERT_FALSE(CfgMgr::instance().ddnsEnabled())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(CfgMgr::instance().
ddnsEnabled()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5098, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().ddnsEnabled()", "true", "false") .c_str
()) = ::testing::Message()
;
5099}
5100// This test verifies that the host reservations can be specified for
5101// respective IPv4 subnets.
5102TEST_F(Dhcp4ParserTest, reservations)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("reservations") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_reservations_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_reservations_Test() = default; ~Dhcp4ParserTest_reservations_Test
() override = default; Dhcp4ParserTest_reservations_Test (const
Dhcp4ParserTest_reservations_Test &) = delete; Dhcp4ParserTest_reservations_Test
& operator=( const Dhcp4ParserTest_reservations_Test &
) = delete; Dhcp4ParserTest_reservations_Test (Dhcp4ParserTest_reservations_Test
&&) noexcept = delete; Dhcp4ParserTest_reservations_Test
& operator=( Dhcp4ParserTest_reservations_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_reservations_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "reservations", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5102
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5102), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5102), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_reservations_Test
>); void Dhcp4ParserTest_reservations_Test::TestBody()
{
5103 ConstElementPtr x;
5104 string config = "{ " + genIfaceConfig() + ","
5105 "\"rebind-timer\": 2000, "
5106 "\"renew-timer\": 1000, "
5107 "\"subnet4\": [ "
5108 " { "
5109 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5110 " \"subnet\": \"192.0.2.0/24\", "
5111 " \"id\": 123,"
5112 " \"reservations\": ["
5113 " ]"
5114 " },"
5115 " {"
5116 " \"reservations\": ["
5117 " {"
5118 " \"duid\": \"01:02:03:04:05:06:07:08:09:0A\","
5119 " \"ip-address\": \"192.0.3.112\","
5120 " \"hostname\": \"\","
5121 " \"option-data\": ["
5122 " {"
5123 " \"name\": \"name-servers\","
5124 " \"data\": \"192.0.3.15\""
5125 " },"
5126 " {"
5127 " \"name\": \"default-ip-ttl\","
5128 " \"data\": \"32\""
5129 " }"
5130 " ]"
5131 " },"
5132 " {"
5133 " \"hw-address\": \"01:02:03:04:05:06\","
5134 " \"ip-address\": \"192.0.3.120\","
5135 " \"hostname\": \"\","
5136 " \"option-data\": ["
5137 " {"
5138 " \"name\": \"name-servers\","
5139 " \"data\": \"192.0.3.95\""
5140 " },"
5141 " {"
5142 " \"name\": \"default-ip-ttl\","
5143 " \"data\": \"11\""
5144 " }"
5145 " ]"
5146 " }"
5147 " ],"
5148 " \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
5149 " \"subnet\": \"192.0.3.0/24\", "
5150 " \"id\": 234"
5151 " },"
5152 " {"
5153 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
5154 " \"subnet\": \"192.0.4.0/24\","
5155 " \"id\": 542,"
5156 " \"reservations\": ["
5157 " {"
5158 " \"duid\": \"0A:09:08:07:06:05:04:03:02:01\","
5159 " \"ip-address\": \"192.0.4.101\","
5160 " \"hostname\": \"\","
5161 " \"option-data\": ["
5162 " {"
5163 " \"name\": \"name-servers\","
5164 " \"data\": \"192.0.4.11\""
5165 " },"
5166 " {"
5167 " \"name\": \"default-ip-ttl\","
5168 " \"data\": \"95\""
5169 " }"
5170 " ]"
5171 " },"
5172 " {"
5173 " \"circuit-id\": \"060504030201\","
5174 " \"ip-address\": \"192.0.4.102\","
5175 " \"hostname\": \"\""
5176 " },"
5177 " {"
5178 " \"client-id\": \"05:01:02:03:04:05:06\","
5179 " \"ip-address\": \"192.0.4.103\","
5180 " \"hostname\": \"\""
5181 " }"
5182 " ]"
5183 " } "
5184 "], "
5185 "\"valid-lifetime\": 4000 }";
5186
5187 ConstElementPtr json;
5188 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5188
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5188
; } } else gtest_label_testnothrow_5188 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5188, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5189 extractConfig(config);
5190
5191 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5191; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5191; } } else gtest_label_testnothrow_5191
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5191, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5192 checkResult(x, 0);
5193
5194 // Make sure all subnets have been successfully configured. There is no
5195 // need to sanity check the subnet properties because it should have
5196 // been already tested by other tests.
5197 const Subnet4Collection* subnets =
5198 CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
5199 ASSERT_TRUE(subnets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnets)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5199, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
5200 ASSERT_EQ(3U, subnets->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("3U", "subnets->size()"
, 3U, subnets->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5200, gtest_ar.failure_message()) = ::testing::Message()
;
5201
5202 // Hosts configuration must be available.
5203 CfgHostsPtr hosts_cfg = CfgMgr::instance().getStagingCfg()->getCfgHosts();
5204 ASSERT_TRUE(hosts_cfg)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(hosts_cfg)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5204, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg", "false", "true") .c_str()) = ::testing::Message
()
;
5205
5206 // Let's create an object holding hardware address of the host having
5207 // a reservation in the subnet having id of 234. For simplicity the
5208 // address is a collection of numbers from 1 to 6.
5209 std::vector<uint8_t> hwaddr;
5210 for (unsigned int i = 1; i < 7; ++i) {
5211 hwaddr.push_back(static_cast<uint8_t>(i));
5212 }
5213 // Retrieve the reservation and sanity check the address reserved.
5214 ConstHostPtr host = hosts_cfg->get4(234, Host::IDENT_HWADDR,
5215 &hwaddr[0], hwaddr.size());
5216 ASSERT_TRUE(host)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(host)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5216
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
5217 EXPECT_EQ("192.0.3.120", host->getIPv4Reservation().toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.0.3.120\""
, "host->getIPv4Reservation().toText()", "192.0.3.120", host
->getIPv4Reservation().toText()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5217, gtest_ar.failure_message()) = ::testing::Message()
;
5218 // This reservation should be solely assigned to the subnet 234,
5219 // and not to other two.
5220 EXPECT_FALSE(hosts_cfg->get4(123, Host::IDENT_HWADDR,switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
123, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5221, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())"
, "true", "false") .c_str()) = ::testing::Message()
5221 &hwaddr[0], hwaddr.size()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
123, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5221, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
5222 EXPECT_FALSE(hosts_cfg->get4(542, Host::IDENT_HWADDR,switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
542, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5223, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(542, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())"
, "true", "false") .c_str()) = ::testing::Message()
5223 &hwaddr[0], hwaddr.size()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
542, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5223, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(542, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
5224 // Check that options are assigned correctly.
5225 Option4AddrLstPtr opt_dns =
5226 retrieveOption<Option4AddrLstPtr>(*host, DHO_NAME_SERVERS);
5227 ASSERT_TRUE(opt_dns)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(opt_dns)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5227, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_dns", "false", "true") .c_str()) = ::testing::Message(
)
;
5228 Option4AddrLst::AddressContainer dns_addrs = opt_dns->getAddresses();
5229 ASSERT_EQ(1U, dns_addrs.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "dns_addrs.size()"
, 1U, dns_addrs.size()))) ; else return ::testing::internal::
AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5229, gtest_ar.failure_message()) = ::testing::Message()
;
5230 EXPECT_EQ("192.0.3.95", dns_addrs[0].toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.0.3.95\""
, "dns_addrs[0].toText()", "192.0.3.95", dns_addrs[0].toText(
)))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5230, gtest_ar.failure_message()) = ::testing::Message()
;
5231 OptionUint8Ptr opt_ttl =
5232 retrieveOption<OptionUint8Ptr>(*host, DHO_DEFAULT_IP_TTL);
5233 ASSERT_TRUE(opt_ttl)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(opt_ttl)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5233, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_ttl", "false", "true") .c_str()) = ::testing::Message(
)
;
5234 EXPECT_EQ(11, static_cast<int>(opt_ttl->getValue()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("11", "static_cast<int>(opt_ttl->getValue())"
, 11, static_cast<int>(opt_ttl->getValue())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5234, gtest_ar.failure_message()) = ::testing::Message()
;
5235
5236 // Do the same test for the DUID based reservation.
5237 std::vector<uint8_t> duid;
5238 for (unsigned int i = 1; i < 0xb; ++i) {
5239 duid.push_back(static_cast<uint8_t>(i));
5240 }
5241 host = hosts_cfg->get4(234, Host::IDENT_DUID, &duid[0], duid.size());
5242 ASSERT_TRUE(host)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(host)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5242
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
5243 EXPECT_EQ("192.0.3.112", host->getIPv4Reservation().toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.0.3.112\""
, "host->getIPv4Reservation().toText()", "192.0.3.112", host
->getIPv4Reservation().toText()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5243, gtest_ar.failure_message()) = ::testing::Message()
;
5244 EXPECT_FALSE(hosts_cfg->get4(123, Host::IDENT_DUID, &duid[0], duid.size()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
123, Host::IDENT_DUID, &duid[0], duid.size())))) ; else ::
testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5244
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_DUID, &duid[0], duid.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
5245 EXPECT_FALSE(hosts_cfg->get4(542, Host::IDENT_DUID, &duid[0], duid.size()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
542, Host::IDENT_DUID, &duid[0], duid.size())))) ; else ::
testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5245
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(542, Host::IDENT_DUID, &duid[0], duid.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
5246 // Check that options are assigned correctly.
5247 opt_dns = retrieveOption<Option4AddrLstPtr>(*host, DHO_NAME_SERVERS);
5248 ASSERT_TRUE(opt_dns)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(opt_dns)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5248, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_dns", "false", "true") .c_str()) = ::testing::Message(
)
;
5249 dns_addrs = opt_dns->getAddresses();
5250 ASSERT_EQ(1U, dns_addrs.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "dns_addrs.size()"
, 1U, dns_addrs.size()))) ; else return ::testing::internal::
AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5250, gtest_ar.failure_message()) = ::testing::Message()
;
5251 EXPECT_EQ("192.0.3.15", dns_addrs[0].toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.0.3.15\""
, "dns_addrs[0].toText()", "192.0.3.15", dns_addrs[0].toText(
)))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5251, gtest_ar.failure_message()) = ::testing::Message()
;
5252 opt_ttl = retrieveOption<OptionUint8Ptr>(*host, DHO_DEFAULT_IP_TTL);
5253 ASSERT_TRUE(opt_ttl)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(opt_ttl)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5253, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_ttl", "false", "true") .c_str()) = ::testing::Message(
)
;
5254 EXPECT_EQ(32, static_cast<int>(opt_ttl->getValue()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("32", "static_cast<int>(opt_ttl->getValue())"
, 32, static_cast<int>(opt_ttl->getValue())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5254, gtest_ar.failure_message()) = ::testing::Message()
;
5255
5256 // The circuit-id used for one of the reservations in the subnet 542
5257 // consists of numbers from 6 to 1. So, let's just reverse the order
5258 // of the address from the previous test.
5259 std::vector<uint8_t> circuit_id(hwaddr.rbegin(), hwaddr.rend());
5260 host = hosts_cfg->get4(542, Host::IDENT_CIRCUIT_ID, &circuit_id[0],
5261 circuit_id.size());
5262 EXPECT_TRUE(host)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(host)) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5262
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
5263 EXPECT_EQ("192.0.4.102", host->getIPv4Reservation().toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.0.4.102\""
, "host->getIPv4Reservation().toText()", "192.0.4.102", host
->getIPv4Reservation().toText()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5263, gtest_ar.failure_message()) = ::testing::Message()
;
5264
5265 // This reservation must not belong to other subnets.
5266 EXPECT_FALSE(hosts_cfg->get4(123, Host::IDENT_CIRCUIT_ID,switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
123, Host::IDENT_CIRCUIT_ID, &circuit_id[0], circuit_id.size
())))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5267, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_CIRCUIT_ID, &circuit_id[0], circuit_id.size())"
, "true", "false") .c_str()) = ::testing::Message()
5267 &circuit_id[0], circuit_id.size()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
123, Host::IDENT_CIRCUIT_ID, &circuit_id[0], circuit_id.size
())))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5267, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_CIRCUIT_ID, &circuit_id[0], circuit_id.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
5268 EXPECT_FALSE(hosts_cfg->get4(234, Host::IDENT_CIRCUIT_ID,switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
234, Host::IDENT_CIRCUIT_ID, &circuit_id[0], circuit_id.size
())))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5269, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(234, Host::IDENT_CIRCUIT_ID, &circuit_id[0], circuit_id.size())"
, "true", "false") .c_str()) = ::testing::Message()
5269 &circuit_id[0], circuit_id.size()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
234, Host::IDENT_CIRCUIT_ID, &circuit_id[0], circuit_id.size
())))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5269, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(234, Host::IDENT_CIRCUIT_ID, &circuit_id[0], circuit_id.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
5270
5271 // Repeat the test for the DUID based reservation in this subnet.
5272 std::vector<uint8_t> duid_r(duid.rbegin(), duid.rend());
5273 host = hosts_cfg->get4(542, Host::IDENT_DUID, &duid_r[0], duid_r.size());
5274 ASSERT_TRUE(host)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(host)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5274
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
5275 EXPECT_EQ("192.0.4.101", host->getIPv4Reservation().toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.0.4.101\""
, "host->getIPv4Reservation().toText()", "192.0.4.101", host
->getIPv4Reservation().toText()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5275, gtest_ar.failure_message()) = ::testing::Message()
;
5276
5277 EXPECT_FALSE(hosts_cfg->get4(123, Host::IDENT_DUID,switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
123, Host::IDENT_DUID, &duid_r[0], duid_r.size())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5278, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_DUID, &duid_r[0], duid_r.size())"
, "true", "false") .c_str()) = ::testing::Message()
5278 &duid_r[0], duid_r.size()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
123, Host::IDENT_DUID, &duid_r[0], duid_r.size())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5278, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_DUID, &duid_r[0], duid_r.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
5279 EXPECT_FALSE(hosts_cfg->get4(234, Host::IDENT_DUID,switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
234, Host::IDENT_DUID, &duid_r[0], duid_r.size())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5280, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(234, Host::IDENT_DUID, &duid_r[0], duid_r.size())"
, "true", "false") .c_str()) = ::testing::Message()
5280 &duid_r[0], duid_r.size()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
234, Host::IDENT_DUID, &duid_r[0], duid_r.size())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5280, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(234, Host::IDENT_DUID, &duid_r[0], duid_r.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
5281 // Check that options are assigned correctly.
5282 opt_dns = retrieveOption<Option4AddrLstPtr>(*host, DHO_NAME_SERVERS);
5283 ASSERT_TRUE(opt_dns)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(opt_dns)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5283, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_dns", "false", "true") .c_str()) = ::testing::Message(
)
;
5284 dns_addrs = opt_dns->getAddresses();
5285 ASSERT_EQ(1U, dns_addrs.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "dns_addrs.size()"
, 1U, dns_addrs.size()))) ; else return ::testing::internal::
AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5285, gtest_ar.failure_message()) = ::testing::Message()
;
5286 EXPECT_EQ("192.0.4.11", dns_addrs[0].toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.0.4.11\""
, "dns_addrs[0].toText()", "192.0.4.11", dns_addrs[0].toText(
)))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5286, gtest_ar.failure_message()) = ::testing::Message()
;
5287 opt_ttl = retrieveOption<OptionUint8Ptr>(*host, DHO_DEFAULT_IP_TTL);
5288 ASSERT_TRUE(opt_ttl)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(opt_ttl)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5288, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_ttl", "false", "true") .c_str()) = ::testing::Message(
)
;
5289 EXPECT_EQ(95, static_cast<int>(opt_ttl->getValue()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("95", "static_cast<int>(opt_ttl->getValue())"
, 95, static_cast<int>(opt_ttl->getValue())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5289, gtest_ar.failure_message()) = ::testing::Message()
;
5290
5291 // Check that we can find reservation using client identifier.
5292 ClientIdPtr client_id = ClientId::fromText("05:01:02:03:04:05:06");
5293 host = hosts_cfg->get4(542, Host::IDENT_CLIENT_ID, &client_id->getClientId()[0],
5294 client_id->getClientId().size());
5295 ASSERT_TRUE(host)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(host)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5295
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
5296 EXPECT_EQ("192.0.4.103", host->getIPv4Reservation().toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.0.4.103\""
, "host->getIPv4Reservation().toText()", "192.0.4.103", host
->getIPv4Reservation().toText()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5296, gtest_ar.failure_message()) = ::testing::Message()
;
5297
5298 // But this reservation should not be returned for other subnet.
5299 host = hosts_cfg->get4(234, Host::IDENT_CLIENT_ID, &client_id->getClientId()[0],
5300 client_id->getClientId().size());
5301 EXPECT_FALSE(host)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(host))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5301
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "true", "false") .c_str()) = ::testing::Message()
;
5302}
5303
5304// This test checks that it is possible to configure option data for a
5305// host using a user defined option format.
5306TEST_F(Dhcp4ParserTest, reservationWithOptionDefinition)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("reservationWithOptionDefinition") >
1, "test_name must not be empty"); class Dhcp4ParserTest_reservationWithOptionDefinition_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_reservationWithOptionDefinition_Test
() = default; ~Dhcp4ParserTest_reservationWithOptionDefinition_Test
() override = default; Dhcp4ParserTest_reservationWithOptionDefinition_Test
(const Dhcp4ParserTest_reservationWithOptionDefinition_Test &
) = delete; Dhcp4ParserTest_reservationWithOptionDefinition_Test
& operator=( const Dhcp4ParserTest_reservationWithOptionDefinition_Test
&) = delete; Dhcp4ParserTest_reservationWithOptionDefinition_Test
(Dhcp4ParserTest_reservationWithOptionDefinition_Test &&
) noexcept = delete; Dhcp4ParserTest_reservationWithOptionDefinition_Test
& operator=( Dhcp4ParserTest_reservationWithOptionDefinition_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_reservationWithOptionDefinition_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "reservationWithOptionDefinition", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5306), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5306), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5306), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_reservationWithOptionDefinition_Test
>); void Dhcp4ParserTest_reservationWithOptionDefinition_Test
::TestBody()
{
5307 ConstElementPtr x;
5308 // The following configuration contains host declaration in which
5309 // a non-standard option is used. This option has option definition
5310 // specified in the configuration.
5311 string config = "{ " + genIfaceConfig() + ","
5312 "\"rebind-timer\": 2000, "
5313 "\"renew-timer\": 1000, "
5314 "\"option-def\": [ {"
5315 " \"name\": \"foo\","
5316 " \"code\": 100,"
5317 " \"type\": \"uint32\","
5318 " \"space\": \"isc\""
5319 "} ],"
5320 "\"subnet4\": [ "
5321 " {"
5322 " \"reservations\": ["
5323 " {"
5324 " \"duid\": \"01:02:03:04:05:06:07:08:09:0A\","
5325 " \"ip-address\": \"192.0.3.112\","
5326 " \"option-data\": ["
5327 " {"
5328 " \"name\": \"foo\","
5329 " \"data\": \"123\","
5330 " \"space\": \"isc\""
5331 " }"
5332 " ]"
5333 " }"
5334 " ],"
5335 " \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
5336 " \"subnet\": \"192.0.3.0/24\", "
5337 " \"id\": 234"
5338 " }"
5339 "],"
5340 "\"valid-lifetime\": 4000 }";
5341
5342 ConstElementPtr json;
5343 ASSERT_NO_THROW(json = parseDHCP4(config, true))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config, true); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5343
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5343
; } } else gtest_label_testnothrow_5343 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5343, ("Expected: " "json = parseDHCP4(config, true)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5344 extractConfig(config);
5345
5346 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5346; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5346; } } else gtest_label_testnothrow_5346
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5346, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5347 checkResult(x, 0);
5348
5349 // Hosts configuration must be available.
5350 CfgHostsPtr hosts_cfg = CfgMgr::instance().getStagingCfg()->getCfgHosts();
5351 ASSERT_TRUE(hosts_cfg)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(hosts_cfg)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5351, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg", "false", "true") .c_str()) = ::testing::Message
()
;
5352
5353 // Let's create an object holding DUID of the host. For simplicity the
5354 // address is a collection of numbers from 1 to A.
5355 std::vector<uint8_t> duid;
5356 for (unsigned int i = 1; i < 0xB; ++i) {
5357 duid.push_back(static_cast<uint8_t>(i));
5358 }
5359 // Retrieve the reservation and sanity check the address reserved.
5360 ConstHostPtr host = hosts_cfg->get4(234, Host::IDENT_DUID,
5361 &duid[0], duid.size());
5362 ASSERT_TRUE(host)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(host)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5362
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
5363 EXPECT_EQ("192.0.3.112", host->getIPv4Reservation().toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.0.3.112\""
, "host->getIPv4Reservation().toText()", "192.0.3.112", host
->getIPv4Reservation().toText()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5363, gtest_ar.failure_message()) = ::testing::Message()
;
5364
5365 // Check if the option has been parsed.
5366 OptionUint32Ptr opt_foo = retrieveOption<OptionUint32Ptr>(*host, "isc",
5367 100);
5368 ASSERT_TRUE(opt_foo)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(opt_foo)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5368, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_foo", "false", "true") .c_str()) = ::testing::Message(
)
;
5369 EXPECT_EQ(100U, opt_foo->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("100U", "opt_foo->getType()"
, 100U, opt_foo->getType()))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5369, gtest_ar.failure_message()) = ::testing::Message()
;
5370 EXPECT_EQ(123U, opt_foo->getValue())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("123U", "opt_foo->getValue()"
, 123U, opt_foo->getValue()))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5370, gtest_ar.failure_message()) = ::testing::Message()
;
5371}
5372
5373// This test verifies that the bogus host reservation would trigger a
5374// server configuration error.
5375TEST_F(Dhcp4ParserTest, reservationBogus)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("reservationBogus") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_reservationBogus_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_reservationBogus_Test() = default;
~Dhcp4ParserTest_reservationBogus_Test() override = default;
Dhcp4ParserTest_reservationBogus_Test (const Dhcp4ParserTest_reservationBogus_Test
&) = delete; Dhcp4ParserTest_reservationBogus_Test &
operator=( const Dhcp4ParserTest_reservationBogus_Test &
) = delete; Dhcp4ParserTest_reservationBogus_Test (Dhcp4ParserTest_reservationBogus_Test
&&) noexcept = delete; Dhcp4ParserTest_reservationBogus_Test
& operator=( Dhcp4ParserTest_reservationBogus_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_reservationBogus_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "reservationBogus", nullptr, nullptr, ::testing::internal::
CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5375), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5375), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5375), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_reservationBogus_Test
>); void Dhcp4ParserTest_reservationBogus_Test::TestBody()
{
5376 // Case 1: misspelled hw-address parameter.
5377 ConstElementPtr x;
5378 string config = "{ " + genIfaceConfig() + ","
5379 "\"rebind-timer\": 2000, "
5380 "\"renew-timer\": 1000, "
5381 "\"subnet4\": [ "
5382 " { "
5383 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
5384 " \"subnet\": \"192.0.4.0/24\","
5385 " \"id\": 542,"
5386 " \"reservations\": ["
5387 " {"
5388 " \"hw-addre\": \"06:05:04:03:02:01\","
5389 " \"ip-address\": \"192.0.4.102\","
5390 " \"hostname\": \"\""
5391 " }"
5392 " ]"
5393 " } "
5394 "], "
5395 "\"valid-lifetime\": 4000 }";
5396
5397 ConstElementPtr json;
5398 ASSERT_NO_THROW(json = parseJSON(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseJSON(config); } else static_assert(true, ""); } catch
(std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5398
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5398
; } } else gtest_label_testnothrow_5398 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5398, ("Expected: " "json = parseJSON(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5399
5400 CfgMgr::instance().clear();
5401
5402 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5402; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5402; } } else gtest_label_testnothrow_5402
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5402, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5403 checkResult(x, CONTROL_RESULT_ERROR);
5404
5405 EXPECT_THROW(parseDHCP4(config), Dhcp4ParseError)switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { bool gtest_caught_expected = false; try { if (
::testing::internal::AlwaysTrue()) { parseDHCP4(config); } else
static_assert(true, ""); } catch (Dhcp4ParseError const&
) { gtest_caught_expected = true; } catch (typename std::conditional
< std::is_same<typename std::remove_cv<typename std::
remove_reference< Dhcp4ParseError>::type>::type, std
::exception>::value, const ::testing::internal::NeverThrown
&, const std::exception&>::type e) { gtest_msg.value
= "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws "; gtest_msg.value
+= ::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testthrow_5405; } catch (...
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_5405; } if (!gtest_caught_expected
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws nothing."; goto gtest_label_testthrow_5405
; } } else gtest_label_testthrow_5405 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5405, gtest_msg.value.c_str()) = ::testing::Message()
;
5406
5407 // Case 2: DUID and HW Address both specified.
5408 config = "{ " + genIfaceConfig() + ","
5409 "\"rebind-timer\": 2000, "
5410 "\"renew-timer\": 1000, "
5411 "\"subnet4\": [ "
5412 " { "
5413 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
5414 " \"subnet\": \"192.0.4.0/24\","
5415 " \"id\": 542,"
5416 " \"reservations\": ["
5417 " {"
5418 " \"duid\": \"01:02:03:04:05:06\","
5419 " \"hw-address\": \"06:05:04:03:02:01\","
5420 " \"ip-address\": \"192.0.4.102\","
5421 " \"hostname\": \"\""
5422 " }"
5423 " ]"
5424 " } ],"
5425 "\"valid-lifetime\": 4000 }";
5426
5427 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5427
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5427
; } } else gtest_label_testnothrow_5427 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5427, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5428
5429 // Remove existing configuration, if any.
5430 CfgMgr::instance().clear();
5431
5432 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5432; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5432; } } else gtest_label_testnothrow_5432
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5432, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5433 checkResult(x, CONTROL_RESULT_ERROR);
5434
5435 // Case 3: Broken specification of option data.
5436 config = "{ " + genIfaceConfig() + ","
5437 "\"rebind-timer\": 2000, "
5438 "\"renew-timer\": 1000, "
5439 "\"subnet4\": [ "
5440 " { "
5441 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
5442 " \"subnet\": \"192.0.4.0/24\","
5443 " \"id\": 542,"
5444 " \"reservations\": ["
5445 " {"
5446 " \"hw-address\": \"06:05:04:03:02:01\","
5447 " \"option-data\": ["
5448 " {"
5449 " \"name\": \"name-servers\","
5450 " \"data\": \"bogus-ip-address\""
5451 " }"
5452 " ]"
5453 " }"
5454 " ]"
5455 " } "
5456 "], "
5457 "\"valid-lifetime\": 4000 }";
5458
5459 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5459
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5459
; } } else gtest_label_testnothrow_5459 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5459, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5460
5461 // Remove existing configuration, if any.
5462 CfgMgr::instance().clear();
5463
5464 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5464; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5464; } } else gtest_label_testnothrow_5464
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5464, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5465 checkResult(x, CONTROL_RESULT_ERROR);
5466}
5467
5468/// The goal of this test is to verify that Host Reservation flags can be
5469/// specified on a per-subnet basis.
5470TEST_F(Dhcp4ParserTest, hostReservationPerSubnet)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("hostReservationPerSubnet") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_hostReservationPerSubnet_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_hostReservationPerSubnet_Test
() = default; ~Dhcp4ParserTest_hostReservationPerSubnet_Test(
) override = default; Dhcp4ParserTest_hostReservationPerSubnet_Test
(const Dhcp4ParserTest_hostReservationPerSubnet_Test &) =
delete; Dhcp4ParserTest_hostReservationPerSubnet_Test & operator
=( const Dhcp4ParserTest_hostReservationPerSubnet_Test &)
= delete; Dhcp4ParserTest_hostReservationPerSubnet_Test (Dhcp4ParserTest_hostReservationPerSubnet_Test
&&) noexcept = delete; Dhcp4ParserTest_hostReservationPerSubnet_Test
& operator=( Dhcp4ParserTest_hostReservationPerSubnet_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_hostReservationPerSubnet_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "hostReservationPerSubnet", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5470), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5470), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5470), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_hostReservationPerSubnet_Test
>); void Dhcp4ParserTest_hostReservationPerSubnet_Test::TestBody
()
{
5471
5472 /// - Configuration:
5473 /// - only addresses (no prefixes)
5474 /// - 7 subnets with:
5475 /// - 192.0.1.0/24 (all reservations enabled)
5476 /// - 192.0.2.0/24 (out-of-pool reservations)
5477 /// - 192.0.3.0/24 (reservations disabled)
5478 /// - 192.0.4.0/24 (global reservations)
5479 /// - 192.0.5.0/24 (reservations not specified)
5480 /// - 192.0.6.0/24 (global + all enabled)
5481 /// - 192.0.7.0/24 (global + out-of-pool enabled)
5482 const char* hr_config =
5483 "{"
5484 "\"rebind-timer\": 2000, "
5485 "\"renew-timer\": 1000, "
5486 "\"subnet4\": [ { "
5487 " \"id\": 1,"
5488 " \"pools\": [ { \"pool\": \"192.0.1.0/24\" } ],"
5489 " \"subnet\": \"192.0.1.0/24\", "
5490 " \"reservations-global\": false,"
5491 " \"reservations-in-subnet\": true,"
5492 " \"reservations-out-of-pool\": false"
5493 " },"
5494 " {"
5495 " \"id\": 2,"
5496 " \"pools\": [ { \"pool\": \"192.0.2.0/24\" } ],"
5497 " \"subnet\": \"192.0.2.0/24\", "
5498 " \"reservations-global\": false,"
5499 " \"reservations-in-subnet\": true,"
5500 " \"reservations-out-of-pool\": true"
5501 " },"
5502 " {"
5503 " \"id\": 3,"
5504 " \"pools\": [ { \"pool\": \"192.0.3.0/24\" } ],"
5505 " \"subnet\": \"192.0.3.0/24\", "
5506 " \"reservations-global\": false,"
5507 " \"reservations-in-subnet\": false"
5508 " },"
5509 " {"
5510 " \"id\": 4,"
5511 " \"pools\": [ { \"pool\": \"192.0.4.0/24\" } ],"
5512 " \"subnet\": \"192.0.4.0/24\", "
5513 " \"reservations-global\": true,"
5514 " \"reservations-in-subnet\": false"
5515 " },"
5516 " {"
5517 " \"id\": 5,"
5518 " \"pools\": [ { \"pool\": \"192.0.5.0/24\" } ],"
5519 " \"subnet\": \"192.0.5.0/24\""
5520 " },"
5521 " {"
5522 " \"id\": 6,"
5523 " \"pools\": [ { \"pool\": \"192.0.6.0/24\" } ],"
5524 " \"subnet\": \"192.0.6.0/24\", "
5525 " \"reservations-global\": true,"
5526 " \"reservations-in-subnet\": true,"
5527 " \"reservations-out-of-pool\": false"
5528 " },"
5529 " {"
5530 " \"id\": 7,"
5531 " \"pools\": [ { \"pool\": \"192.0.7.0/24\" } ],"
5532 " \"subnet\": \"192.0.7.0/24\", "
5533 " \"reservations-global\": true,"
5534 " \"reservations-in-subnet\": true,"
5535 " \"reservations-out-of-pool\": true"
5536 " } ],"
5537 "\"valid-lifetime\": 4000 }";
5538
5539 ConstElementPtr json;
5540 ASSERT_NO_THROW(json = parseDHCP4(hr_config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(hr_config); } else static_assert(true, "")
; } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5540
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5540
; } } else gtest_label_testnothrow_5540 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5540, ("Expected: " "json = parseDHCP4(hr_config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5541 extractConfig(hr_config);
5542
5543 ConstElementPtr status;
5544 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5544; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5544; } } else gtest_label_testnothrow_5544
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5544, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5545
5546 // returned value should be 0 (success)
5547 checkResult(status, 0);
5548 CfgMgr::instance().commit();
5549
5550 // Let's get all subnets and check that there are 7 of them.
5551 ConstCfgSubnets4Ptr subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4();
5552 ASSERT_TRUE(subnets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnets)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5552, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
5553 const Subnet4Collection* subnet_col = subnets->getAll();
5554 ASSERT_EQ(7U, subnet_col->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("7U", "subnet_col->size()"
, 7U, subnet_col->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5554, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 7 subnets
5555
5556 // Let's check if the parsed subnets have correct HR modes.
5557
5558 // Subnet 1
5559 ConstSubnet4Ptr subnet;
5560 subnet = subnets->selectSubnet(IOAddress("192.0.1.1"));
5561 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5561, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5562 EXPECT_FALSE(subnet->getReservationsGlobal())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getReservationsGlobal
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5562, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "true", "false") .c_str
()) = ::testing::Message()
;
5563 EXPECT_TRUE(subnet->getReservationsInSubnet())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->getReservationsInSubnet
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5563, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "false", "true") .c_str
()) = ::testing::Message()
;
5564 EXPECT_FALSE(subnet->getReservationsOutOfPool())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getReservationsOutOfPool
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5564, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "true", "false") .
c_str()) = ::testing::Message()
;
5565
5566 // Subnet 2
5567 subnet = subnets->selectSubnet(IOAddress("192.0.2.1"));
5568 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5568, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5569 EXPECT_FALSE(subnet->getReservationsGlobal())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getReservationsGlobal
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5569, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "true", "false") .c_str
()) = ::testing::Message()
;
5570 EXPECT_TRUE(subnet->getReservationsInSubnet())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->getReservationsInSubnet
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5570, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "false", "true") .c_str
()) = ::testing::Message()
;
5571 EXPECT_TRUE(subnet->getReservationsOutOfPool())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->getReservationsOutOfPool
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5571, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "false", "true") .
c_str()) = ::testing::Message()
;
5572
5573 // Subnet 3
5574 subnet = subnets->selectSubnet(IOAddress("192.0.3.1"));
5575 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5575, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5576 EXPECT_FALSE(subnet->getReservationsGlobal())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getReservationsGlobal
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5576, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "true", "false") .c_str
()) = ::testing::Message()
;
5577 EXPECT_FALSE(subnet->getReservationsInSubnet())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getReservationsInSubnet
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5577, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "true", "false") .c_str
()) = ::testing::Message()
;
5578 EXPECT_FALSE(subnet->getReservationsOutOfPool())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getReservationsOutOfPool
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5578, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "true", "false") .
c_str()) = ::testing::Message()
;
5579
5580 // Subnet 4
5581 subnet = subnets->selectSubnet(IOAddress("192.0.4.1"));
5582 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5582, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5583 EXPECT_TRUE(subnet->getReservationsGlobal())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->getReservationsGlobal
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5583, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "false", "true") .c_str
()) = ::testing::Message()
;
5584 EXPECT_FALSE(subnet->getReservationsInSubnet())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getReservationsInSubnet
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5584, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "true", "false") .c_str
()) = ::testing::Message()
;
5585 EXPECT_FALSE(subnet->getReservationsOutOfPool())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getReservationsOutOfPool
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5585, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "true", "false") .
c_str()) = ::testing::Message()
;
5586
5587 // Subnet 5
5588 subnet = subnets->selectSubnet(IOAddress("192.0.5.1"));
5589 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5589, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5590 EXPECT_FALSE(subnet->getReservationsGlobal())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getReservationsGlobal
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5590, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "true", "false") .c_str
()) = ::testing::Message()
;
5591 EXPECT_TRUE(subnet->getReservationsInSubnet())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->getReservationsInSubnet
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5591, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "false", "true") .c_str
()) = ::testing::Message()
;
5592 EXPECT_FALSE(subnet->getReservationsOutOfPool())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getReservationsOutOfPool
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5592, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "true", "false") .
c_str()) = ::testing::Message()
;
5593
5594 // Subnet 6
5595 subnet = subnets->selectSubnet(IOAddress("192.0.6.1"));
5596 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5596, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5597 EXPECT_TRUE(subnet->getReservationsGlobal())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->getReservationsGlobal
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5597, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "false", "true") .c_str
()) = ::testing::Message()
;
5598 EXPECT_TRUE(subnet->getReservationsInSubnet())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->getReservationsInSubnet
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5598, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "false", "true") .c_str
()) = ::testing::Message()
;
5599 EXPECT_FALSE(subnet->getReservationsOutOfPool())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getReservationsOutOfPool
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5599, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "true", "false") .
c_str()) = ::testing::Message()
;
5600
5601 // Subnet 7
5602 subnet = subnets->selectSubnet(IOAddress("192.0.7.1"));
5603 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5603, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5604 EXPECT_TRUE(subnet->getReservationsGlobal())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->getReservationsGlobal
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5604, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "false", "true") .c_str
()) = ::testing::Message()
;
5605 EXPECT_TRUE(subnet->getReservationsInSubnet())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->getReservationsInSubnet
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5605, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "false", "true") .c_str
()) = ::testing::Message()
;
5606 EXPECT_TRUE(subnet->getReservationsOutOfPool())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->getReservationsOutOfPool
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5606, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "false", "true") .
c_str()) = ::testing::Message()
;
5607}
5608
5609/// The goal of this test is to verify that Host Reservation flags can be
5610/// specified globally.
5611TEST_F(Dhcp4ParserTest, hostReservationGlobal)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("hostReservationGlobal") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_hostReservationGlobal_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_hostReservationGlobal_Test() = default
; ~Dhcp4ParserTest_hostReservationGlobal_Test() override = default
; Dhcp4ParserTest_hostReservationGlobal_Test (const Dhcp4ParserTest_hostReservationGlobal_Test
&) = delete; Dhcp4ParserTest_hostReservationGlobal_Test &
operator=( const Dhcp4ParserTest_hostReservationGlobal_Test &
) = delete; Dhcp4ParserTest_hostReservationGlobal_Test (Dhcp4ParserTest_hostReservationGlobal_Test
&&) noexcept = delete; Dhcp4ParserTest_hostReservationGlobal_Test
& operator=( Dhcp4ParserTest_hostReservationGlobal_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_hostReservationGlobal_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "hostReservationGlobal", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5611), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5611), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5611), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_hostReservationGlobal_Test
>); void Dhcp4ParserTest_hostReservationGlobal_Test::TestBody
()
{
5612
5613 /// - Configuration:
5614 /// - only addresses (no prefixes)
5615 /// - 2 subnets with :
5616 /// - 192.0.2.0/24 (all reservations enabled)
5617 /// - 192.0.3.0/24 (reservations not specified)
5618 const char* hr_config =
5619 "{"
5620 "\"rebind-timer\": 2000, "
5621 "\"renew-timer\": 1000, "
5622 "\"reservations-global\": false,"
5623 "\"reservations-in-subnet\": true,"
5624 "\"reservations-out-of-pool\": true,"
5625 "\"subnet4\": [ { "
5626 " \"id\": 1,"
5627 " \"pools\": [ { \"pool\": \"192.0.2.0/24\" } ],"
5628 " \"subnet\": \"192.0.2.0/24\", "
5629 " \"reservations-global\": false,"
5630 " \"reservations-in-subnet\": true,"
5631 " \"reservations-out-of-pool\": false"
5632 " },"
5633 " {"
5634 " \"id\": 2,"
5635 " \"pools\": [ { \"pool\": \"192.0.3.0/24\" } ],"
5636 " \"subnet\": \"192.0.3.0/24\""
5637 " } ],"
5638 "\"valid-lifetime\": 4000 }";
5639
5640 ConstElementPtr json;
5641 ASSERT_NO_THROW(json = parseDHCP4(hr_config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(hr_config); } else static_assert(true, "")
; } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5641
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5641
; } } else gtest_label_testnothrow_5641 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5641, ("Expected: " "json = parseDHCP4(hr_config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5642 extractConfig(hr_config);
5643
5644 ConstElementPtr status;
5645 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5645; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5645; } } else gtest_label_testnothrow_5645
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5645, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5646
5647 // returned value should be 0 (success)
5648 checkResult(status, 0);
5649 CfgMgr::instance().commit();
5650
5651 // Let's get all subnets and check that there are 4 of them.
5652 ConstCfgSubnets4Ptr subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4();
5653 ASSERT_TRUE(subnets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnets)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5653, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
5654 const Subnet4Collection* subnet_col = subnets->getAll();
5655 ASSERT_EQ(2U, subnet_col->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "subnet_col->size()"
, 2U, subnet_col->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5655, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 2 subnets
5656
5657 // Let's check if the parsed subnets have correct HR modes.
5658
5659 // Subnet 1
5660 ConstSubnet4Ptr subnet;
5661 subnet = subnets->selectSubnet(IOAddress("192.0.2.1"));
5662 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5662, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5663 EXPECT_FALSE(subnet->getReservationsGlobal())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getReservationsGlobal
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5663, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "true", "false") .c_str
()) = ::testing::Message()
;
5664 EXPECT_TRUE(subnet->getReservationsInSubnet())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->getReservationsInSubnet
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5664, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "false", "true") .c_str
()) = ::testing::Message()
;
5665 EXPECT_FALSE(subnet->getReservationsOutOfPool())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getReservationsOutOfPool
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5665, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "true", "false") .
c_str()) = ::testing::Message()
;
5666
5667 // Subnet 2
5668 subnet = subnets->selectSubnet(IOAddress("192.0.3.1"));
5669 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5669, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5670 EXPECT_FALSE(subnet->getReservationsGlobal())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getReservationsGlobal
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5670, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "true", "false") .c_str
()) = ::testing::Message()
;
5671 EXPECT_TRUE(subnet->getReservationsInSubnet())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->getReservationsInSubnet
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5671, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "false", "true") .c_str
()) = ::testing::Message()
;
5672 EXPECT_TRUE(subnet->getReservationsOutOfPool())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet->getReservationsOutOfPool
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5672, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "false", "true") .
c_str()) = ::testing::Message()
;
5673}
5674
5675/// Check that the decline-probation-period has a default value when not
5676/// specified.
5677TEST_F(Dhcp4ParserTest, declineTimerDefault)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("declineTimerDefault") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_declineTimerDefault_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_declineTimerDefault_Test() = default
; ~Dhcp4ParserTest_declineTimerDefault_Test() override = default
; Dhcp4ParserTest_declineTimerDefault_Test (const Dhcp4ParserTest_declineTimerDefault_Test
&) = delete; Dhcp4ParserTest_declineTimerDefault_Test &
operator=( const Dhcp4ParserTest_declineTimerDefault_Test &
) = delete; Dhcp4ParserTest_declineTimerDefault_Test (Dhcp4ParserTest_declineTimerDefault_Test
&&) noexcept = delete; Dhcp4ParserTest_declineTimerDefault_Test
& operator=( Dhcp4ParserTest_declineTimerDefault_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_declineTimerDefault_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "declineTimerDefault", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5677), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5677), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5677), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_declineTimerDefault_Test
>); void Dhcp4ParserTest_declineTimerDefault_Test::TestBody
()
{
5678
5679 string config = "{ " + genIfaceConfig() + ","
5680 "\"subnet4\": [ ] "
5681 "}";
5682
5683 ConstElementPtr json;
5684 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5684
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5684
; } } else gtest_label_testnothrow_5684 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5684, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5685 extractConfig(config);
5686
5687 ConstElementPtr status;
5688 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5688; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5688; } } else gtest_label_testnothrow_5688
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5688, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5689
5690 // returned value should be 0 (success)
5691 checkResult(status, 0);
5692
5693 // The value of decline-probation-period must be equal to the
5694 // default value (86400). The default value is defined in GLOBAL4_DEFAULTS in
5695 // simple_parser4.cc.
5696 EXPECT_EQ(86400U, CfgMgr::instance().getStagingCfg()->getDeclinePeriod())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("86400U",
"CfgMgr::instance().getStagingCfg()->getDeclinePeriod()",
86400U, CfgMgr::instance().getStagingCfg()->getDeclinePeriod
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5696, gtest_ar.failure_message()) = ::testing::Message()
;
5697}
5698
5699/// Check that the dhcp4o6-port default value has a default value if not
5700/// specified explicitly.
5701TEST_F(Dhcp4ParserTest, dhcp4o6portDefault)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("dhcp4o6portDefault") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_dhcp4o6portDefault_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_dhcp4o6portDefault_Test() = default
; ~Dhcp4ParserTest_dhcp4o6portDefault_Test() override = default
; Dhcp4ParserTest_dhcp4o6portDefault_Test (const Dhcp4ParserTest_dhcp4o6portDefault_Test
&) = delete; Dhcp4ParserTest_dhcp4o6portDefault_Test &
operator=( const Dhcp4ParserTest_dhcp4o6portDefault_Test &
) = delete; Dhcp4ParserTest_dhcp4o6portDefault_Test (Dhcp4ParserTest_dhcp4o6portDefault_Test
&&) noexcept = delete; Dhcp4ParserTest_dhcp4o6portDefault_Test
& operator=( Dhcp4ParserTest_dhcp4o6portDefault_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_dhcp4o6portDefault_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "dhcp4o6portDefault", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5701), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5701), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5701), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_dhcp4o6portDefault_Test
>); void Dhcp4ParserTest_dhcp4o6portDefault_Test::TestBody
()
{
5702
5703 string config_txt = "{ " + genIfaceConfig() + ","
5704 "\"subnet4\": [ ] "
5705 "}";
5706 ConstElementPtr config;
5707 ASSERT_NO_THROW(config = parseDHCP4(config_txt))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
config = parseDHCP4(config_txt); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5707
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5707
; } } else gtest_label_testnothrow_5707 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5707, ("Expected: " "config = parseDHCP4(config_txt)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5708 extractConfig(config_txt);
5709
5710 ConstElementPtr status;
5711 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, config); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5711; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5711; } } else gtest_label_testnothrow_5711
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5711, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, config)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5712
5713 // returned value should be 0 (success)
5714 checkResult(status, 0);
5715
5716 // The value of decline-probation-period must be equal to the
5717 // default value (0). The default value is defined in GLOBAL4_DEFAULTS in
5718 // simple_parser4.cc.
5719 EXPECT_EQ(0U, CfgMgr::instance().getStagingCfg()->getDhcp4o6Port())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("0U", "CfgMgr::instance().getStagingCfg()->getDhcp4o6Port()"
, 0U, CfgMgr::instance().getStagingCfg()->getDhcp4o6Port()
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5719, gtest_ar.failure_message()) = ::testing::Message()
;
5720}
5721
5722/// Check that the decline-probation-period value can be set properly.
5723TEST_F(Dhcp4ParserTest, declineTimer)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("declineTimer") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_declineTimer_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_declineTimer_Test() = default; ~Dhcp4ParserTest_declineTimer_Test
() override = default; Dhcp4ParserTest_declineTimer_Test (const
Dhcp4ParserTest_declineTimer_Test &) = delete; Dhcp4ParserTest_declineTimer_Test
& operator=( const Dhcp4ParserTest_declineTimer_Test &
) = delete; Dhcp4ParserTest_declineTimer_Test (Dhcp4ParserTest_declineTimer_Test
&&) noexcept = delete; Dhcp4ParserTest_declineTimer_Test
& operator=( Dhcp4ParserTest_declineTimer_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_declineTimer_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "declineTimer", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5723
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5723), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5723), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_declineTimer_Test
>); void Dhcp4ParserTest_declineTimer_Test::TestBody()
{
5724 string config = "{ " + genIfaceConfig() + ","
5725 "\"decline-probation-period\": 12345,"
5726 "\"subnet4\": [ ]"
5727 "}";
5728
5729 ConstElementPtr json;
5730 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5730
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5730
; } } else gtest_label_testnothrow_5730 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5730, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5731 extractConfig(config);
5732
5733 ConstElementPtr status;
5734 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5734; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5734; } } else gtest_label_testnothrow_5734
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5734, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5735
5736 // returned value should be 0 (success)
5737 checkResult(status, 0);
5738
5739 // The value of decline-probation-period must be equal to the
5740 // value specified.
5741 EXPECT_EQ(12345U,switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("12345U",
"CfgMgr::instance().getStagingCfg()->getDeclinePeriod()",
12345U, CfgMgr::instance().getStagingCfg()->getDeclinePeriod
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5742, gtest_ar.failure_message()) = ::testing::Message()
5742 CfgMgr::instance().getStagingCfg()->getDeclinePeriod())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("12345U",
"CfgMgr::instance().getStagingCfg()->getDeclinePeriod()",
12345U, CfgMgr::instance().getStagingCfg()->getDeclinePeriod
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5742, gtest_ar.failure_message()) = ::testing::Message()
;
5743}
5744
5745/// Check that an incorrect decline-probation-period value will be caught.
5746TEST_F(Dhcp4ParserTest, declineTimerError)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("declineTimerError") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_declineTimerError_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_declineTimerError_Test() = default
; ~Dhcp4ParserTest_declineTimerError_Test() override = default
; Dhcp4ParserTest_declineTimerError_Test (const Dhcp4ParserTest_declineTimerError_Test
&) = delete; Dhcp4ParserTest_declineTimerError_Test &
operator=( const Dhcp4ParserTest_declineTimerError_Test &
) = delete; Dhcp4ParserTest_declineTimerError_Test (Dhcp4ParserTest_declineTimerError_Test
&&) noexcept = delete; Dhcp4ParserTest_declineTimerError_Test
& operator=( Dhcp4ParserTest_declineTimerError_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_declineTimerError_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "declineTimerError", nullptr, nullptr, ::testing::internal::
CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5746), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5746), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5746), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_declineTimerError_Test
>); void Dhcp4ParserTest_declineTimerError_Test::TestBody(
)
{
5747 string config = "{ " + genIfaceConfig() + ","
5748 "\"decline-probation-period\": \"soon\","
5749 "\"subnet4\": [ ]"
5750 "}";
5751
5752 ConstElementPtr json;
5753 ASSERT_NO_THROW(json = parseJSON(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseJSON(config); } else static_assert(true, ""); } catch
(std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5753
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5753
; } } else gtest_label_testnothrow_5753 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5753, ("Expected: " "json = parseJSON(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5754
5755 ConstElementPtr status;
5756 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5756; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5756; } } else gtest_label_testnothrow_5756
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5756, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5757
5758 // returned value should be 1 (error)
5759 checkResult(status, CONTROL_RESULT_ERROR);
5760
5761 // Check that the error contains error position.
5762 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5762, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
5763
5764 // Check that the Dhcp4 parser catches the type error
5765 EXPECT_THROW(parseDHCP4(config), Dhcp4ParseError)switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { bool gtest_caught_expected = false; try { if (
::testing::internal::AlwaysTrue()) { parseDHCP4(config); } else
static_assert(true, ""); } catch (Dhcp4ParseError const&
) { gtest_caught_expected = true; } catch (typename std::conditional
< std::is_same<typename std::remove_cv<typename std::
remove_reference< Dhcp4ParseError>::type>::type, std
::exception>::value, const ::testing::internal::NeverThrown
&, const std::exception&>::type e) { gtest_msg.value
= "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws "; gtest_msg.value
+= ::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testthrow_5765; } catch (...
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_5765; } if (!gtest_caught_expected
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws nothing."; goto gtest_label_testthrow_5765
; } } else gtest_label_testthrow_5765 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5765, gtest_msg.value.c_str()) = ::testing::Message()
;
5766}
5767
5768// Check that configuration for the expired leases processing may be
5769// specified.
5770TEST_F(Dhcp4ParserTest, expiredLeasesProcessing)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("expiredLeasesProcessing") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_expiredLeasesProcessing_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_expiredLeasesProcessing_Test
() = default; ~Dhcp4ParserTest_expiredLeasesProcessing_Test()
override = default; Dhcp4ParserTest_expiredLeasesProcessing_Test
(const Dhcp4ParserTest_expiredLeasesProcessing_Test &) =
delete; Dhcp4ParserTest_expiredLeasesProcessing_Test & operator
=( const Dhcp4ParserTest_expiredLeasesProcessing_Test &) =
delete; Dhcp4ParserTest_expiredLeasesProcessing_Test (Dhcp4ParserTest_expiredLeasesProcessing_Test
&&) noexcept = delete; Dhcp4ParserTest_expiredLeasesProcessing_Test
& operator=( Dhcp4ParserTest_expiredLeasesProcessing_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_expiredLeasesProcessing_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "expiredLeasesProcessing", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5770), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5770), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5770), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_expiredLeasesProcessing_Test
>); void Dhcp4ParserTest_expiredLeasesProcessing_Test::TestBody
()
{
5771 // Create basic configuration with the expiration specific parameters.
5772 string config = "{ " + genIfaceConfig() + ","
5773 "\"expired-leases-processing\": "
5774 "{"
5775 " \"reclaim-timer-wait-time\": 20,"
5776 " \"flush-reclaimed-timer-wait-time\": 35,"
5777 " \"hold-reclaimed-time\": 1800,"
5778 " \"max-reclaim-leases\": 50,"
5779 " \"max-reclaim-time\": 100,"
5780 " \"unwarned-reclaim-cycles\": 10"
5781 "},"
5782 "\"subnet4\": [ ]"
5783 "}";
5784
5785 ConstElementPtr json;
5786 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5786
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5786
; } } else gtest_label_testnothrow_5786 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5786, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5787 extractConfig(config);
5788
5789 ConstElementPtr status;
5790 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5790; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5790; } } else gtest_label_testnothrow_5790
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5790, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5791
5792 // Returned value should be 0 (success)
5793 checkResult(status, 0);
5794
5795 // The value of decline-probation-period must be equal to the
5796 // value specified.
5797 CfgExpirationPtr cfg = CfgMgr::instance().getStagingCfg()->getCfgExpiration();
5798 ASSERT_TRUE(cfg)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(cfg)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5798
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg", "false", "true") .c_str()) = ::testing::Message()
;
5799
5800 // Verify that parameters are correct.
5801 EXPECT_EQ(20U, cfg->getReclaimTimerWaitTime())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("20U", "cfg->getReclaimTimerWaitTime()"
, 20U, cfg->getReclaimTimerWaitTime()))) ; else ::testing::
internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5801
, gtest_ar.failure_message()) = ::testing::Message()
;
5802 EXPECT_EQ(35U, cfg->getFlushReclaimedTimerWaitTime())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("35U", "cfg->getFlushReclaimedTimerWaitTime()"
, 35U, cfg->getFlushReclaimedTimerWaitTime()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5802
, gtest_ar.failure_message()) = ::testing::Message()
;
5803 EXPECT_EQ(1800U, cfg->getHoldReclaimedTime())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1800U", "cfg->getHoldReclaimedTime()"
, 1800U, cfg->getHoldReclaimedTime()))) ; else ::testing::
internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5803
, gtest_ar.failure_message()) = ::testing::Message()
;
5804 EXPECT_EQ(50U, cfg->getMaxReclaimLeases())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("50U", "cfg->getMaxReclaimLeases()"
, 50U, cfg->getMaxReclaimLeases()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5804, gtest_ar.failure_message()) = ::testing::Message()
;
5805 EXPECT_EQ(100U, cfg->getMaxReclaimTime())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("100U", "cfg->getMaxReclaimTime()"
, 100U, cfg->getMaxReclaimTime()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5805, gtest_ar.failure_message()) = ::testing::Message()
;
5806 EXPECT_EQ(10U, cfg->getUnwarnedReclaimCycles())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("10U", "cfg->getUnwarnedReclaimCycles()"
, 10U, cfg->getUnwarnedReclaimCycles()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5806
, gtest_ar.failure_message()) = ::testing::Message()
;
5807}
5808
5809// Check that invalid configuration for the expired leases processing is
5810// causing an error.
5811TEST_F(Dhcp4ParserTest, expiredLeasesProcessingError)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("expiredLeasesProcessingError") > 1
, "test_name must not be empty"); class Dhcp4ParserTest_expiredLeasesProcessingError_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_expiredLeasesProcessingError_Test
() = default; ~Dhcp4ParserTest_expiredLeasesProcessingError_Test
() override = default; Dhcp4ParserTest_expiredLeasesProcessingError_Test
(const Dhcp4ParserTest_expiredLeasesProcessingError_Test &
) = delete; Dhcp4ParserTest_expiredLeasesProcessingError_Test
& operator=( const Dhcp4ParserTest_expiredLeasesProcessingError_Test
&) = delete; Dhcp4ParserTest_expiredLeasesProcessingError_Test
(Dhcp4ParserTest_expiredLeasesProcessingError_Test &&
) noexcept = delete; Dhcp4ParserTest_expiredLeasesProcessingError_Test
& operator=( Dhcp4ParserTest_expiredLeasesProcessingError_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_expiredLeasesProcessingError_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "expiredLeasesProcessingError", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5811), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5811), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5811), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_expiredLeasesProcessingError_Test
>); void Dhcp4ParserTest_expiredLeasesProcessingError_Test
::TestBody()
{
5812 // Create basic configuration with the expiration specific parameters.
5813 // One of the parameters holds invalid value.
5814 string config = "{ " + genIfaceConfig() + ","
5815 "\"expired-leases-processing\": "
5816 "{"
5817 " \"reclaim-timer-wait-time\": -5,"
5818 " \"flush-reclaimed-timer-wait-time\": 35,"
5819 " \"hold-reclaimed-time\": 1800,"
5820 " \"max-reclaim-leases\": 50,"
5821 " \"max-reclaim-time\": 100,"
5822 " \"unwarned-reclaim-cycles\": 10"
5823 "},"
5824 "\"subnet4\": [ ]"
5825 "}";
5826
5827 ConstElementPtr json;
5828 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5828
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5828
; } } else gtest_label_testnothrow_5828 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5828, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5829
5830 ConstElementPtr status;
5831 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5831; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5831; } } else gtest_label_testnothrow_5831
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5831, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5832
5833 // Returned value should be 0 (error)
5834 checkResult(status, CONTROL_RESULT_ERROR);
5835
5836 // Check that the error contains error position.
5837 EXPECT_TRUE(errorContainsPosition(status, "<string>"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(errorContainsPosition
(status, "<string>"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5837, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
5838}
5839
5840// Checks if the DHCPv4 is able to parse the configuration without 4o6 parameters
5841// and does not set 4o6 fields at all.
5842TEST_F(Dhcp4ParserTest, 4o6default)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("4o6default") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_4o6default_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_4o6default_Test() = default; ~Dhcp4ParserTest_4o6default_Test
() override = default; Dhcp4ParserTest_4o6default_Test (const
Dhcp4ParserTest_4o6default_Test &) = delete; Dhcp4ParserTest_4o6default_Test
& operator=( const Dhcp4ParserTest_4o6default_Test &
) = delete; Dhcp4ParserTest_4o6default_Test (Dhcp4ParserTest_4o6default_Test
&&) noexcept = delete; Dhcp4ParserTest_4o6default_Test
& operator=( Dhcp4ParserTest_4o6default_Test &&)
noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_4o6default_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "4o6default", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5842
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5842), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5842), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_4o6default_Test
>); void Dhcp4ParserTest_4o6default_Test::TestBody()
{
5843
5844 ConstElementPtr status;
5845
5846 // Just a plain v4 config (no 4o6 parameters)
5847 string config = "{ " + genIfaceConfig() + ","
5848 "\"rebind-timer\": 2000, "
5849 "\"renew-timer\": 1000, "
5850 "\"subnet4\": [ { "
5851 " \"id\": 1,"
5852 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5853 " \"subnet\": \"192.0.2.0/24\" } ],"
5854 "\"valid-lifetime\": 4000 }";
5855
5856 ConstElementPtr json;
5857 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5857
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5857
; } } else gtest_label_testnothrow_5857 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5857, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5858 extractConfig(config);
5859
5860 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5860; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5860; } } else gtest_label_testnothrow_5860
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5860, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5861
5862 // check if returned status is OK
5863 checkResult(status, 0);
5864
5865 // Now check if the configuration was indeed handled and we have
5866 // expected pool configured.
5867 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
5868 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
5869 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5869, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5870
5871 const Cfg4o6& dhcp4o6 = subnet->get4o6();
5872 EXPECT_FALSE(dhcp4o6.enabled())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(dhcp4o6.enabled()))
) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5872, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dhcp4o6.enabled()", "true", "false") .c_str()) = ::testing
::Message()
;
5873}
5874
5875// Checks if the DHCPv4 is able to parse the configuration with 4o6 subnet
5876// defined.
5877TEST_F(Dhcp4ParserTest, 4o6subnet)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("4o6subnet") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_4o6subnet_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_4o6subnet_Test() = default; ~Dhcp4ParserTest_4o6subnet_Test
() override = default; Dhcp4ParserTest_4o6subnet_Test (const Dhcp4ParserTest_4o6subnet_Test
&) = delete; Dhcp4ParserTest_4o6subnet_Test & operator
=( const Dhcp4ParserTest_4o6subnet_Test &) = delete; Dhcp4ParserTest_4o6subnet_Test
(Dhcp4ParserTest_4o6subnet_Test &&) noexcept = delete
; Dhcp4ParserTest_4o6subnet_Test & operator=( Dhcp4ParserTest_4o6subnet_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_4o6subnet_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "4o6subnet", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5877
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5877), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5877), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_4o6subnet_Test
>); void Dhcp4ParserTest_4o6subnet_Test::TestBody()
{
5878
5879 ConstElementPtr status;
5880
5881 // Just a plain v4 config (no 4o6 parameters)
5882 string config = "{ " + genIfaceConfig() + ","
5883 "\"rebind-timer\": 2000, "
5884 "\"renew-timer\": 1000, "
5885 "\"subnet4\": [ { "
5886 " \"id\": 1,"
5887 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5888 " \"subnet\": \"192.0.2.0/24\","
5889 " \"4o6-subnet\": \"2001:db8::123/45\" } ],"
5890 "\"valid-lifetime\": 4000 }";
5891
5892 ConstElementPtr json;
5893 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5893
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5893
; } } else gtest_label_testnothrow_5893 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5893, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5894 extractConfig(config);
5895
5896 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5896; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5896; } } else gtest_label_testnothrow_5896
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5896, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5897
5898 // check if returned status is OK
5899 checkResult(status, 0);
5900
5901 // Now check if the configuration was indeed handled and we have
5902 // expected pool configured.
5903 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
5904 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
5905 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5905, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5906
5907 const Cfg4o6& dhcp4o6 = subnet->get4o6();
5908 EXPECT_TRUE(dhcp4o6.enabled())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(dhcp4o6.enabled())) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5908, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dhcp4o6.enabled()", "false", "true") .c_str()) = ::testing
::Message()
;
5909 EXPECT_EQ(IOAddress("2001:db8::123"), dhcp4o6.getSubnet4o6().get().first)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("IOAddress(\"2001:db8::123\")"
, "dhcp4o6.getSubnet4o6().get().first", IOAddress("2001:db8::123"
), dhcp4o6.getSubnet4o6().get().first))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5909, gtest_ar.failure_message()) = ::testing::Message()
;
5910 EXPECT_EQ(45U, dhcp4o6.getSubnet4o6().get().second)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("45U", "dhcp4o6.getSubnet4o6().get().second"
, 45U, dhcp4o6.getSubnet4o6().get().second))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5910
, gtest_ar.failure_message()) = ::testing::Message()
;
5911}
5912
5913// Checks if the DHCPv4 is able to parse the configuration with 4o6 subnet
5914// defined.
5915TEST_F(Dhcp4ParserTest, 4o6subnetBogus)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("4o6subnetBogus") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_4o6subnetBogus_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_4o6subnetBogus_Test() = default; ~
Dhcp4ParserTest_4o6subnetBogus_Test() override = default; Dhcp4ParserTest_4o6subnetBogus_Test
(const Dhcp4ParserTest_4o6subnetBogus_Test &) = delete; Dhcp4ParserTest_4o6subnetBogus_Test
& operator=( const Dhcp4ParserTest_4o6subnetBogus_Test &
) = delete; Dhcp4ParserTest_4o6subnetBogus_Test (Dhcp4ParserTest_4o6subnetBogus_Test
&&) noexcept = delete; Dhcp4ParserTest_4o6subnetBogus_Test
& operator=( Dhcp4ParserTest_4o6subnetBogus_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_4o6subnetBogus_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "4o6subnetBogus", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5915
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5915), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5915), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_4o6subnetBogus_Test
>); void Dhcp4ParserTest_4o6subnetBogus_Test::TestBody()
{
5916
5917 ConstElementPtr status;
5918
5919 // Just a plain v4 config (no 4o6 parameters)
5920 string config[] = {
5921 // Bogus configuration 1: missing / in subnet
5922 "{ " + genIfaceConfig() + ","
5923 "\"rebind-timer\": 2000, "
5924 "\"renew-timer\": 1000, "
5925 "\"subnet4\": [ { "
5926 " \"id\": 1,"
5927 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5928 " \"subnet\": \"192.0.2.0/24\","
5929 " \"4o6-subnet\": \"2001:db8::123\" } ],"
5930 "\"valid-lifetime\": 4000 }",
5931
5932 // Bogus configuration 2: incorrect address
5933 "{ " + genIfaceConfig() + ","
5934 "\"rebind-timer\": 2000, "
5935 "\"renew-timer\": 1000, "
5936 "\"subnet4\": [ { "
5937 " \"id\": 1,"
5938 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5939 " \"subnet\": \"192.0.2.0/24\","
5940 " \"4o6-subnet\": \"2001:db8:bogus/45\" } ],"
5941 "\"valid-lifetime\": 4000 }",
5942
5943 // Bogus configuration 3: incorrect prefix length
5944 "{ " + genIfaceConfig() + ","
5945 "\"rebind-timer\": 2000, "
5946 "\"renew-timer\": 1000, "
5947 "\"subnet4\": [ { "
5948 " \"id\": 1,"
5949 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5950 " \"subnet\": \"192.0.2.0/24\","
5951 " \"4o6-subnet\": \"2001:db8::123/200\" } ],"
5952 "\"valid-lifetime\": 4000 }"
5953 };
5954
5955 ConstElementPtr json1;
5956 ASSERT_NO_THROW(json1 = parseDHCP4(config[0]))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json1 = parseDHCP4(config[0]); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5956
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5956
; } } else gtest_label_testnothrow_5956 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5956, ("Expected: " "json1 = parseDHCP4(config[0])" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5957 ConstElementPtr json2;
5958 ASSERT_NO_THROW(json2 = parseDHCP4(config[0]))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json2 = parseDHCP4(config[0]); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5958
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5958
; } } else gtest_label_testnothrow_5958 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5958, ("Expected: " "json2 = parseDHCP4(config[0])" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5959 ConstElementPtr json3;
5960 ASSERT_NO_THROW(json3 = parseDHCP4(config[0]))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json3 = parseDHCP4(config[0]); } else static_assert(true, ""
); } catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5960
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5960
; } } else gtest_label_testnothrow_5960 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5960, ("Expected: " "json3 = parseDHCP4(config[0])" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5961
5962 // Check that the first config is rejected.
5963 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json1))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json1); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5963; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5963; } } else gtest_label_testnothrow_5963
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5963, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json1)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5964 checkResult(status, CONTROL_RESULT_ERROR);
5965
5966 // Check that the second config is rejected.
5967 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json2))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json2); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5967; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5967; } } else gtest_label_testnothrow_5967
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5967, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json2)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5968 checkResult(status, CONTROL_RESULT_ERROR);
5969
5970 // Check that the third config is rejected.
5971 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json3))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json3); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5971; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5971; } } else gtest_label_testnothrow_5971
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5971, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json3)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5972 checkResult(status, CONTROL_RESULT_ERROR);
5973}
5974
5975// Checks if the DHCPv4 is able to parse the configuration with 4o6 network
5976// interface defined.
5977TEST_F(Dhcp4ParserTest, 4o6iface)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("4o6iface") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_4o6iface_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_4o6iface_Test() = default; ~Dhcp4ParserTest_4o6iface_Test
() override = default; Dhcp4ParserTest_4o6iface_Test (const Dhcp4ParserTest_4o6iface_Test
&) = delete; Dhcp4ParserTest_4o6iface_Test & operator
=( const Dhcp4ParserTest_4o6iface_Test &) = delete; Dhcp4ParserTest_4o6iface_Test
(Dhcp4ParserTest_4o6iface_Test &&) noexcept = delete
; Dhcp4ParserTest_4o6iface_Test & operator=( Dhcp4ParserTest_4o6iface_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_4o6iface_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "4o6iface", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 5977
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5977), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5977), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_4o6iface_Test
>); void Dhcp4ParserTest_4o6iface_Test::TestBody()
{
5978
5979 ConstElementPtr status;
5980
5981 // Just a plain v4 config (no 4o6 parameters)
5982 string config = "{ " + genIfaceConfig() + ","
5983 "\"rebind-timer\": 2000, "
5984 "\"renew-timer\": 1000, "
5985 "\"subnet4\": [ { "
5986 " \"id\": 1,"
5987 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5988 " \"subnet\": \"192.0.2.0/24\","
5989 " \"4o6-interface\": \"ethX\" } ],"
5990 "\"valid-lifetime\": 4000 }";
5991
5992 ConstElementPtr json;
5993 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_5993
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5993
; } } else gtest_label_testnothrow_5993 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5993, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5994 extractConfig(config);
5995
5996 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_5996; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5996; } } else gtest_label_testnothrow_5996
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5996, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5997
5998 // check if returned status is OK
5999 checkResult(status, 0);
6000
6001 // Now check if the configuration was indeed handled and we have
6002 // expected pool configured.
6003 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
6004 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
6005 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6005, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
6006
6007 const Cfg4o6& dhcp4o6 = subnet->get4o6();
6008 EXPECT_TRUE(dhcp4o6.enabled())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(dhcp4o6.enabled())) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6008, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dhcp4o6.enabled()", "false", "true") .c_str()) = ::testing
::Message()
;
6009 EXPECT_EQ("ethX", dhcp4o6.getIface4o6().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"ethX\""
, "dhcp4o6.getIface4o6().get()", "ethX", dhcp4o6.getIface4o6(
).get()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6009, gtest_ar.failure_message()) = ::testing::Message()
;
6010}
6011
6012// Checks if the DHCPv4 is able to parse the configuration with both 4o6 network
6013// interface and v6 subnet defined.
6014TEST_F(Dhcp4ParserTest, 4o6subnetIface)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("4o6subnetIface") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_4o6subnetIface_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_4o6subnetIface_Test() = default; ~
Dhcp4ParserTest_4o6subnetIface_Test() override = default; Dhcp4ParserTest_4o6subnetIface_Test
(const Dhcp4ParserTest_4o6subnetIface_Test &) = delete; Dhcp4ParserTest_4o6subnetIface_Test
& operator=( const Dhcp4ParserTest_4o6subnetIface_Test &
) = delete; Dhcp4ParserTest_4o6subnetIface_Test (Dhcp4ParserTest_4o6subnetIface_Test
&&) noexcept = delete; Dhcp4ParserTest_4o6subnetIface_Test
& operator=( Dhcp4ParserTest_4o6subnetIface_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_4o6subnetIface_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "4o6subnetIface", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6014
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6014), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6014), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_4o6subnetIface_Test
>); void Dhcp4ParserTest_4o6subnetIface_Test::TestBody()
{
6015
6016 ConstElementPtr status;
6017
6018 // Just a plain v4 config (no 4o6 parameters)
6019 string config = "{ " + genIfaceConfig() + ","
6020 "\"rebind-timer\": 2000, "
6021 "\"renew-timer\": 1000, "
6022 "\"subnet4\": [ { "
6023 " \"id\": 1,"
6024 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
6025 " \"subnet\": \"192.0.2.0/24\","
6026 " \"4o6-subnet\": \"2001:db8::543/21\","
6027 " \"4o6-interface\": \"ethX\" } ],"
6028 "\"valid-lifetime\": 4000 }";
6029
6030 ConstElementPtr json;
6031 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_6031
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6031
; } } else gtest_label_testnothrow_6031 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6031, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
6032 extractConfig(config);
6033
6034 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_6034; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_6034; } } else gtest_label_testnothrow_6034
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6034, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
6035
6036 // check if returned status is OK
6037 checkResult(status, 0);
6038
6039 // Now check if the configuration was indeed handled and we have
6040 // expected subnet configured...
6041 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
6042 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
6043 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6043, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
6044
6045 // ... and that subnet has 4o6 network interface specified.
6046 const Cfg4o6& dhcp4o6 = subnet->get4o6();
6047 EXPECT_TRUE(dhcp4o6.enabled())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(dhcp4o6.enabled())) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6047, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dhcp4o6.enabled()", "false", "true") .c_str()) = ::testing
::Message()
;
6048 EXPECT_EQ(IOAddress("2001:db8::543"), dhcp4o6.getSubnet4o6().get().first)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("IOAddress(\"2001:db8::543\")"
, "dhcp4o6.getSubnet4o6().get().first", IOAddress("2001:db8::543"
), dhcp4o6.getSubnet4o6().get().first))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6048, gtest_ar.failure_message()) = ::testing::Message()
;
6049 EXPECT_EQ(21U, dhcp4o6.getSubnet4o6().get().second)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("21U", "dhcp4o6.getSubnet4o6().get().second"
, 21U, dhcp4o6.getSubnet4o6().get().second))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6049
, gtest_ar.failure_message()) = ::testing::Message()
;
6050 EXPECT_EQ("ethX", dhcp4o6.getIface4o6().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"ethX\""
, "dhcp4o6.getIface4o6().get()", "ethX", dhcp4o6.getIface4o6(
).get()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6050, gtest_ar.failure_message()) = ::testing::Message()
;
6051}
6052
6053// Checks if the DHCPv4 is able to parse the configuration with 4o6 network
6054// interface-id.
6055TEST_F(Dhcp4ParserTest, 4o6subnetInterfaceId)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("4o6subnetInterfaceId") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_4o6subnetInterfaceId_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_4o6subnetInterfaceId_Test() = default
; ~Dhcp4ParserTest_4o6subnetInterfaceId_Test() override = default
; Dhcp4ParserTest_4o6subnetInterfaceId_Test (const Dhcp4ParserTest_4o6subnetInterfaceId_Test
&) = delete; Dhcp4ParserTest_4o6subnetInterfaceId_Test &
operator=( const Dhcp4ParserTest_4o6subnetInterfaceId_Test &
) = delete; Dhcp4ParserTest_4o6subnetInterfaceId_Test (Dhcp4ParserTest_4o6subnetInterfaceId_Test
&&) noexcept = delete; Dhcp4ParserTest_4o6subnetInterfaceId_Test
& operator=( Dhcp4ParserTest_4o6subnetInterfaceId_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_4o6subnetInterfaceId_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "4o6subnetInterfaceId", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6055), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6055), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6055), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_4o6subnetInterfaceId_Test
>); void Dhcp4ParserTest_4o6subnetInterfaceId_Test::TestBody
()
{
6056
6057 ConstElementPtr status;
6058
6059 // Just a plain v4 config (no 4o6 parameters)
6060 string config = "{ " + genIfaceConfig() + ","
6061 "\"rebind-timer\": 2000, "
6062 "\"renew-timer\": 1000, "
6063 "\"subnet4\": [ { "
6064 " \"id\": 1,"
6065 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
6066 " \"subnet\": \"192.0.2.0/24\","
6067 " \"4o6-interface-id\": \"vlan123\" } ],"
6068 "\"valid-lifetime\": 4000 }";
6069
6070 ConstElementPtr json;
6071 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_6071
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6071
; } } else gtest_label_testnothrow_6071 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6071, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
6072 extractConfig(config);
6073
6074 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_6074; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_6074; } } else gtest_label_testnothrow_6074
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6074, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
6075
6076 // check if returned status is OK
6077 checkResult(status, 0);
6078
6079 // Now check if the configuration was indeed handled and we have
6080 // expected 4o6-interface-id configured.
6081 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
6082 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
6083 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6083, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
6084
6085 const Cfg4o6& dhcp4o6 = subnet->get4o6();
6086 EXPECT_TRUE(dhcp4o6.enabled())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(dhcp4o6.enabled())) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6086, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dhcp4o6.enabled()", "false", "true") .c_str()) = ::testing
::Message()
;
6087 OptionPtr ifaceid = dhcp4o6.getInterfaceId();
6088 ASSERT_TRUE(ifaceid)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ifaceid)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6088, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ifaceid", "false", "true") .c_str()) = ::testing::Message(
)
;
6089
6090 vector<uint8_t> data = ifaceid->getData();
6091 EXPECT_EQ(7U, data.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("7U", "data.size()"
, 7U, data.size()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6091, gtest_ar.failure_message()) = ::testing::Message()
;
6092 const char *exp = "vlan123";
6093 EXPECT_EQ(0, memcmp(&data[0], exp, data.size()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("0", "memcmp(&data[0], exp, data.size())"
, 0, memcmp(&data[0], exp, data.size())))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6093
, gtest_ar.failure_message()) = ::testing::Message()
;
6094}
6095
6096// Verifies that simple list of valid classes parses and
6097// is staged for commit.
6098TEST_F(Dhcp4ParserTest, validClientClassDictionary)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("validClientClassDictionary") > 1,
"test_name must not be empty"); class Dhcp4ParserTest_validClientClassDictionary_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_validClientClassDictionary_Test
() = default; ~Dhcp4ParserTest_validClientClassDictionary_Test
() override = default; Dhcp4ParserTest_validClientClassDictionary_Test
(const Dhcp4ParserTest_validClientClassDictionary_Test &
) = delete; Dhcp4ParserTest_validClientClassDictionary_Test &
operator=( const Dhcp4ParserTest_validClientClassDictionary_Test
&) = delete; Dhcp4ParserTest_validClientClassDictionary_Test
(Dhcp4ParserTest_validClientClassDictionary_Test &&)
noexcept = delete; Dhcp4ParserTest_validClientClassDictionary_Test
& operator=( Dhcp4ParserTest_validClientClassDictionary_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_validClientClassDictionary_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "validClientClassDictionary", nullptr, nullptr, ::testing::
internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6098), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6098), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6098), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_validClientClassDictionary_Test
>); void Dhcp4ParserTest_validClientClassDictionary_Test::
TestBody()
{
6099 string config = "{ " + genIfaceConfig() + ","
6100 "\"valid-lifetime\": 4000, \n"
6101 "\"rebind-timer\": 2000, \n"
6102 "\"renew-timer\": 1000, \n"
6103 "\"client-classes\" : [ \n"
6104 " { \n"
6105 " \"name\": \"one\" \n"
6106 " }, \n"
6107 " { \n"
6108 " \"name\": \"two\" \n"
6109 " }, \n"
6110 " { \n"
6111 " \"name\": \"three\" \n"
6112 " } \n"
6113 "], \n"
6114 "\"subnet4\": [ { \n"
6115 " \"id\": 1, \n"
6116 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ], \n"
6117 " \"subnet\": \"192.0.2.0/24\" \n"
6118 " } ] \n"
6119 "} \n";
6120
6121 ConstElementPtr json;
6122 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_6122
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6122
; } } else gtest_label_testnothrow_6122 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6122, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
6123 extractConfig(config);
6124
6125 ConstElementPtr status;
6126 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_6126; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_6126; } } else gtest_label_testnothrow_6126
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6126, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
6127 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6127, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
6128 checkResult(status, 0);
6129
6130 // We check staging config because CfgMgr::commit hasn't been executed.
6131 ClientClassDictionaryPtr dictionary;
6132 dictionary = CfgMgr::instance().getStagingCfg()->getClientClassDictionary();
6133 ASSERT_TRUE(dictionary)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(dictionary)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6133, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dictionary", "false", "true") .c_str()) = ::testing::Message
()
;
6134 EXPECT_EQ(3U, dictionary->getClasses()->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("3U", "dictionary->getClasses()->size()"
, 3U, dictionary->getClasses()->size()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6134
, gtest_ar.failure_message()) = ::testing::Message()
;
6135
6136 // Execute the commit
6137 ASSERT_NO_THROW(CfgMgr::instance().commit())switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
CfgMgr::instance().commit(); } else static_assert(true, "");
} catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_6137
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6137
; } } else gtest_label_testnothrow_6137 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6137, ("Expected: " "CfgMgr::instance().commit()" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
6138
6139 // Verify that after commit, the current config has the correct dictionary
6140 dictionary = CfgMgr::instance().getCurrentCfg()->getClientClassDictionary();
6141 ASSERT_TRUE(dictionary)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(dictionary)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6141, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dictionary", "false", "true") .c_str()) = ::testing::Message
()
;
6142 EXPECT_EQ(3U, dictionary->getClasses()->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("3U", "dictionary->getClasses()->size()"
, 3U, dictionary->getClasses()->size()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6142
, gtest_ar.failure_message()) = ::testing::Message()
;
6143}
6144
6145// Verifies that a class list containing an invalid
6146// class definition causes a configuration error.
6147TEST_F(Dhcp4ParserTest, invalidClientClassDictionary)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("invalidClientClassDictionary") > 1
, "test_name must not be empty"); class Dhcp4ParserTest_invalidClientClassDictionary_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_invalidClientClassDictionary_Test
() = default; ~Dhcp4ParserTest_invalidClientClassDictionary_Test
() override = default; Dhcp4ParserTest_invalidClientClassDictionary_Test
(const Dhcp4ParserTest_invalidClientClassDictionary_Test &
) = delete; Dhcp4ParserTest_invalidClientClassDictionary_Test
& operator=( const Dhcp4ParserTest_invalidClientClassDictionary_Test
&) = delete; Dhcp4ParserTest_invalidClientClassDictionary_Test
(Dhcp4ParserTest_invalidClientClassDictionary_Test &&
) noexcept = delete; Dhcp4ParserTest_invalidClientClassDictionary_Test
& operator=( Dhcp4ParserTest_invalidClientClassDictionary_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_invalidClientClassDictionary_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "invalidClientClassDictionary", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6147), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6147), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6147), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_invalidClientClassDictionary_Test
>); void Dhcp4ParserTest_invalidClientClassDictionary_Test
::TestBody()
{
6148 string config = "{ " + genIfaceConfig() + ","
6149 "\"valid-lifetime\": 4000, \n"
6150 "\"rebind-timer\": 2000, \n"
6151 "\"renew-timer\": 1000, \n"
6152 "\"client-classes\" : [ \n"
6153 " { \n"
6154 " \"name\": \"one\", \n"
6155 " \"bogus\": \"bad\" \n"
6156 " } \n"
6157 "], \n"
6158 "\"subnet4\": [ { \n"
6159 " \"id\": 1, \n"
6160 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ], \n"
6161 " \"subnet\": \"192.0.2.0/24\" \n"
6162 " } ] \n"
6163 "} \n";
6164
6165 EXPECT_THROW(parseDHCP4(config), Dhcp4ParseError)switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { bool gtest_caught_expected = false; try { if (
::testing::internal::AlwaysTrue()) { parseDHCP4(config); } else
static_assert(true, ""); } catch (Dhcp4ParseError const&
) { gtest_caught_expected = true; } catch (typename std::conditional
< std::is_same<typename std::remove_cv<typename std::
remove_reference< Dhcp4ParseError>::type>::type, std
::exception>::value, const ::testing::internal::NeverThrown
&, const std::exception&>::type e) { gtest_msg.value
= "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws "; gtest_msg.value
+= ::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testthrow_6165; } catch (...
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_6165; } if (!gtest_caught_expected
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws nothing."; goto gtest_label_testthrow_6165
; } } else gtest_label_testthrow_6165 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6165, gtest_msg.value.c_str()) = ::testing::Message()
;
6166}
6167
6168// Verifies that simple list of valid classes parses and
6169// is staged for commit.
6170TEST_F(Dhcp4ParserTest, clientClassValidLifetime)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("clientClassValidLifetime") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_clientClassValidLifetime_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_clientClassValidLifetime_Test
() = default; ~Dhcp4ParserTest_clientClassValidLifetime_Test(
) override = default; Dhcp4ParserTest_clientClassValidLifetime_Test
(const Dhcp4ParserTest_clientClassValidLifetime_Test &) =
delete; Dhcp4ParserTest_clientClassValidLifetime_Test & operator
=( const Dhcp4ParserTest_clientClassValidLifetime_Test &)
= delete; Dhcp4ParserTest_clientClassValidLifetime_Test (Dhcp4ParserTest_clientClassValidLifetime_Test
&&) noexcept = delete; Dhcp4ParserTest_clientClassValidLifetime_Test
& operator=( Dhcp4ParserTest_clientClassValidLifetime_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_clientClassValidLifetime_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "clientClassValidLifetime", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6170), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6170), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6170), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_clientClassValidLifetime_Test
>); void Dhcp4ParserTest_clientClassValidLifetime_Test::TestBody
()
{
6171 string config = "{ " + genIfaceConfig() + ","
6172 "\"client-classes\" : [ \n"
6173 " { \n"
6174 " \"name\": \"one\", \n"
6175 " \"min-valid-lifetime\": 1000, \n"
6176 " \"valid-lifetime\": 2000, \n"
6177 " \"max-valid-lifetime\": 3000 \n"
6178 " }, \n"
6179 " { \n"
6180 " \"name\": \"two\" \n"
6181 " } \n"
6182 "], \n"
6183 "\"subnet4\": [ { \n"
6184 " \"id\": 1, \n"
6185 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ], \n"
6186 " \"subnet\": \"192.0.2.0/24\" \n"
6187 " } ] \n"
6188 "} \n";
6189
6190 ConstElementPtr json;
6191 ASSERT_NO_THROW_LOG(json = parseDHCP4(config)){ try { json = parseDHCP4(config); } catch (const std::exception
& ex) { return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6191, "Failed") = ::testing::Message() << "json = parseDHCP4(config)"
<< " threw type: " << typeid(ex).name() <<
", what: " << ex.what(); } catch (...) { return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6191
, "Failed") = ::testing::Message() << "json = parseDHCP4(config)"
<< " threw non-std::exception"; } }
;
6192 extractConfig(config);
6193
6194 ConstElementPtr status;
6195 ASSERT_NO_THROW_LOG(status = Dhcpv4SrvTest::configure(*srv_, json)){ try { status = Dhcpv4SrvTest::configure(*srv_, json); } catch
(const std::exception& ex) { return ::testing::internal::
AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6195, "Failed") = ::testing::Message() << "status = Dhcpv4SrvTest::configure(*srv_, json)"
<< " threw type: " << typeid(ex).name() <<
", what: " << ex.what(); } catch (...) { return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6195
, "Failed") = ::testing::Message() << "status = Dhcpv4SrvTest::configure(*srv_, json)"
<< " threw non-std::exception"; } }
;
6196 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6196, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
6197 checkResult(status, 0);
6198
6199 // We check staging config because CfgMgr::commit hasn't been executed.
6200 ClientClassDictionaryPtr dictionary;
6201 dictionary = CfgMgr::instance().getStagingCfg()->getClientClassDictionary();
6202 ASSERT_TRUE(dictionary)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(dictionary)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6202, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dictionary", "false", "true") .c_str()) = ::testing::Message
()
;
6203 EXPECT_EQ(2U, dictionary->getClasses()->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "dictionary->getClasses()->size()"
, 2U, dictionary->getClasses()->size()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6203
, gtest_ar.failure_message()) = ::testing::Message()
;
6204
6205 // Execute the commit
6206 ASSERT_NO_THROW(CfgMgr::instance().commit())switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
CfgMgr::instance().commit(); } else static_assert(true, "");
} catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_6206
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6206
; } } else gtest_label_testnothrow_6206 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6206, ("Expected: " "CfgMgr::instance().commit()" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
6207
6208 // Verify that after commit, the current config has the correct dictionary
6209 dictionary = CfgMgr::instance().getCurrentCfg()->getClientClassDictionary();
6210 ASSERT_TRUE(dictionary)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(dictionary)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6210, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dictionary", "false", "true") .c_str()) = ::testing::Message
()
;
6211 EXPECT_EQ(2U, dictionary->getClasses()->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "dictionary->getClasses()->size()"
, 2U, dictionary->getClasses()->size()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6211
, gtest_ar.failure_message()) = ::testing::Message()
;
6212
6213 ClientClassDefPtr class_def = dictionary->findClass("one");
6214 ASSERT_TRUE(class_def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(class_def)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6214, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "class_def", "false", "true") .c_str()) = ::testing::Message
()
;
6215 EXPECT_EQ(class_def->getValid().getMin(), 1000U)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("class_def->getValid().getMin()"
, "1000U", class_def->getValid().getMin(), 1000U))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6215, gtest_ar.failure_message()) = ::testing::Message()
;
6216 EXPECT_EQ(class_def->getValid().get(), 2000U)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("class_def->getValid().get()"
, "2000U", class_def->getValid().get(), 2000U))) ; else ::
testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6216
, gtest_ar.failure_message()) = ::testing::Message()
;
6217 EXPECT_EQ(class_def->getValid().getMax(), 3000U)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("class_def->getValid().getMax()"
, "3000U", class_def->getValid().getMax(), 3000U))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6217, gtest_ar.failure_message()) = ::testing::Message()
;
6218
6219 class_def = dictionary->findClass("two");
6220 ASSERT_TRUE(class_def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(class_def)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6220, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "class_def", "false", "true") .c_str()) = ::testing::Message
()
;
6221 EXPECT_TRUE(class_def->getValid().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(class_def->getValid
().unspecified())) ; else ::testing::internal::AssertHelper(::
testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6221, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "class_def->getValid().unspecified()", "false", "true") .
c_str()) = ::testing::Message()
;
6222}
6223
6224// Verifies that simple list of valid template classes parses and
6225// is staged for commit.
6226TEST_F(Dhcp4ParserTest, templateClientClassValidLifetime)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("templateClientClassValidLifetime") >
1, "test_name must not be empty"); class Dhcp4ParserTest_templateClientClassValidLifetime_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_templateClientClassValidLifetime_Test
() = default; ~Dhcp4ParserTest_templateClientClassValidLifetime_Test
() override = default; Dhcp4ParserTest_templateClientClassValidLifetime_Test
(const Dhcp4ParserTest_templateClientClassValidLifetime_Test
&) = delete; Dhcp4ParserTest_templateClientClassValidLifetime_Test
& operator=( const Dhcp4ParserTest_templateClientClassValidLifetime_Test
&) = delete; Dhcp4ParserTest_templateClientClassValidLifetime_Test
(Dhcp4ParserTest_templateClientClassValidLifetime_Test &&
) noexcept = delete; Dhcp4ParserTest_templateClientClassValidLifetime_Test
& operator=( Dhcp4ParserTest_templateClientClassValidLifetime_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_templateClientClassValidLifetime_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "templateClientClassValidLifetime", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6226), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6226), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6226), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_templateClientClassValidLifetime_Test
>); void Dhcp4ParserTest_templateClientClassValidLifetime_Test
::TestBody()
{
6227 string config = "{ " + genIfaceConfig() + ","
6228 "\"client-classes\" : [ \n"
6229 " { \n"
6230 " \"name\": \"one\", \n"
6231 " \"min-valid-lifetime\": 1000, \n"
6232 " \"valid-lifetime\": 2000, \n"
6233 " \"max-valid-lifetime\": 3000, \n"
6234 " \"template-test\": \"''\" \n"
6235 " }, \n"
6236 " { \n"
6237 " \"name\": \"two\", \n"
6238 " \"template-test\": \"''\" \n"
6239 " } \n"
6240 "], \n"
6241 "\"subnet4\": [ { \n"
6242 " \"id\": 1, \n"
6243 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ], \n"
6244 " \"subnet\": \"192.0.2.0/24\" \n"
6245 " } ] \n"
6246 "} \n";
6247
6248 ConstElementPtr json;
6249 ASSERT_NO_THROW_LOG(json = parseDHCP4(config)){ try { json = parseDHCP4(config); } catch (const std::exception
& ex) { return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6249, "Failed") = ::testing::Message() << "json = parseDHCP4(config)"
<< " threw type: " << typeid(ex).name() <<
", what: " << ex.what(); } catch (...) { return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6249
, "Failed") = ::testing::Message() << "json = parseDHCP4(config)"
<< " threw non-std::exception"; } }
;
6250 extractConfig(config);
6251
6252 ConstElementPtr status;
6253 ASSERT_NO_THROW_LOG(status = Dhcpv4SrvTest::configure(*srv_, json)){ try { status = Dhcpv4SrvTest::configure(*srv_, json); } catch
(const std::exception& ex) { return ::testing::internal::
AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6253, "Failed") = ::testing::Message() << "status = Dhcpv4SrvTest::configure(*srv_, json)"
<< " threw type: " << typeid(ex).name() <<
", what: " << ex.what(); } catch (...) { return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6253
, "Failed") = ::testing::Message() << "status = Dhcpv4SrvTest::configure(*srv_, json)"
<< " threw non-std::exception"; } }
;
6254 ASSERT_TRUE(status)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(status)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6254, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
6255 checkResult(status, 0);
6256
6257 // We check staging config because CfgMgr::commit hasn't been executed.
6258 ClientClassDictionaryPtr dictionary;
6259 dictionary = CfgMgr::instance().getStagingCfg()->getClientClassDictionary();
6260 ASSERT_TRUE(dictionary)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(dictionary)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6260, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dictionary", "false", "true") .c_str()) = ::testing::Message
()
;
6261 EXPECT_EQ(2U, dictionary->getClasses()->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "dictionary->getClasses()->size()"
, 2U, dictionary->getClasses()->size()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6261
, gtest_ar.failure_message()) = ::testing::Message()
;
6262
6263 // Execute the commit
6264 ASSERT_NO_THROW(CfgMgr::instance().commit())switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
CfgMgr::instance().commit(); } else static_assert(true, "");
} catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_6264
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6264
; } } else gtest_label_testnothrow_6264 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6264, ("Expected: " "CfgMgr::instance().commit()" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
6265
6266 // Verify that after commit, the current config has the correct dictionary
6267 dictionary = CfgMgr::instance().getCurrentCfg()->getClientClassDictionary();
6268 ASSERT_TRUE(dictionary)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(dictionary)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6268, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dictionary", "false", "true") .c_str()) = ::testing::Message
()
;
6269 EXPECT_EQ(2U, dictionary->getClasses()->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "dictionary->getClasses()->size()"
, 2U, dictionary->getClasses()->size()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6269
, gtest_ar.failure_message()) = ::testing::Message()
;
6270
6271 ClientClassDefPtr class_def = dictionary->findClass("one");
6272 ASSERT_TRUE(class_def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(class_def)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6272, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "class_def", "false", "true") .c_str()) = ::testing::Message
()
;
6273 ASSERT_TRUE(dynamic_cast<TemplateClientClassDef*>(class_def.get()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(dynamic_cast<TemplateClientClassDef
*>(class_def.get()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6273, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dynamic_cast<TemplateClientClassDef*>(class_def.get())"
, "false", "true") .c_str()) = ::testing::Message()
;
6274 EXPECT_EQ(class_def->getValid().getMin(), 1000U)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("class_def->getValid().getMin()"
, "1000U", class_def->getValid().getMin(), 1000U))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6274, gtest_ar.failure_message()) = ::testing::Message()
;
6275 EXPECT_EQ(class_def->getValid().get(), 2000U)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("class_def->getValid().get()"
, "2000U", class_def->getValid().get(), 2000U))) ; else ::
testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6275
, gtest_ar.failure_message()) = ::testing::Message()
;
6276 EXPECT_EQ(class_def->getValid().getMax(), 3000U)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("class_def->getValid().getMax()"
, "3000U", class_def->getValid().getMax(), 3000U))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6276, gtest_ar.failure_message()) = ::testing::Message()
;
6277
6278 class_def = dictionary->findClass("two");
6279 ASSERT_TRUE(class_def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(class_def)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6279, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "class_def", "false", "true") .c_str()) = ::testing::Message
()
;
6280 ASSERT_TRUE(dynamic_cast<TemplateClientClassDef*>(class_def.get()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(dynamic_cast<TemplateClientClassDef
*>(class_def.get()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6280, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dynamic_cast<TemplateClientClassDef*>(class_def.get())"
, "false", "true") .c_str()) = ::testing::Message()
;
6281 EXPECT_TRUE(class_def->getValid().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(class_def->getValid
().unspecified())) ; else ::testing::internal::AssertHelper(::
testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6281, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "class_def->getValid().unspecified()", "false", "true") .
c_str()) = ::testing::Message()
;
6282}
6283
6284// Test verifies that regular configuration does not provide any user context
6285// in the address pool.
6286TEST_F(Dhcp4ParserTest, poolUserContextMissing)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("poolUserContextMissing") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_poolUserContextMissing_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_poolUserContextMissing_Test
() = default; ~Dhcp4ParserTest_poolUserContextMissing_Test() override
= default; Dhcp4ParserTest_poolUserContextMissing_Test (const
Dhcp4ParserTest_poolUserContextMissing_Test &) = delete;
Dhcp4ParserTest_poolUserContextMissing_Test & operator=(
const Dhcp4ParserTest_poolUserContextMissing_Test &) = delete
; Dhcp4ParserTest_poolUserContextMissing_Test (Dhcp4ParserTest_poolUserContextMissing_Test
&&) noexcept = delete; Dhcp4ParserTest_poolUserContextMissing_Test
& operator=( Dhcp4ParserTest_poolUserContextMissing_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_poolUserContextMissing_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "poolUserContextMissing", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6286), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6286), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6286), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_poolUserContextMissing_Test
>); void Dhcp4ParserTest_poolUserContextMissing_Test::TestBody
()
{
6287 extractConfig(PARSER_CONFIGS[0]);
6288 PoolPtr pool;
6289 getPool(string(PARSER_CONFIGS[0]), 0, 0, pool);
6290 ASSERT_TRUE(pool)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6290
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
6291 EXPECT_FALSE(pool->getContext())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pool->getContext
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6291, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getContext()", "true", "false") .c_str()) = ::testing
::Message()
;
6292}
6293
6294// Test verifies that it's possible to specify empty user context in the
6295// address pool.
6296TEST_F(Dhcp4ParserTest, poolUserContextEmpty)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("poolUserContextEmpty") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_poolUserContextEmpty_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_poolUserContextEmpty_Test() = default
; ~Dhcp4ParserTest_poolUserContextEmpty_Test() override = default
; Dhcp4ParserTest_poolUserContextEmpty_Test (const Dhcp4ParserTest_poolUserContextEmpty_Test
&) = delete; Dhcp4ParserTest_poolUserContextEmpty_Test &
operator=( const Dhcp4ParserTest_poolUserContextEmpty_Test &
) = delete; Dhcp4ParserTest_poolUserContextEmpty_Test (Dhcp4ParserTest_poolUserContextEmpty_Test
&&) noexcept = delete; Dhcp4ParserTest_poolUserContextEmpty_Test
& operator=( Dhcp4ParserTest_poolUserContextEmpty_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_poolUserContextEmpty_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "poolUserContextEmpty", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6296), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6296), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6296), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_poolUserContextEmpty_Test
>); void Dhcp4ParserTest_poolUserContextEmpty_Test::TestBody
()
{
6297 extractConfig(PARSER_CONFIGS[1]);
6298 PoolPtr pool;
6299 getPool(string(PARSER_CONFIGS[1]), 0, 0, pool);
6300 ASSERT_TRUE(pool)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6300
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
6301 ConstElementPtr ctx = pool->getContext();
6302 ASSERT_TRUE(ctx)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6302
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx", "false", "true") .c_str()) = ::testing::Message()
;
6303
6304 // The context should be of type map and not contain any parameters.
6305 EXPECT_EQ(Element::map, ctx->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("Element::map"
, "ctx->getType()", Element::map, ctx->getType()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6305, gtest_ar.failure_message()) = ::testing::Message()
;
6306 EXPECT_EQ(0U, ctx->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("0U", "ctx->size()"
, 0U, ctx->size()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6306, gtest_ar.failure_message()) = ::testing::Message()
;
6307}
6308
6309// Test verifies that it's possible to specify parameters in the user context
6310// in the address pool.
6311TEST_F(Dhcp4ParserTest, poolUserContextData)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("poolUserContextData") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_poolUserContextData_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_poolUserContextData_Test() = default
; ~Dhcp4ParserTest_poolUserContextData_Test() override = default
; Dhcp4ParserTest_poolUserContextData_Test (const Dhcp4ParserTest_poolUserContextData_Test
&) = delete; Dhcp4ParserTest_poolUserContextData_Test &
operator=( const Dhcp4ParserTest_poolUserContextData_Test &
) = delete; Dhcp4ParserTest_poolUserContextData_Test (Dhcp4ParserTest_poolUserContextData_Test
&&) noexcept = delete; Dhcp4ParserTest_poolUserContextData_Test
& operator=( Dhcp4ParserTest_poolUserContextData_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_poolUserContextData_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "poolUserContextData", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6311), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6311), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6311), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_poolUserContextData_Test
>); void Dhcp4ParserTest_poolUserContextData_Test::TestBody
()
{
6312 extractConfig(PARSER_CONFIGS[2]);
6313 PoolPtr pool;
6314 getPool(string(PARSER_CONFIGS[2]), 0, 0, pool);
6315 ASSERT_TRUE(pool)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6315
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
6316 ConstElementPtr ctx = pool->getContext();
6317 ASSERT_TRUE(ctx)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6317
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx", "false", "true") .c_str()) = ::testing::Message()
;
6318
6319 // The context should be of type map and contain 4 parameters.
6320 EXPECT_EQ(Element::map, ctx->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("Element::map"
, "ctx->getType()", Element::map, ctx->getType()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6320, gtest_ar.failure_message()) = ::testing::Message()
;
6321 EXPECT_EQ(3U, ctx->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("3U", "ctx->size()"
, 3U, ctx->size()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6321, gtest_ar.failure_message()) = ::testing::Message()
;
6322 ConstElementPtr int_param = ctx->get("integer-param");
6323 ConstElementPtr str_param = ctx->get("string-param");
6324 ConstElementPtr bool_param = ctx->get("bool-param");
6325
6326 ASSERT_TRUE(int_param)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(int_param)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6326, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "int_param", "false", "true") .c_str()) = ::testing::Message
()
;
6327 ASSERT_EQ(Element::integer, int_param->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("Element::integer"
, "int_param->getType()", Element::integer, int_param->
getType()))) ; else return ::testing::internal::AssertHelper(
::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6327, gtest_ar.failure_message()) = ::testing::Message()
;
6328 int64_t int_value;
6329 EXPECT_NO_THROW(int_param->getValue(int_value))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
int_param->getValue(int_value); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_6329
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6329
; } } else gtest_label_testnothrow_6329 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6329, ("Expected: " "int_param->getValue(int_value)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
6330 EXPECT_EQ(42L, int_value)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("42L", "int_value"
, 42L, int_value))) ; else ::testing::internal::AssertHelper(
::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6330, gtest_ar.failure_message()) = ::testing::Message()
;
6331
6332 ASSERT_TRUE(str_param)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(str_param)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6332, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "str_param", "false", "true") .c_str()) = ::testing::Message
()
;
6333 ASSERT_EQ(Element::string, str_param->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("Element::string"
, "str_param->getType()", Element::string, str_param->getType
()))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6333, gtest_ar.failure_message()) = ::testing::Message()
;
6334 EXPECT_EQ("Sagittarius", str_param->stringValue())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"Sagittarius\""
, "str_param->stringValue()", "Sagittarius", str_param->
stringValue()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6334, gtest_ar.failure_message()) = ::testing::Message()
;
6335
6336 ASSERT_TRUE(bool_param)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(bool_param)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6336, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "bool_param", "false", "true") .c_str()) = ::testing::Message
()
;
6337 bool bool_value;
6338 ASSERT_EQ(Element::boolean, bool_param->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("Element::boolean"
, "bool_param->getType()", Element::boolean, bool_param->
getType()))) ; else return ::testing::internal::AssertHelper(
::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6338, gtest_ar.failure_message()) = ::testing::Message()
;
6339 EXPECT_NO_THROW(bool_param->getValue(bool_value))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
bool_param->getValue(bool_value); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_6339
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6339
; } } else gtest_label_testnothrow_6339 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6339, ("Expected: " "bool_param->getValue(bool_value)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
6340 EXPECT_TRUE(bool_value)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(bool_value)) ; else ::
testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6340
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "bool_value", "false", "true") .c_str()) = ::testing::Message
()
;
6341}
6342
6343// Test verifies that it's possible to specify parameters in the user context
6344// in the min-max address pool.
6345TEST_F(Dhcp4ParserTest, poolMinMaxUserContext)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("poolMinMaxUserContext") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_poolMinMaxUserContext_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_poolMinMaxUserContext_Test() = default
; ~Dhcp4ParserTest_poolMinMaxUserContext_Test() override = default
; Dhcp4ParserTest_poolMinMaxUserContext_Test (const Dhcp4ParserTest_poolMinMaxUserContext_Test
&) = delete; Dhcp4ParserTest_poolMinMaxUserContext_Test &
operator=( const Dhcp4ParserTest_poolMinMaxUserContext_Test &
) = delete; Dhcp4ParserTest_poolMinMaxUserContext_Test (Dhcp4ParserTest_poolMinMaxUserContext_Test
&&) noexcept = delete; Dhcp4ParserTest_poolMinMaxUserContext_Test
& operator=( Dhcp4ParserTest_poolMinMaxUserContext_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_poolMinMaxUserContext_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "poolMinMaxUserContext", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6345), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6345), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6345), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_poolMinMaxUserContext_Test
>); void Dhcp4ParserTest_poolMinMaxUserContext_Test::TestBody
()
{
6346 extractConfig(PARSER_CONFIGS[3]);
6347 PoolPtr pool;
6348 getPool(string(PARSER_CONFIGS[3]), 0, 0, pool);
6349 ASSERT_TRUE(pool)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6349
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
1
Control jumps to 'case 0:' at line 6349
2
Taking true branch
6350 ConstElementPtr ctx = pool->getContext();
6351 ASSERT_TRUE(ctx)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6351
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx", "false", "true") .c_str()) = ::testing::Message()
;
3
Control jumps to 'case 0:' at line 6351
4
Taking true branch
6352
6353 // The context should be of type map and contain 4 parameters.
6354 EXPECT_EQ(Element::map, ctx->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("Element::map"
, "ctx->getType()", Element::map, ctx->getType()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6354, gtest_ar.failure_message()) = ::testing::Message()
;
5
Control jumps to 'case 0:' at line 6354
6
Assuming the condition is true
7
Taking true branch
6355 EXPECT_EQ(3U, ctx->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("3U", "ctx->size()"
, 3U, ctx->size()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6355, gtest_ar.failure_message()) = ::testing::Message()
;
8
Control jumps to 'case 0:' at line 6355
9
Assuming the condition is true
10
Taking true branch
6356 ConstElementPtr int_param = ctx->get("integer-param");
6357 ConstElementPtr str_param = ctx->get("string-param");
6358 ConstElementPtr bool_param = ctx->get("bool-param");
6359
6360 ASSERT_TRUE(int_param)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(int_param)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6360, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "int_param", "false", "true") .c_str()) = ::testing::Message
()
;
11
Control jumps to 'case 0:' at line 6360
12
Taking true branch
6361 ASSERT_EQ(Element::integer, int_param->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("Element::integer"
, "int_param->getType()", Element::integer, int_param->
getType()))) ; else return ::testing::internal::AssertHelper(
::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6361, gtest_ar.failure_message()) = ::testing::Message()
;
13
Control jumps to 'case 0:' at line 6361
14
Assuming the condition is true
15
Taking true branch
6362 int64_t int_value;
6363 EXPECT_NO_THROW(int_param->getValue(int_value))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
int_param->getValue(int_value); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_6363
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6363
; } } else gtest_label_testnothrow_6363 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6363, ("Expected: " "int_param->getValue(int_value)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
16
Control jumps to 'case 0:' at line 6363
17
Taking true branch
18
Assuming the condition is true
19
Taking true branch
6364 EXPECT_EQ(42L, int_value)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("42L", "int_value"
, 42L, int_value))) ; else ::testing::internal::AssertHelper(
::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6364, gtest_ar.failure_message()) = ::testing::Message()
;
20
Control jumps to 'case 0:' at line 6364
21
Assuming the condition is false
22
Taking false branch
6365
6366 ASSERT_TRUE(str_param)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(str_param)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6366, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "str_param", "false", "true") .c_str()) = ::testing::Message
()
;
23
Control jumps to 'case 0:' at line 6366
24
Taking true branch
6367 ASSERT_EQ(Element::string, str_param->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("Element::string"
, "str_param->getType()", Element::string, str_param->getType
()))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6367, gtest_ar.failure_message()) = ::testing::Message()
;
25
Control jumps to 'case 0:' at line 6367
26
Assuming the condition is true
27
Taking true branch
6368 EXPECT_EQ("Sagittarius", str_param->stringValue())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"Sagittarius\""
, "str_param->stringValue()", "Sagittarius", str_param->
stringValue()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6368, gtest_ar.failure_message()) = ::testing::Message()
;
28
Control jumps to 'case 0:' at line 6368
29
Assuming the condition is true
30
Taking true branch
6369
6370 ASSERT_TRUE(bool_param)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(bool_param)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6370, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "bool_param", "false", "true") .c_str()) = ::testing::Message
()
;
31
Control jumps to 'case 0:' at line 6370
32
Taking true branch
6371 bool bool_value;
6372 ASSERT_EQ(Element::boolean, bool_param->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("Element::boolean"
, "bool_param->getType()", Element::boolean, bool_param->
getType()))) ; else return ::testing::internal::AssertHelper(
::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6372, gtest_ar.failure_message()) = ::testing::Message()
;
33
Control jumps to 'case 0:' at line 6372
34
Assuming the condition is true
35
Taking true branch
6373 EXPECT_NO_THROW(bool_param->getValue(bool_value))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
bool_param->getValue(bool_value); } else static_assert(true
, ""); } catch (std::exception const& e) { gtest_msg.value
= "it throws "; gtest_msg.value += ::testing::internal::GetTypeName
(typeid(e)); gtest_msg.value += " with description \""; gtest_msg
.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_6373
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6373
; } } else gtest_label_testnothrow_6373 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6373, ("Expected: " "bool_param->getValue(bool_value)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
36
Control jumps to 'case 0:' at line 6373
37
Taking true branch
38
Assuming the condition is false
39
Taking false branch
6374 EXPECT_TRUE(bool_value)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(bool_value)) ; else ::
testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6374
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "bool_value", "false", "true") .c_str()) = ::testing::Message
()
;
40
Control jumps to 'case 0:' at line 6374
41
Calling constructor for 'AssertionResult'
6375}
6376
6377// Test verifies the error message for an incorrect pool range
6378// is what we expect.
6379TEST_F(Dhcp4ParserTest, invalidPoolRange)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("invalidPoolRange") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_invalidPoolRange_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_invalidPoolRange_Test() = default;
~Dhcp4ParserTest_invalidPoolRange_Test() override = default;
Dhcp4ParserTest_invalidPoolRange_Test (const Dhcp4ParserTest_invalidPoolRange_Test
&) = delete; Dhcp4ParserTest_invalidPoolRange_Test &
operator=( const Dhcp4ParserTest_invalidPoolRange_Test &
) = delete; Dhcp4ParserTest_invalidPoolRange_Test (Dhcp4ParserTest_invalidPoolRange_Test
&&) noexcept = delete; Dhcp4ParserTest_invalidPoolRange_Test
& operator=( Dhcp4ParserTest_invalidPoolRange_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_invalidPoolRange_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "invalidPoolRange", nullptr, nullptr, ::testing::internal::
CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6379), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6379), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6379), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_invalidPoolRange_Test
>); void Dhcp4ParserTest_invalidPoolRange_Test::TestBody()
{
6380 string config = "{ " + genIfaceConfig() + ", \n" +
6381 "\"valid-lifetime\": 4000, \n"
6382 "\"rebind-timer\": 2000, \n"
6383 "\"renew-timer\": 1000, \n"
6384 "\"subnet4\": [ { \n"
6385 " \"id\": 1, \n"
6386 " \"pools\": [ { \"pool\": \"192.0.2.1 - 19.2.0.200\" } ], \n"
6387 " \"subnet\": \"192.0.2.0/24\" \n"
6388 " } ] \n"
6389 "} \n";
6390
6391 string expected = "Failed to create pool defined by: "
6392 "192.0.2.1-19.2.0.200 (<string>:7:26)";
6393
6394 configure(config, CONTROL_RESULT_ERROR, expected);
6395}
6396
6397// Test verifies the error message for an outside subnet pool range
6398// is what we expect.
6399TEST_F(Dhcp4ParserTest, outsideSubnetPool)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("outsideSubnetPool") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_outsideSubnetPool_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_outsideSubnetPool_Test() = default
; ~Dhcp4ParserTest_outsideSubnetPool_Test() override = default
; Dhcp4ParserTest_outsideSubnetPool_Test (const Dhcp4ParserTest_outsideSubnetPool_Test
&) = delete; Dhcp4ParserTest_outsideSubnetPool_Test &
operator=( const Dhcp4ParserTest_outsideSubnetPool_Test &
) = delete; Dhcp4ParserTest_outsideSubnetPool_Test (Dhcp4ParserTest_outsideSubnetPool_Test
&&) noexcept = delete; Dhcp4ParserTest_outsideSubnetPool_Test
& operator=( Dhcp4ParserTest_outsideSubnetPool_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_outsideSubnetPool_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "outsideSubnetPool", nullptr, nullptr, ::testing::internal::
CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6399), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6399), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6399), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_outsideSubnetPool_Test
>); void Dhcp4ParserTest_outsideSubnetPool_Test::TestBody(
)
{
6400 string config = "{ " + genIfaceConfig() + ", \n" +
6401 "\"valid-lifetime\": 4000, \n"
6402 "\"rebind-timer\": 2000, \n"
6403 "\"renew-timer\": 1000, \n"
6404 "\"subnet4\": [ { \n"
6405 " \"id\": 1, \n"
6406 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ], \n"
6407 " \"subnet\": \"10.0.2.0/24\" \n"
6408 " } ] \n"
6409 "} \n";
6410
6411 string expected = "subnet configuration failed: "
6412 "a pool of type V4, with the following address range: "
6413 "192.0.2.1-192.0.2.100 does not match the prefix of a subnet: "
6414 "10.0.2.0/24 to which it is being added (<string>:5:14)";
6415
6416 configure(config, CONTROL_RESULT_ERROR, expected);
6417}
6418
6419// Test verifies that empty shared networks are accepted.
6420TEST_F(Dhcp4ParserTest, sharedNetworksEmpty)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("sharedNetworksEmpty") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_sharedNetworksEmpty_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_sharedNetworksEmpty_Test() = default
; ~Dhcp4ParserTest_sharedNetworksEmpty_Test() override = default
; Dhcp4ParserTest_sharedNetworksEmpty_Test (const Dhcp4ParserTest_sharedNetworksEmpty_Test
&) = delete; Dhcp4ParserTest_sharedNetworksEmpty_Test &
operator=( const Dhcp4ParserTest_sharedNetworksEmpty_Test &
) = delete; Dhcp4ParserTest_sharedNetworksEmpty_Test (Dhcp4ParserTest_sharedNetworksEmpty_Test
&&) noexcept = delete; Dhcp4ParserTest_sharedNetworksEmpty_Test
& operator=( Dhcp4ParserTest_sharedNetworksEmpty_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_sharedNetworksEmpty_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "sharedNetworksEmpty", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6420), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6420), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6420), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworksEmpty_Test
>); void Dhcp4ParserTest_sharedNetworksEmpty_Test::TestBody
()
{
6421 string config = "{\n"
6422 "\"valid-lifetime\": 4000, \n"
6423 "\"rebind-timer\": 2000, \n"
6424 "\"renew-timer\": 1000, \n"
6425 "\"subnet4\": [ { \n"
6426 " \"id\": 1, \n"
6427 " \"pools\": [ { \"pool\": \"10.0.2.1 - 10.0.2.100\" } ], \n"
6428 " \"subnet\": \"10.0.2.0/24\" \n"
6429 " } ],\n"
6430 "\"shared-networks\": [ ]\n"
6431 "} \n";
6432
6433 configure(config, CONTROL_RESULT_SUCCESS, "");
6434}
6435
6436// Test verifies that if a shared network is defined, it at least has to have
6437// a name.
6438TEST_F(Dhcp4ParserTest, sharedNetworksNoName)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("sharedNetworksNoName") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_sharedNetworksNoName_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_sharedNetworksNoName_Test() = default
; ~Dhcp4ParserTest_sharedNetworksNoName_Test() override = default
; Dhcp4ParserTest_sharedNetworksNoName_Test (const Dhcp4ParserTest_sharedNetworksNoName_Test
&) = delete; Dhcp4ParserTest_sharedNetworksNoName_Test &
operator=( const Dhcp4ParserTest_sharedNetworksNoName_Test &
) = delete; Dhcp4ParserTest_sharedNetworksNoName_Test (Dhcp4ParserTest_sharedNetworksNoName_Test
&&) noexcept = delete; Dhcp4ParserTest_sharedNetworksNoName_Test
& operator=( Dhcp4ParserTest_sharedNetworksNoName_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_sharedNetworksNoName_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "sharedNetworksNoName", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6438), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6438), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6438), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworksNoName_Test
>); void Dhcp4ParserTest_sharedNetworksNoName_Test::TestBody
()
{
6439 string config = "{\n"
6440 "\"valid-lifetime\": 4000, \n"
6441 "\"rebind-timer\": 2000, \n"
6442 "\"renew-timer\": 1000, \n"
6443 "\"subnet4\": [ { \n"
6444 " \"id\": 1, \n"
6445 " \"pools\": [ { \"pool\": \"10.0.2.1 - 10.0.2.100\" } ], \n"
6446 " \"subnet\": \"10.0.2.0/24\" \n"
6447 " } ],\n"
6448 "\"shared-networks\": [ { } ]\n"
6449 "} \n";
6450
6451 EXPECT_THROW(parseDHCP4(config, true), Dhcp4ParseError)switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { bool gtest_caught_expected = false; try { if (
::testing::internal::AlwaysTrue()) { parseDHCP4(config, true)
; } else static_assert(true, ""); } catch (Dhcp4ParseError const
&) { gtest_caught_expected = true; } catch (typename std::
conditional< std::is_same<typename std::remove_cv<typename
std::remove_reference< Dhcp4ParseError>::type>::type
, std::exception>::value, const ::testing::internal::NeverThrown
&, const std::exception&>::type e) { gtest_msg.value
= "Expected: " "parseDHCP4(config, true)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws "; gtest_msg.value
+= ::testing::internal::GetTypeName(typeid(e)); gtest_msg.value
+= " with description \""; gtest_msg.value += e.what(); gtest_msg
.value += "\"."; goto gtest_label_testthrow_6451; } catch (...
) { gtest_msg.value = "Expected: " "parseDHCP4(config, true)"
" throws an exception of type " "Dhcp4ParseError" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_6451; } if (!gtest_caught_expected
) { gtest_msg.value = "Expected: " "parseDHCP4(config, true)"
" throws an exception of type " "Dhcp4ParseError" ".\n Actual: it throws nothing."
; goto gtest_label_testthrow_6451; } } else gtest_label_testthrow_6451
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6451, gtest_msg.value.c_str()) = ::testing::Message()
;
6452}
6453
6454// Test verifies that empty shared networks are accepted.
6455TEST_F(Dhcp4ParserTest, sharedNetworksEmptyName)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("sharedNetworksEmptyName") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_sharedNetworksEmptyName_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_sharedNetworksEmptyName_Test
() = default; ~Dhcp4ParserTest_sharedNetworksEmptyName_Test()
override = default; Dhcp4ParserTest_sharedNetworksEmptyName_Test
(const Dhcp4ParserTest_sharedNetworksEmptyName_Test &) =
delete; Dhcp4ParserTest_sharedNetworksEmptyName_Test & operator
=( const Dhcp4ParserTest_sharedNetworksEmptyName_Test &) =
delete; Dhcp4ParserTest_sharedNetworksEmptyName_Test (Dhcp4ParserTest_sharedNetworksEmptyName_Test
&&) noexcept = delete; Dhcp4ParserTest_sharedNetworksEmptyName_Test
& operator=( Dhcp4ParserTest_sharedNetworksEmptyName_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_sharedNetworksEmptyName_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "sharedNetworksEmptyName", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6455), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6455), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6455), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworksEmptyName_Test
>); void Dhcp4ParserTest_sharedNetworksEmptyName_Test::TestBody
()
{
6456 string config = "{\n"
6457 "\"valid-lifetime\": 4000, \n"
6458 "\"rebind-timer\": 2000, \n"
6459 "\"renew-timer\": 1000, \n"
6460 "\"subnet4\": [ { \n"
6461 " \"id\": 1, \n"
6462 " \"pools\": [ { \"pool\": \"10.0.2.1 - 10.0.2.100\" } ], \n"
6463 " \"subnet\": \"10.0.2.0/24\" \n"
6464 " } ],\n"
6465 "\"shared-networks\": [ { \"name\": \"\" } ]\n"
6466 "} \n";
6467
6468 configure(config, CONTROL_RESULT_ERROR,
6469 "Shared-network with subnets is missing mandatory 'name' parameter");
6470}
6471
6472// Test verifies that a degenerated shared-network (no subnets) is
6473// accepted.
6474TEST_F(Dhcp4ParserTest, sharedNetworksName)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("sharedNetworksName") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_sharedNetworksName_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_sharedNetworksName_Test() = default
; ~Dhcp4ParserTest_sharedNetworksName_Test() override = default
; Dhcp4ParserTest_sharedNetworksName_Test (const Dhcp4ParserTest_sharedNetworksName_Test
&) = delete; Dhcp4ParserTest_sharedNetworksName_Test &
operator=( const Dhcp4ParserTest_sharedNetworksName_Test &
) = delete; Dhcp4ParserTest_sharedNetworksName_Test (Dhcp4ParserTest_sharedNetworksName_Test
&&) noexcept = delete; Dhcp4ParserTest_sharedNetworksName_Test
& operator=( Dhcp4ParserTest_sharedNetworksName_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_sharedNetworksName_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "sharedNetworksName", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6474), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6474), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6474), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworksName_Test
>); void Dhcp4ParserTest_sharedNetworksName_Test::TestBody
()
{
6475 string config = "{\n"
6476 "\"subnet4\": [ { \n"
6477 " \"id\": 1, \n"
6478 " \"pools\": [ { \"pool\": \"10.0.2.1 - 10.0.2.100\" } ], \n"
6479 " \"subnet\": \"10.0.2.0/24\" \n"
6480 " } ],\n"
6481 "\"shared-networks\": [ { \"name\": \"foo\" } ]\n"
6482 "} \n";
6483
6484 configure(config, CONTROL_RESULT_SUCCESS, "");
6485
6486 // Now verify that the shared network was indeed configured.
6487 CfgSharedNetworks4Ptr cfg_net = CfgMgr::instance().getStagingCfg()
6488 ->getCfgSharedNetworks4();
6489 ASSERT_TRUE(cfg_net)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(cfg_net)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6489, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg_net", "false", "true") .c_str()) = ::testing::Message(
)
;
6490 const SharedNetwork4Collection* nets = cfg_net->getAll();
6491 ASSERT_TRUE(nets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(nets)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6491
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "nets", "false", "true") .c_str()) = ::testing::Message()
;
6492 ASSERT_EQ(1U, nets->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "nets->size()"
, 1U, nets->size()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6492, gtest_ar.failure_message()) = ::testing::Message()
;
6493 SharedNetwork4Ptr net = *(nets->begin());
6494 ASSERT_TRUE(net)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(net)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6494
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "net", "false", "true") .c_str()) = ::testing::Message()
;
6495 EXPECT_EQ("foo", net->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"foo\""
, "net->getName()", "foo", net->getName()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6495
, gtest_ar.failure_message()) = ::testing::Message()
;
6496
6497 // Verify that there are no subnets in this shared-network
6498 const Subnet4SimpleCollection* subs = net->getAllSubnets();
6499 ASSERT_TRUE(subs)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subs)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6499
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subs", "false", "true") .c_str()) = ::testing::Message()
;
6500 EXPECT_EQ(0U, subs->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("0U", "subs->size()"
, 0U, subs->size()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6500, gtest_ar.failure_message()) = ::testing::Message()
;
6501}
6502
6503// Test verifies that a degenerated shared-network (just one subnet) is
6504// accepted. Also tests that, unless explicitly specified, the subnet
6505// gets default values.
6506TEST_F(Dhcp4ParserTest, sharedNetworks1subnet)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("sharedNetworks1subnet") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_sharedNetworks1subnet_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_sharedNetworks1subnet_Test() = default
; ~Dhcp4ParserTest_sharedNetworks1subnet_Test() override = default
; Dhcp4ParserTest_sharedNetworks1subnet_Test (const Dhcp4ParserTest_sharedNetworks1subnet_Test
&) = delete; Dhcp4ParserTest_sharedNetworks1subnet_Test &
operator=( const Dhcp4ParserTest_sharedNetworks1subnet_Test &
) = delete; Dhcp4ParserTest_sharedNetworks1subnet_Test (Dhcp4ParserTest_sharedNetworks1subnet_Test
&&) noexcept = delete; Dhcp4ParserTest_sharedNetworks1subnet_Test
& operator=( Dhcp4ParserTest_sharedNetworks1subnet_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_sharedNetworks1subnet_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "sharedNetworks1subnet", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6506), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6506), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6506), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworks1subnet_Test
>); void Dhcp4ParserTest_sharedNetworks1subnet_Test::TestBody
()
{
6507 string config = "{\n"
6508 "\"shared-networks\": [ {\n"
6509 " \"name\": \"foo\"\n,"
6510 " \"subnet4\": [ { \n"
6511 " \"id\": 1,\n"
6512 " \"subnet\": \"192.0.2.0/24\",\n"
6513 " \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\" } ]\n"
6514 " } ]\n"
6515 " } ]\n"
6516 "} \n";
6517
6518 configure(config, CONTROL_RESULT_SUCCESS, "");
6519
6520 // Now verify that the shared network was indeed configured.
6521 CfgSharedNetworks4Ptr cfg_net = CfgMgr::instance().getStagingCfg()
6522 ->getCfgSharedNetworks4();
6523 ASSERT_TRUE(cfg_net)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(cfg_net)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6523, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg_net", "false", "true") .c_str()) = ::testing::Message(
)
;
6524
6525 // There should be exactly one shared subnet.
6526 const SharedNetwork4Collection* nets = cfg_net->getAll();
6527 ASSERT_TRUE(nets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(nets)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6527
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "nets", "false", "true") .c_str()) = ::testing::Message()
;
6528 ASSERT_EQ(1U, nets->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "nets->size()"
, 1U, nets->size()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6528, gtest_ar.failure_message()) = ::testing::Message()
;
6529
6530 SharedNetwork4Ptr net = *(nets->begin());
6531 ASSERT_TRUE(net)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(net)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6531
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "net", "false", "true") .c_str()) = ::testing::Message()
;
6532 EXPECT_EQ("foo", net->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"foo\""
, "net->getName()", "foo", net->getName()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6532
, gtest_ar.failure_message()) = ::testing::Message()
;
6533
6534 // It should have one subnet. The subnet should have default values.
6535 const Subnet4SimpleCollection* subs = net->getAllSubnets();
6536 ASSERT_TRUE(subs)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subs)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6536
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subs", "false", "true") .c_str()) = ::testing::Message()
;
6537 EXPECT_EQ(1U, subs->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "subs->size()"
, 1U, subs->size()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6537, gtest_ar.failure_message()) = ::testing::Message()
;
6538 checkSubnet(*subs, "192.0.2.0/24", 0, 0, 7200);
6539
6540 // Now make sure the subnet was added to global list of subnets.
6541 CfgSubnets4Ptr subnets4 = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
6542 ASSERT_TRUE(subnets4)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnets4)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6542, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets4", "false", "true") .c_str()) = ::testing::Message
()
;
6543
6544 const Subnet4Collection* gsubs = subnets4->getAll();
6545 ASSERT_TRUE(gsubs)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(gsubs)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6545, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "gsubs", "false", "true") .c_str()) = ::testing::Message()
;
6546 checkSubnet(*gsubs, "192.0.2.0/24", 0, 0, 7200);
6547}
6548
6549// Test verifies that a proper shared-network (three subnets) is
6550// accepted. It verifies several things:
6551// - that more than one subnet can be added to shared subnets
6552// - that each subnet being part of the shared subnets is also stored in
6553// global subnets collection
6554// - that a subnet can inherit global values
6555// - that subnet can override global parameters
6556// - that overridden parameters only affect one subnet and not others
6557TEST_F(Dhcp4ParserTest, sharedNetworks3subnets)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("sharedNetworks3subnets") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_sharedNetworks3subnets_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_sharedNetworks3subnets_Test
() = default; ~Dhcp4ParserTest_sharedNetworks3subnets_Test() override
= default; Dhcp4ParserTest_sharedNetworks3subnets_Test (const
Dhcp4ParserTest_sharedNetworks3subnets_Test &) = delete;
Dhcp4ParserTest_sharedNetworks3subnets_Test & operator=(
const Dhcp4ParserTest_sharedNetworks3subnets_Test &) = delete
; Dhcp4ParserTest_sharedNetworks3subnets_Test (Dhcp4ParserTest_sharedNetworks3subnets_Test
&&) noexcept = delete; Dhcp4ParserTest_sharedNetworks3subnets_Test
& operator=( Dhcp4ParserTest_sharedNetworks3subnets_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_sharedNetworks3subnets_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "sharedNetworks3subnets", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6557), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6557), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6557), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworks3subnets_Test
>); void Dhcp4ParserTest_sharedNetworks3subnets_Test::TestBody
()
{
6558 string config = "{\n"
6559 "\"valid-lifetime\": 4000, \n"
6560 "\"min-valid-lifetime\": 3000, \n"
6561 "\"max-valid-lifetime\": 5000, \n"
6562 "\"renew-timer\": 1000, \n"
6563 "\"rebind-timer\": 2000, \n"
6564 "\"shared-networks\": [ {\n"
6565 " \"name\": \"foo\"\n,"
6566 " \"subnet4\": [\n"
6567 " { \n"
6568 " \"id\": 1,\n"
6569 " \"subnet\": \"192.0.1.0/24\",\n"
6570 " \"pools\": [ { \"pool\": \"192.0.1.1-192.0.1.10\" } ]\n"
6571 " },\n"
6572 " { \n"
6573 " \"id\": 2,\n"
6574 " \"subnet\": \"192.0.2.0/24\",\n"
6575 " \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\" } ],\n"
6576 " \"renew-timer\": 2,\n"
6577 " \"rebind-timer\": 22,\n"
6578 " \"valid-lifetime\": 222,\n"
6579 " \"min-valid-lifetime\": 111,\n"
6580 " \"max-valid-lifetime\": 333\n"
6581 " },\n"
6582 " { \n"
6583 " \"id\": 3,\n"
6584 " \"subnet\": \"192.0.3.0/24\",\n"
6585 " \"pools\": [ { \"pool\": \"192.0.3.1-192.0.3.10\" } ]\n"
6586 " }\n"
6587 " ]\n"
6588 " } ]\n"
6589 "} \n";
6590
6591 configure(config, CONTROL_RESULT_SUCCESS, "");
6592
6593 // Now verify that the shared network was indeed configured.
6594 CfgSharedNetworks4Ptr cfg_net = CfgMgr::instance().getStagingCfg()
6595 ->getCfgSharedNetworks4();
6596
6597 // There is expected one shared subnet.
6598 ASSERT_TRUE(cfg_net)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(cfg_net)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6598, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg_net", "false", "true") .c_str()) = ::testing::Message(
)
;
6599 const SharedNetwork4Collection* nets = cfg_net->getAll();
6600 ASSERT_TRUE(nets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(nets)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6600
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "nets", "false", "true") .c_str()) = ::testing::Message()
;
6601 ASSERT_EQ(1U, nets->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "nets->size()"
, 1U, nets->size()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6601, gtest_ar.failure_message()) = ::testing::Message()
;
6602
6603 SharedNetwork4Ptr net = *(nets->begin());
6604 ASSERT_TRUE(net)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(net)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6604
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "net", "false", "true") .c_str()) = ::testing::Message()
;
6605
6606 EXPECT_EQ("foo", net->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"foo\""
, "net->getName()", "foo", net->getName()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6606
, gtest_ar.failure_message()) = ::testing::Message()
;
6607
6608 const Subnet4SimpleCollection* subs = net->getAllSubnets();
6609 ASSERT_TRUE(subs)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subs)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6609
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subs", "false", "true") .c_str()) = ::testing::Message()
;
6610 EXPECT_EQ(3U, subs->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("3U", "subs->size()"
, 3U, subs->size()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6610, gtest_ar.failure_message()) = ::testing::Message()
;
6611 checkSubnet(*subs, "192.0.1.0/24", 1000, 2000, 4000, 3000, 5000);
6612 checkSubnet(*subs, "192.0.2.0/24", 2, 22, 222, 111, 333);
6613 checkSubnet(*subs, "192.0.3.0/24", 1000, 2000, 4000, 3000, 5000);
6614
6615 // Now make sure the subnet was added to global list of subnets.
6616 CfgSubnets4Ptr subnets4 = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
6617 ASSERT_TRUE(subnets4)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnets4)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6617, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets4", "false", "true") .c_str()) = ::testing::Message
()
;
6618
6619 const Subnet4Collection* gsubs = subnets4->getAll();
6620 ASSERT_TRUE(gsubs)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(gsubs)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6620, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "gsubs", "false", "true") .c_str()) = ::testing::Message()
;
6621 checkSubnet(*gsubs, "192.0.1.0/24", 1000, 2000, 4000, 3000, 5000);
6622 checkSubnet(*gsubs, "192.0.2.0/24", 2, 22, 222, 111, 333);
6623 checkSubnet(*gsubs, "192.0.3.0/24", 1000, 2000, 4000, 3000, 5000);
6624}
6625
6626// This test checks if parameters are derived properly:
6627// - global to shared network
6628// - shared network to subnet
6629// Also, it tests that more than one shared network can be defined.
6630TEST_F(Dhcp4ParserTest, sharedNetworksDerive)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("sharedNetworksDerive") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_sharedNetworksDerive_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_sharedNetworksDerive_Test() = default
; ~Dhcp4ParserTest_sharedNetworksDerive_Test() override = default
; Dhcp4ParserTest_sharedNetworksDerive_Test (const Dhcp4ParserTest_sharedNetworksDerive_Test
&) = delete; Dhcp4ParserTest_sharedNetworksDerive_Test &
operator=( const Dhcp4ParserTest_sharedNetworksDerive_Test &
) = delete; Dhcp4ParserTest_sharedNetworksDerive_Test (Dhcp4ParserTest_sharedNetworksDerive_Test
&&) noexcept = delete; Dhcp4ParserTest_sharedNetworksDerive_Test
& operator=( Dhcp4ParserTest_sharedNetworksDerive_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_sharedNetworksDerive_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "sharedNetworksDerive", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6630), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6630), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6630), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworksDerive_Test
>); void Dhcp4ParserTest_sharedNetworksDerive_Test::TestBody
()
{
6631
6632 // We need to fake the interfaces present, because we want to test
6633 // interface names inheritance. However, there are sanity checks
6634 // on subnet level that would refuse the value if the interface
6635 // is not present.
6636 IfaceMgrTestConfig iface_config(true);
6637
6638 // This config is structured in a way that the first shared
6639 // subnet have many parameters defined. The first subnet
6640 // should inherit them. The second subnet overrides all
6641 // values and those values should be used, not those from
6642 // shared network scope.
6643 string config = "{\n"
6644 "\"renew-timer\": 1, \n" // global values here
6645 "\"rebind-timer\": 2, \n"
6646 "\"valid-lifetime\": 4, \n"
6647 "\"min-valid-lifetime\": 3, \n"
6648 "\"max-valid-lifetime\": 5, \n"
6649 "\"shared-networks\": [ {\n"
6650 " \"name\": \"foo\"\n," // shared network values here
6651 " \"interface\": \"eth0\",\n"
6652 " \"match-client-id\": false,\n"
6653 " \"authoritative\": true,\n"
6654 " \"next-server\": \"1.2.3.4\",\n"
6655 " \"server-hostname\": \"foo\",\n"
6656 " \"boot-file-name\": \"bar\",\n"
6657 " \"store-extended-info\": true,\n"
6658 " \"relay\": {\n"
6659 " \"ip-addresses\": [ \"5.6.7.8\" ]\n"
6660 " },\n"
6661 " \"reservations-global\": false,\n"
6662 " \"reservations-in-subnet\": false,\n"
6663 " \"renew-timer\": 10,\n"
6664 " \"rebind-timer\": 20,\n"
6665 " \"valid-lifetime\": 40,\n"
6666 " \"min-valid-lifetime\": 30,\n"
6667 " \"max-valid-lifetime\": 50,\n"
6668 " \"subnet4\": [\n"
6669 " { \n"
6670 " \"id\": 1,\n"
6671 " \"subnet\": \"192.0.1.0/24\",\n"
6672 " \"pools\": [ { \"pool\": \"192.0.1.1-192.0.1.10\" } ]\n"
6673 " },\n"
6674 " { \n"
6675 " \"id\": 2,\n"
6676 " \"subnet\": \"192.0.2.0/24\",\n"
6677 " \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\" } ],\n"
6678 " \"renew-timer\": 100,\n"
6679 " \"rebind-timer\": 200,\n"
6680 " \"valid-lifetime\": 400,\n"
6681 " \"min-valid-lifetime\": 300,\n"
6682 " \"max-valid-lifetime\": 500,\n"
6683 " \"match-client-id\": true,\n"
6684 " \"next-server\": \"11.22.33.44\",\n"
6685 " \"server-hostname\": \"some-name.example.org\",\n"
6686 " \"boot-file-name\": \"bootfile.efi\",\n"
6687 " \"relay\": {\n"
6688 " \"ip-addresses\": [ \"55.66.77.88\" ]\n"
6689 " },\n"
6690 " \"reservations-global\": false,\n"
6691 " \"reservations-in-subnet\": true,\n"
6692 " \"reservations-out-of-pool\": true\n"
6693 " }\n"
6694 " ]\n"
6695 " },\n"
6696 "{ // second shared-network starts here\n"
6697 " \"name\": \"bar\",\n"
6698 " \"subnet4\": [\n"
6699 " {\n"
6700 " \"id\": 3,\n"
6701 " \"subnet\": \"192.0.3.0/24\",\n"
6702 " \"pools\": [ { \"pool\": \"192.0.3.1-192.0.3.10\" } ]\n"
6703 " }\n"
6704 " ]\n"
6705 " } ]\n"
6706 "} \n";
6707
6708 configure(config, CONTROL_RESULT_SUCCESS, "");
6709
6710 // Now verify that the shared network was indeed configured.
6711 CfgSharedNetworks4Ptr cfg_net = CfgMgr::instance().getStagingCfg()
6712 ->getCfgSharedNetworks4();
6713
6714 // Two shared networks are expected.
6715 ASSERT_TRUE(cfg_net)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(cfg_net)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6715, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg_net", "false", "true") .c_str()) = ::testing::Message(
)
;
6716 const SharedNetwork4Collection* nets = cfg_net->getAll();
6717 ASSERT_TRUE(nets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(nets)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6717
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "nets", "false", "true") .c_str()) = ::testing::Message()
;
6718 ASSERT_EQ(2U, nets->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "nets->size()"
, 2U, nets->size()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6718, gtest_ar.failure_message()) = ::testing::Message()
;
6719
6720 // Let's check the first one.
6721 SharedNetwork4Ptr net = nets->at(0);
6722 ASSERT_TRUE(net)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(net)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6722
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "net", "false", "true") .c_str()) = ::testing::Message()
;
6723
6724 // The first shared network has two subnets.
6725 const Subnet4SimpleCollection* subs = net->getAllSubnets();
6726 ASSERT_TRUE(subs)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subs)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6726
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subs", "false", "true") .c_str()) = ::testing::Message()
;
6727 EXPECT_EQ(2U, subs->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "subs->size()"
, 2U, subs->size()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6727, gtest_ar.failure_message()) = ::testing::Message()
;
6728
6729 // For the first subnet, the renew-timer should be 10, because it was
6730 // derived from shared-network level. Other parameters a derived
6731 // from global scope to shared-network level and later again to
6732 // subnet4 level.
6733 Subnet4Ptr s = checkSubnet(*subs, "192.0.1.0/24", 10, 20, 40, 30, 50);
6734 ASSERT_TRUE(s)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(s)) ; else return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6734
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s", "false", "true") .c_str()) = ::testing::Message()
;
6735
6736 // These are values derived from shared network scope:
6737 EXPECT_EQ("eth0", s->getIface().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"eth0\""
, "s->getIface().get()", "eth0", s->getIface().get())))
; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6737, gtest_ar.failure_message()) = ::testing::Message()
;
6738 EXPECT_FALSE(s->getMatchClientId())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(s->getMatchClientId
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6738, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getMatchClientId()", "true", "false") .c_str()) = ::
testing::Message()
;
6739 EXPECT_TRUE(s->getAuthoritative())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(s->getAuthoritative
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6739, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getAuthoritative()", "false", "true") .c_str()) = ::
testing::Message()
;
6740 EXPECT_TRUE(s->getStoreExtendedInfo())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(s->getStoreExtendedInfo
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6740, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getStoreExtendedInfo()", "false", "true") .c_str()) =
::testing::Message()
;
6741 EXPECT_EQ(IOAddress("1.2.3.4"), s->getSiaddr())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("IOAddress(\"1.2.3.4\")"
, "s->getSiaddr()", IOAddress("1.2.3.4"), s->getSiaddr(
)))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6741, gtest_ar.failure_message()) = ::testing::Message()
;
6742 EXPECT_EQ("foo", s->getSname().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"foo\""
, "s->getSname().get()", "foo", s->getSname().get()))) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6742, gtest_ar.failure_message()) = ::testing::Message()
;
6743 EXPECT_EQ("bar", s->getFilename().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"bar\""
, "s->getFilename().get()", "bar", s->getFilename().get
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6743, gtest_ar.failure_message()) = ::testing::Message()
;
6744 EXPECT_TRUE(s->hasRelayAddress(IOAddress("5.6.7.8")))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(s->hasRelayAddress
(IOAddress("5.6.7.8")))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6744, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->hasRelayAddress(IOAddress(\"5.6.7.8\"))", "false", "true"
) .c_str()) = ::testing::Message()
;
6745 EXPECT_FALSE(s->getReservationsGlobal())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(s->getReservationsGlobal
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6745, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsGlobal()", "true", "false") .c_str())
= ::testing::Message()
;
6746 EXPECT_FALSE(s->getReservationsInSubnet())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(s->getReservationsInSubnet
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6746, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsInSubnet()", "true", "false") .c_str(
)) = ::testing::Message()
;
6747 EXPECT_FALSE(s->getReservationsOutOfPool())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(s->getReservationsOutOfPool
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6747, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsOutOfPool()", "true", "false") .c_str
()) = ::testing::Message()
;
6748
6749 // For the second subnet, the renew-timer should be 100, because it
6750 // was specified explicitly. Other parameters a derived
6751 // from global scope to shared-network level and later again to
6752 // subnet4 level.
6753 s = checkSubnet(*subs, "192.0.2.0/24", 100, 200, 400, 300, 500);
6754
6755 // These are values derived from shared network scope:
6756 EXPECT_EQ("eth0", s->getIface().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"eth0\""
, "s->getIface().get()", "eth0", s->getIface().get())))
; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6756, gtest_ar.failure_message()) = ::testing::Message()
;
6757 EXPECT_TRUE(s->getMatchClientId())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(s->getMatchClientId
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6757, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getMatchClientId()", "false", "true") .c_str()) = ::
testing::Message()
;
6758 EXPECT_TRUE(s->getAuthoritative())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(s->getAuthoritative
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6758, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getAuthoritative()", "false", "true") .c_str()) = ::
testing::Message()
;
6759 EXPECT_TRUE(s->getStoreExtendedInfo())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(s->getStoreExtendedInfo
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6759, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getStoreExtendedInfo()", "false", "true") .c_str()) =
::testing::Message()
;
6760 EXPECT_EQ(IOAddress("11.22.33.44"), s->getSiaddr().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("IOAddress(\"11.22.33.44\")"
, "s->getSiaddr().get()", IOAddress("11.22.33.44"), s->
getSiaddr().get()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6760, gtest_ar.failure_message()) = ::testing::Message()
;
6761 EXPECT_EQ("some-name.example.org", s->getSname().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"some-name.example.org\""
, "s->getSname().get()", "some-name.example.org", s->getSname
().get()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6761, gtest_ar.failure_message()) = ::testing::Message()
;
6762 EXPECT_EQ("bootfile.efi", s->getFilename().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"bootfile.efi\""
, "s->getFilename().get()", "bootfile.efi", s->getFilename
().get()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6762, gtest_ar.failure_message()) = ::testing::Message()
;
6763 EXPECT_TRUE(s->hasRelayAddress(IOAddress("55.66.77.88")))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(s->hasRelayAddress
(IOAddress("55.66.77.88")))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6763, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->hasRelayAddress(IOAddress(\"55.66.77.88\"))", "false"
, "true") .c_str()) = ::testing::Message()
;
6764 EXPECT_FALSE(s->getReservationsGlobal())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(s->getReservationsGlobal
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6764, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsGlobal()", "true", "false") .c_str())
= ::testing::Message()
;
6765 EXPECT_TRUE(s->getReservationsInSubnet())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(s->getReservationsInSubnet
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6765, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsInSubnet()", "false", "true") .c_str(
)) = ::testing::Message()
;
6766 EXPECT_TRUE(s->getReservationsOutOfPool())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(s->getReservationsOutOfPool
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6766, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsOutOfPool()", "false", "true") .c_str
()) = ::testing::Message()
;
6767
6768 // Ok, now check the second shared subnet.
6769 net = nets->at(1);
6770 ASSERT_TRUE(net)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(net)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6770
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "net", "false", "true") .c_str()) = ::testing::Message()
;
6771
6772 subs = net->getAllSubnets();
6773 ASSERT_TRUE(subs)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subs)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6773
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subs", "false", "true") .c_str()) = ::testing::Message()
;
6774 EXPECT_EQ(1U, subs->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "subs->size()"
, 1U, subs->size()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6774, gtest_ar.failure_message()) = ::testing::Message()
;
6775
6776 // This subnet should derive its renew-timer from global scope.
6777 // All other parameters should have default values.
6778 s = checkSubnet(*subs, "192.0.3.0/24", 1, 2, 4, 3, 5);
6779 EXPECT_EQ("", s->getIface().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\"", "s->getIface().get()"
, "", s->getIface().get()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6779, gtest_ar.failure_message()) = ::testing::Message()
;
6780 EXPECT_TRUE(s->getMatchClientId())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(s->getMatchClientId
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6780, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getMatchClientId()", "false", "true") .c_str()) = ::
testing::Message()
;
6781 EXPECT_FALSE(s->getAuthoritative())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(s->getAuthoritative
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6781, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getAuthoritative()", "true", "false") .c_str()) = ::
testing::Message()
;
6782 EXPECT_FALSE(s->getStoreExtendedInfo())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(s->getStoreExtendedInfo
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6782, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getStoreExtendedInfo()", "true", "false") .c_str()) =
::testing::Message()
;
6783 EXPECT_EQ(IOAddress("0.0.0.0"), s->getSiaddr())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("IOAddress(\"0.0.0.0\")"
, "s->getSiaddr()", IOAddress("0.0.0.0"), s->getSiaddr(
)))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6783, gtest_ar.failure_message()) = ::testing::Message()
;
6784 EXPECT_TRUE(s->getSname().empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(s->getSname().empty
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6784, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getSname().empty()", "false", "true") .c_str()) = ::
testing::Message()
;
6785 EXPECT_TRUE(s->getFilename().empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(s->getFilename().empty
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6785, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getFilename().empty()", "false", "true") .c_str()) =
::testing::Message()
;
6786 EXPECT_FALSE(s->hasRelays())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(s->hasRelays()))
) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6786, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->hasRelays()", "true", "false") .c_str()) = ::testing
::Message()
;
6787 EXPECT_FALSE(s->getReservationsGlobal())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(s->getReservationsGlobal
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6787, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsGlobal()", "true", "false") .c_str())
= ::testing::Message()
;
6788 EXPECT_TRUE(s->getReservationsInSubnet())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(s->getReservationsInSubnet
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6788, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsInSubnet()", "false", "true") .c_str(
)) = ::testing::Message()
;
6789 EXPECT_FALSE(s->getReservationsOutOfPool())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(s->getReservationsOutOfPool
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6789, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsOutOfPool()", "true", "false") .c_str
()) = ::testing::Message()
;
6790}
6791
6792// Since it is not allowed to define both interface-id and interface
6793// for the same subnet, we need dedicated test that will check
6794// interface separately.
6795TEST_F(Dhcp4ParserTest, sharedNetworksDeriveInterfaces)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("sharedNetworksDeriveInterfaces") >
1, "test_name must not be empty"); class Dhcp4ParserTest_sharedNetworksDeriveInterfaces_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_sharedNetworksDeriveInterfaces_Test
() = default; ~Dhcp4ParserTest_sharedNetworksDeriveInterfaces_Test
() override = default; Dhcp4ParserTest_sharedNetworksDeriveInterfaces_Test
(const Dhcp4ParserTest_sharedNetworksDeriveInterfaces_Test &
) = delete; Dhcp4ParserTest_sharedNetworksDeriveInterfaces_Test
& operator=( const Dhcp4ParserTest_sharedNetworksDeriveInterfaces_Test
&) = delete; Dhcp4ParserTest_sharedNetworksDeriveInterfaces_Test
(Dhcp4ParserTest_sharedNetworksDeriveInterfaces_Test &&
) noexcept = delete; Dhcp4ParserTest_sharedNetworksDeriveInterfaces_Test
& operator=( Dhcp4ParserTest_sharedNetworksDeriveInterfaces_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_sharedNetworksDeriveInterfaces_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "sharedNetworksDeriveInterfaces", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6795), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6795), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6795), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworksDeriveInterfaces_Test
>); void Dhcp4ParserTest_sharedNetworksDeriveInterfaces_Test
::TestBody()
{
6796
6797 // We need to fake the interfaces present, because we want to test
6798 // interface names inheritance. However, there are sanity checks
6799 // on subnet level that would refuse the value if the interface
6800 // is not present.
6801 IfaceMgrTestConfig iface_config(true);
6802
6803 string config = "{\n"
6804 "\"shared-networks\": [ {\n"
6805 " \"name\": \"foo\"\n,"
6806 " \"interface\": \"eth0\",\n"
6807 " \"rebind-timer\": 10, \n"
6808 " \"subnet4\": [\n"
6809 " { \n"
6810 " \"id\": 1, \n"
6811 " \"subnet\": \"192.0.1.0/24\",\n"
6812 " \"pools\": [ { \"pool\": \"192.0.1.1-192.0.1.10\" } ]\n"
6813 " },\n"
6814 " { \n"
6815 " \"id\": 2, \n"
6816 " \"subnet\": \"192.0.2.0/24\",\n"
6817 " \"rebind-timer\": 100, \n"
6818 " \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\" } ],\n"
6819 " \"interface\": \"eth0\"\n"
6820 " }\n"
6821 " ]\n"
6822 " },\n"
6823 "{ // second shared-network starts here\n"
6824 " \"name\": \"bar\",\n"
6825 " \"subnet4\": [\n"
6826 " {\n"
6827 " \"id\": 3, \n"
6828 " \"subnet\": \"192.0.3.0/24\",\n"
6829 " \"pools\": [ { \"pool\": \"192.0.3.1-192.0.3.10\" } ]\n"
6830 " }\n"
6831 " ]\n"
6832 "} ]\n"
6833 "} \n";
6834
6835 configure(config, CONTROL_RESULT_SUCCESS, "");
6836
6837 // Now verify that the shared network was indeed configured.
6838 CfgSharedNetworks4Ptr cfg_net = CfgMgr::instance().getStagingCfg()
6839 ->getCfgSharedNetworks4();
6840
6841 // Two shared networks are expected.
6842 ASSERT_TRUE(cfg_net)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(cfg_net)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6842, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg_net", "false", "true") .c_str()) = ::testing::Message(
)
;
6843 const SharedNetwork4Collection* nets = cfg_net->getAll();
6844 ASSERT_TRUE(nets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(nets)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6844
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "nets", "false", "true") .c_str()) = ::testing::Message()
;
6845 ASSERT_EQ(2U, nets->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "nets->size()"
, 2U, nets->size()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6845, gtest_ar.failure_message()) = ::testing::Message()
;
6846
6847 // Let's check the first one.
6848 SharedNetwork4Ptr net = nets->at(0);
6849 ASSERT_TRUE(net)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(net)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6849
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "net", "false", "true") .c_str()) = ::testing::Message()
;
6850
6851 const Subnet4SimpleCollection* subs = net->getAllSubnets();
6852 ASSERT_TRUE(subs)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subs)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6852
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subs", "false", "true") .c_str()) = ::testing::Message()
;
6853 EXPECT_EQ(2U, subs->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "subs->size()"
, 2U, subs->size()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6853, gtest_ar.failure_message()) = ::testing::Message()
;
6854
6855 // For the first subnet, the rebind-timer should be 10, because it was
6856 // derived from shared-network level. Other parameters a derived
6857 // from global scope to shared-network level and later again to
6858 // subnet4 level.
6859 Subnet4Ptr s = checkSubnet(*subs, "192.0.1.0/24", 0, 10, 7200);
6860 ASSERT_TRUE(s)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(s)) ; else return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6860
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s", "false", "true") .c_str()) = ::testing::Message()
;
6861 EXPECT_EQ("eth0", s->getIface().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"eth0\""
, "s->getIface().get()", "eth0", s->getIface().get())))
; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6861, gtest_ar.failure_message()) = ::testing::Message()
;
6862
6863 // For the second subnet, the rebind-timer should be 100, because it
6864 // was specified explicitly. Other parameters a derived
6865 // from global scope to shared-network level and later again to
6866 // subnet4 level.
6867 checkSubnet(*subs, "192.0.2.0/24", 0, 100, 7200);
6868 EXPECT_EQ("eth0", s->getIface().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"eth0\""
, "s->getIface().get()", "eth0", s->getIface().get())))
; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6868, gtest_ar.failure_message()) = ::testing::Message()
;
6869
6870 // Ok, now check the second shared subnet.
6871 net = nets->at(1);
6872 ASSERT_TRUE(net)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(net)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6872
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "net", "false", "true") .c_str()) = ::testing::Message()
;
6873
6874 subs = net->getAllSubnets();
6875 ASSERT_TRUE(subs)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subs)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6875
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subs", "false", "true") .c_str()) = ::testing::Message()
;
6876 EXPECT_EQ(1U, subs->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "subs->size()"
, 1U, subs->size()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6876, gtest_ar.failure_message()) = ::testing::Message()
;
6877
6878 // This subnet should derive its rebind-timer from global scope.
6879 s = checkSubnet(*subs, "192.0.3.0/24", 0, 0, 7200);
6880 EXPECT_EQ("", s->getIface().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\"", "s->getIface().get()"
, "", s->getIface().get()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6880, gtest_ar.failure_message()) = ::testing::Message()
;
6881}
6882
6883// It is not allowed to have different values for interfaces names is subnets
6884// in the same shared network.
6885TEST_F(Dhcp4ParserTest, sharedNetworksInterfacesMixed)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("sharedNetworksInterfacesMixed") >
1, "test_name must not be empty"); class Dhcp4ParserTest_sharedNetworksInterfacesMixed_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_sharedNetworksInterfacesMixed_Test
() = default; ~Dhcp4ParserTest_sharedNetworksInterfacesMixed_Test
() override = default; Dhcp4ParserTest_sharedNetworksInterfacesMixed_Test
(const Dhcp4ParserTest_sharedNetworksInterfacesMixed_Test &
) = delete; Dhcp4ParserTest_sharedNetworksInterfacesMixed_Test
& operator=( const Dhcp4ParserTest_sharedNetworksInterfacesMixed_Test
&) = delete; Dhcp4ParserTest_sharedNetworksInterfacesMixed_Test
(Dhcp4ParserTest_sharedNetworksInterfacesMixed_Test &&
) noexcept = delete; Dhcp4ParserTest_sharedNetworksInterfacesMixed_Test
& operator=( Dhcp4ParserTest_sharedNetworksInterfacesMixed_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_sharedNetworksInterfacesMixed_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "sharedNetworksInterfacesMixed", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6885), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6885), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6885), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworksInterfacesMixed_Test
>); void Dhcp4ParserTest_sharedNetworksInterfacesMixed_Test
::TestBody()
{
6886
6887 // We need to fake the interfaces present, because we want to test
6888 // interface names inheritance. However, there are sanity checks
6889 // on subnet level that would refuse the value if the interface
6890 // is not present.
6891 IfaceMgrTestConfig iface_config(true);
6892
6893 string config = "{\n"
6894 "\"shared-networks\": [ {\n"
6895 " \"name\": \"foo\"\n,"
6896 " \"subnet4\": [\n"
6897 " { \n"
6898 " \"id\": 1, \n"
6899 " \"subnet\": \"192.0.1.0/24\",\n"
6900 " \"interface\": \"eth0\"\n"
6901 " },\n"
6902 " { \n"
6903 " \"id\": 2, \n"
6904 " \"subnet\": \"192.0.2.0/24\",\n"
6905 " \"interface\": \"eth1\"\n"
6906 " }\n"
6907 " ]\n"
6908 " } ]\n"
6909 "} \n";
6910
6911 configure(config, CONTROL_RESULT_ERROR, "Subnet 192.0.2.0/24 has specified "
6912 "interface eth1, but earlier subnet in the same shared-network "
6913 "or the shared-network itself used eth0");
6914}
6915
6916// This test checks multiple host data sources.
6917TEST_F(Dhcp4ParserTest, hostsDatabases)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("hostsDatabases") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_hostsDatabases_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_hostsDatabases_Test() = default; ~
Dhcp4ParserTest_hostsDatabases_Test() override = default; Dhcp4ParserTest_hostsDatabases_Test
(const Dhcp4ParserTest_hostsDatabases_Test &) = delete; Dhcp4ParserTest_hostsDatabases_Test
& operator=( const Dhcp4ParserTest_hostsDatabases_Test &
) = delete; Dhcp4ParserTest_hostsDatabases_Test (Dhcp4ParserTest_hostsDatabases_Test
&&) noexcept = delete; Dhcp4ParserTest_hostsDatabases_Test
& operator=( Dhcp4ParserTest_hostsDatabases_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_hostsDatabases_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "hostsDatabases", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6917
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6917), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6917), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_hostsDatabases_Test
>); void Dhcp4ParserTest_hostsDatabases_Test::TestBody()
{
6918
6919 string config = PARSER_CONFIGS[4];
6920 extractConfig(config);
6921 configure(config, CONTROL_RESULT_SUCCESS, "");
6922
6923 // Check database config
6924 ConstCfgDbAccessPtr cfgdb =
6925 CfgMgr::instance().getStagingCfg()->getCfgDbAccess();
6926 ASSERT_TRUE(cfgdb)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(cfgdb)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6926, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfgdb", "false", "true") .c_str()) = ::testing::Message()
;
6927 const std::list<std::string>& hal = cfgdb->getHostDbAccessStringList();
6928 ASSERT_EQ(2U, hal.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "hal.size()"
, 2U, hal.size()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6928, gtest_ar.failure_message()) = ::testing::Message()
;
6929 // Keywords are in alphabetical order
6930 EXPECT_EQ("name=keatest1 password=keatest type=mysql user=keatest", hal.front())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"name=keatest1 password=keatest type=mysql user=keatest\""
, "hal.front()", "name=keatest1 password=keatest type=mysql user=keatest"
, hal.front()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6930, gtest_ar.failure_message()) = ::testing::Message()
;
6931 EXPECT_EQ("name=keatest2 password=keatest retry-on-startup=true type=mysql user=keatest", hal.back())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"name=keatest2 password=keatest retry-on-startup=true type=mysql user=keatest\""
, "hal.back()", "name=keatest2 password=keatest retry-on-startup=true type=mysql user=keatest"
, hal.back()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6931, gtest_ar.failure_message()) = ::testing::Message()
;
6932}
6933
6934// This test checks comments. Please keep it last.
6935TEST_F(Dhcp4ParserTest, comments)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("comments") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_comments_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_comments_Test() = default; ~Dhcp4ParserTest_comments_Test
() override = default; Dhcp4ParserTest_comments_Test (const Dhcp4ParserTest_comments_Test
&) = delete; Dhcp4ParserTest_comments_Test & operator
=( const Dhcp4ParserTest_comments_Test &) = delete; Dhcp4ParserTest_comments_Test
(Dhcp4ParserTest_comments_Test &&) noexcept = delete
; Dhcp4ParserTest_comments_Test & operator=( Dhcp4ParserTest_comments_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_comments_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "comments", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6935
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6935), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6935), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_comments_Test
>); void Dhcp4ParserTest_comments_Test::TestBody()
{
6936 Dhcpv4SrvTest::setSocketTestPath();
6937 file::PathChecker::enableEnforcement(false);
6938
6939 string config = PARSER_CONFIGS[6];
6940 extractConfig(config);
6941 configure(config, CONTROL_RESULT_SUCCESS, "");
6942
6943 // Check global user context.
6944 ConstElementPtr ctx = CfgMgr::instance().getStagingCfg()->getContext();
6945 ASSERT_TRUE(ctx)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6945
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx", "false", "true") .c_str()) = ::testing::Message()
;
6946 ASSERT_EQ(1U, ctx->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "ctx->size()"
, 1U, ctx->size()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6946, gtest_ar.failure_message()) = ::testing::Message()
;
6947 ASSERT_TRUE(ctx->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx->get("comment"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6947, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx->get(\"comment\")", "false", "true") .c_str()) = ::
testing::Message()
;
6948 EXPECT_EQ("\"A DHCPv4 server\"", ctx->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"A DHCPv4 server\\\"\""
, "ctx->get(\"comment\")->str()", "\"A DHCPv4 server\""
, ctx->get("comment")->str()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6948, gtest_ar.failure_message()) = ::testing::Message()
;
6949
6950 // There is a network interface configuration.
6951 ConstCfgIfacePtr iface = CfgMgr::instance().getStagingCfg()->getCfgIface();
6952 ASSERT_TRUE(iface)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(iface)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6952, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "iface", "false", "true") .c_str()) = ::testing::Message()
;
6953
6954 // Check network interface configuration user context.
6955 ConstElementPtr ctx_iface = iface->getContext();
6956 ASSERT_TRUE(ctx_iface)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_iface)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6956, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_iface", "false", "true") .c_str()) = ::testing::Message
()
;
6957 ASSERT_EQ(1U, ctx_iface->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "ctx_iface->size()"
, 1U, ctx_iface->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6957, gtest_ar.failure_message()) = ::testing::Message()
;
6958 ASSERT_TRUE(ctx_iface->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_iface->get("comment"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6958, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_iface->get(\"comment\")", "false", "true") .c_str()
) = ::testing::Message()
;
6959 EXPECT_EQ("\"Use wildcard\"", ctx_iface->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"Use wildcard\\\"\""
, "ctx_iface->get(\"comment\")->str()", "\"Use wildcard\""
, ctx_iface->get("comment")->str()))) ; else ::testing::
internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6959
, gtest_ar.failure_message()) = ::testing::Message()
;
6960
6961 ConstElementPtr json;
6962 ASSERT_NO_THROW_LOG(json = parseDHCP4(config, true)){ try { json = parseDHCP4(config, true); } catch (const std::
exception& ex) { return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6962, "Failed") = ::testing::Message() << "json = parseDHCP4(config, true)"
<< " threw type: " << typeid(ex).name() <<
", what: " << ex.what(); } catch (...) { return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6962
, "Failed") = ::testing::Message() << "json = parseDHCP4(config, true)"
<< " threw non-std::exception"; } }
;
6963 bool const too_long(SocketPath::isTooLongFromConfig(json));
6964 if (too_long) {
6965 return;
6966 }
6967
6968 // There is a global option definition.
6969 const OptionDefinitionPtr& opt_def =
6970 LibDHCP::getRuntimeOptionDef("isc", 100);
6971 ASSERT_TRUE(opt_def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(opt_def)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6971, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_def", "false", "true") .c_str()) = ::testing::Message(
)
;
6972 EXPECT_EQ("foo", opt_def->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"foo\""
, "opt_def->getName()", "foo", opt_def->getName()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6972, gtest_ar.failure_message()) = ::testing::Message()
;
6973 EXPECT_EQ(100U, opt_def->getCode())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("100U", "opt_def->getCode()"
, 100U, opt_def->getCode()))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6973, gtest_ar.failure_message()) = ::testing::Message()
;
6974 EXPECT_FALSE(opt_def->getArrayType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(opt_def->getArrayType
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6974, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_def->getArrayType()", "true", "false") .c_str()) = ::
testing::Message()
;
6975 EXPECT_EQ(OPT_IPV4_ADDRESS_TYPE, opt_def->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("OPT_IPV4_ADDRESS_TYPE"
, "opt_def->getType()", OPT_IPV4_ADDRESS_TYPE, opt_def->
getType()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6975, gtest_ar.failure_message()) = ::testing::Message()
;
6976 EXPECT_TRUE(opt_def->getEncapsulatedSpace().empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(opt_def->getEncapsulatedSpace
().empty())) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6976, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_def->getEncapsulatedSpace().empty()", "false", "true"
) .c_str()) = ::testing::Message()
;
6977
6978 // Check option definition user context.
6979 ConstElementPtr ctx_opt_def = opt_def->getContext();
6980 ASSERT_TRUE(ctx_opt_def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_opt_def)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6980, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_opt_def", "false", "true") .c_str()) = ::testing::Message
()
;
6981 ASSERT_EQ(1U, ctx_opt_def->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "ctx_opt_def->size()"
, 1U, ctx_opt_def->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6981, gtest_ar.failure_message()) = ::testing::Message()
;
6982 ASSERT_TRUE(ctx_opt_def->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_opt_def->get("comment"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6982, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_opt_def->get(\"comment\")", "false", "true") .c_str
()) = ::testing::Message()
;
6983 EXPECT_EQ("\"An option definition\"", ctx_opt_def->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"An option definition\\\"\""
, "ctx_opt_def->get(\"comment\")->str()", "\"An option definition\""
, ctx_opt_def->get("comment")->str()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6983
, gtest_ar.failure_message()) = ::testing::Message()
;
6984
6985 // There is an option descriptor aka option data.
6986 const OptionDescriptor& opt_desc =
6987 CfgMgr::instance().getStagingCfg()->getCfgOption()->
6988 get(DHCP4_OPTION_SPACE"dhcp4", DHO_DHCP_MESSAGE);
6989 ASSERT_TRUE(opt_desc.option_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(opt_desc.option_)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6989, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_desc.option_", "false", "true") .c_str()) = ::testing::
Message()
;
6990 EXPECT_EQ(DHO_DHCP_MESSAGE, opt_desc.option_->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("DHO_DHCP_MESSAGE"
, "opt_desc.option_->getType()", DHO_DHCP_MESSAGE, opt_desc
.option_->getType()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6990, gtest_ar.failure_message()) = ::testing::Message()
;
6991
6992 // Check option descriptor user context.
6993 ConstElementPtr ctx_opt_desc = opt_desc.getContext();
6994 ASSERT_TRUE(ctx_opt_desc)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_opt_desc)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6994, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_opt_desc", "false", "true") .c_str()) = ::testing::Message
()
;
6995 ASSERT_EQ(1U, ctx_opt_desc->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "ctx_opt_desc->size()"
, 1U, ctx_opt_desc->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6995, gtest_ar.failure_message()) = ::testing::Message()
;
6996 ASSERT_TRUE(ctx_opt_desc->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_opt_desc->get(
"comment"))) ; else return ::testing::internal::AssertHelper(
::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6996, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_opt_desc->get(\"comment\")", "false", "true") .c_str
()) = ::testing::Message()
;
6997 EXPECT_EQ("\"Set option value\"", ctx_opt_desc->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"Set option value\\\"\""
, "ctx_opt_desc->get(\"comment\")->str()", "\"Set option value\""
, ctx_opt_desc->get("comment")->str()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 6997
, gtest_ar.failure_message()) = ::testing::Message()
;
6998
6999 // And there are some client classes.
7000 const ClientClassDictionaryPtr& dict =
7001 CfgMgr::instance().getStagingCfg()->getClientClassDictionary();
7002 ASSERT_TRUE(dict)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(dict)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7002
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dict", "false", "true") .c_str()) = ::testing::Message()
;
7003 EXPECT_EQ(3U, dict->getClasses()->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("3U", "dict->getClasses()->size()"
, 3U, dict->getClasses()->size()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7003, gtest_ar.failure_message()) = ::testing::Message()
;
7004 ClientClassDefPtr cclass = dict->findClass("all");
7005 ASSERT_TRUE(cclass)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(cclass)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7005, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cclass", "false", "true") .c_str()) = ::testing::Message()
;
7006 EXPECT_EQ("all", cclass->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"all\""
, "cclass->getName()", "all", cclass->getName()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7006, gtest_ar.failure_message()) = ::testing::Message()
;
7007 EXPECT_EQ("'' == ''", cclass->getTest())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"'' == ''\""
, "cclass->getTest()", "'' == ''", cclass->getTest())))
; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7007, gtest_ar.failure_message()) = ::testing::Message()
;
7008
7009 // Check client class user context.
7010 ConstElementPtr ctx_class = cclass->getContext();
7011 ASSERT_TRUE(ctx_class)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_class)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7011, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_class", "false", "true") .c_str()) = ::testing::Message
()
;
7012 ASSERT_EQ(1U, ctx_class->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "ctx_class->size()"
, 1U, ctx_class->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7012, gtest_ar.failure_message()) = ::testing::Message()
;
7013 ASSERT_TRUE(ctx_class->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_class->get("comment"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7013, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_class->get(\"comment\")", "false", "true") .c_str()
) = ::testing::Message()
;
7014 EXPECT_EQ("\"match all\"", ctx_class->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"match all\\\"\""
, "ctx_class->get(\"comment\")->str()", "\"match all\""
, ctx_class->get("comment")->str()))) ; else ::testing::
internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7014
, gtest_ar.failure_message()) = ::testing::Message()
;
7015
7016 // The 'none' class has no user-context/comment.
7017 cclass = dict->findClass("none");
7018 ASSERT_TRUE(cclass)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(cclass)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7018, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cclass", "false", "true") .c_str()) = ::testing::Message()
;
7019 EXPECT_EQ("none", cclass->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"none\""
, "cclass->getName()", "none", cclass->getName()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7019, gtest_ar.failure_message()) = ::testing::Message()
;
7020 EXPECT_EQ("", cclass->getTest())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\"", "cclass->getTest()"
, "", cclass->getTest()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7020, gtest_ar.failure_message()) = ::testing::Message()
;
7021 EXPECT_FALSE(cclass->getContext())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(cclass->getContext
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7021, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cclass->getContext()", "true", "false") .c_str()) = ::testing
::Message()
;
7022
7023 // The 'both' class has a user context and a comment.
7024 cclass = dict->findClass("both");
7025 EXPECT_EQ("both", cclass->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"both\""
, "cclass->getName()", "both", cclass->getName()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7025, gtest_ar.failure_message()) = ::testing::Message()
;
7026 EXPECT_EQ("", cclass->getTest())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\"", "cclass->getTest()"
, "", cclass->getTest()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7026, gtest_ar.failure_message()) = ::testing::Message()
;
7027 ctx_class = cclass->getContext();
7028 ASSERT_TRUE(ctx_class)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_class)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7028, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_class", "false", "true") .c_str()) = ::testing::Message
()
;
7029 ASSERT_EQ(2U, ctx_class->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "ctx_class->size()"
, 2U, ctx_class->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7029, gtest_ar.failure_message()) = ::testing::Message()
;
7030 ASSERT_TRUE(ctx_class->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_class->get("comment"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7030, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_class->get(\"comment\")", "false", "true") .c_str()
) = ::testing::Message()
;
7031 EXPECT_EQ("\"a comment\"", ctx_class->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"a comment\\\"\""
, "ctx_class->get(\"comment\")->str()", "\"a comment\""
, ctx_class->get("comment")->str()))) ; else ::testing::
internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7031
, gtest_ar.failure_message()) = ::testing::Message()
;
7032 ASSERT_TRUE(ctx_class->get("version"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_class->get("version"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7032, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_class->get(\"version\")", "false", "true") .c_str()
) = ::testing::Message()
;
7033 EXPECT_EQ("1", ctx_class->get("version")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"1\"", "ctx_class->get(\"version\")->str()"
, "1", ctx_class->get("version")->str()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7033
, gtest_ar.failure_message()) = ::testing::Message()
;
7034
7035 // There is a UNIX control socket.
7036 ConstElementPtr socket =
7037 CfgMgr::instance().getStagingCfg()->getUnixControlSocketInfo();
7038 ASSERT_TRUE(socket)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(socket)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7038, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket", "false", "true") .c_str()) = ::testing::Message()
;
7039 ASSERT_EQ(Element::list, socket->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("Element::list"
, "socket->getType()", Element::list, socket->getType()
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7039, gtest_ar.failure_message()) = ::testing::Message()
;
7040 ASSERT_EQ(socket->size(), 1U)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("socket->size()"
, "1U", socket->size(), 1U))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7040, gtest_ar.failure_message()) = ::testing::Message()
;
7041 socket = socket->get(0);
7042 ASSERT_TRUE(socket)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(socket)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7042, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket", "false", "true") .c_str()) = ::testing::Message()
;
7043 ASSERT_TRUE(socket->get("socket-type"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(socket->get("socket-type"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7043, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket->get(\"socket-type\")", "false", "true") .c_str(
)) = ::testing::Message()
;
7044 EXPECT_EQ("\"unix\"", socket->get("socket-type")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"unix\\\"\""
, "socket->get(\"socket-type\")->str()", "\"unix\"", socket
->get("socket-type")->str()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7044, gtest_ar.failure_message()) = ::testing::Message()
;
7045 ASSERT_TRUE(socket->get("socket-name"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(socket->get("socket-name"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7045, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket->get(\"socket-name\")", "false", "true") .c_str(
)) = ::testing::Message()
;
7046 EXPECT_EQ("\"kea4-ctrl-socket\"", socket->get("socket-name")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"kea4-ctrl-socket\\\"\""
, "socket->get(\"socket-name\")->str()", "\"kea4-ctrl-socket\""
, socket->get("socket-name")->str()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7046
, gtest_ar.failure_message()) = ::testing::Message()
;
7047
7048 // Check UNIX control socket comment and user context.
7049 ConstElementPtr ctx_socket = socket->get("user-context");
7050 ASSERT_TRUE(ctx_socket)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_socket)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7050, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_socket", "false", "true") .c_str()) = ::testing::Message
()
;
7051 ASSERT_EQ(1U, ctx_socket->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "ctx_socket->size()"
, 1U, ctx_socket->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7051, gtest_ar.failure_message()) = ::testing::Message()
;
7052 ASSERT_TRUE(ctx_socket->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_socket->get("comment"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7052, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_socket->get(\"comment\")", "false", "true") .c_str(
)) = ::testing::Message()
;
7053 EXPECT_EQ("\"Indirect comment\"", ctx_socket->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"Indirect comment\\\"\""
, "ctx_socket->get(\"comment\")->str()", "\"Indirect comment\""
, ctx_socket->get("comment")->str()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7053
, gtest_ar.failure_message()) = ::testing::Message()
;
7054
7055 // There is a HTTP control socket with authentication.
7056 socket = CfgMgr::instance().getStagingCfg()->getHttpControlSocketInfo();
7057 ASSERT_TRUE(socket)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(socket)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7057, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket", "false", "true") .c_str()) = ::testing::Message()
;
7058 ASSERT_EQ(Element::list, socket->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("Element::list"
, "socket->getType()", Element::list, socket->getType()
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7058, gtest_ar.failure_message()) = ::testing::Message()
;
7059 ASSERT_EQ(socket->size(), 1U)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("socket->size()"
, "1U", socket->size(), 1U))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7059, gtest_ar.failure_message()) = ::testing::Message()
;
7060 socket = socket->get(0);
7061 ASSERT_TRUE(socket)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(socket)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7061, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket", "false", "true") .c_str()) = ::testing::Message()
;
7062 /// @todo use the configuration object.
7063 ASSERT_TRUE(socket->get("socket-type"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(socket->get("socket-type"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7063, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket->get(\"socket-type\")", "false", "true") .c_str(
)) = ::testing::Message()
;
7064 EXPECT_EQ("\"http\"", socket->get("socket-type")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"http\\\"\""
, "socket->get(\"socket-type\")->str()", "\"http\"", socket
->get("socket-type")->str()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7064, gtest_ar.failure_message()) = ::testing::Message()
;
7065 ASSERT_TRUE(socket->get("socket-address"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(socket->get("socket-address"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7065, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket->get(\"socket-address\")", "false", "true") .c_str
()) = ::testing::Message()
;
7066 EXPECT_EQ("\"::1\"", socket->get("socket-address")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"::1\\\"\""
, "socket->get(\"socket-address\")->str()", "\"::1\"", socket
->get("socket-address")->str()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7066, gtest_ar.failure_message()) = ::testing::Message()
;
7067 ASSERT_TRUE(socket->get("socket-port"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(socket->get("socket-port"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7067, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket->get(\"socket-port\")", "false", "true") .c_str(
)) = ::testing::Message()
;
7068 EXPECT_EQ("8000", socket->get("socket-port")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"8000\""
, "socket->get(\"socket-port\")->str()", "8000", socket
->get("socket-port")->str()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7068, gtest_ar.failure_message()) = ::testing::Message()
;
7069
7070 // Check HTTP control socket comment.
7071 ctx_socket = socket->get("user-context");
7072 ASSERT_TRUE(ctx_socket)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_socket)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7072, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_socket", "false", "true") .c_str()) = ::testing::Message
()
;
7073 ASSERT_EQ(1U, ctx_socket->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "ctx_socket->size()"
, 1U, ctx_socket->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7073, gtest_ar.failure_message()) = ::testing::Message()
;
7074 ASSERT_TRUE(ctx_socket->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_socket->get("comment"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7074, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_socket->get(\"comment\")", "false", "true") .c_str(
)) = ::testing::Message()
;
7075 EXPECT_EQ("\"HTTP control socket\"", ctx_socket->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"HTTP control socket\\\"\""
, "ctx_socket->get(\"comment\")->str()", "\"HTTP control socket\""
, ctx_socket->get("comment")->str()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7075
, gtest_ar.failure_message()) = ::testing::Message()
;
7076
7077 // HTTP headers.
7078 ConstElementPtr headers = socket->get("http-headers");
7079 ASSERT_TRUE(headers)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(headers)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7079, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "headers", "false", "true") .c_str()) = ::testing::Message(
)
;
7080 ASSERT_EQ(1U, headers->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "headers->size()"
, 1U, headers->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7080, gtest_ar.failure_message()) = ::testing::Message()
;
7081 ConstElementPtr header = headers->get(0);
7082 ASSERT_TRUE(header)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(header)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7082, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "header", "false", "true") .c_str()) = ::testing::Message()
;
7083 ASSERT_TRUE(header->get("name"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(header->get("name"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7083, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "header->get(\"name\")", "false", "true") .c_str()) = ::
testing::Message()
;
7084 EXPECT_EQ("\"Strict-Transport-Security\"", header->get("name")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"Strict-Transport-Security\\\"\""
, "header->get(\"name\")->str()", "\"Strict-Transport-Security\""
, header->get("name")->str()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7084, gtest_ar.failure_message()) = ::testing::Message()
;
7085 ASSERT_TRUE(header->get("value"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(header->get("value"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7085, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "header->get(\"value\")", "false", "true") .c_str()) = ::
testing::Message()
;
7086 EXPECT_EQ("\"max-age=31536000\"", header->get("value")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"max-age=31536000\\\"\""
, "header->get(\"value\")->str()", "\"max-age=31536000\""
, header->get("value")->str()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7086, gtest_ar.failure_message()) = ::testing::Message()
;
7087
7088 // Check HTTP header user context.
7089 ConstElementPtr ctx_header = header->get("user-context");
7090 ASSERT_TRUE(ctx_header)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_header)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7090, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_header", "false", "true") .c_str()) = ::testing::Message
()
;
7091 ASSERT_EQ(1U, ctx_header->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "ctx_header->size()"
, 1U, ctx_header->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7091, gtest_ar.failure_message()) = ::testing::Message()
;
7092 ASSERT_TRUE(ctx_header->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_header->get("comment"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7092, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_header->get(\"comment\")", "false", "true") .c_str(
)) = ::testing::Message()
;
7093 EXPECT_EQ("\"HSTS header\"", ctx_header->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"HSTS header\\\"\""
, "ctx_header->get(\"comment\")->str()", "\"HSTS header\""
, ctx_header->get("comment")->str()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7093
, gtest_ar.failure_message()) = ::testing::Message()
;
7094
7095 // HTTP authentication.
7096 ConstElementPtr auth = socket->get("authentication");
7097 ASSERT_TRUE(auth)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(auth)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7097
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "auth", "false", "true") .c_str()) = ::testing::Message()
;
7098 ASSERT_TRUE(auth->get("type"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(auth->get("type"))
) ; else return ::testing::internal::AssertHelper(::testing::
TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7098, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "auth->get(\"type\")", "false", "true") .c_str()) = ::testing
::Message()
;
7099 EXPECT_EQ("\"basic\"", auth->get("type")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"basic\\\"\""
, "auth->get(\"type\")->str()", "\"basic\"", auth->get
("type")->str()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7099, gtest_ar.failure_message()) = ::testing::Message()
;
7100 ConstElementPtr ctx_auth = auth->get("user-context");
7101 ASSERT_TRUE(ctx_auth)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_auth)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7101, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_auth", "false", "true") .c_str()) = ::testing::Message
()
;
7102 ASSERT_EQ(1U, ctx_auth->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "ctx_auth->size()"
, 1U, ctx_auth->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7102, gtest_ar.failure_message()) = ::testing::Message()
;
7103 ASSERT_TRUE(ctx_auth->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_auth->get("comment"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7103, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_auth->get(\"comment\")", "false", "true") .c_str())
= ::testing::Message()
;
7104 EXPECT_EQ("\"basic HTTP authentication\"", ctx_auth->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"basic HTTP authentication\\\"\""
, "ctx_auth->get(\"comment\")->str()", "\"basic HTTP authentication\""
, ctx_auth->get("comment")->str()))) ; else ::testing::
internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7104
, gtest_ar.failure_message()) = ::testing::Message()
;
7105
7106 // Authentication client.
7107 ConstElementPtr clients = auth->get("clients");
7108 ASSERT_TRUE(clients)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(clients)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7108, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "clients", "false", "true") .c_str()) = ::testing::Message(
)
;
7109 ASSERT_EQ(1U, clients->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "clients->size()"
, 1U, clients->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7109, gtest_ar.failure_message()) = ::testing::Message()
;
7110 ConstElementPtr client;
7111 ASSERT_NO_THROW(client = clients->get(0))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
client = clients->get(0); } else static_assert(true, "");
} catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_7111
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_7111
; } } else gtest_label_testnothrow_7111 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7111, ("Expected: " "client = clients->get(0)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
7112 ASSERT_TRUE(client)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(client)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7112, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "client", "false", "true") .c_str()) = ::testing::Message()
;
7113 ASSERT_TRUE(client->get("user"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(client->get("user"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7113, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "client->get(\"user\")", "false", "true") .c_str()) = ::
testing::Message()
;
7114 ASSERT_EQ("\"admin\"", client->get("user")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"admin\\\"\""
, "client->get(\"user\")->str()", "\"admin\"", client->
get("user")->str()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7114, gtest_ar.failure_message()) = ::testing::Message()
;
7115 ASSERT_TRUE(client->get("password"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(client->get("password"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7115, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "client->get(\"password\")", "false", "true") .c_str()) =
::testing::Message()
;
7116 ASSERT_EQ("\"foobar\"", client->get("password")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"foobar\\\"\""
, "client->get(\"password\")->str()", "\"foobar\"", client
->get("password")->str()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7116, gtest_ar.failure_message()) = ::testing::Message()
;
7117 ConstElementPtr ctx_client = client->get("user-context");
7118 ASSERT_TRUE(ctx_client)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_client)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7118, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_client", "false", "true") .c_str()) = ::testing::Message
()
;
7119 ASSERT_EQ(1U, ctx_client->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "ctx_client->size()"
, 1U, ctx_client->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7119, gtest_ar.failure_message()) = ::testing::Message()
;
7120 ASSERT_TRUE(ctx_client->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_client->get("comment"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7120, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_client->get(\"comment\")", "false", "true") .c_str(
)) = ::testing::Message()
;
7121 EXPECT_EQ("\"admin is authorized\"", ctx_client->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"admin is authorized\\\"\""
, "ctx_client->get(\"comment\")->str()", "\"admin is authorized\""
, ctx_client->get("comment")->str()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7121
, gtest_ar.failure_message()) = ::testing::Message()
;
7122
7123 // Now verify that the shared network was indeed configured.
7124 const CfgSharedNetworks4Ptr& cfg_net =
7125 CfgMgr::instance().getStagingCfg()->getCfgSharedNetworks4();
7126 ASSERT_TRUE(cfg_net)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(cfg_net)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7126, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg_net", "false", "true") .c_str()) = ::testing::Message(
)
;
7127 const SharedNetwork4Collection* nets = cfg_net->getAll();
7128 ASSERT_TRUE(nets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(nets)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7128
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "nets", "false", "true") .c_str()) = ::testing::Message()
;
7129 ASSERT_EQ(1U, nets->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "nets->size()"
, 1U, nets->size()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7129, gtest_ar.failure_message()) = ::testing::Message()
;
7130 SharedNetwork4Ptr net = nets->at(0);
7131 ASSERT_TRUE(net)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(net)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7131
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "net", "false", "true") .c_str()) = ::testing::Message()
;
7132 EXPECT_EQ("foo", net->getName())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"foo\""
, "net->getName()", "foo", net->getName()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7132
, gtest_ar.failure_message()) = ::testing::Message()
;
7133
7134 // Check shared network user context.
7135 ConstElementPtr ctx_net = net->getContext();
7136 ASSERT_TRUE(ctx_net)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_net)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7136, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_net", "false", "true") .c_str()) = ::testing::Message(
)
;
7137 ASSERT_EQ(1U, ctx_net->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "ctx_net->size()"
, 1U, ctx_net->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7137, gtest_ar.failure_message()) = ::testing::Message()
;
7138 ASSERT_TRUE(ctx_net->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_net->get("comment"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7138, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_net->get(\"comment\")", "false", "true") .c_str()) =
::testing::Message()
;
7139 EXPECT_EQ("\"A shared network\"", ctx_net->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"A shared network\\\"\""
, "ctx_net->get(\"comment\")->str()", "\"A shared network\""
, ctx_net->get("comment")->str()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7139, gtest_ar.failure_message()) = ::testing::Message()
;
7140
7141 // The shared network has a subnet.
7142 const Subnet4SimpleCollection* subs = net->getAllSubnets();
7143 ASSERT_TRUE(subs)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subs)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7143
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subs", "false", "true") .c_str()) = ::testing::Message()
;
7144 ASSERT_EQ(1U, subs->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "subs->size()"
, 1U, subs->size()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7144, gtest_ar.failure_message()) = ::testing::Message()
;
7145 Subnet4Ptr sub = *subs->begin();
7146 ASSERT_TRUE(sub)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(sub)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7146
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "sub", "false", "true") .c_str()) = ::testing::Message()
;
7147 EXPECT_EQ(100U, sub->getID())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("100U", "sub->getID()"
, 100U, sub->getID()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7147, gtest_ar.failure_message()) = ::testing::Message()
;
7148 EXPECT_EQ("192.0.1.0/24", sub->toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.0.1.0/24\""
, "sub->toText()", "192.0.1.0/24", sub->toText()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7148, gtest_ar.failure_message()) = ::testing::Message()
;
7149
7150 // Check subnet user context.
7151 ConstElementPtr ctx_sub = sub->getContext();
7152 ASSERT_TRUE(ctx_sub)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_sub)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7152, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_sub", "false", "true") .c_str()) = ::testing::Message(
)
;
7153 ASSERT_EQ(1U, ctx_sub->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "ctx_sub->size()"
, 1U, ctx_sub->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7153, gtest_ar.failure_message()) = ::testing::Message()
;
7154 ASSERT_TRUE(ctx_sub->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_sub->get("comment"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7154, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_sub->get(\"comment\")", "false", "true") .c_str()) =
::testing::Message()
;
7155 EXPECT_EQ("\"A subnet\"", ctx_sub->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"A subnet\\\"\""
, "ctx_sub->get(\"comment\")->str()", "\"A subnet\"", ctx_sub
->get("comment")->str()))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7155, gtest_ar.failure_message()) = ::testing::Message()
;
7156
7157 // The subnet has a pool.
7158 const PoolCollection& pools = sub->getPools(Lease::TYPE_V4);
7159 ASSERT_EQ(1U, pools.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "pools.size()"
, 1U, pools.size()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7159, gtest_ar.failure_message()) = ::testing::Message()
;
7160 PoolPtr pool = pools.at(0);
7161 ASSERT_TRUE(pool)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7161
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
7162
7163 // Check pool user context.
7164 ConstElementPtr ctx_pool = pool->getContext();
7165 ASSERT_TRUE(ctx_pool)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_pool)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7165, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_pool", "false", "true") .c_str()) = ::testing::Message
()
;
7166 ASSERT_EQ(1U, ctx_pool->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "ctx_pool->size()"
, 1U, ctx_pool->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7166, gtest_ar.failure_message()) = ::testing::Message()
;
7167 ASSERT_TRUE(ctx_pool->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_pool->get("comment"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7167, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_pool->get(\"comment\")", "false", "true") .c_str())
= ::testing::Message()
;
7168 EXPECT_EQ("\"A pool\"", ctx_pool->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"A pool\\\"\""
, "ctx_pool->get(\"comment\")->str()", "\"A pool\"", ctx_pool
->get("comment")->str()))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7168, gtest_ar.failure_message()) = ::testing::Message()
;
7169
7170 // The subnet has a host reservation.
7171 uint8_t hw[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
7172 ConstHostPtr host =
7173 CfgMgr::instance().getStagingCfg()->getCfgHosts()->
7174 get4(100, Host::IDENT_HWADDR, &hw[0], sizeof(hw));
7175 ASSERT_TRUE(host)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(host)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7175
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
7176 EXPECT_EQ(Host::IDENT_HWADDR, host->getIdentifierType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("Host::IDENT_HWADDR"
, "host->getIdentifierType()", Host::IDENT_HWADDR, host->
getIdentifierType()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7176, gtest_ar.failure_message()) = ::testing::Message()
;
7177 EXPECT_EQ("aa:bb:cc:dd:ee:ff", host->getHWAddress()->toText(false))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"aa:bb:cc:dd:ee:ff\""
, "host->getHWAddress()->toText(false)", "aa:bb:cc:dd:ee:ff"
, host->getHWAddress()->toText(false)))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7177
, gtest_ar.failure_message()) = ::testing::Message()
;
7178 EXPECT_FALSE(host->getDuid())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(host->getDuid())
)) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7178, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host->getDuid()", "true", "false") .c_str()) = ::testing
::Message()
;
7179 EXPECT_EQ(100U, host->getIPv4SubnetID())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("100U", "host->getIPv4SubnetID()"
, 100U, host->getIPv4SubnetID()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7179, gtest_ar.failure_message()) = ::testing::Message()
;
7180 EXPECT_EQ(SUBNET_ID_UNUSED, host->getIPv6SubnetID())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("SUBNET_ID_UNUSED"
, "host->getIPv6SubnetID()", SUBNET_ID_UNUSED, host->getIPv6SubnetID
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7180, gtest_ar.failure_message()) = ::testing::Message()
;
7181 EXPECT_EQ("foo.example.com", host->getHostname())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"foo.example.com\""
, "host->getHostname()", "foo.example.com", host->getHostname
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7181, gtest_ar.failure_message()) = ::testing::Message()
;
7182
7183 // Check host user context.
7184 ConstElementPtr ctx_host = host->getContext();
7185 ASSERT_TRUE(ctx_host)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_host)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7185, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_host", "false", "true") .c_str()) = ::testing::Message
()
;
7186 ASSERT_EQ(1U, ctx_host->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "ctx_host->size()"
, 1U, ctx_host->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7186, gtest_ar.failure_message()) = ::testing::Message()
;
7187 ASSERT_TRUE(ctx_host->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_host->get("comment"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7187, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_host->get(\"comment\")", "false", "true") .c_str())
= ::testing::Message()
;
7188 EXPECT_EQ("\"A host reservation\"", ctx_host->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"A host reservation\\\"\""
, "ctx_host->get(\"comment\")->str()", "\"A host reservation\""
, ctx_host->get("comment")->str()))) ; else ::testing::
internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7188
, gtest_ar.failure_message()) = ::testing::Message()
;
7189
7190 // The host reservation has an option data.
7191 ConstCfgOptionPtr opts = host->getCfgOption4();
7192 ASSERT_TRUE(opts)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(opts)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7192
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opts", "false", "true") .c_str()) = ::testing::Message()
;
7193 EXPECT_FALSE(opts->empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(opts->empty())))
; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7193, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opts->empty()", "true", "false") .c_str()) = ::testing::
Message()
;
7194 const OptionDescriptor& host_desc =
7195 opts->get(DHCP4_OPTION_SPACE"dhcp4", DHO_DOMAIN_NAME);
7196 ASSERT_TRUE(host_desc.option_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(host_desc.option_)) ;
else return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7196, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host_desc.option_", "false", "true") .c_str()) = ::testing
::Message()
;
7197 EXPECT_EQ(DHO_DOMAIN_NAME, host_desc.option_->getType())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("DHO_DOMAIN_NAME"
, "host_desc.option_->getType()", DHO_DOMAIN_NAME, host_desc
.option_->getType()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7197, gtest_ar.failure_message()) = ::testing::Message()
;
7198
7199 // Check embedded option data user context.
7200 ConstElementPtr ctx_host_desc = host_desc.getContext();
7201 ASSERT_TRUE(ctx_host_desc)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_host_desc)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7201, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_host_desc", "false", "true") .c_str()) = ::testing::Message
()
;
7202 ASSERT_EQ(1U, ctx_host_desc->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "ctx_host_desc->size()"
, 1U, ctx_host_desc->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7202, gtest_ar.failure_message()) = ::testing::Message()
;
7203 ASSERT_TRUE(ctx_host_desc->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_host_desc->get
("comment"))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7203, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_host_desc->get(\"comment\")", "false", "true") .c_str
()) = ::testing::Message()
;
7204 EXPECT_EQ("\"An option in a reservation\"",switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"An option in a reservation\\\"\""
, "ctx_host_desc->get(\"comment\")->str()", "\"An option in a reservation\""
, ctx_host_desc->get("comment")->str()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7205
, gtest_ar.failure_message()) = ::testing::Message()
7205 ctx_host_desc->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"An option in a reservation\\\"\""
, "ctx_host_desc->get(\"comment\")->str()", "\"An option in a reservation\""
, ctx_host_desc->get("comment")->str()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7205
, gtest_ar.failure_message()) = ::testing::Message()
;
7206
7207 // Finally dynamic DNS update configuration.
7208 const D2ClientConfigPtr& d2 =
7209 CfgMgr::instance().getStagingCfg()->getD2ClientConfig();
7210 ASSERT_TRUE(d2)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(d2)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7210
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "d2", "false", "true") .c_str()) = ::testing::Message()
;
7211 EXPECT_FALSE(d2->getEnableUpdates())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(d2->getEnableUpdates
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7211, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "d2->getEnableUpdates()", "true", "false") .c_str()) = ::
testing::Message()
;
7212
7213 // Check dynamic DNS update configuration user context.
7214 ConstElementPtr ctx_d2 = d2->getContext();
7215 ASSERT_TRUE(ctx_d2)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_d2)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7215, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_d2", "false", "true") .c_str()) = ::testing::Message()
;
7216 ASSERT_EQ(1U, ctx_d2->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "ctx_d2->size()"
, 1U, ctx_d2->size()))) ; else return ::testing::internal::
AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7216, gtest_ar.failure_message()) = ::testing::Message()
;
7217 ASSERT_TRUE(ctx_d2->get("comment"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ctx_d2->get("comment"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7217, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_d2->get(\"comment\")", "false", "true") .c_str()) =
::testing::Message()
;
7218 EXPECT_EQ("\"No dynamic DNS\"", ctx_d2->get("comment")->str())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"\\\"No dynamic DNS\\\"\""
, "ctx_d2->get(\"comment\")->str()", "\"No dynamic DNS\""
, ctx_d2->get("comment")->str()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7218, gtest_ar.failure_message()) = ::testing::Message()
;
7219}
7220
7221// This test verifies that the global host reservations can be specified.
7222TEST_F(Dhcp4ParserTest, globalReservations)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("globalReservations") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_globalReservations_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_globalReservations_Test() = default
; ~Dhcp4ParserTest_globalReservations_Test() override = default
; Dhcp4ParserTest_globalReservations_Test (const Dhcp4ParserTest_globalReservations_Test
&) = delete; Dhcp4ParserTest_globalReservations_Test &
operator=( const Dhcp4ParserTest_globalReservations_Test &
) = delete; Dhcp4ParserTest_globalReservations_Test (Dhcp4ParserTest_globalReservations_Test
&&) noexcept = delete; Dhcp4ParserTest_globalReservations_Test
& operator=( Dhcp4ParserTest_globalReservations_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_globalReservations_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "globalReservations", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7222), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7222), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7222), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_globalReservations_Test
>); void Dhcp4ParserTest_globalReservations_Test::TestBody
()
{
7223 ConstElementPtr x;
7224 string config = "{ " + genIfaceConfig() + ","
7225 "\"rebind-timer\": 2000, \n"
7226 "\"renew-timer\": 1000,\n"
7227 "\"reservations\": [\n"
7228 " {\n"
7229 " \"duid\": \"01:02:03:04:05:06:07:08:09:0A\",\n"
7230 " \"ip-address\": \"192.0.200.1\",\n"
7231 " \"hostname\": \"global1\",\n"
7232 " \"option-data\": [\n"
7233 " {\n"
7234 " \"name\": \"name-servers\",\n"
7235 " \"data\": \"192.0.3.15\"\n"
7236 " },\n"
7237 " {\n"
7238 " \"name\": \"default-ip-ttl\",\n"
7239 " \"data\": \"32\"\n"
7240 " }\n"
7241 " ]\n"
7242 " },\n"
7243 " {\n"
7244 " \"hw-address\": \"01:02:03:04:05:06\",\n"
7245 " \"hostname\": \"global2\",\n"
7246 " \"option-data\": [\n"
7247 " {\n"
7248 " \"name\": \"name-servers\",\n"
7249 " \"data\": \"192.0.3.95\"\n"
7250 " },\n"
7251 " {\n"
7252 " \"name\": \"default-ip-ttl\",\n"
7253 " \"data\": \"11\"\n"
7254 " }\n"
7255 " ]\n"
7256 " }],\n"
7257 "\"subnet4\": [ \n"
7258 " { \n"
7259 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],\n"
7260 " \"subnet\": \"192.0.2.0/24\", \n"
7261 " \"id\": 123,\n"
7262 " \"reservations\": [\n"
7263 " ]\n"
7264 " },\n"
7265 " {\n"
7266 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],\n"
7267 " \"subnet\": \"192.0.4.0/24\",\n"
7268 " \"id\": 542\n"
7269 " }\n"
7270 "],\n"
7271 "\"valid-lifetime\": 4000 }\n";
7272
7273 ConstElementPtr json;
7274 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_7274
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_7274
; } } else gtest_label_testnothrow_7274 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7274, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
7275 extractConfig(config);
7276
7277 EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
x = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_7277; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7277; } } else gtest_label_testnothrow_7277
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7277, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
7278 checkResult(x, 0);
7279
7280 // Make sure all subnets have been successfully configured. There is no
7281 // need to sanity check the subnet properties because it should have
7282 // been already tested by other tests.
7283 const Subnet4Collection* subnets =
7284 CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
7285 ASSERT_TRUE(subnets)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnets)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7285, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
7286 ASSERT_EQ(2U, subnets->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "subnets->size()"
, 2U, subnets->size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7286, gtest_ar.failure_message()) = ::testing::Message()
;
7287
7288 // Hosts configuration must be available.
7289 CfgHostsPtr hosts_cfg = CfgMgr::instance().getStagingCfg()->getCfgHosts();
7290 ASSERT_TRUE(hosts_cfg)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(hosts_cfg)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7290, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg", "false", "true") .c_str()) = ::testing::Message
()
;
7291
7292 // Let's create a hardware address of the host named "global2"
7293 std::vector<uint8_t> hwaddr;
7294 for (unsigned int i = 1; i < 7; ++i) {
7295 hwaddr.push_back(static_cast<uint8_t>(i));
7296 }
7297
7298 // Retrieve the global reservation and sanity check the hostname reserved.
7299 ConstHostPtr host = hosts_cfg->get4(SUBNET_ID_GLOBAL, Host::IDENT_HWADDR,
7300 &hwaddr[0], hwaddr.size());
7301 ASSERT_TRUE(host)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(host)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7301
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
7302 EXPECT_EQ("global2", host->getHostname())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"global2\""
, "host->getHostname()", "global2", host->getHostname()
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7302, gtest_ar.failure_message()) = ::testing::Message()
;
7303
7304 // This reservation should be solely assigned to the subnet 234,
7305 // and not to other two.
7306 EXPECT_FALSE(hosts_cfg->get4(123, Host::IDENT_HWADDR,switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
123, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7307, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())"
, "true", "false") .c_str()) = ::testing::Message()
7307 &hwaddr[0], hwaddr.size()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
123, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7307, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
7308
7309 EXPECT_FALSE(hosts_cfg->get4(542, Host::IDENT_HWADDR,switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
542, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7310, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(542, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())"
, "true", "false") .c_str()) = ::testing::Message()
7310 &hwaddr[0], hwaddr.size()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
542, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7310, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(542, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
7311 // Check that options are assigned correctly.
7312 Option4AddrLstPtr opt_dns =
7313 retrieveOption<Option4AddrLstPtr>(*host, DHO_NAME_SERVERS);
7314 ASSERT_TRUE(opt_dns)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(opt_dns)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7314, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_dns", "false", "true") .c_str()) = ::testing::Message(
)
;
7315 Option4AddrLst::AddressContainer dns_addrs = opt_dns->getAddresses();
7316 ASSERT_EQ(1U, dns_addrs.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "dns_addrs.size()"
, 1U, dns_addrs.size()))) ; else return ::testing::internal::
AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7316, gtest_ar.failure_message()) = ::testing::Message()
;
7317 EXPECT_EQ("192.0.3.95", dns_addrs[0].toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.0.3.95\""
, "dns_addrs[0].toText()", "192.0.3.95", dns_addrs[0].toText(
)))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7317, gtest_ar.failure_message()) = ::testing::Message()
;
7318 OptionUint8Ptr opt_ttl =
7319 retrieveOption<OptionUint8Ptr>(*host, DHO_DEFAULT_IP_TTL);
7320 ASSERT_TRUE(opt_ttl)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(opt_ttl)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7320, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_ttl", "false", "true") .c_str()) = ::testing::Message(
)
;
7321 EXPECT_EQ(11, static_cast<int>(opt_ttl->getValue()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("11", "static_cast<int>(opt_ttl->getValue())"
, 11, static_cast<int>(opt_ttl->getValue())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7321, gtest_ar.failure_message()) = ::testing::Message()
;
7322
7323 // Do the same test for the DUID based reservation.
7324 std::vector<uint8_t> duid;
7325 for (unsigned int i = 1; i < 0xb; ++i) {
7326 duid.push_back(static_cast<uint8_t>(i));
7327 }
7328
7329 // Retrieve the global reservation and sanity check the hostname reserved.
7330 host = hosts_cfg->get4(SUBNET_ID_GLOBAL, Host::IDENT_DUID, &duid[0], duid.size());
7331 ASSERT_TRUE(host)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(host)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7331
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
7332 EXPECT_EQ("global1", host->getHostname())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"global1\""
, "host->getHostname()", "global1", host->getHostname()
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7332, gtest_ar.failure_message()) = ::testing::Message()
;
7333
7334 // Check that options are assigned correctly.
7335 opt_dns = retrieveOption<Option4AddrLstPtr>(*host, DHO_NAME_SERVERS);
7336 ASSERT_TRUE(opt_dns)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(opt_dns)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7336, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_dns", "false", "true") .c_str()) = ::testing::Message(
)
;
7337 dns_addrs = opt_dns->getAddresses();
7338 ASSERT_EQ(1U, dns_addrs.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "dns_addrs.size()"
, 1U, dns_addrs.size()))) ; else return ::testing::internal::
AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7338, gtest_ar.failure_message()) = ::testing::Message()
;
7339 EXPECT_EQ("192.0.3.15", dns_addrs[0].toText())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"192.0.3.15\""
, "dns_addrs[0].toText()", "192.0.3.15", dns_addrs[0].toText(
)))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7339, gtest_ar.failure_message()) = ::testing::Message()
;
7340 opt_ttl = retrieveOption<OptionUint8Ptr>(*host, DHO_DEFAULT_IP_TTL);
7341 ASSERT_TRUE(opt_ttl)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(opt_ttl)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7341, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_ttl", "false", "true") .c_str()) = ::testing::Message(
)
;
7342 EXPECT_EQ(32, static_cast<int>(opt_ttl->getValue()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("32", "static_cast<int>(opt_ttl->getValue())"
, 32, static_cast<int>(opt_ttl->getValue())))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7342, gtest_ar.failure_message()) = ::testing::Message()
;
7343
7344 // This reservation should be global solely and not assigned to
7345 // either subnet
7346 EXPECT_FALSE(hosts_cfg->get4(123, Host::IDENT_DUID, &duid[0], duid.size()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
123, Host::IDENT_DUID, &duid[0], duid.size())))) ; else ::
testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7346
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_DUID, &duid[0], duid.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
7347 EXPECT_FALSE(hosts_cfg->get4(542, Host::IDENT_DUID, &duid[0], duid.size()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(hosts_cfg->get4(
542, Host::IDENT_DUID, &duid[0], duid.size())))) ; else ::
testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7347
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(542, Host::IDENT_DUID, &duid[0], duid.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
7348}
7349
7350// Rather than disable these tests they are compiled out. This avoids them
7351// reporting as disabled and thereby drawing attention to them.
7352// This test verifies that configuration control with unsupported type fails
7353TEST_F(Dhcp4ParserTest, configControlInfoNoFactory)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("configControlInfoNoFactory") > 1,
"test_name must not be empty"); class Dhcp4ParserTest_configControlInfoNoFactory_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_configControlInfoNoFactory_Test
() = default; ~Dhcp4ParserTest_configControlInfoNoFactory_Test
() override = default; Dhcp4ParserTest_configControlInfoNoFactory_Test
(const Dhcp4ParserTest_configControlInfoNoFactory_Test &
) = delete; Dhcp4ParserTest_configControlInfoNoFactory_Test &
operator=( const Dhcp4ParserTest_configControlInfoNoFactory_Test
&) = delete; Dhcp4ParserTest_configControlInfoNoFactory_Test
(Dhcp4ParserTest_configControlInfoNoFactory_Test &&)
noexcept = delete; Dhcp4ParserTest_configControlInfoNoFactory_Test
& operator=( Dhcp4ParserTest_configControlInfoNoFactory_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_configControlInfoNoFactory_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "configControlInfoNoFactory", nullptr, nullptr, ::testing::
internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7353), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7353), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7353), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_configControlInfoNoFactory_Test
>); void Dhcp4ParserTest_configControlInfoNoFactory_Test::
TestBody()
{
7354 string config = PARSER_CONFIGS[5];
7355
7356 // Unregister "mysql" and ignore the return value.
7357 static_cast<void>(TestConfigBackendDHCPv4::
7358 unregisterBackendType(ConfigBackendDHCPv4Mgr::instance(),
7359 "mysql"));
7360
7361 // Should fail because "type=mysql" has no factories.
7362 configure(config, CONTROL_RESULT_FATAL_ERROR,
7363 "during update from config backend database: "
7364 "The Kea server has not been compiled with support for configuration "
7365 "database type: mysql. Did you forget to use -D mysql=enabled during "
7366 "setup or to load libdhcp_mysql hook library?");
7367}
7368
7369// This test verifies that configuration control info gets populated.
7370TEST_F(Dhcp4ParserTest, configControlInfo)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("configControlInfo") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_configControlInfo_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_configControlInfo_Test() = default
; ~Dhcp4ParserTest_configControlInfo_Test() override = default
; Dhcp4ParserTest_configControlInfo_Test (const Dhcp4ParserTest_configControlInfo_Test
&) = delete; Dhcp4ParserTest_configControlInfo_Test &
operator=( const Dhcp4ParserTest_configControlInfo_Test &
) = delete; Dhcp4ParserTest_configControlInfo_Test (Dhcp4ParserTest_configControlInfo_Test
&&) noexcept = delete; Dhcp4ParserTest_configControlInfo_Test
& operator=( Dhcp4ParserTest_configControlInfo_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_configControlInfo_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "configControlInfo", nullptr, nullptr, ::testing::internal::
CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7370), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7370), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7370), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_configControlInfo_Test
>); void Dhcp4ParserTest_configControlInfo_Test::TestBody(
)
{
7371 string config = PARSER_CONFIGS[5];
7372
7373 // Should be able to register a backend factory for "mysql".
7374 ASSERT_TRUE(TestConfigBackendDHCPv4::switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(TestConfigBackendDHCPv4
:: registerBackendType(ConfigBackendDHCPv4Mgr::instance(), "mysql"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7376, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "TestConfigBackendDHCPv4:: registerBackendType(ConfigBackendDHCPv4Mgr::instance(), \"mysql\")"
, "false", "true") .c_str()) = ::testing::Message()
7375 registerBackendType(ConfigBackendDHCPv4Mgr::instance(),switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(TestConfigBackendDHCPv4
:: registerBackendType(ConfigBackendDHCPv4Mgr::instance(), "mysql"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7376, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "TestConfigBackendDHCPv4:: registerBackendType(ConfigBackendDHCPv4Mgr::instance(), \"mysql\")"
, "false", "true") .c_str()) = ::testing::Message()
7376 "mysql"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(TestConfigBackendDHCPv4
:: registerBackendType(ConfigBackendDHCPv4Mgr::instance(), "mysql"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7376, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "TestConfigBackendDHCPv4:: registerBackendType(ConfigBackendDHCPv4Mgr::instance(), \"mysql\")"
, "false", "true") .c_str()) = ::testing::Message()
;
7377
7378 // Should parse ok, now that the factory has been registered.
7379 configure(config, CONTROL_RESULT_SUCCESS, "");
7380
7381 // Make sure the config control info is there.
7382 process::ConstConfigControlInfoPtr info =
7383 CfgMgr::instance().getStagingCfg()->getConfigControlInfo();
7384 ASSERT_TRUE(info)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(info)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7384
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "info", "false", "true") .c_str()) = ::testing::Message()
;
7385
7386 // Fetch the list of config dbs. It should have two entries.
7387 const process::ConfigDbInfoList& dblist = info->getConfigDatabases();
7388 ASSERT_EQ(2U, dblist.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("2U", "dblist.size()"
, 2U, dblist.size()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7388, gtest_ar.failure_message()) = ::testing::Message()
;
7389
7390 // Make sure the entries are what we expect and in the right order.
7391 // (DbAccessParser creates access strings with the keywords in
7392 // alphabetical order).
7393 EXPECT_EQ("name=keatest1 password=keatest type=mysql user=keatest",switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"name=keatest1 password=keatest type=mysql user=keatest\""
, "dblist.front().getAccessString()", "name=keatest1 password=keatest type=mysql user=keatest"
, dblist.front().getAccessString()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7394, gtest_ar.failure_message()) = ::testing::Message()
7394 dblist.front().getAccessString())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"name=keatest1 password=keatest type=mysql user=keatest\""
, "dblist.front().getAccessString()", "name=keatest1 password=keatest type=mysql user=keatest"
, dblist.front().getAccessString()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7394, gtest_ar.failure_message()) = ::testing::Message()
;
7395 EXPECT_EQ("name=keatest2 password=keatest retry-on-startup=true type=mysql user=keatest",switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"name=keatest2 password=keatest retry-on-startup=true type=mysql user=keatest\""
, "dblist.back().getAccessString()", "name=keatest2 password=keatest retry-on-startup=true type=mysql user=keatest"
, dblist.back().getAccessString()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7396, gtest_ar.failure_message()) = ::testing::Message()
7396 dblist.back().getAccessString())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"name=keatest2 password=keatest retry-on-startup=true type=mysql user=keatest\""
, "dblist.back().getAccessString()", "name=keatest2 password=keatest retry-on-startup=true type=mysql user=keatest"
, dblist.back().getAccessString()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7396, gtest_ar.failure_message()) = ::testing::Message()
;
7397
7398 // Verify that the config-fetch-wait-time is correct.
7399 EXPECT_FALSE(info->getConfigFetchWaitTime().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(info->getConfigFetchWaitTime
().unspecified()))) ; else ::testing::internal::AssertHelper(
::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7399, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "info->getConfigFetchWaitTime().unspecified()", "true", "false"
) .c_str()) = ::testing::Message()
;
7400 EXPECT_EQ(10U, info->getConfigFetchWaitTime().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("10U", "info->getConfigFetchWaitTime().get()"
, 10U, info->getConfigFetchWaitTime().get()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7400
, gtest_ar.failure_message()) = ::testing::Message()
;
7401}
7402
7403// Check whether it is possible to configure server-tag
7404TEST_F(Dhcp4ParserTest, serverTag)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("serverTag") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_serverTag_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_serverTag_Test() = default; ~Dhcp4ParserTest_serverTag_Test
() override = default; Dhcp4ParserTest_serverTag_Test (const Dhcp4ParserTest_serverTag_Test
&) = delete; Dhcp4ParserTest_serverTag_Test & operator
=( const Dhcp4ParserTest_serverTag_Test &) = delete; Dhcp4ParserTest_serverTag_Test
(Dhcp4ParserTest_serverTag_Test &&) noexcept = delete
; Dhcp4ParserTest_serverTag_Test & operator=( Dhcp4ParserTest_serverTag_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_serverTag_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "serverTag", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7404
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7404), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7404), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_serverTag_Test
>); void Dhcp4ParserTest_serverTag_Test::TestBody()
{
7405 // Config without server-tag
7406 string config_no_tag = "{ " + genIfaceConfig() + ","
7407 "\"subnet4\": [ ] "
7408 "}";
7409
7410 // Config with server-tag
7411 string config_tag = "{ " + genIfaceConfig() + ","
7412 "\"server-tag\": \"boo\", "
7413 "\"subnet4\": [ ] "
7414 "}";
7415
7416 // Config with an invalid server-tag
7417 string bad_tag = "{ " + genIfaceConfig() + ","
7418 "\"server-tag\": 777, "
7419 "\"subnet4\": [ ] "
7420 "}";
7421
7422 // Let's check the default. It should be empty.
7423 ASSERT_TRUE(CfgMgr::instance().getStagingCfg()->getServerTag().empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(CfgMgr::instance().getStagingCfg
()->getServerTag().empty())) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7423, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getServerTag().empty()"
, "false", "true") .c_str()) = ::testing::Message()
;
7424
7425 // Configuration with no tag should default to an emtpy tag value.
7426 configure(config_no_tag, CONTROL_RESULT_SUCCESS, "");
7427 EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getServerTag().empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(CfgMgr::instance().getStagingCfg
()->getServerTag().empty())) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7427, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getServerTag().empty()"
, "false", "true") .c_str()) = ::testing::Message()
;
7428
7429 // Clear the config
7430 CfgMgr::instance().clear();
7431
7432 // Configuration with the tag should have the tag value.
7433 configure(config_tag, CONTROL_RESULT_SUCCESS, "");
7434 EXPECT_EQ("boo", CfgMgr::instance().getStagingCfg()->getServerTag().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"boo\""
, "CfgMgr::instance().getStagingCfg()->getServerTag().get()"
, "boo", CfgMgr::instance().getStagingCfg()->getServerTag(
).get()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7434, gtest_ar.failure_message()) = ::testing::Message()
;
7435
7436 // Make sure a invalid server-tag fails to parse.
7437 ASSERT_THROW(parseDHCP4(bad_tag), std::exception)switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { bool gtest_caught_expected = false; try { if (
::testing::internal::AlwaysTrue()) { parseDHCP4(bad_tag); } else
static_assert(true, ""); } catch (std::exception const&)
{ gtest_caught_expected = true; } catch (typename std::conditional
< std::is_same<typename std::remove_cv<typename std::
remove_reference< std::exception>::type>::type, std::
exception>::value, const ::testing::internal::NeverThrown&
, const std::exception&>::type e) { gtest_msg.value = "Expected: "
"parseDHCP4(bad_tag)" " throws an exception of type " "std::exception"
".\n Actual: it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testthrow_7437; } catch (...) { gtest_msg.value =
"Expected: " "parseDHCP4(bad_tag)" " throws an exception of type "
"std::exception" ".\n Actual: it throws a different type.";
goto gtest_label_testthrow_7437; } if (!gtest_caught_expected
) { gtest_msg.value = "Expected: " "parseDHCP4(bad_tag)" " throws an exception of type "
"std::exception" ".\n Actual: it throws nothing."; goto gtest_label_testthrow_7437
; } } else gtest_label_testthrow_7437 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7437, gtest_msg.value.c_str()) = ::testing::Message()
;
7438}
7439
7440// Check whether it is possible to configure packet queue
7441TEST_F(Dhcp4ParserTest, dhcpQueueControl)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("dhcpQueueControl") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_dhcpQueueControl_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_dhcpQueueControl_Test() = default;
~Dhcp4ParserTest_dhcpQueueControl_Test() override = default;
Dhcp4ParserTest_dhcpQueueControl_Test (const Dhcp4ParserTest_dhcpQueueControl_Test
&) = delete; Dhcp4ParserTest_dhcpQueueControl_Test &
operator=( const Dhcp4ParserTest_dhcpQueueControl_Test &
) = delete; Dhcp4ParserTest_dhcpQueueControl_Test (Dhcp4ParserTest_dhcpQueueControl_Test
&&) noexcept = delete; Dhcp4ParserTest_dhcpQueueControl_Test
& operator=( Dhcp4ParserTest_dhcpQueueControl_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_dhcpQueueControl_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "dhcpQueueControl", nullptr, nullptr, ::testing::internal::
CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7441), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7441), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7441), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_dhcpQueueControl_Test
>); void Dhcp4ParserTest_dhcpQueueControl_Test::TestBody()
{
7442 struct Scenario {
7443 std::string description_;
7444 std::string json_;
7445 std::string mt_json_;
7446 };
7447
7448 std::vector<Scenario> scenarios = {
7449 {
7450 "no entry",
7451 "",
7452 "",
7453 },
7454 {
7455 "queue disabled",
7456 "{ \n"
7457 " \"enable-queue\": false \n"
7458 "} \n",
7459 R"("multi-threading": {
7460 "enable-multi-threading": false
7461 })",
7462 },
7463 {
7464 "queue enabled at first, but gets forcefully disabled by MT",
7465 "{ \n"
7466 " \"enable-queue\": true \n"
7467 "} \n",
7468 R"("multi-threading": {
7469 "enable-multi-threading": true
7470 })",
7471 },
7472 {
7473 "queue disabled, arbitrary content allowed",
7474 "{ \n"
7475 " \"enable-queue\": false, \n"
7476 " \"foo\": \"bogus\", \n"
7477 " \"random-int\" : 1234 \n"
7478 "} \n",
7479 R"("multi-threading": {
7480 "enable-multi-threading": false
7481 })",
7482 },
7483 {
7484 "queue enabled, with queue-type",
7485 "{ \n"
7486 " \"enable-queue\": true, \n"
7487 " \"queue-type\": \"some-type\" \n"
7488 "} \n",
7489 R"("multi-threading": {
7490 "enable-multi-threading": false
7491 })",
7492 },
7493 {
7494 "queue enabled with queue-type and arbitrary content",
7495 "{ \n"
7496 " \"enable-queue\": true, \n"
7497 " \"queue-type\": \"some-type\", \n"
7498 " \"foo\": \"bogus\", \n"
7499 " \"random-int\" : 1234 \n"
7500 "} \n",
7501 R"("multi-threading": {
7502 "enable-multi-threading": false
7503 })",
7504 }
7505 };
7506
7507 // Let's check the default. It should be empty.
7508 data::ConstElementPtr staged_control;
7509 staged_control = CfgMgr::instance().getStagingCfg()->getDHCPQueueControl();
7510 ASSERT_FALSE(staged_control)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(staged_control))) ;
else return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7510, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "staged_control", "true", "false") .c_str()) = ::testing::Message
()
;
7511
7512 // Iterate over the valid scenarios and verify they succeed.
7513 data::ElementPtr exp_control;
7514 for (auto const& scenario : scenarios) {
7515 SCOPED_TRACE(scenario.description_)const ::testing::ScopedTrace gtest_trace_7515( "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7515, (scenario.description_))
;
7516 {
7517 // Clear the config
7518 CfgMgr::instance().clear();
7519
7520 // Construct the config JSON
7521 std::stringstream os;
7522 os << "{ " + genIfaceConfig();
7523 if (!scenario.json_.empty()) {
7524 os << ",\n \"dhcp-queue-control\": " << scenario.json_;
7525 }
7526 if (!scenario.mt_json_.empty()) {
7527 os << ",\n" << scenario.mt_json_;
7528 }
7529 os << "\n}\n";
7530
7531 // Configure the server. This should succeed.
7532 configure(os.str(), CONTROL_RESULT_SUCCESS, "");
7533
7534 // Fetch the queue control info.
7535 staged_control = CfgMgr::instance().getStagingCfg()->getDHCPQueueControl();
7536
7537 // Make sure the staged queue config exists.
7538 ASSERT_TRUE(staged_control)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(staged_control)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7538, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "staged_control", "false", "true") .c_str()) = ::testing::Message
()
;
7539
7540 // Now build the expected queue control content.
7541 if (scenario.json_.empty()) {
7542 exp_control = Element::createMap();
7543 } else {
7544 try {
7545 exp_control = boost::const_pointer_cast<Element>(Element::fromJSON(scenario.json_));
7546 } catch (const std::exception& ex) {
7547 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7547, "Failed") = ::testing::Message()
<< " cannot convert expected JSON, test is broken:"
7548 << ex.what();
7549 }
7550 }
7551
7552 // Add the defaults to expected queue control.
7553 SimpleParser4::setDefaults(exp_control, SimpleParser4::DHCP_QUEUE_CONTROL4_DEFAULTS);
7554
7555 // This specific scenario is the only one where we expect enable-queue
7556 // to be changed from what the user set it to.
7557 if (scenario.description_ == "queue enabled at first, but gets forcefully disabled by MT") {
7558 exp_control->set("enable-queue", Element::create(false));
7559 }
7560
7561 // Verify that the staged queue control equals the expected queue control.
7562 expectEqWithDiff(staged_control, exp_control);
7563 }
7564 }
7565}
7566
7567// Check that we catch invalid dhcp-queue-control content
7568TEST_F(Dhcp4ParserTest, dhcpQueueControlInvalid)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("dhcpQueueControlInvalid") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_dhcpQueueControlInvalid_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_dhcpQueueControlInvalid_Test
() = default; ~Dhcp4ParserTest_dhcpQueueControlInvalid_Test()
override = default; Dhcp4ParserTest_dhcpQueueControlInvalid_Test
(const Dhcp4ParserTest_dhcpQueueControlInvalid_Test &) =
delete; Dhcp4ParserTest_dhcpQueueControlInvalid_Test & operator
=( const Dhcp4ParserTest_dhcpQueueControlInvalid_Test &) =
delete; Dhcp4ParserTest_dhcpQueueControlInvalid_Test (Dhcp4ParserTest_dhcpQueueControlInvalid_Test
&&) noexcept = delete; Dhcp4ParserTest_dhcpQueueControlInvalid_Test
& operator=( Dhcp4ParserTest_dhcpQueueControlInvalid_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_dhcpQueueControlInvalid_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "dhcpQueueControlInvalid", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7568), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7568), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7568), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_dhcpQueueControlInvalid_Test
>); void Dhcp4ParserTest_dhcpQueueControlInvalid_Test::TestBody
()
{
7569 struct Scenario {
7570 std::string description_;
7571 std::string json_;
7572 std::string exp_error_;
7573 };
7574
7575 std::vector<Scenario> scenarios = {
7576 {
7577 "not a map",
7578 "75 \n",
7579 "<string>:2.24-25: syntax error, unexpected integer, expecting {"
7580 },
7581 {
7582 "enable-queue missing",
7583 "{ \n"
7584 " \"enable-type\": \"some-type\" \n"
7585 "} \n",
7586 "missing parameter 'enable-queue' (<string>:2:2) "
7587 "[dhcp-queue-control map between <string>:2:24 and <string>:4:1]"
7588 },
7589 {
7590 "enable-queue not boolean",
7591 "{ \n"
7592 " \"enable-queue\": \"always\" \n"
7593 "} \n",
7594 "<string>:3.20-27: syntax error, unexpected constant string, "
7595 "expecting boolean"
7596 },
7597 {
7598 "queue enabled, type not a string",
7599 "{ \n"
7600 " \"enable-queue\": true, \n"
7601 " \"queue-type\": 7777 \n"
7602 "} \n",
7603 "<string>:4.18-21: syntax error, unexpected integer, "
7604 "expecting constant string"
7605 }
7606 };
7607
7608 // Iterate over the incorrect scenarios and verify they
7609 // fail as expected. Note, we use parseDHCP4() directly
7610 // as all of the errors above are enforced by the grammar.
7611 for (auto const& scenario : scenarios) {
7612 SCOPED_TRACE(scenario.description_)const ::testing::ScopedTrace gtest_trace_7612( "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7612, (scenario.description_))
;
7613 {
7614 // Construct the config JSON
7615 std::stringstream os;
7616 os << "{ " + genIfaceConfig();
7617 os << ",\n \"dhcp-queue-control\": " << scenario.json_;
7618 os << "} \n";
7619
7620 std::string error_msg = "";
7621 try {
7622 ASSERT_TRUE(parseDHCP4(os.str(), false))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(parseDHCP4(os.str(), false
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7622, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "parseDHCP4(os.str(), false)", "false", "true") .c_str()) =
::testing::Message()
<< "parser returned empty element";
7623 } catch(const std::exception& ex) {
7624 error_msg = ex.what();
7625 }
7626
7627 ASSERT_FALSE(error_msg.empty())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(error_msg.empty()))
) ; else return ::testing::internal::AssertHelper(::testing::
TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7627, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "error_msg.empty()", "true", "false") .c_str()) = ::testing
::Message()
<< "parseDHCP4 should have thrown";
7628 EXPECT_EQ(scenario.exp_error_, error_msg)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("scenario.exp_error_"
, "error_msg", scenario.exp_error_, error_msg))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7628
, gtest_ar.failure_message()) = ::testing::Message()
;
7629 }
7630 }
7631}
7632
7633// Checks inheritence of calculate-tee-times, t1-percent, t2-percent
7634TEST_F(Dhcp4ParserTest, calculateTeeTimesInheritence)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("calculateTeeTimesInheritence") > 1
, "test_name must not be empty"); class Dhcp4ParserTest_calculateTeeTimesInheritence_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_calculateTeeTimesInheritence_Test
() = default; ~Dhcp4ParserTest_calculateTeeTimesInheritence_Test
() override = default; Dhcp4ParserTest_calculateTeeTimesInheritence_Test
(const Dhcp4ParserTest_calculateTeeTimesInheritence_Test &
) = delete; Dhcp4ParserTest_calculateTeeTimesInheritence_Test
& operator=( const Dhcp4ParserTest_calculateTeeTimesInheritence_Test
&) = delete; Dhcp4ParserTest_calculateTeeTimesInheritence_Test
(Dhcp4ParserTest_calculateTeeTimesInheritence_Test &&
) noexcept = delete; Dhcp4ParserTest_calculateTeeTimesInheritence_Test
& operator=( Dhcp4ParserTest_calculateTeeTimesInheritence_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_calculateTeeTimesInheritence_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "calculateTeeTimesInheritence", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7634), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7634), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7634), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_calculateTeeTimesInheritence_Test
>); void Dhcp4ParserTest_calculateTeeTimesInheritence_Test
::TestBody()
{
7635 // Configure the server. This should succeed.
7636 string config =
7637 "{ \n"
7638 " \"interfaces-config\": { \n"
7639 " \"interfaces\": [\"*\" ] \n"
7640 " }, \n"
7641 " \"valid-lifetime\": 4000, \n"
7642 " \"shared-networks\": [ { \n"
7643 " \"name\": \"foo\", \n"
7644 " \"calculate-tee-times\": true, \n"
7645 " \"t1-percent\": .4, \n"
7646 " \"t2-percent\": .75,\n"
7647 " \"subnet4\": ["
7648 " { "
7649 " \"id\": 100,"
7650 " \"subnet\": \"192.0.1.0/24\", \n"
7651 " \"pools\": [ { \"pool\": \"192.0.1.1-192.0.1.10\" } ], \n"
7652 " \"calculate-tee-times\": false,\n"
7653 " \"t1-percent\": .45, \n"
7654 " \"t2-percent\": .65 \n"
7655 " }, \n"
7656 " { \n"
7657 " \"id\": 200, \n"
7658 " \"subnet\": \"192.0.2.0/24\", \n"
7659 " \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\" } ] \n"
7660 " } \n"
7661 " ] \n"
7662 " } ], \n"
7663 " \"subnet4\": [ { \n"
7664 " \"id\": 300, \n"
7665 " \"subnet\": \"192.0.3.0/24\", \n"
7666 " \"pools\": [ { \"pool\": \"192.0.3.0 - 192.0.3.15\" } ]\n"
7667 " } ] \n"
7668 "} \n";
7669
7670 extractConfig(config);
7671 configure(config, CONTROL_RESULT_SUCCESS, "");
7672
7673 CfgSubnets4Ptr subnets4 = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
7674
7675 // Subnet 100 should use its own explicit values.
7676 ConstSubnet4Ptr subnet4 = subnets4->getBySubnetId(100);
7677 ASSERT_TRUE(subnet4)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet4)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7677, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet4", "false", "true") .c_str()) = ::testing::Message(
)
;
7678 EXPECT_FALSE(subnet4->getCalculateTeeTimes())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet4->getCalculateTeeTimes
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7678, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet4->getCalculateTeeTimes()", "true", "false") .c_str
()) = ::testing::Message()
;
7679 EXPECT_TRUE(util::areDoublesEquivalent(0.45, subnet4->getT1Percent()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(util::areDoublesEquivalent
(0.45, subnet4->getT1Percent()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7679, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "util::areDoublesEquivalent(0.45, subnet4->getT1Percent())"
, "false", "true") .c_str()) = ::testing::Message()
;
7680 EXPECT_TRUE(util::areDoublesEquivalent(0.65, subnet4->getT2Percent()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(util::areDoublesEquivalent
(0.65, subnet4->getT2Percent()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7680, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "util::areDoublesEquivalent(0.65, subnet4->getT2Percent())"
, "false", "true") .c_str()) = ::testing::Message()
;
7681
7682 // Subnet 200 should use the shared-network values.
7683 subnet4 = subnets4->getBySubnetId(200);
7684 ASSERT_TRUE(subnet4)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet4)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7684, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet4", "false", "true") .c_str()) = ::testing::Message(
)
;
7685 EXPECT_TRUE(subnet4->getCalculateTeeTimes())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet4->getCalculateTeeTimes
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7685, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet4->getCalculateTeeTimes()", "false", "true") .c_str
()) = ::testing::Message()
;
7686 EXPECT_TRUE(util::areDoublesEquivalent(0.4, subnet4->getT1Percent()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(util::areDoublesEquivalent
(0.4, subnet4->getT1Percent()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7686, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "util::areDoublesEquivalent(0.4, subnet4->getT1Percent())"
, "false", "true") .c_str()) = ::testing::Message()
;
7687 EXPECT_TRUE(util::areDoublesEquivalent(0.75, subnet4->getT2Percent()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(util::areDoublesEquivalent
(0.75, subnet4->getT2Percent()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7687, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "util::areDoublesEquivalent(0.75, subnet4->getT2Percent())"
, "false", "true") .c_str()) = ::testing::Message()
;
7688
7689 // Subnet 300 should use the global values.
7690 subnet4 = subnets4->getBySubnetId(300);
7691 ASSERT_TRUE(subnet4)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet4)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7691, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet4", "false", "true") .c_str()) = ::testing::Message(
)
;
7692 EXPECT_FALSE(subnet4->getCalculateTeeTimes())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet4->getCalculateTeeTimes
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7692, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet4->getCalculateTeeTimes()", "true", "false") .c_str
()) = ::testing::Message()
;
7693 EXPECT_TRUE(util::areDoublesEquivalent(0.5, subnet4->getT1Percent()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(util::areDoublesEquivalent
(0.5, subnet4->getT1Percent()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7693, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "util::areDoublesEquivalent(0.5, subnet4->getT1Percent())"
, "false", "true") .c_str()) = ::testing::Message()
;
7694 EXPECT_TRUE(util::areDoublesEquivalent(0.875, subnet4->getT2Percent()))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(util::areDoublesEquivalent
(0.875, subnet4->getT2Percent()))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7694, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "util::areDoublesEquivalent(0.875, subnet4->getT2Percent())"
, "false", "true") .c_str()) = ::testing::Message()
;
7695}
7696
7697// This test checks that the global store-extended-info parameter is optional
7698// and that values under the subnet are used.
7699TEST_F(Dhcp4ParserTest, storeExtendedInfoNoGlobal)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("storeExtendedInfoNoGlobal") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_storeExtendedInfoNoGlobal_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_storeExtendedInfoNoGlobal_Test
() = default; ~Dhcp4ParserTest_storeExtendedInfoNoGlobal_Test
() override = default; Dhcp4ParserTest_storeExtendedInfoNoGlobal_Test
(const Dhcp4ParserTest_storeExtendedInfoNoGlobal_Test &)
= delete; Dhcp4ParserTest_storeExtendedInfoNoGlobal_Test &
operator=( const Dhcp4ParserTest_storeExtendedInfoNoGlobal_Test
&) = delete; Dhcp4ParserTest_storeExtendedInfoNoGlobal_Test
(Dhcp4ParserTest_storeExtendedInfoNoGlobal_Test &&) noexcept
= delete; Dhcp4ParserTest_storeExtendedInfoNoGlobal_Test &
operator=( Dhcp4ParserTest_storeExtendedInfoNoGlobal_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_storeExtendedInfoNoGlobal_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "storeExtendedInfoNoGlobal", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7699), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7699), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7699), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_storeExtendedInfoNoGlobal_Test
>); void Dhcp4ParserTest_storeExtendedInfoNoGlobal_Test::TestBody
()
{
7700 const string config = "{ " + genIfaceConfig() + ","
7701 "\"rebind-timer\": 2000, "
7702 "\"renew-timer\": 1000, "
7703 "\"subnet4\": [ "
7704 "{"
7705 " \"id\": 1,"
7706 " \"store-extended-info\": true,"
7707 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
7708 " \"subnet\": \"192.0.2.0/24\""
7709 "},"
7710 "{"
7711 " \"id\": 2,"
7712 " \"store-extended-info\": false,"
7713 " \"pools\": [ { \"pool\": \"192.0.3.1 - 192.0.3.100\" } ],"
7714 " \"subnet\": \"192.0.3.0/24\""
7715 "} ],"
7716 "\"valid-lifetime\": 4000 }";
7717
7718 ConstElementPtr json;
7719 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_7719
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_7719
; } } else gtest_label_testnothrow_7719 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7719, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
7720 extractConfig(config);
7721
7722 ConstElementPtr status;
7723 ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_7723; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7723; } } else gtest_label_testnothrow_7723
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7723, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
7724 checkResult(status, 0);
7725
7726 // First subnet should use global default.
7727 CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
7728 ConstSubnet4Ptr subnet1 = cfg->selectSubnet(IOAddress("192.0.2.1"));
7729 ASSERT_TRUE(subnet1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet1)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7729, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1", "false", "true") .c_str()) = ::testing::Message(
)
;
7730 // Reset the fetch global function to staging (vs current) config.
7731 Subnet4Ptr mutable_subnet1 = boost::const_pointer_cast<Subnet4>(subnet1);
7732 mutable_subnet1->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
7733 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
7734 });
7735 EXPECT_TRUE(subnet1->getStoreExtendedInfo())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet1->getStoreExtendedInfo
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7735, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1->getStoreExtendedInfo()", "false", "true") .c_str
()) = ::testing::Message()
;
7736
7737 // Second subnet should use its own value.
7738 ConstSubnet4Ptr subnet2 = cfg->selectSubnet(IOAddress("192.0.3.1"));
7739 ASSERT_TRUE(subnet2)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet2)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7739, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2", "false", "true") .c_str()) = ::testing::Message(
)
;
7740 // Reset the fetch global function to staging (vs current) config.
7741 Subnet4Ptr mutable_subnet2 = boost::const_pointer_cast<Subnet4>(subnet2);
7742 mutable_subnet2->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
7743 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
7744 });
7745 EXPECT_FALSE(subnet2->getStoreExtendedInfo())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet2->getStoreExtendedInfo
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7745, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2->getStoreExtendedInfo()", "true", "false") .c_str
()) = ::testing::Message()
;
7746}
7747
7748// This test checks that the global store-extended-info parameter is used
7749// when there is no such parameter under subnet and that the parameter
7750// specified for a subnet overrides the global setting.
7751TEST_F(Dhcp4ParserTest, storeExtendedInfoGlobal)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("storeExtendedInfoGlobal") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_storeExtendedInfoGlobal_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_storeExtendedInfoGlobal_Test
() = default; ~Dhcp4ParserTest_storeExtendedInfoGlobal_Test()
override = default; Dhcp4ParserTest_storeExtendedInfoGlobal_Test
(const Dhcp4ParserTest_storeExtendedInfoGlobal_Test &) =
delete; Dhcp4ParserTest_storeExtendedInfoGlobal_Test & operator
=( const Dhcp4ParserTest_storeExtendedInfoGlobal_Test &) =
delete; Dhcp4ParserTest_storeExtendedInfoGlobal_Test (Dhcp4ParserTest_storeExtendedInfoGlobal_Test
&&) noexcept = delete; Dhcp4ParserTest_storeExtendedInfoGlobal_Test
& operator=( Dhcp4ParserTest_storeExtendedInfoGlobal_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_storeExtendedInfoGlobal_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "storeExtendedInfoGlobal", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7751), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7751), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7751), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_storeExtendedInfoGlobal_Test
>); void Dhcp4ParserTest_storeExtendedInfoGlobal_Test::TestBody
()
{
7752 const string config = "{ " + genIfaceConfig() + ","
7753 "\"rebind-timer\": 2000, "
7754 "\"renew-timer\": 1000, "
7755 "\"store-extended-info\": true,"
7756 "\"subnet4\": [ "
7757 "{"
7758 " \"id\": 1,"
7759 " \"store-extended-info\": false,"
7760 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
7761 " \"subnet\": \"192.0.2.0/24\""
7762 "},"
7763 "{"
7764 " \"id\": 2,"
7765 " \"pools\": [ { \"pool\": \"192.0.3.1 - 192.0.3.100\" } ],"
7766 " \"subnet\": \"192.0.3.0/24\""
7767 "} ],"
7768 "\"valid-lifetime\": 4000 }";
7769
7770 ConstElementPtr json;
7771 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_7771
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_7771
; } } else gtest_label_testnothrow_7771 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7771, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
7772 extractConfig(config);
7773
7774 ConstElementPtr status;
7775 ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_7775; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7775; } } else gtest_label_testnothrow_7775
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7775, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
7776 checkResult(status, 0);
7777
7778 // First subnet should override the global value.
7779 CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
7780 ConstSubnet4Ptr subnet1 = cfg->selectSubnet(IOAddress("192.0.2.1"));
7781 ASSERT_TRUE(subnet1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet1)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7781, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1", "false", "true") .c_str()) = ::testing::Message(
)
;
7782 // Reset the fetch global function to staging (vs current) config.
7783 Subnet4Ptr mutable_subnet1 = boost::const_pointer_cast<Subnet4>(subnet1);
7784 mutable_subnet1->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
7785 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
7786 });
7787 EXPECT_FALSE(subnet1->getStoreExtendedInfo())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet1->getStoreExtendedInfo
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7787, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1->getStoreExtendedInfo()", "true", "false") .c_str
()) = ::testing::Message()
;
7788
7789 ConstSubnet4Ptr subnet2 = cfg->selectSubnet(IOAddress("192.0.3.1"));
7790 ASSERT_TRUE(subnet2)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet2)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7790, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2", "false", "true") .c_str()) = ::testing::Message(
)
;
7791 // Reset the fetch global function to staging (vs current) config.
7792 Subnet4Ptr mutable_subnet2 = boost::const_pointer_cast<Subnet4>(subnet2);
7793 mutable_subnet2->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
7794 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
7795 });
7796 EXPECT_TRUE(subnet2->getStoreExtendedInfo())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet2->getStoreExtendedInfo
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7796, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2->getStoreExtendedInfo()", "false", "true") .c_str
()) = ::testing::Message()
;
7797}
7798
7799/// This test checks that the statistic-default-sample-count and age
7800/// global parameters are committed to the stats manager as expected.
7801TEST_F(Dhcp4ParserTest, statsDefaultLimits)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("statsDefaultLimits") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_statsDefaultLimits_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_statsDefaultLimits_Test() = default
; ~Dhcp4ParserTest_statsDefaultLimits_Test() override = default
; Dhcp4ParserTest_statsDefaultLimits_Test (const Dhcp4ParserTest_statsDefaultLimits_Test
&) = delete; Dhcp4ParserTest_statsDefaultLimits_Test &
operator=( const Dhcp4ParserTest_statsDefaultLimits_Test &
) = delete; Dhcp4ParserTest_statsDefaultLimits_Test (Dhcp4ParserTest_statsDefaultLimits_Test
&&) noexcept = delete; Dhcp4ParserTest_statsDefaultLimits_Test
& operator=( Dhcp4ParserTest_statsDefaultLimits_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_statsDefaultLimits_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "statsDefaultLimits", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7801), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7801), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7801), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_statsDefaultLimits_Test
>); void Dhcp4ParserTest_statsDefaultLimits_Test::TestBody
()
{
7802 std::string config = "{ " + genIfaceConfig() + ","
7803 "\"rebind-timer\": 2000, "
7804 "\"renew-timer\": 1000, "
7805 "\"statistic-default-sample-count\": 10, "
7806 "\"statistic-default-sample-age\": 5, "
7807 "\"valid-lifetime\": 4000 }";
7808
7809 ConstElementPtr json;
7810 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_7810
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_7810
; } } else gtest_label_testnothrow_7810 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7810, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
7811 extractConfig(config);
7812
7813 ConstElementPtr status;
7814 ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_7814; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7814; } } else gtest_label_testnothrow_7814
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7814, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
7815 checkResult(status, 0);
7816
7817 CfgMgr::instance().commit();
7818
7819 stats::StatsMgr& stats_mgr = stats::StatsMgr::instance();
7820 EXPECT_EQ(10U, stats_mgr.getMaxSampleCountDefault())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("10U", "stats_mgr.getMaxSampleCountDefault()"
, 10U, stats_mgr.getMaxSampleCountDefault()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7820
, gtest_ar.failure_message()) = ::testing::Message()
;
7821 EXPECT_EQ("00:00:05",switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"00:00:05\""
, "util::durationToText(stats_mgr.getMaxSampleAgeDefault(), 0)"
, "00:00:05", util::durationToText(stats_mgr.getMaxSampleAgeDefault
(), 0)))) ; else ::testing::internal::AssertHelper(::testing::
TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7822, gtest_ar.failure_message()) = ::testing::Message()
7822 util::durationToText(stats_mgr.getMaxSampleAgeDefault(), 0))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("\"00:00:05\""
, "util::durationToText(stats_mgr.getMaxSampleAgeDefault(), 0)"
, "00:00:05", util::durationToText(stats_mgr.getMaxSampleAgeDefault
(), 0)))) ; else ::testing::internal::AssertHelper(::testing::
TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7822, gtest_ar.failure_message()) = ::testing::Message()
;
7823}
7824
7825// This test checks that using default multi threading settings works.
7826TEST_F(Dhcp4ParserTest, multiThreadingDefaultSettings)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("multiThreadingDefaultSettings") >
1, "test_name must not be empty"); class Dhcp4ParserTest_multiThreadingDefaultSettings_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_multiThreadingDefaultSettings_Test
() = default; ~Dhcp4ParserTest_multiThreadingDefaultSettings_Test
() override = default; Dhcp4ParserTest_multiThreadingDefaultSettings_Test
(const Dhcp4ParserTest_multiThreadingDefaultSettings_Test &
) = delete; Dhcp4ParserTest_multiThreadingDefaultSettings_Test
& operator=( const Dhcp4ParserTest_multiThreadingDefaultSettings_Test
&) = delete; Dhcp4ParserTest_multiThreadingDefaultSettings_Test
(Dhcp4ParserTest_multiThreadingDefaultSettings_Test &&
) noexcept = delete; Dhcp4ParserTest_multiThreadingDefaultSettings_Test
& operator=( Dhcp4ParserTest_multiThreadingDefaultSettings_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_multiThreadingDefaultSettings_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "multiThreadingDefaultSettings", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7826), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7826), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7826), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_multiThreadingDefaultSettings_Test
>); void Dhcp4ParserTest_multiThreadingDefaultSettings_Test
::TestBody()
{
7827 std::string config = "{ " + genIfaceConfig() + ","
7828 "\"subnet4\": [ ]"
7829 "}";
7830
7831 ConstElementPtr json;
7832 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_7832
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_7832
; } } else gtest_label_testnothrow_7832 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7832, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
7833 extractConfig(config);
7834
7835 ConstElementPtr status;
7836 ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_7836; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7836; } } else gtest_label_testnothrow_7836
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7836, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
7837 checkResult(status, 0);
7838
7839 ConstElementPtr cfg = CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading();
7840 ASSERT_TRUE(cfg)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(cfg)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7840
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg", "false", "true") .c_str()) = ::testing::Message()
;
7841
7842 std::string content_json =
7843 "{"
7844 " \"enable-multi-threading\": true,\n"
7845 " \"thread-pool-size\": 0,\n"
7846 " \"packet-queue-size\": 64\n"
7847 "}";
7848 ConstElementPtr param;
7849 ASSERT_NO_THROW(param = Element::fromJSON(content_json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
param = Element::fromJSON(content_json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_7849; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7849; } } else gtest_label_testnothrow_7849
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7849, ("Expected: " "param = Element::fromJSON(content_json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
7850 << "invalid context_json, test is broken";
7851 ASSERT_TRUE(param->equals(*cfg))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(param->equals(*cfg
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7851, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "param->equals(*cfg)", "false", "true") .c_str()) = ::testing
::Message()
7852 << "expected: " << *(param) << std::endl
7853 << " actual: " << *(cfg) << std::endl;
7854}
7855
7856// This test checks that adding multi threading settings works.
7857TEST_F(Dhcp4ParserTest, multiThreadingSettings)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("multiThreadingSettings") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_multiThreadingSettings_Test : public
Dhcp4ParserTest { public: Dhcp4ParserTest_multiThreadingSettings_Test
() = default; ~Dhcp4ParserTest_multiThreadingSettings_Test() override
= default; Dhcp4ParserTest_multiThreadingSettings_Test (const
Dhcp4ParserTest_multiThreadingSettings_Test &) = delete;
Dhcp4ParserTest_multiThreadingSettings_Test & operator=(
const Dhcp4ParserTest_multiThreadingSettings_Test &) = delete
; Dhcp4ParserTest_multiThreadingSettings_Test (Dhcp4ParserTest_multiThreadingSettings_Test
&&) noexcept = delete; Dhcp4ParserTest_multiThreadingSettings_Test
& operator=( Dhcp4ParserTest_multiThreadingSettings_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_multiThreadingSettings_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "multiThreadingSettings", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7857), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7857), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7857), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_multiThreadingSettings_Test
>); void Dhcp4ParserTest_multiThreadingSettings_Test::TestBody
()
{
7858 std::string content_json =
7859 "{"
7860 " \"enable-multi-threading\": true,\n"
7861 " \"thread-pool-size\": 48,\n"
7862 " \"packet-queue-size\": 1024\n"
7863 "}";
7864 std::string config = "{ " + genIfaceConfig() + ","
7865 "\"subnet4\": [ ], "
7866 "\"multi-threading\": " + content_json + "}";
7867
7868 ConstElementPtr json;
7869 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_7869
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_7869
; } } else gtest_label_testnothrow_7869 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7869, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
7870 extractConfig(config);
7871
7872 ConstElementPtr status;
7873 ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_7873; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7873; } } else gtest_label_testnothrow_7873
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7873, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
7874 checkResult(status, 0);
7875
7876 ConstElementPtr cfg = CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading();
7877 ASSERT_TRUE(cfg)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(cfg)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 7877
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg", "false", "true") .c_str()) = ::testing::Message()
;
7878
7879 ConstElementPtr param;
7880 ASSERT_NO_THROW(param = Element::fromJSON(content_json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
param = Element::fromJSON(content_json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_7880; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7880; } } else gtest_label_testnothrow_7880
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7880, ("Expected: " "param = Element::fromJSON(content_json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
7881 << "invalid context_json, test is broken";
7882 ASSERT_TRUE(param->equals(*cfg))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(param->equals(*cfg
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7882, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "param->equals(*cfg)", "false", "true") .c_str()) = ::testing
::Message()
7883 << "expected: " << *(param) << std::endl
7884 << " actual: " << *(cfg) << std::endl;
7885}
7886
7887// Verify that parsing for the global parameter, parked-packet-limit,
7888// is correct.
7889TEST_F(Dhcp4ParserTest, parkedPacketLimit)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("parkedPacketLimit") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_parkedPacketLimit_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_parkedPacketLimit_Test() = default
; ~Dhcp4ParserTest_parkedPacketLimit_Test() override = default
; Dhcp4ParserTest_parkedPacketLimit_Test (const Dhcp4ParserTest_parkedPacketLimit_Test
&) = delete; Dhcp4ParserTest_parkedPacketLimit_Test &
operator=( const Dhcp4ParserTest_parkedPacketLimit_Test &
) = delete; Dhcp4ParserTest_parkedPacketLimit_Test (Dhcp4ParserTest_parkedPacketLimit_Test
&&) noexcept = delete; Dhcp4ParserTest_parkedPacketLimit_Test
& operator=( Dhcp4ParserTest_parkedPacketLimit_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_parkedPacketLimit_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "parkedPacketLimit", nullptr, nullptr, ::testing::internal::
CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7889), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7889), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7889), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_parkedPacketLimit_Test
>); void Dhcp4ParserTest_parkedPacketLimit_Test::TestBody(
)
{
7890 // Config without parked-packet-limit
7891 string config_no_limit = "{ " + genIfaceConfig() + ","
7892 "\"subnet4\": [ ] "
7893 "}";
7894
7895 // Config with parked-packet-limit
7896 string config_limit = "{ " + genIfaceConfig() + ","
7897 "\"parked-packet-limit\": 777, "
7898 "\"subnet4\": [ ] "
7899 "}";
7900
7901 // Config with an invalid parked-packet-limit
7902 string bad_limit = "{ " + genIfaceConfig() + ","
7903 "\"parked-packet-limit\": \"boo\", "
7904 "\"subnet4\": [ ] "
7905 "}";
7906
7907 // Should not exist after construction.
7908 ASSERT_FALSE(CfgMgr::instance().getStagingCfg()->getConfiguredGlobal("parked-packet-limit"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(CfgMgr::instance().
getStagingCfg()->getConfiguredGlobal("parked-packet-limit"
)))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7908, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getConfiguredGlobal(\"parked-packet-limit\")"
, "true", "false") .c_str()) = ::testing::Message()
;
7909
7910 // Configuration with no limit should default to 256.
7911 configure(config_no_limit, CONTROL_RESULT_SUCCESS, "");
7912 ConstElementPtr ppl;
7913 ASSERT_TRUE(ppl = CfgMgr::instance().getStagingCfg()->getConfiguredGlobal("parked-packet-limit"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ppl = CfgMgr::instance
().getStagingCfg()->getConfiguredGlobal("parked-packet-limit"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7913, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ppl = CfgMgr::instance().getStagingCfg()->getConfiguredGlobal(\"parked-packet-limit\")"
, "false", "true") .c_str()) = ::testing::Message()
;
7914 EXPECT_EQ(256U, ppl->intValue())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("256U", "ppl->intValue()"
, 256U, ppl->intValue()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7914, gtest_ar.failure_message()) = ::testing::Message()
;
7915
7916 // Clear the config
7917 CfgMgr::instance().clear();
7918
7919 // Configuration with the limit should have the limit value.
7920 configure(config_limit, CONTROL_RESULT_SUCCESS, "");
7921
7922 ASSERT_TRUE(ppl = CfgMgr::instance().getStagingCfg()->getConfiguredGlobal("parked-packet-limit"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ppl = CfgMgr::instance
().getStagingCfg()->getConfiguredGlobal("parked-packet-limit"
))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7922, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ppl = CfgMgr::instance().getStagingCfg()->getConfiguredGlobal(\"parked-packet-limit\")"
, "false", "true") .c_str()) = ::testing::Message()
;
7923 EXPECT_EQ(777U, ppl->intValue())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("777U", "ppl->intValue()"
, 777U, ppl->intValue()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7923, gtest_ar.failure_message()) = ::testing::Message()
;
7924
7925 // Make sure an invalid limit fails to parse.
7926 ASSERT_THROW(parseDHCP4(bad_limit), std::exception)switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { bool gtest_caught_expected = false; try { if (
::testing::internal::AlwaysTrue()) { parseDHCP4(bad_limit); }
else static_assert(true, ""); } catch (std::exception const&
) { gtest_caught_expected = true; } catch (typename std::conditional
< std::is_same<typename std::remove_cv<typename std::
remove_reference< std::exception>::type>::type, std::
exception>::value, const ::testing::internal::NeverThrown&
, const std::exception&>::type e) { gtest_msg.value = "Expected: "
"parseDHCP4(bad_limit)" " throws an exception of type " "std::exception"
".\n Actual: it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testthrow_7926; } catch (...) { gtest_msg.value =
"Expected: " "parseDHCP4(bad_limit)" " throws an exception of type "
"std::exception" ".\n Actual: it throws a different type.";
goto gtest_label_testthrow_7926; } if (!gtest_caught_expected
) { gtest_msg.value = "Expected: " "parseDHCP4(bad_limit)" " throws an exception of type "
"std::exception" ".\n Actual: it throws nothing."; goto gtest_label_testthrow_7926
; } } else gtest_label_testthrow_7926 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7926, gtest_msg.value.c_str()) = ::testing::Message()
;
7927}
7928
7929// This test checks that ddns-conflict-resolution-mode value can be specified at
7930// global and subnet levels.
7931TEST_F(Dhcp4ParserTest, storeDdnsConflictResolutionMode)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("storeDdnsConflictResolutionMode") >
1, "test_name must not be empty"); class Dhcp4ParserTest_storeDdnsConflictResolutionMode_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_storeDdnsConflictResolutionMode_Test
() = default; ~Dhcp4ParserTest_storeDdnsConflictResolutionMode_Test
() override = default; Dhcp4ParserTest_storeDdnsConflictResolutionMode_Test
(const Dhcp4ParserTest_storeDdnsConflictResolutionMode_Test &
) = delete; Dhcp4ParserTest_storeDdnsConflictResolutionMode_Test
& operator=( const Dhcp4ParserTest_storeDdnsConflictResolutionMode_Test
&) = delete; Dhcp4ParserTest_storeDdnsConflictResolutionMode_Test
(Dhcp4ParserTest_storeDdnsConflictResolutionMode_Test &&
) noexcept = delete; Dhcp4ParserTest_storeDdnsConflictResolutionMode_Test
& operator=( Dhcp4ParserTest_storeDdnsConflictResolutionMode_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_storeDdnsConflictResolutionMode_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "storeDdnsConflictResolutionMode", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7931), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7931), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7931), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_storeDdnsConflictResolutionMode_Test
>); void Dhcp4ParserTest_storeDdnsConflictResolutionMode_Test
::TestBody()
{
7932 std::string config = "{ " + genIfaceConfig() + ","
7933 "\"rebind-timer\": 2000, "
7934 "\"renew-timer\": 1000, "
7935 "\"subnet4\": [ "
7936 "{"
7937 " \"id\": 1,"
7938 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
7939 " \"ddns-conflict-resolution-mode\": \"check-with-dhcid\","
7940 " \"subnet\": \"192.0.2.0/24\""
7941 "},"
7942 "{"
7943 " \"id\": 2,"
7944 " \"pools\": [ { \"pool\": \"192.0.3.1 - 192.0.3.100\" } ],"
7945 " \"ddns-conflict-resolution-mode\": \"check-exists-with-dhcid\","
7946 " \"subnet\": \"192.0.3.0/24\""
7947 "},"
7948 "{"
7949 " \"id\": 3,"
7950 " \"pools\": [ { \"pool\": \"192.0.4.1 - 192.0.4.100\" } ],"
7951 " \"ddns-conflict-resolution-mode\": \"no-check-without-dhcid\","
7952 " \"subnet\": \"192.0.4.0/24\""
7953 "},"
7954 "{"
7955 " \"id\": 4,"
7956 " \"pools\": [ { \"pool\": \"192.0.5.1 - 192.0.5.100\" } ],"
7957 " \"ddns-conflict-resolution-mode\": \"no-check-with-dhcid\","
7958 " \"subnet\": \"192.0.5.0/24\""
7959 "},"
7960 "{"
7961 " \"id\": 5,"
7962 " \"pools\": [ { \"pool\": \"192.0.6.1 - 192.0.6.100\" } ],"
7963 " \"subnet\": \"192.0.6.0/24\""
7964 "} ],"
7965 "\"valid-lifetime\": 4000,"
7966 "\"ddns-conflict-resolution-mode\": \"no-check-with-dhcid\" }";
7967
7968 ConstElementPtr json;
7969 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_7969
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_7969
; } } else gtest_label_testnothrow_7969 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7969, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
7970 extractConfig(config);
7971
7972 ConstElementPtr status;
7973 ASSERT_NO_THROW(status = configureDhcp4Server(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = configureDhcp4Server(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_7973; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7973; } } else gtest_label_testnothrow_7973
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7973, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
7974 checkResult(status, 0);
7975
7976 // Check global value.
7977 checkGlobal("ddns-conflict-resolution-mode", "no-check-with-dhcid");
7978
7979 // Check values for all the subnets.
7980 std::string expectedValues[] = {
7981 "check-with-dhcid",
7982 "check-exists-with-dhcid",
7983 "no-check-without-dhcid",
7984 "no-check-with-dhcid",
7985 "no-check-with-dhcid"
7986 };
7987 CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
7988 char addr[10];
7989 ConstSubnet4Ptr subnet1;
7990 for (int i = 0; i < 5; i++) {
7991 snprintf(addr, sizeof(addr), "192.0.%d.1", i+2);
7992 subnet1 = cfg->selectSubnet(IOAddress(addr));
7993 ASSERT_TRUE(subnet1)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet1)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7993, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1", "false", "true") .c_str()) = ::testing::Message(
)
;
7994 // Reset the fetch global function to staging (vs current) config.
7995 Subnet4Ptr mutable_subnet1 = boost::const_pointer_cast<Subnet4>(subnet1);
7996 mutable_subnet1->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
7997 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
7998 });
7999 EXPECT_EQ(expectedValues[i], subnet1->getDdnsConflictResolutionMode().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("expectedValues[i]"
, "subnet1->getDdnsConflictResolutionMode().get()", expectedValues
[i], subnet1->getDdnsConflictResolutionMode().get()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7999, gtest_ar.failure_message()) = ::testing::Message()
;
8000 }
8001}
8002
8003// This test verifies that class tagging can occur at any scope.
8004TEST_F(Dhcp4ParserTest, classTagging)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("classTagging") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_classTagging_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_classTagging_Test() = default; ~Dhcp4ParserTest_classTagging_Test
() override = default; Dhcp4ParserTest_classTagging_Test (const
Dhcp4ParserTest_classTagging_Test &) = delete; Dhcp4ParserTest_classTagging_Test
& operator=( const Dhcp4ParserTest_classTagging_Test &
) = delete; Dhcp4ParserTest_classTagging_Test (Dhcp4ParserTest_classTagging_Test
&&) noexcept = delete; Dhcp4ParserTest_classTagging_Test
& operator=( Dhcp4ParserTest_classTagging_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_classTagging_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "classTagging", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8004
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8004), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8004), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_classTagging_Test
>); void Dhcp4ParserTest_classTagging_Test::TestBody()
{
8005 std::string config = "{ " + genIfaceConfig() + ","
8006 R"^(
8007 "option-data": [{
8008 "name": "domain-name",
8009 "data": "example.com",
8010 "client-classes": [ "in-global" ]
8011 }],
8012 "valid-lifetime": 4000,
8013 "rebind-timer": 2000,
8014 "renew-timer": 1000,
8015 "shared-networks": [{
8016 "name": "foo",
8017 "subnet4": [{
8018 "id": 1,
8019 "subnet": "192.0.2.0/24",
8020 "option-data": [{
8021 "name": "domain-name",
8022 "data": "example.com",
8023 "client-classes": [ "in-subnet" ]
8024 }],
8025 "pools": [{
8026 "pool": "192.0.2.0/28",
8027 "option-data": [{
8028 "name": "domain-name",
8029 "data": "example.com",
8030 "client-classes": [ "in-pool" ]
8031 }]
8032 }],
8033 "reservations": [{
8034 "hw-address": "AA:BB:CC:DD:EE:FF",
8035 "option-data": [{
8036 "name": "domain-name",
8037 "data": "example.com",
8038 "client-classes": [ "in-reservation" ]
8039 }]
8040 }]
8041 }],
8042 "option-data": [{
8043 "name": "domain-name",
8044 "data": "example.com",
8045 "client-classes": [ "in-network" ]
8046 }]
8047 }],
8048 "client-classes": [{
8049 "name": "foo",
8050 "option-data": [{
8051 "name": "domain-name",
8052 "data": "example.com",
8053 "client-classes": [ "in-class" ]
8054 }]
8055 }]
8056 })^";
8057
8058 ConstElementPtr json;
8059 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_8059
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8059
; } } else gtest_label_testnothrow_8059 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8059, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8060 extractConfig(config);
8061
8062 ConstElementPtr status;
8063 ASSERT_NO_THROW(status = configureDhcp4Server(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = configureDhcp4Server(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_8063; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8063; } } else gtest_label_testnothrow_8063
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8063, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8064 checkResult(status, 0);
8065}
8066
8067// This test verifies that duplicates in option-data.client-classes
8068// are ignored and do not affect class order.
8069TEST_F(Dhcp4ParserTest, optionClientClassesDuplicateCheck)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("optionClientClassesDuplicateCheck") >
1, "test_name must not be empty"); class Dhcp4ParserTest_optionClientClassesDuplicateCheck_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_optionClientClassesDuplicateCheck_Test
() = default; ~Dhcp4ParserTest_optionClientClassesDuplicateCheck_Test
() override = default; Dhcp4ParserTest_optionClientClassesDuplicateCheck_Test
(const Dhcp4ParserTest_optionClientClassesDuplicateCheck_Test
&) = delete; Dhcp4ParserTest_optionClientClassesDuplicateCheck_Test
& operator=( const Dhcp4ParserTest_optionClientClassesDuplicateCheck_Test
&) = delete; Dhcp4ParserTest_optionClientClassesDuplicateCheck_Test
(Dhcp4ParserTest_optionClientClassesDuplicateCheck_Test &&
) noexcept = delete; Dhcp4ParserTest_optionClientClassesDuplicateCheck_Test
& operator=( Dhcp4ParserTest_optionClientClassesDuplicateCheck_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_optionClientClassesDuplicateCheck_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "optionClientClassesDuplicateCheck", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8069), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8069), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8069), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionClientClassesDuplicateCheck_Test
>); void Dhcp4ParserTest_optionClientClassesDuplicateCheck_Test
::TestBody()
{
8070 std::string config = "{ " + genIfaceConfig() + ","
8071 R"^(
8072 "option-data": [{
8073 "name": "domain-name",
8074 "data": "example.com",
8075 "client-classes": [ "foo", "bar", "foo", "bar" ]
8076 }],
8077 "rebind-timer": 2000,
8078 "renew-timer": 1000,
8079 "subnet4": [],
8080 "valid-lifetime": 400
8081 })^";
8082
8083 ConstElementPtr json;
8084 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_8084
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8084
; } } else gtest_label_testnothrow_8084 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8084, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8085 extractConfig(config);
8086
8087 ConstElementPtr status;
8088 ASSERT_NO_THROW(status = configureDhcp4Server(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = configureDhcp4Server(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_8088; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8088; } } else gtest_label_testnothrow_8088
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8088, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8089 checkResult(status, 0);
8090
8091 CfgOptionPtr cfg = CfgMgr::instance().getStagingCfg()->getCfgOption();
8092 const auto desc = cfg->get(DHCP4_OPTION_SPACE"dhcp4", DHO_DOMAIN_NAME);
8093 ASSERT_TRUE(desc.option_)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(desc.option_)) ; else
return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8093, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc.option_", "false", "true") .c_str()) = ::testing::Message
()
;
8094 ASSERT_EQ(desc.client_classes_.size(), 2U)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("desc.client_classes_.size()"
, "2U", desc.client_classes_.size(), 2U))) ; else return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8094
, gtest_ar.failure_message()) = ::testing::Message()
;
8095 auto cclasses = desc.client_classes_.begin();
8096 EXPECT_EQ(*cclasses, "foo")switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("*cclasses"
, "\"foo\"", *cclasses, "foo"))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8096, gtest_ar.failure_message()) = ::testing::Message()
;
8097 ++cclasses;
8098 EXPECT_EQ(*cclasses, "bar")switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("*cclasses"
, "\"bar\"", *cclasses, "bar"))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8098, gtest_ar.failure_message()) = ::testing::Message()
;
8099}
8100
8101// This test verifies that deprecated require-client-classes
8102// gets handled properly.
8103TEST_F(Dhcp4ParserTest, deprecatedRequireClientClassesCheck)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("deprecatedRequireClientClassesCheck"
) > 1, "test_name must not be empty"); class Dhcp4ParserTest_deprecatedRequireClientClassesCheck_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_deprecatedRequireClientClassesCheck_Test
() = default; ~Dhcp4ParserTest_deprecatedRequireClientClassesCheck_Test
() override = default; Dhcp4ParserTest_deprecatedRequireClientClassesCheck_Test
(const Dhcp4ParserTest_deprecatedRequireClientClassesCheck_Test
&) = delete; Dhcp4ParserTest_deprecatedRequireClientClassesCheck_Test
& operator=( const Dhcp4ParserTest_deprecatedRequireClientClassesCheck_Test
&) = delete; Dhcp4ParserTest_deprecatedRequireClientClassesCheck_Test
(Dhcp4ParserTest_deprecatedRequireClientClassesCheck_Test &&
) noexcept = delete; Dhcp4ParserTest_deprecatedRequireClientClassesCheck_Test
& operator=( Dhcp4ParserTest_deprecatedRequireClientClassesCheck_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_deprecatedRequireClientClassesCheck_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "deprecatedRequireClientClassesCheck", nullptr, nullptr, ::
testing::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8103), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8103), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8103), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_deprecatedRequireClientClassesCheck_Test
>); void Dhcp4ParserTest_deprecatedRequireClientClassesCheck_Test
::TestBody()
{
8104 // Verify that require-client-classes gets translated
8105 // to evaluate-additional-classes.
8106 std::string config = "{ " + genIfaceConfig() + ","
8107 R"^(
8108 "rebind-timer": 2000,
8109 "renew-timer": 1000,
8110 "shared-networks":[{
8111 "name": "net1",
8112 "require-client-classes": [ "one" ],
8113 "subnet4": [{
8114 "require-client-classes": [ "two" ],
8115 "pools": [{
8116 "pool": "192.0.2.0/28",
8117 "require-client-classes": [ "three" ]
8118 }],
8119 "id": 1,
8120 "subnet": "192.0.2.0/24"
8121 }],
8122 }],
8123 "valid-lifetime": 400
8124 })^";
8125
8126 ConstElementPtr json;
8127 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_8127
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8127
; } } else gtest_label_testnothrow_8127 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8127, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8128 extractConfig(config);
8129
8130 ConstElementPtr status;
8131 ASSERT_NO_THROW(status = configureDhcp4Server(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = configureDhcp4Server(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_8131; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8131; } } else gtest_label_testnothrow_8131
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8131, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8132 checkResult(status, 0);
8133
8134 SharedNetwork4Ptr network = CfgMgr::instance().getStagingCfg()->
8135 getCfgSharedNetworks4()->getByName("net1");
8136 ASSERT_TRUE(network)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(network)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8136, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "network", "false", "true") .c_str()) = ::testing::Message(
)
;
8137
8138 auto& net_class_list = network->getAdditionalClasses();
8139 EXPECT_EQ(1U, net_class_list.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "net_class_list.size()"
, 1U, net_class_list.size()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8139, gtest_ar.failure_message()) = ::testing::Message()
;
8140 auto cclasses = net_class_list.begin();
8141 EXPECT_EQ(*cclasses, "one")switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("*cclasses"
, "\"one\"", *cclasses, "one"))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8141, gtest_ar.failure_message()) = ::testing::Message()
;
8142
8143 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
8144 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.0"));
8145 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8145, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
8146
8147 auto& sub_class_list = subnet->getAdditionalClasses();
8148 EXPECT_EQ(1U, sub_class_list.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "sub_class_list.size()"
, 1U, sub_class_list.size()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8148, gtest_ar.failure_message()) = ::testing::Message()
;
8149 cclasses = sub_class_list.begin();
8150 EXPECT_EQ(*cclasses, "two")switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("*cclasses"
, "\"two\"", *cclasses, "two"))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8150, gtest_ar.failure_message()) = ::testing::Message()
;
8151
8152 PoolPtr pool = subnet->getPool(Lease::TYPE_V4, IOAddress("192.0.2.0"), false);
8153 ASSERT_TRUE(pool)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8153
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
8154
8155 auto& pool_class_list = pool->getAdditionalClasses();
8156 EXPECT_EQ(1U, pool_class_list.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "pool_class_list.size()"
, 1U, pool_class_list.size()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8156, gtest_ar.failure_message()) = ::testing::Message()
;
8157 cclasses = pool_class_list.begin();
8158 EXPECT_EQ(*cclasses, "three")switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("*cclasses"
, "\"three\"", *cclasses, "three"))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8158, gtest_ar.failure_message()) = ::testing::Message()
;
8159
8160 // Now verify that users cannot specify both.
8161 config = "{ " + genIfaceConfig() + ","
8162 R"^(
8163 "rebind-timer": 2000,
8164 "renew-timer": 1000,
8165 "subnet4": [{
8166 "require-client-classes": [ "foo" ],
8167 "evaluate-additional-classes": [ "foo" ],
8168 "pools": [{ "pool": "192.0.2.0/28" }],
8169 "id": 1,
8170 "subnet": "192.0.2.0/24"
8171 }],
8172 "valid-lifetime": 400
8173 })^";
8174
8175 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_8175
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8175
; } } else gtest_label_testnothrow_8175 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8175, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8176
8177 ASSERT_NO_THROW(status = configureDhcp4Server(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = configureDhcp4Server(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_8177; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8177; } } else gtest_label_testnothrow_8177
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8177, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8178 checkResult(status, CONTROL_RESULT_ERROR,
8179 "subnet configuration failed: cannot specify both 'require-client-classes'"
8180 " and 'evaluate-additional-classes'. Use only the latter.");
8181}
8182
8183// This test verifies that deprecated only-if-required
8184// gets handled properly.
8185TEST_F(Dhcp4ParserTest, deprecatedOnlyIfRequiredCheck)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("deprecatedOnlyIfRequiredCheck") >
1, "test_name must not be empty"); class Dhcp4ParserTest_deprecatedOnlyIfRequiredCheck_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_deprecatedOnlyIfRequiredCheck_Test
() = default; ~Dhcp4ParserTest_deprecatedOnlyIfRequiredCheck_Test
() override = default; Dhcp4ParserTest_deprecatedOnlyIfRequiredCheck_Test
(const Dhcp4ParserTest_deprecatedOnlyIfRequiredCheck_Test &
) = delete; Dhcp4ParserTest_deprecatedOnlyIfRequiredCheck_Test
& operator=( const Dhcp4ParserTest_deprecatedOnlyIfRequiredCheck_Test
&) = delete; Dhcp4ParserTest_deprecatedOnlyIfRequiredCheck_Test
(Dhcp4ParserTest_deprecatedOnlyIfRequiredCheck_Test &&
) noexcept = delete; Dhcp4ParserTest_deprecatedOnlyIfRequiredCheck_Test
& operator=( Dhcp4ParserTest_deprecatedOnlyIfRequiredCheck_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_deprecatedOnlyIfRequiredCheck_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "deprecatedOnlyIfRequiredCheck", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8185), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8185), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8185), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_deprecatedOnlyIfRequiredCheck_Test
>); void Dhcp4ParserTest_deprecatedOnlyIfRequiredCheck_Test
::TestBody()
{
8186 // Verifies that only-if-required gets translated
8187 // to only-in-additional-list.
8188 std::string config = "{ " + genIfaceConfig() + ","
8189 R"^(
8190 "rebind-timer": 2000,
8191 "renew-timer": 1000,
8192 "client-classes": [{
8193 "name": "foo",
8194 "only-if-required": true
8195 }],
8196 "subnet4": [ ],
8197 "valid-lifetime": 400
8198 })^";
8199
8200 ConstElementPtr json;
8201 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_8201
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8201
; } } else gtest_label_testnothrow_8201 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8201, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8202 extractConfig(config);
8203
8204 ConstElementPtr status;
8205 ASSERT_NO_THROW(status = configureDhcp4Server(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = configureDhcp4Server(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_8205; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8205; } } else gtest_label_testnothrow_8205
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8205, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8206 checkResult(status, 0);
8207
8208 auto dictionary = CfgMgr::instance().getStagingCfg()->getClientClassDictionary();
8209 ASSERT_TRUE(dictionary)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(dictionary)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8209, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dictionary", "false", "true") .c_str()) = ::testing::Message
()
;
8210 EXPECT_EQ(1U, dictionary->getClasses()->size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "dictionary->getClasses()->size()"
, 1U, dictionary->getClasses()->size()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8210
, gtest_ar.failure_message()) = ::testing::Message()
;
8211
8212 ClientClassDefPtr class_def = dictionary->findClass("foo");
8213 ASSERT_TRUE(class_def)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(class_def)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8213, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "class_def", "false", "true") .c_str()) = ::testing::Message
()
;
8214 EXPECT_TRUE(class_def->getAdditional())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(class_def->getAdditional
())) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8214, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "class_def->getAdditional()", "false", "true") .c_str())
= ::testing::Message()
;
8215
8216 // Now verify that users cannot specify both.
8217 config = "{ " + genIfaceConfig() + ","
8218 R"^(
8219 "rebind-timer": 2000,
8220 "renew-timer": 1000,
8221 "client-classes": [{
8222 "name": "foo",
8223 "only-if-required": true,
8224 "only-in-additional-list": true
8225 }],
8226 "subnet4": [ ],
8227 "valid-lifetime": 400
8228 })^";
8229
8230 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_8230
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8230
; } } else gtest_label_testnothrow_8230 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8230, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8231
8232 ASSERT_NO_THROW(status = configureDhcp4Server(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = configureDhcp4Server(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_8232; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8232; } } else gtest_label_testnothrow_8232
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8232, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8233 checkResult(status, CONTROL_RESULT_ERROR,
8234 "cannot specify both 'only-if-required' and"
8235 " 'only-in-additional-list'. Use only the latter.");
8236}
8237
8238// This test verifies that deprecated client-class
8239// gets handled properly.
8240TEST_F(Dhcp4ParserTest, deprecatedClientClassesCheck)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("deprecatedClientClassesCheck") > 1
, "test_name must not be empty"); class Dhcp4ParserTest_deprecatedClientClassesCheck_Test
: public Dhcp4ParserTest { public: Dhcp4ParserTest_deprecatedClientClassesCheck_Test
() = default; ~Dhcp4ParserTest_deprecatedClientClassesCheck_Test
() override = default; Dhcp4ParserTest_deprecatedClientClassesCheck_Test
(const Dhcp4ParserTest_deprecatedClientClassesCheck_Test &
) = delete; Dhcp4ParserTest_deprecatedClientClassesCheck_Test
& operator=( const Dhcp4ParserTest_deprecatedClientClassesCheck_Test
&) = delete; Dhcp4ParserTest_deprecatedClientClassesCheck_Test
(Dhcp4ParserTest_deprecatedClientClassesCheck_Test &&
) noexcept = delete; Dhcp4ParserTest_deprecatedClientClassesCheck_Test
& operator=( Dhcp4ParserTest_deprecatedClientClassesCheck_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_deprecatedClientClassesCheck_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "deprecatedClientClassesCheck", nullptr, nullptr, ::testing
::internal::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8240), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8240), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8240), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_deprecatedClientClassesCheck_Test
>); void Dhcp4ParserTest_deprecatedClientClassesCheck_Test
::TestBody()
{
8241 // Verify that require-client-classes gets translated
8242 // to evaluate-additional-classes.
8243 std::string config = "{ " + genIfaceConfig() + ","
8244 R"^(
8245 "rebind-timer": 2000,
8246 "renew-timer": 1000,
8247 "shared-networks":[{
8248 "name": "net1",
8249 "client-class": "one",
8250 "subnet4": [{
8251 "client-class": "two",
8252 "pools": [{
8253 "pool": "192.0.2.0/28",
8254 "client-class": "three"
8255 }],
8256 "id": 1,
8257 "subnet": "192.0.2.0/24"
8258 }],
8259 }],
8260 "valid-lifetime": 400
8261 })^";
8262
8263 ConstElementPtr json;
8264 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_8264
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8264
; } } else gtest_label_testnothrow_8264 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8264, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8265 extractConfig(config);
8266
8267 ConstElementPtr status;
8268 ASSERT_NO_THROW(status = configureDhcp4Server(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = configureDhcp4Server(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_8268; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8268; } } else gtest_label_testnothrow_8268
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8268, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8269 checkResult(status, 0);
8270
8271 SharedNetwork4Ptr network = CfgMgr::instance().getStagingCfg()->
8272 getCfgSharedNetworks4()->getByName("net1");
8273 ASSERT_TRUE(network)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(network)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8273, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "network", "false", "true") .c_str()) = ::testing::Message(
)
;
8274
8275 auto& net_class_list = network->getClientClasses();
8276 ASSERT_EQ(1U, net_class_list.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "net_class_list.size()"
, 1U, net_class_list.size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8276, gtest_ar.failure_message()) = ::testing::Message()
;
8277 auto cclasses = net_class_list.begin();
8278 EXPECT_EQ(*cclasses, "one")switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("*cclasses"
, "\"one\"", *cclasses, "one"))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8278, gtest_ar.failure_message()) = ::testing::Message()
;
8279
8280 auto subnet = CfgMgr::instance().getStagingCfg()->
8281 getCfgSubnets4()->getBySubnetId(1);
8282 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8282, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
8283
8284 auto& sub_class_list = subnet->getClientClasses();
8285 ASSERT_EQ(1U, sub_class_list.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "sub_class_list.size()"
, 1U, sub_class_list.size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8285, gtest_ar.failure_message()) = ::testing::Message()
;
8286 cclasses = sub_class_list.begin();
8287 EXPECT_EQ(*cclasses, "two")switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("*cclasses"
, "\"two\"", *cclasses, "two"))) ; else ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8287, gtest_ar.failure_message()) = ::testing::Message()
;
8288
8289 PoolPtr pool = subnet->getPool(Lease::TYPE_V4, IOAddress("192.0.2.0"), false);
8290 ASSERT_TRUE(pool)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8290
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
8291
8292 auto& pool_class_list = pool->getClientClasses();
8293 ASSERT_EQ(1U, pool_class_list.size())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "pool_class_list.size()"
, 1U, pool_class_list.size()))) ; else return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8293, gtest_ar.failure_message()) = ::testing::Message()
;
8294 cclasses = pool_class_list.begin();
8295 EXPECT_EQ(*cclasses, "three")switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("*cclasses"
, "\"three\"", *cclasses, "three"))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8295, gtest_ar.failure_message()) = ::testing::Message()
;
8296
8297 // Now verify that users cannot specify both. We don't check all scopes
8298 // as they all use the same function.
8299 config = "{ " + genIfaceConfig() + ","
8300 R"^(
8301 "rebind-timer": 2000,
8302 "renew-timer": 1000,
8303 "subnet4": [{
8304 "client-class": "foo",
8305 "client-classes": [ "bar" ],
8306 "pools": [{ "pool": "192.0.2.0/28" }],
8307 "id": 1,
8308 "subnet": "192.0.2.0/24"
8309 }],
8310 "valid-lifetime": 400
8311 })^";
8312
8313 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_8313
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8313
; } } else gtest_label_testnothrow_8313 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8313, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8314
8315 ASSERT_NO_THROW(status = configureDhcp4Server(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = configureDhcp4Server(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_8315; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8315; } } else gtest_label_testnothrow_8315
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8315, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8316 checkResult(status, CONTROL_RESULT_ERROR,
8317 "subnet configuration failed: cannot specify both 'client-class'"
8318 " and 'client-classes'. Use only the latter.");
8319}
8320
8321// Verifies ddns-ttl-percent is supported at global,
8322// shared-network, and subnet scopes.
8323TEST_F(Dhcp4ParserTest, ddnsTtlPercent)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("ddnsTtlPercent") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_ddnsTtlPercent_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_ddnsTtlPercent_Test() = default; ~
Dhcp4ParserTest_ddnsTtlPercent_Test() override = default; Dhcp4ParserTest_ddnsTtlPercent_Test
(const Dhcp4ParserTest_ddnsTtlPercent_Test &) = delete; Dhcp4ParserTest_ddnsTtlPercent_Test
& operator=( const Dhcp4ParserTest_ddnsTtlPercent_Test &
) = delete; Dhcp4ParserTest_ddnsTtlPercent_Test (Dhcp4ParserTest_ddnsTtlPercent_Test
&&) noexcept = delete; Dhcp4ParserTest_ddnsTtlPercent_Test
& operator=( Dhcp4ParserTest_ddnsTtlPercent_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_ddnsTtlPercent_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "ddnsTtlPercent", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8323
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8323), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8323), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_ddnsTtlPercent_Test
>); void Dhcp4ParserTest_ddnsTtlPercent_Test::TestBody()
{
8324 string config = R"(
8325 {
8326 "ddns-ttl-percent": 0.75,
8327 "valid-lifetime": 4000,
8328 "shared-networks": [{
8329 "name": "net",
8330 "ddns-ttl-percent": 0.50,
8331 "subnet4": [{
8332 "id": 1,
8333 "subnet": "10.0.2.0/24",
8334 "ddns-ttl-percent": 0.25
8335 }],
8336 }]
8337 }
8338 )";
8339
8340 ConstElementPtr json;
8341 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_8341
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8341
; } } else gtest_label_testnothrow_8341 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8341, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8342 extractConfig(config);
8343
8344 ConstElementPtr status;
8345
8346 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_8346; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8346; } } else gtest_label_testnothrow_8346
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8346, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8347 // returned value should be 0 (success)
8348 checkResult(status, 0);
8349
8350 // Commit it so global inheritance works.
8351 CfgMgr::instance().commit();
8352
8353 ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
8354 getCfgSubnets4()->selectSubnet(IOAddress("10.0.2.0"));
8355 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8355, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
8356
8357 EXPECT_FALSE(subnet->getDdnsTtlPercent(Network::Inheritance::NONE).unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getDdnsTtlPercent
(Network::Inheritance::NONE).unspecified()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8357
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlPercent(Network::Inheritance::NONE).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8358 EXPECT_EQ(0.25, subnet->getDdnsTtlPercent(Network::Inheritance::NONE).get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("0.25", "subnet->getDdnsTtlPercent(Network::Inheritance::NONE).get()"
, 0.25, subnet->getDdnsTtlPercent(Network::Inheritance::NONE
).get()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8358, gtest_ar.failure_message()) = ::testing::Message()
;
8359
8360 EXPECT_FALSE(subnet->getDdnsTtlPercent(Network::Inheritance::PARENT_NETWORK).unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getDdnsTtlPercent
(Network::Inheritance::PARENT_NETWORK).unspecified()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8360, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlPercent(Network::Inheritance::PARENT_NETWORK).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8361 EXPECT_EQ(0.50, subnet->getDdnsTtlPercent(Network::Inheritance::PARENT_NETWORK).get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("0.50", "subnet->getDdnsTtlPercent(Network::Inheritance::PARENT_NETWORK).get()"
, 0.50, subnet->getDdnsTtlPercent(Network::Inheritance::PARENT_NETWORK
).get()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8361, gtest_ar.failure_message()) = ::testing::Message()
;
8362
8363 EXPECT_FALSE(subnet->getDdnsTtlPercent(Network::Inheritance::GLOBAL).unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getDdnsTtlPercent
(Network::Inheritance::GLOBAL).unspecified()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8363
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlPercent(Network::Inheritance::GLOBAL).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8364 EXPECT_EQ(0.75, subnet->getDdnsTtlPercent(Network::Inheritance::GLOBAL).get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("0.75", "subnet->getDdnsTtlPercent(Network::Inheritance::GLOBAL).get()"
, 0.75, subnet->getDdnsTtlPercent(Network::Inheritance::GLOBAL
).get()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8364, gtest_ar.failure_message()) = ::testing::Message()
;
8365}
8366
8367// Verifies ddns-ttl is supported at global,
8368// shared-network, and subnet scopes.
8369TEST_F(Dhcp4ParserTest, ddnsTtl)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("ddnsTtl") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_ddnsTtl_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_ddnsTtl_Test() = default; ~Dhcp4ParserTest_ddnsTtl_Test
() override = default; Dhcp4ParserTest_ddnsTtl_Test (const Dhcp4ParserTest_ddnsTtl_Test
&) = delete; Dhcp4ParserTest_ddnsTtl_Test & operator
=( const Dhcp4ParserTest_ddnsTtl_Test &) = delete; Dhcp4ParserTest_ddnsTtl_Test
(Dhcp4ParserTest_ddnsTtl_Test &&) noexcept = delete;
Dhcp4ParserTest_ddnsTtl_Test & operator=( Dhcp4ParserTest_ddnsTtl_Test
&&) noexcept = delete; private: void TestBody() override
; [[maybe_unused]] static ::testing::TestInfo* const test_info_
; }; ::testing::TestInfo* const Dhcp4ParserTest_ddnsTtl_Test::
test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "ddnsTtl", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8369
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8369), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8369), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_ddnsTtl_Test
>); void Dhcp4ParserTest_ddnsTtl_Test::TestBody()
{
8370 string config = R"(
8371 {
8372 "ddns-ttl": 750,
8373 "valid-lifetime": 4000,
8374 "shared-networks": [{
8375 "name": "net",
8376 "ddns-ttl": 500,
8377 "subnet4": [{
8378 "id": 1,
8379 "subnet": "10.0.2.0/24",
8380 "ddns-ttl": 250
8381 }],
8382 }]
8383 }
8384 )";
8385
8386 ConstElementPtr json;
8387 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_8387
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8387
; } } else gtest_label_testnothrow_8387 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8387, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8388 extractConfig(config);
8389
8390 ConstElementPtr status;
8391 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_8391; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8391; } } else gtest_label_testnothrow_8391
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8391, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8392
8393 // returned value should be 0 (success)
8394 checkResult(status, 0);
8395
8396 // Commit it so global inheritance works.
8397 CfgMgr::instance().commit();
8398
8399 ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
8400 getCfgSubnets4()->selectSubnet(IOAddress("10.0.2.0"));
8401 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8401, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
8402
8403 EXPECT_FALSE(subnet->getDdnsTtl(Network::Inheritance::NONE).unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getDdnsTtl
(Network::Inheritance::NONE).unspecified()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8403
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtl(Network::Inheritance::NONE).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8404 EXPECT_EQ(250U, subnet->getDdnsTtl(Network::Inheritance::NONE).get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("250U", "subnet->getDdnsTtl(Network::Inheritance::NONE).get()"
, 250U, subnet->getDdnsTtl(Network::Inheritance::NONE).get
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8404, gtest_ar.failure_message()) = ::testing::Message()
;
8405
8406 EXPECT_FALSE(subnet->getDdnsTtl(Network::Inheritance::PARENT_NETWORK).unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getDdnsTtl
(Network::Inheritance::PARENT_NETWORK).unspecified()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8406, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtl(Network::Inheritance::PARENT_NETWORK).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8407 EXPECT_EQ(500U, subnet->getDdnsTtl(Network::Inheritance::PARENT_NETWORK).get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("500U", "subnet->getDdnsTtl(Network::Inheritance::PARENT_NETWORK).get()"
, 500U, subnet->getDdnsTtl(Network::Inheritance::PARENT_NETWORK
).get()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8407, gtest_ar.failure_message()) = ::testing::Message()
;
8408
8409 EXPECT_FALSE(subnet->getDdnsTtl(Network::Inheritance::GLOBAL).unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getDdnsTtl
(Network::Inheritance::GLOBAL).unspecified()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8409
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtl(Network::Inheritance::GLOBAL).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8410 EXPECT_EQ(750U, subnet->getDdnsTtl(Network::Inheritance::GLOBAL).get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("750U", "subnet->getDdnsTtl(Network::Inheritance::GLOBAL).get()"
, 750U, subnet->getDdnsTtl(Network::Inheritance::GLOBAL).get
()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8410, gtest_ar.failure_message()) = ::testing::Message()
;
8411}
8412
8413// Verifies ddns-ttl-min is supported at global,
8414// shared-network, and subnet scopes.
8415TEST_F(Dhcp4ParserTest, ddnsTtlMin)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("ddnsTtlMin") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_ddnsTtlMin_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_ddnsTtlMin_Test() = default; ~Dhcp4ParserTest_ddnsTtlMin_Test
() override = default; Dhcp4ParserTest_ddnsTtlMin_Test (const
Dhcp4ParserTest_ddnsTtlMin_Test &) = delete; Dhcp4ParserTest_ddnsTtlMin_Test
& operator=( const Dhcp4ParserTest_ddnsTtlMin_Test &
) = delete; Dhcp4ParserTest_ddnsTtlMin_Test (Dhcp4ParserTest_ddnsTtlMin_Test
&&) noexcept = delete; Dhcp4ParserTest_ddnsTtlMin_Test
& operator=( Dhcp4ParserTest_ddnsTtlMin_Test &&)
noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_ddnsTtlMin_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "ddnsTtlMin", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8415
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8415), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8415), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_ddnsTtlMin_Test
>); void Dhcp4ParserTest_ddnsTtlMin_Test::TestBody()
{
8416 string config = R"(
8417 {
8418 "ddns-ttl-min": 750,
8419 "valid-lifetime": 4000,
8420 "shared-networks": [{
8421 "name": "net",
8422 "ddns-ttl-min": 500,
8423 "subnet4": [{
8424 "id": 1,
8425 "subnet": "10.0.2.0/24",
8426 "ddns-ttl-min": 250
8427 }],
8428 }]
8429 }
8430 )";
8431
8432 ConstElementPtr json;
8433 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_8433
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8433
; } } else gtest_label_testnothrow_8433 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8433, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8434 extractConfig(config);
8435
8436 ConstElementPtr status;
8437 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_8437; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8437; } } else gtest_label_testnothrow_8437
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8437, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8438
8439 // returned value should be 0 (success)
8440 checkResult(status, 0);
8441
8442 // Commit it so global inheritance works.
8443 CfgMgr::instance().commit();
8444
8445 ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
8446 getCfgSubnets4()->selectSubnet(IOAddress("10.0.2.0"));
8447 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8447, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
8448
8449 EXPECT_FALSE(subnet->getDdnsTtlMin(Network::Inheritance::NONE).unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getDdnsTtlMin
(Network::Inheritance::NONE).unspecified()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8449
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlMin(Network::Inheritance::NONE).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8450 EXPECT_EQ(250U, subnet->getDdnsTtlMin(Network::Inheritance::NONE).get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("250U", "subnet->getDdnsTtlMin(Network::Inheritance::NONE).get()"
, 250U, subnet->getDdnsTtlMin(Network::Inheritance::NONE).
get()))) ; else ::testing::internal::AssertHelper(::testing::
TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8450, gtest_ar.failure_message()) = ::testing::Message()
;
8451
8452 EXPECT_FALSE(subnet->getDdnsTtlMin(Network::Inheritance::PARENT_NETWORK).unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getDdnsTtlMin
(Network::Inheritance::PARENT_NETWORK).unspecified()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8452, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlMin(Network::Inheritance::PARENT_NETWORK).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8453 EXPECT_EQ(500U, subnet->getDdnsTtlMin(Network::Inheritance::PARENT_NETWORK).get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("500U", "subnet->getDdnsTtlMin(Network::Inheritance::PARENT_NETWORK).get()"
, 500U, subnet->getDdnsTtlMin(Network::Inheritance::PARENT_NETWORK
).get()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8453, gtest_ar.failure_message()) = ::testing::Message()
;
8454
8455 EXPECT_FALSE(subnet->getDdnsTtlMin(Network::Inheritance::GLOBAL).unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getDdnsTtlMin
(Network::Inheritance::GLOBAL).unspecified()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8455
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlMin(Network::Inheritance::GLOBAL).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8456 EXPECT_EQ(750U, subnet->getDdnsTtlMin(Network::Inheritance::GLOBAL).get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("750U", "subnet->getDdnsTtlMin(Network::Inheritance::GLOBAL).get()"
, 750U, subnet->getDdnsTtlMin(Network::Inheritance::GLOBAL
).get()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8456, gtest_ar.failure_message()) = ::testing::Message()
;
8457}
8458
8459// Verifies ddns-ttl-max is supported at global,
8460// shared-network, and subnet scopes.
8461TEST_F(Dhcp4ParserTest, ddnsTtlMax)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("ddnsTtlMax") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_ddnsTtlMax_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_ddnsTtlMax_Test() = default; ~Dhcp4ParserTest_ddnsTtlMax_Test
() override = default; Dhcp4ParserTest_ddnsTtlMax_Test (const
Dhcp4ParserTest_ddnsTtlMax_Test &) = delete; Dhcp4ParserTest_ddnsTtlMax_Test
& operator=( const Dhcp4ParserTest_ddnsTtlMax_Test &
) = delete; Dhcp4ParserTest_ddnsTtlMax_Test (Dhcp4ParserTest_ddnsTtlMax_Test
&&) noexcept = delete; Dhcp4ParserTest_ddnsTtlMax_Test
& operator=( Dhcp4ParserTest_ddnsTtlMax_Test &&)
noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_ddnsTtlMax_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "ddnsTtlMax", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8461
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8461), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8461), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_ddnsTtlMax_Test
>); void Dhcp4ParserTest_ddnsTtlMax_Test::TestBody()
{
8462 string config = R"(
8463 {
8464 "ddns-ttl-max": 750,
8465 "valid-lifetime": 4000,
8466 "shared-networks": [{
8467 "name": "net",
8468 "ddns-ttl-max": 500,
8469 "subnet4": [{
8470 "id": 1,
8471 "subnet": "10.0.2.0/24",
8472 "ddns-ttl-max": 250
8473 }],
8474 }]
8475 }
8476 )";
8477
8478 ConstElementPtr json;
8479 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_8479
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8479
; } } else gtest_label_testnothrow_8479 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8479, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8480 extractConfig(config);
8481
8482 ConstElementPtr status;
8483 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_8483; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8483; } } else gtest_label_testnothrow_8483
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8483, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8484
8485 // returned value should be 0 (success)
8486 checkResult(status, 0);
8487
8488 // Commit it so global inheritance works.
8489 CfgMgr::instance().commit();
8490
8491 ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
8492 getCfgSubnets4()->selectSubnet(IOAddress("10.0.2.0"));
8493 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8493, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
8494
8495 EXPECT_FALSE(subnet->getDdnsTtlMax(Network::Inheritance::NONE).unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getDdnsTtlMax
(Network::Inheritance::NONE).unspecified()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8495
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlMax(Network::Inheritance::NONE).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8496 EXPECT_EQ(250U, subnet->getDdnsTtlMax(Network::Inheritance::NONE).get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("250U", "subnet->getDdnsTtlMax(Network::Inheritance::NONE).get()"
, 250U, subnet->getDdnsTtlMax(Network::Inheritance::NONE).
get()))) ; else ::testing::internal::AssertHelper(::testing::
TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8496, gtest_ar.failure_message()) = ::testing::Message()
;
8497
8498 EXPECT_FALSE(subnet->getDdnsTtlMax(Network::Inheritance::PARENT_NETWORK).unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getDdnsTtlMax
(Network::Inheritance::PARENT_NETWORK).unspecified()))) ; else
::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8498, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlMax(Network::Inheritance::PARENT_NETWORK).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8499 EXPECT_EQ(500U, subnet->getDdnsTtlMax(Network::Inheritance::PARENT_NETWORK).get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("500U", "subnet->getDdnsTtlMax(Network::Inheritance::PARENT_NETWORK).get()"
, 500U, subnet->getDdnsTtlMax(Network::Inheritance::PARENT_NETWORK
).get()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8499, gtest_ar.failure_message()) = ::testing::Message()
;
8500
8501 EXPECT_FALSE(subnet->getDdnsTtlMax(Network::Inheritance::GLOBAL).unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(subnet->getDdnsTtlMax
(Network::Inheritance::GLOBAL).unspecified()))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8501
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlMax(Network::Inheritance::GLOBAL).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8502 EXPECT_EQ(750U, subnet->getDdnsTtlMax(Network::Inheritance::GLOBAL).get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("750U", "subnet->getDdnsTtlMax(Network::Inheritance::GLOBAL).get()"
, 750U, subnet->getDdnsTtlMax(Network::Inheritance::GLOBAL
).get()))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8502, gtest_ar.failure_message()) = ::testing::Message()
;
8503}
8504
8505// Verifies that DDNS parameters are supported in pools.
8506TEST_F(Dhcp4ParserTest, poolDdnsParameters)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("poolDdnsParameters") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_poolDdnsParameters_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_poolDdnsParameters_Test() = default
; ~Dhcp4ParserTest_poolDdnsParameters_Test() override = default
; Dhcp4ParserTest_poolDdnsParameters_Test (const Dhcp4ParserTest_poolDdnsParameters_Test
&) = delete; Dhcp4ParserTest_poolDdnsParameters_Test &
operator=( const Dhcp4ParserTest_poolDdnsParameters_Test &
) = delete; Dhcp4ParserTest_poolDdnsParameters_Test (Dhcp4ParserTest_poolDdnsParameters_Test
&&) noexcept = delete; Dhcp4ParserTest_poolDdnsParameters_Test
& operator=( Dhcp4ParserTest_poolDdnsParameters_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_poolDdnsParameters_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "poolDdnsParameters", nullptr, nullptr, ::testing::internal
::CodeLocation("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8506), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8506), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8506), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_poolDdnsParameters_Test
>); void Dhcp4ParserTest_poolDdnsParameters_Test::TestBody
()
{
8507 string config = R"(
8508 {
8509 "valid-lifetime": 4000,
8510 "subnet4": [{
8511 "id": 1,
8512 "subnet": "192.0.0.0/16",
8513 "pools": [{
8514 "pool": "192.0.1.0/24",
8515 "ddns-send-updates": true,
8516 "ddns-override-no-update": true,
8517 "ddns-override-client-update": true,
8518 "ddns-replace-client-name": "always",
8519 "ddns-generated-prefix": "prefix",
8520 "ddns-qualifying-suffix": "suffix",
8521 "hostname-char-set": "[a-z]",
8522 "hostname-char-replacement": "X",
8523 "ddns-update-on-renew": true,
8524 "ddns-ttl-percent": 0.5,
8525 "ddns-conflict-resolution-mode": "check-with-dhcid",
8526 "ddns-ttl-min": 200,
8527 "ddns-ttl-max": 500
8528 },
8529 {
8530 "pool": "192.0.2.0/24",
8531 "ddns-ttl": 300
8532 }]
8533 }]
8534 }
8535 )";
8536
8537 ConstElementPtr json;
8538 ASSERT_NO_THROW(json = parseDHCP4(config))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
json = parseDHCP4(config); } else static_assert(true, ""); }
catch (std::exception const& e) { gtest_msg.value = "it throws "
; gtest_msg.value += ::testing::internal::GetTypeName(typeid(
e)); gtest_msg.value += " with description \""; gtest_msg.value
+= e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_8538
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8538
; } } else gtest_label_testnothrow_8538 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8538, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8539 extractConfig(config);
8540
8541 ConstElementPtr status;
8542 EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json))switch (0) case 0: default: if (::testing::internal::TrueWithString
gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) {
status = Dhcpv4SrvTest::configure(*srv_, json); } else static_assert
(true, ""); } catch (std::exception const& e) { gtest_msg
.value = "it throws "; gtest_msg.value += ::testing::internal
::GetTypeName(typeid(e)); gtest_msg.value += " with description \""
; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto
gtest_label_testnothrow_8542; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8542; } } else gtest_label_testnothrow_8542
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8542, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8543
8544 // returned value should be 0 (success)
8545 checkResult(status, 0);
8546
8547 // Commit it so global inheritance works.
8548 CfgMgr::instance().commit();
8549
8550 ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
8551 getCfgSubnets4()->selectSubnet(IOAddress("192.0.0.0"));
8552 ASSERT_TRUE(subnet)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(subnet)) ; else return
::testing::internal::AssertHelper(::testing::TestPartResult::
kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8552, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
8553
8554 const PoolCollection pools = subnet->getPools(Lease::TYPE_V4);
8555 ASSERT_GE(pools.size(), 2U)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::CmpHelperGE("pools.size()",
"2U", pools.size(), 2U))) ; else return ::testing::internal::
AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8555, gtest_ar.failure_message()) = ::testing::Message()
;
8556
8557 // First pool specifies all but ddns-ttl.
8558 PoolPtr pool = pools.at(0);
8559 ASSERT_TRUE(pool)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8559
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
8560
8561 ASSERT_FALSE(pool->getDdnsSendUpdates().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pool->getDdnsSendUpdates
().unspecified()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8561, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsSendUpdates().unspecified()", "true", "false"
) .c_str()) = ::testing::Message()
;
8562 EXPECT_TRUE(pool->getDdnsSendUpdates().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getDdnsSendUpdates
().get())) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8562, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsSendUpdates().get()", "false", "true") .c_str
()) = ::testing::Message()
;
8563
8564 ASSERT_FALSE(pool->getDdnsOverrideNoUpdate().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pool->getDdnsOverrideNoUpdate
().unspecified()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8564, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsOverrideNoUpdate().unspecified()", "true",
"false") .c_str()) = ::testing::Message()
;
8565 EXPECT_TRUE(pool->getDdnsOverrideNoUpdate().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getDdnsOverrideNoUpdate
().get())) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8565, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsOverrideNoUpdate().get()", "false", "true"
) .c_str()) = ::testing::Message()
;
8566
8567 ASSERT_FALSE(pool->getDdnsOverrideClientUpdate().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pool->getDdnsOverrideClientUpdate
().unspecified()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8567, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsOverrideClientUpdate().unspecified()", "true"
, "false") .c_str()) = ::testing::Message()
;
8568 EXPECT_TRUE(pool->getDdnsOverrideClientUpdate().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getDdnsOverrideClientUpdate
().get())) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8568, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsOverrideClientUpdate().get()", "false", "true"
) .c_str()) = ::testing::Message()
;
8569
8570 ASSERT_FALSE(pool->getDdnsReplaceClientNameMode().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pool->getDdnsReplaceClientNameMode
().unspecified()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8570, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsReplaceClientNameMode().unspecified()", "true"
, "false") .c_str()) = ::testing::Message()
;
8571 EXPECT_EQ(pool->getDdnsReplaceClientNameMode().get(),switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("pool->getDdnsReplaceClientNameMode().get()"
, "D2ClientConfig::RCM_ALWAYS", pool->getDdnsReplaceClientNameMode
().get(), D2ClientConfig::RCM_ALWAYS))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8572, gtest_ar.failure_message()) = ::testing::Message()
8572 D2ClientConfig::RCM_ALWAYS)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("pool->getDdnsReplaceClientNameMode().get()"
, "D2ClientConfig::RCM_ALWAYS", pool->getDdnsReplaceClientNameMode
().get(), D2ClientConfig::RCM_ALWAYS))) ; else ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8572, gtest_ar.failure_message()) = ::testing::Message()
;
8573
8574 ASSERT_FALSE(pool->getDdnsGeneratedPrefix().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pool->getDdnsGeneratedPrefix
().unspecified()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8574, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsGeneratedPrefix().unspecified()", "true", "false"
) .c_str()) = ::testing::Message()
;
8575 EXPECT_EQ(pool->getDdnsGeneratedPrefix().get(), "prefix")switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("pool->getDdnsGeneratedPrefix().get()"
, "\"prefix\"", pool->getDdnsGeneratedPrefix().get(), "prefix"
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8575, gtest_ar.failure_message()) = ::testing::Message()
;
8576
8577 ASSERT_FALSE(pool->getDdnsQualifyingSuffix().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pool->getDdnsQualifyingSuffix
().unspecified()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8577, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsQualifyingSuffix().unspecified()", "true",
"false") .c_str()) = ::testing::Message()
;
8578 EXPECT_EQ(pool->getDdnsQualifyingSuffix().get(), "suffix")switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("pool->getDdnsQualifyingSuffix().get()"
, "\"suffix\"", pool->getDdnsQualifyingSuffix().get(), "suffix"
))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8578, gtest_ar.failure_message()) = ::testing::Message()
;
8579
8580 ASSERT_FALSE(pool->getHostnameCharSet().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pool->getHostnameCharSet
().unspecified()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8580, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getHostnameCharSet().unspecified()", "true", "false"
) .c_str()) = ::testing::Message()
;
8581 EXPECT_EQ(pool->getHostnameCharSet().get(), "[a-z]")switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("pool->getHostnameCharSet().get()"
, "\"[a-z]\"", pool->getHostnameCharSet().get(), "[a-z]"))
) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8581, gtest_ar.failure_message()) = ::testing::Message()
;
8582
8583 ASSERT_FALSE(pool->getHostnameCharReplacement().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pool->getHostnameCharReplacement
().unspecified()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8583, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getHostnameCharReplacement().unspecified()", "true"
, "false") .c_str()) = ::testing::Message()
;
8584 EXPECT_EQ(pool->getHostnameCharReplacement().get(), "X")switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("pool->getHostnameCharReplacement().get()"
, "\"X\"", pool->getHostnameCharReplacement().get(), "X"))
) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8584, gtest_ar.failure_message()) = ::testing::Message()
;
8585
8586 ASSERT_FALSE(pool->getDdnsUpdateOnRenew().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pool->getDdnsUpdateOnRenew
().unspecified()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8586, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsUpdateOnRenew().unspecified()", "true", "false"
) .c_str()) = ::testing::Message()
;
8587 EXPECT_TRUE(pool->getDdnsUpdateOnRenew().get())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getDdnsUpdateOnRenew
().get())) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8587, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsUpdateOnRenew().get()", "false", "true") .
c_str()) = ::testing::Message()
;
8588
8589 ASSERT_FALSE(pool->getDdnsTtlPercent().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pool->getDdnsTtlPercent
().unspecified()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8589, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsTtlPercent().unspecified()", "true", "false"
) .c_str()) = ::testing::Message()
;
8590 EXPECT_EQ(pool->getDdnsTtlPercent().get(), 0.5)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("pool->getDdnsTtlPercent().get()"
, "0.5", pool->getDdnsTtlPercent().get(), 0.5))) ; else ::
testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8590
, gtest_ar.failure_message()) = ::testing::Message()
;
8591
8592 ASSERT_FALSE(pool->getDdnsConflictResolutionMode().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pool->getDdnsConflictResolutionMode
().unspecified()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8592, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsConflictResolutionMode().unspecified()", "true"
, "false") .c_str()) = ::testing::Message()
;
8593 EXPECT_EQ(pool->getDdnsConflictResolutionMode().get(), "check-with-dhcid")switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("pool->getDdnsConflictResolutionMode().get()"
, "\"check-with-dhcid\"", pool->getDdnsConflictResolutionMode
().get(), "check-with-dhcid"))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8593, gtest_ar.failure_message()) = ::testing::Message()
;
8594
8595 ASSERT_TRUE(pool->getDdnsTtl().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getDdnsTtl()
.unspecified())) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8595, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsTtl().unspecified()", "false", "true") .c_str
()) = ::testing::Message()
;
8596
8597 ASSERT_FALSE(pool->getDdnsTtlMin().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pool->getDdnsTtlMin
().unspecified()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8597, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsTtlMin().unspecified()", "true", "false") .
c_str()) = ::testing::Message()
;
8598 EXPECT_EQ(pool->getDdnsTtlMin().get(), 200U)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("pool->getDdnsTtlMin().get()"
, "200U", pool->getDdnsTtlMin().get(), 200U))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8598
, gtest_ar.failure_message()) = ::testing::Message()
;
8599
8600 ASSERT_FALSE(pool->getDdnsTtlMax().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pool->getDdnsTtlMax
().unspecified()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8600, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsTtlMax().unspecified()", "true", "false") .
c_str()) = ::testing::Message()
;
8601 EXPECT_EQ(pool->getDdnsTtlMax().get(), 500U)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("pool->getDdnsTtlMax().get()"
, "500U", pool->getDdnsTtlMax().get(), 500U))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8601
, gtest_ar.failure_message()) = ::testing::Message()
;
8602
8603 // Second pool only specifies ddns-ttl.
8604 pool = pools.at(1);
8605 ASSERT_TRUE(pool)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool)) ; else return ::
testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8605
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
8606
8607 ASSERT_TRUE(pool->getDdnsSendUpdates().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getDdnsSendUpdates
().unspecified())) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8607, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsSendUpdates().unspecified()", "false", "true"
) .c_str()) = ::testing::Message()
;
8608 ASSERT_TRUE(pool->getDdnsOverrideNoUpdate().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getDdnsOverrideNoUpdate
().unspecified())) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8608, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsOverrideNoUpdate().unspecified()", "false"
, "true") .c_str()) = ::testing::Message()
;
8609 ASSERT_TRUE(pool->getDdnsOverrideClientUpdate().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getDdnsOverrideClientUpdate
().unspecified())) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8609, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsOverrideClientUpdate().unspecified()", "false"
, "true") .c_str()) = ::testing::Message()
;
8610 ASSERT_TRUE(pool->getDdnsReplaceClientNameMode().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getDdnsReplaceClientNameMode
().unspecified())) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8610, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsReplaceClientNameMode().unspecified()", "false"
, "true") .c_str()) = ::testing::Message()
;
8611 ASSERT_TRUE(pool->getDdnsGeneratedPrefix().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getDdnsGeneratedPrefix
().unspecified())) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8611, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsGeneratedPrefix().unspecified()", "false",
"true") .c_str()) = ::testing::Message()
;
8612 ASSERT_TRUE(pool->getDdnsQualifyingSuffix().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getDdnsQualifyingSuffix
().unspecified())) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8612, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsQualifyingSuffix().unspecified()", "false"
, "true") .c_str()) = ::testing::Message()
;
8613 ASSERT_TRUE(pool->getHostnameCharSet().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getHostnameCharSet
().unspecified())) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8613, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getHostnameCharSet().unspecified()", "false", "true"
) .c_str()) = ::testing::Message()
;
8614 ASSERT_TRUE(pool->getHostnameCharReplacement().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getHostnameCharReplacement
().unspecified())) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8614, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getHostnameCharReplacement().unspecified()", "false"
, "true") .c_str()) = ::testing::Message()
;
8615 ASSERT_TRUE(pool->getDdnsUpdateOnRenew().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getDdnsUpdateOnRenew
().unspecified())) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8615, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsUpdateOnRenew().unspecified()", "false", "true"
) .c_str()) = ::testing::Message()
;
8616 ASSERT_TRUE(pool->getDdnsTtlPercent().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getDdnsTtlPercent
().unspecified())) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8616, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsTtlPercent().unspecified()", "false", "true"
) .c_str()) = ::testing::Message()
;
8617 ASSERT_TRUE(pool->getDdnsConflictResolutionMode().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getDdnsConflictResolutionMode
().unspecified())) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8617, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsConflictResolutionMode().unspecified()", "false"
, "true") .c_str()) = ::testing::Message()
;
8618 ASSERT_TRUE(pool->getDdnsTtlMin().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getDdnsTtlMin
().unspecified())) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8618, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsTtlMin().unspecified()", "false", "true") .
c_str()) = ::testing::Message()
;
8619
8620 ASSERT_FALSE(pool->getDdnsTtl().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(pool->getDdnsTtl
().unspecified()))) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8620, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsTtl().unspecified()", "true", "false") .c_str
()) = ::testing::Message()
;
8621 EXPECT_EQ(pool->getDdnsTtl().get(), 300U)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("pool->getDdnsTtl().get()"
, "300U", pool->getDdnsTtl().get(), 300U))) ; else ::testing
::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8621
, gtest_ar.failure_message()) = ::testing::Message()
;
8622
8623 ASSERT_TRUE(pool->getDdnsTtlMax().unspecified())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(pool->getDdnsTtlMax
().unspecified())) ; else return ::testing::internal::AssertHelper
(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8623, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsTtlMax().unspecified()", "false", "true") .
c_str()) = ::testing::Message()
;
8624}
8625
8626// Verifies hosts-datatbase parsing (warning and conflict with hosts-databases.
8627TEST_F(Dhcp4ParserTest, hostsDatabase)static_assert(sizeof("Dhcp4ParserTest") > 1, "test_suite_name must not be empty"
); static_assert(sizeof("hostsDatabase") > 1, "test_name must not be empty"
); class Dhcp4ParserTest_hostsDatabase_Test : public Dhcp4ParserTest
{ public: Dhcp4ParserTest_hostsDatabase_Test() = default; ~Dhcp4ParserTest_hostsDatabase_Test
() override = default; Dhcp4ParserTest_hostsDatabase_Test (const
Dhcp4ParserTest_hostsDatabase_Test &) = delete; Dhcp4ParserTest_hostsDatabase_Test
& operator=( const Dhcp4ParserTest_hostsDatabase_Test &
) = delete; Dhcp4ParserTest_hostsDatabase_Test (Dhcp4ParserTest_hostsDatabase_Test
&&) noexcept = delete; Dhcp4ParserTest_hostsDatabase_Test
& operator=( Dhcp4ParserTest_hostsDatabase_Test &&
) noexcept = delete; private: void TestBody() override; [[maybe_unused
]] static ::testing::TestInfo* const test_info_; }; ::testing
::TestInfo* const Dhcp4ParserTest_hostsDatabase_Test::test_info_
= ::testing::internal::MakeAndRegisterTestInfo( "Dhcp4ParserTest"
, "hostsDatabase", nullptr, nullptr, ::testing::internal::CodeLocation
("../../../src/bin/dhcp4/tests/config_parser_unittest.cc", 8627
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8627), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8627), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_hostsDatabase_Test
>); void Dhcp4ParserTest_hostsDatabase_Test::TestBody()
{
8628 string config = R"(
8629 {
8630 "hosts-database": {
8631 "type": "mysql"
8632 },
8633 "hosts-databases": [ {
8634 "type": "mysql"
8635 } ]
8636 }
8637 )";
8638
8639 string expected = "can't use hosts-database and hosts-databases at the same time";
8640 configure(config, CONTROL_RESULT_ERROR, expected);
8641 EXPECT_EQ(1U, countFile("DHCP4_CONFIG_HOSTS_DATABASE_DEPRECATED"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("1U", "countFile(\"DHCP4_CONFIG_HOSTS_DATABASE_DEPRECATED\")"
, 1U, countFile("DHCP4_CONFIG_HOSTS_DATABASE_DEPRECATED")))) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8641, gtest_ar.failure_message()) = ::testing::Message()
;
8642}
8643
8644} // namespace

←

/usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/bits/basic_string.h

→
1// Components for manipulating sequences of characters -*- C++ -*-
2
3// Copyright (C) 1997-2026 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/basic_string.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{string}
28 */
29
30//
31// ISO C++ 14882: 21 Strings library
32//
33
34#ifndef _BASIC_STRING_H1
35#define _BASIC_STRING_H1 1
36
37#ifdef _GLIBCXX_SYSHDR
38#pragma GCC system_header
39#endif
40
41#include <ext/alloc_traits.h>
42#include <debug/debug.h>
43
44#if __cplusplus201703L >= 201103L
45#include <initializer_list>
46#endif
47
48#include <bits/version.h>
49
50#ifdef __glibcxx_string_view201803L // >= C++17
51# include <string_view>
52#endif
53
54#if __glibcxx_containers_ranges // C++ >= 23
55# include <bits/ranges_algobase.h> // ranges::copy
56# include <bits/ranges_util.h> // ranges::subrange
57#endif
58
59#if __glibcxx_to_string >= 202306L // C++ >= 26
60# include <charconv>
61#endif
62
63#if ! _GLIBCXX_USE_CXX11_ABI1
64# include "cow_string.h"
65#else
66
67namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
68{
69_GLIBCXX_BEGIN_NAMESPACE_VERSION
70_GLIBCXX_BEGIN_NAMESPACE_CXX11namespace __cxx11 {
71
72 /**
73 * @class basic_string basic_string.h <string>
74 * @brief Managing sequences of characters and character-like objects.
75 *
76 * @ingroup strings
77 * @ingroup sequences
78 * @headerfile string
79 * @since C++98
80 *
81 * @tparam _CharT Type of character
82 * @tparam _Traits Traits for character type, defaults to
83 * char_traits<_CharT>.
84 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
85 *
86 * Meets the requirements of a <a href="tables.html#65">container</a>, a
87 * <a href="tables.html#66">reversible container</a>, and a
88 * <a href="tables.html#67">sequence</a>. Of the
89 * <a href="tables.html#68">optional sequence requirements</a>, only
90 * @c push_back, @c at, and @c %array access are supported.
91 */
92 template<typename _CharT, typename _Traits, typename _Alloc>
93 class basic_string
94 {
95#if __cplusplus201703L >= 202002L
96 static_assert(is_trivially_copyable_v<_CharT>
97 && is_trivially_default_constructible_v<_CharT>
98 && is_standard_layout_v<_CharT>);
99 static_assert(is_same_v<_CharT, typename _Traits::char_type>);
100 static_assert(is_same_v<_CharT, typename _Alloc::value_type>);
101 using _Char_alloc_type = _Alloc;
102#else
103 typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
104 rebind<_CharT>::other _Char_alloc_type;
105#endif
106
107 typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits;
108
109 // Types:
110 public:
111 typedef _Traits traits_type;
112 typedef typename _Traits::char_type value_type;
113 typedef _Char_alloc_type allocator_type;
114 typedef typename _Alloc_traits::size_type size_type;
115 typedef typename _Alloc_traits::difference_type difference_type;
116 typedef typename _Alloc_traits::reference reference;
117 typedef typename _Alloc_traits::const_reference const_reference;
118 typedef typename _Alloc_traits::pointer pointer;
119 typedef typename _Alloc_traits::const_pointer const_pointer;
120 typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator;
121 typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
122 const_iterator;
123 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
124 typedef std::reverse_iterator<iterator> reverse_iterator;
125
126 /// Value returned by various member functions when they fail.
127 static const size_type npos = static_cast<size_type>(-1);
128
129 protected:
130 // type used for positions in insert, erase etc.
131#if __cplusplus201703L < 201103L
132 typedef iterator __const_iterator;
133#else
134 typedef const_iterator __const_iterator;
135#endif
136
137 private:
138 static _GLIBCXX20_CONSTEXPR pointer
139 _S_allocate(_Char_alloc_type& __a, size_type __n)
140 {
141 pointer __p = _Alloc_traits::allocate(__a, __n);
142#if __glibcxx_constexpr_string201611L >= 201907L
143 // std::char_traits begins the lifetime of characters,
144 // but custom traits might not, so do it here.
145 if constexpr (!is_same_v<_Traits, char_traits<_CharT>>)
146 if (std::__is_constant_evaluated())
147 // Begin the lifetime of characters in allocated storage.
148 for (size_type __i = 0; __i < __n; ++__i)
149 std::construct_at(__builtin_addressof(__p[__i]));
150#endif
151 return __p;
152 }
153
154#ifdef __glibcxx_string_view201803L // >= C++17
155 // A helper type for avoiding boiler-plate.
156 typedef basic_string_view<_CharT, _Traits> __sv_type;
157
158 template<typename _Tp, typename _Res>
159 using _If_sv = enable_if_t<
160 __and_<is_convertible<const _Tp&, __sv_type>,
161 __not_<is_convertible<const _Tp*, const basic_string*>>,
162 __not_<is_convertible<const _Tp&, const _CharT*>>>::value,
163 _Res>;
164
165 // Allows an implicit conversion to __sv_type.
166 _GLIBCXX20_CONSTEXPR
167 static __sv_type
168 _S_to_string_view(__sv_type __svt) noexcept
169 { return __svt; }
170
171 // Wraps a string_view by explicit conversion and thus
172 // allows to add an internal constructor that does not
173 // participate in overload resolution when a string_view
174 // is provided.
175 struct __sv_wrapper
176 {
177 _GLIBCXX20_CONSTEXPR explicit
178 __sv_wrapper(__sv_type __sv) noexcept : _M_sv(__sv) { }
179
180 __sv_type _M_sv;
181 };
182
183 /**
184 * @brief Only internally used: Construct string from a string view
185 * wrapper.
186 * @param __svw string view wrapper.
187 * @param __a Allocator to use.
188 */
189 _GLIBCXX20_CONSTEXPR
190 explicit
191 basic_string(__sv_wrapper __svw, const _Alloc& __a)
192 : basic_string(__svw._M_sv.data(), __svw._M_sv.size(), __a) { }
193#endif
194
195 // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
196 struct _Alloc_hider : allocator_type // TODO check __is_final
197 {
198#if __cplusplus201703L < 201103L
199 _Alloc_hider(pointer __dat, const _Alloc& __a = _Alloc())
200 : allocator_type(__a), _M_p(__dat) { }
201#else
202 _GLIBCXX20_CONSTEXPR
203 _Alloc_hider(pointer __dat, const _Alloc& __a)
204 : allocator_type(__a), _M_p(__dat) { }
205
206 _GLIBCXX20_CONSTEXPR
207 _Alloc_hider(pointer __dat, _Alloc&& __a = _Alloc())
208 : allocator_type(std::move(__a)), _M_p(__dat) { }
209#endif
210
211 pointer _M_p; // The actual data.
212 };
213
214 _Alloc_hider _M_dataplus;
215 size_type _M_string_length;
216
217 enum { _S_local_capacity = 15 / sizeof(_CharT) };
218
219 union
220 {
221 _CharT _M_local_buf[_S_local_capacity + 1];
222 size_type _M_allocated_capacity;
223 };
224
225 _GLIBCXX20_CONSTEXPR
226 void
227 _M_data(pointer __p)
228 { _M_dataplus._M_p = __p; }
229
230 _GLIBCXX20_CONSTEXPR
231 void
232 _M_length(size_type __length)
233 { _M_string_length = __length; }
234
235 _GLIBCXX20_CONSTEXPR
236 pointer
237 _M_data() const
238 { return _M_dataplus._M_p; }
239
240 _GLIBCXX20_CONSTEXPR
241 pointer
242 _M_local_data()
243 {
244#if __cplusplus201703L >= 201103L
245 return std::pointer_traits<pointer>::pointer_to(*_M_local_buf);
246#else
247 return pointer(_M_local_buf);
248#endif
249 }
250
251 _GLIBCXX20_CONSTEXPR
252 const_pointer
253 _M_local_data() const
254 {
255#if __cplusplus201703L >= 201103L
256 return std::pointer_traits<const_pointer>::pointer_to(*_M_local_buf);
257#else
258 return const_pointer(_M_local_buf);
259#endif
260 }
261
262 _GLIBCXX20_CONSTEXPR
263 void
264 _M_capacity(size_type __capacity)
265 { _M_allocated_capacity = __capacity; }
266
267 _GLIBCXX20_CONSTEXPR
268 void
269 _M_set_length(size_type __n)
270 {
271 traits_type::assign(_M_data()[__n], _CharT());
272 _M_length(__n);
273 }
274
275 _GLIBCXX20_CONSTEXPR
276 bool
277 _M_is_local() const
278 {
279 if (_M_data() == _M_local_data())
280 {
281 if (_M_string_length > _S_local_capacity)
282 __builtin_unreachable();
283 return true;
284 }
285 return false;
286 }
287
288 // Create & Destroy
289 _GLIBCXX20_CONSTEXPR
290 pointer
291 _M_create(size_type&, size_type);
292
293 _GLIBCXX20_CONSTEXPR
294 void
295 _M_dispose()
296 {
297 if (!_M_is_local())
298 _M_destroy(_M_allocated_capacity);
299 }
300
301 _GLIBCXX20_CONSTEXPR
302 void
303 _M_destroy(size_type __size) throw()
304 { _Alloc_traits::deallocate(_M_get_allocator(), _M_data(), __size + 1); }
305
306#if __cplusplus201703L < 201103L || defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
307 // _M_construct_aux is used to implement the 21.3.1 para 15 which
308 // requires special behaviour if _InIterator is an integral type
309 template<typename _InIterator>
310 void
311 _M_construct_aux(_InIterator __beg, _InIterator __end,
312 std::__false_type)
313 {
314 typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
315 _M_construct(__beg, __end, _Tag());
316 }
317
318 // _GLIBCXX_RESOLVE_LIB_DEFECTS
319 // 438. Ambiguity in the "do the right thing" clause
320 template<typename _Integer>
321 void
322 _M_construct_aux(_Integer __beg, _Integer __end, std::__true_type)
323 { _M_construct_aux_2(static_cast<size_type>(__beg), __end); }
324
325 void
326 _M_construct_aux_2(size_type __req, _CharT __c)
327 { _M_construct(__req, __c); }
328#endif
329
330 // For Input Iterators, used in istreambuf_iterators, etc.
331 template<typename _InIterator>
332 _GLIBCXX20_CONSTEXPR
333 void
334 _M_construct(_InIterator __beg, _InIterator __end,
335 std::input_iterator_tag);
336
337 // For forward_iterators up to random_access_iterators, used for
338 // string::iterator, _CharT*, etc.
339 template<typename _FwdIterator>
340 _GLIBCXX20_CONSTEXPR
341 void
342 _M_construct(_FwdIterator __beg, _FwdIterator __end,
343 std::forward_iterator_tag);
344
345 _GLIBCXX20_CONSTEXPR
346 void
347 _M_construct(size_type __req, _CharT __c);
348
349 // Construct using block of memory of known size.
350 // If _Terminated is true assume that source is already 0 terminated.
351 template<bool _Terminated>
352 _GLIBCXX20_CONSTEXPR
353 void
354 _M_construct(const _CharT *__c, size_type __n);
355
356#if __cplusplus201703L >= 202302L
357 constexpr void
358 _M_construct(basic_string&& __str, size_type __pos, size_type __n);
359#endif
360
361 _GLIBCXX20_CONSTEXPR
362 allocator_type&
363 _M_get_allocator()
364 { return _M_dataplus; }
365
366 _GLIBCXX20_CONSTEXPR
367 const allocator_type&
368 _M_get_allocator() const
369 { return _M_dataplus; }
370
371 // Ensure that _M_local_buf is the active member of the union.
372 __attribute__((__always_inline__))
373 _GLIBCXX14_CONSTEXPRconstexpr
374 void
375 _M_init_local_buf() _GLIBCXX_NOEXCEPTnoexcept
376 {
377#if __glibcxx_is_constant_evaluated
378 if (std::is_constant_evaluated())
379 for (size_type __i = 0; __i <= _S_local_capacity; ++__i)
380 _M_local_buf[__i] = _CharT();
381#endif
382 }
383
384 __attribute__((__always_inline__))
385 _GLIBCXX14_CONSTEXPRconstexpr
386 pointer
387 _M_use_local_data() _GLIBCXX_NOEXCEPTnoexcept
388 {
389#if __cpp_lib_is_constant_evaluated
390 _M_init_local_buf();
391#endif
392 return _M_local_data();
393 }
394
395 private:
396
397#ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST
398 // The explicit instantiations in misc-inst.cc require this due to
399 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64063
400 template<typename _Tp, bool _Requires =
401 !__are_same<_Tp, _CharT*>::__value
402 && !__are_same<_Tp, const _CharT*>::__value
403 && !__are_same<_Tp, iterator>::__value
404 && !__are_same<_Tp, const_iterator>::__value>
405 struct __enable_if_not_native_iterator
406 { typedef basic_string& __type; };
407 template<typename _Tp>
408 struct __enable_if_not_native_iterator<_Tp, false> { };
409#endif
410
411 _GLIBCXX20_CONSTEXPR
412 size_type
413 _M_check(size_type __pos, const char* __s) const
414 {
415 if (__pos > this->size())
416 __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > "("%s: __pos (which is %zu) > " "this->size() (which is %zu)"
)
417 "this->size() (which is %zu)")("%s: __pos (which is %zu) > " "this->size() (which is %zu)"
)
,
418 __s, (size_t)__pos, (size_t)this->size());
419 return __pos;
420 }
421
422 _GLIBCXX20_CONSTEXPR
423 void
424 _M_check_length(size_type __n1, size_type __n2, const char* __s) const
425 {
426 if (this->max_size() - (this->size() - __n1) < __n2)
427 __throw_length_error(__N(__s)(__s));
428 }
429
430
431 // NB: _M_limit doesn't check for a bad __pos value.
432 _GLIBCXX20_CONSTEXPR
433 size_type
434 _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPTnoexcept
435 {
436 const bool __testoff = __off < this->size() - __pos;
437 return __testoff ? __off : this->size() - __pos;
438 }
439
440 // True if _Rep and source do not overlap.
441 bool
442 _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPTnoexcept
443 {
444 return (less<const _CharT*>()(__s, _M_data())
445 || less<const _CharT*>()(_M_data() + this->size(), __s));
446 }
447
448 // When __n = 1 way faster than the general multichar
449 // traits_type::copy/move/assign.
450 _GLIBCXX20_CONSTEXPR
451 static void
452 _S_copy(_CharT* __d, const _CharT* __s, size_type __n)
453 {
454 if (__n == 1)
455 traits_type::assign(*__d, *__s);
456 else
457 traits_type::copy(__d, __s, __n);
458 }
459
460 _GLIBCXX20_CONSTEXPR
461 static void
462 _S_move(_CharT* __d, const _CharT* __s, size_type __n)
463 {
464 if (__n == 1)
465 traits_type::assign(*__d, *__s);
466 else
467 traits_type::move(__d, __s, __n);
468 }
469
470 _GLIBCXX20_CONSTEXPR
471 static void
472 _S_assign(_CharT* __d, size_type __n, _CharT __c)
473 {
474 if (__n == 1)
475 traits_type::assign(*__d, __c);
476 else
477 traits_type::assign(__d, __n, __c);
478 }
479
480#pragma GCC diagnostic push
481#pragma GCC diagnostic ignored "-Wc++17-extensions"
482 // _S_copy_chars is a separate template to permit specialization
483 // to optimize for the common case of pointers as iterators.
484 template<class _Iterator>
485 _GLIBCXX20_CONSTEXPR
486 static void
487 _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
488 {
489#if __cplusplus201703L >= 201103L
490 using _IterBase = decltype(std::__niter_base(__k1));
491 if constexpr (__or_<is_same<_IterBase, _CharT*>,
492 is_same<_IterBase, const _CharT*>>::value)
493 _S_copy(__p, std::__niter_base(__k1), __k2 - __k1);
494#if __cpp_lib_concepts
495 else if constexpr (requires {
496 requires contiguous_iterator<_Iterator>;
497 { std::to_address(__k1) }
498 -> convertible_to<const _CharT*>;
499 })
500 {
501 const auto __d = __k2 - __k1;
502 (void) (__k1 + __d); // See P3349R1
503 _S_copy(__p, std::to_address(__k1), static_cast<size_type>(__d));
504 }
505#endif
506 else
507#endif
508 for (; __k1 != __k2; ++__k1, (void)++__p)
509 traits_type::assign(*__p, static_cast<_CharT>(*__k1));
510 }
511#pragma GCC diagnostic pop
512
513#if __cplusplus201703L < 201103L || defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
514 static void
515 _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2)
516 { _S_copy_chars(__p, __k1.base(), __k2.base()); }
517
518 static void
519 _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
520 { _S_copy_chars(__p, __k1.base(), __k2.base()); }
521
522 static void
523 _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
524 { _S_copy(__p, __k1, __k2 - __k1); }
525
526 static void
527 _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
528 { _S_copy(__p, __k1, __k2 - __k1); }
529#endif
530
531#if __glibcxx_containers_ranges // C++ >= 23
532 // pre: __n == ranges::distance(__rg). __p+[0,__n) is a valid range.
533 template<typename _Rg>
534 static constexpr void
535 _S_copy_range(pointer __p, _Rg&& __rg, size_type __n)
536 {
537 if constexpr (requires {
538 requires ranges::contiguous_range<_Rg>;
539 { ranges::data(std::forward<_Rg>(__rg)) }
540 -> convertible_to<const _CharT*>;
541 })
542 _S_copy(__p, ranges::data(std::forward<_Rg>(__rg)), __n);
543 else
544 {
545 auto __first = ranges::begin(__rg);
546 const auto __last = ranges::end(__rg);
547 for (; __first != __last; ++__first)
548 traits_type::assign(*__p++, static_cast<_CharT>(*__first));
549 }
550 }
551#endif
552
553 _GLIBCXX20_CONSTEXPR
554 static int
555 _S_compare(size_type __n1, size_type __n2) _GLIBCXX_NOEXCEPTnoexcept
556 {
557 const difference_type __d = difference_type(__n1 - __n2);
558
559 if (__d > __gnu_cxx::__numeric_traits<int>::__max)
560 return __gnu_cxx::__numeric_traits<int>::__max;
561 else if (__d < __gnu_cxx::__numeric_traits<int>::__min)
562 return __gnu_cxx::__numeric_traits<int>::__min;
563 else
564 return int(__d);
565 }
566
567 _GLIBCXX20_CONSTEXPR
568 void
569 _M_assign(const basic_string&);
570
571 _GLIBCXX20_CONSTEXPR
572 void
573 _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
574 size_type __len2);
575
576 _GLIBCXX20_CONSTEXPR
577 void
578 _M_erase(size_type __pos, size_type __n);
579
580 public:
581 // Construct/copy/destroy:
582 // NB: We overload ctors in some cases instead of using default
583 // arguments, per 17.4.4.4 para. 2 item 2.
584
585 /**
586 * @brief Default constructor creates an empty string.
587 */
588 _GLIBCXX20_CONSTEXPR
589 basic_string()
590 _GLIBCXX_NOEXCEPT_IF(is_nothrow_default_constructible<_Alloc>::value)noexcept(is_nothrow_default_constructible<_Alloc>::value
)
591#if __cpp_concepts && __glibcxx_type_trait_variable_templates201510L
592 requires is_default_constructible_v<_Alloc>
593#endif
594 : _M_dataplus(_M_local_data())
595 {
596 _M_init_local_buf();
597 _M_set_length(0);
598 }
599
600 /**
601 * @brief Construct an empty string using allocator @a a.
602 */
603 _GLIBCXX20_CONSTEXPR
604 explicit
605 basic_string(const _Alloc& __a) _GLIBCXX_NOEXCEPTnoexcept
606 : _M_dataplus(_M_local_data(), __a)
607 {
608 _M_init_local_buf();
609 _M_set_length(0);
610 }
611
612 /**
613 * @brief Construct string with copy of value of @a __str.
614 * @param __str Source string.
615 */
616 _GLIBCXX20_CONSTEXPR
617 basic_string(const basic_string& __str)
618 : _M_dataplus(_M_local_data(),
619 _Alloc_traits::_S_select_on_copy(__str._M_get_allocator()))
620 {
621 _M_construct<true>(__str._M_data(), __str.length());
622 }
623
624 // _GLIBCXX_RESOLVE_LIB_DEFECTS
625 // 2583. no way to supply an allocator for basic_string(str, pos)
626 /**
627 * @brief Construct string as copy of a substring.
628 * @param __str Source string.
629 * @param __pos Index of first character to copy from.
630 * @param __a Allocator to use.
631 */
632 _GLIBCXX20_CONSTEXPR
633 basic_string(const basic_string& __str, size_type __pos,
634 const _Alloc& __a = _Alloc())
635 : _M_dataplus(_M_local_data(), __a)
636 {
637 const _CharT* __start = __str._M_data()
638 + __str._M_check(__pos, "basic_string::basic_string");
639 _M_construct(__start, __start + __str._M_limit(__pos, npos),
640 std::forward_iterator_tag());
641 }
642
643 /**
644 * @brief Construct string as copy of a substring.
645 * @param __str Source string.
646 * @param __pos Index of first character to copy from.
647 * @param __n Number of characters to copy.
648 */
649 _GLIBCXX20_CONSTEXPR
650 basic_string(const basic_string& __str, size_type __pos,
651 size_type __n)
652 : _M_dataplus(_M_local_data())
653 {
654 const _CharT* __start = __str._M_data()
655 + __str._M_check(__pos, "basic_string::basic_string");
656 _M_construct(__start, __start + __str._M_limit(__pos, __n),
657 std::forward_iterator_tag());
658 }
659
660 /**
661 * @brief Construct string as copy of a substring.
662 * @param __str Source string.
663 * @param __pos Index of first character to copy from.
664 * @param __n Number of characters to copy.
665 * @param __a Allocator to use.
666 */
667 _GLIBCXX20_CONSTEXPR
668 basic_string(const basic_string& __str, size_type __pos,
669 size_type __n, const _Alloc& __a)
670 : _M_dataplus(_M_local_data(), __a)
671 {
672 const _CharT* __start
673 = __str._M_data() + __str._M_check(__pos, "string::string");
674 _M_construct(__start, __start + __str._M_limit(__pos, __n),
675 std::forward_iterator_tag());
676 }
677
678#if __cplusplus201703L >= 202302L
679 _GLIBCXX20_CONSTEXPR
680 basic_string(basic_string&& __str, size_type __pos,
681 const _Alloc& __a = _Alloc())
682 : _M_dataplus(_M_local_data(), __a)
683 {
684 __pos = __str._M_check(__pos, "string::string");
685 _M_construct(std::move(__str), __pos, __str.length() - __pos);
686 }
687
688 _GLIBCXX20_CONSTEXPR
689 basic_string(basic_string&& __str, size_type __pos, size_type __n,
690 const _Alloc& __a = _Alloc())
691 : _M_dataplus(_M_local_data(), __a)
692 {
693 __pos = __str._M_check(__pos, "string::string");
694 _M_construct(std::move(__str), __pos, __str._M_limit(__pos, __n));
695 }
696#endif // C++23
697
698 /**
699 * @brief Construct string initialized by a character %array.
700 * @param __s Source character %array.
701 * @param __n Number of characters to copy.
702 * @param __a Allocator to use (default is default allocator).
703 *
704 * NB: @a __s must have at least @a __n characters, &apos;\\0&apos;
705 * has no special meaning.
706 */
707 _GLIBCXX20_CONSTEXPR
708 basic_string(const _CharT* __s, size_type __n,
709 const _Alloc& __a = _Alloc())
710 : _M_dataplus(_M_local_data(), __a)
711 {
712 // NB: Not required, but considered best practice.
713 if (__s == 0 && __n > 0)
714 std::__throw_logic_error(__N("basic_string: "("basic_string: " "construction from null is not valid")
715 "construction from null is not valid")("basic_string: " "construction from null is not valid"));
716 _M_construct(__s, __s + __n, std::forward_iterator_tag());
717 }
718
719 /**
720 * @brief Construct string as copy of a C string.
721 * @param __s Source C string.
722 * @param __a Allocator to use (default is default allocator).
723 */
724#if __cpp_deduction_guides201703L && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
725 // _GLIBCXX_RESOLVE_LIB_DEFECTS
726 // 3076. basic_string CTAD ambiguity
727 template<typename = _RequireAllocator<_Alloc>>
728#endif
729 _GLIBCXX20_CONSTEXPR
730 basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
731 : _M_dataplus(_M_local_data(), __a)
732 {
733 // NB: Not required, but considered best practice.
734 if (__s == 0)
735 std::__throw_logic_error(__N("basic_string: "("basic_string: " "construction from null is not valid")
736 "construction from null is not valid")("basic_string: " "construction from null is not valid"));
737 const _CharT* __end = __s + traits_type::length(__s);
738 _M_construct(__s, __end, forward_iterator_tag());
739 }
740
741 /**
742 * @brief Construct string as multiple characters.
743 * @param __n Number of characters.
744 * @param __c Character to use.
745 * @param __a Allocator to use (default is default allocator).
746 */
747#if __cpp_deduction_guides201703L && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
748 // _GLIBCXX_RESOLVE_LIB_DEFECTS
749 // 3076. basic_string CTAD ambiguity
750 template<typename = _RequireAllocator<_Alloc>>
751#endif
752 _GLIBCXX20_CONSTEXPR
753 basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc())
754 : _M_dataplus(_M_local_data(), __a)
755 { _M_construct(__n, __c); }
756
757#if __cplusplus201703L >= 201103L
758 /**
759 * @brief Move construct string.
760 * @param __str Source string.
761 *
762 * The newly-created string contains the exact contents of @a __str.
763 * @a __str is a valid, but unspecified string.
764 */
765 _GLIBCXX20_CONSTEXPR
766 basic_string(basic_string&& __str) noexcept
767 : _M_dataplus(_M_local_data(), std::move(__str._M_get_allocator()))
768 {
769 if (__str._M_is_local())
770 {
771 _M_init_local_buf();
772 traits_type::copy(_M_local_buf, __str._M_local_buf,
773 __str.length() + 1);
774 }
775 else
776 {
777 _M_data(__str._M_data());
778 _M_capacity(__str._M_allocated_capacity);
779 }
780
781 // Must use _M_length() here not _M_set_length() because
782 // basic_stringbuf relies on writing into unallocated capacity so
783 // we mess up the contents if we put a '\0' in the string.
784 _M_length(__str.length());
785 __str._M_data(__str._M_use_local_data());
786 __str._M_set_length(0);
787 }
788
789#if __glibcxx_containers_ranges // C++ >= 23
790 /**
791 * @brief Construct a string from a range.
792 * @since C++23
793 */
794 template<__detail::__container_compatible_range<_CharT> _Rg>
795 constexpr
796 basic_string(from_range_t, _Rg&& __rg, const _Alloc& __a = _Alloc())
797 : basic_string(__a)
798 {
799 if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>)
800 {
801 const auto __n = static_cast<size_type>(ranges::distance(__rg));
802 reserve(__n);
803 _S_copy_range(_M_data(), std::forward<_Rg>(__rg), __n);
804 _M_set_length(__n);
805 }
806 else
807 {
808 auto __first = ranges::begin(__rg);
809 const auto __last = ranges::end(__rg);
810 for (; __first != __last; ++__first)
811 push_back(*__first);
812 }
813 }
814#endif
815
816 /**
817 * @brief Construct string from an initializer %list.
818 * @param __l std::initializer_list of characters.
819 * @param __a Allocator to use (default is default allocator).
820 */
821 _GLIBCXX20_CONSTEXPR
822 basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc())
823 : _M_dataplus(_M_local_data(), __a)
824 { _M_construct(__l.begin(), __l.end(), std::forward_iterator_tag()); }
825
826 _GLIBCXX20_CONSTEXPR
827 basic_string(const basic_string& __str, const _Alloc& __a)
828 : _M_dataplus(_M_local_data(), __a)
829 { _M_construct(__str.begin(), __str.end(), std::forward_iterator_tag()); }
830
831 _GLIBCXX20_CONSTEXPR
832 basic_string(basic_string&& __str, const _Alloc& __a)
833 noexcept(_Alloc_traits::_S_always_equal())
834 : _M_dataplus(_M_local_data(), __a)
835 {
836 if (__str._M_is_local())
837 {
838 _M_init_local_buf();
839 traits_type::copy(_M_local_buf, __str._M_local_buf,
840 __str.length() + 1);
841 _M_length(__str.length());
842 __str._M_set_length(0);
843 }
844 else if (_Alloc_traits::_S_always_equal()
845 || __str.get_allocator() == __a)
846 {
847 _M_data(__str._M_data());
848 _M_length(__str.length());
849 _M_capacity(__str._M_allocated_capacity);
850 __str._M_data(__str._M_use_local_data());
851 __str._M_set_length(0);
852 }
853 else
854 _M_construct(__str.begin(), __str.end(), std::forward_iterator_tag());
855 }
856#endif // C++11
857
858#if __cplusplus201703L >= 202100L
859 basic_string(nullptr_t) = delete;
860 basic_string& operator=(nullptr_t) = delete;
861#endif // C++23
862
863 /**
864 * @brief Construct string as copy of a range.
865 * @param __beg Start of range.
866 * @param __end End of range.
867 * @param __a Allocator to use (default is default allocator).
868 */
869#if __cplusplus201703L >= 201103L
870 template<typename _InputIterator,
871 typename = std::_RequireInputIter<_InputIterator>>
872#else
873 template<typename _InputIterator>
874#endif
875 _GLIBCXX20_CONSTEXPR
876 basic_string(_InputIterator __beg, _InputIterator __end,
877 const _Alloc& __a = _Alloc())
878 : _M_dataplus(_M_local_data(), __a), _M_string_length(0)
879 {
880#if __cplusplus201703L >= 201103L
881 _M_construct(__beg, __end, std::__iterator_category(__beg));
882#else
883 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
884 _M_construct_aux(__beg, __end, _Integral());
885#endif
886 }
887
888#ifdef __glibcxx_string_view201803L // >= C++17
889 /**
890 * @brief Construct string from a substring of a string_view.
891 * @param __t Source object convertible to string view.
892 * @param __pos The index of the first character to copy from __t.
893 * @param __n The number of characters to copy from __t.
894 * @param __a Allocator to use.
895 */
896 template<typename _Tp,
897 typename = enable_if_t<is_convertible_v<const _Tp&, __sv_type>>>
898 _GLIBCXX20_CONSTEXPR
899 basic_string(const _Tp& __t, size_type __pos, size_type __n,
900 const _Alloc& __a = _Alloc())
901 : basic_string(_S_to_string_view(__t).substr(__pos, __n), __a) { }
902
903 /**
904 * @brief Construct string from a string_view.
905 * @param __t Source object convertible to string view.
906 * @param __a Allocator to use (default is default allocator).
907 */
908 template<typename _Tp, typename = _If_sv<_Tp, void>>
909 _GLIBCXX20_CONSTEXPR
910 explicit
911 basic_string(const _Tp& __t, const _Alloc& __a = _Alloc())
912 : basic_string(__sv_wrapper(_S_to_string_view(__t)), __a) { }
913#endif // C++17
914
915 /**
916 * @brief Destroy the string instance.
917 */
918 _GLIBCXX20_CONSTEXPR
919 ~basic_string()
920 { _M_dispose(); }
921
922 /**
923 * @brief Assign the value of @a str to this string.
924 * @param __str Source string.
925 */
926 _GLIBCXX20_CONSTEXPR
927 basic_string&
928 operator=(const basic_string& __str)
929 {
930 return this->assign(__str);
931 }
932
933 /**
934 * @brief Copy contents of @a s into this string.
935 * @param __s Source null-terminated string.
936 */
937 _GLIBCXX20_CONSTEXPR
938 basic_string&
939 operator=(const _CharT* __s)
940 { return this->assign(__s); }
941
942 /**
943 * @brief Set value to string of length 1.
944 * @param __c Source character.
945 *
946 * Assigning to a character makes this string length 1 and
947 * (*this)[0] == @a c.
948 */
949 _GLIBCXX20_CONSTEXPR
950 basic_string&
951 operator=(_CharT __c)
952 {
953 this->assign(1, __c);
954 return *this;
955 }
956
957#if __cplusplus201703L >= 201103L
958 /**
959 * @brief Move assign the value of @a str to this string.
960 * @param __str Source string.
961 *
962 * The contents of @a str are moved into this string (without copying).
963 * @a str is a valid, but unspecified string.
964 */
965 // _GLIBCXX_RESOLVE_LIB_DEFECTS
966 // 2063. Contradictory requirements for string move assignment
967 _GLIBCXX20_CONSTEXPR
968 basic_string&
969 operator=(basic_string&& __str)
970 noexcept(_Alloc_traits::_S_nothrow_move())
971 {
972 const bool __equal_allocs = _Alloc_traits::_S_always_equal()
973 || _M_get_allocator() == __str._M_get_allocator();
974 if (!_M_is_local() && _Alloc_traits::_S_propagate_on_move_assign()
975 && !__equal_allocs)
976 {
977 // Destroy existing storage before replacing allocator.
978 _M_destroy(_M_allocated_capacity);
979 _M_data(_M_local_data());
980 _M_set_length(0);
981 }
982 // Replace allocator if POCMA is true.
983 std::__alloc_on_move(_M_get_allocator(), __str._M_get_allocator());
984
985 if (__str._M_is_local())
986 {
987 // We've always got room for a short string, just copy it
988 // (unless this is a self-move, because that would violate the
989 // char_traits::copy precondition that the ranges don't overlap).
990 if (__builtin_expect(std::__addressof(__str) != this, true))
991 {
992 if (__str.size())
993 this->_S_copy(_M_data(), __str._M_data(), __str.size());
994 _M_set_length(__str.size());
995 }
996 }
997 else if (_Alloc_traits::_S_propagate_on_move_assign() || __equal_allocs)
998 {
999 // Just move the allocated pointer, our allocator can free it.
1000 pointer __data = nullptr;
1001 size_type __capacity;
1002 if (!_M_is_local())
1003 {
1004 if (__equal_allocs)
1005 {
1006 // __str can reuse our existing storage.
1007 __data = _M_data();
1008 __capacity = _M_allocated_capacity;
1009 }
1010 else // __str can't use it, so free it.
1011 _M_destroy(_M_allocated_capacity);
1012 }
1013
1014 _M_data(__str._M_data());
1015 _M_length(__str.length());
1016 _M_capacity(__str._M_allocated_capacity);
1017 if (__data)
1018 {
1019 __str._M_data(__data);
1020 __str._M_capacity(__capacity);
1021 }
1022 else
1023 __str._M_data(__str._M_use_local_data());
1024 }
1025 else // Need to do a deep copy
1026 _M_assign(__str);
1027 __str.clear();
1028 return *this;
1029 }
1030
1031 /**
1032 * @brief Set value to string constructed from initializer %list.
1033 * @param __l std::initializer_list.
1034 */
1035 _GLIBCXX20_CONSTEXPR
1036 basic_string&
1037 operator=(initializer_list<_CharT> __l)
1038 {
1039 this->assign(__l.begin(), __l.size());
1040 return *this;
1041 }
1042#endif // C++11
1043
1044#ifdef __glibcxx_string_view201803L // >= C++17
1045 /**
1046 * @brief Set value to string constructed from a string_view.
1047 * @param __svt An object convertible to string_view.
1048 */
1049 template<typename _Tp>
1050 _GLIBCXX20_CONSTEXPR
1051 _If_sv<_Tp, basic_string&>
1052 operator=(const _Tp& __svt)
1053 { return this->assign(__svt); }
1054
1055 /**
1056 * @brief Convert to a string_view.
1057 * @return A string_view.
1058 */
1059 _GLIBCXX20_CONSTEXPR
1060 operator __sv_type() const noexcept
1061 { return __sv_type(data(), size()); }
1062#endif // C++17
1063
1064 // Iterators:
1065 /**
1066 * Returns a read/write iterator that points to the first character in
1067 * the %string.
1068 */
1069 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1070 iterator
1071 begin() _GLIBCXX_NOEXCEPTnoexcept
1072 { return iterator(_M_data()); }
1073
1074 /**
1075 * Returns a read-only (constant) iterator that points to the first
1076 * character in the %string.
1077 */
1078 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1079 const_iterator
1080 begin() const _GLIBCXX_NOEXCEPTnoexcept
1081 { return const_iterator(_M_data()); }
1082
1083 /**
1084 * Returns a read/write iterator that points one past the last
1085 * character in the %string.
1086 */
1087 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1088 iterator
1089 end() _GLIBCXX_NOEXCEPTnoexcept
1090 { return iterator(_M_data() + this->size()); }
1091
1092 /**
1093 * Returns a read-only (constant) iterator that points one past the
1094 * last character in the %string.
1095 */
1096 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1097 const_iterator
1098 end() const _GLIBCXX_NOEXCEPTnoexcept
1099 { return const_iterator(_M_data() + this->size()); }
1100
1101 /**
1102 * Returns a read/write reverse iterator that points to the last
1103 * character in the %string. Iteration is done in reverse element
1104 * order.
1105 */
1106 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1107 reverse_iterator
1108 rbegin() _GLIBCXX_NOEXCEPTnoexcept
1109 { return reverse_iterator(this->end()); }
1110
1111 /**
1112 * Returns a read-only (constant) reverse iterator that points
1113 * to the last character in the %string. Iteration is done in
1114 * reverse element order.
1115 */
1116 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1117 const_reverse_iterator
1118 rbegin() const _GLIBCXX_NOEXCEPTnoexcept
1119 { return const_reverse_iterator(this->end()); }
1120
1121 /**
1122 * Returns a read/write reverse iterator that points to one before the
1123 * first character in the %string. Iteration is done in reverse
1124 * element order.
1125 */
1126 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1127 reverse_iterator
1128 rend() _GLIBCXX_NOEXCEPTnoexcept
1129 { return reverse_iterator(this->begin()); }
1130
1131 /**
1132 * Returns a read-only (constant) reverse iterator that points
1133 * to one before the first character in the %string. Iteration
1134 * is done in reverse element order.
1135 */
1136 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1137 const_reverse_iterator
1138 rend() const _GLIBCXX_NOEXCEPTnoexcept
1139 { return const_reverse_iterator(this->begin()); }
1140
1141#if __cplusplus201703L >= 201103L
1142 /**
1143 * Returns a read-only (constant) iterator that points to the first
1144 * character in the %string.
1145 */
1146 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1147 const_iterator
1148 cbegin() const noexcept
1149 { return const_iterator(this->_M_data()); }
1150
1151 /**
1152 * Returns a read-only (constant) iterator that points one past the
1153 * last character in the %string.
1154 */
1155 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1156 const_iterator
1157 cend() const noexcept
1158 { return const_iterator(this->_M_data() + this->size()); }
1159
1160 /**
1161 * Returns a read-only (constant) reverse iterator that points
1162 * to the last character in the %string. Iteration is done in
1163 * reverse element order.
1164 */
1165 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1166 const_reverse_iterator
1167 crbegin() const noexcept
1168 { return const_reverse_iterator(this->end()); }
1169
1170 /**
1171 * Returns a read-only (constant) reverse iterator that points
1172 * to one before the first character in the %string. Iteration
1173 * is done in reverse element order.
1174 */
1175 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1176 const_reverse_iterator
1177 crend() const noexcept
1178 { return const_reverse_iterator(this->begin()); }
1179#endif
1180
1181 public:
1182 // Capacity:
1183 /// Returns the number of characters in the string, not including any
1184 /// null-termination.
1185 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1186 size_type
1187 size() const _GLIBCXX_NOEXCEPTnoexcept
1188 {
1189 size_type __sz = _M_string_length;
1190 if (__sz > max_size ())
1191 __builtin_unreachable();
1192 return __sz;
1193 }
1194
1195 /// Returns the number of characters in the string, not including any
1196 /// null-termination.
1197 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1198 size_type
1199 length() const _GLIBCXX_NOEXCEPTnoexcept
1200 { return size(); }
1201
1202 /// Returns the size() of the largest possible %string.
1203 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1204 size_type
1205 max_size() const _GLIBCXX_NOEXCEPTnoexcept
1206 {
1207 const size_t __diffmax
1208 = __gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(_CharT);
1209 const size_t __allocmax = _Alloc_traits::max_size(_M_get_allocator());
1210 return (std::min)(__diffmax, __allocmax) - 1;
1211 }
1212
1213 /**
1214 * @brief Resizes the %string to the specified number of characters.
1215 * @param __n Number of characters the %string should contain.
1216 * @param __c Character to fill any new elements.
1217 *
1218 * This function will %resize the %string to the specified
1219 * number of characters. If the number is smaller than the
1220 * %string's current size the %string is truncated, otherwise
1221 * the %string is extended and new elements are %set to @a __c.
1222 */
1223 _GLIBCXX20_CONSTEXPR
1224 void
1225 resize(size_type __n, _CharT __c);
1226
1227 /**
1228 * @brief Resizes the %string to the specified number of characters.
1229 * @param __n Number of characters the %string should contain.
1230 *
1231 * This function will resize the %string to the specified length. If
1232 * the new size is smaller than the %string's current size the %string
1233 * is truncated, otherwise the %string is extended and new characters
1234 * are default-constructed. For basic types such as char, this means
1235 * setting them to 0.
1236 */
1237 _GLIBCXX20_CONSTEXPR
1238 void
1239 resize(size_type __n)
1240 { this->resize(__n, _CharT()); }
1241
1242#if __cplusplus201703L >= 201103L
1243#pragma GCC diagnostic push
1244#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1245 /// A non-binding request to reduce capacity() to size().
1246 _GLIBCXX20_CONSTEXPR
1247 void
1248 shrink_to_fit() noexcept
1249 { reserve(); }
1250#pragma GCC diagnostic pop
1251#endif
1252
1253#ifdef __glibcxx_string_resize_and_overwrite // C++ >= 23
1254 /** Resize the string and call a function to fill it.
1255 *
1256 * @param __n The maximum size requested.
1257 * @param __op A callable object that writes characters to the string.
1258 *
1259 * This is a low-level function that is easy to misuse, be careful.
1260 *
1261 * Calling `str.resize_and_overwrite(n, op)` will reserve at least `n`
1262 * characters in `str`, evaluate `n2 = std::move(op)(str.data(), n)`,
1263 * and finally set the string length to `n2` (adding a null terminator
1264 * at the end). The function object `op` is allowed to write to the
1265 * extra capacity added by the initial reserve operation, which is not
1266 * allowed if you just call `str.reserve(n)` yourself.
1267 *
1268 * This can be used to efficiently fill a `string` buffer without the
1269 * overhead of zero-initializing characters that will be overwritten
1270 * anyway.
1271 *
1272 * The callable `op` must not access the string directly (only through
1273 * the pointer passed as its first argument), must not write more than
1274 * `n` characters to the string, must return a value no greater than `n`,
1275 * and must ensure that all characters up to the returned length are
1276 * valid after it returns (i.e. there must be no uninitialized values
1277 * left in the string after the call, because accessing them would
1278 * have undefined behaviour). If `op` exits by throwing an exception
1279 * the behaviour is undefined.
1280 *
1281 * @since C++23
1282 */
1283 template<typename _Operation>
1284 constexpr void
1285 resize_and_overwrite(size_type __n, _Operation __op);
1286#endif
1287
1288#if __cplusplus201703L >= 201103L
1289 /// Non-standard version of resize_and_overwrite for C++11 and above.
1290 template<typename _Operation>
1291 _GLIBCXX20_CONSTEXPR void
1292 __resize_and_overwrite(size_type __n, _Operation __op);
1293#endif
1294
1295 /**
1296 * Returns the total number of characters that the %string can hold
1297 * before needing to allocate more memory.
1298 */
1299 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1300 size_type
1301 capacity() const _GLIBCXX_NOEXCEPTnoexcept
1302 {
1303 size_t __sz = _M_is_local() ? size_type(_S_local_capacity)
1304 : _M_allocated_capacity;
1305 if (__sz < _S_local_capacity || __sz > max_size ())
1306 __builtin_unreachable();
1307 return __sz;
1308 }
1309
1310 /**
1311 * @brief Attempt to preallocate enough memory for specified number of
1312 * characters.
1313 * @param __res_arg Number of characters required.
1314 * @throw std::length_error If @a __res_arg exceeds @c max_size().
1315 *
1316 * This function attempts to reserve enough memory for the
1317 * %string to hold the specified number of characters. If the
1318 * number requested is more than max_size(), length_error is
1319 * thrown.
1320 *
1321 * The advantage of this function is that if optimal code is a
1322 * necessity and the user can determine the string length that will be
1323 * required, the user can reserve the memory in %advance, and thus
1324 * prevent a possible reallocation of memory and copying of %string
1325 * data.
1326 */
1327 _GLIBCXX20_CONSTEXPR
1328 void
1329 reserve(size_type __res_arg);
1330
1331 /**
1332 * Equivalent to shrink_to_fit().
1333 */
1334#if __cplusplus201703L >= 202002L
1335 [[deprecated("use shrink_to_fit() instead")]]
1336#endif
1337 _GLIBCXX20_CONSTEXPR
1338 void
1339 reserve();
1340
1341 /**
1342 * Erases the string, making it empty.
1343 */
1344 _GLIBCXX20_CONSTEXPR
1345 void
1346 clear() _GLIBCXX_NOEXCEPTnoexcept
1347 { _M_set_length(0); }
1348
1349 /**
1350 * Returns true if the %string is empty. Equivalent to
1351 * <code>*this == ""</code>.
1352 */
1353 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1354 bool
1355 empty() const _GLIBCXX_NOEXCEPTnoexcept
1356 { return _M_string_length == 0; }
1357
1358 // Element access:
1359 /**
1360 * @brief Subscript access to the data contained in the %string.
1361 * @param __pos The index of the character to access.
1362 * @return Read-only (constant) reference to the character.
1363 *
1364 * This operator allows for easy, array-style, data access.
1365 * Note that data access with this operator is unchecked and
1366 * out_of_range lookups are not defined. (For checked lookups
1367 * see at().)
1368 */
1369 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1370 const_reference
1371 operator[] (size_type __pos) const _GLIBCXX_NOEXCEPTnoexcept
1372 {
1373 __glibcxx_assert(__pos <= size())do { if (__builtin_expect(!bool(__pos <= size()), false)) std
::__glibcxx_assert_fail("/usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/bits/basic_string.h"
, 1373, __PRETTY_FUNCTION__, "__pos <= size()"); } while (
false)
;
1374 return _M_data()[__pos];
1375 }
1376
1377 /**
1378 * @brief Subscript access to the data contained in the %string.
1379 * @param __pos The index of the character to access.
1380 * @return Read/write reference to the character.
1381 *
1382 * This operator allows for easy, array-style, data access.
1383 * Note that data access with this operator is unchecked and
1384 * out_of_range lookups are not defined. (For checked lookups
1385 * see at().)
1386 */
1387 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1388 reference
1389 operator[](size_type __pos)
1390 {
1391 // Allow pos == size() both in C++98 mode, as v3 extension,
1392 // and in C++11 mode.
1393 __glibcxx_assert(__pos <= size())do { if (__builtin_expect(!bool(__pos <= size()), false)) std
::__glibcxx_assert_fail("/usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/bits/basic_string.h"
, 1393, __PRETTY_FUNCTION__, "__pos <= size()"); } while (
false)
;
1394 // In pedantic mode be strict in C++98 mode.
1395 _GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L || __pos < size());
1396 return _M_data()[__pos];
1397 }
1398
1399 /**
1400 * @brief Provides access to the data contained in the %string.
1401 * @param __n The index of the character to access.
1402 * @return Read-only (const) reference to the character.
1403 * @throw std::out_of_range If @a n is an invalid index.
1404 *
1405 * This function provides for safer data access. The parameter is
1406 * first checked that it is in the range of the string. The function
1407 * throws out_of_range if the check fails.
1408 */
1409 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1410 const_reference
1411 at(size_type __n) const
1412 {
1413 if (__n >= this->size())
1414 __throw_out_of_range_fmt(__N("basic_string::at: __n "("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
1415 "(which is %zu) >= this->size() "("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
1416 "(which is %zu)")("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
,
1417 __n, this->size());
1418 return _M_data()[__n];
1419 }
1420
1421 /**
1422 * @brief Provides access to the data contained in the %string.
1423 * @param __n The index of the character to access.
1424 * @return Read/write reference to the character.
1425 * @throw std::out_of_range If @a n is an invalid index.
1426 *
1427 * This function provides for safer data access. The parameter is
1428 * first checked that it is in the range of the string. The function
1429 * throws out_of_range if the check fails.
1430 */
1431 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1432 reference
1433 at(size_type __n)
1434 {
1435 if (__n >= size())
1436 __throw_out_of_range_fmt(__N("basic_string::at: __n "("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
1437 "(which is %zu) >= this->size() "("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
1438 "(which is %zu)")("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
,
1439 __n, this->size());
1440 return _M_data()[__n];
1441 }
1442
1443#if __cplusplus201703L >= 201103L
1444 /**
1445 * Returns a read/write reference to the data at the first
1446 * element of the %string.
1447 */
1448 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1449 reference
1450 front() noexcept
1451 {
1452 __glibcxx_assert(!empty())do { if (__builtin_expect(!bool(!empty()), false)) std::__glibcxx_assert_fail
("/usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/bits/basic_string.h"
, 1452, __PRETTY_FUNCTION__, "!empty()"); } while (false)
;
1453 return operator[](0);
1454 }
1455
1456 /**
1457 * Returns a read-only (constant) reference to the data at the first
1458 * element of the %string.
1459 */
1460 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1461 const_reference
1462 front() const noexcept
1463 {
1464 __glibcxx_assert(!empty())do { if (__builtin_expect(!bool(!empty()), false)) std::__glibcxx_assert_fail
("/usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/bits/basic_string.h"
, 1464, __PRETTY_FUNCTION__, "!empty()"); } while (false)
;
1465 return operator[](0);
1466 }
1467
1468 /**
1469 * Returns a read/write reference to the data at the last
1470 * element of the %string.
1471 */
1472 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1473 reference
1474 back() noexcept
1475 {
1476 __glibcxx_assert(!empty())do { if (__builtin_expect(!bool(!empty()), false)) std::__glibcxx_assert_fail
("/usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/bits/basic_string.h"
, 1476, __PRETTY_FUNCTION__, "!empty()"); } while (false)
;
1477 return operator[](this->size() - 1);
1478 }
1479
1480 /**
1481 * Returns a read-only (constant) reference to the data at the
1482 * last element of the %string.
1483 */
1484 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1485 const_reference
1486 back() const noexcept
1487 {
1488 __glibcxx_assert(!empty())do { if (__builtin_expect(!bool(!empty()), false)) std::__glibcxx_assert_fail
("/usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/bits/basic_string.h"
, 1488, __PRETTY_FUNCTION__, "!empty()"); } while (false)
;
1489 return operator[](this->size() - 1);
1490 }
1491#endif
1492
1493 // Modifiers:
1494 /**
1495 * @brief Append a string to this string.
1496 * @param __str The string to append.
1497 * @return Reference to this string.
1498 */
1499 _GLIBCXX20_CONSTEXPR
1500 basic_string&
1501 operator+=(const basic_string& __str)
1502 { return this->append(__str); }
1503
1504 /**
1505 * @brief Append a C string.
1506 * @param __s The C string to append.
1507 * @return Reference to this string.
1508 */
1509 _GLIBCXX20_CONSTEXPR
1510 basic_string&
1511 operator+=(const _CharT* __s)
1512 { return this->append(__s); }
1513
1514 /**
1515 * @brief Append a character.
1516 * @param __c The character to append.
1517 * @return Reference to this string.
1518 */
1519 _GLIBCXX20_CONSTEXPR
1520 basic_string&
1521 operator+=(_CharT __c)
1522 {
1523 this->push_back(__c);
1524 return *this;
1525 }
1526
1527#if __cplusplus201703L >= 201103L
1528 /**
1529 * @brief Append an initializer_list of characters.
1530 * @param __l The initializer_list of characters to be appended.
1531 * @return Reference to this string.
1532 */
1533 _GLIBCXX20_CONSTEXPR
1534 basic_string&
1535 operator+=(initializer_list<_CharT> __l)
1536 { return this->append(__l.begin(), __l.size()); }
1537#endif // C++11
1538
1539#ifdef __glibcxx_string_view201803L // >= C++17
1540 /**
1541 * @brief Append a string_view.
1542 * @param __svt An object convertible to string_view to be appended.
1543 * @return Reference to this string.
1544 */
1545 template<typename _Tp>
1546 _GLIBCXX20_CONSTEXPR
1547 _If_sv<_Tp, basic_string&>
1548 operator+=(const _Tp& __svt)
1549 { return this->append(__svt); }
1550#endif // C++17
1551
1552 /**
1553 * @brief Append a string to this string.
1554 * @param __str The string to append.
1555 * @return Reference to this string.
1556 */
1557 _GLIBCXX20_CONSTEXPR
1558 basic_string&
1559 append(const basic_string& __str)
1560 { return this->append(__str._M_data(), __str.size()); }
1561
1562 /**
1563 * @brief Append a substring.
1564 * @param __str The string to append.
1565 * @param __pos Index of the first character of str to append.
1566 * @param __n The number of characters to append.
1567 * @return Reference to this string.
1568 * @throw std::out_of_range if @a __pos is not a valid index.
1569 *
1570 * This function appends @a __n characters from @a __str
1571 * starting at @a __pos to this string. If @a __n is is larger
1572 * than the number of available characters in @a __str, the
1573 * remainder of @a __str is appended.
1574 */
1575 _GLIBCXX20_CONSTEXPR
1576 basic_string&
1577 append(const basic_string& __str, size_type __pos, size_type __n = npos)
1578 { return this->append(__str._M_data()
1579 + __str._M_check(__pos, "basic_string::append"),
1580 __str._M_limit(__pos, __n)); }
1581
1582 /**
1583 * @brief Append a C substring.
1584 * @param __s The C string to append.
1585 * @param __n The number of characters to append.
1586 * @return Reference to this string.
1587 */
1588 _GLIBCXX20_CONSTEXPR
1589 basic_string&
1590 append(const _CharT* __s, size_type __n)
1591 {
1592 __glibcxx_requires_string_len(__s, __n);
1593 _M_check_length(size_type(0), __n, "basic_string::append");
1594 return _M_append(__s, __n);
1595 }
1596
1597 /**
1598 * @brief Append a C string.
1599 * @param __s The C string to append.
1600 * @return Reference to this string.
1601 */
1602 _GLIBCXX20_CONSTEXPR
1603 basic_string&
1604 append(const _CharT* __s)
1605 {
1606 __glibcxx_requires_string(__s);
1607 const size_type __n = traits_type::length(__s);
1608 _M_check_length(size_type(0), __n, "basic_string::append");
1609 return _M_append(__s, __n);
1610 }
1611
1612 /**
1613 * @brief Append multiple characters.
1614 * @param __n The number of characters to append.
1615 * @param __c The character to use.
1616 * @return Reference to this string.
1617 *
1618 * Appends __n copies of __c to this string.
1619 */
1620 _GLIBCXX20_CONSTEXPR
1621 basic_string&
1622 append(size_type __n, _CharT __c)
1623 { return _M_replace_aux(this->size(), size_type(0), __n, __c); }
1624
1625#if __glibcxx_containers_ranges // C++ >= 23
1626 /**
1627 * @brief Append a range to the string.
1628 * @param __rg A range of values that are convertible to `value_type`.
1629 * @since C++23
1630 *
1631 * The range `__rg` is allowed to overlap with `*this`.
1632 */
1633 template<__detail::__container_compatible_range<_CharT> _Rg>
1634 constexpr basic_string&
1635 append_range(_Rg&& __rg)
1636 {
1637 // N.B. __rg may overlap with *this, so we must copy from __rg before
1638 // existing elements or iterators referring to *this are invalidated.
1639 // e.g. in s.append_range(views::concat(s, str)), rg overlaps s.
1640 if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>)
1641 {
1642 const auto __len = size_type(ranges::distance(__rg));
1643
1644 // Don't care if this addition wraps around, we check it below:
1645 const size_type __newlen = size() + __len;
1646
1647 if ((capacity() - size()) >= __len)
1648 _S_copy_range(_M_data() + size(), std::forward<_Rg>(__rg),
1649 __len);
1650 else
1651 {
1652 _M_check_length(0, __len, "basic_string::append_range");
1653 basic_string __s(_M_get_allocator());
1654 __s.reserve(__newlen);
1655 _S_copy_range(__s._M_data() + size(), std::forward<_Rg>(__rg),
1656 __len);
1657 _S_copy(__s._M_data(), _M_data(), size());
1658 if (!_M_is_local())
1659 _M_destroy(_M_allocated_capacity);
1660 _M_data(__s._M_data());
1661 _M_capacity(__s._M_allocated_capacity);
1662 __s._M_data(__s._M_local_data());
1663 __s._M_length(0);
1664 }
1665 _M_set_length(__newlen); // adds null-terminator
1666 }
1667 else
1668 {
1669 basic_string __s(from_range, std::forward<_Rg>(__rg),
1670 _M_get_allocator());
1671 append(__s);
1672 }
1673 return *this;
1674 }
1675#endif
1676
1677#if __cplusplus201703L >= 201103L
1678 /**
1679 * @brief Append an initializer_list of characters.
1680 * @param __l The initializer_list of characters to append.
1681 * @return Reference to this string.
1682 */
1683 _GLIBCXX20_CONSTEXPR
1684 basic_string&
1685 append(initializer_list<_CharT> __l)
1686 { return this->append(__l.begin(), __l.size()); }
1687#endif // C++11
1688
1689 /**
1690 * @brief Append a range of characters.
1691 * @param __first Iterator referencing the first character to append.
1692 * @param __last Iterator marking the end of the range.
1693 * @return Reference to this string.
1694 *
1695 * Appends characters in the range [__first,__last) to this string.
1696 */
1697#if __cplusplus201703L >= 201103L
1698 template<class _InputIterator,
1699 typename = std::_RequireInputIter<_InputIterator>>
1700 _GLIBCXX20_CONSTEXPR
1701#else
1702 template<class _InputIterator>
1703#endif
1704 basic_string&
1705 append(_InputIterator __first, _InputIterator __last)
1706 { return this->replace(end(), end(), __first, __last); }
1707
1708#ifdef __glibcxx_string_view201803L
1709 /**
1710 * @brief Append a string_view.
1711 * @param __svt An object convertible to string_view to be appended.
1712 * @return Reference to this string.
1713 */
1714 template<typename _Tp>
1715 _GLIBCXX20_CONSTEXPR
1716 _If_sv<_Tp, basic_string&>
1717 append(const _Tp& __svt)
1718 {
1719 __sv_type __sv = __svt;
1720 return this->append(__sv.data(), __sv.size());
1721 }
1722
1723 /**
1724 * @brief Append a range of characters from a string_view.
1725 * @param __svt An object convertible to string_view to be appended from.
1726 * @param __pos The position in the string_view to append from.
1727 * @param __n The number of characters to append from the string_view.
1728 * @return Reference to this string.
1729 */
1730 template<typename _Tp>
1731 _GLIBCXX20_CONSTEXPR
1732 _If_sv<_Tp, basic_string&>
1733 append(const _Tp& __svt, size_type __pos, size_type __n = npos)
1734 {
1735 __sv_type __sv = __svt;
1736 return _M_append(__sv.data()
1737 + std::__sv_check(__sv.size(), __pos, "basic_string::append"),
1738 std::__sv_limit(__sv.size(), __pos, __n));
1739 }
1740#endif // C++17
1741
1742 /**
1743 * @brief Append a single character.
1744 * @param __c Character to append.
1745 */
1746 _GLIBCXX20_CONSTEXPR
1747 void
1748 push_back(_CharT __c)
1749 {
1750 const size_type __size = this->size();
1751 if (__size + 1 > this->capacity())
1752 this->_M_mutate(__size, size_type(0), 0, size_type(1));
1753 traits_type::assign(this->_M_data()[__size], __c);
1754 this->_M_set_length(__size + 1);
1755 }
1756
1757 /**
1758 * @brief Set value to contents of another string.
1759 * @param __str Source string to use.
1760 * @return Reference to this string.
1761 */
1762 _GLIBCXX20_CONSTEXPR
1763 basic_string&
1764 assign(const basic_string& __str)
1765 {
1766#if __cplusplus201703L >= 201103L
1767 if (_Alloc_traits::_S_propagate_on_copy_assign())
1768 {
1769 if (!_Alloc_traits::_S_always_equal() && !_M_is_local()
1770 && _M_get_allocator() != __str._M_get_allocator())
1771 {
1772 // Propagating allocator cannot free existing storage so must
1773 // deallocate it before replacing current allocator.
1774 if (__str.size() <= _S_local_capacity)
1775 {
1776 _M_destroy(_M_allocated_capacity);
1777 _M_data(_M_use_local_data());
1778 _M_set_length(0);
1779 }
1780 else
1781 {
1782 const auto __len = __str.size();
1783 auto __alloc = __str._M_get_allocator();
1784 // If this allocation throws there are no effects:
1785 auto __ptr = _S_allocate(__alloc, __len + 1);
1786 _M_destroy(_M_allocated_capacity);
1787 _M_data(__ptr);
1788 _M_capacity(__len);
1789 _M_set_length(__len);
1790 }
1791 }
1792 std::__alloc_on_copy(_M_get_allocator(), __str._M_get_allocator());
1793 }
1794#endif
1795 this->_M_assign(__str);
1796 return *this;
1797 }
1798
1799#if __cplusplus201703L >= 201103L
1800 /**
1801 * @brief Set value to contents of another string.
1802 * @param __str Source string to use.
1803 * @return Reference to this string.
1804 *
1805 * This function sets this string to the exact contents of @a __str.
1806 * @a __str is a valid, but unspecified string.
1807 */
1808 _GLIBCXX20_CONSTEXPR
1809 basic_string&
1810 assign(basic_string&& __str)
1811 noexcept(_Alloc_traits::_S_nothrow_move())
1812 {
1813 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1814 // 2063. Contradictory requirements for string move assignment
1815 return *this = std::move(__str);
1816 }
1817#endif // C++11
1818
1819 /**
1820 * @brief Set value to a substring of a string.
1821 * @param __str The string to use.
1822 * @param __pos Index of the first character of str.
1823 * @param __n Number of characters to use.
1824 * @return Reference to this string.
1825 * @throw std::out_of_range if @a pos is not a valid index.
1826 *
1827 * This function sets this string to the substring of @a __str
1828 * consisting of @a __n characters at @a __pos. If @a __n is
1829 * is larger than the number of available characters in @a
1830 * __str, the remainder of @a __str is used.
1831 */
1832 _GLIBCXX20_CONSTEXPR
1833 basic_string&
1834 assign(const basic_string& __str, size_type __pos, size_type __n = npos)
1835 { return _M_replace(size_type(0), this->size(), __str._M_data()
1836 + __str._M_check(__pos, "basic_string::assign"),
1837 __str._M_limit(__pos, __n)); }
1838
1839 /**
1840 * @brief Set value to a C substring.
1841 * @param __s The C string to use.
1842 * @param __n Number of characters to use.
1843 * @return Reference to this string.
1844 *
1845 * This function sets the value of this string to the first @a __n
1846 * characters of @a __s. If @a __n is is larger than the number of
1847 * available characters in @a __s, the remainder of @a __s is used.
1848 */
1849 _GLIBCXX20_CONSTEXPR
1850 basic_string&
1851 assign(const _CharT* __s, size_type __n)
1852 {
1853 __glibcxx_requires_string_len(__s, __n);
1854 return _M_replace(size_type(0), this->size(), __s, __n);
1855 }
1856
1857 /**
1858 * @brief Set value to contents of a C string.
1859 * @param __s The C string to use.
1860 * @return Reference to this string.
1861 *
1862 * This function sets the value of this string to the value of @a __s.
1863 * The data is copied, so there is no dependence on @a __s once the
1864 * function returns.
1865 */
1866 _GLIBCXX20_CONSTEXPR
1867 basic_string&
1868 assign(const _CharT* __s)
1869 {
1870 __glibcxx_requires_string(__s);
1871 return _M_replace(size_type(0), this->size(), __s,
1872 traits_type::length(__s));
1873 }
1874
1875 /**
1876 * @brief Set value to multiple characters.
1877 * @param __n Length of the resulting string.
1878 * @param __c The character to use.
1879 * @return Reference to this string.
1880 *
1881 * This function sets the value of this string to @a __n copies of
1882 * character @a __c.
1883 */
1884 _GLIBCXX20_CONSTEXPR
1885 basic_string&
1886 assign(size_type __n, _CharT __c)
1887 { return _M_replace_aux(size_type(0), this->size(), __n, __c); }
1888
1889 /**
1890 * @brief Set value to a range of characters.
1891 * @param __first Iterator referencing the first character to append.
1892 * @param __last Iterator marking the end of the range.
1893 * @return Reference to this string.
1894 *
1895 * Sets value of string to characters in the range [__first,__last).
1896 */
1897#if __cplusplus201703L >= 201103L
1898#pragma GCC diagnostic push
1899#pragma GCC diagnostic ignored "-Wc++17-extensions"
1900 template<class _InputIterator,
1901 typename = std::_RequireInputIter<_InputIterator>>
1902 _GLIBCXX20_CONSTEXPR
1903 basic_string&
1904 assign(_InputIterator __first, _InputIterator __last)
1905 {
1906 using _IterTraits = iterator_traits<_InputIterator>;
1907 if constexpr (is_pointer<decltype(std::__niter_base(__first))>::value
1908 && is_same<typename _IterTraits::value_type,
1909 _CharT>::value)
1910 {
1911 __glibcxx_requires_valid_range(__first, __last);
1912 return _M_replace(size_type(0), size(),
1913 std::__niter_base(__first), __last - __first);
1914 }
1915#if __cplusplus201703L >= 202002L
1916 else if constexpr (contiguous_iterator<_InputIterator>
1917 && is_same_v<iter_value_t<_InputIterator>,
1918 _CharT>)
1919 {
1920 __glibcxx_requires_valid_range(__first, __last);
1921 return _M_replace(size_type(0), size(),
1922 std::to_address(__first), __last - __first);
1923 }
1924#endif
1925 else
1926 return *this = basic_string(__first, __last, get_allocator());
1927 }
1928#pragma GCC diagnostic pop
1929#else
1930 template<class _InputIterator>
1931 basic_string&
1932 assign(_InputIterator __first, _InputIterator __last)
1933 { return this->replace(begin(), end(), __first, __last); }
1934#endif
1935
1936#if __glibcxx_containers_ranges // C++ >= 23
1937 /**
1938 * @brief Assign a range to the string.
1939 * @param __rg A range of values that are convertible to `value_type`.
1940 * @since C++23
1941 *
1942 * The range `__rg` is allowed to overlap with `*this`.
1943 */
1944 template<__detail::__container_compatible_range<_CharT> _Rg>
1945 constexpr basic_string&
1946 assign_range(_Rg&& __rg)
1947 {
1948 basic_string __s(from_range, std::forward<_Rg>(__rg),
1949 _M_get_allocator());
1950 assign(std::move(__s));
1951 return *this;
1952 }
1953#endif
1954
1955#if __cplusplus201703L >= 201103L
1956 /**
1957 * @brief Set value to an initializer_list of characters.
1958 * @param __l The initializer_list of characters to assign.
1959 * @return Reference to this string.
1960 */
1961 _GLIBCXX20_CONSTEXPR
1962 basic_string&
1963 assign(initializer_list<_CharT> __l)
1964 {
1965 // The initializer_list array cannot alias the characters in *this
1966 // so we don't need to use replace to that case.
1967 const size_type __n = __l.size();
1968 if (__n > capacity())
1969 *this = basic_string(__l.begin(), __l.end(), get_allocator());
1970 else
1971 {
1972 if (__n)
1973 _S_copy(_M_data(), __l.begin(), __n);
1974 _M_set_length(__n);
1975 }
1976 return *this;
1977 }
1978#endif // C++11
1979
1980#ifdef __glibcxx_string_view201803L // >= C++17
1981 /**
1982 * @brief Set value from a string_view.
1983 * @param __svt The source object convertible to string_view.
1984 * @return Reference to this string.
1985 */
1986 template<typename _Tp>
1987 _GLIBCXX20_CONSTEXPR
1988 _If_sv<_Tp, basic_string&>
1989 assign(const _Tp& __svt)
1990 {
1991 __sv_type __sv = __svt;
1992 return this->assign(__sv.data(), __sv.size());
1993 }
1994
1995 /**
1996 * @brief Set value from a range of characters in a string_view.
1997 * @param __svt The source object convertible to string_view.
1998 * @param __pos The position in the string_view to assign from.
1999 * @param __n The number of characters to assign.
2000 * @return Reference to this string.
2001 */
2002 template<typename _Tp>
2003 _GLIBCXX20_CONSTEXPR
2004 _If_sv<_Tp, basic_string&>
2005 assign(const _Tp& __svt, size_type __pos, size_type __n = npos)
2006 {
2007 __sv_type __sv = __svt;
2008 return _M_replace(size_type(0), this->size(),
2009 __sv.data()
2010 + std::__sv_check(__sv.size(), __pos, "basic_string::assign"),
2011 std::__sv_limit(__sv.size(), __pos, __n));
2012 }
2013#endif // C++17
2014
2015#if __cplusplus201703L >= 201103L
2016 /**
2017 * @brief Insert multiple characters.
2018 * @param __p Const_iterator referencing location in string to
2019 * insert at.
2020 * @param __n Number of characters to insert
2021 * @param __c The character to insert.
2022 * @return Iterator referencing the first inserted char.
2023 * @throw std::length_error If new length exceeds @c max_size().
2024 *
2025 * Inserts @a __n copies of character @a __c starting at the
2026 * position referenced by iterator @a __p. If adding
2027 * characters causes the length to exceed max_size(),
2028 * length_error is thrown. The value of the string doesn't
2029 * change if an error is thrown.
2030 */
2031 _GLIBCXX20_CONSTEXPR
2032 iterator
2033 insert(const_iterator __p, size_type __n, _CharT __c)
2034 {
2035 _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
2036 const size_type __pos = __p - begin();
2037 this->replace(__p, __p, __n, __c);
2038 return iterator(this->_M_data() + __pos);
2039 }
2040#else
2041 /**
2042 * @brief Insert multiple characters.
2043 * @param __p Iterator referencing location in string to insert at.
2044 * @param __n Number of characters to insert
2045 * @param __c The character to insert.
2046 * @throw std::length_error If new length exceeds @c max_size().
2047 *
2048 * Inserts @a __n copies of character @a __c starting at the
2049 * position referenced by iterator @a __p. If adding
2050 * characters causes the length to exceed max_size(),
2051 * length_error is thrown. The value of the string doesn't
2052 * change if an error is thrown.
2053 */
2054 void
2055 insert(iterator __p, size_type __n, _CharT __c)
2056 { this->replace(__p, __p, __n, __c); }
2057#endif
2058
2059#if __cplusplus201703L >= 201103L
2060 /**
2061 * @brief Insert a range of characters.
2062 * @param __p Const_iterator referencing location in string to
2063 * insert at.
2064 * @param __beg Start of range.
2065 * @param __end End of range.
2066 * @return Iterator referencing the first inserted char.
2067 * @throw std::length_error If new length exceeds @c max_size().
2068 *
2069 * Inserts characters in range [beg,end). If adding characters
2070 * causes the length to exceed max_size(), length_error is
2071 * thrown. The value of the string doesn't change if an error
2072 * is thrown.
2073 */
2074 template<class _InputIterator,
2075 typename = std::_RequireInputIter<_InputIterator>>
2076 _GLIBCXX20_CONSTEXPR
2077 iterator
2078 insert(const_iterator __p, _InputIterator __beg, _InputIterator __end)
2079 {
2080 _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
2081 const size_type __pos = __p - begin();
2082 this->replace(__p, __p, __beg, __end);
2083 return iterator(this->_M_data() + __pos);
2084 }
2085#else
2086 /**
2087 * @brief Insert a range of characters.
2088 * @param __p Iterator referencing location in string to insert at.
2089 * @param __beg Start of range.
2090 * @param __end End of range.
2091 * @throw std::length_error If new length exceeds @c max_size().
2092 *
2093 * Inserts characters in range [__beg,__end). If adding
2094 * characters causes the length to exceed max_size(),
2095 * length_error is thrown. The value of the string doesn't
2096 * change if an error is thrown.
2097 */
2098 template<class _InputIterator>
2099 void
2100 insert(iterator __p, _InputIterator __beg, _InputIterator __end)
2101 { this->replace(__p, __p, __beg, __end); }
2102#endif
2103
2104#if __glibcxx_containers_ranges // C++ >= 23
2105 /**
2106 * @brief Insert a range into the string.
2107 * @param __rg A range of values that are convertible to `value_type`.
2108 * @since C++23
2109 *
2110 * The range `__rg` is allowed to overlap with `*this`.
2111 */
2112 template<__detail::__container_compatible_range<_CharT> _Rg>
2113 constexpr iterator
2114 insert_range(const_iterator __p, _Rg&& __rg)
2115 {
2116 auto __pos = __p - cbegin();
2117
2118 if constexpr (ranges::forward_range<_Rg>)
2119 if (ranges::empty(__rg))
2120 return begin() + __pos;
2121
2122
2123 if (__p == cend())
2124 append_range(std::forward<_Rg>(__rg));
2125 else
2126 {
2127 basic_string __s(from_range, std::forward<_Rg>(__rg),
2128 _M_get_allocator());
2129 insert(__pos, __s);
2130 }
2131 return begin() + __pos;
2132 }
2133#endif
2134
2135#if __cplusplus201703L >= 201103L
2136 /**
2137 * @brief Insert an initializer_list of characters.
2138 * @param __p Iterator referencing location in string to insert at.
2139 * @param __l The initializer_list of characters to insert.
2140 * @throw std::length_error If new length exceeds @c max_size().
2141 */
2142 _GLIBCXX20_CONSTEXPR
2143 iterator
2144 insert(const_iterator __p, initializer_list<_CharT> __l)
2145 { return this->insert(__p, __l.begin(), __l.end()); }
2146
2147#ifdef _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
2148 // See PR libstdc++/83328
2149 void
2150 insert(iterator __p, initializer_list<_CharT> __l)
2151 {
2152 _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
2153 this->insert(__p - begin(), __l.begin(), __l.size());
2154 }
2155#endif
2156#endif // C++11
2157
2158 /**
2159 * @brief Insert value of a string.
2160 * @param __pos1 Position in string to insert at.
2161 * @param __str The string to insert.
2162 * @return Reference to this string.
2163 * @throw std::length_error If new length exceeds @c max_size().
2164 *
2165 * Inserts value of @a __str starting at @a __pos1. If adding
2166 * characters causes the length to exceed max_size(),
2167 * length_error is thrown. The value of the string doesn't
2168 * change if an error is thrown.
2169 */
2170 _GLIBCXX20_CONSTEXPR
2171 basic_string&
2172 insert(size_type __pos1, const basic_string& __str)
2173 { return this->replace(__pos1, size_type(0),
2174 __str._M_data(), __str.size()); }
2175
2176 /**
2177 * @brief Insert a substring.
2178 * @param __pos1 Position in string to insert at.
2179 * @param __str The string to insert.
2180 * @param __pos2 Start of characters in str to insert.
2181 * @param __n Number of characters to insert.
2182 * @return Reference to this string.
2183 * @throw std::length_error If new length exceeds @c max_size().
2184 * @throw std::out_of_range If @a pos1 > size() or
2185 * @a __pos2 > @a str.size().
2186 *
2187 * Starting at @a pos1, insert @a __n character of @a __str
2188 * beginning with @a __pos2. If adding characters causes the
2189 * length to exceed max_size(), length_error is thrown. If @a
2190 * __pos1 is beyond the end of this string or @a __pos2 is
2191 * beyond the end of @a __str, out_of_range is thrown. The
2192 * value of the string doesn't change if an error is thrown.
2193 */
2194 _GLIBCXX20_CONSTEXPR
2195 basic_string&
2196 insert(size_type __pos1, const basic_string& __str,
2197 size_type __pos2, size_type __n = npos)
2198 { return this->replace(__pos1, size_type(0), __str._M_data()
2199 + __str._M_check(__pos2, "basic_string::insert"),
2200 __str._M_limit(__pos2, __n)); }
2201
2202 /**
2203 * @brief Insert a C substring.
2204 * @param __pos Position in string to insert at.
2205 * @param __s The C string to insert.
2206 * @param __n The number of characters to insert.
2207 * @return Reference to this string.
2208 * @throw std::length_error If new length exceeds @c max_size().
2209 * @throw std::out_of_range If @a __pos is beyond the end of this
2210 * string.
2211 *
2212 * Inserts the first @a __n characters of @a __s starting at @a
2213 * __pos. If adding characters causes the length to exceed
2214 * max_size(), length_error is thrown. If @a __pos is beyond
2215 * end(), out_of_range is thrown. The value of the string
2216 * doesn't change if an error is thrown.
2217 */
2218 _GLIBCXX20_CONSTEXPR
2219 basic_string&
2220 insert(size_type __pos, const _CharT* __s, size_type __n)
2221 { return this->replace(__pos, size_type(0), __s, __n); }
2222
2223 /**
2224 * @brief Insert a C string.
2225 * @param __pos Position in string to insert at.
2226 * @param __s The C string to insert.
2227 * @return Reference to this string.
2228 * @throw std::length_error If new length exceeds @c max_size().
2229 * @throw std::out_of_range If @a pos is beyond the end of this
2230 * string.
2231 *
2232 * Inserts the first @a n characters of @a __s starting at @a __pos. If
2233 * adding characters causes the length to exceed max_size(),
2234 * length_error is thrown. If @a __pos is beyond end(), out_of_range is
2235 * thrown. The value of the string doesn't change if an error is
2236 * thrown.
2237 */
2238 _GLIBCXX20_CONSTEXPR
2239 basic_string&
2240 insert(size_type __pos, const _CharT* __s)
2241 {
2242 __glibcxx_requires_string(__s);
2243 return this->replace(__pos, size_type(0), __s,
2244 traits_type::length(__s));
2245 }
2246
2247 /**
2248 * @brief Insert multiple characters.
2249 * @param __pos Index in string to insert at.
2250 * @param __n Number of characters to insert
2251 * @param __c The character to insert.
2252 * @return Reference to this string.
2253 * @throw std::length_error If new length exceeds @c max_size().
2254 * @throw std::out_of_range If @a __pos is beyond the end of this
2255 * string.
2256 *
2257 * Inserts @a __n copies of character @a __c starting at index
2258 * @a __pos. If adding characters causes the length to exceed
2259 * max_size(), length_error is thrown. If @a __pos > length(),
2260 * out_of_range is thrown. The value of the string doesn't
2261 * change if an error is thrown.
2262 */
2263 _GLIBCXX20_CONSTEXPR
2264 basic_string&
2265 insert(size_type __pos, size_type __n, _CharT __c)
2266 { return _M_replace_aux(_M_check(__pos, "basic_string::insert"),
2267 size_type(0), __n, __c); }
2268
2269 /**
2270 * @brief Insert one character.
2271 * @param __p Iterator referencing position in string to insert at.
2272 * @param __c The character to insert.
2273 * @return Iterator referencing newly inserted char.
2274 * @throw std::length_error If new length exceeds @c max_size().
2275 *
2276 * Inserts character @a __c at position referenced by @a __p.
2277 * If adding character causes the length to exceed max_size(),
2278 * length_error is thrown. If @a __p is beyond end of string,
2279 * out_of_range is thrown. The value of the string doesn't
2280 * change if an error is thrown.
2281 */
2282 _GLIBCXX20_CONSTEXPR
2283 iterator
2284 insert(__const_iterator __p, _CharT __c)
2285 {
2286 _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
2287 const size_type __pos = __p - begin();
2288 _M_replace_aux(__pos, size_type(0), size_type(1), __c);
2289 return iterator(_M_data() + __pos);
2290 }
2291
2292#ifdef __glibcxx_string_view201803L // >= C++17
2293 /**
2294 * @brief Insert a string_view.
2295 * @param __pos Position in string to insert at.
2296 * @param __svt The object convertible to string_view to insert.
2297 * @return Reference to this string.
2298 */
2299 template<typename _Tp>
2300 _GLIBCXX20_CONSTEXPR
2301 _If_sv<_Tp, basic_string&>
2302 insert(size_type __pos, const _Tp& __svt)
2303 {
2304 __sv_type __sv = __svt;
2305 return this->insert(__pos, __sv.data(), __sv.size());
2306 }
2307
2308 /**
2309 * @brief Insert a string_view.
2310 * @param __pos1 Position in string to insert at.
2311 * @param __svt The object convertible to string_view to insert from.
2312 * @param __pos2 Start of characters in str to insert.
2313 * @param __n The number of characters to insert.
2314 * @return Reference to this string.
2315 */
2316 template<typename _Tp>
2317 _GLIBCXX20_CONSTEXPR
2318 _If_sv<_Tp, basic_string&>
2319 insert(size_type __pos1, const _Tp& __svt,
2320 size_type __pos2, size_type __n = npos)
2321 {
2322 __sv_type __sv = __svt;
2323 return this->replace(__pos1, size_type(0),
2324 __sv.data()
2325 + std::__sv_check(__sv.size(), __pos2, "basic_string::insert"),
2326 std::__sv_limit(__sv.size(), __pos2, __n));
2327 }
2328#endif // C++17
2329
2330 /**
2331 * @brief Remove characters.
2332 * @param __pos Index of first character to remove (default 0).
2333 * @param __n Number of characters to remove (default remainder).
2334 * @return Reference to this string.
2335 * @throw std::out_of_range If @a pos is beyond the end of this
2336 * string.
2337 *
2338 * Removes @a __n characters from this string starting at @a
2339 * __pos. The length of the string is reduced by @a __n. If
2340 * there are < @a __n characters to remove, the remainder of
2341 * the string is truncated. If @a __p is beyond end of string,
2342 * out_of_range is thrown. The value of the string doesn't
2343 * change if an error is thrown.
2344 */
2345 _GLIBCXX20_CONSTEXPR
2346 basic_string&
2347 erase(size_type __pos = 0, size_type __n = npos)
2348 {
2349 _M_check(__pos, "basic_string::erase");
2350 if (__n == npos)
2351 this->_M_set_length(__pos);
2352 else if (__n != 0)
2353 this->_M_erase(__pos, _M_limit(__pos, __n));
2354 return *this;
2355 }
2356
2357 /**
2358 * @brief Remove one character.
2359 * @param __position Iterator referencing the character to remove.
2360 * @return iterator referencing same location after removal.
2361 *
2362 * Removes the character at @a __position from this string. The value
2363 * of the string doesn't change if an error is thrown.
2364 */
2365 _GLIBCXX20_CONSTEXPR
2366 iterator
2367 erase(__const_iterator __position)
2368 {
2369 _GLIBCXX_DEBUG_PEDASSERT(__position >= begin()
2370 && __position < end());
2371 const size_type __pos = __position - begin();
2372 this->_M_erase(__pos, size_type(1));
2373 return iterator(_M_data() + __pos);
2374 }
2375
2376 /**
2377 * @brief Remove a range of characters.
2378 * @param __first Iterator referencing the first character to remove.
2379 * @param __last Iterator referencing the end of the range.
2380 * @return Iterator referencing location of first after removal.
2381 *
2382 * Removes the characters in the range [first,last) from this string.
2383 * The value of the string doesn't change if an error is thrown.
2384 */
2385 _GLIBCXX20_CONSTEXPR
2386 iterator
2387 erase(__const_iterator __first, __const_iterator __last)
2388 {
2389 _GLIBCXX_DEBUG_PEDASSERT(__first >= begin() && __first <= __last
2390 && __last <= end());
2391 const size_type __pos = __first - begin();
2392 if (__last == end())
2393 this->_M_set_length(__pos);
2394 else
2395 this->_M_erase(__pos, __last - __first);
2396 return iterator(this->_M_data() + __pos);
2397 }
2398
2399#if __cplusplus201703L >= 201103L
2400 /**
2401 * @brief Remove the last character.
2402 *
2403 * The string must be non-empty.
2404 */
2405 _GLIBCXX20_CONSTEXPR
2406 void
2407 pop_back() noexcept
2408 {
2409 __glibcxx_assert(!empty())do { if (__builtin_expect(!bool(!empty()), false)) std::__glibcxx_assert_fail
("/usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/bits/basic_string.h"
, 2409, __PRETTY_FUNCTION__, "!empty()"); } while (false)
;
2410 _M_erase(size() - 1, 1);
2411 }
2412#endif // C++11
2413
2414 /**
2415 * @brief Replace characters with value from another string.
2416 * @param __pos Index of first character to replace.
2417 * @param __n Number of characters to be replaced.
2418 * @param __str String to insert.
2419 * @return Reference to this string.
2420 * @throw std::out_of_range If @a pos is beyond the end of this
2421 * string.
2422 * @throw std::length_error If new length exceeds @c max_size().
2423 *
2424 * Removes the characters in the range [__pos,__pos+__n) from
2425 * this string. In place, the value of @a __str is inserted.
2426 * If @a __pos is beyond end of string, out_of_range is thrown.
2427 * If the length of the result exceeds max_size(), length_error
2428 * is thrown. The value of the string doesn't change if an
2429 * error is thrown.
2430 */
2431 _GLIBCXX20_CONSTEXPR
2432 basic_string&
2433 replace(size_type __pos, size_type __n, const basic_string& __str)
2434 { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
2435
2436 /**
2437 * @brief Replace characters with value from another string.
2438 * @param __pos1 Index of first character to replace.
2439 * @param __n1 Number of characters to be replaced.
2440 * @param __str String to insert.
2441 * @param __pos2 Index of first character of str to use.
2442 * @param __n2 Number of characters from str to use.
2443 * @return Reference to this string.
2444 * @throw std::out_of_range If @a __pos1 > size() or @a __pos2 >
2445 * __str.size().
2446 * @throw std::length_error If new length exceeds @c max_size().
2447 *
2448 * Removes the characters in the range [__pos1,__pos1 + n) from this
2449 * string. In place, the value of @a __str is inserted. If @a __pos is
2450 * beyond end of string, out_of_range is thrown. If the length of the
2451 * result exceeds max_size(), length_error is thrown. The value of the
2452 * string doesn't change if an error is thrown.
2453 */
2454 _GLIBCXX20_CONSTEXPR
2455 basic_string&
2456 replace(size_type __pos1, size_type __n1, const basic_string& __str,
2457 size_type __pos2, size_type __n2 = npos)
2458 { return this->replace(__pos1, __n1, __str._M_data()
2459 + __str._M_check(__pos2, "basic_string::replace"),
2460 __str._M_limit(__pos2, __n2)); }
2461
2462 /**
2463 * @brief Replace characters with value of a C substring.
2464 * @param __pos Index of first character to replace.
2465 * @param __n1 Number of characters to be replaced.
2466 * @param __s C string to insert.
2467 * @param __n2 Number of characters from @a s to use.
2468 * @return Reference to this string.
2469 * @throw std::out_of_range If @a pos1 > size().
2470 * @throw std::length_error If new length exceeds @c max_size().
2471 *
2472 * Removes the characters in the range [__pos,__pos + __n1)
2473 * from this string. In place, the first @a __n2 characters of
2474 * @a __s are inserted, or all of @a __s if @a __n2 is too large. If
2475 * @a __pos is beyond end of string, out_of_range is thrown. If
2476 * the length of result exceeds max_size(), length_error is
2477 * thrown. The value of the string doesn't change if an error
2478 * is thrown.
2479 */
2480 _GLIBCXX20_CONSTEXPR
2481 basic_string&
2482 replace(size_type __pos, size_type __n1, const _CharT* __s,
2483 size_type __n2)
2484 {
2485 __glibcxx_requires_string_len(__s, __n2);
2486 return _M_replace(_M_check(__pos, "basic_string::replace"),
2487 _M_limit(__pos, __n1), __s, __n2);
2488 }
2489
2490 /**
2491 * @brief Replace characters with value of a C string.
2492 * @param __pos Index of first character to replace.
2493 * @param __n1 Number of characters to be replaced.
2494 * @param __s C string to insert.
2495 * @return Reference to this string.
2496 * @throw std::out_of_range If @a pos > size().
2497 * @throw std::length_error If new length exceeds @c max_size().
2498 *
2499 * Removes the characters in the range [__pos,__pos + __n1)
2500 * from this string. In place, the characters of @a __s are
2501 * inserted. If @a __pos is beyond end of string, out_of_range
2502 * is thrown. If the length of result exceeds max_size(),
2503 * length_error is thrown. The value of the string doesn't
2504 * change if an error is thrown.
2505 */
2506 _GLIBCXX20_CONSTEXPR
2507 basic_string&
2508 replace(size_type __pos, size_type __n1, const _CharT* __s)
2509 {
2510 __glibcxx_requires_string(__s);
2511 return this->replace(__pos, __n1, __s, traits_type::length(__s));
2512 }
2513
2514 /**
2515 * @brief Replace characters with multiple characters.
2516 * @param __pos Index of first character to replace.
2517 * @param __n1 Number of characters to be replaced.
2518 * @param __n2 Number of characters to insert.
2519 * @param __c Character to insert.
2520 * @return Reference to this string.
2521 * @throw std::out_of_range If @a __pos > size().
2522 * @throw std::length_error If new length exceeds @c max_size().
2523 *
2524 * Removes the characters in the range [pos,pos + n1) from this
2525 * string. In place, @a __n2 copies of @a __c are inserted.
2526 * If @a __pos is beyond end of string, out_of_range is thrown.
2527 * If the length of result exceeds max_size(), length_error is
2528 * thrown. The value of the string doesn't change if an error
2529 * is thrown.
2530 */
2531 _GLIBCXX20_CONSTEXPR
2532 basic_string&
2533 replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
2534 { return _M_replace_aux(_M_check(__pos, "basic_string::replace"),
2535 _M_limit(__pos, __n1), __n2, __c); }
2536
2537 /**
2538 * @brief Replace range of characters with string.
2539 * @param __i1 Iterator referencing start of range to replace.
2540 * @param __i2 Iterator referencing end of range to replace.
2541 * @param __str String value to insert.
2542 * @return Reference to this string.
2543 * @throw std::length_error If new length exceeds @c max_size().
2544 *
2545 * Removes the characters in the range [__i1,__i2). In place,
2546 * the value of @a __str is inserted. If the length of result
2547 * exceeds max_size(), length_error is thrown. The value of
2548 * the string doesn't change if an error is thrown.
2549 */
2550 _GLIBCXX20_CONSTEXPR
2551 basic_string&
2552 replace(__const_iterator __i1, __const_iterator __i2,
2553 const basic_string& __str)
2554 { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
2555
2556 /**
2557 * @brief Replace range of characters with C substring.
2558 * @param __i1 Iterator referencing start of range to replace.
2559 * @param __i2 Iterator referencing end of range to replace.
2560 * @param __s C string value to insert.
2561 * @param __n Number of characters from s to insert.
2562 * @return Reference to this string.
2563 * @throw std::length_error If new length exceeds @c max_size().
2564 *
2565 * Removes the characters in the range [__i1,__i2). In place,
2566 * the first @a __n characters of @a __s are inserted. If the
2567 * length of result exceeds max_size(), length_error is thrown.
2568 * The value of the string doesn't change if an error is
2569 * thrown.
2570 */
2571 _GLIBCXX20_CONSTEXPR
2572 basic_string&
2573 replace(__const_iterator __i1, __const_iterator __i2,
2574 const _CharT* __s, size_type __n)
2575 {
2576 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2577 && __i2 <= end());
2578 return this->replace(__i1 - begin(), __i2 - __i1, __s, __n);
2579 }
2580
2581 /**
2582 * @brief Replace range of characters with C string.
2583 * @param __i1 Iterator referencing start of range to replace.
2584 * @param __i2 Iterator referencing end of range to replace.
2585 * @param __s C string value to insert.
2586 * @return Reference to this string.
2587 * @throw std::length_error If new length exceeds @c max_size().
2588 *
2589 * Removes the characters in the range [__i1,__i2). In place,
2590 * the characters of @a __s are inserted. If the length of
2591 * result exceeds max_size(), length_error is thrown. The
2592 * value of the string doesn't change if an error is thrown.
2593 */
2594 _GLIBCXX20_CONSTEXPR
2595 basic_string&
2596 replace(__const_iterator __i1, __const_iterator __i2, const _CharT* __s)
2597 {
2598 __glibcxx_requires_string(__s);
2599 return this->replace(__i1, __i2, __s, traits_type::length(__s));
2600 }
2601
2602 /**
2603 * @brief Replace range of characters with multiple characters
2604 * @param __i1 Iterator referencing start of range to replace.
2605 * @param __i2 Iterator referencing end of range to replace.
2606 * @param __n Number of characters to insert.
2607 * @param __c Character to insert.
2608 * @return Reference to this string.
2609 * @throw std::length_error If new length exceeds @c max_size().
2610 *
2611 * Removes the characters in the range [__i1,__i2). In place,
2612 * @a __n copies of @a __c are inserted. If the length of
2613 * result exceeds max_size(), length_error is thrown. The
2614 * value of the string doesn't change if an error is thrown.
2615 */
2616 _GLIBCXX20_CONSTEXPR
2617 basic_string&
2618 replace(__const_iterator __i1, __const_iterator __i2, size_type __n,
2619 _CharT __c)
2620 {
2621 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2622 && __i2 <= end());
2623 return _M_replace_aux(__i1 - begin(), __i2 - __i1, __n, __c);
2624 }
2625
2626 /**
2627 * @brief Replace range of characters with range.
2628 * @param __i1 Iterator referencing start of range to replace.
2629 * @param __i2 Iterator referencing end of range to replace.
2630 * @param __k1 Iterator referencing start of range to insert.
2631 * @param __k2 Iterator referencing end of range to insert.
2632 * @return Reference to this string.
2633 * @throw std::length_error If new length exceeds @c max_size().
2634 *
2635 * Removes the characters in the range [__i1,__i2). In place,
2636 * characters in the range [__k1,__k2) are inserted. If the
2637 * length of result exceeds max_size(), length_error is thrown.
2638 * The value of the string doesn't change if an error is
2639 * thrown.
2640 */
2641#if __cplusplus201703L >= 201103L
2642 template<class _InputIterator,
2643 typename = std::_RequireInputIter<_InputIterator>>
2644 _GLIBCXX20_CONSTEXPR
2645 basic_string&
2646 replace(const_iterator __i1, const_iterator __i2,
2647 _InputIterator __k1, _InputIterator __k2)
2648 {
2649 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2650 && __i2 <= end());
2651 __glibcxx_requires_valid_range(__k1, __k2);
2652 return this->_M_replace_dispatch(__i1, __i2, __k1, __k2,
2653 std::__false_type());
2654 }
2655#else
2656 template<class _InputIterator>
2657#ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST
2658 typename __enable_if_not_native_iterator<_InputIterator>::__type
2659#else
2660 basic_string&
2661#endif
2662 replace(iterator __i1, iterator __i2,
2663 _InputIterator __k1, _InputIterator __k2)
2664 {
2665 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2666 && __i2 <= end());
2667 __glibcxx_requires_valid_range(__k1, __k2);
2668 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
2669 return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());
2670 }
2671#endif
2672
2673 // Specializations for the common case of pointer and iterator:
2674 // useful to avoid the overhead of temporary buffering in _M_replace.
2675 _GLIBCXX20_CONSTEXPR
2676 basic_string&
2677 replace(__const_iterator __i1, __const_iterator __i2,
2678 _CharT* __k1, _CharT* __k2)
2679 {
2680 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2681 && __i2 <= end());
2682 __glibcxx_requires_valid_range(__k1, __k2);
2683 return this->replace(__i1 - begin(), __i2 - __i1,
2684 __k1, __k2 - __k1);
2685 }
2686
2687 _GLIBCXX20_CONSTEXPR
2688 basic_string&
2689 replace(__const_iterator __i1, __const_iterator __i2,
2690 const _CharT* __k1, const _CharT* __k2)
2691 {
2692 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2693 && __i2 <= end());
2694 __glibcxx_requires_valid_range(__k1, __k2);
2695 return this->replace(__i1 - begin(), __i2 - __i1,
2696 __k1, __k2 - __k1);
2697 }
2698
2699 _GLIBCXX20_CONSTEXPR
2700 basic_string&
2701 replace(__const_iterator __i1, __const_iterator __i2,
2702 iterator __k1, iterator __k2)
2703 {
2704 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2705 && __i2 <= end());
2706 __glibcxx_requires_valid_range(__k1, __k2);
2707 return this->replace(__i1 - begin(), __i2 - __i1,
2708 __k1.base(), __k2 - __k1);
2709 }
2710
2711 _GLIBCXX20_CONSTEXPR
2712 basic_string&
2713 replace(__const_iterator __i1, __const_iterator __i2,
2714 const_iterator __k1, const_iterator __k2)
2715 {
2716 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2717 && __i2 <= end());
2718 __glibcxx_requires_valid_range(__k1, __k2);
2719 return this->replace(__i1 - begin(), __i2 - __i1,
2720 __k1.base(), __k2 - __k1);
2721 }
2722
2723#if __glibcxx_containers_ranges // C++ >= 23
2724 /**
2725 * @brief Replace part of the string with a range.
2726 * @param __rg A range of values that are convertible to `value_type`.
2727 * @since C++23
2728 *
2729 * The range `__rg` is allowed to overlap with `*this`.
2730 */
2731 template<__detail::__container_compatible_range<_CharT> _Rg>
2732 constexpr basic_string&
2733 replace_with_range(const_iterator __i1, const_iterator __i2, _Rg&& __rg)
2734 {
2735 if (__i1 == cend())
2736 append_range(std::forward<_Rg>(__rg));
2737 else
2738 {
2739 basic_string __s(from_range, std::forward<_Rg>(__rg),
2740 _M_get_allocator());
2741 replace(__i1, __i2, __s);
2742 }
2743 return *this;
2744 }
2745#endif
2746
2747#if __cplusplus201703L >= 201103L
2748 /**
2749 * @brief Replace range of characters with initializer_list.
2750 * @param __i1 Iterator referencing start of range to replace.
2751 * @param __i2 Iterator referencing end of range to replace.
2752 * @param __l The initializer_list of characters to insert.
2753 * @return Reference to this string.
2754 * @throw std::length_error If new length exceeds @c max_size().
2755 *
2756 * Removes the characters in the range [__i1,__i2). In place,
2757 * characters in the range [__k1,__k2) are inserted. If the
2758 * length of result exceeds max_size(), length_error is thrown.
2759 * The value of the string doesn't change if an error is
2760 * thrown.
2761 */
2762 _GLIBCXX20_CONSTEXPR
2763 basic_string& replace(const_iterator __i1, const_iterator __i2,
2764 initializer_list<_CharT> __l)
2765 { return this->replace(__i1, __i2, __l.begin(), __l.size()); }
2766#endif // C++11
2767
2768#ifdef __glibcxx_string_view201803L // >= C++17
2769 /**
2770 * @brief Replace range of characters with string_view.
2771 * @param __pos The position to replace at.
2772 * @param __n The number of characters to replace.
2773 * @param __svt The object convertible to string_view to insert.
2774 * @return Reference to this string.
2775 */
2776 template<typename _Tp>
2777 _GLIBCXX20_CONSTEXPR
2778 _If_sv<_Tp, basic_string&>
2779 replace(size_type __pos, size_type __n, const _Tp& __svt)
2780 {
2781 __sv_type __sv = __svt;
2782 return this->replace(__pos, __n, __sv.data(), __sv.size());
2783 }
2784
2785 /**
2786 * @brief Replace range of characters with string_view.
2787 * @param __pos1 The position to replace at.
2788 * @param __n1 The number of characters to replace.
2789 * @param __svt The object convertible to string_view to insert from.
2790 * @param __pos2 The position in the string_view to insert from.
2791 * @param __n2 The number of characters to insert.
2792 * @return Reference to this string.
2793 */
2794 template<typename _Tp>
2795 _GLIBCXX20_CONSTEXPR
2796 _If_sv<_Tp, basic_string&>
2797 replace(size_type __pos1, size_type __n1, const _Tp& __svt,
2798 size_type __pos2, size_type __n2 = npos)
2799 {
2800 __sv_type __sv = __svt;
2801 return this->replace(__pos1, __n1,
2802 __sv.data()
2803 + std::__sv_check(__sv.size(), __pos2, "basic_string::replace"),
2804 std::__sv_limit(__sv.size(), __pos2, __n2));
2805 }
2806
2807 /**
2808 * @brief Replace range of characters with string_view.
2809 * @param __i1 An iterator referencing the start position
2810 to replace at.
2811 * @param __i2 An iterator referencing the end position
2812 for the replace.
2813 * @param __svt The object convertible to string_view to insert from.
2814 * @return Reference to this string.
2815 */
2816 template<typename _Tp>
2817 _GLIBCXX20_CONSTEXPR
2818 _If_sv<_Tp, basic_string&>
2819 replace(const_iterator __i1, const_iterator __i2, const _Tp& __svt)
2820 {
2821 __sv_type __sv = __svt;
2822 return this->replace(__i1 - begin(), __i2 - __i1, __sv);
2823 }
2824#endif // C++17
2825
2826 private:
2827 template<class _Integer>
2828 _GLIBCXX20_CONSTEXPR
2829 basic_string&
2830 _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
2831 _Integer __n, _Integer __val, __true_type)
2832 { return _M_replace_aux(__i1 - begin(), __i2 - __i1, __n, __val); }
2833
2834 template<class _InputIterator>
2835 _GLIBCXX20_CONSTEXPR
2836 basic_string&
2837 _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
2838 _InputIterator __k1, _InputIterator __k2,
2839 __false_type);
2840
2841 _GLIBCXX20_CONSTEXPR
2842 basic_string&
2843 _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
2844 _CharT __c);
2845
2846 __attribute__((__noinline__, __noclone__, __cold__)) void
2847 _M_replace_cold(pointer __p, size_type __len1, const _CharT* __s,
2848 const size_type __len2, const size_type __how_much);
2849
2850 _GLIBCXX20_CONSTEXPR
2851 basic_string&
2852 _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
2853 const size_type __len2);
2854
2855 _GLIBCXX20_CONSTEXPR
2856 basic_string&
2857 _M_append(const _CharT* __s, size_type __n);
2858
2859 public:
2860
2861 /**
2862 * @brief Copy substring into C string.
2863 * @param __s C string to copy value into.
2864 * @param __n Number of characters to copy.
2865 * @param __pos Index of first character to copy.
2866 * @return Number of characters actually copied
2867 * @throw std::out_of_range If __pos > size().
2868 *
2869 * Copies up to @a __n characters starting at @a __pos into the
2870 * C string @a __s. If @a __pos is %greater than size(),
2871 * out_of_range is thrown.
2872 */
2873 _GLIBCXX20_CONSTEXPR
2874 size_type
2875 copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
2876
2877 /**
2878 * @brief Swap contents with another string.
2879 * @param __s String to swap with.
2880 *
2881 * Exchanges the contents of this string with that of @a __s in constant
2882 * time.
2883 */
2884 _GLIBCXX20_CONSTEXPR
2885 void
2886 swap(basic_string& __s) _GLIBCXX_NOEXCEPTnoexcept;
2887
2888 // String operations:
2889 /**
2890 * @brief Return const pointer to null-terminated contents.
2891 *
2892 * This is a handle to internal data. Do not modify or dire things may
2893 * happen.
2894 */
2895 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
2896 const _CharT*
2897 c_str() const _GLIBCXX_NOEXCEPTnoexcept
2898 { return _M_data(); }
2899
2900 /**
2901 * @brief Return const pointer to contents.
2902 *
2903 * This is a pointer to internal data. It is undefined to modify
2904 * the contents through the returned pointer. To get a pointer that
2905 * allows modifying the contents use @c &str[0] instead,
2906 * (or in C++17 the non-const @c str.data() overload).
2907 */
2908 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
2909 const _CharT*
2910 data() const _GLIBCXX_NOEXCEPTnoexcept
2911 { return _M_data(); }
2912
2913#if __cplusplus201703L >= 201703L
2914 /**
2915 * @brief Return non-const pointer to contents.
2916 *
2917 * This is a pointer to the character sequence held by the string.
2918 * Modifying the characters in the sequence is allowed.
2919 */
2920 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
2921 _CharT*
2922 data() noexcept
2923 { return _M_data(); }
2924#endif
2925
2926 /**
2927 * @brief Return copy of allocator used to construct this string.
2928 */
2929 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
2930 allocator_type
2931 get_allocator() const _GLIBCXX_NOEXCEPTnoexcept
2932 { return _M_get_allocator(); }
2933
2934 /**
2935 * @brief Find position of a C substring.
2936 * @param __s C string to locate.
2937 * @param __pos Index of character to search from.
2938 * @param __n Number of characters from @a s to search for.
2939 * @return Index of start of first occurrence.
2940 *
2941 * Starting from @a __pos, searches forward for the first @a
2942 * __n characters in @a __s within this string. If found,
2943 * returns the index where it begins. If not found, returns
2944 * npos.
2945 */
2946 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
2947 size_type
2948 find(const _CharT* __s, size_type __pos, size_type __n) const
2949 _GLIBCXX_NOEXCEPTnoexcept;
2950
2951 /**
2952 * @brief Find position of a string.
2953 * @param __str String to locate.
2954 * @param __pos Index of character to search from (default 0).
2955 * @return Index of start of first occurrence.
2956 *
2957 * Starting from @a __pos, searches forward for value of @a __str within
2958 * this string. If found, returns the index where it begins. If not
2959 * found, returns npos.
2960 */
2961 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
2962 size_type
2963 find(const basic_string& __str, size_type __pos = 0) const
2964 _GLIBCXX_NOEXCEPTnoexcept
2965 { return this->find(__str.data(), __pos, __str.size()); }
2966
2967#ifdef __glibcxx_string_view201803L // >= C++17
2968 /**
2969 * @brief Find position of a string_view.
2970 * @param __svt The object convertible to string_view to locate.
2971 * @param __pos Index of character to search from (default 0).
2972 * @return Index of start of first occurrence.
2973 */
2974 template<typename _Tp>
2975 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
2976 _If_sv<_Tp, size_type>
2977 find(const _Tp& __svt, size_type __pos = 0) const
2978 noexcept(is_same<_Tp, __sv_type>::value)
2979 {
2980 __sv_type __sv = __svt;
2981 return this->find(__sv.data(), __pos, __sv.size());
2982 }
2983#endif // C++17
2984
2985 /**
2986 * @brief Find position of a C string.
2987 * @param __s C string to locate.
2988 * @param __pos Index of character to search from (default 0).
2989 * @return Index of start of first occurrence.
2990 *
2991 * Starting from @a __pos, searches forward for the value of @a
2992 * __s within this string. If found, returns the index where
2993 * it begins. If not found, returns npos.
2994 */
2995 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
2996 size_type
2997 find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPTnoexcept
2998 {
2999 __glibcxx_requires_string(__s);
3000 return this->find(__s, __pos, traits_type::length(__s));
3001 }
3002
3003 /**
3004 * @brief Find position of a character.
3005 * @param __c Character to locate.
3006 * @param __pos Index of character to search from (default 0).
3007 * @return Index of first occurrence.
3008 *
3009 * Starting from @a __pos, searches forward for @a __c within
3010 * this string. If found, returns the index where it was
3011 * found. If not found, returns npos.
3012 */
3013 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3014 size_type
3015 find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPTnoexcept;
3016
3017 /**
3018 * @brief Find last position of a string.
3019 * @param __str String to locate.
3020 * @param __pos Index of character to search back from (default end).
3021 * @return Index of start of last occurrence.
3022 *
3023 * Starting from @a __pos, searches backward for value of @a
3024 * __str within this string. If found, returns the index where
3025 * it begins. If not found, returns npos.
3026 */
3027 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3028 size_type
3029 rfind(const basic_string& __str, size_type __pos = npos) const
3030 _GLIBCXX_NOEXCEPTnoexcept
3031 { return this->rfind(__str.data(), __pos, __str.size()); }
3032
3033#ifdef __glibcxx_string_view201803L // >= C++17
3034 /**
3035 * @brief Find last position of a string_view.
3036 * @param __svt The object convertible to string_view to locate.
3037 * @param __pos Index of character to search back from (default end).
3038 * @return Index of start of last occurrence.
3039 */
3040 template<typename _Tp>
3041 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3042 _If_sv<_Tp, size_type>
3043 rfind(const _Tp& __svt, size_type __pos = npos) const
3044 noexcept(is_same<_Tp, __sv_type>::value)
3045 {
3046 __sv_type __sv = __svt;
3047 return this->rfind(__sv.data(), __pos, __sv.size());
3048 }
3049#endif // C++17
3050
3051 /**
3052 * @brief Find last position of a C substring.
3053 * @param __s C string to locate.
3054 * @param __pos Index of character to search back from.
3055 * @param __n Number of characters from s to search for.
3056 * @return Index of start of last occurrence.
3057 *
3058 * Starting from @a __pos, searches backward for the first @a
3059 * __n characters in @a __s within this string. If found,
3060 * returns the index where it begins. If not found, returns
3061 * npos.
3062 */
3063 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3064 size_type
3065 rfind(const _CharT* __s, size_type __pos, size_type __n) const
3066 _GLIBCXX_NOEXCEPTnoexcept;
3067
3068 /**
3069 * @brief Find last position of a C string.
3070 * @param __s C string to locate.
3071 * @param __pos Index of character to start search at (default end).
3072 * @return Index of start of last occurrence.
3073 *
3074 * Starting from @a __pos, searches backward for the value of
3075 * @a __s within this string. If found, returns the index
3076 * where it begins. If not found, returns npos.
3077 */
3078 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3079 size_type
3080 rfind(const _CharT* __s, size_type __pos = npos) const
3081 {
3082 __glibcxx_requires_string(__s);
3083 return this->rfind(__s, __pos, traits_type::length(__s));
3084 }
3085
3086 /**
3087 * @brief Find last position of a character.
3088 * @param __c Character to locate.
3089 * @param __pos Index of character to search back from (default end).
3090 * @return Index of last occurrence.
3091 *
3092 * Starting from @a __pos, searches backward for @a __c within
3093 * this string. If found, returns the index where it was
3094 * found. If not found, returns npos.
3095 */
3096 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3097 size_type
3098 rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPTnoexcept;
3099
3100 /**
3101 * @brief Find position of a character of string.
3102 * @param __str String containing characters to locate.
3103 * @param __pos Index of character to search from (default 0).
3104 * @return Index of first occurrence.
3105 *
3106 * Starting from @a __pos, searches forward for one of the
3107 * characters of @a __str within this string. If found,
3108 * returns the index where it was found. If not found, returns
3109 * npos.
3110 */
3111 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3112 size_type
3113 find_first_of(const basic_string& __str, size_type __pos = 0) const
3114 _GLIBCXX_NOEXCEPTnoexcept
3115 { return this->find_first_of(__str.data(), __pos, __str.size()); }
3116
3117#ifdef __glibcxx_string_view201803L // >= C++17
3118 /**
3119 * @brief Find position of a character of a string_view.
3120 * @param __svt An object convertible to string_view containing
3121 * characters to locate.
3122 * @param __pos Index of character to search from (default 0).
3123 * @return Index of first occurrence.
3124 */
3125 template<typename _Tp>
3126 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3127 _If_sv<_Tp, size_type>
3128 find_first_of(const _Tp& __svt, size_type __pos = 0) const
3129 noexcept(is_same<_Tp, __sv_type>::value)
3130 {
3131 __sv_type __sv = __svt;
3132 return this->find_first_of(__sv.data(), __pos, __sv.size());
3133 }
3134#endif // C++17
3135
3136 /**
3137 * @brief Find position of a character of C substring.
3138 * @param __s String containing characters to locate.
3139 * @param __pos Index of character to search from.
3140 * @param __n Number of characters from s to search for.
3141 * @return Index of first occurrence.
3142 *
3143 * Starting from @a __pos, searches forward for one of the
3144 * first @a __n characters of @a __s within this string. If
3145 * found, returns the index where it was found. If not found,
3146 * returns npos.
3147 */
3148 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3149 size_type
3150 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
3151 _GLIBCXX_NOEXCEPTnoexcept;
3152
3153 /**
3154 * @brief Find position of a character of C string.
3155 * @param __s String containing characters to locate.
3156 * @param __pos Index of character to search from (default 0).
3157 * @return Index of first occurrence.
3158 *
3159 * Starting from @a __pos, searches forward for one of the
3160 * characters of @a __s within this string. If found, returns
3161 * the index where it was found. If not found, returns npos.
3162 */
3163 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3164 size_type
3165 find_first_of(const _CharT* __s, size_type __pos = 0) const
3166 _GLIBCXX_NOEXCEPTnoexcept
3167 {
3168 __glibcxx_requires_string(__s);
3169 return this->find_first_of(__s, __pos, traits_type::length(__s));
3170 }
3171
3172 /**
3173 * @brief Find position of a character.
3174 * @param __c Character to locate.
3175 * @param __pos Index of character to search from (default 0).
3176 * @return Index of first occurrence.
3177 *
3178 * Starting from @a __pos, searches forward for the character
3179 * @a __c within this string. If found, returns the index
3180 * where it was found. If not found, returns npos.
3181 *
3182 * Note: equivalent to find(__c, __pos).
3183 */
3184 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3185 size_type
3186 find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPTnoexcept
3187 { return this->find(__c, __pos); }
3188
3189 /**
3190 * @brief Find last position of a character of string.
3191 * @param __str String containing characters to locate.
3192 * @param __pos Index of character to search back from (default end).
3193 * @return Index of last occurrence.
3194 *
3195 * Starting from @a __pos, searches backward for one of the
3196 * characters of @a __str within this string. If found,
3197 * returns the index where it was found. If not found, returns
3198 * npos.
3199 */
3200 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3201 size_type
3202 find_last_of(const basic_string& __str, size_type __pos = npos) const
3203 _GLIBCXX_NOEXCEPTnoexcept
3204 { return this->find_last_of(__str.data(), __pos, __str.size()); }
3205
3206#ifdef __glibcxx_string_view201803L // >= C++17
3207 /**
3208 * @brief Find last position of a character of string.
3209 * @param __svt An object convertible to string_view containing
3210 * characters to locate.
3211 * @param __pos Index of character to search back from (default end).
3212 * @return Index of last occurrence.
3213 */
3214 template<typename _Tp>
3215 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3216 _If_sv<_Tp, size_type>
3217 find_last_of(const _Tp& __svt, size_type __pos = npos) const
3218 noexcept(is_same<_Tp, __sv_type>::value)
3219 {
3220 __sv_type __sv = __svt;
3221 return this->find_last_of(__sv.data(), __pos, __sv.size());
3222 }
3223#endif // C++17
3224
3225 /**
3226 * @brief Find last position of a character of C substring.
3227 * @param __s C string containing characters to locate.
3228 * @param __pos Index of character to search back from.
3229 * @param __n Number of characters from s to search for.
3230 * @return Index of last occurrence.
3231 *
3232 * Starting from @a __pos, searches backward for one of the
3233 * first @a __n characters of @a __s within this string. If
3234 * found, returns the index where it was found. If not found,
3235 * returns npos.
3236 */
3237 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3238 size_type
3239 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
3240 _GLIBCXX_NOEXCEPTnoexcept;
3241
3242 /**
3243 * @brief Find last position of a character of C string.
3244 * @param __s C string containing characters to locate.
3245 * @param __pos Index of character to search back from (default end).
3246 * @return Index of last occurrence.
3247 *
3248 * Starting from @a __pos, searches backward for one of the
3249 * characters of @a __s within this string. If found, returns
3250 * the index where it was found. If not found, returns npos.
3251 */
3252 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3253 size_type
3254 find_last_of(const _CharT* __s, size_type __pos = npos) const
3255 _GLIBCXX_NOEXCEPTnoexcept
3256 {
3257 __glibcxx_requires_string(__s);
3258 return this->find_last_of(__s, __pos, traits_type::length(__s));
3259 }
3260
3261 /**
3262 * @brief Find last position of a character.
3263 * @param __c Character to locate.
3264 * @param __pos Index of character to search back from (default end).
3265 * @return Index of last occurrence.
3266 *
3267 * Starting from @a __pos, searches backward for @a __c within
3268 * this string. If found, returns the index where it was
3269 * found. If not found, returns npos.
3270 *
3271 * Note: equivalent to rfind(__c, __pos).
3272 */
3273 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3274 size_type
3275 find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPTnoexcept
3276 { return this->rfind(__c, __pos); }
3277
3278 /**
3279 * @brief Find position of a character not in string.
3280 * @param __str String containing characters to avoid.
3281 * @param __pos Index of character to search from (default 0).
3282 * @return Index of first occurrence.
3283 *
3284 * Starting from @a __pos, searches forward for a character not contained
3285 * in @a __str within this string. If found, returns the index where it
3286 * was found. If not found, returns npos.
3287 */
3288 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3289 size_type
3290 find_first_not_of(const basic_string& __str, size_type __pos = 0) const
3291 _GLIBCXX_NOEXCEPTnoexcept
3292 { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
3293
3294#ifdef __glibcxx_string_view201803L // >= C++17
3295 /**
3296 * @brief Find position of a character not in a string_view.
3297 * @param __svt A object convertible to string_view containing
3298 * characters to avoid.
3299 * @param __pos Index of character to search from (default 0).
3300 * @return Index of first occurrence.
3301 */
3302 template<typename _Tp>
3303 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3304 _If_sv<_Tp, size_type>
3305 find_first_not_of(const _Tp& __svt, size_type __pos = 0) const
3306 noexcept(is_same<_Tp, __sv_type>::value)
3307 {
3308 __sv_type __sv = __svt;
3309 return this->find_first_not_of(__sv.data(), __pos, __sv.size());
3310 }
3311#endif // C++17
3312
3313 /**
3314 * @brief Find position of a character not in C substring.
3315 * @param __s C string containing characters to avoid.
3316 * @param __pos Index of character to search from.
3317 * @param __n Number of characters from __s to consider.
3318 * @return Index of first occurrence.
3319 *
3320 * Starting from @a __pos, searches forward for a character not
3321 * contained in the first @a __n characters of @a __s within
3322 * this string. If found, returns the index where it was
3323 * found. If not found, returns npos.
3324 */
3325 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3326 size_type
3327 find_first_not_of(const _CharT* __s, size_type __pos,
3328 size_type __n) const _GLIBCXX_NOEXCEPTnoexcept;
3329
3330 /**
3331 * @brief Find position of a character not in C string.
3332 * @param __s C string containing characters to avoid.
3333 * @param __pos Index of character to search from (default 0).
3334 * @return Index of first occurrence.
3335 *
3336 * Starting from @a __pos, searches forward for a character not
3337 * contained in @a __s within this string. If found, returns
3338 * the index where it was found. If not found, returns npos.
3339 */
3340 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3341 size_type
3342 find_first_not_of(const _CharT* __s, size_type __pos = 0) const
3343 _GLIBCXX_NOEXCEPTnoexcept
3344 {
3345 __glibcxx_requires_string(__s);
3346 return this->find_first_not_of(__s, __pos, traits_type::length(__s));
3347 }
3348
3349 /**
3350 * @brief Find position of a different character.
3351 * @param __c Character to avoid.
3352 * @param __pos Index of character to search from (default 0).
3353 * @return Index of first occurrence.
3354 *
3355 * Starting from @a __pos, searches forward for a character
3356 * other than @a __c within this string. If found, returns the
3357 * index where it was found. If not found, returns npos.
3358 */
3359 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3360 size_type
3361 find_first_not_of(_CharT __c, size_type __pos = 0) const
3362 _GLIBCXX_NOEXCEPTnoexcept;
3363
3364 /**
3365 * @brief Find last position of a character not in string.
3366 * @param __str String containing characters to avoid.
3367 * @param __pos Index of character to search back from (default end).
3368 * @return Index of last occurrence.
3369 *
3370 * Starting from @a __pos, searches backward for a character
3371 * not contained in @a __str within this string. If found,
3372 * returns the index where it was found. If not found, returns
3373 * npos.
3374 */
3375 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3376 size_type
3377 find_last_not_of(const basic_string& __str, size_type __pos = npos) const
3378 _GLIBCXX_NOEXCEPTnoexcept
3379 { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
3380
3381#ifdef __glibcxx_string_view201803L // >= C++17
3382 /**
3383 * @brief Find last position of a character not in a string_view.
3384 * @param __svt An object convertible to string_view containing
3385 * characters to avoid.
3386 * @param __pos Index of character to search back from (default end).
3387 * @return Index of last occurrence.
3388 */
3389 template<typename _Tp>
3390 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3391 _If_sv<_Tp, size_type>
3392 find_last_not_of(const _Tp& __svt, size_type __pos = npos) const
3393 noexcept(is_same<_Tp, __sv_type>::value)
3394 {
3395 __sv_type __sv = __svt;
3396 return this->find_last_not_of(__sv.data(), __pos, __sv.size());
3397 }
3398#endif // C++17
3399
3400 /**
3401 * @brief Find last position of a character not in C substring.
3402 * @param __s C string containing characters to avoid.
3403 * @param __pos Index of character to search back from.
3404 * @param __n Number of characters from s to consider.
3405 * @return Index of last occurrence.
3406 *
3407 * Starting from @a __pos, searches backward for a character not
3408 * contained in the first @a __n characters of @a __s within this string.
3409 * If found, returns the index where it was found. If not found,
3410 * returns npos.
3411 */
3412 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3413 size_type
3414 find_last_not_of(const _CharT* __s, size_type __pos,
3415 size_type __n) const _GLIBCXX_NOEXCEPTnoexcept;
3416 /**
3417 * @brief Find last position of a character not in C string.
3418 * @param __s C string containing characters to avoid.
3419 * @param __pos Index of character to search back from (default end).
3420 * @return Index of last occurrence.
3421 *
3422 * Starting from @a __pos, searches backward for a character
3423 * not contained in @a __s within this string. If found,
3424 * returns the index where it was found. If not found, returns
3425 * npos.
3426 */
3427 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3428 size_type
3429 find_last_not_of(const _CharT* __s, size_type __pos = npos) const
3430 _GLIBCXX_NOEXCEPTnoexcept
3431 {
3432 __glibcxx_requires_string(__s);
3433 return this->find_last_not_of(__s, __pos, traits_type::length(__s));
3434 }
3435
3436 /**
3437 * @brief Find last position of a different character.
3438 * @param __c Character to avoid.
3439 * @param __pos Index of character to search back from (default end).
3440 * @return Index of last occurrence.
3441 *
3442 * Starting from @a __pos, searches backward for a character other than
3443 * @a __c within this string. If found, returns the index where it was
3444 * found. If not found, returns npos.
3445 */
3446 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3447 size_type
3448 find_last_not_of(_CharT __c, size_type __pos = npos) const
3449 _GLIBCXX_NOEXCEPTnoexcept;
3450
3451 /**
3452 * @brief Get a substring.
3453 * @param __pos Index of first character (default 0).
3454 * @param __n Number of characters in substring (default remainder).
3455 * @return The new string.
3456 * @throw std::out_of_range If __pos > size().
3457 *
3458 * Construct and return a new string using the @a __n
3459 * characters starting at @a __pos. If the string is too
3460 * short, use the remainder of the characters. If @a __pos is
3461 * beyond the end of the string, out_of_range is thrown.
3462 */
3463 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3464 basic_string
3465 substr(size_type __pos = 0, size_type __n = npos) const
3466 { return basic_string(*this,
3467 _M_check(__pos, "basic_string::substr"), __n); }
3468
3469#if __cplusplus201703L >= 202302L
3470 _GLIBCXX_NODISCARD[[__nodiscard__]]
3471 constexpr basic_string
3472 substr(size_type __pos = 0) &&
3473 { return basic_string(std::move(*this), __pos); }
3474
3475 _GLIBCXX_NODISCARD[[__nodiscard__]]
3476 constexpr basic_string
3477 substr(size_type __pos, size_type __n) &&
3478 { return basic_string(std::move(*this), __pos, __n); }
3479#endif // C++23
3480
3481#ifdef __glibcxx_string_subview // >= C++26
3482 /**
3483 * @brief Get a subview.
3484 * @param __pos Index of first character (default 0).
3485 * @param __n Number of characters in subview (default remainder).
3486 * @return The subview.
3487 * @throw std::out_of_range If __pos > size().
3488 *
3489 * Construct and return a subview using the `__n` characters starting at
3490 * `__pos`. If the string is too short, use the remainder of the
3491 * characters. If `__pos` is beyond the end of the string, out_of_range
3492 * is thrown.
3493 */
3494 [[nodiscard]]
3495 constexpr basic_string_view<_CharT, _Traits>
3496 subview(size_type __pos = 0, size_type __n = npos) const
3497 { return __sv_type(*this).subview(__pos, __n); }
3498#endif
3499
3500 /**
3501 * @brief Compare to a string.
3502 * @param __str String to compare against.
3503 * @return Integer < 0, 0, or > 0.
3504 *
3505 * Returns an integer < 0 if this string is ordered before @a
3506 * __str, 0 if their values are equivalent, or > 0 if this
3507 * string is ordered after @a __str. Determines the effective
3508 * length rlen of the strings to compare as the smallest of
3509 * size() and str.size(). The function then compares the two
3510 * strings by calling traits::compare(data(), str.data(),rlen).
3511 * If the result of the comparison is nonzero returns it,
3512 * otherwise the shorter one is ordered first.
3513 */
3514 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3515 int
3516 compare(const basic_string& __str) const
3517 {
3518 const size_type __size = this->size();
3519 const size_type __osize = __str.size();
3520 const size_type __len = std::min(__size, __osize);
3521
3522 int __r = traits_type::compare(_M_data(), __str.data(), __len);
3523 if (!__r)
3524 __r = _S_compare(__size, __osize);
3525 return __r;
3526 }
3527
3528#ifdef __glibcxx_string_view201803L // >= C++17
3529 /**
3530 * @brief Compare to a string_view.
3531 * @param __svt An object convertible to string_view to compare against.
3532 * @return Integer < 0, 0, or > 0.
3533 */
3534 template<typename _Tp>
3535 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3536 _If_sv<_Tp, int>
3537 compare(const _Tp& __svt) const
3538 noexcept(is_same<_Tp, __sv_type>::value)
3539 {
3540 __sv_type __sv = __svt;
3541 const size_type __size = this->size();
3542 const size_type __osize = __sv.size();
3543 const size_type __len = std::min(__size, __osize);
3544
3545 int __r = traits_type::compare(_M_data(), __sv.data(), __len);
3546 if (!__r)
3547 __r = _S_compare(__size, __osize);
3548 return __r;
3549 }
3550
3551 /**
3552 * @brief Compare to a string_view.
3553 * @param __pos A position in the string to start comparing from.
3554 * @param __n The number of characters to compare.
3555 * @param __svt An object convertible to string_view to compare
3556 * against.
3557 * @return Integer < 0, 0, or > 0.
3558 */
3559 template<typename _Tp>
3560 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3561 _If_sv<_Tp, int>
3562 compare(size_type __pos, size_type __n, const _Tp& __svt) const
3563 {
3564 __sv_type __sv = __svt;
3565 return __sv_type(*this).substr(__pos, __n).compare(__sv);
3566 }
3567
3568 /**
3569 * @brief Compare to a string_view.
3570 * @param __pos1 A position in the string to start comparing from.
3571 * @param __n1 The number of characters to compare.
3572 * @param __svt An object convertible to string_view to compare
3573 * against.
3574 * @param __pos2 A position in the string_view to start comparing from.
3575 * @param __n2 The number of characters to compare.
3576 * @return Integer < 0, 0, or > 0.
3577 */
3578 template<typename _Tp>
3579 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3580 _If_sv<_Tp, int>
3581 compare(size_type __pos1, size_type __n1, const _Tp& __svt,
3582 size_type __pos2, size_type __n2 = npos) const
3583 {
3584 __sv_type __sv = __svt;
3585 return __sv_type(*this)
3586 .substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
3587 }
3588#endif // C++17
3589
3590 /**
3591 * @brief Compare substring to a string.
3592 * @param __pos Index of first character of substring.
3593 * @param __n Number of characters in substring.
3594 * @param __str String to compare against.
3595 * @return Integer < 0, 0, or > 0.
3596 *
3597 * Form the substring of this string from the @a __n characters
3598 * starting at @a __pos. Returns an integer < 0 if the
3599 * substring is ordered before @a __str, 0 if their values are
3600 * equivalent, or > 0 if the substring is ordered after @a
3601 * __str. Determines the effective length rlen of the strings
3602 * to compare as the smallest of the length of the substring
3603 * and @a __str.size(). The function then compares the two
3604 * strings by calling
3605 * traits::compare(substring.data(),str.data(),rlen). If the
3606 * result of the comparison is nonzero returns it, otherwise
3607 * the shorter one is ordered first.
3608 */
3609 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3610 int
3611 compare(size_type __pos, size_type __n, const basic_string& __str) const
3612 {
3613 _M_check(__pos, "basic_string::compare");
3614 __n = _M_limit(__pos, __n);
3615 const size_type __osize = __str.size();
3616 const size_type __len = std::min(__n, __osize);
3617 int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
3618 if (!__r)
3619 __r = _S_compare(__n, __osize);
3620 return __r;
3621 }
3622
3623 /**
3624 * @brief Compare substring to a substring.
3625 * @param __pos1 Index of first character of substring.
3626 * @param __n1 Number of characters in substring.
3627 * @param __str String to compare against.
3628 * @param __pos2 Index of first character of substring of str.
3629 * @param __n2 Number of characters in substring of str.
3630 * @return Integer < 0, 0, or > 0.
3631 *
3632 * Form the substring of this string from the @a __n1
3633 * characters starting at @a __pos1. Form the substring of @a
3634 * __str from the @a __n2 characters starting at @a __pos2.
3635 * Returns an integer < 0 if this substring is ordered before
3636 * the substring of @a __str, 0 if their values are equivalent,
3637 * or > 0 if this substring is ordered after the substring of
3638 * @a __str. Determines the effective length rlen of the
3639 * strings to compare as the smallest of the lengths of the
3640 * substrings. The function then compares the two strings by
3641 * calling
3642 * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen).
3643 * If the result of the comparison is nonzero returns it,
3644 * otherwise the shorter one is ordered first.
3645 */
3646 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3647 int
3648 compare(size_type __pos1, size_type __n1, const basic_string& __str,
3649 size_type __pos2, size_type __n2 = npos) const
3650 {
3651 _M_check(__pos1, "basic_string::compare");
3652 __str._M_check(__pos2, "basic_string::compare");
3653 __n1 = _M_limit(__pos1, __n1);
3654 __n2 = __str._M_limit(__pos2, __n2);
3655 const size_type __len = std::min(__n1, __n2);
3656 int __r = traits_type::compare(_M_data() + __pos1,
3657 __str.data() + __pos2, __len);
3658 if (!__r)
3659 __r = _S_compare(__n1, __n2);
3660 return __r;
3661 }
3662
3663 /**
3664 * @brief Compare to a C string.
3665 * @param __s C string to compare against.
3666 * @return Integer < 0, 0, or > 0.
3667 *
3668 * Returns an integer < 0 if this string is ordered before @a __s, 0 if
3669 * their values are equivalent, or > 0 if this string is ordered after
3670 * @a __s. Determines the effective length rlen of the strings to
3671 * compare as the smallest of size() and the length of a string
3672 * constructed from @a __s. The function then compares the two strings
3673 * by calling traits::compare(data(),s,rlen). If the result of the
3674 * comparison is nonzero returns it, otherwise the shorter one is
3675 * ordered first.
3676 */
3677 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3678 int
3679 compare(const _CharT* __s) const _GLIBCXX_NOEXCEPTnoexcept
3680 {
3681 __glibcxx_requires_string(__s);
3682 const size_type __size = this->size();
3683 const size_type __osize = traits_type::length(__s);
3684 const size_type __len = std::min(__size, __osize);
3685 int __r = traits_type::compare(_M_data(), __s, __len);
3686 if (!__r)
3687 __r = _S_compare(__size, __osize);
3688 return __r;
3689 }
3690
3691 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3692 // 5 String::compare specification questionable
3693 /**
3694 * @brief Compare substring to a C string.
3695 * @param __pos Index of first character of substring.
3696 * @param __n1 Number of characters in substring.
3697 * @param __s C string to compare against.
3698 * @return Integer < 0, 0, or > 0.
3699 *
3700 * Form the substring of this string from the @a __n1
3701 * characters starting at @a pos. Returns an integer < 0 if
3702 * the substring is ordered before @a __s, 0 if their values
3703 * are equivalent, or > 0 if the substring is ordered after @a
3704 * __s. Determines the effective length rlen of the strings to
3705 * compare as the smallest of the length of the substring and
3706 * the length of a string constructed from @a __s. The
3707 * function then compares the two string by calling
3708 * traits::compare(substring.data(),__s,rlen). If the result of
3709 * the comparison is nonzero returns it, otherwise the shorter
3710 * one is ordered first.
3711 */
3712 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3713 int
3714 compare(size_type __pos, size_type __n1, const _CharT* __s) const
3715 {
3716 __glibcxx_requires_string(__s);
3717 _M_check(__pos, "basic_string::compare");
3718 __n1 = _M_limit(__pos, __n1);
3719 const size_type __osize = traits_type::length(__s);
3720 const size_type __len = std::min(__n1, __osize);
3721 int __r = traits_type::compare(_M_data() + __pos, __s, __len);
3722 if (!__r)
3723 __r = _S_compare(__n1, __osize);
3724 return __r;
3725 }
3726
3727 /**
3728 * @brief Compare substring against a character %array.
3729 * @param __pos Index of first character of substring.
3730 * @param __n1 Number of characters in substring.
3731 * @param __s character %array to compare against.
3732 * @param __n2 Number of characters of s.
3733 * @return Integer < 0, 0, or > 0.
3734 *
3735 * Form the substring of this string from the @a __n1
3736 * characters starting at @a __pos. Form a string from the
3737 * first @a __n2 characters of @a __s. Returns an integer < 0
3738 * if this substring is ordered before the string from @a __s,
3739 * 0 if their values are equivalent, or > 0 if this substring
3740 * is ordered after the string from @a __s. Determines the
3741 * effective length rlen of the strings to compare as the
3742 * smallest of the length of the substring and @a __n2. The
3743 * function then compares the two strings by calling
3744 * traits::compare(substring.data(),s,rlen). If the result of
3745 * the comparison is nonzero returns it, otherwise the shorter
3746 * one is ordered first.
3747 *
3748 * NB: s must have at least n2 characters, &apos;\\0&apos; has
3749 * no special meaning.
3750 */
3751 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3752 int
3753 compare(size_type __pos, size_type __n1, const _CharT* __s,
3754 size_type __n2) const
3755 {
3756 __glibcxx_requires_string_len(__s, __n2);
3757 _M_check(__pos, "basic_string::compare");
3758 __n1 = _M_limit(__pos, __n1);
3759 const size_type __len = std::min(__n1, __n2);
3760 int __r = traits_type::compare(_M_data() + __pos, __s, __len);
3761 if (!__r)
3762 __r = _S_compare(__n1, __n2);
3763 return __r;
3764 }
3765
3766#if __cplusplus201703L >= 202002L
3767 [[nodiscard]]
3768 constexpr bool
3769 starts_with(basic_string_view<_CharT, _Traits> __x) const noexcept
3770 { return __sv_type(this->data(), this->size()).starts_with(__x); }
3771
3772 [[nodiscard]]
3773 constexpr bool
3774 starts_with(_CharT __x) const noexcept
3775 { return __sv_type(this->data(), this->size()).starts_with(__x); }
3776
3777 [[nodiscard, __gnu__::__nonnull__]]
3778 constexpr bool
3779 starts_with(const _CharT* __x) const noexcept
3780 { return __sv_type(this->data(), this->size()).starts_with(__x); }
3781
3782 [[nodiscard]]
3783 constexpr bool
3784 ends_with(basic_string_view<_CharT, _Traits> __x) const noexcept
3785 { return __sv_type(this->data(), this->size()).ends_with(__x); }
3786
3787 [[nodiscard]]
3788 constexpr bool
3789 ends_with(_CharT __x) const noexcept
3790 { return __sv_type(this->data(), this->size()).ends_with(__x); }
3791
3792 [[nodiscard, __gnu__::__nonnull__]]
3793 constexpr bool
3794 ends_with(const _CharT* __x) const noexcept
3795 { return __sv_type(this->data(), this->size()).ends_with(__x); }
3796#endif // C++20
3797
3798#if __cplusplus201703L > 202002L
3799 [[nodiscard]]
3800 constexpr bool
3801 contains(basic_string_view<_CharT, _Traits> __x) const noexcept
3802 { return __sv_type(this->data(), this->size()).contains(__x); }
3803
3804 [[nodiscard]]
3805 constexpr bool
3806 contains(_CharT __x) const noexcept
3807 { return __sv_type(this->data(), this->size()).contains(__x); }
3808
3809 [[nodiscard, __gnu__::__nonnull__]]
3810 constexpr bool
3811 contains(const _CharT* __x) const noexcept
3812 { return __sv_type(this->data(), this->size()).contains(__x); }
3813#endif // C++23
3814
3815 // Allow basic_stringbuf::__xfer_bufptrs to call _M_length:
3816 template<typename, typename, typename> friend class basic_stringbuf;
3817 };
3818_GLIBCXX_END_NAMESPACE_CXX11}
3819_GLIBCXX_END_NAMESPACE_VERSION
3820} // namespace std
3821#endif // _GLIBCXX_USE_CXX11_ABI
3822
3823namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
3824{
3825_GLIBCXX_BEGIN_NAMESPACE_VERSION
3826
3827#if __cpp_deduction_guides201703L >= 201606
3828_GLIBCXX_BEGIN_NAMESPACE_CXX11namespace __cxx11 {
3829 template<typename _InputIterator, typename _CharT
3830 = typename iterator_traits<_InputIterator>::value_type,
3831 typename _Allocator = allocator<_CharT>,
3832 typename = _RequireInputIter<_InputIterator>,
3833 typename = _RequireAllocator<_Allocator>>
3834 basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
3835 -> basic_string<_CharT, char_traits<_CharT>, _Allocator>;
3836
3837 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3838 // 3075. basic_string needs deduction guides from basic_string_view
3839 template<typename _CharT, typename _Traits,
3840 typename _Allocator = allocator<_CharT>,
3841 typename = _RequireAllocator<_Allocator>>
3842 basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator())
3843 -> basic_string<_CharT, _Traits, _Allocator>;
3844
3845 template<typename _CharT, typename _Traits,
3846 typename _Allocator = allocator<_CharT>,
3847 typename = _RequireAllocator<_Allocator>>
3848 basic_string(basic_string_view<_CharT, _Traits>,
3849 typename basic_string<_CharT, _Traits, _Allocator>::size_type,
3850 typename basic_string<_CharT, _Traits, _Allocator>::size_type,
3851 const _Allocator& = _Allocator())
3852 -> basic_string<_CharT, _Traits, _Allocator>;
3853
3854#if __glibcxx_containers_ranges // C++ >= 23
3855 template<ranges::input_range _Rg,
3856 typename _Allocator = allocator<ranges::range_value_t<_Rg>>>
3857 basic_string(from_range_t, _Rg&&, _Allocator = _Allocator())
3858 -> basic_string<ranges::range_value_t<_Rg>,
3859 char_traits<ranges::range_value_t<_Rg>>,
3860 _Allocator>;
3861#endif
3862_GLIBCXX_END_NAMESPACE_CXX11}
3863#endif
3864
3865 template<typename _Str>
3866 _GLIBCXX20_CONSTEXPR
3867 inline _Str
3868 __str_concat(typename _Str::value_type const* __lhs,
3869 typename _Str::size_type __lhs_len,
3870 typename _Str::value_type const* __rhs,
3871 typename _Str::size_type __rhs_len,
3872 typename _Str::allocator_type const& __a)
3873 {
3874 typedef typename _Str::allocator_type allocator_type;
3875 typedef __gnu_cxx::__alloc_traits<allocator_type> _Alloc_traits;
3876 _Str __str(_Alloc_traits::_S_select_on_copy(__a));
3877 __str.reserve(__lhs_len + __rhs_len);
3878 __str.append(__lhs, __lhs_len);
3879 __str.append(__rhs, __rhs_len);
3880 return __str;
3881 }
3882
3883 // operator+
3884 /**
3885 * @brief Concatenate two strings.
3886 * @param __lhs First string.
3887 * @param __rhs Last string.
3888 * @return New string with value of @a __lhs followed by @a __rhs.
3889 */
3890 template<typename _CharT, typename _Traits, typename _Alloc>
3891 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3892 inline basic_string<_CharT, _Traits, _Alloc>
3893 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3894 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
3895 {
3896 typedef basic_string<_CharT, _Traits, _Alloc> _Str;
3897 return std::__str_concat<_Str>(__lhs.c_str(), __lhs.size(),
3898 __rhs.c_str(), __rhs.size(),
3899 __lhs.get_allocator());
3900 }
3901
3902 /**
3903 * @brief Concatenate C string and string.
3904 * @param __lhs First string.
3905 * @param __rhs Last string.
3906 * @return New string with value of @a __lhs followed by @a __rhs.
3907 */
3908 template<typename _CharT, typename _Traits, typename _Alloc>
3909 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3910 inline basic_string<_CharT,_Traits,_Alloc>
3911 operator+(const _CharT* __lhs,
3912 const basic_string<_CharT,_Traits,_Alloc>& __rhs)
3913 {
3914 __glibcxx_requires_string(__lhs);
3915 typedef basic_string<_CharT, _Traits, _Alloc> _Str;
3916 return std::__str_concat<_Str>(__lhs, _Traits::length(__lhs),
3917 __rhs.c_str(), __rhs.size(),
3918 __rhs.get_allocator());
3919 }
3920
3921 /**
3922 * @brief Concatenate character and string.
3923 * @param __lhs First string.
3924 * @param __rhs Last string.
3925 * @return New string with @a __lhs followed by @a __rhs.
3926 */
3927 template<typename _CharT, typename _Traits, typename _Alloc>
3928 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3929 inline basic_string<_CharT,_Traits,_Alloc>
3930 operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs)
3931 {
3932 typedef basic_string<_CharT, _Traits, _Alloc> _Str;
3933 return std::__str_concat<_Str>(__builtin_addressof(__lhs), 1,
3934 __rhs.c_str(), __rhs.size(),
3935 __rhs.get_allocator());
3936 }
3937
3938 /**
3939 * @brief Concatenate string and C string.
3940 * @param __lhs First string.
3941 * @param __rhs Last string.
3942 * @return New string with @a __lhs followed by @a __rhs.
3943 */
3944 template<typename _CharT, typename _Traits, typename _Alloc>
3945 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3946 inline basic_string<_CharT, _Traits, _Alloc>
3947 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3948 const _CharT* __rhs)
3949 {
3950 __glibcxx_requires_string(__rhs);
3951 typedef basic_string<_CharT, _Traits, _Alloc> _Str;
3952 return std::__str_concat<_Str>(__lhs.c_str(), __lhs.size(),
3953 __rhs, _Traits::length(__rhs),
3954 __lhs.get_allocator());
3955 }
3956 /**
3957 * @brief Concatenate string and character.
3958 * @param __lhs First string.
3959 * @param __rhs Last string.
3960 * @return New string with @a __lhs followed by @a __rhs.
3961 */
3962 template<typename _CharT, typename _Traits, typename _Alloc>
3963 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3964 inline basic_string<_CharT, _Traits, _Alloc>
3965 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
3966 {
3967 typedef basic_string<_CharT, _Traits, _Alloc> _Str;
3968 return std::__str_concat<_Str>(__lhs.c_str(), __lhs.size(),
3969 __builtin_addressof(__rhs), 1,
3970 __lhs.get_allocator());
3971 }
3972
3973#if __cplusplus201703L >= 201103L
3974 template<typename _CharT, typename _Traits, typename _Alloc>
3975 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3976 inline basic_string<_CharT, _Traits, _Alloc>
3977 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
3978 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
3979 { return std::move(__lhs.append(__rhs)); }
3980
3981 template<typename _CharT, typename _Traits, typename _Alloc>
3982 _GLIBCXX20_CONSTEXPR
3983 inline basic_string<_CharT, _Traits, _Alloc>
3984 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3985 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
3986 { return std::move(__rhs.insert(0, __lhs)); }
3987
3988 template<typename _CharT, typename _Traits, typename _Alloc>
3989 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
3990 inline basic_string<_CharT, _Traits, _Alloc>
3991 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
3992 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
3993 {
3994#pragma GCC diagnostic push
3995#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
3996 // Return value must use __lhs.get_allocator(), but if __rhs has equal
3997 // allocator then we can choose which parameter to modify in-place.
3998 bool __use_rhs = false;
3999 if constexpr (allocator_traits<_Alloc>::is_always_equal::value)
4000 __use_rhs = true;
4001 else if (__lhs.get_allocator() == __rhs.get_allocator())
4002 __use_rhs = true;
4003 if (__use_rhs)
4004 {
4005 const auto __size = __lhs.size() + __rhs.size();
4006 if (__size > __lhs.capacity() && __size <= __rhs.capacity())
4007 return std::move(__rhs.insert(0, __lhs));
4008 }
4009 return std::move(__lhs.append(__rhs));
4010#pragma GCC diagnostic pop
4011 }
4012
4013 template<typename _CharT, typename _Traits, typename _Alloc>
4014 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
4015 inline basic_string<_CharT, _Traits, _Alloc>
4016 operator+(const _CharT* __lhs,
4017 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
4018 { return std::move(__rhs.insert(0, __lhs)); }
4019
4020 template<typename _CharT, typename _Traits, typename _Alloc>
4021 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
4022 inline basic_string<_CharT, _Traits, _Alloc>
4023 operator+(_CharT __lhs,
4024 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
4025 { return std::move(__rhs.insert(0, 1, __lhs)); }
4026
4027 template<typename _CharT, typename _Traits, typename _Alloc>
4028 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
4029 inline basic_string<_CharT, _Traits, _Alloc>
4030 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
4031 const _CharT* __rhs)
4032 { return std::move(__lhs.append(__rhs)); }
4033
4034 template<typename _CharT, typename _Traits, typename _Alloc>
4035 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
4036 inline basic_string<_CharT, _Traits, _Alloc>
4037 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
4038 _CharT __rhs)
4039 { return std::move(__lhs.append(1, __rhs)); }
4040#endif
4041
4042#if __glibcxx_string_view201803L >= 202403L
4043 // const string & + string_view
4044 template<typename _CharT, typename _Traits, typename _Alloc>
4045 [[nodiscard]]
4046 constexpr basic_string<_CharT, _Traits, _Alloc>
4047 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4048 type_identity_t<basic_string_view<_CharT, _Traits>> __rhs)
4049 {
4050 using _Str = basic_string<_CharT, _Traits, _Alloc>;
4051 return std::__str_concat<_Str>(__lhs.data(), __lhs.size(),
4052 __rhs.data(), __rhs.size(),
4053 __lhs.get_allocator());
4054 }
4055
4056 // string && + string_view
4057 template<typename _CharT, typename _Traits, typename _Alloc>
4058 [[nodiscard]]
4059 constexpr basic_string<_CharT, _Traits, _Alloc>
4060 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
4061 type_identity_t<basic_string_view<_CharT, _Traits>> __rhs)
4062 {
4063 return std::move(__lhs.append(__rhs));
4064 }
4065
4066 // string_view + const string &
4067 template<typename _CharT, typename _Traits, typename _Alloc>
4068 [[nodiscard]]
4069 constexpr basic_string<_CharT, _Traits, _Alloc>
4070 operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
4071 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4072 {
4073 using _Str = basic_string<_CharT, _Traits, _Alloc>;
4074 return std::__str_concat<_Str>(__lhs.data(), __lhs.size(),
4075 __rhs.data(), __rhs.size(),
4076 __rhs.get_allocator());
4077 }
4078
4079 // string_view + string &&
4080 template<typename _CharT, typename _Traits, typename _Alloc>
4081 [[nodiscard]]
4082 constexpr basic_string<_CharT, _Traits, _Alloc>
4083 operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
4084 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
4085 {
4086 return std::move(__rhs.insert(0, __lhs));
4087 }
4088#endif
4089
4090 // operator ==
4091 /**
4092 * @brief Test equivalence of two strings.
4093 * @param __lhs First string.
4094 * @param __rhs Second string.
4095 * @return True if @a __lhs.compare(@a __rhs) == 0. False otherwise.
4096 */
4097 template<typename _CharT, typename _Traits, typename _Alloc>
4098 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
4099 inline bool
4100 operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4101 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4102 _GLIBCXX_NOEXCEPTnoexcept
4103 {
4104 return __lhs.size() == __rhs.size()
4105 && !_Traits::compare(__lhs.data(), __rhs.data(), __lhs.size());
4106 }
4107
4108 /**
4109 * @brief Test equivalence of string and C string.
4110 * @param __lhs String.
4111 * @param __rhs C string.
4112 * @return True if @a __lhs.compare(@a __rhs) == 0. False otherwise.
4113 */
4114 template<typename _CharT, typename _Traits, typename _Alloc>
4115 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
4116 inline bool
4117 operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4118 const _CharT* __rhs)
4119 {
4120 return __lhs.size() == _Traits::length(__rhs)
4121 && !_Traits::compare(__lhs.data(), __rhs, __lhs.size());
4122 }
4123
4124#if __cpp_lib_three_way_comparison
4125 /**
4126 * @brief Three-way comparison of a string and a C string.
4127 * @param __lhs A string.
4128 * @param __rhs A null-terminated string.
4129 * @return A value indicating whether `__lhs` is less than, equal to,
4130 * greater than, or incomparable with `__rhs`.
4131 */
4132 template<typename _CharT, typename _Traits, typename _Alloc>
4133 [[nodiscard]]
4134 constexpr auto
4135 operator<=>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4136 const basic_string<_CharT, _Traits, _Alloc>& __rhs) noexcept
4137 -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
4138 { return __detail::__char_traits_cmp_cat<_Traits>(__lhs.compare(__rhs)); }
4139
4140 /**
4141 * @brief Three-way comparison of a string and a C string.
4142 * @param __lhs A string.
4143 * @param __rhs A null-terminated string.
4144 * @return A value indicating whether `__lhs` is less than, equal to,
4145 * greater than, or incomparable with `__rhs`.
4146 */
4147 template<typename _CharT, typename _Traits, typename _Alloc>
4148 [[nodiscard]]
4149 constexpr auto
4150 operator<=>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4151 const _CharT* __rhs) noexcept
4152 -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
4153 { return __detail::__char_traits_cmp_cat<_Traits>(__lhs.compare(__rhs)); }
4154#else
4155 /**
4156 * @brief Test equivalence of C string and string.
4157 * @param __lhs C string.
4158 * @param __rhs String.
4159 * @return True if @a __rhs.compare(@a __lhs) == 0. False otherwise.
4160 */
4161 template<typename _CharT, typename _Traits, typename _Alloc>
4162 _GLIBCXX_NODISCARD[[__nodiscard__]]
4163 inline bool
4164 operator==(const _CharT* __lhs,
4165 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4166 { return __rhs == __lhs; }
4167
4168 // operator !=
4169 /**
4170 * @brief Test difference of two strings.
4171 * @param __lhs First string.
4172 * @param __rhs Second string.
4173 * @return True if @a __lhs.compare(@a __rhs) != 0. False otherwise.
4174 */
4175 template<typename _CharT, typename _Traits, typename _Alloc>
4176 _GLIBCXX_NODISCARD[[__nodiscard__]]
4177 inline bool
4178 operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4179 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4180 _GLIBCXX_NOEXCEPTnoexcept
4181 { return !(__lhs == __rhs); }
4182
4183 /**
4184 * @brief Test difference of C string and string.
4185 * @param __lhs C string.
4186 * @param __rhs String.
4187 * @return True if @a __rhs.compare(@a __lhs) != 0. False otherwise.
4188 */
4189 template<typename _CharT, typename _Traits, typename _Alloc>
4190 _GLIBCXX_NODISCARD[[__nodiscard__]]
4191 inline bool
4192 operator!=(const _CharT* __lhs,
4193 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4194 { return !(__rhs == __lhs); }
4195
4196 /**
4197 * @brief Test difference of string and C string.
4198 * @param __lhs String.
4199 * @param __rhs C string.
4200 * @return True if @a __lhs.compare(@a __rhs) != 0. False otherwise.
4201 */
4202 template<typename _CharT, typename _Traits, typename _Alloc>
4203 _GLIBCXX_NODISCARD[[__nodiscard__]]
4204 inline bool
4205 operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4206 const _CharT* __rhs)
4207 { return !(__lhs == __rhs); }
4208
4209 // operator <
4210 /**
4211 * @brief Test if string precedes string.
4212 * @param __lhs First string.
4213 * @param __rhs Second string.
4214 * @return True if @a __lhs precedes @a __rhs. False otherwise.
4215 */
4216 template<typename _CharT, typename _Traits, typename _Alloc>
4217 _GLIBCXX_NODISCARD[[__nodiscard__]]
4218 inline bool
4219 operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4220 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4221 _GLIBCXX_NOEXCEPTnoexcept
4222 { return __lhs.compare(__rhs) < 0; }
4223
4224 /**
4225 * @brief Test if string precedes C string.
4226 * @param __lhs String.
4227 * @param __rhs C string.
4228 * @return True if @a __lhs precedes @a __rhs. False otherwise.
4229 */
4230 template<typename _CharT, typename _Traits, typename _Alloc>
4231 _GLIBCXX_NODISCARD[[__nodiscard__]]
4232 inline bool
4233 operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4234 const _CharT* __rhs)
4235 { return __lhs.compare(__rhs) < 0; }
4236
4237 /**
4238 * @brief Test if C string precedes string.
4239 * @param __lhs C string.
4240 * @param __rhs String.
4241 * @return True if @a __lhs precedes @a __rhs. False otherwise.
4242 */
4243 template<typename _CharT, typename _Traits, typename _Alloc>
4244 _GLIBCXX_NODISCARD[[__nodiscard__]]
4245 inline bool
4246 operator<(const _CharT* __lhs,
4247 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4248 { return __rhs.compare(__lhs) > 0; }
4249
4250 // operator >
4251 /**
4252 * @brief Test if string follows string.
4253 * @param __lhs First string.
4254 * @param __rhs Second string.
4255 * @return True if @a __lhs follows @a __rhs. False otherwise.
4256 */
4257 template<typename _CharT, typename _Traits, typename _Alloc>
4258 _GLIBCXX_NODISCARD[[__nodiscard__]]
4259 inline bool
4260 operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4261 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4262 _GLIBCXX_NOEXCEPTnoexcept
4263 { return __lhs.compare(__rhs) > 0; }
4264
4265 /**
4266 * @brief Test if string follows C string.
4267 * @param __lhs String.
4268 * @param __rhs C string.
4269 * @return True if @a __lhs follows @a __rhs. False otherwise.
4270 */
4271 template<typename _CharT, typename _Traits, typename _Alloc>
4272 _GLIBCXX_NODISCARD[[__nodiscard__]]
4273 inline bool
4274 operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4275 const _CharT* __rhs)
4276 { return __lhs.compare(__rhs) > 0; }
4277
4278 /**
4279 * @brief Test if C string follows string.
4280 * @param __lhs C string.
4281 * @param __rhs String.
4282 * @return True if @a __lhs follows @a __rhs. False otherwise.
4283 */
4284 template<typename _CharT, typename _Traits, typename _Alloc>
4285 _GLIBCXX_NODISCARD[[__nodiscard__]]
4286 inline bool
4287 operator>(const _CharT* __lhs,
4288 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4289 { return __rhs.compare(__lhs) < 0; }
4290
4291 // operator <=
4292 /**
4293 * @brief Test if string doesn't follow string.
4294 * @param __lhs First string.
4295 * @param __rhs Second string.
4296 * @return True if @a __lhs doesn't follow @a __rhs. False otherwise.
4297 */
4298 template<typename _CharT, typename _Traits, typename _Alloc>
4299 _GLIBCXX_NODISCARD[[__nodiscard__]]
4300 inline bool
4301 operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4302 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4303 _GLIBCXX_NOEXCEPTnoexcept
4304 { return __lhs.compare(__rhs) <= 0; }
4305
4306 /**
4307 * @brief Test if string doesn't follow C string.
4308 * @param __lhs String.
4309 * @param __rhs C string.
4310 * @return True if @a __lhs doesn't follow @a __rhs. False otherwise.
4311 */
4312 template<typename _CharT, typename _Traits, typename _Alloc>
4313 _GLIBCXX_NODISCARD[[__nodiscard__]]
4314 inline bool
4315 operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4316 const _CharT* __rhs)
4317 { return __lhs.compare(__rhs) <= 0; }
4318
4319 /**
4320 * @brief Test if C string doesn't follow string.
4321 * @param __lhs C string.
4322 * @param __rhs String.
4323 * @return True if @a __lhs doesn't follow @a __rhs. False otherwise.
4324 */
4325 template<typename _CharT, typename _Traits, typename _Alloc>
4326 _GLIBCXX_NODISCARD[[__nodiscard__]]
4327 inline bool
4328 operator<=(const _CharT* __lhs,
4329 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4330 { return __rhs.compare(__lhs) >= 0; }
4331
4332 // operator >=
4333 /**
4334 * @brief Test if string doesn't precede string.
4335 * @param __lhs First string.
4336 * @param __rhs Second string.
4337 * @return True if @a __lhs doesn't precede @a __rhs. False otherwise.
4338 */
4339 template<typename _CharT, typename _Traits, typename _Alloc>
4340 _GLIBCXX_NODISCARD[[__nodiscard__]]
4341 inline bool
4342 operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4343 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4344 _GLIBCXX_NOEXCEPTnoexcept
4345 { return __lhs.compare(__rhs) >= 0; }
4346
4347 /**
4348 * @brief Test if string doesn't precede C string.
4349 * @param __lhs String.
4350 * @param __rhs C string.
4351 * @return True if @a __lhs doesn't precede @a __rhs. False otherwise.
4352 */
4353 template<typename _CharT, typename _Traits, typename _Alloc>
4354 _GLIBCXX_NODISCARD[[__nodiscard__]]
4355 inline bool
4356 operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4357 const _CharT* __rhs)
4358 { return __lhs.compare(__rhs) >= 0; }
4359
4360 /**
4361 * @brief Test if C string doesn't precede string.
4362 * @param __lhs C string.
4363 * @param __rhs String.
4364 * @return True if @a __lhs doesn't precede @a __rhs. False otherwise.
4365 */
4366 template<typename _CharT, typename _Traits, typename _Alloc>
4367 _GLIBCXX_NODISCARD[[__nodiscard__]]
4368 inline bool
4369 operator>=(const _CharT* __lhs,
4370 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4371 { return __rhs.compare(__lhs) <= 0; }
4372#endif // three-way comparison
4373
4374 /**
4375 * @brief Swap contents of two strings.
4376 * @param __lhs First string.
4377 * @param __rhs Second string.
4378 *
4379 * Exchanges the contents of @a __lhs and @a __rhs in constant time.
4380 */
4381 template<typename _CharT, typename _Traits, typename _Alloc>
4382 _GLIBCXX20_CONSTEXPR
4383 inline void
4384 swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
4385 basic_string<_CharT, _Traits, _Alloc>& __rhs)
4386 _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))noexcept(noexcept(__lhs.swap(__rhs)))
4387 { __lhs.swap(__rhs); }
4388
4389
4390 /**
4391 * @brief Read stream into a string.
4392 * @param __is Input stream.
4393 * @param __str Buffer to store into.
4394 * @return Reference to the input stream.
4395 *
4396 * Stores characters from @a __is into @a __str until whitespace is
4397 * found, the end of the stream is encountered, or str.max_size()
4398 * is reached. If is.width() is non-zero, that is the limit on the
4399 * number of characters stored into @a __str. Any previous
4400 * contents of @a __str are erased.
4401 */
4402 template<typename _CharT, typename _Traits, typename _Alloc>
4403 basic_istream<_CharT, _Traits>&
4404 operator>>(basic_istream<_CharT, _Traits>& __is,
4405 basic_string<_CharT, _Traits, _Alloc>& __str);
4406
4407 template<>
4408 basic_istream<char>&
4409 operator>>(basic_istream<char>& __is, basic_string<char>& __str);
4410
4411 /**
4412 * @brief Write string to a stream.
4413 * @param __os Output stream.
4414 * @param __str String to write out.
4415 * @return Reference to the output stream.
4416 *
4417 * Output characters of @a __str into os following the same rules as for
4418 * writing a C string.
4419 */
4420 template<typename _CharT, typename _Traits, typename _Alloc>
4421 inline basic_ostream<_CharT, _Traits>&
4422 operator<<(basic_ostream<_CharT, _Traits>& __os,
4423 const basic_string<_CharT, _Traits, _Alloc>& __str)
4424 {
4425 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4426 // 586. string inserter not a formatted function
4427 return __ostream_insert(__os, __str.data(), __str.size());
4428 }
4429
4430 /**
4431 * @brief Read a line from stream into a string.
4432 * @param __is Input stream.
4433 * @param __str Buffer to store into.
4434 * @param __delim Character marking end of line.
4435 * @return Reference to the input stream.
4436 *
4437 * Stores characters from @a __is into @a __str until @a __delim is
4438 * found, the end of the stream is encountered, or str.max_size()
4439 * is reached. Any previous contents of @a __str are erased. If
4440 * @a __delim is encountered, it is extracted but not stored into
4441 * @a __str.
4442 */
4443 template<typename _CharT, typename _Traits, typename _Alloc>
4444 basic_istream<_CharT, _Traits>&
4445 getline(basic_istream<_CharT, _Traits>& __is,
4446 basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
4447
4448 /**
4449 * @brief Read a line from stream into a string.
4450 * @param __is Input stream.
4451 * @param __str Buffer to store into.
4452 * @return Reference to the input stream.
4453 *
4454 * Stores characters from is into @a __str until &apos;\n&apos; is
4455 * found, the end of the stream is encountered, or str.max_size()
4456 * is reached. Any previous contents of @a __str are erased. If
4457 * end of line is encountered, it is extracted but not stored into
4458 * @a __str.
4459 */
4460 template<typename _CharT, typename _Traits, typename _Alloc>
4461 inline basic_istream<_CharT, _Traits>&
4462 getline(basic_istream<_CharT, _Traits>& __is,
4463 basic_string<_CharT, _Traits, _Alloc>& __str)
4464 { return std::getline(__is, __str, __is.widen('\n')); }
4465
4466#if __cplusplus201703L >= 201103L
4467 /// Read a line from an rvalue stream into a string.
4468 template<typename _CharT, typename _Traits, typename _Alloc>
4469 inline basic_istream<_CharT, _Traits>&
4470 getline(basic_istream<_CharT, _Traits>&& __is,
4471 basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
4472 { return std::getline(__is, __str, __delim); }
4473
4474 /// Read a line from an rvalue stream into a string.
4475 template<typename _CharT, typename _Traits, typename _Alloc>
4476 inline basic_istream<_CharT, _Traits>&
4477 getline(basic_istream<_CharT, _Traits>&& __is,
4478 basic_string<_CharT, _Traits, _Alloc>& __str)
4479 { return std::getline(__is, __str); }
4480#endif
4481
4482 template<>
4483 basic_istream<char>&
4484 getline(basic_istream<char>& __in, basic_string<char>& __str,
4485 char __delim);
4486
4487#ifdef _GLIBCXX_USE_WCHAR_T1
4488 template<>
4489 basic_istream<wchar_t>&
4490 getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
4491 wchar_t __delim);
4492#endif
4493
4494_GLIBCXX_END_NAMESPACE_VERSION
4495} // namespace
4496
4497#if __cplusplus201703L >= 201103L
4498
4499#include <ext/string_conversions.h>
4500#include <bits/charconv.h>
4501
4502namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
4503{
4504_GLIBCXX_BEGIN_NAMESPACE_VERSION
4505_GLIBCXX_BEGIN_NAMESPACE_CXX11namespace __cxx11 {
4506
4507 // 21.4 Numeric Conversions [string.conversions].
4508 inline int
4509 stoi(const string& __str, size_t* __idx = 0, int __base = 10)
4510 { return __gnu_cxx::__stoa<long, int>(&std::strtol, "stoi", __str.c_str(),
4511 __idx, __base); }
4512
4513 inline long
4514 stol(const string& __str, size_t* __idx = 0, int __base = 10)
4515 { return __gnu_cxx::__stoa(&std::strtol, "stol", __str.c_str(),
4516 __idx, __base); }
4517
4518 inline unsigned long
4519 stoul(const string& __str, size_t* __idx = 0, int __base = 10)
4520 { return __gnu_cxx::__stoa(&std::strtoul, "stoul", __str.c_str(),
4521 __idx, __base); }
4522
4523#if _GLIBCXX_USE_C99_STDLIB1
4524 inline long long
4525 stoll(const string& __str, size_t* __idx = 0, int __base = 10)
4526 { return __gnu_cxx::__stoa(&std::strtoll, "stoll", __str.c_str(),
4527 __idx, __base); }
4528
4529 inline unsigned long long
4530 stoull(const string& __str, size_t* __idx = 0, int __base = 10)
4531 { return __gnu_cxx::__stoa(&std::strtoull, "stoull", __str.c_str(),
4532 __idx, __base); }
4533#elif __LONG_WIDTH__64 == __LONG_LONG_WIDTH__
4534 inline long long
4535 stoll(const string& __str, size_t* __idx = 0, int __base = 10)
4536 { return std::stol(__str, __idx, __base); }
4537
4538 inline unsigned long long
4539 stoull(const string& __str, size_t* __idx = 0, int __base = 10)
4540 { return std::stoul(__str, __idx, __base); }
4541#endif
4542
4543 inline double
4544 stod(const string& __str, size_t* __idx = 0)
4545 { return __gnu_cxx::__stoa(&std::strtod, "stod", __str.c_str(), __idx); }
4546
4547#if _GLIBCXX_HAVE_STRTOF1
4548 // NB: strtof vs strtod.
4549 inline float
4550 stof(const string& __str, size_t* __idx = 0)
4551 { return __gnu_cxx::__stoa(&std::strtof, "stof", __str.c_str(), __idx); }
4552#else
4553 inline float
4554 stof(const string& __str, size_t* __idx = 0)
4555 {
4556 double __d = std::stod(__str, __idx);
4557 if (__builtin_isfinite(__d) && __d != 0.0)
4558 {
4559 double __abs_d = __builtin_fabs(__d);
4560 if (__abs_d < __FLT_MIN__1.17549435e-38F || __abs_d > __FLT_MAX__3.40282347e+38F)
4561 {
4562 errno(*__errno_location ()) = ERANGE34;
4563 std::__throw_out_of_range("stof");
4564 }
4565 }
4566 return __d;
4567 }
4568#endif
4569
4570#if _GLIBCXX_HAVE_STRTOLD1 && ! _GLIBCXX_HAVE_BROKEN_STRTOLD
4571 inline long double
4572 stold(const string& __str, size_t* __idx = 0)
4573 { return __gnu_cxx::__stoa(&std::strtold, "stold", __str.c_str(), __idx); }
4574#elif __DBL_MANT_DIG__53 == __LDBL_MANT_DIG__64
4575 inline long double
4576 stold(const string& __str, size_t* __idx = 0)
4577 { return std::stod(__str, __idx); }
4578#endif
4579
4580 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4581 // DR 1261. Insufficent overloads for to_string / to_wstring
4582
4583 _GLIBCXX_NODISCARD[[__nodiscard__]]
4584 inline string
4585 to_string(int __val)
4586#if _GLIBCXX_USE_CXX11_ABI1 && (__CHAR_BIT__8 * __SIZEOF_INT__4) <= 32
4587 noexcept // any 32-bit value fits in the SSO buffer
4588#endif
4589 {
4590 const bool __neg = __val < 0;
4591 const unsigned __uval = __neg ? (unsigned)~__val + 1u : __val;
4592 const auto __len = __detail::__to_chars_len(__uval);
4593 string __str;
4594 __str.__resize_and_overwrite(__neg + __len, [=](char* __p, size_t __n) {
4595 __p[0] = '-';
4596 __detail::__to_chars_10_impl(__p + (int)__neg, __len, __uval);
4597 return __n;
4598 });
4599 return __str;
4600 }
4601
4602 _GLIBCXX_NODISCARD[[__nodiscard__]]
4603 inline string
4604 to_string(unsigned __val)
4605#if _GLIBCXX_USE_CXX11_ABI1 && (__CHAR_BIT__8 * __SIZEOF_INT__4) <= 32
4606 noexcept // any 32-bit value fits in the SSO buffer
4607#endif
4608 {
4609 const auto __len = __detail::__to_chars_len(__val);
4610 string __str;
4611 __str.__resize_and_overwrite(__len, [__val](char* __p, size_t __n) {
4612 __detail::__to_chars_10_impl(__p, __n, __val);
4613 return __n;
4614 });
4615 return __str;
4616 }
4617
4618 _GLIBCXX_NODISCARD[[__nodiscard__]]
4619 inline string
4620 to_string(long __val)
4621#if _GLIBCXX_USE_CXX11_ABI1 && (__CHAR_BIT__8 * __SIZEOF_LONG__8) <= 32
4622 noexcept // any 32-bit value fits in the SSO buffer
4623#endif
4624 {
4625 const bool __neg = __val < 0;
4626 const unsigned long __uval = __neg ? (unsigned long)~__val + 1ul : __val;
4627 const auto __len = __detail::__to_chars_len(__uval);
4628 string __str;
4629 __str.__resize_and_overwrite(__neg + __len, [=](char* __p, size_t __n) {
4630 __p[0] = '-';
4631 __detail::__to_chars_10_impl(__p + (int)__neg, __len, __uval);
4632 return __n;
4633 });
4634 return __str;
4635 }
4636
4637 _GLIBCXX_NODISCARD[[__nodiscard__]]
4638 inline string
4639 to_string(unsigned long __val)
4640#if _GLIBCXX_USE_CXX11_ABI1 && (__CHAR_BIT__8 * __SIZEOF_LONG__8) <= 32
4641 noexcept // any 32-bit value fits in the SSO buffer
4642#endif
4643 {
4644 const auto __len = __detail::__to_chars_len(__val);
4645 string __str;
4646 __str.__resize_and_overwrite(__len, [__val](char* __p, size_t __n) {
4647 __detail::__to_chars_10_impl(__p, __n, __val);
4648 return __n;
4649 });
4650 return __str;
4651 }
4652
4653 _GLIBCXX_NODISCARD[[__nodiscard__]]
4654 inline string
4655 to_string(long long __val)
4656 {
4657 const bool __neg = __val < 0;
4658 const unsigned long long __uval
4659 = __neg ? (unsigned long long)~__val + 1ull : __val;
4660 const auto __len = __detail::__to_chars_len(__uval);
4661 string __str;
4662 __str.__resize_and_overwrite(__neg + __len, [=](char* __p, size_t __n) {
4663 __p[0] = '-';
4664 __detail::__to_chars_10_impl(__p + (int)__neg, __len, __uval);
4665 return __n;
4666 });
4667 return __str;
4668 }
4669
4670 _GLIBCXX_NODISCARD[[__nodiscard__]]
4671 inline string
4672 to_string(unsigned long long __val)
4673 {
4674 const auto __len = __detail::__to_chars_len(__val);
4675 string __str;
4676 __str.__resize_and_overwrite(__len, [__val](char* __p, size_t __n) {
4677 __detail::__to_chars_10_impl(__p, __n, __val);
4678 return __n;
4679 });
4680 return __str;
4681 }
4682
4683#if __glibcxx_to_string >= 202306L // C++ >= 26
4684
4685 [[nodiscard]]
4686 inline string
4687 to_string(float __val)
4688 {
4689 string __str;
4690 size_t __len = 15;
4691 do {
4692 __str.resize_and_overwrite(__len,
4693 [__val, &__len] (char* __p, size_t __n) {
4694 auto [__end, __err] = std::to_chars(__p, __p + __n, __val);
4695 if (__err == errc{}) [[likely]]
4696 return __end - __p;
4697 __len *= 2;
4698 return __p - __p;;
4699 });
4700 } while (__str.empty());
4701 return __str;
4702 }
4703
4704 [[nodiscard]]
4705 inline string
4706 to_string(double __val)
4707 {
4708 string __str;
4709 size_t __len = 15;
4710 do {
4711 __str.resize_and_overwrite(__len,
4712 [__val, &__len] (char* __p, size_t __n) {
4713 auto [__end, __err] = std::to_chars(__p, __p + __n, __val);
4714 if (__err == errc{}) [[likely]]
4715 return __end - __p;
4716 __len *= 2;
4717 return __p - __p;;
4718 });
4719 } while (__str.empty());
4720 return __str;
4721 }
4722
4723 [[nodiscard]]
4724 inline string
4725 to_string(long double __val)
4726 {
4727 string __str;
4728 size_t __len = 15;
4729 do {
4730 __str.resize_and_overwrite(__len,
4731 [__val, &__len] (char* __p, size_t __n) {
4732 auto [__end, __err] = std::to_chars(__p, __p + __n, __val);
4733 if (__err == errc{}) [[likely]]
4734 return __end - __p;
4735 __len *= 2;
4736 return __p - __p;;
4737 });
4738 } while (__str.empty());
4739 return __str;
4740 }
4741#elif _GLIBCXX_USE_C99_STDIO1
4742#pragma GCC diagnostic push
4743#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
4744 // NB: (v)snprintf vs sprintf.
4745
4746 _GLIBCXX_NODISCARD[[__nodiscard__]]
4747 inline string
4748 to_string(float __val)
4749 {
4750 const int __n =
4751 __gnu_cxx::__numeric_traits<float>::__max_exponent10 + 20;
4752 return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
4753 "%f", __val);
4754 }
4755
4756 _GLIBCXX_NODISCARD[[__nodiscard__]]
4757 inline string
4758 to_string(double __val)
4759 {
4760 const int __n =
4761 __gnu_cxx::__numeric_traits<double>::__max_exponent10 + 20;
4762 return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
4763 "%f", __val);
4764 }
4765
4766 _GLIBCXX_NODISCARD[[__nodiscard__]]
4767 inline string
4768 to_string(long double __val)
4769 {
4770 const int __n =
4771 __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 20;
4772 return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
4773 "%Lf", __val);
4774 }
4775#pragma GCC diagnostic pop
4776#endif // _GLIBCXX_USE_C99_STDIO
4777
4778#if defined(_GLIBCXX_USE_WCHAR_T1) && _GLIBCXX_USE_C99_WCHAR1
4779 inline int
4780 stoi(const wstring& __str, size_t* __idx = 0, int __base = 10)
4781 { return __gnu_cxx::__stoa<long, int>(&std::wcstol, "stoi", __str.c_str(),
4782 __idx, __base); }
4783
4784 inline long
4785 stol(const wstring& __str, size_t* __idx = 0, int __base = 10)
4786 { return __gnu_cxx::__stoa(&std::wcstol, "stol", __str.c_str(),
4787 __idx, __base); }
4788
4789 inline unsigned long
4790 stoul(const wstring& __str, size_t* __idx = 0, int __base = 10)
4791 { return __gnu_cxx::__stoa(&std::wcstoul, "stoul", __str.c_str(),
4792 __idx, __base); }
4793
4794 inline long long
4795 stoll(const wstring& __str, size_t* __idx = 0, int __base = 10)
4796 { return __gnu_cxx::__stoa(&std::wcstoll, "stoll", __str.c_str(),
4797 __idx, __base); }
4798
4799 inline unsigned long long
4800 stoull(const wstring& __str, size_t* __idx = 0, int __base = 10)
4801 { return __gnu_cxx::__stoa(&std::wcstoull, "stoull", __str.c_str(),
4802 __idx, __base); }
4803
4804 // NB: wcstof vs wcstod.
4805 inline float
4806 stof(const wstring& __str, size_t* __idx = 0)
4807 { return __gnu_cxx::__stoa(&std::wcstof, "stof", __str.c_str(), __idx); }
4808
4809 inline double
4810 stod(const wstring& __str, size_t* __idx = 0)
4811 { return __gnu_cxx::__stoa(&std::wcstod, "stod", __str.c_str(), __idx); }
4812
4813 inline long double
4814 stold(const wstring& __str, size_t* __idx = 0)
4815 { return __gnu_cxx::__stoa(&std::wcstold, "stold", __str.c_str(), __idx); }
4816#endif
4817
4818#ifdef _GLIBCXX_USE_WCHAR_T1
4819#pragma GCC diagnostic push
4820#pragma GCC diagnostic ignored "-Wc++17-extensions"
4821 _GLIBCXX20_CONSTEXPR
4822 inline void
4823 __to_wstring_numeric(const char* __s, int __len, wchar_t* __wout)
4824 {
4825 // This condition is true if exec-charset and wide-exec-charset share the
4826 // same values for the ASCII subset or the EBCDIC invariant character set.
4827 if constexpr (wchar_t('0') == L'0' && wchar_t('-') == L'-'
4828 && wchar_t('.') == L'.' && wchar_t('e') == L'e')
4829 {
4830 for (int __i = 0; __i < __len; ++__i)
4831 __wout[__i] = (wchar_t) __s[__i];
4832 }
4833 else
4834 {
4835 wchar_t __wc[256];
4836 for (int __i = '0'; __i <= '9'; ++__i)
4837 __wc[__i] = L'0' + __i;
4838 __wc['.'] = L'.';
4839 __wc['+'] = L'+';
4840 __wc['-'] = L'-';
4841 __wc['a'] = L'a';
4842 __wc['b'] = L'b';
4843 __wc['c'] = L'c';
4844 __wc['d'] = L'd';
4845 __wc['e'] = L'e';
4846 __wc['f'] = L'f';
4847 __wc['i'] = L'i'; // for "inf"
4848 __wc['n'] = L'n'; // for "nan" and "inf"
4849 __wc['p'] = L'p'; // for hexfloats "0x1p1"
4850 __wc['x'] = L'x';
4851 __wc['A'] = L'A';
4852 __wc['B'] = L'B';
4853 __wc['C'] = L'C';
4854 __wc['D'] = L'D';
4855 __wc['E'] = L'E';
4856 __wc['F'] = L'F';
4857 __wc['I'] = L'I';
4858 __wc['N'] = L'N';
4859 __wc['P'] = L'P';
4860 __wc['X'] = L'X';
4861
4862 for (int __i = 0; __i < __len; ++__i)
4863 __wout[__i] = __wc[(int)__s[__i]];
4864 }
4865 }
4866
4867#if __glibcxx_constexpr_string201611L >= 201907L
4868 constexpr
4869#endif
4870 inline wstring
4871#ifdef __glibcxx_string_view201803L // >= C++17
4872 __to_wstring_numeric(string_view __s)
4873#else
4874 __to_wstring_numeric(const string& __s)
4875#endif
4876 {
4877 if constexpr (wchar_t('0') == L'0' && wchar_t('-') == L'-'
4878 && wchar_t('.') == L'.' && wchar_t('e') == L'e')
4879 return wstring(__s.data(), __s.data() + __s.size());
4880 else
4881 {
4882 wstring __ws;
4883 auto __f = __s.data();
4884 __ws.__resize_and_overwrite(__s.size(),
4885 [__f] (wchar_t* __to, int __n) {
4886 std::__to_wstring_numeric(__f, __n, __to);
4887 return __n;
4888 });
4889 return __ws;
4890 }
4891 }
4892#pragma GCC diagnostic pop
4893
4894 _GLIBCXX_NODISCARD[[__nodiscard__]]
4895 inline wstring
4896 to_wstring(int __val)
4897 { return std::__to_wstring_numeric(std::to_string(__val)); }
4898
4899 _GLIBCXX_NODISCARD[[__nodiscard__]]
4900 inline wstring
4901 to_wstring(unsigned __val)
4902 { return std::__to_wstring_numeric(std::to_string(__val)); }
4903
4904 _GLIBCXX_NODISCARD[[__nodiscard__]]
4905 inline wstring
4906 to_wstring(long __val)
4907 { return std::__to_wstring_numeric(std::to_string(__val)); }
4908
4909 _GLIBCXX_NODISCARD[[__nodiscard__]]
4910 inline wstring
4911 to_wstring(unsigned long __val)
4912 { return std::__to_wstring_numeric(std::to_string(__val)); }
4913
4914 _GLIBCXX_NODISCARD[[__nodiscard__]]
4915 inline wstring
4916 to_wstring(long long __val)
4917 { return std::__to_wstring_numeric(std::to_string(__val)); }
4918
4919 _GLIBCXX_NODISCARD[[__nodiscard__]]
4920 inline wstring
4921 to_wstring(unsigned long long __val)
4922 { return std::__to_wstring_numeric(std::to_string(__val)); }
4923
4924#if __glibcxx_to_string || _GLIBCXX_USE_C99_STDIO1
4925 _GLIBCXX_NODISCARD[[__nodiscard__]]
4926 inline wstring
4927 to_wstring(float __val)
4928 { return std::__to_wstring_numeric(std::to_string(__val)); }
4929
4930 _GLIBCXX_NODISCARD[[__nodiscard__]]
4931 inline wstring
4932 to_wstring(double __val)
4933 { return std::__to_wstring_numeric(std::to_string(__val)); }
4934
4935 _GLIBCXX_NODISCARD[[__nodiscard__]]
4936 inline wstring
4937 to_wstring(long double __val)
4938 { return std::__to_wstring_numeric(std::to_string(__val)); }
4939#endif
4940#endif // _GLIBCXX_USE_WCHAR_T
4941
4942_GLIBCXX_END_NAMESPACE_CXX11}
4943_GLIBCXX_END_NAMESPACE_VERSION
4944} // namespace
4945
4946#endif /* C++11 */
4947
4948#if __cplusplus201703L >= 201103L
4949
4950#include <bits/functional_hash.h>
4951
4952namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
4953{
4954_GLIBCXX_BEGIN_NAMESPACE_VERSION
4955
4956 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4957 // 3705. Hashability shouldn't depend on basic_string's allocator
4958
4959 template<typename _CharT, typename _Alloc,
4960 typename _StrT = basic_string<_CharT, char_traits<_CharT>, _Alloc>>
4961 struct __str_hash_base
4962 : public __hash_base<size_t, _StrT>
4963 {
4964 [[__nodiscard__]]
4965 size_t
4966 operator()(const _StrT& __s) const noexcept
4967 { return _Hash_impl::hash(__s.data(), __s.length() * sizeof(_CharT)); }
4968 };
4969
4970#ifndef _GLIBCXX_COMPATIBILITY_CXX0X
4971 /// std::hash specialization for string.
4972 template<typename _Alloc>
4973 struct hash<basic_string<char, char_traits<char>, _Alloc>>
4974 : public __str_hash_base<char, _Alloc>
4975 { };
4976
4977 /// std::hash specialization for wstring.
4978 template<typename _Alloc>
4979 struct hash<basic_string<wchar_t, char_traits<wchar_t>, _Alloc>>
4980 : public __str_hash_base<wchar_t, _Alloc>
4981 { };
4982
4983 template<typename _Alloc>
4984 struct __is_fast_hash<hash<basic_string<wchar_t, char_traits<wchar_t>,
4985 _Alloc>>>
4986 : std::false_type
4987 { };
4988#endif /* _GLIBCXX_COMPATIBILITY_CXX0X */
4989
4990#ifdef _GLIBCXX_USE_CHAR8_T
4991 /// std::hash specialization for u8string.
4992 template<typename _Alloc>
4993 struct hash<basic_string<char8_t, char_traits<char8_t>, _Alloc>>
4994 : public __str_hash_base<char8_t, _Alloc>
4995 { };
4996#endif
4997
4998 /// std::hash specialization for u16string.
4999 template<typename _Alloc>
5000 struct hash<basic_string<char16_t, char_traits<char16_t>, _Alloc>>
5001 : public __str_hash_base<char16_t, _Alloc>
5002 { };
5003
5004 /// std::hash specialization for u32string.
5005 template<typename _Alloc>
5006 struct hash<basic_string<char32_t, char_traits<char32_t>, _Alloc>>
5007 : public __str_hash_base<char32_t, _Alloc>
5008 { };
5009
5010#if ! _GLIBCXX_INLINE_VERSION0
5011 // PR libstdc++/105907 - __is_fast_hash affects unordered container ABI.
5012 template<> struct __is_fast_hash<hash<string>> : std::false_type { };
5013 template<> struct __is_fast_hash<hash<wstring>> : std::false_type { };
5014 template<> struct __is_fast_hash<hash<u16string>> : std::false_type { };
5015 template<> struct __is_fast_hash<hash<u32string>> : std::false_type { };
5016#ifdef _GLIBCXX_USE_CHAR8_T
5017 template<> struct __is_fast_hash<hash<u8string>> : std::false_type { };
5018#endif
5019#else
5020 // For versioned namespace, assume every std::hash<basic_string<>> is slow.
5021 template<typename _CharT, typename _Traits, typename _Alloc>
5022 struct __is_fast_hash<hash<basic_string<_CharT, _Traits, _Alloc>>>
5023 : std::false_type
5024 { };
5025#endif
5026
5027#ifdef __glibcxx_string_udls201304L // C++ >= 14
5028 inline namespace literals
5029 {
5030 inline namespace string_literals
5031 {
5032#pragma GCC diagnostic push
5033#pragma GCC diagnostic ignored "-Wliteral-suffix"
5034
5035#if __glibcxx_constexpr_string201611L >= 201907L
5036# define _GLIBCXX_STRING_CONSTEXPR constexpr
5037#else
5038# define _GLIBCXX_STRING_CONSTEXPR
5039#endif
5040
5041 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11"))) _GLIBCXX_STRING_CONSTEXPR
5042 inline basic_string<char>
5043 operator""s(const char* __str, size_t __len)
5044 { return basic_string<char>{__str, __len}; }
5045
5046 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11"))) _GLIBCXX_STRING_CONSTEXPR
5047 inline basic_string<wchar_t>
5048 operator""s(const wchar_t* __str, size_t __len)
5049 { return basic_string<wchar_t>{__str, __len}; }
5050
5051#ifdef _GLIBCXX_USE_CHAR8_T
5052 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11"))) _GLIBCXX_STRING_CONSTEXPR
5053 inline basic_string<char8_t>
5054 operator""s(const char8_t* __str, size_t __len)
5055 { return basic_string<char8_t>{__str, __len}; }
5056#endif
5057
5058 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11"))) _GLIBCXX_STRING_CONSTEXPR
5059 inline basic_string<char16_t>
5060 operator""s(const char16_t* __str, size_t __len)
5061 { return basic_string<char16_t>{__str, __len}; }
5062
5063 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11"))) _GLIBCXX_STRING_CONSTEXPR
5064 inline basic_string<char32_t>
5065 operator""s(const char32_t* __str, size_t __len)
5066 { return basic_string<char32_t>{__str, __len}; }
5067
5068#undef _GLIBCXX_STRING_CONSTEXPR
5069#pragma GCC diagnostic pop
5070 } // inline namespace string_literals
5071 } // inline namespace literals
5072#endif // __glibcxx_string_udls
5073
5074#ifdef __glibcxx_variant202102L // >= C++17
5075 namespace __detail::__variant
5076 {
5077 template<typename> struct _Never_valueless_alt; // see <variant>
5078
5079 // Provide the strong exception-safety guarantee when emplacing a
5080 // basic_string into a variant, but only if moving the string cannot throw.
5081 template<typename _Tp, typename _Traits, typename _Alloc>
5082 struct _Never_valueless_alt<std::basic_string<_Tp, _Traits, _Alloc>>
5083 : __and_<
5084 is_nothrow_move_constructible<std::basic_string<_Tp, _Traits, _Alloc>>,
5085 is_nothrow_move_assignable<std::basic_string<_Tp, _Traits, _Alloc>>
5086 >::type
5087 { };
5088 } // namespace __detail::__variant
5089#endif // C++17
5090
5091_GLIBCXX_END_NAMESPACE_VERSION
5092} // namespace std
5093
5094#endif // C++11
5095
5096#endif /* _BASIC_STRING_H */

←

/usr/src/googletest/googletest/include/gtest/gtest-assertion-result.h

1// Copyright 2005, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30// The Google C++ Testing and Mocking Framework (Google Test)
31//
32// This file implements the AssertionResult type.
33
34// IWYU pragma: private, include "gtest/gtest.h"
35// IWYU pragma: friend gtest/.*
36// IWYU pragma: friend gmock/.*
37
38#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_
39#define GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_
40
41#include <memory>
42#include <ostream>
43#include <string>
44#include <type_traits>
45
46#include "gtest/gtest-message.h"
47#include "gtest/internal/gtest-port.h"
48
49GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
50/* class A needs to have dll-interface to be used by clients of class B */)
51
52namespace testing {
53
54// A class for indicating whether an assertion was successful. When
55// the assertion wasn't successful, the AssertionResult object
56// remembers a non-empty message that describes how it failed.
57//
58// To create an instance of this class, use one of the factory functions
59// (AssertionSuccess() and AssertionFailure()).
60//
61// This class is useful for two purposes:
62// 1. Defining predicate functions to be used with Boolean test assertions
63// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts
64// 2. Defining predicate-format functions to be
65// used with predicate assertions (ASSERT_PRED_FORMAT*, etc).
66//
67// For example, if you define IsEven predicate:
68//
69// testing::AssertionResult IsEven(int n) {
70// if ((n % 2) == 0)
71// return testing::AssertionSuccess();
72// else
73// return testing::AssertionFailure() << n << " is odd";
74// }
75//
76// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5)))
77// will print the message
78//
79// Value of: IsEven(Fib(5))
80// Actual: false (5 is odd)
81// Expected: true
82//
83// instead of a more opaque
84//
85// Value of: IsEven(Fib(5))
86// Actual: false
87// Expected: true
88//
89// in case IsEven is a simple Boolean predicate.
90//
91// If you expect your predicate to be reused and want to support informative
92// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up
93// about half as often as positive ones in our tests), supply messages for
94// both success and failure cases:
95//
96// testing::AssertionResult IsEven(int n) {
97// if ((n % 2) == 0)
98// return testing::AssertionSuccess() << n << " is even";
99// else
100// return testing::AssertionFailure() << n << " is odd";
101// }
102//
103// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print
104//
105// Value of: IsEven(Fib(6))
106// Actual: true (8 is even)
107// Expected: false
108//
109// NB: Predicates that support negative Boolean assertions have reduced
110// performance in positive ones so be careful not to use them in tests
111// that have lots (tens of thousands) of positive Boolean assertions.
112//
113// To use this class with EXPECT_PRED_FORMAT assertions such as:
114//
115// // Verifies that Foo() returns an even number.
116// EXPECT_PRED_FORMAT1(IsEven, Foo());
117//
118// you need to define:
119//
120// testing::AssertionResult IsEven(const char* expr, int n) {
121// if ((n % 2) == 0)
122// return testing::AssertionSuccess();
123// else
124// return testing::AssertionFailure()
125// << "Expected: " << expr << " is even\n Actual: it's " << n;
126// }
127//
128// If Foo() returns 5, you will see the following message:
129//
130// Expected: Foo() is even
131// Actual: it's 5
132
133class GTEST_API___attribute__((visibility("default"))) AssertionResult {
134 public:
135 // Copy constructor.
136 // Used in EXPECT_TRUE/FALSE(assertion_result).
137 AssertionResult(const AssertionResult& other);
138
139// C4800 is a level 3 warning in Visual Studio 2015 and earlier.
140// This warning is not emitted in Visual Studio 2017.
141// This warning is off by default starting in Visual Studio 2019 but can be
142// enabled with command-line options.
143#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
144 GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */)
145#endif
146
147 // Used in the EXPECT_TRUE/FALSE(bool_expression).
148 //
149 // T must be contextually convertible to bool.
150 //
151 // The second parameter prevents this overload from being considered if
152 // the argument is implicitly convertible to AssertionResult. In that case
153 // we want AssertionResult's copy constructor to be used.
154 template <typename T>
155 explicit AssertionResult(
156 const T& success,
157 typename std::enable_if<
158 !std::is_convertible<T, AssertionResult>::value>::type*
159 /*enabler*/
160 = nullptr)
161 : success_(success) {}
42
Assigned value is uninitialized
162
163#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
164 GTEST_DISABLE_MSC_WARNINGS_POP_()
165#endif
166
167 // Assignment operator.
168 AssertionResult& operator=(AssertionResult other) {
169 swap(other);
170 return *this;
171 }
172
173 // Returns true if and only if the assertion succeeded.
174 operator bool() const { return success_; } // NOLINT
175
176 // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
177 AssertionResult operator!() const;
178
179 // Returns the text streamed into this AssertionResult. Test assertions
180 // use it when they fail (i.e., the predicate's outcome doesn't match the
181 // assertion's expectation). When nothing has been streamed into the
182 // object, returns an empty string.
183 const char* message() const {
184 return message_ != nullptr ? message_->c_str() : "";
185 }
186 // Deprecated; please use message() instead.
187 const char* failure_message() const { return message(); }
188
189 // Streams a custom failure message into this object.
190 template <typename T>
191 AssertionResult& operator<<(const T& value) {
192 AppendMessage(Message() << value);
193 return *this;
194 }
195
196 // Allows streaming basic output manipulators such as endl or flush into
197 // this object.
198 AssertionResult& operator<<(
199 ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) {
200 AppendMessage(Message() << basic_manipulator);
201 return *this;
202 }
203
204 private:
205 // Appends the contents of message to message_.
206 void AppendMessage(const Message& a_message) {
207 if (message_ == nullptr) message_ = ::std::make_unique<::std::string>();
208 message_->append(a_message.GetString().c_str());
209 }
210
211 // Swap the contents of this AssertionResult with other.
212 void swap(AssertionResult& other);
213
214 // Stores result of the assertion predicate.
215 bool success_;
216 // Stores the message describing the condition in case the expectation
217 // construct is not satisfied with the predicate's outcome.
218 // Referenced via a pointer to avoid taking too much stack frame space
219 // with test assertions.
220 std::unique_ptr< ::std::string> message_;
221};
222
223// Makes a successful assertion result.
224GTEST_API___attribute__((visibility("default"))) AssertionResult AssertionSuccess();
225
226// Makes a failed assertion result.
227GTEST_API___attribute__((visibility("default"))) AssertionResult AssertionFailure();
228
229// Makes a failed assertion result with the given failure message.
230// Deprecated; use AssertionFailure() << msg.
231GTEST_API___attribute__((visibility("default"))) AssertionResult AssertionFailure(const Message& msg);
232
233} // namespace testing
234
235GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
236
237#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_