X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=blobdiff_plain;f=t%2Fcore%2Fobject_test.c;h=e00d300177b4694a5fd2b6d90a1ee9d9a3e72c84;hp=f5b7bf68a4cb5cddfb7c9cec1907b7a12f4a6d2b;hb=ddb7ffc175e49abfa69c82777b88d73e1f1103fb;hpb=47b37be23f31d28f358d394d5377a6f7aed2f2fd diff --git a/t/core/object_test.c b/t/core/object_test.c index f5b7bf6..e00d300 100644 --- a/t/core/object_test.c +++ b/t/core/object_test.c @@ -52,30 +52,44 @@ obj_destroy_noop(sdb_object_t *obj) fail_unless(obj != NULL, "obj destroy function: received obj == NULL"); } /* obj_destroy_noop */ -START_TEST(test_obj_create) +struct noop { + sdb_object_t super; + int data; +}; +static sdb_type_t noop_type = { + /* size = */ sizeof(struct noop), + /* init = */ obj_init_noop, + /* destroy = */ obj_destroy_noop, +}; + +static void *wrapped = (void *)0x42; + +static int destroy_wrapper_called = 0; +static void +wrapper_destroy(void *obj) { - struct noop { - sdb_object_t super; - int data; - }; - sdb_type_t noop_type = { - /* size = */ sizeof(struct noop), - /* init = */ obj_init_noop, - /* destroy = */ obj_destroy_noop, - }; + ++destroy_wrapper_called; + fail_unless(obj == wrapped, + "wrapper_destroy received unexpected obj %p; expected: %p", + obj, wrapped); +} /* wrapper_destroy */ +START_TEST(test_obj_create) +{ sdb_object_t *obj; + sdb_type_t test_type = noop_type; + const char *name = "test-object"; init_noop_called = 0; init_noop_retval = 0; destroy_noop_called = 0; - obj = sdb_object_create(name, noop_type); + obj = sdb_object_create(name, test_type); fail_unless(obj != NULL, "sdb_object_create() = NULL; expected: a new object"); - fail_unless(obj->type.size == noop_type.size, + fail_unless(obj->type.size == test_type.size, "after sdb_object_create(): type size mismatch; got: %zu; " - "expected: %zu", obj->type.size, noop_type.size); + "expected: %zu", obj->type.size, test_type.size); fail_unless(obj->ref_cnt == 1, "after sdb_object_create(): obj->ref_cnt = %d; expected: 1", obj->ref_cnt); @@ -104,7 +118,7 @@ START_TEST(test_obj_create) init_noop_called = 0; init_noop_retval = -1; destroy_noop_called = 0; - obj = sdb_object_create(name, noop_type); + obj = sdb_object_create(name, test_type); fail_unless(obj == NULL, "sdb_object_create() = %p; expected NULL (init returned -1)", obj); @@ -114,11 +128,11 @@ START_TEST(test_obj_create) "sdb_object_create() did not call object's destroy function " "after init failure"); - noop_type.size = 1; + test_type.size = 1; init_noop_called = 0; init_noop_retval = 0; destroy_noop_called = 0; - obj = sdb_object_create(name, noop_type); + obj = sdb_object_create(name, test_type); fail_unless(obj == NULL, "sdb_object_create() = %p; expected NULL (type's size too small)", obj); @@ -129,22 +143,157 @@ START_TEST(test_obj_create) "sdb_object_create() called object's destroy function " "when size was too small"); - noop_type.size = sizeof(struct noop); + test_type.size = sizeof(struct noop); init_noop_retval = 0; - noop_type.init = NULL; - obj = sdb_object_create(name, noop_type); + test_type.init = NULL; + obj = sdb_object_create(name, test_type); fail_unless(obj != NULL, "sdb_object_create() fails without init callback"); sdb_object_deref(obj); - noop_type.destroy = NULL; - obj = sdb_object_create(name, noop_type); + test_type.destroy = NULL; + obj = sdb_object_create(name, test_type); fail_unless(obj != NULL, "sdb_object_create() fails without destroy callback"); sdb_object_deref(obj); } END_TEST +START_TEST(test_obj_wrapper) +{ + sdb_object_t *obj; + const char *name = "wrapped-object"; + + destroy_wrapper_called = 0; + obj = sdb_object_create_wrapper(name, wrapped, wrapper_destroy); + fail_unless(obj != NULL, + "sdb_object_create_wrapper() = NULL; expected: wrapper object"); + fail_unless(obj->ref_cnt == 1, + "after sdb_object_create_wrapper(); obj->ref_cnt = %d; " + "expected: 1", obj->ref_cnt); + fail_unless(!strcmp(obj->name, name), + "after sdb_object_create_wrapper(); obj->name = %s; expected: %s", + obj->name, name); + fail_unless(obj->name != name, + "sdb_object_create_wrapper() did not copy object name"); + fail_unless(SDB_OBJ_WRAPPER(obj)->data == wrapped, + "wrapped object wraps unexpected data %p; expected: %p", + SDB_OBJ_WRAPPER(obj)->data, wrapped); + + fail_unless(destroy_wrapper_called == 0, + "sdb_object_create_wrapper() called object's destructor"); + + sdb_object_deref(obj); + fail_unless(destroy_wrapper_called == 1, + "sdb_object_deref() did not call wrapped object's destructor"); +} +END_TEST + +START_TEST(test_obj_ref) +{ + sdb_object_t *obj; + sdb_type_t test_type = noop_type; + + init_noop_called = 0; + init_noop_retval = 0; + destroy_noop_called = 0; + + obj = sdb_object_create("test-object", test_type); + fail_unless(obj != NULL, + "sdb_object_create() = NULL; expected: valid object"); + + sdb_object_ref(obj); + fail_unless(obj->ref_cnt == 2, + "after db_object_ref(): obj->ref_cnt = %d; expected: 2", + obj->ref_cnt); + + sdb_object_ref(obj); + fail_unless(obj->ref_cnt == 3, + "after db_object_ref(): obj->ref_cnt = %d; expected: 3", + obj->ref_cnt); + + obj->ref_cnt = 42; + sdb_object_ref(obj); + fail_unless(obj->ref_cnt == 43, + "after db_object_ref(): obj->ref_cnt = %d; expected: 43", + obj->ref_cnt); + + fail_unless(init_noop_called == 1, + "after some sdb_object_ref(); object's init called %d times; " + "expected: 1", init_noop_called); + fail_unless(destroy_noop_called == 0, + "after some sdb_object_ref(); object's destroy called %d time%s; " + "expected: 0", destroy_noop_called == 1 ? "" : "2", + destroy_noop_called); + + sdb_object_deref(obj); + fail_unless(obj->ref_cnt == 42, + "after db_object_deref(): obj->ref_cnt = %d; expected: 42", + obj->ref_cnt); + + obj->ref_cnt = 23; + sdb_object_deref(obj); + fail_unless(obj->ref_cnt == 22, + "after db_object_deref(): obj->ref_cnt = %d; expected: 22", + obj->ref_cnt); + + fail_unless(init_noop_called == 1, + "after some sdb_object_{de,}ref(); object's init called %d times; " + "expected: 1", init_noop_called); + fail_unless(destroy_noop_called == 0, + "after some sdb_object_{de,}ref(); object's destroy called " + "%d time%s; expected: 0", destroy_noop_called == 1 ? "" : "2", + destroy_noop_called); + + /* test_obj_create already checks the ref_cnt == 1 case */ + obj->ref_cnt = 0; + sdb_object_deref(obj); + fail_unless(obj->ref_cnt <= 0, + "after db_object_deref(): obj->ref_cnt = %d; expected: <= 0", + obj->ref_cnt); + + fail_unless(init_noop_called == 1, + "after some sdb_object_{de,}ref(); object's init called %d times; " + "expected: 1", init_noop_called); + fail_unless(destroy_noop_called == 1, + "after some sdb_object_{de,}ref(); object's destroy called " + "%d times; expected: 1", destroy_noop_called); + + /* this should work */ + sdb_object_deref(NULL); +} +END_TEST + +START_TEST(test_obj_cmp) +{ + sdb_object_t *obj1, *obj2, *obj3, *obj4; + int status; + + obj1 = sdb_object_create("a", noop_type); + obj2 = sdb_object_create("b", noop_type); + obj3 = sdb_object_create("B", noop_type); + obj4 = sdb_object_create("c", noop_type); + + status = sdb_object_cmp_by_name(obj1, obj2); + fail_unless(status == -1, + "sdb_object_cmp_by_name('a', 'b') = %d; expected: -1", status); + status = sdb_object_cmp_by_name(obj2, obj3); + fail_unless(status == 0, + "sdb_object_cmp_by_name('b', 'B') = %d; expected: 0", status); + status = sdb_object_cmp_by_name(obj4, obj3); + fail_unless(status == 1, + "sdb_object_cmp_by_name('c', 'B') = %d; expected: 1", status); + status = sdb_object_cmp_by_name(obj1, obj1); + fail_unless(status == 0, + "sdb_object_cmp_by_name('a', 'a') = %d; expected: 0", status); + + sdb_object_deref(obj1); + sdb_object_deref(obj2); + sdb_object_deref(obj3); + sdb_object_deref(obj4); +} +END_TEST + Suite * core_object_suite(void) { @@ -153,6 +302,9 @@ core_object_suite(void) tc = tcase_create("core"); tcase_add_test(tc, test_obj_create); + tcase_add_test(tc, test_obj_wrapper); + tcase_add_test(tc, test_obj_ref); + tcase_add_test(tc, test_obj_cmp); suite_add_tcase(s, tc); return s;