The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
pair_nested_tests.c
Go to the documentation of this file.
1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation; either
5  * version 2.1 of the License, or (at your option) any later version.
6  *
7  * This library 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 GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /** Tests for a AVP manipulation and search API.
18  *
19  * @file src/lib/util/pair_tests.c
20  * @author Jorge Pereira <jpereira@freeradius.org>
21  * @copyright 2020 Network RADIUS SAS (legal@networkradius.com)
22  */
23 
24 /**
25  * The 'TEST_INIT' macro provided by 'acutest.h' allowing to register a function to be called
26  * before call the unit tests. Therefore, It calls the function ALL THE TIME causing an overhead.
27  * That is why we are initializing test_init() by "__attribute__((constructor));" reducing the
28  * test execution by 50% of the time.
29  */
30 #define USE_CONSTRUCTOR
31 
32 /*
33  * It should be declared before include the "acutest.h"
34  */
35 #ifdef USE_CONSTRUCTOR
36 static void test_init(void) __attribute__((constructor));
37 #else
38 static void test_init(void);
39 # define TEST_INIT test_init()
40 #endif
41 
42 #include <freeradius-devel/util/acutest.h>
43 #include <freeradius-devel/util/acutest_helpers.h>
44 #include <freeradius-devel/util/pair_test_helpers.h>
45 
46 #include <freeradius-devel/util/conf.h>
47 #include <freeradius-devel/util/dict.h>
48 
49 #ifdef HAVE_GPERFTOOLS_PROFILER_H
50 # include <gperftools/profiler.h>
51 #endif
52 
53 static TALLOC_CTX *autofree;
55 static fr_dict_t *test_dict;
56 
57 /** Global initialisation
58  */
59 static void test_init(void)
60 {
62  if (!autofree) {
63  error:
64 #ifdef TEST_NESTED_PAIRS
65  fr_perror("pair_nested_tests");
66 #else
67  fr_perror("pair_tests");
68 #endif
69  fr_exit_now(EXIT_FAILURE);
70  }
71 
72  /*
73  * Mismatch between the binary and the libraries it depends on
74  */
75  if (fr_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) goto error;
76 
77  if (fr_dict_test_init(autofree, &test_dict, NULL) < 0) goto error;
78 
79  /* Initialize the "test_pairs" list */
81 
82 #ifdef TEST_NESTED_PAIRS
83  if (fr_pair_test_list_alloc_nested(autofree, &test_pairs, NULL) < 0) goto error;
84 #else
85  if (fr_pair_test_list_alloc(autofree, &test_pairs, NULL) < 0) goto error;
86 #endif
87 }
88 
89 /*
90  * Tests functions
91  */
92 static void test_fr_pair_afrom_da(void)
93 {
94  fr_pair_t *vp;
95 
96  TEST_CASE("Allocation using fr_pair_afrom_da");
98 
99  TEST_CHECK(vp != NULL);
100  if (!vp) return;
101 
103 
104  TEST_CASE("Validating PAIR_VERIFY()");
105  PAIR_VERIFY(vp);
106 
107  TEST_CHECK(vp && strcmp(vp->vp_strvalue, test_string) == 0);
108  TEST_MSG("Expected vp->vp_strvalue == test_string");
109 
110  talloc_free(vp);
111 }
112 
114 {
115  fr_pair_t *vp;
116  unsigned int attr = FR_TEST_ATTR_STRING;
117 
118  TEST_CASE("Allocation using fr_pair_afrom_child_num");
120 
121  TEST_CASE("Validating PAIR_VERIFY()");
122  PAIR_VERIFY(vp);
123 
124  TEST_CHECK(vp && vp->da->attr == FR_TEST_ATTR_STRING);
125  TEST_MSG("Expected attr(%d) == vp->da->attr(%d)", attr, vp->da->attr);
126 
127  talloc_free(vp);
128 }
129 
131 {
132  fr_pair_t *vp, *parent = NULL;
134 
136 
137  TEST_CASE("Allocation using fr_pair_afrom_da_nested");
139 
141  TEST_MSG("Expected attr(%s) == vp->da->attr(%s)", fr_dict_attr_test_tlv_string->name, vp->da->name);
142 
143  TEST_CASE("Validating PAIR_VERIFY()");
144  PAIR_VERIFY(vp);
145 
146  TEST_CASE("Top list does not have the tlv child attribute");
148 
149  TEST_CASE("Top list does have the tlv attribute");
151  TEST_ASSERT(parent != NULL);
152 
153  TEST_CASE("Parent list does have the tlv child attribute");
155 
156  talloc_free(parent); /* not vp! */
157 }
158 
160 {
161  int count;
162  fr_pair_t *vp, *parent = NULL;
164 
166 
167  TEST_CASE("Allocation using fr_pair_afrom_da_nested");
169 
171  TEST_MSG("Expected attr(%s) == vp->da->attr(%s)", fr_dict_attr_test_tlv_string->name, vp->da->name);
172 
173  TEST_CASE("Deleted nested pair");
175 
176  TEST_CASE("Top list still has the tlv attribute");
178  TEST_ASSERT(parent != NULL);
179 
180  TEST_CASE("Parent list does not have the tlv child attribute");
182 
184 }
185 
186 static void test_fr_pair_nested_verify(void)
187 {
189  TEST_MSG("Expected %s cannot parent %s", fr_dict_attr_test_vsa->name, fr_dict_attr_test_tlv_string->name);
190 }
191 
192 
193 static void test_fr_pair_copy(void)
194 {
195  fr_pair_t *vp, *copy;
196 
197  TEST_CASE("Allocation using fr_pair_copy");
199 
200  TEST_CASE("Validating PAIR_VERIFY()");
201  PAIR_VERIFY(vp);
202 
203  copy = fr_pair_copy(autofree, vp);
204 
205  TEST_CASE("Validating PAIR_VERIFY()");
206  PAIR_VERIFY(copy);
207 
208  vp->op = T_OP_CMP_EQ;
209 
210  TEST_CASE("Compare fr_pair_cmp(copy == vp) should be TRUE");
211  TEST_CHECK(fr_pair_cmp(vp, copy) == 1);
212 
213  talloc_free(vp);
214  talloc_free(copy);
215 }
216 
217 static void test_fr_pair_steal(void)
218 {
219  fr_pair_t *vp;
220  TALLOC_CTX *ctx = talloc_null_ctx();
221 
222  TEST_CASE("Allocate a new attribute fr_pair_afrom_da");
224 
225  TEST_CASE("Validating PAIR_VERIFY()");
226  PAIR_VERIFY(vp);
227 
228  TEST_CASE("Stealing 'vp' pair using fr_pair_steal()");
229  fr_pair_steal(autofree, vp); /* It should exit without memory-leaks */
230 
231  TEST_CASE("Checking if talloc_parent(vp) == autofree");
232  TEST_CHECK(talloc_parent(vp) == autofree);
233 }
234 
236 {
237  fr_pair_t *vp;
238  uint8_t value = 0;
239 
240  TEST_CASE("Allocate a new attribute fr_pair_afrom_da");
242 
243  TEST_CASE("Validating PAIR_VERIFY()");
244  PAIR_VERIFY(vp);
245 
246  TEST_CASE("Converting regular 'vp' as unknown");
248 
249  TEST_CASE("Checking if a real 'raw' vp");
250  TEST_CHECK(vp && vp->vp_raw);
251 }
252 
254 {
255  fr_pair_t *vp, *needle;
256  fr_dcursor_t cursor;
257 
258  TEST_CASE("Searching for fr_dict_attr_test_uint32 using fr_pair_dcursor_by_da_init()");
259  needle = NULL;
261  vp;
262  vp = fr_dcursor_next(&cursor)) {
263  if (!needle) {
264  needle = vp;
265  continue;
266  }
267  TEST_CHECK(1 == 1); /* this never will be reached */
268  }
269 
270  TEST_CASE("Validating PAIR_VERIFY()");
271 
272  TEST_CHECK(needle != NULL);
273  if (needle) PAIR_VERIFY(needle);
274 
275  TEST_CASE("Expected (needle->da == fr_dict_attr_test_uint32)");
276  TEST_CHECK(needle && needle->da == fr_dict_attr_test_uint32);
277 }
278 
280 {
281  fr_pair_t *vp, *needle;
282  fr_dcursor_t cursor;
283 
284  TEST_CASE("Searching for fr_dict_attr_test_tlv_string as ascend of fr_dict_attr_test_tlv using fr_pair_dcursor_by_ancestor_init()");
285  needle = NULL;
287  vp;
288  vp = fr_dcursor_next(&cursor)) {
289  TEST_CHECK(vp != NULL);
291  needle = vp;
292  continue;
293  }
294  }
295 
296  TEST_CHECK(needle != NULL);
297 
298  TEST_CASE("Validating PAIR_VERIFY()");
299  if (needle) PAIR_VERIFY(needle);
300 
301  TEST_CASE("Expected (needle->da == fr_dict_attr_test_tlv_string)");
302  TEST_CHECK(needle && needle->da == fr_dict_attr_test_tlv_string);
303 }
304 
306 {
307  int i = 0;
308  fr_value_box_t *box;
309  fr_dcursor_t cursor;
310  fr_pair_t *vp;
312 
314 
316  fr_pair_value_strdup(vp, "hello", false);
318 
320  vp->vp_uint32 = 6809;
322 
324  vp->vp_uint8 = 12;
326 
327  TEST_CASE("Searching for fr_dict_attr_test_tlv_string as ascend of fr_dict_attr_test_tlv using fr_pair_dcursor_by_ancestor_init()");
328  for (box = fr_pair_dcursor_value_init(&cursor);
329  box;
330  box = fr_dcursor_next(&cursor), i++) {
331  switch (i) {
332  case 0:
333  TEST_CASE("First box is a string with value 'hello'");
334  TEST_CHECK(box->type == FR_TYPE_STRING);
335  TEST_CHECK(strcmp(box->vb_strvalue, "hello") == 0);
336  break;
337 
338  case 1:
339  TEST_CASE("First box is a uint32 with value 6809");
340  TEST_CHECK(box->type == FR_TYPE_UINT32);
341  TEST_CHECK(box->vb_uint32 == 6809);
342  break;
343 
344  case 2:
345  TEST_CASE("First box is a uint8 r with value 12");
346  TEST_CHECK(box->type == FR_TYPE_UINT8);
347  TEST_CHECK(box->vb_uint8 == 12);
348  break;
349 
350  default:
351  TEST_CASE("Too many pairs");
352  TEST_CHECK(i < 3);
353  break;
354  }
355  }
356 
358 }
359 
361 {
362  fr_pair_t *vp;
363 
364  TEST_CASE("Search for fr_dict_attr_test_string using fr_pair_find_by_da_idx()");
366 
367  TEST_CASE("Validating PAIR_VERIFY()");
368  PAIR_VERIFY(vp);
369 
370  TEST_CASE("Expected (vp->da == fr_dict_attr_test_string)");
372 }
373 
375 {
376  fr_pair_t *vp;
377 
378  TEST_CASE("Search for FR_TEST_ATTR_STRING using fr_pair_find_by_child_num_idx()");
380 
381  TEST_CASE("Validating PAIR_VERIFY()");
382  PAIR_VERIFY(vp);
383 
384  TEST_CASE("Expected (vp->da == fr_dict_attr_test_string)");
386 }
387 
389 {
390  fr_pair_t *vp1, *vp2, *vp3, *vp4, *vp5, *vp_found;
392 
394 
395  /*
396  * Build a list with 2 TLV structures, each with different leaf nodes
397  */
401  fr_pair_append(&vp1->vp_group, vp2);
403  fr_pair_append(&vp2->vp_group, vp1);
407  fr_pair_append(&vp2->vp_group, vp3);
409  fr_pair_append(&vp3->vp_group, vp2);
410 
412  TEST_CASE("Find child node in first TLV");
413  TEST_CHECK_PAIR(vp_found, vp1);
414 
416  TEST_CASE("Find child node in second TLV");
417  TEST_CHECK_PAIR(vp_found, vp2);
418 
420  TEST_CASE("Look for child in first node after second");
421  TEST_CHECK_PAIR(vp_found, NULL);
422 
423  /*
424  * Add third nested TLV with child of same type as first
425  */
429  fr_pair_append(&vp3->vp_group, vp4);
431  fr_pair_append(&vp4->vp_group, vp3);
432 
433  /*
434  * Repeat search 3 times to find both instances and then NULL
435  */
437  TEST_CASE("Find child node in first TLV");
438  TEST_CHECK_PAIR(vp_found, vp1);
439 
441  TEST_CASE("Find child node in third TLV");
442  TEST_CHECK_PAIR(vp_found, vp3);
443 
445  TEST_CASE("Find child node after third TLV");
446  TEST_CHECK_PAIR(vp_found, NULL);
447 
448  /*
449  * Add some "flat list" attributes
450  */
455 
456  /*
457  * Repeat search 5 times to find all instances and then NULL
458  * fr_pair_find_by_da_nested searches nested first then flat
459  */
461  TEST_CASE("Find child node in first TLV");
462  TEST_CHECK_PAIR(vp_found, vp1);
463 
465  TEST_CASE("Find child node in third TLV");
466  TEST_CHECK_PAIR(vp_found, vp3);
467 
469  TEST_CASE("Find first entry in \"flat\" list");
470  TEST_CHECK_PAIR(vp_found, vp4);
471 
473  TEST_CASE("Find second \"flat\" list entry");
474  TEST_CHECK_PAIR(vp_found, vp5);
475 
477  TEST_CASE("Find NULL at end of list");
478  TEST_CHECK_PAIR(vp_found, NULL);
479 
481 }
482 
483 static void test_fr_pair_append(void)
484 {
485  fr_dcursor_t cursor;
486  fr_pair_t *vp;
488  size_t count = 0;
489 
490  TEST_CASE("Add 3 pairs using fr_pair_append()");
491 
493 
500 
501  /* lets' count */
502  for (vp = fr_pair_dcursor_init(&cursor, &local_pairs);
503  vp;
504  vp = fr_dcursor_next(&cursor)) count++;
505 
506  TEST_CASE("Expected (count == 3)");
507  TEST_CHECK(count == 3);
508 
510 }
511 
513 {
514  fr_pair_t *leaf1, *leaf2, *found, *inter1, *inter2;
516  int ret;
517 
519 
520  TEST_CASE("Add nested attribute including parents");
522  TEST_CHECK(ret == 0);
523  TEST_CHECK(leaf1 != NULL);
524 
525  TEST_CASE("Check nested attributes added");
527  TEST_ASSERT(found != NULL);
528  inter1 = found;
529  found = fr_pair_find_by_da(&inter1->vp_group, NULL, fr_dict_attr_test_nested_child_tlv);
530  TEST_ASSERT(found != NULL);
531  inter2 = found;
532  found = fr_pair_find_by_da(&inter2->vp_group, NULL, fr_dict_attr_test_nested_leaf_int32);
533  TEST_CHECK_PAIR(found, leaf1);
534 
535  TEST_CASE("Ensure no flat list attribute created");
537  TEST_CHECK_PAIR(found, NULL);
538 
539  TEST_CASE("Add additional nested attribute where parents exist");
541  TEST_CHECK(ret == 0);
542  TEST_CHECK(leaf2 != NULL);
543  TEST_CHECK(leaf2 != leaf1);
544 
545  TEST_CASE("Check additional leaf added under existing parent");
546  found = fr_pair_find_by_da(&inter2->vp_group, NULL, fr_dict_attr_test_nested_leaf_string);
547  TEST_CHECK_PAIR(found, leaf2);
548 
549  TEST_CASE("Check no extra parent attributes created");
551  TEST_CHECK_PAIR(found, inter1);
553  TEST_CHECK_PAIR(found, NULL);
554 
555  found = fr_pair_find_by_da(&inter1->vp_group, NULL, fr_dict_attr_test_nested_child_tlv);
556  TEST_CHECK_PAIR(found, inter2);
557  found = fr_pair_find_by_da(&inter1->vp_group, inter2, fr_dict_attr_test_nested_child_tlv);
558  TEST_CHECK_PAIR(found, NULL);
559 
561 }
562 
564 {
565  TEST_CASE("Delete fr_dict_attr_test_string using fr_pair_delete_by_child_num()");
567 
568  TEST_CASE("The fr_dict_attr_test_string shouldn't exist in 'test_pairs'");
570 
571  TEST_CASE("Add fr_dict_attr_test_string back into 'test_pairs'");
573 }
574 
575 static void test_fr_pair_prepend_by_da(void)
576 {
577  fr_dcursor_t cursor;
578  fr_pair_t *vp;
580  TALLOC_CTX *ctx = talloc_null_ctx();
581 
583 
584  TEST_CASE("Add using fr_pair_prepend_by_da()");
586 
587  /* lets' count */
588  for (vp = fr_pair_dcursor_init(&cursor, &local_pairs);
589  vp;
590  vp = fr_dcursor_next(&cursor)) {
591  TEST_CASE("Expected (vp->da == fr_dict_attr_test_string)");
593  }
594 
596 }
597 
599 {
600  fr_pair_t *vp, *group;
601 
603  if (!group) return; /* quiet clang scan */
604 
605  TEST_CASE("Update Add using fr_pair_prepend_by_da()");
606  TEST_CHECK(fr_pair_update_by_da_parent(group, &vp, fr_dict_attr_test_uint32) == 0); /* attribute doesn't exist in this group */
607  vp->vp_uint32 = 54321;
608 
609  TEST_CASE("Expected fr_dict_attr_test_uint32 (vp->vp_uint32 == 54321)");
610  TEST_CHECK((vp = fr_pair_find_by_da(&group->vp_group, NULL, fr_dict_attr_test_uint32)) != NULL);
611 
612  TEST_CASE("Validating PAIR_VERIFY()");
613  PAIR_VERIFY(vp);
614 
615  TEST_CASE("Expected (vp == 54321)");
616  TEST_CHECK(vp && vp->vp_uint32 == 54321);
617 
618  talloc_free(group);
619 }
620 
621 static void test_fr_pair_delete_by_da(void)
622 {
623  TEST_CASE("Delete fr_dict_attr_test_string using fr_pair_delete_by_da()");
625 
626  TEST_CASE("The fr_dict_attr_test_string shouldn't exist in 'test_pairs'");
628 
629  TEST_CASE("Add fr_dict_attr_test_string back into 'test_pairs'");
631 }
632 
633 static void test_fr_pair_delete(void)
634 {
635  fr_pair_t *vp;
636 
637  TEST_CASE("Delete fr_dict_attr_test_string using fr_pair_delete()");
640 
641  TEST_CASE("The fr_dict_attr_test_string shouldn't exist in 'test_pairs'");
643 
644  TEST_CASE("Add fr_dict_attr_test_string back into 'test_pairs'");
646 }
647 
648 static void test_fr_pair_cmp(void)
649 {
650  fr_pair_t *vp1, *vp2;
651 
652  TEST_CASE("Create the vp1 'Test-Integer = 123'");
654 
655  TEST_CASE("Validating PAIR_VERIFY()");
656  PAIR_VERIFY(vp1);
657 
658  vp1->op = T_OP_EQ;
659  vp1->vp_uint32 = 123;
660 
661  TEST_CASE("Create the vp2 'Test-Integer = 321'");
663 
664  TEST_CASE("Validating PAIR_VERIFY()");
665  PAIR_VERIFY(vp2);
666 
667  vp2->op = T_OP_CMP_EQ;
668  vp2->vp_uint32 = 321;
669 
670  TEST_CASE("Compare fr_pair_cmp(vp1 == vp2) should be FALSE");
671  TEST_CHECK(fr_pair_cmp(vp1, vp2) == 0);
672 }
673 
674 static void test_fr_pair_list_cmp(void)
675 {
676  fr_pair_list_t local_pairs1, local_pairs2;
677 
678  fr_pair_list_init(&local_pairs1);
679  fr_pair_list_init(&local_pairs2);
680 
681  TEST_CASE("Create 'local_pairs1'");
682  TEST_CHECK(fr_pair_test_list_alloc(autofree, &local_pairs1, NULL) == 0);
683 
684  TEST_CASE("Create 'local_pairs2'");
685  TEST_CHECK(fr_pair_test_list_alloc(autofree, &local_pairs2, NULL) == 0);
686 
687  TEST_CASE("Check if 'local_pairs1' == 'local_pairs2' using fr_pair_list_cmp()");
688  TEST_CHECK(fr_pair_list_cmp(&local_pairs1, &local_pairs2) == 0);
689 
690  fr_pair_list_free(&local_pairs1);
691  fr_pair_list_free(&local_pairs2);
692 }
693 
694 static void test_fr_pair_list_copy(void)
695 {
697 
699 
700  TEST_CASE("Copy 'test_pairs' into 'local_pairs'");
702 
703  TEST_CASE("Check if 'local_pairs' == 'test_pairs' using fr_pair_list_cmp()");
705 
707 }
708 
710 {
711  fr_dcursor_t cursor;
712  fr_pair_t *vp;
714 
716 
717  TEST_CASE("Copy 'test_pairs' into 'local_pairs'");
719 
720  TEST_CASE("The 'local_pairs' should have only fr_dict_attr_test_string");
721  for (vp = fr_pair_dcursor_init(&cursor, &local_pairs);
722  vp;
723  vp = fr_dcursor_next(&cursor)) {
724  TEST_CASE("Validating PAIR_VERIFY()");
725  PAIR_VERIFY(vp);
726 
727  TEST_CASE("Expected (vp->da == fr_dict_attr_test_string)");
729  }
730 
732 }
733 
735 {
736  fr_pair_t *vp;
738 
740 
741  TEST_CASE("Copy 'test_pairs' into 'local_pairs'");
743 
744  TEST_CASE("The 'local_pairs' should have only one attribute in it");
746 
747  TEST_CASE("The 'local_pairs' should have only fr_dict_attr_test_tlv_string (ancestor of 'Test-TLV-Root'");
749 
750  TEST_CASE("Validating we copied the attribute");
751  TEST_CHECK(vp != NULL);
752  if (!vp) return;
753 
754 #ifdef TEST_NESTED_PAIRS
755  TEST_CASE("Expected copied attribute == fr_dict_attr_test_tlv)");
757 #else
758  TEST_CASE("Expected copied attribute == fr_dict_attr_test_tlv_string)");
760 #endif
761 
762  TEST_CASE("Verifying the copied attribute");
763  PAIR_VERIFY(vp);
764 
765  TEST_CASE("Expecting nothing else in local list");
767 
769 }
770 
771 static void test_fr_pair_list_sort(void)
772 {
773  fr_dcursor_t cursor;
774  fr_pair_t *vp;
776  TALLOC_CTX *ctx = talloc_null_ctx();
777 
778  TEST_CASE("Create 'local_pairs' with 3 attributes not ordered");
780 
781  TEST_CASE("Add fr_dict_attr_test_string back into 'local_pairs'");
786  TEST_CHECK(fr_pair_prepend_by_da(ctx, NULL, &local_pairs, fr_dict_attr_test_enum) == 0); // It will be go to the tail
788 
789  /*
790  * FIXME - This test doesn't check for intra-type stability
791  */
792  TEST_CASE("Sorting 'local_pairs' by fr_pair_list_sort(local_pairs, fr_pair_cmp_by_da)");
794 
795  TEST_CASE("1st (da == fr_dict_attr_test_string)");
796  TEST_CHECK((vp = fr_pair_dcursor_init(&cursor, &local_pairs)) != NULL);
798 
799  TEST_CASE("2nd (da == fr_dict_attr_test_octets)");
800  TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
802 
803  TEST_CASE("3rd (da == fr_dict_attr_test_ipv4_addr)");
804  TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
806 
807  TEST_CASE("4th (da == fr_dict_attr_test_uint32)");
808  TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
810 
811  TEST_CASE("5th (da == fr_dict_attr_test_date)");
812  TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
814 
815  TEST_CASE("6th (da == fr_dict_attr_test_enum)");
816  TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
818 
820 }
821 
822 static void test_fr_pair_value_copy(void)
823 {
824  fr_pair_t *vp1, *vp2;
825 
826  TEST_CASE("Create 'vp1' with Test-Integer = 123");
828  vp1->vp_uint32 = 123;
829 
830  TEST_CASE("Validating PAIR_VERIFY()");
831  PAIR_VERIFY(vp1);
832 
833  TEST_CASE("Create 'vp2'");
835 
836  TEST_CASE("Validating PAIR_VERIFY()");
837  PAIR_VERIFY(vp2);
838 
839  TEST_CASE("Copy 'vp1' to 'vp2' using fr_pair_value_copy()");
840  TEST_CHECK(fr_pair_value_copy(vp2, vp1) == 0);
841 
842  TEST_CASE("Validating PAIR_VERIFY()");
843  PAIR_VERIFY(vp2);
844 
845  TEST_CASE("Check (vp1 == vp2)");
846  TEST_CHECK(vp2->vp_uint32 == 123);
847 }
848 
850 {
851  fr_pair_t *vp;
852 
853  TEST_CASE("Find 'Test-String'");
855 
856  TEST_CASE("Validating PAIR_VERIFY()");
857  PAIR_VERIFY(vp);
858 
859  TEST_CASE("Convert 'test_string' value to attribute value using fr_pair_value_from_str()");
861 
862  TEST_CASE("Validating PAIR_VERIFY()");
863  PAIR_VERIFY(vp);
864 
865  TEST_CASE("Check (vp->vp_string == test_string)");
866  TEST_CHECK(vp && strcmp(vp->vp_strvalue, test_string) == 0);
867 }
868 
869 static void test_fr_pair_value_strdup(void)
870 {
871  fr_pair_t *vp;
872 
873  TEST_CASE("Find 'Test-String'");
875 
876  TEST_CASE("Validating PAIR_VERIFY()");
877  PAIR_VERIFY(vp);
878 
879  TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_strdup()");
881 
882  TEST_CASE("Validating PAIR_VERIFY()");
883  PAIR_VERIFY(vp);
884 
885  TEST_CASE("Check (vp->vp_string == test_string)");
886  TEST_CHECK(vp && strcmp(vp->vp_strvalue, test_string) == 0);
887 }
888 
890 {
891  fr_pair_t *vp, *nvp;
892  char *copy_test_string;
893 
894  TEST_CASE("Find 'Test-String'");
896 
897  TEST_CASE("Validating PAIR_VERIFY()");
898  PAIR_VERIFY(vp);
899 
900  MEM(nvp = fr_pair_copy(NULL, vp));
901 
902  copy_test_string = talloc_strdup(nvp, test_string);
903  talloc_set_type(copy_test_string, char);
904 
905  TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_strdup_shallow()");
906  TEST_CHECK(fr_pair_value_strdup_shallow(nvp, copy_test_string, true) == 0);
907 
908  TEST_CASE("Validating PAIR_VERIFY()");
909  PAIR_VERIFY(nvp);
910 
911  TEST_CASE("Check (vp->vp_string == copy_test_string)");
912  TEST_CHECK(nvp && strncmp(nvp->vp_strvalue, test_string, strlen(copy_test_string)) == 0);
913 
914  talloc_free(nvp);
915 }
916 
917 static void test_fr_pair_value_strtrim(void)
918 {
919  fr_pair_t *vp;
920 
921  TEST_CASE("Find 'Test-String'");
923 
924  TEST_CASE("Validating PAIR_VERIFY()");
925  PAIR_VERIFY(vp);
926 
927  TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_strdup_shallow()");
929 
930  TEST_CASE("Trim the length of the string buffer using fr_pair_value_strtrim()");
932 
933  TEST_CASE("Validating PAIR_VERIFY()");
934  PAIR_VERIFY(vp);
935 
936  TEST_CASE("Check (vp->vp_string == test_string)");
937  TEST_CHECK(vp && strcmp(vp->vp_strvalue, test_string) == 0);
938 }
939 
940 static void test_fr_pair_value_aprintf(void)
941 {
942  fr_pair_t *vp;
943  char fmt_test[64];
944  fr_time_t now = fr_time();
945 
946  snprintf(fmt_test, sizeof(fmt_test), "Now is %"PRId64, fr_time_unwrap(now));
947 
948  TEST_CASE("Find 'Test-String'");
950 
951  TEST_CASE("Validating PAIR_VERIFY()");
952  PAIR_VERIFY(vp);
953 
954  TEST_CASE("Copy content of 'fmt_test' to attribute value using fr_pair_value_aprintf()");
955  TEST_CHECK(fr_pair_value_aprintf(vp, "Now is %"PRId64, fr_time_unwrap(now)) == 0);
956 
957  TEST_CASE("Validating PAIR_VERIFY()");
958  PAIR_VERIFY(vp);
959 
960  TEST_CASE("Check (vp->vp_string == fmt_test)");
961  TEST_CHECK(vp && strcmp(vp->vp_strvalue, fmt_test) == 0);
962 }
963 
965 {
966  fr_pair_t *vp;
967  char *out = NULL;
968 
969  TEST_CASE("Find 'Test-String'");
971 
972  TEST_CASE("Validating PAIR_VERIFY()");
973  PAIR_VERIFY(vp);
974 
975  TEST_CASE("Pre-allocate a memory buffer using fr_pair_value_bstr_alloc()");
977 
978  TEST_CASE("Validating PAIR_VERIFY()");
979  PAIR_VERIFY(vp);
980 
981  TEST_CASE("Copy 'test_string' to the pre-allocated pointer");
983 
984  TEST_CASE("Check (out == test_string)");
985  TEST_CHECK(memcmp(out, test_string, test_string_len-1) == 0);
986 
987  TEST_CASE("Check (vp->vp_string == test_string)");
988  TEST_CHECK(vp && memcmp(vp->vp_strvalue, test_string, test_string_len-1) == 0);
989 }
990 
992 {
993  fr_pair_t *vp;
994  char *out = NULL;
995 
996  TEST_CASE("Find 'Test-String'");
998 
999  TEST_CASE("Validating PAIR_VERIFY()");
1000  PAIR_VERIFY(vp);
1001 
1002  TEST_CASE("Pre-allocate 1 byte of memory buffer using fr_pair_value_bstr_alloc()");
1003  TEST_CHECK(fr_pair_value_bstr_alloc(vp, &out, 1, false) == 0);
1004 
1005  TEST_CASE("Re-allocate (test_string_len-1) byte of memory buffer using fr_pair_value_bstr_realloc()");
1007 
1008  TEST_CASE("Validating PAIR_VERIFY()");
1009  PAIR_VERIFY(vp);
1010 
1011  TEST_CASE("Copy 'test_string' to the pre-allocated pointer");
1013 
1014  TEST_CASE("Check (out == test_string)");
1015  TEST_CHECK(memcmp(out, test_string, test_string_len-1) == 0);
1016 
1017  TEST_CASE("Check (vp->vp_string == test_string)");
1018  TEST_CHECK(vp && memcmp(vp->vp_strvalue, test_string, test_string_len-1) == 0);
1019 }
1020 
1022 {
1023  fr_pair_t *vp;
1024 
1025  TEST_CASE("Find 'Test-String'");
1027 
1028  TEST_CASE("Validating PAIR_VERIFY()");
1029  PAIR_VERIFY(vp);
1030 
1031  TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_bstrndup()");
1033 
1034  TEST_CASE("Check (vp->vp_string == test_string)");
1035  TEST_CHECK(vp && memcmp(vp->vp_strvalue, test_string, test_string_len-1) == 0);
1036 }
1037 
1039 {
1040  fr_pair_t *vp;
1041  char *copy_test_string;
1042 
1043  TEST_CASE("Find 'Test-String'");
1045 
1046  TEST_CASE("Validating PAIR_VERIFY()");
1047  PAIR_VERIFY(vp);
1048 
1049  copy_test_string = talloc_strdup(vp, test_string);
1050  talloc_set_type(copy_test_string, char);
1051 
1052  TEST_CASE("Copy content of 'copy_test_string' to attribute value using fr_pair_value_bstrdup_buffer()");
1053  TEST_CHECK(fr_pair_value_bstrdup_buffer(vp, copy_test_string, false) == 0);
1054 
1055  TEST_CASE("Check (vp->vp_string == test_string)");
1056  TEST_CHECK(vp && strcmp(vp->vp_strvalue, copy_test_string) == 0);
1057 
1058  talloc_free(copy_test_string);
1059 }
1060 
1062 {
1063  fr_pair_t *vp;
1064  char *copy_test_string;
1065 
1066  TEST_CASE("Find 'Test-String'");
1068 
1069  TEST_CASE("Validating PAIR_VERIFY()");
1070  PAIR_VERIFY(vp);
1071 
1072  copy_test_string = talloc_strdup(vp, test_string);
1073  talloc_set_type(copy_test_string, char);
1074 
1075  TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_bstrndup_shallow()");
1076  TEST_CHECK(fr_pair_value_bstrndup_shallow(vp, copy_test_string, strlen(copy_test_string), true) == 0);
1077 
1078  TEST_CASE("Check (vp->vp_string == copy_test_string)");
1079  TEST_CHECK(vp && strncmp(vp->vp_strvalue, test_string, test_string_len) == 0);
1080 
1081  talloc_free(copy_test_string);
1082 }
1083 
1085 {
1086  fr_pair_t *vp;
1087  char *copy_test_string;
1088 
1089  TEST_CASE("Find 'Test-String'");
1091 
1092  TEST_CASE("Validating PAIR_VERIFY()");
1093  PAIR_VERIFY(vp);
1094 
1095  copy_test_string = talloc_strdup(vp, test_string);
1096  talloc_set_type(copy_test_string, char);
1097 
1098  TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_bstrdup_buffer_shallow()");
1099  TEST_CHECK(fr_pair_value_bstrdup_buffer_shallow(vp, copy_test_string, true) == 0);
1100 
1101  TEST_CASE("Check (vp->vp_string == copy_test_string)");
1102  TEST_CHECK(vp && strncmp(vp->vp_strvalue, test_string, test_string_len) == 0);
1103 
1104  talloc_free(copy_test_string);
1105 }
1106 
1108 {
1109  fr_pair_t *vp;
1110  char *copy_test_string;
1111 
1112  TEST_CASE("Find 'Test-String'");
1114 
1115  TEST_CASE("Validating PAIR_VERIFY()");
1116  PAIR_VERIFY(vp);
1117 
1118  copy_test_string = talloc_strdup(vp, test_string);
1119  talloc_set_type(copy_test_string, char);
1120 
1121  TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_bstrndup()");
1123 
1124  TEST_CASE("Append the 'copy_test_string' value using fr_pair_value_bstrn_append()");
1125  TEST_CHECK(fr_pair_value_bstrn_append(vp, copy_test_string, test_string_len, true) == 0);
1126 
1127  // awful hack, just verify the first part of buffer and then the second part. yep, just appended twice.
1128  TEST_CASE("Check 1. part (vp->vp_string == test_string)");
1129  TEST_CHECK(vp && strncmp(vp->vp_strvalue, test_string, test_string_len) == 0);
1130 
1131  TEST_CASE("Check 2. part ((vp->vp_string+test_string_len) == test_string)");
1132  TEST_CHECK(vp && strncmp(vp->vp_strvalue+test_string_len, test_string, test_string_len) == 0);
1133 
1134  talloc_free(copy_test_string);
1135 }
1136 
1138 {
1139  fr_pair_t *vp;
1140  char *copy_test_string;
1141 
1142  TEST_CASE("Find 'Test-String'");
1144 
1145  TEST_CASE("Validating PAIR_VERIFY()");
1146  PAIR_VERIFY(vp);
1147 
1148  copy_test_string = talloc_strdup(vp, test_string);
1149  talloc_set_type(copy_test_string, char);
1150 
1151  TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_bstrndup()");
1153 
1154  TEST_CASE("Append the 'copy_test_string' value using fr_pair_value_bstr_append_buffer()");
1155  TEST_CHECK(fr_pair_value_bstr_append_buffer(vp, copy_test_string, true) == 0);
1156 
1157  TEST_CASE("Validating PAIR_VERIFY()");
1158  PAIR_VERIFY(vp);
1159 
1160  // awful hack, just verify the first part of buffer and then the second part. yep, just appended twice.
1161  TEST_CASE("Check 1. part (vp->vp_string == test_string)");
1162  TEST_CHECK(vp && strncmp(vp->vp_strvalue, test_string, test_string_len) == 0);
1163 
1164  TEST_CASE("Check 2. part ((vp->vp_string+test_string_len) == test_string)");
1165  TEST_CHECK(vp && strncmp(vp->vp_strvalue+test_string_len, test_string, test_string_len) == 0);
1166 
1167  talloc_free(copy_test_string);
1168 }
1169 
1171 {
1172  fr_pair_t *vp;
1173  uint8_t *out;
1174 
1175  TEST_CASE("Find 'Test-Octets'");
1177 
1178  TEST_CASE("Validating PAIR_VERIFY()");
1179  PAIR_VERIFY(vp);
1180 
1181  TEST_CASE("Pre-allocate a memory buffer using fr_pair_value_bstr_alloc()");
1183 
1184  TEST_CASE("Copy 'test_octets' to the pre-allocated pointer");
1185  TEST_CHECK(memcpy(out, test_octets, NUM_ELEMENTS(test_octets)) != NULL);
1186 
1187  TEST_CASE("Check (out == test_octets)");
1189 
1190  TEST_CASE("Check (vp->vp_octets == test_octets)");
1191  TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1192 }
1193 
1195 {
1196  fr_pair_t *vp;
1197  uint8_t *out;
1198 
1199  TEST_CASE("Find 'Test-Octets'");
1201 
1202  TEST_CASE("Validating PAIR_VERIFY()");
1203  PAIR_VERIFY(vp);
1204 
1205  TEST_CASE("Pre-allocate a memory buffer using fr_pair_value_bstr_alloc()");
1207 
1208  TEST_CASE("Copy 'test_octets' to the pre-allocated pointer");
1209  TEST_CHECK(memcpy(out, test_octets, NUM_ELEMENTS(test_octets)) != NULL);
1210 
1211  TEST_CASE("Realloc pre-allocated pointer to fit extra 'test_octets' copy");
1213 
1214  TEST_CASE("Copy 'test_octets' into the tail");
1216 
1217  TEST_CASE("Check first chunk (out == test_octets)");
1219 
1220  TEST_CHECK(vp != NULL);
1221 
1222  TEST_CASE("Check first chunk (vp->vp_octets == test_octets)");
1223  TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1224 
1225  TEST_CASE("Check second chunk (out+NUM_ELEMENTS(test_octets) == test_octets)");
1227 
1228  TEST_CASE("Check second chunk (vp->vp_octets+NUM_ELEMENTS(test_octets) == test_octets)");
1229  TEST_CHECK(vp && memcmp(vp->vp_octets+NUM_ELEMENTS(test_octets), test_octets, NUM_ELEMENTS(test_octets)) == 0);
1230 }
1231 
1232 static void test_fr_pair_value_memdup(void)
1233 {
1234  fr_pair_t *vp;
1235 
1236  TEST_CASE("Find 'Test-Octets'");
1238 
1239  TEST_CASE("Validating PAIR_VERIFY()");
1240  PAIR_VERIFY(vp);
1241 
1242  TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup()");
1244 
1245  TEST_CASE("Check (vp->vp_octets == test_octets)");
1246  TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1247 }
1248 
1250 {
1251  fr_pair_t *vp;
1252  uint8_t *copy_test_octets;
1253 
1254  TEST_CASE("Find 'Test-Octets'");
1256 
1257  TEST_CASE("Validating PAIR_VERIFY()");
1258  PAIR_VERIFY(vp);
1259 
1260  copy_test_octets = talloc_memdup(vp, test_octets, NUM_ELEMENTS(test_octets));
1261  talloc_set_type(copy_test_octets, uint8_t);
1262 
1263  TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup_buffer()");
1264  TEST_CHECK(fr_pair_value_memdup_buffer(vp, copy_test_octets, true) == 0);
1265 
1266  TEST_CASE("Check (vp->vp_octets == test_octets)");
1267  TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1268 
1269  talloc_free(copy_test_octets);
1270 }
1271 
1273 {
1274  fr_pair_t *vp;
1275  uint8_t *copy_test_octets;
1276 
1277  TEST_CASE("Find 'Test-Octets'");
1279 
1280  TEST_CASE("Validating PAIR_VERIFY()");
1281  PAIR_VERIFY(vp);
1282 
1283  copy_test_octets = talloc_memdup(vp, test_octets, NUM_ELEMENTS(test_octets));
1284  talloc_set_type(copy_test_octets, uint8_t);
1285 
1286  TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup_shallow()");
1287  TEST_CHECK(fr_pair_value_memdup_shallow(vp, copy_test_octets, NUM_ELEMENTS(test_octets), true) == 0);
1288 
1289  TEST_CASE("Check (vp->vp_octets == test_octets)");
1290  TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1291 
1292  talloc_free(copy_test_octets);
1293 }
1294 
1296 {
1297  fr_pair_t *vp;
1298  uint8_t *copy_test_octets;
1299 
1300  TEST_CASE("Find 'Test-Octets'");
1302 
1303  TEST_CASE("Validating PAIR_VERIFY()");
1304  PAIR_VERIFY(vp);
1305 
1306  copy_test_octets = talloc_memdup(vp, test_octets, NUM_ELEMENTS(test_octets));
1307  talloc_set_type(copy_test_octets, uint8_t);
1308 
1309  TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup_buffer_shallow()");
1310  TEST_CHECK(fr_pair_value_memdup_buffer_shallow(vp, copy_test_octets, true) == 0);
1311 
1312  TEST_CASE("Check (vp->vp_octets == copy_test_octets)");
1313  TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1314 
1315  talloc_free(copy_test_octets);
1316 }
1317 
1319 {
1320  fr_pair_t *vp;
1321 
1322  TEST_CASE("Find 'Test-Octets'");
1324 
1325  TEST_CASE("Validating PAIR_VERIFY()");
1326  PAIR_VERIFY(vp);
1327 
1328  TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup()");
1330 
1331  TEST_CASE("Append the 'test_octets' value using fr_pair_value_mem_append()");
1333 
1334  // awful hack, just verify the first part of buffer and then the second part. yep, just appended twice.
1335  TEST_CASE("Check 1. part (vp->vp_octets == test_octets)");
1336  TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1337 
1338  TEST_CASE("Check 2. part ((vp->vp_string+NUM_ELEMENTS(test_octets)) == test_octets)");
1339  TEST_CHECK(vp && memcmp(vp->vp_octets+NUM_ELEMENTS(test_octets), test_octets, NUM_ELEMENTS(test_octets)) == 0);
1340 }
1341 
1343 {
1344  fr_pair_t *vp;
1345  uint8_t *copy_test_octets;
1346 
1347  TEST_CASE("Find 'Test-Octets'");
1349 
1350  TEST_CASE("Validating PAIR_VERIFY()");
1351  PAIR_VERIFY(vp);
1352 
1353  copy_test_octets = talloc_memdup(vp, test_octets, NUM_ELEMENTS(test_octets));
1354  talloc_set_type(copy_test_octets, uint8_t);
1355 
1356  TEST_CASE("Copy content of 'copy_test_octets' to attribute value using fr_pair_value_memdup()");
1357  TEST_CHECK(fr_pair_value_memdup(vp, copy_test_octets, NUM_ELEMENTS(test_octets), false) == 0);
1358 
1359  TEST_CASE("Append the 'copy_test_octets' value using fr_pair_value_mem_append_buffer()");
1360  TEST_CHECK(fr_pair_value_mem_append_buffer(vp, copy_test_octets, true) == 0);
1361 
1362  // awful hack, just verify the first part of buffer and then the second part. yep, just appended twice.
1363  TEST_CASE("Check 1. part (vp->vp_octets == test_octets)");
1364  TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1365 
1366  TEST_CASE("Check 2. part ((vp->vp_string+NUM_ELEMENTS(test_octets)) == test_octets)");
1367  TEST_CHECK(vp && memcmp(vp->vp_octets+NUM_ELEMENTS(test_octets), test_octets, NUM_ELEMENTS(test_octets)) == 0);
1368 
1369  talloc_free(copy_test_octets);
1370 }
1371 
1372 static void test_fr_pair_value_enum(void)
1373 {
1374  fr_pair_t *vp;
1375  char const *var;
1376  char buf[20];
1377 
1378  TEST_CASE("Find 'Test-Values'");
1380 
1381  TEST_CASE("Validating PAIR_VERIFY()");
1382  PAIR_VERIFY(vp);
1383 
1384  vp->vp_uint32 = 123;
1385 
1386  TEST_CASE("Lookup enum value attribute using fr_pair_value_enum()");
1387 
1388  TEST_CHECK((var = fr_pair_value_enum(vp, buf)) != NULL);
1389  TEST_MSG("Checking fr_pair_value_enum()");
1390 
1391  TEST_CHECK(var && strcmp(var, "test123") == 0);
1392  TEST_MSG("Expected var == 'test123'");
1393 }
1394 
1396 {
1397  fr_pair_t *vp;
1398  fr_value_box_t const *vb;
1399 
1400  TEST_CASE("Find 'Test-Values'");
1402 
1403  TEST_CASE("Validating PAIR_VERIFY()");
1404  PAIR_VERIFY(vp);
1405 
1406  vp->vp_uint32 = 123;
1407 
1408  TEST_CASE("Lookup enum value attribute using fr_pair_value_enum_box()");
1409 
1410  TEST_CHECK(fr_pair_value_enum_box(&vb, vp) >= 0);
1411  TEST_MSG("Checking fr_pair_value_enum()");
1412 
1413  TEST_CHECK(vb->vb_uint32 == 123);
1414  TEST_MSG("Expected vb->vb_uint32 == 123");
1415 }
1416 
1418  /*
1419  * Allocation and management
1420  */
1421  { "fr_pair_afrom_da", test_fr_pair_afrom_da },
1422  { "fr_pair_afrom_child_num", test_fr_pair_afrom_child_num },
1423  { "fr_pair_afrom_da_nested", test_fr_pair_afrom_da_nested },
1424  { "fr_pair_copy", test_fr_pair_copy },
1425  { "fr_pair_steal", test_fr_pair_steal },
1426 
1427  /* Searching and list modification */
1428  { "fr_dcursor_iter_by_da_init", test_fr_pair_dcursor_by_da_init },
1429  { "fr_pair_dcursor_by_ancestor_init", test_fr_pair_dcursor_by_ancestor_init },
1430  { "fr_pair_dcursor_value_init", test_fr_pair_dcursor_value_init },
1431  { "fr_pair_raw_afrom_pair", test_fr_pair_raw_afrom_pair },
1432  { "fr_pair_find_by_da_idx", test_fr_pair_find_by_da_idx },
1433  { "fr_pair_find_by_child_num_idx", test_fr_pair_find_by_child_num_idx },
1434  { "fr_pair_find_by_da_nested", test_fr_pair_find_by_da_nested },
1435  { "fr_pair_append", test_fr_pair_append },
1436  { "fr_pair_prepend_by_da", test_fr_pair_prepend_by_da },
1437  { "fr_pair_append_by_da_parent", test_fr_pair_append_by_da_parent },
1438  { "fr_pair_delete_by_child_num", test_fr_pair_delete_by_child_num },
1439  { "fr_pair_update_by_da_parent", test_fr_pair_update_by_da_parent },
1440  { "fr_pair_delete", test_fr_pair_delete },
1441  { "fr_pair_delete_by_da", test_fr_pair_delete_by_da },
1442  { "fr_pair_delete_by_da_nested", test_fr_pair_delete_by_da_nested },
1443 
1444  /* Compare */
1445  { "fr_pair_cmp", test_fr_pair_cmp },
1446  { "fr_pair_list_cmp", test_fr_pair_list_cmp },
1447 
1448  /* Lists */
1449  { "fr_pair_list_copy", test_fr_pair_list_copy },
1450  { "fr_pair_list_copy_by_da", test_fr_pair_list_copy_by_da },
1451  { "fr_pair_list_copy_by_ancestor", test_fr_pair_list_copy_by_ancestor },
1452  { "fr_pair_list_sort", test_fr_pair_list_sort },
1453 
1454  /* Copy */
1455  { "fr_pair_value_copy", test_fr_pair_value_copy },
1456 
1457 
1458  /* parenting */
1459  { "test_fr_pair_nested_verify", test_fr_pair_nested_verify },
1460 
1461  /* Strings */
1462  { "fr_pair_value_from_str", test_fr_pair_value_from_str },
1463  { "fr_pair_value_strdup", test_fr_pair_value_strdup },
1464  { "fr_pair_value_strdup_shallow", test_fr_pair_value_strdup_shallow },
1465  { "fr_pair_value_strtrim", test_fr_pair_value_strtrim },
1466  { "fr_pair_value_aprintf", test_fr_pair_value_aprintf },
1467 
1468  /* Assign and manipulate binary-safe strings */
1469  { "fr_pair_value_bstr_alloc", test_fr_pair_value_bstr_alloc },
1470  { "fr_pair_value_bstr_realloc", test_fr_pair_value_bstr_realloc },
1471  { "fr_pair_value_bstrndup", test_fr_pair_value_bstrndup },
1472  { "fr_pair_value_bstrdup_buffer", test_fr_pair_value_bstrdup_buffer },
1473  { "fr_pair_value_bstrndup_shallow", test_fr_pair_value_bstrndup_shallow },
1474  { "fr_pair_value_bstrdup_buffer_shallow", test_fr_pair_value_bstrdup_buffer_shallow },
1475  { "fr_pair_value_bstrn_append", test_fr_pair_value_bstrn_append },
1476  { "fr_pair_value_bstr_append_buffer", test_fr_pair_value_bstr_append_buffer },
1477 
1478  /* Assign and manipulate octets strings */
1479  { "fr_pair_value_mem_alloc", test_fr_pair_value_mem_alloc },
1480  { "fr_pair_value_mem_realloc", test_fr_pair_value_mem_realloc },
1481  { "fr_pair_value_memdup", test_fr_pair_value_memdup },
1482  { "fr_pair_value_memdup_buffer", test_fr_pair_value_memdup_buffer },
1483  { "fr_pair_value_memdup_shallow", test_fr_pair_value_memdup_shallow },
1484  { "fr_pair_value_memdup_buffer_shallow", test_fr_pair_value_memdup_buffer_shallow },
1485  { "fr_pair_value_mem_append", test_fr_pair_value_mem_append },
1486  { "fr_pair_value_mem_append_buffer", test_fr_pair_value_mem_append_buffer },
1487 
1488  /* Enum functions */
1489  { "fr_pair_value_enum", test_fr_pair_value_enum },
1490  { "fr_pair_value_enum_box", test_fr_pair_value_enum_box },
1491 
1492  { NULL }
1493 };
#define TEST_CHECK(cond)
Definition: acutest.h:85
#define TEST_CASE(name)
Definition: acutest.h:184
#define TEST_ASSERT(cond)
Definition: acutest.h:108
#define TEST_MSG(...)
Definition: acutest.h:215
typedef __attribute__
#define NUM_ELEMENTS(_t)
Definition: build.h:335
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
Definition: dcursor.h:287
#define fr_exit_now(_x)
Exit without calling atexit() handlers, producing a log message in debug builds.
Definition: debug.h:232
bool fr_dict_attr_can_contain(fr_dict_attr_t const *parent, fr_dict_attr_t const *child)
See if a structural da is allowed to contain another da.
Definition: dict_util.c:4464
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition: dict_util.c:1997
fr_dict_attr_t const * fr_dict_attr_test_tlv_string
Definition: dict_test.c:65
fr_dict_attr_t const * fr_dict_attr_test_nested_leaf_string
Definition: dict_test.c:78
fr_dict_attr_t const * fr_dict_attr_test_enum
Definition: dict_test.c:81
fr_dict_attr_t const * fr_dict_attr_test_date
Definition: dict_test.c:58
fr_dict_attr_t const * fr_dict_attr_test_tlv
Definition: dict_test.c:64
fr_dict_attr_t const * fr_dict_attr_test_nested_top_tlv
Definition: dict_test.c:76
fr_dict_attr_t const * fr_dict_attr_test_uint32
Definition: dict_test.c:47
fr_dict_attr_t const * fr_dict_attr_test_octets
Definition: dict_test.c:31
fr_dict_attr_t const * fr_dict_attr_test_string
Definition: dict_test.c:30
fr_dict_attr_t const * fr_dict_attr_test_ipv4_addr
Definition: dict_test.c:33
fr_dict_attr_t const * fr_dict_attr_test_nested_child_tlv
Definition: dict_test.c:77
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
fr_dict_attr_t const * fr_dict_attr_test_uint8
Definition: dict_test.c:45
fr_dict_attr_t const * fr_dict_attr_test_group
Definition: dict_test.c:74
fr_dict_attr_t const * fr_dict_attr_test_nested_leaf_int32
Definition: dict_test.c:79
fr_dict_attr_t const * fr_dict_attr_test_vsa
Definition: dict_test.c:70
@ FR_TEST_ATTR_STRING
Definition: dict_test.h:37
Test enumeration values.
Definition: dict_test.h:92
talloc_free(reap)
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
@ FR_TYPE_UINT8
8 Bit unsigned integer.
Definition: merged_model.c:97
@ FR_TYPE_UINT32
32 Bit unsigned integer.
Definition: merged_model.c:99
unsigned char uint8_t
Definition: merged_model.c:30
int fr_pair_list_copy_by_da(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from, fr_dict_attr_t const *da, unsigned int count)
Duplicate pairs in a list matching the specified da.
Definition: pair.c:2403
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:688
int fr_pair_value_bstrn_append(fr_pair_t *vp, char const *src, size_t len, bool tainted)
Append bytes from a buffer to an existing "string" type value pair.
Definition: pair.c:2877
int fr_pair_list_cmp(fr_pair_list_t const *a, fr_pair_list_t const *b)
Determine equality of two lists.
Definition: pair.c:2044
int fr_pair_value_memdup_buffer(fr_pair_t *vp, uint8_t const *src, bool tainted)
Copy data from a talloced buffer into an "octets" data type.
Definition: pair.c:3008
fr_pair_t * fr_pair_find_by_child_num_idx(fr_pair_list_t const *list, fr_dict_attr_t const *parent, unsigned int attr, unsigned int idx)
Find the pair with the matching child attribute at a given index.
Definition: pair.c:888
int fr_pair_value_enum_box(fr_value_box_t const **out, fr_pair_t *vp)
Get value box of a VP, optionally prefer enum value.
Definition: pair.c:3161
int fr_pair_value_aprintf(fr_pair_t *vp, char const *fmt,...)
Print data into an "string" data type.
Definition: pair.c:2695
int fr_pair_delete_by_da_nested(fr_pair_list_t *list, fr_dict_attr_t const *da)
Delete matching pairs from the specified list, and prune any empty branches.
Definition: pair.c:1708
int fr_pair_value_mem_append(fr_pair_t *vp, uint8_t *src, size_t len, bool tainted)
Append bytes from a buffer to an existing "octets" type value pair.
Definition: pair.c:3075
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
Definition: pair.c:278
int fr_pair_list_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from)
Duplicate a list of pairs.
Definition: pair.c:2316
int fr_pair_value_mem_append_buffer(fr_pair_t *vp, uint8_t *src, bool tainted)
Append a talloced buffer to an existing "octets" type value pair.
Definition: pair.c:3098
int fr_pair_value_memdup(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted)
Copy data into an "octets" data type.
Definition: pair.c:2978
int fr_pair_value_strdup(fr_pair_t *vp, char const *src, bool tainted)
Copy data into an "string" data type.
Definition: pair.c:2631
int fr_pair_value_bstrdup_buffer_shallow(fr_pair_t *vp, char const *src, bool tainted)
Assign a string to a "string" type value pair.
Definition: pair.c:2852
int fr_pair_cmp(fr_pair_t const *a, fr_pair_t const *b)
Compare two pairs, using the operator from "a".
Definition: pair.c:1966
int fr_pair_value_bstrndup_shallow(fr_pair_t *vp, char const *src, size_t len, bool tainted)
Assign a string to a "string" type value pair.
Definition: pair.c:2832
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:1340
int fr_pair_delete_by_da(fr_pair_list_t *list, fr_dict_attr_t const *da)
Delete matching pairs from the specified list.
Definition: pair.c:1684
char const * fr_pair_value_enum(fr_pair_t const *vp, char buff[20])
Return a const buffer for an enum type attribute.
Definition: pair.c:3122
int fr_pair_update_by_da_parent(fr_pair_t *parent, fr_pair_t **out, fr_dict_attr_t const *da)
Return the first fr_pair_t matching the fr_dict_attr_t or alloc a new fr_pair_t and its subtree (and ...
Definition: pair.c:1591
int fr_pair_list_copy_by_ancestor(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from, fr_dict_attr_t const *parent_da)
Duplicate pairs in a list where the da is a descendant of parent_da.
Definition: pair.c:2452
fr_pair_t * fr_pair_delete(fr_pair_list_t *list, fr_pair_t *vp)
Remove fr_pair_t from a list and free.
Definition: pair.c:1819
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
Definition: pair.c:46
int fr_pair_value_mem_realloc(fr_pair_t *vp, uint8_t **out, size_t size)
Change the length of a buffer for a "octets" type value pair.
Definition: pair.c:2952
fr_pair_t * fr_pair_afrom_da_nested(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_attr_t const *da)
Create a pair (and all intermediate parents), and append it to the list.
Definition: pair.c:462
fr_pair_t * fr_pair_afrom_child_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int attr)
Create a new valuepair.
Definition: pair.c:366
int fr_pair_value_bstrndup(fr_pair_t *vp, char const *src, size_t len, bool tainted)
Copy data into a "string" type value pair.
Definition: pair.c:2781
int fr_pair_value_bstr_alloc(fr_pair_t *vp, char **out, size_t size, bool tainted)
Pre-allocate a memory buffer for a "string" type value pair.
Definition: pair.c:2727
int fr_pair_value_bstr_append_buffer(fr_pair_t *vp, char const *src, bool tainted)
Append a talloced buffer to an existing "string" type value pair.
Definition: pair.c:2900
int fr_pair_value_bstr_realloc(fr_pair_t *vp, char **out, size_t size)
Change the length of a buffer for a "string" type value pair.
Definition: pair.c:2752
int fr_pair_append_by_da_parent(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list, fr_dict_attr_t const *da)
Alloc a new fr_pair_t, adding the parent attributes if required.
Definition: pair.c:1518
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:736
int fr_pair_delete_by_child_num(fr_pair_list_t *list, fr_dict_attr_t const *parent, unsigned int attr)
Delete matching pairs from the specified list.
Definition: pair.c:1803
int fr_pair_value_copy(fr_pair_t *dst, fr_pair_t *src)
Copy the value from one pair to another.
Definition: pair.c:2560
int fr_pair_steal(TALLOC_CTX *ctx, fr_pair_t *vp)
Steal one VP.
Definition: pair.c:516
fr_pair_t * fr_pair_copy(TALLOC_CTX *ctx, fr_pair_t const *vp)
Copy a single valuepair.
Definition: pair.c:484
int fr_pair_value_memdup_shallow(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted)
Assign a buffer to a "octets" type value pair.
Definition: pair.c:3033
fr_pair_t * fr_pair_find_by_da_nested(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find a pair with a matching fr_dict_attr_t, by walking the nested fr_dict_attr_t tree.
Definition: pair.c:765
int fr_pair_value_mem_alloc(fr_pair_t *vp, uint8_t **out, size_t size, bool tainted)
Pre-allocate a memory buffer for a "octets" type value pair.
Definition: pair.c:2927
int fr_pair_value_strtrim(fr_pair_t *vp)
Trim the length of the string buffer to match the length of the C string.
Definition: pair.c:2674
int fr_pair_value_from_str(fr_pair_t *vp, char const *value, size_t inlen, fr_sbuff_unescape_rules_t const *uerules, bool tainted)
Convert string value to native attribute value.
Definition: pair.c:2586
int fr_pair_prepend(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the start of the list.
Definition: pair.c:1309
int fr_pair_raw_afrom_pair(fr_pair_t *vp, uint8_t const *data, size_t data_len)
Mark malformed attribute as raw.
Definition: pair.c:588
fr_value_box_t * fr_pair_dcursor_value_init(fr_dcursor_t *cursor)
Initialises a special dcursor over a fr_pair_list_t, but which returns fr_value_box_t.
Definition: pair.c:1243
int8_t fr_pair_cmp_by_da(void const *a, void const *b)
Order attributes by their da, and tag.
Definition: pair.c:1841
int fr_pair_value_memdup_buffer_shallow(fr_pair_t *vp, uint8_t const *src, bool tainted)
Assign a talloced buffer to a "octets" type value pair.
Definition: pair.c:3053
int fr_pair_value_strdup_shallow(fr_pair_t *vp, char const *src, bool tainted)
Assign a buffer containing a nul terminated string to a vp, but don't copy it.
Definition: pair.c:2655
int fr_pair_prepend_by_da(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list, fr_dict_attr_t const *da)
Alloc a new fr_pair_t (and prepend)
Definition: pair.c:1488
static void test_fr_pair_value_memdup_shallow(void)
static void test_fr_pair_value_mem_append_buffer(void)
static void test_fr_pair_list_copy_by_ancestor(void)
static void test_fr_pair_afrom_child_num(void)
static void test_fr_pair_value_aprintf(void)
static void test_fr_pair_value_mem_realloc(void)
static void test_fr_pair_value_memdup_buffer(void)
static void test_fr_pair_value_enum_box(void)
static void test_fr_pair_value_bstrdup_buffer(void)
static void test_fr_pair_value_copy(void)
static void test_fr_pair_delete(void)
static void test_fr_pair_list_cmp(void)
static void test_fr_pair_value_bstrn_append(void)
static void test_fr_pair_copy(void)
static void test_fr_pair_afrom_da(void)
static void test_fr_pair_value_mem_alloc(void)
static void test_fr_pair_value_bstrndup(void)
static void test_fr_pair_find_by_child_num_idx(void)
static void test_fr_pair_value_bstrndup_shallow(void)
static void test_fr_pair_value_bstrdup_buffer_shallow(void)
static void test_fr_pair_list_copy(void)
static void test_fr_pair_value_memdup_buffer_shallow(void)
static void test_fr_pair_value_bstr_realloc(void)
static void test_fr_pair_dcursor_by_da_init(void)
static void test_fr_pair_delete_by_da(void)
static void test_fr_pair_append(void)
static void test_fr_pair_value_strdup_shallow(void)
static void test_fr_pair_find_by_da_idx(void)
static void test_fr_pair_nested_verify(void)
static void test_fr_pair_value_strtrim(void)
static void test_fr_pair_value_enum(void)
static void test_fr_pair_value_bstr_alloc(void)
static void test_fr_pair_list_sort(void)
static void test_fr_pair_value_strdup(void)
static void test_fr_pair_cmp(void)
static void test_fr_pair_prepend_by_da(void)
static void test_fr_pair_afrom_da_nested(void)
static void test_fr_pair_list_copy_by_da(void)
static void test_fr_pair_value_from_str(void)
static void test_fr_pair_value_mem_append(void)
static void test_fr_pair_append_by_da_parent(void)
static void test_fr_pair_steal(void)
static void test_fr_pair_delete_by_child_num(void)
static void test_fr_pair_dcursor_by_ancestor_init(void)
static void test_fr_pair_delete_by_da_nested(void)
static void test_init(void)
Global initialisation.
static void test_fr_pair_raw_afrom_pair(void)
static void test_fr_pair_update_by_da_parent(void)
static void test_fr_pair_find_by_da_nested(void)
static void test_fr_pair_value_bstr_append_buffer(void)
static void test_fr_pair_dcursor_value_init(void)
static void test_fr_pair_value_memdup(void)
static fr_pair_list_t test_pairs
static fr_dict_t * test_dict
static int fr_pair_test_list_alloc_nested(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_test_attr_t const *test_defs)
static uint8_t test_octets[]
static int fr_pair_test_list_alloc(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_test_attr_t const *test_defs)
static size_t test_string_len
static char const * test_string
static TALLOC_CTX * autofree
Definition: radclient-ng.c:104
#define local_pairs
Convenience macro for accessing the state list.
Definition: request.h:134
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition: snprintf.c:689
return count
Definition: module.c:175
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
fr_pair_value_bstrdup_buffer(vp, eap_session->identity, true)
fr_pair_t * vp
#define fr_time()
Allow us to arbitrarily manipulate time.
Definition: state_test.c:8
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition: strlcpy.c:34
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
void * talloc_null_ctx(void)
Retrieve the current talloc NULL ctx.
Definition: talloc.c:49
#define talloc_autofree_context
The original function is deprecated, so replace it with our version.
Definition: talloc.h:51
static int64_t fr_time_unwrap(fr_time_t time)
Definition: time.h:146
"server local" time.
Definition: time.h:69
@ T_OP_EQ
Definition: token.h:83
@ T_OP_CMP_EQ
Definition: token.h:106
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
#define fr_pair_dcursor_by_da_init(_cursor, _list, _da)
Initialise a cursor that will return only attributes matching the specified fr_dict_attr_t.
Definition: pair.h:627
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
#define PAIR_VERIFY(_x)
Definition: pair.h:190
void fr_pair_list_sort(fr_pair_list_t *list, fr_cmp_t cmp)
Sort a doubly linked list of fr_pair_ts using merge sort.
Definition: pair_inline.c:140
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
Definition: pair_inline.c:113
#define fr_pair_dcursor_init(_cursor, _list)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
Definition: pair.h:590
#define fr_pair_dcursor_by_ancestor_init(_cursor, _list, _da)
Initialise a cursor that will return only attributes descended from the specified fr_dict_attr_t.
Definition: pair.h:645
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
static fr_slen_t parent
Definition: pair.h:844
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
fr_sbuff_unescape_rules_t fr_value_unescape_double
Definition: value.c:266
static size_t char ** out
Definition: value.h:984