libamxrt  0.4.2
Ambiorix Run Time Library
test_amxrt_save_load.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 <stdlib.h>
55 #include <stdio.h>
56 #include <setjmp.h>
57 #include <stdarg.h>
58 #include <cmocka.h>
59 #include <sys/stat.h>
60 
61 #include <amxrt/amxrt.h>
62 
63 #include "test_amxrt_save_load.h"
64 
65 #include <amxd/amxd_transaction.h>
66 
67 static int event_count;
68 
69 static void handle_events(void) {
70  printf("Handling events ");
71  while(amxp_signal_read() == 0) {
72  printf(".");
73  event_count++;
74  }
75  printf("\n");
76 }
77 
78 static void read_sigalrm(void) {
79  sigset_t mask;
80  int sfd;
81  struct signalfd_siginfo fdsi;
82  ssize_t s;
83 
84  sigemptyset(&mask);
85  sigaddset(&mask, SIGALRM);
86 
87  sigprocmask(SIG_BLOCK, &mask, NULL);
88 
89  sfd = signalfd(-1, &mask, 0);
90  s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
91  assert_int_equal(s, sizeof(struct signalfd_siginfo));
92  if(fdsi.ssi_signo == SIGALRM) {
93  printf("Got SIGALRM\n");
94  amxp_timers_calculate();
95  amxp_timers_check();
96  } else {
97  printf("Read unexpected signal\n");
98  }
99 }
100 
101 int test_save_load_setup(UNUSED void** state) {
102  amxc_var_t* odl = NULL;
103  amxc_var_t* config = NULL;
104  amxd_dm_t* dm = NULL;
105 
106  amxrt_new();
108  dm = amxrt_get_dm();
109  odl = amxc_var_add_key(amxc_htable_t, config, "odl", NULL);
110 
111  amxc_var_add_key(bool, odl, "dm-load", true);
112  amxc_var_add_key(bool, odl, "dm-save", true);
113  amxc_var_add_key(uint32_t, odl, "dm-save-init-delay", 1000);
114 
115  amxp_sigmngr_enable(&dm->sigmngr, true);
116 
117  return 0;
118 }
119 
120 int test_save_load_teardown(UNUSED void** state) {
121  amxrt_delete();
122  return 0;
123 }
124 
125 void test_can_start_with_no_storage_type(UNUSED void** state) {
126  amxc_var_t* config = amxrt_get_config();
127  amxo_parser_t* parser = amxrt_get_parser();
128  amxd_dm_t* dm = amxrt_get_dm();
129  amxc_var_t* storage = GET_ARG(config, "storage-type");
130  amxc_var_take_it(storage);
131 
132  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
133  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
134 
135  amxc_var_set_key(config, "storage-type", storage, AMXC_VAR_FLAG_DEFAULT);
136 }
137 
138 void test_can_start_with_no_odl_storage_type(UNUSED void** state) {
139  amxc_var_t* config = amxrt_get_config();
140  amxo_parser_t* parser = amxrt_get_parser();
141  amxd_dm_t* dm = amxrt_get_dm();
142  amxc_var_t* storage = GET_ARG(config, "storage-type");
143  amxc_var_set(cstring_t, storage, "uci");
144 
145  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
146  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
147 }
148 
149 void test_can_start_with_odl_storage_type(UNUSED void** state) {
150  amxc_var_t* config = amxrt_get_config();
151  amxo_parser_t* parser = amxrt_get_parser();
152  amxd_dm_t* dm = amxrt_get_dm();
153  amxc_var_t* storage = GET_ARG(config, "storage-type");
154  amxc_var_set(cstring_t, storage, "odl");
155 
156  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
157  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
158 }
159 
160 void test_can_start_with_no_storage_path(UNUSED void** state) {
161  amxc_var_t* config = amxrt_get_config();
162  amxo_parser_t* parser = amxrt_get_parser();
163  amxd_dm_t* dm = amxrt_get_dm();
164  amxc_var_t* storage = GET_ARG(config, "storage-path");
165  amxc_var_take_it(storage);
166 
167  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
168  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
169 
170  amxc_var_set_key(config, "storage-path", storage, AMXC_VAR_FLAG_DEFAULT);
171 }
172 
173 void test_can_start_with_directory_configured(UNUSED void** state) {
174  amxc_var_t* config = amxrt_get_config();
175  amxo_parser_t* parser = amxrt_get_parser();
176  amxd_dm_t* dm = amxrt_get_dm();
177 
178  amxc_var_t* odl = GET_ARG(config, "odl");
179  amxc_var_add_key(cstring_t, odl, "directory", "./odl");
180 
181  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
182  amxp_sigmngr_trigger_signal(&dm->sigmngr, "app:start", NULL);
183  handle_events();
184  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
185  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
186  amxd_dm_clean(dm);
187 }
188 
190  amxc_var_t* config = amxrt_get_config();
191  amxo_parser_t* parser = amxrt_get_parser();
192  amxd_dm_t* dm = amxrt_get_dm();
193 
194  amxc_var_t* odl = GET_ARG(config, "odl");
195  amxc_var_t* events = NULL;
196 
197  amxd_dm_init(dm);
198 
199  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
200  event_count = 0;
201  amxp_sigmngr_trigger_signal(&dm->sigmngr, "app:start", NULL);
202  handle_events();
203  assert_int_equal(event_count, 0);
204  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
205  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
206 
207  amxd_dm_clean(dm);
208  amxd_dm_init(dm);
209 
210  events = amxc_var_add_key(bool, odl, "load-dm-events", true);
211  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
212  event_count = 0;
213  amxp_sigmngr_trigger_signal(&dm->sigmngr, "app:start", NULL);
214  handle_events();
215  assert_int_not_equal(event_count, 0);
216  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
217  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
218 
219  amxc_var_delete(&events);
220  amxd_dm_clean(dm);
221 }
222 
224  amxc_var_t* config = amxrt_get_config();
225  amxo_parser_t* parser = amxrt_get_parser();
226  amxd_dm_t* dm = amxrt_get_dm();
227 
228  amxc_var_t* dir = GETP_ARG(config, "odl.directory");
229  amxc_var_set(cstring_t, dir, "./rubish");
230 
231  amxd_dm_init(dm);
232 
233  assert_int_not_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
234  assert_null(amxd_dm_findf(dm, "Test.Table"));
235  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
236  amxd_dm_clean(dm);
237 }
238 
239 void test_loads_default_when_valid_dir_is_used(UNUSED void** state) {
240  amxc_var_t* config = amxrt_get_config();
241  amxo_parser_t* parser = amxrt_get_parser();
242  amxd_dm_t* dm = amxrt_get_dm();
243 
244  amxc_var_t* odl = GET_ARG(config, "odl");
245  amxc_var_add_key(cstring_t, odl, "dm-defaults", "./defaults");
246 
247  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
248  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
249  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
250  amxd_dm_clean(dm);
251 }
252 
254  amxc_var_t* config = amxrt_get_config();
255  amxo_parser_t* parser = amxrt_get_parser();
256  amxd_dm_t* dm = amxrt_get_dm();
257 
258  amxc_var_t* dir = GETP_ARG(config, "odl.dm-defaults");
259  amxc_var_set(cstring_t, dir, "./rubish");
260 
261  amxd_dm_init(dm);
262 
263  assert_int_not_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
264  assert_null(amxd_dm_findf(dm, "Test.Table"));
265  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
266 }
267 
268 void test_can_save_all_objects(UNUSED void** state) {
269  amxc_var_t* config = amxrt_get_config();
270  amxo_parser_t* parser = amxrt_get_parser();
271  amxd_dm_t* dm = amxrt_get_dm();
272  struct stat statbuf;
273 
274  amxc_var_t* dir = GETP_ARG(config, "odl.dm-defaults");
275  amxc_var_t* save = GETP_ARG(config, "odl.dm-save");
276 
277  amxc_var_delete(&dir);
278 
279  dir = GETP_ARG(config, "odl.directory");
280  amxc_var_set(cstring_t, dir, "./odl");
281  amxc_var_add_key(cstring_t, config, "name", "save_test");
282 
283  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
284  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
285  assert_non_null(amxd_dm_findf(dm, "Test2"));
286  amxc_var_set(bool, save, true);
287  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
288 
289  assert_int_not_equal(stat("./odl/save_test.odl", &statbuf), -1);
290  unlink("./odl/save_test.odl");
291  amxd_dm_clean(dm);
292 }
293 
294 void test_save_fails_when_invalid_dir(UNUSED void** state) {
295  amxc_var_t* config = amxrt_get_config();
296  amxo_parser_t* parser = amxrt_get_parser();
297  amxd_dm_t* dm = amxrt_get_dm();
298  struct stat statbuf;
299  amxc_var_t* dir = GETP_ARG(config, "odl.directory");
300  amxc_var_set(cstring_t, dir, "./odl");
301 
302  amxd_dm_init(dm);
303 
304  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
305  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
306  assert_non_null(amxd_dm_findf(dm, "Test2"));
307  amxc_var_set(cstring_t, dir, "./rubish");
308  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
309 
310  assert_int_equal(stat("./odl/save_test.odl", &statbuf), -1);
311  amxc_var_set(cstring_t, dir, "./odl");
312  amxd_dm_clean(dm);
313 }
314 
315 void test_can_save_separate_objects_csv(UNUSED void** state) {
316  amxc_var_t* config = amxrt_get_config();
317  amxo_parser_t* parser = amxrt_get_parser();
318  amxd_dm_t* dm = amxrt_get_dm();
319 
320  struct stat statbuf;
321  amxc_var_t* odl = GET_ARG(config, "odl");
322  amxc_var_add_key(csv_string_t, odl, "dm-objects", "Test,Test2.");
323 
324  amxd_dm_init(dm);
325 
326  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
327  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
328  assert_non_null(amxd_dm_findf(dm, "Test2"));
329  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
330 
331 
332  assert_int_not_equal(stat("./odl/00_Test.odl", &statbuf), -1);
333  unlink("./odl/00_Test.odl");
334  assert_int_not_equal(stat("./odl/01_Test2.odl", &statbuf), -1);
335  unlink("./odl/01_Test2.odl");
336  amxd_dm_clean(dm);
337 }
338 
340  amxc_var_t* config = amxrt_get_config();
341  amxo_parser_t* parser = amxrt_get_parser();
342  amxd_dm_t* dm = amxrt_get_dm();
343 
344  struct stat statbuf;
345  amxc_var_t* dir = GETP_ARG(config, "odl.directory");
346  amxc_var_set(cstring_t, dir, "./odl");
347 
348  amxd_dm_init(dm);
349 
350  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
351  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
352  assert_non_null(amxd_dm_findf(dm, "Test2"));
353  amxc_var_set(cstring_t, dir, "./rubish");
354  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
355 
356  assert_int_equal(stat("./odl/00_Test.odl", &statbuf), -1);
357  assert_int_equal(stat("./odl/01_Test2.odl", &statbuf), -1);
358  amxc_var_set(cstring_t, dir, "./odl");
359  amxd_dm_clean(dm);
360 }
361 
362 void test_can_save_separate_objects_string(UNUSED void** state) {
363  amxc_var_t* config = amxrt_get_config();
364  amxo_parser_t* parser = amxrt_get_parser();
365  amxd_dm_t* dm = amxrt_get_dm();
366 
367  struct stat statbuf;
368  amxc_var_t* objects = GETP_ARG(config, "odl.dm-objects");
369  amxc_var_set(cstring_t, objects, "Test,Test2");
370 
371  amxd_dm_init(dm);
372 
373  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
374  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
375  assert_non_null(amxd_dm_findf(dm, "Test2"));
376  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
377 
378  assert_int_not_equal(stat("./odl/00_Test.odl", &statbuf), -1);
379  unlink("./odl/00_Test.odl");
380  assert_int_not_equal(stat("./odl/01_Test2.odl", &statbuf), -1);
381  unlink("./odl/01_Test2.odl");
382  amxd_dm_clean(dm);
383 }
384 
385 void test_does_not_save_when_invalid_objects(UNUSED void** state) {
386  amxc_var_t* config = amxrt_get_config();
387  amxo_parser_t* parser = amxrt_get_parser();
388  amxd_dm_t* dm = amxrt_get_dm();
389 
390  struct stat statbuf;
391  amxc_var_t* objects = GETP_ARG(config, "odl.dm-objects");
392  amxc_var_set(uint32_t, objects, 100);
393 
394  amxd_dm_init(dm);
395 
396  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
397  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
398  assert_non_null(amxd_dm_findf(dm, "Test2"));
399  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
400 
401  assert_int_equal(stat("./odl/00_Test.odl", &statbuf), -1);
402  assert_int_equal(stat("./odl/01_Test2.odl", &statbuf), -1);
403  amxd_dm_clean(dm);
404 }
405 
406 void test_save_skips_unknown_objects(UNUSED void** state) {
407  amxc_var_t* config = amxrt_get_config();
408  amxo_parser_t* parser = amxrt_get_parser();
409  amxd_dm_t* dm = amxrt_get_dm();
410 
411  struct stat statbuf;
412  amxc_var_t* objects = GETP_ARG(config, "odl.dm-objects");
413  amxc_var_set(csv_string_t, objects, "Test3, Test, Test4, Test2");
414 
415  amxd_dm_init(dm);
416 
417  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
418  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
419  assert_non_null(amxd_dm_findf(dm, "Test2"));
420  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
421 
422  assert_int_not_equal(stat("./odl/00_Test.odl", &statbuf), -1);
423  unlink("./odl/00_Test.odl");
424  assert_int_not_equal(stat("./odl/01_Test2.odl", &statbuf), -1);
425  unlink("./odl/01_Test2.odl");
426  assert_int_equal(stat("./odl/00_Test3.odl", &statbuf), -1);
427  assert_int_equal(stat("./odl/02_Test4.odl", &statbuf), -1);
428  amxd_dm_clean(dm);
429 }
430 
431 void test_can_save_on_changes(UNUSED void** state) {
432  amxc_var_t* config = amxrt_get_config();
433  amxo_parser_t* parser = amxrt_get_parser();
434  amxd_dm_t* dm = amxrt_get_dm();
435 
436  struct stat statbuf;
437  amxd_trans_t transaction;
438  amxc_var_t* odl = GET_ARG(config, "odl");
439  amxc_var_t* objects = GETP_ARG(config, "odl.dm-objects");
440  amxc_var_delete(&objects);
441  amxc_var_add_key(bool, odl, "dm-save-on-changed", true);
442 
443  amxd_dm_init(dm);
444 
445  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
446  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
447  assert_non_null(amxd_dm_findf(dm, "Test2"));
448  amxp_sigmngr_trigger_signal(&dm->sigmngr, "app:start", NULL);
449 
450  handle_events();
451 
452  amxd_trans_init(&transaction);
453  amxd_trans_select_pathf(&transaction, "Test.Table");
454  amxd_trans_add_inst(&transaction, 0, NULL);
455  amxd_trans_set_value(cstring_t, &transaction, "Text", "Hallo");
456  amxd_trans_apply(&transaction, dm);
457  amxd_trans_clean(&transaction);
458 
459  handle_events();
460  read_sigalrm();
461  handle_events();
462  assert_int_not_equal(stat("./odl/save_test.odl", &statbuf), -1);
463 
464  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
465 
466  unlink("./odl/save_test.odl");
467  amxd_dm_clean(dm);
468 }
469 
471  amxo_parser_t* parser = amxrt_get_parser();
472  amxd_dm_t* dm = amxrt_get_dm();
473 
474  struct stat statbuf;
475  amxd_trans_t transaction;
476 
477  amxd_dm_init(dm);
478 
479  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
480  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
481  assert_non_null(amxd_dm_findf(dm, "Test2"));
482  amxp_sigmngr_trigger_signal(&dm->sigmngr, "app:start", NULL);
483 
484  handle_events();
485 
486  amxd_trans_init(&transaction);
487  amxd_trans_select_pathf(&transaction, "Test.Table");
488  amxd_trans_add_inst(&transaction, 0, NULL);
489  amxd_trans_set_value(cstring_t, &transaction, "Text", "Hallo");
490  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
491  amxd_trans_clean(&transaction);
492 
493  handle_events();
494  read_sigalrm();
495  handle_events();
496  assert_int_not_equal(stat("./odl/save_test.odl", &statbuf), -1);
497  unlink("./odl/save_test.odl");
498 
499  amxd_trans_init(&transaction);
500  amxd_trans_select_pathf(&transaction, "Test.Table.1");
501  amxd_trans_set_value(cstring_t, &transaction, "Text", "World");
502  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
503  amxd_trans_clean(&transaction);
504 
505  handle_events();
506  read_sigalrm();
507  handle_events();
508  assert_int_not_equal(stat("./odl/save_test.odl", &statbuf), -1);
509 
510  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
511  unlink("./odl/save_test.odl");
512  amxd_dm_clean(dm);
513 }
514 
516  amxo_parser_t* parser = amxrt_get_parser();
517  amxd_dm_t* dm = amxrt_get_dm();
518 
519  struct stat statbuf;
520  amxd_trans_t transaction;
521 
522  amxd_dm_init(dm);
523 
524  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
525  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
526  assert_non_null(amxd_dm_findf(dm, "Test2"));
527  amxp_sigmngr_trigger_signal(&dm->sigmngr, "app:start", NULL);
528 
529  handle_events();
530 
531  amxd_trans_init(&transaction);
532  amxd_trans_select_pathf(&transaction, "Test.Table");
533  amxd_trans_add_inst(&transaction, 0, NULL);
534  amxd_trans_set_value(cstring_t, &transaction, "Text", "Hallo");
535  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
536  amxd_trans_clean(&transaction);
537 
538  handle_events();
539  read_sigalrm();
540  handle_events();
541  assert_int_not_equal(stat("./odl/save_test.odl", &statbuf), -1);
542  unlink("./odl/save_test.odl");
543 
544  amxd_trans_init(&transaction);
545  amxd_trans_select_pathf(&transaction, "Test.Table.1");
546  amxd_trans_set_value(uint32_t, &transaction, "Number", 999);
547  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
548  amxd_trans_clean(&transaction);
549 
550  handle_events();
551  sleep(1);
552  amxp_timers_calculate();
553  amxp_timers_check();
554  handle_events();
555  assert_int_equal(stat("./odl/save_test.odl", &statbuf), -1);
556 
557  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
558  unlink("./odl/save_test.odl");
559  amxd_dm_clean(dm);
560 }
561 
562 void test_saves_when_instance_deleted(UNUSED void** state) {
563  amxo_parser_t* parser = amxrt_get_parser();
564  amxd_dm_t* dm = amxrt_get_dm();
565  struct stat statbuf;
566  amxd_trans_t transaction;
567 
568  amxd_dm_init(dm);
569 
570  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
571  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
572  assert_non_null(amxd_dm_findf(dm, "Test2"));
573  amxp_sigmngr_trigger_signal(&dm->sigmngr, "app:start", NULL);
574 
575  handle_events();
576 
577  amxd_trans_init(&transaction);
578  amxd_trans_select_pathf(&transaction, "Test.Table");
579  amxd_trans_del_inst(&transaction, 1, NULL);
580  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
581  amxd_trans_clean(&transaction);
582 
583  handle_events();
584  read_sigalrm();
585  handle_events();
586  assert_int_not_equal(stat("./odl/save_test.odl", &statbuf), -1);
587 
588  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
589  unlink("./odl/save_test.odl");
590  amxd_dm_clean(dm);
591 }
592 
593 void test_can_save_on_changes_with_object_list(UNUSED void** state) {
594  amxc_var_t* config = amxrt_get_config();
595  amxo_parser_t* parser = amxrt_get_parser();
596  amxd_dm_t* dm = amxrt_get_dm();
597 
598  struct stat statbuf;
599  amxd_trans_t transaction;
600  amxc_var_t* odl = GET_ARG(config, "odl");
601  amxc_var_add_key(csv_string_t, odl, "dm-objects", "Test2");
602 
603  amxd_dm_init(dm);
604 
605  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
606  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
607  assert_non_null(amxd_dm_findf(dm, "Test2"));
608  amxp_sigmngr_trigger_signal(&dm->sigmngr, "app:start", NULL);
609 
610  handle_events();
611 
612  amxd_trans_init(&transaction);
613  amxd_trans_select_pathf(&transaction, "Test2");
614  amxd_trans_set_value(cstring_t, &transaction, "Text", "Hallo");
615  amxd_trans_select_pathf(&transaction, "Test.Table.");
616  amxd_trans_add_inst(&transaction, 0, NULL);
617  amxd_trans_set_value(cstring_t, &transaction, "Text", "Hallo");
618  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
619  amxd_trans_clean(&transaction);
620 
621  handle_events();
622 
623  amxd_trans_init(&transaction);
624  amxd_trans_select_pathf(&transaction, "Test2");
625  amxd_trans_set_value(cstring_t, &transaction, "Text", "World");
626  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
627  amxd_trans_clean(&transaction);
628 
629  handle_events();
630  read_sigalrm();
631  handle_events();
632  assert_int_not_equal(stat("./odl/00_Test2.odl", &statbuf), -1);
633  assert_int_equal(stat("./odl/02_Test.odl", &statbuf), -1);
634 
635  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
636 
637  unlink("./odl/00_Test2.odl");
638  amxd_dm_clean(dm);
639 }
640 
642  amxc_var_t* config = amxrt_get_config();
643  amxo_parser_t* parser = amxrt_get_parser();
644  amxd_dm_t* dm = amxrt_get_dm();
645 
646  struct stat statbuf;
647  amxd_trans_t transaction;
648  amxc_var_t* objects = GETP_ARG(config, "odl.dm-objects");
649  amxc_var_set(uint32_t, objects, 100);
650 
651  amxd_dm_init(dm);
652 
653  assert_int_equal(amxrt_dm_save_load_main(AMXO_START, dm, parser), 0);
654  assert_non_null(amxd_dm_findf(dm, "Test.Table"));
655  assert_non_null(amxd_dm_findf(dm, "Test2"));
656  amxp_sigmngr_trigger_signal(&dm->sigmngr, "app:start", NULL);
657 
658  amxd_trans_init(&transaction);
659  amxd_trans_select_pathf(&transaction, "Test2");
660  amxd_trans_set_value(cstring_t, &transaction, "Text", "Hallo");
661  amxd_trans_select_pathf(&transaction, "Test.Table.");
662  amxd_trans_add_inst(&transaction, 0, NULL);
663  amxd_trans_set_value(cstring_t, &transaction, "Text", "Hallo");
664  assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
665  amxd_trans_clean(&transaction);
666 
667  handle_events();
668  sleep(1);
669  amxp_timers_calculate();
670  amxp_timers_check();
671  handle_events();
672 
673  assert_int_equal(stat("./odl/save_test.odl", &statbuf), -1);
674  assert_int_equal(stat("./odl/Test2.odl", &statbuf), -1);
675  assert_int_equal(stat("./odl/Test2.odl", &statbuf), -1);
676 
677  assert_int_equal(amxrt_dm_save_load_main(AMXO_STOP, dm, parser), 0);
678 
679  amxd_dm_clean(dm);
680 }
static odl_storage_t storage
amxc_var_t * amxrt_get_config(void)
Gets the htable variant containing the configuration options.
Definition: amxrt.c:301
int amxrt_dm_save_load_main(int reason, amxd_dm_t *dm, amxo_parser_t *parser)
The data model auto load and save module.
void amxrt_delete(void)
Clean-up ambiorix runtime.
Definition: amxrt.c:378
amxd_dm_t * amxrt_get_dm(void)
Gets the runtime data model storage.
Definition: amxrt.c:309
void amxrt_new(void)
Create the ambiorix runtime.
Definition: amxrt.c:313
amxo_parser_t * amxrt_get_parser(void)
Gets runtime odl parser.
Definition: amxrt.c:305
&include test odl
config
Definition: test.odl:54
void test_save_fails_when_invalid_dir(UNUSED void **state)
int test_save_load_setup(UNUSED void **state)
void test_saves_when_persistent_parameter_changes(UNUSED void **state)
void test_can_save_on_changes(UNUSED void **state)
void test_does_not_save_when_invalid_objects(UNUSED void **state)
void test_can_save_on_changes_with_object_list(UNUSED void **state)
void test_can_save_separate_objects_csv(UNUSED void **state)
void test_can_start_with_directory_configured(UNUSED void **state)
void test_loads_default_when_valid_dir_is_used(UNUSED void **state)
void test_can_start_with_odl_storage_type(UNUSED void **state)
void test_can_start_with_no_storage_type(UNUSED void **state)
void test_can_start_with_no_storage_path(UNUSED void **state)
void test_can_start_with_no_odl_storage_type(UNUSED void **state)
void test_does_not_save_when_not_persistent_parameter_changes(UNUSED void **state)
void test_start_fails_with_invalid_directory_configured(UNUSED void **state)
static void read_sigalrm(void)
void test_saves_when_instance_deleted(UNUSED void **state)
static int event_count
void test_load_fails_with_invalid_dir_and_invalid_defaults(UNUSED void **state)
void test_can_load_files_with_eventing_on_or_off(UNUSED void **state)
void test_does_not_save_on_changed_when_invalid_objects(UNUSED void **state)
int test_save_load_teardown(UNUSED void **state)
void test_can_save_separate_objects_string(UNUSED void **state)
void test_save_skips_unknown_objects(UNUSED void **state)
void test_save_separate_objects_fail_when_invalid_dir(UNUSED void **state)
static void handle_events(void)
void test_can_save_all_objects(UNUSED void **state)