libamxo  4.3.4
Object Definition Language (ODL) parsing
test_synchronize.c
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** SPDX-License-Identifier: BSD-2-Clause-Patent
4 **
5 ** SPDX-FileCopyrightText: Copyright (c) 2023 SoftAtHome
6 **
7 ** Redistribution and use in source and binary forms, with or without modification,
8 ** are permitted provided that the following conditions are met:
9 **
10 ** 1. Redistributions of source code must retain the above copyright notice,
11 ** this list of conditions and the following disclaimer.
12 **
13 ** 2. Redistributions in binary form must reproduce the above copyright notice,
14 ** this list of conditions and the following disclaimer in the documentation
15 ** and/or other materials provided with the distribution.
16 **
17 ** Subject to the terms and conditions of this license, each copyright holder
18 ** and contributor hereby grants to those receiving rights under this license
19 ** a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
20 ** (except for failure to satisfy the conditions of this license) patent license
21 ** to make, have made, use, offer to sell, sell, import, and otherwise transfer
22 ** this software, where such license applies only to those patent claims, already
23 ** acquired or hereafter acquired, licensable by such copyright holder or contributor
24 ** that are necessarily infringed by:
25 **
26 ** (a) their Contribution(s) (the licensed copyrights of copyright holders and
27 ** non-copyrightable additions of contributors, in source or binary form) alone;
28 ** or
29 **
30 ** (b) combination of their Contribution(s) with the work of authorship to which
31 ** such Contribution(s) was added by such copyright holder or contributor, if,
32 ** at the time the Contribution is added, such addition causes such combination
33 ** to be necessarily infringed. The patent license shall not apply to any other
34 ** combinations which include the Contribution.
35 **
36 ** Except as expressly stated above, no rights or licenses from any copyright
37 ** holder or contributor is granted under this license, whether expressly, by
38 ** implication, estoppel or otherwise.
39 **
40 ** DISCLAIMER
41 **
42 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
43 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
46 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
48 ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
49 ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
51 ** USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 **
53 ****************************************************************************/
54 #include <sys/time.h>
55 #include <sys/resource.h>
56 #include <sys/types.h>
57 #include <sys/stat.h>
58 
59 #include <string.h>
60 #include <stdlib.h>
61 #include <stdio.h>
62 #include <stdarg.h>
63 #include <stddef.h>
64 #include <setjmp.h>
65 #include <inttypes.h>
66 #include <limits.h>
67 #include <unistd.h>
68 #include <fcntl.h>
69 #include <cmocka.h>
70 
71 #include <amxc/amxc.h>
72 #include <amxp/amxp_signal.h>
73 #include <amxp/amxp_slot.h>
74 #include <amxd/amxd_dm.h>
75 #include <amxd/amxd_object.h>
76 #include <amxd/amxd_parameter.h>
77 #include <amxd/amxd_transaction.h>
78 #include <amxs/amxs.h>
79 #include <amxo/amxo.h>
80 #include <amxo/amxo_hooks.h>
81 
82 #include "test_synchronize.h"
83 #include "../../include_priv/amxo_parser_priv.h"
84 
85 #include <amxc/amxc_macros.h>
86 
87 static amxs_status_t translate_object(UNUSED const amxs_sync_entry_t* entry,
88  UNUSED amxs_sync_direction_t direction,
89  UNUSED const amxc_var_t* input,
90  UNUSED amxc_var_t* output,
91  UNUSED void* priv) {
92  printf("Translate object\n");
93  return amxs_status_ok;
94 }
95 
96 static amxs_status_t apply_object(UNUSED const amxs_sync_entry_t* entry,
97  UNUSED amxs_sync_direction_t direction,
98  UNUSED amxc_var_t* data,
99  UNUSED void* priv) {
100  printf("Apply object\n");
101  return amxs_status_ok;
102 }
103 
104 static amxs_status_t translate_param(UNUSED const amxs_sync_entry_t* entry,
105  UNUSED amxs_sync_direction_t direction,
106  UNUSED const amxc_var_t* input,
107  UNUSED amxc_var_t* output,
108  UNUSED void* priv) {
109  printf("Translate param\n");
110  return amxs_status_ok;
111 }
112 
113 static amxs_status_t apply_param(UNUSED const amxs_sync_entry_t* entry,
114  UNUSED amxs_sync_direction_t direction,
115  UNUSED amxc_var_t* data,
116  UNUSED void* priv) {
117  printf("Apply param\n");
118  return amxs_status_ok;
119 }
120 
122  amxd_dm_t dm;
123  amxo_parser_t parser;
124  const char* file = "./odl/valid_synchronize.odl";
125 
126  const char* odl =
127  "%populate {"
128  " synchronize 'A.' <-> 'B.' {"
129  " %batch parameter param_A <-> param_B;"
130  " object 'A_template.' <-> 'B_template.' {"
131  " %batch parameter uint_A <-> uint_B;"
132  " %batch parameter string_A <-> string_B;"
133  " }"
134  " }"
135  "}";
136 
137  amxd_dm_init(&dm);
138  amxo_parser_init(&parser);
139 
140  assert_int_equal(amxo_parser_parse_file(&parser, file, amxd_dm_get_root(&dm)), 0);
141  assert_int_equal(amxo_parser_parse_string(&parser, odl, amxd_dm_get_root(&dm)), 0);
142  assert_non_null(parser.sync_contexts);
143  assert_false(amxc_llist_is_empty(parser.sync_contexts));
144 
145  assert_true(amxo_parser_get_sync_type(&parser) == amxs_sync_type_ctx);
146 
147  amxo_parser_clean(&parser);
148  amxd_dm_clean(&dm);
149 }
150 
152  amxd_dm_t dm;
153  amxo_parser_t parser;
154  const char* file = "./odl/valid_synchronize.odl";
155 
156  const char* odl1 =
157  "%populate {"
158  " synchronize 'A.' <-> 'B.' {"
159  " %batch parameter param_A -> param_B;"
160  " %batch parameter param_A <- param_B;"
161  " }"
162  "}";
163 
164  const char* odl2 =
165  "%populate {"
166  " synchronize 'A.' <-> 'B.' {"
167  " %batch parameter param_A -> param_B;"
168  " %batch parameter param_B -> param_A;"
169  " }"
170  "}";
171 
172  amxd_dm_init(&dm);
173  amxo_parser_init(&parser);
174 
175  assert_int_equal(amxo_parser_parse_file(&parser, file, amxd_dm_get_root(&dm)), 0);
176  assert_int_equal(amxo_parser_parse_string(&parser, odl1, amxd_dm_get_root(&dm)), 0);
177  assert_non_null(parser.sync_contexts);
178  assert_false(amxc_llist_is_empty(parser.sync_contexts));
179 
180  assert_true(amxo_parser_get_sync_type(&parser) == amxs_sync_type_ctx);
181 
182  assert_int_equal(amxo_parser_parse_string(&parser, odl2, amxd_dm_get_root(&dm)), 0);
183  assert_non_null(parser.sync_contexts);
184  assert_false(amxc_llist_is_empty(parser.sync_contexts));
185  assert_int_equal(amxc_llist_size(parser.sync_contexts), 2);
186 
187  amxo_parser_clean(&parser);
188  amxd_dm_clean(&dm);
189 }
190 
192  amxd_dm_t dm;
193  amxo_parser_t parser;
194  const char* file = "./odl/valid_synchronize.odl";
195 
196  const char* odl =
197  "%populate {"
198  " synchronize '${prefix_}C.' <-> '${prefix_}D.' {"
199  " %batch parameter '${prefix_}string_C' <-> '${prefix_}string_D';"
200  " object '${prefix_}C_template.' <-> '${prefix_}D_template.' {"
201  " %batch parameter '${prefix_}string_C' <-> '${prefix_}string_D';"
202  " }"
203  " }"
204  "}";
205 
206  amxd_dm_init(&dm);
207  amxo_parser_init(&parser);
208 
209  assert_int_equal(amxo_parser_parse_file(&parser, file, amxd_dm_get_root(&dm)), 0);
210  assert_int_equal(amxo_parser_parse_string(&parser, odl, amxd_dm_get_root(&dm)), 0);
211  assert_non_null(parser.sync_contexts);
212  assert_false(amxc_llist_is_empty(parser.sync_contexts));
213 
214  assert_true(amxo_parser_get_sync_type(&parser) == amxs_sync_type_ctx);
215 
216  amxo_parser_clean(&parser);
217  amxd_dm_clean(&dm);
218 }
219 
221  amxd_dm_t dm;
222  amxo_parser_t parser;
223  const char* file = "./odl/valid_synchronize.odl";
224 
225  const char* odl =
226  "%populate {"
227  " synchronize 'A.' <-> 'B.' {"
228  " parameter param_A <-> param_B {"
229  " on action translate call translate_param;"
230  " on action apply call apply_param;"
231  " }"
232  " object 'A_template.' <-> 'B_template.' {"
233  " on action translate call translate_object;"
234  " on action apply call apply_object;"
235  " %batch parameter uint_A <-> uint_B;"
236  " %batch parameter string_A <-> string_B;"
237  " }"
238  " }"
239  "}";
240 
241  amxd_dm_init(&dm);
242  amxo_parser_init(&parser);
243 
244  amxo_resolver_ftab_add(&parser, "translate_object", AMXO_FUNC(translate_object));
245  amxo_resolver_ftab_add(&parser, "translate_param", AMXO_FUNC(translate_param));
246  amxo_resolver_ftab_add(&parser, "apply_object", AMXO_FUNC(apply_object));
247  amxo_resolver_ftab_add(&parser, "apply_param", AMXO_FUNC(apply_param));
248 
249  assert_int_equal(amxo_parser_parse_file(&parser, file, amxd_dm_get_root(&dm)), 0);
250  assert_int_equal(amxo_parser_parse_string(&parser, odl, amxd_dm_get_root(&dm)), 0);
251  assert_non_null(parser.sync_contexts);
252  assert_false(amxc_llist_is_empty(parser.sync_contexts));
253 
254  amxo_parser_clean(&parser);
255  amxd_dm_clean(&dm);
256 }
257 
259  amxd_dm_t dm;
260  amxo_parser_t parser;
261  const char* file = "./odl/valid_synchronize.odl";
262 
263  const char* odl1 =
264  "%populate {"
265  " synchronize 'A.' <-> 'B.' {"
266  " %batch parameter param_A -> param_B;"
267  " %batch parameter param_A -> param_B;"
268  " }"
269  "}";
270 
271  amxd_dm_init(&dm);
272  amxo_parser_init(&parser);
273 
274  assert_int_equal(amxo_parser_parse_file(&parser, file, amxd_dm_get_root(&dm)), 0);
275  assert_int_not_equal(amxo_parser_parse_string(&parser, odl1, amxd_dm_get_root(&dm)), 0);
276  assert_non_null(parser.sync_contexts);
277 
278  amxo_parser_clean(&parser);
279  amxd_dm_clean(&dm);
280 }
281 
283  amxd_dm_t dm;
284  amxo_parser_t parser;
285  const char* file = "./odl/valid_synchronize.odl";
286 
287  const char* odl =
288  "%populate {"
289  " synchronize 'A.' <-> 'B.' { }"
290  "}";
291 
292  amxd_dm_init(&dm);
293  amxo_parser_init(&parser);
294 
295  assert_int_equal(amxo_parser_parse_file(&parser, file, amxd_dm_get_root(&dm)), 0);
296  assert_int_not_equal(amxo_parser_parse_string(&parser, odl, amxd_dm_get_root(&dm)), 0);
297  assert_null(parser.sync_contexts);
298 
299  amxo_parser_clean(&parser);
300  amxd_dm_clean(&dm);
301 }
302 
304  amxd_dm_t dm;
305  amxo_parser_t parser;
306  const char* file = "./odl/valid_synchronize.odl";
307 
308  const char* odl1 =
309  "%populate {"
310  " synchronize 'A' -> 'B' {"
311  " %batch parameter param_A -> param_B;"
312  " }"
313  "}";
314 
315  const char* odl2 =
316  "%populate {"
317  " synchronize '' -> '' {"
318  " %batch parameter param_A -> param_B;"
319  " }"
320  "}";
321 
322  amxd_dm_init(&dm);
323  amxo_parser_init(&parser);
324 
325  assert_int_equal(amxo_parser_parse_file(&parser, file, amxd_dm_get_root(&dm)), 0);
326  assert_int_not_equal(amxo_parser_parse_string(&parser, odl1, amxd_dm_get_root(&dm)), 0);
327  assert_null(parser.sync_contexts);
328 
329  assert_int_not_equal(amxo_parser_parse_string(&parser, odl2, amxd_dm_get_root(&dm)), 0);
330  assert_null(parser.sync_contexts);
331 
332  amxo_parser_clean(&parser);
333  amxd_dm_clean(&dm);
334 }
335 
337  amxd_dm_t dm;
338  amxo_parser_t parser;
339  const char* file = "./odl/valid_synchronize.odl";
340 
341  const char* odl =
342  "%populate {"
343  " synchronize 'A.' <-> 'B.' {"
344  " object 'A_template.' <-> 'B_template.' {"
345  " }"
346  " }"
347  "}";
348 
349  amxd_dm_init(&dm);
350  amxo_parser_init(&parser);
351 
352  assert_int_equal(amxo_parser_parse_file(&parser, file, amxd_dm_get_root(&dm)), 0);
353  assert_int_not_equal(amxo_parser_parse_string(&parser, odl, amxd_dm_get_root(&dm)), 0);
354  assert_null(parser.sync_contexts);
355 
356  amxo_parser_clean(&parser);
357  amxd_dm_clean(&dm);
358 }
359 
361  amxd_dm_t dm;
362  amxo_parser_t parser;
363  const char* file = "./odl/valid_synchronize.odl";
364 
365  const char* odl =
366  "%populate {"
367  " synchronize 'A.' <-> 'B.' {"
368  " object 'A_template.' <-> 'B_template.' {"
369  " on action translate call object_translate;"
370  " }"
371  " }"
372  "}";
373 
374  amxd_dm_init(&dm);
375  amxo_parser_init(&parser);
376 
377  amxo_resolver_ftab_add(&parser, "param_translate", AMXO_FUNC(translate_object));
378 
379  assert_int_equal(amxo_parser_parse_file(&parser, file, amxd_dm_get_root(&dm)), 0);
380  assert_int_not_equal(amxo_parser_parse_string(&parser, odl, amxd_dm_get_root(&dm)), 0);
381  assert_null(parser.sync_contexts);
382 
383  amxo_parser_clean(&parser);
384  amxd_dm_clean(&dm);
385 }
386 
388  amxd_dm_t dm;
389  amxo_parser_t parser;
390  const char* file = "./odl/valid_synchronize.odl";
391 
392  const char* odl1 =
393  "%populate {"
394  " synchronize 'A.' <-> 'B.' {"
395  " %batch parameter param_A <-> param_B {"
396  " on action translate call param_translate;"
397  " }"
398  " }"
399  "}";
400  const char* odl2 =
401  "%populate {"
402  " synchronize 'A.' <-> 'B.' {"
403  " %batch parameter param_A <-> param_B {"
404  " on action apply call param_apply;"
405  " }"
406  " }"
407  "}";
408 
409  amxd_dm_init(&dm);
410  amxo_parser_init(&parser);
411 
412  amxo_resolver_ftab_add(&parser, "param_translate", AMXO_FUNC(translate_param));
413  amxo_resolver_ftab_add(&parser, "param_apply", AMXO_FUNC(apply_param));
414 
415  assert_int_equal(amxo_parser_parse_file(&parser, file, amxd_dm_get_root(&dm)), 0);
416  assert_int_not_equal(amxo_parser_parse_string(&parser, odl1, amxd_dm_get_root(&dm)), 0);
417  assert_null(parser.sync_contexts);
418 
419  assert_int_not_equal(amxo_parser_parse_string(&parser, odl2, amxd_dm_get_root(&dm)), 0);
420  assert_null(parser.sync_contexts);
421 
422  amxo_parser_clean(&parser);
423  amxd_dm_clean(&dm);
424 }
425 
427  amxd_dm_t dm;
428  amxo_parser_t parser;
429  const char* file = "./odl/valid_synchronize.odl";
430 
431  const char* odl1 =
432  "%populate {"
433  " synchronize 'A.' -> 'B.' {"
434  " %batch parameter param_A <- param_B;"
435  " }"
436  "}";
437  const char* odl2 =
438  "%populate {"
439  " synchronize 'A.' <- 'B.' {"
440  " object 'A_template.' -> 'B_template.' {"
441  " %batch parameter uint_A <-> uint_B;"
442  " }"
443  " }"
444  "}";
445 
446  amxd_dm_init(&dm);
447  amxo_parser_init(&parser);
448 
449  assert_int_equal(amxo_parser_parse_file(&parser, file, amxd_dm_get_root(&dm)), 0);
450  assert_int_not_equal(amxo_parser_parse_string(&parser, odl1, amxd_dm_get_root(&dm)), 0);
451  assert_null(parser.sync_contexts);
452 
453  assert_int_not_equal(amxo_parser_parse_string(&parser, odl2, amxd_dm_get_root(&dm)), 0);
454  assert_null(parser.sync_contexts);
455 
456  amxo_parser_clean(&parser);
457  amxd_dm_clean(&dm);
458 }
459 
461  amxd_dm_t dm;
462  amxo_parser_t parser;
463  const char* file = "./odl/valid_synchronize.odl";
464 
465  const char* odl =
466  "%populate {"
467  " synchronize 'A.' <-> 'B.' {"
468  " %batch parameter param_A <-> param_B {"
469  " on action read call data_read;"
470  " }"
471  " }"
472  "}";
473 
474  amxd_dm_init(&dm);
475  amxo_parser_init(&parser);
476 
477  amxo_resolver_ftab_add(&parser, "data_read", AMXO_FUNC(translate_param));
478 
479  assert_int_equal(amxo_parser_parse_file(&parser, file, amxd_dm_get_root(&dm)), 0);
480  assert_int_not_equal(amxo_parser_parse_string(&parser, odl, amxd_dm_get_root(&dm)), 0);
481  assert_null(parser.sync_contexts);
482 
483  amxo_parser_clean(&parser);
484  amxd_dm_clean(&dm);
485 }
486 
488  amxd_dm_t dm;
489  amxo_parser_t parser;
490  const char* file = "./odl/valid_synchronize.odl";
491 
492  const char* odl =
493  "%populate {"
494  " synchronize 'A.' <-> 'B.' {"
495  " %batch parameter param_A <-> param_B;"
496  " object 'A_template.' <-> 'B_template.' {"
497  " %batch parameter uint_A <-> uint_B;"
498  " %batch parameter string_A <-> string_B;"
499  " }"
500  " }"
501  "}";
502 
503  amxd_dm_init(&dm);
504  amxo_parser_init(&parser);
505 
506  assert_int_equal(amxo_parser_parse_file(&parser, file, amxd_dm_get_root(&dm)), 0);
507  assert_int_equal(amxo_parser_parse_string(&parser, odl, amxd_dm_get_root(&dm)), 0);
508  assert_non_null(parser.sync_contexts);
509  assert_false(amxc_llist_is_empty(parser.sync_contexts));
510 
511  assert_int_not_equal(amxo_parser_start_synchronize(&parser), 0);
512 
513  amxo_parser_clean(&parser);
514  amxd_dm_clean(&dm);
515 }
516 
518  amxd_dm_t* dm = amxut_bus_dm();
519  amxo_parser_t* parser = amxut_bus_parser();
520  amxd_object_t* object = NULL;
521  amxd_trans_t transaction;
522  char* txt = NULL;
523 
524  const char* file = "./odl/valid_synchronize.odl";
525 
526  const char* odl =
527  "%populate {"
528  " synchronize 'A.' <-> 'B.' {"
529  " %batch parameter param_A <-> param_B;"
530  " object 'A_template.' <-> 'B_template.' {"
531  " %batch parameter uint_A <-> uint_B;"
532  " %batch parameter string_A <-> string_B;"
533  " }"
534  " }"
535  "}";
536 
537 
538  amxd_trans_init(&transaction);
539 
540  assert_int_equal(amxo_parser_parse_file(parser, file, amxd_dm_get_root(dm)), 0);
541  assert_int_equal(amxo_parser_parse_string(parser, odl, amxd_dm_get_root(dm)), 0);
542  assert_non_null(parser->sync_contexts);
543  assert_false(amxc_llist_is_empty(parser->sync_contexts));
544 
545  assert_int_equal(amxo_parser_start_synchronize(parser), 0);
546 
547  object = amxd_dm_findf(dm, "B");
548  assert_non_null(object);
549  assert_int_equal(amxd_object_get_value(uint32_t, object, "param_B", NULL), 2);
550 
551  amxd_trans_select_pathf(&transaction, "B.B_template.");
552  amxd_trans_add_inst(&transaction, 0, NULL);
553  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
554  amxd_trans_clean(&transaction);
555 
556  while(amxp_signal_read() == 0) {
557  }
558 
559  object = amxd_dm_findf(dm, "A.A_template.1.");
560  assert_non_null(object);
561  assert_int_equal(amxd_object_get_value(uint32_t, object, "uint_A", NULL), 3);
562  txt = amxd_object_get_value(cstring_t, object, "string_A", NULL);
563  assert_string_equal(txt, "I am B");
564  free(txt);
565 
567 }
568 
570  amxd_dm_t* dm = amxut_bus_dm();
571  amxo_parser_t* parser = amxut_bus_parser();
572 
573  const char* file = "./odl/valid_synchronize.odl";
574 
575  const char* odl =
576  "%populate {"
577  " synchronize '${prefix_}C.' <-> '${prefix_}D.' {"
578  " %batch parameter '${prefix_}string_C' <-> '${prefix_}string_D';"
579  " object '${prefix_}C_template.' <-> '${prefix_}D_template.' {"
580  " %batch parameter '${prefix_}string_C' <-> '${prefix_}string_D';"
581  " }"
582  " }"
583  "}";
584 
585  assert_int_equal(amxo_parser_parse_file(parser, file, amxd_dm_get_root(dm)), 0);
586  assert_int_equal(amxo_parser_parse_string(parser, odl, amxd_dm_get_root(dm)), 0);
587  assert_non_null(parser->sync_contexts);
588  assert_false(amxc_llist_is_empty(parser->sync_contexts));
589 
590  assert_int_equal(amxo_parser_start_synchronize(parser), 0);
592 }
593 
594 
596  amxd_dm_t* dm = amxut_bus_dm();
597  amxo_parser_t* parser = amxut_bus_parser();
598  amxd_object_t* object = NULL;
599  amxd_trans_t transaction;
600  char* txt = NULL;
601 
602  const char* file = "./odl/valid_synchronize.odl";
603 
604  const char* odl =
605  "%populate {"
606  " synchronize 'A.' -> 'B.' {"
607  " parameter param_A -> param_B;"
608  " object 'A_template.' -> 'B_template.' {"
609  " parameter uint_A -> uint_B;"
610  " parameter string_A -> string_B;"
611  " }"
612  " }"
613  "}";
614 
615 
616  amxd_trans_init(&transaction);
617 
618  assert_int_equal(amxo_parser_parse_file(parser, file, amxd_dm_get_root(dm)), 0);
619  assert_int_equal(amxo_parser_parse_string(parser, odl, amxd_dm_get_root(dm)), 0);
620  assert_non_null(parser->sync_contexts);
621  assert_false(amxc_llist_is_empty(parser->sync_contexts));
622 
623  assert_int_equal(amxo_parser_start_synchronize(parser), 0);
624 
625  object = amxd_dm_findf(dm, "A");
626  assert_non_null(object);
627  assert_int_equal(amxd_object_get_value(uint32_t, object, "param_A", NULL), 2);
628 
629  amxd_trans_select_pathf(&transaction, "A.A_template.");
630  amxd_trans_add_inst(&transaction, 0, NULL);
631  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
632  amxd_trans_clean(&transaction);
633 
634  while(amxp_signal_read() == 0) {
635  }
636 
637  object = amxd_dm_findf(dm, "B.B_template.1.");
638  assert_non_null(object);
639  assert_int_equal(amxd_object_get_value(uint32_t, object, "uint_B", NULL), 1);
640  txt = amxd_object_get_value(cstring_t, object, "string_B", NULL);
641  assert_string_equal(txt, "I am A");
642  free(txt);
643 
644  amxd_trans_select_pathf(&transaction, "B.B_template.1.");
645  amxd_trans_set_value(cstring_t, &transaction, "string_B", "Hello");
646  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
647  amxd_trans_clean(&transaction);
648 
649  while(amxp_signal_read() == 0) {
650  }
651 
652  object = amxd_dm_findf(dm, "A.A_template.1.");
653  assert_non_null(object);
654  txt = amxd_object_get_value(cstring_t, object, "string_A", NULL);
655  assert_string_equal(txt, "I am A");
656  free(txt);
657 
659 }
660 
662  amxd_dm_t* dm = amxut_bus_dm();
663  amxo_parser_t* parser = amxut_bus_parser();
664  amxd_object_t* object = NULL;
665  amxd_trans_t transaction;
666  char* txt = NULL;
667 
668  const char* file = "./odl/valid_synchronize.odl";
669 
670  const char* odl =
671  "%populate {"
672  " synchronize 'A.' <-> 'B.' {"
673  " parameter param_A <-> param_B;"
674  " object 'A_template.' -> 'B_template.' {"
675  " parameter uint_A -> uint_B;"
676  " parameter string_A -> string_B;"
677  " }"
678  " }"
679  "}";
680 
681 
682  amxd_trans_init(&transaction);
683 
684  assert_int_equal(amxo_parser_parse_file(parser, file, amxd_dm_get_root(dm)), 0);
685  assert_int_equal(amxo_parser_parse_string(parser, odl, amxd_dm_get_root(dm)), 0);
686  assert_non_null(parser->sync_contexts);
687  assert_false(amxc_llist_is_empty(parser->sync_contexts));
688 
689  assert_int_equal(amxo_parser_start_synchronize(parser), 0);
690 
691  object = amxd_dm_findf(dm, "A");
692  assert_non_null(object);
693  assert_int_equal(amxd_object_get_value(uint32_t, object, "param_A", NULL), 2);
694 
695  amxd_trans_select_pathf(&transaction, "A.A_template.");
696  amxd_trans_add_inst(&transaction, 0, NULL);
697  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
698  amxd_trans_clean(&transaction);
699 
700  while(amxp_signal_read() == 0) {
701  }
702 
703  object = amxd_dm_findf(dm, "B.B_template.1.");
704  assert_non_null(object);
705  assert_int_equal(amxd_object_get_value(uint32_t, object, "uint_B", NULL), 1);
706  txt = amxd_object_get_value(cstring_t, object, "string_B", NULL);
707  assert_string_equal(txt, "I am A");
708  free(txt);
709 
710  amxd_trans_select_pathf(&transaction, "B.B_template.1.");
711  amxd_trans_set_value(cstring_t, &transaction, "string_B", "Hello");
712  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
713  amxd_trans_clean(&transaction);
714 
715  while(amxp_signal_read() == 0) {
716  }
717 
718  object = amxd_dm_findf(dm, "A.A_template.1.");
719  assert_non_null(object);
720  txt = amxd_object_get_value(cstring_t, object, "string_A", NULL);
721  assert_string_equal(txt, "I am A");
722  free(txt);
723 
725 }
726 
728  amxd_dm_t* dm = amxut_bus_dm();
729  amxo_parser_t* parser = amxut_bus_parser();
730  amxd_object_t* object = NULL;
731  amxd_trans_t transaction;
732  char* txt = NULL;
733 
734  const char* file = "./odl/valid_synchronize.odl";
735 
736  const char* odl =
737  "%populate {"
738  " synchronize 'A.' <-> 'B.' {"
739  " %batch parameter param_A <-> param_B;"
740  " object 'A_template.' <-> 'B_template.' {"
741  " %batch parameter uint_A -> uint_B;"
742  " %batch parameter string_A -> string_B;"
743  " }"
744  " }"
745  "}";
746 
747 
748  amxd_trans_init(&transaction);
749 
750  assert_int_equal(amxo_parser_parse_file(parser, file, amxd_dm_get_root(dm)), 0);
751  assert_int_equal(amxo_parser_parse_string(parser, odl, amxd_dm_get_root(dm)), 0);
752  assert_non_null(parser->sync_contexts);
753  assert_false(amxc_llist_is_empty(parser->sync_contexts));
754 
755  assert_int_equal(amxo_parser_start_synchronize(parser), 0);
756 
757  object = amxd_dm_findf(dm, "A");
758  assert_non_null(object);
759  assert_int_equal(amxd_object_get_value(uint32_t, object, "param_A", NULL), 2);
760 
761  amxd_trans_select_pathf(&transaction, "A.A_template.");
762  amxd_trans_add_inst(&transaction, 0, NULL);
763  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
764  amxd_trans_clean(&transaction);
765 
766  while(amxp_signal_read() == 0) {
767  }
768 
769  object = amxd_dm_findf(dm, "B.B_template.1.");
770  assert_non_null(object);
771  assert_int_equal(amxd_object_get_value(uint32_t, object, "uint_B", NULL), 1);
772  txt = amxd_object_get_value(cstring_t, object, "string_B", NULL);
773  assert_string_equal(txt, "I am A");
774  free(txt);
775 
776  amxd_trans_select_pathf(&transaction, "B.B_template.1.");
777  amxd_trans_set_value(cstring_t, &transaction, "string_B", "Hello");
778  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
779  amxd_trans_clean(&transaction);
780 
781  while(amxp_signal_read() == 0) {
782  }
783 
784  object = amxd_dm_findf(dm, "A.A_template.1.");
785  assert_non_null(object);
786  txt = amxd_object_get_value(cstring_t, object, "string_A", NULL);
787  assert_string_equal(txt, "I am A");
788  free(txt);
789 
791 }
792 
794  amxd_dm_t* dm = amxut_bus_dm();
795  amxo_parser_t* parser = amxut_bus_parser();
796  amxd_object_t* object = NULL;
797  amxd_trans_t transaction;
798  char* txt = NULL;
799 
800  const char* file = "./odl/valid_synchronize.odl";
801 
802  const char* odl =
803  "%populate {"
804  " synchronize 'A.' <- 'B.' {"
805  " %batch parameter param_A <- param_B;"
806  " object 'A_template.' <- 'B_template.' {"
807  " %batch parameter uint_A <- uint_B;"
808  " %batch parameter ReadOnlyText <- ReadOnlyText;"
809  " }"
810  " }"
811  "}";
812 
813 
814  amxd_trans_init(&transaction);
815 
816  assert_int_equal(amxo_parser_parse_file(parser, file, amxd_dm_get_root(dm)), 0);
817  assert_int_equal(amxo_parser_parse_string(parser, odl, amxd_dm_get_root(dm)), 0);
818  assert_non_null(parser->sync_contexts);
819  assert_false(amxc_llist_is_empty(parser->sync_contexts));
820 
821  assert_int_equal(amxo_parser_start_synchronize(parser), 0);
822 
823  object = amxd_dm_findf(dm, "B");
824  assert_non_null(object);
825 
826  amxd_trans_select_pathf(&transaction, "B.B_template.");
827  amxd_trans_add_inst(&transaction, 0, NULL);
828  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
829  amxd_trans_clean(&transaction);
830 
831  while(amxp_signal_read() == 0) {
832  }
833 
834  object = amxd_dm_findf(dm, "A.A_template.1.");
835  assert_non_null(object);
836  txt = amxd_object_get_value(cstring_t, object, "ReadOnlyText", NULL);
837  assert_string_equal(txt, "5678");
838  free(txt);
839 
841 }
842 
844  amxd_dm_t* dm = amxut_bus_dm();
845  amxo_parser_t* parser = amxut_bus_parser();
846  amxd_object_t* object = NULL;
847  amxd_trans_t transaction;
848  char* txt = NULL;
849  amxs_sync_ctx_t* sync_ctx = NULL;
850 
851  const char* file = "./odl/valid_synchronize.odl";
852 
853  const char* odl =
854  "%populate {"
855  " synchronize 'A.A_template.{i}.' <-> 'B.B_template.{i}.' as 'A2B'{"
856  " %batch parameter uint_A <-> uint_B;"
857  " %batch parameter string_A <-> string_B;"
858  " }"
859  "}";
860 
861 
862  amxd_trans_init(&transaction);
863 
864  assert_int_equal(amxo_parser_parse_file(parser, file, amxd_dm_get_root(dm)), 0);
865  assert_int_equal(amxo_parser_parse_string(parser, odl, amxd_dm_get_root(dm)), 0);
866  assert_non_null(parser->sync_contexts);
867  assert_false(amxc_llist_is_empty(parser->sync_contexts));
868 
869  assert_int_equal(amxo_parser_start_synchronize(parser), 0);
870 
871  object = amxd_dm_findf(dm, "A");
872  assert_non_null(object);
873 
874  amxd_trans_select_pathf(&transaction, "A.A_template.");
875  amxd_trans_add_inst(&transaction, 0, NULL);
876  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
877  amxd_trans_clean(&transaction);
878 
879  object = amxd_dm_findf(dm, "B");
880  assert_non_null(object);
881 
882  amxd_trans_select_pathf(&transaction, "B.B_template.");
883  amxd_trans_add_inst(&transaction, 0, NULL);
884  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
885  amxd_trans_clean(&transaction);
886 
887  while(amxp_signal_read() == 0) {
888  }
889 
890  sync_ctx = amxo_parser_new_sync_ctx("A2B", "A.A_template.1.", "B.B_template.1.");
891  assert_non_null(sync_ctx);
892  amxs_sync_ctx_start_sync(sync_ctx);
893 
894  amxd_trans_select_pathf(&transaction, "B.B_template.1.");
895  amxd_trans_set_value(cstring_t, &transaction, "string_B", "Hello");
896  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
897  amxd_trans_clean(&transaction);
898 
899  while(amxp_signal_read() == 0) {
900  }
901 
902  object = amxd_dm_findf(dm, "A.A_template.1.");
903  assert_non_null(object);
904  txt = amxd_object_get_value(cstring_t, object, "string_A", NULL);
905  assert_string_equal(txt, "Hello");
906  free(txt);
907 
908  amxs_sync_ctx_delete(&sync_ctx);
909  assert_null(sync_ctx);
911 }
912 
914  amxd_dm_t* dm = amxut_bus_dm();
915  amxo_parser_t* parser = amxut_bus_parser();
916 
917  const char* file = "./odl/valid_synchronize.odl";
918 
919  const char* odl1 =
920  "%populate {"
921  " synchronize 'A.A_template.1.' <-> 'B.B_template.5.' as 'A1_2_B5'{"
922  " %batch parameter uint_A <-> uint_B;"
923  " %batch parameter string_A <-> string_B;"
924  " }"
925  "}";
926  const char* odl2 =
927  "%populate {"
928  " synchronize 'A.A_template.[Alias == \"test\"].' <-> 'B.B_template.[Alias == \"mapped\"].' as 'A2B'{"
929  " %batch parameter uint_A <-> uint_B;"
930  " %batch parameter string_A <-> string_B;"
931  " }"
932  "}";
933  const char* odl3 =
934  "%populate {"
935  " synchronize 'A.' <-> 'B.' as 'A2B_valid'{"
936  " %batch parameter param_A <-> param_B;"
937  " }"
938  "}";
939 
940 
941  assert_int_equal(amxo_parser_parse_file(parser, file, amxd_dm_get_root(dm)), 0);
942  assert_int_not_equal(amxo_parser_parse_string(parser, odl1, amxd_dm_get_root(dm)), 0);
943  assert_int_not_equal(amxo_parser_parse_string(parser, odl2, amxd_dm_get_root(dm)), 0);
944  assert_int_equal(amxo_parser_parse_string(parser, odl3, amxd_dm_get_root(dm)), 0);
945 }
Ambiorix ODL parser header file.
include test_include odl
Definition: test_valid.odl:66
PRIVATE amxs_sync_entry_type_t amxo_parser_get_sync_type(amxo_parser_t *pctx)
int amxo_parser_start_synchronize(amxo_parser_t *parser)
Start all object and parameter synchronizations that were declared in the loaded odl files.
int amxo_parser_parse_string(amxo_parser_t *parser, const char *text, amxd_object_t *object)
Parses a string containing a valid ODL part.
void amxo_parser_clean(amxo_parser_t *parser)
Cleans up the odl parser instance.
int amxo_parser_parse_file(amxo_parser_t *parser, const char *file_path, amxd_object_t *object)
Parses an odl file.
amxs_sync_ctx_t * amxo_parser_new_sync_ctx(const char *sync_template, const char *object_a, const char *object_b)
Create a new synchronization context from a synchronization template.
int amxo_parser_init(amxo_parser_t *parser)
Initializes a new odl parser instance.
void amxo_parser_stop_synchronize(amxo_parser_t *parser)
Stop all object and parameter synchronizations that were declared in odl files.
int amxo_resolver_ftab_add(amxo_parser_t *parser, const char *fn_name, amxo_fn_ptr_t fn)
Adds a C function to the function table.
#define AMXO_FUNC(x)
Function ponter caster macro.
Definition: amxo_types.h:80
The ODL parser structure.
Definition: amxo_types.h:245
amxc_llist_t * sync_contexts
Definition: amxo_types.h:290
#define UNUSED
Definition: test_issue_48.c:84
void test_synchronization_can_use_template(UNUSED void **state)
void test_can_parser_synchronize_definition(UNUSED void **state)
void test_parse_empty_synchronize_context_fails(UNUSED void **state)
void test_can_setup_synchronization_with_vars(UNUSED void **state)
static amxs_status_t translate_param(UNUSED const amxs_sync_entry_t *entry, UNUSED amxs_sync_direction_t direction, UNUSED const amxc_var_t *input, UNUSED amxc_var_t *output, UNUSED void *priv)
void test_can_setup_synchronization(UNUSED void **state)
static amxs_status_t apply_object(UNUSED const amxs_sync_entry_t *entry, UNUSED amxs_sync_direction_t direction, UNUSED amxc_var_t *data, UNUSED void *priv)
void test_synchronization_respects_direction(UNUSED void **state)
void test_synchronization_template_must_use_supported_path(UNUSED void **state)
void test_parser_sync_duplicates_fails(UNUSED void **state)
void test_synchronization_respects_direction_3(UNUSED void **state)
void test_parse_synchronize_with_invalid_action_fails(UNUSED void **state)
void test_can_parser_synchronize_definition_with_vars(UNUSED void **state)
void test_can_parser_synchronize_definition_with_cb(UNUSED void **state)
void test_synchronize_start_fails_when_no_bus_connections(UNUSED void **state)
void test_parse_synchronize_object_fails_without_entries(UNUSED void **state)
void test_parse_empty_synchronize_object_fails(UNUSED void **state)
void test_synchronization_respects_direction_2(UNUSED void **state)
void test_synchronization_can_set_readonly(UNUSED void **state)
void test_parse_sync_invalid_context_paths_fails(UNUSED void **state)
void test_can_parser_synchronize_definition_alternate(UNUSED void **state)
void test_create_sync_tree_fails_with_conflicting_directions(UNUSED void **state)
void test_parse_batch_parameter_with_cb_fails(UNUSED void **state)
static amxs_status_t apply_param(UNUSED const amxs_sync_entry_t *entry, UNUSED amxs_sync_direction_t direction, UNUSED amxc_var_t *data, UNUSED void *priv)
static amxs_status_t translate_object(UNUSED const amxs_sync_entry_t *entry, UNUSED amxs_sync_direction_t direction, UNUSED const amxc_var_t *input, UNUSED amxc_var_t *output, UNUSED void *priv)