--- /dev/null
+#include "helpers.h"
+#include "common.h"
+
+#define STRUCTURE_NAME faultd_object
+#define STR_SIZE 20
+
+#define GET_OBJ_FROM_STATE(obj, state) \
+ struct STRUCTURE_NAME *obj = *state
+
+#define GET_CHILDREN_OBJ(child, parent) \
+ struct STRUCTURE_NAME *child = list_first_entry(&parent->val.children, \
+ struct faultd_object, \
+ node)
+
+#define ASSERT_OBJECT(obj, k, t) \
+ assert_non_null(obj); \
+ assert_string_equal(obj->key, k); \
+ assert_int_equal(obj->type, t)
+
+static int setup(void **state)
+{
+ struct faultd_object *obj;
+ int ret;
+
+ ret = faultd_object_new(&obj);
+ assert_int_equal(ret, 0);
+
+ *state = obj;
+ return 0;
+}
+
+static int teardown(void **state)
+{
+ GET_OBJ_FROM_STATE(obj, state);
+ faultd_object_unref(obj);
+ return 0;
+}
+
+static void faultd_object_new_test(void **state)
+{
+ struct faultd_object *obj;
+ int ret;
+
+ ret = faultd_object_new(&obj);
+ assert_int_equal(ret, 0);
+ assert_int_equal(obj->type, TYPE_OBJECT);
+ assert_null(obj->key);
+
+ assert_true(list_empty(&obj->val.children));
+}
+
+static void append_oid_test(void **state)
+{
+ GET_OBJ_FROM_STATE(parent, state);
+ char *key;
+ faultd_oid_t val = generate_oid();
+ int ret;
+
+ key = generate_string(STR_SIZE);
+ assert_non_null(key);
+
+ ret = faultd_object_append_oid(parent, key, &val);
+ assert_int_equal(ret, 0);
+
+ GET_CHILDREN_OBJ(data, parent);
+ ASSERT_OBJECT(data, key, TYPE_OID);
+ assert_memory_equal(&data->val.oid, &val, sizeof(val));
+
+ free(key);
+}
+
+static void append_string_test(void **state)
+{
+ GET_OBJ_FROM_STATE(parent, state);
+ char *key;
+ char *val;
+ char *val_orig;
+ int ret;
+
+ key = generate_string(STR_SIZE);
+ assert_non_null(key);
+ val = generate_string(STR_SIZE);
+ assert_non_null(val);
+ val_orig = strdup(val);
+ assert_non_null(val_orig);
+
+ ret = faultd_object_append_string(parent, key, val);
+ assert_int_equal(ret, 0);
+
+ for (int i = 0; i < strlen(val); ++i)
+ val[i] = generate_char();
+
+ GET_CHILDREN_OBJ(data, parent);
+ ASSERT_OBJECT(data, key, TYPE_STRING);
+ assert_string_equal(data->val.s, val_orig);
+ assert_string_not_equal(data->val.s, val);
+
+ free(key);
+ free(val);
+ free(val_orig);
+}
+
+
+
+static void append_int_test(void **state)
+{
+ GET_OBJ_FROM_STATE(parent, state);
+ char *key;
+ int val = generate_int();
+ int ret;
+
+ key = generate_string(STR_SIZE);
+ assert_non_null(key);
+
+ ret = faultd_object_append_int(parent, key, val);
+ assert_int_equal(ret, 0);
+
+ GET_CHILDREN_OBJ(data, parent);
+ ASSERT_OBJECT(data, key, TYPE_INT);
+ assert_int_equal(data->val.i, val);
+
+ free(key);
+}
+
+static void append_time_t_test(void **state)
+{
+ GET_OBJ_FROM_STATE(parent, state);
+ char *key;
+ time_t val = generate_time_t();
+ int ret;
+
+ key = generate_string(STR_SIZE);
+ assert_non_null(key);
+
+ ret = faultd_object_append_time_t(parent, key, val);
+ assert_int_equal(ret, 0);
+
+ GET_CHILDREN_OBJ(data, parent);
+ ASSERT_OBJECT(data, key, TYPE_TIME_T);
+ assert_memory_equal(&data->val.time, &val, sizeof(val));
+
+ free(key);
+}
+
+static void append_timespec_test(void **state)
+{
+ GET_OBJ_FROM_STATE(parent, state);
+ char *key;
+ struct timespec val = generate_timespec();
+ int ret;
+
+ key = generate_string(STR_SIZE);
+ assert_non_null(key);
+
+ ret = faultd_object_append_timespec(parent, key, &val);
+ assert_int_equal(ret, 0);
+
+ GET_CHILDREN_OBJ(data, parent);
+ ASSERT_OBJECT(data, key, TYPE_TIMESPEC);
+ assert_memory_equal(&data->val.ts, &val, sizeof(val));
+
+ free(key);
+}
+
+static void append_uuid_test(void **state)
+{
+ GET_OBJ_FROM_STATE(parent, state);
+ char *key;
+ sd_id128_t val = generate_uuid();
+ int ret;
+
+ key = generate_string(STR_SIZE);
+ assert_non_null(key);
+
+ ret = faultd_object_append_uuid(parent, key, &val);
+ assert_int_equal(ret, 0);
+
+ GET_CHILDREN_OBJ(data, parent);
+ ASSERT_OBJECT(data, key, TYPE_UUID);
+ assert_memory_equal(&data->val.uuid, &val, sizeof(val));
+
+ free(key);
+}
+
+static void append_object_test(void **state)
+{
+ GET_OBJ_FROM_STATE(parent, state);
+ struct faultd_object *child;
+ char *key;
+ char *key2;
+ char *val;
+ int ret;
+
+ key = generate_string(STR_SIZE);
+ assert_non_null(key);
+ key2 = generate_string(STR_SIZE);
+ assert_non_null(key2);
+ val = generate_string(STR_SIZE);
+ assert_non_null(val);
+
+ ret = faultd_object_new(&child);
+ assert_int_equal(ret, 0);
+ ret = faultd_object_append_string(child, key2, val);
+ assert_int_equal(ret, 0);
+ ret = faultd_object_append_object(parent, key, child);
+ assert_int_equal(ret, 0);
+
+ GET_CHILDREN_OBJ(child2, parent);
+ ASSERT_OBJECT(child2, key, TYPE_OBJECT);
+
+ GET_CHILDREN_OBJ(data, child2);
+ ASSERT_OBJECT(data, key2, TYPE_STRING);
+ assert_string_equal(data->val.s, val);
+
+ faultd_object_unref(child);
+ free(key);
+ free(key2);
+ free(val);
+}
+
+static void get_string_test(void **state)
+{
+ GET_OBJ_FROM_STATE(parent, state);
+ char *key;
+ char *val;
+ char *val2 = NULL;
+ int ret;
+
+ key = generate_string(STR_SIZE);
+ assert_non_null(key);
+ val = generate_string(STR_SIZE);
+ assert_non_null(val);
+
+ ret = faultd_object_append_string(parent, key, val);
+ assert_int_equal(ret, 0);
+
+ ret = faultd_object_get_string(parent, key, &val2);
+ assert_int_equal(ret, 0);
+ assert_string_equal(val2, val);
+
+ free(key);
+ free(val);
+}
+
+static void get_int_test(void **state)
+{
+ GET_OBJ_FROM_STATE(parent, state);
+ char *key;
+ int val = generate_int();
+ int val2;
+ int ret;
+
+ key = generate_string(STR_SIZE);
+ assert_non_null(key);
+
+ ret = faultd_object_append_int(parent, key, val);
+ assert_int_equal(ret, 0);
+
+ ret = faultd_object_get_int(parent, key, &val2);
+ assert_int_equal(ret, 0);
+ assert_int_equal(val2, val);
+
+ free(key);
+}
+
+static void get_timespec_test(void **state)
+{
+ GET_OBJ_FROM_STATE(parent, state);
+ char *key;
+ struct timespec val = generate_timespec();
+ struct timespec val2;
+ int ret;
+
+ key = generate_string(STR_SIZE);
+ assert_non_null(key);
+
+ ret = faultd_object_append_timespec(parent, key, &val);
+ assert_int_equal(ret, 0);
+
+ ret = faultd_object_get_timespec(parent, key, &val2);
+ assert_int_equal(ret, 0);
+ assert_memory_equal(&val2, &val, sizeof(val));
+
+ free(key);
+}
+
+static void get_uuid_test(void **state)
+{
+ GET_OBJ_FROM_STATE(parent, state);
+ char *key;
+ sd_id128_t val = generate_uuid();
+ sd_id128_t val2 = SD_ID128_NULL;
+ int ret;
+
+ key = generate_string(STR_SIZE);
+ assert_non_null(key);
+
+ ret = faultd_object_append_uuid(parent, key, &val);
+ assert_int_equal(ret, 0);
+
+ ret = faultd_object_get_uuid(parent, key, &val2);
+ assert_int_equal(ret, 0);
+ assert_memory_equal(&val2, &val, sizeof(val));
+
+ free(key);
+}
+
+static void get_object_test(void **state)
+{
+ GET_OBJ_FROM_STATE(parent, state);
+ struct faultd_object *child;
+ struct faultd_object *child2;
+ char *key;
+ char *key2;
+ char *val;
+ int ret;
+
+ key = generate_string(STR_SIZE);
+ assert_non_null(key);
+ key2 = generate_string(STR_SIZE);
+ assert_non_null(key2);
+ val = generate_string(STR_SIZE);
+ assert_non_null(val);
+
+ ret = faultd_object_new(&child);
+ assert_int_equal(ret, 0);
+ ret = faultd_object_append_string(child, key2, val);
+ assert_int_equal(ret, 0);
+ ret = faultd_object_append_object(parent, key, child);
+ assert_int_equal(ret, 0);
+
+ ret = faultd_object_get_object(parent, key, &child2);
+ assert_int_equal(ret, 0);
+ assert_memory_equal(child2, child, sizeof(*child));
+
+ faultd_object_unref(child);
+ free(key);
+ free(key2);
+ free(val);
+}
+
+FAULTD_TEST_GROUP(
+ FAULTD_TEST_CASE_ST(faultd_object_new_test, NULL, teardown),
+ FAULTD_TEST_CASE_ST(append_oid_test, setup, teardown),
+ FAULTD_TEST_CASE_ST(append_string_test, setup, teardown),
+ FAULTD_TEST_CASE_ST(append_int_test, setup, teardown),
+ FAULTD_TEST_CASE_ST(append_time_t_test, setup, teardown),
+ FAULTD_TEST_CASE_ST(append_timespec_test, setup, teardown),
+ FAULTD_TEST_CASE_ST(append_uuid_test, setup, teardown),
+ FAULTD_TEST_CASE_ST(append_object_test, setup, teardown),
+ FAULTD_TEST_CASE_ST(get_string_test, setup, teardown),
+ FAULTD_TEST_CASE_ST(get_int_test, setup, teardown),
+ FAULTD_TEST_CASE_ST(get_timespec_test, setup, teardown),
+ FAULTD_TEST_CASE_ST(get_uuid_test, setup, teardown),
+ FAULTD_TEST_CASE_ST(get_object_test, setup, teardown)
+)