libamxd  6.4.1
Data Model Manager
test_amxd_object_event.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <cmocka.h>
#include <sys/signalfd.h>
#include <string.h>
#include <amxc/amxc.h>
#include <amxp/amxp_signal.h>
#include <amxp/amxp_slot.h>
#include <amxp/amxp_timer.h>
#include <amxd/amxd_common.h>
#include <amxd/amxd_dm.h>
#include <amxd/amxd_object.h>
#include <amxd/amxd_object_event.h>
#include <amxd/amxd_transaction.h>
#include "test_amxd_object_event.h"
#include <amxc/amxc_macros.h>

Go to the source code of this file.

Functions

static void test_event_handler (UNUSED const char *const sig_name, UNUSED const amxc_var_t *const data, void *const priv)
 
static void test_build_dm (void)
 
static int read_sig_alarm (void)
 
int test_object_event_setup (UNUSED void **state)
 
int test_object_event_teardown (UNUSED void **state)
 
void test_can_start_and_stop_periodic_inform (UNUSED void **state)
 
void test_only_one_periodic_inform_per_object (UNUSED void **state)
 
void test_timer_stops_when_object_is_destroyed (UNUSED void **state)
 
void test_events_are_not_duplicated (UNUSED void **state)
 
void test_can_allocate_event_data (UNUSED void **state)
 
void test_allocate_event_data_fails_when_event_not_found (UNUSED void **state)
 
void test_can_send_event (UNUSED void **state)
 
void test_can_change_event_definition (UNUSED void **state)
 
void test_can_remove_event_definition (UNUSED void **state)
 
void test_event_changed_is_send (UNUSED void **state)
 

Variables

static amxd_dm_t dm
 
static int sfd
 
static sigset_t mask
 

Function Documentation

◆ read_sig_alarm()

static int read_sig_alarm ( void  )
static

Definition at line 133 of file test_amxd_object_event.c.

133  {
134  while(1) {
135  struct signalfd_siginfo si;
136  ssize_t res;
137  res = read(sfd, &si, sizeof(si));
138  assert_false(res < 0);
139  assert_false(res != sizeof(si));
140  if(si.ssi_signo == SIGALRM) {
141  amxp_timers_calculate();
142  amxp_timers_check();
143  break;
144  }
145  }
146 
147  while(amxp_signal_read() == 0) {
148  }
149 
150  return 0;
151 }
static int sfd

◆ test_allocate_event_data_fails_when_event_not_found()

void test_allocate_event_data_fails_when_event_not_found ( UNUSED void **  state)

Definition at line 329 of file test_amxd_object_event.c.

