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/*
52 * Global variables
53 */
54
55static fr_dict_t *test_dict;
56static TALLOC_CTX *autofree;
57
58static char const *test_attrs_0 = \
59 "Test-String-# = \"hello\"," /* 1 */
60 "Test-Octets-# = 0x0102030405060708," /* 2 */
61 "Test-IPv4-Addr-# = 192.168.1.1," /* 3 */
62 "Test-IPv4-Prefix-# = 192.168/16," /* 4 */
63 "Test-IPv6-Addr-# = fd12:3456:789a:1::1," /* 5 */
64 "Test-IPv6-Prefix-# = fd12:3456:789a:1::/64," /* 6 */
65 "Test-Ethernet-# = 11:22:33:44:55:66," /* 7 */
66 "Test-Uint8-# = 255," /* 8 */
67 "Test-Uint16-# = 65535," /* 9 */
68 "Test-Uint32-# = 4294967295," /* 10 */
69 "Test-Uint64-# = 18446744073709551615," /* 11 */
70 "Test-Int8-# = -120," /* 12 */
71 "Test-Int16-# = -4573," /* 13 */
72 "Test-Int32-# = 45645," /* 14 */
73 "Test-Int64-# = 85645," /* 15 */
74 "Test-Float32-# = 1.134," /* 16 */
75 "Test-Float64-# = 1.1345," /* 17 */
76 "Test-Date-# += \"Jan 1 2020 00:00:00 UTC\"," /* 18 */
77 "Test-TLV-#.String = \"nested\"," /* 19 */
78 "Test-Struct-#.uint32 = 1234"; /* 20 */
79
80static char const *test_attrs_25 = \
81 "Test-String-# += \"hello\"," /* 1 */
82 "Test-String-# += \"goodbye\"," /* 2 */
83 "Test-String-# += \"hola\"," /* 3 */
84 "Test-String-# += \"hasta pronto\"," /* 4 */
85 "Test-String-# += \"bonjour\"," /* 5 */
86 "Test-Octets-# += 0x0102030405060708," /* 6 */
87 "Test-IPv4-Addr-# = 192.168.1.1," /* 7 */
88 "Test-IPv4-Prefix-# = 192.168/16," /* 8 */
89 "Test-IPv6-Addr-# = fd12:3456:789a:1::1," /* 9 */
90 "Test-IPv6-Prefix-# = fd12:3456:789a:1::/64," /* 10 */
91 "Test-Ethernet-# = 11:22:33:44:55:66," /* 11 */
92 "Test-Uint8-# = 255," /* 12 */
93 "Test-Uint16-# = 65535," /* 13 */
94 "Test-Uint32-# = 4294967295," /* 14 */
95 "Test-Uint64-# = 18446744073709551615," /* 15 */
96 "Test-Int64-# = 85645," /* 16 */
97 "Test-Float32-# = 1.134," /* 17 */
98 "Test-Date-# += \"Jan 1 2020 00:00:00 UTC\"," /* 18 */
99 "Test-TLV-#.String = \"nested\"," /* 19 */
100 "Test-Struct-#.uint32 = 1234"; /* 20 */
101
102static char const *test_attrs_50 = \
103 "Test-String-# += \"hello\"," /* 1 */
104 "Test-String-# += \"goodbye\"," /* 2 */
105 "Test-String-# += \"hola\"," /* 3 */
106 "Test-String-# += \"hasta pronto\"," /* 4 */
107 "Test-String-# += \"bonjour\"," /* 5 */
108 "Test-String-# += \"au revoir\"," /* 6 */
109 "Test-String-# += \"halo\"," /* 7 */
110 "Test-String-# += \"kwaheri\"," /* 8 */
111 "Test-String-# += \"ciao\"," /* 9 */
112 "Test-String-# += \"arrivederci\"," /* 10 */
113 "Test-IPv4-Addr-# = 192.168.1.1," /* 11 */
114 "Test-IPv4-Prefix-# = 192.168/16," /* 12 */
115 "Test-IPv6-Addr-# = fd12:3456:789a:1::1," /* 13 */
116 "Test-IPv6-Prefix-# = fd12:3456:789a:1::/64," /* 14 */
117 "Test-Ethernet-# = 11:22:33:44:55:66," /* 15 */
118 "Test-Uint8-# = 255," /* 16 */
119 "Test-Int64-# = 85645," /* 17 */
120 "Test-Date-# += \"Jan 1 2020 00:00:00 UTC\"," /* 18 */
121 "Test-TLV-#.String = \"nested\"," /* 19 */
122 "Test-Struct-#.uint32 = 1234"; /* 20 */
123
124static char const *test_attrs_75 = \
125 "Test-String-# += \"hello\"," /* 1 */
126 "Test-String-# += \"goodbye\"," /* 2 */
127 "Test-String-# += \"hola\"," /* 3 */
128 "Test-String-# += \"hasta pronto\"," /* 4 */
129 "Test-String-# += \"bonjour\"," /* 5 */
130 "Test-String-# += \"au revoir\"," /* 6 */
131 "Test-String-# += \"halo\"," /* 7 */
132 "Test-String-# += \"kwaheri\"," /* 8 */
133 "Test-String-# += \"ciao\"," /* 9 */
134 "Test-String-# += \"arrivederci\"," /* 10 */
135 "Test-String-# += \"halo\"," /* 11 */
136 "Test-String-# += \"selamat tinggal\"," /* 12 */
137 "Test-String-# += \"你好\"," /* 13 */
138 "Test-String-# += \"再见\"," /* 14 */
139 "Test-String-# += \"Привет\"," /* 15 */
140 "Test-Uint8-# = 255," /* 16 */
141 "Test-Int64-# = 85645," /* 17 */
142 "Test-Date-# += \"Jan 1 2020 00:00:00 UTC\"," /* 18 */
143 "Test-TLV-#.String = \"nested\"," /* 19 */
144 "Test-Struct-#.uint32 = 1234"; /* 20 */
145
146static char const *test_attrs_100 = \
147 "Test-String-# += \"hello\"," /* 1 */
148 "Test-String-# += \"goodbye\"," /* 2 */
149 "Test-String-# += \"hola\"," /* 3 */
150 "Test-String-# += \"hasta pronto\"," /* 4 */
151 "Test-String-# += \"bonjour\"," /* 5 */
152 "Test-String-# += \"au revoir\"," /* 6 */
153 "Test-String-# += \"halo\"," /* 7 */
154 "Test-String-# += \"kwaheri\"," /* 8 */
155 "Test-String-# += \"ciao\"," /* 9 */
156 "Test-String-# += \"arrivederci\"," /* 10 */
157 "Test-String-# += \"halo\"," /* 11 */
158 "Test-String-# += \"selamat tinggal\"," /* 12 */
159 "Test-String-# += \"你好\"," /* 13 */
160 "Test-String-# += \"再见\"," /* 14 */
161 "Test-String-# += \"Привет\"," /* 15 */
162 "Test-String-# += \"до свидания\"," /* 16 */
163 "Test-String-# += \"вся слава советской россии\"," /* 17 */
164 "Test-String-# += \"у нас есть видео с мочой\"," /* 18 */
165 "Test-String-# += \"Байден заплатит за\"," /* 19 */
166 "Test-String-# += \"приставание к бурундукам\""; /* 20 */
167
168static fr_pair_t **source_vps_0; //!< List with zero duplicate attributes.
169static fr_pair_t **source_vps_25; //!< List with 25% duplicate attributes.
170static fr_pair_t **source_vps_50; //!< List with 50% duplicate attributes.
171static fr_pair_t **source_vps_75; //!< List with 75% duplicate attributes.
172static fr_pair_t **source_vps_100; //!< List with 100% duplicate attributes, i.e. all the same.
173
174static void pair_list_init(TALLOC_CTX *ctx, fr_pair_t ***out, fr_dict_t const *dict, char const *pairs,
175 int const perc, int const reps)
176{
177 fr_pair_list_t list, full_list, dups;
178 char *prep_pairs, *p;
179 fr_pair_t *vp, *next;
180 int i;
181 size_t j;
182 ssize_t slen;
183 fr_pair_t **vp_array;
184 size_t input_count;
185
186 fr_pair_list_init(&list);
187 fr_pair_list_init(&full_list);
188 fr_pair_list_init(&dups);
189
190 prep_pairs = talloc_array(NULL, char, strlen(pairs) + 1);
191
192 /*
193 * Build a list of pairs, repeating the source list 'reps' times
194 * replacing the '#' in the source string with the number of this
195 * repetition.
196 */
197 for (i = 0; i < reps; i++) {
198 fr_pair_parse_t root, relative;
199
200 root = (fr_pair_parse_t) {
201 .ctx = ctx,
202 .da = fr_dict_root(dict),
203 .list = &list,
204 };
205 relative = (fr_pair_parse_t) { };
206
207 strcpy(prep_pairs, pairs);
208 p = prep_pairs;
209 while ((p = strchr(p, '#'))) {
210 *p = (char)(i + 48);
211 }
212 slen = fr_pair_list_afrom_substr(&root, &relative, &FR_SBUFF_IN(prep_pairs, strlen(prep_pairs)));
213 if (slen <= 0) fr_perror("pair_list_perf_tests");
214 TEST_ASSERT(slen > 0);
215
216 input_count = fr_pair_list_num_elements(&list);
217
218 if ((i == 0) && (perc > 0) && (reps > 0)) {
219 fr_pair_t *new_vp;
220 /*
221 * Copy the required number of attributes from the first iteration
222 * to use for duplicating attributes to required percentage.
223 * Duplicates are at the beginning of the source list
224 */
225 /* coverity[dereference] */
226 vp = fr_pair_list_head(&list);
227 for (j = 0; j < (size_t)(input_count * perc / 100); j++) {
228 /* coverity[dereference] */
229 new_vp = fr_pair_copy(ctx, vp);
230 fr_pair_append(&dups, new_vp);
231 /* coverity[dereference] */
232 vp = fr_pair_list_next(&list, vp);
233 }
234 }
235
236 if (i == 0) {
237 /*
238 * On the first iteration, just move the test pairs to the final list
239 */
240 fr_pair_list_append(&full_list, &list);
241 } else {
242 /*
243 * With subsequent iterations, replicate the duplicates from the first
244 * iteration to maintain the percentage of attribute repeats
245 */
246 vp = fr_pair_list_head(&dups);
247 fr_pair_sublist_copy(ctx, &full_list, &dups, vp, 0);
248
249 /*
250 * Walk past equivalent pairs in new source list
251 */
252 vp = fr_pair_list_head(&list);
253 for (j = 0; j < fr_pair_list_num_elements(&dups); j++) vp = fr_pair_list_next(&list, vp);
254
255 /*
256 * Append copy remaining pairs from source list to destination
257 */
258 fr_pair_sublist_copy(ctx, &full_list, &list, vp, 0);
259
260 /*
261 * We copied pairs rather than moving, free the source
262 */
263 fr_pair_list_free(&list);
264 }
265 }
266
267 talloc_free(prep_pairs);
268
269 /*
270 * Move vps to array so we can pick them randomly to populate the test list.
271 */
272 vp_array = talloc_array(ctx, fr_pair_t *, fr_pair_list_num_elements(&full_list));
273 for (vp = fr_pair_list_head(&full_list), i = 0; vp; vp = next, i++) {
274 next = fr_pair_list_next(&full_list, vp);
275 fr_pair_remove(&full_list, vp);
276 vp_array[i] = vp;
277 }
278
279 *out = vp_array;
280}
281
282void pair_list_perf_init(void)
283{
285 if (!autofree) {
286 error:
287 fr_perror("pair_list_perf_tests");
288 fr_exit_now(EXIT_FAILURE);
289 }
290
291 /*
292 * Mismatch between the binary and the libraries it depends on
293 */
294 if (fr_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) goto error;
295
296 if (fr_dict_test_init(autofree, &test_dict, NULL) < 0) goto error;
297
298 if (fr_dict_test_attrs_init(test_dict, fr_dict_test_attrs, 100, 1) < 0) goto error;
299 if (fr_dict_test_attrs_init(test_dict, fr_dict_test_attrs, 200, 2) < 0) goto error;
300 if (fr_dict_test_attrs_init(test_dict, fr_dict_test_attrs, 300, 3) < 0) goto error;
301 if (fr_dict_test_attrs_init(test_dict, fr_dict_test_attrs, 400, 4) < 0) goto error;
302
303 pair_list_init(autofree, &source_vps_0, test_dict, test_attrs_0, 0, 5);
304 pair_list_init(autofree, &source_vps_25, test_dict, test_attrs_25, 25, 5);
305 pair_list_init(autofree, &source_vps_50, test_dict, test_attrs_50, 50, 5);
306 pair_list_init(autofree, &source_vps_75, test_dict, test_attrs_75, 75, 5);
307 pair_list_init(autofree, &source_vps_100, test_dict, test_attrs_100, 100, 5);
308
310}
311
312static void do_test_fr_pair_append(unsigned int len, unsigned int perc, unsigned int reps, fr_pair_t *source_vps[])
313{
314 fr_pair_list_t test_vps;
315 unsigned int i, j;
316 fr_pair_t *new_vp;
317 fr_time_t start, end;
319 size_t input_count = talloc_array_length(source_vps);
320 fr_fast_rand_t rand_ctx;
321
322 fr_pair_list_init(&test_vps);
323 rand_ctx.a = fr_rand();
324 rand_ctx.b = fr_rand();
325
326 /*
327 * Only use up to the number of pairs needed from the source to maintain ratio
328 * of attribute repeats.
329 */
330 if (input_count > len) input_count = len;
331
332 /*
333 * Insert pairs into the test list, choosing randomly from the source list
334 */
335 for (i = 0; i < reps; i++) {
336 for (j = 0; j < len; j++) {
337 int idx = fr_fast_rand(&rand_ctx) % input_count;
338 new_vp = fr_pair_copy(autofree, source_vps[idx]);
339 start = fr_time();
340 fr_pair_append(&test_vps, new_vp);
341 end = fr_time();
342 used = fr_time_delta_add(used, fr_time_sub(end, start));
343 }
344 TEST_CHECK(fr_pair_list_num_elements(&test_vps) == len);
345 fr_pair_list_free(&test_vps);
346 }
347 TEST_MSG_ALWAYS("repetitions=%u", reps);
348 TEST_MSG_ALWAYS("perc_rep=%u", perc);
349 TEST_MSG_ALWAYS("list_length=%u", len);
350 TEST_MSG_ALWAYS("used=%"PRId64, fr_time_delta_unwrap(used));
351 TEST_MSG_ALWAYS("per_sec=%0.0lf", (reps * len)/(fr_time_delta_unwrap(used) / (double)NSEC));
352}
353
354static void do_test_fr_pair_find_by_da_idx(unsigned int len, unsigned int perc, unsigned int reps, fr_pair_t *source_vps[])
355{
356 fr_pair_list_t test_vps;
357 unsigned int i, j;
358 fr_pair_t *new_vp;
359 fr_time_t start, end;
361 fr_dict_attr_t const *da;
362 size_t input_count = talloc_array_length(source_vps);
363 fr_fast_rand_t rand_ctx;
364
365 fr_pair_list_init(&test_vps);
366 if (input_count > len) input_count = len;
367 rand_ctx.a = fr_rand();
368 rand_ctx.b = fr_rand();
369
370 /*
371 * Initialise the test list
372 */
373 for (i = 0; i < len; i++) {
374 int idx = fr_fast_rand(&rand_ctx) % input_count;
375 new_vp = fr_pair_copy(autofree, source_vps[idx]);
376 fr_pair_append(&test_vps, new_vp);
377 }
378
379 /*
380 * Find first instance of specific DA
381 */
382 for (i = 0; i < reps; i++) {
383 for (j = 0; j < len; j++) {
384 int idx = fr_fast_rand(&rand_ctx) % input_count;
385 da = source_vps[idx]->da;
386 start = fr_time();
387 (void) fr_pair_find_by_da(&test_vps, NULL, da);
388 end = fr_time();
389 used = fr_time_delta_add(used, fr_time_sub(end, start));
390 }
391 }
392 fr_pair_list_free(&test_vps);
393 TEST_MSG_ALWAYS("repetitions=%u", reps);
394 TEST_MSG_ALWAYS("perc_rep=%u", perc);
395 TEST_MSG_ALWAYS("list_length=%u", len);
396 TEST_MSG_ALWAYS("used=%"PRId64, fr_time_delta_unwrap(used));
397 TEST_MSG_ALWAYS("per_sec=%0.0lf", (reps * len)/(fr_time_delta_unwrap(used) / (double)NSEC));
398}
399
400static void do_test_find_nth(unsigned int len, unsigned int perc, unsigned int reps, fr_pair_t *source_vps[])
401{
402 fr_pair_list_t test_vps;
403 unsigned int i, j, nth_item;
404 fr_pair_t *new_vp;
405 fr_time_t start, end;
407 fr_dict_attr_t const *da;
408 size_t input_count = talloc_array_length(source_vps);
409 fr_fast_rand_t rand_ctx;
410
411 fr_pair_list_init(&test_vps);
412 if (input_count > len) input_count = len;
413 rand_ctx.a = fr_rand();
414 rand_ctx.b = fr_rand();
415
416 /*
417 * Initialise the test list
418 */
419 for (i = 0; i < len; i++) {
420 int idx = fr_fast_rand(&rand_ctx) % input_count;
421 new_vp = fr_pair_copy(autofree, source_vps[idx]);
422 fr_pair_append(&test_vps, new_vp);
423 }
424
425 /*
426 * Find nth instance of specific DA. nth is based on the percentage
427 * of attributes which are repeats.
428 */
429 nth_item = perc == 0 ? 1 : (unsigned int)(len * perc / 100);
430 for (i = 0; i < reps; i++) {
431 for (j = 0; j < len; j++) {
432 int idx = fr_fast_rand(&rand_ctx) % input_count;
433
434 da = source_vps[idx]->da;
435 start = fr_time();
436 (void) fr_pair_find_by_da_idx(&test_vps, da, nth_item);
437 end = fr_time();
438 used = fr_time_delta_add(used, fr_time_sub(end, start));
439 }
440 }
441 fr_pair_list_free(&test_vps);
442 TEST_MSG_ALWAYS("repetitions=%u", reps);
443 TEST_MSG_ALWAYS("perc_rep=%u", perc);
444 TEST_MSG_ALWAYS("list_length=%u", len);
445 TEST_MSG_ALWAYS("used=%"PRId64, fr_time_delta_unwrap(used));
446 TEST_MSG_ALWAYS("per_sec=%0.0lf", (reps * len)/(fr_time_delta_unwrap(used) / (double)NSEC));
447}
448
449static void do_test_fr_pair_list_free(unsigned int len, unsigned int perc, unsigned int reps, fr_pair_t *source_vps[])
450{
451 fr_pair_list_t test_vps;
452 unsigned int i, j;
453 fr_pair_t *new_vp;
454 fr_time_t start, end;
456 size_t input_count = talloc_array_length(source_vps);
457 fr_fast_rand_t rand_ctx;
458
459 fr_pair_list_init(&test_vps);
460 if (input_count > len) input_count = len;
461 rand_ctx.a = fr_rand();
462 rand_ctx.b = fr_rand();
463
464 for (i = 0; i < reps; i++) {
465 for (j = 0; j < len; j++) {
466 int idx = fr_fast_rand(&rand_ctx) % input_count;
467 new_vp = fr_pair_copy(autofree, source_vps[idx]);
468 fr_pair_append(&test_vps, new_vp);
469 }
470 start = fr_time();
471 fr_pair_list_free(&test_vps);
472 end = fr_time();
473 used = fr_time_delta_add(used, fr_time_sub(end, start));
474 }
475 fr_pair_list_free(&test_vps);
476 TEST_MSG_ALWAYS("repetitions=%u", reps);
477 TEST_MSG_ALWAYS("perc_rep=%u", perc);
478 TEST_MSG_ALWAYS("list_length=%u", len);
479 TEST_MSG_ALWAYS("used=%"PRId64, fr_time_delta_unwrap(used));
480 TEST_MSG_ALWAYS("per_sec=%0.0lf", (reps * len)/(fr_time_delta_unwrap(used) / (double)NSEC));
481}
482
483#define test_func(_func, _count, _perc, _source_vps) \
484static void test_ ## _func ## _ ## _count ## _ ## _perc(void)\
485{\
486 do_test_ ## _func(_count, _perc, 10000, _source_vps);\
487}
488
489#define test_funcs(_func, _perc) \
490 test_func(_func, 20, _perc, source_vps_ ## _perc) \
491 test_func(_func, 40, _perc, source_vps_ ## _perc) \
492 test_func(_func, 60, _perc, source_vps_ ## _perc) \
493 test_func(_func, 80, _perc, source_vps_ ## _perc) \
494 test_func(_func, 100, _perc, source_vps_ ## _perc)
495
496#define all_test_funcs(_func) \
497 test_funcs(_func, 0) \
498 test_funcs(_func, 25) \
499 test_funcs(_func, 50) \
500 test_funcs(_func, 75) \
501 test_funcs(_func, 100)
502
505all_test_funcs(find_nth)
507
508#define repetition_tests(_func, _perc) \
509 { #_func "_20_" #_perc, test_ ## _func ## _20_ ## _perc},\
510 { #_func "_40_" #_perc, test_ ## _func ## _40_ ## _perc},\
511 { #_func "_60_" #_perc, test_ ## _func ## _60_ ## _perc},\
512 { #_func "_80_" #_perc, test_ ## _func ## _80_ ## _perc},\
513 { #_func "_100_" #_perc, test_ ## _func ## _100_ ## _perc},\
514
515#define all_repetition_tests(_func) \
516 repetition_tests(_func, 0) \
517 repetition_tests(_func, 25) \
518 repetition_tests(_func, 50) \
519 repetition_tests(_func, 75) \
520 repetition_tests(_func, 100)
521
522TEST_LIST = {
525 all_repetition_tests(find_nth)
527
528 { NULL }
529};
#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:2402
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:695
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:1347
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:743
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:2510
fr_pair_t * fr_pair_copy(TALLOC_CTX *ctx, fr_pair_t const *vp)
Copy a single valuepair.
Definition pair.c:491
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:69
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:93
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:42
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:732
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:1012