diff options
author | Joshua Colp <jcolp@digium.com> | 2013-02-10 14:58:37 +0000 |
---|---|---|
committer | Joshua Colp <jcolp@digium.com> | 2013-02-10 14:58:37 +0000 |
commit | 27882b859976103e4e039b0107c0290604b17380 (patch) | |
tree | 287554cf4890bc30e0ddf9adfe8611a01ebc3878 /tests/test_sorcery.c | |
parent | 0e442112ada90d53cf8991b63bd3970cfaa7cc7a (diff) |
Add additional functionality to the Sorcery API.
This commit adds native implementation support for copying and diffing objects,
as well as the ability to load or reload on a per-object type level.
Review: https://reviewboard.asterisk.org/r/2320/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@381134 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'tests/test_sorcery.c')
-rw-r--r-- | tests/test_sorcery.c | 156 |
1 files changed, 149 insertions, 7 deletions
diff --git a/tests/test_sorcery.c b/tests/test_sorcery.c index cf53b1918..68e4fe8fc 100644 --- a/tests/test_sorcery.c +++ b/tests/test_sorcery.c @@ -77,6 +77,22 @@ static struct ast_variable *test_sorcery_transform(struct ast_variable *set) return transformed; } +/*! \brief Internal function which copies pre-defined data into an object, natively */ +static int test_sorcery_copy(const void *src, void *dst) +{ + struct test_sorcery_object *obj = dst; + obj->bob = 10; + obj->joe = 20; + return 0; +} + +/*! \brief Internal function which creates a pre-defined diff natively */ +static int test_sorcery_diff(const void *original, const void *modified, struct ast_variable **changes) +{ + *changes = ast_variable_new("yes", "itworks", ""); + return 0; +} + /*! \brief Test structure for caching */ struct sorcery_test_caching { /*! \brief Whether the object has been created in the cache or not */ @@ -142,18 +158,18 @@ static struct ast_sorcery *alloc_and_initialize_sorcery(void) { struct ast_sorcery *sorcery; - if (!(sorcery = ast_sorcery_open())) { + if (!(sorcery = ast_sorcery_open())) { return NULL; - } + } - if (ast_sorcery_apply_default(sorcery, "test", "memory", NULL) || - ast_sorcery_object_register(sorcery, "test", test_sorcery_object_alloc, NULL, NULL)) { + if (ast_sorcery_apply_default(sorcery, "test", "memory", NULL) || + ast_sorcery_object_register(sorcery, "test", test_sorcery_object_alloc, NULL, NULL)) { ast_sorcery_unref(sorcery); return NULL; - } + } - ast_sorcery_object_field_register(sorcery, "test", "bob", "5", OPT_UINT_T, 0, FLDSET(struct test_sorcery_object, bob)); - ast_sorcery_object_field_register(sorcery, "test", "joe", "10", OPT_UINT_T, 0, FLDSET(struct test_sorcery_object, joe)); + ast_sorcery_object_field_register(sorcery, "test", "bob", "5", OPT_UINT_T, 0, FLDSET(struct test_sorcery_object, bob)); + ast_sorcery_object_field_register(sorcery, "test", "joe", "10", OPT_UINT_T, 0, FLDSET(struct test_sorcery_object, joe)); return sorcery; } @@ -333,6 +349,11 @@ AST_TEST_DEFINE(object_register) return AST_TEST_FAIL; } + if (!ast_sorcery_object_register(sorcery, "test", test_sorcery_object_alloc, NULL, NULL)) { + ast_test_status_update(test, "Registered object type a second time, despite it being registered already\n"); + return AST_TEST_FAIL; + } + return AST_TEST_PASS; } @@ -544,6 +565,57 @@ AST_TEST_DEFINE(object_copy) return res; } +AST_TEST_DEFINE(object_copy_native) +{ + int res = AST_TEST_PASS; + RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref); + RAII_VAR(struct test_sorcery_object *, obj, NULL, ao2_cleanup); + RAII_VAR(struct test_sorcery_object *, copy, NULL, ao2_cleanup); + + switch (cmd) { + case TEST_INIT: + info->name = "object_copy_native"; + info->category = "/main/sorcery/"; + info->summary = "sorcery object native copy unit test"; + info->description = + "Test object native copy in sorcery"; + return AST_TEST_NOT_RUN; + case TEST_EXECUTE: + break; + } + + if (!(sorcery = alloc_and_initialize_sorcery())) { + ast_test_status_update(test, "Failed to open sorcery structure\n"); + return AST_TEST_FAIL; + } + + ast_sorcery_object_set_copy_handler(sorcery, "test", test_sorcery_copy); + + if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) { + ast_test_status_update(test, "Failed to allocate a known object type\n"); + return AST_TEST_FAIL; + } + + obj->bob = 50; + obj->joe = 100; + + if (!(copy = ast_sorcery_copy(sorcery, obj))) { + ast_test_status_update(test, "Failed to create a copy of a known valid object\n"); + res = AST_TEST_FAIL; + } else if (copy == obj) { + ast_test_status_update(test, "Created copy is actually the original object\n"); + res = AST_TEST_FAIL; + } else if (copy->bob != 10) { + ast_test_status_update(test, "Value of 'bob' on newly created copy is not the predefined native copy value\n"); + res = AST_TEST_FAIL; + } else if (copy->joe != 20) { + ast_test_status_update(test, "Value of 'joe' on newly created copy is not the predefined native copy value\n"); + res = AST_TEST_FAIL; + } + + return res; +} + AST_TEST_DEFINE(object_diff) { RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref); @@ -608,6 +680,72 @@ AST_TEST_DEFINE(object_diff) return res; } +AST_TEST_DEFINE(object_diff_native) +{ + RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref); + RAII_VAR(struct test_sorcery_object *, obj1, NULL, ao2_cleanup); + RAII_VAR(struct test_sorcery_object *, obj2, NULL, ao2_cleanup); + RAII_VAR(struct ast_variable *, changes, NULL, ast_variables_destroy); + struct ast_variable *field; + int res = AST_TEST_PASS; + + switch (cmd) { + case TEST_INIT: + info->name = "object_diff_native"; + info->category = "/main/sorcery/"; + info->summary = "sorcery object native diff unit test"; + info->description = + "Test native object diffing in sorcery"; + return AST_TEST_NOT_RUN; + case TEST_EXECUTE: + break; + } + + if (!(sorcery = alloc_and_initialize_sorcery())) { + ast_test_status_update(test, "Failed to open sorcery structure\n"); + return AST_TEST_FAIL; + } + + ast_sorcery_object_set_diff_handler(sorcery, "test", test_sorcery_diff); + + if (!(obj1 = ast_sorcery_alloc(sorcery, "test", "blah"))) { + ast_test_status_update(test, "Failed to allocate a known object type\n"); + return AST_TEST_FAIL; + } + + obj1->bob = 99; + obj1->joe = 55; + + if (!(obj2 = ast_sorcery_alloc(sorcery, "test", "blah2"))) { + ast_test_status_update(test, "Failed to allocate a second known object type\n"); + return AST_TEST_FAIL; + } + + obj2->bob = 99; + obj2->joe = 42; + + if (ast_sorcery_diff(sorcery, obj1, obj2, &changes)) { + ast_test_status_update(test, "Failed to diff obj1 and obj2\n"); + } else if (!changes) { + ast_test_status_update(test, "Failed to produce a diff of two objects, despite there being differences\n"); + return AST_TEST_FAIL; + } + + for (field = changes; field; field = field->next) { + if (!strcmp(field->name, "yes")) { + if (strcmp(field->value, "itworks")) { + ast_test_status_update(test, "Object diff produced unexpected value '%s' for joe\n", field->value); + res = AST_TEST_FAIL; + } + } else { + ast_test_status_update(test, "Object diff produced unexpected field '%s'\n", field->name); + res = AST_TEST_FAIL; + } + } + + return res; +} + AST_TEST_DEFINE(objectset_create) { int res = AST_TEST_PASS; @@ -1946,7 +2084,9 @@ static int unload_module(void) AST_TEST_UNREGISTER(object_alloc_with_id); AST_TEST_UNREGISTER(object_alloc_without_id); AST_TEST_UNREGISTER(object_copy); + AST_TEST_UNREGISTER(object_copy_native); AST_TEST_UNREGISTER(object_diff); + AST_TEST_UNREGISTER(object_diff_native); AST_TEST_UNREGISTER(objectset_create); AST_TEST_UNREGISTER(objectset_apply); AST_TEST_UNREGISTER(objectset_apply_handler); @@ -1985,7 +2125,9 @@ static int load_module(void) AST_TEST_REGISTER(object_alloc_with_id); AST_TEST_REGISTER(object_alloc_without_id); AST_TEST_REGISTER(object_copy); + AST_TEST_REGISTER(object_copy_native); AST_TEST_REGISTER(object_diff); + AST_TEST_REGISTER(object_diff_native); AST_TEST_REGISTER(objectset_create); AST_TEST_REGISTER(objectset_apply); AST_TEST_REGISTER(objectset_apply_handler); |