The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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
37 static void pair_list_perf_init(void) __attribute__((constructor));
38 #else
39 static 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 
58 static fr_dict_t *test_dict;
59 static TALLOC_CTX *autofree;
60 
61 static 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 
83 static 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 
105 static 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 
127 static 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 
149 static 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 
171 static fr_pair_t **source_vps_0; //!< List with zero duplicate attributes.
172 static fr_pair_t **source_vps_25; //!< List with 25% duplicate attributes.
173 static fr_pair_t **source_vps_50; //!< List with 50% duplicate attributes.
174 static fr_pair_t **source_vps_75; //!< List with 75% duplicate attributes.
175 static fr_pair_t **source_vps_100; //!< List with 100% duplicate attributes, i.e. all the same.
176 
177 static 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 
285 void 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 
312  fr_time_start();
313 }
314 
315 static 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=%d", reps);
351  TEST_MSG_ALWAYS("perc_rep=%d", perc);
352  TEST_MSG_ALWAYS("list_length=%d", 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 
357 static 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=%d", reps);
397  TEST_MSG_ALWAYS("perc_rep=%d", perc);
398  TEST_MSG_ALWAYS("list_length=%d", 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 
403 static 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=%d", reps);
446  TEST_MSG_ALWAYS("perc_rep=%d", perc);
447  TEST_MSG_ALWAYS("list_length=%d", 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 
452 static 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=%d", reps);
480  TEST_MSG_ALWAYS("perc_rep=%d", perc);
481  TEST_MSG_ALWAYS("list_length=%d", 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) \
487 static 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 
508 all_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 
525 TEST_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
typedef __attribute__
static fr_dict_t * dict
Definition: fuzzer.c:46
next
Definition: dcursor.h:178
#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
Definition: merged_model.c:24
unsigned long int size_t
Definition: merged_model.c:25
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
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
Definition: pair.c:46
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
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.
Definition: pair_legacy.c:150
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
Definition: radclient-ng.c:107
uint32_t fr_fast_rand(fr_fast_rand_t *ctx)
Definition: rand.c:280
uint32_t fr_rand(void)
Return a 32-bit random number.
Definition: rand.c:106
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_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
Definition: pair_inline.c:43
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
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
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
Definition: pair_inline.c:113
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.
Definition: pair_inline.c:182
size_t fr_pair_list_num_elements(fr_pair_list_t const *list)
Get the length of a list of fr_pair_t.
Definition: pair_inline.c:151
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