--- /dev/null
+#include "helpers.h"
+#include "common.h"
+
+#define TESTED_MOD ejdb
+#define STR_SIZE 20
+
+#define GET_STATE(var, state_ptr) \
+ struct state_structure *var = *state_ptr
+
+#define FAULTD_OBJECT_APPEND(TYPE, OBJ, KEY, VAL) \
+ assert_int_equal(faultd_object_append_ ## TYPE(OBJ, KEY, VAL), 0);
+
+DECLARE_TEST_ENTRY_POINT(TESTED_MOD, faultd_object_to_bson, int);
+DECLARE_TEST_ENTRY_POINT(TESTED_MOD, bson_to_faultd_object, int);
+
+struct state_structure {
+ struct faultd_object *f;
+ bson *b;
+};
+
+static int allocate_structure(void **state)
+{
+ struct state_structure *s;
+ int ret;
+
+ s = calloc(1, sizeof(*s));
+ assert_non_null(s);
+
+ ret = faultd_object_new(&s->f);
+ assert_int_equal(ret, 0);
+
+ s->b = bson_create();
+ assert_non_null(s->b);
+
+ *state = s;
+ return 0;
+}
+
+static void init_faultd_object(struct faultd_object *f)
+{
+ faultd_oid_t oid_val;
+ char *string_val;
+ int int_val;
+ struct timespec ts_val;
+ time_t time_val;
+ sd_id128_t uuid_val;
+ struct faultd_object *child;
+ int ret;
+
+ memset(&oid_val, 0, sizeof(oid_val));
+ oid_val.bson = generate_bson_oid_t();
+ string_val = generate_string(STR_SIZE);
+ int_val = generate_int();
+ ts_val = generate_timespec();
+ time_val = generate_time_t();
+ uuid_val = generate_uuid();
+
+ FAULTD_OBJECT_APPEND(oid, f, "oid_key", &oid_val);
+ FAULTD_OBJECT_APPEND(string, f, "string_key", string_val);
+ FAULTD_OBJECT_APPEND(int, f, "int_key", int_val);
+ FAULTD_OBJECT_APPEND(timespec, f, "timespec_key", &ts_val);
+ FAULTD_OBJECT_APPEND(time_t, f, "time_t_key", time_val);
+ FAULTD_OBJECT_APPEND(uuid, f, "uuid_key", &uuid_val);
+
+ ret = faultd_object_new(&child);
+ assert_int_equal(ret, 0);
+ FAULTD_OBJECT_APPEND(string, child, "string_key", string_val);
+ FAULTD_OBJECT_APPEND(int, child, "int_key", int_val);
+ FAULTD_OBJECT_APPEND(timespec, child, "timespec_key", &ts_val);
+ FAULTD_OBJECT_APPEND(object, f, "child_key", child);
+
+ faultd_object_unref(child);
+ free(string_val);
+}
+
+static int setup(void **state)
+{
+ allocate_structure(state);
+
+ GET_STATE(s, state);
+ init_faultd_object(s->f);
+ return 0;
+}
+
+static int teardown(void **state)
+{
+ GET_STATE(s, state);
+
+ faultd_object_unref(s->f);
+ bson_del(s->b);
+ free(s);
+ return 0;
+}
+
+static void faultd_object_to_bson_test(void **state)
+{
+ GET_STATE(s, state);
+ struct faultd_object *f2;
+ int ret;
+
+ /* faultd_object to bson */
+ ret = CALL_TEST_ENTRY_POINT(TESTED_MOD, faultd_object_to_bson)(s->f, s->b);
+ assert_int_equal(ret, 0);
+
+ /* TODO: split faultd_object -> bson and bson -> faultd_object tests */
+ /* bson to faultd_object */
+ ret = faultd_object_new(&f2);
+ assert_int_equal(ret, 0);
+
+ ret = CALL_TEST_ENTRY_POINT(TESTED_MOD, bson_to_faultd_object)(s->b, f2);
+ assert_int_equal(ret, 0);
+
+ assert_faultd_object_equal(f2, s->f);
+}
+
+FAULTD_TEST_GROUP(
+ FAULTD_TEST_CASE_ST(faultd_object_to_bson_test, setup, teardown)
+)
#include "helpers.h"
+void assert_faultd_object_equal(struct faultd_object *actual,
+ struct faultd_object *desired)
+{
+ struct faultd_object *child_actual;
+ struct faultd_object *child_desired;
+
+ child_actual = list_first_entry(&actual->val.children,
+ struct faultd_object,
+ node);
+
+ child_desired = list_first_entry(&desired->val.children,
+ struct faultd_object,
+ node);
+
+ while (&child_actual->node != &actual->val.children)
+ {
+ if (child_actual->type == TYPE_OBJECT) {
+ assert_faultd_object_equal(child_actual, child_desired);
+ } else {
+ assert_int_equal(child_actual->type, child_desired->type);
+ assert_data_equal(child_actual->type,
+ &child_actual->val, &child_desired->val);
+ }
+
+ child_actual = list_next_entry(child_actual, node);
+ child_desired = list_next_entry(child_desired, node);
+ }
+}
+
+void assert_data_equal(int type, void *actual, void *desired)
+{
+ switch (type) {
+ case TYPE_OID:
+ assert_oid_equal(actual, desired);
+ break;
+ case TYPE_STRING:
+ assert_string_equal(*(char **)actual, *(char **)desired);
+ break;
+ case TYPE_INT:
+ assert_int_equal(*(int*)(actual),
+ *(int*)(desired));
+ break;
+ case TYPE_TIMESPEC:
+ assert_timespec_equal(actual, desired);
+ break;
+ case TYPE_TIME_T:
+ assert_time_t_equal(*(time_t*)actual,
+ *(time_t*)desired);
+ break;
+ case TYPE_UUID:
+ assert_uuid_equal(actual, desired);
+ break;
+ default:
+ fprintf(stderr, "Type '%d' is not supported\n", type);
+ fail();
+ break;
+ }
+}
+
int faultd_object_count_children(struct faultd_object *obj)
{
struct faultd_object *child;