summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2013-02-10 14:58:37 +0000
committerJoshua Colp <jcolp@digium.com>2013-02-10 14:58:37 +0000
commit27882b859976103e4e039b0107c0290604b17380 (patch)
tree287554cf4890bc30e0ddf9adfe8611a01ebc3878 /tests
parent0e442112ada90d53cf8991b63bd3970cfaa7cc7a (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')
-rw-r--r--tests/test_sorcery.c156
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);