The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
tmpl_dcursor_tests.c
Go to the documentation of this file.
1 static void test_init(void);
2 # define TEST_INIT test_init()
3 
4 #include <freeradius-devel/util/acutest.h>
5 #include <freeradius-devel/util/acutest_helpers.h>
6 #include <freeradius-devel/util/dict_test.h>
7 #include <freeradius-devel/server/tmpl_dcursor.h>
8 #include <freeradius-devel/server/pair.h>
9 
10 
11 static TALLOC_CTX *autofree;
13 
14 DIAG_OFF(declaration-after-statement)
15 
16 /** Global initialisation
17  */
18 static void test_init(void)
19 {
21  if (!autofree) {
22  error:
23  fr_perror("tmpl_dcursor_tests");
24  fr_exit_now(EXIT_FAILURE);
25  }
26 
27  /*
28  * Mismatch between the binary and the libraries it depends on
29  */
30  if (fr_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) goto error;
31 
32  if (fr_dict_test_init(autofree, &test_dict, NULL) < 0) goto error;
33 
34  if (request_global_init() < 0) goto error;
35 }
36 
38 {
39  request_t *request;
40 
41  /*
42  * Create and initialize the new request.
43  */
44  request = request_local_alloc_external(autofree, NULL);
45 
46  request->packet = fr_packet_alloc(request, false);
47  TEST_CHECK(request->packet != NULL);
48 
49  request->reply = fr_packet_alloc(request, false);
50  TEST_CHECK(request->reply != NULL);
51 
52  return request;
53 }
54 
55 #define pair_defs(_x) \
56  fr_pair_t *int32_vp ## _x; \
57  fr_pair_t *string_vp ## _x; \
58  fr_pair_t *group_vp ## _x; \
59  fr_pair_t *child_vp ## _x; \
60  fr_pair_t *top_vp ## _x; \
61  fr_pair_t *mid_vp ## _x; \
62  fr_pair_t *leaf_string_vp ## _x; \
63  fr_pair_t *leaf_int32_vp ## _x
64 
65 #define pair_defs_thin(_x) \
66  fr_pair_t *int32_vp ## _x; \
67  fr_pair_t *group_vp ## _x; \
68  fr_pair_t *top_vp ## _x; \
69  fr_pair_t *mid_vp ## _x; \
70  fr_pair_t *leaf_int32_vp ## _x
71 
72 #define pair_populate(_x) do { \
73  pair_append_request(&int32_vp ## _x, fr_dict_attr_test_int32); \
74  pair_append_request(&string_vp ## _x, fr_dict_attr_test_string); \
75  pair_append_request(&group_vp ## _x, fr_dict_attr_test_group); \
76  fr_pair_append_by_da(group_vp ## _x, &child_vp ## _x, &group_vp ## _x->children, fr_dict_attr_test_int16); \
77  pair_append_request(&top_vp ## _x, fr_dict_attr_test_nested_top_tlv); \
78  fr_pair_append_by_da(top_vp ## _x, &mid_vp ## _x, &top_vp ## _x->children, fr_dict_attr_test_nested_child_tlv); \
79  fr_pair_append_by_da(mid_vp ## _x, &leaf_string_vp ## _x, &mid_vp ## _x->children, fr_dict_attr_test_nested_leaf_string); \
80  fr_pair_append_by_da(mid_vp ## _x, &leaf_int32_vp ## _x, &mid_vp ## _x->children, fr_dict_attr_test_nested_leaf_int32); \
81  } while (0)
82 
83 #define pair_populate_thin(_x) do { \
84  pair_append_request(&int32_vp ## _x, fr_dict_attr_test_int32); \
85  pair_append_request(&group_vp ## _x, fr_dict_attr_test_group); \
86  pair_append_request(&top_vp ## _x, fr_dict_attr_test_nested_top_tlv); \
87  fr_pair_append_by_da(top_vp ## _x, &mid_vp ## _x, &top_vp ## _x->children, fr_dict_attr_test_nested_child_tlv); \
88  fr_pair_append_by_da(mid_vp ## _x, &leaf_int32_vp ## _x, &mid_vp ## _x->children, fr_dict_attr_test_nested_leaf_int32); \
89  } while (0)
90 
91 /*
92  * Top level attribute names in the test dictionary all have -0 on the end
93  * due to the ability to add multiple instances of each attribute for the
94  * pair list performance tests.
95  *
96  * So, when entering strings to build tmpls, ensure the top level attributes
97  * all end -0.
98  *
99  * The same applies to immediate children of group attributes since they will
100  * be other top level attributes.
101  */
102 
103 typedef struct {
106  int err;
110 
111 #define test_cursor() &vars.cursor
112 #define test_vp() vars.vp
113 #define test_vp_p() &vars.vp
114 #define test_vp_set(_vp) vars.vp = _vp
115 
116 /*
117  * Variables used in all tests
118  */
119 #define common_vars \
120  tmpl_dcursor_vars_t vars; \
121  request_t *request = request_fake_alloc()
122 
123 /** Initialise a tmpl using the _attr_str string, and return the first pair
124  *
125  * @param[out] vp_out where to write the returned pair
126  * @param[in,out] vars test variables
127  * @param[in] request the current request.
128  * @param[in] ref Attribute reference string.
129  */
130 static inline CC_HINT(always_inline)
131 int _tmpl_setup_and_cursor_init(fr_pair_t **vp_out, tmpl_dcursor_vars_t *vars, request_t *request, char const *ref)
132 {
133  tmpl_afrom_attr_substr(autofree, NULL, &vars->vpt, &FR_SBUFF_IN(ref, strlen(ref)), NULL, &(tmpl_rules_t){
134  .attr = {
135  .dict_def = test_dict,
136  .list_def = request_attr_request,
137  }});
138  TEST_CHECK(vars->vpt!= NULL);
139  TEST_MSG("Failed creating tmpl from %s: %s", ref, fr_strerror());
140  if (!vars->vpt) {
141  *vp_out = NULL;
142  return -1;
143  }
144 
145  *vp_out = tmpl_dcursor_init(&vars->err, NULL, &vars->cc, &vars->cursor, request, vars->vpt);
146  return 0;
147 }
148 
149 #define tmpl_setup_and_cursor_init(_vp_out, _ref) \
150  if (_tmpl_setup_and_cursor_init(_vp_out, &vars, request, _ref)) return
151 
152 /** Initialise a tmpl using the _attr_str string, and return the first pair
153  *
154  * @param[out] vp_out where to write the returned pair.
155  * @param[in,out] vars test variables
156  * @param[in] request the current request.
157  * @param[in] ref Attribute reference string.
158  */
159 static inline CC_HINT(always_inline)
160 int _tmpl_setup_and_cursor_build_init(fr_pair_t **vp_out, tmpl_dcursor_vars_t *vars, request_t *request, char const *ref)
161 {
162  tmpl_afrom_attr_substr(autofree, NULL, &vars->vpt, &FR_SBUFF_IN(ref, strlen(ref)), NULL, &(tmpl_rules_t){
163  .attr = {
164  .dict_def = test_dict,
165  .list_def = request_attr_request,
166  }});
167  TEST_CHECK(vars->vpt!= NULL);
168  TEST_MSG("Failed creating tmpl from %s: %s", ref, fr_strerror());
169  if (!vars->vpt) {
170  *vp_out = NULL;
171  return -1;
172  }
173 
174  *vp_out = tmpl_dcursor_build_init(&vars->err, autofree, &vars->cc, &vars->cursor, request, vars->vpt, &tmpl_dcursor_pair_build, NULL);
175  return 0;
176 }
177 
178 #define tmpl_setup_and_cursor_build_init(_vp_out, _ref) \
179  if (_tmpl_setup_and_cursor_build_init(_vp_out, &vars, request, _ref)) return
180 
181 /*
182  * How every test ends
183  */
184 #define test_end \
185  debug_attr_list(&request->request_pairs, 0); \
186  vars.vp = fr_dcursor_next(test_cursor()); \
187  TEST_CHECK_PAIR(vars.vp, NULL); \
188  TEST_MSG("Cursor should've been empty (i.e. returned NULL) at end of test"); \
189  tmpl_dcursor_clear(&vars.cc); \
190  TEST_CHECK_RET(talloc_free(vars.vpt), 0); \
191  TEST_CHECK_RET(talloc_free(request), 0)
192 
193 /*
194  * Call after "build" cursors
195  * Checks that no additional attributes are created
196  */
197 #define build_test_end \
198  debug_attr_list(&request->request_pairs, 0); \
199  test_vp_set(fr_dcursor_next(test_cursor())); \
200  TEST_CHECK_PAIR(test_vp(), NULL); \
201  tmpl_dcursor_clear(&vars.cc)
202 
203 static void debug_attr_list(fr_pair_list_t *list, int indent)
204 {
205  fr_pair_t *vp = NULL;
206  while ((vp = fr_pair_list_next(list, vp))) {
207  switch (vp->vp_type) {
208  case FR_TYPE_STRUCTURAL:
209  TEST_MSG("%*s%s => {", indent, "", vp->da->name);
210  debug_attr_list(&vp->vp_group, indent + 2);
211  TEST_MSG("%*s}", indent, "");
212  break;
213  default:
214  TEST_MSG("%*s%s", indent, "", vp->da->name);
215  }
216  }
217 }
218 
219 /*
220  * One instance of attribute at the top level
221  */
222 static void test_level_1_one(void)
223 {
224  common_vars;
225  pair_defs(1);
226 
227  pair_populate(1);
228  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Int32-0");
229  TEST_CHECK_PAIR(test_vp(), int32_vp1);
230 
231  test_end;
232 }
233 
234 /*
235  * One instance of attribute at the top level - search for second
236  */
237 static void test_level_1_one_second(void)
238 {
239  common_vars;
240  pair_defs(1);
241 
242  pair_populate(1);
243  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Int32-0[1]");
244  TEST_CHECK_PAIR(test_vp(), NULL);
245 
246  test_end;
247 }
248 
249 /*
250  * One instance of attribute at the top level - search for all
251  */
252 static void test_level_1_one_all(void)
253 {
254  common_vars;
255  pair_defs(1);
256 
257  pair_populate(1);
258  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Int32-0[*]");
259  TEST_CHECK_PAIR(test_vp(), int32_vp1);
260 
261  test_end;
262 }
263 
264 /*
265  * One instance of attribute at the top level - search for non-existent
266  */
267 static void test_level_1_one_missing(void)
268 {
269  common_vars;
270  pair_defs(1);
271 
272  pair_populate(1);
273  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Int16-0");
274  TEST_CHECK_PAIR(test_vp(), NULL);
275 
276  test_end;
277 }
278 
279 /*
280  * One instance of attribute at the top level - search for last
281  */
282 static void test_level_1_one_last(void)
283 {
284  common_vars;
285  pair_defs(1);
286 
287  pair_populate(1);
288  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Int32-0[n]");
289  TEST_CHECK_PAIR(test_vp(), int32_vp1);
290 
291  test_end;
292 }
293 
294 /*
295  * Two instances of attribute at the top level
296  */
297 static void test_level_1_two(void)
298 {
299  common_vars;
300  pair_defs(1);
301  pair_defs(2);
302 
303  pair_populate(1);
304  pair_populate(2);
305  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Int32-0");
306  TEST_CHECK_PAIR(test_vp(), int32_vp1);
307 
308  test_end;
309 }
310 
311 /*
312  * Two instances of attribute at the top level - choose second
313  */
314 static void test_level_1_two_second(void)
315 {
316  common_vars;
317  pair_defs(1);
318  pair_defs(2);
319 
320  pair_populate(1);
321  pair_populate(2);
322  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Int32-0[1]");
323  TEST_CHECK_PAIR(test_vp(), int32_vp2);
324 
325  test_end;
326 }
327 
328 /*
329  * Two instances of attribute at the top level - choose third - should be NULL
330  */
331 static void test_level_1_two_third(void)
332 {
333  common_vars;
334  pair_defs(1);
335  pair_defs(2);
336 
337  pair_populate(1);
338  pair_populate(2);
339  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Int32-0[2]");
340  TEST_CHECK_PAIR(test_vp(), NULL);
341 
342  test_end;
343 }
344 
345 /*
346  * Two instances of attribute at the top level - choose all
347  */
348 static void test_level_1_two_all(void)
349 {
350  common_vars;
351  pair_defs(1);
352  pair_defs(2);
353 
354  pair_populate(1);
355  pair_populate(2);
356  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Int32-0[*]");
357 
358  TEST_CHECK_PAIR(test_vp(), int32_vp1);
359 
361  TEST_CHECK_PAIR(test_vp(), int32_vp2);
362 
363  test_end;
364 }
365 
366 /*
367  * Two instances of attribute at the top level - choose last
368  */
369 static void test_level_1_two_last(void)
370 {
371  common_vars;
372  pair_defs(1);
373  pair_defs(2);
374 
375  pair_populate(1);
376  pair_populate(2);
377  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Int32-0[n]");
378  TEST_CHECK_PAIR(test_vp(), int32_vp2);
379 
380  test_end;
381 }
382 
383 /*
384  * Two instances of attribute at the top level - use count suffix
385  */
386 static void test_level_1_two_count(void)
387 {
388  common_vars;
389  pair_defs(1);
390  pair_defs(2);
391 
392  pair_populate(1);
393  pair_populate(2);
394  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Int32-0[#]");
395  TEST_CHECK_PAIR(test_vp(), int32_vp1);
396 
398  TEST_CHECK_PAIR(test_vp(), int32_vp2);
399 
400  test_end;
401 }
402 
403 /*
404  * One instance of a group attribute
405  */
406 static void test_level_2_one(void)
407 {
408  common_vars;
409  pair_defs(1);
410 
411  pair_populate(1);
412  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Group-0.Test-Int16-0");
413  TEST_CHECK_PAIR(test_vp(), child_vp1);
414 
415  test_end;
416 }
417 
418 /*
419  * One instance of a group attribute - look for second child
420  */
421 static void test_level_2_one_second(void)
422 {
423  common_vars;
424  pair_defs(1);
425 
426  pair_populate(1);
427  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Group-0.Test-Int16-0[1]");
428  TEST_CHECK_PAIR(test_vp(), NULL);
429 
430  test_end;
431 }
432 
433 /*
434  * One instance of a group attribute - look for all
435  */
436 static void test_level_2_one_all(void)
437 {
438  common_vars;
439  pair_defs(1);
440 
441  pair_populate(1);
442  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Group-0.Test-Int16-0[*]");
443  TEST_CHECK_PAIR(test_vp(), child_vp1);
444 
445  test_end;
446 }
447 
448 /*
449  * One instance of a group attribute - look for missing
450  */
451 static void test_level_2_one_missing(void)
452 {
453  common_vars;
454  pair_defs(1);
455 
456  pair_populate(1);
457  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Group-0.Test-Int32-0");
458  TEST_CHECK_PAIR(test_vp(), NULL);
459 
460  test_end;
461 }
462 
463 /*
464  * Two instances of a group attribute
465  */
466 static void test_level_2_two(void)
467 {
468  common_vars;
469  pair_defs(1);
470  pair_defs(2);
471 
472  pair_populate(1);
473  pair_populate(2);
474  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Group-0.Test-Int16-0");
475  TEST_CHECK_PAIR(test_vp(), child_vp1);
476 
477  test_end;
478 }
479 
480 /*
481  * Two instances of a group attribute - look for child in second parent
482  */
483 static void test_level_2_two_second(void)
484 {
485  common_vars;
486  pair_defs(1);
487  pair_defs(2);
488 
489  pair_populate(1);
490  pair_populate(2);
491  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Group-0[1].Test-Int16-0");
492  TEST_CHECK_PAIR(test_vp(), child_vp2);
493 
494  test_end;
495 }
496 
497 /*
498  * Two instances of a group attribute - children of all parents
499  */
500 static void test_level_2_two_all(void)
501 {
502  common_vars;
503  pair_defs(1);
504  pair_defs(2);
505 
506  pair_populate(1);
507  pair_populate(2);
508  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Group-0[*].Test-Int16-0");
509  TEST_CHECK_PAIR(test_vp(), child_vp1);
510 
512  TEST_CHECK_PAIR(test_vp(), child_vp2);
513 
514  test_end;
515 }
516 
517 /*
518  * Two instances of a group attribute - children of last parent
519  */
520 static void test_level_2_two_last(void)
521 {
522  common_vars;
523  pair_defs(1);
524  pair_defs(2);
525 
526  pair_populate(1);
527  pair_populate(2);
528  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Group-0[n].Test-Int16-0");
529  TEST_CHECK_PAIR(test_vp(), child_vp2);
530 
531  test_end;
532 }
533 
534 /*
535  * Two instances of a group attribute - missing children of all parents
536  */
537 static void test_level_2_two_missing(void)
538 {
539  common_vars;
540  pair_defs(1);
541  pair_defs(2);
542 
543  pair_populate(1);
544  pair_populate(2);
545  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Group-0[*].Test-Int32-0");
546  TEST_CHECK_PAIR(test_vp(), NULL);
547 
548  test_end;
549 }
550 
551 /*
552  * Single instance of three level TLV
553  */
554 static void test_level_3_one(void)
555 {
556  common_vars;
557  pair_defs(1);
558 
559  pair_populate(1);
560  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Nested-Top-TLV-0[0].Child-TLV[0].Leaf-String");
561  TEST_CHECK_PAIR(test_vp(), leaf_string_vp1);
562 
563  test_end;
564 }
565 
566 /*
567  * Single instance of three level TLV - look for a second instance of level 2 TLV
568  */
569 static void test_level_3_one_second(void)
570 {
571  common_vars;
572  pair_defs(1);
573 
574  pair_populate(1);
575  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Nested-Top-TLV-0[0].Child-TLV[1].Leaf-String");
576  TEST_CHECK_PAIR(test_vp(), NULL);
577 
578  test_end;
579 }
580 
581 /*
582  * Single instance of three level TLV - look for a second instance of level 2 TLV
583  */
584 static void test_level_3_one_all(void)
585 {
586  common_vars;
587  pair_defs(1);
588 
589  pair_populate(1);
590  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Nested-Top-TLV-0[0].Child-TLV[*].Leaf-String");
591  TEST_CHECK_PAIR(test_vp(), leaf_string_vp1);
592 
593  test_end;
594 }
595 
596 static void test_level_3_two(void)
597 {
598  common_vars;
599  pair_defs(1);
600  pair_defs(2);
601 
602  pair_populate(1);
603  pair_populate(2);
604  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Nested-Top-TLV-0[0].Child-TLV[0].Leaf-Int32");
605  TEST_CHECK_PAIR(test_vp(), leaf_int32_vp1);
606 
607  test_end;
608 }
609 
610 static void test_level_3_two_all(void)
611 {
612  common_vars;
613  pair_defs(1);
614  pair_defs(2);
615 
616  pair_populate(1);
617  pair_populate(2);
618  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Nested-Top-TLV-0[*].Child-TLV[*].Leaf-Int32");
619  TEST_CHECK_PAIR(test_vp(), leaf_int32_vp1);
620 
622  TEST_CHECK_PAIR(test_vp(), leaf_int32_vp2);
623 
624  test_end;
625 }
626 
627 static void test_level_3_two_last(void)
628 {
629  common_vars;
630  pair_defs(1);
631  pair_defs(2);
632 
633  pair_populate(1);
634  pair_populate(2);
635  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Nested-Top-TLV-0[n].Child-TLV[n].Leaf-Int32[n]");
636  TEST_CHECK_PAIR(test_vp(), leaf_int32_vp2);
637 
638  test_end;
639 }
640 
641 static void test_level_1_build(void)
642 {
643  common_vars;
644  pair_defs(1);
645  fr_pair_t *inserted;
646 
647  pair_populate(1);
648  tmpl_setup_and_cursor_build_init(&inserted, "&Test-Int16-0");
649  TEST_CHECK_PAIR_NEQ(inserted, NULL);
651 
652  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Int16-0");
653  TEST_CHECK_PAIR(test_vp(), inserted);
654 
655  test_end;
656 }
657 
658 static void test_level_2_build_leaf(void)
659 {
660  common_vars;
661  pair_defs(1);
662  fr_pair_t *inserted;
663 
664  pair_populate(1);
665  tmpl_setup_and_cursor_build_init(&inserted, "&Test-Group-0.Test-Int32-0");
666  TEST_CHECK_PAIR_NEQ(inserted, NULL);
668 
669  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Group-0.Test-Int32-0");
670  TEST_CHECK_PAIR(test_vp(), inserted);
671 
672  test_end;
673 }
674 
676 {
677  common_vars;
678  fr_pair_t *inserted;
679 
680  tmpl_setup_and_cursor_build_init(&inserted, "&Test-Group-0.Test-Int16-0");
681  TEST_CHECK_PAIR_NEQ(inserted, NULL);
683 
684  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Group-0.Test-Int16-0");
685  TEST_CHECK_PAIR(test_vp(), inserted);
686 
687  test_end;
688 }
689 
690 static void test_level_2_build_multi(void)
691 {
692  common_vars;
693  pair_defs_thin(1);
694  pair_defs_thin(2);
695  fr_pair_t *inserted, *second;
696 
699  tmpl_setup_and_cursor_build_init(&inserted, "&Test-Group-0[*].Test-Int32-0");
700  TEST_CHECK_PAIR_NEQ(inserted, NULL);
701 
702  second = fr_dcursor_next(test_cursor());
703  TEST_CHECK_PAIR_NEQ(second, NULL);
704  TEST_CHECK_PAIR_NEQ(second, inserted);
706 
707  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Group-0[*].Test-Int32-0");
708  TEST_CHECK_PAIR(test_vp(), inserted);
710  TEST_CHECK_PAIR(test_vp(), second);
711 
712  test_end;
713 }
714 
715 static void test_level_3_build_leaf(void)
716 {
717  common_vars;
718  pair_defs(1);
719  fr_pair_t *inserted;
720 
721  pair_populate(1);
722  tmpl_setup_and_cursor_build_init(&inserted, "&Test-Group-0.Test-Group-0.Test-String-0");
723  TEST_CHECK_PAIR_NEQ(inserted, NULL);
725 
726  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Group-0.Test-Group-0.Test-String-0");
727  TEST_CHECK_PAIR(test_vp(), inserted);
728 
729  test_end;
730 }
731 
732 static void test_level_3_build_entire(void)
733 {
734  common_vars;
735  fr_pair_t *inserted;
736 
737  tmpl_setup_and_cursor_build_init(&inserted, "&Test-Nested-Top-TLV-0[0].Child-TLV[0].Leaf-String");
738  TEST_CHECK_PAIR_NEQ(inserted, NULL);
740 
741  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Nested-Top-TLV-0[0].Child-TLV[0].Leaf-String");
742  TEST_CHECK_PAIR(test_vp(), inserted);
743 
744  test_end;
745 }
746 
747 static void test_level_3_build_partial(void)
748 {
749  common_vars;
750  pair_defs(1);
751  pair_defs_thin(2);
752  fr_pair_t *inserted;
753 
754  pair_populate(1);
756  tmpl_setup_and_cursor_build_init(&inserted, "&Test-Nested-Top-TLV-0[1].Child-TLV[0].Leaf-String");
757  TEST_CHECK_PAIR_NEQ(inserted, NULL);
758  TEST_CHECK_PAIR_NEQ(inserted, leaf_string_vp1);
760 
761  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Nested-Top-TLV-0[1].Child-TLV[0].Leaf-String");
762  TEST_CHECK_PAIR(test_vp(), inserted);
763 
764  test_end;
765 }
766 
768 {
769  common_vars;
770  fr_pair_t *inserted;
771 
772  tmpl_setup_and_cursor_build_init(&inserted, "&Test-Nested-Top-TLV-0[3].Child-TLV[0].Leaf-String");
773  TEST_CHECK_PAIR(inserted, NULL);
775 
776  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Nested-Top-TLV-0[3].Child-TLV[0].Leaf-String");
777  TEST_CHECK_PAIR(test_vp(), NULL);
778 
779  test_end;
780 }
781 
783 {
784  common_vars;
785  fr_pair_t *inserted;
786 
787  tmpl_setup_and_cursor_build_init(&inserted, "&Test-Nested-Top-TLV-0[*].Child-TLV[0].Leaf-String");
788  TEST_CHECK_PAIR(inserted, NULL);
790 
791  tmpl_setup_and_cursor_init(test_vp_p(), "&Test-Nested-Top-TLV-0[*].Child-TLV[0].Leaf-String");
792  TEST_CHECK_PAIR(test_vp(), NULL);
793 
794  test_end;
795 }
796 
798  { "test_level_1_one", test_level_1_one },
799  { "test_level_1_one_second", test_level_1_one_second },
800  { "test_level_1_one_all", test_level_1_one_all },
801  { "test_level_1_one_missing", test_level_1_one_missing },
802  { "test_level_1_one_last", test_level_1_one_last },
803  { "test_level_1_two", test_level_1_two },
804  { "test_level_1_two_second", test_level_1_two_second },
805  { "test_level_1_two_third", test_level_1_two_third },
806  { "test_level_1_two_all", test_level_1_two_all },
807  { "test_level_1_two_last", test_level_1_two_last },
808  { "test_level_1_two_count", test_level_1_two_count },
809  { "test_level_2_one", test_level_2_one },
810  { "test_level_2_one_second", test_level_2_one_second },
811  { "test_level_2_one_all", test_level_2_one_all },
812  { "test_level_2_one_missing", test_level_2_one_missing },
813  { "test_level_2_two", test_level_2_two },
814  { "test_level_2_two_second", test_level_2_two_second },
815  { "test_level_2_two_all", test_level_2_two_all },
816  { "test_level_2_two_last", test_level_2_two_last },
817  { "test_level_2_two_missing", test_level_2_two_missing },
818  { "test_level_3_one", test_level_3_one },
819  { "test_level_3_one_second", test_level_3_one_second },
820  { "test_level_3_one_all", test_level_3_one_all },
821  { "test_level_3_two", test_level_3_two },
822  { "test_level_3_two_all", test_level_3_two_all },
823  { "test_level_3_two_last", test_level_3_two_last },
824 
825  { "test_level_1_build", test_level_1_build },
826  { "test_level_2_build_leaf", test_level_2_build_leaf },
827  { "test_level_2_build_intermediate", test_level_2_build_intermediate },
828  { "test_level_2_build_multi", test_level_2_build_multi },
829  { "test_level_3_build_leaf", test_level_3_build_leaf },
830  { "test_level_3_build_entire", test_level_3_build_entire },
831  { "test_level_3_build_partial", test_level_3_build_partial },
832  { "test_level_3_build_invalid1", test_level_3_build_invalid1 },
833  { "test_level_3_build_invalid2", test_level_3_build_invalid2 },
834 
835  { NULL }
836 };
837 
838 DIAG_ON(declaration-after-statement)
#define TEST_CHECK(cond)
Definition: acutest.h:85
#define TEST_MSG(...)
Definition: acutest.h:215
#define DIAG_ON(_x)
Definition: build.h:456
#define DIAG_OFF(_x)
Definition: build.h:455
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
Definition: dcursor.h:288
#define fr_exit_now(_x)
Exit without calling atexit() handlers, producing a log message in debug builds.
Definition: debug.h:234
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_packet_t * fr_packet_alloc(TALLOC_CTX *ctx, bool new_vector)
Allocate a new fr_packet_t.
Definition: packet.c:38
fr_dict_attr_t const * request_attr_request
Definition: request.c:45
int request_global_init(void)
Definition: request.c:722
#define request_local_alloc_external(_ctx, _args)
Allocate a new external request outside of the request pool.
Definition: request.h:316
#define FR_SBUFF_IN(_start, _len_or_end)
ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, tmpl_t **out, fr_sbuff_t *name, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules))
Parse a string into a TMPL_TYPE_ATTR_* type tmpl_t.
Optional arguments passed to vp_tmpl functions.
Definition: tmpl.h:341
fr_pair_t * vp
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
fr_pair_t * tmpl_dcursor_pair_build(fr_pair_t *parent, fr_dcursor_t *cursor, fr_dict_attr_t const *da, UNUSED void *uctx)
Simple pair building callback for use with tmpl_dcursors.
Definition: tmpl_dcursor.c:523
#define tmpl_dcursor_build_init(_err, _ctx, _cc, _cursor, _request, _vpt, _build, _uctx)
Definition: tmpl_dcursor.h:103
#define tmpl_dcursor_init(_err, _ctx, _cc, _cursor, _request, _vpt)
Definition: tmpl_dcursor.h:100
Maintains state between cursor calls.
Definition: tmpl_dcursor.h:62
static void test_level_3_build_entire(void)
static void test_level_2_two_last(void)
#define pair_populate(_x)
static void test_level_3_two(void)
#define tmpl_setup_and_cursor_build_init(_vp_out, _ref)
static TALLOC_CTX * autofree
static void test_level_3_two_last(void)
static int _tmpl_setup_and_cursor_build_init(fr_pair_t **vp_out, tmpl_dcursor_vars_t *vars, request_t *request, char const *ref)
Initialise a tmpl using the _attr_str string, and return the first pair.
static void test_level_2_two_missing(void)
static void test_level_1_build(void)
static void test_level_1_two_all(void)
tmpl_dcursor_ctx_t cc
static void test_level_1_two_third(void)
static void test_level_3_one_all(void)
#define test_vp_set(_vp)
static void test_level_2_build_intermediate(void)
#define pair_populate_thin(_x)
#define pair_defs_thin(_x)
static void test_level_2_two_second(void)
static void test_level_1_two_second(void)
static int _tmpl_setup_and_cursor_init(fr_pair_t **vp_out, tmpl_dcursor_vars_t *vars, request_t *request, char const *ref)
Initialise a tmpl using the _attr_str string, and return the first pair.
static void test_level_1_two_count(void)
#define pair_defs(_x)
static void test_level_1_one_second(void)
static void test_level_1_one(void)
static void debug_attr_list(fr_pair_list_t *list, int indent)
static void test_level_2_build_leaf(void)
static void test_level_3_build_invalid2(void)
static fr_dict_t * test_dict
static void test_level_3_one_second(void)
static void test_level_2_two(void)
static void test_level_1_one_last(void)
#define test_cursor()
static void test_level_2_one_missing(void)
static void test_level_3_build_partial(void)
static void test_level_2_one(void)
static void test_level_3_two_all(void)
#define common_vars
static void test_level_1_two(void)
static void test_level_1_one_all(void)
#define tmpl_setup_and_cursor_init(_vp_out, _ref)
static void test_init(void)
Global initialisation.
static void test_level_1_one_missing(void)
static void test_level_3_one(void)
#define test_vp()
static void test_level_2_one_all(void)
#define test_vp_p()
#define test_end
#define build_test_end
static void test_level_2_build_multi(void)
static void test_level_1_two_last(void)
static void test_level_2_one_second(void)
static void test_level_2_two_all(void)
static void test_level_3_build_invalid1(void)
static request_t * request_fake_alloc(void)
static void test_level_3_build_leaf(void)
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_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
Definition: strerror.c:733
char const * fr_strerror(void)
Get the last library error.
Definition: strerror.c:554
#define FR_TYPE_STRUCTURAL
Definition: types.h:296
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