From 637c8f065efead83f56455a4ab45785e34ed56fb Mon Sep 17 00:00:00 2001 From: George Joseph Date: Tue, 5 May 2015 14:32:08 -0600 Subject: sorcery: Add API to insert/remove a wizard to/from an object type's list Currently you can 'apply' a wizard to an object type but the wizard always goes at the end of the object type's wizard list. This patch adds a new ast_sorcery_insert_wizard_mapping function that allows you to insert a wizard anyplace in the list. I.E. You could add a caching wizard to an object type and place it before all wizards. ast_sorcery_get_wizard_mapping_count and ast_sorcery_get_wizard_mapping were added to allow examination of the mapping list. ast_sorcery_remove_mapping was added to remove a mapping by name. As part of this patch, the object type's wizard list was converted from an ao2_container to an AST_VECTOR_RW. A new test was added to test_sorcery for this capability. ASTERISK-25044 #close Change-Id: I9d2469a9296b2698082c0989e25e6848dc403b57 --- tests/test_sorcery.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 131 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test_sorcery.c b/tests/test_sorcery.c index 9d32e3b8d..521d6e861 100644 --- a/tests/test_sorcery.c +++ b/tests/test_sorcery.c @@ -179,6 +179,19 @@ static struct sorcery_test_caching cache = { 0, }; /*! \brief Global scope observer structure for testing */ static struct sorcery_test_observer observer; +static void *wizard2_data; + +static void *sorcery_test_open(const char *data) +{ + wizard2_data = (void *)data; + return wizard2_data; +} + +static void sorcery_test_close(void *data) +{ + +} + static int sorcery_test_create(const struct ast_sorcery *sorcery, void *data, void *object) { cache.created = 1; @@ -204,7 +217,7 @@ static int sorcery_test_delete(const struct ast_sorcery *sorcery, void *data, vo return 0; } -/*! \brief Dummy sorcery wizard, not actually used so we only populate the name and nothing else */ +/*! \brief Dummy sorcery wizards, not actually used so we only populate the name and nothing else */ static struct ast_sorcery_wizard test_wizard = { .name = "test", .create = sorcery_test_create, @@ -213,6 +226,16 @@ static struct ast_sorcery_wizard test_wizard = { .delete = sorcery_test_delete, }; +static struct ast_sorcery_wizard test_wizard2 = { + .name = "test2", + .open = sorcery_test_open, + .close = sorcery_test_close, + .create = sorcery_test_create, + .retrieve_id = sorcery_test_retrieve_id, + .update = sorcery_test_update, + .delete = sorcery_test_delete, +}; + static void sorcery_observer_created(const void *object) { SCOPED_MUTEX(lock, &observer.lock); @@ -3340,6 +3363,111 @@ AST_TEST_DEFINE(wizard_observation) return AST_TEST_PASS; } +AST_TEST_DEFINE(wizard_apply_and_insert) +{ + RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref); + RAII_VAR(struct ast_sorcery_wizard *, wizard1, &test_wizard, ast_sorcery_wizard_unregister); + RAII_VAR(struct ast_sorcery_wizard *, wizard2, &test_wizard2, ast_sorcery_wizard_unregister); + RAII_VAR(struct ast_sorcery_wizard *, wizard, NULL, ao2_cleanup); + void *data; + + switch (cmd) { + case TEST_INIT: + info->name = "wizard_apply_and_insert"; + info->category = "/main/sorcery/"; + info->summary = "sorcery wizard apply and insert test"; + info->description = + "sorcery wizard apply and insert test"; + return AST_TEST_NOT_RUN; + case TEST_EXECUTE: + break; + } + + wizard1->load = sorcery_test_load; + wizard1->reload = sorcery_test_load; + + wizard2->load = sorcery_test_load; + wizard2->reload = sorcery_test_load; + + if (!(sorcery = ast_sorcery_open())) { + ast_test_status_update(test, "Failed to open a sorcery instance\n"); + return AST_TEST_FAIL; + } + + ast_sorcery_wizard_register(wizard1); + ast_sorcery_wizard_register(wizard2); + + /* test_object_type isn't registered yet so count should return error */ + ast_test_validate(test, + ast_sorcery_get_wizard_mapping_count(sorcery, "test_object_type") == -1); + + ast_sorcery_apply_default(sorcery, "test_object_type", "test", NULL); + + ast_test_validate(test, + ast_sorcery_get_wizard_mapping_count(sorcery, "test_object_type") == 1); + + ast_test_validate(test, + ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 0, &wizard, NULL) == 0); + ast_test_validate(test, strcmp("test", wizard->name) == 0); + ao2_ref(wizard, -1); + wizard = NULL; + + ast_test_validate(test, + ast_sorcery_insert_wizard_mapping(sorcery, "test_object_type", "test2", "test2data", 0, 0) == 0); + + ast_test_validate(test, + ast_sorcery_insert_wizard_mapping(sorcery, "test_object_type", "test2", "test2data", 0, 0) != 0); + + ast_test_validate(test, + ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 0, &wizard, &data) == 0); + ast_test_validate(test, strcmp("test2", wizard->name) == 0); + ast_test_validate(test, strcmp("test2data", data) == 0); + ao2_ref(wizard, -1); + wizard = NULL; + + ast_test_validate(test, + ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 1, &wizard, NULL) == 0); + ast_test_validate(test, strcmp("test", wizard->name) == 0); + ao2_ref(wizard, -1); + wizard = NULL; + + /* Test failures */ + ast_test_validate(test, + ast_sorcery_get_wizard_mapping(sorcery, "non-existent-type", 0, &wizard, NULL) != 0); + + ast_test_validate(test, + ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", -1, &wizard, &data) != 0); + + ast_test_validate(test, + ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 2, &wizard, NULL) != 0); + + ast_test_validate(test, + ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 2, NULL, NULL) != 0); + + /* Test remove */ + /* Should fail */ + ast_test_validate(test, + ast_sorcery_remove_wizard_mapping(sorcery, "non-existent-type", "somewizard") != 0); + ast_test_validate(test, + ast_sorcery_remove_wizard_mapping(sorcery, "test_object_type", "somewizard") != 0); + + /* should work */ + ast_test_validate(test, + ast_sorcery_remove_wizard_mapping(sorcery, "test_object_type", "test") == 0); + + ast_test_validate(test, + ast_sorcery_get_wizard_mapping_count(sorcery, "test_object_type") == 1); + + ast_test_validate(test, + ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 0, &wizard, &data) == 0); + ast_test_validate(test, strcmp("test2", wizard->name) == 0); + ast_test_validate(test, strcmp("test2data", data) == 0); + ao2_ref(wizard, -1); + wizard = NULL; + + return AST_TEST_PASS; +} + static int unload_module(void) { AST_TEST_UNREGISTER(wizard_registration); @@ -3390,12 +3518,14 @@ static int unload_module(void) AST_TEST_UNREGISTER(global_observation); AST_TEST_UNREGISTER(instance_observation); AST_TEST_UNREGISTER(wizard_observation); + AST_TEST_UNREGISTER(wizard_apply_and_insert); return 0; } static int load_module(void) { + AST_TEST_REGISTER(wizard_apply_and_insert); AST_TEST_REGISTER(wizard_registration); AST_TEST_REGISTER(sorcery_open); AST_TEST_REGISTER(apply_default); -- cgit v1.2.3