test_SOURCES = \
tests/unit/ejdb_tests.c \
+ tests/unit/decision_made_event_tests.c \
+ tests/unit/resource_violation_event_tests.c \
+ tests/unit/service_failed_event_tests.c \
+ tests/unit/system_booted_event_tests.c \
tests/unit/faultd_object_tests.c \
tests/unit/runner.c \
tests/unit/helpers.c \
src/util/systemd_dbus.c \
src/util/log.c \
src/util/common.c \
- src/database/ejdb.c
+ src/database/ejdb.c \
+ src/event_types/decision_made_event.c \
+ src/event_types/resource_violation_event.c \
+ src/event_types/service_failed_event.c \
+ src/event_types/system_booted_event.c
TESTS = $(check_PROGRAMS)
endif
faultd_object_append_string(out, DM_EV_ACTION, dm_ev->action);
faultd_object_append_object(out, DM_EV_ACTION_DATA, dm_ev->action_data);
}
+TEST_ENTRY_POINT(dm_event_serialize);
static struct faultd_event_type decision_made_event_type = {
.name = DECISION_MADE_EVENT_ID,
faultd_object_append_int(out, RV_EV_RES_TYPE, rv_ev->resource_type);
faultd_object_append_int(out, RV_EV_PID, rv_ev->pid);
}
+TEST_ENTRY_POINT(rv_event_serialize);
static struct faultd_event_type resource_violation_event_type = {
.name = RESOURCE_VIOLATION_EVENT_ID,
systemd_service_serialize(&sf_ev->service, out);
faultd_object_append_time_t(out, SF_EV_DTIME, sf_ev->detection_time);
}
+TEST_ENTRY_POINT(sf_event_serialize);
static struct faultd_event_type service_failed_event_type = {
.name = SERVICE_FAILED_EVENT_ID,
faultd_event_serialize_internal(ev, out);
faultd_object_append_uuid(out, "prev_boot_id", &sb_ev->prev_boot_id);
}
+TEST_ENTRY_POINT(sb_event_serialize);
static struct faultd_event_type system_booted_event_type = {
.name = SYSTEM_BOOTED_EVENT_ID,
--- /dev/null
+#include "decision_made_event.h"
+#include "helpers.h"
+
+#define TESTED_MOD decision_made_event
+
+DECLARE_TEST_ENTRY_POINT(TESTED_MOD, dm_event_serialize, void);
+
+#define KEY1 "somekey"
+#define VAL1 "value"
+
+#define KEY2 "somekey2"
+#define VAL2 "value2"
+
+static struct faultd_event *alloc_event()
+{
+ struct decision_made_event *dm_ev;
+
+ dm_ev = calloc(1, sizeof(*dm_ev));
+ assert_non_null(dm_ev);
+
+ fill_event(&dm_ev->event);
+
+ dm_ev->reason = calloc(1, sizeof(*(dm_ev->reason)));
+ assert_non_null(dm_ev->reason);
+
+ dm_ev->reason->oid = generate_oid();
+ dm_ev->who_made = generate_string(STR_SIZE);
+ dm_ev->action = generate_string(STR_SIZE);
+
+ faultd_object_new(&dm_ev->action_data);
+ faultd_object_append_string(dm_ev->action_data, KEY1, VAL1);
+ faultd_object_append_string(dm_ev->action_data, KEY2, VAL2);
+
+ return &dm_ev->event;
+}
+
+static void generate_test_attrs(struct serialize_test_data *td)
+{
+ struct decision_made_event *dm_ev = to_decision_made_event(td->ev);
+ struct serialized_element action_data[] = {
+ S_ELEMENT(KEY1, TYPE_STRING, VAL1),
+ S_ELEMENT(KEY2, TYPE_STRING, VAL2)
+ };
+
+ struct serialized_element serialized_attrs[] = {
+ S_ELEMENT_EVENT(dm_ev->event),
+ S_ELEMENT(DM_EV_REASON, TYPE_OID, &dm_ev->reason->oid),
+ S_ELEMENT(DM_EV_WHO, TYPE_STRING, dm_ev->who_made),
+ S_ELEMENT(DM_EV_ACTION, TYPE_STRING, dm_ev->action),
+ S_ELEMENT_OBJ(DM_EV_ACTION_DATA, dm_ev->action_data,
+ action_data, ARRAY_SIZE(action_data))
+ };
+
+ td->test_data = serialized_elems_dup(serialized_attrs,
+ ARRAY_SIZE(serialized_attrs));
+ td->size = ARRAY_SIZE(serialized_attrs);
+}
+
+static int setup(void **state)
+{
+ return setup_event_serialization(state, alloc_event, generate_test_attrs,
+ (serialize_func_t)CALL_TEST_ENTRY_POINT(
+ TESTED_MOD, dm_event_serialize));
+}
+
+static int teardown(void **state)
+{
+ struct serialize_test_data *td = *state;
+ struct decision_made_event *dm_ev = to_decision_made_event(td->ev);
+
+ faultd_object_unref(dm_ev->action_data);
+ free_event(&dm_ev->event);
+ free(dm_ev->who_made);
+ free(dm_ev->action);
+ free(dm_ev->reason);
+ free(dm_ev);
+ serialized_elems_free(td->test_data, td->size);
+ free(td);
+
+ return 0;
+}
+
+FAULTD_TEST_GROUP(
+ FAULTD_TEST_CASE_NST("dm_ev_serialize_test", test_event_serialization,
+ setup, teardown)
+)
#include "helpers.h"
+void test_serialization(struct serialized_element *data, int size, struct faultd_object *parent)
+{
+ for (int i = 0; i < size; ++i) {
+ switch (data[i].type) {
+ case TYPE_OID:
+ {
+ GET_FAULTD_OBJECT_VAL(faultd_oid_t, val, parent, data[i].key, data[i].type);
+ assert_oid_equal(&val, data[i].desired);
+ break;
+ }
+ case TYPE_STRING:
+ {
+ GET_FAULTD_OBJECT_VAL(char*, val, parent, data[i].key, data[i].type);
+ assert_string_equal(val, data[i].desired);
+ break;
+ }
+ case TYPE_INT:
+ {
+ GET_FAULTD_OBJECT_VAL(int, val, parent, data[i].key, data[i].type);
+ assert_int_equal(val, *(int*)(data[i].desired));
+ break;
+ }
+ case TYPE_TIMESPEC:
+ {
+ GET_FAULTD_OBJECT_VAL(struct timespec, val, parent, data[i].key, data[i].type);
+ assert_timespec_equal(&val, data[i].desired);
+ break;
+ }
+ case TYPE_TIME_T:
+ {
+ GET_FAULTD_OBJECT_VAL(time_t, val, parent, data[i].key, data[i].type);
+ assert_time_t_equal(val, *(time_t*)data[i].desired);
+ break;
+ }
+ case TYPE_UUID:
+ {
+ GET_FAULTD_OBJECT_VAL(sd_id128_t, val, parent, data[i].key, data[i].type);
+ assert_uuid_equal(&val, data[i].desired);
+ break;
+ }
+ case TYPE_OBJECT:
+ {
+ struct faultd_object *child;
+ int ret;
+
+ ret = faultd_object_get_object(parent, data[i].key, &child);
+ assert_int_equal(ret, 0);
+ test_serialization(data[i].child, data[i].children_num, child);
+ break;
+ }
+ default:
+ fprintf(stderr, "Type '%d' is not supported (key: '%s')\n",
+ data[i].type, data[i].key);
+ fail();
+ break;
+ }
+ }
+
+ assert_int_equal(faultd_object_count_children(parent), size);
+}
+
void assert_faultd_object_equal(struct faultd_object *actual,
struct faultd_object *desired)
{
t.tv_nsec = generate_int();
return t;
}
+
+void test_event_serialization(void **state)
+{
+ struct serialize_test_data *td = *state;
+ struct faultd_object *parent;
+ int ret;
+
+ ret = faultd_object_new(&parent);
+ assert_int_equal(ret, 0);
+
+ td->serialize_func(td->ev, parent);
+
+ test_serialization(td->test_data, td->size, parent);
+
+ faultd_object_unref(parent);
+}
+
+struct serialized_element *serialized_elems_dup(
+ struct serialized_element *elems, size_t size)
+{
+ struct serialized_element *new_elems;
+ int i;
+
+ new_elems = calloc(size, sizeof(*elems));
+ assert_non_null(new_elems);
+
+ memcpy(new_elems, elems, sizeof(*elems)*size);
+
+ for (i = 0; i < size; ++i)
+ if (new_elems[i].type == TYPE_OBJECT)
+ new_elems[i].child = serialized_elems_dup(new_elems[i].child,
+ new_elems[i].children_num);
+
+ return new_elems;
+}
+
+void serialized_elems_free(struct serialized_element *elems, size_t size)
+{
+ int i;
+
+ for (i = 0; i < size; ++i)
+ if (elems[i].type == TYPE_OBJECT)
+ serialized_elems_free(elems[i].child, elems[i].children_num);
+}
+
+int setup_event_serialization(void **state,
+ struct faultd_event *(*alloc_event)(),
+ void (*generate_attrs)(
+ struct serialize_test_data *td),
+ serialize_func_t serialize_func)
+{
+ struct serialize_test_data *td;
+
+ srand(time(NULL));
+
+ td = calloc(1, sizeof(*td));
+ assert_non_null(td);
+
+ td->ev = alloc_event();
+
+ generate_attrs(td);
+
+ td->serialize_func = serialize_func;
+
+ *state = td;
+ return 0;
+}
#define FAULTD_HELPERS_H
#include "fdtf.h"
+#include "event.h"
+#include "service.h"
#include <time.h>
#include <stdio.h>
#include <systemd/sd-id128.h>
#include <systemd/sd-bus.h>
+#define STR_SIZE 20
+
+#define GET_FAULTD_OBJECT_VAL(TYPE, VAR, OBJ, KEY, TYPE2) \
+ TYPE VAR; \
+ assert_int_equal(faultd_object_get_val(OBJ, KEY, TYPE2, &VAR), 0);
+
+#define _S_ELEMENT(KEY, TYPE, DESIRED) \
+ .key = KEY, \
+ .type = TYPE, \
+ .desired = DESIRED
+
+#define S_ELEMENT(TYPE, DESIRED, KEY) { \
+ _S_ELEMENT(TYPE, DESIRED, KEY) \
+}
+
+#define S_ELEMENT_EVENT(EV) \
+ S_ELEMENT(EV_BOOT_ID, TYPE_UUID, &EV.boot_id), \
+ S_ELEMENT(EV_TYPE_NAME, TYPE_STRING, EV.type->name), \
+ S_ELEMENT(EV_TIMESTAMP, TYPE_TIMESPEC, &EV.timestamp)
+
+#define S_ELEMENT_SERVICE(srv) \
+ S_ELEMENT(SYSD_SERVICE_DBUS_PATH, TYPE_STRING, \
+ srv.dbus_path), \
+ S_ELEMENT(SYSD_SERVICE_SERVICE_TYPE, TYPE_STRING, \
+ srv.service_type), \
+ S_ELEMENT(SYSD_SERVICE_RECOVERY_UNIT, TYPE_STRING, \
+ srv.recovery_unit)
+
+#define S_ELEMENT_OBJ(KEY, DESIRED, CHILD, CHILDREN_NUM) { \
+ _S_ELEMENT(KEY, TYPE_OBJECT, DESIRED), \
+ .child = CHILD, \
+ .children_num = CHILDREN_NUM \
+}
+
+struct serialized_element {
+ int type;
+ void *desired;
+ char *key;
+ struct serialized_element *child;
+ int children_num;
+};
+
+void test_serialization(struct serialized_element *data, int size,
+ struct faultd_object *parent);
int faultd_object_count_children(struct faultd_object *obj);
void assert_faultd_object_equal(struct faultd_object *actual,
faultd_oid_t generate_oid();
struct timespec generate_timespec();
-#endif /* FAULTD_UNIT_H */
+typedef void (*serialize_func_t)(struct faultd_event *, struct faultd_object *);
+
+struct serialize_test_data {
+ struct faultd_event *ev;
+ struct serialized_element *test_data;
+ size_t size;
+ serialize_func_t serialize_func;
+};
+
+void test_event_serialization(void **state);
+
+struct serialized_element *serialized_elems_dup(
+ struct serialized_element *elems, size_t size);
+
+void serialized_elems_free(struct serialized_element *elems, size_t size);
+
+int setup_event_serialization(void **state,
+ struct faultd_event *(*alloc_event)(),
+ void (*generate_attrs)(
+ struct serialize_test_data *td),
+ serialize_func_t serialize_func);
+
+static inline void fill_event(struct faultd_event *ev)
+{
+ ev->boot_id = generate_uuid();
+ ev->type = calloc(1, sizeof(*(ev->type)));
+ assert_non_null(ev->type);
+ ev->type->name = generate_string(STR_SIZE);
+ ev->timestamp = generate_timespec();
+}
+
+static inline void free_event(struct faultd_event *ev)
+{
+ free(ev->type->name);
+ free(ev->type);
+}
+
+static inline void fill_service(struct systemd_service *srv)
+{
+ srv->dbus_path = generate_string(STR_SIZE);
+ srv->service_type = generate_string(STR_SIZE);
+ srv->recovery_unit = generate_string(STR_SIZE);
+}
+
+static inline void free_service(struct systemd_service *srv)
+{
+ free(srv->dbus_path);
+ free(srv->service_type);
+ free(srv->recovery_unit);
+}
+
+#endif /* FAULTD_HELPERS_H */
--- /dev/null
+#include "resource_violation_event.h"
+#include "helpers.h"
+
+#define TESTED_MOD resource_violation_event
+
+DECLARE_TEST_ENTRY_POINT(TESTED_MOD, rv_event_serialize, void);
+
+static struct faultd_event *alloc_event()
+{
+ struct resource_violation_event *rv_ev;
+
+ rv_ev = calloc(1, sizeof(*rv_ev));
+ assert_non_null(rv_ev);
+
+ fill_event(&rv_ev->event);
+ fill_service(&rv_ev->service);
+ rv_ev->detection_time = generate_time_t();
+ rv_ev->pid = generate_int();
+ rv_ev->resource_type = generate_int();
+
+ return &rv_ev->event;
+}
+
+static void generate_test_attrs(struct serialize_test_data *td)
+{
+ struct resource_violation_event *rv_ev = to_resource_violation_event(td->ev);
+ struct serialized_element service_data[] = {
+ S_ELEMENT_SERVICE(rv_ev->service)
+ };
+
+ struct serialized_element serialized_attrs[] = {
+ S_ELEMENT_EVENT(rv_ev->event),
+ S_ELEMENT_OBJ(SYSD_SERVICE, NULL,
+ service_data, ARRAY_SIZE(service_data)),
+ S_ELEMENT(RV_EV_DTIME, TYPE_TIME_T, &rv_ev->detection_time),
+ S_ELEMENT(RV_EV_RES_TYPE, TYPE_INT, &rv_ev->resource_type),
+ S_ELEMENT(RV_EV_PID, TYPE_INT, &rv_ev->pid)
+ };
+
+ td->test_data = serialized_elems_dup(serialized_attrs,
+ ARRAY_SIZE(serialized_attrs));
+ td->size = ARRAY_SIZE(serialized_attrs);
+}
+
+static int setup(void **state)
+{
+ return setup_event_serialization(state, alloc_event, generate_test_attrs,
+ (serialize_func_t)CALL_TEST_ENTRY_POINT(
+ TESTED_MOD, rv_event_serialize));
+}
+
+static int teardown(void **state)
+{
+ struct serialize_test_data *td = *state;
+ struct resource_violation_event *rv_ev = to_resource_violation_event(td->ev);
+
+ free_event(&rv_ev->event);
+ free_service(&rv_ev->service);
+ free(rv_ev);
+ serialized_elems_free(td->test_data, td->size);
+ free(td);
+ return 0;
+}
+
+FAULTD_TEST_GROUP(
+ FAULTD_TEST_CASE_NST("rv_ev_serialize_test", test_event_serialization,
+ setup, teardown)
+)
--- /dev/null
+#include "service_failed_event.h"
+#include "helpers.h"
+
+#define TESTED_MOD service_failed_event
+
+DECLARE_TEST_ENTRY_POINT(TESTED_MOD, sf_event_serialize, void);
+
+static struct faultd_event *alloc_event()
+{
+ struct service_failed_event *sf_ev;
+
+ sf_ev = calloc(1, sizeof(*sf_ev));
+ assert_non_null(sf_ev);
+
+ fill_event(&sf_ev->event);
+ fill_service(&sf_ev->service);
+ sf_ev->detection_time = generate_time_t();
+
+ return &sf_ev->event;
+}
+
+static void generate_test_attrs(struct serialize_test_data *td)
+{
+ struct service_failed_event *sf_ev = to_service_failed_event(td->ev);
+ struct serialized_element service_data[] = {
+ S_ELEMENT_SERVICE(sf_ev->service)
+ };
+
+ struct serialized_element serialized_attrs[] = {
+ S_ELEMENT_EVENT(sf_ev->event),
+ S_ELEMENT_OBJ(SYSD_SERVICE, NULL,
+ service_data, ARRAY_SIZE(service_data)),
+ S_ELEMENT(SF_EV_DTIME, TYPE_TIME_T, &sf_ev->detection_time)
+ };
+
+ td->test_data = serialized_elems_dup(serialized_attrs,
+ ARRAY_SIZE(serialized_attrs));
+ td->size = ARRAY_SIZE(serialized_attrs);
+}
+
+static int setup(void **state)
+{
+ return setup_event_serialization(state, alloc_event, generate_test_attrs,
+ (serialize_func_t)CALL_TEST_ENTRY_POINT(
+ TESTED_MOD, sf_event_serialize));
+}
+
+static int teardown(void **state)
+{
+ struct serialize_test_data *td = *state;
+ struct service_failed_event *sf_ev = to_service_failed_event(td->ev);
+
+ free_event(&sf_ev->event);
+ free_service(&sf_ev->service);
+ free(sf_ev);
+ serialized_elems_free(td->test_data, td->size);
+ free(td);
+ return 0;
+}
+
+FAULTD_TEST_GROUP(
+ FAULTD_TEST_CASE_NST("sf_ev_serialize_test", test_event_serialization,
+ setup, teardown)
+)
--- /dev/null
+#include "system_booted_event.h"
+#include "helpers.h"
+
+#define TESTED_MOD system_booted_event
+
+DECLARE_TEST_ENTRY_POINT(TESTED_MOD, sb_event_serialize, void);
+
+static struct faultd_event *alloc_event()
+{
+ struct system_booted_event *sb_ev;
+
+ sb_ev = calloc(1, sizeof(*sb_ev));
+ assert_non_null(sb_ev);
+
+ fill_event(&sb_ev->event);
+ sb_ev->prev_boot_id = generate_uuid();
+
+ return &sb_ev->event;
+}
+
+static void generate_test_attrs(struct serialize_test_data *td)
+{
+ struct system_booted_event *sb_ev = to_system_booted_event(td->ev);
+ struct serialized_element serialized_attrs[] = {
+ S_ELEMENT_EVENT(sb_ev->event),
+ S_ELEMENT("prev_boot_id", TYPE_UUID, &sb_ev->prev_boot_id)
+ };
+
+ td->test_data = serialized_elems_dup(serialized_attrs,
+ ARRAY_SIZE(serialized_attrs));
+ td->size = ARRAY_SIZE(serialized_attrs);
+}
+
+static int setup(void **state)
+{
+ return setup_event_serialization(state, alloc_event, generate_test_attrs,
+ (serialize_func_t)CALL_TEST_ENTRY_POINT(
+ TESTED_MOD, sb_event_serialize));
+}
+
+static int teardown(void **state)
+{
+ struct serialize_test_data *td = *state;
+ struct system_booted_event *sb_ev = to_system_booted_event(td->ev);
+
+ free_event(&sb_ev->event);
+ free(sb_ev);
+ serialized_elems_free(td->test_data, td->size);
+ free(td);
+ return 0;
+}
+
+FAULTD_TEST_GROUP(
+ FAULTD_TEST_CASE_NST("sb_ev_serialize_test", test_event_serialization,
+ setup, teardown)
+)