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