libamxo  4.3.4
Object Definition Language (ODL) parsing
test_valid_odl.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 <amxd/amxd_dm.h>
74 #include <amxd/amxd_object.h>
75 #include <amxd/amxd_object_event.h>
76 #include <amxd/amxd_parameter.h>
77 #include <amxo/amxo.h>
78 
79 #include "test_valid_odl.h"
80 
81 #include <amxc/amxc_macros.h>
83  amxc_var_t* option = amxo_parser_get_config(parser, "test_option_number");
84  assert_ptr_not_equal(option, NULL);
85  assert_int_equal(amxc_var_type_of(option), AMXC_VAR_ID_INT64);
86 
87  option = amxo_parser_get_config(parser, "test_option_string");
88  assert_ptr_not_equal(option, NULL);
89  assert_int_equal(amxc_var_type_of(option), AMXC_VAR_ID_CSTRING);
90 
91  option = amxo_parser_get_config(parser, "test_option_bool");
92  assert_ptr_not_equal(option, NULL);
93  assert_int_equal(amxc_var_type_of(option), AMXC_VAR_ID_BOOL);
94 }
95 
96 static void check_objects_exist(amxd_dm_t* dm) {
97  amxd_object_t* root = amxd_dm_get_root(dm);
98  static const char* paths[] = {
99  "TestObjectRoot",
100  "TestObjectRoot.TestObjectSingelton",
101  "TestObjectRoot.TestObjSingletonAttr",
102  "TestObjectRoot.TestObjectTemplate",
103  "TestObjectRoot.TestObjTemplateAttr",
104  "TestObjectRoot.TestObjectParamTypes",
105  "TestObjectRoot.TestObjectFunctions",
106  "TestObjectRoot.TestSingeltonParamAttr",
107  "TestObjectRoot.TestTemplateParamAttr.99",
108  "TestObjectRoot.TestTemplateParamAttr.100",
109  "TestObjectRoot.TestSingletonFuncAttr",
110  "TestObjectRoot.TestTemplateFuncAttr",
111  "TestObjectRoot.TestObjectTemplateWithChild",
112  "TestObjectRoot.TestObjectTemplateWithChild.TemplateChildObject",
113  "TestObjectRoot.TestObjectTemplateWithChild.Name1",
114  "TestObjectRoot.TestObjectTemplateWithChild.Name1.TemplateChildObject",
115  "TestObjectRoot.TestObjectTemplateWithChild.Name2",
116  "TestObjectRoot.TestObjectTemplateWithChild.Name2.MibObject",
117  "TestObjectRoot.TestObjectTemplateWithChild.Name2.TemplateChildObject",
118  "TestObjectRoot.ExtendWithTestMib",
119  "TestObjectRoot.ExtendWithTestMib.MibObject",
120  NULL
121  };
122 
123  for(int i = 0; paths[i] != NULL; i++) {
124  printf("Checking %s exists\n", paths[i]);
125  assert_ptr_not_equal(amxd_object_findf(root, paths[i]), NULL);
126  }
127 }
128 
129 static void check_parameters_exist(amxd_dm_t* dm) {
130  amxd_object_t* root = amxd_dm_get_root(dm);
131  amxd_object_t* object = NULL;
132  amxd_param_t* param = NULL;
133  static const char* types_params[] = {
134  "Param1",
135  "Param2",
136  "Param3",
137  "Param4",
138  "Param5",
139  "Param6",
140  "Param7",
141  "Param8",
142  "Param9",
143  "Param10",
144  "Param11",
145  "Param12",
146  "Param13",
147  NULL
148  };
149 
150  object = amxd_object_findf(root, "TestObjectRoot.TestObjectParamTypes");
151  assert_int_equal(amxd_object_get_param_count(object, amxd_dm_access_protected), 13);
152  for(int i = 0; types_params[i] != NULL; i++) {
153  assert_ptr_not_equal(amxd_object_get_param_def(object, types_params[i]), NULL);
154  }
155 
156  object = amxd_object_findf(root, "TestObjectRoot.TestSingeltonParamAttr");
157  assert_int_equal(amxd_object_get_param_count(object, amxd_dm_access_private), 1);
158  param = amxd_object_get_param_def(object, "Param1");
159  assert_ptr_not_equal(param, NULL);
160  assert_true(amxd_param_is_attr_set(param, amxd_pattr_private));
161  assert_true(amxd_param_is_attr_set(param, amxd_pattr_read_only));
162  assert_true(amxd_param_is_attr_set(param, amxd_pattr_variable));
163  assert_true(amxd_param_is_attr_set(param, amxd_pattr_instance));
164  assert_true(amxd_param_is_attr_set(param, amxd_pattr_template));
165 
166  object = amxd_object_findf(root, "TestObjectRoot.TestTemplateParamAttr");
167  assert_int_equal(amxd_object_get_param_count(object, amxd_dm_access_private), 3);
168  param = amxd_object_get_param_def(object, "Param1");
169  assert_ptr_not_equal(param, NULL);
170  assert_true(amxd_param_is_attr_set(param, amxd_pattr_private));
171  assert_true(amxd_param_is_attr_set(param, amxd_pattr_read_only));
172  assert_true(amxd_param_is_attr_set(param, amxd_pattr_variable));
173  assert_true(amxd_param_is_attr_set(param, amxd_pattr_instance));
174  assert_true(amxd_param_is_attr_set(param, amxd_pattr_template));
175  param = amxd_object_get_param_def(object, "Param2");
176  assert_ptr_not_equal(param, NULL);
177  assert_false(amxd_param_is_attr_set(param, amxd_pattr_private));
178  assert_false(amxd_param_is_attr_set(param, amxd_pattr_read_only));
179  assert_false(amxd_param_is_attr_set(param, amxd_pattr_variable));
180  assert_false(amxd_param_is_attr_set(param, amxd_pattr_instance));
181  assert_true(amxd_param_is_attr_set(param, amxd_pattr_template));
182  param = amxd_object_get_param_def(object, "Param3");
183  assert_ptr_not_equal(param, NULL);
184  assert_false(amxd_param_is_attr_set(param, amxd_pattr_private));
185  assert_false(amxd_param_is_attr_set(param, amxd_pattr_read_only));
186  assert_false(amxd_param_is_attr_set(param, amxd_pattr_variable));
187  assert_true(amxd_param_is_attr_set(param, amxd_pattr_instance));
188  assert_false(amxd_param_is_attr_set(param, amxd_pattr_template));
189 
190  object = amxd_object_findf(root, "TestObjectRoot");
191  assert_int_equal(amxd_object_get_param_count(object, amxd_dm_access_private), 2);
192  param = amxd_object_get_param_def(object, "TestObjectTemplateWithChildCounter");
193  assert_ptr_not_equal(param, NULL);
194  object = amxd_object_findf(root, "TestObjectRoot.TestObjectTemplateWithChild.TemplateChildObject");
195  assert_int_equal(amxd_object_get_param_count(object, amxd_dm_access_private), 1);
196  param = amxd_object_get_param_def(object, "Param1");
197  assert_ptr_not_equal(param, NULL);
198  object = amxd_object_findf(root, "TestObjectRoot.TestObjectTemplateWithChild.1.TemplateChildObject");
199  assert_int_equal(amxd_object_get_param_count(object, amxd_dm_access_private), 1);
200  param = amxd_object_get_param_def(object, "Param1");
201  assert_ptr_not_equal(param, NULL);
202 
203  object = amxd_object_findf(root, "TestObjectRoot.TestObjectTemplateWithKeys.1.");
204  param = amxd_object_get_param_def(object, "KeyPart1");
205  assert_true(amxd_param_is_attr_set(param, amxd_pattr_key));
206  assert_false(amxd_param_is_attr_set(param, amxd_pattr_mutable));
207  param = amxd_object_get_param_def(object, "KeyPart2");
208  assert_true(amxd_param_is_attr_set(param, amxd_pattr_key));
209  assert_true(amxd_param_is_attr_set(param, amxd_pattr_mutable));
210 }
211 
212 static void check_functions_exist(amxd_dm_t* dm) {
213  amxd_object_t* root = amxd_dm_get_root(dm);
214  amxd_object_t* object = NULL;
215  amxd_function_t* func = NULL;
216  static const char* obj_funcs[] = {
217  "func1",
218  "func2",
219  "func3",
220  "func4",
221  "func5",
222  "func6",
223  "func7",
224  "func8",
225  "func9",
226  "func10",
227  "func11",
228  "func12",
229  "func13",
230  "func14",
231  "func15",
232  "func16",
233  NULL
234  };
235 
236  object = amxd_object_findf(root, "TestObjectRoot.TestObjectFunctions");
237  assert_int_equal(amxd_object_get_function_count(object, amxd_dm_access_private), 25);
238  for(int i = 0; obj_funcs[i] != NULL; i++) {
239  assert_ptr_not_equal(amxd_object_get_function(object, obj_funcs[i]), NULL);
240  }
241 
242  object = amxd_object_findf(root, "TestObjectRoot.TestSingletonFuncAttr");
243  assert_int_equal(amxd_object_get_function_count(object, amxd_dm_access_private), 11);
244  func = amxd_object_get_function(object, "TestFunc1");
245  assert_true(amxd_function_is_attr_set(func, amxd_fattr_template));
246  assert_true(amxd_function_is_attr_set(func, amxd_fattr_instance));
247  assert_true(amxd_function_is_attr_set(func, amxd_fattr_private));
248 
249  func = amxd_object_get_function(object, "TestFunc2");
250  assert_false(amxd_function_is_attr_set(func, amxd_fattr_template));
251  assert_false(amxd_function_is_attr_set(func, amxd_fattr_instance));
252  assert_false(amxd_function_is_attr_set(func, amxd_fattr_private));
253 }
254 
255 static void check_mib_extions_work(amxd_dm_t* dm) {
256  amxd_object_t* object = amxd_dm_findf(dm, "TestObjectRoot.ExtendWithTestMib");
257 
258  assert_ptr_not_equal(object, NULL);
259  assert_true(amxd_object_has_mib(object, "TestMib"));
260  assert_ptr_not_equal(amxd_object_get_param_def(object, "mibparam"), NULL);
261  assert_ptr_not_equal(amxd_object_get_function(object, "mibfunc"), NULL);
262 }
263 
264 void test_can_parse_odl_file(UNUSED void** state) {
265  amxd_dm_t dm;
266  amxc_var_t* lib_dirs = NULL;
267  amxo_parser_t parser;
268 
269  amxd_dm_init(&dm);
270  amxo_parser_init(&parser);
271 
272  lib_dirs = amxo_parser_get_config(&parser, "import-dirs");
273  amxc_var_add(cstring_t, lib_dirs, "../test_plugin/");
274  amxc_var_dump(&parser.config, STDOUT_FILENO);
275 
276  assert_int_equal(amxo_parser_parse_file(&parser, "test_valid.odl", amxd_dm_get_root(&dm)), 0);
277  assert_int_equal(amxo_parser_get_status(&parser), amxd_status_ok);
278 
280  check_objects_exist(&dm);
284 
285  amxo_parser_clean(&parser);
286  amxd_dm_clean(&dm);
288 }
289 
291  amxd_dm_t dm;
292  amxc_var_t* lib_dirs = NULL;
293  amxo_parser_t parser;
294  amxc_var_t* odl_resolve = NULL;
295 
296  amxd_dm_init(&dm);
297  amxo_parser_init(&parser);
298 
299  lib_dirs = amxo_parser_get_config(&parser, "import-dirs");
300  odl_resolve = amxo_parser_claim_config(&parser, "odl-resolve");
301  amxc_var_set(bool, odl_resolve, false);
302 
303  amxc_var_add(cstring_t, lib_dirs, "../test_plugin/");
304  amxc_var_dump(&parser.config, STDOUT_FILENO);
305 
306  assert_int_equal(amxo_parser_parse_file(&parser, "test_valid.odl", amxd_dm_get_root(&dm)), 0);
307  assert_int_equal(amxo_parser_get_status(&parser), amxd_status_ok);
308 
310  check_objects_exist(&dm);
314 
315  amxo_parser_clean(&parser);
316  amxd_dm_clean(&dm);
318 }
319 
320 void test_can_parse_empty_file(UNUSED void** state) {
321  amxd_dm_t dm;
322  amxo_parser_t parser;
323 
324  amxd_dm_init(&dm);
325  amxo_parser_init(&parser);
326 
327  assert_int_equal(amxo_parser_parse_file(&parser, "empty.odl", amxd_dm_get_root(&dm)), 0);
328  assert_int_equal(amxo_parser_get_status(&parser), amxd_status_ok);
329 
330  amxo_parser_clean(&parser);
331  amxd_dm_clean(&dm);
332 }
333 
334 
335 void test_can_parse_fd(UNUSED void** state) {
336  amxd_dm_t dm;
337  amxo_parser_t parser;
338  amxc_var_t* lib_dirs = NULL;
339  int fd = open("test_valid.odl", O_RDONLY);
340 
341  amxd_dm_init(&dm);
342  amxo_parser_init(&parser);
343 
344  lib_dirs = amxo_parser_get_config(&parser, "import-dirs");
345  amxc_var_add(cstring_t, lib_dirs, "../test_plugin/");
346  amxc_var_dump(&parser.config, STDOUT_FILENO);
347 
348  assert_int_equal(amxo_parser_parse_fd(&parser, fd, amxd_dm_get_root(&dm)), 0);
349  assert_int_equal(amxo_parser_get_status(&parser), amxd_status_ok);
350  close(fd);
351 
353  check_objects_exist(&dm);
356 
357  amxo_parser_clean(&parser);
358  amxd_dm_clean(&dm);
360 }
361 
362 void test_can_parse_string(UNUSED void** state) {
363  amxd_dm_t dm;
364  amxo_parser_t parser;
365 
366  amxd_dm_init(&dm);
367  amxo_parser_init(&parser);
368 
369  assert_int_equal(amxo_parser_parse_string(&parser, "%config {} %define{} %populate { } %config { }", amxd_dm_get_root(&dm)), 0);
370  assert_int_equal(amxo_parser_get_status(&parser), amxd_status_ok);
371  assert_int_equal(amxo_parser_parse_string(&parser, " ", amxd_dm_get_root(&dm)), 0);
372  assert_int_equal(amxo_parser_get_status(&parser), amxd_status_ok);
373 
374  amxo_parser_clean(&parser);
375  amxd_dm_clean(&dm);
376 }
377 
378 void test_duplicate_func_name(UNUSED void** state) {
379  amxd_dm_t dm;
380  amxo_parser_t parser;
381  const char* odl = "%define { object Test { void F1(); void F2(); void F1(); } }";
382 
383  amxd_dm_init(&dm);
384  amxo_parser_init(&parser);
385 
386  assert_int_equal(amxo_parser_parse_string(&parser, odl, amxd_dm_get_root(&dm)), 0);
387  assert_int_equal(amxo_parser_get_status(&parser), amxd_status_ok);
388 
389  amxo_parser_clean(&parser);
390  amxd_dm_clean(&dm);
391 }
392 
393 void test_object_has_event(UNUSED void** state) {
394  amxd_dm_t dm;
395  amxo_parser_t parser;
396  amxd_object_t* obj = NULL;
397  amxc_var_t events;
398  amxc_var_t* lib_dirs = NULL;
399 
400  amxd_dm_init(&dm);
401  amxo_parser_init(&parser);
402  amxc_var_init(&events);
403 
404  lib_dirs = amxo_parser_get_config(&parser, "import-dirs");
405  amxc_var_add(cstring_t, lib_dirs, "../test_plugin/");
406  amxc_var_dump(&parser.config, STDOUT_FILENO);
407 
408  assert_int_equal(amxo_parser_parse_file(&parser, "test_valid.odl", amxd_dm_get_root(&dm)), 0);
409  assert_int_equal(amxo_parser_get_status(&parser), amxd_status_ok);
410 
411  obj = amxd_dm_findf(&dm, "TestObjectRoot.TestObjectEvent.");
412  assert_non_null(obj);
413  assert_int_equal(amxd_object_describe_events(obj, &events, amxd_dm_access_protected), 0);
414  assert_non_null(GETP_ARG(&events, "0"));
415 
416  amxc_var_clean(&events);
417  amxo_parser_clean(&parser);
418  amxd_dm_clean(&dm);
419 }
Ambiorix ODL parser header file.
include test_include odl
Definition: test_valid.odl:66
amxc_var_t * amxo_parser_get_config(amxo_parser_t *parser, const char *path)
Gets a configuration option.
amxc_var_t * amxo_parser_claim_config(amxo_parser_t *parser, const char *path)
Gets or creates a configuration option.
int amxo_parser_parse_fd(amxo_parser_t *parser, int fd, amxd_object_t *object)
Parses an odl file.
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.
static amxd_status_t amxo_parser_get_status(amxo_parser_t *parser)
Get the status of the odl parser.
Definition: amxo.h:414
int amxo_parser_init(amxo_parser_t *parser)
Initializes a new odl parser instance.
void amxo_resolver_import_close_all(void)
Unloads all loaded shared objects.
The ODL parser structure.
Definition: amxo_types.h:245
amxc_var_t config
Definition: amxo_types.h:250
static amxc_var_t events
Definition: test_events.c:92
#define UNUSED
Definition: test_issue_48.c:84
void test_can_parse_string(UNUSED void **state)
void test_object_has_event(UNUSED void **state)
void test_duplicate_func_name(UNUSED void **state)
static void check_functions_exist(amxd_dm_t *dm)
void test_can_parse_empty_file(UNUSED void **state)
static void check_options_are_available(amxo_parser_t *parser)
void test_can_parse_odl_file_no_resolve(UNUSED void **state)
static void check_objects_exist(amxd_dm_t *dm)
static void check_parameters_exist(amxd_dm_t *dm)
void test_can_parse_odl_file(UNUSED void **state)
static void check_mib_extions_work(amxd_dm_t *dm)
void test_can_parse_fd(UNUSED void **state)