libamxd  6.4.1
Data Model Manager
test_amxd_transaction.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 
55 #include <stdlib.h>
56 #include <stdarg.h>
57 #include <stddef.h>
58 #include <string.h>
59 #include <setjmp.h>
60 #include <fcntl.h>
61 #include <unistd.h>
62 #include <signal.h>
63 #include <cmocka.h>
64 
65 #include <amxc/amxc.h>
66 #include <amxp/amxp_signal.h>
67 #include <amxp/amxp_slot.h>
68 
69 #include <amxd/amxd_common.h>
70 #include <amxd/amxd_dm.h>
71 #include <amxd/amxd_object.h>
72 #include <amxd/amxd_parameter.h>
73 #include <amxd/amxd_function.h>
74 #include <amxd/amxd_action.h>
75 #include <amxd/amxd_transaction.h>
76 
77 #include "test_amxd_transaction.h"
78 
79 #include <amxc/amxc_macros.h>
80 static amxd_dm_t dm;
81 
82 static char* validate = "VALIDATE";
83 static char* delinst = "DELINST";
84 static char* addinst = "ADDINST";
85 
87  amxd_param_t* const param,
88  amxd_action_t reason,
89  const amxc_var_t* const args,
90  amxc_var_t* const retval,
91  void* priv) {
92 
93  assert_int_equal(reason, action_object_validate);
94  assert_ptr_not_equal(object, NULL);
95  assert_ptr_equal(param, NULL);
96  assert_ptr_equal(args, NULL);
97  assert_ptr_equal(retval, NULL);
98  assert_ptr_equal(priv, validate);
99 
100  bool enabled = amxd_object_get_value(bool, object, "Enable", NULL);
101  uint32_t length = amxd_object_get_value(uint32_t, object, "Length", NULL);
102  char* text = amxd_object_get_value(cstring_t, object, "Text", NULL);
104 
105  if(enabled) {
106  if(text && (strlen(text) > length)) {
108  }
109  } else {
110  if(text && (strcmp(text, "INVALID") == 0)) {
112  }
113  }
114 
115  free(text);
116  return status;
117 }
118 
120  amxd_param_t* const param,
121  amxd_action_t reason,
122  const amxc_var_t* const args,
123  amxc_var_t* const retval,
124  void* priv) {
125  assert_int_equal(reason, action_object_del_inst);
126  assert_ptr_not_equal(object, NULL);
127  assert_int_equal(amxd_object_get_type(object), amxd_object_template);
128  assert_ptr_equal(param, NULL);
129  assert_ptr_not_equal(args, NULL);
130  assert_int_equal(amxc_var_type_of(args), AMXC_VAR_ID_HTABLE);
131  assert_ptr_not_equal(retval, NULL);
132  assert_ptr_equal(priv, delinst);
133 
134  uint32_t index = 0;
135  char* key = NULL;
136  amxc_var_t* temp = NULL;
137  amxd_object_t* inst = NULL;
138  bool sticky = false;
140 
141  temp = amxc_var_get_key(args, "index", AMXC_VAR_FLAG_DEFAULT);
142  index = amxc_var_is_null(temp) ? 0 : amxc_var_dyncast(uint32_t, temp);
143  temp = amxc_var_get_key(args, "name", AMXC_VAR_FLAG_DEFAULT);
144  key = amxc_var_is_null(temp) ? NULL : amxc_var_dyncast(cstring_t, temp);
145 
146  inst = amxd_object_get_instance(object, key, index);
147  if(inst == NULL) {
149  } else {
150  sticky = amxd_object_get_value(bool, inst, "Sticky", NULL);
151  if(sticky) {
153  }
154  }
155 
156  free(key);
157  return status;
158 }
159 
161  amxd_param_t* const param,
162  amxd_action_t reason,
163  const amxc_var_t* const args,
164  amxc_var_t* const retval,
165  void* priv) {
166  assert_int_equal(reason, action_object_add_inst);
167  assert_ptr_not_equal(object, NULL);
168  assert_int_equal(amxd_object_get_type(object), amxd_object_template);
169  assert_ptr_equal(param, NULL);
170  assert_ptr_not_equal(args, NULL);
171  assert_int_equal(amxc_var_type_of(args), AMXC_VAR_ID_HTABLE);
172  assert_ptr_not_equal(retval, NULL);
173  assert_ptr_equal(priv, addinst);
174 
175  char* key = NULL;
176  amxc_var_t* temp = NULL;
178 
179  temp = amxc_var_get_key(args, "name", AMXC_VAR_FLAG_DEFAULT);
180  key = amxc_var_is_null(temp) ? NULL : amxc_var_dyncast(cstring_t, temp);
181 
182  if((key != NULL) && (strcmp(key, "INVALID") == 0)) {
184  } else {
185  status = amxd_action_object_add_inst(object, param, reason, args, retval, NULL);
186  }
187 
188  free(key);
189  return status;
190 }
191 
192 void test_build_dm(void) {
193  amxd_object_t* object = NULL;
194  amxd_object_t* template = NULL;
195  amxd_param_t* param = NULL;
196 
197  assert_int_equal(amxd_dm_init(&dm), 0);
198 
199  assert_int_equal(amxd_object_new(&object, amxd_object_singleton, "Top1"), 0);
200  assert_int_equal(amxd_dm_add_root_object(&dm, object), 0);
201  assert_int_equal(amxd_param_new(&param, "Enable", AMXC_VAR_ID_BOOL), 0);
202  assert_int_equal(amxd_object_add_param(object, param), 0);
203  assert_int_equal(amxd_param_new(&param, "Length", AMXC_VAR_ID_UINT32), 0);
204  assert_int_equal(amxd_object_add_param(object, param), 0);
205  assert_int_equal(amxd_param_new(&param, "Text", AMXC_VAR_ID_CSTRING), 0);
206  assert_int_equal(amxd_object_add_param(object, param), 0);
207  assert_int_equal(amxd_param_new(&param, "ROText", AMXC_VAR_ID_CSTRING), 0);
208  assert_int_equal(amxd_param_set_attr(param, amxd_pattr_read_only, true), 0);
209  assert_int_equal(amxd_object_add_param(object, param), 0);
211 
212  assert_int_equal(amxd_object_new(&object, amxd_object_singleton, "Top2"), 0);
213  assert_int_equal(amxd_param_new(&param, "TextA", AMXC_VAR_ID_CSTRING), 0);
214  assert_int_equal(amxd_object_add_param(object, param), 0);
215  assert_int_equal(amxd_param_new(&param, "TextB", AMXC_VAR_ID_CSTRING), 0);
216  assert_int_equal(amxd_object_add_param(object, param), 0);
217  assert_int_equal(amxd_dm_add_root_object(&dm, object), 0);
218 
219  assert_int_equal(amxd_object_new(&template, amxd_object_template, "TObject"), 0);
220  assert_int_equal(amxd_object_add_object(object, template), 0);
221  assert_int_equal(amxd_param_new(&param, "Sticky", AMXC_VAR_ID_BOOL), 0);
222  assert_int_equal(amxd_object_add_param(template, param), 0);
223  assert_int_equal(amxd_param_new(&param, "Text", AMXC_VAR_ID_CSTRING), 0);
224  assert_int_equal(amxd_object_add_param(template, param), 0);
227  assert_int_equal(amxd_object_new(&object, amxd_object_singleton, "TChild"), 0);
228  assert_int_equal(amxd_object_add_object(template, object), 0);
229  assert_int_equal(amxd_param_new(&param, "Text", AMXC_VAR_ID_CSTRING), 0);
230  assert_int_equal(amxd_object_add_param(object, param), 0);
232  assert_int_equal(amxd_object_new(&object, amxd_object_template, "TemplateChild"), 0);
233  assert_int_equal(amxd_object_add_object(template, object), 0);
234 
235  assert_int_equal(amxd_object_new(&object, amxd_object_mib, "MObject"), 0);
236  assert_int_equal(amxd_param_new(&param, "Extra", AMXC_VAR_ID_BOOL), 0);
237  assert_int_equal(amxd_object_add_param(object, param), 0);
238  assert_int_equal(amxd_param_new(&param, "Number", AMXC_VAR_ID_CSTRING), 0);
239  assert_int_equal(amxd_object_add_param(object, param), 0);
240  assert_int_equal(amxd_dm_store_mib(&dm, object), 0);
241 }
242 
244  return &dm;
245 }
246 
247 void test_clean_dm(void) {
248  amxd_dm_clean(&dm);
249 }
250 
251 void test_amxd_transaction_new_delete(UNUSED void** state) {
252  amxd_trans_t* transaction = NULL;
253 
254  assert_int_equal(amxd_trans_new(&transaction), 0);
255  assert_ptr_not_equal(transaction, NULL);
256 
257  amxd_trans_delete(&transaction);
258  assert_ptr_equal(transaction, NULL);
259 
260  amxd_trans_delete(&transaction);
261  amxd_trans_delete(NULL);
262  assert_int_not_equal(amxd_trans_new(NULL), 0);
263 }
264 
265 void test_amxd_transaction_init_clean(UNUSED void** state) {
266  amxd_trans_t transaction;
267 
268  assert_int_equal(amxd_trans_init(&transaction), 0);
269  amxd_trans_clean(&transaction);
270 
271  amxd_trans_clean(NULL);
272  assert_int_not_equal(amxd_trans_init(NULL), 0);
273 }
274 
275 void test_amxd_transaction_add_action(UNUSED void** state) {
276  amxd_trans_t transaction;
277  amxd_object_t* inst = NULL;
278  amxd_object_t* obj = NULL;
279  test_build_dm();
280 
281  assert_int_equal(amxd_trans_init(&transaction), 0);
282  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top2.TObject"), 0);
283  assert_int_equal(amxd_trans_add_action(&transaction, action_object_add_inst, NULL), 0);
284  assert_int_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
285  amxd_trans_clean(&transaction);
286 
287  inst = amxd_dm_findf(test_get_dm(), "Top2.TObject.1");
288  assert_ptr_not_equal(inst, NULL);
289 
290  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top2.TObject"), 0);
291  assert_int_not_equal(amxd_trans_add_action(NULL, action_object_add_inst, NULL), 0);
292  assert_int_not_equal(amxd_trans_add_action(&transaction, action_object_read, NULL), 0);
293  assert_int_not_equal(amxd_trans_add_action(&transaction, action_object_validate, NULL), 0);
294  assert_int_not_equal(amxd_trans_add_action(&transaction, action_object_list, NULL), 0);
295  assert_int_not_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
296  amxd_trans_clean(&transaction);
297 
298  obj = amxd_dm_findf(test_get_dm(), "Top2.TObject");
299  assert_ptr_not_equal(obj, NULL);
300  assert_int_equal(amxd_object_get_instance_count(obj), 1);
301 
302  test_clean_dm();
303 }
304 
306  amxd_trans_t transaction;
307  amxd_object_t* inst = NULL;
308  amxd_object_t* obj = NULL;
309  amxc_var_t args;
310  test_build_dm();
311 
312  amxc_var_init(&args);
313  amxc_var_set_type(&args, AMXC_VAR_ID_HTABLE);
314 
315  assert_int_equal(amxd_trans_init(&transaction), 0);
316  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top2.TObject"), 0);
317  assert_int_equal(amxd_trans_add_action(&transaction, action_object_add_inst, NULL), 0);
318  assert_int_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
319  amxd_trans_clean(&transaction);
320 
321  inst = amxd_dm_findf(test_get_dm(), "Top2.TObject.1");
322  assert_ptr_not_equal(inst, NULL);
323 
324  amxc_var_add_key(int32_t, &args, "index", 1);
325  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top2.TObject"), 0);
326  assert_int_equal(amxd_trans_add_action(&transaction, action_object_del_inst, &args), 0);
327  assert_int_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
328  amxd_trans_clean(&transaction);
329 
330  obj = amxd_dm_findf(test_get_dm(), "Top2.TObject");
331  assert_ptr_not_equal(obj, NULL);
332  assert_int_equal(amxd_object_get_instance_count(obj), 0);
333 
334  test_clean_dm();
335  amxc_var_clean(&args);
336 }
337 
338 void test_amxd_transaction_select(UNUSED void** state) {
339  amxd_trans_t transaction;
340  amxd_object_t* obj = NULL;
341  test_build_dm();
342 
343  assert_int_equal(amxd_trans_init(&transaction), 0);
344  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top2.TObject"), 0);
345  assert_int_equal(amxd_trans_select_pathf(&transaction, ".^"), 0);
346  assert_int_equal(amxd_trans_select_pathf(&transaction, ".TObject"), 0);
347  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top1"), 0);
348  obj = amxd_dm_findf(test_get_dm(), "Top2.TObject");
349  assert_int_equal(amxd_trans_select_object(&transaction, obj), 0);
350  assert_int_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
351  amxd_trans_clean(&transaction);
352 
353  assert_int_not_equal(amxd_trans_select_pathf(NULL, "Top2.TObject"), 0);
354  assert_int_not_equal(amxd_trans_select_object(NULL, obj), 0);
355  assert_int_not_equal(amxd_trans_select_pathf(&transaction, NULL), 0);
356  assert_int_not_equal(amxd_trans_select_pathf(&transaction, "%s", ""), 0);
357  assert_int_not_equal(amxd_trans_select_object(&transaction, NULL), 0);
358  assert_int_not_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
359  amxd_trans_clean(&transaction);
360 
361  test_clean_dm();
362 }
363 
364 void test_amxd_transaction_set_param(UNUSED void** state) {
365  amxd_trans_t transaction;
366  amxd_object_t* obj = NULL;
367  char* text = NULL;
369 
370  test_build_dm();
371 
372  assert_int_equal(amxd_trans_init(&transaction), 0);
373  assert_int_equal(amxd_trans_set_attr(&transaction, amxd_tattr_change_ro, true), 0);
374  assert_int_equal(amxd_trans_set_attr(&transaction, amxd_tattr_change_pub, true), 0);
375  assert_int_equal(amxd_trans_set_attr(&transaction, amxd_tattr_change_pub, false), 0);
376  assert_int_equal(amxd_trans_set_attr(&transaction, amxd_tattr_change_prot, true), 0);
377  assert_int_equal(amxd_trans_set_attr(&transaction, amxd_tattr_change_prot, false), 0);
378  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top1"), 0);
379  assert_int_equal(amxd_trans_set_value(cstring_t, &transaction, "Text", "Hello world"), 0);
380  assert_int_equal(amxd_trans_set_value(bool, &transaction, "Enable", true), 0);
381  assert_int_equal(amxd_trans_set_value(int32_t, &transaction, "Length", 64), 0);
382  assert_int_equal(amxd_trans_set_value(cstring_t, &transaction, "ROText", "Hello world"), 0);
383  amxd_trans_dump(&transaction, STDOUT_FILENO, false);
384  assert_int_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
385  amxd_trans_clean(&transaction);
386 
387  obj = amxd_dm_findf(test_get_dm(), "Top1");
388  text = amxd_object_get_value(cstring_t, obj, "Text", &status);
389  assert_int_equal(status, amxd_status_ok);
390  assert_ptr_not_equal(text, NULL);
391  assert_string_equal(text, "Hello world");
392  free(text);
393  assert_true(amxd_object_get_value(bool, obj, "Enable", &status));
394  assert_int_equal(status, amxd_status_ok);
395  assert_int_equal(amxd_object_get_value(uint32_t, obj, "Length", &status), 64);
396  assert_int_equal(status, amxd_status_ok);
397  text = amxd_object_get_value(cstring_t, obj, "ROText", &status);
398  assert_int_equal(status, amxd_status_ok);
399  assert_ptr_not_equal(text, NULL);
400  assert_string_equal(text, "Hello world");
401  free(text);
402 
403  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top1"), 0);
404  assert_int_not_equal(amxd_trans_set_value(cstring_t, NULL, "Text", "Hello world"), 0);
405  assert_int_not_equal(amxd_trans_set_value(cstring_t, &transaction, NULL, "Hello world"), 0);
406  assert_int_not_equal(amxd_trans_set_value(cstring_t, &transaction, "", "Hello world"), 0);
407  assert_int_not_equal(amxd_trans_set_param(&transaction, "Text", NULL), 0);
408  assert_int_not_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
409  amxd_trans_clean(&transaction);
410 
411  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top1"), 0);
412  assert_int_equal(amxd_trans_set_value(cstring_t, &transaction, "Text", "Hello Universe"), 0);
413  assert_int_equal(amxd_trans_set_value(int32_t, &transaction, "Length", 5), 0);
414  assert_int_not_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
415  amxd_trans_clean(&transaction);
416 
417  text = amxd_object_get_value(cstring_t, obj, "Text", &status);
418  assert_int_equal(status, amxd_status_ok);
419  assert_ptr_not_equal(text, NULL);
420  assert_string_equal(text, "Hello world");
421  assert_true(amxd_object_get_value(bool, obj, "Enable", &status));
422  assert_int_equal(status, amxd_status_ok);
423  assert_int_equal(amxd_object_get_value(uint32_t, obj, "Length", &status), 64);
424  assert_int_equal(status, amxd_status_ok);
425  free(text);
426 
427  test_clean_dm();
428 }
429 
430 void test_amxd_transaction_add_inst(UNUSED void** state) {
431  amxd_trans_t transaction;
432  amxd_object_t* obj = NULL;
433  char* text = NULL;
435 
436  test_build_dm();
437 
438  assert_int_equal(amxd_trans_init(&transaction), 0);
439  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top2.TObject"), 0);
440  assert_int_equal(amxd_trans_add_inst(&transaction, 99, "Inst1"), 0);
441  amxd_trans_set_value(cstring_t, &transaction, "Text", "InInst1");
442  assert_int_equal(amxd_trans_select_pathf(&transaction, ".^"), 0);
443  assert_int_equal(amxd_trans_add_inst(&transaction, 100, "Inst2"), 0);
444  amxd_trans_set_value(cstring_t, &transaction, "Text", "InInst2");
445 
446  amxd_trans_dump(&transaction, STDOUT_FILENO, false);
447  assert_int_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
448 
449  amxd_trans_clean(&transaction);
450 
451  obj = amxd_dm_findf(test_get_dm(), "Top2.TObject");
452  assert_int_equal(amxd_object_get_instance_count(obj), 2);
453 
454  obj = amxd_dm_findf(test_get_dm(), "Top2.TObject.Inst1");
455  assert_ptr_not_equal(obj, NULL);
456  text = amxd_object_get_value(cstring_t, obj, "Text", &status);
457  assert_int_equal(status, amxd_status_ok);
458  assert_ptr_not_equal(text, NULL);
459  assert_string_equal(text, "InInst1");
460  free(text);
461 
462  obj = amxd_dm_findf(test_get_dm(), "Top2.TObject.100");
463  assert_ptr_not_equal(obj, NULL);
464  text = amxd_object_get_value(cstring_t, obj, "Text", &status);
465  assert_int_equal(status, amxd_status_ok);
466  assert_ptr_not_equal(text, NULL);
467  assert_string_equal(text, "InInst2");
468  free(text);
469 
470  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top2.TObject.100"), 0);
471  amxd_trans_set_value(cstring_t, &transaction, "Text", "Changed");
472  assert_int_equal(amxd_trans_select_pathf(&transaction, ".^"), 0);
473  assert_int_equal(amxd_trans_add_inst(&transaction, 0, "INVALID"), 0);
474  amxd_trans_set_value(cstring_t, &transaction, "Text", "Test");
475 
476  amxd_trans_dump(&transaction, STDOUT_FILENO, false);
477  assert_int_not_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
478  amxd_trans_clean(&transaction);
479 
480  obj = amxd_dm_findf(test_get_dm(), "Top2.TObject.100");
481  assert_ptr_not_equal(obj, NULL);
482  text = amxd_object_get_value(cstring_t, obj, "Text", &status);
483  assert_int_equal(status, amxd_status_ok);
484  assert_ptr_not_equal(text, NULL);
485  assert_string_equal(text, "InInst2");
486  free(text);
487 
488  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top2.TObject"), 0);
489  assert_int_equal(amxd_trans_add_inst(&transaction, 101, NULL), 0);
490  assert_int_equal(amxd_trans_select_pathf(&transaction, ".^"), 0);
491  assert_int_equal(amxd_trans_add_inst(&transaction, 0, NULL), 0);
492  assert_int_equal(amxd_trans_select_pathf(&transaction, ".TChild"), 0);
493  amxd_trans_set_value(cstring_t, &transaction, "Text", "INVALID");
494 
495  amxd_trans_dump(&transaction, STDOUT_FILENO, false);
496  assert_int_not_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
497  amxd_trans_clean(&transaction);
498 
499  obj = amxd_dm_findf(test_get_dm(), "Top2.TObject");
500  assert_int_equal(amxd_object_get_instance_count(obj), 2);
501  obj = amxd_dm_findf(test_get_dm(), "Top2.TObject.101");
502  assert_ptr_equal(obj, NULL);
503 
504  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top2.TObject.100"), 0);
505  assert_int_not_equal(amxd_trans_add_inst(NULL, 0, "Name"), 0);
506  assert_int_equal(amxd_trans_add_inst(&transaction, 0, NULL), 0);
507  amxd_trans_clean(&transaction);
508 
509  test_clean_dm();
510 }
511 
512 void test_amxd_transaction_del_inst(UNUSED void** state) {
513  amxd_trans_t transaction;
514  amxd_object_t* obj = NULL;
515  char* text = NULL;
517 
518  test_build_dm();
519 
520  assert_int_equal(amxd_trans_init(&transaction), 0);
521  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top1"), 0);
522  amxd_trans_set_value(cstring_t, &transaction, "Text", "AcraCadabra");
523  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top2.TObject"), 0);
524  assert_int_equal(amxd_trans_add_inst(&transaction, 99, "Inst1"), 0);
525  amxd_trans_set_value(cstring_t, &transaction, "Text", "InInst1");
526  amxd_trans_set_value(bool, &transaction, "Sticky", true);
527  assert_int_equal(amxd_trans_select_pathf(&transaction, ".^"), 0);
528  assert_int_equal(amxd_trans_add_inst(&transaction, 100, "Inst2"), 0);
529  amxd_trans_set_value(cstring_t, &transaction, "Text", "InInst2");
530  assert_int_equal(amxd_trans_select_pathf(&transaction, ".TemplateChild"), 0);
531  assert_int_equal(amxd_trans_add_inst(&transaction, 1, NULL), 0);
532 
533  amxd_trans_dump(&transaction, STDOUT_FILENO, false);
534  assert_int_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
535  amxd_trans_clean(&transaction);
536 
537  obj = amxd_dm_findf(test_get_dm(), "Top2.TObject");
538  assert_int_equal(amxd_object_get_instance_count(obj), 2);
539  obj = amxd_dm_findf(test_get_dm(), "Top2.TObject.99");
540  assert_true(amxd_object_get_value(bool, obj, "Sticky", NULL));
541  assert_ptr_equal(amxd_dm_findf(test_get_dm(), "Top2.TObject.Inst1"), obj);
542 
543  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top1"), 0);
544  amxd_trans_set_value(cstring_t, &transaction, "Text", "Hello World");
545  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top2.TObject.100.TemplateChild."), 0);
546  assert_int_equal(amxd_trans_del_inst(&transaction, 1, NULL), 0);
547  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top2.TObject"), 0);
548  assert_int_equal(amxd_trans_del_inst(&transaction, 0, "Inst1"), 0);
549  assert_int_equal(amxd_trans_del_inst(&transaction, 100, NULL), 0);
550  assert_int_equal(amxd_trans_del_inst(&transaction, 100, NULL), 0);
551  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top2.TObject.100.TemplateChild."), 0);
552  assert_int_equal(amxd_trans_del_inst(&transaction, 1, NULL), 0);
553 
554  amxd_trans_dump(&transaction, STDOUT_FILENO, false);
555  assert_int_not_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
556  amxd_trans_clean(&transaction);
557 
558  obj = amxd_dm_findf(test_get_dm(), "Top2.TObject");
559  assert_int_equal(amxd_object_get_instance_count(obj), 2);
560 
561  obj = amxd_dm_findf(test_get_dm(), "Top1");
562  text = amxd_object_get_value(cstring_t, obj, "Text", &status);
563  assert_string_equal(text, "AcraCadabra");
564  free(text);
565 
566  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top2.TObject"), 0);
567  assert_int_not_equal(amxd_trans_del_inst(NULL, 99, NULL), 0);
568  assert_int_not_equal(amxd_trans_del_inst(&transaction, 0, NULL), 0);
569  amxd_trans_clean(&transaction);
570 
571  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top1"), 0);
572  amxd_trans_set_value(cstring_t, &transaction, "Text", "Hello World");
573  assert_int_equal(amxd_trans_select_pathf(&transaction, "Top2.TObject.Inst1"), 0);
574  amxd_trans_set_value(bool, &transaction, "Sticky", false);
575  assert_int_equal(amxd_trans_select_pathf(&transaction, ".^"), 0);
576  assert_int_equal(amxd_trans_del_inst(&transaction, 99, NULL), 0);
577  assert_int_equal(amxd_trans_del_inst(&transaction, 0, "Inst2"), 0);
578  amxd_trans_dump(&transaction, STDOUT_FILENO, false);
579  assert_int_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
580  amxd_trans_clean(&transaction);
581 
582  obj = amxd_dm_findf(test_get_dm(), "Top2.TObject");
583  assert_int_equal(amxd_object_get_instance_count(obj), 0);
584 
585  obj = amxd_dm_findf(test_get_dm(), "Top1");
586  text = amxd_object_get_value(cstring_t, obj, "Text", &status);
587  assert_string_equal(text, "Hello World");
588  free(text);
589 
590  test_clean_dm();
591 }
592 
593 void test_amxd_transaction_apply(UNUSED void** state) {
594  amxd_trans_t transaction;
595  amxd_object_t* inst = NULL;
596  amxd_object_t* obj = NULL;
598  char* text = NULL;
599  test_build_dm();
600 
601  assert_int_equal(amxd_trans_init(&transaction), 0);
602  amxd_trans_select_pathf(&transaction, "Top1");
603  amxd_trans_set_value(cstring_t, &transaction, "Text", "Hello world");
604  amxd_trans_set_value(cstring_t, &transaction, "Length", "1234");
605  amxd_trans_select_pathf(&transaction, "Top2.TObject");
606  amxd_trans_add_inst(&transaction, 1, "TestInst");
607  amxd_trans_set_value(cstring_t, &transaction, "Text", "Hi");
608  amxd_trans_select_pathf(&transaction, ".^");
609  amxd_trans_add_inst(&transaction, 0, NULL);
610  amxd_trans_set_value(cstring_t, &transaction, "Text", "Hi Back");
611  amxd_trans_select_pathf(&transaction, ".TChild");
612  amxd_trans_set_value(cstring_t, &transaction, "Text", "Sub Hi");
613  amxd_trans_select_pathf(&transaction, ".^.^");
614  amxd_trans_add_inst(&transaction, 0, NULL);
615  amxd_trans_set_value(cstring_t, &transaction, "Text", "Hi Back Again");
616  amxd_trans_set_value(cstring_t, &transaction, "TChild.Text", "Sub Hi Again");
617 
618  amxd_trans_dump(&transaction, STDOUT_FILENO, false);
619  assert_int_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
620 
621  amxd_trans_clean(&transaction);
622 
623  obj = amxd_dm_findf(test_get_dm(), "Top2.TObject");
624  assert_int_equal(amxd_object_get_instance_count(obj), 3);
625 
626  inst = amxd_dm_findf(test_get_dm(), "Top2.TObject.1");
627  assert_ptr_not_equal(inst, NULL);
628  text = amxd_object_get_value(cstring_t, inst, "Text", &status);
629  assert_int_equal(status, amxd_status_ok);
630  assert_ptr_not_equal(text, NULL);
631  assert_string_equal(text, "Hi");
632  free(text);
633 
634  inst = amxd_dm_findf(test_get_dm(), "Top2.TObject.2");
635  assert_ptr_not_equal(inst, NULL);
636  text = amxd_object_get_value(cstring_t, inst, "Text", &status);
637  assert_int_equal(status, amxd_status_ok);
638  assert_ptr_not_equal(text, NULL);
639  assert_string_equal(text, "Hi Back");
640  free(text);
641 
642  obj = amxd_object_get_child(inst, "TChild");
643  assert_ptr_not_equal(obj, NULL);
644  text = amxd_object_get_value(cstring_t, obj, "Text", &status);
645  assert_int_equal(status, amxd_status_ok);
646  assert_ptr_not_equal(text, NULL);
647  assert_string_equal(text, "Sub Hi");
648  free(text);
649 
650  amxd_trans_select_pathf(&transaction, "Top2.TObject");
651  amxd_trans_del_inst(&transaction, 0, "TestInst");
652  amxd_trans_select_pathf(&transaction, ".2");
653  amxd_trans_set_value(cstring_t, &transaction, "Text", "Yahoo");
654  amxd_trans_dump(&transaction, STDOUT_FILENO, false);
655  amxd_trans_dump(&transaction, STDOUT_FILENO, true);
656  assert_int_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
657  amxd_trans_clean(&transaction);
658 
659  obj = amxd_dm_findf(test_get_dm(), "Top2.TObject");
660  assert_int_equal(amxd_object_get_instance_count(obj), 2);
661  inst = amxd_dm_findf(test_get_dm(), "Top2.TObject.2");
662  assert_ptr_not_equal(inst, NULL);
663  text = amxd_object_get_value(cstring_t, inst, "Text", &status);
664  assert_int_equal(status, amxd_status_ok);
665  assert_ptr_not_equal(text, NULL);
666  assert_string_equal(text, "Yahoo");
667  free(text);
668 
669  assert_int_not_equal(amxd_trans_apply(NULL, test_get_dm()), 0);
670  assert_int_not_equal(amxd_trans_apply(&transaction, NULL), 0);
671 
672  test_clean_dm();
673 }
674 
675 void test_amxd_transaction_on_null_object(UNUSED void** state) {
676  amxd_trans_t transaction;
677  amxc_var_t var;
678 
679  amxc_var_init(&var);
680  amxc_var_set(cstring_t, &var, "Hello");
681 
682  test_build_dm();
683 
684  assert_int_equal(amxd_trans_init(&transaction), 0);
685  amxd_trans_select_object(&transaction, NULL);
686  amxd_trans_set_param(&transaction, "ExternalIPAddress", &var);
687  assert_int_not_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
688  amxd_trans_clean(&transaction);
689 
690  assert_int_equal(amxd_trans_init(&transaction), 0);
691  amxd_trans_set_param(&transaction, "ExternalIPAddress", &var);
692  assert_int_not_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
693  amxd_trans_clean(&transaction);
694 
695  test_clean_dm();
696 
697  amxc_var_clean(&var);
698 }
699 
700 void test_amxd_transaction_can_add_mib(UNUSED void** state) {
701  amxd_trans_t transaction;
702 
703  test_build_dm();
704 
705  assert_int_equal(amxd_trans_init(&transaction), 0);
706  amxd_trans_select_pathf(&transaction, "Top2.TObject");
707  amxd_trans_add_mib(&transaction, "MObject");
708  assert_int_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
709  amxd_trans_clean(&transaction);
710 
711  test_clean_dm();
712 }
713 
714 static void test_check_changed_event(UNUSED const char* const sig_name,
715  const amxc_var_t* const data,
716  UNUSED void* const priv) {
717  amxd_dm_t* dm = test_get_dm();
718  const char* path = NULL;
719  amxd_object_t* object = NULL;
720  amxc_var_dump(data, STDOUT_FILENO);
721 
722  assert_string_equal(GET_CHAR(data, "path"), "Top2.");
723  assert_non_null(GETP_ARG(data, "parameters.TextA"));
724  assert_non_null(GETP_ARG(data, "parameters.TextB"));
725 
726  path = amxd_dm_signal_get_path(dm, data);
727  assert_string_equal(path, "Top2.");
728 
729  amxd_dm_signal_get_path(NULL, data);
731 
732  object = amxd_dm_signal_get_object(dm, data);
733  assert_non_null(object);
734 
735  amxd_dm_signal_get_object(NULL, data);
737 }
738 
739 void test_amxd_transaction_changed_event(UNUSED void** state) {
740  amxd_trans_t transaction;
741  amxd_dm_t* dm = NULL;
742 
743  test_build_dm();
744 
745  dm = test_get_dm();
746  while(amxp_signal_read() == 0) {
747  }
748 
749  assert_int_equal(amxp_slot_connect(&dm->sigmngr,
750  "dm:object-changed",
751  NULL,
753  NULL), 0);
754  assert_int_equal(amxd_trans_init(&transaction), 0);
755  amxd_trans_select_pathf(&transaction, "Top2.");
756  amxd_trans_set_value(cstring_t, &transaction, "TextA", "Test1");
757  amxd_trans_select_pathf(&transaction, ".TObject.");
758  amxd_trans_add_inst(&transaction, 0, NULL);
759  amxd_trans_set_value(cstring_t, &transaction, "Text", "Test");
760  amxd_trans_select_pathf(&transaction, ".^.^.");
761  amxd_trans_set_value(cstring_t, &transaction, "TextB", "Test2");
762 
763  assert_int_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
764 
765  amxd_trans_clean(&transaction);
766 
767  while(amxp_signal_read() == 0) {
768  }
769 
770  test_clean_dm();
771 }
772 
773 void test_amxd_transaction_revert(UNUSED void** state) {
774  amxd_trans_t transaction;
775  amxd_dm_t* dm = NULL;
776  amxd_object_t* object = NULL;
777  amxc_var_t value;
778 
779  test_build_dm();
780  amxc_var_init(&value);
781 
782  dm = test_get_dm();
783  while(amxp_signal_read() == 0) {
784  }
785 
786  assert_int_equal(amxd_trans_init(&transaction), 0);
787  amxd_trans_select_pathf(&transaction, "Top2.");
788  amxd_trans_set_value(cstring_t, &transaction, "TextA", "Test1");
789  amxd_trans_select_pathf(&transaction, ".TObject.");
790  amxd_trans_add_inst(&transaction, 0, NULL);
791  amxd_trans_set_value(cstring_t, &transaction, "Text", "Test");
792  amxd_trans_select_pathf(&transaction, ".^.^.");
793  amxd_trans_set_value(cstring_t, &transaction, "TextB", "Test2");
794 
795  assert_int_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
796 
797  amxd_trans_clean(&transaction);
798 
799  while(amxp_signal_read() == 0) {
800  }
801 
802  assert_int_equal(amxd_trans_init(&transaction), 0);
803  amxd_trans_select_pathf(&transaction, "Top2.");
804  amxd_trans_set_value(cstring_t, &transaction, "TextA", "Test10");
805  amxd_trans_select_pathf(&transaction, ".TObject.");
806  amxd_trans_add_inst(&transaction, 0, NULL);
807  amxd_trans_set_value(cstring_t, &transaction, "Text", "Test10");
808  amxd_trans_select_pathf(&transaction, ".^.^.");
809  amxd_trans_set_value(cstring_t, &transaction, "ERROR", "Test2");
810 
811  assert_int_not_equal(amxd_trans_apply(&transaction, test_get_dm()), 0);
812 
813  object = amxd_dm_findf(dm, "Top2.");
814  amxd_object_get_param(object, "TextA", &value);
815  assert_string_equal(GET_CHAR(&value, NULL), "Test1");
816 
817  amxd_trans_clean(&transaction);
818 
819  amxc_var_clean(&value);
820  test_clean_dm();
821 }
Ambiorix Data Model Default actions header file.
amxd_status_t amxd_action_object_add_inst(amxd_object_t *const object, amxd_param_t *const param, amxd_action_t reason, const amxc_var_t *const args, amxc_var_t *const retval, void *priv)
Ambiorix Data Model API header file.
amxd_status_t amxd_dm_store_mib(amxd_dm_t *const dm, amxd_object_t *const object)
Definition: amxd_dm.c:378
amxd_object_t * amxd_dm_findf(amxd_dm_t *const dm, const char *abs_path,...) __attribute__((format(printf
Ambiorix Data Model RPC methods API header file.
Ambiorix Data Model API header file.
amxd_status_t amxd_object_add_action_cb(amxd_object_t *const object, const amxd_action_t reason, amxd_action_fn_t fn, void *priv)
static uint32_t amxd_object_get_instance_count(const amxd_object_t *object)
amxd_status_t amxd_param_new(amxd_param_t **param, const char *name, const uint32_t type)
amxd_status_t amxd_param_set_attr(amxd_param_t *param, const amxd_pattr_id_t attr, const bool enable)
Ambiorix Data Model API header file.
amxd_status_t amxd_trans_add_mib(amxd_trans_t *const trans, const char *mib_name)
@ amxd_pattr_read_only
Definition: amxd_types.h:358
@ action_object_add_inst
Definition: amxd_types.h:123
@ action_object_del_inst
Definition: amxd_types.h:124
@ action_object_read
Definition: amxd_types.h:117
@ action_object_list
Definition: amxd_types.h:120
@ action_object_validate
Definition: amxd_types.h:119
enum _amxd_action amxd_action_t
enum _amxd_status amxd_status_t
@ amxd_status_invalid_name
Definition: amxd_types.h:86
@ amxd_status_object_not_found
Definition: amxd_types.h:80
@ amxd_status_ok
Definition: amxd_types.h:78
@ amxd_status_invalid_value
Definition: amxd_types.h:88
@ amxd_status_invalid_action
Definition: amxd_types.h:89
@ amxd_object_template
Definition: amxd_types.h:183
@ amxd_object_mib
Definition: amxd_types.h:188
@ amxd_object_singleton
Definition: amxd_types.h:181
amxd_object_t amxd_status_t amxd_status_t const char * amxd_dm_signal_get_path(amxd_dm_t *const dm, const amxc_var_t *const signal_data)
Get the object path from a data model signal.
Definition: amxd_dm.c:560
amxd_status_t amxd_dm_add_root_object(amxd_dm_t *const dm, amxd_object_t *const object)
Adds an object to the root of the data model.
Definition: amxd_dm.c:418
amxd_object_t * amxd_dm_signal_get_object(amxd_dm_t *const dm, const amxc_var_t *const signal_data)
Get the object from a data model using the path in the recieved signal.
Definition: amxd_dm.c:573
amxd_status_t amxd_dm_init(amxd_dm_t *dm)
Initializes a data model structure.
Definition: amxd_dm.c:334
void amxd_dm_clean(amxd_dm_t *dm)
Cleans a data model structure.
Definition: amxd_dm.c:365
amxd_object_t * amxd_object_get_child(const amxd_object_t *object, const char *name)
Get a child of the object.
amxd_status_t amxd_object_add_object(amxd_object_t *const parent, amxd_object_t *const child)
Adds an object in the data model tree.
Definition: amxd_object.c:207
amxd_object_t * amxd_object_get_instance(const amxd_object_t *object, const char *name, uint32_t index)
Get an instance of the template object.
#define amxd_object_get_value(type, object, name, status)
Helper macro for getting a value.
amxd_status_t amxd_object_get_param(amxd_object_t *const object, const char *name, amxc_var_t *const value)
Gets a single parameter value.
amxd_status_t amxd_object_add_param(amxd_object_t *const object, amxd_param_t *const param)
Adds a parameter definition to an object.
amxd_status_t amxd_object_new(amxd_object_t **object, const amxd_object_type_t type, const char *name)
Data model object constructor function.
Definition: amxd_object.c:185
static amxd_object_type_t amxd_object_get_type(const amxd_object_t *const object)
Returns the object type.
Definition: amxd_object.h:586
amxd_status_t amxd_trans_new(amxd_trans_t **trans)
Allocates a transaction object on the heap and initializes it.
amxd_status_t amxd_trans_add_action(amxd_trans_t *const trans, const amxd_action_t reason, const amxc_var_t *data)
Adds an action to a transaction.
void amxd_trans_dump(const amxd_trans_t *const trans, const int fd, const bool reverse)
Dumps the transaction to a file descriptor.
amxd_status_t amxd_trans_set_attr(amxd_trans_t *trans, amxd_tattr_id_t attr, bool enable)
Set the transaction attributes.
void amxd_trans_clean(amxd_trans_t *const trans)
Cleans the transaction object.
amxd_status_t amxd_trans_apply(amxd_trans_t *const trans, amxd_dm_t *const dm)
Applies all previously added actions.
#define amxd_trans_set_value(type, trans, name, value)
Helper macro for setting a value.
amxd_status_t amxd_trans_add_inst(amxd_trans_t *const trans, const uint32_t index, const char *name)
Adds an instance add action to a transaction.
void amxd_trans_delete(amxd_trans_t **trans)
Frees the memory previously allocated for a transaction object.
amxd_status_t amxd_trans_del_inst(amxd_trans_t *const trans, const uint32_t index, const char *name)
Adds an instance delete action to a transaction.
amxd_status_t amxd_trans_select_pathf(amxd_trans_t *const trans, const char *path,...) __attribute__((format(printf
Selects an object using a absolute or relative path.
amxd_status_t amxd_status_t amxd_trans_select_object(amxd_trans_t *trans, const amxd_object_t *const object)
Selects an object using an object pointer.
amxd_status_t amxd_trans_set_param(amxd_trans_t *const trans, const char *param_name, amxc_var_t *const value)
Adds a set value action to a transaction.
amxd_status_t amxd_trans_init(amxd_trans_t *const trans)
Initializes a transaction object.
@ amxd_tattr_change_prot
@ amxd_tattr_change_ro
@ amxd_tattr_change_pub
amxp_signal_mngr_t sigmngr
Definition: amxd_types.h:261
static amxd_status_t status
void test_amxd_transaction_new_delete(UNUSED void **state)
void test_amxd_transaction_on_null_object(UNUSED void **state)
static amxd_status_t amxd_action_test_validate(amxd_object_t *const object, amxd_param_t *const param, amxd_action_t reason, const amxc_var_t *const args, amxc_var_t *const retval, void *priv)
void test_build_dm(void)
static amxd_status_t amxd_action_test_del_inst(amxd_object_t *const object, amxd_param_t *const param, amxd_action_t reason, const amxc_var_t *const args, amxc_var_t *const retval, void *priv)
static amxd_dm_t dm
static char * addinst
void test_amxd_transaction_select(UNUSED void **state)
static char * validate
amxd_dm_t * test_get_dm(void)
static void test_check_changed_event(UNUSED const char *const sig_name, const amxc_var_t *const data, UNUSED void *const priv)
void test_amxd_transaction_revert(UNUSED void **state)
void test_amxd_transaction_init_clean(UNUSED void **state)
void test_amxd_transaction_apply(UNUSED void **state)
void test_amxd_transaction_add_action(UNUSED void **state)
void test_amxd_transaction_del_inst(UNUSED void **state)
void test_amxd_transaction_set_param(UNUSED void **state)
void test_amxd_transaction_changed_event(UNUSED void **state)
static amxd_status_t amxd_action_test_add_inst(amxd_object_t *const object, amxd_param_t *const param, amxd_action_t reason, const amxc_var_t *const args, amxc_var_t *const retval, void *priv)
void test_clean_dm(void)
void test_amxd_transaction_can_add_mib(UNUSED void **state)
void test_amxd_transaction_add_inst(UNUSED void **state)
void test_amxd_transaction_add_action_signed_index(UNUSED void **state)
static char * delinst