Line data Source code
1 : // Copyright (c) 2019-2025 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/prinbee
4 : // contact@m2osw.com
5 : //
6 : // This program is free software: you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation, either version 3 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program 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 : // You should have received a copy of the GNU General Public License
17 : // along with this program. If not, see <https://www.gnu.org/licenses/>.
18 :
19 : // self
20 : //
21 : #include "catch_main.h"
22 :
23 :
24 : // prinbee
25 : //
26 : #include <prinbee/utils.h>
27 :
28 :
29 : // advgetopt
30 : //
31 : //#include <advgetopt/options.h>
32 :
33 :
34 : // snapdev
35 : //
36 : //#include <snapdev/enum_class_math.h>
37 : //#include <snapdev/not_reached.h>
38 :
39 :
40 : // C++
41 : //
42 : //#include <iomanip>
43 :
44 :
45 : // last include
46 : //
47 : #include <snapdev/poison.h>
48 :
49 :
50 :
51 : namespace
52 : {
53 :
54 :
55 :
56 :
57 : }
58 : // no name namespace
59 :
60 :
61 2 : CATCH_TEST_CASE("utils_defaults", "[utils][valid]")
62 : {
63 4 : CATCH_START_SECTION("utils_defaults: verify default context path")
64 : {
65 1 : CATCH_REQUIRE(strcmp(prinbee::get_default_prinbee_path(), "/var/lib/prinbee") == 0);
66 : }
67 3 : CATCH_END_SECTION()
68 :
69 4 : CATCH_START_SECTION("utils_defaults: verify default user:group names")
70 : {
71 1 : CATCH_REQUIRE(strcmp(prinbee::get_prinbee_user(), "prinbee") == 0);
72 1 : CATCH_REQUIRE(strcmp(prinbee::get_prinbee_group(), "prinbee") == 0);
73 : }
74 3 : CATCH_END_SECTION()
75 2 : }
76 :
77 :
78 4 : CATCH_TEST_CASE("utils_validate_name", "[utils][valid]")
79 : {
80 6 : CATCH_START_SECTION("utils_validate_name: validate name -- first character")
81 : {
82 96 : for(char c(' '); c <= '~'; ++c)
83 : {
84 95 : char buf[2] = { c, '\0' };
85 95 : if((c >= 'A' && c <= 'Z')
86 69 : || (c >= 'a' && c <= 'z')
87 43 : || c == '_')
88 : {
89 53 : CATCH_REQUIRE(prinbee::validate_name(buf));
90 53 : }
91 : else
92 : {
93 42 : CATCH_REQUIRE_FALSE(prinbee::validate_name(buf));
94 : }
95 : }
96 : }
97 5 : CATCH_END_SECTION()
98 :
99 6 : CATCH_START_SECTION("utils_validate_name: validate name -- beyond first character")
100 : {
101 96 : for(char c(' '); c <= '~'; ++c)
102 : {
103 95 : char buf1[3] = { '_', c, '\0' };
104 95 : char buf2[4] = { '_', c, c, '\0' };
105 95 : if((c >= 'A' && c <= 'Z')
106 69 : || (c >= 'a' && c <= 'z')
107 43 : || (c >= '0' && c <= '9')
108 33 : || c == '_')
109 : {
110 63 : CATCH_REQUIRE(prinbee::validate_name(buf1));
111 63 : CATCH_REQUIRE(prinbee::validate_name(buf2));
112 63 : }
113 : else
114 : {
115 32 : CATCH_REQUIRE_FALSE(prinbee::validate_name(buf1));
116 32 : CATCH_REQUIRE_FALSE(prinbee::validate_name(buf2));
117 : }
118 : }
119 : }
120 5 : CATCH_END_SECTION()
121 :
122 6 : CATCH_START_SECTION("utils_validate_name: validate name -- empty/null")
123 : {
124 1 : CATCH_REQUIRE_FALSE(prinbee::validate_name(nullptr));
125 1 : CATCH_REQUIRE_FALSE(prinbee::validate_name(""));
126 : }
127 5 : CATCH_END_SECTION()
128 :
129 6 : CATCH_START_SECTION("utils_validate_name: validate name -- too long")
130 : {
131 3 : std::string const too_long("too_long");
132 1 : CATCH_REQUIRE(prinbee::validate_name(too_long.c_str())); // it works with default max_length
133 :
134 : // it fails when max_length < too_long.length()
135 : //
136 8 : for(std::size_t size(1); size < too_long.length(); ++size)
137 : {
138 7 : CATCH_REQUIRE_FALSE(prinbee::validate_name(too_long.c_str(), size));
139 : }
140 1 : }
141 5 : CATCH_END_SECTION()
142 4 : }
143 :
144 :
145 6 : CATCH_TEST_CASE("utils_validate_bitfield_name", "[utils][valid]")
146 : {
147 8 : CATCH_START_SECTION("utils_validate_bitfield_name: validate bit field name -- first character")
148 : {
149 96 : for(char c(' '); c <= '~'; ++c)
150 : {
151 95 : char buf[4] = { c, '=', c, '\0' };
152 95 : if((c >= 'A' && c <= 'Z')
153 69 : || (c >= 'a' && c <= 'z')
154 43 : || c == '_')
155 : {
156 53 : CATCH_REQUIRE(prinbee::validate_bit_field_name(buf));
157 53 : }
158 : else
159 : {
160 42 : CATCH_REQUIRE_FALSE(prinbee::validate_bit_field_name(buf));
161 : }
162 : }
163 : }
164 7 : CATCH_END_SECTION()
165 :
166 8 : CATCH_START_SECTION("utils_validate_bitfield_name: validate bit field name -- beyond first character")
167 : {
168 96 : for(char c(' '); c <= '~'; ++c)
169 : {
170 95 : char buf1[5] = { '_', c, '=', 'a', '\0' };
171 95 : char buf2[6] = { '_', c, c, '=', 'a', '\0' };
172 95 : if((c >= 'A' && c <= 'Z')
173 69 : || (c >= 'a' && c <= 'z')
174 43 : || (c >= '0' && c <= '9')
175 33 : || c == '_')
176 : {
177 63 : CATCH_REQUIRE(prinbee::validate_bit_field_name(buf1));
178 63 : CATCH_REQUIRE(prinbee::validate_bit_field_name(buf2));
179 63 : }
180 : else
181 : {
182 32 : CATCH_REQUIRE_FALSE(prinbee::validate_bit_field_name(buf1));
183 32 : CATCH_REQUIRE_FALSE(prinbee::validate_bit_field_name(buf2));
184 : }
185 : }
186 : }
187 7 : CATCH_END_SECTION()
188 :
189 8 : CATCH_START_SECTION("utils_validate_bitfield_name: validate bit field name -- empty/null")
190 : {
191 1 : CATCH_REQUIRE_FALSE(prinbee::validate_bit_field_name(nullptr));
192 1 : CATCH_REQUIRE_FALSE(prinbee::validate_bit_field_name(""));
193 : }
194 7 : CATCH_END_SECTION()
195 :
196 8 : CATCH_START_SECTION("utils_validate_bitfield_name: validate bit field name -- too long")
197 : {
198 3 : std::string const too_long("too_long");
199 1 : CATCH_REQUIRE(prinbee::validate_bit_field_name((too_long + "=foo").c_str())); // it works with default max_length
200 1 : CATCH_REQUIRE(prinbee::validate_bit_field_name((too_long + "=foo").c_str(), too_long.length())); // and the exact si
201 :
202 : // it fails when max_length < too_long.length()
203 : //
204 8 : for(std::size_t size(1); size < too_long.length(); ++size)
205 : {
206 7 : CATCH_REQUIRE_FALSE(prinbee::validate_bit_field_name((too_long + "=foo").c_str(), size));
207 : }
208 1 : }
209 7 : CATCH_END_SECTION()
210 :
211 8 : CATCH_START_SECTION("utils_validate_bitfield_name: validate flag name -- too long")
212 : {
213 3 : std::string const too_long("too_long");
214 1 : CATCH_REQUIRE(prinbee::validate_bit_field_name(("b=" + too_long).c_str())); // it works with default max_length
215 1 : CATCH_REQUIRE(prinbee::validate_bit_field_name(("b=" + too_long).c_str(), too_long.length())); // and the exact size
216 :
217 : // it fails when max_length < too_long.length()
218 : //
219 8 : for(std::size_t size(1); size < too_long.length(); ++size)
220 : {
221 7 : CATCH_REQUIRE_FALSE(prinbee::validate_bit_field_name(("b=" + too_long).c_str(), size));
222 7 : CATCH_REQUIRE_FALSE(prinbee::validate_bit_field_name(("b=" + too_long + ":12").c_str(), size));
223 7 : CATCH_REQUIRE_FALSE(prinbee::validate_bit_field_name(("b=" + too_long + ":12/f").c_str(), size));
224 7 : CATCH_REQUIRE_FALSE(prinbee::validate_bit_field_name(("b=" + too_long + "/f").c_str(), size));
225 : }
226 1 : }
227 7 : CATCH_END_SECTION()
228 :
229 8 : CATCH_START_SECTION("utils_validate_bitfield_name: validate bit field name -- with fields")
230 : {
231 1 : CATCH_REQUIRE(prinbee::validate_bit_field_name("bits=foo"));
232 1 : CATCH_REQUIRE(prinbee::validate_bit_field_name("bits=foo:1"));
233 1 : CATCH_REQUIRE(prinbee::validate_bit_field_name("bits=foo:2"));
234 1 : CATCH_REQUIRE(prinbee::validate_bit_field_name("bits=foo:58"));
235 1 : CATCH_REQUIRE(prinbee::validate_bit_field_name("bits=foo:58/bar"));
236 1 : CATCH_REQUIRE(prinbee::validate_bit_field_name("bits=foo/bar:58"));
237 1 : CATCH_REQUIRE(prinbee::validate_bit_field_name("bits=foo:7/bar:9"));
238 :
239 1 : CATCH_REQUIRE(prinbee::validate_bit_field_name("eight_bits=null/advance:4/efficient:2/sign"));
240 1 : CATCH_REQUIRE(prinbee::validate_bit_field_name("bloom_filter_flags=algorithm:4/renewing"));
241 :
242 1 : CATCH_REQUIRE_FALSE(prinbee::validate_bit_field_name("bits=123"));
243 1 : CATCH_REQUIRE_FALSE(prinbee::validate_bit_field_name("bits=foo:"));
244 1 : CATCH_REQUIRE_FALSE(prinbee::validate_bit_field_name("bits=foo:/bar"));
245 1 : CATCH_REQUIRE_FALSE(prinbee::validate_bit_field_name("bits=foo/bar/"));
246 : }
247 7 : CATCH_END_SECTION()
248 6 : }
249 :
250 :
251 5 : CATCH_TEST_CASE("utils_validate_char_name", "[utils][valid]")
252 : {
253 7 : CATCH_START_SECTION("utils_validate_char_name: validate CHAR field name -- first character")
254 : {
255 96 : for(char c(' '); c <= '~'; ++c)
256 : {
257 95 : char buf[4] = { c, '=', '3', '\0' };
258 95 : if((c >= 'A' && c <= 'Z')
259 69 : || (c >= 'a' && c <= 'z')
260 43 : || c == '_')
261 : {
262 53 : CATCH_REQUIRE(prinbee::validate_char_field_name(buf));
263 53 : }
264 : else
265 : {
266 42 : CATCH_REQUIRE_FALSE(prinbee::validate_char_field_name(buf));
267 : }
268 : }
269 : }
270 6 : CATCH_END_SECTION()
271 :
272 7 : CATCH_START_SECTION("utils_validate_char_name: validate CHAR field name -- beyond first character")
273 : {
274 96 : for(char c(' '); c <= '~'; ++c)
275 : {
276 95 : char buf1[5] = { '_', c, '=', '5', '\0' };
277 95 : char buf2[6] = { '_', c, c, '=', '5', '\0' };
278 95 : if((c >= 'A' && c <= 'Z')
279 69 : || (c >= 'a' && c <= 'z')
280 43 : || (c >= '0' && c <= '9')
281 33 : || c == '_')
282 : {
283 63 : CATCH_REQUIRE(prinbee::validate_char_field_name(buf1));
284 63 : CATCH_REQUIRE(prinbee::validate_char_field_name(buf2));
285 63 : }
286 : else
287 : {
288 32 : CATCH_REQUIRE_FALSE(prinbee::validate_char_field_name(buf1));
289 32 : CATCH_REQUIRE_FALSE(prinbee::validate_char_field_name(buf2));
290 : }
291 : }
292 : }
293 6 : CATCH_END_SECTION()
294 :
295 7 : CATCH_START_SECTION("utils_validate_char_name: validate CHAR field name -- empty/null")
296 : {
297 1 : CATCH_REQUIRE_FALSE(prinbee::validate_char_field_name(nullptr));
298 1 : CATCH_REQUIRE_FALSE(prinbee::validate_char_field_name(""));
299 : }
300 6 : CATCH_END_SECTION()
301 :
302 7 : CATCH_START_SECTION("utils_validate_char_name: validate CHAR field name -- too long")
303 : {
304 3 : std::string const too_long("too_long");
305 1 : CATCH_REQUIRE(prinbee::validate_char_field_name((too_long + "=123").c_str())); // it works with default max_length
306 1 : CATCH_REQUIRE(prinbee::validate_char_field_name((too_long + "=123").c_str(), too_long.length())); // and the exact size
307 :
308 : // it fails when max_length < too_long.length()
309 : //
310 8 : for(std::size_t size(1); size < too_long.length(); ++size)
311 : {
312 7 : CATCH_REQUIRE_FALSE(prinbee::validate_char_field_name((too_long + "=123").c_str(), size));
313 : }
314 1 : }
315 6 : CATCH_END_SECTION()
316 :
317 7 : CATCH_START_SECTION("utils_validate_char_name: validate CHAR field name -- with fields")
318 : {
319 1 : CATCH_REQUIRE(prinbee::validate_char_field_name("char=0"));
320 1 : CATCH_REQUIRE(prinbee::validate_char_field_name("char=1"));
321 1 : CATCH_REQUIRE(prinbee::validate_char_field_name("char=2"));
322 1 : CATCH_REQUIRE(prinbee::validate_char_field_name("char=12345"));
323 1 : CATCH_REQUIRE(prinbee::validate_char_field_name("char=99999999999999999999999999999999")); // number is too large, but we do not check that here
324 :
325 1 : CATCH_REQUIRE_FALSE(prinbee::validate_char_field_name("char"));
326 1 : CATCH_REQUIRE_FALSE(prinbee::validate_char_field_name("char="));
327 1 : CATCH_REQUIRE_FALSE(prinbee::validate_char_field_name("char=foo"));
328 1 : CATCH_REQUIRE_FALSE(prinbee::validate_char_field_name("char=123foo"));
329 1 : CATCH_REQUIRE_FALSE(prinbee::validate_char_field_name("char=123!"));
330 : }
331 6 : CATCH_END_SECTION()
332 5 : }
333 :
334 :
335 3 : CATCH_TEST_CASE("utils_invalid", "[utils][invalid]")
336 : {
337 5 : CATCH_START_SECTION("utils_invalid: validate_name() max_length cannot be 0")
338 : {
339 3 : CATCH_REQUIRE_THROWS_MATCHES(
340 : prinbee::validate_name("bad_max_length", 0)
341 : , prinbee::logic_error
342 : , Catch::Matchers::ExceptionMessage("logic_error: max_length parameter cannot be zero in validate_name()."));
343 : }
344 4 : CATCH_END_SECTION()
345 :
346 5 : CATCH_START_SECTION("utils_invalid: validate_bit_field_name() max_length cannot be 0")
347 : {
348 3 : CATCH_REQUIRE_THROWS_MATCHES(
349 : prinbee::validate_bit_field_name("bad_max_length=flag:3", 0)
350 : , prinbee::logic_error
351 : , Catch::Matchers::ExceptionMessage("logic_error: max_length parameter cannot be zero in validate_bit_field_name()."));
352 : }
353 4 : CATCH_END_SECTION()
354 :
355 5 : CATCH_START_SECTION("utils_invalid: validate_char_field_name() max_length cannot be 0")
356 : {
357 3 : CATCH_REQUIRE_THROWS_MATCHES(
358 : prinbee::validate_char_field_name("bad_max_length=32", 0)
359 : , prinbee::logic_error
360 : , Catch::Matchers::ExceptionMessage("logic_error: max_length parameter cannot be zero in validate_char_field_name()."));
361 : }
362 4 : CATCH_END_SECTION()
363 3 : }
364 :
365 :
366 :
367 : // vim: ts=4 sw=4 et
|