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/tmpz0p224zs -fcoverage-compilation-dir=/home/fedora/workspace/kea-dev/clang-static-analyzer/build/meson-private/tmpz0p224zs -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 src/hooks/dhcp -I ../../../src/hooks/dhcp -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/tmpz0p224zs/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/tmpz0p224zs/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-06-18-163926-5114-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 <dhcpsrv/cfg_expiration.h>
25#include <dhcpsrv/cfg_hosts.h>
26#include <dhcpsrv/cfg_subnets4.h>
27#include <dhcpsrv/cfgmgr.h>
28#include <dhcpsrv/parsers/simple_parser4.h>
29#include <dhcpsrv/subnet.h>
30#include <dhcpsrv/subnet_selector.h>
31#include <dhcpsrv/testutils/config_result_check.h>
32#include <dhcpsrv/testutils/test_config_backend_dhcp4.h>
33#include <hooks/hooks_manager.h>
34#include <hooks/hooks_parser.h>
35#include <process/config_ctl_info.h>
36#include <stats/stats_mgr.h>
37#include <testutils/gtest_utils.h>
38#include <testutils/log_utils.h>
39#include <testutils/test_to_element.h>
40#include <util/chrono_time_utils.h>
41#include <util/doubles.h>
42#include <util/filesystem.h>
43
44#include <boost/scoped_ptr.hpp>
45
46#include <iostream>
47#include <sstream>
48#include <string>
49#include <vector>
50
51#include <arpa/inet.h>
52#include <gtest/gtest.h>
53#include <unistd.h>
54
55#include "dhcp4_test_utils.h"
56#include "get_config_unittest.h"
57#include "marker_file.h"
58#include "test_libraries.h"
59
60using namespace isc;
61using namespace isc::asiolink;
62using namespace isc::config;
63using namespace isc::config::test;
64using namespace isc::data;
65using namespace isc::dhcp;
66using namespace isc::dhcp::test;
67using namespace isc::hooks;
68using namespace isc::test;
69using namespace isc::util;
70using namespace std;
71
72namespace {
73
74const char* PARSER_CONFIGS[] = {
75 // Configuration 0: one subnet with one pool, no user contexts
76 "{"
77 " \"interfaces-config\": {"
78 " \"interfaces\": [\"*\" ]"
79 " },"
80 " \"valid-lifetime\": 4000,"
81 " \"rebind-timer\": 2000,"
82 " \"renew-timer\": 1000,"
83 " \"subnet4\": [ {"
84 " \"pools\": [ "
85 " { \"pool\": \"192.0.2.0/28\" }"
86 " ],"
87 " \"id\": 1,"
88 " \"subnet\": \"192.0.2.0/24\""
89 " } ]"
90 "}",
91
92 // Configuration 1: one pool with empty user context
93 "{"
94 " \"interfaces-config\": {"
95 " \"interfaces\": [\"*\" ]"
96 " },"
97 " \"valid-lifetime\": 4000,"
98 " \"rebind-timer\": 2000,"
99 " \"renew-timer\": 1000,"
100 " \"subnet4\": [ {"
101 " \"pools\": [ "
102 " { \"pool\": \"192.0.2.0/28\","
103 " \"user-context\": {"
104 " }"
105 " }"
106 " ],"
107 " \"id\": 1,"
108 " \"subnet\": \"192.0.2.0/24\""
109 " } ]"
110 "}",
111
112 // Configuration 2: one pool with user context containing lw4over6 parameters
113 "{"
114 " \"interfaces-config\": {"
115 " \"interfaces\": [\"*\" ]"
116 " },"
117 " \"valid-lifetime\": 4000,"
118 " \"rebind-timer\": 2000,"
119 " \"renew-timer\": 1000,"
120 " \"subnet4\": [ {"
121 " \"pools\": [ "
122 " { \"pool\": \"192.0.2.0/28\","
123 " \"user-context\": {"
124 " \"integer-param\": 42,"
125 " \"string-param\": \"Sagittarius\","
126 " \"bool-param\": true"
127 " }"
128 " }"
129 " ],"
130 " \"id\": 1,"
131 " \"subnet\": \"192.0.2.0/24\""
132 " } ]"
133 "}",
134
135 // Configuration 3: one min-max pool with user context containing lw4over6 parameters
136 "{"
137 " \"interfaces-config\": {"
138 " \"interfaces\": [\"*\" ]"
139 " },"
140 " \"valid-lifetime\": 4000,"
141 " \"rebind-timer\": 2000,"
142 " \"renew-timer\": 1000,"
143 " \"subnet4\": [ {"
144 " \"pools\": [ "
145 " { \"pool\": \"192.0.2.0 - 192.0.2.15\","
146 " \"user-context\": {"
147 " \"integer-param\": 42,"
148 " \"string-param\": \"Sagittarius\","
149 " \"bool-param\": true"
150 " }"
151 " }"
152 " ],"
153 " \"id\": 1,"
154 " \"subnet\": \"192.0.2.0/24\""
155 " } ]"
156 "}",
157
158 // Configuration 4: two host databases
159 "{"
160 " \"interfaces-config\": {"
161 " \"interfaces\": [\"*\" ]"
162 " },"
163 " \"valid-lifetime\": 4000,"
164 " \"rebind-timer\": 2000,"
165 " \"renew-timer\": 1000,"
166 " \"hosts-databases\": [ {"
167 " \"type\": \"mysql\","
168 " \"name\": \"keatest1\","
169 " \"user\": \"keatest\","
170 " \"password\": \"keatest\""
171 " },{"
172 " \"type\": \"mysql\","
173 " \"name\": \"keatest2\","
174 " \"user\": \"keatest\","
175 " \"retry-on-startup\": true,"
176 " \"password\": \"keatest\""
177 " }"
178 " ]"
179 "}",
180
181 // Configuration 5: config databases
182 "{ \n"
183 " \"interfaces-config\": { \n"
184 " \"interfaces\": [\"*\" ] \n"
185 " }, \n"
186 " \"valid-lifetime\": 4000, \n"
187 " \"rebind-timer\": 2000, \n"
188 " \"renew-timer\": 1000, \n"
189 " \"config-control\": { \n"
190 " \"config-fetch-wait-time\": 10, \n"
191 " \"config-databases\": [ { \n"
192 " \"type\": \"mysql\", \n"
193 " \"name\": \"keatest1\", \n"
194 " \"user\": \"keatest\", \n"
195 " \"password\": \"keatest\" \n"
196 " },{ \n"
197 " \"type\": \"mysql\", \n"
198 " \"name\": \"keatest2\", \n"
199 " \"user\": \"keatest\", \n"
200 " \"retry-on-startup\": true, \n"
201 " \"password\": \"keatest\" \n"
202 " } \n"
203 " ] \n"
204 " } \n"
205 "} \n",
206
207 // Configuration 6 for comments
208 "{"
209 " \"comment\": \"A DHCPv4 server\","
210 " \"interfaces-config\": {"
211 " \"comment\": \"Use wildcard\","
212 " \"interfaces\": [ \"*\" ] },"
213 " \"option-def\": [ {"
214 " \"comment\": \"An option definition\","
215 " \"name\": \"foo\","
216 " \"code\": 100,"
217 " \"type\": \"ipv4-address\","
218 " \"space\": \"isc\""
219 " } ],"
220 " \"option-data\": [ {"
221 " \"comment\": \"Set option value\","
222 " \"name\": \"dhcp-message\","
223 " \"data\": \"ABCDEF0105\","
224 " \"csv-format\": false"
225 " } ],"
226 " \"client-classes\": ["
227 " {"
228 " \"comment\": \"match all\","
229 " \"name\": \"all\","
230 " \"test\": \"'' == ''\""
231 " },"
232 " {"
233 " \"name\": \"none\""
234 " },"
235 " {"
236 " \"comment\": \"a comment\","
237 " \"name\": \"both\","
238 " \"user-context\": {"
239 " \"version\": 1"
240 " }"
241 " }"
242 " ],"
243 " \"control-sockets\": ["
244 " {"
245 " \"socket-type\": \"unix\","
246 " \"socket-name\": \"kea4-ctrl-socket\","
247 " \"user-context\": { \"comment\": \"Indirect comment\" }"
248 " },"
249 " {"
250 " \"comment\": \"HTTP control socket\","
251 " \"socket-type\": \"http\","
252 " \"socket-address\": \"::1\","
253 " \"socket-port\": 8000,"
254 " \"http-headers\": [ {"
255 " \"comment\": \"HSTS header\","
256 " \"name\": \"Strict-Transport-Security\","
257 " \"value\": \"max-age=31536000\""
258 " } ],"
259 " \"authentication\": {"
260 " \"comment\": \"basic HTTP authentication\","
261 " \"type\": \"basic\","
262 " \"clients\": [ {"
263 " \"comment\": \"admin is authorized\","
264 " \"user\": \"admin\","
265 " \"password\": \"foobar\""
266 " } ]"
267 " }"
268 " }"
269 " ],"
270 " \"shared-networks\": [ {"
271 " \"comment\": \"A shared network\","
272 " \"name\": \"foo\","
273 " \"subnet4\": ["
274 " { "
275 " \"comment\": \"A subnet\","
276 " \"subnet\": \"192.0.1.0/24\","
277 " \"id\": 100,"
278 " \"pools\": ["
279 " {"
280 " \"comment\": \"A pool\","
281 " \"pool\": \"192.0.1.1-192.0.1.10\""
282 " }"
283 " ],"
284 " \"reservations\": ["
285 " {"
286 " \"comment\": \"A host reservation\","
287 " \"hw-address\": \"AA:BB:CC:DD:EE:FF\","
288 " \"hostname\": \"foo.example.com\","
289 " \"option-data\": [ {"
290 " \"comment\": \"An option in a reservation\","
291 " \"name\": \"domain-name\","
292 " \"data\": \"example.com\""
293 " } ]"
294 " }"
295 " ]"
296 " }"
297 " ]"
298 " } ],"
299 " \"dhcp-ddns\": {"
300 " \"comment\": \"No dynamic DNS\","
301 " \"enable-updates\": false"
302 " }"
303 "}"
304};
305
306class Dhcp4ParserTest : public LogContentTest {
307protected:
308 // Check that no hooks libraries are loaded. This is a pre-condition for
309 // a number of tests, so is checked in one place. As this uses an
310 // ASSERT call - and it is not clear from the documentation that Gtest
311 // predicates can be used in a constructor - the check is placed in SetUp.
312 virtual void SetUp() {
313 std::vector<std::string> libraries = HooksManager::getLibraryNames();
314 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"
, 314, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "libraries.empty()", "false", "true") .c_str()) = ::testing
::Message()
;
315 }
316
317public:
318 Dhcp4ParserTest() : rcode_(-1) {
319 // Open port 0 means to not open any sockets. We don't want to
320 // deal with sockets here, just check if configuration handling
321 // is sane.
322 srv_.reset(new ControlledDhcpv4Srv(0));
323
324 const IfaceCollection& ifaces = IfaceMgr::instance().getIfaces();
325
326 // There must be some interface detected
327 if (ifaces.empty()) {
328 // We can't use ASSERT in constructor
329 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 329, "Failed") = ::testing::Message()
<< "No interfaces detected.";
330 }
331
332 valid_iface_ = (*ifaces.begin())->getName();
333 bogus_iface_ = "nonexisting0";
334
335 if (IfaceMgr::instance().getIface(bogus_iface_)) {
336 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 336, "Failed") = ::testing::Message()
<< "The '" << bogus_iface_ << "' exists on this system"
337 << " while the test assumes that it doesn't, to execute"
338 << " some negative scenarios. Can't continue this test.";
339 }
340 // Reset configuration for each test.
341 resetConfiguration();
342
343 resetHooksPath();
344 Dhcpv4SrvTest::resetSocketPath();
345 file::PathChecker::enableEnforcement(true);
346 }
347
348 ~Dhcp4ParserTest() {
349 // Reset configuration database after each test.
350 resetConfiguration();
351
352 // ... and delete the hooks library marker files if present
353 static_cast<void>(remove(LOAD_MARKER_FILE));
354 static_cast<void>(remove(UNLOAD_MARKER_FILE));
355
356 resetHooksPath();
357 Dhcpv4SrvTest::resetSocketPath();
358 file::PathChecker::enableEnforcement(true);
359 };
360
361 /// @brief Sets the Hooks path from which hooks can be loaded.
362 /// @param explicit_path path to use as the hooks path.
363 void setHooksTestPath(const std::string explicit_path = "") {
364 HooksLibrariesParser::getHooksPath(true,
365 (!explicit_path.empty() ?
366 explicit_path : DHCP4_HOOKS_TEST_PATH));
367 }
368
369 /// @brief Resets the hooks path to DEFAULT_HOOKS_PATH.
370 void resetHooksPath() {
371 HooksLibrariesParser::getHooksPath(true);
372 }
373
374 // Checks if the result of DHCP server configuration has
375 // expected code (0 for success, other for failures).
376 // Also stores result in rcode_ and comment_.
377 void checkResult(ConstElementPtr status, int expected_code) {
378 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"
, 378, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
379 comment_ = parseAnswerText(rcode_, status);
380 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"
, 380, gtest_ar.failure_message()) = ::testing::Message()
<< "error text:" << comment_->stringValue();
381 }
382
383 // Checks if the result of DHCP server configuration has
384 // expected code (0 for success, other for failures) and
385 // the text part. Also stores result in rcode_ and comment_.
386 void checkResult(ConstElementPtr status, int expected_code,
387 string expected_txt) {
388 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"
, 388, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
389 comment_ = parseAnswerText(rcode_, status);
390 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"
, 390, gtest_ar.failure_message()) = ::testing::Message()
<< "error text:" << comment_->stringValue();
391 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"
, 391, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "comment_", "false", "true") .c_str()) = ::testing::Message
()
;
392 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"
, 392, gtest_ar.failure_message()) = ::testing::Message()
;
393 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"
, 393, gtest_ar.failure_message()) = ::testing::Message()
;
394 }
395
396 /// @brief Convenience method for running configuration
397 ///
398 /// This method does not throw, but signals errors using gtest macros.
399 ///
400 /// @param config text to be parsed as JSON
401 /// @param expected_code expected code (see cc/command_interpreter.h)
402 /// @param exp_error expected text error (check skipped if empty)
403 void configure(std::string config, int expected_code,
404 std::string exp_error = "") {
405 ConstElementPtr json;
406 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"
, 406, "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", 406
, "Failed") = ::testing::Message() << "json = parseDHCP4(config, true)"
<< " threw non-std::exception"; } }
;
407
408 ConstElementPtr status;
409 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_409; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_409; } } else gtest_label_testnothrow_409
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 409, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
410 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"
, 410, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
411
412 int rcode;
413 ConstElementPtr comment = parseAnswerText(rcode, status);
414
415 string text;
416 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"
, 416, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "comment", "false", "true") .c_str()) = ::testing::Message(
)
;
417 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_417
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_417
; } } else gtest_label_testnothrow_417 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 417, ("Expected: " "text = comment->stringValue()" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
418
419 // Socket name too long?
420 bool const too_long(SocketPath::isTooLongFromConfig(json));
421 if (too_long) {
422 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", 422
, gtest_ar.failure_message()) = ::testing::Message()
;
423 exp_error = "name too long";
424 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"
, 424, gtest_ar.failure_message()) = ::testing::Message()
;
425 return;
426 }
427
428 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"
, 428, gtest_ar.failure_message()) = ::testing::Message()
;
429 if (expected_code != rcode) {
430 std::cout << "Reported status: " << text << std::endl;
431 }
432
433 if ((rcode != 0)) {
434 if (!exp_error.empty()) {
435 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"
, 435, gtest_ar.failure_message()) = ::testing::Message()
;
436 }
437 }
438 }
439
440 /// @brief Returns an interface configuration used by the most of the
441 /// unit tests.
442 std::string genIfaceConfig() const {
443 return ("\"interfaces-config\": {"
444 " \"interfaces\": [ \"*\" ]"
445 "}");
446 }
447
448 /// @brief Create the simple configuration with single option.
449 ///
450 /// This function allows to set one of the parameters that configure
451 /// option value. These parameters are: "name", "code", "data",
452 /// "csv-format" and "space".
453 ///
454 /// @param param_value string holding option parameter value to be
455 /// injected into the configuration string.
456 /// @param parameter name of the parameter to be configured with
457 /// param value.
458 /// @return configuration string containing custom values of parameters
459 /// describing an option.
460 std::string createConfigWithOption(const std::string& param_value,
461 const std::string& parameter) {
462 std::map<std::string, std::string> params;
463 if (parameter == "name") {
464 params["name"] = param_value;
465 params["space"] = DHCP4_OPTION_SPACE"dhcp4";
466 params["code"] = "56";
467 params["data"] = "ABCDEF0105";
468 params["csv-format"] = "false";
469 } else if (parameter == "space") {
470 params["name"] = "dhcp-message";
471 params["space"] = param_value;
472 params["code"] = "56";
473 params["data"] = "ABCDEF0105";
474 params["csv-format"] = "false";
475 } else if (parameter == "code") {
476 params["name"] = "dhcp-message";
477 params["space"] = DHCP4_OPTION_SPACE"dhcp4";
478 params["code"] = param_value;
479 params["data"] = "ABCDEF0105";
480 params["csv-format"] = "false";
481 } else if (parameter == "data") {
482 params["name"] = "dhcp-message";
483 params["space"] = DHCP4_OPTION_SPACE"dhcp4";
484 params["code"] = "56";
485 params["data"] = param_value;
486 params["csv-format"] = "false";
487 } else if (parameter == "csv-format") {
488 params["name"] = "dhcp-message";
489 params["space"] = DHCP4_OPTION_SPACE"dhcp4";
490 params["code"] = "56";
491 params["data"] = "ABCDEF0105";
492 params["csv-format"] = param_value;
493 }
494 return (createConfigWithOption(params));
495 }
496
497 /// @brief Create simple configuration with single option.
498 ///
499 /// This function creates a configuration for a single option with
500 /// custom values for all parameters that describe the option.
501 ///
502 /// @params params map holding parameters and their values.
503 /// @return configuration string containing custom values of parameters
504 /// describing an option.
505 std::string createConfigWithOption(const std::map<std::string,
506 std::string>& params) {
507 std::ostringstream stream;
508 stream << "{ " << genIfaceConfig() << "," <<
509 "\"rebind-timer\": 2000, "
510 "\"renew-timer\": 1000, "
511 "\"subnet4\": [ { "
512 " \"id\": 1,"
513 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
514 " \"subnet\": \"192.0.2.0/24\", "
515 " \"option-data\": [ {";
516 bool first = true;
517 for (auto const& param : params) {
518 if (!first) {
519 stream << ", ";
520 } else {
521 // cppcheck-suppress unreadVariable
522 first = false;
523 }
524 if (param.first == "name") {
525 stream << "\"name\": \"" << param.second << "\"";
526 } else if (param.first == "space") {
527 stream << "\"space\": \"" << param.second << "\"";
528 } else if (param.first == "code") {
529 stream << "\"code\": " << param.second;
530 } else if (param.first == "data") {
531 stream << "\"data\": \"" << param.second << "\"";
532 } else if (param.first == "csv-format") {
533 stream << "\"csv-format\": " << param.second;
534 }
535 }
536 stream <<
537 " } ]"
538 " } ],"
539 "\"valid-lifetime\": 4000 }";
540 return (stream.str());
541 }
542
543 /// @brief Returns an option from the subnet.
544 ///
545 /// This function returns an option from a subnet to which the
546 /// specified subnet address belongs. The option is identified
547 /// by its code.
548 ///
549 /// @param subnet_address Address which belongs to the subnet from
550 /// which the option is to be returned.
551 /// @param option_code Code of the option to be returned.
552 /// @param expected_options_count Expected number of options in
553 /// the particular subnet.
554 ///
555 /// @return Descriptor of the option. If the descriptor holds a
556 /// NULL option pointer, it means that there was no such option
557 /// in the subnet.
558 OptionDescriptor
559 getOptionFromSubnet(const IOAddress& subnet_address,
560 const uint16_t option_code,
561 const uint16_t expected_options_count = 1) {
562 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
563 getCfgSubnets4()->selectSubnet(subnet_address);
564 if (!subnet) {
565 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 565, "Failed") = ::testing::Message()
<< "A subnet for the specified address "
566 << subnet_address
567 << " does not exist in Config Manager";
568 return (OptionDescriptor(false, false));
569 }
570 OptionContainerPtr options =
571 subnet->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
572 if (expected_options_count != options->size()) {
573 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 573, "Failed") = ::testing::Message()
<< "The number of options in the subnet '"
574 << subnet_address.toText() << "' is different "
575 " than expected number of options '"
576 << expected_options_count << "'";
577 }
578
579 // Get the search index. Index #1 is to search using option code.
580 const OptionContainerTypeIndex& idx = options->get<1>();
581
582 // Get the options for specified index. Expecting one option to be
583 // returned but in theory we may have multiple options with the same
584 // code so we get the range.
585 std::pair<OptionContainerTypeIndex::const_iterator,
586 OptionContainerTypeIndex::const_iterator> range =
587 idx.equal_range(option_code);
588 if (std::distance(range.first, range.second) > 1) {
589 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 589, "Failed") = ::testing::Message()
<< "There is more than one option having the"
590 " option code '" << option_code << "' in a subnet '"
591 << subnet_address.toText() << "'. Expected "
592 " at most one option";
593 } else if (std::distance(range.first, range.second) == 0) {
594 return (OptionDescriptor(OptionPtr(), false, false));
595 }
596
597 return (*range.first);
598 }
599
600 /// @brief Test invalid option parameter value.
601 ///
602 /// This test function constructs the simple configuration
603 /// string and injects invalid option configuration into it.
604 /// It expects that parser will fail with provided option code.
605 ///
606 /// @param param_value string holding invalid option parameter value
607 /// to be injected into configuration string.
608 /// @param parameter name of the parameter to be configured with
609 /// param_value (can be any of "name", "code", "data")
610 void testInvalidOptionParam(const std::string& param_value,
611 const std::string& parameter) {
612 ConstElementPtr x;
613 std::string config = createConfigWithOption(param_value, parameter);
614 ConstElementPtr json = parseDHCP4(config);
615 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_615; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_615; } } else gtest_label_testnothrow_615
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 615, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
616 checkResult(x, CONTROL_RESULT_ERROR);
617 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"
, 617, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(x, \"<string>\")", "false", "true"
) .c_str()) = ::testing::Message()
;
618 CfgMgr::instance().clear();
619 }
620
621 /// @brief Test invalid option parameter value.
622 ///
623 /// This test function constructs the simple configuration
624 /// string and injects invalid option configuration into it.
625 /// It expects that parser will fail with provided option code.
626 ///
627 /// @param params Map of parameters defining an option.
628 void
629 testInvalidOptionParam(const std::map<std::string, std::string>& params) {
630 ConstElementPtr x;
631 std::string config = createConfigWithOption(params);
632 ConstElementPtr json = parseDHCP4(config);
633 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_633; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_633; } } else gtest_label_testnothrow_633
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 633, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
634 checkResult(x, CONTROL_RESULT_ERROR);
635 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"
, 635, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(x, \"<string>\")", "false", "true"
) .c_str()) = ::testing::Message()
;
636 CfgMgr::instance().clear();
637 }
638
639 /// @brief Test option against given code and data.
640 ///
641 /// @param option_desc option descriptor that carries the option to
642 /// be tested.
643 /// @param expected_code expected code of the option.
644 /// @param expected_data expected data in the option.
645 /// @param expected_data_len length of the reference data.
646 /// @param extra_data if true extra data is allowed in an option
647 /// after tested data.
648 void testOption(const OptionDescriptor& option_desc,
649 uint16_t expected_code, const uint8_t* expected_data,
650 size_t expected_data_len,
651 bool extra_data = false) {
652 // Check if option descriptor contains valid option pointer.
653 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"
, 653, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option_desc.option_", "false", "true") .c_str()) = ::testing
::Message()
;
654 // Verify option type.
655 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"
, 655, gtest_ar.failure_message()) = ::testing::Message()
;
656 // We may have many different option types being created. Some of them
657 // have dedicated classes derived from Option class. In such case if
658 // we want to verify the option contents against expected_data we have
659 // to prepare raw buffer with the contents of the option. The easiest
660 // way is to call pack() which will prepare on-wire data.
661 util::OutputBuffer buf(option_desc.option_->getData().size());
662 option_desc.option_->pack(buf);
663 if (extra_data) {
664 // The length of the buffer must be at least equal to size of the
665 // reference data but it can sometimes be greater than that. This is
666 // because some options carry suboptions that increase the overall
667 // length.
668 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", 669
, gtest_ar.failure_message()) = ::testing::Message()
669 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", 669
, gtest_ar.failure_message()) = ::testing::Message()
;
670 } else {
671 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", 672
, gtest_ar.failure_message()) = ::testing::Message()
672 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", 672
, gtest_ar.failure_message()) = ::testing::Message()
;
673 }
674 // Verify that the data is correct. Do not verify suboptions and a header.
675 const uint8_t* data = buf.getData();
676 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"
, 678, gtest_ar.failure_message()) = ::testing::Message()
677 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"
, 678, gtest_ar.failure_message()) = ::testing::Message()
678 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"
, 678, gtest_ar.failure_message()) = ::testing::Message()
;
679 }
680
681 /// @brief Test option configuration.
682 ///
683 /// This function creates a configuration for a specified option using
684 /// a map of parameters specified as the argument. The map holds
685 /// name/value pairs which identifies option's configuration parameters:
686 /// - name
687 /// - space
688 /// - code
689 /// - data
690 /// - csv-format.
691 /// This function applies a new server configuration and checks that the
692 /// option being configured is inserted into CfgMgr. The raw contents of
693 /// this option are compared with the binary data specified as expected
694 /// data passed to this function.
695 ///
696 /// @param params Map of parameters defining an option.
697 /// @param option_code Option code.
698 /// @param expected_data Array containing binary data expected to be stored
699 /// in the configured option.
700 /// @param expected_data_len Length of the array holding reference data.
701 void testConfiguration(const std::map<std::string, std::string>& params,
702 const uint16_t option_code,
703 const uint8_t* expected_data,
704 const size_t expected_data_len) {
705 CfgMgr::instance().clear();
706
707 std::string config = createConfigWithOption(params);
708 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", 708
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "executeConfiguration(config, \"parse option configuration\")"
, "false", "true") .c_str()) = ::testing::Message()
;
709
710 // The subnet should now hold one option with the specified option code.
711 OptionDescriptor desc =
712 getOptionFromSubnet(IOAddress("192.0.2.24"), option_code);
713 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"
, 713, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc.option_", "false", "true") .c_str()) = ::testing::Message
()
;
714 testOption(desc, option_code, expected_data, expected_data_len);
715 CfgMgr::instance().clear();
716 }
717
718 /// @brief Parse and Execute configuration
719 ///
720 /// Parses a configuration and executes a configuration of the server.
721 /// If the operation fails, the current test will register a failure.
722 ///
723 /// @param config Configuration to parse
724 /// @param operation Operation being performed. In the case of an error,
725 /// the error text will include the string "unable to <operation>.".
726 ///
727 /// @return true if the configuration succeeded, false if not. In the
728 /// latter case, a failure will have been added to the current test.
729 bool
730 executeConfiguration(const std::string& config, const char* operation) {
731 CfgMgr::instance().clear();
732 ConstElementPtr json;
733 ConstElementPtr status;
734 try {
735 json = parseJSON(config);
736 status = Dhcpv4SrvTest::configure(*srv_, json);
737 } catch (const std::exception& ex) {
738 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 738, "Failed") = ::testing::Message()
<< "Unable to " << operation << ". "
739 << "The following configuration was used: " << std::endl
740 << config << std::endl
741 << " and the following error message was returned:"
742 << ex.what() << std::endl;
743 return (false);
744 }
745
746 // The status object must not be NULL
747 if (!status) {
748 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 748, "Failed") = ::testing::Message()
<< "Unable to " << operation << ". "
749 << "The configuration function returned a null pointer.";
750 return (false);
751 }
752
753 // Store the answer if we need it.
754
755 // Returned value should be 0 (configuration success)
756 comment_ = parseAnswerText(rcode_, status);
757 if (rcode_ != 0) {
758 string reason = "";
759 if (comment_) {
760 reason = string(" (") + comment_->stringValue() + string(")");
761 }
762 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 762, "Failed") = ::testing::Message()
<< "Unable to " << operation << ". "
763 << "The configuration function returned error code "
764 << rcode_ << reason;
765 return (false);
766 }
767
768 return (true);
769 }
770
771 /// @brief Reset configuration database.
772 ///
773 /// This function resets configuration data base by removing all subnets
774 /// option-data, and hooks libraries. The reset must be performed after each
775 /// test to make sure that contents of the database do not affect the
776 /// results of subsequent tests.
777 void resetConfiguration() {
778 // The default setting is to listen on all interfaces. In order to
779 // properly test interface configuration we disable listening on
780 // all interfaces before each test and later check that this setting
781 // has been overridden by the configuration used in the test.
782 CfgMgr::instance().clear();
783 string config = "{ \"interfaces-config\": {"
784 " \"interfaces\": [ ]"
785 "},"
786 "\"hooks-libraries\": [ ],"
787 "\"rebind-timer\": 2000, "
788 "\"renew-timer\": 1000, "
789 "\"valid-lifetime\": 4000, "
790 "\"subnet4\": [ ], "
791 "\"dhcp-ddns\": { \"enable-updates\" : false }, "
792 "\"option-def\": [ ], "
793 "\"option-data\": [ ] }";
794 static_cast<void>(executeConfiguration(config,
795 "reset configuration database"));
796 CfgMgr::instance().clearStagingConfiguration();
797 }
798
799 /// @brief Retrieve an option associated with a host.
800 ///
801 /// The option is retrieved from the "dhcp4" option space.
802 ///
803 /// @param host Reference to a host for which an option should be retrieved.
804 /// @param option_code Option code.
805 /// @tparam ReturnType Type of the pointer object returned.
806 ///
807 /// @return Pointer to an option or NULL pointer if not found.
808 template<typename ReturnType>
809 ReturnType
810 retrieveOption(const Host& host, const uint16_t option_code) const {
811 return (retrieveOption<ReturnType>(host, DHCP4_OPTION_SPACE"dhcp4", option_code));
812 }
813
814 /// @brief Retrieve an option associated with a host.
815 ///
816 /// @param host Reference to a host for which an option should be retrieved.
817 /// @param space Option space from which option should be retrieved.
818 /// @param option_code Option code.
819 /// @tparam ReturnType Type of the pointer object returned.
820 ///
821 /// @return Pointer to an option or NULL pointer if not found.
822 template<typename ReturnType>
823 ReturnType
824 retrieveOption(const Host& host, const std::string& space,
825 const uint16_t option_code) const {
826 ConstCfgOptionPtr cfg_option = host.getCfgOption4();
827 if (cfg_option) {
828 OptionDescriptor opt_desc = cfg_option->get(space, option_code);
829 if (opt_desc.option_) {
830 return (boost::dynamic_pointer_cast<
831 typename ReturnType::element_type>(opt_desc.option_));
832 }
833 }
834 return (ReturnType());
835 }
836
837 /// @brief Checks if specified subnet is part of the collection
838 ///
839 /// @tparam CollectionType type of subnet4 collections i.e.
840 /// either Subnet4SimpleCollection or Subnet4Collection
841 /// @param col collection of subnets to be inspected
842 /// @param subnet text notation (e.g. 192.0.2.0/24)
843 /// @param t1 expected renew-timer value
844 /// @param t2 expected rebind-timer value
845 /// @param valid expected valid-lifetime value
846 /// @param min_valid expected min-valid-lifetime value
847 /// (0 (default) means same as valid)
848 /// @param max_valid expected max-valid-lifetime value
849 /// (0 (default) means same as valid)
850 /// @return the subnet that was examined
851 template <typename CollectionType>
852 Subnet4Ptr
853 checkSubnet(const CollectionType& col, std::string subnet,
854 uint32_t t1, uint32_t t2, uint32_t valid,
855 uint32_t min_valid = 0, uint32_t max_valid = 0) {
856 auto const& index = col.template get<SubnetPrefixIndexTag>();
857 auto subnet_it = index.find(subnet);
858 if (subnet_it == index.cend()) {
859 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 859, "Failed") = ::testing::Message()
<< "Unable to find expected subnet " << subnet;
860 return (Subnet4Ptr());
861 }
862 Subnet4Ptr s = *subnet_it;
863
864 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"
, 864, gtest_ar.failure_message()) = ::testing::Message()
;
865 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"
, 865, gtest_ar.failure_message()) = ::testing::Message()
;
866 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"
, 866, gtest_ar.failure_message()) = ::testing::Message()
;
867 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"
, 867, gtest_ar.failure_message()) = ::testing::Message()
;
868 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"
, 868, gtest_ar.failure_message()) = ::testing::Message()
;
869
870 return (s);
871 }
872
873 /// @brief This utility method attempts to configure using specified
874 /// config and then returns requested pool from requested subnet
875 ///
876 /// @param config configuration to be applied
877 /// @param subnet_index index of the subnet to be returned (0 - the first subnet)
878 /// @param pool_index index of the pool within a subnet (0 - the first pool)
879 /// @param pool [out] Pool pointer will be stored here (if found)
880 void getPool(const std::string& config, size_t subnet_index,
881 size_t pool_index, PoolPtr& pool) {
882 ConstElementPtr status;
883 ConstElementPtr json;
884
885 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_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: " "json = parseDHCP4(config, true)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
886 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_886; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_886; } } else gtest_label_testnothrow_886
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 886, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
887 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"
, 887, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
888 checkResult(status, 0);
889
890 ConstCfgSubnets4Ptr subnets4 = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
891 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"
, 891, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets4", "false", "true") .c_str()) = ::testing::Message
()
;
892
893 const Subnet4Collection* subnets = subnets4->getAll();
894 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"
, 894, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
895 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"
, 895, gtest_ar.failure_message()) = ::testing::Message()
;
896
897 auto subnet = subnets->begin();
898 // std::advance is not available for subnets iterators.
899 for (size_t i = 0; i < subnet_index; ++i) {
900 subnet = std::next(subnet);
901 }
902 const PoolCollection pools = (*subnet)->getPools(Lease::TYPE_V4);
903 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"
, 903, gtest_ar.failure_message()) = ::testing::Message()
;
904
905 pool = pools.at(pool_index);
906 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", 906
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
907 }
908
909 /// @brief Tests if the current config has a given global parameter value
910 /// @param name name of the global parameter expected to exist
911 /// @param value expected value of the global parameter
912 template <typename ValueType>
913 void checkGlobal(const std::string name, ValueType value) {
914 ConstElementPtr param;
915 ConstElementPtr exp_value;
916 param = CfgMgr::instance().getStagingCfg()->getConfiguredGlobal(name);
917 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"
, 917, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "param", "false", "true") .c_str()) = ::testing::Message()
<< "global: " << name << ", expected but not found";
918 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_918
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_918
; } } else gtest_label_testnothrow_918 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 918, ("Expected: " "exp_value = Element::create(value)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
919 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"
, 919, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "param->equals(*exp_value)", "false", "true") .c_str()) =
::testing::Message()
<< "global: " << name
920 << isc::data::prettyPrint(param)
921 << " does not match expected: "
922 << isc::data::prettyPrint(exp_value);
923 }
924
925 int rcode_; ///< Return code from element parsing
926 boost::scoped_ptr<Dhcpv4Srv> srv_; ///< Instance of the Dhcpv4Srv used during tests
927 ConstElementPtr comment_; ///< Comment (see @ref isc::config::parseAnswer)
928 string valid_iface_; ///< Valid network interface name (present in system)
929 string bogus_iface_; ///< invalid network interface name (not in system)
930 isc::dhcp::ClientClasses classify_; ///< used in client classification
931};
932
933/// The goal of this test is to verify that the code accepts only
934/// valid commands and malformed or unsupported parameters are rejected.
935TEST_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", 935
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 935), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 935), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_bogusCommand_Test
>); void Dhcp4ParserTest_bogusCommand_Test::TestBody()
{
936
937 ConstElementPtr x;
938
939 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_940; } catch (...
) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_940
; } } else gtest_label_testnothrow_940 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 940, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, parseJSON(\"{\\\"bogus\\\": 5}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
940 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_940; } catch (...
) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_940
; } } else gtest_label_testnothrow_940 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 940, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, parseJSON(\"{\\\"bogus\\\": 5}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
941
942 // returned value must be 1 (configuration parse error)
943 checkResult(x, CONTROL_RESULT_ERROR);
944
945 // it should be refused by syntax too
946 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_946; } 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_946; } 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_946; } } else gtest_label_testthrow_946
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 946, gtest_msg.value.c_str()) = ::testing::Message()
;
947}
948
949/// The goal of this test is to verify empty interface-config is accepted.
950TEST_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"
, 950), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 950), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 950), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_emptyInterfaceConfig_Test
>); void Dhcp4ParserTest_emptyInterfaceConfig_Test::TestBody
()
{
951
952 ConstElementPtr json;
953 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_956
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_956
; } } else gtest_label_testnothrow_956 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 956, ("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 "\"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_956
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_956
; } } else gtest_label_testnothrow_956 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 956, ("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 "\"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_956
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_956
; } } else gtest_label_testnothrow_956 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 956, ("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 "\"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_956
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_956
; } } else gtest_label_testnothrow_956 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 956, ("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()
;
957
958 ConstElementPtr status;
959 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_959; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_959; } } else gtest_label_testnothrow_959
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 959, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
960
961 // returned value should be 0 (success)
962 checkResult(status, 0);
963}
964
965/// Check that valid-lifetime must be between min-valid-lifetime and
966/// max-valid-lifetime when a bound is specified, *AND* a subnet is
967/// specified (boundary check is done when lifetimes are applied).
968TEST_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"
, 968), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 968), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 968), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_outBoundValidLifetime_Test
>); void Dhcp4ParserTest_outBoundValidLifetime_Test::TestBody
()
{
969
970 string too_small = "{ " + genIfaceConfig() + ","
971 "\"subnet4\": [ { "
972 " \"id\": 1,"
973 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
974 " \"subnet\": \"192.0.2.0/24\" } ],"
975 "\"valid-lifetime\": 1000, \"min-valid-lifetime\": 2000 }";
976
977 ConstElementPtr json;
978 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_978
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_978
; } } else gtest_label_testnothrow_978 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 978, ("Expected: " "json = parseDHCP4(too_small)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
979
980 ConstElementPtr status;
981 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_981; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_981; } } else gtest_label_testnothrow_981
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 981, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
982 string expected = "subnet configuration failed: "
983 "the value of min-valid-lifetime (2000) is not "
984 "less than (default) valid-lifetime (1000)";
985 checkResult(status, CONTROL_RESULT_ERROR, expected);
986 resetConfiguration();
987
988 string too_large = "{ " + genIfaceConfig() + ","
989 "\"subnet4\": [ { "
990 " \"id\": 1,"
991 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
992 " \"subnet\": \"192.0.2.0/24\" } ],"
993 "\"valid-lifetime\": 2000, \"max-valid-lifetime\": 1000 }";
994
995 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_995
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_995
; } } else gtest_label_testnothrow_995 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 995, ("Expected: " "json = parseDHCP4(too_large)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
996 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_996; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_996; } } else gtest_label_testnothrow_996
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 996, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
997 expected = "subnet configuration failed: "
998 "the value of (default) valid-lifetime (2000) is not "
999 "less than max-valid-lifetime (1000)";
1000 checkResult(status, CONTROL_RESULT_ERROR, expected);
1001 resetConfiguration();
1002
1003 string before = "{ " + genIfaceConfig() + ","
1004 "\"subnet4\": [ { "
1005 " \"id\": 1,"
1006 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1007 " \"subnet\": \"192.0.2.0/24\" } ],"
1008 "\"valid-lifetime\": 1000, \"min-valid-lifetime\": 2000, "
1009 "\"max-valid-lifetime\": 4000 }";
1010
1011 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_1011
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1011
; } } else gtest_label_testnothrow_1011 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1011, ("Expected: " "json = parseDHCP4(before)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1012 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_1012; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1012; } } else gtest_label_testnothrow_1012
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1012, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1013 expected = "subnet configuration failed: "
1014 "the value of (default) valid-lifetime (1000) is not "
1015 "between min-valid-lifetime (2000) and max-valid-lifetime (4000)";
1016 checkResult(status, CONTROL_RESULT_ERROR, expected);
1017 resetConfiguration();
1018
1019 string after = "{ " + genIfaceConfig() + ","
1020 "\"subnet4\": [ { "
1021 " \"id\": 1,"
1022 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1023 " \"subnet\": \"192.0.2.0/24\" } ],"
1024 "\"valid-lifetime\": 5000, \"min-valid-lifetime\": 1000, "
1025 "\"max-valid-lifetime\": 4000 }";
1026
1027 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_1027
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1027
; } } else gtest_label_testnothrow_1027 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1027, ("Expected: " "json = parseDHCP4(after)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1028 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_1028; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1028; } } else gtest_label_testnothrow_1028
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1028, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1029 expected = "subnet configuration failed: "
1030 "the value of (default) valid-lifetime (5000) is not "
1031 "between min-valid-lifetime (1000) and max-valid-lifetime (4000)";
1032 checkResult(status, CONTROL_RESULT_ERROR, expected);
1033 resetConfiguration();
1034
1035 string crossed = "{ " + genIfaceConfig() + ","
1036 "\"subnet4\": [ { "
1037 " \"id\": 1,"
1038 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1039 " \"subnet\": \"192.0.2.0/24\" } ],"
1040 "\"valid-lifetime\": 1500, \"min-valid-lifetime\": 2000, "
1041 "\"max-valid-lifetime\": 1000 }";
1042
1043 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_1043
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1043
; } } else gtest_label_testnothrow_1043 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1043, ("Expected: " "json = parseDHCP4(crossed)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1044 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_1044; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1044; } } else gtest_label_testnothrow_1044
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1044, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1045 expected = "subnet configuration failed: "
1046 "the value of min-valid-lifetime (2000) is not "
1047 "less than max-valid-lifetime (1000)";
1048 checkResult(status, CONTROL_RESULT_ERROR, expected);
1049}
1050
1051/// Check that valid-lifetime must be between min-valid-lifetime and
1052/// max-valid-lifetime when a bound is specified. Check on global
1053/// parameters only.
1054TEST_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"
, 1054), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1054), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1054), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_outBoundGlobalValidLifetime_Test
>); void Dhcp4ParserTest_outBoundGlobalValidLifetime_Test::
TestBody()
{
1055
1056 string too_small = "{ " + genIfaceConfig() + ","
1057 "\"valid-lifetime\": 1000, \"min-valid-lifetime\": 2000 }";
1058
1059 ConstElementPtr json;
1060 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_1060
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1060
; } } else gtest_label_testnothrow_1060 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1060, ("Expected: " "json = parseDHCP4(too_small)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1061
1062 ConstElementPtr status;
1063 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_1063; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1063; } } else gtest_label_testnothrow_1063
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1063, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1064 string expected =
1065 "the value of min-valid-lifetime (2000) is not "
1066 "less than (default) valid-lifetime (1000)";
1067 checkResult(status, CONTROL_RESULT_ERROR, expected);
1068 resetConfiguration();
1069
1070 string too_large = "{ " + genIfaceConfig() + ","
1071 "\"valid-lifetime\": 2000, \"max-valid-lifetime\": 1000 }";
1072
1073 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_1073
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1073
; } } else gtest_label_testnothrow_1073 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1073, ("Expected: " "json = parseDHCP4(too_large)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1074 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_1074; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1074; } } else gtest_label_testnothrow_1074
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1074, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1075 expected =
1076 "the value of (default) valid-lifetime (2000) is not "
1077 "less than max-valid-lifetime (1000)";
1078 checkResult(status, CONTROL_RESULT_ERROR, expected);
1079 resetConfiguration();
1080
1081 string before = "{ " + genIfaceConfig() + ","
1082 "\"valid-lifetime\": 1000, \"min-valid-lifetime\": 2000, "
1083 "\"max-valid-lifetime\": 4000 }";
1084
1085 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_1085
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1085
; } } else gtest_label_testnothrow_1085 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1085, ("Expected: " "json = parseDHCP4(before)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1086 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_1086; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1086; } } else gtest_label_testnothrow_1086
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1086, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1087 expected =
1088 "the value of (default) valid-lifetime (1000) is not "
1089 "between min-valid-lifetime (2000) and max-valid-lifetime (4000)";
1090 checkResult(status, CONTROL_RESULT_ERROR, expected);
1091 resetConfiguration();
1092
1093 string after = "{ " + genIfaceConfig() + ","
1094 "\"valid-lifetime\": 5000, \"min-valid-lifetime\": 1000, "
1095 "\"max-valid-lifetime\": 4000 }";
1096
1097 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_1097
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1097
; } } else gtest_label_testnothrow_1097 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1097, ("Expected: " "json = parseDHCP4(after)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1098 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_1098; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1098; } } else gtest_label_testnothrow_1098
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1098, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1099 expected =
1100 "the value of (default) valid-lifetime (5000) is not "
1101 "between min-valid-lifetime (1000) and max-valid-lifetime (4000)";
1102 checkResult(status, CONTROL_RESULT_ERROR, expected);
1103 resetConfiguration();
1104
1105 string crossed = "{ " + genIfaceConfig() + ","
1106 "\"valid-lifetime\": 1500, \"min-valid-lifetime\": 2000, "
1107 "\"max-valid-lifetime\": 1000 }";
1108
1109 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_1109
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1109
; } } else gtest_label_testnothrow_1109 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1109, ("Expected: " "json = parseDHCP4(crossed)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1110 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_1110; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1110; } } else gtest_label_testnothrow_1110
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1110, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1111 expected =
1112 "the value of min-valid-lifetime (2000) is not "
1113 "less than max-valid-lifetime (1000)";
1114 checkResult(status, CONTROL_RESULT_ERROR, expected);
1115}
1116
1117/// Check that the renew-timer doesn't have to be specified, in which case
1118/// it is marked unspecified in the Subnet.
1119TEST_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"
, 1119), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1119), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1119), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_unspecifiedRenewTimer_Test
>); void Dhcp4ParserTest_unspecifiedRenewTimer_Test::TestBody
()
{
1120
1121 string config = "{ " + genIfaceConfig() + ","
1122 "\"rebind-timer\": 2000, "
1123 "\"subnet4\": [ { "
1124 " \"id\": 1,"
1125 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1126 " \"subnet\": \"192.0.2.0/24\" } ],"
1127 "\"valid-lifetime\": 4000 }";
1128
1129 ConstElementPtr json;
1130 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_1130
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1130
; } } else gtest_label_testnothrow_1130 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1130, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1131 extractConfig(config);
1132
1133 ConstElementPtr status;
1134 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_1134; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1134; } } else gtest_label_testnothrow_1134
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1134, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1135
1136 // returned value should be 0 (success)
1137 checkResult(status, 0);
1138
1139 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
1140 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
1141 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"
, 1141, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
1142
1143 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"
, 1143, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getT1().unspecified()", "false", "true") .c_str
()) = ::testing::Message()
;
1144 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"
, 1144, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getT2().unspecified()", "true", "false") .c_str
()) = ::testing::Message()
;
1145 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"
, 1145, gtest_ar.failure_message()) = ::testing::Message()
;
1146 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"
, 1146, gtest_ar.failure_message()) = ::testing::Message()
;
1147
1148 // Check that subnet-id is 1
1149 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"
, 1149, gtest_ar.failure_message()) = ::testing::Message()
;
1150}
1151
1152/// Check that the rebind-timer doesn't have to be specified, in which case
1153/// it is marked unspecified in the Subnet.
1154TEST_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"
, 1154), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1154), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1154), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_unspecifiedRebindTimer_Test
>); void Dhcp4ParserTest_unspecifiedRebindTimer_Test::TestBody
()
{
1155
1156 string config = "{ " + genIfaceConfig() + ","
1157 "\"renew-timer\": 1000, "
1158 "\"subnet4\": [ { "
1159 " \"id\": 1,"
1160 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1161 " \"subnet\": \"192.0.2.0/24\" } ],"
1162 "\"valid-lifetime\": 4000 }";
1163
1164 ConstElementPtr json;
1165 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_1165
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1165
; } } else gtest_label_testnothrow_1165 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1165, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1166 extractConfig(config);
1167
1168 ConstElementPtr status;
1169 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_1169; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1169; } } else gtest_label_testnothrow_1169
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1169, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1170
1171 // returned value should be 0 (success)
1172 checkResult(status, 0);
1173
1174 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
1175 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
1176 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"
, 1176, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
1177 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"
, 1177, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getT1().unspecified()", "true", "false") .c_str
()) = ::testing::Message()
;
1178 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"
, 1178, gtest_ar.failure_message()) = ::testing::Message()
;
1179 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"
, 1179, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getT2().unspecified()", "false", "true") .c_str
()) = ::testing::Message()
;
1180 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"
, 1180, gtest_ar.failure_message()) = ::testing::Message()
;
1181
1182 // Check that subnet-id is 1
1183 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"
, 1183, gtest_ar.failure_message()) = ::testing::Message()
;
1184}
1185
1186/// The goal of this test is to verify if configuration without any
1187/// subnets defined can be accepted.
1188TEST_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", 1188
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1188), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1188), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_emptySubnet_Test
>); void Dhcp4ParserTest_emptySubnet_Test::TestBody()
{
1189
1190 string config = "{ " + genIfaceConfig() + ","
1191 "\"rebind-timer\": 2000, "
1192 "\"renew-timer\": 1000, "
1193 "\"subnet4\": [ ], "
1194 "\"valid-lifetime\": 4000 }";
1195
1196 ConstElementPtr json;
1197 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_1197
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1197
; } } else gtest_label_testnothrow_1197 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1197, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1198 extractConfig(config);
1199
1200 ConstElementPtr status;
1201 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_1201; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1201; } } else gtest_label_testnothrow_1201
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1201, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1202
1203 // returned value should be 0 (success)
1204 checkResult(status, 0);
1205}
1206
1207/// The goal of this test is to verify if defined subnet uses global
1208/// parameter timer definitions.
1209TEST_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"
, 1209), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1209), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1209), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_subnetGlobalDefaults_Test
>); void Dhcp4ParserTest_subnetGlobalDefaults_Test::TestBody
()
{
1210
1211 string config = "{ " + genIfaceConfig() + ","
1212 "\"rebind-timer\": 2000, "
1213 "\"renew-timer\": 1000, "
1214 "\"subnet4\": [ { "
1215 " \"id\": 1,"
1216 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1217 " \"subnet\": \"192.0.2.0/24\" } ],"
1218 "\"valid-lifetime\": 4000,"
1219 "\"min-valid-lifetime\": 3000,"
1220 "\"max-valid-lifetime\": 5000 }";
1221
1222 ConstElementPtr json;
1223 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_1223
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1223
; } } else gtest_label_testnothrow_1223 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1223, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1224 extractConfig(config);
1225
1226 ConstElementPtr status;
1227 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_1227; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1227; } } else gtest_label_testnothrow_1227
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1227, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1228
1229 // check if returned status is OK
1230 checkResult(status, 0);
1231
1232 // Now check if the configuration was indeed handled and we have
1233 // expected pool configured.
1234 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
1235 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
1236 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"
, 1236, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
1237 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"
, 1237, gtest_ar.failure_message()) = ::testing::Message()
;
1238 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"
, 1238, gtest_ar.failure_message()) = ::testing::Message()
;
1239 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"
, 1239, gtest_ar.failure_message()) = ::testing::Message()
;
1240 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", 1240
, gtest_ar.failure_message()) = ::testing::Message()
;
1241 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", 1241
, gtest_ar.failure_message()) = ::testing::Message()
;
1242
1243 // Check that subnet-id is 1
1244 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"
, 1244, gtest_ar.failure_message()) = ::testing::Message()
;
1245}
1246
1247// This test checks that it is possible to assign arbitrary ids for subnets.
1248TEST_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"
, 1248), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1248), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1248), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_multipleSubnetsExplicitIDs_Test
>); void Dhcp4ParserTest_multipleSubnetsExplicitIDs_Test::
TestBody()
{
1249 ConstElementPtr x;
1250 // Four subnets with arbitrary subnet ids.
1251 string config = "{ " + genIfaceConfig() + ","
1252 "\"rebind-timer\": 2000, "
1253 "\"renew-timer\": 1000, "
1254 "\"subnet4\": [ { "
1255 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1256 " \"subnet\": \"192.0.2.0/24\", "
1257 " \"id\": 1024"
1258 " },"
1259 " {"
1260 " \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
1261 " \"subnet\": \"192.0.3.0/24\", "
1262 " \"id\": 100"
1263 " },"
1264 " {"
1265 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
1266 " \"subnet\": \"192.0.4.0/24\", "
1267 " \"id\": 1"
1268 " },"
1269 " {"
1270 " \"pools\": [ { \"pool\": \"192.0.5.101 - 192.0.5.150\" } ],"
1271 " \"subnet\": \"192.0.5.0/24\", "
1272 " \"id\": 34"
1273 " } ],"
1274 "\"valid-lifetime\": 4000 }";
1275
1276 int cnt = 0; // Number of reconfigurations
1277
1278 ConstElementPtr json;
1279 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_1279
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1279
; } } else gtest_label_testnothrow_1279 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1279, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1280 extractConfig(config);
1281
1282 do {
1283 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_1283; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1283; } } else gtest_label_testnothrow_1283
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1283, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1284 checkResult(x, 0);
1285
1286 CfgMgr::instance().commit();
1287
1288 const Subnet4Collection* subnets =
1289 CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
1290 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"
, 1290, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
1291 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"
, 1291, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 4 subnets
1292
1293 // Verify that subnet ids are as expected.
1294 // Now the subnet order is the subnet id one.
1295 auto subnet = subnets->begin();
1296 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"
, 1296, gtest_ar.failure_message()) = ::testing::Message()
;
1297 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"
, 1297, gtest_ar.failure_message()) = ::testing::Message()
;
1298 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"
, 1298, gtest_ar.failure_message()) = ::testing::Message()
;
1299 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"
, 1299, gtest_ar.failure_message()) = ::testing::Message()
;
1300
1301 // Repeat reconfiguration process 10 times and check that the subnet-id
1302 // is set to the same value.
1303 } while (++cnt < 3);
1304}
1305
1306// Check that the configuration with two subnets having the same ID is rejected.
1307TEST_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"
, 1307), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1307), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1307), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_multipleSubnetsOverlappingIDs_Test
>); void Dhcp4ParserTest_multipleSubnetsOverlappingIDs_Test
::TestBody()
{
1308 ConstElementPtr x;
1309 // Four subnets, two of them have the same id.
1310 string config = "{ " + genIfaceConfig() + ","
1311 "\"rebind-timer\": 2000, "
1312 "\"renew-timer\": 1000, "
1313 "\"subnet4\": [ { "
1314 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1315 " \"subnet\": \"192.0.2.0/24\", "
1316 " \"id\": 1024"
1317 " },"
1318 " {"
1319 " \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
1320 " \"subnet\": \"192.0.3.0/24\", "
1321 " \"id\": 100"
1322 " },"
1323 " {"
1324 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
1325 " \"subnet\": \"192.0.4.0/24\", "
1326 " \"id\": 1024"
1327 " },"
1328 " {"
1329 " \"pools\": [ { \"pool\": \"192.0.5.101 - 192.0.5.150\" } ],"
1330 " \"subnet\": \"192.0.5.0/24\", "
1331 " \"id\": 34"
1332 " } ],"
1333 "\"valid-lifetime\": 4000 }";
1334
1335 ConstElementPtr json;
1336 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_1336
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1336
; } } else gtest_label_testnothrow_1336 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1336, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1337
1338 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_1338; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1338; } } else gtest_label_testnothrow_1338
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1338, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1339 checkResult(x, CONTROL_RESULT_ERROR);
1340 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"
, 1340, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(x, \"<string>\")", "false", "true"
) .c_str()) = ::testing::Message()
;
1341}
1342
1343// Goal of this test is to verify that a previously configured subnet can be
1344// deleted in subsequent reconfiguration.
1345TEST_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"
, 1345), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1345), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1345), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_reconfigureRemoveSubnet_Test
>); void Dhcp4ParserTest_reconfigureRemoveSubnet_Test::TestBody
()
{
1346 ConstElementPtr x;
1347
1348 // All four subnets
1349 string config4 = "{ " + genIfaceConfig() + ","
1350 "\"rebind-timer\": 2000, "
1351 "\"renew-timer\": 1000, "
1352 "\"subnet4\": [ { "
1353 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1354 " \"subnet\": \"192.0.2.0/24\", "
1355 " \"id\": 1"
1356 " },"
1357 " {"
1358 " \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
1359 " \"subnet\": \"192.0.3.0/24\", "
1360 " \"id\": 2"
1361 " },"
1362 " {"
1363 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
1364 " \"subnet\": \"192.0.4.0/24\", "
1365 " \"id\": 3"
1366 " },"
1367 " {"
1368 " \"pools\": [ { \"pool\": \"192.0.5.101 - 192.0.5.150\" } ],"
1369 " \"subnet\": \"192.0.5.0/24\", "
1370 " \"id\": 4"
1371 " } ],"
1372 "\"valid-lifetime\": 4000 }";
1373
1374 // Three subnets (the last one removed)
1375 string config_first3 = "{ " + genIfaceConfig() + ","
1376 "\"rebind-timer\": 2000, "
1377 "\"renew-timer\": 1000, "
1378 "\"subnet4\": [ { "
1379 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1380 " \"subnet\": \"192.0.2.0/24\", "
1381 " \"id\": 1"
1382 " },"
1383 " {"
1384 " \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
1385 " \"subnet\": \"192.0.3.0/24\", "
1386 " \"id\": 2"
1387 " },"
1388 " {"
1389 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
1390 " \"subnet\": \"192.0.4.0/24\", "
1391 " \"id\": 3"
1392 " } ],"
1393 "\"valid-lifetime\": 4000 }";
1394
1395 // Second subnet removed
1396 string config_second_removed = "{ " + genIfaceConfig() + ","
1397 "\"rebind-timer\": 2000, "
1398 "\"renew-timer\": 1000, "
1399 "\"subnet4\": [ { "
1400 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1401 " \"subnet\": \"192.0.2.0/24\", "
1402 " \"id\": 1"
1403 " },"
1404 " {"
1405 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
1406 " \"subnet\": \"192.0.4.0/24\", "
1407 " \"id\": 3"
1408 " },"
1409 " {"
1410 " \"pools\": [ { \"pool\": \"192.0.5.101 - 192.0.5.150\" } ],"
1411 " \"subnet\": \"192.0.5.0/24\", "
1412 " \"id\": 4"
1413 " } ],"
1414 "\"valid-lifetime\": 4000 }";
1415
1416 // CASE 1: Configure 4 subnets, then reconfigure and remove the
1417 // last one.
1418
1419 ConstElementPtr json;
1420 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_1420
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1420
; } } else gtest_label_testnothrow_1420 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1420, ("Expected: " "json = parseDHCP4(config4)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1421 extractConfig(config4);
1422 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_1422; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1422; } } else gtest_label_testnothrow_1422
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1422, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1423 checkResult(x, 0);
1424
1425 CfgMgr::instance().commit();
1426
1427 const Subnet4Collection* subnets =
1428 CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
1429 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"
, 1429, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
1430 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"
, 1430, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 4 subnets
1431
1432 CfgMgr::instance().clear();
1433
1434 // Do the reconfiguration (the last subnet is removed)
1435 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_1435
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1435
; } } else gtest_label_testnothrow_1435 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1435, ("Expected: " "json = parseDHCP4(config_first3)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1436 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_1436; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1436; } } else gtest_label_testnothrow_1436
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1436, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1437 checkResult(x, 0);
1438
1439 CfgMgr::instance().commit();
1440
1441 subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
1442 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"
, 1442, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
1443 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"
, 1443, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 3 subnets now (4th is removed)
1444
1445 // Check subnet-ids of each subnet (it should be monotonously increasing)
1446 auto subnet = subnets->begin();
1447 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"
, 1447, gtest_ar.failure_message()) = ::testing::Message()
;
1448 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"
, 1448, gtest_ar.failure_message()) = ::testing::Message()
;
1449 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"
, 1449, gtest_ar.failure_message()) = ::testing::Message()
;
1450
1451 CfgMgr::instance().clear();
1452
1453 /// CASE 2: Configure 4 subnets, then reconfigure and remove one
1454 /// from in between (not first, not last)
1455 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_1455
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1455
; } } else gtest_label_testnothrow_1455 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1455, ("Expected: " "json = parseDHCP4(config4)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1456 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_1456; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1456; } } else gtest_label_testnothrow_1456
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1456, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1457 checkResult(x, 0);
1458
1459 CfgMgr::instance().commit();
1460
1461 // Do reconfiguration
1462 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_1462; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1462; } } else gtest_label_testnothrow_1462
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1462, ("Expected: " "json = parseDHCP4(config_second_removed)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1463 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_1463; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1463; } } else gtest_label_testnothrow_1463
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1463, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1464 checkResult(x, 0);
1465
1466 CfgMgr::instance().commit();
1467
1468 subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
1469 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"
, 1469, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
1470 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"
, 1470, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 4 subnets
1471
1472 subnet = subnets->begin();
1473 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"
, 1473, gtest_ar.failure_message()) = ::testing::Message()
;
1474 // The second subnet (with subnet-id = 2) is no longer there
1475 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"
, 1475, gtest_ar.failure_message()) = ::testing::Message()
;
1476 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"
, 1476, gtest_ar.failure_message()) = ::testing::Message()
;
1477}
1478
1479/// @todo: implement subnet removal test as part of #3281.
1480
1481// Checks if the next-server and other fixed BOOTP fields defined as
1482// global parameter are taken into consideration.
1483TEST_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"
, 1483), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1483), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1483), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_nextServerGlobal_Test
>); void Dhcp4ParserTest_nextServerGlobal_Test::TestBody()
{
1484
1485 string config = "{ " + genIfaceConfig() + ","
1486 "\"rebind-timer\": 2000, "
1487 "\"renew-timer\": 1000, "
1488 "\"next-server\": \"1.2.3.4\", "
1489 "\"server-hostname\": \"foo\", "
1490 "\"boot-file-name\": \"bar\", "
1491 "\"subnet4\": [ { "
1492 " \"id\": 1,"
1493 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1494 " \"subnet\": \"192.0.2.0/24\" } ],"
1495 "\"valid-lifetime\": 4000 }";
1496
1497 ConstElementPtr json;
1498 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_1498
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1498
; } } else gtest_label_testnothrow_1498 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1498, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1499 extractConfig(config);
1500
1501 ConstElementPtr status;
1502 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_1502; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1502; } } else gtest_label_testnothrow_1502
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1502, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1503
1504 // check if returned status is OK
1505 checkResult(status, 0);
1506
1507 // Now check if the configuration was indeed handled and we have
1508 // expected pool configured.
1509 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
1510 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
1511 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"
, 1511, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
1512 // Reset the fetch global function to staging (vs current) config.
1513 Subnet4Ptr mutable_subnet = boost::const_pointer_cast<Subnet4>(subnet);
1514 mutable_subnet->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
1515 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
1516 });
1517 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"
, 1517, gtest_ar.failure_message()) = ::testing::Message()
;
1518 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"
, 1518, gtest_ar.failure_message()) = ::testing::Message()
;
1519 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"
, 1519, gtest_ar.failure_message()) = ::testing::Message()
;
1520}
1521
1522// Checks if the next-server and other fixed BOOTP fields defined as
1523// subnet parameter are taken into consideration.
1524TEST_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"
, 1524), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1524), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1524), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_nextServerSubnet_Test
>); void Dhcp4ParserTest_nextServerSubnet_Test::TestBody()
{
1525
1526 string config = "{ " + genIfaceConfig() + ","
1527 "\"rebind-timer\": 2000, "
1528 "\"renew-timer\": 1000, "
1529 "\"subnet4\": [ { "
1530 " \"id\": 1,"
1531 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1532 " \"next-server\": \"1.2.3.4\", "
1533 " \"server-hostname\": \"foo\", "
1534 " \"boot-file-name\": \"bar\", "
1535 " \"subnet\": \"192.0.2.0/24\" } ],"
1536 "\"valid-lifetime\": 4000 }";
1537
1538 ConstElementPtr json;
1539 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_1539
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1539
; } } else gtest_label_testnothrow_1539 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1539, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1540 extractConfig(config);
1541
1542 ConstElementPtr status;
1543 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_1543; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1543; } } else gtest_label_testnothrow_1543
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1543, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1544
1545 // check if returned status is OK
1546 checkResult(status, 0);
1547
1548 // Now check if the configuration was indeed handled and we have
1549 // expected pool configured.
1550 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
1551 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
1552 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"
, 1552, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
1553 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"
, 1553, gtest_ar.failure_message()) = ::testing::Message()
;
1554 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"
, 1554, gtest_ar.failure_message()) = ::testing::Message()
;
1555 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"
, 1555, gtest_ar.failure_message()) = ::testing::Message()
;
1556}
1557
1558// Test checks several negative scenarios for next-server configuration: bogus
1559// address, IPv6 address and empty string.
1560TEST_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"
, 1560), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1560), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1560), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_nextServerNegative_Test
>); void Dhcp4ParserTest_nextServerNegative_Test::TestBody
()
{
1561 IfaceMgrTestConfig test_config(true);
1562
1563 // Config with junk instead of next-server address
1564 string config_bogus1 = "{ " + genIfaceConfig() + ","
1565 "\"rebind-timer\": 2000, "
1566 "\"renew-timer\": 1000, "
1567 "\"subnet4\": [ { "
1568 " \"id\": 1,"
1569 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1570 " \"rebind-timer\": 2000, "
1571 " \"renew-timer\": 1000, "
1572 " \"next-server\": \"a.b.c.d\", "
1573 " \"subnet\": \"192.0.2.0/24\" } ],"
1574 "\"valid-lifetime\": 4000 }";
1575
1576 // Config with IPv6 next server address
1577 string config_bogus2 = "{ " + genIfaceConfig() + ","
1578 "\"rebind-timer\": 2000, "
1579 "\"renew-timer\": 1000, "
1580 "\"subnet4\": [ { "
1581 " \"id\": 1,"
1582 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1583 " \"rebind-timer\": 2000, "
1584 " \"renew-timer\": 1000, "
1585 " \"next-server\": \"2001:db8::1\", "
1586 " \"subnet\": \"192.0.2.0/24\" } ],"
1587 "\"valid-lifetime\": 4000 }";
1588
1589 // Config with empty next server address
1590 string config_bogus3 = "{ " + genIfaceConfig() + ","
1591 "\"rebind-timer\": 2000, "
1592 "\"renew-timer\": 1000, "
1593 "\"subnet4\": [ { "
1594 " \"id\": 1,"
1595 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1596 " \"rebind-timer\": 2000, "
1597 " \"renew-timer\": 1000, "
1598 " \"next-server\": \"\", "
1599 " \"subnet\": \"192.0.2.0/24\" } ],"
1600 "\"valid-lifetime\": 4000 }";
1601
1602 // Config with too large server-hostname
1603 string bigsname(Pkt4::MAX_SNAME_LEN + 1, ' ');
1604 string config_bogus4 = "{ " + genIfaceConfig() + ","
1605 "\"rebind-timer\": 2000, "
1606 "\"renew-timer\": 1000, "
1607 "\"subnet4\": [ { "
1608 " \"id\": 1,"
1609 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1610 " \"rebind-timer\": 2000, "
1611 " \"renew-timer\": 1000, "
1612 " \"server-hostname\": \"" + bigsname + "\", " +
1613 " \"subnet\": \"192.0.2.0/24\" } ],"
1614 "\"valid-lifetime\": 4000 }";
1615
1616 // Config with too large boot-file-hostname
1617 string bigfilename(Pkt4::MAX_FILE_LEN + 1, ' ');
1618 string config_bogus5 = "{ " + genIfaceConfig() + ","
1619 "\"rebind-timer\": 2000, "
1620 "\"renew-timer\": 1000, "
1621 "\"subnet4\": [ { "
1622 " \"id\": 1,"
1623 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1624 " \"rebind-timer\": 2000, "
1625 " \"renew-timer\": 1000, "
1626 " \"boot-file-name\": \"" + bigfilename + "\", " +
1627 " \"subnet\": \"192.0.2.0/24\" } ],"
1628 "\"valid-lifetime\": 4000 }";
1629
1630 ConstElementPtr json1;
1631 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_1631
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1631
; } } else gtest_label_testnothrow_1631 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1631, ("Expected: " "json1 = parseDHCP4(config_bogus1)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1632 ConstElementPtr json2;
1633 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_1633
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1633
; } } else gtest_label_testnothrow_1633 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1633, ("Expected: " "json2 = parseDHCP4(config_bogus2)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1634 ConstElementPtr json3;
1635 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_1635
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1635
; } } else gtest_label_testnothrow_1635 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1635, ("Expected: " "json3 = parseDHCP4(config_bogus3)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1636 ConstElementPtr json4;
1637 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_1637
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1637
; } } else gtest_label_testnothrow_1637 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1637, ("Expected: " "json4 = parseDHCP4(config_bogus4)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1638 ConstElementPtr json5;
1639 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_1639
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1639
; } } else gtest_label_testnothrow_1639 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1639, ("Expected: " "json5 = parseDHCP4(config_bogus5)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1640
1641 // check if returned status is always a failure
1642 ConstElementPtr status;
1643 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_1643; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1643; } } else gtest_label_testnothrow_1643
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1643, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json1)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1644 checkResult(status, CONTROL_RESULT_ERROR);
1645 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"
, 1645, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
1646
1647 CfgMgr::instance().clear();
1648
1649 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_1649; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1649; } } else gtest_label_testnothrow_1649
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1649, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json2)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1650 checkResult(status, CONTROL_RESULT_ERROR);
1651 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"
, 1651, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
1652
1653 CfgMgr::instance().clear();
1654
1655 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_1655; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1655; } } else gtest_label_testnothrow_1655
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1655, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json3)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1656 checkResult(status, 0);
1657 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"
, 1657, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "true"
, "false") .c_str()) = ::testing::Message()
;
1658
1659 CfgMgr::instance().clear();
1660
1661 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_1661; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1661; } } else gtest_label_testnothrow_1661
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1661, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json4)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1662 checkResult(status, CONTROL_RESULT_ERROR);
1663 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"
, 1663, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
1664
1665 CfgMgr::instance().clear();
1666
1667 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_1667; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1667; } } else gtest_label_testnothrow_1667
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1667, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json5)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1668 checkResult(status, CONTROL_RESULT_ERROR);
1669 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"
, 1669, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
1670}
1671
1672// Checks if the next-server defined as global value is overridden by subnet
1673// specific value.
1674TEST_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"
, 1674), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1674), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1674), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_nextServerOverride_Test
>); void Dhcp4ParserTest_nextServerOverride_Test::TestBody
()
{
1675
1676 string config = "{ " + genIfaceConfig() + ","
1677 "\"rebind-timer\": 2000, "
1678 "\"renew-timer\": 1000, "
1679 "\"next-server\": \"192.0.0.1\", "
1680 "\"server-hostname\": \"nohost\","
1681 "\"boot-file-name\": \"nofile\","
1682 "\"subnet4\": [ { "
1683 " \"id\": 1,"
1684 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1685 " \"next-server\": \"1.2.3.4\", "
1686 " \"server-hostname\": \"some-name.example.org\","
1687 " \"boot-file-name\": \"bootfile.efi\","
1688 " \"subnet\": \"192.0.2.0/24\" } ],"
1689 "\"valid-lifetime\": 4000 }";
1690
1691 ConstElementPtr json;
1692 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_1692
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1692
; } } else gtest_label_testnothrow_1692 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1692, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1693 extractConfig(config);
1694
1695 ConstElementPtr status;
1696 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_1696; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1696; } } else gtest_label_testnothrow_1696
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1696, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1697
1698 // check if returned status is OK
1699 checkResult(status, 0);
1700
1701 // Now check if the configuration was indeed handled and we have
1702 // expected pool configured.
1703 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
1704 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
1705 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"
, 1705, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
1706 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"
, 1706, gtest_ar.failure_message()) = ::testing::Message()
;
1707 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"
, 1707, gtest_ar.failure_message()) = ::testing::Message()
;
1708 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"
, 1708, gtest_ar.failure_message()) = ::testing::Message()
;
1709}
1710
1711// Check whether it is possible to configure echo-client-id
1712TEST_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", 1712
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1712), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1712), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_echoClientId_Test
>); void Dhcp4ParserTest_echoClientId_Test::TestBody()
{
1713
1714 string config_false = "{ " + genIfaceConfig() + ","
1715 "\"rebind-timer\": 2000, "
1716 "\"renew-timer\": 1000, "
1717 "\"echo-client-id\": false,"
1718 "\"subnet4\": [ { "
1719 " \"id\": 1,"
1720 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1721 " \"subnet\": \"192.0.2.0/24\" } ],"
1722 "\"valid-lifetime\": 4000 }";
1723
1724 string config_true = "{ " + genIfaceConfig() + ","
1725 "\"rebind-timer\": 2000, "
1726 "\"renew-timer\": 1000, "
1727 "\"echo-client-id\": true,"
1728 "\"subnet4\": [ { "
1729 " \"id\": 1,"
1730 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1731 " \"subnet\": \"192.0.2.0/24\" } ],"
1732 "\"valid-lifetime\": 4000 }";
1733
1734 ConstElementPtr json_false;
1735 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_1735; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1735; } } else gtest_label_testnothrow_1735
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1735, ("Expected: " "json_false = parseDHCP4(config_false)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1736 extractConfig(config_false);
1737 ConstElementPtr json_true;
1738 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_1738
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1738
; } } else gtest_label_testnothrow_1738 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1738, ("Expected: " "json_true = parseDHCP4(config_true)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1739 extractConfig(config_true);
1740
1741 // Let's check the default. It should be true
1742 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"
, 1742, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getEchoClientId()",
"false", "true") .c_str()) = ::testing::Message()
;
1743
1744 // Now check that "false" configuration is really applied.
1745 ConstElementPtr status;
1746 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_1746; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1746; } } else gtest_label_testnothrow_1746
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1746, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json_false)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1747 checkResult(status, 0);
1748 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", 1748
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getEchoClientId()",
"true", "false") .c_str()) = ::testing::Message()
;
1749
1750 CfgMgr::instance().clear();
1751
1752 // Now check that "true" configuration is really applied.
1753 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_1753; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1753; } } else gtest_label_testnothrow_1753
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1753, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json_true)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1754 checkResult(status, 0);
1755 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"
, 1755, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getEchoClientId()",
"false", "true") .c_str()) = ::testing::Message()
;
1756
1757 // In any case revert back to the default value (true)
1758 CfgMgr::instance().getStagingCfg()->setEchoClientId(true);
1759}
1760
1761// Check whether it is possible to configure compatibility flags.
1762TEST_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", 1762
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1762), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1762), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_compatibility_Test
>); void Dhcp4ParserTest_compatibility_Test::TestBody()
{
1763 string config = "{ " + genIfaceConfig() + ","
1764 "\"rebind-timer\": 2000, "
1765 "\"renew-timer\": 1000, "
1766 "\"compatibility\": { "
1767 " \"lenient-option-parsing\": true,"
1768 " \"ignore-dhcp-server-identifier\": true,"
1769 " \"ignore-rai-link-selection\": true,"
1770 " \"exclude-first-last-24\": true"
1771 "},"
1772 "\"subnet4\": [ { "
1773 " \"id\": 1,"
1774 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1775 " \"subnet\": \"192.0.2.0/24\" } ],"
1776 "\"valid-lifetime\": 4000 }";
1777
1778 ConstElementPtr json;
1779 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_1779
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1779
; } } else gtest_label_testnothrow_1779 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1779, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
<< "bad config: " << config;
1780 extractConfig(config);
1781
1782 // Check defaults: they should be false.
1783 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", 1783
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getLenientOptionParsing()"
, "true", "false") .c_str()) = ::testing::Message()
;
1784 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", 1784
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getIgnoreServerIdentifier()"
, "true", "false") .c_str()) = ::testing::Message()
;
1785 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", 1785
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getIgnoreRAILinkSelection()"
, "true", "false") .c_str()) = ::testing::Message()
;
1786 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", 1786
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getExcludeFirstLast24()"
, "true", "false") .c_str()) = ::testing::Message()
;
1787
1788 // Check the configuration was really applied.
1789 ConstElementPtr status;
1790 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_1790; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1790; } } else gtest_label_testnothrow_1790
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1790, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1791 checkResult(status, 0);
1792
1793 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"
, 1793, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getLenientOptionParsing()"
, "false", "true") .c_str()) = ::testing::Message()
;
1794 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"
, 1794, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getIgnoreServerIdentifier()"
, "false", "true") .c_str()) = ::testing::Message()
;
1795 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"
, 1795, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getIgnoreRAILinkSelection()"
, "false", "true") .c_str()) = ::testing::Message()
;
1796 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"
, 1796, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getExcludeFirstLast24()"
, "false", "true") .c_str()) = ::testing::Message()
;
1797}
1798
1799// Check that unknown compatibility flag raises error.
1800TEST_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"
, 1800), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1800), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1800), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_compatibilityUnknown_Test
>); void Dhcp4ParserTest_compatibilityUnknown_Test::TestBody
()
{
1801 string config = "{ " + genIfaceConfig() + ","
1802 "\"rebind-timer\": 2000, "
1803 "\"renew-timer\": 1000, "
1804 "\"compatibility\": { "
1805 " \"foo-bar\": true"
1806 "},"
1807 "\"subnet4\": [ { "
1808 " \"id\": 1,"
1809 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1810 " \"subnet\": \"192.0.2.0/24\" } ],"
1811 "\"valid-lifetime\": 4000 }";
1812
1813 // Syntax is incorrect.
1814 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_1814; } catch (...
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_1814; } 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_1814
; } } else gtest_label_testthrow_1814 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1814, gtest_msg.value.c_str()) = ::testing::Message()
;
1815 ConstElementPtr json;
1816 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_1816
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1816
; } } else gtest_label_testnothrow_1816 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1816, ("Expected: " "json = parseJSON(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1817
1818 // Unknown keyword is detected.
1819 ConstElementPtr status;
1820 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_1820; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1820; } } else gtest_label_testnothrow_1820
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1820, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1821 string expected = "unsupported compatibility parameter: ";
1822 expected += "foo-bar (<string>:1:127)";
1823 checkResult(status, CONTROL_RESULT_ERROR, expected);
1824}
1825
1826// Check that not boolean compatibility flag value raises error.
1827TEST_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"
, 1827), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1827), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1827), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_compatibilityNotBool_Test
>); void Dhcp4ParserTest_compatibilityNotBool_Test::TestBody
()
{
1828 string config = "{ " + genIfaceConfig() + ","
1829 "\"rebind-timer\": 2000, "
1830 "\"renew-timer\": 1000, "
1831 "\"compatibility\": { "
1832 " \"lenient-option-parsing\": 1"
1833 "},"
1834 "\"subnet4\": [ { "
1835 " \"id\": 1,"
1836 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1837 " \"subnet\": \"192.0.2.0/24\" } ],"
1838 "\"valid-lifetime\": 4000 }";
1839
1840 // Syntax is incorrect.
1841 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_1841; } catch (...
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_1841; } 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_1841
; } } else gtest_label_testthrow_1841 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1841, gtest_msg.value.c_str()) = ::testing::Message()
;
1842 ConstElementPtr json;
1843 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_1843
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1843
; } } else gtest_label_testnothrow_1843 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1843, ("Expected: " "json = parseJSON(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1844
1845 // Bad value type is detected.
1846 ConstElementPtr status;
1847 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_1847; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1847; } } else gtest_label_testnothrow_1847
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1847, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1848 string expected = "compatibility parameter values must be boolean ";
1849 expected += "(lenient-option-parsing at <string>:1:142)";
1850 checkResult(status, CONTROL_RESULT_ERROR, expected);
1851}
1852
1853// This test checks that the global match-client-id parameter is optional
1854// and that values under the subnet are used.
1855TEST_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"
, 1855), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1855), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1855), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_matchClientIdNoGlobal_Test
>); void Dhcp4ParserTest_matchClientIdNoGlobal_Test::TestBody
()
{
1856 std::string config = "{ " + genIfaceConfig() + ","
1857 "\"rebind-timer\": 2000, "
1858 "\"renew-timer\": 1000, "
1859 "\"subnet4\": [ "
1860 "{"
1861 " \"id\": 1,"
1862 " \"match-client-id\": true,"
1863 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1864 " \"subnet\": \"192.0.2.0/24\""
1865 "},"
1866 "{"
1867 " \"id\": 2,"
1868 " \"match-client-id\": false,"
1869 " \"pools\": [ { \"pool\": \"192.0.3.1 - 192.0.3.100\" } ],"
1870 " \"subnet\": \"192.0.3.0/24\""
1871 "} ],"
1872 "\"valid-lifetime\": 4000 }";
1873
1874 ConstElementPtr json;
1875 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_1875
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1875
; } } else gtest_label_testnothrow_1875 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1875, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1876 extractConfig(config);
1877
1878 ConstElementPtr status;
1879 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_1879; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1879; } } else gtest_label_testnothrow_1879
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1879, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1880 checkResult(status, 0);
1881
1882 CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
1883 ConstSubnet4Ptr subnet1 = cfg->selectSubnet(IOAddress("192.0.2.1"));
1884 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"
, 1884, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1", "false", "true") .c_str()) = ::testing::Message(
)
;
1885 // Reset the fetch global function to staging (vs current) config.
1886 Subnet4Ptr mutable_subnet1 = boost::const_pointer_cast<Subnet4>(subnet1);
1887 mutable_subnet1->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
1888 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
1889 });
1890 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"
, 1890, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1->getMatchClientId()", "false", "true") .c_str()
) = ::testing::Message()
;
1891
1892 ConstSubnet4Ptr subnet2 = cfg->selectSubnet(IOAddress("192.0.3.1"));
1893 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"
, 1893, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2", "false", "true") .c_str()) = ::testing::Message(
)
;
1894 // Reset the fetch global function to staging (vs current) config.
1895 Subnet4Ptr mutable_subnet2 = boost::const_pointer_cast<Subnet4>(subnet2);
1896 mutable_subnet2->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
1897 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
1898 });
1899 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"
, 1899, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2->getMatchClientId()", "true", "false") .c_str()
) = ::testing::Message()
;
1900}
1901
1902// This test checks that the global match-client-id parameter is used
1903// when there is no such parameter under subnet and that the parameter
1904// specified for a subnet overrides the global setting.
1905TEST_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"
, 1905), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1905), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1905), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_matchClientIdGlobal_Test
>); void Dhcp4ParserTest_matchClientIdGlobal_Test::TestBody
()
{
1906 std::string config = "{ " + genIfaceConfig() + ","
1907 "\"rebind-timer\": 2000, "
1908 "\"renew-timer\": 1000, "
1909 "\"match-client-id\": true,"
1910 "\"subnet4\": [ "
1911 "{"
1912 " \"id\": 1,"
1913 " \"match-client-id\": false,"
1914 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1915 " \"subnet\": \"192.0.2.0/24\""
1916 "},"
1917 "{"
1918 " \"id\": 2,"
1919 " \"pools\": [ { \"pool\": \"192.0.3.1 - 192.0.3.100\" } ],"
1920 " \"subnet\": \"192.0.3.0/24\""
1921 "} ],"
1922 "\"valid-lifetime\": 4000 }";
1923
1924 ConstElementPtr json;
1925 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_1925
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1925
; } } else gtest_label_testnothrow_1925 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1925, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1926 extractConfig(config);
1927
1928 ConstElementPtr status;
1929 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_1929; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1929; } } else gtest_label_testnothrow_1929
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1929, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1930 checkResult(status, 0);
1931
1932 CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
1933 ConstSubnet4Ptr subnet1 = cfg->selectSubnet(IOAddress("192.0.2.1"));
1934 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"
, 1934, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1", "false", "true") .c_str()) = ::testing::Message(
)
;
1935 // Reset the fetch global function to staging (vs current) config.
1936 Subnet4Ptr mutable_subnet1 = boost::const_pointer_cast<Subnet4>(subnet1);
1937 mutable_subnet1->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
1938 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
1939 });
1940 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"
, 1940, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1->getMatchClientId()", "true", "false") .c_str()
) = ::testing::Message()
;
1941
1942 ConstSubnet4Ptr subnet2 = cfg->selectSubnet(IOAddress("192.0.3.1"));
1943 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"
, 1943, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2", "false", "true") .c_str()) = ::testing::Message(
)
;
1944 // Reset the fetch global function to staging (vs current) config.
1945 Subnet4Ptr mutable_subnet2 = boost::const_pointer_cast<Subnet4>(subnet2);
1946 mutable_subnet2->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
1947 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
1948 });
1949 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"
, 1949, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2->getMatchClientId()", "false", "true") .c_str()
) = ::testing::Message()
;
1950}
1951
1952// This test checks that the global authoritative parameter is optional
1953// and that values under the subnet are used.
1954TEST_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"
, 1954), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1954), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1954), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_authoritativeNoGlobal_Test
>); void Dhcp4ParserTest_authoritativeNoGlobal_Test::TestBody
()
{
1955 std::string config = "{ " + genIfaceConfig() + ","
1956 "\"rebind-timer\": 2000, "
1957 "\"renew-timer\": 1000, "
1958 "\"subnet4\": [ "
1959 "{"
1960 " \"id\": 1,"
1961 " \"authoritative\": true,"
1962 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
1963 " \"subnet\": \"192.0.2.0/24\""
1964 "},"
1965 "{"
1966 " \"id\": 2,"
1967 " \"authoritative\": false,"
1968 " \"pools\": [ { \"pool\": \"192.0.3.1 - 192.0.3.100\" } ],"
1969 " \"subnet\": \"192.0.3.0/24\""
1970 "} ],"
1971 "\"valid-lifetime\": 4000 }";
1972
1973 ConstElementPtr json;
1974 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_1974
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1974
; } } else gtest_label_testnothrow_1974 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1974, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
1975 extractConfig(config);
1976
1977 ConstElementPtr status;
1978 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_1978; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_1978; } } else gtest_label_testnothrow_1978
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 1978, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
1979 checkResult(status, 0);
1980
1981 CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
1982 ConstSubnet4Ptr subnet1 = cfg->selectSubnet(IOAddress("192.0.2.1"));
1983 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"
, 1983, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1", "false", "true") .c_str()) = ::testing::Message(
)
;
1984 // Reset the fetch global function to staging (vs current) config.
1985 Subnet4Ptr mutable_subnet1 = boost::const_pointer_cast<Subnet4>(subnet1);
1986 mutable_subnet1->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
1987 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
1988 });
1989 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"
, 1989, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1->getAuthoritative()", "false", "true") .c_str()
) = ::testing::Message()
;
1990
1991 ConstSubnet4Ptr subnet2 = cfg->selectSubnet(IOAddress("192.0.3.1"));
1992 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"
, 1992, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2", "false", "true") .c_str()) = ::testing::Message(
)
;
1993 // Reset the fetch global function to staging (vs current) config.
1994 Subnet4Ptr mutable_subnet2 = boost::const_pointer_cast<Subnet4>(subnet2);
1995 mutable_subnet2->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
1996 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
1997 });
1998 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"
, 1998, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2->getAuthoritative()", "true", "false") .c_str()
) = ::testing::Message()
;
1999}
2000
2001// This test checks that the global authoritative parameter is used
2002// when there is no such parameter under subnet and that the parameter
2003// specified for a subnet overrides the global setting.
2004TEST_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"
, 2004), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2004), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2004), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_authoritativeGlobal_Test
>); void Dhcp4ParserTest_authoritativeGlobal_Test::TestBody
()
{
2005 std::string config = "{ " + genIfaceConfig() + ","
2006 "\"rebind-timer\": 2000, "
2007 "\"renew-timer\": 1000, "
2008 "\"authoritative\": true,"
2009 "\"subnet4\": [ "
2010 "{"
2011 " \"id\": 1,"
2012 " \"authoritative\": false,"
2013 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
2014 " \"subnet\": \"192.0.2.0/24\""
2015 "},"
2016 "{"
2017 " \"id\": 2,"
2018 " \"pools\": [ { \"pool\": \"192.0.3.1 - 192.0.3.100\" } ],"
2019 " \"subnet\": \"192.0.3.0/24\""
2020 "} ],"
2021 "\"valid-lifetime\": 4000 }";
2022
2023 ConstElementPtr json;
2024 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_2024
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2024
; } } else gtest_label_testnothrow_2024 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2024, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2025 extractConfig(config);
2026
2027 ConstElementPtr status;
2028 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_2028; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2028; } } else gtest_label_testnothrow_2028
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2028, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2029 checkResult(status, 0);
2030
2031 CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
2032 ConstSubnet4Ptr subnet1 = cfg->selectSubnet(IOAddress("192.0.2.1"));
2033 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"
, 2033, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1", "false", "true") .c_str()) = ::testing::Message(
)
;
2034 // Reset the fetch global function to staging (vs current) config.
2035 Subnet4Ptr mutable_subnet1 = boost::const_pointer_cast<Subnet4>(subnet1);
2036 mutable_subnet1->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
2037 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
2038 });
2039 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"
, 2039, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1->getAuthoritative()", "true", "false") .c_str()
) = ::testing::Message()
;
2040
2041 ConstSubnet4Ptr subnet2 = cfg->selectSubnet(IOAddress("192.0.3.1"));
2042 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"
, 2042, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2", "false", "true") .c_str()) = ::testing::Message(
)
;
2043 // Reset the fetch global function to staging (vs current) config.
2044 Subnet4Ptr mutable_subnet2 = boost::const_pointer_cast<Subnet4>(subnet2);
2045 mutable_subnet2->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
2046 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
2047 });
2048 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"
, 2048, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2->getAuthoritative()", "false", "true") .c_str()
) = ::testing::Message()
;
2049}
2050
2051// This test checks if it is possible to override global values
2052// on a per subnet basis.
2053TEST_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", 2053
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2053), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2053), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_subnetLocal_Test
>); void Dhcp4ParserTest_subnetLocal_Test::TestBody()
{
2054
2055 string config = "{ " + genIfaceConfig() + ","
2056 "\"rebind-timer\": 2000, "
2057 "\"renew-timer\": 1000, "
2058 "\"subnet4\": [ { "
2059 " \"id\": 1,"
2060 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
2061 " \"renew-timer\": 1, "
2062 " \"rebind-timer\": 2, "
2063 " \"valid-lifetime\": 4,"
2064 " \"min-valid-lifetime\": 3,"
2065 " \"max-valid-lifetime\": 5,"
2066 " \"subnet\": \"192.0.2.0/24\" } ],"
2067 "\"valid-lifetime\": 4000,"
2068 "\"min-valid-lifetime\": 3000,"
2069 "\"max-valid-lifetime\": 5000 }";
2070
2071 ConstElementPtr json;
2072 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_2072
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2072
; } } else gtest_label_testnothrow_2072 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2072, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2073 extractConfig(config);
2074
2075 ConstElementPtr status;
2076 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_2076; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2076; } } else gtest_label_testnothrow_2076
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2076, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2077
2078 // returned value should be 0 (configuration success)
2079 checkResult(status, 0);
2080
2081 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
2082 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
2083 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"
, 2083, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
2084 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"
, 2084, gtest_ar.failure_message()) = ::testing::Message()
;
2085 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"
, 2085, gtest_ar.failure_message()) = ::testing::Message()
;
2086 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"
, 2086, gtest_ar.failure_message()) = ::testing::Message()
;
2087 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"
, 2087, gtest_ar.failure_message()) = ::testing::Message()
;
2088 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"
, 2088, gtest_ar.failure_message()) = ::testing::Message()
;
2089}
2090
2091// This test checks if it is possible to define a subnet with an
2092// interface defined.
2093TEST_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", 2093
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2093), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2093), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_subnetInterface_Test
>); void Dhcp4ParserTest_subnetInterface_Test::TestBody()
{
2094
2095 // There should be at least one interface
2096 // As far as I can tell, this is the first lambda in Kea code. Cool.
2097 auto config = [this](string iface) {
2098 return ("{ " + genIfaceConfig() + ","
2099 "\"rebind-timer\": 2000, "
2100 "\"renew-timer\": 1000, "
2101 "\"subnet4\": [ { "
2102 " \"id\": 1,"
2103 " \"pools\": [ { "
2104 " \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
2105 " \"interface\": \"" + iface + "\","
2106 " \"subnet\": \"192.0.2.0/24\" } ],"
2107 "\"valid-lifetime\": 4000 }"); };
2108 cout << config(valid_iface_) << endl;
2109
2110 ConstElementPtr json;
2111 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_2111; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2111; } } else gtest_label_testnothrow_2111
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2111, ("Expected: " "json = parseDHCP4(config(valid_iface_))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2112 extractConfig(config("eth0"));
2113
2114 ConstElementPtr status;
2115 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_2115; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2115; } } else gtest_label_testnothrow_2115
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2115, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2116
2117 // returned value should be 0 (configuration success)
2118 checkResult(status, 0);
2119
2120 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
2121 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"), classify_);
2122 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"
, 2122, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
2123 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"
, 2123, gtest_ar.failure_message()) = ::testing::Message()
;
2124}
2125
2126// This test checks if invalid interface name will be rejected in
2127// Subnet4 definition.
2128TEST_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"
, 2128), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2128), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2128), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_subnetInterfaceBogus_Test
>); void Dhcp4ParserTest_subnetInterfaceBogus_Test::TestBody
()
{
2129
2130 // There should be at least one interface
2131
2132 string config = "{ " + genIfaceConfig() + ","
2133 "\"rebind-timer\": 2000, "
2134 "\"renew-timer\": 1000, "
2135 "\"subnet4\": [ { "
2136 " \"id\": 1,"
2137 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
2138 " \"interface\": \"" + bogus_iface_ + "\","
2139 " \"subnet\": \"192.0.2.0/24\" } ],"
2140 "\"valid-lifetime\": 4000 }";
2141 cout << config << endl;
2142
2143 ConstElementPtr json;
2144 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_2144
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2144
; } } else gtest_label_testnothrow_2144 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2144, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2145
2146 ConstElementPtr status;
2147 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_2147; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2147; } } else gtest_label_testnothrow_2147
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2147, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2148
2149 // returned value should be 1 (configuration error)
2150 checkResult(status, CONTROL_RESULT_ERROR);
2151 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"
, 2151, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2152
2153 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
2154 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"), classify_);
2155 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", 2155
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "true", "false") .c_str()) = ::testing::Message()
;
2156}
2157
2158// This test checks if it is not allowed to define global interface
2159// parameter.
2160TEST_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", 2160
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2160), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2160), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_interfaceGlobal_Test
>); void Dhcp4ParserTest_interfaceGlobal_Test::TestBody()
{
2161
2162 string config = "{ " + genIfaceConfig() + ","
2163 "\"rebind-timer\": 2000, "
2164 "\"renew-timer\": 1000, "
2165 "\"interface\": \"" + valid_iface_ + "\"," // Not valid. Can be defined in subnet only
2166 "\"subnet4\": [ { "
2167 " \"id\": 1,"
2168 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
2169 " \"subnet\": \"192.0.2.0/24\" } ],"
2170 "\"valid-lifetime\": 4000 }";
2171 cout << config << endl;
2172
2173 ConstElementPtr json = parseJSON(config);
2174
2175 ConstElementPtr status;
2176 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_2176; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2176; } } else gtest_label_testnothrow_2176
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2176, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2177
2178 // returned value should be 1 (parse error)
2179 checkResult(status, CONTROL_RESULT_ERROR);
2180 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"
, 2180, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2181
2182 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_2182; } catch (...
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_2182; } 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_2182
; } } else gtest_label_testthrow_2182 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2182, gtest_msg.value.c_str()) = ::testing::Message()
;
2183}
2184
2185// Goal of this test is to verify that invalid subnet fails to be parsed.
2186TEST_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", 2186
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2186), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2186), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_badSubnetValues_Test
>); void Dhcp4ParserTest_badSubnetValues_Test::TestBody()
{
2187
2188 // Contains parts needed for a single test scenario.
2189 struct Scenario {
2190 std::string description_;
2191 std::string config_json_;
2192 std::string exp_error_msg_;
2193 };
2194
2195 // Vector of scenarios.
2196 std::vector<Scenario> scenarios = {
2197 {
2198 "IP is not an address",
2199 "{ \"subnet4\": [ { "
2200 " \"subnet\": \"not an address/24\" } ],"
2201 "\"valid-lifetime\": 4000 }",
2202 "subnet configuration failed: "
2203 "Failed to convert string to address 'notanaddress': Invalid argument"
2204 },
2205 {
2206 "IP is Invalid",
2207 "{ \"subnet4\": [ { "
2208 " \"subnet\": \"256.16.1.0/24\" } ],"
2209 "\"valid-lifetime\": 4000 }",
2210 "subnet configuration failed: "
2211 "Failed to convert string to address '256.16.1.0': Invalid argument"
2212 },
2213 {
2214 "Missing prefix",
2215 "{ \"subnet4\": [ { "
2216 " \"subnet\": \"192.0.2.0\" } ],"
2217 "\"valid-lifetime\": 4000 }",
2218 "subnet configuration failed: "
2219 "Invalid subnet syntax (prefix/len expected):192.0.2.0 (<string>:1:32)"
2220 },
2221 {
2222 "Prefix not an integer (2 slashes)",
2223 "{ \"subnet4\": [ { "
2224 " \"subnet\": \"192.0.2.0//24\" } ],"
2225 "\"valid-lifetime\": 4000 }",
2226 "subnet configuration failed: "
2227 "prefix length: '/24' is not an integer (<string>:1:32)"
2228 },
2229 {
2230 "Prefix value is insane",
2231 "{ \"subnet4\": [ { "
2232 " \"subnet\": \"192.0.2.0/45938\" } ],"
2233 "\"valid-lifetime\": 4000 }",
2234 "subnet configuration failed: "
2235 "Invalid prefix length specified for subnet: 45938 (<string>:1:32)"
2236 }
2237 };
2238
2239 // Iterate over the list of scenarios. Each should fail to parse with
2240 // a specific error message.
2241 for (auto const& scenario : scenarios) {
2242 SCOPED_TRACE(scenario.description_)const ::testing::ScopedTrace gtest_trace_2242( "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2242, (scenario.description_))
;
2243 ConstElementPtr config;
2244 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_2244; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2244; } } else gtest_label_testnothrow_2244
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2244, ("Expected: " "config = parseDHCP4(scenario.config_json_)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
2245 << "invalid json, broken test";
2246 ConstElementPtr status;
2247 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_2247; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2247; } } else gtest_label_testnothrow_2247
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2247, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, config)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2248 checkResult(status, CONTROL_RESULT_ERROR);
2249 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"
, 2249, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "comment_", "false", "true") .c_str()) = ::testing::Message
()
;
2250 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"
, 2250, gtest_ar.failure_message()) = ::testing::Message()
;
2251 }
2252}
2253
2254// This test checks that multiple pools can be defined and handled properly.
2255// The test defines 2 subnets, each with 2 pools.
2256TEST_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", 2256
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2256), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2256), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_multiplePools_Test
>); void Dhcp4ParserTest_multiplePools_Test::TestBody()
{
2257 // Collection with two subnets, each with 2 pools.
2258 string config = "{ " + genIfaceConfig() + ","
2259 "\"rebind-timer\": 2000, "
2260 "\"renew-timer\": 1000, "
2261 "\"subnet4\": [ { "
2262 " \"id\": 1,"
2263 " \"pools\": [ "
2264 " { \"pool\": \"192.0.2.0/28\" },"
2265 " { \"pool\": \"192.0.2.200-192.0.2.255\" }"
2266 " ],"
2267 " \"subnet\": \"192.0.2.0/24\" "
2268 " },"
2269 " {"
2270 " \"id\": 2,"
2271 " \"pools\": [ "
2272 " { \"pool\": \"192.0.3.0/25\" },"
2273 " { \"pool\": \"192.0.3.128/25\" }"
2274 " ],"
2275 " \"subnet\": \"192.0.3.0/24\""
2276 " } ],"
2277 "\"valid-lifetime\": 4000 }";
2278 ConstElementPtr json;
2279 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_2279
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2279
; } } else gtest_label_testnothrow_2279 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2279, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2280 extractConfig(config);
2281
2282 ConstElementPtr status;
2283 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_2283; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2283; } } else gtest_label_testnothrow_2283
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2283, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2284 checkResult(status, 0);
2285
2286 const Subnet4Collection* subnets =
2287 CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
2288 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"
, 2288, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
2289 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"
, 2289, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 2 subnets
2290
2291 // Check the first subnet
2292 auto subnet = subnets->begin();
2293 const PoolCollection& pools1 = (*subnet)->getPools(Lease::TYPE_V4);
2294 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"
, 2294, gtest_ar.failure_message()) = ::testing::Message()
;
2295 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"
, 2296, gtest_ar.failure_message()) = ::testing::Message()
2296 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"
, 2296, gtest_ar.failure_message()) = ::testing::Message()
;
2297 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"
, 2298, gtest_ar.failure_message()) = ::testing::Message()
2298 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"
, 2298, gtest_ar.failure_message()) = ::testing::Message()
;
2299 // There shouldn't be any PD pools
2300 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_2300
; } 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_2300; } 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_2300; } } else gtest_label_testthrow_2300
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2300, gtest_msg.value.c_str()) = ::testing::Message()
;
2301
2302 // Check the second subnet
2303 ++subnet;
2304 const PoolCollection& pools2 = (*subnet)->getPools(Lease::TYPE_V4);
2305 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"
, 2305, gtest_ar.failure_message()) = ::testing::Message()
;
2306 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"
, 2307, gtest_ar.failure_message()) = ::testing::Message()
2307 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"
, 2307, gtest_ar.failure_message()) = ::testing::Message()
;
2308 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"
, 2309, gtest_ar.failure_message()) = ::testing::Message()
2309 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"
, 2309, gtest_ar.failure_message()) = ::testing::Message()
;
2310 // There shouldn't be any PD pools
2311 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_2311
; } 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_2311; } 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_2311; } } else gtest_label_testthrow_2311
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2311, gtest_msg.value.c_str()) = ::testing::Message()
;
2312}
2313
2314// Test verifies that a subnet with pool values that do not belong to that
2315// pool are rejected.
2316TEST_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", 2316
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2316), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2316), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_poolOutOfSubnet_Test
>); void Dhcp4ParserTest_poolOutOfSubnet_Test::TestBody()
{
2317
2318 string config = "{ " + genIfaceConfig() + ","
2319 "\"rebind-timer\": 2000, "
2320 "\"renew-timer\": 1000, "
2321 "\"subnet4\": [ { "
2322 " \"id\": 1,"
2323 " \"pools\": [ { \"pool\": \"192.0.4.0/28\" } ],"
2324 " \"subnet\": \"192.0.2.0/24\" } ],"
2325 "\"valid-lifetime\": 4000 }";
2326
2327 ConstElementPtr json;
2328 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_2328
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2328
; } } else gtest_label_testnothrow_2328 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2328, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2329
2330 ConstElementPtr status;
2331 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_2331; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2331; } } else gtest_label_testnothrow_2331
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2331, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2332
2333 // returned value must be 1 (values error)
2334 // as the pool does not belong to that subnet
2335 checkResult(status, CONTROL_RESULT_ERROR);
2336 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"
, 2336, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2337}
2338
2339// Goal of this test is to verify if pools can be defined
2340// using prefix/length notation. There is no separate test for min-max
2341// notation as it was tested in several previous tests.
2342TEST_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", 2342
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2342), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2342), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_poolPrefixLen_Test
>); void Dhcp4ParserTest_poolPrefixLen_Test::TestBody()
{
2343 string config = "{ " + genIfaceConfig() + ","
2344 "\"rebind-timer\": 2000, "
2345 "\"renew-timer\": 1000, "
2346 "\"subnet4\": [ { "
2347 " \"id\": 1,"
2348 " \"pools\": [ { \"pool\": \"192.0.2.128/28\" } ],"
2349 " \"subnet\": \"192.0.2.0/24\" } ],"
2350 "\"valid-lifetime\": 4000 }";
2351
2352 ConstElementPtr json;
2353 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_2353
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2353
; } } else gtest_label_testnothrow_2353 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2353, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2354 extractConfig(config);
2355
2356 ConstElementPtr status;
2357 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_2357; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2357; } } else gtest_label_testnothrow_2357
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2357, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2358
2359 // returned value must be 0 (configuration accepted)
2360 checkResult(status, 0);
2361
2362 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
2363 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
2364 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"
, 2364, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
2365 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"
, 2365, gtest_ar.failure_message()) = ::testing::Message()
;
2366 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"
, 2366, gtest_ar.failure_message()) = ::testing::Message()
;
2367 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"
, 2367, gtest_ar.failure_message()) = ::testing::Message()
;
2368}
2369
2370// Goal of this test is to verify if invalid pool definitions
2371// return a location in the error message.
2372TEST_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", 2372
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2372), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2372), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_badPools_Test
>); void Dhcp4ParserTest_badPools_Test::TestBody()
{
2373
2374 // not a prefix
2375 string config_bogus1 = "{ " + genIfaceConfig() + ","
2376 "\"rebind-timer\": 2000, "
2377 "\"renew-timer\": 1000, "
2378 "\"subnet4\": [ { "
2379 " \"id\": 1,"
2380 " \"pools\": [ { \"pool\": \"foo/28\" } ],"
2381 " \"subnet\": \"192.0.2.0/24\" } ],"
2382 "\"valid-lifetime\": 4000 }";
2383
2384 // not a length
2385 string config_bogus2 = "{ " + genIfaceConfig() + ","
2386 "\"rebind-timer\": 2000, "
2387 "\"renew-timer\": 1000, "
2388 "\"subnet4\": [ { "
2389 " \"id\": 1,"
2390 " \"pools\": [ { \"pool\": \"192.0.2.128/foo\" } ],"
2391 " \"subnet\": \"192.0.2.0/24\" } ],"
2392 "\"valid-lifetime\": 4000 }";
2393
2394 // invalid prefix length
2395 string config_bogus3 = "{ " + genIfaceConfig() + ","
2396 "\"rebind-timer\": 2000, "
2397 "\"renew-timer\": 1000, "
2398 "\"subnet4\": [ { "
2399 " \"id\": 1,"
2400 " \"pools\": [ { \"pool\": \"192.0.2.128/100\" } ],"
2401 " \"subnet\": \"192.0.2.0/24\" } ],"
2402 "\"valid-lifetime\": 4000 }";
2403
2404 // not a prefix nor a min-max
2405 string config_bogus4 = "{ " + genIfaceConfig() + ","
2406 "\"rebind-timer\": 2000, "
2407 "\"renew-timer\": 1000, "
2408 "\"subnet4\": [ { "
2409 " \"id\": 1,"
2410 " \"pools\": [ { \"pool\": \"foo\" } ],"
2411 " \"subnet\": \"192.0.2.0/24\" } ],"
2412 "\"valid-lifetime\": 4000 }";
2413
2414 // not an address
2415 string config_bogus5 = "{ " + genIfaceConfig() + ","
2416 "\"rebind-timer\": 2000, "
2417 "\"renew-timer\": 1000, "
2418 "\"subnet4\": [ { "
2419 " \"id\": 1,"
2420 " \"pools\": [ { \"pool\": \"foo - bar\" } ],"
2421 " \"subnet\": \"192.0.2.0/24\" } ],"
2422 "\"valid-lifetime\": 4000 }";
2423
2424 // min > max
2425 string config_bogus6 = "{ " + genIfaceConfig() + ","
2426 "\"rebind-timer\": 2000, "
2427 "\"renew-timer\": 1000, "
2428 "\"subnet4\": [ { "
2429 " \"id\": 1,"
2430 " \"pools\": [ { \"pool\": \"192.0.2.200 - 192.0.2.100\" } ],"
2431 " \"subnet\": \"192.0.2.0/24\" } ],"
2432 "\"valid-lifetime\": 4000 }";
2433
2434 // out of range prefix length (new check)
2435 string config_bogus7 = "{ " + genIfaceConfig() + ","
2436 "\"rebind-timer\": 2000, "
2437 "\"renew-timer\": 1000, "
2438 "\"subnet4\": [ { "
2439 " \"id\": 1,"
2440 " \"pools\": [ { \"pool\": \"192.0.2.128/1052\" } ],"
2441 " \"subnet\": \"192.0.2.0/24\" } ],"
2442 "\"valid-lifetime\": 4000 }";
2443
2444 ConstElementPtr json1;
2445 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_2445
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2445
; } } else gtest_label_testnothrow_2445 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2445, ("Expected: " "json1 = parseDHCP4(config_bogus1)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2446 ConstElementPtr json2;
2447 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_2447
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2447
; } } else gtest_label_testnothrow_2447 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2447, ("Expected: " "json2 = parseDHCP4(config_bogus2)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2448 ConstElementPtr json3;
2449 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_2449
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2449
; } } else gtest_label_testnothrow_2449 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2449, ("Expected: " "json3 = parseDHCP4(config_bogus3)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2450 ConstElementPtr json4;
2451 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_2451
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2451
; } } else gtest_label_testnothrow_2451 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2451, ("Expected: " "json4 = parseDHCP4(config_bogus4)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2452 ConstElementPtr json5;
2453 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_2453
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2453
; } } else gtest_label_testnothrow_2453 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2453, ("Expected: " "json5 = parseDHCP4(config_bogus5)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2454 ConstElementPtr json6;
2455 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_2455
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2455
; } } else gtest_label_testnothrow_2455 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2455, ("Expected: " "json6 = parseDHCP4(config_bogus6)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2456 ConstElementPtr json7;
2457 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_2457
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2457
; } } else gtest_label_testnothrow_2457 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2457, ("Expected: " "json7 = parseDHCP4(config_bogus7)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2458
2459 ConstElementPtr status;
2460 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_2460; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2460; } } else gtest_label_testnothrow_2460
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2460, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json1)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2461
2462 // check if returned status is always a failure
2463 checkResult(status, CONTROL_RESULT_ERROR);
2464 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"
, 2464, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2465
2466 CfgMgr::instance().clear();
2467
2468 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_2468; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2468; } } else gtest_label_testnothrow_2468
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2468, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json2)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2469 checkResult(status, CONTROL_RESULT_ERROR);
2470 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"
, 2470, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2471
2472 CfgMgr::instance().clear();
2473
2474 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_2474; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2474; } } else gtest_label_testnothrow_2474
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2474, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json3)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2475 checkResult(status, CONTROL_RESULT_ERROR);
2476 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"
, 2476, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2477
2478 CfgMgr::instance().clear();
2479
2480 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_2480; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2480; } } else gtest_label_testnothrow_2480
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2480, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json4)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2481 checkResult(status, CONTROL_RESULT_ERROR);
2482 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"
, 2482, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2483
2484 CfgMgr::instance().clear();
2485
2486 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_2486; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2486; } } else gtest_label_testnothrow_2486
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2486, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json5)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2487 checkResult(status, CONTROL_RESULT_ERROR);
2488 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"
, 2488, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2489
2490 CfgMgr::instance().clear();
2491
2492 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_2492; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2492; } } else gtest_label_testnothrow_2492
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2492, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json6)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2493 checkResult(status, CONTROL_RESULT_ERROR);
2494 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"
, 2494, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2495
2496 CfgMgr::instance().clear();
2497
2498 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_2498; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2498; } } else gtest_label_testnothrow_2498
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2498, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json7)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2499 checkResult(status, CONTROL_RESULT_ERROR);
2500 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"
, 2500, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2501}
2502
2503// Goal of this test is to verify no pool definitions is invalid
2504// and returns a location in the error message.
2505TEST_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", 2505
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2505), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2505), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_noPools_Test
>); void Dhcp4ParserTest_noPools_Test::TestBody()
{
2506
2507 // Configuration string.
2508 string config = "{ " + genIfaceConfig() + ","
2509 "\"rebind-timer\": 2000, "
2510 "\"renew-timer\": 1000, "
2511 "\"subnet4\": [ { "
2512 " \"id\": 1,"
2513 " \"pools\": [ { \"user-context\": { } } ],"
2514 " \"subnet\": \"192.0.2.0/24\" } ],"
2515 "\"valid-lifetime\": 4000 }";
2516
2517 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_2517; } 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_2517; } 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_2517; } } else gtest_label_testthrow_2517
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2517, gtest_msg.value.c_str()) = ::testing::Message()
;
2518}
2519
2520
2521// Goal of this test is to verify that unknown interface fails
2522// to be parsed.
2523TEST_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"
, 2523), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2523), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2523), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_unknownInterface_Test
>); void Dhcp4ParserTest_unknownInterface_Test::TestBody()
{
2524
2525 // Configuration string.
2526 string config = "{ " + genIfaceConfig() + ","
2527 "\"rebind-timer\": 2000, "
2528 "\"renew-timer\": 1000, "
2529 "\"subnet4\": [ { "
2530 " \"id\": 1,"
2531 " \"pools\": [ ],"
2532 " \"subnet\": \"192.0.2.0/24\","
2533 " \"interface\": \"ethX\" } ],"
2534 "\"valid-lifetime\": 4000 }";
2535
2536 ConstElementPtr json;
2537 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_2537
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2537
; } } else gtest_label_testnothrow_2537 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2537, ("Expected: " "json = parseDHCP4(config, true)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2538 ConstElementPtr status;
2539 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_2539; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2539; } } else gtest_label_testnothrow_2539
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2539, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2540 checkResult(status, CONTROL_RESULT_ERROR);
2541 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"
, 2541, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2542}
2543
2544// The goal of this test is to check whether an option definition
2545// that defines an option carrying an IPv4 address can be created.
2546TEST_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"
, 2546), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2546), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2546), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefIpv4Address_Test
>); void Dhcp4ParserTest_optionDefIpv4Address_Test::TestBody
()
{
2547
2548 // Configuration string.
2549 std::string config =
2550 "{ \"option-def\": [ {"
2551 " \"name\": \"foo\","
2552 " \"code\": 100,"
2553 " \"type\": \"ipv4-address\","
2554 " \"space\": \"isc\""
2555 " } ]"
2556 "}";
2557 ConstElementPtr json;
2558 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_2558; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2558; } } else gtest_label_testnothrow_2558
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2558, ("Expected: " "json = parseOPTION_DEFS(config, true)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2559 extractConfig(config);
2560
2561 // Make sure that the particular option definition does not exist.
2562 OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
2563 getCfgOptionDef()->get("isc", 100);
2564 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"
, 2564, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "true", "false") .c_str()) = ::testing::Message()
;
2565
2566 // Use the configuration string to create new option definition.
2567 ConstElementPtr status;
2568 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_2568; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2568; } } else gtest_label_testnothrow_2568
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2568, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2569 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"
, 2569, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2570 checkResult(status, 0);
2571
2572 // We need to commit option definitions because later in this test we
2573 // will be checking if they get removed when "option-def" parameter
2574 // is removed from a configuration.
2575 LibDHCP::commitRuntimeOptionDefs();
2576
2577 // The option definition should now be available in the CfgMgr.
2578 def = CfgMgr::instance().getStagingCfg()->getCfgOptionDef()->get("isc", 100);
2579 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", 2579
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "false", "true") .c_str()) = ::testing::Message()
;
2580
2581 // Verify that the option definition data is valid.
2582 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", 2582
, gtest_ar.failure_message()) = ::testing::Message()
;
2583 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"
, 2583, gtest_ar.failure_message()) = ::testing::Message()
;
2584 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"
, 2584, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getArrayType()", "true", "false") .c_str()) = ::testing
::Message()
;
2585 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"
, 2585, gtest_ar.failure_message()) = ::testing::Message()
;
2586 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"
, 2586, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getEncapsulatedSpace().empty()", "false", "true") .
c_str()) = ::testing::Message()
;
2587
2588 // The copy of the option definition should be available in the libdhcp++.
2589 OptionDefinitionPtr def_libdhcp = LibDHCP::getRuntimeOptionDef("isc", 100);
2590 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"
, 2590, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def_libdhcp", "false", "true") .c_str()) = ::testing::Message
()
;
2591
2592 // Both definitions should be held in distinct pointers but they should
2593 // be equal.
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 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"
, 2595, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "*def_libdhcp == *def", "false", "true") .c_str()) = ::testing
::Message()
;
2596
2597 // Let's apply empty configuration. This removes the option definitions
2598 // configuration and should result in removal of the option 100 from the
2599 // libdhcp++. Note DHCP4 or OPTION_DEFS parsers do not accept empty maps.
2600 json.reset(new MapElement());
2601 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_2601; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2601; } } else gtest_label_testnothrow_2601
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2601, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2602 checkResult(status, 0);
2603
2604 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"
, 2604, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "LibDHCP::getRuntimeOptionDef(\"isc\", 100)", "true", "false"
) .c_str()) = ::testing::Message()
;
2605}
2606
2607// The goal of this test is to check whether an option definition
2608// that defines an option carrying a record of data fields can
2609// be created.
2610TEST_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", 2610
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2610), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2610), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefRecord_Test
>); void Dhcp4ParserTest_optionDefRecord_Test::TestBody()
{
2611
2612 // Configuration string.
2613 std::string config =
2614 "{ \"option-def\": [ {"
2615 " \"name\": \"foo\","
2616 " \"code\": 100,"
2617 " \"type\": \"record\","
2618 " \"record-types\": \"uint16, ipv4-address, ipv6-address, string\","
2619 " \"space\": \"isc\""
2620 " } ]"
2621 "}";
2622 ConstElementPtr json;
2623 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_2623
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2623
; } } else gtest_label_testnothrow_2623 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2623, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2624 extractConfig(config);
2625
2626 // Make sure that the particular option definition does not exist.
2627 OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
2628 getCfgOptionDef()->get("isc", 100);
2629 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"
, 2629, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "true", "false") .c_str()) = ::testing::Message()
;
2630
2631 // Use the configuration string to create new option definition.
2632 ConstElementPtr status;
2633 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_2633; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2633; } } else gtest_label_testnothrow_2633
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2633, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2634 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"
, 2634, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2635 checkResult(status, 0);
2636
2637 // The option definition should now be available in the CfgMgr.
2638 def = CfgMgr::instance().getStagingCfg()->getCfgOptionDef()->get("isc", 100);
2639 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", 2639
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "false", "true") .c_str()) = ::testing::Message()
;
2640
2641 // Check the option data.
2642 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", 2642
, gtest_ar.failure_message()) = ::testing::Message()
;
2643 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"
, 2643, gtest_ar.failure_message()) = ::testing::Message()
;
2644 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"
, 2644, gtest_ar.failure_message()) = ::testing::Message()
;
2645 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"
, 2645, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getArrayType()", "true", "false") .c_str()) = ::testing
::Message()
;
2646 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"
, 2646, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getEncapsulatedSpace().empty()", "false", "true") .
c_str()) = ::testing::Message()
;
2647
2648 // The option comprises the record of data fields. Verify that all
2649 // fields are present and they are of the expected types.
2650 const OptionDefinition::RecordFieldsCollection& record_fields =
2651 def->getRecordFields();
2652 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"
, 2652, gtest_ar.failure_message()) = ::testing::Message()
;
2653 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"
, 2653, gtest_ar.failure_message()) = ::testing::Message()
;
2654 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"
, 2654, gtest_ar.failure_message()) = ::testing::Message()
;
2655 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"
, 2655, gtest_ar.failure_message()) = ::testing::Message()
;
2656 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"
, 2656, gtest_ar.failure_message()) = ::testing::Message()
;
2657}
2658
2659// The goal of this test is to verify that multiple option definitions
2660// can be created.
2661TEST_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"
, 2661), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2661), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2661), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefMultiple_Test
>); void Dhcp4ParserTest_optionDefMultiple_Test::TestBody(
)
{
2662 // Configuration string.
2663 std::string config =
2664 "{ \"option-def\": [ {"
2665 " \"name\": \"foo\","
2666 " \"code\": 100,"
2667 " \"type\": \"uint32\","
2668 " \"space\": \"isc\""
2669 " },"
2670 " {"
2671 " \"name\": \"foo-2\","
2672 " \"code\": 101,"
2673 " \"type\": \"ipv4-address\","
2674 " \"space\": \"isc\""
2675 " } ]"
2676 "}";
2677 ConstElementPtr json;
2678 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_2678
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2678
; } } else gtest_label_testnothrow_2678 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2678, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2679 extractConfig(config);
2680
2681 // Make sure that the option definitions do not exist yet.
2682 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"
, 2683, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()-> getCfgOptionDef()->get(\"isc\", 100)"
, "true", "false") .c_str()) = ::testing::Message()
2683 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"
, 2683, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()-> getCfgOptionDef()->get(\"isc\", 100)"
, "true", "false") .c_str()) = ::testing::Message()
;
2684 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"
, 2685, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()-> getCfgOptionDef()->get(\"isc\", 101)"
, "true", "false") .c_str()) = ::testing::Message()
2685 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"
, 2685, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()-> getCfgOptionDef()->get(\"isc\", 101)"
, "true", "false") .c_str()) = ::testing::Message()
;
2686
2687 // Use the configuration string to create new option definitions.
2688 ConstElementPtr status;
2689 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_2689; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2689; } } else gtest_label_testnothrow_2689
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2689, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2690 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"
, 2690, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2691 checkResult(status, 0);
2692
2693 // Check the first definition we have created.
2694 OptionDefinitionPtr def1 = CfgMgr::instance().getStagingCfg()->
2695 getCfgOptionDef()->get("isc", 100);
2696 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", 2696
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def1", "false", "true") .c_str()) = ::testing::Message()
;
2697
2698 // Check the option data.
2699 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", 2699
, gtest_ar.failure_message()) = ::testing::Message()
;
2700 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"
, 2700, gtest_ar.failure_message()) = ::testing::Message()
;
2701 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"
, 2701, gtest_ar.failure_message()) = ::testing::Message()
;
2702 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"
, 2702, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def1->getArrayType()", "true", "false") .c_str()) = ::testing
::Message()
;
2703 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"
, 2703, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def1->getEncapsulatedSpace().empty()", "false", "true")
.c_str()) = ::testing::Message()
;
2704
2705 // Check the second option definition we have created.
2706 OptionDefinitionPtr def2 = CfgMgr::instance().getStagingCfg()->
2707 getCfgOptionDef()->get("isc", 101);
2708 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", 2708
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def2", "false", "true") .c_str()) = ::testing::Message()
;
2709
2710 // Check the option data.
2711 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"
, 2711, gtest_ar.failure_message()) = ::testing::Message()
;
2712 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"
, 2712, gtest_ar.failure_message()) = ::testing::Message()
;
2713 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"
, 2713, gtest_ar.failure_message()) = ::testing::Message()
;
2714 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"
, 2714, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def2->getArrayType()", "true", "false") .c_str()) = ::testing
::Message()
;
2715 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"
, 2715, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def2->getEncapsulatedSpace().empty()", "false", "true")
.c_str()) = ::testing::Message()
;
2716}
2717
2718// The goal of this test is to verify that the duplicated option
2719// definition is not accepted.
2720TEST_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"
, 2720), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2720), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2720), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefDuplicate_Test
>); void Dhcp4ParserTest_optionDefDuplicate_Test::TestBody
()
{
2721 // Preconfigure libdhcp++ with option definitions. The new configuration
2722 // should override it, but when the new configuration fails, it should
2723 // revert to this original configuration.
2724 OptionDefSpaceContainer defs;
2725 OptionDefinitionPtr def(new OptionDefinition("bar", 233, "isc", "string"));
2726 defs.addItem(def);
2727 LibDHCP::setRuntimeOptionDefs(defs);
2728 LibDHCP::commitRuntimeOptionDefs();
2729
2730 // Configuration string. Both option definitions have
2731 // the same code and belong to the same option space.
2732 // This configuration should not be accepted.
2733 std::string config =
2734 "{ \"option-def\": [ {"
2735 " \"name\": \"foo\","
2736 " \"code\": 100,"
2737 " \"type\": \"uint32\","
2738 " \"space\": \"isc\""
2739 " },"
2740 " {"
2741 " \"name\": \"foo-2\","
2742 " \"code\": 100,"
2743 " \"type\": \"ipv4-address\","
2744 " \"space\": \"isc\""
2745 " } ]"
2746 "}";
2747 ConstElementPtr json;
2748 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_2748
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2748
; } } else gtest_label_testnothrow_2748 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2748, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2749
2750 // Make sure that the option definition does not exist yet.
2751 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"
, 2752, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()-> getCfgOptionDef()->get(\"isc\", 100)"
, "true", "false") .c_str()) = ::testing::Message()
2752 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"
, 2752, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()-> getCfgOptionDef()->get(\"isc\", 100)"
, "true", "false") .c_str()) = ::testing::Message()
;
2753
2754 // Use the configuration string to create new option definitions.
2755 ConstElementPtr status;
2756 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_2756; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2756; } } else gtest_label_testnothrow_2756
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2756, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2757 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"
, 2757, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2758 checkResult(status, CONTROL_RESULT_ERROR);
2759 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"
, 2759, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2760
2761 // Specific check for incorrect report using default config pair
2762 // as option-def is parsed first.
2763 string expected = "failed to create or run parser for configuration ";
2764 expected += "element option-def: option definition with code '100' ";
2765 expected += "already exists in option space 'isc'";
2766 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"
, 2766, gtest_ar.failure_message()) = ::testing::Message()
;
2767
2768 // The new configuration should have inserted option 100, but
2769 // once configuration failed (on the duplicate option definition)
2770 // the original configuration in libdhcp++ should be reverted.
2771 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"
, 2771, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "LibDHCP::getRuntimeOptionDef(\"isc\", 100)", "true", "false"
) .c_str()) = ::testing::Message()
;
2772 def = LibDHCP::getRuntimeOptionDef("isc", 233);
2773 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", 2773
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "false", "true") .c_str()) = ::testing::Message()
;
2774 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", 2774
, gtest_ar.failure_message()) = ::testing::Message()
;
2775 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"
, 2775, gtest_ar.failure_message()) = ::testing::Message()
;
2776}
2777
2778// The goal of this test is to verify that the option definition
2779// comprising an array of uint32 values can be created.
2780TEST_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", 2780
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2780), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2780), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefArray_Test
>); void Dhcp4ParserTest_optionDefArray_Test::TestBody()
{
2781
2782 // Configuration string. Created option definition should
2783 // comprise an array of uint32 values.
2784 std::string config =
2785 "{ \"option-def\": [ {"
2786 " \"name\": \"foo\","
2787 " \"code\": 100,"
2788 " \"type\": \"uint32\","
2789 " \"array\": true,"
2790 " \"space\": \"isc\""
2791 " } ]"
2792 "}";
2793 ConstElementPtr json;
2794 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_2794
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2794
; } } else gtest_label_testnothrow_2794 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2794, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2795 extractConfig(config);
2796
2797 // Make sure that the particular option definition does not exist.
2798 OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
2799 getCfgOptionDef()->get("isc", 100);
2800 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"
, 2800, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "true", "false") .c_str()) = ::testing::Message()
;
2801
2802 // Use the configuration string to create new option definition.
2803 ConstElementPtr status;
2804 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_2804; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2804; } } else gtest_label_testnothrow_2804
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2804, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2805 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"
, 2805, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2806 checkResult(status, 0);
2807
2808 // The option definition should now be available in the CfgMgr.
2809 def = CfgMgr::instance().getStagingCfg()->
2810 getCfgOptionDef()->get("isc", 100);
2811 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", 2811
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "false", "true") .c_str()) = ::testing::Message()
;
2812
2813 // Check the option data.
2814 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", 2814
, gtest_ar.failure_message()) = ::testing::Message()
;
2815 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"
, 2815, gtest_ar.failure_message()) = ::testing::Message()
;
2816 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"
, 2816, gtest_ar.failure_message()) = ::testing::Message()
;
2817 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"
, 2817, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getArrayType()", "false", "true") .c_str()) = ::testing
::Message()
;
2818 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"
, 2818, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getEncapsulatedSpace().empty()", "false", "true") .
c_str()) = ::testing::Message()
;
2819}
2820
2821// The purpose of this test to verify that encapsulated option
2822// space name may be specified.
2823TEST_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"
, 2823), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2823), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2823), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefEncapsulate_Test
>); void Dhcp4ParserTest_optionDefEncapsulate_Test::TestBody
()
{
2824
2825 // Configuration string. Included the encapsulated
2826 // option space name.
2827 std::string config =
2828 "{ \"option-def\": [ {"
2829 " \"name\": \"foo\","
2830 " \"code\": 100,"
2831 " \"type\": \"uint32\","
2832 " \"space\": \"isc\","
2833 " \"encapsulate\": \"sub-opts-space\""
2834 " } ]"
2835 "}";
2836 ConstElementPtr json;
2837 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_2837
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2837
; } } else gtest_label_testnothrow_2837 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2837, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2838 extractConfig(config);
2839
2840 // Make sure that the particular option definition does not exist.
2841 OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
2842 getCfgOptionDef()->get("isc", 100);
2843 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"
, 2843, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "true", "false") .c_str()) = ::testing::Message()
;
2844
2845 // Use the configuration string to create new option definition.
2846 ConstElementPtr status;
2847 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_2847; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2847; } } else gtest_label_testnothrow_2847
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2847, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2848 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"
, 2848, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2849 checkResult(status, 0);
2850
2851 // The option definition should now be available in the CfgMgr.
2852 def = CfgMgr::instance().getStagingCfg()->
2853 getCfgOptionDef()->get("isc", 100);
2854 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", 2854
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "false", "true") .c_str()) = ::testing::Message()
;
2855
2856 // Check the option data.
2857 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", 2857
, gtest_ar.failure_message()) = ::testing::Message()
;
2858 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"
, 2858, gtest_ar.failure_message()) = ::testing::Message()
;
2859 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"
, 2859, gtest_ar.failure_message()) = ::testing::Message()
;
2860 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"
, 2860, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getArrayType()", "true", "false") .c_str()) = ::testing
::Message()
;
2861 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"
, 2861, gtest_ar.failure_message()) = ::testing::Message()
;
2862}
2863
2864/// The purpose of this test is to verify that the option definition
2865/// with invalid name is not accepted.
2866TEST_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"
, 2866), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2866), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2866), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefInvalidName_Test
>); void Dhcp4ParserTest_optionDefInvalidName_Test::TestBody
()
{
2867 // Configuration string. The option name is invalid as it
2868 // contains the % character.
2869 std::string config =
2870 "{ \"option-def\": [ {"
2871 " \"name\": \"invalid%name\","
2872 " \"code\": 100,"
2873 " \"type\": \"string\","
2874 " \"space\": \"isc\""
2875 " } ]"
2876 "}";
2877 ConstElementPtr json;
2878 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_2878
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2878
; } } else gtest_label_testnothrow_2878 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2878, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2879
2880 // Use the configuration string to create new option definition.
2881 ConstElementPtr status;
2882 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_2882; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2882; } } else gtest_label_testnothrow_2882
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2882, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2883 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"
, 2883, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2884 // Expecting parsing error (error code 1).
2885 checkResult(status, CONTROL_RESULT_ERROR);
2886 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"
, 2886, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2887}
2888
2889/// The purpose of this test is to verify that the option definition
2890/// with invalid type is not accepted.
2891TEST_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"
, 2891), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2891), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2891), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefInvalidType_Test
>); void Dhcp4ParserTest_optionDefInvalidType_Test::TestBody
()
{
2892 // Configuration string. The option type is invalid. It is
2893 // "sting" instead of "string".
2894 std::string config =
2895 "{ \"option-def\": [ {"
2896 " \"name\": \"foo\","
2897 " \"code\": 100,"
2898 " \"type\": \"sting\","
2899 " \"space\": \"isc\""
2900 " } ]"
2901 "}";
2902 ConstElementPtr json;
2903 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_2903
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2903
; } } else gtest_label_testnothrow_2903 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2903, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2904
2905 // Use the configuration string to create new option definition.
2906 ConstElementPtr status;
2907 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_2907; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2907; } } else gtest_label_testnothrow_2907
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2907, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2908 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"
, 2908, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2909 // Expecting parsing error (error code 1).
2910 checkResult(status, CONTROL_RESULT_ERROR);
2911 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"
, 2911, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2912}
2913
2914/// The purpose of this test is to verify that the option definition
2915/// with invalid type is not accepted.
2916TEST_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"
, 2916), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2916), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2916), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefInvalidRecordType_Test
>); void Dhcp4ParserTest_optionDefInvalidRecordType_Test::
TestBody()
{
2917 // Configuration string. The third of the record fields
2918 // is invalid. It is "sting" instead of "string".
2919 std::string config =
2920 "{ \"option-def\": [ {"
2921 " \"name\": \"foo\","
2922 " \"code\": 100,"
2923 " \"type\": \"record\","
2924 " \"record-types\": \"uint32,uint8,sting\","
2925 " \"space\": \"isc\""
2926 " } ]"
2927 "}";
2928 ConstElementPtr json;
2929 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_2929
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2929
; } } else gtest_label_testnothrow_2929 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2929, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2930
2931 // Use the configuration string to create new option definition.
2932 ConstElementPtr status;
2933 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_2933; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2933; } } else gtest_label_testnothrow_2933
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2933, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2934 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"
, 2934, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2935 // Expecting parsing error (error code 1).
2936 checkResult(status, CONTROL_RESULT_ERROR);
2937 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"
, 2937, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2938}
2939
2940/// The purpose of this test is to verify that various integer types
2941/// are supported.
2942TEST_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"
, 2942), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2942), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2942), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionIntegerTypes_Test
>); void Dhcp4ParserTest_optionIntegerTypes_Test::TestBody
()
{
2943 // Configuration string. The third of the record fields
2944 // is invalid. It is "sting" instead of "string".
2945 std::string config =
2946 "{ \"option-def\": [ {"
2947 " \"name\": \"foo\","
2948 " \"code\": 100,"
2949 " \"type\": \"record\","
2950 " \"record-types\": \"uint8,uint16,uint32,int8,int16,int32\","
2951 " \"space\": \"isc\""
2952 " } ]"
2953 "}";
2954 ConstElementPtr json;
2955 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_2955
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2955
; } } else gtest_label_testnothrow_2955 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2955, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2956
2957 // Use the configuration string to create new option definition.
2958 ConstElementPtr status;
2959 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_2959; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2959; } } else gtest_label_testnothrow_2959
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2959, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2960 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"
, 2960, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2961 // Expecting parsing error (error code 1).
2962 checkResult(status, 0);
2963}
2964
2965/// The goal of this test is to verify that the invalid encapsulated
2966/// option space name is not accepted.
2967TEST_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"
, 2967), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2967), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2967), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefInvalidEncapsulatedSpace_Test
>); void Dhcp4ParserTest_optionDefInvalidEncapsulatedSpace_Test
::TestBody()
{
2968 // Configuration string. The encapsulated option space
2969 // name is invalid (% character is not allowed).
2970 std::string config =
2971 "{ \"option-def\": [ {"
2972 " \"name\": \"foo\","
2973 " \"code\": 100,"
2974 " \"type\": \"uint32\","
2975 " \"space\": \"isc\","
2976 " \"encapsulate\": \"invalid%space%name\""
2977 " } ]"
2978 "}";
2979 ConstElementPtr json;
2980 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_2980
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_2980
; } } else gtest_label_testnothrow_2980 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2980, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
2981
2982 // Use the configuration string to create new option definition.
2983 ConstElementPtr status;
2984 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_2984; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_2984; } } else gtest_label_testnothrow_2984
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2984, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
2985 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"
, 2985, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
2986 // Expecting parsing error (error code 1).
2987 checkResult(status, CONTROL_RESULT_ERROR);
2988 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"
, 2988, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
2989}
2990
2991/// The goal of this test is to verify that the encapsulated
2992/// option space name can't be specified for the option that
2993/// comprises an array of data fields.
2994TEST_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"
, 2994), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2994), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 2994), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefEncapsulatedSpaceAndArray_Test
>); void Dhcp4ParserTest_optionDefEncapsulatedSpaceAndArray_Test
::TestBody()
{
2995 // Configuration string. The encapsulated option space
2996 // name is set to non-empty value and the array flag
2997 // is set.
2998 std::string config =
2999 "{ \"option-def\": [ {"
3000 " \"name\": \"foo\","
3001 " \"code\": 100,"
3002 " \"type\": \"uint32\","
3003 " \"array\": true,"
3004 " \"space\": \"isc\","
3005 " \"encapsulate\": \"valid-space-name\""
3006 " } ]"
3007 "}";
3008 ConstElementPtr json;
3009 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_3009
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3009
; } } else gtest_label_testnothrow_3009 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3009, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3010
3011 // Use the configuration string to create new option definition.
3012 ConstElementPtr status;
3013 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_3013; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3013; } } else gtest_label_testnothrow_3013
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3013, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3014 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"
, 3014, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
3015 // Expecting parsing error (error code 1).
3016 checkResult(status, CONTROL_RESULT_ERROR);
3017 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"
, 3017, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
3018}
3019
3020/// The goal of this test is to verify that the option may not
3021/// encapsulate option space it belongs to.
3022TEST_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"
, 3022), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3022), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3022), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDefEncapsulateOwnSpace_Test
>); void Dhcp4ParserTest_optionDefEncapsulateOwnSpace_Test
::TestBody()
{
3023 // Configuration string. Option is set to encapsulate
3024 // option space it belongs to.
3025 std::string config =
3026 "{ \"option-def\": [ {"
3027 " \"name\": \"foo\","
3028 " \"code\": 100,"
3029 " \"type\": \"uint32\","
3030 " \"space\": \"isc\","
3031 " \"encapsulate\": \"isc\""
3032 " } ]"
3033 "}";
3034 ConstElementPtr json;
3035 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_3035
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3035
; } } else gtest_label_testnothrow_3035 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3035, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3036
3037 // Use the configuration string to create new option definition.
3038 ConstElementPtr status;
3039 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_3039; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3039; } } else gtest_label_testnothrow_3039
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3039, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3040 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"
, 3040, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
3041 // Expecting parsing error (error code 1).
3042 checkResult(status, CONTROL_RESULT_ERROR);
3043 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"
, 3043, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
3044}
3045
3046/// The purpose of this test is to verify that it is not allowed
3047/// to override the standard option (that belongs to dhcp4 option
3048/// space and has its definition) and that it is allowed to define
3049/// option in the dhcp4 option space that has a code which is not
3050/// used by any of the standard options.
3051TEST_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"
, 3051), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3051), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3051), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionStandardDefOverride_Test
>); void Dhcp4ParserTest_optionStandardDefOverride_Test::TestBody
()
{
3052
3053 // Configuration string. The option code 109 is unassigned
3054 // so it can be used for a custom option definition in
3055 // dhcp4 option space.
3056 std::string config =
3057 "{ \"option-def\": [ {"
3058 " \"name\": \"foo\","
3059 " \"code\": 109,"
3060 " \"type\": \"string\","
3061 " \"space\": \"dhcp4\""
3062 " } ]"
3063 "}";
3064 ConstElementPtr json;
3065 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_3065
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3065
; } } else gtest_label_testnothrow_3065 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3065, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3066 extractConfig(config);
3067
3068 OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
3069 getCfgOptionDef()->get(DHCP4_OPTION_SPACE"dhcp4", 109);
3070 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"
, 3070, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "true", "false") .c_str()) = ::testing::Message()
;
3071
3072 // Use the configuration string to create new option definition.
3073 ConstElementPtr status;
3074 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_3074; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3074; } } else gtest_label_testnothrow_3074
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3074, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3075 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"
, 3075, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
3076 checkResult(status, 0);
3077
3078 // The option definition should now be available in the CfgMgr.
3079 def = CfgMgr::instance().getStagingCfg()->
3080 getCfgOptionDef()->get(DHCP4_OPTION_SPACE"dhcp4", 109);
3081 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", 3081
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "false", "true") .c_str()) = ::testing::Message()
;
3082
3083 // Check the option data.
3084 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", 3084
, gtest_ar.failure_message()) = ::testing::Message()
;
3085 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"
, 3085, gtest_ar.failure_message()) = ::testing::Message()
;
3086 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"
, 3086, gtest_ar.failure_message()) = ::testing::Message()
;
3087 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"
, 3087, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getArrayType()", "true", "false") .c_str()) = ::testing
::Message()
;
3088
3089 // The combination of option space and code is invalid. The 'dhcp4'
3090 // option space groups standard options and the code 3 is reserved
3091 // for one of them.
3092 config =
3093 "{ \"option-def\": [ {"
3094 " \"name\": \"routers\","
3095 " \"code\": 3,"
3096 " \"type\": \"ipv4-address\","
3097 " \"space\": \"dhcp4\""
3098 " } ]"
3099 "}";
3100 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_3100
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3100
; } } else gtest_label_testnothrow_3100 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3100, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3101
3102 // Use the configuration string to create new option definition.
3103 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_3103; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3103; } } else gtest_label_testnothrow_3103
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3103, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3104 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"
, 3104, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
3105 // Expecting parsing error (error code 1).
3106 checkResult(status, CONTROL_RESULT_ERROR);
3107 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"
, 3107, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
3108
3109 /// There is no definition for unassigned option 170.
3110 config =
3111 "{ \"option-def\": [ {"
3112 " \"name\": \"unassigned-option-170\","
3113 " \"code\": 170,"
3114 " \"type\": \"string\","
3115 " \"space\": \"dhcp4\""
3116 " } ]"
3117 "}";
3118 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_3118
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3118
; } } else gtest_label_testnothrow_3118 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3118, ("Expected: " "json = parseOPTION_DEFS(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3119 extractConfig(config);
3120
3121 // Use the configuration string to create new option definition.
3122 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_3122; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3122; } } else gtest_label_testnothrow_3122
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3122, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3123 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"
, 3123, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
3124 // Expecting success.
3125 checkResult(status, 0);
3126
3127 def = CfgMgr::instance().getStagingCfg()->
3128 getCfgOptionDef()->get(DHCP4_OPTION_SPACE"dhcp4", 170);
3129 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", 3129
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def", "false", "true") .c_str()) = ::testing::Message()
;
3130
3131 // Check the option data.
3132 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"
, 3132, gtest_ar.failure_message()) = ::testing::Message()
;
3133 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"
, 3133, gtest_ar.failure_message()) = ::testing::Message()
;
3134 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"
, 3134, gtest_ar.failure_message()) = ::testing::Message()
;
3135 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"
, 3135, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "def->getArrayType()", "true", "false") .c_str()) = ::testing
::Message()
;
3136}
3137
3138// Goal of this test is to verify that global option data is configured
3139TEST_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"
, 3139), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3139), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3139), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataDefaultsGlobal_Test
>); void Dhcp4ParserTest_optionDataDefaultsGlobal_Test::TestBody
()
{
3140 ConstElementPtr x;
3141 string config = "{ " + genIfaceConfig() + ","
3142 "\"rebind-timer\": 2000,"
3143 "\"renew-timer\": 1000,"
3144 "\"option-data\": [ {"
3145 " \"name\": \"dhcp-message\","
3146 " \"data\": \"ABCDEF0105\","
3147 " \"csv-format\": false"
3148 " },"
3149 " {"
3150 " \"name\": \"default-ip-ttl\","
3151 " \"data\": \"01\","
3152 " \"csv-format\": false"
3153 " } ],"
3154 "\"subnet4\": [ { "
3155 " \"id\": 1,"
3156 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
3157 " \"subnet\": \"192.0.2.0/24\""
3158 " } ],"
3159 "\"valid-lifetime\": 4000 }";
3160
3161 ConstElementPtr json;
3162 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_3162
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3162
; } } else gtest_label_testnothrow_3162 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3162, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3163 extractConfig(config);
3164
3165 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_3165; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3165; } } else gtest_label_testnothrow_3165
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3165, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3166 checkResult(x, 0);
3167
3168 // These options are global
3169 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
3170 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
3171 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"
, 3171, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
3172 OptionContainerPtr options = subnet->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3173 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"
, 3173, gtest_ar.failure_message()) = ::testing::Message()
;
3174
3175 options = CfgMgr::instance().getStagingCfg()->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3176 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"
, 3176, gtest_ar.failure_message()) = ::testing::Message()
;
3177
3178 // Get the search index. Index #1 is to search using option code.
3179 const OptionContainerTypeIndex& idx = options->get<1>();
3180
3181 // Get the options for specified index. Expecting one option to be
3182 // returned but in theory we may have multiple options with the same
3183 // code so we get the range.
3184 std::pair<OptionContainerTypeIndex::const_iterator,
3185 OptionContainerTypeIndex::const_iterator> range =
3186 idx.equal_range(56);
3187 // Expect single option with the code equal to 56.
3188 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"
, 3188, gtest_ar.failure_message()) = ::testing::Message()
;
3189 const uint8_t foo_expected[] = {
3190 0xAB, 0xCD, 0xEF, 0x01, 0x05
3191 };
3192 // Check if option is valid in terms of code and carried data.
3193 testOption(*range.first, 56, foo_expected, sizeof(foo_expected));
3194
3195 range = idx.equal_range(23);
3196 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"
, 3196, gtest_ar.failure_message()) = ::testing::Message()
;
3197 // Do another round of testing with second option.
3198 const uint8_t foo2_expected[] = {
3199 0x01
3200 };
3201 testOption(*range.first, 23, foo2_expected, sizeof(foo2_expected));
3202
3203 // Check that options with other option codes are not returned.
3204 for (uint8_t code = 24; code < 35; ++code) {
3205 range = idx.equal_range(code);
3206 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", 3206
, gtest_ar.failure_message()) = ::testing::Message()
;
3207 }
3208}
3209
3210// Goal of this test is to verify that subnet option data is configured
3211TEST_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"
, 3211), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3211), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3211), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataDefaultsSubnet_Test
>); void Dhcp4ParserTest_optionDataDefaultsSubnet_Test::TestBody
()
{
3212 ConstElementPtr x;
3213 string config = "{ " + genIfaceConfig() + ","
3214 "\"rebind-timer\": 2000,"
3215 "\"renew-timer\": 1000,"
3216 "\"subnet4\": [ { "
3217 " \"id\": 1,"
3218 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
3219 " \"subnet\": \"192.0.2.0/24\","
3220 " \"option-data\": [ {"
3221 " \"name\": \"dhcp-message\","
3222 " \"data\": \"ABCDEF0105\","
3223 " \"csv-format\": false"
3224 " },"
3225 " {"
3226 " \"name\": \"default-ip-ttl\","
3227 " \"data\": \"01\","
3228 " \"csv-format\": false"
3229 " } ]"
3230 " } ],"
3231 "\"valid-lifetime\": 4000 }";
3232
3233 ConstElementPtr json;
3234 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_3234
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3234
; } } else gtest_label_testnothrow_3234 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3234, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3235 extractConfig(config);
3236
3237 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_3237; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3237; } } else gtest_label_testnothrow_3237
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3237, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3238 checkResult(x, 0);
3239
3240 // These options are subnet options
3241 OptionContainerPtr options =
3242 CfgMgr::instance().getStagingCfg()->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3243 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"
, 3243, gtest_ar.failure_message()) = ::testing::Message()
;
3244
3245 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
3246 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
3247 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"
, 3247, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
3248 options = subnet->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3249 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"
, 3249, gtest_ar.failure_message()) = ::testing::Message()
;
3250
3251 // Get the search index. Index #1 is to search using option code.
3252 const OptionContainerTypeIndex& idx = options->get<1>();
3253
3254 // Get the options for specified index. Expecting one option to be
3255 // returned but in theory we may have multiple options with the same
3256 // code so we get the range.
3257 std::pair<OptionContainerTypeIndex::const_iterator,
3258 OptionContainerTypeIndex::const_iterator> range =
3259 idx.equal_range(56);
3260 // Expect single option with the code equal to 56.
3261 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"
, 3261, gtest_ar.failure_message()) = ::testing::Message()
;
3262 const uint8_t foo_expected[] = {
3263 0xAB, 0xCD, 0xEF, 0x01, 0x05
3264 };
3265 // Check if option is valid in terms of code and carried data.
3266 testOption(*range.first, 56, foo_expected, sizeof(foo_expected));
3267
3268 range = idx.equal_range(23);
3269 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"
, 3269, gtest_ar.failure_message()) = ::testing::Message()
;
3270 // Do another round of testing with second option.
3271 const uint8_t foo2_expected[] = {
3272 0x01
3273 };
3274 testOption(*range.first, 23, foo2_expected, sizeof(foo2_expected));
3275}
3276
3277/// The goal of this test is to verify that two options having the same
3278/// option code can be added to different option spaces.
3279TEST_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"
, 3279), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3279), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3279), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataTwoSpaces_Test
>); void Dhcp4ParserTest_optionDataTwoSpaces_Test::TestBody
()
{
3280
3281 // This configuration string is to configure two options
3282 // sharing the code 56 and having different definitions
3283 // and belonging to the different option spaces.
3284 // The option definition must be provided for the
3285 // option that belongs to the 'isc' option space.
3286 // The definition is not required for the option that
3287 // belongs to the 'dhcp4' option space as it is the
3288 // standard option.
3289 string config = "{ " + genIfaceConfig() + ","
3290 "\"valid-lifetime\": 4000,"
3291 "\"rebind-timer\": 2000,"
3292 "\"renew-timer\": 1000,"
3293 "\"option-data\": [ {"
3294 " \"name\": \"dhcp-message\","
3295 " \"data\": \"ABCDEF0105\","
3296 " \"csv-format\": false"
3297 " },"
3298 " {"
3299 " \"name\": \"foo\","
3300 " \"space\": \"isc\","
3301 " \"data\": \"1234\""
3302 " } ],"
3303 "\"option-def\": [ {"
3304 " \"name\": \"foo\","
3305 " \"code\": 56,"
3306 " \"type\": \"uint32\","
3307 " \"space\": \"isc\""
3308 " } ],"
3309 "\"subnet4\": [ { "
3310 " \"id\": 1,"
3311 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
3312 " \"subnet\": \"192.0.2.0/24\""
3313 " } ]"
3314 "}";
3315
3316 ConstElementPtr json;
3317 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_3317
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3317
; } } else gtest_label_testnothrow_3317 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3317, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3318 extractConfig(config);
3319
3320 ConstElementPtr status;
3321 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_3321; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3321; } } else gtest_label_testnothrow_3321
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3321, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3322 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"
, 3322, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
3323 checkResult(status, 0);
3324
3325 // Options should be now available
3326 // Try to get the option from the space dhcp4.
3327 OptionDescriptor desc1 =
3328 CfgMgr::instance().getStagingCfg()->getCfgOption()->get(DHCP4_OPTION_SPACE"dhcp4", 56);
3329 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"
, 3329, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc1.option_", "false", "true") .c_str()) = ::testing::Message
()
;
3330 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"
, 3330, gtest_ar.failure_message()) = ::testing::Message()
;
3331 // Try to get the option from the space isc.
3332 OptionDescriptor desc2 =
3333 CfgMgr::instance().getStagingCfg()->getCfgOption()->get("isc", 56);
3334 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"
, 3334, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc2.option_", "false", "true") .c_str()) = ::testing::Message
()
;
3335 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"
, 3335, gtest_ar.failure_message()) = ::testing::Message()
;
3336 // Try to get the non-existing option from the non-existing
3337 // option space and expect that option is not returned.
3338 OptionDescriptor desc3 = CfgMgr::instance().getStagingCfg()->
3339 getCfgOption()->get("non-existing", 56);
3340 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"
, 3340, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc3.option_", "true", "false") .c_str()) = ::testing::Message
()
;
3341}
3342
3343// The goal of this test is to verify that it is possible to
3344// encapsulate option space containing some options with
3345// another option. In this test we create base option that
3346// encapsulates option space 'isc' that comprises two other
3347// options. Also, for all options their definitions are
3348// created.
3349TEST_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"
, 3349), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3349), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3349), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataEncapsulate_Test
>); void Dhcp4ParserTest_optionDataEncapsulate_Test::TestBody
()
{
3350
3351 // @todo DHCP configurations has many dependencies between
3352 // parameters. First of all, configuration for subnet is
3353 // inherited from the global values. Thus subnet has to be
3354 // configured when all global values have been configured.
3355 // Also, an option can encapsulate another option only
3356 // if the latter has been configured. For this reason in this
3357 // test we created two-stage configuration where first we
3358 // created options that belong to encapsulated option space.
3359 // In the second stage we add the base option. Also, the Subnet
3360 // object is configured in the second stage so it is created
3361 // at the very end (when all other parameters are configured).
3362
3363 // Starting stage 1. Configure sub-options and their definitions.
3364 string config = "{ " + genIfaceConfig() + ","
3365 "\"valid-lifetime\": 4000,"
3366 "\"rebind-timer\": 2000,"
3367 "\"renew-timer\": 1000,"
3368 "\"option-data\": [ {"
3369 " \"name\": \"foo\","
3370 " \"space\": \"isc\","
3371 " \"data\": \"1234\""
3372 " },"
3373 " {"
3374 " \"name\": \"foo2\","
3375 " \"space\": \"isc\","
3376 " \"data\": \"192.168.2.1\""
3377 " } ],"
3378 "\"option-def\": [ {"
3379 " \"name\": \"foo\","
3380 " \"code\": 1,"
3381 " \"type\": \"uint32\","
3382 " \"space\": \"isc\""
3383 " },"
3384 " {"
3385 " \"name\": \"foo2\","
3386 " \"code\": 2,"
3387 " \"type\": \"ipv4-address\","
3388 " \"space\": \"isc\""
3389 " } ]"
3390 "}";
3391
3392 ConstElementPtr json;
3393 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_3393
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3393
; } } else gtest_label_testnothrow_3393 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3393, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3394 extractConfig(config);
3395
3396 ConstElementPtr status;
3397 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_3397; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3397; } } else gtest_label_testnothrow_3397
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3397, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3398 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"
, 3398, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
3399 checkResult(status, 0);
3400
3401 CfgMgr::instance().clear();
3402
3403 // Stage 2. Configure base option and a subnet. Please note that
3404 // the configuration from the stage 2 is repeated because Kea
3405 // configuration manager sends whole configuration for the lists
3406 // where at least one element is being modified or added.
3407 config = "{ " + genIfaceConfig() + ","
3408 "\"valid-lifetime\": 3000,"
3409 "\"rebind-timer\": 2000,"
3410 "\"renew-timer\": 1000,"
3411 "\"option-data\": [ {"
3412 " \"name\": \"base-option\","
3413 " \"data\": \"11\""
3414 " },"
3415 " {"
3416 " \"name\": \"foo\","
3417 " \"space\": \"isc\","
3418 " \"data\": \"1234\""
3419 " },"
3420 " {"
3421 " \"name\": \"foo2\","
3422 " \"space\": \"isc\","
3423 " \"data\": \"192.168.2.1\""
3424 " } ],"
3425 "\"option-def\": [ {"
3426 " \"name\": \"base-option\","
3427 " \"code\": 222,"
3428 " \"type\": \"uint8\","
3429 " \"space\": \"dhcp4\","
3430 " \"encapsulate\": \"isc\""
3431 "},"
3432 "{"
3433 " \"name\": \"foo\","
3434 " \"code\": 1,"
3435 " \"type\": \"uint32\","
3436 " \"space\": \"isc\""
3437 " },"
3438 " {"
3439 " \"name\": \"foo2\","
3440 " \"code\": 2,"
3441 " \"type\": \"ipv4-address\","
3442 " \"space\": \"isc\""
3443 " } ],"
3444 "\"subnet4\": [ { "
3445 " \"id\": 1,"
3446 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
3447 " \"subnet\": \"192.0.2.0/24\""
3448 " } ]"
3449 "}";
3450
3451 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_3451
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3451
; } } else gtest_label_testnothrow_3451 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3451, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3452 extractConfig(config);
3453
3454 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_3454; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3454; } } else gtest_label_testnothrow_3454
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3454, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3455 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"
, 3455, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
3456 checkResult(status, 0);
3457
3458 // We should have one option available.
3459 OptionContainerPtr options =
3460 CfgMgr::instance().getStagingCfg()->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3461 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"
, 3461, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "options", "false", "true") .c_str()) = ::testing::Message(
)
;
3462 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"
, 3462, gtest_ar.failure_message()) = ::testing::Message()
;
3463
3464 // Get the option.
3465 OptionDescriptor desc =
3466 CfgMgr::instance().getStagingCfg()->getCfgOption()->get(DHCP4_OPTION_SPACE"dhcp4", 222);
3467 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"
, 3467, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc.option_", "false", "true") .c_str()) = ::testing::Message
()
;
3468 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"
, 3468, gtest_ar.failure_message()) = ::testing::Message()
;
3469
3470 // This option should comprise two sub-options.
3471 // One of them is 'foo' with code 1.
3472 OptionPtr option_foo = desc.option_->getOption(1);
3473 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"
, 3473, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option_foo", "false", "true") .c_str()) = ::testing::Message
()
;
3474 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"
, 3474, gtest_ar.failure_message()) = ::testing::Message()
;
3475
3476 // ...another one 'foo2' with code 2.
3477 OptionPtr option_foo2 = desc.option_->getOption(2);
3478 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"
, 3478, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option_foo2", "false", "true") .c_str()) = ::testing::Message
()
;
3479 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"
, 3479, gtest_ar.failure_message()) = ::testing::Message()
;
3480}
3481
3482// Goal of this test is to verify options configuration
3483// for a single subnet. In particular this test checks
3484// that local options configuration overrides global
3485// option setting.
3486TEST_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"
, 3486), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3486), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3486), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataInSingleSubnet_Test
>); void Dhcp4ParserTest_optionDataInSingleSubnet_Test::TestBody
()
{
3487 ConstElementPtr x;
3488 string config = "{ " + genIfaceConfig() + ","
3489 "\"rebind-timer\": 2000, "
3490 "\"renew-timer\": 1000, "
3491 "\"option-data\": [ {"
3492 " \"name\": \"dhcp-message\","
3493 " \"data\": \"AB\","
3494 " \"csv-format\": false"
3495 " } ],"
3496 "\"subnet4\": [ { "
3497 " \"id\": 1,"
3498 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
3499 " \"subnet\": \"192.0.2.0/24\", "
3500 " \"option-data\": [ {"
3501 " \"name\": \"dhcp-message\","
3502 " \"data\": \"ABCDEF0105\","
3503 " \"csv-format\": false"
3504 " },"
3505 " {"
3506 " \"name\": \"default-ip-ttl\","
3507 " \"data\": \"01\","
3508 " \"csv-format\": false"
3509 " } ]"
3510 " } ],"
3511 "\"valid-lifetime\": 4000 }";
3512
3513 ConstElementPtr json;
3514 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_3514
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3514
; } } else gtest_label_testnothrow_3514 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3514, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3515 extractConfig(config);
3516
3517 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_3517; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3517; } } else gtest_label_testnothrow_3517
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3517, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3518 checkResult(x, 0);
3519
3520 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
3521 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.24"));
3522 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"
, 3522, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
3523 OptionContainerPtr options = subnet->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3524 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"
, 3524, gtest_ar.failure_message()) = ::testing::Message()
;
3525
3526 // Get the search index. Index #1 is to search using option code.
3527 const OptionContainerTypeIndex& idx = options->get<1>();
3528
3529 // Get the options for specified index. Expecting one option to be
3530 // returned but in theory we may have multiple options with the same
3531 // code so we get the range.
3532 std::pair<OptionContainerTypeIndex::const_iterator,
3533 OptionContainerTypeIndex::const_iterator> range =
3534 idx.equal_range(56);
3535 // Expect single option with the code equal to 100.
3536 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"
, 3536, gtest_ar.failure_message()) = ::testing::Message()
;
3537 const uint8_t foo_expected[] = {
3538 0xAB, 0xCD, 0xEF, 0x01, 0x05
3539 };
3540 // Check if option is valid in terms of code and carried data.
3541 testOption(*range.first, 56, foo_expected, sizeof(foo_expected));
3542
3543 range = idx.equal_range(23);
3544 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"
, 3544, gtest_ar.failure_message()) = ::testing::Message()
;
3545 // Do another round of testing with second option.
3546 const uint8_t foo2_expected[] = {
3547 0x01
3548 };
3549 testOption(*range.first, 23, foo2_expected, sizeof(foo2_expected));
3550}
3551
3552// The goal of this test is to check that the option carrying a boolean
3553// value can be configured using one of the values: "true", "false", "0"
3554// or "1".
3555TEST_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"
, 3555), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3555), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3555), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataBoolean_Test
>); void Dhcp4ParserTest_optionDataBoolean_Test::TestBody(
)
{
3556 // Create configuration. Use standard option 19 (ip-forwarding).
3557 std::map<std::string, std::string> params;
3558 params["name"] = "ip-forwarding";
3559 params["space"] = DHCP4_OPTION_SPACE"dhcp4";
3560 params["code"] = "19";
3561 params["data"] = "true";
3562 params["csv-format"] = "true";
3563
3564 std::string config = createConfigWithOption(params);
3565 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"
, 3566, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "executeConfiguration(config, \"parse configuration with a\" \" boolean value\")"
, "false", "true") .c_str()) = ::testing::Message()
3566 " 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"
, 3566, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "executeConfiguration(config, \"parse configuration with a\" \" boolean value\")"
, "false", "true") .c_str()) = ::testing::Message()
;
3567
3568 // The subnet should now hold one option with the code 19.
3569 OptionDescriptor desc = getOptionFromSubnet(IOAddress("192.0.2.24"), 19);
3570 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"
, 3570, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc.option_", "false", "true") .c_str()) = ::testing::Message
()
;
3571
3572 // This option should be set to "true", represented as 0x1 in the option
3573 // buffer.
3574 uint8_t expected_option_data[] = {
3575 0x1
3576 };
3577 testConfiguration(params, 19, expected_option_data,
3578 sizeof(expected_option_data));
3579
3580 // Configure the option with the "1" value. This should have the same
3581 // effect as if "true" was specified.
3582 params["data"] = "1";
3583 testConfiguration(params, 19, expected_option_data,
3584 sizeof(expected_option_data));
3585
3586 // The value of "1" with a few leading zeros should work too.
3587 params["data"] = "00001";
3588 testConfiguration(params, 19, expected_option_data,
3589 sizeof(expected_option_data));
3590
3591 // Configure the option with the "false" value.
3592 params["data"] = "false";
3593 // The option buffer should now hold the value of 0.
3594 expected_option_data[0] = 0;
3595 testConfiguration(params, 19, expected_option_data,
3596 sizeof(expected_option_data));
3597
3598 // Specifying "0" should have the same effect as "false".
3599 params["data"] = "0";
3600 testConfiguration(params, 19, expected_option_data,
3601 sizeof(expected_option_data));
3602
3603 // The same effect should be for multiple 0 chars.
3604 params["data"] = "00000";
3605 testConfiguration(params, 19, expected_option_data,
3606 sizeof(expected_option_data));
3607
3608 // Bogus values should not be accepted.
3609 params["data"] = "bogus";
3610 testInvalidOptionParam(params);
3611
3612 params["data"] = "2";
3613 testInvalidOptionParam(params);
3614
3615 // Now let's test that it is possible to use binary format.
3616 params["data"] = "0";
3617 params["csv-format"] = "false";
3618 testConfiguration(params, 19, expected_option_data,
3619 sizeof(expected_option_data));
3620
3621 // The binary 1 should work as well.
3622 params["data"] = "1";
3623 expected_option_data[0] = 1;
3624 testConfiguration(params, 19, expected_option_data,
3625 sizeof(expected_option_data));
3626
3627 // As well as an even number of digits.
3628 params["data"] = "01";
3629 testConfiguration(params, 19, expected_option_data,
3630 sizeof(expected_option_data));
3631}
3632
3633// Goal of this test is to verify options configuration
3634// for multiple subnets.
3635TEST_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"
, 3635), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3635), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3635), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataInMultipleSubnets_Test
>); void Dhcp4ParserTest_optionDataInMultipleSubnets_Test::
TestBody()
{
3636 ConstElementPtr x;
3637 string config = "{ " + genIfaceConfig() + ","
3638 "\"rebind-timer\": 2000, "
3639 "\"renew-timer\": 1000, "
3640 "\"subnet4\": [ { "
3641 " \"id\": 1,"
3642 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
3643 " \"subnet\": \"192.0.2.0/24\", "
3644 " \"option-data\": [ {"
3645 " \"name\": \"dhcp-message\","
3646 " \"data\": \"0102030405060708090A\","
3647 " \"csv-format\": false"
3648 " } ]"
3649 " },"
3650 " {"
3651 " \"id\": 2,"
3652 " \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
3653 " \"subnet\": \"192.0.3.0/24\", "
3654 " \"option-data\": [ {"
3655 " \"name\": \"default-ip-ttl\","
3656 " \"data\": \"FF\","
3657 " \"csv-format\": false"
3658 " } ]"
3659 " } ],"
3660 "\"valid-lifetime\": 4000 }";
3661
3662 ConstElementPtr json;
3663 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_3663
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3663
; } } else gtest_label_testnothrow_3663 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3663, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3664 extractConfig(config);
3665
3666 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_3666; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3666; } } else gtest_label_testnothrow_3666
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3666, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3667 checkResult(x, 0);
3668
3669 ConstSubnet4Ptr subnet1 = CfgMgr::instance().getStagingCfg()->
3670 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.100"));
3671 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"
, 3671, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1", "false", "true") .c_str()) = ::testing::Message(
)
;
3672 OptionContainerPtr options1 = subnet1->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3673 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"
, 3673, gtest_ar.failure_message()) = ::testing::Message()
;
3674
3675 // Get the search index. Index #1 is to search using option code.
3676 const OptionContainerTypeIndex& idx1 = options1->get<1>();
3677
3678 // Get the options for specified index. Expecting one option to be
3679 // returned but in theory we may have multiple options with the same
3680 // code so we get the range.
3681 std::pair<OptionContainerTypeIndex::const_iterator,
3682 OptionContainerTypeIndex::const_iterator> range1 =
3683 idx1.equal_range(56);
3684 // Expect single option with the code equal to 56.
3685 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"
, 3685, gtest_ar.failure_message()) = ::testing::Message()
;
3686 const uint8_t foo_expected[] = {
3687 0x01, 0x02, 0x03, 0x04, 0x05,
3688 0x06, 0x07, 0x08, 0x09, 0x0A
3689 };
3690 // Check if option is valid in terms of code and carried data.
3691 testOption(*range1.first, 56, foo_expected, sizeof(foo_expected));
3692
3693 // Test another subnet in the same way.
3694 ConstSubnet4Ptr subnet2 = CfgMgr::instance().getStagingCfg()->
3695 getCfgSubnets4()->selectSubnet(IOAddress("192.0.3.102"));
3696 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"
, 3696, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2", "false", "true") .c_str()) = ::testing::Message(
)
;
3697 OptionContainerPtr options2 = subnet2->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3698 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"
, 3698, gtest_ar.failure_message()) = ::testing::Message()
;
3699
3700 const OptionContainerTypeIndex& idx2 = options2->get<1>();
3701 std::pair<OptionContainerTypeIndex::const_iterator,
3702 OptionContainerTypeIndex::const_iterator> range2 =
3703 idx2.equal_range(23);
3704 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"
, 3704, gtest_ar.failure_message()) = ::testing::Message()
;
3705
3706 const uint8_t foo2_expected[] = { 0xFF };
3707 testOption(*range2.first, 23, foo2_expected, sizeof(foo2_expected));
3708}
3709
3710// This test verifies that it is possible to specify options on
3711// pool levels.
3712TEST_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"
, 3712), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3712), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3712), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataSinglePool_Test
>); void Dhcp4ParserTest_optionDataSinglePool_Test::TestBody
()
{
3713 ConstElementPtr x;
3714 string config = "{ " + genIfaceConfig() + ","
3715 "\"rebind-timer\": 2000, "
3716 "\"renew-timer\": 1000, "
3717 "\"subnet4\": [ { "
3718 " \"id\": 1,"
3719 " \"pools\": [ { "
3720 " \"pool\": \"192.0.2.1 - 192.0.2.100\","
3721 " \"option-data\": [ {"
3722 " \"name\": \"dhcp-message\","
3723 " \"data\": \"ABCDEF0105\","
3724 " \"csv-format\": false"
3725 " },"
3726 " {"
3727 " \"name\": \"default-ip-ttl\","
3728 " \"data\": \"01\","
3729 " \"csv-format\": false"
3730 " } ]"
3731 " } ],"
3732 " \"subnet\": \"192.0.2.0/24\""
3733 " } ],"
3734 "\"valid-lifetime\": 4000 }";
3735
3736 ConstElementPtr json;
3737 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_3737
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3737
; } } else gtest_label_testnothrow_3737 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3737, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3738 extractConfig(config);
3739
3740 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_3740; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3740; } } else gtest_label_testnothrow_3740
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3740, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3741 checkResult(x, 0);
3742
3743 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
3744 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.24"), classify_);
3745 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"
, 3745, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
3746
3747 PoolPtr pool = subnet->getPool(Lease::TYPE_V4, IOAddress("192.0.2.24"), false);
3748 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", 3748
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
3749 Pool4Ptr pool4 = boost::dynamic_pointer_cast<Pool4>(pool);
3750 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"
, 3750, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool4", "false", "true") .c_str()) = ::testing::Message()
;
3751
3752 OptionContainerPtr options =
3753 pool4->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3754 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"
, 3754, gtest_ar.failure_message()) = ::testing::Message()
;
3755
3756 // Get the search index. Index #1 is to search using option code.
3757 const OptionContainerTypeIndex& idx = options->get<1>();
3758
3759 // Get the options for specified index. Expecting one option to be
3760 // returned but in theory we may have multiple options with the same
3761 // code so we get the range.
3762 std::pair<OptionContainerTypeIndex::const_iterator,
3763 OptionContainerTypeIndex::const_iterator> range =
3764 idx.equal_range(56);
3765 // Expect a single option with the code equal to 100.
3766 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"
, 3766, gtest_ar.failure_message()) = ::testing::Message()
;
3767 const uint8_t foo_expected[] = {
3768 0xAB, 0xCD, 0xEF, 0x01, 0x05
3769 };
3770 // Check if option is valid in terms of code and carried data.
3771 testOption(*range.first, 56, foo_expected, sizeof(foo_expected));
3772
3773 range = idx.equal_range(23);
3774 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"
, 3774, gtest_ar.failure_message()) = ::testing::Message()
;
3775 // Do another round of testing with second option.
3776
3777 const uint8_t foo2_expected[] = {
3778 0x01
3779 };
3780 testOption(*range.first, 23, foo2_expected, sizeof(foo2_expected));
3781}
3782
3783// This test verifies that it's possible to define different options in
3784// different pools and those options are not confused.
3785TEST_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"
, 3785), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3785), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3785), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataMultiplePools_Test
>); void Dhcp4ParserTest_optionDataMultiplePools_Test::TestBody
()
{
3786 ConstElementPtr x;
3787 string config = "{ " + genIfaceConfig() + ","
3788 "\"rebind-timer\": 2000, "
3789 "\"renew-timer\": 1000, "
3790 "\"subnet4\": [ { "
3791 " \"id\": 1,"
3792 " \"pools\": [ { "
3793 " \"pool\": \"192.0.2.1 - 192.0.2.100\","
3794 " \"option-data\": [ {"
3795 " \"name\": \"dhcp-message\","
3796 " \"data\": \"ABCDEF0105\","
3797 " \"csv-format\": false"
3798 " } ]"
3799 " },"
3800 " {"
3801 " \"pool\": \"192.0.2.200 - 192.0.2.250\","
3802 " \"option-data\": [ {"
3803 " \"name\": \"default-ip-ttl\","
3804 " \"data\": \"01\","
3805 " \"csv-format\": false"
3806 " } ]"
3807 " } ],"
3808 " \"subnet\": \"192.0.2.0/24\""
3809 " } ],"
3810 "\"valid-lifetime\": 4000 }";
3811
3812 ConstElementPtr json;
3813 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_3813
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3813
; } } else gtest_label_testnothrow_3813 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3813, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3814 extractConfig(config);
3815
3816 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_3816; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3816; } } else gtest_label_testnothrow_3816
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3816, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3817 checkResult(x, 0);
3818
3819 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
3820 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.24"), classify_);
3821 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"
, 3821, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
3822
3823 PoolPtr pool1 = subnet->getPool(Lease::TYPE_V4, IOAddress("192.0.2.24"), false);
3824 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"
, 3824, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool1", "false", "true") .c_str()) = ::testing::Message()
;
3825 Pool4Ptr pool41 = boost::dynamic_pointer_cast<Pool4>(pool1);
3826 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"
, 3826, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool41", "false", "true") .c_str()) = ::testing::Message()
;
3827
3828 OptionContainerPtr options1 =
3829 pool41->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3830 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"
, 3830, gtest_ar.failure_message()) = ::testing::Message()
;
3831
3832 // Get the search index. Index #1 is to search using option code.
3833 const OptionContainerTypeIndex& idx1 = options1->get<1>();
3834
3835 // Get the options for specified index. Expecting one option to be
3836 // returned but in theory we may have multiple options with the same
3837 // code so we get the range.
3838 std::pair<OptionContainerTypeIndex::const_iterator,
3839 OptionContainerTypeIndex::const_iterator> range1 =
3840 idx1.equal_range(56);
3841 // Expect a single option with the code equal to 100.
3842 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"
, 3842, gtest_ar.failure_message()) = ::testing::Message()
;
3843 const uint8_t foo_expected[] = {
3844 0xAB, 0xCD, 0xEF, 0x01, 0x05
3845 };
3846 // Check if option is valid in terms of code and carried data.
3847 testOption(*range1.first, 56, foo_expected, sizeof(foo_expected));
3848
3849 // Test another pool in the same way.
3850 PoolPtr pool2 = subnet->getPool(Lease::TYPE_V4, IOAddress("192.0.2.240"), false);
3851 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"
, 3851, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool2", "false", "true") .c_str()) = ::testing::Message()
;
3852 Pool4Ptr pool42 = boost::dynamic_pointer_cast<Pool4>(pool2);
3853 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"
, 3853, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool42", "false", "true") .c_str()) = ::testing::Message()
;
3854
3855 OptionContainerPtr options2 =
3856 pool42->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3857 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"
, 3857, gtest_ar.failure_message()) = ::testing::Message()
;
3858
3859 const OptionContainerTypeIndex& idx2 = options2->get<1>();
3860 std::pair<OptionContainerTypeIndex::const_iterator,
3861 OptionContainerTypeIndex::const_iterator> range2 =
3862 idx2.equal_range(23);
3863 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"
, 3863, gtest_ar.failure_message()) = ::testing::Message()
;
3864 const uint8_t foo2_expected[] = {
3865 0x01
3866 };
3867 testOption(*range2.first, 23, foo2_expected, sizeof(foo2_expected));
3868}
3869
3870// Verify that empty option name is rejected in the configuration.
3871TEST_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", 3871
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3871), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3871), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionNameEmpty_Test
>); void Dhcp4ParserTest_optionNameEmpty_Test::TestBody()
{
3872 // Empty option names not allowed.
3873 testInvalidOptionParam("", "name");
3874}
3875
3876// Verify that empty option name with spaces is rejected
3877// in the configuration.
3878TEST_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"
, 3878), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3878), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3878), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionNameSpaces_Test
>); void Dhcp4ParserTest_optionNameSpaces_Test::TestBody()
{
3879 // Spaces in option names not allowed.
3880 testInvalidOptionParam("option foo", "name");
3881}
3882
3883// Verify that negative option code is rejected in the configuration.
3884TEST_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"
, 3884), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3884), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3884), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionCodeNegative_Test
>); void Dhcp4ParserTest_optionCodeNegative_Test::TestBody
()
{
3885 // Check negative option code -4. This should fail too.
3886 testInvalidOptionParam("-4", "code");
3887}
3888
3889// Verify that out of bounds option code is rejected in the configuration.
3890TEST_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"
, 3890), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3890), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3890), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionCodeNonUint8_Test
>); void Dhcp4ParserTest_optionCodeNonUint8_Test::TestBody
()
{
3891 // The valid option codes are uint8_t values so passing
3892 // uint8_t maximum value incremented by 1 should result
3893 // in failure.
3894 testInvalidOptionParam("257", "code");
3895}
3896
3897// Verify that out of bounds option code is rejected in the configuration.
3898TEST_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"
, 3898), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3898), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3898), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionCodeHighNonUint8_Test
>); void Dhcp4ParserTest_optionCodeHighNonUint8_Test::TestBody
()
{
3899 // Another check for uint8_t overflow but this time
3900 // let's pass even greater option code value.
3901 testInvalidOptionParam("500", "code");
3902}
3903
3904// Verify that zero option code is rejected in the configuration.
3905TEST_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", 3905
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3905), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3905), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionCodeZero_Test
>); void Dhcp4ParserTest_optionCodeZero_Test::TestBody()
{
3906 // Option code 0 is reserved and should not be accepted
3907 // by configuration parser.
3908 testInvalidOptionParam("0", "code");
3909}
3910
3911// Verify that invalid hex literals for option data are detected.
3912TEST_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"
, 3912), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3912), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3912), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataInvalidHexLiterals_Test
>); void Dhcp4ParserTest_optionDataInvalidHexLiterals_Test
::TestBody()
{
3913 testInvalidOptionParam("01020R", "data"); // non hex digit
3914 testInvalidOptionParam("0x01:02", "data"); // 0x prefix with colon separator
3915 testInvalidOptionParam("0x01 02", "data"); // 0x prefix with space separator
3916 testInvalidOptionParam("0X0102", "data"); // 0X upper case X in prefix
3917 testInvalidOptionParam("01.02", "data"); // invalid separator
3918}
3919
3920// Verify the valid forms hex literals in option data are supported.
3921TEST_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"
, 3921), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3921), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3921), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionDataValidHexLiterals_Test
>); void Dhcp4ParserTest_optionDataValidHexLiterals_Test::
TestBody()
{
3922
3923 std::vector<std::string> valid_hexes =
3924 {
3925 "0a0b0C0D", // upper and lower case
3926 "0A:0B:0C:0D", // colon seperator
3927 "0A 0B 0C 0D", // space seperator
3928 "A0B0C0D", // odd number of digits
3929 "0xA0B0C0D" // 0x prefix
3930 };
3931
3932 for (auto const& valid_hex : valid_hexes) {
3933 ConstElementPtr x;
3934 std::string config = createConfigWithOption(valid_hex, "data");
3935 ConstElementPtr json;
3936 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_3936
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3936
; } } else gtest_label_testnothrow_3936 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3936, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3937
3938 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_3938; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3938; } } else gtest_label_testnothrow_3938
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3938, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3939 checkResult(x, 0);
3940
3941 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
3942 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.5"));
3943 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"
, 3943, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
3944 OptionContainerPtr options = subnet->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3945 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"
, 3945, gtest_ar.failure_message()) = ::testing::Message()
;
3946
3947 // Get the search index. Index #1 is to search using option code.
3948 const OptionContainerTypeIndex& idx = options->get<1>();
3949
3950 // Get the options for specified index. Expecting one option to be
3951 // returned but in theory we may have multiple options with the same
3952 // code so we get the range.
3953 std::pair<OptionContainerTypeIndex::const_iterator,
3954 OptionContainerTypeIndex::const_iterator> range =
3955 idx.equal_range(56);
3956
3957 // Expect single option with the code equal to 100.
3958 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"
, 3958, gtest_ar.failure_message()) = ::testing::Message()
;
3959 const uint8_t foo_expected[] = { 0x0A, 0x0B, 0x0C, 0x0D };
3960
3961 // Check if option is valid in terms of code and carried data.
3962 testOption(*range.first, 56, foo_expected, sizeof(foo_expected));
3963
3964 // Clear configuration for the next pass.
3965 resetConfiguration();
3966 }
3967}
3968
3969// Verify that specific option object is returned for standard
3970// option which has dedicated option class derived from Option.
3971TEST_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", 3971
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3971), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3971), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_stdOptionData_Test
>); void Dhcp4ParserTest_stdOptionData_Test::TestBody()
{
3972 ConstElementPtr x;
3973 std::map<std::string, std::string> params;
3974 params["name"] = "nis-servers";
3975 params["space"] = DHCP4_OPTION_SPACE"dhcp4";
3976 // Option code 41 means nis-servers.
3977 params["code"] = "41";
3978 // Specify option values in a CSV (user friendly) format.
3979 params["data"] = "192.0.2.10, 192.0.2.1, 192.0.2.3";
3980 params["csv-format"] = "true";
3981
3982 std::string config = createConfigWithOption(params);
3983 ConstElementPtr json;
3984 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_3984
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_3984
; } } else gtest_label_testnothrow_3984 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3984, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
3985
3986 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_3986; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_3986; } } else gtest_label_testnothrow_3986
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 3986, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
3987 checkResult(x, 0);
3988
3989 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
3990 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.5"));
3991 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"
, 3991, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
3992 OptionContainerPtr options = subnet->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
3993 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"
, 3993, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "options", "false", "true") .c_str()) = ::testing::Message(
)
;
3994 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"
, 3994, gtest_ar.failure_message()) = ::testing::Message()
;
3995
3996 // Get the search index. Index #1 is to search using option code.
3997 const OptionContainerTypeIndex& idx = options->get<1>();
3998
3999 // Get the options for specified index. Expecting one option to be
4000 // returned but in theory we may have multiple options with the same
4001 // code so we get the range.
4002 std::pair<OptionContainerTypeIndex::const_iterator,
4003 OptionContainerTypeIndex::const_iterator> range =
4004 idx.equal_range(DHO_NIS_SERVERS);
4005 // Expect single option with the code equal to NIS_SERVERS option code.
4006 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"
, 4006, gtest_ar.failure_message()) = ::testing::Message()
;
4007 // The actual pointer to the option is held in the option field
4008 // in the structure returned.
4009 OptionPtr option = range.first->option_;
4010 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"
, 4010, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option", "false", "true") .c_str()) = ::testing::Message()
;
4011 // Option object returned for here is expected to be Option4AddrLst
4012 // which is derived from Option. This class is dedicated to
4013 // represent standard option DHO_NIS_SERVERS.
4014 boost::shared_ptr<Option4AddrLst> option_addrs =
4015 boost::dynamic_pointer_cast<Option4AddrLst>(option);
4016 // If cast is unsuccessful than option returned was of a
4017 // different type than Option4AddrLst. This is wrong.
4018 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"
, 4018, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option_addrs", "false", "true") .c_str()) = ::testing::Message
()
;
4019
4020 // Get addresses from the option.
4021 Option4AddrLst::AddressContainer addrs = option_addrs->getAddresses();
4022 // Verify that the addresses have been configured correctly.
4023 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"
, 4023, gtest_ar.failure_message()) = ::testing::Message()
;
4024 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"
, 4024, gtest_ar.failure_message()) = ::testing::Message()
;
4025 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"
, 4025, gtest_ar.failure_message()) = ::testing::Message()
;
4026 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"
, 4026, gtest_ar.failure_message()) = ::testing::Message()
;
4027}
4028
4029/// This test checks if Uint32Parser can really parse the whole range
4030/// and properly err of out of range values. As we can't call Uint32Parser
4031/// directly, we are exploiting the fact that it is used to parse global
4032/// parameter renew-timer and the results are stored in uint32_defaults.
4033/// We get the uint32_defaults using a getUint32Defaults functions which
4034/// is defined only to access the values from this test.
4035TEST_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"
, 4035), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4035), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4035), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_DISABLED_Uint32Parser_Test
>); void Dhcp4ParserTest_DISABLED_Uint32Parser_Test::TestBody
()
{
4036
4037 ConstElementPtr status;
4038
4039 // CASE 1: 0 - minimum value, should work
4040 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_4041; } catch (
...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4041
; } } else gtest_label_testnothrow_4041 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4041, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, parseDHCP4(\"{\\\"renew-timer\\\": 0}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
4041 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_4041; } catch (
...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4041
; } } else gtest_label_testnothrow_4041 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4041, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, parseDHCP4(\"{\\\"renew-timer\\\": 0}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4042
4043 // returned value must be ok (0 is a proper value)
4044 checkResult(status, 0);
4045 /// @todo: check that the renew-timer is really 0
4046
4047 // CASE 2: 4294967295U (UINT_MAX) should work as well
4048 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_4049; } catch (
...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4049
; } } else gtest_label_testnothrow_4049 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4049, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, parseDHCP4(\"{\\\"renew-timer\\\": 4294967295}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
4049 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_4049; } catch (
...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4049
; } } else gtest_label_testnothrow_4049 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4049, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, parseDHCP4(\"{\\\"renew-timer\\\": 4294967295}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4050
4051 // returned value must be ok (0 is a proper value)
4052 checkResult(status, 0);
4053 /// @todo: check that the renew-timer is really 4294967295U
4054
4055 // CASE 3: 4294967296U (UINT_MAX + 1) should not work
4056 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_4057; } catch (
...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4057
; } } else gtest_label_testnothrow_4057 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4057, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, parseJSON(\"{\\\"renew-timer\\\": 4294967296}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
4057 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_4057; } catch (
...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4057
; } } else gtest_label_testnothrow_4057 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4057, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, parseJSON(\"{\\\"renew-timer\\\": 4294967296}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4058
4059 // returned value must be rejected (1 configuration error)
4060 checkResult(status, CONTROL_RESULT_ERROR);
4061 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"
, 4061, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
4062
4063 // CASE 4: -1 (UINT_MIN -1 ) should not work
4064 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_4065; } catch (
...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4065
; } } else gtest_label_testnothrow_4065 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4065, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, parseJSON(\"{\\\"renew-timer\\\": -1}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
4065 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_4065; } catch (
...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4065
; } } else gtest_label_testnothrow_4065 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4065, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, parseJSON(\"{\\\"renew-timer\\\": -1}\"))"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4066
4067 // returned value must be rejected (1 configuration error)
4068 checkResult(status, CONTROL_RESULT_ERROR);
4069 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"
, 4069, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
4070}
4071
4072// The goal of this test is to verify that the domain-search option
4073// can be set using domain names
4074TEST_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"
, 4074), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4074), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4074), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_domainSearchOption_Test
>); void Dhcp4ParserTest_domainSearchOption_Test::TestBody
()
{
4075 // Create configuration.
4076 std::map<std::string, std::string> params;
4077 params["name"] = "domain-search";
4078 params["space"] = DHCP4_OPTION_SPACE"dhcp4";
4079 params["code"] = "119"; // DHO_DOMAIN_SEARCH
4080 params["data"] = "mydomain.example.com, example.com";
4081 params["csv-format"] = "true";
4082
4083 std::string config = createConfigWithOption(params);
4084 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"
, 4085, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "executeConfiguration(config, \"parse configuration with a\" \" domain-search option\")"
, "false", "true") .c_str()) = ::testing::Message()
4085 " 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"
, 4085, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "executeConfiguration(config, \"parse configuration with a\" \" domain-search option\")"
, "false", "true") .c_str()) = ::testing::Message()
;
4086}
4087
4088// The goal of this test is to verify that the slp-directory-agent
4089// option can be set using a trailing array of addresses and
4090// slp-service-scope without option scope list
4091TEST_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", 4091
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4091), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4091), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_slpOptions_Test
>); void Dhcp4ParserTest_slpOptions_Test::TestBody()
{
4092 ConstElementPtr x;
4093 string config = "{ " + genIfaceConfig() + ","
4094 "\"rebind-timer\": 2000,"
4095 "\"renew-timer\": 1000,"
4096 "\"option-data\": [ {"
4097 " \"name\": \"slp-directory-agent\","
4098 " \"data\": \"true, 10.0.0.3, 127.0.0.1\""
4099 " },"
4100 " {"
4101 " \"name\": \"slp-service-scope\","
4102 " \"data\": \"false, \""
4103 " } ],"
4104 "\"subnet4\": [ { "
4105 " \"id\": 1,"
4106 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
4107 " \"subnet\": \"192.0.2.0/24\""
4108 " } ],"
4109 "\"valid-lifetime\": 4000 }";
4110
4111 ConstElementPtr json;
4112 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_4112
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4112
; } } else gtest_label_testnothrow_4112 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4112, ("Expected: " "json = parseDHCP4(config, true)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4113 extractConfig(config);
4114
4115 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_4115; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4115; } } else gtest_label_testnothrow_4115
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4115, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4116 checkResult(x, 0);
4117
4118 // Get options
4119 OptionContainerPtr options = CfgMgr::instance().getStagingCfg()->
4120 getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
4121 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"
, 4121, gtest_ar.failure_message()) = ::testing::Message()
;
4122
4123 // Get the search index. Index #1 is to search using option code.
4124 const OptionContainerTypeIndex& idx = options->get<1>();
4125
4126 // Get the options for specified index. Expecting one option to be
4127 // returned but in theory we may have multiple options with the same
4128 // code so we get the range.
4129 std::pair<OptionContainerTypeIndex::const_iterator,
4130 OptionContainerTypeIndex::const_iterator> range =
4131 idx.equal_range(DHO_DIRECTORY_AGENT);
4132 // Expect a single option with the code equal to 78.
4133 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"
, 4133, gtest_ar.failure_message()) = ::testing::Message()
;
4134 const uint8_t sda_expected[] = {
4135 0x01, 0x0a, 0x00, 0x00, 0x03, 0x7f, 0x00, 0x00, 0x01
4136 };
4137 // Check if option is valid in terms of code and carried data.
4138 testOption(*range.first, 78, sda_expected, sizeof(sda_expected));
4139
4140 range = idx.equal_range(DHO_SERVICE_SCOPE);
4141 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"
, 4141, gtest_ar.failure_message()) = ::testing::Message()
;
4142 // Do another round of testing with second option.
4143 const uint8_t sss_expected[] = {
4144 0x00
4145 };
4146 testOption(*range.first, 79, sss_expected, sizeof(sss_expected));
4147}
4148
4149// The goal of this test is to verify that the standard option can
4150// be configured to encapsulate multiple other options.
4151TEST_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"
, 4151), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4151), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4151), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_stdOptionDataEncapsulate_Test
>); void Dhcp4ParserTest_stdOptionDataEncapsulate_Test::TestBody
()
{
4152
4153 // The configuration is two stage process in this test.
4154 // In the first stage we create definitions of suboptions
4155 // that we will add to the base option.
4156 // Let's create some dummy options: foo and foo2.
4157 string config = "{ " + genIfaceConfig() + ","
4158 "\"valid-lifetime\": 4000,"
4159 "\"rebind-timer\": 2000,"
4160 "\"renew-timer\": 1000,"
4161 "\"option-data\": [ {"
4162 " \"name\": \"foo\","
4163 " \"space\": \"vendor-encapsulated-options-space\","
4164 " \"data\": \"1234\""
4165 " },"
4166 " {"
4167 " \"name\": \"foo2\","
4168 " \"space\": \"vendor-encapsulated-options-space\","
4169 " \"data\": \"192.168.2.1\""
4170 " } ],"
4171 "\"option-def\": [ {"
4172 " \"name\": \"foo\","
4173 " \"code\": 1,"
4174 " \"type\": \"uint32\","
4175 " \"space\": \"vendor-encapsulated-options-space\""
4176 " },"
4177 " {"
4178 " \"name\": \"foo2\","
4179 " \"code\": 2,"
4180 " \"type\": \"ipv4-address\","
4181 " \"space\": \"vendor-encapsulated-options-space\""
4182 " } ]"
4183 "}";
4184
4185 ConstElementPtr json;
4186 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_4186
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4186
; } } else gtest_label_testnothrow_4186 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4186, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4187 extractConfig(config);
4188
4189 ConstElementPtr status;
4190 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_4190; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4190; } } else gtest_label_testnothrow_4190
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4190, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4191 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"
, 4191, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4192 checkResult(status, 0);
4193
4194 CfgMgr::instance().clear();
4195
4196 // Once the definitions have been added we can configure the
4197 // standard option #43. This option comprises an enterprise
4198 // number and sub options. By convention (introduced in
4199 // std_option_defs.h) option named 'vendor-encapsulated-options'
4200 // encapsulates the option space named 'vendor-encapsulated-options-space'.
4201 // We add our dummy options to this option space and thus
4202 // they should be included as sub-options in the
4203 // 'vendor-encapsulated-options' option.
4204 config = "{ " + genIfaceConfig() + ","
4205 "\"valid-lifetime\": 3000,"
4206 "\"rebind-timer\": 2000,"
4207 "\"renew-timer\": 1000,"
4208 "\"option-data\": [ {"
4209 " \"name\": \"vendor-encapsulated-options\","
4210 " \"csv-format\": false"
4211 " },"
4212 " {"
4213 " \"name\": \"foo\","
4214 " \"space\": \"vendor-encapsulated-options-space\","
4215 " \"data\": \"1234\""
4216 " },"
4217 " {"
4218 " \"name\": \"foo2\","
4219 " \"space\": \"vendor-encapsulated-options-space\","
4220 " \"code\": 2,"
4221 " \"data\": \"192.168.2.1\","
4222 " \"csv-format\": true"
4223 " } ],"
4224 "\"option-def\": [ {"
4225 " \"name\": \"foo\","
4226 " \"code\": 1,"
4227 " \"type\": \"uint32\","
4228 " \"space\": \"vendor-encapsulated-options-space\""
4229 " },"
4230 " {"
4231 " \"name\": \"foo2\","
4232 " \"code\": 2,"
4233 " \"type\": \"ipv4-address\","
4234 " \"space\": \"vendor-encapsulated-options-space\""
4235 " } ],"
4236 "\"subnet4\": [ { "
4237 " \"id\": 1,"
4238 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
4239 " \"subnet\": \"192.0.2.0/24\""
4240 " } ]"
4241 "}";
4242
4243 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_4243
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4243
; } } else gtest_label_testnothrow_4243 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4243, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4244 extractConfig(config);
4245
4246 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_4246; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4246; } } else gtest_label_testnothrow_4246
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4246, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4247 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"
, 4247, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4248 checkResult(status, 0);
4249
4250 // We should have one option available.
4251 OptionContainerPtr options =
4252 CfgMgr::instance().getStagingCfg()->getCfgOption()->getAll(DHCP4_OPTION_SPACE"dhcp4");
4253 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"
, 4253, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "options", "false", "true") .c_str()) = ::testing::Message(
)
;
4254 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"
, 4254, gtest_ar.failure_message()) = ::testing::Message()
;
4255
4256 // Get the option.
4257 OptionDescriptor desc = CfgMgr::instance().getStagingCfg()->
4258 getCfgOption()->get(DHCP4_OPTION_SPACE"dhcp4", DHO_VENDOR_ENCAPSULATED_OPTIONS);
4259 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"
, 4259, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc.option_", "false", "true") .c_str()) = ::testing::Message
()
;
4260 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"
, 4260, gtest_ar.failure_message()) = ::testing::Message()
;
4261
4262 // Option with the code 1 should be added as a sub-option.
4263 OptionPtr option_foo = desc.option_->getOption(1);
4264 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"
, 4264, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option_foo", "false", "true") .c_str()) = ::testing::Message
()
;
4265 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"
, 4265, gtest_ar.failure_message()) = ::testing::Message()
;
4266 // This option comprises a single uint32_t value thus it is
4267 // represented by OptionInt<uint32_t> class. Let's get the
4268 // object of this type.
4269 boost::shared_ptr<OptionInt<uint32_t> > option_foo_uint32 =
4270 boost::dynamic_pointer_cast<OptionInt<uint32_t> >(option_foo);
4271 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"
, 4271, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option_foo_uint32", "false", "true") .c_str()) = ::testing
::Message()
;
4272 // Validate the value according to the configuration.
4273 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", 4273
, gtest_ar.failure_message()) = ::testing::Message()
;
4274
4275 // Option with the code 2 should be added as a sub-option.
4276 OptionPtr option_foo2 = desc.option_->getOption(2);
4277 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"
, 4277, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option_foo2", "false", "true") .c_str()) = ::testing::Message
()
;
4278 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"
, 4278, gtest_ar.failure_message()) = ::testing::Message()
;
4279 // This option comprises the IPV4 address. Such option is
4280 // represented by OptionCustom object.
4281 OptionCustomPtr option_foo2_v4 =
4282 boost::dynamic_pointer_cast<OptionCustom>(option_foo2);
4283 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"
, 4283, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "option_foo2_v4", "false", "true") .c_str()) = ::testing::Message
()
;
4284 // Get the IP address carried by this option and validate it.
4285 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", 4285
, gtest_ar.failure_message()) = ::testing::Message()
;
4286
4287 // Option with the code 3 should not be added.
4288 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"
, 4288, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc.option_->getOption(3)", "true", "false") .c_str())
= ::testing::Message()
;
4289}
4290
4291// This test checks if vendor options can be specified in the config file
4292// (in hex format), and later retrieved from configured subnet
4293TEST_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"
, 4293), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4293), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4293), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_vendorOptionsHex_Test
>); void Dhcp4ParserTest_vendorOptionsHex_Test::TestBody()
{
4294
4295 // This configuration string is to configure two options
4296 // sharing the code 1 and belonging to the different vendor spaces.
4297 // (different vendor-id values).
4298 string config = "{ " + genIfaceConfig() + ","
4299 "\"valid-lifetime\": 4000,"
4300 "\"rebind-timer\": 2000,"
4301 "\"renew-timer\": 1000,"
4302 "\"option-data\": [ {"
4303 " \"name\": \"option-one\","
4304 " \"space\": \"vendor-4491\"," // VENDOR_ID_CABLE_LABS = 4491
4305 " \"code\": 100," // just a random code
4306 " \"data\": \"ABCDEF0105\","
4307 " \"csv-format\": false"
4308 " },"
4309 " {"
4310 " \"name\": \"option-two\","
4311 " \"space\": \"vendor-1234\","
4312 " \"code\": 100,"
4313 " \"data\": \"1234\","
4314 " \"csv-format\": false"
4315 " } ],"
4316 "\"subnet4\": [ { "
4317 " \"id\": 1,"
4318 " \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\" } ],"
4319 " \"subnet\": \"192.0.2.0/24\""
4320 " } ]"
4321 "}";
4322
4323 ConstElementPtr json;
4324 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_4324
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4324
; } } else gtest_label_testnothrow_4324 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4324, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4325 extractConfig(config);
4326
4327 ConstElementPtr status;
4328 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_4328; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4328; } } else gtest_label_testnothrow_4328
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4328, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4329 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"
, 4329, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4330 checkResult(status, 0);
4331
4332 // Options should be now available
4333 // Try to get the option from the vendor space 4491
4334 OptionDescriptor desc1 = CfgMgr::instance().getStagingCfg()->
4335 getCfgOption()->get(VENDOR_ID_CABLE_LABS4491U, 100);
4336 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"
, 4336, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc1.option_", "false", "true") .c_str()) = ::testing::Message
()
;
4337 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"
, 4337, gtest_ar.failure_message()) = ::testing::Message()
;
4338 // Try to get the option from the vendor space 1234
4339 OptionDescriptor desc2 =
4340 CfgMgr::instance().getStagingCfg()->getCfgOption()->get(1234, 100);
4341 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"
, 4341, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc2.option_", "false", "true") .c_str()) = ::testing::Message
()
;
4342 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"
, 4342, gtest_ar.failure_message()) = ::testing::Message()
;
4343
4344 // Try to get the non-existing option from the non-existing
4345 // option space and expect that option is not returned.
4346 OptionDescriptor desc3 =
4347 CfgMgr::instance().getStagingCfg()->getCfgOption()->get(5678, 100);
4348 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"
, 4348, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc3.option_", "true", "false") .c_str()) = ::testing::Message
()
;
4349}
4350
4351// This test checks if vendor options can be specified in the config file,
4352// (in csv format), and later retrieved from configured subnet
4353TEST_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"
, 4353), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4353), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4353), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_vendorOptionsCsv_Test
>); void Dhcp4ParserTest_vendorOptionsCsv_Test::TestBody()
{
4354
4355 // This configuration string is to configure two options
4356 // sharing the code 1 and belonging to the different vendor spaces.
4357 // (different vendor-id values).
4358 string config = "{ " + genIfaceConfig() + ","
4359 "\"valid-lifetime\": 4000,"
4360 "\"rebind-timer\": 2000,"
4361 "\"renew-timer\": 1000,"
4362 "\"option-data\": [ {"
4363 " \"name\": \"foo\","
4364 " \"space\": \"vendor-4491\","
4365 " \"code\": 100,"
4366 " \"data\": \"this is a string vendor-opt\""
4367 " } ],"
4368 "\"option-def\": [ {"
4369 " \"name\": \"foo\","
4370 " \"code\": 100,"
4371 " \"type\": \"string\","
4372 " \"space\": \"vendor-4491\""
4373 " } ],"
4374 "\"subnet4\": [ { "
4375 " \"id\": 1,"
4376 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
4377 " \"subnet\": \"192.0.2.0/24\" "
4378 " } ]"
4379 "}";
4380
4381 ConstElementPtr status;
4382
4383 ConstElementPtr json;
4384 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_4384
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4384
; } } else gtest_label_testnothrow_4384 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4384, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4385 extractConfig(config);
4386
4387 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_4387; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4387; } } else gtest_label_testnothrow_4387
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4387, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4388 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"
, 4388, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4389 checkResult(status, 0);
4390
4391 // Options should be now available.
4392 // Try to get the option from the vendor space 4491
4393 OptionDescriptor desc1 = CfgMgr::instance().getStagingCfg()->
4394 getCfgOption()->get(VENDOR_ID_CABLE_LABS4491U, 100);
4395 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"
, 4395, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc1.option_", "false", "true") .c_str()) = ::testing::Message
()
;
4396 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"
, 4396, gtest_ar.failure_message()) = ::testing::Message()
;
4397
4398 // Try to get the non-existing option from the non-existing
4399 // option space and expect that option is not returned.
4400 OptionDescriptor desc2 =
4401 CfgMgr::instance().getStagingCfg()->getCfgOption()->get(5678, 100);
4402 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"
, 4402, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc2.option_", "true", "false") .c_str()) = ::testing::Message
()
;
4403}
4404
4405// Tests of the hooks libraries configuration. All tests have the pre-
4406// condition (checked in the test fixture's SetUp() method) that no hooks
4407// libraries are loaded at the start of the tests.
4408
4409// Helper function to return a configuration containing an arbitrary number
4410// of hooks libraries.
4411std::string
4412buildHooksLibrariesConfig(const std::vector<std::string>& libraries = {},
4413 bool multi_threading = true) {
4414 const string lbrace("{");
4415 const string rbrace("}");
4416 const string liblabel("\"library\": ");
4417 const string quote("\"");
4418
4419 // Create the first part of the configuration string.
4420 string config =
4421 "{ \"interfaces-config\": { \"interfaces\": [] },"
4422 "\"hooks-libraries\": [";
4423
4424 // Append the libraries (separated by commas if needed)
4425 for (unsigned int i = 0; i < libraries.size(); ++i) {
4426 if (i > 0) {
4427 config += string(", ");
4428 }
4429 config += (lbrace + liblabel + quote + libraries[i] + quote + rbrace);
4430 }
4431
4432 // Append the remainder of the configuration.
4433 config += string(
4434 "],"
4435 "\"valid-lifetime\": 4000,"
4436 "\"rebind-timer\": 2000,"
4437 "\"renew-timer\": 1000,"
4438 "\"option-data\": [ {"
4439 " \"name\": \"dhcp-message\","
4440 " \"data\": \"ABCDEF0105\","
4441 " \"csv-format\": false"
4442 " },"
4443 " {"
4444 " \"name\": \"foo\","
4445 " \"space\": \"isc\","
4446 " \"data\": \"1234\""
4447 " } ],"
4448 "\"option-def\": [ {"
4449 " \"name\": \"foo\","
4450 " \"code\": 56,"
4451 " \"type\": \"uint32\","
4452 " \"space\": \"isc\""
4453 " } ],"
4454 "\"subnet4\": [ { "
4455 " \"id\": 1,"
4456 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
4457 " \"subnet\": \"192.0.2.0/24\""
4458 " } ]");
4459
4460 config += R"(,
4461 "multi-threading": {
4462 "enable-multi-threading": )" +
4463 string(multi_threading ? "true" : "false") + R"(
4464 })";
4465
4466 config += string("}");
4467
4468 return (config);
4469}
4470
4471// The goal of this test is to verify the configuration of hooks libraries if
4472// none are specified.
4473TEST_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"
, 4473), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4473), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4473), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_NoHooksLibraries_Test
>); void Dhcp4ParserTest_NoHooksLibraries_Test::TestBody()
{
4474 // Parse a configuration containing no names.
4475 string config = buildHooksLibrariesConfig();
4476 if (!executeConfiguration(config,
4477 "set configuration with no hooks libraries")) {
4478 FAIL()return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4478, "Failed") = ::testing::Message()
<< "Unable to execute configuration";
4479
4480 } else {
4481 // No libraries should be loaded at the end of the test.
4482 std::vector<std::string> libraries = HooksManager::getLibraryNames();
4483 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"
, 4483, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "libraries.empty()", "false", "true") .c_str()) = ::testing
::Message()
;
4484 }
4485}
4486
4487// Verify parsing fails with one library that will fail validation.
4488TEST_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", 4488
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4488), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4488), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_InvalidLibrary_Test
>); void Dhcp4ParserTest_InvalidLibrary_Test::TestBody()
{
4489 // Parse a configuration containing a failing library.
4490 string config = buildHooksLibrariesConfig({NOT_PRESENT_LIBRARY});
4491
4492 ConstElementPtr json;
4493 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_4493
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4493
; } } else gtest_label_testnothrow_4493 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4493, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4494
4495 ConstElementPtr status;
4496 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_4496; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4496; } } else gtest_label_testnothrow_4496
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4496, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4497
4498 // The status object must not be NULL
4499 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"
, 4499, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4500
4501 // Returned value should not be 0
4502 comment_ = parseAnswer(rcode_, status);
4503 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"
, 4503, gtest_ar.failure_message()) = ::testing::Message()
;
4504}
4505
4506// Verify the configuration of hooks libraries with two being specified.
4507TEST_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"
, 4507), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4507), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4507), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_LibrariesSpecified_Test
>); void Dhcp4ParserTest_LibrariesSpecified_Test::TestBody
()
{
4508 setHooksTestPath();
4509
4510 // Marker files should not be present.
4511 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"
, 4511, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(LOAD_MARKER_FILE)", "true", "false")
.c_str()) = ::testing::Message()
;
4512 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"
, 4512, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(UNLOAD_MARKER_FILE)", "true", "false"
) .c_str()) = ::testing::Message()
;
4513
4514 // Set up the configuration with two libraries and load them.
4515 // Disable multi-threading since one of the libraries is single-threaded.
4516 string config = buildHooksLibrariesConfig({CALLOUT_LIBRARY_1, CALLOUT_LIBRARY_2},
4517 /* multi_threading = */ false);
4518 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", 4519
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "executeConfiguration(config, \"load two valid libraries\")"
, "false", "true") .c_str()) = ::testing::Message()
4519 "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", 4519
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "executeConfiguration(config, \"load two valid libraries\")"
, "false", "true") .c_str()) = ::testing::Message()
;
4520
4521 // Expect two libraries to be loaded in the correct order (load marker file
4522 // is present, no unload marker file).
4523 std::vector<std::string> libraries = HooksManager::getLibraryNames();
4524 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"
, 4524, gtest_ar.failure_message()) = ::testing::Message()
;
4525 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"
, 4525, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFile(LOAD_MARKER_FILE, \"12\")", "false", "true"
) .c_str()) = ::testing::Message()
;
4526 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"
, 4526, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(UNLOAD_MARKER_FILE)", "true", "false"
) .c_str()) = ::testing::Message()
;
4527
4528 // Commit the changes so as we get the fresh configuration for the
4529 // second part of this test.
4530 CfgMgr::instance().commit();
4531
4532 // Unload the libraries. The load file should not have changed, but
4533 // the unload one should indicate the unload() functions have been run.
4534 config = buildHooksLibrariesConfig();
4535 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"
, 4535, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "executeConfiguration(config, \"unloading libraries\")", "false"
, "true") .c_str()) = ::testing::Message()
;
4536 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"
, 4536, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFile(LOAD_MARKER_FILE, \"12\")", "false", "true"
) .c_str()) = ::testing::Message()
;
4537 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"
, 4537, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFile(UNLOAD_MARKER_FILE, \"21\")", "false", "true"
) .c_str()) = ::testing::Message()
;
4538
4539 // Expect the hooks system to say that none are loaded.
4540 libraries = HooksManager::getLibraryNames();
4541 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"
, 4541, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "libraries.empty()", "false", "true") .c_str()) = ::testing
::Message()
;
4542}
4543
4544// Verify the configuration of hooks libraries which are not compatible with
4545// multi threading is rejected.
4546TEST_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"
, 4546), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4546), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4546), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_IncompatibleLibrary2Specified_Test
>); void Dhcp4ParserTest_IncompatibleLibrary2Specified_Test
::TestBody()
{
4547 // Marker files should not be present.
4548 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"
, 4548, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(LOAD_MARKER_FILE)", "true", "false")
.c_str()) = ::testing::Message()
;
4549 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"
, 4549, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(UNLOAD_MARKER_FILE)", "true", "false"
) .c_str()) = ::testing::Message()
;
4550
4551 std::vector<std::string> libraries;
4552 libraries.push_back(string(CALLOUT_LIBRARY_2));
4553
4554 // Set up the configuration with two libraries and load them.
4555 string config = buildHooksLibrariesConfig(libraries, true);
4556 ConstElementPtr json;
4557 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_4557
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4557
; } } else gtest_label_testnothrow_4557 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4557, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4558 ConstElementPtr status;
4559 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_4559; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4559; } } else gtest_label_testnothrow_4559
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4559, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4560
4561 // The status object must not be NULL
4562 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"
, 4562, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4563
4564 // Returned value should not be 0
4565 comment_ = parseAnswer(rcode_, status);
4566 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"
, 4566, gtest_ar.failure_message()) = ::testing::Message()
;
4567
4568 // Expect the library to be rejected by the server (no load marker file, no
4569 // unload marker file).
4570 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"
, 4570, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(LOAD_MARKER_FILE)", "true", "false")
.c_str()) = ::testing::Message()
;
4571 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"
, 4571, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(UNLOAD_MARKER_FILE)", "true", "false"
) .c_str()) = ::testing::Message()
;
4572
4573 // Expect the hooks system to say that none are loaded.
4574 libraries = HooksManager::getLibraryNames();
4575 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"
, 4575, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "libraries.empty()", "false", "true") .c_str()) = ::testing
::Message()
;
4576}
4577
4578// Verify the configuration of hooks libraries which are not compatible with
4579// multi threading is rejected.
4580TEST_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"
, 4580), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4580), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4580), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_IncompatibleLibrary3Specified_Test
>); void Dhcp4ParserTest_IncompatibleLibrary3Specified_Test
::TestBody()
{
4581 // Marker files should not be present.
4582 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"
, 4582, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(LOAD_MARKER_FILE)", "true", "false")
.c_str()) = ::testing::Message()
;
4583 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"
, 4583, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(UNLOAD_MARKER_FILE)", "true", "false"
) .c_str()) = ::testing::Message()
;
4584
4585 std::vector<std::string> libraries;
4586 libraries.push_back(string(CALLOUT_LIBRARY_3));
4587
4588 // Set up the configuration with two libraries and load them.
4589 string config = buildHooksLibrariesConfig(libraries, true);
4590 ConstElementPtr json;
4591 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_4591
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4591
; } } else gtest_label_testnothrow_4591 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4591, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4592 ConstElementPtr status;
4593 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_4593; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4593; } } else gtest_label_testnothrow_4593
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4593, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4594
4595 // The status object must not be NULL
4596 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"
, 4596, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4597
4598 // Returned value should not be 0
4599 comment_ = parseAnswer(rcode_, status);
4600 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"
, 4600, gtest_ar.failure_message()) = ::testing::Message()
;
4601
4602 // Expect the library to be rejected by the server (no load marker file, no
4603 // unload marker file).
4604 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"
, 4604, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(LOAD_MARKER_FILE)", "true", "false")
.c_str()) = ::testing::Message()
;
4605 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"
, 4605, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "checkMarkerFileExists(UNLOAD_MARKER_FILE)", "true", "false"
) .c_str()) = ::testing::Message()
;
4606
4607 // Expect the hooks system to say that none are loaded.
4608 libraries = HooksManager::getLibraryNames();
4609 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"
, 4609, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "libraries.empty()", "false", "true") .c_str()) = ::testing
::Message()
;
4610}
4611
4612// This test verifies that it is possible to select subset of interfaces
4613// on which server should listen.
4614TEST_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"
, 4614), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4614), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4614), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_selectedInterfaces_Test
>); void Dhcp4ParserTest_selectedInterfaces_Test::TestBody
()
{
4615 IfaceMgrTestConfig test_config(true);
4616
4617 // Make sure the config manager is clean and there is no hanging
4618 // interface configuration.
4619 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"
, 4619, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth0\", 2)", "true", "false") .c_str
()) = ::testing::Message()
;
4620 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"
, 4620, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth1\", 2)", "true", "false") .c_str
()) = ::testing::Message()
;
4621
4622 string config = "{ \"interfaces-config\": {"
4623 " \"interfaces\": [ \"eth0\", \"eth1\" ]"
4624 "},"
4625 "\"rebind-timer\": 2000, "
4626 "\"renew-timer\": 1000, "
4627 "\"valid-lifetime\": 4000 }";
4628
4629 ConstElementPtr json;
4630 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_4630
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4630
; } } else gtest_label_testnothrow_4630 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4630, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4631 extractConfig(config);
4632
4633 ConstElementPtr status;
4634 // Apply configuration.
4635 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_4635; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4635; } } else gtest_label_testnothrow_4635
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4635, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4636 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"
, 4636, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4637 // returned value must be 0 (configuration accepted)
4638 checkResult(status, 0);
4639
4640 CfgMgr::instance().getStagingCfg()->getCfgIface()->openSockets(AF_INET2, 10000);
4641
4642 // eth0 and eth1 were explicitly selected. eth2 was not.
4643 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"
, 4643, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth0\", 2)", "false", "true") .c_str
()) = ::testing::Message()
;
4644 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"
, 4644, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth1\", 2)", "false", "true") .c_str
()) = ::testing::Message()
;
4645}
4646
4647// This test verifies that it is possible to configure the server in such a way
4648// that it listens on all interfaces.
4649TEST_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", 4649
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4649), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4649), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_allInterfaces_Test
>); void Dhcp4ParserTest_allInterfaces_Test::TestBody()
{
4650 IfaceMgrTestConfig test_config(true);
4651
4652 // Make sure there is no old configuration.
4653 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"
, 4653, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth0\", 2)", "true", "false") .c_str
()) = ::testing::Message()
;
4654 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"
, 4654, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth1\", 2)", "true", "false") .c_str
()) = ::testing::Message()
;
4655
4656 // This configuration specifies two interfaces on which server should listen
4657 // but it also includes asterisk. The asterisk switches server into the
4658 // mode when it listens on all interfaces regardless of what interface names
4659 // were specified in the "interfaces" parameter.
4660 string config = "{ \"interfaces-config\": {"
4661 " \"interfaces\": [ \"eth0\", \"*\", \"eth1\" ]"
4662 "},"
4663 "\"rebind-timer\": 2000, "
4664 "\"renew-timer\": 1000, "
4665 "\"valid-lifetime\": 4000 }";
4666
4667 ConstElementPtr json;
4668 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_4668
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4668
; } } else gtest_label_testnothrow_4668 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4668, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4669 extractConfig(config);
4670
4671 ConstElementPtr status;
4672
4673 // Apply configuration.
4674 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_4674; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4674; } } else gtest_label_testnothrow_4674
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4674, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4675 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"
, 4675, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4676 checkResult(status, 0);
4677
4678 CfgMgr::instance().getStagingCfg()->getCfgIface()->openSockets(AF_INET2, 10000);
4679
4680 // All interfaces should be now active.
4681 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"
, 4681, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth0\", 2)", "false", "true") .c_str
()) = ::testing::Message()
;
4682 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"
, 4682, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth1\", 2)", "false", "true") .c_str
()) = ::testing::Message()
;
4683}
4684
4685// This test verifies that it is possible to select subset of interfaces
4686// and addresses.
4687TEST_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"
, 4687), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4687), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4687), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_selectedInterfacesAndAddresses_Test
>); void Dhcp4ParserTest_selectedInterfacesAndAddresses_Test
::TestBody()
{
4688 IfaceMgrTestConfig test_config(true);
4689
4690 ConstElementPtr x;
4691 string config = "{ \"interfaces-config\": {"
4692 " \"interfaces\": [ \"eth0/10.0.0.1\", \"eth1/192.0.2.3\" ]"
4693 "},"
4694 "\"rebind-timer\": 2000, "
4695 "\"renew-timer\": 1000, "
4696 "\"valid-lifetime\": 4000 }";
4697
4698 ConstElementPtr json;
4699 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_4699
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4699
; } } else gtest_label_testnothrow_4699 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4699, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4700
4701 ConstElementPtr status;
4702
4703 // Make sure the config manager is clean and there is no hanging
4704 // interface configuration.
4705 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"
, 4705, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth0\", \"10.0.0.1\")", "true", "false"
) .c_str()) = ::testing::Message()
;
4706 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"
, 4706, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth1\", \"192.0.2.3\")", "true", "false"
) .c_str()) = ::testing::Message()
;
4707 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"
, 4707, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth1\", \"192.0.2.5\")", "true", "false"
) .c_str()) = ::testing::Message()
;
4708
4709 // Apply configuration.
4710 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_4710; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4710; } } else gtest_label_testnothrow_4710
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4710, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4711 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"
, 4711, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
4712 checkResult(status, 0);
4713
4714 CfgMgr::instance().getStagingCfg()->getCfgIface()->openSockets(AF_INET2, 10000);
4715
4716 // An address on eth0 was selected
4717 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"
, 4717, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth0\", \"10.0.0.1\")", "false", "true"
) .c_str()) = ::testing::Message()
;
4718 // The 192.0.2.3 address on eth1 was selected.
4719 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"
, 4719, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth1\", \"192.0.2.3\")", "false",
"true") .c_str()) = ::testing::Message()
;
4720 // The 192.0.2.5 was not selected, thus the socket should not
4721 // be bound to this address.
4722 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"
, 4722, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "test_config.socketOpen(\"eth1\", \"192.0.2.5\")", "true", "false"
) .c_str()) = ::testing::Message()
;
4723}
4724
4725// This test checks if it is possible to specify relay information
4726TEST_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", 4726
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4726), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4726), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_subnetRelayInfo_Test
>); void Dhcp4ParserTest_subnetRelayInfo_Test::TestBody()
{
4727
4728 // A config with relay information.
4729 string config = "{ " + genIfaceConfig() + ","
4730 "\"rebind-timer\": 2000, "
4731 "\"renew-timer\": 1000, "
4732 "\"subnet4\": [ { "
4733 " \"id\": 1,"
4734 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
4735 " \"renew-timer\": 1, "
4736 " \"rebind-timer\": 2, "
4737 " \"valid-lifetime\": 4,"
4738 " \"relay\": { "
4739 " \"ip-addresses\": [ \"192.0.2.123\" ]"
4740 " },"
4741 " \"subnet\": \"192.0.2.0/24\" } ],"
4742 "\"valid-lifetime\": 4000 }";
4743
4744 ConstElementPtr json;
4745 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_4745
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4745
; } } else gtest_label_testnothrow_4745 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4745, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4746 extractConfig(config);
4747
4748 ConstElementPtr status;
4749 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_4749; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4749; } } else gtest_label_testnothrow_4749
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4749, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4750
4751 // returned value should be 0 (configuration success)
4752 checkResult(status, 0);
4753
4754 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
4755 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
4756 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"
, 4756, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
4757
4758 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"
, 4758, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->hasRelays()", "false", "true") .c_str()) = ::testing
::Message()
;
4759 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"
, 4759, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->hasRelayAddress(IOAddress(\"192.0.2.123\"))", "false"
, "true") .c_str()) = ::testing::Message()
;
4760}
4761
4762// This test checks if it is possible to specify a list of relays
4763TEST_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"
, 4763), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4763), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4763), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_subnetRelayInfoList_Test
>); void Dhcp4ParserTest_subnetRelayInfoList_Test::TestBody
()
{
4764 // A config with relay information.
4765 string config = "{ " + genIfaceConfig() + ","
4766 "\"rebind-timer\": 2000, "
4767 "\"renew-timer\": 1000, "
4768 "\"subnet4\": [ { "
4769 " \"id\": 1,"
4770 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
4771 " \"renew-timer\": 1, "
4772 " \"rebind-timer\": 2, "
4773 " \"valid-lifetime\": 4,"
4774 " \"relay\": { "
4775 " \"ip-addresses\": [ \"192.0.3.123\", \"192.0.3.124\" ]"
4776 " },"
4777 " \"subnet\": \"192.0.2.0/24\" } ],"
4778 "\"valid-lifetime\": 4000 }";
4779
4780 ConstElementPtr json;
4781 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_4781
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4781
; } } else gtest_label_testnothrow_4781 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4781, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4782 extractConfig(config);
4783
4784 ConstElementPtr status;
4785 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_4785; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4785; } } else gtest_label_testnothrow_4785
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4785, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4786
4787 // returned value should be 0 (configuration success)
4788 checkResult(status, 0);
4789
4790 SubnetSelector selector;
4791 selector.giaddr_ = IOAddress("192.0.2.200");
4792
4793 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
4794 getCfgSubnets4()->selectSubnet(selector);
4795 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"
, 4795, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
4796
4797 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"
, 4797, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->hasRelays()", "false", "true") .c_str()) = ::testing
::Message()
;
4798 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"
, 4798, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->hasRelayAddress(IOAddress(\"192.0.3.123\"))", "false"
, "true") .c_str()) = ::testing::Message()
;
4799 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"
, 4799, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->hasRelayAddress(IOAddress(\"192.0.3.124\"))", "false"
, "true") .c_str()) = ::testing::Message()
;
4800}
4801
4802// Goal of this test is to verify that multiple subnets can be configured
4803// with defined client classes.
4804TEST_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", 4804
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4804), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4804), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_classifySubnets_Test
>); void Dhcp4ParserTest_classifySubnets_Test::TestBody()
{
4805 ConstElementPtr x;
4806 string config = "{ " + genIfaceConfig() + ","
4807 "\"rebind-timer\": 2000, "
4808 "\"renew-timer\": 1000, "
4809 "\"subnet4\": [ { "
4810 " \"id\": 1,"
4811 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
4812 " \"subnet\": \"192.0.2.0/24\", "
4813 " \"client-class\": \"alpha\" "
4814 " },"
4815 " {"
4816 " \"id\": 2,"
4817 " \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
4818 " \"subnet\": \"192.0.3.0/24\", "
4819 " \"client-class\": \"beta\" "
4820 " },"
4821 " {"
4822 " \"id\": 3,"
4823 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
4824 " \"subnet\": \"192.0.4.0/24\", "
4825 " \"client-classes\": [ \"gamma\" ] "
4826 " },"
4827 " {"
4828 " \"id\": 4,"
4829 " \"pools\": [ { \"pool\": \"192.0.5.101 - 192.0.5.150\" } ],"
4830 " \"subnet\": \"192.0.5.0/24\" "
4831 " } ],"
4832 "\"valid-lifetime\": 4000 }";
4833
4834 ConstElementPtr json;
4835 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_4835
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4835
; } } else gtest_label_testnothrow_4835 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4835, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4836 extractConfig(config);
4837
4838 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_4838; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4838; } } else gtest_label_testnothrow_4838
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4838, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4839 checkResult(x, 0);
4840
4841 const Subnet4Collection* subnets =
4842 CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
4843 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"
, 4843, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
4844 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"
, 4844, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 4 subnets
4845
4846 // Let's check if client belonging to alpha class is supported in subnet[0]
4847 // and not supported in any other subnet (except subnet[3], which allows
4848 // everyone).
4849 ClientClasses classes;
4850 classes.insert("alpha");
4851 auto subnet0 = subnets->begin();
4852 auto subnet1 = std::next(subnet0);
4853 auto subnet2 = std::next(subnet1);
4854 auto subnet3 = std::next(subnet2);
4855 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"
, 4855, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet0)->clientSupported(classes)", "false", "true")
.c_str()) = ::testing::Message()
;
4856 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"
, 4856, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet1)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4857 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"
, 4857, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet2)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4858 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"
, 4858, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet3)->clientSupported(classes)", "false", "true")
.c_str()) = ::testing::Message()
;
4859
4860 // Let's check if client belonging to beta class is supported in subnet[1]
4861 // and not supported in any other subnet (except subnet[3], which allows
4862 // everyone).
4863 classes.clear();
4864 classes.insert("beta");
4865 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"
, 4865, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet0)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4866 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"
, 4866, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet1)->clientSupported(classes)", "false", "true")
.c_str()) = ::testing::Message()
;
4867 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"
, 4867, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet2)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4868 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"
, 4868, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet3)->clientSupported(classes)", "false", "true")
.c_str()) = ::testing::Message()
;
4869
4870 // Let's check if client belonging to gamma class is supported in subnet[2]
4871 // and not supported in any other subnet (except subnet[3], which allows
4872 // everyone).
4873 classes.clear();
4874 classes.insert("gamma");
4875 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"
, 4875, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet0)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4876 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"
, 4876, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet1)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4877 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"
, 4877, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet2)->clientSupported(classes)", "false", "true")
.c_str()) = ::testing::Message()
;
4878 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"
, 4878, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet3)->clientSupported(classes)", "false", "true")
.c_str()) = ::testing::Message()
;
4879
4880 // Let's check if client belonging to some other class (not mentioned in
4881 // the config) is supported only in subnet[3], which allows everyone.
4882 classes.clear();
4883 classes.insert("delta");
4884 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"
, 4884, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet0)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4885 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"
, 4885, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet1)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4886 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"
, 4886, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet2)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4887 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"
, 4887, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet3)->clientSupported(classes)", "false", "true")
.c_str()) = ::testing::Message()
;
4888
4889 // Finally, let's check class-less client. He should be allowed only in
4890 // the last subnet, which does not have any class restrictions.
4891 classes.clear();
4892 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"
, 4892, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet0)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4893 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"
, 4893, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet1)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4894 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"
, 4894, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet2)->clientSupported(classes)", "true", "false")
.c_str()) = ::testing::Message()
;
4895 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"
, 4895, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "(*subnet3)->clientSupported(classes)", "false", "true")
.c_str()) = ::testing::Message()
;
4896}
4897
4898// Goal of this test is to verify that multiple pools can be configured
4899// with defined client classes.
4900TEST_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", 4900
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4900), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4900), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_classifyPools_Test
>); void Dhcp4ParserTest_classifyPools_Test::TestBody()
{
4901 ConstElementPtr x;
4902 string config = "{ " + genIfaceConfig() + ","
4903 "\"rebind-timer\": 2000, "
4904 "\"renew-timer\": 1000, "
4905 "\"subnet4\": [ { "
4906 " \"id\": 1,"
4907 " \"pools\": [ { "
4908 " \"pool\": \"192.0.2.1 - 192.0.2.100\", "
4909 " \"client-classes\": [ \"alpha\" ]"
4910 " },"
4911 " {"
4912 " \"pool\": \"192.0.3.101 - 192.0.3.150\", "
4913 " \"client-classes\": [ \"beta\" ] "
4914 " },"
4915 " {"
4916 " \"pool\": \"192.0.4.101 - 192.0.4.150\", "
4917 " \"client-classes\": [ \"gamma\" ] "
4918 " },"
4919 " {"
4920 " \"pool\": \"192.0.5.101 - 192.0.5.150\" "
4921 " } ],"
4922 " \"subnet\": \"192.0.0.0/16\" "
4923 " } ],"
4924 "\"valid-lifetime\": 4000 }";
4925
4926 ConstElementPtr json;
4927 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_4927
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_4927
; } } else gtest_label_testnothrow_4927 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4927, ("Expected: " "json = parseDHCP4(config, true)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
4928 extractConfig(config);
4929
4930 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_4930; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_4930; } } else gtest_label_testnothrow_4930
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4930, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
4931 checkResult(x, 0);
4932
4933 const Subnet4Collection* subnets =
4934 CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
4935 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"
, 4935, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
4936 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"
, 4936, gtest_ar.failure_message()) = ::testing::Message()
;
4937 const PoolCollection& pools = (*subnets->begin())->getPools(Lease::TYPE_V4);
4938 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"
, 4938, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 4 pools
4939
4940 // Let's check if client belonging to alpha class is supported in pool[0]
4941 // and not supported in any other pool (except pool[3], which allows
4942 // everyone).
4943 ClientClasses classes;
4944 classes.insert("alpha");
4945 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"
, 4945, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(0)->clientSupported(classes)", "false", "true"
) .c_str()) = ::testing::Message()
;
4946 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"
, 4946, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(1)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4947 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"
, 4947, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(2)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4948 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"
, 4948, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(3)->clientSupported(classes)", "false", "true"
) .c_str()) = ::testing::Message()
;
4949
4950 // Let's check if client belonging to beta class is supported in pool[1]
4951 // and not supported in any other pool (except pool[3], which allows
4952 // everyone).
4953 classes.clear();
4954 classes.insert("beta");
4955 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"
, 4955, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(0)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4956 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"
, 4956, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(1)->clientSupported(classes)", "false", "true"
) .c_str()) = ::testing::Message()
;
4957 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"
, 4957, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(2)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4958 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"
, 4958, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(3)->clientSupported(classes)", "false", "true"
) .c_str()) = ::testing::Message()
;
4959
4960 // Let's check if client belonging to gamma class is supported in pool[2]
4961 // and not supported in any other pool (except pool[3], which allows
4962 // everyone).
4963 classes.clear();
4964 classes.insert("gamma");
4965 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"
, 4965, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(0)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4966 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"
, 4966, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(1)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4967 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"
, 4967, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(2)->clientSupported(classes)", "false", "true"
) .c_str()) = ::testing::Message()
;
4968 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"
, 4968, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(3)->clientSupported(classes)", "false", "true"
) .c_str()) = ::testing::Message()
;
4969
4970 // Let's check if client belonging to some other class (not mentioned in
4971 // the config) is supported only in pool[3], which allows everyone.
4972 classes.clear();
4973 classes.insert("delta");
4974 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"
, 4974, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(0)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4975 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"
, 4975, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(1)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4976 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"
, 4976, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(2)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4977 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"
, 4977, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(3)->clientSupported(classes)", "false", "true"
) .c_str()) = ::testing::Message()
;
4978
4979 // Finally, let's check class-less client. He should be allowed only in
4980 // the last pool, which does not have any class restrictions.
4981 classes.clear();
4982 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"
, 4982, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(0)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4983 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"
, 4983, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(1)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4984 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"
, 4984, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(2)->clientSupported(classes)", "true", "false"
) .c_str()) = ::testing::Message()
;
4985 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"
, 4985, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pools.at(3)->clientSupported(classes)", "false", "true"
) .c_str()) = ::testing::Message()
;
4986}
4987
4988// This test verifies that valid d2CliengConfig works correctly.
4989TEST_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"
, 4989), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4989), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 4989), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_d2ClientConfigValid_Test
>); void Dhcp4ParserTest_d2ClientConfigValid_Test::TestBody
()
{
4990 // Verify that the D2 configuration can be fetched and is set to disabled.
4991 D2ClientConfigPtr d2_client_config = CfgMgr::instance().getD2ClientConfig();
4992 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"
, 4992, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "d2_client_config->getEnableUpdates()", "true", "false")
.c_str()) = ::testing::Message()
;
4993
4994 // Verify that the convenience method agrees.
4995 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"
, 4995, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().ddnsEnabled()", "true", "false") .c_str
()) = ::testing::Message()
;
4996
4997 string config_str = "{ " + genIfaceConfig() + ","
4998 "\"rebind-timer\": 2000, "
4999 "\"renew-timer\": 1000, "
5000 "\"subnet4\": [ { "
5001 " \"id\": 1,"
5002 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5003 " \"subnet\": \"192.0.2.0/24\" } ],"
5004 " \"dhcp-ddns\" : {"
5005 " \"enable-updates\" : true, "
5006 " \"server-ip\" : \"192.168.2.1\", "
5007 " \"server-port\" : 777, "
5008 " \"sender-ip\" : \"192.168.2.2\", "
5009 " \"sender-port\" : 778, "
5010 " \"max-queue-size\" : 2048, "
5011 " \"ncr-protocol\" : \"UDP\", "
5012 " \"ncr-format\" : \"JSON\"}, "
5013 "\"valid-lifetime\": 4000 }";
5014
5015 // Convert the JSON string to configuration elements.
5016 ConstElementPtr config;
5017 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_5017; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5017; } } else gtest_label_testnothrow_5017
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5017, ("Expected: " "config = parseDHCP4(config_str, true)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5018 extractConfig(config_str);
5019
5020 // Pass the configuration in for parsing.
5021 ConstElementPtr status;
5022 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_5022; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5022; } } else gtest_label_testnothrow_5022
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5022, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, config)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5023
5024 // check if returned status is OK
5025 checkResult(status, 0);
5026
5027 // Verify that DHCP-DDNS updating is enabled.
5028 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"
, 5028, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().ddnsEnabled()", "false", "true") .c_str
()) = ::testing::Message()
;
5029
5030 // Verify that the D2 configuration can be retrieved.
5031 d2_client_config = CfgMgr::instance().getD2ClientConfig();
5032 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"
, 5032, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "d2_client_config", "false", "true") .c_str()) = ::testing::
Message()
;
5033
5034 // Verify that the configuration values are correct.
5035 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"
, 5035, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "d2_client_config->getEnableUpdates()", "false", "true")
.c_str()) = ::testing::Message()
;
5036 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", 5036
, gtest_ar.failure_message()) = ::testing::Message()
;
5037 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", 5037
, gtest_ar.failure_message()) = ::testing::Message()
;
5038 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", 5038
, gtest_ar.failure_message()) = ::testing::Message()
;
5039 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", 5039
, gtest_ar.failure_message()) = ::testing::Message()
;
5040 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", 5040
, gtest_ar.failure_message()) = ::testing::Message()
;
5041 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", 5041
, gtest_ar.failure_message()) = ::testing::Message()
;
5042 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"
, 5042, gtest_ar.failure_message()) = ::testing::Message()
;
5043
5044 // ddns-send-updates should be global default
5045 checkGlobal("ddns-send-updates", true);
5046 checkGlobal("ddns-conflict-resolution-mode", "check-with-dhcid");
5047
5048 // The following, deprecated dhcp-ddns parameters,
5049 // should all have global default values.
5050 checkGlobal("ddns-override-no-update", false);
5051 checkGlobal("ddns-override-client-update", false);
5052 checkGlobal("ddns-replace-client-name", "never");
5053 checkGlobal("ddns-generated-prefix", "myhost");
5054 checkGlobal("ddns-qualifying-suffix", "");
5055}
5056
5057// This test checks the ability of the server to handle a configuration
5058// containing an invalid dhcp-ddns (D2ClientConfig) entry.
5059TEST_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"
, 5059), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5059), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5059), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_invalidD2ClientConfig_Test
>); void Dhcp4ParserTest_invalidD2ClientConfig_Test::TestBody
()
{
5060 // Configuration string with an invalid D2 client config,
5061 // "server-ip" is invalid.
5062 string config_str = "{ " + genIfaceConfig() + ","
5063 "\"rebind-timer\": 2000, "
5064 "\"renew-timer\": 1000, "
5065 "\"ddns-override-no-update\" : true, "
5066 "\"ddns-override-client-update\" : true, "
5067 "\"ddns-replace-client-name\" : \"when-present\", "
5068 "\"ddns-generated-prefix\" : \"test.prefix\", "
5069 "\"ddns-qualifying-suffix\" : \"test.suffix.\", "
5070 "\"subnet4\": [ { "
5071 " \"id\": 1,"
5072 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5073 " \"subnet\": \"192.0.2.0/24\" } ],"
5074 " \"dhcp-ddns\" : {"
5075 " \"enable-updates\" : true, "
5076 " \"server-ip\" : \"bogus-value\", "
5077 " \"server-port\" : 5301, "
5078 " \"ncr-protocol\" : \"UDP\", "
5079 " \"ncr-format\" : \"JSON\"},"
5080 "\"valid-lifetime\": 4000 }";
5081
5082 // Convert the JSON string to configuration elements.
5083 ConstElementPtr config;
5084 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_5084
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5084
; } } else gtest_label_testnothrow_5084 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5084, ("Expected: " "config = parseDHCP4(config_str)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5085
5086 // Configuration should not throw, but should fail.
5087 ConstElementPtr status;
5088 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_5088; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5088; } } else gtest_label_testnothrow_5088
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5088, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, config)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5089
5090 // check if returned status is failed.
5091 checkResult(status, CONTROL_RESULT_ERROR);
5092 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"
, 5092, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
5093
5094 // Verify that the D2 configuration can be fetched and is set to disabled.
5095 D2ClientConfigPtr d2_client_config = CfgMgr::instance().getD2ClientConfig();
5096 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"
, 5096, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "d2_client_config->getEnableUpdates()", "true", "false")
.c_str()) = ::testing::Message()
;
5097
5098 // Verify that the convenience method agrees.
5099 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"
, 5099, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().ddnsEnabled()", "true", "false") .c_str
()) = ::testing::Message()
;
5100}
5101// This test verifies that the host reservations can be specified for
5102// respective IPv4 subnets.
5103TEST_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", 5103
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5103), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5103), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_reservations_Test
>); void Dhcp4ParserTest_reservations_Test::TestBody()
{
5104 ConstElementPtr x;
5105 string config = "{ " + genIfaceConfig() + ","
5106 "\"rebind-timer\": 2000, "
5107 "\"renew-timer\": 1000, "
5108 "\"subnet4\": [ "
5109 " { "
5110 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5111 " \"subnet\": \"192.0.2.0/24\", "
5112 " \"id\": 123,"
5113 " \"reservations\": ["
5114 " ]"
5115 " },"
5116 " {"
5117 " \"reservations\": ["
5118 " {"
5119 " \"duid\": \"01:02:03:04:05:06:07:08:09:0A\","
5120 " \"ip-address\": \"192.0.3.112\","
5121 " \"hostname\": \"\","
5122 " \"option-data\": ["
5123 " {"
5124 " \"name\": \"name-servers\","
5125 " \"data\": \"192.0.3.15\""
5126 " },"
5127 " {"
5128 " \"name\": \"default-ip-ttl\","
5129 " \"data\": \"32\""
5130 " }"
5131 " ]"
5132 " },"
5133 " {"
5134 " \"hw-address\": \"01:02:03:04:05:06\","
5135 " \"ip-address\": \"192.0.3.120\","
5136 " \"hostname\": \"\","
5137 " \"option-data\": ["
5138 " {"
5139 " \"name\": \"name-servers\","
5140 " \"data\": \"192.0.3.95\""
5141 " },"
5142 " {"
5143 " \"name\": \"default-ip-ttl\","
5144 " \"data\": \"11\""
5145 " }"
5146 " ]"
5147 " }"
5148 " ],"
5149 " \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
5150 " \"subnet\": \"192.0.3.0/24\", "
5151 " \"id\": 234"
5152 " },"
5153 " {"
5154 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
5155 " \"subnet\": \"192.0.4.0/24\","
5156 " \"id\": 542,"
5157 " \"reservations\": ["
5158 " {"
5159 " \"duid\": \"0A:09:08:07:06:05:04:03:02:01\","
5160 " \"ip-address\": \"192.0.4.101\","
5161 " \"hostname\": \"\","
5162 " \"option-data\": ["
5163 " {"
5164 " \"name\": \"name-servers\","
5165 " \"data\": \"192.0.4.11\""
5166 " },"
5167 " {"
5168 " \"name\": \"default-ip-ttl\","
5169 " \"data\": \"95\""
5170 " }"
5171 " ]"
5172 " },"
5173 " {"
5174 " \"circuit-id\": \"060504030201\","
5175 " \"ip-address\": \"192.0.4.102\","
5176 " \"hostname\": \"\""
5177 " },"
5178 " {"
5179 " \"client-id\": \"05:01:02:03:04:05:06\","
5180 " \"ip-address\": \"192.0.4.103\","
5181 " \"hostname\": \"\""
5182 " }"
5183 " ]"
5184 " } "
5185 "], "
5186 "\"valid-lifetime\": 4000 }";
5187
5188 ConstElementPtr json;
5189 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_5189
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5189
; } } else gtest_label_testnothrow_5189 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5189, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5190 extractConfig(config);
5191
5192 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_5192; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5192; } } else gtest_label_testnothrow_5192
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5192, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5193 checkResult(x, 0);
5194
5195 // Make sure all subnets have been successfully configured. There is no
5196 // need to sanity check the subnet properties because it should have
5197 // been already tested by other tests.
5198 const Subnet4Collection* subnets =
5199 CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
5200 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"
, 5200, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
5201 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"
, 5201, gtest_ar.failure_message()) = ::testing::Message()
;
5202
5203 // Hosts configuration must be available.
5204 CfgHostsPtr hosts_cfg = CfgMgr::instance().getStagingCfg()->getCfgHosts();
5205 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"
, 5205, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg", "false", "true") .c_str()) = ::testing::Message
()
;
5206
5207 // Let's create an object holding hardware address of the host having
5208 // a reservation in the subnet having id of 234. For simplicity the
5209 // address is a collection of numbers from 1 to 6.
5210 std::vector<uint8_t> hwaddr;
5211 for (unsigned int i = 1; i < 7; ++i) {
5212 hwaddr.push_back(static_cast<uint8_t>(i));
5213 }
5214 // Retrieve the reservation and sanity check the address reserved.
5215 ConstHostPtr host = hosts_cfg->get4(234, Host::IDENT_HWADDR,
5216 &hwaddr[0], hwaddr.size());
5217 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", 5217
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
5218 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"
, 5218, gtest_ar.failure_message()) = ::testing::Message()
;
5219 // This reservation should be solely assigned to the subnet 234,
5220 // and not to other two.
5221 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"
, 5222, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())"
, "true", "false") .c_str()) = ::testing::Message()
5222 &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"
, 5222, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
5223 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"
, 5224, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(542, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())"
, "true", "false") .c_str()) = ::testing::Message()
5224 &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"
, 5224, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(542, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
5225 // Check that options are assigned correctly.
5226 Option4AddrLstPtr opt_dns =
5227 retrieveOption<Option4AddrLstPtr>(*host, DHO_NAME_SERVERS);
5228 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"
, 5228, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_dns", "false", "true") .c_str()) = ::testing::Message(
)
;
5229 Option4AddrLst::AddressContainer dns_addrs = opt_dns->getAddresses();
5230 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"
, 5230, gtest_ar.failure_message()) = ::testing::Message()
;
5231 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"
, 5231, gtest_ar.failure_message()) = ::testing::Message()
;
5232 OptionUint8Ptr opt_ttl =
5233 retrieveOption<OptionUint8Ptr>(*host, DHO_DEFAULT_IP_TTL);
5234 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"
, 5234, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_ttl", "false", "true") .c_str()) = ::testing::Message(
)
;
5235 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"
, 5235, gtest_ar.failure_message()) = ::testing::Message()
;
5236
5237 // Do the same test for the DUID based reservation.
5238 std::vector<uint8_t> duid;
5239 for (unsigned int i = 1; i < 0xb; ++i) {
5240 duid.push_back(static_cast<uint8_t>(i));
5241 }
5242 host = hosts_cfg->get4(234, Host::IDENT_DUID, &duid[0], duid.size());
5243 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", 5243
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
5244 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"
, 5244, gtest_ar.failure_message()) = ::testing::Message()
;
5245 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", 5245
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_DUID, &duid[0], duid.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
5246 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", 5246
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(542, Host::IDENT_DUID, &duid[0], duid.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
5247 // Check that options are assigned correctly.
5248 opt_dns = retrieveOption<Option4AddrLstPtr>(*host, DHO_NAME_SERVERS);
5249 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"
, 5249, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_dns", "false", "true") .c_str()) = ::testing::Message(
)
;
5250 dns_addrs = opt_dns->getAddresses();
5251 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"
, 5251, gtest_ar.failure_message()) = ::testing::Message()
;
5252 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"
, 5252, gtest_ar.failure_message()) = ::testing::Message()
;
5253 opt_ttl = retrieveOption<OptionUint8Ptr>(*host, DHO_DEFAULT_IP_TTL);
5254 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"
, 5254, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_ttl", "false", "true") .c_str()) = ::testing::Message(
)
;
5255 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"
, 5255, gtest_ar.failure_message()) = ::testing::Message()
;
5256
5257 // The circuit-id used for one of the reservations in the subnet 542
5258 // consists of numbers from 6 to 1. So, let's just reverse the order
5259 // of the address from the previous test.
5260 std::vector<uint8_t> circuit_id(hwaddr.rbegin(), hwaddr.rend());
5261 host = hosts_cfg->get4(542, Host::IDENT_CIRCUIT_ID, &circuit_id[0],
5262 circuit_id.size());
5263 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", 5263
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
5264 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"
, 5264, gtest_ar.failure_message()) = ::testing::Message()
;
5265
5266 // This reservation must not belong to other subnets.
5267 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"
, 5268, ::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 &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"
, 5268, ::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()
;
5269 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"
, 5270, ::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 &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"
, 5270, ::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()
;
5271
5272 // Repeat the test for the DUID based reservation in this subnet.
5273 std::vector<uint8_t> duid_r(duid.rbegin(), duid.rend());
5274 host = hosts_cfg->get4(542, Host::IDENT_DUID, &duid_r[0], duid_r.size());
5275 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", 5275
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
5276 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"
, 5276, gtest_ar.failure_message()) = ::testing::Message()
;
5277
5278 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"
, 5279, ::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 &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"
, 5279, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_DUID, &duid_r[0], duid_r.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
5280 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"
, 5281, ::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 &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"
, 5281, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(234, Host::IDENT_DUID, &duid_r[0], duid_r.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
5282 // Check that options are assigned correctly.
5283 opt_dns = retrieveOption<Option4AddrLstPtr>(*host, DHO_NAME_SERVERS);
5284 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"
, 5284, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_dns", "false", "true") .c_str()) = ::testing::Message(
)
;
5285 dns_addrs = opt_dns->getAddresses();
5286 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"
, 5286, gtest_ar.failure_message()) = ::testing::Message()
;
5287 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"
, 5287, gtest_ar.failure_message()) = ::testing::Message()
;
5288 opt_ttl = retrieveOption<OptionUint8Ptr>(*host, DHO_DEFAULT_IP_TTL);
5289 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"
, 5289, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_ttl", "false", "true") .c_str()) = ::testing::Message(
)
;
5290 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"
, 5290, gtest_ar.failure_message()) = ::testing::Message()
;
5291
5292 // Check that we can find reservation using client identifier.
5293 ClientIdPtr client_id = ClientId::fromText("05:01:02:03:04:05:06");
5294 host = hosts_cfg->get4(542, Host::IDENT_CLIENT_ID, &client_id->getClientId()[0],
5295 client_id->getClientId().size());
5296 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", 5296
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
5297 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"
, 5297, gtest_ar.failure_message()) = ::testing::Message()
;
5298
5299 // But this reservation should not be returned for other subnet.
5300 host = hosts_cfg->get4(234, Host::IDENT_CLIENT_ID, &client_id->getClientId()[0],
5301 client_id->getClientId().size());
5302 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", 5302
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "true", "false") .c_str()) = ::testing::Message()
;
5303}
5304
5305// This test checks that it is possible to configure option data for a
5306// host using a user defined option format.
5307TEST_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"
, 5307), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5307), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5307), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_reservationWithOptionDefinition_Test
>); void Dhcp4ParserTest_reservationWithOptionDefinition_Test
::TestBody()
{
5308 ConstElementPtr x;
5309 // The following configuration contains host declaration in which
5310 // a non-standard option is used. This option has option definition
5311 // specified in the configuration.
5312 string config = "{ " + genIfaceConfig() + ","
5313 "\"rebind-timer\": 2000, "
5314 "\"renew-timer\": 1000, "
5315 "\"option-def\": [ {"
5316 " \"name\": \"foo\","
5317 " \"code\": 100,"
5318 " \"type\": \"uint32\","
5319 " \"space\": \"isc\""
5320 "} ],"
5321 "\"subnet4\": [ "
5322 " {"
5323 " \"reservations\": ["
5324 " {"
5325 " \"duid\": \"01:02:03:04:05:06:07:08:09:0A\","
5326 " \"ip-address\": \"192.0.3.112\","
5327 " \"option-data\": ["
5328 " {"
5329 " \"name\": \"foo\","
5330 " \"data\": \"123\","
5331 " \"space\": \"isc\""
5332 " }"
5333 " ]"
5334 " }"
5335 " ],"
5336 " \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
5337 " \"subnet\": \"192.0.3.0/24\", "
5338 " \"id\": 234"
5339 " }"
5340 "],"
5341 "\"valid-lifetime\": 4000 }";
5342
5343 ConstElementPtr json;
5344 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_5344
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5344
; } } else gtest_label_testnothrow_5344 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5344, ("Expected: " "json = parseDHCP4(config, true)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5345 extractConfig(config);
5346
5347 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_5347; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5347; } } else gtest_label_testnothrow_5347
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5347, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5348 checkResult(x, 0);
5349
5350 // Hosts configuration must be available.
5351 CfgHostsPtr hosts_cfg = CfgMgr::instance().getStagingCfg()->getCfgHosts();
5352 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"
, 5352, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg", "false", "true") .c_str()) = ::testing::Message
()
;
5353
5354 // Let's create an object holding DUID of the host. For simplicity the
5355 // address is a collection of numbers from 1 to A.
5356 std::vector<uint8_t> duid;
5357 for (unsigned int i = 1; i < 0xB; ++i) {
5358 duid.push_back(static_cast<uint8_t>(i));
5359 }
5360 // Retrieve the reservation and sanity check the address reserved.
5361 ConstHostPtr host = hosts_cfg->get4(234, Host::IDENT_DUID,
5362 &duid[0], duid.size());
5363 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", 5363
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
5364 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"
, 5364, gtest_ar.failure_message()) = ::testing::Message()
;
5365
5366 // Check if the option has been parsed.
5367 OptionUint32Ptr opt_foo = retrieveOption<OptionUint32Ptr>(*host, "isc",
5368 100);
5369 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"
, 5369, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_foo", "false", "true") .c_str()) = ::testing::Message(
)
;
5370 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"
, 5370, gtest_ar.failure_message()) = ::testing::Message()
;
5371 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"
, 5371, gtest_ar.failure_message()) = ::testing::Message()
;
5372}
5373
5374// This test verifies that the bogus host reservation would trigger a
5375// server configuration error.
5376TEST_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"
, 5376), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5376), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5376), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_reservationBogus_Test
>); void Dhcp4ParserTest_reservationBogus_Test::TestBody()
{
5377 // Case 1: misspelled hw-address parameter.
5378 ConstElementPtr x;
5379 string config = "{ " + genIfaceConfig() + ","
5380 "\"rebind-timer\": 2000, "
5381 "\"renew-timer\": 1000, "
5382 "\"subnet4\": [ "
5383 " { "
5384 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
5385 " \"subnet\": \"192.0.4.0/24\","
5386 " \"id\": 542,"
5387 " \"reservations\": ["
5388 " {"
5389 " \"hw-addre\": \"06:05:04:03:02:01\","
5390 " \"ip-address\": \"192.0.4.102\","
5391 " \"hostname\": \"\""
5392 " }"
5393 " ]"
5394 " } "
5395 "], "
5396 "\"valid-lifetime\": 4000 }";
5397
5398 ConstElementPtr json;
5399 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_5399
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5399
; } } else gtest_label_testnothrow_5399 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5399, ("Expected: " "json = parseJSON(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5400
5401 CfgMgr::instance().clear();
5402
5403 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_5403; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5403; } } else gtest_label_testnothrow_5403
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5403, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5404 checkResult(x, CONTROL_RESULT_ERROR);
5405
5406 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_5406; } catch (...
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_5406; } 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_5406
; } } else gtest_label_testthrow_5406 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5406, gtest_msg.value.c_str()) = ::testing::Message()
;
5407
5408 // Case 2: DUID and HW Address both specified.
5409 config = "{ " + genIfaceConfig() + ","
5410 "\"rebind-timer\": 2000, "
5411 "\"renew-timer\": 1000, "
5412 "\"subnet4\": [ "
5413 " { "
5414 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
5415 " \"subnet\": \"192.0.4.0/24\","
5416 " \"id\": 542,"
5417 " \"reservations\": ["
5418 " {"
5419 " \"duid\": \"01:02:03:04:05:06\","
5420 " \"hw-address\": \"06:05:04:03:02:01\","
5421 " \"ip-address\": \"192.0.4.102\","
5422 " \"hostname\": \"\""
5423 " }"
5424 " ]"
5425 " } ],"
5426 "\"valid-lifetime\": 4000 }";
5427
5428 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_5428
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5428
; } } else gtest_label_testnothrow_5428 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5428, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5429
5430 // Remove existing configuration, if any.
5431 CfgMgr::instance().clear();
5432
5433 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_5433; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5433; } } else gtest_label_testnothrow_5433
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5433, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5434 checkResult(x, CONTROL_RESULT_ERROR);
5435
5436 // Case 3: Broken specification of option data.
5437 config = "{ " + genIfaceConfig() + ","
5438 "\"rebind-timer\": 2000, "
5439 "\"renew-timer\": 1000, "
5440 "\"subnet4\": [ "
5441 " { "
5442 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
5443 " \"subnet\": \"192.0.4.0/24\","
5444 " \"id\": 542,"
5445 " \"reservations\": ["
5446 " {"
5447 " \"hw-address\": \"06:05:04:03:02:01\","
5448 " \"option-data\": ["
5449 " {"
5450 " \"name\": \"name-servers\","
5451 " \"data\": \"bogus-ip-address\""
5452 " }"
5453 " ]"
5454 " }"
5455 " ]"
5456 " } "
5457 "], "
5458 "\"valid-lifetime\": 4000 }";
5459
5460 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_5460
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5460
; } } else gtest_label_testnothrow_5460 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5460, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5461
5462 // Remove existing configuration, if any.
5463 CfgMgr::instance().clear();
5464
5465 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_5465; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5465; } } else gtest_label_testnothrow_5465
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5465, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5466 checkResult(x, CONTROL_RESULT_ERROR);
5467}
5468
5469/// The goal of this test is to verify that Host Reservation flags can be
5470/// specified on a per-subnet basis.
5471TEST_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"
, 5471), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5471), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5471), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_hostReservationPerSubnet_Test
>); void Dhcp4ParserTest_hostReservationPerSubnet_Test::TestBody
()
{
5472
5473 /// - Configuration:
5474 /// - only addresses (no prefixes)
5475 /// - 7 subnets with:
5476 /// - 192.0.1.0/24 (all reservations enabled)
5477 /// - 192.0.2.0/24 (out-of-pool reservations)
5478 /// - 192.0.3.0/24 (reservations disabled)
5479 /// - 192.0.4.0/24 (global reservations)
5480 /// - 192.0.5.0/24 (reservations not specified)
5481 /// - 192.0.6.0/24 (global + all enabled)
5482 /// - 192.0.7.0/24 (global + out-of-pool enabled)
5483 const char* hr_config =
5484 "{"
5485 "\"rebind-timer\": 2000, "
5486 "\"renew-timer\": 1000, "
5487 "\"subnet4\": [ { "
5488 " \"id\": 1,"
5489 " \"pools\": [ { \"pool\": \"192.0.1.0/24\" } ],"
5490 " \"subnet\": \"192.0.1.0/24\", "
5491 " \"reservations-global\": false,"
5492 " \"reservations-in-subnet\": true,"
5493 " \"reservations-out-of-pool\": false"
5494 " },"
5495 " {"
5496 " \"id\": 2,"
5497 " \"pools\": [ { \"pool\": \"192.0.2.0/24\" } ],"
5498 " \"subnet\": \"192.0.2.0/24\", "
5499 " \"reservations-global\": false,"
5500 " \"reservations-in-subnet\": true,"
5501 " \"reservations-out-of-pool\": true"
5502 " },"
5503 " {"
5504 " \"id\": 3,"
5505 " \"pools\": [ { \"pool\": \"192.0.3.0/24\" } ],"
5506 " \"subnet\": \"192.0.3.0/24\", "
5507 " \"reservations-global\": false,"
5508 " \"reservations-in-subnet\": false"
5509 " },"
5510 " {"
5511 " \"id\": 4,"
5512 " \"pools\": [ { \"pool\": \"192.0.4.0/24\" } ],"
5513 " \"subnet\": \"192.0.4.0/24\", "
5514 " \"reservations-global\": true,"
5515 " \"reservations-in-subnet\": false"
5516 " },"
5517 " {"
5518 " \"id\": 5,"
5519 " \"pools\": [ { \"pool\": \"192.0.5.0/24\" } ],"
5520 " \"subnet\": \"192.0.5.0/24\""
5521 " },"
5522 " {"
5523 " \"id\": 6,"
5524 " \"pools\": [ { \"pool\": \"192.0.6.0/24\" } ],"
5525 " \"subnet\": \"192.0.6.0/24\", "
5526 " \"reservations-global\": true,"
5527 " \"reservations-in-subnet\": true,"
5528 " \"reservations-out-of-pool\": false"
5529 " },"
5530 " {"
5531 " \"id\": 7,"
5532 " \"pools\": [ { \"pool\": \"192.0.7.0/24\" } ],"
5533 " \"subnet\": \"192.0.7.0/24\", "
5534 " \"reservations-global\": true,"
5535 " \"reservations-in-subnet\": true,"
5536 " \"reservations-out-of-pool\": true"
5537 " } ],"
5538 "\"valid-lifetime\": 4000 }";
5539
5540 ConstElementPtr json;
5541 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_5541
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5541
; } } else gtest_label_testnothrow_5541 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5541, ("Expected: " "json = parseDHCP4(hr_config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5542 extractConfig(hr_config);
5543
5544 ConstElementPtr status;
5545 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_5545; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5545; } } else gtest_label_testnothrow_5545
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5545, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5546
5547 // returned value should be 0 (success)
5548 checkResult(status, 0);
5549 CfgMgr::instance().commit();
5550
5551 // Let's get all subnets and check that there are 7 of them.
5552 ConstCfgSubnets4Ptr subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4();
5553 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"
, 5553, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
5554 const Subnet4Collection* subnet_col = subnets->getAll();
5555 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"
, 5555, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 7 subnets
5556
5557 // Let's check if the parsed subnets have correct HR modes.
5558
5559 // Subnet 1
5560 ConstSubnet4Ptr subnet;
5561 subnet = subnets->selectSubnet(IOAddress("192.0.1.1"));
5562 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"
, 5562, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5563 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"
, 5563, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "true", "false") .c_str
()) = ::testing::Message()
;
5564 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"
, 5564, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "false", "true") .c_str
()) = ::testing::Message()
;
5565 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"
, 5565, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "true", "false") .
c_str()) = ::testing::Message()
;
5566
5567 // Subnet 2
5568 subnet = subnets->selectSubnet(IOAddress("192.0.2.1"));
5569 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"
, 5569, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5570 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"
, 5570, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "true", "false") .c_str
()) = ::testing::Message()
;
5571 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"
, 5571, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "false", "true") .c_str
()) = ::testing::Message()
;
5572 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"
, 5572, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "false", "true") .
c_str()) = ::testing::Message()
;
5573
5574 // Subnet 3
5575 subnet = subnets->selectSubnet(IOAddress("192.0.3.1"));
5576 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"
, 5576, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5577 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"
, 5577, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "true", "false") .c_str
()) = ::testing::Message()
;
5578 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"
, 5578, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "true", "false") .c_str
()) = ::testing::Message()
;
5579 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"
, 5579, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "true", "false") .
c_str()) = ::testing::Message()
;
5580
5581 // Subnet 4
5582 subnet = subnets->selectSubnet(IOAddress("192.0.4.1"));
5583 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"
, 5583, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5584 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"
, 5584, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "false", "true") .c_str
()) = ::testing::Message()
;
5585 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"
, 5585, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "true", "false") .c_str
()) = ::testing::Message()
;
5586 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"
, 5586, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "true", "false") .
c_str()) = ::testing::Message()
;
5587
5588 // Subnet 5
5589 subnet = subnets->selectSubnet(IOAddress("192.0.5.1"));
5590 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"
, 5590, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5591 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"
, 5591, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "true", "false") .c_str
()) = ::testing::Message()
;
5592 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"
, 5592, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "false", "true") .c_str
()) = ::testing::Message()
;
5593 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"
, 5593, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "true", "false") .
c_str()) = ::testing::Message()
;
5594
5595 // Subnet 6
5596 subnet = subnets->selectSubnet(IOAddress("192.0.6.1"));
5597 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"
, 5597, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5598 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"
, 5598, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "false", "true") .c_str
()) = ::testing::Message()
;
5599 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"
, 5599, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "false", "true") .c_str
()) = ::testing::Message()
;
5600 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"
, 5600, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "true", "false") .
c_str()) = ::testing::Message()
;
5601
5602 // Subnet 7
5603 subnet = subnets->selectSubnet(IOAddress("192.0.7.1"));
5604 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"
, 5604, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5605 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"
, 5605, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "false", "true") .c_str
()) = ::testing::Message()
;
5606 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"
, 5606, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "false", "true") .c_str
()) = ::testing::Message()
;
5607 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"
, 5607, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "false", "true") .
c_str()) = ::testing::Message()
;
5608}
5609
5610/// The goal of this test is to verify that Host Reservation flags can be
5611/// specified globally.
5612TEST_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"
, 5612), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5612), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5612), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_hostReservationGlobal_Test
>); void Dhcp4ParserTest_hostReservationGlobal_Test::TestBody
()
{
5613
5614 /// - Configuration:
5615 /// - only addresses (no prefixes)
5616 /// - 2 subnets with :
5617 /// - 192.0.2.0/24 (all reservations enabled)
5618 /// - 192.0.3.0/24 (reservations not specified)
5619 const char* hr_config =
5620 "{"
5621 "\"rebind-timer\": 2000, "
5622 "\"renew-timer\": 1000, "
5623 "\"reservations-global\": false,"
5624 "\"reservations-in-subnet\": true,"
5625 "\"reservations-out-of-pool\": true,"
5626 "\"subnet4\": [ { "
5627 " \"id\": 1,"
5628 " \"pools\": [ { \"pool\": \"192.0.2.0/24\" } ],"
5629 " \"subnet\": \"192.0.2.0/24\", "
5630 " \"reservations-global\": false,"
5631 " \"reservations-in-subnet\": true,"
5632 " \"reservations-out-of-pool\": false"
5633 " },"
5634 " {"
5635 " \"id\": 2,"
5636 " \"pools\": [ { \"pool\": \"192.0.3.0/24\" } ],"
5637 " \"subnet\": \"192.0.3.0/24\""
5638 " } ],"
5639 "\"valid-lifetime\": 4000 }";
5640
5641 ConstElementPtr json;
5642 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_5642
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5642
; } } else gtest_label_testnothrow_5642 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5642, ("Expected: " "json = parseDHCP4(hr_config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5643 extractConfig(hr_config);
5644
5645 ConstElementPtr status;
5646 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_5646; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5646; } } else gtest_label_testnothrow_5646
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5646, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5647
5648 // returned value should be 0 (success)
5649 checkResult(status, 0);
5650 CfgMgr::instance().commit();
5651
5652 // Let's get all subnets and check that there are 4 of them.
5653 ConstCfgSubnets4Ptr subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4();
5654 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"
, 5654, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
5655 const Subnet4Collection* subnet_col = subnets->getAll();
5656 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"
, 5656, gtest_ar.failure_message()) = ::testing::Message()
; // We expect 2 subnets
5657
5658 // Let's check if the parsed subnets have correct HR modes.
5659
5660 // Subnet 1
5661 ConstSubnet4Ptr subnet;
5662 subnet = subnets->selectSubnet(IOAddress("192.0.2.1"));
5663 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"
, 5663, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5664 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"
, 5664, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "true", "false") .c_str
()) = ::testing::Message()
;
5665 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"
, 5665, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "false", "true") .c_str
()) = ::testing::Message()
;
5666 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"
, 5666, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "true", "false") .
c_str()) = ::testing::Message()
;
5667
5668 // Subnet 2
5669 subnet = subnets->selectSubnet(IOAddress("192.0.3.1"));
5670 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"
, 5670, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5671 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"
, 5671, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsGlobal()", "true", "false") .c_str
()) = ::testing::Message()
;
5672 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"
, 5672, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsInSubnet()", "false", "true") .c_str
()) = ::testing::Message()
;
5673 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"
, 5673, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getReservationsOutOfPool()", "false", "true") .
c_str()) = ::testing::Message()
;
5674}
5675
5676/// Check that the decline-probation-period has a default value when not
5677/// specified.
5678TEST_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"
, 5678), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5678), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5678), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_declineTimerDefault_Test
>); void Dhcp4ParserTest_declineTimerDefault_Test::TestBody
()
{
5679
5680 string config = "{ " + genIfaceConfig() + ","
5681 "\"subnet4\": [ ] "
5682 "}";
5683
5684 ConstElementPtr json;
5685 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_5685
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5685
; } } else gtest_label_testnothrow_5685 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5685, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5686 extractConfig(config);
5687
5688 ConstElementPtr status;
5689 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_5689; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5689; } } else gtest_label_testnothrow_5689
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5689, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5690
5691 // returned value should be 0 (success)
5692 checkResult(status, 0);
5693
5694 // The value of decline-probation-period must be equal to the
5695 // default value (86400). The default value is defined in GLOBAL4_DEFAULTS in
5696 // simple_parser4.cc.
5697 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"
, 5697, gtest_ar.failure_message()) = ::testing::Message()
;
5698}
5699
5700/// Check that the dhcp4o6-port default value has a default value if not
5701/// specified explicitly.
5702TEST_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"
, 5702), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5702), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5702), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_dhcp4o6portDefault_Test
>); void Dhcp4ParserTest_dhcp4o6portDefault_Test::TestBody
()
{
5703
5704 string config_txt = "{ " + genIfaceConfig() + ","
5705 "\"subnet4\": [ ] "
5706 "}";
5707 ConstElementPtr config;
5708 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_5708
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5708
; } } else gtest_label_testnothrow_5708 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5708, ("Expected: " "config = parseDHCP4(config_txt)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5709 extractConfig(config_txt);
5710
5711 ConstElementPtr status;
5712 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_5712; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5712; } } else gtest_label_testnothrow_5712
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5712, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, config)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5713
5714 // returned value should be 0 (success)
5715 checkResult(status, 0);
5716
5717 // The value of decline-probation-period must be equal to the
5718 // default value (0). The default value is defined in GLOBAL4_DEFAULTS in
5719 // simple_parser4.cc.
5720 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"
, 5720, gtest_ar.failure_message()) = ::testing::Message()
;
5721}
5722
5723/// Check that the decline-probation-period value can be set properly.
5724TEST_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", 5724
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5724), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5724), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_declineTimer_Test
>); void Dhcp4ParserTest_declineTimer_Test::TestBody()
{
5725 string config = "{ " + genIfaceConfig() + ","
5726 "\"decline-probation-period\": 12345,"
5727 "\"subnet4\": [ ]"
5728 "}";
5729
5730 ConstElementPtr json;
5731 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_5731
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5731
; } } else gtest_label_testnothrow_5731 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5731, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5732 extractConfig(config);
5733
5734 ConstElementPtr status;
5735 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_5735; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5735; } } else gtest_label_testnothrow_5735
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5735, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5736
5737 // returned value should be 0 (success)
5738 checkResult(status, 0);
5739
5740 // The value of decline-probation-period must be equal to the
5741 // value specified.
5742 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"
, 5743, gtest_ar.failure_message()) = ::testing::Message()
5743 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"
, 5743, gtest_ar.failure_message()) = ::testing::Message()
;
5744}
5745
5746/// Check that an incorrect decline-probation-period value will be caught.
5747TEST_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"
, 5747), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5747), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5747), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_declineTimerError_Test
>); void Dhcp4ParserTest_declineTimerError_Test::TestBody(
)
{
5748 string config = "{ " + genIfaceConfig() + ","
5749 "\"decline-probation-period\": \"soon\","
5750 "\"subnet4\": [ ]"
5751 "}";
5752
5753 ConstElementPtr json;
5754 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_5754
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5754
; } } else gtest_label_testnothrow_5754 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5754, ("Expected: " "json = parseJSON(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5755
5756 ConstElementPtr status;
5757 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_5757; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5757; } } else gtest_label_testnothrow_5757
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5757, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5758
5759 // returned value should be 1 (error)
5760 checkResult(status, CONTROL_RESULT_ERROR);
5761
5762 // Check that the error contains error position.
5763 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"
, 5763, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
5764
5765 // Check that the Dhcp4 parser catches the type error
5766 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_5766; } catch (...
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_5766; } 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_5766
; } } else gtest_label_testthrow_5766 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5766, gtest_msg.value.c_str()) = ::testing::Message()
;
5767}
5768
5769// Check that configuration for the expired leases processing may be
5770// specified.
5771TEST_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"
, 5771), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5771), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5771), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_expiredLeasesProcessing_Test
>); void Dhcp4ParserTest_expiredLeasesProcessing_Test::TestBody
()
{
5772 // Create basic configuration with the expiration specific parameters.
5773 string config = "{ " + genIfaceConfig() + ","
5774 "\"expired-leases-processing\": "
5775 "{"
5776 " \"reclaim-timer-wait-time\": 20,"
5777 " \"flush-reclaimed-timer-wait-time\": 35,"
5778 " \"hold-reclaimed-time\": 1800,"
5779 " \"max-reclaim-leases\": 50,"
5780 " \"max-reclaim-time\": 100,"
5781 " \"unwarned-reclaim-cycles\": 10"
5782 "},"
5783 "\"subnet4\": [ ]"
5784 "}";
5785
5786 ConstElementPtr json;
5787 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_5787
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5787
; } } else gtest_label_testnothrow_5787 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5787, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5788 extractConfig(config);
5789
5790 ConstElementPtr status;
5791 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_5791; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5791; } } else gtest_label_testnothrow_5791
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5791, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5792
5793 // Returned value should be 0 (success)
5794 checkResult(status, 0);
5795
5796 // The value of decline-probation-period must be equal to the
5797 // value specified.
5798 CfgExpirationPtr cfg = CfgMgr::instance().getStagingCfg()->getCfgExpiration();
5799 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", 5799
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg", "false", "true") .c_str()) = ::testing::Message()
;
5800
5801 // Verify that parameters are correct.
5802 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", 5802
, gtest_ar.failure_message()) = ::testing::Message()
;
5803 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", 5803
, gtest_ar.failure_message()) = ::testing::Message()
;
5804 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", 5804
, gtest_ar.failure_message()) = ::testing::Message()
;
5805 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"
, 5805, gtest_ar.failure_message()) = ::testing::Message()
;
5806 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"
, 5806, gtest_ar.failure_message()) = ::testing::Message()
;
5807 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", 5807
, gtest_ar.failure_message()) = ::testing::Message()
;
5808}
5809
5810// Check that invalid configuration for the expired leases processing is
5811// causing an error.
5812TEST_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"
, 5812), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5812), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5812), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_expiredLeasesProcessingError_Test
>); void Dhcp4ParserTest_expiredLeasesProcessingError_Test
::TestBody()
{
5813 // Create basic configuration with the expiration specific parameters.
5814 // One of the parameters holds invalid value.
5815 string config = "{ " + genIfaceConfig() + ","
5816 "\"expired-leases-processing\": "
5817 "{"
5818 " \"reclaim-timer-wait-time\": -5,"
5819 " \"flush-reclaimed-timer-wait-time\": 35,"
5820 " \"hold-reclaimed-time\": 1800,"
5821 " \"max-reclaim-leases\": 50,"
5822 " \"max-reclaim-time\": 100,"
5823 " \"unwarned-reclaim-cycles\": 10"
5824 "},"
5825 "\"subnet4\": [ ]"
5826 "}";
5827
5828 ConstElementPtr json;
5829 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_5829
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5829
; } } else gtest_label_testnothrow_5829 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5829, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5830
5831 ConstElementPtr status;
5832 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_5832; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5832; } } else gtest_label_testnothrow_5832
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5832, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5833
5834 // Returned value should be 0 (error)
5835 checkResult(status, CONTROL_RESULT_ERROR);
5836
5837 // Check that the error contains error position.
5838 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"
, 5838, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "errorContainsPosition(status, \"<string>\")", "false"
, "true") .c_str()) = ::testing::Message()
;
5839}
5840
5841// Checks if the DHCPv4 is able to parse the configuration without 4o6 parameters
5842// and does not set 4o6 fields at all.
5843TEST_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", 5843
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5843), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5843), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_4o6default_Test
>); void Dhcp4ParserTest_4o6default_Test::TestBody()
{
5844
5845 ConstElementPtr status;
5846
5847 // Just a plain v4 config (no 4o6 parameters)
5848 string config = "{ " + genIfaceConfig() + ","
5849 "\"rebind-timer\": 2000, "
5850 "\"renew-timer\": 1000, "
5851 "\"subnet4\": [ { "
5852 " \"id\": 1,"
5853 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5854 " \"subnet\": \"192.0.2.0/24\" } ],"
5855 "\"valid-lifetime\": 4000 }";
5856
5857 ConstElementPtr json;
5858 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_5858
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5858
; } } else gtest_label_testnothrow_5858 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5858, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5859 extractConfig(config);
5860
5861 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_5861; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5861; } } else gtest_label_testnothrow_5861
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5861, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5862
5863 // check if returned status is OK
5864 checkResult(status, 0);
5865
5866 // Now check if the configuration was indeed handled and we have
5867 // expected pool configured.
5868 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
5869 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
5870 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"
, 5870, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5871
5872 const Cfg4o6& dhcp4o6 = subnet->get4o6();
5873 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"
, 5873, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dhcp4o6.enabled()", "true", "false") .c_str()) = ::testing
::Message()
;
5874}
5875
5876// Checks if the DHCPv4 is able to parse the configuration with 4o6 subnet
5877// defined.
5878TEST_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", 5878
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5878), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5878), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_4o6subnet_Test
>); void Dhcp4ParserTest_4o6subnet_Test::TestBody()
{
5879
5880 ConstElementPtr status;
5881
5882 // Just a plain v4 config (no 4o6 parameters)
5883 string config = "{ " + genIfaceConfig() + ","
5884 "\"rebind-timer\": 2000, "
5885 "\"renew-timer\": 1000, "
5886 "\"subnet4\": [ { "
5887 " \"id\": 1,"
5888 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5889 " \"subnet\": \"192.0.2.0/24\","
5890 " \"4o6-subnet\": \"2001:db8::123/45\" } ],"
5891 "\"valid-lifetime\": 4000 }";
5892
5893 ConstElementPtr json;
5894 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_5894
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5894
; } } else gtest_label_testnothrow_5894 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5894, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5895 extractConfig(config);
5896
5897 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_5897; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5897; } } else gtest_label_testnothrow_5897
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5897, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5898
5899 // check if returned status is OK
5900 checkResult(status, 0);
5901
5902 // Now check if the configuration was indeed handled and we have
5903 // expected pool configured.
5904 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
5905 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
5906 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"
, 5906, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
5907
5908 const Cfg4o6& dhcp4o6 = subnet->get4o6();
5909 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"
, 5909, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dhcp4o6.enabled()", "false", "true") .c_str()) = ::testing
::Message()
;
5910 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"
, 5910, gtest_ar.failure_message()) = ::testing::Message()
;
5911 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", 5911
, gtest_ar.failure_message()) = ::testing::Message()
;
5912}
5913
5914// Checks if the DHCPv4 is able to parse the configuration with 4o6 subnet
5915// defined.
5916TEST_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", 5916
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5916), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5916), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_4o6subnetBogus_Test
>); void Dhcp4ParserTest_4o6subnetBogus_Test::TestBody()
{
5917
5918 ConstElementPtr status;
5919
5920 // Just a plain v4 config (no 4o6 parameters)
5921 string config[] = {
5922 // Bogus configuration 1: missing / in subnet
5923 "{ " + genIfaceConfig() + ","
5924 "\"rebind-timer\": 2000, "
5925 "\"renew-timer\": 1000, "
5926 "\"subnet4\": [ { "
5927 " \"id\": 1,"
5928 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5929 " \"subnet\": \"192.0.2.0/24\","
5930 " \"4o6-subnet\": \"2001:db8::123\" } ],"
5931 "\"valid-lifetime\": 4000 }",
5932
5933 // Bogus configuration 2: incorrect address
5934 "{ " + genIfaceConfig() + ","
5935 "\"rebind-timer\": 2000, "
5936 "\"renew-timer\": 1000, "
5937 "\"subnet4\": [ { "
5938 " \"id\": 1,"
5939 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5940 " \"subnet\": \"192.0.2.0/24\","
5941 " \"4o6-subnet\": \"2001:db8:bogus/45\" } ],"
5942 "\"valid-lifetime\": 4000 }",
5943
5944 // Bogus configuration 3: incorrect prefix length
5945 "{ " + genIfaceConfig() + ","
5946 "\"rebind-timer\": 2000, "
5947 "\"renew-timer\": 1000, "
5948 "\"subnet4\": [ { "
5949 " \"id\": 1,"
5950 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5951 " \"subnet\": \"192.0.2.0/24\","
5952 " \"4o6-subnet\": \"2001:db8::123/200\" } ],"
5953 "\"valid-lifetime\": 4000 }"
5954 };
5955
5956 ConstElementPtr json1;
5957 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_5957
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5957
; } } else gtest_label_testnothrow_5957 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5957, ("Expected: " "json1 = parseDHCP4(config[0])" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5958 ConstElementPtr json2;
5959 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_5959
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5959
; } } else gtest_label_testnothrow_5959 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5959, ("Expected: " "json2 = parseDHCP4(config[0])" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5960 ConstElementPtr json3;
5961 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_5961
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5961
; } } else gtest_label_testnothrow_5961 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5961, ("Expected: " "json3 = parseDHCP4(config[0])" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5962
5963 // Check that the first config is rejected.
5964 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_5964; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5964; } } else gtest_label_testnothrow_5964
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5964, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json1)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5965 checkResult(status, CONTROL_RESULT_ERROR);
5966
5967 // Check that the second config is rejected.
5968 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_5968; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5968; } } else gtest_label_testnothrow_5968
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5968, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json2)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5969 checkResult(status, CONTROL_RESULT_ERROR);
5970
5971 // Check that the third config is rejected.
5972 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_5972; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5972; } } else gtest_label_testnothrow_5972
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5972, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json3)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5973 checkResult(status, CONTROL_RESULT_ERROR);
5974}
5975
5976// Checks if the DHCPv4 is able to parse the configuration with 4o6 network
5977// interface defined.
5978TEST_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", 5978
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5978), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5978), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_4o6iface_Test
>); void Dhcp4ParserTest_4o6iface_Test::TestBody()
{
5979
5980 ConstElementPtr status;
5981
5982 // Just a plain v4 config (no 4o6 parameters)
5983 string config = "{ " + genIfaceConfig() + ","
5984 "\"rebind-timer\": 2000, "
5985 "\"renew-timer\": 1000, "
5986 "\"subnet4\": [ { "
5987 " \"id\": 1,"
5988 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
5989 " \"subnet\": \"192.0.2.0/24\","
5990 " \"4o6-interface\": \"ethX\" } ],"
5991 "\"valid-lifetime\": 4000 }";
5992
5993 ConstElementPtr json;
5994 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_5994
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_5994
; } } else gtest_label_testnothrow_5994 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5994, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
5995 extractConfig(config);
5996
5997 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_5997; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_5997; } } else gtest_label_testnothrow_5997
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 5997, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
5998
5999 // check if returned status is OK
6000 checkResult(status, 0);
6001
6002 // Now check if the configuration was indeed handled and we have
6003 // expected pool configured.
6004 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
6005 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
6006 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"
, 6006, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
6007
6008 const Cfg4o6& dhcp4o6 = subnet->get4o6();
6009 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"
, 6009, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dhcp4o6.enabled()", "false", "true") .c_str()) = ::testing
::Message()
;
6010 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"
, 6010, gtest_ar.failure_message()) = ::testing::Message()
;
6011}
6012
6013// Checks if the DHCPv4 is able to parse the configuration with both 4o6 network
6014// interface and v6 subnet defined.
6015TEST_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", 6015
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6015), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6015), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_4o6subnetIface_Test
>); void Dhcp4ParserTest_4o6subnetIface_Test::TestBody()
{
6016
6017 ConstElementPtr status;
6018
6019 // Just a plain v4 config (no 4o6 parameters)
6020 string config = "{ " + genIfaceConfig() + ","
6021 "\"rebind-timer\": 2000, "
6022 "\"renew-timer\": 1000, "
6023 "\"subnet4\": [ { "
6024 " \"id\": 1,"
6025 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
6026 " \"subnet\": \"192.0.2.0/24\","
6027 " \"4o6-subnet\": \"2001:db8::543/21\","
6028 " \"4o6-interface\": \"ethX\" } ],"
6029 "\"valid-lifetime\": 4000 }";
6030
6031 ConstElementPtr json;
6032 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_6032
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6032
; } } else gtest_label_testnothrow_6032 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6032, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
6033 extractConfig(config);
6034
6035 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_6035; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_6035; } } else gtest_label_testnothrow_6035
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6035, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
6036
6037 // check if returned status is OK
6038 checkResult(status, 0);
6039
6040 // Now check if the configuration was indeed handled and we have
6041 // expected subnet configured...
6042 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
6043 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
6044 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"
, 6044, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
6045
6046 // ... and that subnet has 4o6 network interface specified.
6047 const Cfg4o6& dhcp4o6 = subnet->get4o6();
6048 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"
, 6048, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dhcp4o6.enabled()", "false", "true") .c_str()) = ::testing
::Message()
;
6049 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"
, 6049, gtest_ar.failure_message()) = ::testing::Message()
;
6050 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", 6050
, gtest_ar.failure_message()) = ::testing::Message()
;
6051 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"
, 6051, gtest_ar.failure_message()) = ::testing::Message()
;
6052}
6053
6054// Checks if the DHCPv4 is able to parse the configuration with 4o6 network
6055// interface-id.
6056TEST_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"
, 6056), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6056), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6056), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_4o6subnetInterfaceId_Test
>); void Dhcp4ParserTest_4o6subnetInterfaceId_Test::TestBody
()
{
6057
6058 ConstElementPtr status;
6059
6060 // Just a plain v4 config (no 4o6 parameters)
6061 string config = "{ " + genIfaceConfig() + ","
6062 "\"rebind-timer\": 2000, "
6063 "\"renew-timer\": 1000, "
6064 "\"subnet4\": [ { "
6065 " \"id\": 1,"
6066 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
6067 " \"subnet\": \"192.0.2.0/24\","
6068 " \"4o6-interface-id\": \"vlan123\" } ],"
6069 "\"valid-lifetime\": 4000 }";
6070
6071 ConstElementPtr json;
6072 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_6072
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6072
; } } else gtest_label_testnothrow_6072 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6072, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
6073 extractConfig(config);
6074
6075 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_6075; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_6075; } } else gtest_label_testnothrow_6075
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6075, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
6076
6077 // check if returned status is OK
6078 checkResult(status, 0);
6079
6080 // Now check if the configuration was indeed handled and we have
6081 // expected 4o6-interface-id configured.
6082 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
6083 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
6084 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"
, 6084, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
6085
6086 const Cfg4o6& dhcp4o6 = subnet->get4o6();
6087 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"
, 6087, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dhcp4o6.enabled()", "false", "true") .c_str()) = ::testing
::Message()
;
6088 OptionPtr ifaceid = dhcp4o6.getInterfaceId();
6089 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"
, 6089, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ifaceid", "false", "true") .c_str()) = ::testing::Message(
)
;
6090
6091 vector<uint8_t> data = ifaceid->getData();
6092 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"
, 6092, gtest_ar.failure_message()) = ::testing::Message()
;
6093 const char *exp = "vlan123";
6094 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", 6094
, gtest_ar.failure_message()) = ::testing::Message()
;
6095}
6096
6097// Verifies that simple list of valid classes parses and
6098// is staged for commit.
6099TEST_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"
, 6099), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6099), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6099), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_validClientClassDictionary_Test
>); void Dhcp4ParserTest_validClientClassDictionary_Test::
TestBody()
{
6100 string config = "{ " + genIfaceConfig() + ","
6101 "\"valid-lifetime\": 4000, \n"
6102 "\"rebind-timer\": 2000, \n"
6103 "\"renew-timer\": 1000, \n"
6104 "\"client-classes\" : [ \n"
6105 " { \n"
6106 " \"name\": \"one\" \n"
6107 " }, \n"
6108 " { \n"
6109 " \"name\": \"two\" \n"
6110 " }, \n"
6111 " { \n"
6112 " \"name\": \"three\" \n"
6113 " } \n"
6114 "], \n"
6115 "\"subnet4\": [ { \n"
6116 " \"id\": 1, \n"
6117 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ], \n"
6118 " \"subnet\": \"192.0.2.0/24\" \n"
6119 " } ] \n"
6120 "} \n";
6121
6122 ConstElementPtr json;
6123 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_6123
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6123
; } } else gtest_label_testnothrow_6123 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6123, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
6124 extractConfig(config);
6125
6126 ConstElementPtr status;
6127 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_6127; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_6127; } } else gtest_label_testnothrow_6127
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6127, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
6128 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"
, 6128, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
6129 checkResult(status, 0);
6130
6131 // We check staging config because CfgMgr::commit hasn't been executed.
6132 ClientClassDictionaryPtr dictionary;
6133 dictionary = CfgMgr::instance().getStagingCfg()->getClientClassDictionary();
6134 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"
, 6134, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dictionary", "false", "true") .c_str()) = ::testing::Message
()
;
6135 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", 6135
, gtest_ar.failure_message()) = ::testing::Message()
;
6136
6137 // Execute the commit
6138 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_6138
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6138
; } } else gtest_label_testnothrow_6138 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6138, ("Expected: " "CfgMgr::instance().commit()" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
6139
6140 // Verify that after commit, the current config has the correct dictionary
6141 dictionary = CfgMgr::instance().getCurrentCfg()->getClientClassDictionary();
6142 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"
, 6142, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dictionary", "false", "true") .c_str()) = ::testing::Message
()
;
6143 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", 6143
, gtest_ar.failure_message()) = ::testing::Message()
;
6144}
6145
6146// Verifies that a class list containing an invalid
6147// class definition causes a configuration error.
6148TEST_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"
, 6148), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6148), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6148), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_invalidClientClassDictionary_Test
>); void Dhcp4ParserTest_invalidClientClassDictionary_Test
::TestBody()
{
6149 string config = "{ " + genIfaceConfig() + ","
6150 "\"valid-lifetime\": 4000, \n"
6151 "\"rebind-timer\": 2000, \n"
6152 "\"renew-timer\": 1000, \n"
6153 "\"client-classes\" : [ \n"
6154 " { \n"
6155 " \"name\": \"one\", \n"
6156 " \"bogus\": \"bad\" \n"
6157 " } \n"
6158 "], \n"
6159 "\"subnet4\": [ { \n"
6160 " \"id\": 1, \n"
6161 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ], \n"
6162 " \"subnet\": \"192.0.2.0/24\" \n"
6163 " } ] \n"
6164 "} \n";
6165
6166 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_6166; } catch (...
) { gtest_msg.value = "Expected: " "parseDHCP4(config)" " throws an exception of type "
"Dhcp4ParseError" ".\n Actual: it throws a different type."
; goto gtest_label_testthrow_6166; } 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_6166
; } } else gtest_label_testthrow_6166 : ::testing::internal::
AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6166, gtest_msg.value.c_str()) = ::testing::Message()
;
6167}
6168
6169// Verifies that simple list of valid classes parses and
6170// is staged for commit.
6171TEST_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"
, 6171), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6171), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6171), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_clientClassValidLifetime_Test
>); void Dhcp4ParserTest_clientClassValidLifetime_Test::TestBody
()
{
6172 string config = "{ " + genIfaceConfig() + ","
6173 "\"client-classes\" : [ \n"
6174 " { \n"
6175 " \"name\": \"one\", \n"
6176 " \"min-valid-lifetime\": 1000, \n"
6177 " \"valid-lifetime\": 2000, \n"
6178 " \"max-valid-lifetime\": 3000 \n"
6179 " }, \n"
6180 " { \n"
6181 " \"name\": \"two\" \n"
6182 " } \n"
6183 "], \n"
6184 "\"subnet4\": [ { \n"
6185 " \"id\": 1, \n"
6186 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ], \n"
6187 " \"subnet\": \"192.0.2.0/24\" \n"
6188 " } ] \n"
6189 "} \n";
6190
6191 ConstElementPtr json;
6192 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"
, 6192, "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", 6192
, "Failed") = ::testing::Message() << "json = parseDHCP4(config)"
<< " threw non-std::exception"; } }
;
6193 extractConfig(config);
6194
6195 ConstElementPtr status;
6196 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"
, 6196, "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", 6196
, "Failed") = ::testing::Message() << "status = Dhcpv4SrvTest::configure(*srv_, json)"
<< " threw non-std::exception"; } }
;
6197 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"
, 6197, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
6198 checkResult(status, 0);
6199
6200 // We check staging config because CfgMgr::commit hasn't been executed.
6201 ClientClassDictionaryPtr dictionary;
6202 dictionary = CfgMgr::instance().getStagingCfg()->getClientClassDictionary();
6203 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"
, 6203, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dictionary", "false", "true") .c_str()) = ::testing::Message
()
;
6204 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", 6204
, gtest_ar.failure_message()) = ::testing::Message()
;
6205
6206 // Execute the commit
6207 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_6207
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6207
; } } else gtest_label_testnothrow_6207 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6207, ("Expected: " "CfgMgr::instance().commit()" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
6208
6209 // Verify that after commit, the current config has the correct dictionary
6210 dictionary = CfgMgr::instance().getCurrentCfg()->getClientClassDictionary();
6211 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"
, 6211, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dictionary", "false", "true") .c_str()) = ::testing::Message
()
;
6212 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", 6212
, gtest_ar.failure_message()) = ::testing::Message()
;
6213
6214 ClientClassDefPtr class_def = dictionary->findClass("one");
6215 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"
, 6215, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "class_def", "false", "true") .c_str()) = ::testing::Message
()
;
6216 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"
, 6216, gtest_ar.failure_message()) = ::testing::Message()
;
6217 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", 6217
, gtest_ar.failure_message()) = ::testing::Message()
;
6218 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"
, 6218, gtest_ar.failure_message()) = ::testing::Message()
;
6219
6220 class_def = dictionary->findClass("two");
6221 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"
, 6221, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "class_def", "false", "true") .c_str()) = ::testing::Message
()
;
6222 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"
, 6222, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "class_def->getValid().unspecified()", "false", "true") .
c_str()) = ::testing::Message()
;
6223}
6224
6225// Verifies that simple list of valid template classes parses and
6226// is staged for commit.
6227TEST_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"
, 6227), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6227), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6227), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_templateClientClassValidLifetime_Test
>); void Dhcp4ParserTest_templateClientClassValidLifetime_Test
::TestBody()
{
6228 string config = "{ " + genIfaceConfig() + ","
6229 "\"client-classes\" : [ \n"
6230 " { \n"
6231 " \"name\": \"one\", \n"
6232 " \"min-valid-lifetime\": 1000, \n"
6233 " \"valid-lifetime\": 2000, \n"
6234 " \"max-valid-lifetime\": 3000, \n"
6235 " \"template-test\": \"''\" \n"
6236 " }, \n"
6237 " { \n"
6238 " \"name\": \"two\", \n"
6239 " \"template-test\": \"''\" \n"
6240 " } \n"
6241 "], \n"
6242 "\"subnet4\": [ { \n"
6243 " \"id\": 1, \n"
6244 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ], \n"
6245 " \"subnet\": \"192.0.2.0/24\" \n"
6246 " } ] \n"
6247 "} \n";
6248
6249 ConstElementPtr json;
6250 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"
, 6250, "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", 6250
, "Failed") = ::testing::Message() << "json = parseDHCP4(config)"
<< " threw non-std::exception"; } }
;
6251 extractConfig(config);
6252
6253 ConstElementPtr status;
6254 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"
, 6254, "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", 6254
, "Failed") = ::testing::Message() << "status = Dhcpv4SrvTest::configure(*srv_, json)"
<< " threw non-std::exception"; } }
;
6255 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"
, 6255, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "status", "false", "true") .c_str()) = ::testing::Message()
;
6256 checkResult(status, 0);
6257
6258 // We check staging config because CfgMgr::commit hasn't been executed.
6259 ClientClassDictionaryPtr dictionary;
6260 dictionary = CfgMgr::instance().getStagingCfg()->getClientClassDictionary();
6261 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"
, 6261, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dictionary", "false", "true") .c_str()) = ::testing::Message
()
;
6262 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", 6262
, gtest_ar.failure_message()) = ::testing::Message()
;
6263
6264 // Execute the commit
6265 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_6265
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6265
; } } else gtest_label_testnothrow_6265 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6265, ("Expected: " "CfgMgr::instance().commit()" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
6266
6267 // Verify that after commit, the current config has the correct dictionary
6268 dictionary = CfgMgr::instance().getCurrentCfg()->getClientClassDictionary();
6269 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"
, 6269, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dictionary", "false", "true") .c_str()) = ::testing::Message
()
;
6270 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", 6270
, gtest_ar.failure_message()) = ::testing::Message()
;
6271
6272 ClientClassDefPtr class_def = dictionary->findClass("one");
6273 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"
, 6273, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "class_def", "false", "true") .c_str()) = ::testing::Message
()
;
6274 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"
, 6274, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dynamic_cast<TemplateClientClassDef*>(class_def.get())"
, "false", "true") .c_str()) = ::testing::Message()
;
6275 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"
, 6275, gtest_ar.failure_message()) = ::testing::Message()
;
6276 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", 6276
, gtest_ar.failure_message()) = ::testing::Message()
;
6277 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"
, 6277, gtest_ar.failure_message()) = ::testing::Message()
;
6278
6279 class_def = dictionary->findClass("two");
6280 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"
, 6280, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "class_def", "false", "true") .c_str()) = ::testing::Message
()
;
6281 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"
, 6281, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dynamic_cast<TemplateClientClassDef*>(class_def.get())"
, "false", "true") .c_str()) = ::testing::Message()
;
6282 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"
, 6282, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "class_def->getValid().unspecified()", "false", "true") .
c_str()) = ::testing::Message()
;
6283}
6284
6285// Test verifies that regular configuration does not provide any user context
6286// in the address pool.
6287TEST_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"
, 6287), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6287), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6287), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_poolUserContextMissing_Test
>); void Dhcp4ParserTest_poolUserContextMissing_Test::TestBody
()
{
6288 extractConfig(PARSER_CONFIGS[0]);
6289 PoolPtr pool;
6290 getPool(string(PARSER_CONFIGS[0]), 0, 0, pool);
6291 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", 6291
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
6292 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"
, 6292, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getContext()", "true", "false") .c_str()) = ::testing
::Message()
;
6293}
6294
6295// Test verifies that it's possible to specify empty user context in the
6296// address pool.
6297TEST_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"
, 6297), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6297), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6297), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_poolUserContextEmpty_Test
>); void Dhcp4ParserTest_poolUserContextEmpty_Test::TestBody
()
{
6298 extractConfig(PARSER_CONFIGS[1]);
6299 PoolPtr pool;
6300 getPool(string(PARSER_CONFIGS[1]), 0, 0, pool);
6301 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", 6301
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
6302 ConstElementPtr ctx = pool->getContext();
6303 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", 6303
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx", "false", "true") .c_str()) = ::testing::Message()
;
6304
6305 // The context should be of type map and not contain any parameters.
6306 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"
, 6306, gtest_ar.failure_message()) = ::testing::Message()
;
6307 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"
, 6307, gtest_ar.failure_message()) = ::testing::Message()
;
6308}
6309
6310// Test verifies that it's possible to specify parameters in the user context
6311// in the address pool.
6312TEST_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"
, 6312), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6312), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6312), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_poolUserContextData_Test
>); void Dhcp4ParserTest_poolUserContextData_Test::TestBody
()
{
6313 extractConfig(PARSER_CONFIGS[2]);
6314 PoolPtr pool;
6315 getPool(string(PARSER_CONFIGS[2]), 0, 0, pool);
6316 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", 6316
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
6317 ConstElementPtr ctx = pool->getContext();
6318 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", 6318
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx", "false", "true") .c_str()) = ::testing::Message()
;
6319
6320 // The context should be of type map and contain 4 parameters.
6321 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"
, 6321, gtest_ar.failure_message()) = ::testing::Message()
;
6322 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"
, 6322, gtest_ar.failure_message()) = ::testing::Message()
;
6323 ConstElementPtr int_param = ctx->get("integer-param");
6324 ConstElementPtr str_param = ctx->get("string-param");
6325 ConstElementPtr bool_param = ctx->get("bool-param");
6326
6327 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"
, 6327, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "int_param", "false", "true") .c_str()) = ::testing::Message
()
;
6328 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"
, 6328, gtest_ar.failure_message()) = ::testing::Message()
;
6329 int64_t int_value;
6330 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_6330
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6330
; } } else gtest_label_testnothrow_6330 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6330, ("Expected: " "int_param->getValue(int_value)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
6331 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"
, 6331, gtest_ar.failure_message()) = ::testing::Message()
;
6332
6333 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"
, 6333, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "str_param", "false", "true") .c_str()) = ::testing::Message
()
;
6334 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"
, 6334, gtest_ar.failure_message()) = ::testing::Message()
;
6335 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"
, 6335, gtest_ar.failure_message()) = ::testing::Message()
;
6336
6337 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"
, 6337, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "bool_param", "false", "true") .c_str()) = ::testing::Message
()
;
6338 bool bool_value;
6339 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"
, 6339, gtest_ar.failure_message()) = ::testing::Message()
;
6340 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_6340
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6340
; } } else gtest_label_testnothrow_6340 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6340, ("Expected: " "bool_param->getValue(bool_value)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
6341 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", 6341
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "bool_value", "false", "true") .c_str()) = ::testing::Message
()
;
6342}
6343
6344// Test verifies that it's possible to specify parameters in the user context
6345// in the min-max address pool.
6346TEST_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"
, 6346), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6346), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6346), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_poolMinMaxUserContext_Test
>); void Dhcp4ParserTest_poolMinMaxUserContext_Test::TestBody
()
{
6347 extractConfig(PARSER_CONFIGS[3]);
6348 PoolPtr pool;
6349 getPool(string(PARSER_CONFIGS[3]), 0, 0, pool);
6350 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", 6350
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
1
Control jumps to 'case 0:' at line 6350
2
Taking true branch
6351 ConstElementPtr ctx = pool->getContext();
6352 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", 6352
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx", "false", "true") .c_str()) = ::testing::Message()
;
3
Control jumps to 'case 0:' at line 6352
4
Taking true branch
6353
6354 // The context should be of type map and contain 4 parameters.
6355 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"
, 6355, gtest_ar.failure_message()) = ::testing::Message()
;
5
Control jumps to 'case 0:' at line 6355
6
Assuming the condition is true
7
Taking true branch
6356 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"
, 6356, gtest_ar.failure_message()) = ::testing::Message()
;
8
Control jumps to 'case 0:' at line 6356
9
Assuming the condition is true
10
Taking true branch
6357 ConstElementPtr int_param = ctx->get("integer-param");
6358 ConstElementPtr str_param = ctx->get("string-param");
6359 ConstElementPtr bool_param = ctx->get("bool-param");
6360
6361 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"
, 6361, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "int_param", "false", "true") .c_str()) = ::testing::Message
()
;
11
Control jumps to 'case 0:' at line 6361
12
Taking true branch
6362 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"
, 6362, gtest_ar.failure_message()) = ::testing::Message()
;
13
Control jumps to 'case 0:' at line 6362
14
Assuming the condition is true
15
Taking true branch
6363 int64_t int_value;
6364 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_6364
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6364
; } } else gtest_label_testnothrow_6364 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6364, ("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 6364
17
Taking true branch
18
Assuming the condition is true
19
Taking true branch
6365 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"
, 6365, gtest_ar.failure_message()) = ::testing::Message()
;
20
Control jumps to 'case 0:' at line 6365
21
Assuming the condition is false
22
Taking false branch
6366
6367 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"
, 6367, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "str_param", "false", "true") .c_str()) = ::testing::Message
()
;
23
Control jumps to 'case 0:' at line 6367
24
Taking true branch
6368 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"
, 6368, gtest_ar.failure_message()) = ::testing::Message()
;
25
Control jumps to 'case 0:' at line 6368
26
Assuming the condition is true
27
Taking true branch
6369 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"
, 6369, gtest_ar.failure_message()) = ::testing::Message()
;
28
Control jumps to 'case 0:' at line 6369
29
Assuming the condition is true
30
Taking true branch
6370
6371 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"
, 6371, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "bool_param", "false", "true") .c_str()) = ::testing::Message
()
;
31
Control jumps to 'case 0:' at line 6371
32
Taking true branch
6372 bool bool_value;
6373 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"
, 6373, gtest_ar.failure_message()) = ::testing::Message()
;
33
Control jumps to 'case 0:' at line 6373
34
Assuming the condition is true
35
Taking true branch
6374 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_6374
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_6374
; } } else gtest_label_testnothrow_6374 : ::testing::internal
::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6374, ("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 6374
37
Taking true branch
38
Assuming the condition is false
39
Taking false branch
6375 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", 6375
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "bool_value", "false", "true") .c_str()) = ::testing::Message
()
;
40
Control jumps to 'case 0:' at line 6375
41
Calling constructor for 'AssertionResult'
6376}
6377
6378// Test verifies the error message for an incorrect pool range
6379// is what we expect.
6380TEST_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"
, 6380), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6380), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6380), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_invalidPoolRange_Test
>); void Dhcp4ParserTest_invalidPoolRange_Test::TestBody()
{
6381 string config = "{ " + genIfaceConfig() + ", \n" +
6382 "\"valid-lifetime\": 4000, \n"
6383 "\"rebind-timer\": 2000, \n"
6384 "\"renew-timer\": 1000, \n"
6385 "\"subnet4\": [ { \n"
6386 " \"id\": 1, \n"
6387 " \"pools\": [ { \"pool\": \"192.0.2.1 - 19.2.0.200\" } ], \n"
6388 " \"subnet\": \"192.0.2.0/24\" \n"
6389 " } ] \n"
6390 "} \n";
6391
6392 string expected = "Failed to create pool defined by: "
6393 "192.0.2.1-19.2.0.200 (<string>:7:26)";
6394
6395 configure(config, CONTROL_RESULT_ERROR, expected);
6396}
6397
6398// Test verifies the error message for an outside subnet pool range
6399// is what we expect.
6400TEST_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"
, 6400), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6400), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6400), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_outsideSubnetPool_Test
>); void Dhcp4ParserTest_outsideSubnetPool_Test::TestBody(
)
{
6401 string config = "{ " + genIfaceConfig() + ", \n" +
6402 "\"valid-lifetime\": 4000, \n"
6403 "\"rebind-timer\": 2000, \n"
6404 "\"renew-timer\": 1000, \n"
6405 "\"subnet4\": [ { \n"
6406 " \"id\": 1, \n"
6407 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ], \n"
6408 " \"subnet\": \"10.0.2.0/24\" \n"
6409 " } ] \n"
6410 "} \n";
6411
6412 string expected = "subnet configuration failed: "
6413 "a pool of type V4, with the following address range: "
6414 "192.0.2.1-192.0.2.100 does not match the prefix of a subnet: "
6415 "10.0.2.0/24 to which it is being added (<string>:5:14)";
6416
6417 configure(config, CONTROL_RESULT_ERROR, expected);
6418}
6419
6420// Test verifies that empty shared networks are accepted.
6421TEST_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"
, 6421), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6421), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6421), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworksEmpty_Test
>); void Dhcp4ParserTest_sharedNetworksEmpty_Test::TestBody
()
{
6422 string config = "{\n"
6423 "\"valid-lifetime\": 4000, \n"
6424 "\"rebind-timer\": 2000, \n"
6425 "\"renew-timer\": 1000, \n"
6426 "\"subnet4\": [ { \n"
6427 " \"id\": 1, \n"
6428 " \"pools\": [ { \"pool\": \"10.0.2.1 - 10.0.2.100\" } ], \n"
6429 " \"subnet\": \"10.0.2.0/24\" \n"
6430 " } ],\n"
6431 "\"shared-networks\": [ ]\n"
6432 "} \n";
6433
6434 configure(config, CONTROL_RESULT_SUCCESS, "");
6435}
6436
6437// Test verifies that if a shared network is defined, it at least has to have
6438// a name.
6439TEST_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"
, 6439), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6439), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6439), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworksNoName_Test
>); void Dhcp4ParserTest_sharedNetworksNoName_Test::TestBody
()
{
6440 string config = "{\n"
6441 "\"valid-lifetime\": 4000, \n"
6442 "\"rebind-timer\": 2000, \n"
6443 "\"renew-timer\": 1000, \n"
6444 "\"subnet4\": [ { \n"
6445 " \"id\": 1, \n"
6446 " \"pools\": [ { \"pool\": \"10.0.2.1 - 10.0.2.100\" } ], \n"
6447 " \"subnet\": \"10.0.2.0/24\" \n"
6448 " } ],\n"
6449 "\"shared-networks\": [ { } ]\n"
6450 "} \n";
6451
6452 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_6452; } 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_6452; } 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_6452; } } else gtest_label_testthrow_6452
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6452, gtest_msg.value.c_str()) = ::testing::Message()
;
6453}
6454
6455// Test verifies that empty shared networks are accepted.
6456TEST_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"
, 6456), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6456), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6456), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworksEmptyName_Test
>); void Dhcp4ParserTest_sharedNetworksEmptyName_Test::TestBody
()
{
6457 string config = "{\n"
6458 "\"valid-lifetime\": 4000, \n"
6459 "\"rebind-timer\": 2000, \n"
6460 "\"renew-timer\": 1000, \n"
6461 "\"subnet4\": [ { \n"
6462 " \"id\": 1, \n"
6463 " \"pools\": [ { \"pool\": \"10.0.2.1 - 10.0.2.100\" } ], \n"
6464 " \"subnet\": \"10.0.2.0/24\" \n"
6465 " } ],\n"
6466 "\"shared-networks\": [ { \"name\": \"\" } ]\n"
6467 "} \n";
6468
6469 configure(config, CONTROL_RESULT_ERROR,
6470 "Shared-network with subnets is missing mandatory 'name' parameter");
6471}
6472
6473// Test verifies that a degenerated shared-network (no subnets) is
6474// accepted.
6475TEST_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"
, 6475), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6475), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6475), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworksName_Test
>); void Dhcp4ParserTest_sharedNetworksName_Test::TestBody
()
{
6476 string config = "{\n"
6477 "\"subnet4\": [ { \n"
6478 " \"id\": 1, \n"
6479 " \"pools\": [ { \"pool\": \"10.0.2.1 - 10.0.2.100\" } ], \n"
6480 " \"subnet\": \"10.0.2.0/24\" \n"
6481 " } ],\n"
6482 "\"shared-networks\": [ { \"name\": \"foo\" } ]\n"
6483 "} \n";
6484
6485 configure(config, CONTROL_RESULT_SUCCESS, "");
6486
6487 // Now verify that the shared network was indeed configured.
6488 CfgSharedNetworks4Ptr cfg_net = CfgMgr::instance().getStagingCfg()
6489 ->getCfgSharedNetworks4();
6490 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"
, 6490, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg_net", "false", "true") .c_str()) = ::testing::Message(
)
;
6491 const SharedNetwork4Collection* nets = cfg_net->getAll();
6492 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", 6492
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "nets", "false", "true") .c_str()) = ::testing::Message()
;
6493 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"
, 6493, gtest_ar.failure_message()) = ::testing::Message()
;
6494 SharedNetwork4Ptr net = *(nets->begin());
6495 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", 6495
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "net", "false", "true") .c_str()) = ::testing::Message()
;
6496 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", 6496
, gtest_ar.failure_message()) = ::testing::Message()
;
6497
6498 // Verify that there are no subnets in this shared-network
6499 const Subnet4SimpleCollection* subs = net->getAllSubnets();
6500 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", 6500
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subs", "false", "true") .c_str()) = ::testing::Message()
;
6501 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"
, 6501, gtest_ar.failure_message()) = ::testing::Message()
;
6502}
6503
6504// Test verifies that a degenerated shared-network (just one subnet) is
6505// accepted. Also tests that, unless explicitly specified, the subnet
6506// gets default values.
6507TEST_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"
, 6507), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6507), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6507), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworks1subnet_Test
>); void Dhcp4ParserTest_sharedNetworks1subnet_Test::TestBody
()
{
6508 string config = "{\n"
6509 "\"shared-networks\": [ {\n"
6510 " \"name\": \"foo\"\n,"
6511 " \"subnet4\": [ { \n"
6512 " \"id\": 1,\n"
6513 " \"subnet\": \"192.0.2.0/24\",\n"
6514 " \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\" } ]\n"
6515 " } ]\n"
6516 " } ]\n"
6517 "} \n";
6518
6519 configure(config, CONTROL_RESULT_SUCCESS, "");
6520
6521 // Now verify that the shared network was indeed configured.
6522 CfgSharedNetworks4Ptr cfg_net = CfgMgr::instance().getStagingCfg()
6523 ->getCfgSharedNetworks4();
6524 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"
, 6524, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg_net", "false", "true") .c_str()) = ::testing::Message(
)
;
6525
6526 // There should be exactly one shared subnet.
6527 const SharedNetwork4Collection* nets = cfg_net->getAll();
6528 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", 6528
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "nets", "false", "true") .c_str()) = ::testing::Message()
;
6529 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"
, 6529, gtest_ar.failure_message()) = ::testing::Message()
;
6530
6531 SharedNetwork4Ptr net = *(nets->begin());
6532 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", 6532
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "net", "false", "true") .c_str()) = ::testing::Message()
;
6533 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", 6533
, gtest_ar.failure_message()) = ::testing::Message()
;
6534
6535 // It should have one subnet. The subnet should have default values.
6536 const Subnet4SimpleCollection* subs = net->getAllSubnets();
6537 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", 6537
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subs", "false", "true") .c_str()) = ::testing::Message()
;
6538 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"
, 6538, gtest_ar.failure_message()) = ::testing::Message()
;
6539 checkSubnet(*subs, "192.0.2.0/24", 0, 0, 7200);
6540
6541 // Now make sure the subnet was added to global list of subnets.
6542 CfgSubnets4Ptr subnets4 = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
6543 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"
, 6543, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets4", "false", "true") .c_str()) = ::testing::Message
()
;
6544
6545 const Subnet4Collection* gsubs = subnets4->getAll();
6546 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"
, 6546, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "gsubs", "false", "true") .c_str()) = ::testing::Message()
;
6547 checkSubnet(*gsubs, "192.0.2.0/24", 0, 0, 7200);
6548}
6549
6550// Test verifies that a proper shared-network (three subnets) is
6551// accepted. It verifies several things:
6552// - that more than one subnet can be added to shared subnets
6553// - that each subnet being part of the shared subnets is also stored in
6554// global subnets collection
6555// - that a subnet can inherit global values
6556// - that subnet can override global parameters
6557// - that overridden parameters only affect one subnet and not others
6558TEST_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"
, 6558), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6558), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6558), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworks3subnets_Test
>); void Dhcp4ParserTest_sharedNetworks3subnets_Test::TestBody
()
{
6559 string config = "{\n"
6560 "\"valid-lifetime\": 4000, \n"
6561 "\"min-valid-lifetime\": 3000, \n"
6562 "\"max-valid-lifetime\": 5000, \n"
6563 "\"renew-timer\": 1000, \n"
6564 "\"rebind-timer\": 2000, \n"
6565 "\"shared-networks\": [ {\n"
6566 " \"name\": \"foo\"\n,"
6567 " \"subnet4\": [\n"
6568 " { \n"
6569 " \"id\": 1,\n"
6570 " \"subnet\": \"192.0.1.0/24\",\n"
6571 " \"pools\": [ { \"pool\": \"192.0.1.1-192.0.1.10\" } ]\n"
6572 " },\n"
6573 " { \n"
6574 " \"id\": 2,\n"
6575 " \"subnet\": \"192.0.2.0/24\",\n"
6576 " \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\" } ],\n"
6577 " \"renew-timer\": 2,\n"
6578 " \"rebind-timer\": 22,\n"
6579 " \"valid-lifetime\": 222,\n"
6580 " \"min-valid-lifetime\": 111,\n"
6581 " \"max-valid-lifetime\": 333\n"
6582 " },\n"
6583 " { \n"
6584 " \"id\": 3,\n"
6585 " \"subnet\": \"192.0.3.0/24\",\n"
6586 " \"pools\": [ { \"pool\": \"192.0.3.1-192.0.3.10\" } ]\n"
6587 " }\n"
6588 " ]\n"
6589 " } ]\n"
6590 "} \n";
6591
6592 configure(config, CONTROL_RESULT_SUCCESS, "");
6593
6594 // Now verify that the shared network was indeed configured.
6595 CfgSharedNetworks4Ptr cfg_net = CfgMgr::instance().getStagingCfg()
6596 ->getCfgSharedNetworks4();
6597
6598 // There is expected one shared subnet.
6599 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"
, 6599, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg_net", "false", "true") .c_str()) = ::testing::Message(
)
;
6600 const SharedNetwork4Collection* nets = cfg_net->getAll();
6601 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", 6601
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "nets", "false", "true") .c_str()) = ::testing::Message()
;
6602 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"
, 6602, gtest_ar.failure_message()) = ::testing::Message()
;
6603
6604 SharedNetwork4Ptr net = *(nets->begin());
6605 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", 6605
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "net", "false", "true") .c_str()) = ::testing::Message()
;
6606
6607 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", 6607
, gtest_ar.failure_message()) = ::testing::Message()
;
6608
6609 const Subnet4SimpleCollection* subs = net->getAllSubnets();
6610 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", 6610
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subs", "false", "true") .c_str()) = ::testing::Message()
;
6611 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"
, 6611, gtest_ar.failure_message()) = ::testing::Message()
;
6612 checkSubnet(*subs, "192.0.1.0/24", 1000, 2000, 4000, 3000, 5000);
6613 checkSubnet(*subs, "192.0.2.0/24", 2, 22, 222, 111, 333);
6614 checkSubnet(*subs, "192.0.3.0/24", 1000, 2000, 4000, 3000, 5000);
6615
6616 // Now make sure the subnet was added to global list of subnets.
6617 CfgSubnets4Ptr subnets4 = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
6618 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"
, 6618, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets4", "false", "true") .c_str()) = ::testing::Message
()
;
6619
6620 const Subnet4Collection* gsubs = subnets4->getAll();
6621 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"
, 6621, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "gsubs", "false", "true") .c_str()) = ::testing::Message()
;
6622 checkSubnet(*gsubs, "192.0.1.0/24", 1000, 2000, 4000, 3000, 5000);
6623 checkSubnet(*gsubs, "192.0.2.0/24", 2, 22, 222, 111, 333);
6624 checkSubnet(*gsubs, "192.0.3.0/24", 1000, 2000, 4000, 3000, 5000);
6625}
6626
6627// This test checks if parameters are derived properly:
6628// - global to shared network
6629// - shared network to subnet
6630// Also, it tests that more than one shared network can be defined.
6631TEST_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"
, 6631), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6631), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6631), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworksDerive_Test
>); void Dhcp4ParserTest_sharedNetworksDerive_Test::TestBody
()
{
6632
6633 // We need to fake the interfaces present, because we want to test
6634 // interface names inheritance. However, there are sanity checks
6635 // on subnet level that would refuse the value if the interface
6636 // is not present.
6637 IfaceMgrTestConfig iface_config(true);
6638
6639 // This config is structured in a way that the first shared
6640 // subnet have many parameters defined. The first subnet
6641 // should inherit them. The second subnet overrides all
6642 // values and those values should be used, not those from
6643 // shared network scope.
6644 string config = "{\n"
6645 "\"renew-timer\": 1, \n" // global values here
6646 "\"rebind-timer\": 2, \n"
6647 "\"valid-lifetime\": 4, \n"
6648 "\"min-valid-lifetime\": 3, \n"
6649 "\"max-valid-lifetime\": 5, \n"
6650 "\"shared-networks\": [ {\n"
6651 " \"name\": \"foo\"\n," // shared network values here
6652 " \"interface\": \"eth0\",\n"
6653 " \"match-client-id\": false,\n"
6654 " \"authoritative\": true,\n"
6655 " \"next-server\": \"1.2.3.4\",\n"
6656 " \"server-hostname\": \"foo\",\n"
6657 " \"boot-file-name\": \"bar\",\n"
6658 " \"store-extended-info\": true,\n"
6659 " \"relay\": {\n"
6660 " \"ip-addresses\": [ \"5.6.7.8\" ]\n"
6661 " },\n"
6662 " \"reservations-global\": false,\n"
6663 " \"reservations-in-subnet\": false,\n"
6664 " \"renew-timer\": 10,\n"
6665 " \"rebind-timer\": 20,\n"
6666 " \"valid-lifetime\": 40,\n"
6667 " \"min-valid-lifetime\": 30,\n"
6668 " \"max-valid-lifetime\": 50,\n"
6669 " \"subnet4\": [\n"
6670 " { \n"
6671 " \"id\": 1,\n"
6672 " \"subnet\": \"192.0.1.0/24\",\n"
6673 " \"pools\": [ { \"pool\": \"192.0.1.1-192.0.1.10\" } ]\n"
6674 " },\n"
6675 " { \n"
6676 " \"id\": 2,\n"
6677 " \"subnet\": \"192.0.2.0/24\",\n"
6678 " \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\" } ],\n"
6679 " \"renew-timer\": 100,\n"
6680 " \"rebind-timer\": 200,\n"
6681 " \"valid-lifetime\": 400,\n"
6682 " \"min-valid-lifetime\": 300,\n"
6683 " \"max-valid-lifetime\": 500,\n"
6684 " \"match-client-id\": true,\n"
6685 " \"next-server\": \"11.22.33.44\",\n"
6686 " \"server-hostname\": \"some-name.example.org\",\n"
6687 " \"boot-file-name\": \"bootfile.efi\",\n"
6688 " \"relay\": {\n"
6689 " \"ip-addresses\": [ \"55.66.77.88\" ]\n"
6690 " },\n"
6691 " \"reservations-global\": false,\n"
6692 " \"reservations-in-subnet\": true,\n"
6693 " \"reservations-out-of-pool\": true\n"
6694 " }\n"
6695 " ]\n"
6696 " },\n"
6697 "{ // second shared-network starts here\n"
6698 " \"name\": \"bar\",\n"
6699 " \"subnet4\": [\n"
6700 " {\n"
6701 " \"id\": 3,\n"
6702 " \"subnet\": \"192.0.3.0/24\",\n"
6703 " \"pools\": [ { \"pool\": \"192.0.3.1-192.0.3.10\" } ]\n"
6704 " }\n"
6705 " ]\n"
6706 " } ]\n"
6707 "} \n";
6708
6709 configure(config, CONTROL_RESULT_SUCCESS, "");
6710
6711 // Now verify that the shared network was indeed configured.
6712 CfgSharedNetworks4Ptr cfg_net = CfgMgr::instance().getStagingCfg()
6713 ->getCfgSharedNetworks4();
6714
6715 // Two shared networks are expected.
6716 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"
, 6716, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg_net", "false", "true") .c_str()) = ::testing::Message(
)
;
6717 const SharedNetwork4Collection* nets = cfg_net->getAll();
6718 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", 6718
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "nets", "false", "true") .c_str()) = ::testing::Message()
;
6719 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"
, 6719, gtest_ar.failure_message()) = ::testing::Message()
;
6720
6721 // Let's check the first one.
6722 SharedNetwork4Ptr net = nets->at(0);
6723 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", 6723
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "net", "false", "true") .c_str()) = ::testing::Message()
;
6724
6725 // The first shared network has two subnets.
6726 const Subnet4SimpleCollection* subs = net->getAllSubnets();
6727 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", 6727
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subs", "false", "true") .c_str()) = ::testing::Message()
;
6728 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"
, 6728, gtest_ar.failure_message()) = ::testing::Message()
;
6729
6730 // For the first subnet, the renew-timer should be 10, because it was
6731 // derived from shared-network level. Other parameters a derived
6732 // from global scope to shared-network level and later again to
6733 // subnet4 level.
6734 Subnet4Ptr s = checkSubnet(*subs, "192.0.1.0/24", 10, 20, 40, 30, 50);
6735 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", 6735
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s", "false", "true") .c_str()) = ::testing::Message()
;
6736
6737 // These are values derived from shared network scope:
6738 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"
, 6738, gtest_ar.failure_message()) = ::testing::Message()
;
6739 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"
, 6739, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getMatchClientId()", "true", "false") .c_str()) = ::
testing::Message()
;
6740 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"
, 6740, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getAuthoritative()", "false", "true") .c_str()) = ::
testing::Message()
;
6741 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"
, 6741, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getStoreExtendedInfo()", "false", "true") .c_str()) =
::testing::Message()
;
6742 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"
, 6742, gtest_ar.failure_message()) = ::testing::Message()
;
6743 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"
, 6743, gtest_ar.failure_message()) = ::testing::Message()
;
6744 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"
, 6744, gtest_ar.failure_message()) = ::testing::Message()
;
6745 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"
, 6745, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->hasRelayAddress(IOAddress(\"5.6.7.8\"))", "false", "true"
) .c_str()) = ::testing::Message()
;
6746 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"
, 6746, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsGlobal()", "true", "false") .c_str())
= ::testing::Message()
;
6747 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"
, 6747, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsInSubnet()", "true", "false") .c_str(
)) = ::testing::Message()
;
6748 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"
, 6748, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsOutOfPool()", "true", "false") .c_str
()) = ::testing::Message()
;
6749
6750 // For the second subnet, the renew-timer should be 100, because it
6751 // was specified explicitly. Other parameters a derived
6752 // from global scope to shared-network level and later again to
6753 // subnet4 level.
6754 s = checkSubnet(*subs, "192.0.2.0/24", 100, 200, 400, 300, 500);
6755
6756 // These are values derived from shared network scope:
6757 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"
, 6757, gtest_ar.failure_message()) = ::testing::Message()
;
6758 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"
, 6758, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getMatchClientId()", "false", "true") .c_str()) = ::
testing::Message()
;
6759 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"
, 6759, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getAuthoritative()", "false", "true") .c_str()) = ::
testing::Message()
;
6760 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"
, 6760, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getStoreExtendedInfo()", "false", "true") .c_str()) =
::testing::Message()
;
6761 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"
, 6761, gtest_ar.failure_message()) = ::testing::Message()
;
6762 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"
, 6762, gtest_ar.failure_message()) = ::testing::Message()
;
6763 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"
, 6763, gtest_ar.failure_message()) = ::testing::Message()
;
6764 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"
, 6764, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->hasRelayAddress(IOAddress(\"55.66.77.88\"))", "false"
, "true") .c_str()) = ::testing::Message()
;
6765 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"
, 6765, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsGlobal()", "true", "false") .c_str())
= ::testing::Message()
;
6766 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"
, 6766, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsInSubnet()", "false", "true") .c_str(
)) = ::testing::Message()
;
6767 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"
, 6767, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsOutOfPool()", "false", "true") .c_str
()) = ::testing::Message()
;
6768
6769 // Ok, now check the second shared subnet.
6770 net = nets->at(1);
6771 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", 6771
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "net", "false", "true") .c_str()) = ::testing::Message()
;
6772
6773 subs = net->getAllSubnets();
6774 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", 6774
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subs", "false", "true") .c_str()) = ::testing::Message()
;
6775 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"
, 6775, gtest_ar.failure_message()) = ::testing::Message()
;
6776
6777 // This subnet should derive its renew-timer from global scope.
6778 // All other parameters should have default values.
6779 s = checkSubnet(*subs, "192.0.3.0/24", 1, 2, 4, 3, 5);
6780 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"
, 6780, gtest_ar.failure_message()) = ::testing::Message()
;
6781 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"
, 6781, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getMatchClientId()", "false", "true") .c_str()) = ::
testing::Message()
;
6782 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"
, 6782, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getAuthoritative()", "true", "false") .c_str()) = ::
testing::Message()
;
6783 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"
, 6783, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getStoreExtendedInfo()", "true", "false") .c_str()) =
::testing::Message()
;
6784 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"
, 6784, gtest_ar.failure_message()) = ::testing::Message()
;
6785 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"
, 6785, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getSname().empty()", "false", "true") .c_str()) = ::
testing::Message()
;
6786 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"
, 6786, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getFilename().empty()", "false", "true") .c_str()) =
::testing::Message()
;
6787 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"
, 6787, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->hasRelays()", "true", "false") .c_str()) = ::testing
::Message()
;
6788 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"
, 6788, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsGlobal()", "true", "false") .c_str())
= ::testing::Message()
;
6789 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"
, 6789, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsInSubnet()", "false", "true") .c_str(
)) = ::testing::Message()
;
6790 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"
, 6790, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s->getReservationsOutOfPool()", "true", "false") .c_str
()) = ::testing::Message()
;
6791}
6792
6793// Since it is not allowed to define both interface-id and interface
6794// for the same subnet, we need dedicated test that will check
6795// interface separately.
6796TEST_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"
, 6796), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6796), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6796), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworksDeriveInterfaces_Test
>); void Dhcp4ParserTest_sharedNetworksDeriveInterfaces_Test
::TestBody()
{
6797
6798 // We need to fake the interfaces present, because we want to test
6799 // interface names inheritance. However, there are sanity checks
6800 // on subnet level that would refuse the value if the interface
6801 // is not present.
6802 IfaceMgrTestConfig iface_config(true);
6803
6804 string config = "{\n"
6805 "\"shared-networks\": [ {\n"
6806 " \"name\": \"foo\"\n,"
6807 " \"interface\": \"eth0\",\n"
6808 " \"rebind-timer\": 10, \n"
6809 " \"subnet4\": [\n"
6810 " { \n"
6811 " \"id\": 1, \n"
6812 " \"subnet\": \"192.0.1.0/24\",\n"
6813 " \"pools\": [ { \"pool\": \"192.0.1.1-192.0.1.10\" } ]\n"
6814 " },\n"
6815 " { \n"
6816 " \"id\": 2, \n"
6817 " \"subnet\": \"192.0.2.0/24\",\n"
6818 " \"rebind-timer\": 100, \n"
6819 " \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\" } ],\n"
6820 " \"interface\": \"eth0\"\n"
6821 " }\n"
6822 " ]\n"
6823 " },\n"
6824 "{ // second shared-network starts here\n"
6825 " \"name\": \"bar\",\n"
6826 " \"subnet4\": [\n"
6827 " {\n"
6828 " \"id\": 3, \n"
6829 " \"subnet\": \"192.0.3.0/24\",\n"
6830 " \"pools\": [ { \"pool\": \"192.0.3.1-192.0.3.10\" } ]\n"
6831 " }\n"
6832 " ]\n"
6833 "} ]\n"
6834 "} \n";
6835
6836 configure(config, CONTROL_RESULT_SUCCESS, "");
6837
6838 // Now verify that the shared network was indeed configured.
6839 CfgSharedNetworks4Ptr cfg_net = CfgMgr::instance().getStagingCfg()
6840 ->getCfgSharedNetworks4();
6841
6842 // Two shared networks are expected.
6843 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"
, 6843, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg_net", "false", "true") .c_str()) = ::testing::Message(
)
;
6844 const SharedNetwork4Collection* nets = cfg_net->getAll();
6845 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", 6845
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "nets", "false", "true") .c_str()) = ::testing::Message()
;
6846 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"
, 6846, gtest_ar.failure_message()) = ::testing::Message()
;
6847
6848 // Let's check the first one.
6849 SharedNetwork4Ptr net = nets->at(0);
6850 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", 6850
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "net", "false", "true") .c_str()) = ::testing::Message()
;
6851
6852 const Subnet4SimpleCollection* subs = net->getAllSubnets();
6853 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", 6853
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subs", "false", "true") .c_str()) = ::testing::Message()
;
6854 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"
, 6854, gtest_ar.failure_message()) = ::testing::Message()
;
6855
6856 // For the first subnet, the rebind-timer should be 10, because it was
6857 // derived from shared-network level. Other parameters a derived
6858 // from global scope to shared-network level and later again to
6859 // subnet4 level.
6860 Subnet4Ptr s = checkSubnet(*subs, "192.0.1.0/24", 0, 10, 7200);
6861 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", 6861
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "s", "false", "true") .c_str()) = ::testing::Message()
;
6862 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"
, 6862, gtest_ar.failure_message()) = ::testing::Message()
;
6863
6864 // For the second subnet, the rebind-timer should be 100, because it
6865 // was specified explicitly. Other parameters a derived
6866 // from global scope to shared-network level and later again to
6867 // subnet4 level.
6868 checkSubnet(*subs, "192.0.2.0/24", 0, 100, 7200);
6869 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"
, 6869, gtest_ar.failure_message()) = ::testing::Message()
;
6870
6871 // Ok, now check the second shared subnet.
6872 net = nets->at(1);
6873 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", 6873
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "net", "false", "true") .c_str()) = ::testing::Message()
;
6874
6875 subs = net->getAllSubnets();
6876 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", 6876
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subs", "false", "true") .c_str()) = ::testing::Message()
;
6877 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"
, 6877, gtest_ar.failure_message()) = ::testing::Message()
;
6878
6879 // This subnet should derive its rebind-timer from global scope.
6880 s = checkSubnet(*subs, "192.0.3.0/24", 0, 0, 7200);
6881 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"
, 6881, gtest_ar.failure_message()) = ::testing::Message()
;
6882}
6883
6884// It is not allowed to have different values for interfaces names is subnets
6885// in the same shared network.
6886TEST_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"
, 6886), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6886), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6886), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_sharedNetworksInterfacesMixed_Test
>); void Dhcp4ParserTest_sharedNetworksInterfacesMixed_Test
::TestBody()
{
6887
6888 // We need to fake the interfaces present, because we want to test
6889 // interface names inheritance. However, there are sanity checks
6890 // on subnet level that would refuse the value if the interface
6891 // is not present.
6892 IfaceMgrTestConfig iface_config(true);
6893
6894 string config = "{\n"
6895 "\"shared-networks\": [ {\n"
6896 " \"name\": \"foo\"\n,"
6897 " \"subnet4\": [\n"
6898 " { \n"
6899 " \"id\": 1, \n"
6900 " \"subnet\": \"192.0.1.0/24\",\n"
6901 " \"interface\": \"eth0\"\n"
6902 " },\n"
6903 " { \n"
6904 " \"id\": 2, \n"
6905 " \"subnet\": \"192.0.2.0/24\",\n"
6906 " \"interface\": \"eth1\"\n"
6907 " }\n"
6908 " ]\n"
6909 " } ]\n"
6910 "} \n";
6911
6912 configure(config, CONTROL_RESULT_ERROR, "Subnet 192.0.2.0/24 has specified "
6913 "interface eth1, but earlier subnet in the same shared-network "
6914 "or the shared-network itself used eth0");
6915}
6916
6917// This test checks multiple host data sources.
6918TEST_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", 6918
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6918), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6918), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_hostsDatabases_Test
>); void Dhcp4ParserTest_hostsDatabases_Test::TestBody()
{
6919
6920 string config = PARSER_CONFIGS[4];
6921 extractConfig(config);
6922 configure(config, CONTROL_RESULT_SUCCESS, "");
6923
6924 // Check database config
6925 ConstCfgDbAccessPtr cfgdb =
6926 CfgMgr::instance().getStagingCfg()->getCfgDbAccess();
6927 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"
, 6927, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfgdb", "false", "true") .c_str()) = ::testing::Message()
;
6928 const std::list<std::string>& hal = cfgdb->getHostDbAccessStringList();
6929 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"
, 6929, gtest_ar.failure_message()) = ::testing::Message()
;
6930 // Keywords are in alphabetical order
6931 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"
, 6931, gtest_ar.failure_message()) = ::testing::Message()
;
6932 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"
, 6932, gtest_ar.failure_message()) = ::testing::Message()
;
6933}
6934
6935// This test checks comments. Please keep it last.
6936TEST_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", 6936
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6936), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 6936), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_comments_Test
>); void Dhcp4ParserTest_comments_Test::TestBody()
{
6937 Dhcpv4SrvTest::setSocketTestPath();
6938 file::PathChecker::enableEnforcement(false);
6939
6940 string config = PARSER_CONFIGS[6];
6941 extractConfig(config);
6942 configure(config, CONTROL_RESULT_SUCCESS, "");
6943
6944 // Check global user context.
6945 ConstElementPtr ctx = CfgMgr::instance().getStagingCfg()->getContext();
6946 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", 6946
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx", "false", "true") .c_str()) = ::testing::Message()
;
6947 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"
, 6947, gtest_ar.failure_message()) = ::testing::Message()
;
6948 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"
, 6948, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx->get(\"comment\")", "false", "true") .c_str()) = ::
testing::Message()
;
6949 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"
, 6949, gtest_ar.failure_message()) = ::testing::Message()
;
6950
6951 // There is a network interface configuration.
6952 ConstCfgIfacePtr iface = CfgMgr::instance().getStagingCfg()->getCfgIface();
6953 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"
, 6953, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "iface", "false", "true") .c_str()) = ::testing::Message()
;
6954
6955 // Check network interface configuration user context.
6956 ConstElementPtr ctx_iface = iface->getContext();
6957 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"
, 6957, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_iface", "false", "true") .c_str()) = ::testing::Message
()
;
6958 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"
, 6958, gtest_ar.failure_message()) = ::testing::Message()
;
6959 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"
, 6959, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_iface->get(\"comment\")", "false", "true") .c_str()
) = ::testing::Message()
;
6960 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", 6960
, gtest_ar.failure_message()) = ::testing::Message()
;
6961
6962 ConstElementPtr json;
6963 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"
, 6963, "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", 6963
, "Failed") = ::testing::Message() << "json = parseDHCP4(config, true)"
<< " threw non-std::exception"; } }
;
6964 bool const too_long(SocketPath::isTooLongFromConfig(json));
6965 if (too_long) {
6966 return;
6967 }
6968
6969 // There is a global option definition.
6970 const OptionDefinitionPtr& opt_def =
6971 LibDHCP::getRuntimeOptionDef("isc", 100);
6972 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"
, 6972, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_def", "false", "true") .c_str()) = ::testing::Message(
)
;
6973 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"
, 6973, gtest_ar.failure_message()) = ::testing::Message()
;
6974 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"
, 6974, gtest_ar.failure_message()) = ::testing::Message()
;
6975 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"
, 6975, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_def->getArrayType()", "true", "false") .c_str()) = ::
testing::Message()
;
6976 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"
, 6976, gtest_ar.failure_message()) = ::testing::Message()
;
6977 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"
, 6977, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_def->getEncapsulatedSpace().empty()", "false", "true"
) .c_str()) = ::testing::Message()
;
6978
6979 // Check option definition user context.
6980 ConstElementPtr ctx_opt_def = opt_def->getContext();
6981 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"
, 6981, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_opt_def", "false", "true") .c_str()) = ::testing::Message
()
;
6982 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"
, 6982, gtest_ar.failure_message()) = ::testing::Message()
;
6983 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"
, 6983, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_opt_def->get(\"comment\")", "false", "true") .c_str
()) = ::testing::Message()
;
6984 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", 6984
, gtest_ar.failure_message()) = ::testing::Message()
;
6985
6986 // There is an option descriptor aka option data.
6987 const OptionDescriptor& opt_desc =
6988 CfgMgr::instance().getStagingCfg()->getCfgOption()->
6989 get(DHCP4_OPTION_SPACE"dhcp4", DHO_DHCP_MESSAGE);
6990 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"
, 6990, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_desc.option_", "false", "true") .c_str()) = ::testing::
Message()
;
6991 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"
, 6991, gtest_ar.failure_message()) = ::testing::Message()
;
6992
6993 // Check option descriptor user context.
6994 ConstElementPtr ctx_opt_desc = opt_desc.getContext();
6995 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"
, 6995, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_opt_desc", "false", "true") .c_str()) = ::testing::Message
()
;
6996 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"
, 6996, gtest_ar.failure_message()) = ::testing::Message()
;
6997 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"
, 6997, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_opt_desc->get(\"comment\")", "false", "true") .c_str
()) = ::testing::Message()
;
6998 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", 6998
, gtest_ar.failure_message()) = ::testing::Message()
;
6999
7000 // And there are some client classes.
7001 const ClientClassDictionaryPtr& dict =
7002 CfgMgr::instance().getStagingCfg()->getClientClassDictionary();
7003 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", 7003
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dict", "false", "true") .c_str()) = ::testing::Message()
;
7004 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"
, 7004, gtest_ar.failure_message()) = ::testing::Message()
;
7005 ClientClassDefPtr cclass = dict->findClass("all");
7006 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"
, 7006, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cclass", "false", "true") .c_str()) = ::testing::Message()
;
7007 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"
, 7007, gtest_ar.failure_message()) = ::testing::Message()
;
7008 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"
, 7008, gtest_ar.failure_message()) = ::testing::Message()
;
7009
7010 // Check client class user context.
7011 ConstElementPtr ctx_class = cclass->getContext();
7012 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"
, 7012, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_class", "false", "true") .c_str()) = ::testing::Message
()
;
7013 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"
, 7013, gtest_ar.failure_message()) = ::testing::Message()
;
7014 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"
, 7014, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_class->get(\"comment\")", "false", "true") .c_str()
) = ::testing::Message()
;
7015 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", 7015
, gtest_ar.failure_message()) = ::testing::Message()
;
7016
7017 // The 'none' class has no user-context/comment.
7018 cclass = dict->findClass("none");
7019 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"
, 7019, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cclass", "false", "true") .c_str()) = ::testing::Message()
;
7020 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"
, 7020, gtest_ar.failure_message()) = ::testing::Message()
;
7021 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"
, 7021, gtest_ar.failure_message()) = ::testing::Message()
;
7022 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"
, 7022, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cclass->getContext()", "true", "false") .c_str()) = ::testing
::Message()
;
7023
7024 // The 'both' class has a user context and a comment.
7025 cclass = dict->findClass("both");
7026 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"
, 7026, gtest_ar.failure_message()) = ::testing::Message()
;
7027 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"
, 7027, gtest_ar.failure_message()) = ::testing::Message()
;
7028 ctx_class = cclass->getContext();
7029 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"
, 7029, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_class", "false", "true") .c_str()) = ::testing::Message
()
;
7030 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"
, 7030, gtest_ar.failure_message()) = ::testing::Message()
;
7031 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"
, 7031, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_class->get(\"comment\")", "false", "true") .c_str()
) = ::testing::Message()
;
7032 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", 7032
, gtest_ar.failure_message()) = ::testing::Message()
;
7033 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"
, 7033, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_class->get(\"version\")", "false", "true") .c_str()
) = ::testing::Message()
;
7034 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", 7034
, gtest_ar.failure_message()) = ::testing::Message()
;
7035
7036 // There is a UNIX control socket.
7037 ConstElementPtr socket =
7038 CfgMgr::instance().getStagingCfg()->getUnixControlSocketInfo();
7039 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"
, 7039, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket", "false", "true") .c_str()) = ::testing::Message()
;
7040 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"
, 7040, gtest_ar.failure_message()) = ::testing::Message()
;
7041 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"
, 7041, gtest_ar.failure_message()) = ::testing::Message()
;
7042 socket = socket->get(0);
7043 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"
, 7043, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket", "false", "true") .c_str()) = ::testing::Message()
;
7044 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"
, 7044, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket->get(\"socket-type\")", "false", "true") .c_str(
)) = ::testing::Message()
;
7045 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"
, 7045, gtest_ar.failure_message()) = ::testing::Message()
;
7046 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"
, 7046, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket->get(\"socket-name\")", "false", "true") .c_str(
)) = ::testing::Message()
;
7047 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", 7047
, gtest_ar.failure_message()) = ::testing::Message()
;
7048
7049 // Check UNIX control socket comment and user context.
7050 ConstElementPtr ctx_socket = socket->get("user-context");
7051 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"
, 7051, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_socket", "false", "true") .c_str()) = ::testing::Message
()
;
7052 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"
, 7052, gtest_ar.failure_message()) = ::testing::Message()
;
7053 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"
, 7053, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_socket->get(\"comment\")", "false", "true") .c_str(
)) = ::testing::Message()
;
7054 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", 7054
, gtest_ar.failure_message()) = ::testing::Message()
;
7055
7056 // There is a HTTP control socket with authentication.
7057 socket = CfgMgr::instance().getStagingCfg()->getHttpControlSocketInfo();
7058 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"
, 7058, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket", "false", "true") .c_str()) = ::testing::Message()
;
7059 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"
, 7059, gtest_ar.failure_message()) = ::testing::Message()
;
7060 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"
, 7060, gtest_ar.failure_message()) = ::testing::Message()
;
7061 socket = socket->get(0);
7062 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"
, 7062, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket", "false", "true") .c_str()) = ::testing::Message()
;
7063 /// @todo use the configuration object.
7064 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"
, 7064, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket->get(\"socket-type\")", "false", "true") .c_str(
)) = ::testing::Message()
;
7065 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"
, 7065, gtest_ar.failure_message()) = ::testing::Message()
;
7066 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"
, 7066, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket->get(\"socket-address\")", "false", "true") .c_str
()) = ::testing::Message()
;
7067 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"
, 7067, gtest_ar.failure_message()) = ::testing::Message()
;
7068 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"
, 7068, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "socket->get(\"socket-port\")", "false", "true") .c_str(
)) = ::testing::Message()
;
7069 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"
, 7069, gtest_ar.failure_message()) = ::testing::Message()
;
7070
7071 // Check HTTP control socket comment.
7072 ctx_socket = socket->get("user-context");
7073 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"
, 7073, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_socket", "false", "true") .c_str()) = ::testing::Message
()
;
7074 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"
, 7074, gtest_ar.failure_message()) = ::testing::Message()
;
7075 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"
, 7075, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_socket->get(\"comment\")", "false", "true") .c_str(
)) = ::testing::Message()
;
7076 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", 7076
, gtest_ar.failure_message()) = ::testing::Message()
;
7077
7078 // HTTP headers.
7079 ConstElementPtr headers = socket->get("http-headers");
7080 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"
, 7080, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "headers", "false", "true") .c_str()) = ::testing::Message(
)
;
7081 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"
, 7081, gtest_ar.failure_message()) = ::testing::Message()
;
7082 ConstElementPtr header = headers->get(0);
7083 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"
, 7083, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "header", "false", "true") .c_str()) = ::testing::Message()
;
7084 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"
, 7084, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "header->get(\"name\")", "false", "true") .c_str()) = ::
testing::Message()
;
7085 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"
, 7085, gtest_ar.failure_message()) = ::testing::Message()
;
7086 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"
, 7086, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "header->get(\"value\")", "false", "true") .c_str()) = ::
testing::Message()
;
7087 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"
, 7087, gtest_ar.failure_message()) = ::testing::Message()
;
7088
7089 // Check HTTP header user context.
7090 ConstElementPtr ctx_header = header->get("user-context");
7091 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"
, 7091, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_header", "false", "true") .c_str()) = ::testing::Message
()
;
7092 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"
, 7092, gtest_ar.failure_message()) = ::testing::Message()
;
7093 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"
, 7093, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_header->get(\"comment\")", "false", "true") .c_str(
)) = ::testing::Message()
;
7094 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", 7094
, gtest_ar.failure_message()) = ::testing::Message()
;
7095
7096 // HTTP authentication.
7097 ConstElementPtr auth = socket->get("authentication");
7098 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", 7098
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "auth", "false", "true") .c_str()) = ::testing::Message()
;
7099 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"
, 7099, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "auth->get(\"type\")", "false", "true") .c_str()) = ::testing
::Message()
;
7100 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"
, 7100, gtest_ar.failure_message()) = ::testing::Message()
;
7101 ConstElementPtr ctx_auth = auth->get("user-context");
7102 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"
, 7102, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_auth", "false", "true") .c_str()) = ::testing::Message
()
;
7103 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"
, 7103, gtest_ar.failure_message()) = ::testing::Message()
;
7104 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"
, 7104, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_auth->get(\"comment\")", "false", "true") .c_str())
= ::testing::Message()
;
7105 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", 7105
, gtest_ar.failure_message()) = ::testing::Message()
;
7106
7107 // Authentication client.
7108 ConstElementPtr clients = auth->get("clients");
7109 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"
, 7109, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "clients", "false", "true") .c_str()) = ::testing::Message(
)
;
7110 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"
, 7110, gtest_ar.failure_message()) = ::testing::Message()
;
7111 ConstElementPtr client;
7112 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_7112
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_7112
; } } else gtest_label_testnothrow_7112 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7112, ("Expected: " "client = clients->get(0)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
7113 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"
, 7113, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "client", "false", "true") .c_str()) = ::testing::Message()
;
7114 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"
, 7114, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "client->get(\"user\")", "false", "true") .c_str()) = ::
testing::Message()
;
7115 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"
, 7115, gtest_ar.failure_message()) = ::testing::Message()
;
7116 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"
, 7116, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "client->get(\"password\")", "false", "true") .c_str()) =
::testing::Message()
;
7117 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"
, 7117, gtest_ar.failure_message()) = ::testing::Message()
;
7118 ConstElementPtr ctx_client = client->get("user-context");
7119 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"
, 7119, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_client", "false", "true") .c_str()) = ::testing::Message
()
;
7120 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"
, 7120, gtest_ar.failure_message()) = ::testing::Message()
;
7121 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"
, 7121, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_client->get(\"comment\")", "false", "true") .c_str(
)) = ::testing::Message()
;
7122 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", 7122
, gtest_ar.failure_message()) = ::testing::Message()
;
7123
7124 // Now verify that the shared network was indeed configured.
7125 const CfgSharedNetworks4Ptr& cfg_net =
7126 CfgMgr::instance().getStagingCfg()->getCfgSharedNetworks4();
7127 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"
, 7127, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg_net", "false", "true") .c_str()) = ::testing::Message(
)
;
7128 const SharedNetwork4Collection* nets = cfg_net->getAll();
7129 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", 7129
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "nets", "false", "true") .c_str()) = ::testing::Message()
;
7130 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"
, 7130, gtest_ar.failure_message()) = ::testing::Message()
;
7131 SharedNetwork4Ptr net = nets->at(0);
7132 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", 7132
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "net", "false", "true") .c_str()) = ::testing::Message()
;
7133 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", 7133
, gtest_ar.failure_message()) = ::testing::Message()
;
7134
7135 // Check shared network user context.
7136 ConstElementPtr ctx_net = net->getContext();
7137 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"
, 7137, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_net", "false", "true") .c_str()) = ::testing::Message(
)
;
7138 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"
, 7138, gtest_ar.failure_message()) = ::testing::Message()
;
7139 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"
, 7139, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_net->get(\"comment\")", "false", "true") .c_str()) =
::testing::Message()
;
7140 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"
, 7140, gtest_ar.failure_message()) = ::testing::Message()
;
7141
7142 // The shared network has a subnet.
7143 const Subnet4SimpleCollection* subs = net->getAllSubnets();
7144 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", 7144
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subs", "false", "true") .c_str()) = ::testing::Message()
;
7145 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"
, 7145, gtest_ar.failure_message()) = ::testing::Message()
;
7146 Subnet4Ptr sub = *subs->begin();
7147 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", 7147
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "sub", "false", "true") .c_str()) = ::testing::Message()
;
7148 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"
, 7148, gtest_ar.failure_message()) = ::testing::Message()
;
7149 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"
, 7149, gtest_ar.failure_message()) = ::testing::Message()
;
7150
7151 // Check subnet user context.
7152 ConstElementPtr ctx_sub = sub->getContext();
7153 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"
, 7153, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_sub", "false", "true") .c_str()) = ::testing::Message(
)
;
7154 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"
, 7154, gtest_ar.failure_message()) = ::testing::Message()
;
7155 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"
, 7155, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_sub->get(\"comment\")", "false", "true") .c_str()) =
::testing::Message()
;
7156 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"
, 7156, gtest_ar.failure_message()) = ::testing::Message()
;
7157
7158 // The subnet has a pool.
7159 const PoolCollection& pools = sub->getPools(Lease::TYPE_V4);
7160 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"
, 7160, gtest_ar.failure_message()) = ::testing::Message()
;
7161 PoolPtr pool = pools.at(0);
7162 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", 7162
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
7163
7164 // Check pool user context.
7165 ConstElementPtr ctx_pool = pool->getContext();
7166 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"
, 7166, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_pool", "false", "true") .c_str()) = ::testing::Message
()
;
7167 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"
, 7167, gtest_ar.failure_message()) = ::testing::Message()
;
7168 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"
, 7168, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_pool->get(\"comment\")", "false", "true") .c_str())
= ::testing::Message()
;
7169 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"
, 7169, gtest_ar.failure_message()) = ::testing::Message()
;
7170
7171 // The subnet has a host reservation.
7172 uint8_t hw[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
7173 ConstHostPtr host =
7174 CfgMgr::instance().getStagingCfg()->getCfgHosts()->
7175 get4(100, Host::IDENT_HWADDR, &hw[0], sizeof(hw));
7176 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", 7176
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
7177 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"
, 7177, gtest_ar.failure_message()) = ::testing::Message()
;
7178 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", 7178
, gtest_ar.failure_message()) = ::testing::Message()
;
7179 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"
, 7179, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host->getDuid()", "true", "false") .c_str()) = ::testing
::Message()
;
7180 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"
, 7180, gtest_ar.failure_message()) = ::testing::Message()
;
7181 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"
, 7181, gtest_ar.failure_message()) = ::testing::Message()
;
7182 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"
, 7182, gtest_ar.failure_message()) = ::testing::Message()
;
7183
7184 // Check host user context.
7185 ConstElementPtr ctx_host = host->getContext();
7186 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"
, 7186, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_host", "false", "true") .c_str()) = ::testing::Message
()
;
7187 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"
, 7187, gtest_ar.failure_message()) = ::testing::Message()
;
7188 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"
, 7188, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_host->get(\"comment\")", "false", "true") .c_str())
= ::testing::Message()
;
7189 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", 7189
, gtest_ar.failure_message()) = ::testing::Message()
;
7190
7191 // The host reservation has an option data.
7192 ConstCfgOptionPtr opts = host->getCfgOption4();
7193 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", 7193
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opts", "false", "true") .c_str()) = ::testing::Message()
;
7194 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"
, 7194, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opts->empty()", "true", "false") .c_str()) = ::testing::
Message()
;
7195 const OptionDescriptor& host_desc =
7196 opts->get(DHCP4_OPTION_SPACE"dhcp4", DHO_DOMAIN_NAME);
7197 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"
, 7197, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host_desc.option_", "false", "true") .c_str()) = ::testing
::Message()
;
7198 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"
, 7198, gtest_ar.failure_message()) = ::testing::Message()
;
7199
7200 // Check embedded option data user context.
7201 ConstElementPtr ctx_host_desc = host_desc.getContext();
7202 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"
, 7202, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_host_desc", "false", "true") .c_str()) = ::testing::Message
()
;
7203 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"
, 7203, gtest_ar.failure_message()) = ::testing::Message()
;
7204 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"
, 7204, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_host_desc->get(\"comment\")", "false", "true") .c_str
()) = ::testing::Message()
;
7205 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", 7206
, gtest_ar.failure_message()) = ::testing::Message()
7206 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", 7206
, gtest_ar.failure_message()) = ::testing::Message()
;
7207
7208 // Finally dynamic DNS update configuration.
7209 const D2ClientConfigPtr& d2 =
7210 CfgMgr::instance().getStagingCfg()->getD2ClientConfig();
7211 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", 7211
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "d2", "false", "true") .c_str()) = ::testing::Message()
;
7212 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"
, 7212, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "d2->getEnableUpdates()", "true", "false") .c_str()) = ::
testing::Message()
;
7213
7214 // Check dynamic DNS update configuration user context.
7215 ConstElementPtr ctx_d2 = d2->getContext();
7216 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"
, 7216, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_d2", "false", "true") .c_str()) = ::testing::Message()
;
7217 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"
, 7217, gtest_ar.failure_message()) = ::testing::Message()
;
7218 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"
, 7218, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ctx_d2->get(\"comment\")", "false", "true") .c_str()) =
::testing::Message()
;
7219 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"
, 7219, gtest_ar.failure_message()) = ::testing::Message()
;
7220}
7221
7222// This test verifies that the global host reservations can be specified.
7223TEST_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"
, 7223), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7223), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7223), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_globalReservations_Test
>); void Dhcp4ParserTest_globalReservations_Test::TestBody
()
{
7224 ConstElementPtr x;
7225 string config = "{ " + genIfaceConfig() + ","
7226 "\"rebind-timer\": 2000, \n"
7227 "\"renew-timer\": 1000,\n"
7228 "\"reservations\": [\n"
7229 " {\n"
7230 " \"duid\": \"01:02:03:04:05:06:07:08:09:0A\",\n"
7231 " \"ip-address\": \"192.0.200.1\",\n"
7232 " \"hostname\": \"global1\",\n"
7233 " \"option-data\": [\n"
7234 " {\n"
7235 " \"name\": \"name-servers\",\n"
7236 " \"data\": \"192.0.3.15\"\n"
7237 " },\n"
7238 " {\n"
7239 " \"name\": \"default-ip-ttl\",\n"
7240 " \"data\": \"32\"\n"
7241 " }\n"
7242 " ]\n"
7243 " },\n"
7244 " {\n"
7245 " \"hw-address\": \"01:02:03:04:05:06\",\n"
7246 " \"hostname\": \"global2\",\n"
7247 " \"option-data\": [\n"
7248 " {\n"
7249 " \"name\": \"name-servers\",\n"
7250 " \"data\": \"192.0.3.95\"\n"
7251 " },\n"
7252 " {\n"
7253 " \"name\": \"default-ip-ttl\",\n"
7254 " \"data\": \"11\"\n"
7255 " }\n"
7256 " ]\n"
7257 " }],\n"
7258 "\"subnet4\": [ \n"
7259 " { \n"
7260 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],\n"
7261 " \"subnet\": \"192.0.2.0/24\", \n"
7262 " \"id\": 123,\n"
7263 " \"reservations\": [\n"
7264 " ]\n"
7265 " },\n"
7266 " {\n"
7267 " \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],\n"
7268 " \"subnet\": \"192.0.4.0/24\",\n"
7269 " \"id\": 542\n"
7270 " }\n"
7271 "],\n"
7272 "\"valid-lifetime\": 4000 }\n";
7273
7274 ConstElementPtr json;
7275 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_7275
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_7275
; } } else gtest_label_testnothrow_7275 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7275, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
7276 extractConfig(config);
7277
7278 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_7278; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7278; } } else gtest_label_testnothrow_7278
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7278, ("Expected: " "x = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
7279 checkResult(x, 0);
7280
7281 // Make sure all subnets have been successfully configured. There is no
7282 // need to sanity check the subnet properties because it should have
7283 // been already tested by other tests.
7284 const Subnet4Collection* subnets =
7285 CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
7286 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"
, 7286, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnets", "false", "true") .c_str()) = ::testing::Message(
)
;
7287 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"
, 7287, gtest_ar.failure_message()) = ::testing::Message()
;
7288
7289 // Hosts configuration must be available.
7290 CfgHostsPtr hosts_cfg = CfgMgr::instance().getStagingCfg()->getCfgHosts();
7291 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"
, 7291, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg", "false", "true") .c_str()) = ::testing::Message
()
;
7292
7293 // Let's create a hardware address of the host named "global2"
7294 std::vector<uint8_t> hwaddr;
7295 for (unsigned int i = 1; i < 7; ++i) {
7296 hwaddr.push_back(static_cast<uint8_t>(i));
7297 }
7298
7299 // Retrieve the global reservation and sanity check the hostname reserved.
7300 ConstHostPtr host = hosts_cfg->get4(SUBNET_ID_GLOBAL, Host::IDENT_HWADDR,
7301 &hwaddr[0], hwaddr.size());
7302 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", 7302
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
7303 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"
, 7303, gtest_ar.failure_message()) = ::testing::Message()
;
7304
7305 // This reservation should be solely assigned to the subnet 234,
7306 // and not to other two.
7307 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"
, 7308, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())"
, "true", "false") .c_str()) = ::testing::Message()
7308 &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"
, 7308, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
7309
7310 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"
, 7311, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(542, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())"
, "true", "false") .c_str()) = ::testing::Message()
7311 &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"
, 7311, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(542, Host::IDENT_HWADDR, &hwaddr[0], hwaddr.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
7312 // Check that options are assigned correctly.
7313 Option4AddrLstPtr opt_dns =
7314 retrieveOption<Option4AddrLstPtr>(*host, DHO_NAME_SERVERS);
7315 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"
, 7315, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_dns", "false", "true") .c_str()) = ::testing::Message(
)
;
7316 Option4AddrLst::AddressContainer dns_addrs = opt_dns->getAddresses();
7317 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"
, 7317, gtest_ar.failure_message()) = ::testing::Message()
;
7318 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"
, 7318, gtest_ar.failure_message()) = ::testing::Message()
;
7319 OptionUint8Ptr opt_ttl =
7320 retrieveOption<OptionUint8Ptr>(*host, DHO_DEFAULT_IP_TTL);
7321 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"
, 7321, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_ttl", "false", "true") .c_str()) = ::testing::Message(
)
;
7322 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"
, 7322, gtest_ar.failure_message()) = ::testing::Message()
;
7323
7324 // Do the same test for the DUID based reservation.
7325 std::vector<uint8_t> duid;
7326 for (unsigned int i = 1; i < 0xb; ++i) {
7327 duid.push_back(static_cast<uint8_t>(i));
7328 }
7329
7330 // Retrieve the global reservation and sanity check the hostname reserved.
7331 host = hosts_cfg->get4(SUBNET_ID_GLOBAL, Host::IDENT_DUID, &duid[0], duid.size());
7332 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", 7332
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "host", "false", "true") .c_str()) = ::testing::Message()
;
7333 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"
, 7333, gtest_ar.failure_message()) = ::testing::Message()
;
7334
7335 // Check that options are assigned correctly.
7336 opt_dns = retrieveOption<Option4AddrLstPtr>(*host, DHO_NAME_SERVERS);
7337 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"
, 7337, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_dns", "false", "true") .c_str()) = ::testing::Message(
)
;
7338 dns_addrs = opt_dns->getAddresses();
7339 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"
, 7339, gtest_ar.failure_message()) = ::testing::Message()
;
7340 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"
, 7340, gtest_ar.failure_message()) = ::testing::Message()
;
7341 opt_ttl = retrieveOption<OptionUint8Ptr>(*host, DHO_DEFAULT_IP_TTL);
7342 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"
, 7342, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "opt_ttl", "false", "true") .c_str()) = ::testing::Message(
)
;
7343 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"
, 7343, gtest_ar.failure_message()) = ::testing::Message()
;
7344
7345 // This reservation should be global solely and not assigned to
7346 // either subnet
7347 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", 7347
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(123, Host::IDENT_DUID, &duid[0], duid.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
7348 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", 7348
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "hosts_cfg->get4(542, Host::IDENT_DUID, &duid[0], duid.size())"
, "true", "false") .c_str()) = ::testing::Message()
;
7349}
7350
7351// Rather than disable these tests they are compiled out. This avoids them
7352// reporting as disabled and thereby drawing attention to them.
7353// This test verifies that configuration control with unsupported type fails
7354TEST_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"
, 7354), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7354), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7354), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_configControlInfoNoFactory_Test
>); void Dhcp4ParserTest_configControlInfoNoFactory_Test::
TestBody()
{
7355 string config = PARSER_CONFIGS[5];
7356
7357 // Unregister "mysql" and ignore the return value.
7358 static_cast<void>(TestConfigBackendDHCPv4::
7359 unregisterBackendType(ConfigBackendDHCPv4Mgr::instance(),
7360 "mysql"));
7361
7362 // Should fail because "type=mysql" has no factories.
7363 configure(config, CONTROL_RESULT_FATAL_ERROR,
7364 "during update from config backend database: "
7365 "The Kea server has not been compiled with support for configuration "
7366 "database type: mysql. Did you forget to use -D mysql=enabled during "
7367 "setup or to load libdhcp_mysql hook library?");
7368}
7369
7370// This test verifies that configuration control info gets populated.
7371TEST_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"
, 7371), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7371), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7371), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_configControlInfo_Test
>); void Dhcp4ParserTest_configControlInfo_Test::TestBody(
)
{
7372 string config = PARSER_CONFIGS[5];
7373
7374 // Should be able to register a backend factory for "mysql".
7375 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"
, 7377, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "TestConfigBackendDHCPv4:: registerBackendType(ConfigBackendDHCPv4Mgr::instance(), \"mysql\")"
, "false", "true") .c_str()) = ::testing::Message()
7376 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"
, 7377, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "TestConfigBackendDHCPv4:: registerBackendType(ConfigBackendDHCPv4Mgr::instance(), \"mysql\")"
, "false", "true") .c_str()) = ::testing::Message()
7377 "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"
, 7377, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "TestConfigBackendDHCPv4:: registerBackendType(ConfigBackendDHCPv4Mgr::instance(), \"mysql\")"
, "false", "true") .c_str()) = ::testing::Message()
;
7378
7379 // Should parse ok, now that the factory has been registered.
7380 configure(config, CONTROL_RESULT_SUCCESS, "");
7381
7382 // Make sure the config control info is there.
7383 process::ConstConfigControlInfoPtr info =
7384 CfgMgr::instance().getStagingCfg()->getConfigControlInfo();
7385 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", 7385
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "info", "false", "true") .c_str()) = ::testing::Message()
;
7386
7387 // Fetch the list of config dbs. It should have two entries.
7388 const process::ConfigDbInfoList& dblist = info->getConfigDatabases();
7389 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"
, 7389, gtest_ar.failure_message()) = ::testing::Message()
;
7390
7391 // Make sure the entries are what we expect and in the right order.
7392 // (DbAccessParser creates access strings with the keywords in
7393 // alphabetical order).
7394 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"
, 7395, gtest_ar.failure_message()) = ::testing::Message()
7395 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"
, 7395, gtest_ar.failure_message()) = ::testing::Message()
;
7396 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"
, 7397, gtest_ar.failure_message()) = ::testing::Message()
7397 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"
, 7397, gtest_ar.failure_message()) = ::testing::Message()
;
7398
7399 // Verify that the config-fetch-wait-time is correct.
7400 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"
, 7400, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "info->getConfigFetchWaitTime().unspecified()", "true", "false"
) .c_str()) = ::testing::Message()
;
7401 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", 7401
, gtest_ar.failure_message()) = ::testing::Message()
;
7402}
7403
7404// Check whether it is possible to configure server-tag
7405TEST_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", 7405
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7405), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7405), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_serverTag_Test
>); void Dhcp4ParserTest_serverTag_Test::TestBody()
{
7406 // Config without server-tag
7407 string config_no_tag = "{ " + genIfaceConfig() + ","
7408 "\"subnet4\": [ ] "
7409 "}";
7410
7411 // Config with server-tag
7412 string config_tag = "{ " + genIfaceConfig() + ","
7413 "\"server-tag\": \"boo\", "
7414 "\"subnet4\": [ ] "
7415 "}";
7416
7417 // Config with an invalid server-tag
7418 string bad_tag = "{ " + genIfaceConfig() + ","
7419 "\"server-tag\": 777, "
7420 "\"subnet4\": [ ] "
7421 "}";
7422
7423 // Let's check the default. It should be empty.
7424 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"
, 7424, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getServerTag().empty()"
, "false", "true") .c_str()) = ::testing::Message()
;
7425
7426 // Configuration with no tag should default to an emtpy tag value.
7427 configure(config_no_tag, CONTROL_RESULT_SUCCESS, "");
7428 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"
, 7428, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getServerTag().empty()"
, "false", "true") .c_str()) = ::testing::Message()
;
7429
7430 // Clear the config
7431 CfgMgr::instance().clear();
7432
7433 // Configuration with the tag should have the tag value.
7434 configure(config_tag, CONTROL_RESULT_SUCCESS, "");
7435 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"
, 7435, gtest_ar.failure_message()) = ::testing::Message()
;
7436
7437 // Make sure a invalid server-tag fails to parse.
7438 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_7438; } 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_7438; } 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_7438
; } } else gtest_label_testthrow_7438 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7438, gtest_msg.value.c_str()) = ::testing::Message()
;
7439}
7440
7441// Check whether it is possible to configure packet queue
7442TEST_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"
, 7442), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7442), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7442), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_dhcpQueueControl_Test
>); void Dhcp4ParserTest_dhcpQueueControl_Test::TestBody()
{
7443 struct Scenario {
7444 std::string description_;
7445 std::string json_;
7446 std::string mt_json_;
7447 };
7448
7449 std::vector<Scenario> scenarios = {
7450 {
7451 "no entry",
7452 "",
7453 "",
7454 },
7455 {
7456 "queue disabled",
7457 "{ \n"
7458 " \"enable-queue\": false \n"
7459 "} \n",
7460 R"("multi-threading": {
7461 "enable-multi-threading": false
7462 })",
7463 },
7464 {
7465 "queue enabled at first, but gets forcefully disabled by MT",
7466 "{ \n"
7467 " \"enable-queue\": true \n"
7468 "} \n",
7469 R"("multi-threading": {
7470 "enable-multi-threading": true
7471 })",
7472 },
7473 {
7474 "queue disabled, arbitrary content allowed",
7475 "{ \n"
7476 " \"enable-queue\": false, \n"
7477 " \"foo\": \"bogus\", \n"
7478 " \"random-int\" : 1234 \n"
7479 "} \n",
7480 R"("multi-threading": {
7481 "enable-multi-threading": false
7482 })",
7483 },
7484 {
7485 "queue enabled, with queue-type",
7486 "{ \n"
7487 " \"enable-queue\": true, \n"
7488 " \"queue-type\": \"some-type\" \n"
7489 "} \n",
7490 R"("multi-threading": {
7491 "enable-multi-threading": false
7492 })",
7493 },
7494 {
7495 "queue enabled with queue-type and arbitrary content",
7496 "{ \n"
7497 " \"enable-queue\": true, \n"
7498 " \"queue-type\": \"some-type\", \n"
7499 " \"foo\": \"bogus\", \n"
7500 " \"random-int\" : 1234 \n"
7501 "} \n",
7502 R"("multi-threading": {
7503 "enable-multi-threading": false
7504 })",
7505 }
7506 };
7507
7508 // Let's check the default. It should be empty.
7509 data::ConstElementPtr staged_control;
7510 staged_control = CfgMgr::instance().getStagingCfg()->getDHCPQueueControl();
7511 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"
, 7511, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "staged_control", "true", "false") .c_str()) = ::testing::Message
()
;
7512
7513 // Iterate over the valid scenarios and verify they succeed.
7514 data::ElementPtr exp_control;
7515 for (auto const& scenario : scenarios) {
7516 SCOPED_TRACE(scenario.description_)const ::testing::ScopedTrace gtest_trace_7516( "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7516, (scenario.description_))
;
7517 {
7518 // Clear the config
7519 CfgMgr::instance().clear();
7520
7521 // Construct the config JSON
7522 std::stringstream os;
7523 os << "{ " + genIfaceConfig();
7524 if (!scenario.json_.empty()) {
7525 os << ",\n \"dhcp-queue-control\": " << scenario.json_;
7526 }
7527 if (!scenario.mt_json_.empty()) {
7528 os << ",\n" << scenario.mt_json_;
7529 }
7530 os << "\n}\n";
7531
7532 // Configure the server. This should succeed.
7533 configure(os.str(), CONTROL_RESULT_SUCCESS, "");
7534
7535 // Fetch the queue control info.
7536 staged_control = CfgMgr::instance().getStagingCfg()->getDHCPQueueControl();
7537
7538 // Make sure the staged queue config exists.
7539 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"
, 7539, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "staged_control", "false", "true") .c_str()) = ::testing::Message
()
;
7540
7541 // Now build the expected queue control content.
7542 if (scenario.json_.empty()) {
7543 exp_control = Element::createMap();
7544 } else {
7545 try {
7546 exp_control = boost::const_pointer_cast<Element>(Element::fromJSON(scenario.json_));
7547 } catch (const std::exception& ex) {
7548 ADD_FAILURE()::testing::internal::AssertHelper(::testing::TestPartResult::
kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7548, "Failed") = ::testing::Message()
<< " cannot convert expected JSON, test is broken:"
7549 << ex.what();
7550 }
7551 }
7552
7553 // Add the defaults to expected queue control.
7554 SimpleParser4::setDefaults(exp_control, SimpleParser4::DHCP_QUEUE_CONTROL4_DEFAULTS);
7555
7556 // This specific scenario is the only one where we expect enable-queue
7557 // to be changed from what the user set it to.
7558 if (scenario.description_ == "queue enabled at first, but gets forcefully disabled by MT") {
7559 exp_control->set("enable-queue", Element::create(false));
7560 }
7561
7562 // Verify that the staged queue control equals the expected queue control.
7563 expectEqWithDiff(staged_control, exp_control);
7564 }
7565 }
7566}
7567
7568// Check that we catch invalid dhcp-queue-control content
7569TEST_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"
, 7569), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7569), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7569), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_dhcpQueueControlInvalid_Test
>); void Dhcp4ParserTest_dhcpQueueControlInvalid_Test::TestBody
()
{
7570 struct Scenario {
7571 std::string description_;
7572 std::string json_;
7573 std::string exp_error_;
7574 };
7575
7576 std::vector<Scenario> scenarios = {
7577 {
7578 "not a map",
7579 "75 \n",
7580 "<string>:2.24-25: syntax error, unexpected integer, expecting {"
7581 },
7582 {
7583 "enable-queue missing",
7584 "{ \n"
7585 " \"enable-type\": \"some-type\" \n"
7586 "} \n",
7587 "missing parameter 'enable-queue' (<string>:2:2) "
7588 "[dhcp-queue-control map between <string>:2:24 and <string>:4:1]"
7589 },
7590 {
7591 "enable-queue not boolean",
7592 "{ \n"
7593 " \"enable-queue\": \"always\" \n"
7594 "} \n",
7595 "<string>:3.20-27: syntax error, unexpected constant string, "
7596 "expecting boolean"
7597 },
7598 {
7599 "queue enabled, type not a string",
7600 "{ \n"
7601 " \"enable-queue\": true, \n"
7602 " \"queue-type\": 7777 \n"
7603 "} \n",
7604 "<string>:4.18-21: syntax error, unexpected integer, "
7605 "expecting constant string"
7606 }
7607 };
7608
7609 // Iterate over the incorrect scenarios and verify they
7610 // fail as expected. Note, we use parseDHCP4() directly
7611 // as all of the errors above are enforced by the grammar.
7612 for (auto const& scenario : scenarios) {
7613 SCOPED_TRACE(scenario.description_)const ::testing::ScopedTrace gtest_trace_7613( "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7613, (scenario.description_))
;
7614 {
7615 // Construct the config JSON
7616 std::stringstream os;
7617 os << "{ " + genIfaceConfig();
7618 os << ",\n \"dhcp-queue-control\": " << scenario.json_;
7619 os << "} \n";
7620
7621 std::string error_msg = "";
7622 try {
7623 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"
, 7623, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "parseDHCP4(os.str(), false)", "false", "true") .c_str()) =
::testing::Message()
<< "parser returned empty element";
7624 } catch(const std::exception& ex) {
7625 error_msg = ex.what();
7626 }
7627
7628 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"
, 7628, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "error_msg.empty()", "true", "false") .c_str()) = ::testing
::Message()
<< "parseDHCP4 should have thrown";
7629 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", 7629
, gtest_ar.failure_message()) = ::testing::Message()
;
7630 }
7631 }
7632}
7633
7634// Checks inheritence of calculate-tee-times, t1-percent, t2-percent
7635TEST_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"
, 7635), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7635), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7635), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_calculateTeeTimesInheritence_Test
>); void Dhcp4ParserTest_calculateTeeTimesInheritence_Test
::TestBody()
{
7636 // Configure the server. This should succeed.
7637 string config =
7638 "{ \n"
7639 " \"interfaces-config\": { \n"
7640 " \"interfaces\": [\"*\" ] \n"
7641 " }, \n"
7642 " \"valid-lifetime\": 4000, \n"
7643 " \"shared-networks\": [ { \n"
7644 " \"name\": \"foo\", \n"
7645 " \"calculate-tee-times\": true, \n"
7646 " \"t1-percent\": .4, \n"
7647 " \"t2-percent\": .75,\n"
7648 " \"subnet4\": ["
7649 " { "
7650 " \"id\": 100,"
7651 " \"subnet\": \"192.0.1.0/24\", \n"
7652 " \"pools\": [ { \"pool\": \"192.0.1.1-192.0.1.10\" } ], \n"
7653 " \"calculate-tee-times\": false,\n"
7654 " \"t1-percent\": .45, \n"
7655 " \"t2-percent\": .65 \n"
7656 " }, \n"
7657 " { \n"
7658 " \"id\": 200, \n"
7659 " \"subnet\": \"192.0.2.0/24\", \n"
7660 " \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\" } ] \n"
7661 " } \n"
7662 " ] \n"
7663 " } ], \n"
7664 " \"subnet4\": [ { \n"
7665 " \"id\": 300, \n"
7666 " \"subnet\": \"192.0.3.0/24\", \n"
7667 " \"pools\": [ { \"pool\": \"192.0.3.0 - 192.0.3.15\" } ]\n"
7668 " } ] \n"
7669 "} \n";
7670
7671 extractConfig(config);
7672 configure(config, CONTROL_RESULT_SUCCESS, "");
7673
7674 CfgSubnets4Ptr subnets4 = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
7675
7676 // Subnet 100 should use its own explicit values.
7677 ConstSubnet4Ptr subnet4 = subnets4->getBySubnetId(100);
7678 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"
, 7678, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet4", "false", "true") .c_str()) = ::testing::Message(
)
;
7679 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"
, 7679, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet4->getCalculateTeeTimes()", "true", "false") .c_str
()) = ::testing::Message()
;
7680 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"
, 7680, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "util::areDoublesEquivalent(0.45, subnet4->getT1Percent())"
, "false", "true") .c_str()) = ::testing::Message()
;
7681 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"
, 7681, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "util::areDoublesEquivalent(0.65, subnet4->getT2Percent())"
, "false", "true") .c_str()) = ::testing::Message()
;
7682
7683 // Subnet 200 should use the shared-network values.
7684 subnet4 = subnets4->getBySubnetId(200);
7685 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"
, 7685, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet4", "false", "true") .c_str()) = ::testing::Message(
)
;
7686 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"
, 7686, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet4->getCalculateTeeTimes()", "false", "true") .c_str
()) = ::testing::Message()
;
7687 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"
, 7687, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "util::areDoublesEquivalent(0.4, subnet4->getT1Percent())"
, "false", "true") .c_str()) = ::testing::Message()
;
7688 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"
, 7688, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "util::areDoublesEquivalent(0.75, subnet4->getT2Percent())"
, "false", "true") .c_str()) = ::testing::Message()
;
7689
7690 // Subnet 300 should use the global values.
7691 subnet4 = subnets4->getBySubnetId(300);
7692 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"
, 7692, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet4", "false", "true") .c_str()) = ::testing::Message(
)
;
7693 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"
, 7693, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet4->getCalculateTeeTimes()", "true", "false") .c_str
()) = ::testing::Message()
;
7694 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"
, 7694, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "util::areDoublesEquivalent(0.5, subnet4->getT1Percent())"
, "false", "true") .c_str()) = ::testing::Message()
;
7695 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"
, 7695, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "util::areDoublesEquivalent(0.875, subnet4->getT2Percent())"
, "false", "true") .c_str()) = ::testing::Message()
;
7696}
7697
7698// This test checks that the global store-extended-info parameter is optional
7699// and that values under the subnet are used.
7700TEST_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"
, 7700), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7700), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7700), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_storeExtendedInfoNoGlobal_Test
>); void Dhcp4ParserTest_storeExtendedInfoNoGlobal_Test::TestBody
()
{
7701 const string config = "{ " + genIfaceConfig() + ","
7702 "\"rebind-timer\": 2000, "
7703 "\"renew-timer\": 1000, "
7704 "\"subnet4\": [ "
7705 "{"
7706 " \"id\": 1,"
7707 " \"store-extended-info\": true,"
7708 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
7709 " \"subnet\": \"192.0.2.0/24\""
7710 "},"
7711 "{"
7712 " \"id\": 2,"
7713 " \"store-extended-info\": false,"
7714 " \"pools\": [ { \"pool\": \"192.0.3.1 - 192.0.3.100\" } ],"
7715 " \"subnet\": \"192.0.3.0/24\""
7716 "} ],"
7717 "\"valid-lifetime\": 4000 }";
7718
7719 ConstElementPtr json;
7720 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_7720
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_7720
; } } else gtest_label_testnothrow_7720 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7720, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
7721 extractConfig(config);
7722
7723 ConstElementPtr status;
7724 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_7724; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7724; } } else gtest_label_testnothrow_7724
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7724, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
7725 checkResult(status, 0);
7726
7727 // First subnet should use global default.
7728 CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
7729 ConstSubnet4Ptr subnet1 = cfg->selectSubnet(IOAddress("192.0.2.1"));
7730 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"
, 7730, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1", "false", "true") .c_str()) = ::testing::Message(
)
;
7731 // Reset the fetch global function to staging (vs current) config.
7732 Subnet4Ptr mutable_subnet1 = boost::const_pointer_cast<Subnet4>(subnet1);
7733 mutable_subnet1->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
7734 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
7735 });
7736 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"
, 7736, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1->getStoreExtendedInfo()", "false", "true") .c_str
()) = ::testing::Message()
;
7737
7738 // Second subnet should use its own value.
7739 ConstSubnet4Ptr subnet2 = cfg->selectSubnet(IOAddress("192.0.3.1"));
7740 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"
, 7740, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2", "false", "true") .c_str()) = ::testing::Message(
)
;
7741 // Reset the fetch global function to staging (vs current) config.
7742 Subnet4Ptr mutable_subnet2 = boost::const_pointer_cast<Subnet4>(subnet2);
7743 mutable_subnet2->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
7744 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
7745 });
7746 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"
, 7746, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2->getStoreExtendedInfo()", "true", "false") .c_str
()) = ::testing::Message()
;
7747}
7748
7749// This test checks that the global store-extended-info parameter is used
7750// when there is no such parameter under subnet and that the parameter
7751// specified for a subnet overrides the global setting.
7752TEST_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"
, 7752), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7752), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7752), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_storeExtendedInfoGlobal_Test
>); void Dhcp4ParserTest_storeExtendedInfoGlobal_Test::TestBody
()
{
7753 const string config = "{ " + genIfaceConfig() + ","
7754 "\"rebind-timer\": 2000, "
7755 "\"renew-timer\": 1000, "
7756 "\"store-extended-info\": true,"
7757 "\"subnet4\": [ "
7758 "{"
7759 " \"id\": 1,"
7760 " \"store-extended-info\": false,"
7761 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
7762 " \"subnet\": \"192.0.2.0/24\""
7763 "},"
7764 "{"
7765 " \"id\": 2,"
7766 " \"pools\": [ { \"pool\": \"192.0.3.1 - 192.0.3.100\" } ],"
7767 " \"subnet\": \"192.0.3.0/24\""
7768 "} ],"
7769 "\"valid-lifetime\": 4000 }";
7770
7771 ConstElementPtr json;
7772 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_7772
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_7772
; } } else gtest_label_testnothrow_7772 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7772, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
7773 extractConfig(config);
7774
7775 ConstElementPtr status;
7776 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_7776; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7776; } } else gtest_label_testnothrow_7776
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7776, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
7777 checkResult(status, 0);
7778
7779 // First subnet should override the global value.
7780 CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
7781 ConstSubnet4Ptr subnet1 = cfg->selectSubnet(IOAddress("192.0.2.1"));
7782 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"
, 7782, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1", "false", "true") .c_str()) = ::testing::Message(
)
;
7783 // Reset the fetch global function to staging (vs current) config.
7784 Subnet4Ptr mutable_subnet1 = boost::const_pointer_cast<Subnet4>(subnet1);
7785 mutable_subnet1->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
7786 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
7787 });
7788 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"
, 7788, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1->getStoreExtendedInfo()", "true", "false") .c_str
()) = ::testing::Message()
;
7789
7790 ConstSubnet4Ptr subnet2 = cfg->selectSubnet(IOAddress("192.0.3.1"));
7791 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"
, 7791, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2", "false", "true") .c_str()) = ::testing::Message(
)
;
7792 // Reset the fetch global function to staging (vs current) config.
7793 Subnet4Ptr mutable_subnet2 = boost::const_pointer_cast<Subnet4>(subnet2);
7794 mutable_subnet2->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
7795 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
7796 });
7797 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"
, 7797, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet2->getStoreExtendedInfo()", "false", "true") .c_str
()) = ::testing::Message()
;
7798}
7799
7800/// This test checks that the statistic-default-sample-count and age
7801/// global parameters are committed to the stats manager as expected.
7802TEST_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"
, 7802), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7802), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7802), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_statsDefaultLimits_Test
>); void Dhcp4ParserTest_statsDefaultLimits_Test::TestBody
()
{
7803 std::string config = "{ " + genIfaceConfig() + ","
7804 "\"rebind-timer\": 2000, "
7805 "\"renew-timer\": 1000, "
7806 "\"statistic-default-sample-count\": 10, "
7807 "\"statistic-default-sample-age\": 5, "
7808 "\"valid-lifetime\": 4000 }";
7809
7810 ConstElementPtr json;
7811 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_7811
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_7811
; } } else gtest_label_testnothrow_7811 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7811, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
7812 extractConfig(config);
7813
7814 ConstElementPtr status;
7815 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_7815; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7815; } } else gtest_label_testnothrow_7815
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7815, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
7816 checkResult(status, 0);
7817
7818 CfgMgr::instance().commit();
7819
7820 stats::StatsMgr& stats_mgr = stats::StatsMgr::instance();
7821 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", 7821
, gtest_ar.failure_message()) = ::testing::Message()
;
7822 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"
, 7823, gtest_ar.failure_message()) = ::testing::Message()
7823 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"
, 7823, gtest_ar.failure_message()) = ::testing::Message()
;
7824}
7825
7826// This test checks that using default multi threading settings works.
7827TEST_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"
, 7827), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7827), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7827), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_multiThreadingDefaultSettings_Test
>); void Dhcp4ParserTest_multiThreadingDefaultSettings_Test
::TestBody()
{
7828 std::string config = "{ " + genIfaceConfig() + ","
7829 "\"subnet4\": [ ]"
7830 "}";
7831
7832 ConstElementPtr json;
7833 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_7833
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_7833
; } } else gtest_label_testnothrow_7833 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7833, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
7834 extractConfig(config);
7835
7836 ConstElementPtr status;
7837 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_7837; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7837; } } else gtest_label_testnothrow_7837
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7837, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
7838 checkResult(status, 0);
7839
7840 ConstElementPtr cfg = CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading();
7841 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", 7841
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg", "false", "true") .c_str()) = ::testing::Message()
;
7842
7843 std::string content_json =
7844 "{"
7845 " \"enable-multi-threading\": true,\n"
7846 " \"thread-pool-size\": 0,\n"
7847 " \"packet-queue-size\": 64\n"
7848 "}";
7849 ConstElementPtr param;
7850 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_7850; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7850; } } else gtest_label_testnothrow_7850
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7850, ("Expected: " "param = Element::fromJSON(content_json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
7851 << "invalid context_json, test is broken";
7852 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"
, 7852, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "param->equals(*cfg)", "false", "true") .c_str()) = ::testing
::Message()
7853 << "expected: " << *(param) << std::endl
7854 << " actual: " << *(cfg) << std::endl;
7855}
7856
7857// This test checks that adding multi threading settings works.
7858TEST_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"
, 7858), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7858), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7858), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_multiThreadingSettings_Test
>); void Dhcp4ParserTest_multiThreadingSettings_Test::TestBody
()
{
7859 std::string content_json =
7860 "{"
7861 " \"enable-multi-threading\": true,\n"
7862 " \"thread-pool-size\": 48,\n"
7863 " \"packet-queue-size\": 1024\n"
7864 "}";
7865 std::string config = "{ " + genIfaceConfig() + ","
7866 "\"subnet4\": [ ], "
7867 "\"multi-threading\": " + content_json + "}";
7868
7869 ConstElementPtr json;
7870 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_7870
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_7870
; } } else gtest_label_testnothrow_7870 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7870, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
7871 extractConfig(config);
7872
7873 ConstElementPtr status;
7874 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_7874; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7874; } } else gtest_label_testnothrow_7874
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7874, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
7875 checkResult(status, 0);
7876
7877 ConstElementPtr cfg = CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading();
7878 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", 7878
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "cfg", "false", "true") .c_str()) = ::testing::Message()
;
7879
7880 ConstElementPtr param;
7881 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_7881; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7881; } } else gtest_label_testnothrow_7881
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7881, ("Expected: " "param = Element::fromJSON(content_json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
7882 << "invalid context_json, test is broken";
7883 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"
, 7883, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "param->equals(*cfg)", "false", "true") .c_str()) = ::testing
::Message()
7884 << "expected: " << *(param) << std::endl
7885 << " actual: " << *(cfg) << std::endl;
7886}
7887
7888// Verify that parsing for the global parameter, parked-packet-limit,
7889// is correct.
7890TEST_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"
, 7890), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7890), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7890), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_parkedPacketLimit_Test
>); void Dhcp4ParserTest_parkedPacketLimit_Test::TestBody(
)
{
7891 // Config without parked-packet-limit
7892 string config_no_limit = "{ " + genIfaceConfig() + ","
7893 "\"subnet4\": [ ] "
7894 "}";
7895
7896 // Config with parked-packet-limit
7897 string config_limit = "{ " + genIfaceConfig() + ","
7898 "\"parked-packet-limit\": 777, "
7899 "\"subnet4\": [ ] "
7900 "}";
7901
7902 // Config with an invalid parked-packet-limit
7903 string bad_limit = "{ " + genIfaceConfig() + ","
7904 "\"parked-packet-limit\": \"boo\", "
7905 "\"subnet4\": [ ] "
7906 "}";
7907
7908 // Should not exist after construction.
7909 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"
, 7909, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "CfgMgr::instance().getStagingCfg()->getConfiguredGlobal(\"parked-packet-limit\")"
, "true", "false") .c_str()) = ::testing::Message()
;
7910
7911 // Configuration with no limit should default to 256.
7912 configure(config_no_limit, CONTROL_RESULT_SUCCESS, "");
7913 ConstElementPtr ppl;
7914 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"
, 7914, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ppl = CfgMgr::instance().getStagingCfg()->getConfiguredGlobal(\"parked-packet-limit\")"
, "false", "true") .c_str()) = ::testing::Message()
;
7915 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"
, 7915, gtest_ar.failure_message()) = ::testing::Message()
;
7916
7917 // Clear the config
7918 CfgMgr::instance().clear();
7919
7920 // Configuration with the limit should have the limit value.
7921 configure(config_limit, CONTROL_RESULT_SUCCESS, "");
7922
7923 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"
, 7923, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ppl = CfgMgr::instance().getStagingCfg()->getConfiguredGlobal(\"parked-packet-limit\")"
, "false", "true") .c_str()) = ::testing::Message()
;
7924 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"
, 7924, gtest_ar.failure_message()) = ::testing::Message()
;
7925
7926 // Make sure an invalid limit fails to parse.
7927 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_7927; } 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_7927; } 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_7927
; } } else gtest_label_testthrow_7927 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7927, gtest_msg.value.c_str()) = ::testing::Message()
;
7928}
7929
7930// This test checks that ddns-conflict-resolution-mode value can be specified at
7931// global and subnet levels.
7932TEST_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"
, 7932), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7932), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7932), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_storeDdnsConflictResolutionMode_Test
>); void Dhcp4ParserTest_storeDdnsConflictResolutionMode_Test
::TestBody()
{
7933 std::string config = "{ " + genIfaceConfig() + ","
7934 "\"rebind-timer\": 2000, "
7935 "\"renew-timer\": 1000, "
7936 "\"subnet4\": [ "
7937 "{"
7938 " \"id\": 1,"
7939 " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
7940 " \"ddns-conflict-resolution-mode\": \"check-with-dhcid\","
7941 " \"subnet\": \"192.0.2.0/24\""
7942 "},"
7943 "{"
7944 " \"id\": 2,"
7945 " \"pools\": [ { \"pool\": \"192.0.3.1 - 192.0.3.100\" } ],"
7946 " \"ddns-conflict-resolution-mode\": \"check-exists-with-dhcid\","
7947 " \"subnet\": \"192.0.3.0/24\""
7948 "},"
7949 "{"
7950 " \"id\": 3,"
7951 " \"pools\": [ { \"pool\": \"192.0.4.1 - 192.0.4.100\" } ],"
7952 " \"ddns-conflict-resolution-mode\": \"no-check-without-dhcid\","
7953 " \"subnet\": \"192.0.4.0/24\""
7954 "},"
7955 "{"
7956 " \"id\": 4,"
7957 " \"pools\": [ { \"pool\": \"192.0.5.1 - 192.0.5.100\" } ],"
7958 " \"ddns-conflict-resolution-mode\": \"no-check-with-dhcid\","
7959 " \"subnet\": \"192.0.5.0/24\""
7960 "},"
7961 "{"
7962 " \"id\": 5,"
7963 " \"pools\": [ { \"pool\": \"192.0.6.1 - 192.0.6.100\" } ],"
7964 " \"subnet\": \"192.0.6.0/24\""
7965 "} ],"
7966 "\"valid-lifetime\": 4000,"
7967 "\"ddns-conflict-resolution-mode\": \"no-check-with-dhcid\" }";
7968
7969 ConstElementPtr json;
7970 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_7970
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_7970
; } } else gtest_label_testnothrow_7970 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7970, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
7971 extractConfig(config);
7972
7973 ConstElementPtr status;
7974 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_7974; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_7974; } } else gtest_label_testnothrow_7974
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 7974, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
7975 checkResult(status, 0);
7976
7977 // Check global value.
7978 checkGlobal("ddns-conflict-resolution-mode", "no-check-with-dhcid");
7979
7980 // Check values for all the subnets.
7981 std::string expectedValues[] = {
7982 "check-with-dhcid",
7983 "check-exists-with-dhcid",
7984 "no-check-without-dhcid",
7985 "no-check-with-dhcid",
7986 "no-check-with-dhcid"
7987 };
7988 CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
7989 char addr[10];
7990 ConstSubnet4Ptr subnet1;
7991 for (int i = 0; i < 5; i++) {
7992 snprintf(addr, sizeof(addr), "192.0.%d.1", i+2);
7993 subnet1 = cfg->selectSubnet(IOAddress(addr));
7994 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"
, 7994, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet1", "false", "true") .c_str()) = ::testing::Message(
)
;
7995 // Reset the fetch global function to staging (vs current) config.
7996 Subnet4Ptr mutable_subnet1 = boost::const_pointer_cast<Subnet4>(subnet1);
7997 mutable_subnet1->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
7998 return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
7999 });
8000 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"
, 8000, gtest_ar.failure_message()) = ::testing::Message()
;
8001 }
8002}
8003
8004// This test verifies that class tagging can occur at any scope.
8005TEST_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", 8005
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8005), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8005), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_classTagging_Test
>); void Dhcp4ParserTest_classTagging_Test::TestBody()
{
8006 std::string config = "{ " + genIfaceConfig() + ","
8007 R"^(
8008 "option-data": [{
8009 "name": "domain-name",
8010 "data": "example.com",
8011 "client-classes": [ "in-global" ]
8012 }],
8013 "valid-lifetime": 4000,
8014 "rebind-timer": 2000,
8015 "renew-timer": 1000,
8016 "shared-networks": [{
8017 "name": "foo",
8018 "subnet4": [{
8019 "id": 1,
8020 "subnet": "192.0.2.0/24",
8021 "option-data": [{
8022 "name": "domain-name",
8023 "data": "example.com",
8024 "client-classes": [ "in-subnet" ]
8025 }],
8026 "pools": [{
8027 "pool": "192.0.2.0/28",
8028 "option-data": [{
8029 "name": "domain-name",
8030 "data": "example.com",
8031 "client-classes": [ "in-pool" ]
8032 }]
8033 }],
8034 "reservations": [{
8035 "hw-address": "AA:BB:CC:DD:EE:FF",
8036 "option-data": [{
8037 "name": "domain-name",
8038 "data": "example.com",
8039 "client-classes": [ "in-reservation" ]
8040 }]
8041 }]
8042 }],
8043 "option-data": [{
8044 "name": "domain-name",
8045 "data": "example.com",
8046 "client-classes": [ "in-network" ]
8047 }]
8048 }],
8049 "client-classes": [{
8050 "name": "foo",
8051 "option-data": [{
8052 "name": "domain-name",
8053 "data": "example.com",
8054 "client-classes": [ "in-class" ]
8055 }]
8056 }]
8057 })^";
8058
8059 ConstElementPtr json;
8060 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_8060
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8060
; } } else gtest_label_testnothrow_8060 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8060, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8061 extractConfig(config);
8062
8063 ConstElementPtr status;
8064 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_8064; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8064; } } else gtest_label_testnothrow_8064
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8064, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8065 checkResult(status, 0);
8066}
8067
8068// This test verifies that duplicates in option-data.client-classes
8069// are ignored and do not affect class order.
8070TEST_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"
, 8070), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8070), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8070), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_optionClientClassesDuplicateCheck_Test
>); void Dhcp4ParserTest_optionClientClassesDuplicateCheck_Test
::TestBody()
{
8071 std::string config = "{ " + genIfaceConfig() + ","
8072 R"^(
8073 "option-data": [{
8074 "name": "domain-name",
8075 "data": "example.com",
8076 "client-classes": [ "foo", "bar", "foo", "bar" ]
8077 }],
8078 "rebind-timer": 2000,
8079 "renew-timer": 1000,
8080 "subnet4": [],
8081 "valid-lifetime": 400
8082 })^";
8083
8084 ConstElementPtr json;
8085 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_8085
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8085
; } } else gtest_label_testnothrow_8085 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8085, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8086 extractConfig(config);
8087
8088 ConstElementPtr status;
8089 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_8089; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8089; } } else gtest_label_testnothrow_8089
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8089, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8090 checkResult(status, 0);
8091
8092 CfgOptionPtr cfg = CfgMgr::instance().getStagingCfg()->getCfgOption();
8093 const auto desc = cfg->get(DHCP4_OPTION_SPACE"dhcp4", DHO_DOMAIN_NAME);
8094 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"
, 8094, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "desc.option_", "false", "true") .c_str()) = ::testing::Message
()
;
8095 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", 8095
, gtest_ar.failure_message()) = ::testing::Message()
;
8096 auto cclasses = desc.client_classes_.begin();
8097 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"
, 8097, gtest_ar.failure_message()) = ::testing::Message()
;
8098 ++cclasses;
8099 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"
, 8099, gtest_ar.failure_message()) = ::testing::Message()
;
8100}
8101
8102// This test verifies that deprecated require-client-classes
8103// gets handled properly.
8104TEST_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"
, 8104), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8104), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8104), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_deprecatedRequireClientClassesCheck_Test
>); void Dhcp4ParserTest_deprecatedRequireClientClassesCheck_Test
::TestBody()
{
8105 // Verify that require-client-classes gets translated
8106 // to evaluate-additional-classes.
8107 std::string config = "{ " + genIfaceConfig() + ","
8108 R"^(
8109 "rebind-timer": 2000,
8110 "renew-timer": 1000,
8111 "shared-networks":[{
8112 "name": "net1",
8113 "require-client-classes": [ "one" ],
8114 "subnet4": [{
8115 "require-client-classes": [ "two" ],
8116 "pools": [{
8117 "pool": "192.0.2.0/28",
8118 "require-client-classes": [ "three" ]
8119 }],
8120 "id": 1,
8121 "subnet": "192.0.2.0/24"
8122 }],
8123 }],
8124 "valid-lifetime": 400
8125 })^";
8126
8127 ConstElementPtr json;
8128 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_8128
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8128
; } } else gtest_label_testnothrow_8128 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8128, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8129 extractConfig(config);
8130
8131 ConstElementPtr status;
8132 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_8132; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8132; } } else gtest_label_testnothrow_8132
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8132, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8133 checkResult(status, 0);
8134
8135 SharedNetwork4Ptr network = CfgMgr::instance().getStagingCfg()->
8136 getCfgSharedNetworks4()->getByName("net1");
8137 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"
, 8137, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "network", "false", "true") .c_str()) = ::testing::Message(
)
;
8138
8139 auto& net_class_list = network->getAdditionalClasses();
8140 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"
, 8140, gtest_ar.failure_message()) = ::testing::Message()
;
8141 auto cclasses = net_class_list.begin();
8142 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"
, 8142, gtest_ar.failure_message()) = ::testing::Message()
;
8143
8144 ConstSubnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
8145 getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.0"));
8146 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"
, 8146, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
8147
8148 auto& sub_class_list = subnet->getAdditionalClasses();
8149 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"
, 8149, gtest_ar.failure_message()) = ::testing::Message()
;
8150 cclasses = sub_class_list.begin();
8151 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"
, 8151, gtest_ar.failure_message()) = ::testing::Message()
;
8152
8153 PoolPtr pool = subnet->getPool(Lease::TYPE_V4, IOAddress("192.0.2.0"), false);
8154 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", 8154
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
8155
8156 auto& pool_class_list = pool->getAdditionalClasses();
8157 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"
, 8157, gtest_ar.failure_message()) = ::testing::Message()
;
8158 cclasses = pool_class_list.begin();
8159 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"
, 8159, gtest_ar.failure_message()) = ::testing::Message()
;
8160
8161 // Now verify that users cannot specify both.
8162 config = "{ " + genIfaceConfig() + ","
8163 R"^(
8164 "rebind-timer": 2000,
8165 "renew-timer": 1000,
8166 "subnet4": [{
8167 "require-client-classes": [ "foo" ],
8168 "evaluate-additional-classes": [ "foo" ],
8169 "pools": [{ "pool": "192.0.2.0/28" }],
8170 "id": 1,
8171 "subnet": "192.0.2.0/24"
8172 }],
8173 "valid-lifetime": 400
8174 })^";
8175
8176 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_8176
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8176
; } } else gtest_label_testnothrow_8176 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8176, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8177
8178 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_8178; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8178; } } else gtest_label_testnothrow_8178
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8178, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8179 checkResult(status, CONTROL_RESULT_ERROR,
8180 "subnet configuration failed: cannot specify both 'require-client-classes'"
8181 " and 'evaluate-additional-classes'. Use only the latter.");
8182}
8183
8184// This test verifies that deprecated only-if-required
8185// gets handled properly.
8186TEST_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"
, 8186), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8186), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8186), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_deprecatedOnlyIfRequiredCheck_Test
>); void Dhcp4ParserTest_deprecatedOnlyIfRequiredCheck_Test
::TestBody()
{
8187 // Verifies that only-if-required gets translated
8188 // to only-in-additional-list.
8189 std::string config = "{ " + genIfaceConfig() + ","
8190 R"^(
8191 "rebind-timer": 2000,
8192 "renew-timer": 1000,
8193 "client-classes": [{
8194 "name": "foo",
8195 "only-if-required": true
8196 }],
8197 "subnet4": [ ],
8198 "valid-lifetime": 400
8199 })^";
8200
8201 ConstElementPtr json;
8202 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_8202
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8202
; } } else gtest_label_testnothrow_8202 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8202, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8203 extractConfig(config);
8204
8205 ConstElementPtr status;
8206 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_8206; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8206; } } else gtest_label_testnothrow_8206
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8206, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8207 checkResult(status, 0);
8208
8209 auto dictionary = CfgMgr::instance().getStagingCfg()->getClientClassDictionary();
8210 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"
, 8210, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "dictionary", "false", "true") .c_str()) = ::testing::Message
()
;
8211 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", 8211
, gtest_ar.failure_message()) = ::testing::Message()
;
8212
8213 ClientClassDefPtr class_def = dictionary->findClass("foo");
8214 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"
, 8214, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "class_def", "false", "true") .c_str()) = ::testing::Message
()
;
8215 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"
, 8215, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "class_def->getAdditional()", "false", "true") .c_str())
= ::testing::Message()
;
8216
8217 // Now verify that users cannot specify both.
8218 config = "{ " + genIfaceConfig() + ","
8219 R"^(
8220 "rebind-timer": 2000,
8221 "renew-timer": 1000,
8222 "client-classes": [{
8223 "name": "foo",
8224 "only-if-required": true,
8225 "only-in-additional-list": true
8226 }],
8227 "subnet4": [ ],
8228 "valid-lifetime": 400
8229 })^";
8230
8231 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_8231
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8231
; } } else gtest_label_testnothrow_8231 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8231, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8232
8233 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_8233; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8233; } } else gtest_label_testnothrow_8233
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8233, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8234 checkResult(status, CONTROL_RESULT_ERROR,
8235 "cannot specify both 'only-if-required' and"
8236 " 'only-in-additional-list'. Use only the latter.");
8237}
8238
8239// This test verifies that deprecated client-class
8240// gets handled properly.
8241TEST_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"
, 8241), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8241), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8241), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_deprecatedClientClassesCheck_Test
>); void Dhcp4ParserTest_deprecatedClientClassesCheck_Test
::TestBody()
{
8242 // Verify that require-client-classes gets translated
8243 // to evaluate-additional-classes.
8244 std::string config = "{ " + genIfaceConfig() + ","
8245 R"^(
8246 "rebind-timer": 2000,
8247 "renew-timer": 1000,
8248 "shared-networks":[{
8249 "name": "net1",
8250 "client-class": "one",
8251 "subnet4": [{
8252 "client-class": "two",
8253 "pools": [{
8254 "pool": "192.0.2.0/28",
8255 "client-class": "three"
8256 }],
8257 "id": 1,
8258 "subnet": "192.0.2.0/24"
8259 }],
8260 }],
8261 "valid-lifetime": 400
8262 })^";
8263
8264 ConstElementPtr json;
8265 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_8265
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8265
; } } else gtest_label_testnothrow_8265 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8265, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8266 extractConfig(config);
8267
8268 ConstElementPtr status;
8269 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_8269; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8269; } } else gtest_label_testnothrow_8269
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8269, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8270 checkResult(status, 0);
8271
8272 SharedNetwork4Ptr network = CfgMgr::instance().getStagingCfg()->
8273 getCfgSharedNetworks4()->getByName("net1");
8274 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"
, 8274, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "network", "false", "true") .c_str()) = ::testing::Message(
)
;
8275
8276 auto& net_class_list = network->getClientClasses();
8277 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"
, 8277, gtest_ar.failure_message()) = ::testing::Message()
;
8278 auto cclasses = net_class_list.begin();
8279 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"
, 8279, gtest_ar.failure_message()) = ::testing::Message()
;
8280
8281 auto subnet = CfgMgr::instance().getStagingCfg()->
8282 getCfgSubnets4()->getBySubnetId(1);
8283 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"
, 8283, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
8284
8285 auto& sub_class_list = subnet->getClientClasses();
8286 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"
, 8286, gtest_ar.failure_message()) = ::testing::Message()
;
8287 cclasses = sub_class_list.begin();
8288 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"
, 8288, gtest_ar.failure_message()) = ::testing::Message()
;
8289
8290 PoolPtr pool = subnet->getPool(Lease::TYPE_V4, IOAddress("192.0.2.0"), false);
8291 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", 8291
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
8292
8293 auto& pool_class_list = pool->getClientClasses();
8294 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"
, 8294, gtest_ar.failure_message()) = ::testing::Message()
;
8295 cclasses = pool_class_list.begin();
8296 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"
, 8296, gtest_ar.failure_message()) = ::testing::Message()
;
8297
8298 // Now verify that users cannot specify both. We don't check all scopes
8299 // as they all use the same function.
8300 config = "{ " + genIfaceConfig() + ","
8301 R"^(
8302 "rebind-timer": 2000,
8303 "renew-timer": 1000,
8304 "subnet4": [{
8305 "client-class": "foo",
8306 "client-classes": [ "bar" ],
8307 "pools": [{ "pool": "192.0.2.0/28" }],
8308 "id": 1,
8309 "subnet": "192.0.2.0/24"
8310 }],
8311 "valid-lifetime": 400
8312 })^";
8313
8314 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_8314
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8314
; } } else gtest_label_testnothrow_8314 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8314, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8315
8316 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_8316; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8316; } } else gtest_label_testnothrow_8316
: return ::testing::internal::AssertHelper(::testing::TestPartResult
::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8316, ("Expected: " "status = configureDhcp4Server(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8317 checkResult(status, CONTROL_RESULT_ERROR,
8318 "subnet configuration failed: cannot specify both 'client-class'"
8319 " and 'client-classes'. Use only the latter.");
8320}
8321
8322// Verifies ddns-ttl-percent is supported at global,
8323// shared-network, and subnet scopes.
8324TEST_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", 8324
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8324), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8324), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_ddnsTtlPercent_Test
>); void Dhcp4ParserTest_ddnsTtlPercent_Test::TestBody()
{
8325 string config = R"(
8326 {
8327 "ddns-ttl-percent": 0.75,
8328 "valid-lifetime": 4000,
8329 "shared-networks": [{
8330 "name": "net",
8331 "ddns-ttl-percent": 0.50,
8332 "subnet4": [{
8333 "id": 1,
8334 "subnet": "10.0.2.0/24",
8335 "ddns-ttl-percent": 0.25
8336 }],
8337 }]
8338 }
8339 )";
8340
8341 ConstElementPtr json;
8342 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_8342
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8342
; } } else gtest_label_testnothrow_8342 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8342, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8343 extractConfig(config);
8344
8345 ConstElementPtr status;
8346
8347 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_8347; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8347; } } else gtest_label_testnothrow_8347
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8347, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8348 // returned value should be 0 (success)
8349 checkResult(status, 0);
8350
8351 // Commit it so global inheritance works.
8352 CfgMgr::instance().commit();
8353
8354 ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
8355 getCfgSubnets4()->selectSubnet(IOAddress("10.0.2.0"));
8356 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"
, 8356, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
8357
8358 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", 8358
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlPercent(Network::Inheritance::NONE).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8359 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"
, 8359, gtest_ar.failure_message()) = ::testing::Message()
;
8360
8361 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"
, 8361, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlPercent(Network::Inheritance::PARENT_NETWORK).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8362 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"
, 8362, gtest_ar.failure_message()) = ::testing::Message()
;
8363
8364 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", 8364
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlPercent(Network::Inheritance::GLOBAL).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8365 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"
, 8365, gtest_ar.failure_message()) = ::testing::Message()
;
8366}
8367
8368// Verifies ddns-ttl is supported at global,
8369// shared-network, and subnet scopes.
8370TEST_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", 8370
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8370), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8370), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_ddnsTtl_Test
>); void Dhcp4ParserTest_ddnsTtl_Test::TestBody()
{
8371 string config = R"(
8372 {
8373 "ddns-ttl": 750,
8374 "valid-lifetime": 4000,
8375 "shared-networks": [{
8376 "name": "net",
8377 "ddns-ttl": 500,
8378 "subnet4": [{
8379 "id": 1,
8380 "subnet": "10.0.2.0/24",
8381 "ddns-ttl": 250
8382 }],
8383 }]
8384 }
8385 )";
8386
8387 ConstElementPtr json;
8388 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_8388
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8388
; } } else gtest_label_testnothrow_8388 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8388, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8389 extractConfig(config);
8390
8391 ConstElementPtr status;
8392 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_8392; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8392; } } else gtest_label_testnothrow_8392
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8392, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8393
8394 // returned value should be 0 (success)
8395 checkResult(status, 0);
8396
8397 // Commit it so global inheritance works.
8398 CfgMgr::instance().commit();
8399
8400 ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
8401 getCfgSubnets4()->selectSubnet(IOAddress("10.0.2.0"));
8402 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"
, 8402, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
8403
8404 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", 8404
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtl(Network::Inheritance::NONE).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8405 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"
, 8405, gtest_ar.failure_message()) = ::testing::Message()
;
8406
8407 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"
, 8407, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtl(Network::Inheritance::PARENT_NETWORK).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8408 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"
, 8408, gtest_ar.failure_message()) = ::testing::Message()
;
8409
8410 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", 8410
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtl(Network::Inheritance::GLOBAL).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8411 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"
, 8411, gtest_ar.failure_message()) = ::testing::Message()
;
8412}
8413
8414// Verifies ddns-ttl-min is supported at global,
8415// shared-network, and subnet scopes.
8416TEST_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", 8416
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8416), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8416), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_ddnsTtlMin_Test
>); void Dhcp4ParserTest_ddnsTtlMin_Test::TestBody()
{
8417 string config = R"(
8418 {
8419 "ddns-ttl-min": 750,
8420 "valid-lifetime": 4000,
8421 "shared-networks": [{
8422 "name": "net",
8423 "ddns-ttl-min": 500,
8424 "subnet4": [{
8425 "id": 1,
8426 "subnet": "10.0.2.0/24",
8427 "ddns-ttl-min": 250
8428 }],
8429 }]
8430 }
8431 )";
8432
8433 ConstElementPtr json;
8434 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_8434
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8434
; } } else gtest_label_testnothrow_8434 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8434, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8435 extractConfig(config);
8436
8437 ConstElementPtr status;
8438 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_8438; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8438; } } else gtest_label_testnothrow_8438
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8438, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8439
8440 // returned value should be 0 (success)
8441 checkResult(status, 0);
8442
8443 // Commit it so global inheritance works.
8444 CfgMgr::instance().commit();
8445
8446 ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
8447 getCfgSubnets4()->selectSubnet(IOAddress("10.0.2.0"));
8448 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"
, 8448, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
8449
8450 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", 8450
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlMin(Network::Inheritance::NONE).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8451 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"
, 8451, gtest_ar.failure_message()) = ::testing::Message()
;
8452
8453 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"
, 8453, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlMin(Network::Inheritance::PARENT_NETWORK).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8454 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"
, 8454, gtest_ar.failure_message()) = ::testing::Message()
;
8455
8456 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", 8456
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlMin(Network::Inheritance::GLOBAL).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8457 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"
, 8457, gtest_ar.failure_message()) = ::testing::Message()
;
8458}
8459
8460// Verifies ddns-ttl-max is supported at global,
8461// shared-network, and subnet scopes.
8462TEST_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", 8462
), (::testing::internal::GetTypeId<Dhcp4ParserTest>()),
::testing::internal::SuiteApiResolver< Dhcp4ParserTest>
::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8462), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8462), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_ddnsTtlMax_Test
>); void Dhcp4ParserTest_ddnsTtlMax_Test::TestBody()
{
8463 string config = R"(
8464 {
8465 "ddns-ttl-max": 750,
8466 "valid-lifetime": 4000,
8467 "shared-networks": [{
8468 "name": "net",
8469 "ddns-ttl-max": 500,
8470 "subnet4": [{
8471 "id": 1,
8472 "subnet": "10.0.2.0/24",
8473 "ddns-ttl-max": 250
8474 }],
8475 }]
8476 }
8477 )";
8478
8479 ConstElementPtr json;
8480 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_8480
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8480
; } } else gtest_label_testnothrow_8480 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8480, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8481 extractConfig(config);
8482
8483 ConstElementPtr status;
8484 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_8484; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8484; } } else gtest_label_testnothrow_8484
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8484, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8485
8486 // returned value should be 0 (success)
8487 checkResult(status, 0);
8488
8489 // Commit it so global inheritance works.
8490 CfgMgr::instance().commit();
8491
8492 ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
8493 getCfgSubnets4()->selectSubnet(IOAddress("10.0.2.0"));
8494 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"
, 8494, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
8495
8496 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", 8496
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlMax(Network::Inheritance::NONE).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8497 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"
, 8497, gtest_ar.failure_message()) = ::testing::Message()
;
8498
8499 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"
, 8499, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlMax(Network::Inheritance::PARENT_NETWORK).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8500 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"
, 8500, gtest_ar.failure_message()) = ::testing::Message()
;
8501
8502 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", 8502
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet->getDdnsTtlMax(Network::Inheritance::GLOBAL).unspecified()"
, "true", "false") .c_str()) = ::testing::Message()
;
8503 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"
, 8503, gtest_ar.failure_message()) = ::testing::Message()
;
8504}
8505
8506// Verifies that DDNS parameters are supported in pools.
8507TEST_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"
, 8507), (::testing::internal::GetTypeId<Dhcp4ParserTest>
()), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetSetUpCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8507), ::testing::internal::SuiteApiResolver< Dhcp4ParserTest
>::GetTearDownCaseOrSuite("../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8507), new ::testing::internal::TestFactoryImpl<Dhcp4ParserTest_poolDdnsParameters_Test
>); void Dhcp4ParserTest_poolDdnsParameters_Test::TestBody
()
{
8508 string config = R"(
8509 {
8510 "valid-lifetime": 4000,
8511 "subnet4": [{
8512 "id": 1,
8513 "subnet": "192.0.0.0/16",
8514 "pools": [{
8515 "pool": "192.0.1.0/24",
8516 "ddns-send-updates": true,
8517 "ddns-override-no-update": true,
8518 "ddns-override-client-update": true,
8519 "ddns-replace-client-name": "always",
8520 "ddns-generated-prefix": "prefix",
8521 "ddns-qualifying-suffix": "suffix",
8522 "hostname-char-set": "[a-z]",
8523 "hostname-char-replacement": "X",
8524 "ddns-update-on-renew": true,
8525 "ddns-ttl-percent": 0.5,
8526 "ddns-conflict-resolution-mode": "check-with-dhcid",
8527 "ddns-ttl-min": 200,
8528 "ddns-ttl-max": 500
8529 },
8530 {
8531 "pool": "192.0.2.0/24",
8532 "ddns-ttl": 300
8533 }]
8534 }]
8535 }
8536 )";
8537
8538 ConstElementPtr json;
8539 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_8539
; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_8539
; } } else gtest_label_testnothrow_8539 : return ::testing::internal
::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8539, ("Expected: " "json = parseDHCP4(config)" " doesn't throw an exception.\n"
" Actual: " + gtest_msg.value) .c_str()) = ::testing::Message
()
;
8540 extractConfig(config);
8541
8542 ConstElementPtr status;
8543 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_8543; } catch (...) { gtest_msg.value
= "it throws."; goto gtest_label_testnothrow_8543; } } else gtest_label_testnothrow_8543
: ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "../../../src/bin/dhcp4/tests/config_parser_unittest.cc"
, 8543, ("Expected: " "status = Dhcpv4SrvTest::configure(*srv_, json)"
" doesn't throw an exception.\n" " Actual: " + gtest_msg.value
) .c_str()) = ::testing::Message()
;
8544
8545 // returned value should be 0 (success)
8546 checkResult(status, 0);
8547
8548 // Commit it so global inheritance works.
8549 CfgMgr::instance().commit();
8550
8551 ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
8552 getCfgSubnets4()->selectSubnet(IOAddress("192.0.0.0"));
8553 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"
, 8553, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "subnet", "false", "true") .c_str()) = ::testing::Message()
;
8554
8555 const PoolCollection pools = subnet->getPools(Lease::TYPE_V4);
8556 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"
, 8556, gtest_ar.failure_message()) = ::testing::Message()
;
8557
8558 // First pool specifies all but ddns-ttl.
8559 PoolPtr pool = pools.at(0);
8560 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", 8560
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
8561
8562 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"
, 8562, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsSendUpdates().unspecified()", "true", "false"
) .c_str()) = ::testing::Message()
;
8563 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"
, 8563, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsSendUpdates().get()", "false", "true") .c_str
()) = ::testing::Message()
;
8564
8565 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"
, 8565, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsOverrideNoUpdate().unspecified()", "true",
"false") .c_str()) = ::testing::Message()
;
8566 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"
, 8566, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsOverrideNoUpdate().get()", "false", "true"
) .c_str()) = ::testing::Message()
;
8567
8568 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"
, 8568, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsOverrideClientUpdate().unspecified()", "true"
, "false") .c_str()) = ::testing::Message()
;
8569 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"
, 8569, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsOverrideClientUpdate().get()", "false", "true"
) .c_str()) = ::testing::Message()
;
8570
8571 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"
, 8571, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsReplaceClientNameMode().unspecified()", "true"
, "false") .c_str()) = ::testing::Message()
;
8572 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"
, 8573, gtest_ar.failure_message()) = ::testing::Message()
8573 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"
, 8573, gtest_ar.failure_message()) = ::testing::Message()
;
8574
8575 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"
, 8575, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsGeneratedPrefix().unspecified()", "true", "false"
) .c_str()) = ::testing::Message()
;
8576 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"
, 8576, gtest_ar.failure_message()) = ::testing::Message()
;
8577
8578 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"
, 8578, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsQualifyingSuffix().unspecified()", "true",
"false") .c_str()) = ::testing::Message()
;
8579 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"
, 8579, gtest_ar.failure_message()) = ::testing::Message()
;
8580
8581 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"
, 8581, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getHostnameCharSet().unspecified()", "true", "false"
) .c_str()) = ::testing::Message()
;
8582 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"
, 8582, gtest_ar.failure_message()) = ::testing::Message()
;
8583
8584 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"
, 8584, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getHostnameCharReplacement().unspecified()", "true"
, "false") .c_str()) = ::testing::Message()
;
8585 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"
, 8585, gtest_ar.failure_message()) = ::testing::Message()
;
8586
8587 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"
, 8587, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsUpdateOnRenew().unspecified()", "true", "false"
) .c_str()) = ::testing::Message()
;
8588 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"
, 8588, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsUpdateOnRenew().get()", "false", "true") .
c_str()) = ::testing::Message()
;
8589
8590 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"
, 8590, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsTtlPercent().unspecified()", "true", "false"
) .c_str()) = ::testing::Message()
;
8591 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", 8591
, gtest_ar.failure_message()) = ::testing::Message()
;
8592
8593 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"
, 8593, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsConflictResolutionMode().unspecified()", "true"
, "false") .c_str()) = ::testing::Message()
;
8594 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"
, 8594, gtest_ar.failure_message()) = ::testing::Message()
;
8595
8596 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"
, 8596, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsTtl().unspecified()", "false", "true") .c_str
()) = ::testing::Message()
;
8597
8598 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"
, 8598, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsTtlMin().unspecified()", "true", "false") .
c_str()) = ::testing::Message()
;
8599 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", 8599
, gtest_ar.failure_message()) = ::testing::Message()
;
8600
8601 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"
, 8601, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsTtlMax().unspecified()", "true", "false") .
c_str()) = ::testing::Message()
;
8602 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", 8602
, gtest_ar.failure_message()) = ::testing::Message()
;
8603
8604 // Second pool only specifies ddns-ttl.
8605 pool = pools.at(1);
8606 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", 8606
, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool", "false", "true") .c_str()) = ::testing::Message()
;
8607
8608 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"
, 8608, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsSendUpdates().unspecified()", "false", "true"
) .c_str()) = ::testing::Message()
;
8609 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"
, 8609, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsOverrideNoUpdate().unspecified()", "false"
, "true") .c_str()) = ::testing::Message()
;
8610 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"
, 8610, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsOverrideClientUpdate().unspecified()", "false"
, "true") .c_str()) = ::testing::Message()
;
8611 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"
, 8611, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsReplaceClientNameMode().unspecified()", "false"
, "true") .c_str()) = ::testing::Message()
;
8612 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"
, 8612, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsGeneratedPrefix().unspecified()", "false",
"true") .c_str()) = ::testing::Message()
;
8613 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"
, 8613, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsQualifyingSuffix().unspecified()", "false"
, "true") .c_str()) = ::testing::Message()
;
8614 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"
, 8614, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getHostnameCharSet().unspecified()", "false", "true"
) .c_str()) = ::testing::Message()
;
8615 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"
, 8615, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getHostnameCharReplacement().unspecified()", "false"
, "true") .c_str()) = ::testing::Message()
;
8616 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"
, 8616, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsUpdateOnRenew().unspecified()", "false", "true"
) .c_str()) = ::testing::Message()
;
8617 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"
, 8617, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsTtlPercent().unspecified()", "false", "true"
) .c_str()) = ::testing::Message()
;
8618 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"
, 8618, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsConflictResolutionMode().unspecified()", "false"
, "true") .c_str()) = ::testing::Message()
;
8619 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"
, 8619, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsTtlMin().unspecified()", "false", "true") .
c_str()) = ::testing::Message()
;
8620
8621 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"
, 8621, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsTtl().unspecified()", "true", "false") .c_str
()) = ::testing::Message()
;
8622 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", 8622
, gtest_ar.failure_message()) = ::testing::Message()
;
8623
8624 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"
, 8624, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "pool->getDdnsTtlMax().unspecified()", "false", "true") .
c_str()) = ::testing::Message()
;
8625}
8626
8627} // 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_