mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
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
This commit is contained in:
@@ -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);
|
||||
|
Reference in New Issue
Block a user