The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
pair_list_perf_test.c
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/** Performance tests for lists of fr_pair_t
18 *
19 * @file src/lib/util/pair_list_perf_test.c
20 * @author Nick Porter <nick.porter@networkradius.com>
21 *
22 * @copyright 2021 Network RADIUS SAS <legal@networkradius.com>
23 */
24
25/**
26 * The 'TEST_INIT' macro provided by 'acutest.h' allows registering a function to be called
27 * before call the unit tests. Therefore, It calls the function ALL THE TIME causing an overhead.
28 * That is why we are initializing pair_list_perf_init() by "__attribute__((constructor));" reducing the
29 * test execution by 50% of the time.
30 */
31#define USE_CONSTRUCTOR
32
33/*
34 * It should be declared before including "acutest.h"
35 */
36#ifdef USE_CONSTRUCTOR
37static void pair_list_perf_init(void) __attribute__((constructor));
38#else
39static void pair_list_perf_init(void);
40#define TEST_INIT pair_list_perf_init()
41#endif
42
43#include <freeradius-devel/util/acutest.h>
44
45#ifdef WITH_VERIFY_PTR
46#undef WITH_VERIFY_PTR
47#endif
48
49#include <freeradius-devel/util/dict_test.h>
50#include <freeradius-devel/server/base.h>
51#include <freeradius-devel/util/rand.h>
52#include <freeradius-devel/util/pair.h>
53#include <freeradius-devel/util/pair_legacy.h>
54/*
55 * Global variables
56 */
57
58static fr_dict_t *test_dict;
59static TALLOC_CTX *autofree;
60
61static char const *test_attrs_0 = \
62 "Test-String-# = \"hello\"," /* 1 */
63 "Test-Octets-# = 0x0102030405060708," /* 2 */
64 "Test-IPv4-Addr-# = 192.168.1.1," /* 3 */
65 "Test-IPv4-Prefix-# = 192.168/16," /* 4 */
66 "Test-IPv6-Addr-# = fd12:3456:789a:1::1," /* 5 */
67 "Test-IPv6-Prefix-# = fd12:3456:789a:1::/64," /* 6 */
68 "Test-Ethernet-# = 11:22:33:44:55:66," /* 7 */
69 "Test-Uint8-# = 255," /* 8 */
70 "Test-Uint16-# = 65535," /* 9 */
71 "Test-Uint32-# = 4294967295," /* 10 */
72 "Test-Uint64-# = 18446744073709551615," /* 11 */
73 "Test-Int8-# = -120," /* 12 */
74 "Test-Int16-# = -4573," /* 13 */
75 "Test-Int32-# = 45645," /* 14 */
76 "Test-Int64-# = 85645," /* 15 */
77 "Test-Float32-# = 1.134," /* 16 */
78 "Test-Float64-# = 1.1345," /* 17 */
79 "Test-Date-# += \"Jan 1 2020 00:00:00 UTC\"," /* 18 */
80 "Test-TLV-#.String = \"nested\"," /* 19 */
81 "Test-Struct-#.uint32 = 1234"; /* 20 */
82
83static char const *test_attrs_25 = \
84 "Test-String-# += \"hello\"," /* 1 */
85 "Test-String-# += \"goodbye\"," /* 2 */
86 "Test-String-# += \"hola\"," /* 3 */
87 "Test-String-# += \"hasta pronto\"," /* 4 */
88 "Test-String-# += \"bonjour\"," /* 5 */
89 "Test-Octets-# += 0x0102030405060708," /* 6 */
90 "Test-IPv4-Addr-# = 192.168.1.1," /* 7 */
91 "Test-IPv4-Prefix-# = 192.168/16," /* 8 */
92 "Test-IPv6-Addr-# = fd12:3456:789a:1::1," /* 9 */
93 "Test-IPv6-Prefix-# = fd12:3456:789a:1::/64," /* 10 */
94 "Test-Ethernet-# = 11:22:33:44:55:66," /* 11 */
95 "Test-Uint8-# = 255," /* 12 */
96 "Test-Uint16-# = 65535," /* 13 */
97 "Test-Uint32-# = 4294967295," /* 14 */
98 "Test-Uint64-# = 18446744073709551615," /* 15 */
99 "Test-Int64-# = 85645," /* 16 */
100 "Test-Float32-# = 1.134," /* 17 */
101 "Test-Date-# += \"Jan 1 2020 00:00:00 UTC\"," /* 18 */
102 "Test-TLV-#.String = \"nested\"," /* 19 */
103 "Test-Struct-#.uint32 = 1234"; /* 20 */
104
105static char const *test_attrs_50 = \
106 "Test-String-# += \"hello\"," /* 1 */
107 "Test-String-# += \"goodbye\"," /* 2 */
108 "Test-String-# += \"hola\"," /* 3 */
109 "Test-String-# += \"hasta pronto\"," /* 4 */
110 "Test-String-# += \"bonjour\"," /* 5 */
111 "Test-String-# += \"au revoir\"," /* 6 */
112 "Test-String-# += \"halo\"," /* 7 */
113 "Test-String-# += \"kwaheri\"," /* 8 */
114 "Test-String-# += \"ciao\"," /* 9 */
115 "Test-String-# += \"arrivederci\"," /* 10 */
116 "Test-IPv4-Addr-# = 192.168.1.1," /* 11 */
117 "Test-IPv4-Prefix-# = 192.168/16," /* 12 */
118 "Test-IPv6-Addr-# = fd12:3456:789a:1::1," /* 13 */
119 "Test-IPv6-Prefix-# = fd12:3456:789a:1::/64," /* 14 */
120 "Test-Ethernet-# = 11:22:33:44:55:66," /* 15 */
121 "Test-Uint8-# = 255," /* 16 */
122 "Test-Int64-# = 85645," /* 17 */
123 "Test-Date-# += \"Jan 1 2020 00:00:00 UTC\"," /* 18 */
124 "Test-TLV-#.String = \"nested\"," /* 19 */
125 "Test-Struct-#.uint32 = 1234"; /* 20 */
126
127static char const *test_attrs_75 = \
128 "Test-String-# += \"hello\"," /* 1 */
129 "Test-String-# += \"goodbye\"," /* 2 */
130 "Test-String-# += \"hola\"," /* 3 */
131 "Test-String-# += \"hasta pronto\"," /* 4 */
132 "Test-String-# += \"bonjour\"," /* 5 */
133 "Test-String-# += \"au revoir\"," /* 6 */
134 "Test-String-# += \"halo\"," /* 7 */
135 "Test-String-# += \"kwaheri\"," /* 8 */
136 "Test-String-# += \"ciao\"," /* 9 */
137 "Test-String-# += \"arrivederci\"," /* 10 */
138 "Test-String-# += \"halo\"," /* 11 */
139 "Test-String-# += \"selamat tinggal\"," /* 12 */
140 "Test-String-# += \"你好\"," /* 13 */
141 "Test-String-# += \"再见\"," /* 14 */
142 "Test-String-# += \"Привет\"," /* 15 */
143 "Test-Uint8-# = 255," /* 16 */
144 "Test-Int64-# = 85645," /* 17 */
145 "Test-Date-# += \"Jan 1 2020 00:00:00 UTC\"," /* 18 */
146 "Test-TLV-#.String = \"nested\"," /* 19 */
147 "Test-Struct-#.uint32 = 1234"; /* 20 */
148
149static char const *test_attrs_100 = \
150 "Test-String-# += \"hello\"," /* 1 */
151 "Test-String-# += \"goodbye\"," /* 2 */
152 "Test-String-# += \"hola\"," /* 3 */
153 "Test-String-# += \"hasta pronto\"," /* 4 */
154 "Test-String-# += \"bonjour\"," /* 5 */
155 "Test-String-# += \"au revoir\"," /* 6 */
156 "Test-String-# += \"halo\"," /* 7 */
157 "Test-String-# += \"kwaheri\"," /* 8 */
158 "Test-String-# += \"ciao\"," /* 9 */
159 "Test-String-# += \"arrivederci\"," /* 10 */
160 "Test-String-# += \"halo\"," /* 11 */
161 "Test-String-# += \"selamat tinggal\"," /* 12 */
162 "Test-String-# += \"你好\"," /* 13 */
163 "Test-String-# += \"再见\"," /* 14 */
164 "Test-String-# += \"Привет\"," /* 15 */
165 "Test-String-# += \"до свидания\"," /* 16 */
166 "Test-String-# += \"вся слава советской россии\"," /* 17 */
167 "Test-String-# += \"у нас есть видео с мочой\"," /* 18 */
168 "Test-String-# += \"Байден заплатит за\"," /* 19 */
169 "Test-String-# += \"приставание к бурундукам\""; /* 20 */
170
171static fr_pair_t **source_vps_0; //!< List with zero duplicate attributes.
172static fr_pair_t **source_vps_25; //!< List with 25% duplicate attributes.
173static fr_pair_t **source_vps_50; //!< List with 50% duplicate attributes.
174static fr_pair_t **source_vps_75; //!< List with 75% duplicate attributes.
175static fr_pair_t **source_vps_100; //!< List with 100% duplicate attributes, i.e. all the same.
176
177static void pair_list_init(TALLOC_CTX *ctx, fr_pair_t ***out, fr_dict_t const *dict, char const *pairs,
178 int const perc, int const reps)
179{
180 fr_pair_list_t list, full_list, dups;
181 char *prep_pairs, *p;
182 fr_pair_t *vp, *next;
183 int i;
184 size_t j;
185 ssize_t slen;
186 fr_pair_t **vp_array;
187 size_t input_count;
188
189 fr_pair_list_init(&list);
190 fr_pair_list_init(&full_list);
191 fr_pair_list_init(&dups);
192
193 prep_pairs = talloc_array(NULL, char, strlen(pairs) + 1);
194
195 /*
196 * Build a list of pairs, repeating the source list 'reps' times
197 * replacing the '#' in the source string with the number of this
198 * repetition.
199 */
200 for (i = 0; i < reps; i++) {
201 fr_pair_parse_t root, relative;
202
203 root = (fr_pair_parse_t) {
204 .ctx = ctx,
205 .da = fr_dict_root(dict),
206 .list = &list,
207 };
208 relative = (fr_pair_parse_t) { };
209
210 strcpy(prep_pairs, pairs);
211 p = prep_pairs;
212 while ((p = strchr(p, '#'))) {
213 *p = (char)(i + 48);
214 }
215 slen = fr_pair_list_afrom_substr(&root, &relative, &FR_SBUFF_IN(prep_pairs, strlen(prep_pairs)));
216 if (slen <= 0) fr_perror("pair_list_perf_tests");
217 TEST_ASSERT(slen > 0);
218
219 input_count = fr_pair_list_num_elements(&list);
220
221 if ((i == 0) && (perc > 0) && (reps > 0)) {
222 fr_pair_t *new_vp;
223 /*
224 * Copy the required number of attributes from the first iteration
225 * to use for duplicating attributes to required percentage.
226 * Duplicates are at the beginning of the source list
227 */
228 /* coverity[dereference] */
229 vp = fr_pair_list_head(&list);
230 for (j = 0; j < (size_t)(input_count * perc / 100); j++) {
231 /* coverity[dereference] */
232 new_vp = fr_pair_copy(ctx, vp);
233 fr_pair_append(&dups, new_vp);
234 /* coverity[dereference] */
235 vp = fr_pair_list_next(&list, vp);
236 }
237 }
238
239 if (i == 0) {
240 /*
241 * On the first iteration, just move the test pairs to the final list
242 */
243 fr_pair_list_append(&full_list, &list);
244 } else {
245 /*
246 * With subsequent iterations, replicate the duplicates from the first
247 * iteration to maintain the percentage of attribute repeats
248 */
249 vp = fr_pair_list_head(&dups);
250 fr_pair_sublist_copy(ctx, &full_list, &dups, vp, 0);
251
252 /*
253 * Walk past equivalent pairs in new source list
254 */
255 vp = fr_pair_list_head(&list);
256 for (j = 0; j < fr_pair_list_num_elements(&dups); j++) vp = fr_pair_list_next(&list, vp);
257
258 /*
259 * Append copy remaining pairs from source list to destination
260 */
261 fr_pair_sublist_copy(ctx, &full_list, &list, vp, 0);
262
263 /*
264 * We copied pairs rather than moving, free the source
265 */
266 fr_pair_list_free(&list);
267 }
268 }
269
270 talloc_free(prep_pairs);
271
272 /*
273 * Move vps to array so we can pick them randomly to populate the test list.
274 */
275 vp_array = talloc_array(ctx, fr_pair_t *, fr_pair_list_num_elements(&full_list));
276 for (vp = fr_pair_list_head(&full_list), i = 0; vp; vp = next, i++) {
277 next = fr_pair_list_next(&full_list, vp);
278 fr_pair_remove(&full_list, vp);
279 vp_array[i] = vp;
280 }
281
282 *out = vp_array;
283}
284
285void pair_list_perf_init(void)
286{
288 if (!autofree) {
289 error:
290 fr_perror("pair_list_perf_tests");
291 fr_exit_now(EXIT_FAILURE);
292 }
293
294 /*
295 * Mismatch between the binary and the libraries it depends on
296 */
297 if (fr_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) goto error;
298
299 if (fr_dict_test_init(autofree, &test_dict, NULL) < 0) goto error;
300
301 if (fr_dict_test_attrs_init(test_dict, fr_dict_test_attrs, 100, 1) < 0) goto error;
302 if (fr_dict_test_attrs_init(test_dict, fr_dict_test_attrs, 200, 2) < 0) goto error;
303 if (fr_dict_test_attrs_init(test_dict, fr_dict_test_attrs, 300, 3) < 0) goto error;
304 if (fr_dict_test_attrs_init(test_dict, fr_dict_test_attrs, 400, 4) < 0) goto error;
305
306 pair_list_init(autofree, &source_vps_0, test_dict, test_attrs_0, 0, 5);
307 pair_list_init(autofree, &source_vps_25, test_dict, test_attrs_25, 25, 5);
308 pair_list_init(autofree, &source_vps_50, test_dict, test_attrs_50, 50, 5);
309 pair_list_init(autofree, &source_vps_75, test_dict, test_attrs_75, 75, 5);
310 pair_list_init(autofree, &source_vps_100, test_dict, test_attrs_100, 100, 5);
311
313}
314
315static void do_test_fr_pair_append(unsigned int len, unsigned int perc, unsigned int reps, fr_pair_t *source_vps[])
316{
317 fr_pair_list_t test_vps;
318 unsigned int i, j;
319 fr_pair_t *new_vp;
320 fr_time_t start, end;
322 size_t input_count = talloc_array_length(source_vps);
323 fr_fast_rand_t rand_ctx;
324
325 fr_pair_list_init(&test_vps);
326 rand_ctx.a = fr_rand();
327 rand_ctx.b = fr_rand();
328
329 /*
330 * Only use up to the number of pairs needed from the source to maintain ratio
331 * of attribute repeats.
332 */
333 if (input_count > len) input_count = len;
334
335 /*
336 * Insert pairs into the test list, choosing randomly from the source list
337 */
338 for (i = 0; i < reps; i++) {
339 for (j = 0; j < len; j++) {
340 int idx = fr_fast_rand(&rand_ctx) % input_count;
341 new_vp = fr_pair_copy(autofree, source_vps[idx]);
342 start = fr_time();
343 fr_pair_append(&test_vps, new_vp);
344 end = fr_time();
345 used = fr_time_delta_add(used, fr_time_sub(end, start));
346 }
347 TEST_CHECK(fr_pair_list_num_elements(&test_vps) == len);
348 fr_pair_list_free(&test_vps);
349 }
350 TEST_MSG_ALWAYS("repetitions=%u", reps);
351 TEST_MSG_ALWAYS("perc_rep=%u", perc);
352 TEST_MSG_ALWAYS("list_length=%u", len);
353 TEST_MSG_ALWAYS("used=%"PRId64, fr_time_delta_unwrap(used));
354 TEST_MSG_ALWAYS("per_sec=%0.0lf", (reps * len)/(fr_time_delta_unwrap(used) / (double)NSEC));
355}
356
357static void do_test_fr_pair_find_by_da_idx(unsigned int len, unsigned int perc, unsigned int reps, fr_pair_t *source_vps[])
358{
359 fr_pair_list_t test_vps;
360 unsigned int i, j;
361 fr_pair_t *new_vp;
362 fr_time_t start, end;
364 fr_dict_attr_t const *da;
365 size_t input_count = talloc_array_length(source_vps);
366 fr_fast_rand_t rand_ctx;
367
368 fr_pair_list_init(&test_vps);
369 if (input_count > len) input_count = len;
370 rand_ctx.a = fr_rand();
371 rand_ctx.b = fr_rand();
372
373 /*
374 * Initialise the test list
375 */
376 for (i = 0; i < len; i++) {
377 int idx = fr_fast_rand(&rand_ctx) % input_count;
378 new_vp = fr_pair_copy(autofree, source_vps[idx]);
379 fr_pair_append(&test_vps, new_vp);
380 }
381
382 /*
383 * Find first instance of specific DA
384 */
385 for (i = 0; i < reps; i++) {
386 for (j = 0; j < len; j++) {
387 int idx = fr_fast_rand(&rand_ctx) % input_count;
388 da = source_vps[idx]->da;
389 start = fr_time();
390 (void) fr_pair_find_by_da(&test_vps, NULL, da);
391 end = fr_time();
392 used = fr_time_delta_add(used, fr_time_sub(end, start));
393 }
394 }
395 fr_pair_list_free(&test_vps);
396 TEST_MSG_ALWAYS("repetitions=%u", reps);
397 TEST_MSG_ALWAYS("perc_rep=%u", perc);
398 TEST_MSG_ALWAYS("list_length=%u", len);
399 TEST_MSG_ALWAYS("used=%"PRId64, fr_time_delta_unwrap(used));
400 TEST_MSG_ALWAYS("per_sec=%0.0lf", (reps * len)/(fr_time_delta_unwrap(used) / (double)NSEC));
401}
402
403static void do_test_find_nth(unsigned int len, unsigned int perc, unsigned int reps, fr_pair_t *source_vps[])
404{
405 fr_pair_list_t test_vps;
406 unsigned int i, j, nth_item;
407 fr_pair_t *new_vp;
408 fr_time_t start, end;
410 fr_dict_attr_t const *da;
411 size_t input_count = talloc_array_length(source_vps);
412 fr_fast_rand_t rand_ctx;
413
414 fr_pair_list_init(&test_vps);
415 if (input_count > len) input_count = len;
416 rand_ctx.a = fr_rand();
417 rand_ctx.b = fr_rand();
418
419 /*
420 * Initialise the test list
421 */
422 for (i = 0; i < len; i++) {
423 int idx = fr_fast_rand(&rand_ctx) % input_count;
424 new_vp = fr_pair_copy(autofree, source_vps[idx]);
425 fr_pair_append(&test_vps, new_vp);
426 }
427
428 /*
429 * Find nth instance of specific DA. nth is based on the percentage
430 * of attributes which are repeats.
431 */
432 nth_item = perc == 0 ? 1 : (unsigned int)(len * perc / 100);
433 for (i = 0; i < reps; i++) {
434 for (j = 0; j < len; j++) {
435 int idx = fr_fast_rand(&rand_ctx) % input_count;
436
437 da = source_vps[idx]->da;
438 start = fr_time();
439 (void) fr_pair_find_by_da_idx(&test_vps, da, nth_item);
440 end = fr_time();
441 used = fr_time_delta_add(used, fr_time_sub(end, start));
442 }
443 }
444 fr_pair_list_free(&test_vps);
445 TEST_MSG_ALWAYS("repetitions=%u", reps);
446 TEST_MSG_ALWAYS("perc_rep=%u", perc);
447 TEST_MSG_ALWAYS("list_length=%u", len);
448 TEST_MSG_ALWAYS("used=%"PRId64, fr_time_delta_unwrap(used));
449 TEST_MSG_ALWAYS("per_sec=%0.0lf", (reps * len)/(fr_time_delta_unwrap(used) / (double)NSEC));
450}
451
452static void do_test_fr_pair_list_free(unsigned int len, unsigned int perc, unsigned int reps, fr_pair_t *source_vps[])
453{
454 fr_pair_list_t test_vps;
455 unsigned int i, j;
456 fr_pair_t *new_vp;
457 fr_time_t start, end;
459 size_t input_count = talloc_array_length(source_vps);
460 fr_fast_rand_t rand_ctx;
461
462 fr_pair_list_init(&test_vps);
463 if (input_count > len) input_count = len;
464 rand_ctx.a = fr_rand();
465 rand_ctx.b = fr_rand();
466
467 for (i = 0; i < reps; i++) {
468 for (j = 0; j < len; j++) {
469 int idx = fr_fast_rand(&rand_ctx) % input_count;
470 new_vp = fr_pair_copy(autofree, source_vps[idx]);
471 fr_pair_append(&test_vps, new_vp);
472 }
473 start = fr_time();
474 fr_pair_list_free(&test_vps);
475 end = fr_time();
476 used = fr_time_delta_add(used, fr_time_sub(end, start));
477 }
478 fr_pair_list_free(&test_vps);
479 TEST_MSG_ALWAYS("repetitions=%u", reps);
480 TEST_MSG_ALWAYS("perc_rep=%u", perc);
481 TEST_MSG_ALWAYS("list_length=%u", len);
482 TEST_MSG_ALWAYS("used=%"PRId64, fr_time_delta_unwrap(used));
483 TEST_MSG_ALWAYS("per_sec=%0.0lf", (reps * len)/(fr_time_delta_unwrap(used) / (double)NSEC));
484}
485
486#define test_func(_func, _count, _perc, _source_vps) \
487static void test_ ## _func ## _ ## _count ## _ ## _perc(void)\
488{\
489 do_test_ ## _func(_count, _perc, 10000, _source_vps);\
490}
491
492#define test_funcs(_func, _perc) \
493 test_func(_func, 20, _perc, source_vps_ ## _perc) \
494 test_func(_func, 40, _perc, source_vps_ ## _perc) \
495 test_func(_func, 60, _perc, source_vps_ ## _perc) \
496 test_func(_func, 80, _perc, source_vps_ ## _perc) \
497 test_func(_func, 100, _perc, source_vps_ ## _perc)
498
499#define all_test_funcs(_func) \
500 test_funcs(_func, 0) \
501 test_funcs(_func, 25) \
502 test_funcs(_func, 50) \
503 test_funcs(_func, 75) \
504 test_funcs(_func, 100)
505
508all_test_funcs(find_nth)
510
511#define repetition_tests(_func, _perc) \
512 { #_func "_20_" #_perc, test_ ## _func ## _20_ ## _perc},\
513 { #_func "_40_" #_perc, test_ ## _func ## _40_ ## _perc},\
514 { #_func "_60_" #_perc, test_ ## _func ## _60_ ## _perc},\
515 { #_func "_80_" #_perc, test_ ## _func ## _80_ ## _perc},\
516 { #_func "_100_" #_perc, test_ ## _func ## _100_ ## _perc},\
517
518#define all_repetition_tests(_func) \
519 repetition_tests(_func, 0) \
520 repetition_tests(_func, 25) \
521 repetition_tests(_func, 50) \
522 repetition_tests(_func, 75) \
523 repetition_tests(_func, 100)
524
525TEST_LIST = {
528 all_repetition_tests(find_nth)
530
531 { NULL }
532};
#define TEST_MSG_ALWAYS(...)
Definition acutest.h:222
#define TEST_CHECK(cond)
Definition acutest.h:85
#define TEST_LIST
Definition acutest.h:62
strcpy(log_entry->msg, buffer)
#define TEST_ASSERT(cond)
Definition acutest.h:108
#define fr_exit_now(_x)
Exit without calling atexit() handlers, producing a log message in debug builds.
Definition debug.h:234
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2400
fr_dict_test_attr_t const fr_dict_test_attrs[]
Definition dict_test.c:86
int fr_dict_test_attrs_init(fr_dict_t *dict, fr_dict_test_attr_t const *test_defs, unsigned int base, int inst)
Add our test attributes to our test dictionary.
Definition dict_test.c:176
int fr_dict_test_init(TALLOC_CTX *ctx, fr_dict_t **dict_p, fr_dict_test_attr_t const *test_defs)
Initialise a test dictionary and add our test_defs to it.
Definition dict_test.c:248
talloc_free(reap)
long int ssize_t
unsigned long int size_t
static size_t used
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
Definition pair.c:693
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
Definition pair.c:1345
fr_pair_t * fr_pair_find_by_da_idx(fr_pair_list_t const *list, fr_dict_attr_t const *da, unsigned int idx)
Find a pair with a matching da at a given index.
Definition pair.c:741
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
Definition pair.c:46
int fr_pair_sublist_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from, fr_pair_t const *start, unsigned int count)
Duplicate a list of pairs starting at a particular item.
Definition pair.c:2508
fr_pair_t * fr_pair_copy(TALLOC_CTX *ctx, fr_pair_t const *vp)
Copy a single valuepair.
Definition pair.c:489
fr_slen_t fr_pair_list_afrom_substr(fr_pair_parse_t const *root, fr_pair_parse_t *relative, fr_sbuff_t *in)
Parse a fr_pair_list_t from a substring.
struct fr_pair_parse_s fr_pair_parse_t
TALLOC_CTX * ctx
Definition pair_legacy.h:43
static void do_test_fr_pair_find_by_da_idx(unsigned int len, unsigned int perc, unsigned int reps, fr_pair_t *source_vps[])
#define all_repetition_tests(_func)
static void do_test_fr_pair_append(unsigned int len, unsigned int perc, unsigned int reps, fr_pair_t *source_vps[])
static void pair_list_perf_init(void)
static void do_test_find_nth(unsigned int len, unsigned int perc, unsigned int reps, fr_pair_t *source_vps[])
#define all_test_funcs(_func)
static void do_test_fr_pair_list_free(unsigned int len, unsigned int perc, unsigned int reps, fr_pair_t *source_vps[])
static fr_dict_t * test_dict
static TALLOC_CTX * autofree
uint32_t fr_fast_rand(fr_fast_rand_t *ctx)
Definition rand.c:279
uint32_t fr_rand(void)
Return a 32-bit random number.
Definition rand.c:105
uint32_t b
Definition rand.h:55
uint32_t a
Definition rand.h:55
Smaller fast random number generator.
Definition rand.h:54
#define FR_SBUFF_IN(_start, _len_or_end)
fr_pair_t * vp
#define fr_time()
Allow us to arbitrarily manipulate time.
Definition state_test.c:8
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
Definition pair.h:69
#define talloc_autofree_context
The original function is deprecated, so replace it with our version.
Definition talloc.h:51
int fr_time_start(void)
Initialize the local time.
Definition time.c:150
static fr_time_delta_t fr_time_delta_add(fr_time_delta_t a, fr_time_delta_t b)
Definition time.h:255
static int64_t fr_time_delta_unwrap(fr_time_delta_t time)
Definition time.h:154
#define fr_time_delta_wrap(_time)
Definition time.h:152
#define NSEC
Definition time.h:379
#define fr_time_sub(_a, _b)
Subtract one time from another.
Definition time.h:229
A time delta, a difference in time measured in nanoseconds.
Definition time.h:80
"server local" time.
Definition time.h:69
fr_pair_t * fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
Definition pair_inline.c:70
fr_pair_t * fr_pair_remove(fr_pair_list_t *list, fr_pair_t *vp)
Remove fr_pair_t from a list without freeing.
Definition pair_inline.c:94
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
void fr_pair_list_append(fr_pair_list_t *dst, fr_pair_list_t *src)
Appends a list of fr_pair_t from a temporary list to a destination list.
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
Definition pair_inline.c:43
size_t fr_pair_list_num_elements(fr_pair_list_t const *list)
Get the length of a list of fr_pair_t.
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
Definition strerror.c:733
int fr_check_lib_magic(uint64_t magic)
Check if the application linking to the library has the correct magic number.
Definition version.c:40
#define RADIUSD_MAGIC_NUMBER
Definition version.h:81
static size_t char ** out
Definition value.h:997