Line data Source code
1 : // Copyright (c) 2011-2023 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/libaddr
4 : // contact@m2osw.com
5 : //
6 : // Permission is hereby granted, free of charge, to any
7 : // person obtaining a copy of this software and
8 : // associated documentation files (the "Software"), to
9 : // deal in the Software without restriction, including
10 : // without limitation the rights to use, copy, modify,
11 : // merge, publish, distribute, sublicense, and/or sell
12 : // copies of the Software, and to permit persons to whom
13 : // the Software is furnished to do so, subject to the
14 : // following conditions:
15 : //
16 : // The above copyright notice and this permission notice
17 : // shall be included in all copies or substantial
18 : // portions of the Software.
19 : //
20 : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
21 : // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
22 : // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 : // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
24 : // EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 : // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 : // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 : // ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 : // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 : // SOFTWARE.
30 :
31 :
32 : /** \file
33 : * \brief Test the Address Validator.
34 : *
35 : * The advgetopt library comes with a way to validate command line options.
36 : * The validator_address class extends that feature by offering programmers
37 : * a way to validate input data as an IP address.
38 : */
39 :
40 : // addr
41 : //
42 : #include <libaddr/validator_address.h>
43 :
44 :
45 : // self
46 : //
47 : #include "catch_main.h"
48 :
49 :
50 : // last include
51 : //
52 : #include <snapdev/poison.h>
53 :
54 :
55 :
56 :
57 8 : CATCH_TEST_CASE("validator", "[validator]")
58 : {
59 8 : CATCH_START_SECTION("validator: default validation")
60 : {
61 4 : advgetopt::validator::pointer_t address_validator(advgetopt::validator::create("address", advgetopt::string_list_t()));
62 :
63 1 : CATCH_REQUIRE(address_validator != nullptr);
64 1 : CATCH_REQUIRE(address_validator->name() == "address");
65 :
66 1 : CATCH_REQUIRE(address_validator->validate("192.168.1.1"));
67 1 : CATCH_REQUIRE(address_validator->validate("10.0.0.10:5434"));
68 1 : CATCH_REQUIRE_FALSE(address_validator->validate("10.0.0.10:5434/24"));
69 1 : CATCH_REQUIRE(address_validator->validate("::"));
70 1 : CATCH_REQUIRE(address_validator->validate("[::]:307"));
71 1 : CATCH_REQUIRE(address_validator->validate("f801::5"));
72 1 : }
73 8 : CATCH_END_SECTION()
74 :
75 8 : CATCH_START_SECTION("validator: allow all")
76 : {
77 1 : advgetopt::string_list_t const flags{
78 : "address=commas spaces newlines range lookup",
79 : "port=yes",
80 : "mask=address",
81 : "comment",
82 : "defaults=192.168.2.1:4040/24",
83 13 : };
84 3 : advgetopt::validator::pointer_t address_validator(advgetopt::validator::create("address", flags));
85 :
86 1 : CATCH_REQUIRE(address_validator != nullptr);
87 1 : CATCH_REQUIRE(address_validator->name() == "address");
88 :
89 1 : CATCH_REQUIRE(address_validator->validate("192.168.1.1"));
90 1 : CATCH_REQUIRE(address_validator->validate("10.0.0.10:5434"));
91 1 : CATCH_REQUIRE(address_validator->validate("10.0.0.10:5434/24"));
92 1 : CATCH_REQUIRE(address_validator->validate(":5/255.255.255.0"));
93 1 : CATCH_REQUIRE(address_validator->validate("::"));
94 1 : CATCH_REQUIRE(address_validator->validate("f801::5/48"));
95 1 : }
96 8 : CATCH_END_SECTION()
97 :
98 8 : CATCH_START_SECTION("validator: allow \"nothing\"")
99 : {
100 1 : advgetopt::string_list_t const flags{
101 : "address=no",
102 : "port=yes",
103 7 : };
104 3 : advgetopt::validator::pointer_t address_validator(advgetopt::validator::create("address", flags));
105 :
106 1 : CATCH_REQUIRE(address_validator != nullptr);
107 1 : CATCH_REQUIRE(address_validator->name() == "address");
108 :
109 1 : CATCH_REQUIRE(address_validator->validate("192.168.1.1"));
110 1 : CATCH_REQUIRE(address_validator->validate("10.0.0.10:5434"));
111 1 : CATCH_REQUIRE(address_validator->validate("::"));
112 1 : CATCH_REQUIRE(address_validator->validate("f801::5"));
113 1 : }
114 8 : CATCH_END_SECTION()
115 :
116 8 : CATCH_START_SECTION("validator: unknown option")
117 : {
118 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: \"coment=\" is not a known option for the address validator.");
119 1 : advgetopt::string_list_t const flags{
120 : "", // ignored
121 : "coment=", // "comment" mispelled
122 : "", // ignored
123 9 : };
124 3 : advgetopt::validator::pointer_t address_validator(advgetopt::validator::create("address", flags));
125 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
126 :
127 1 : CATCH_REQUIRE(address_validator != nullptr);
128 1 : CATCH_REQUIRE(address_validator->name() == "address");
129 :
130 1 : CATCH_REQUIRE(address_validator->validate("5.6.7.8"));
131 1 : }
132 8 : CATCH_END_SECTION()
133 :
134 8 : CATCH_START_SECTION("validator: address=no prevents any other option")
135 : {
136 1 : std::vector<std::string> options = {
137 : "commas",
138 : "lookup",
139 : "newlines",
140 : "range",
141 : "required",
142 : "spaces",
143 : "yes",
144 17 : };
145 8 : for(auto const & opt : options)
146 : {
147 14 : std::string address("address=");
148 7 : if((rand() & 1) == 0)
149 : {
150 3 : address += "no " + opt;
151 : }
152 : else
153 : {
154 4 : address += opt + " no";
155 : }
156 7 : advgetopt::string_list_t const flags{
157 : address,
158 : "port=yes",
159 42 : };
160 7 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: the \"no\" option in the address=... option must be used by itself.");
161 21 : advgetopt::validator::pointer_t address_validator(advgetopt::validator::create("address", flags));
162 7 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
163 :
164 7 : CATCH_REQUIRE(address_validator != nullptr);
165 7 : CATCH_REQUIRE(address_validator->name() == "address");
166 :
167 7 : CATCH_REQUIRE(address_validator->validate("192.168.1.1"));
168 7 : CATCH_REQUIRE(address_validator->validate("10.0.0.10:5434"));
169 7 : CATCH_REQUIRE(address_validator->validate("::"));
170 7 : CATCH_REQUIRE(address_validator->validate("f801::5"));
171 7 : }
172 1 : }
173 8 : CATCH_END_SECTION()
174 :
175 8 : CATCH_START_SECTION("validator: address=<invalid flag name>")
176 : {
177 : // first character of each supported/valid flag to hit that break;
178 : // statement in the address sub-switch()
179 : //
180 1 : std::vector<std::string> options = {
181 : "console",
182 : "loop",
183 : "now",
184 : "real",
185 : "slice",
186 : "yield",
187 : "zero", // plus one that has no case ...
188 17 : };
189 8 : for(auto const & opt : options)
190 : {
191 7 : advgetopt::string_list_t const flags{
192 14 : "address=" + opt + " required",
193 : "port=yes",
194 49 : };
195 14 : SNAP_CATCH2_NAMESPACE::push_expected_log(
196 : "error: the \""
197 14 : + opt
198 21 : + "\" parameter is not understood by the \"address\" options.");
199 21 : advgetopt::validator::pointer_t address_validator(advgetopt::validator::create("address", flags));
200 7 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
201 :
202 7 : CATCH_REQUIRE(address_validator != nullptr);
203 7 : CATCH_REQUIRE(address_validator->name() == "address");
204 :
205 7 : CATCH_REQUIRE(address_validator->validate("192.168.1.1"));
206 7 : CATCH_REQUIRE(address_validator->validate("10.0.0.10:5434"));
207 7 : CATCH_REQUIRE(address_validator->validate("::"));
208 7 : CATCH_REQUIRE(address_validator->validate("f801::5"));
209 7 : }
210 1 : }
211 8 : CATCH_END_SECTION()
212 :
213 8 : CATCH_START_SECTION("validator: address=<required vs yes>")
214 : {
215 : // first character of each supported/valid flag to hit that break;
216 : // statement in the address sub-switch()
217 : //
218 1 : std::vector<std::string> options = {
219 : "address=required yes",
220 : "address=yes required",
221 7 : };
222 3 : for(auto const & opt : options)
223 : {
224 2 : advgetopt::string_list_t const flags{
225 : opt,
226 : "port=yes",
227 12 : };
228 2 : SNAP_CATCH2_NAMESPACE::push_expected_log(
229 : "error: the \"yes\" and \"required\" options are mutually exclusive, use one or the other (or none, which defaults to \"yes\").");
230 6 : advgetopt::validator::pointer_t address_validator(advgetopt::validator::create("address", flags));
231 2 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
232 :
233 2 : CATCH_REQUIRE(address_validator != nullptr);
234 2 : CATCH_REQUIRE(address_validator->name() == "address");
235 :
236 2 : CATCH_REQUIRE(address_validator->validate("192.168.1.1"));
237 2 : CATCH_REQUIRE(address_validator->validate("10.0.0.10:5434"));
238 2 : CATCH_REQUIRE(address_validator->validate("::"));
239 2 : CATCH_REQUIRE(address_validator->validate("f801::5"));
240 2 : }
241 1 : }
242 8 : CATCH_END_SECTION()
243 :
244 8 : CATCH_START_SECTION("validator: <invalid parameter name>=<whatever>")
245 : {
246 : // first character of each supported/valid flag to hit that break;
247 : // statement in the address sub-switch()
248 : //
249 1 : std::vector<std::string> parameters = {
250 : "audio",
251 : "call",
252 : "drawing",
253 : "mug",
254 : "paint",
255 : "zero", // plus one that has no case ...
256 15 : };
257 7 : for(auto const & p : parameters)
258 : {
259 6 : advgetopt::string_list_t const flags{
260 : p + "=yes",
261 24 : };
262 12 : SNAP_CATCH2_NAMESPACE::push_expected_log(
263 : "error: \""
264 12 : + p
265 18 : + "=yes\" is not a known option for the address validator.");
266 18 : advgetopt::validator::pointer_t address_validator(advgetopt::validator::create("address", flags));
267 6 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
268 :
269 6 : CATCH_REQUIRE(address_validator != nullptr);
270 6 : CATCH_REQUIRE(address_validator->name() == "address");
271 :
272 6 : CATCH_REQUIRE(address_validator->validate("192.168.1.1"));
273 6 : CATCH_REQUIRE(address_validator->validate("10.0.0.10:5434"));
274 6 : CATCH_REQUIRE(address_validator->validate("::"));
275 6 : CATCH_REQUIRE(address_validator->validate("f801::5"));
276 6 : }
277 1 : }
278 8 : CATCH_END_SECTION()
279 8 : }
280 :
281 :
282 :
283 : // vim: ts=4 sw=4 et
|