329  {
330  amxc_var_t* event_data = NULL;
331  amxd_object_t* object = amxd_dm_findf(&dm, "MyRootObject.MyChildObject2.");
332  assert_non_null(object);
333 
334  event_data = amxd_object_new_event_data(object, "MyEvent3!");
335  assert_null(event_data);
336 
337  event_data = amxd_object_new_event_data(object, NULL);
338  assert_null(event_data);
339 
340  event_data = amxd_object_new_event_data(object, "");
341  assert_null(event_data);
342 
343  event_data = amxd_object_new_event_data(NULL, "MyEvent2!");
344  assert_null(event_data);
345 }
amxd_object_t * amxd_dm_findf(amxd_dm_t *const dm, const char *abs_path,...) __attribute__((format(printf
amxc_var_t * amxd_object_new_event_data(const amxd_object_t *object, const char *event_name)
Allocates a variant that contains the predefined event data.
static amxd_dm_t dm

◆ test_build_dm()

static void test_build_dm ( void  )
static

Definition at line 95 of file test_amxd_object_event.c.

95  {
96  amxd_object_t* object = NULL;
97  amxd_object_t* child_object = NULL;
98  amxd_param_t* param = NULL;
99  amxc_var_t* event_data = NULL;
100 
101  assert_int_equal(amxd_dm_init(&dm), 0);
102  amxc_var_new(&event_data);
103  amxc_var_set_type(event_data, AMXC_VAR_ID_HTABLE);
104  amxc_var_add_key(cstring_t, event_data, "param1", "Text");
105  amxc_var_add_key(uint32_t, event_data, "param2", 100);
106 
107  assert_int_equal(amxd_object_new(&object, amxd_object_singleton, "MyRootObject"), 0);
108  assert_int_equal(amxd_dm_add_root_object(&dm, object), 0);
109 
110  assert_int_equal(amxd_object_new(&child_object, amxd_object_singleton, "MyChildObject1"), 0);
111  assert_int_equal(amxd_object_add_object(object, child_object), 0);
112 
113  assert_int_equal(amxd_param_new(&param, "MyParam1", AMXC_VAR_ID_CSTRING), 0);
114  assert_int_equal(amxd_object_add_param(child_object, param), 0);
115  assert_int_equal(amxd_param_new(&param, "MyParam2", AMXC_VAR_ID_BOOL), 0);
116  assert_int_equal(amxd_object_add_param(child_object, param), 0);
117  assert_int_equal(amxd_param_new(&param, "MyParam3", AMXC_VAR_ID_UINT32), 0);
118  assert_int_equal(amxd_object_add_param(child_object, param), 0);
119 
120  assert_int_equal(amxd_object_new(&child_object, amxd_object_singleton, "MyChildObject2"), 0);
121  assert_int_equal(amxd_object_add_object(object, child_object), 0);
122 
123  assert_int_equal(amxd_param_new(&param, "MyParam1", AMXC_VAR_ID_CSTRING), 0);
124  assert_int_equal(amxd_object_add_param(child_object, param), 0);
125  assert_int_equal(amxd_param_new(&param, "MyParam2", AMXC_VAR_ID_BOOL), 0);
126  assert_int_equal(amxd_object_add_param(child_object, param), 0);
127  assert_int_equal(amxd_param_new(&param, "MyParam3", AMXC_VAR_ID_UINT32), 0);
128  assert_int_equal(amxd_object_add_param(child_object, param), 0);
129  assert_int_equal(amxd_object_add_event(child_object, "MyEvent1!"), 0);
130  assert_int_equal(amxd_object_add_event_ext(child_object, "MyEvent2!", event_data), 0);
131 }
amxd_status_t amxd_param_new(amxd_param_t **param, const char *name, const uint32_t type)
@ amxd_object_singleton
Definition: amxd_types.h:181
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_status_t amxd_dm_init(amxd_dm_t *dm)
Initializes a data model structure.
Definition: amxd_dm.c:334
amxd_status_t amxd_object_add_event_ext(amxd_object_t *const object, const char *event_name, amxc_var_t *event_data)
Adds an event definition to the object.
amxd_status_t amxd_object_add_event(amxd_object_t *const object, const char *event_name)
Adds an event definition to 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_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

◆ test_can_allocate_event_data()

void test_can_allocate_event_data ( UNUSED void **  state)

Definition at line 311 of file test_amxd_object_event.c.

311  {
312  amxc_var_t* event_data = NULL;
313  amxd_object_t* object = amxd_dm_findf(&dm, "MyRootObject.MyChildObject2.");
314  assert_non_null(object);
315 
316  event_data = amxd_object_new_event_data(object, "MyEvent1!");
317  assert_non_null(event_data);
318 
319  assert_int_equal(amxc_var_type_of(event_data), AMXC_VAR_ID_NULL);
320  amxc_var_delete(&event_data);
321 
322  event_data = amxd_object_new_event_data(object, "MyEvent2!");
323  assert_non_null(event_data);
324  assert_int_equal(amxc_var_type_of(event_data), AMXC_VAR_ID_HTABLE);
325 
326  amxc_var_delete(&event_data);
327 }

◆ test_can_change_event_definition()

void test_can_change_event_definition ( UNUSED void **  state)

Definition at line 367 of file test_amxd_object_event.c.

367  {
368  amxc_var_t* event_data = NULL;
369  amxd_object_t* object = amxd_dm_findf(&dm, "MyRootObject.MyChildObject2.");
370  assert_non_null(object);
371 
372  assert_int_equal(amxd_object_add_event(object, "MyEvent2!"), 0);
373  event_data = amxd_object_new_event_data(object, "MyEvent2!");
374  assert_non_null(event_data);
375 
376  assert_int_equal(amxc_var_type_of(event_data), AMXC_VAR_ID_NULL);
377  amxc_var_delete(&event_data);
378 }

◆ test_can_remove_event_definition()

void test_can_remove_event_definition ( UNUSED void **  state)

Definition at line 380 of file test_amxd_object_event.c.

380  {
381  amxc_var_t* event_data = NULL;
382  amxd_object_t* object = amxd_dm_findf(&dm, "MyRootObject.MyChildObject2.");
383  assert_non_null(object);
384 
385  amxd_object_remove_event(object, "MyEvent2!");
386  event_data = amxd_object_new_event_data(object, "MyEvent2!");
387  assert_null(event_data);
388 }
void amxd_object_remove_event(amxd_object_t *const object, const char *event_name)
Removes an event definition to the object.

◆ test_can_send_event()

void test_can_send_event ( UNUSED void **  state)

Definition at line 347 of file test_amxd_object_event.c.

347  {
348  amxc_var_t* event_data = NULL;
349  uint32_t count = 0;
350  amxd_object_t* object = amxd_dm_findf(&dm, "MyRootObject.MyChildObject2.");
351  assert_non_null(object);
352 
353  while(amxp_signal_read() == 0) {
354  }
355 
356  event_data = amxd_object_new_event_data(object, "MyEvent2!");
357  amxd_object_emit_signal(object, "MyEvent2!", event_data);
358  amxc_var_delete(&event_data);
359 
360  while(amxp_signal_read() == 0) {
361  count++;
362  }
363 
364  assert_int_equal(count, 1);
365 }
AMXD_INLINE void amxd_object_emit_signal(amxd_object_t *const object, const char *name, amxc_var_t *const data)
Emit an object signal/event.

◆ test_can_start_and_stop_periodic_inform()

void test_can_start_and_stop_periodic_inform ( UNUSED void **  state)

Definition at line 175 of file test_amxd_object_event.c.

175  {
176  amxd_object_t* object = NULL;
177  amxp_timer_t* expire = NULL;
178  int counter = 0;
179 
180  amxp_timer_new(&expire, NULL, NULL);
181  object = amxd_dm_findf(&dm, "MyRootObject.MyChildObject1");
182 
183  amxp_timer_start(expire, 5000);
184 
185  counter = 0;
186  amxp_slot_connect(&dm.sigmngr, "dm:periodic-inform", NULL, test_event_handler, &counter);
187  assert_int_equal(amxd_object_new_pi(object, 1), 0);
188  read_sig_alarm();
189  read_sig_alarm();
190  read_sig_alarm();
191  assert_int_equal(amxd_object_delete_pi(object), 0);
192  assert_int_equal(counter, 3);
193 
194  counter = 0;
195  read_sig_alarm();
196  assert_int_equal(counter, 0);
197 
198  while(amxp_signal_read() == 0) {
199  }
200 
201  amxp_timer_start(expire, 5000);
202 
203  assert_int_equal(amxd_object_new_pi(object, 1), 0);
204  read_sig_alarm();
205  read_sig_alarm();
206  read_sig_alarm();
207  assert_int_equal(amxd_object_delete_pi(object), 0);
208  assert_true(counter >= 2);
209 
210  counter = 0;
211  read_sig_alarm();
212  assert_int_equal(counter, 0);
213 
214  amxp_timer_set_interval(expire, 1000);
215  amxp_timer_start(expire, 5000);
216 
217  counter = 0;
218  read_sig_alarm();
219  read_sig_alarm();
220  read_sig_alarm();
221  assert_int_equal(counter, 0);
222  amxp_timer_delete(&expire);
223  amxp_slot_disconnect(&dm.sigmngr, "dm:periodic-inform", test_event_handler);
224 }
amxd_status_t amxd_object_new_pi(amxd_object_t *object, uint32_t sec)
Creates and starts a periodic inform event timer.
amxd_status_t amxd_object_delete_pi(amxd_object_t *object)
Stops and deletes a periodic inform event timer.
amxp_signal_mngr_t sigmngr
Definition: amxd_types.h:261
static int counter
static void test_event_handler(UNUSED const char *const sig_name, UNUSED const amxc_var_t *const data, void *const priv)
static int read_sig_alarm(void)

◆ test_event_changed_is_send()

void test_event_changed_is_send ( UNUSED void **  state)

Definition at line 390 of file test_amxd_object_event.c.

390  {
391  amxd_trans_t transaction;
392  int counter = 0;
393  amxc_var_t data;
394  amxc_var_t* params = NULL;
395 
396  amxp_slot_connect(&dm.sigmngr, "dm:object-changed", NULL, test_event_handler, &counter);
397 
398  assert_int_equal(amxd_trans_init(&transaction), 0);
399  assert_int_equal(amxd_trans_select_pathf(&transaction, "MyRootObject.MyChildObject2."), 0);
400  assert_int_equal(amxd_trans_set_value(cstring_t, &transaction, "MyParam1", "Hello world"), 0);
401  assert_int_equal(amxd_trans_set_value(bool, &transaction, "MyParam2", true), 0);
402  amxd_trans_dump(&transaction, STDOUT_FILENO, false);
403  assert_int_equal(amxd_trans_apply(&transaction, &dm), 0);
404  amxd_trans_clean(&transaction);
405 
406  while(amxp_signal_read() == 0) {
407  }
408  assert_int_equal(counter, 1);
409  counter = 0;
410 
411  amxc_var_init(&data);
412  amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
413  amxc_var_add_key(uint32_t, &data, "access", amxd_dm_access_public);
414  amxc_var_add_key(bool, &data, "set_read_only", false);
415  params = amxc_var_add_key(amxc_htable_t, &data, "oparameters", NULL);
416  amxc_var_add_key(cstring_t, params, "MyParam1", "Hello Universe");
417  amxc_var_add_key(bool, params, "MyParam2", false);
418 
419  assert_int_equal(amxd_trans_init(&transaction), 0);
420  assert_int_equal(amxd_trans_select_pathf(&transaction, "MyRootObject.MyChildObject2."), 0);
421  amxd_trans_add_action(&transaction, action_object_write, &data);
422  amxd_trans_dump(&transaction, STDOUT_FILENO, false);
423  assert_int_equal(amxd_trans_apply(&transaction, &dm), 0);
424  amxd_trans_clean(&transaction);
425 
426  while(amxp_signal_read() == 0) {
427  }
428  assert_int_equal(counter, 1);
429 
430  amxc_var_clean(&data);
431  amxp_slot_disconnect(&dm.sigmngr, "dm:object-changed", test_event_handler);
432 }
@ action_object_write
Definition: amxd_types.h:118
@ amxd_dm_access_public
Definition: amxd_types.h:136
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.
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_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_trans_init(amxd_trans_t *const trans)
Initializes a transaction object.

◆ test_event_handler()

static void test_event_handler ( UNUSED const char *const  sig_name,
UNUSED const amxc_var_t *const  data,
void *const  priv 
)
static

Definition at line 87 of file test_amxd_object_event.c.

89  {
90  int* counter = (int*) priv;
91  printf("event recieved %s\n", sig_name);
92  (*counter)++;
93 }

◆ test_events_are_not_duplicated()

void test_events_are_not_duplicated ( UNUSED void **  state)

Definition at line 277 of file test_amxd_object_event.c.

277  {
278  amxd_trans_t transaction;
279  int counter = 0;
280  amxd_object_t* child_object = NULL;
281  amxd_object_t* child_object2 = NULL;
282  amxd_object_t* root = amxd_dm_findf(&dm, "MyRootObject");
283 
284  amxp_slot_connect(&dm.sigmngr, "*", NULL, test_event_handler, &counter);
285 
286  assert_int_equal(amxd_object_new(&child_object, amxd_object_template, "MyTemplate"), 0);
287  assert_int_equal(amxd_object_add_object(root, child_object), 0);
288  assert_int_equal(amxd_object_new(&child_object2, amxd_object_singleton, "MySubObject"), 0);
289  assert_int_equal(amxd_object_set_attr(child_object2, amxd_oattr_private, true), 0);
290  assert_int_equal(amxd_object_add_object(child_object, child_object2), 0);
291  assert_int_equal(amxd_object_new(&child_object2, amxd_object_template, "MySubTemplate"), 0);
292  assert_int_equal(amxd_object_add_object(child_object, child_object2), 0);
293 
294  amxd_trans_init(&transaction);
295  amxd_trans_select_pathf(&transaction, "MyRootObject.MyTemplate.");
296  amxd_trans_add_inst(&transaction, 0, NULL);
297  amxd_trans_select_pathf(&transaction, ".MySubTemplate.");
298  amxd_trans_add_inst(&transaction, 0, NULL);
299  assert_int_equal(amxd_trans_apply(&transaction, &dm), 0);
300 
301  while(amxp_signal_read() == 0) {
302  }
303 
304  assert_int_equal(counter, 6); // 2 instance add + 4 object added
305 
306  amxp_slot_disconnect_all(test_event_handler);
307 
308  amxd_trans_clean(&transaction);
309 }
@ amxd_oattr_private
Definition: amxd_types.h:202
@ amxd_object_template
Definition: amxd_types.h:183
amxd_status_t amxd_object_set_attr(amxd_object_t *const object, const amxd_oattr_id_t attr, const bool enable)
Sets or unsets an object attribute.
Definition: amxd_object.c:269
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.

◆ test_object_event_setup()

int test_object_event_setup ( UNUSED void **  state)

Definition at line 153 of file test_amxd_object_event.c.

153  {
154  test_build_dm();
155 
156  sigemptyset(&mask);
157  sigaddset(&mask, SIGALRM);
158 
159  int rv = sigprocmask(SIG_BLOCK, &mask, NULL);
160  assert_false(rv < 0);
161 
162  sfd = signalfd(-1, &mask, 0);
163  assert_false(sfd < 0);
164 
165  return 0;
166 }
static sigset_t mask
static void test_build_dm(void)

◆ test_object_event_teardown()

int test_object_event_teardown ( UNUSED void **  state)

Definition at line 168 of file test_amxd_object_event.c.

168  {
169  close(sfd);
170  amxd_dm_clean(&dm);
171 
172  return 0;
173 }
void amxd_dm_clean(amxd_dm_t *dm)
Cleans a data model structure.
Definition: amxd_dm.c:365

◆ test_only_one_periodic_inform_per_object()

void test_only_one_periodic_inform_per_object ( UNUSED void **  state)

Definition at line 226 of file test_amxd_object_event.c.

226  {
227  amxd_object_t* object = NULL;
228  amxp_timer_t* expire = NULL;
229  int counter = 0;
230 
231  amxp_timer_new(&expire, NULL, NULL);
232  object = amxd_dm_findf(&dm, "MyRootObject.MyChildObject1");
233 
234  amxp_slot_connect(&dm.sigmngr, "dm:periodic-inform", NULL, test_event_handler, &counter);
235  assert_int_equal(amxd_object_new_pi(object, 2), 0);
236  assert_int_not_equal(amxd_object_new_pi(object, 1), 0);
237  read_sig_alarm();
238  read_sig_alarm();
239  read_sig_alarm();
240  assert_int_equal(amxd_object_delete_pi(object), 0);
241  assert_true(counter >= 2);
242 
243  counter = 0;
244  amxp_timer_set_interval(expire, 10000);
245  amxp_timer_start(expire, 1000);
246  read_sig_alarm();
247  read_sig_alarm();
248  read_sig_alarm();
249  assert_int_equal(counter, 0);
250  amxp_timer_delete(&expire);
251  amxp_slot_disconnect(&dm.sigmngr, "dm:periodic-inform", test_event_handler);
252 }

◆ test_timer_stops_when_object_is_destroyed()

void test_timer_stops_when_object_is_destroyed ( UNUSED void **  state)

Definition at line 254 of file test_amxd_object_event.c.

254  {
255  amxd_object_t* object = NULL;
256  amxp_timer_t* expire = NULL;
257  int counter = 0;
258 
259  amxp_timer_new(&expire, NULL, NULL);
260  object = amxd_dm_findf(&dm, "MyRootObject.MyChildObject1");
261 
262  amxp_timer_start(expire, 5000);
263  read_sig_alarm();
264  assert_int_equal(counter, 0);
265 
266  amxp_timer_start(expire, 5000);
267  amxp_slot_connect(&dm.sigmngr, "dm:periodic-inform", NULL, test_event_handler, &counter);
268  assert_int_equal(amxd_object_new_pi(object, 1), 0);
269  read_sig_alarm();
270  amxd_object_delete(&object);
271  read_sig_alarm();
272  assert_int_equal(counter, 1);
273  amxp_timer_delete(&expire);
274  amxp_slot_disconnect(&dm.sigmngr, "dm:periodic-inform", test_event_handler);
275 }
void amxd_object_delete(amxd_object_t **object)
Invokes the destroy handler(s) of the object.

Variable Documentation

◆ dm

amxd_dm_t dm
static

Definition at line 83 of file test_amxd_object_event.c.

◆ mask

sigset_t mask
static

Definition at line 85 of file test_amxd_object_event.c.

◆ sfd

int sfd
static

Definition at line 84 of file test_amxd_object_event.c.