Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Data Structures | Functions | Variables
test_sorcery.c File Reference

Sorcery Unit Tests. More...

#include "asterisk.h"
#include "asterisk/test.h"
#include "asterisk/module.h"
#include "asterisk/astobj2.h"
#include "asterisk/pbx.h"
#include "asterisk/sorcery.h"
#include "asterisk/logger.h"
#include "asterisk/json.h"
Include dependency graph for test_sorcery.c:

Go to the source code of this file.

Data Structures

struct  sorcery_test_caching
 Test structure for caching. More...
 
struct  sorcery_test_observer
 Test structure for observer. More...
 
struct  test_sorcery_object
 Dummy sorcery object. More...
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static struct ast_sorceryalloc_and_initialize_sorcery (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (apply_config)
 
 AST_TEST_DEFINE (apply_default)
 
 AST_TEST_DEFINE (caching_wizard_behavior)
 
 AST_TEST_DEFINE (changeset_create)
 
 AST_TEST_DEFINE (changeset_create_unchanged)
 
 AST_TEST_DEFINE (configuration_file_wizard)
 
 AST_TEST_DEFINE (configuration_file_wizard_retrieve_field)
 
 AST_TEST_DEFINE (configuration_file_wizard_retrieve_multiple)
 
 AST_TEST_DEFINE (configuration_file_wizard_retrieve_multiple_all)
 
 AST_TEST_DEFINE (configuration_file_wizard_with_criteria)
 
 AST_TEST_DEFINE (configuration_file_wizard_with_file_integrity)
 
 AST_TEST_DEFINE (dialplan_function)
 
 AST_TEST_DEFINE (extended_fields)
 
 AST_TEST_DEFINE (global_observation)
 
 AST_TEST_DEFINE (instance_observation)
 
 AST_TEST_DEFINE (object_alloc_with_id)
 
 AST_TEST_DEFINE (object_alloc_without_id)
 
 AST_TEST_DEFINE (object_copy)
 
 AST_TEST_DEFINE (object_copy_native)
 
 AST_TEST_DEFINE (object_create)
 
 AST_TEST_DEFINE (object_delete)
 
 AST_TEST_DEFINE (object_delete_uncreated)
 
 AST_TEST_DEFINE (object_diff)
 
 AST_TEST_DEFINE (object_diff_native)
 
 AST_TEST_DEFINE (object_field_register)
 
 AST_TEST_DEFINE (object_field_registered)
 
 AST_TEST_DEFINE (object_fields_register)
 
 AST_TEST_DEFINE (object_is_stale)
 
 AST_TEST_DEFINE (object_register)
 
 AST_TEST_DEFINE (object_register_without_mapping)
 
 AST_TEST_DEFINE (object_retrieve_field)
 
 AST_TEST_DEFINE (object_retrieve_id)
 
 AST_TEST_DEFINE (object_retrieve_multiple_all)
 
 AST_TEST_DEFINE (object_retrieve_multiple_field)
 
 AST_TEST_DEFINE (object_retrieve_regex)
 
 AST_TEST_DEFINE (object_type_observer)
 
 AST_TEST_DEFINE (object_update)
 
 AST_TEST_DEFINE (object_update_uncreated)
 
 AST_TEST_DEFINE (objectset_apply)
 
 AST_TEST_DEFINE (objectset_apply_fields)
 
 AST_TEST_DEFINE (objectset_apply_handler)
 
 AST_TEST_DEFINE (objectset_apply_invalid)
 
 AST_TEST_DEFINE (objectset_create)
 
 AST_TEST_DEFINE (objectset_create_regex)
 
 AST_TEST_DEFINE (objectset_json_create)
 
 AST_TEST_DEFINE (objectset_transform)
 
 AST_TEST_DEFINE (sorcery_open)
 
 AST_TEST_DEFINE (wizard_apply_and_insert)
 
 AST_TEST_DEFINE (wizard_observation)
 
 AST_TEST_DEFINE (wizard_read_only)
 
 AST_TEST_DEFINE (wizard_registration)
 
static void instance_loaded_observer (const char *name, const struct ast_sorcery *sorcery, int reloaded)
 
static void instance_observer (const char *name, struct ast_sorcery *sorcery)
 
static void instance_reloaded_observer (const char *name, const struct ast_sorcery *sorcery, int reloaded)
 
static int jack_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 
static int jack_str (const void *obj, const intptr_t *args, char **buf)
 
static int jim_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 
static int jim_vl (const void *obj, struct ast_variable **fields)
 
static int load_module (void)
 
static void object_type_loaded_observer (const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
 
static void object_type_registered_observer (const char *name, struct ast_sorcery *sorcery, const char *object_type)
 
static void object_type_reloaded_observer (const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
 
static void sorcery_observer_created (const void *object)
 
static void sorcery_observer_deleted (const void *object)
 
static void sorcery_observer_loaded (const char *object_type)
 
static void sorcery_observer_updated (const void *object)
 
static void sorcery_test_close (void *data)
 
static int sorcery_test_create (const struct ast_sorcery *sorcery, void *data, void *object)
 
static int sorcery_test_delete (const struct ast_sorcery *sorcery, void *data, void *object)
 
static int sorcery_test_is_stale (const struct ast_sorcery *sorcery, void *data, void *object)
 
static void sorcery_test_load (void *data, const struct ast_sorcery *sorcery, const char *type)
 
static void * sorcery_test_open (const char *data)
 
static void * sorcery_test_retrieve_id (const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
 
static int sorcery_test_update (const struct ast_sorcery *sorcery, void *data, void *object)
 
static int test_apply_handler (const struct ast_sorcery *sorcery, void *obj)
 Simple apply handler which sets global scope integer to 1 if called. More...
 
static int test_sorcery_copy (const void *src, void *dst)
 Internal function which copies pre-defined data into an object, natively. More...
 
static int test_sorcery_diff (const void *original, const void *modified, struct ast_variable **changes)
 Internal function which creates a pre-defined diff natively. More...
 
static void * test_sorcery_object_alloc (const char *id)
 Internal function to allocate a test object. More...
 
static void test_sorcery_object_destroy (void *obj)
 Internal function to destroy a test object. More...
 
static int test_sorcery_regex_fields (const void *obj, struct ast_variable **fields)
 Internal function which creates some ast_variable structures. More...
 
static int test_sorcery_regex_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Internal function which sets some values. More...
 
static struct ast_variabletest_sorcery_transform (struct ast_variable *set)
 Internal function for object set transformation. More...
 
static int unload_module (void)
 
static void wizard_loaded_observer (const char *name, const struct ast_sorcery_wizard *wizard, const char *object_type, int reloaded)
 
static void wizard_mapped_observer (const char *name, struct ast_sorcery *sorcery, const char *object_type, struct ast_sorcery_wizard *wizard, const char *wizard_args, void *wizard_data)
 
static void wizard_observer (const char *name, const struct ast_sorcery_wizard *wizard)
 
static void wizard_reloaded_observer (const char *name, const struct ast_sorcery_wizard *wizard, const char *object_type, int reloaded)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Sorcery test module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static int apply_handler_called
 Global scope apply handler integer to make sure it executed. More...
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct sorcery_test_caching cache = { 0, }
 Global scope caching structure for testing. More...
 
static int event_observed
 
static struct sorcery_test_observer observer
 Global scope observer structure for testing. More...
 
static const struct ast_sorcery_observer test_observer
 Test sorcery observer implementation. More...
 
static struct ast_sorcery_wizard test_read_only_wizard
 
static struct ast_sorcery_wizard test_wizard
 Dummy sorcery wizards, not actually used so we only populate the name and nothing else. More...
 
static struct ast_sorcery_wizard test_wizard2
 
static void * wizard2_data
 

Detailed Description

Sorcery Unit Tests.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file test_sorcery.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 3745 of file test_sorcery.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 3745 of file test_sorcery.c.

◆ alloc_and_initialize_sorcery()

static struct ast_sorcery * alloc_and_initialize_sorcery ( void  )
static

Definition at line 332 of file test_sorcery.c.

333{
334 struct ast_sorcery *sorcery;
335
336 if (!(sorcery = ast_sorcery_open())) {
337 return NULL;
338 }
339
343 return NULL;
344 }
345
350
351 return sorcery;
352}
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
@ OPT_UINT_T
Type for default option handler for unsigned integers.
static struct ast_sorcery * sorcery
#define NULL
Definition: resample.c:96
#define ast_sorcery_unref(sorcery)
Decrease the reference count of a sorcery structure.
Definition: sorcery.h:1500
#define ast_sorcery_object_field_register_nodoc(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object without documentation.
Definition: sorcery.h:987
#define ast_sorcery_object_field_register_custom_nodoc(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags,...)
Register a field within an object with custom handlers without documentation.
Definition: sorcery.h:1041
#define ast_sorcery_internal_object_register(sorcery, type, alloc, transform, apply)
Register an internal, hidden object type.
Definition: sorcery.h:867
#define ast_sorcery_apply_default(sorcery, type, name, data)
Definition: sorcery.h:476
#define ast_sorcery_open()
Open a new sorcery structure.
Definition: sorcery.h:406
@ AST_SORCERY_APPLY_SUCCESS
Definition: sorcery.h:427
Full structure for sorcery.
Definition: sorcery.c:230
Dummy sorcery object.
Definition: test_sorcery.c:44
static void * test_sorcery_object_alloc(const char *id)
Internal function to allocate a test object.
Definition: test_sorcery.c:61
static int jim_vl(const void *obj, struct ast_variable **fields)
Definition: test_sorcery.c:307
static int jack_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: test_sorcery.c:294
static int jim_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: test_sorcery.c:284
static int jack_str(const void *obj, const intptr_t *args, char **buf)
Definition: test_sorcery.c:316

References ast_sorcery_apply_default, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_internal_object_register, ast_sorcery_object_field_register_custom_nodoc, ast_sorcery_object_field_register_nodoc, ast_sorcery_open, ast_sorcery_unref, FLDSET, jack_handler(), jack_str(), jim_handler(), jim_vl(), NULL, OPT_UINT_T, sorcery, and test_sorcery_object_alloc().

Referenced by AST_TEST_DEFINE().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 3745 of file test_sorcery.c.

◆ AST_TEST_DEFINE() [1/51]

AST_TEST_DEFINE ( apply_config  )

Definition at line 504 of file test_sorcery.c.

505{
507 struct ast_config *config;
509
510 switch (cmd) {
511 case TEST_INIT:
512 info->name = "apply_config";
513 info->category = "/main/sorcery/";
514 info->summary = "sorcery object mapping configuration unit test";
515 info->description =
516 "Test configured object mapping in sorcery";
517 return AST_TEST_NOT_RUN;
518 case TEST_EXECUTE:
519 break;
520 }
521
522 if (!(config = ast_config_load2("sorcery.conf", "test_sorcery", flags))) {
523 ast_test_status_update(test, "Sorcery configuration file not present - skipping apply_config test\n");
524 return AST_TEST_NOT_RUN;
525 }
526
527 if (!ast_category_get(config, "test_sorcery_section", NULL)) {
528 ast_test_status_update(test, "Sorcery configuration file does not have test_sorcery section\n");
530 return AST_TEST_NOT_RUN;
531 }
532
534
535 if (!(sorcery = ast_sorcery_open())) {
536 ast_test_status_update(test, "Failed to open sorcery structure\n");
537 return AST_TEST_FAIL;
538 }
539
540 if (ast_sorcery_apply_config(sorcery, "test_sorcery_section") != AST_SORCERY_APPLY_SUCCESS) {
541 ast_test_status_update(test, "Failed to apply configured object mappings\n");
542 return AST_TEST_FAIL;
543 }
544
545 return AST_TEST_PASS;
546}
static const char config[]
Definition: chan_ooh323.c:111
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3321
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
struct ast_category * ast_category_get(const struct ast_config *config, const char *category_name, const char *filter)
Retrieve a category if it exists.
Definition: main/config.c:1111
@ CONFIG_FLAG_NOCACHE
def info(msg)
#define ast_sorcery_apply_config(sorcery, name)
Definition: sorcery.h:455
Structure used to handle boolean flags.
Definition: utils.h:199
unsigned int flags
Definition: utils.h:200
@ TEST_INIT
Definition: test.h:200
@ TEST_EXECUTE
Definition: test.h:201
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
@ AST_TEST_PASS
Definition: test.h:195
@ AST_TEST_FAIL
Definition: test.h:196
@ AST_TEST_NOT_RUN
Definition: test.h:194
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References ast_category_get(), ast_config_destroy(), ast_config_load2(), ast_sorcery_apply_config, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_open, ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, config, CONFIG_FLAG_NOCACHE, ast_flags::flags, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [2/51]

AST_TEST_DEFINE ( apply_default  )

Definition at line 465 of file test_sorcery.c.

466{
468
469 switch (cmd) {
470 case TEST_INIT:
471 info->name = "apply_default";
472 info->category = "/main/sorcery/";
473 info->summary = "sorcery default wizard unit test";
474 info->description =
475 "Test setting default type wizard in sorcery";
476 return AST_TEST_NOT_RUN;
477 case TEST_EXECUTE:
478 break;
479 }
480
481 if (!(sorcery = ast_sorcery_open())) {
482 ast_test_status_update(test, "Failed to open sorcery structure\n");
483 return AST_TEST_FAIL;
484 }
485
487 ast_test_status_update(test, "Successfully set a default wizard that doesn't exist\n");
488 return AST_TEST_FAIL;
489 }
490
492 ast_test_status_update(test, "Failed to set a known wizard as a default\n");
493 return AST_TEST_FAIL;
494 }
495
497 ast_test_status_update(test, "Successfully set a default wizard on a type twice\n");
498 return AST_TEST_FAIL;
499 }
500
501 return AST_TEST_PASS;
502}
@ AST_SORCERY_APPLY_FAIL
Definition: sorcery.h:425
@ AST_SORCERY_APPLY_DEFAULT_UNNECESSARY
Definition: sorcery.h:431

References ast_sorcery_apply_default, AST_SORCERY_APPLY_DEFAULT_UNNECESSARY, AST_SORCERY_APPLY_FAIL, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_open, ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [3/51]

AST_TEST_DEFINE ( caching_wizard_behavior  )

Definition at line 2312 of file test_sorcery.c.

2313{
2314 struct ast_flags flags = { CONFIG_FLAG_NOCACHE };
2315 struct ast_config *config;
2318 RAII_VAR(struct test_sorcery_object *, obj2, NULL, ao2_cleanup);
2319 int res = AST_TEST_FAIL;
2320
2321 switch (cmd) {
2322 case TEST_INIT:
2323 info->name = "caching_wizard_behavior";
2324 info->category = "/main/sorcery/";
2325 info->summary = "sorcery caching wizard behavior unit test";
2326 info->description =
2327 "Test internal behavior of caching wizards";
2328 return AST_TEST_NOT_RUN;
2329 case TEST_EXECUTE:
2330 break;
2331 }
2332
2333 if (!(config = ast_config_load2("sorcery.conf", "test_sorcery_cache", flags))) {
2334 ast_test_status_update(test, "Sorcery configuration file not present - skipping caching_wizard_behavior test\n");
2335 return AST_TEST_NOT_RUN;
2336 }
2337
2338 if (!ast_category_get(config, "test_sorcery_cache", NULL)) {
2339 ast_test_status_update(test, "Sorcery configuration file does not contain 'test_sorcery_cache' section\n");
2341 return AST_TEST_NOT_RUN;
2342 }
2343
2345
2347 ast_test_status_update(test, "Failed to register a perfectly valid sorcery wizard\n");
2348 return AST_TEST_FAIL;
2349 }
2350
2351 if (!(sorcery = ast_sorcery_open())) {
2352 ast_test_status_update(test, "Failed to open sorcery structure\n");
2353 goto end;
2354 }
2355
2356 if (ast_sorcery_apply_config(sorcery, "test_sorcery_cache") != AST_SORCERY_APPLY_SUCCESS) {
2357 ast_test_status_update(test, "Failed to apply configured object mappings\n");
2358 goto end;
2359 }
2360
2362 ast_test_status_update(test, "Failed to register object type\n");
2363 goto end;
2364 }
2365
2366 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
2367 ast_test_status_update(test, "Failed to allocate a known object type\n");
2368 goto end;
2369 }
2370
2371 if (ast_sorcery_create(sorcery, obj)) {
2372 ast_test_status_update(test, "Failed to create object using in-memory wizard\n");
2373 goto end;
2374 }
2375
2376 ao2_cleanup(obj);
2377
2378 if (!(obj = ast_sorcery_retrieve_by_id(sorcery, "test", "blah"))) {
2379 ast_test_status_update(test, "Failed to retrieve just created object\n");
2380 goto end;
2381 } else if (!cache.created) {
2382 ast_test_status_update(test, "Caching wizard was not told to cache just created object\n");
2383 goto end;
2384 } else if (!(obj2 = ast_sorcery_retrieve_by_id(sorcery, "test", "blah"))) {
2385 ast_test_status_update(test, "Failed to retrieve just cached object\n");
2386 goto end;
2387 } else if (obj == obj2) {
2388 ast_test_status_update(test, "Returned object is *NOT* a cached object\n");
2389 goto end;
2390 } else if (ast_sorcery_update(sorcery, obj)) {
2391 ast_test_status_update(test, "Failed to update a known stored object\n");
2392 goto end;
2393 } else if (!cache.updated) {
2394 ast_test_status_update(test, "Caching wizard was not told to update object\n");
2395 goto end;
2396 } else if (ast_sorcery_delete(sorcery, obj)) {
2397 ast_test_status_update(test, "Failed to delete a known stored object\n");
2398 goto end;
2399 } else if (!cache.deleted) {
2400 ast_test_status_update(test, "Caching wizard was not told to delete object\n");
2401 goto end;
2402 }
2403
2404 ao2_cleanup(obj2);
2405
2406 if ((obj2 = ast_sorcery_retrieve_by_id(sorcery, "test", "blah"))) {
2407 ast_test_status_update(test, "Retrieved an object that should have been deleted\n");
2408 goto end;
2409 }
2410
2411 res = AST_TEST_PASS;
2412
2413end:
2415 sorcery = NULL;
2416
2418 ast_test_status_update(test, "Failed to unregister test sorcery wizard\n");
2419 return AST_TEST_FAIL;
2420 }
2421
2422 return res;
2423}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
char * end
Definition: eagi_proxy.c:73
int ast_sorcery_wizard_unregister(const struct ast_sorcery_wizard *interface)
Unregister a sorcery wizard.
Definition: sorcery.c:474
int ast_sorcery_create(const struct ast_sorcery *sorcery, void *object)
Create and potentially persist an object using an available wizard.
Definition: sorcery.c:2062
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
#define ast_sorcery_wizard_register(interface)
See __ast_sorcery_wizard_register()
Definition: sorcery.h:383
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
Definition: sorcery.c:1744
int ast_sorcery_update(const struct ast_sorcery *sorcery, void *object)
Update an object.
Definition: sorcery.c:2150
int ast_sorcery_delete(const struct ast_sorcery *sorcery, void *object)
Delete an object.
Definition: sorcery.c:2238
unsigned int updated
Whether the object has been updated in the cache or not.
Definition: test_sorcery.c:134
unsigned int deleted
Whether the object has been deleted from the cache or not.
Definition: test_sorcery.c:137
unsigned int created
Whether the object has been created in the cache or not.
Definition: test_sorcery.c:131
static struct ast_sorcery_wizard test_wizard
Dummy sorcery wizards, not actually used so we only populate the name and nothing else.
Definition: test_sorcery.c:228
static struct sorcery_test_caching cache
Global scope caching structure for testing.
Definition: test_sorcery.c:178

References ao2_cleanup, ast_category_get(), ast_config_destroy(), ast_config_load2(), ast_sorcery_alloc(), ast_sorcery_apply_config, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_create(), ast_sorcery_delete(), ast_sorcery_internal_object_register, ast_sorcery_open, ast_sorcery_retrieve_by_id(), ast_sorcery_unref, ast_sorcery_update(), ast_sorcery_wizard_register, ast_sorcery_wizard_unregister(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, cache, config, CONFIG_FLAG_NOCACHE, sorcery_test_caching::created, sorcery_test_caching::deleted, end, ast_flags::flags, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, test_sorcery_object_alloc(), test_wizard, and sorcery_test_caching::updated.

◆ AST_TEST_DEFINE() [4/51]

AST_TEST_DEFINE ( changeset_create  )

Definition at line 1579 of file test_sorcery.c.

1580{
1581 int res = AST_TEST_PASS;
1582 RAII_VAR(struct ast_variable *, original, NULL, ast_variables_destroy);
1583 RAII_VAR(struct ast_variable *, modified, NULL, ast_variables_destroy);
1584 RAII_VAR(struct ast_variable *, changes, NULL, ast_variables_destroy);
1585 struct ast_variable *tmp;
1586
1587 switch (cmd) {
1588 case TEST_INIT:
1589 info->name = "changeset_create";
1590 info->category = "/main/sorcery/";
1591 info->summary = "sorcery changeset creation unit test";
1592 info->description =
1593 "Test changeset creation in sorcery";
1594 return AST_TEST_NOT_RUN;
1595 case TEST_EXECUTE:
1596 break;
1597 }
1598
1599 if (!(tmp = ast_variable_new("bananas", "purple", ""))) {
1600 ast_test_status_update(test, "Failed to create first field for original objectset\n");
1601 return AST_TEST_FAIL;
1602 }
1603 tmp->next = original;
1604 original = tmp;
1605
1606 if (!(tmp = ast_variable_new("apples", "orange", ""))) {
1607 ast_test_status_update(test, "Failed to create second field for original objectset\n");
1608 return AST_TEST_FAIL;
1609 }
1610 tmp->next = original;
1611 original = tmp;
1612
1613 if (!(tmp = ast_variable_new("bananas", "green", ""))) {
1614 ast_test_status_update(test, "Failed to create first field for modified objectset\n");
1615 return AST_TEST_FAIL;
1616 }
1617 tmp->next = modified;
1618 modified = tmp;
1619
1620 if (!(tmp = ast_variable_new("apples", "orange", ""))) {
1621 ast_test_status_update(test, "Failed to create second field for modified objectset\n");
1622 return AST_TEST_FAIL;
1623 }
1624 tmp->next = modified;
1625 modified = tmp;
1626
1627 if (ast_sorcery_changeset_create(original, modified, &changes)) {
1628 ast_test_status_update(test, "Failed to create a changeset due to an error\n");
1629 return AST_TEST_FAIL;
1630 } else if (!changes) {
1631 ast_test_status_update(test, "Failed to produce a changeset when there should be one\n");
1632 return AST_TEST_FAIL;
1633 }
1634
1635 for (tmp = changes; tmp; tmp = tmp->next) {
1636 if (!strcmp(tmp->name, "bananas")) {
1637 if (strcmp(tmp->value, "green")) {
1638 ast_test_status_update(test, "Changeset produced had unexpected value '%s' for bananas\n", tmp->value);
1639 res = AST_TEST_FAIL;
1640 }
1641 } else {
1642 ast_test_status_update(test, "Changeset produced had unexpected field '%s'\n", tmp->name);
1643 res = AST_TEST_FAIL;
1644 }
1645 }
1646
1647 return res;
1648}
static int tmp()
Definition: bt_open.c:389
#define ast_variable_new(name, value, filename)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
int ast_sorcery_changeset_create(const struct ast_variable *original, const struct ast_variable *modified, struct ast_variable **changes)
Create a changeset given two object sets.
Definition: sorcery.c:1663
Structure for variables, used for configurations and for channel variables.

References ast_sorcery_changeset_create(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variable_new, ast_variables_destroy(), sip_to_pjsip::info(), NULL, RAII_VAR, TEST_EXECUTE, TEST_INIT, and tmp().

◆ AST_TEST_DEFINE() [5/51]

AST_TEST_DEFINE ( changeset_create_unchanged  )

Definition at line 1650 of file test_sorcery.c.

1651{
1652 RAII_VAR(struct ast_variable *, original, NULL, ast_variables_destroy);
1653 RAII_VAR(struct ast_variable *, changes, NULL, ast_variables_destroy);
1655 struct ast_variable *tmp;
1656
1657 switch (cmd) {
1658 case TEST_INIT:
1659 info->name = "changeset_create_unchanged";
1660 info->category = "/main/sorcery/";
1661 info->summary = "sorcery changeset creation unit test when no changes exist";
1662 info->description =
1663 "Test changeset creation in sorcery when no changes actually exist";
1664 return AST_TEST_NOT_RUN;
1665 case TEST_EXECUTE:
1666 break;
1667 }
1668
1669 if (!(tmp = ast_variable_new("bananas", "purple", ""))) {
1670 ast_test_status_update(test, "Failed to create first field for original objectset\n");
1671 return AST_TEST_FAIL;
1672 }
1673 tmp->next = original;
1674 original = tmp;
1675
1676 if (!(tmp = ast_variable_new("apples", "orange", ""))) {
1677 ast_test_status_update(test, "Failed to create second field for original objectset\n");
1678 return AST_TEST_FAIL;
1679 }
1680 tmp->next = original;
1681 original = tmp;
1682
1683 if (ast_sorcery_changeset_create(original, original, &changes)) {
1684 ast_test_status_update(test, "Failed to create a changeset due to an error\n");
1685 return AST_TEST_FAIL;
1686 } else if (changes) {
1687 ast_test_status_update(test, "Created a changeset when no changes actually exist\n");
1688 return AST_TEST_FAIL;
1689 }
1690
1691 if (!(tmp = ast_variable_new("bananas", "purple", ""))) {
1692 ast_test_status_update(test, "Failed to create first field for same objectset\n");
1693 return AST_TEST_FAIL;
1694 }
1695 tmp->next = same;
1696 same = tmp;
1697
1698 if (!(tmp = ast_variable_new("apples", "orange", ""))) {
1699 ast_test_status_update(test, "Failed to create second field for same objectset\n");
1700 return AST_TEST_FAIL;
1701 }
1702 tmp->next = same;
1703 same = tmp;
1704
1705 if (ast_sorcery_changeset_create(original, same, &changes)) {
1706 ast_test_status_update(test, "Failed to create a changeset due to an error\n");
1707 return AST_TEST_FAIL;
1708 } else if (changes) {
1709 ast_test_status_update(test, "Created a changeset between two different objectsets when no changes actually exist\n");
1710 return AST_TEST_FAIL;
1711 }
1712
1713 return AST_TEST_PASS;
1714}

References ast_sorcery_changeset_create(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variable_new, ast_variables_destroy(), sip_to_pjsip::info(), NULL, RAII_VAR, TEST_EXECUTE, TEST_INIT, and tmp().

◆ AST_TEST_DEFINE() [6/51]

AST_TEST_DEFINE ( configuration_file_wizard  )

Definition at line 2570 of file test_sorcery.c.

2571{
2572 struct ast_flags flags = { CONFIG_FLAG_NOCACHE };
2573 struct ast_config *config;
2576
2577 switch (cmd) {
2578 case TEST_INIT:
2579 info->name = "configuration_file_wizard";
2580 info->category = "/main/sorcery/";
2581 info->summary = "sorcery configuration file wizard unit test";
2582 info->description =
2583 "Test the configuration file wizard in sorcery";
2584 return AST_TEST_NOT_RUN;
2585 case TEST_EXECUTE:
2586 break;
2587 }
2588
2589 if (!(config = ast_config_load2("test_sorcery.conf", "test_sorcery", flags))) {
2590 ast_test_status_update(test, "Test sorcery configuration file wizard file not present - skipping configuration_file_wizard test\n");
2591 return AST_TEST_NOT_RUN;
2592 }
2593
2595
2596 if (!(sorcery = ast_sorcery_open())) {
2597 ast_test_status_update(test, "Failed to open sorcery structure\n");
2598 return AST_TEST_FAIL;
2599 }
2600
2601 if (ast_sorcery_apply_default(sorcery, "test", "config", "test_sorcery.conf") != AST_SORCERY_APPLY_SUCCESS) {
2602 ast_test_status_update(test, "Could not set a default wizard of the 'config' type, so skipping since it may not be loaded\n");
2603 return AST_TEST_NOT_RUN;
2604 }
2605
2607 ast_test_status_update(test, "Failed to register object type\n");
2608 return AST_TEST_FAIL;
2609 }
2610
2613
2615
2616 if ((obj = ast_sorcery_retrieve_by_id(sorcery, "test", "hey2"))) {
2617 ast_test_status_update(test, "Retrieved object which has an unknown field\n");
2618 return AST_TEST_FAIL;
2619 } else if (!(obj = ast_sorcery_retrieve_by_id(sorcery, "test", "hey"))) {
2620 ast_test_status_update(test, "Failed to retrieve a known object that has been configured in the configuration file\n");
2621 return AST_TEST_FAIL;
2622 } else if (obj->bob != 98) {
2623 ast_test_status_update(test, "Value of 'bob' on object is not what is configured in configuration file\n");
2624 return AST_TEST_FAIL;
2625 } else if (obj->joe != 41) {
2626 ast_test_status_update(test, "Value of 'joe' on object is not what is configured in configuration file\n");
2627 return AST_TEST_FAIL;
2628 }
2629
2630 return AST_TEST_PASS;
2631}
void ast_sorcery_load(const struct ast_sorcery *sorcery)
Inform any wizards to load persistent objects.
Definition: sorcery.c:1377

References ao2_cleanup, ast_config_destroy(), ast_config_load2(), ast_sorcery_apply_default, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_internal_object_register, ast_sorcery_load(), ast_sorcery_object_field_register_nodoc, ast_sorcery_open, ast_sorcery_retrieve_by_id(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, config, CONFIG_FLAG_NOCACHE, ast_flags::flags, FLDSET, sip_to_pjsip::info(), NULL, OPT_UINT_T, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, and test_sorcery_object_alloc().

◆ AST_TEST_DEFINE() [7/51]

AST_TEST_DEFINE ( configuration_file_wizard_retrieve_field  )

Definition at line 2745 of file test_sorcery.c.

2746{
2747 struct ast_flags flags = { CONFIG_FLAG_NOCACHE };
2748 struct ast_config *config;
2751 RAII_VAR(struct ast_variable *, fields, ast_variable_new("joe", "41", ""), ast_variables_destroy);
2752
2753 switch (cmd) {
2754 case TEST_INIT:
2755 info->name = "configuration_file_wizard_retrieve_field";
2756 info->category = "/main/sorcery/";
2757 info->summary = "sorcery configuration file wizard field retrieval unit test";
2758 info->description =
2759 "Test the configuration file wizard retrieval using field in sorcery";
2760 return AST_TEST_NOT_RUN;
2761 case TEST_EXECUTE:
2762 break;
2763 }
2764
2765 if (!(config = ast_config_load2("test_sorcery.conf", "test_sorcery", flags))) {
2766 ast_test_status_update(test, "Test sorcery configuration file wizard file not present - skipping configuration_file_wizard_retrieve_field test\n");
2767 return AST_TEST_NOT_RUN;
2768 }
2769
2771
2772 if (!(sorcery = ast_sorcery_open())) {
2773 ast_test_status_update(test, "Failed to open sorcery structure\n");
2774 return AST_TEST_FAIL;
2775 }
2776
2777 if (ast_sorcery_apply_default(sorcery, "test", "config", "test_sorcery.conf") != AST_SORCERY_APPLY_SUCCESS) {
2778 ast_test_status_update(test, "Could not set a default wizard of the 'config' type, so skipping since it may not be loaded\n");
2779 return AST_TEST_NOT_RUN;
2780 }
2781
2783 ast_test_status_update(test, "Failed to register object type\n");
2784 return AST_TEST_FAIL;
2785 }
2786
2789
2791
2792 if (!(obj = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, fields))) {
2793 ast_test_status_update(test, "Failed to retrieve a known object that has been configured with the correct field\n");
2794 return AST_TEST_FAIL;
2795 } else if (strcmp(ast_sorcery_object_get_id(obj), "hey")) {
2796 ast_test_status_update(test, "Retrieved object has incorrect object id of '%s'\n", ast_sorcery_object_get_id(obj));
2797 return AST_TEST_FAIL;
2798 }
2799
2800 return AST_TEST_PASS;
2801}
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2317
@ AST_RETRIEVE_FLAG_DEFAULT
Default retrieval flags.
Definition: sorcery.h:117
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
Definition: sorcery.c:1897

References ao2_cleanup, ast_config_destroy(), ast_config_load2(), AST_RETRIEVE_FLAG_DEFAULT, ast_sorcery_apply_default, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_internal_object_register, ast_sorcery_load(), ast_sorcery_object_field_register_nodoc, ast_sorcery_object_get_id(), ast_sorcery_open, ast_sorcery_retrieve_by_fields(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variable_new, ast_variables_destroy(), config, CONFIG_FLAG_NOCACHE, ast_flags::flags, FLDSET, sip_to_pjsip::info(), NULL, OPT_UINT_T, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, and test_sorcery_object_alloc().

◆ AST_TEST_DEFINE() [8/51]

AST_TEST_DEFINE ( configuration_file_wizard_retrieve_multiple  )

Definition at line 2803 of file test_sorcery.c.

2804{
2805 struct ast_flags flags = { CONFIG_FLAG_NOCACHE };
2806 struct ast_config *config;
2808 RAII_VAR(struct ao2_container *, objects, NULL, ao2_cleanup);
2809 RAII_VAR(struct ast_variable *, fields, ast_variable_new("joe", "99", ""), ast_variables_destroy);
2810
2811 switch (cmd) {
2812 case TEST_INIT:
2813 info->name = "configuration_file_wizard_retrieve_multiple";
2814 info->category = "/main/sorcery/";
2815 info->summary = "sorcery configuration file wizard multiple retrieval unit test";
2816 info->description =
2817 "Test the configuration file wizard multiple retrieval in sorcery";
2818 return AST_TEST_NOT_RUN;
2819 case TEST_EXECUTE:
2820 break;
2821 }
2822
2823 if (!(config = ast_config_load2("test_sorcery.conf", "test_sorcery", flags))) {
2824 ast_test_status_update(test, "Test sorcery configuration file wizard file not present - skipping configuration_file_wizard_retrieve_multiple test\n");
2825 return AST_TEST_NOT_RUN;
2826 }
2827
2829
2830 if (!fields) {
2831 ast_test_status_update(test, "Failed to create fields for multiple retrieve\n");
2832 return AST_TEST_FAIL;
2833 }
2834
2835 if (!(sorcery = ast_sorcery_open())) {
2836 ast_test_status_update(test, "Failed to open sorcery structure\n");
2837 return AST_TEST_FAIL;
2838 }
2839
2840 if (ast_sorcery_apply_default(sorcery, "test", "config", "test_sorcery.conf") != AST_SORCERY_APPLY_SUCCESS) {
2841 ast_test_status_update(test, "Could not set a default wizard of the 'config' type, so skipping since it may not be loaded\n");
2842 return AST_TEST_NOT_RUN;
2843 }
2844
2846 ast_test_status_update(test, "Failed to register object type\n");
2847 return AST_TEST_FAIL;
2848 }
2849
2852
2854
2855 if (!(objects = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE, fields))) {
2856 ast_test_status_update(test, "Failed to retrieve an empty container when retrieving multiple\n");
2857 return AST_TEST_FAIL;
2858 } else if (ao2_container_count(objects)) {
2859 ast_test_status_update(test, "Received a container with objects when there should be none in it\n");
2860 return AST_TEST_FAIL;
2861 }
2862
2863 ao2_cleanup(objects);
2864 ast_variables_destroy(fields);
2865
2866 if (!(fields = ast_variable_new("joe", "41", ""))) {
2867 ast_test_status_update(test, "Failed to create fields for multiple retrieve\n");
2868 return AST_TEST_FAIL;
2869 } else if (!(objects = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE, fields))) {
2870 ast_test_status_update(test, "Failed to retrieve a container when retrieving multiple\n");
2871 return AST_TEST_FAIL;
2872 } else if (ao2_container_count(objects) != 1) {
2873 ast_test_status_update(test, "Received a container with no objects in it when there should be\n");
2874 return AST_TEST_FAIL;
2875 }
2876
2877 return AST_TEST_PASS;
2878}
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
Definition: sorcery.h:120
Generic container type.

References ao2_cleanup, ao2_container_count(), ast_config_destroy(), ast_config_load2(), AST_RETRIEVE_FLAG_MULTIPLE, ast_sorcery_apply_default, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_internal_object_register, ast_sorcery_load(), ast_sorcery_object_field_register_nodoc, ast_sorcery_open, ast_sorcery_retrieve_by_fields(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variable_new, ast_variables_destroy(), config, CONFIG_FLAG_NOCACHE, ast_flags::flags, FLDSET, sip_to_pjsip::info(), NULL, OPT_UINT_T, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, and test_sorcery_object_alloc().

◆ AST_TEST_DEFINE() [9/51]

AST_TEST_DEFINE ( configuration_file_wizard_retrieve_multiple_all  )

Definition at line 2880 of file test_sorcery.c.

2881{
2882 struct ast_flags flags = { CONFIG_FLAG_NOCACHE };
2883 struct ast_config *config;
2885 RAII_VAR(struct ao2_container *, objects, NULL, ao2_cleanup);
2886
2887 switch (cmd) {
2888 case TEST_INIT:
2889 info->name = "configuration_file_wizard_retrieve_multiple_all";
2890 info->category = "/main/sorcery/";
2891 info->summary = "sorcery configuration file wizard multiple retrieve all unit test";
2892 info->description =
2893 "Test the configuration file wizard multiple retrieve all in sorcery";
2894 return AST_TEST_NOT_RUN;
2895 case TEST_EXECUTE:
2896 break;
2897 }
2898
2899 if (!(config = ast_config_load2("test_sorcery.conf", "test_sorcery", flags))) {
2900 ast_test_status_update(test, "Test sorcery configuration file wizard file not present - skipping configuration_file_wizard_retrieve_multiple_all test\n");
2901 return AST_TEST_NOT_RUN;
2902 }
2903
2905
2906 if (!(sorcery = ast_sorcery_open())) {
2907 ast_test_status_update(test, "Failed to open sorcery structure\n");
2908 return AST_TEST_FAIL;
2909 }
2910
2911 if (ast_sorcery_apply_default(sorcery, "test", "config", "test_sorcery.conf") != AST_SORCERY_APPLY_SUCCESS) {
2912 ast_test_status_update(test, "Could not set a default wizard of the 'config' type, so skipping since it may not be loaded\n");
2913 return AST_TEST_NOT_RUN;
2914 }
2915
2917 ast_test_status_update(test, "Failed to register object type\n");
2918 return AST_TEST_FAIL;
2919 }
2920
2923
2925
2927 ast_test_status_update(test, "Failed to retrieve a container with all objects when there should be one\n");
2928 return AST_TEST_FAIL;
2929 } else if (ao2_container_count(objects) != 2) {
2930 ast_test_status_update(test, "Returned container does not have the correct number of objects in it\n");
2931 return AST_TEST_FAIL;
2932 }
2933
2934 return AST_TEST_PASS;
2935}
@ AST_RETRIEVE_FLAG_ALL
Perform no matching, return all objects.
Definition: sorcery.h:123

References ao2_cleanup, ao2_container_count(), ast_config_destroy(), ast_config_load2(), AST_RETRIEVE_FLAG_ALL, AST_RETRIEVE_FLAG_MULTIPLE, ast_sorcery_apply_default, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_internal_object_register, ast_sorcery_load(), ast_sorcery_object_field_register_nodoc, ast_sorcery_open, ast_sorcery_retrieve_by_fields(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, config, CONFIG_FLAG_NOCACHE, ast_flags::flags, FLDSET, sip_to_pjsip::info(), NULL, OPT_UINT_T, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, and test_sorcery_object_alloc().

◆ AST_TEST_DEFINE() [10/51]

AST_TEST_DEFINE ( configuration_file_wizard_with_criteria  )

Definition at line 2687 of file test_sorcery.c.

2688{
2689 struct ast_flags flags = { CONFIG_FLAG_NOCACHE };
2690 struct ast_config *config;
2693
2694 switch (cmd) {
2695 case TEST_INIT:
2696 info->name = "configuration_file_wizard_with_criteria";
2697 info->category = "/main/sorcery/";
2698 info->summary = "sorcery configuration file wizard with criteria unit test";
2699 info->description =
2700 "Test the configuration file wizard with criteria matching in sorcery";
2701 return AST_TEST_NOT_RUN;
2702 case TEST_EXECUTE:
2703 break;
2704 }
2705
2706 if (!(config = ast_config_load2("test_sorcery.conf", "test_sorcery", flags))) {
2707 ast_test_status_update(test, "Test sorcery configuration file wizard file not present - skipping configuration_file_wizard_with_criteria test\n");
2708 return AST_TEST_NOT_RUN;
2709 }
2710
2712
2713 if (!(sorcery = ast_sorcery_open())) {
2714 ast_test_status_update(test, "Failed to open sorcery structure\n");
2715 return AST_TEST_FAIL;
2716 }
2717
2718 if (ast_sorcery_apply_default(sorcery, "test", "config", "test_sorcery.conf,criteria=type=zombies") != AST_SORCERY_APPLY_SUCCESS) {
2719 ast_test_status_update(test, "Could not set a default wizard of the 'config' type, so skipping since it may not be loaded\n");
2720 return AST_TEST_NOT_RUN;
2721 }
2722
2724 ast_test_status_update(test, "Failed to register object type\n");
2725 return AST_TEST_FAIL;
2726 }
2727
2731
2733
2734 if ((obj = ast_sorcery_retrieve_by_id(sorcery, "test", "hey"))) {
2735 ast_test_status_update(test, "Retrieved object which did not match criteria\n");
2736 return AST_TEST_FAIL;
2737 } else if (!(obj = ast_sorcery_retrieve_by_id(sorcery, "test", "hey2"))) {
2738 ast_test_status_update(test, "Failed to retrieve a known object which matches criteria\n");
2739 return AST_TEST_FAIL;
2740 }
2741
2742 return AST_TEST_PASS;
2743}
@ OPT_NOOP_T
Type for a default handler that should do nothing.

References ao2_cleanup, ast_config_destroy(), ast_config_load2(), ast_sorcery_apply_default, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_internal_object_register, ast_sorcery_load(), ast_sorcery_object_field_register_nodoc, ast_sorcery_open, ast_sorcery_retrieve_by_id(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, config, CONFIG_FLAG_NOCACHE, ast_flags::flags, FLDSET, sip_to_pjsip::info(), NULL, OPT_NOOP_T, OPT_UINT_T, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, and test_sorcery_object_alloc().

◆ AST_TEST_DEFINE() [11/51]

AST_TEST_DEFINE ( configuration_file_wizard_with_file_integrity  )

Definition at line 2633 of file test_sorcery.c.

2634{
2635 struct ast_flags flags = { CONFIG_FLAG_NOCACHE };
2636 struct ast_config *config;
2639
2640 switch (cmd) {
2641 case TEST_INIT:
2642 info->name = "configuration_file_wizard_with_file_integrity";
2643 info->category = "/main/sorcery/";
2644 info->summary = "sorcery configuration file wizard file integrity unit test";
2645 info->description =
2646 "Test the configuration file wizard with file integrity turned on in sorcery";
2647 return AST_TEST_NOT_RUN;
2648 case TEST_EXECUTE:
2649 break;
2650 }
2651
2652 if (!(config = ast_config_load2("test_sorcery.conf", "test_sorcery", flags))) {
2653 ast_test_status_update(test, "Test sorcery configuration file wizard file not present - skipping configuration_file_wizard_with_file_integrity test\n");
2654 return AST_TEST_NOT_RUN;
2655 }
2656
2658
2659 if (!(sorcery = ast_sorcery_open())) {
2660 ast_test_status_update(test, "Failed to open sorcery structure\n");
2661 return AST_TEST_FAIL;
2662 }
2663
2664 if (ast_sorcery_apply_default(sorcery, "test", "config", "test_sorcery.conf,integrity=file") != AST_SORCERY_APPLY_SUCCESS) {
2665 ast_test_status_update(test, "Could not set a default wizard of the 'config' type, so skipping since it may not be loaded\n");
2666 return AST_TEST_NOT_RUN;
2667 }
2668
2670 ast_test_status_update(test, "Failed to register object type\n");
2671 return AST_TEST_FAIL;
2672 }
2673
2676
2678
2679 if ((obj = ast_sorcery_retrieve_by_id(sorcery, "test", "hey"))) {
2680 ast_test_status_update(test, "Retrieved object which has an unknown field\n");
2681 return AST_TEST_FAIL;
2682 }
2683
2684 return AST_TEST_PASS;
2685}

References ao2_cleanup, ast_config_destroy(), ast_config_load2(), ast_sorcery_apply_default, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_internal_object_register, ast_sorcery_load(), ast_sorcery_object_field_register_nodoc, ast_sorcery_open, ast_sorcery_retrieve_by_id(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, config, CONFIG_FLAG_NOCACHE, ast_flags::flags, FLDSET, sip_to_pjsip::info(), NULL, OPT_UINT_T, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, and test_sorcery_object_alloc().

◆ AST_TEST_DEFINE() [12/51]

AST_TEST_DEFINE ( dialplan_function  )

Definition at line 2937 of file test_sorcery.c.

2938{
2941 RAII_VAR(struct ast_variable *, objset, NULL, ast_variables_destroy);
2942 struct ast_str *buf;
2943 char expression[256];
2944
2945 switch (cmd) {
2946 case TEST_INIT:
2947 info->name = "dialplan_function";
2948 info->category = "/main/sorcery/";
2949 info->summary = "AST_SORCERY dialplan function";
2950 info->description =
2951 "Test the AST_SORCERY dialplan function";
2952 return AST_TEST_NOT_RUN;
2953 case TEST_EXECUTE:
2954 break;
2955 }
2956
2958 ast_test_status_update(test, "Failed to open sorcery structure\n");
2959 return AST_TEST_FAIL;
2960 }
2961
2962 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
2963 ast_test_status_update(test, "Failed to allocate a known object type\n");
2964 return AST_TEST_FAIL;
2965 }
2966
2967 if (ast_sorcery_create(sorcery, obj)) {
2968 ast_test_status_update(test, "Failed to create a known object type\n");
2969 return AST_TEST_FAIL;
2970 }
2971
2972 if (!(buf = ast_str_create(16))) {
2973 ast_test_status_update(test, "Failed to allocate return buffer\n");
2974 return AST_TEST_FAIL;
2975 }
2976
2978 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s)", "notest_sorcery", "test", "blah", "bob");
2979 if (!ast_func_read2(NULL, expression, &buf, 16)) {
2980 ast_free(buf);
2981 ast_test_status_update(test, "Retrieved a non-existent module\n");
2982 return AST_TEST_FAIL;
2983 }
2984
2986 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s)", "test_sorcery", "notest", "blah", "bob");
2987 if (!ast_func_read2(NULL, expression, &buf, 16)) {
2988 ast_free(buf);
2989 ast_test_status_update(test, "Retrieved a non-existent type\n");
2990 return AST_TEST_FAIL;
2991 }
2992
2994 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s)", "test_sorcery", "test", "noid", "bob");
2995 if (!ast_func_read2(NULL, expression, &buf, 16)) {
2996 ast_free(buf);
2997 ast_test_status_update(test, "Retrieved a non-existent id\n");
2998 return AST_TEST_FAIL;
2999 }
3000
3002 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s)", "test_sorcery", "test", "blah", "nobob");
3003 if (!ast_func_read2(NULL, expression, &buf, 16)) {
3004 ast_free(buf);
3005 ast_test_status_update(test, "Retrieved a non-existent field\n");
3006 return AST_TEST_FAIL;
3007 }
3008
3010 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s)", "test_sorcery", "test", "blah", "bob");
3011 if (ast_func_read2(NULL, expression, &buf, 16)) {
3012 ast_free(buf);
3013 ast_test_status_update(test, "Failed retrieve field 'bob'\n");
3014 return AST_TEST_FAIL;
3015 }
3016 if (strcmp(ast_str_buffer(buf), "5")) {
3017 ast_free(buf);
3018 ast_test_status_update(test, "Failed retrieve field. Got '%u', should be '5'\n", obj->bob);
3019 return AST_TEST_FAIL;
3020 }
3021
3023 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s,single,1)", "test_sorcery", "test", "blah", "bob");
3024 if (ast_func_read2(NULL, expression, &buf, 16)) {
3025 ast_free(buf);
3026 ast_test_status_update(test, "Failed retrieve field 'bob'\n");
3027 return AST_TEST_FAIL;
3028 }
3029 if (strcmp(ast_str_buffer(buf), "5")) {
3030 ast_free(buf);
3031 ast_test_status_update(test, "Failed retrieve field. Got '%u', should be '5'\n", obj->bob);
3032 return AST_TEST_FAIL;
3033 }
3034
3036 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s,single,2)", "test_sorcery", "test", "blah", "bob");
3037 if (!ast_func_read2(NULL, expression, &buf, 16)) {
3038 ast_free(buf);
3039 ast_test_status_update(test, "Got a second 'bob' and shouldn't have\n");
3040 return AST_TEST_FAIL;
3041 }
3042
3043 /* 444 is already the first item in the list */
3044 jim_handler(NULL, ast_variable_new("jim", "555", ""), obj);
3045 jim_handler(NULL, ast_variable_new("jim", "666", ""), obj);
3046
3048 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s)", "test_sorcery", "test", "blah", "jim");
3049 if (ast_func_read2(NULL, expression, &buf, 16)) {
3050 ast_free(buf);
3051 ast_test_status_update(test, "Couldn't retrieve 'jim'\n");
3052 return AST_TEST_FAIL;
3053 }
3054 if (strcmp(ast_str_buffer(buf), "444,555,666")) {
3055 ast_free(buf);
3056 ast_test_status_update(test, "Failed retrieve jim. Got '%s', should be '444,555,666'\n", ast_str_buffer(buf));
3057 return AST_TEST_FAIL;
3058 }
3059
3061 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s,single,2)", "test_sorcery", "test", "blah", "jim");
3062 if (ast_func_read2(NULL, expression, &buf, 16)) {
3063 ast_free(buf);
3064 ast_test_status_update(test, "Couldn't retrieve 2nd jim\n");
3065 return AST_TEST_FAIL;
3066 }
3067 if (strcmp(ast_str_buffer(buf), "555")) {
3068 ast_free(buf);
3069 ast_test_status_update(test, "Failed retrieve 2nd jim. Got '%s', should be '555'\n", ast_str_buffer(buf));
3070 return AST_TEST_FAIL;
3071 }
3072
3074 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s,concat,|)", "test_sorcery", "test", "blah", "jim");
3075 if (ast_func_read2(NULL, expression, &buf, 16)) {
3076 ast_free(buf);
3077 ast_test_status_update(test, "Couldn't retrieve any 'jim'\n");
3078 return AST_TEST_FAIL;
3079 }
3080 if (strcmp(ast_str_buffer(buf), "444|555|666")) {
3081 ast_free(buf);
3082 ast_test_status_update(test, "Failed retrieve 'jim'. Got '%s', should be '444|555|666'\n", ast_str_buffer(buf));
3083 return AST_TEST_FAIL;
3084 }
3085
3087 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s,noconcat,3)", "test_sorcery", "test", "blah", "jim");
3088 if (!ast_func_read2(NULL, expression, &buf, 16)) {
3089 ast_free(buf);
3090 ast_test_status_update(test, "Should have failed with invalid retrieval_type\n");
3091 return AST_TEST_FAIL;
3092 }
3093
3095 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s,single,|)", "test_sorcery", "test", "blah", "jim");
3096 if (!ast_func_read2(NULL, expression, &buf, 16)) {
3097 ast_free(buf);
3098 ast_test_status_update(test, "Should have failed with invalid occurrence_number\n");
3099 return AST_TEST_FAIL;
3100 }
3101
3102 ast_free(buf);
3103
3104 return AST_TEST_PASS;
3105}
#define ast_free(a)
Definition: astmm.h:180
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int ast_func_read2(struct ast_channel *chan, const char *function, struct ast_str **str, ssize_t maxlen)
executes a read operation on a function
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:693
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
Support for dynamic strings.
Definition: strings.h:623
static struct ast_sorcery * alloc_and_initialize_sorcery(void)
Definition: test_sorcery.c:332

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_free, ast_func_read2(), ast_sorcery_alloc(), ast_sorcery_create(), ast_sorcery_unref, ast_str_buffer(), ast_str_create, ast_str_reset(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variable_new, ast_variables_destroy(), buf, sip_to_pjsip::info(), jim_handler(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [13/51]

AST_TEST_DEFINE ( extended_fields  )

Definition at line 1514 of file test_sorcery.c.

1515{
1516 int res = AST_TEST_PASS;
1519 RAII_VAR(struct ast_variable *, objset, NULL, ast_variables_destroy);
1520 const char *value;
1521
1522 switch (cmd) {
1523 case TEST_INIT:
1524 info->name = "extended_fields";
1525 info->category = "/main/sorcery/";
1526 info->summary = "sorcery object extended fields unit test";
1527 info->description =
1528 "Test extended fields support in sorcery";
1529 return AST_TEST_NOT_RUN;
1530 case TEST_EXECUTE:
1531 break;
1532 }
1533
1535 ast_test_status_update(test, "Failed to open sorcery structure\n");
1536 return AST_TEST_FAIL;
1537 }
1538
1539 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
1540 ast_test_status_update(test, "Failed to allocate a known object type\n");
1541 return AST_TEST_FAIL;
1542 }
1543
1544 if (!(objset = ast_variable_new("@testing", "toast", ""))) {
1545 ast_test_status_update(test, "Failed to create an object set, test could not occur\n");
1546 res = AST_TEST_FAIL;
1547 } else if (ast_sorcery_objectset_apply(sorcery, obj, objset)) {
1548 ast_test_status_update(test, "Failed to apply valid object set to object\n");
1549 res = AST_TEST_FAIL;
1550 } else if (!(value = ast_sorcery_object_get_extended(obj, "testing"))) {
1551 ast_test_status_update(test, "Extended field, which was set using object set, could not be found\n");
1552 res = AST_TEST_FAIL;
1553 } else if (strcmp(value, "toast")) {
1554 ast_test_status_update(test, "Extended field does not contain expected value\n");
1555 res = AST_TEST_FAIL;
1556 } else if (ast_sorcery_object_set_extended(obj, "@tacos", "supreme")) {
1557 ast_test_status_update(test, "Extended field could not be set\n");
1558 res = AST_TEST_FAIL;
1559 } else if (!(value = ast_sorcery_object_get_extended(obj, "tacos"))) {
1560 ast_test_status_update(test, "Extended field, which was set using the API, could not be found\n");
1561 res = AST_TEST_FAIL;
1562 } else if (strcmp(value, "supreme")) {
1563 ast_test_status_update(test, "Extended field does not contain expected value\n");
1564 res = AST_TEST_FAIL;
1565 } else if (ast_sorcery_object_set_extended(obj, "@tacos", "canadian")) {
1566 ast_test_status_update(test, "Extended field could not be set a second time\n");
1567 res = AST_TEST_FAIL;
1568 } else if (!(value = ast_sorcery_object_get_extended(obj, "tacos"))) {
1569 ast_test_status_update(test, "Extended field, which was set using the API, could not be found\n");
1570 res = AST_TEST_FAIL;
1571 } else if (strcmp(value, "canadian")) {
1572 ast_test_status_update(test, "Extended field does not contain expected value\n");
1573 res = AST_TEST_FAIL;
1574 }
1575
1576 return res;
1577}
const char * ast_sorcery_object_get_extended(const void *object, const char *name)
Get an extended field value from a sorcery object.
Definition: sorcery.c:2335
int ast_sorcery_object_set_extended(const void *object, const char *name, const char *value)
Set an extended field value on a sorcery object.
Definition: sorcery.c:2349
int ast_sorcery_objectset_apply(const struct ast_sorcery *sorcery, void *object, struct ast_variable *objectset)
Apply an object set (KVP list) to an object.
Definition: sorcery.c:1632
int value
Definition: syslog.c:37

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_object_get_extended(), ast_sorcery_object_set_extended(), ast_sorcery_objectset_apply(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variable_new, ast_variables_destroy(), sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, and value.

◆ AST_TEST_DEFINE() [14/51]

AST_TEST_DEFINE ( global_observation  )

Definition at line 3165 of file test_sorcery.c.

3166{
3169 const struct ast_sorcery_global_observer observer = {
3170 .wizard_registered = wizard_observer,
3171 .instance_created = instance_observer,
3172 .wizard_unregistering = wizard_observer,
3173 .instance_destroying = instance_observer,
3174 };
3175
3176 switch (cmd) {
3177 case TEST_INIT:
3178 info->name = "global_observation";
3179 info->category = "/main/sorcery/";
3180 info->summary = "global sorcery observation test";
3181 info->description =
3182 "Test observation of sorcery (global)";
3183 return AST_TEST_NOT_RUN;
3184 case TEST_EXECUTE:
3185 break;
3186 }
3187
3189
3190 event_observed = 0;
3192 ast_test_validate(test, (event_observed == 1), "Wizard registered failed");
3193
3194 event_observed = 0;
3196 ast_test_validate(test, (event_observed == 1), "Wizard unregistered failed");
3197
3198 event_observed = 0;
3200 ast_test_validate(test, (event_observed == 1), "Instance created failed");
3201
3202 event_observed = 0;
3204 sorcery = NULL;
3205 ast_test_validate(test, (event_observed == 1), "Instance destroyed failed");
3206
3208 event_observed = 0;
3210 ast_test_validate(test, (event_observed == 0), "Observer removed failed");
3211
3212 return AST_TEST_PASS;
3213}
void ast_sorcery_global_observer_remove(const struct ast_sorcery_global_observer *callbacks)
Remove a global observer from sorcery.
Definition: sorcery.c:514
int ast_sorcery_global_observer_add(const struct ast_sorcery_global_observer *callbacks)
Add a global observer to sorcery.
Definition: sorcery.c:498
Interface for the global sorcery observer.
Definition: sorcery.h:220
Interface for a sorcery wizard.
Definition: sorcery.h:276
static int event_observed
static void wizard_observer(const char *name, const struct ast_sorcery_wizard *wizard)
static void instance_observer(const char *name, struct ast_sorcery *sorcery)
static struct sorcery_test_observer observer
Global scope observer structure for testing.
Definition: test_sorcery.c:181

References ast_sorcery_global_observer_add(), ast_sorcery_global_observer_remove(), ast_sorcery_open, ast_sorcery_unref, ast_sorcery_wizard_register, ast_sorcery_wizard_unregister(), AST_TEST_NOT_RUN, AST_TEST_PASS, event_observed, sip_to_pjsip::info(), instance_observer(), NULL, observer, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, test_wizard, and wizard_observer().

◆ AST_TEST_DEFINE() [15/51]

AST_TEST_DEFINE ( instance_observation  )

Definition at line 3267 of file test_sorcery.c.

3268{
3271 .wizard_mapped = wizard_mapped_observer,
3272 .object_type_registered = object_type_registered_observer,
3273 };
3274
3275 switch (cmd) {
3276 case TEST_INIT:
3277 info->name = "instance_observation";
3278 info->category = "/main/sorcery/";
3279 info->summary = "sorcery instance observation test";
3280 info->description =
3281 "Test observation of sorcery (instance)";
3282 return AST_TEST_NOT_RUN;
3283 case TEST_EXECUTE:
3284 break;
3285 }
3286
3287 /* Test instance load */
3288 if (!(sorcery = ast_sorcery_open())) {
3289 ast_test_status_update(test, "Failed to open a sorcery instance\n");
3290 return AST_TEST_FAIL;
3291 }
3292 observer.instance_loading = instance_loaded_observer;
3293 observer.instance_loaded = instance_loaded_observer;
3295 event_observed = 0;
3297 ast_test_validate(test, (event_observed == 2), "Instance loaded failed");
3298 event_observed = 0;
3300 ast_test_validate(test, (event_observed == 0), "Instance reloaded failed");
3301
3302 /* Test instance reload */
3304 observer.instance_loading = instance_reloaded_observer;
3305 observer.instance_loaded = instance_reloaded_observer;
3307 event_observed = 0;
3309 ast_test_validate(test, (event_observed == 0), "Instance loaded failed");
3310 event_observed = 0;
3312 ast_test_validate(test, (event_observed == 2), "Instance reloaded failed");
3313
3314 /* Test wizard mapping */
3315 event_observed = 0;
3316 ast_sorcery_apply_default(sorcery, "test_object_type", "memory", "memwiz");
3317 ast_test_validate(test, (event_observed == 1), "Wizard mapping failed");
3318
3319 /* Test object type register */
3320 event_observed = 0;
3323 ast_test_validate(test, (event_observed == 1), "Object type registered failed");
3324
3325 /* Test object type load */
3327 observer.object_type_loading = object_type_loaded_observer;
3328 observer.object_type_loaded = object_type_loaded_observer;
3330 event_observed = 0;
3331 ast_sorcery_load_object(sorcery, "test_object_type");
3332 ast_test_validate(test, (event_observed == 2), "Object type loaded failed");
3333 event_observed = 0;
3334 ast_sorcery_reload_object(sorcery, "test_object_type");
3335 ast_test_validate(test, (event_observed == 0), "Object type reloaded failed");
3336
3337 /* Test object type reload */
3339 observer.object_type_loading = object_type_reloaded_observer;
3340 observer.object_type_loaded = object_type_reloaded_observer;
3342 event_observed = 0;
3343 ast_sorcery_load_object(sorcery, "test_object_type");
3344 ast_test_validate(test, (event_observed == 0), "Object type loaded failed");
3345 event_observed = 0;
3346 ast_sorcery_reload_object(sorcery, "test_object_type");
3347 ast_test_validate(test, (event_observed == 2), "Object type reloaded failed");
3348
3350 event_observed = 0;
3351 ast_sorcery_apply_default(sorcery, "test_object_type", "memory", "memwiz");
3352 ast_test_validate(test, (event_observed == 0), "Observer remove failed");
3353
3354 return AST_TEST_PASS;
3355}
void ast_sorcery_instance_observer_remove(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Remove an observer from a sorcery instance.
Definition: sorcery.c:537
void ast_sorcery_reload(const struct ast_sorcery *sorcery)
Inform any wizards to reload persistent objects.
Definition: sorcery.c:1408
void ast_sorcery_load_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to load persistent objects.
Definition: sorcery.c:1393
void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to reload persistent objects.
Definition: sorcery.c:1442
int ast_sorcery_instance_observer_add(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Add an observer to a sorcery instance.
Definition: sorcery.c:520
Interface for the sorcery instance observer.
Definition: sorcery.h:237
static void object_type_reloaded_observer(const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
static void instance_loaded_observer(const char *name, const struct ast_sorcery *sorcery, int reloaded)
static void object_type_loaded_observer(const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
static void object_type_registered_observer(const char *name, struct ast_sorcery *sorcery, const char *object_type)
static void wizard_mapped_observer(const char *name, struct ast_sorcery *sorcery, const char *object_type, struct ast_sorcery_wizard *wizard, const char *wizard_args, void *wizard_data)
static void instance_reloaded_observer(const char *name, const struct ast_sorcery *sorcery, int reloaded)

References ast_sorcery_apply_default, ast_sorcery_instance_observer_add(), ast_sorcery_instance_observer_remove(), ast_sorcery_internal_object_register, ast_sorcery_load(), ast_sorcery_load_object(), ast_sorcery_open, ast_sorcery_reload(), ast_sorcery_reload_object(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, event_observed, sip_to_pjsip::info(), instance_loaded_observer(), instance_reloaded_observer(), NULL, object_type_loaded_observer(), object_type_registered_observer(), object_type_reloaded_observer(), observer, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, test_sorcery_object_alloc(), and wizard_mapped_observer().

◆ AST_TEST_DEFINE() [16/51]

AST_TEST_DEFINE ( object_alloc_with_id  )

Definition at line 714 of file test_sorcery.c.

715{
716 int res = AST_TEST_PASS;
719
720 switch (cmd) {
721 case TEST_INIT:
722 info->name = "object_alloc_with_id";
723 info->category = "/main/sorcery/";
724 info->summary = "sorcery object allocation (with id) unit test";
725 info->description =
726 "Test object allocation in sorcery with a provided id";
727 return AST_TEST_NOT_RUN;
728 case TEST_EXECUTE:
729 break;
730 }
731
733 ast_test_status_update(test, "Failed to open sorcery structure\n");
734 return AST_TEST_FAIL;
735 }
736
737 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
738 ast_test_status_update(test, "Failed to allocate a known object type\n");
739 res = AST_TEST_FAIL;
741 ast_test_status_update(test, "Allocated object has empty id when it should not\n");
742 res = AST_TEST_FAIL;
743 } else if (strcmp(ast_sorcery_object_get_id(obj), "blah")) {
744 ast_test_status_update(test, "Allocated object does not have correct id\n");
745 res = AST_TEST_FAIL;
747 ast_test_status_update(test, "Allocated object has empty type when it should not\n");
748 res = AST_TEST_FAIL;
749 } else if (strcmp(ast_sorcery_object_get_type(obj), "test")) {
750 ast_test_status_update(test, "Allocated object does not have correct type\n");
751 res = AST_TEST_FAIL;
752 } else if ((obj->bob != 5) || (obj->joe != 10)) {
753 ast_test_status_update(test, "Allocated object does not have defaults set as it should\n");
754 res = AST_TEST_FAIL;
755 }
756
757 return res;
758}
const char * ast_sorcery_object_get_type(const void *object)
Get the type of a sorcery object.
Definition: sorcery.c:2329
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_object_get_id(), ast_sorcery_object_get_type(), ast_sorcery_unref, ast_strlen_zero(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [17/51]

AST_TEST_DEFINE ( object_alloc_without_id  )

Definition at line 760 of file test_sorcery.c.

761{
762 int res = AST_TEST_PASS;
765
766 switch (cmd) {
767 case TEST_INIT:
768 info->name = "object_alloc_without_id";
769 info->category = "/main/sorcery/";
770 info->summary = "sorcery object allocation (without id) unit test";
771 info->description =
772 "Test object allocation in sorcery with no provided id";
773 return AST_TEST_NOT_RUN;
774 case TEST_EXECUTE:
775 break;
776 }
777
779 ast_test_status_update(test, "Failed to open sorcery structure\n");
780 return AST_TEST_FAIL;
781 }
782
783 if (!(obj = ast_sorcery_alloc(sorcery, "test", NULL))) {
784 ast_test_status_update(test, "Failed to allocate a known object type\n");
785 res = AST_TEST_FAIL;
787 ast_test_status_update(test, "Allocated object has empty id when it should not\n");
788 res = AST_TEST_FAIL;
789 }
790
791 return res;
792}

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_object_get_id(), ast_sorcery_unref, ast_strlen_zero(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [18/51]

AST_TEST_DEFINE ( object_copy  )

Definition at line 795 of file test_sorcery.c.

796{
797 int res = AST_TEST_PASS;
801
802 switch (cmd) {
803 case TEST_INIT:
804 info->name = "object_copy";
805 info->category = "/main/sorcery/";
806 info->summary = "sorcery object copy unit test";
807 info->description =
808 "Test object copy in sorcery";
809 return AST_TEST_NOT_RUN;
810 case TEST_EXECUTE:
811 break;
812 }
813
815 ast_test_status_update(test, "Failed to open sorcery structure\n");
816 return AST_TEST_FAIL;
817 }
818
819 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
820 ast_test_status_update(test, "Failed to allocate a known object type\n");
821 return AST_TEST_FAIL;
822 }
823
824 obj->bob = 50;
825 obj->joe = 100;
826 jim_handler(NULL, ast_variable_new("jim", "444", ""), obj);
827 jim_handler(NULL, ast_variable_new("jim", "555", ""), obj);
828
829 if (!(copy = ast_sorcery_copy(sorcery, obj))) {
830 ast_test_status_update(test, "Failed to create a copy of a known valid object\n");
831 res = AST_TEST_FAIL;
832 } else if (copy == obj) {
833 ast_test_status_update(test, "Created copy is actually the original object\n");
834 res = AST_TEST_FAIL;
835 } else if (copy->bob != obj->bob) {
836 ast_test_status_update(test, "Value of 'bob' on newly created copy is not the same as original\n");
837 res = AST_TEST_FAIL;
838 } else if (copy->joe != obj->joe) {
839 ast_test_status_update(test, "Value of 'joe' on newly created copy is not the same as original\n");
840 res = AST_TEST_FAIL;
841 } else if (!copy->jim) {
842 ast_test_status_update(test, "A new ast_variable was not created for 'jim'\n");
843 res = AST_TEST_FAIL;
844 } else if (copy->jim == obj->jim) {
845 ast_test_status_update(test, "Created copy of 'jim' is actually the original 'jim'\n");
846 res = AST_TEST_FAIL;
847 } else if (strcmp(copy->jim->value, obj->jim->value)) {
848 ast_test_status_update(test, "Value of 1st 'jim' on newly created copy is not the same as original\n");
849 res = AST_TEST_FAIL;
850 } else if (!copy->jim->next) {
851 ast_test_status_update(test, "A new ast_variable was not created for 2nd 'jim'\n");
852 res = AST_TEST_FAIL;
853 } else if (strcmp(copy->jim->next->value, obj->jim->next->value)) {
854 ast_test_status_update(test, "Value of 2nd 'jim' (%s %s) on newly created copy is not the same as original (%s %s)\n",
855 copy->jim->value, copy->jim->next->value, obj->jim->value, obj->jim->next->value);
856 res = AST_TEST_FAIL;
857 }
858
859 return res;
860}
static int copy(char *infile, char *outfile)
Utility function to copy a file.
void * ast_sorcery_copy(const struct ast_sorcery *sorcery, const void *object)
Create a copy of an object.
Definition: sorcery.c:1778

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_copy(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variable_new, copy(), sip_to_pjsip::info(), jim_handler(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [19/51]

AST_TEST_DEFINE ( object_copy_native  )

Definition at line 862 of file test_sorcery.c.

863{
864 int res = AST_TEST_PASS;
868
869 switch (cmd) {
870 case TEST_INIT:
871 info->name = "object_copy_native";
872 info->category = "/main/sorcery/";
873 info->summary = "sorcery object native copy unit test";
874 info->description =
875 "Test object native copy in sorcery";
876 return AST_TEST_NOT_RUN;
877 case TEST_EXECUTE:
878 break;
879 }
880
882 ast_test_status_update(test, "Failed to open sorcery structure\n");
883 return AST_TEST_FAIL;
884 }
885
887
888 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
889 ast_test_status_update(test, "Failed to allocate a known object type\n");
890 return AST_TEST_FAIL;
891 }
892
893 obj->bob = 50;
894 obj->joe = 100;
895
896 if (!(copy = ast_sorcery_copy(sorcery, obj))) {
897 ast_test_status_update(test, "Failed to create a copy of a known valid object\n");
898 res = AST_TEST_FAIL;
899 } else if (copy == obj) {
900 ast_test_status_update(test, "Created copy is actually the original object\n");
901 res = AST_TEST_FAIL;
902 } else if (copy->bob != 10) {
903 ast_test_status_update(test, "Value of 'bob' on newly created copy is not the predefined native copy value\n");
904 res = AST_TEST_FAIL;
905 } else if (copy->joe != 20) {
906 ast_test_status_update(test, "Value of 'joe' on newly created copy is not the predefined native copy value\n");
907 res = AST_TEST_FAIL;
908 } else if (!copy->jim) {
909 ast_test_status_update(test, "A new ast_variable was not created for 'jim'\n");
910 res = AST_TEST_FAIL;
911 } else if (strcmp(copy->jim->value, "444")) {
912 ast_test_status_update(test, "Value of 'jim' on newly created copy is not the predefined native copy value\n");
913 res = AST_TEST_FAIL;
914 }
915
916 return res;
917}
void ast_sorcery_object_set_copy_handler(struct ast_sorcery *sorcery, const char *type, sorcery_copy_handler copy)
Set the copy handler for an object type.
Definition: sorcery.c:1128
static int test_sorcery_copy(const void *src, void *dst)
Internal function which copies pre-defined data into an object, natively.
Definition: test_sorcery.c:93

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_copy(), ast_sorcery_object_set_copy_handler(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, copy(), sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, and test_sorcery_copy().

◆ AST_TEST_DEFINE() [20/51]

AST_TEST_DEFINE ( object_create  )

Definition at line 1716 of file test_sorcery.c.

1717{
1720
1721 switch (cmd) {
1722 case TEST_INIT:
1723 info->name = "object_create";
1724 info->category = "/main/sorcery/";
1725 info->summary = "sorcery object creation unit test";
1726 info->description =
1727 "Test object creation in sorcery";
1728 return AST_TEST_NOT_RUN;
1729 case TEST_EXECUTE:
1730 break;
1731 }
1732
1734 ast_test_status_update(test, "Failed to open sorcery structure\n");
1735 return AST_TEST_FAIL;
1736 }
1737
1738 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
1739 ast_test_status_update(test, "Failed to allocate a known object type\n");
1740 return AST_TEST_FAIL;
1741 }
1742
1743 if (ast_sorcery_create(sorcery, obj)) {
1744 ast_test_status_update(test, "Failed to create object using in-memory wizard\n");
1745 return AST_TEST_FAIL;
1746 }
1747
1748 return AST_TEST_PASS;
1749}

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_create(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [21/51]

AST_TEST_DEFINE ( object_delete  )

Definition at line 2152 of file test_sorcery.c.

2153{
2156
2157 switch (cmd) {
2158 case TEST_INIT:
2159 info->name = "object_delete";
2160 info->category = "/main/sorcery/";
2161 info->summary = "sorcery object deletion unit test";
2162 info->description =
2163 "Test object deletion in sorcery";
2164 return AST_TEST_NOT_RUN;
2165 case TEST_EXECUTE:
2166 break;
2167 }
2168
2170 ast_test_status_update(test, "Failed to open sorcery structure\n");
2171 return AST_TEST_FAIL;
2172 }
2173
2174 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
2175 ast_test_status_update(test, "Failed to allocate a known object type\n");
2176 return AST_TEST_FAIL;
2177 }
2178
2179 if (ast_sorcery_create(sorcery, obj)) {
2180 ast_test_status_update(test, "Failed to create object using in-memory wizard\n");
2181 return AST_TEST_FAIL;
2182 }
2183
2184 if (ast_sorcery_delete(sorcery, obj)) {
2185 ast_test_status_update(test, "Failed to delete object using in-memory wizard\n");
2186 return AST_TEST_FAIL;
2187 }
2188
2189 ao2_cleanup(obj);
2190
2191 if ((obj = ast_sorcery_retrieve_by_id(sorcery, "test", "blah"))) {
2192 ast_test_status_update(test, "Retrieved deleted object that should not be there\n");
2193 return AST_TEST_FAIL;
2194 }
2195
2196 return AST_TEST_PASS;
2197}

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_create(), ast_sorcery_delete(), ast_sorcery_retrieve_by_id(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [22/51]

AST_TEST_DEFINE ( object_delete_uncreated  )

Definition at line 2199 of file test_sorcery.c.

2200{
2203
2204 switch (cmd) {
2205 case TEST_INIT:
2206 info->name = "object_delete_uncreated";
2207 info->category = "/main/sorcery/";
2208 info->summary = "sorcery object deletion unit test";
2209 info->description =
2210 "Test object deletion of an uncreated object in sorcery";
2211 return AST_TEST_NOT_RUN;
2212 case TEST_EXECUTE:
2213 break;
2214 }
2215
2217 ast_test_status_update(test, "Failed to open sorcery structure\n");
2218 return AST_TEST_FAIL;
2219 }
2220
2221 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
2222 ast_test_status_update(test, "Failed to allocate a known object type\n");
2223 return AST_TEST_FAIL;
2224 }
2225
2226 if (!ast_sorcery_delete(sorcery, obj)) {
2227 ast_test_status_update(test, "Successfully deleted an object which was never created\n");
2228 return AST_TEST_FAIL;
2229 }
2230
2231 return AST_TEST_PASS;
2232}

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_delete(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [23/51]

AST_TEST_DEFINE ( object_diff  )

Definition at line 919 of file test_sorcery.c.

920{
924 RAII_VAR(struct ast_variable *, changes, NULL, ast_variables_destroy);
925 struct ast_variable *field;
926 int res = AST_TEST_PASS;
927 int jims = 0;
928
929 switch (cmd) {
930 case TEST_INIT:
931 info->name = "object_diff";
932 info->category = "/main/sorcery/";
933 info->summary = "sorcery object diff unit test";
934 info->description =
935 "Test object diffing in sorcery";
936 return AST_TEST_NOT_RUN;
937 case TEST_EXECUTE:
938 break;
939 }
940
942 ast_test_status_update(test, "Failed to open sorcery structure\n");
943 return AST_TEST_FAIL;
944 }
945
946 if (!(obj1 = ast_sorcery_alloc(sorcery, "test", "blah"))) {
947 ast_test_status_update(test, "Failed to allocate a known object type\n");
948 return AST_TEST_FAIL;
949 }
950
951 obj1->bob = 99;
952 obj1->joe = 55;
953 jim_handler(NULL, ast_variable_new("jim", "444", ""), obj1);
954 jim_handler(NULL, ast_variable_new("jim", "555", ""), obj1);
955
956 if (!(obj2 = ast_sorcery_alloc(sorcery, "test", "blah2"))) {
957 ast_test_status_update(test, "Failed to allocate a second known object type\n");
958 return AST_TEST_FAIL;
959 }
960
961 obj2->bob = 99;
962 obj2->joe = 42;
963 jim_handler(NULL, ast_variable_new("jim", "444", ""), obj2);
964 jim_handler(NULL, ast_variable_new("jim", "666", ""), obj2);
965 jim_handler(NULL, ast_variable_new("jim", "777", ""), obj2);
966
967 if (ast_sorcery_diff(sorcery, obj1, obj2, &changes)) {
968 ast_test_status_update(test, "Failed to diff obj1 and obj2\n");
969 } else if (!changes) {
970 ast_test_status_update(test, "Failed to produce a diff of two objects, despite there being differences\n");
971 return AST_TEST_FAIL;
972 }
973
974 for (field = changes; field; field = field->next) {
975 if (!strcmp(field->name, "joe")) {
976 if (strcmp(field->value, "42")) {
978 "Object diff produced unexpected value '%s' for joe\n", field->value);
979 res = AST_TEST_FAIL;
980 }
981 } else if (!strcmp(field->name, "jim")) {
982 jims++;
983 if (!strcmp(field->value, "555")) {
985 "Object diff produced unexpected value '%s' for jim\n", field->value);
986 res = AST_TEST_FAIL;
987 }
988 } else {
989 ast_test_status_update(test, "Object diff produced unexpected field '%s'\n",
990 field->name);
991 res = AST_TEST_FAIL;
992 }
993 }
994
995 if (jims != 2) {
996 ast_test_status_update(test, "Object diff didn't produce 2 jims\n");
997 res = AST_TEST_FAIL;
998 }
999
1000 return res;
1001}
int ast_sorcery_diff(const struct ast_sorcery *sorcery, const void *original, const void *modified, struct ast_variable **changes)
Create a changeset of two objects.
Definition: sorcery.c:1805
struct ast_variable * next

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_diff(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variable_new, ast_variables_destroy(), sip_to_pjsip::info(), jim_handler(), ast_variable::name, ast_variable::next, NULL, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, and ast_variable::value.

◆ AST_TEST_DEFINE() [24/51]

AST_TEST_DEFINE ( object_diff_native  )

Definition at line 1003 of file test_sorcery.c.

1004{
1006 RAII_VAR(struct test_sorcery_object *, obj1, NULL, ao2_cleanup);
1007 RAII_VAR(struct test_sorcery_object *, obj2, NULL, ao2_cleanup);
1008 RAII_VAR(struct ast_variable *, changes, NULL, ast_variables_destroy);
1009 struct ast_variable *field;
1010 int res = AST_TEST_PASS;
1011
1012 switch (cmd) {
1013 case TEST_INIT:
1014 info->name = "object_diff_native";
1015 info->category = "/main/sorcery/";
1016 info->summary = "sorcery object native diff unit test";
1017 info->description =
1018 "Test native object diffing in sorcery";
1019 return AST_TEST_NOT_RUN;
1020 case TEST_EXECUTE:
1021 break;
1022 }
1023
1025 ast_test_status_update(test, "Failed to open sorcery structure\n");
1026 return AST_TEST_FAIL;
1027 }
1028
1030
1031 if (!(obj1 = ast_sorcery_alloc(sorcery, "test", "blah"))) {
1032 ast_test_status_update(test, "Failed to allocate a known object type\n");
1033 return AST_TEST_FAIL;
1034 }
1035
1036 obj1->bob = 99;
1037 obj1->joe = 55;
1038
1039 if (!(obj2 = ast_sorcery_alloc(sorcery, "test", "blah2"))) {
1040 ast_test_status_update(test, "Failed to allocate a second known object type\n");
1041 return AST_TEST_FAIL;
1042 }
1043
1044 obj2->bob = 99;
1045 obj2->joe = 42;
1046
1047 if (ast_sorcery_diff(sorcery, obj1, obj2, &changes)) {
1048 ast_test_status_update(test, "Failed to diff obj1 and obj2\n");
1049 } else if (!changes) {
1050 ast_test_status_update(test, "Failed to produce a diff of two objects, despite there being differences\n");
1051 return AST_TEST_FAIL;
1052 }
1053
1054 for (field = changes; field; field = field->next) {
1055 if (!strcmp(field->name, "yes")) {
1056 if (strcmp(field->value, "itworks")) {
1057 ast_test_status_update(test, "Object diff produced unexpected value '%s' for joe\n", field->value);
1058 res = AST_TEST_FAIL;
1059 }
1060 } else {
1061 ast_test_status_update(test, "Object diff produced unexpected field '%s'\n", field->name);
1062 res = AST_TEST_FAIL;
1063 }
1064 }
1065
1066 return res;
1067}
void ast_sorcery_object_set_diff_handler(struct ast_sorcery *sorcery, const char *type, sorcery_diff_handler diff)
Set the diff handler for an object type.
Definition: sorcery.c:1139
static int test_sorcery_diff(const void *original, const void *modified, struct ast_variable **changes)
Internal function which creates a pre-defined diff natively.
Definition: test_sorcery.c:104

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_diff(), ast_sorcery_object_set_diff_handler(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variables_destroy(), sip_to_pjsip::info(), ast_variable::name, ast_variable::next, NULL, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, test_sorcery_diff(), and ast_variable::value.

◆ AST_TEST_DEFINE() [25/51]

AST_TEST_DEFINE ( object_field_register  )

Definition at line 616 of file test_sorcery.c.

617{
619
620 switch (cmd) {
621 case TEST_INIT:
622 info->name = "object_field_register";
623 info->category = "/main/sorcery/";
624 info->summary = "sorcery object field registration unit test";
625 info->description =
626 "Test object field registration in sorcery with a provided id";
627 return AST_TEST_NOT_RUN;
628 case TEST_EXECUTE:
629 break;
630 }
631
632 if (!(sorcery = ast_sorcery_open())) {
633 ast_test_status_update(test, "Failed to open sorcery structure\n");
634 return AST_TEST_FAIL;
635 }
636
637 if (!ast_sorcery_object_field_register_nodoc(sorcery, "test", "bob", "5", OPT_UINT_T, 0, FLDSET(struct test_sorcery_object, bob))) {
638 ast_test_status_update(test, "Registered an object field successfully when no mappings or object types exist\n");
639 return AST_TEST_FAIL;
640 }
641
643 ast_test_status_update(test, "Failed to set a known wizard as a default\n");
644 return AST_TEST_FAIL;
645 }
646
647 if (!ast_sorcery_object_field_register_nodoc(sorcery, "test", "bob", "5", OPT_UINT_T, 0, FLDSET(struct test_sorcery_object, bob))) {
648 ast_test_status_update(test, "Registered an object field successfully when object type does not exist\n");
649 return AST_TEST_FAIL;
650 }
651
653 ast_test_status_update(test, "Failed to register object type\n");
654 return AST_TEST_FAIL;
655 }
656
657 if (ast_sorcery_object_field_register_nodoc(sorcery, "test", "bob", "5", OPT_UINT_T, 0, FLDSET(struct test_sorcery_object, bob))) {
658 ast_test_status_update(test, "Could not successfully register object field when mapping and object type exists\n");
659 return AST_TEST_FAIL;
660 }
661
662 return AST_TEST_PASS;
663}

References ast_sorcery_apply_default, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_internal_object_register, ast_sorcery_object_field_register_nodoc, ast_sorcery_open, ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, FLDSET, sip_to_pjsip::info(), NULL, OPT_UINT_T, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, and test_sorcery_object_alloc().

◆ AST_TEST_DEFINE() [26/51]

AST_TEST_DEFINE ( object_field_registered  )

Definition at line 3107 of file test_sorcery.c.

3108{
3110 RAII_VAR(struct ast_sorcery_object_type *, object_type, NULL, ao2_cleanup);
3111
3112 switch (cmd) {
3113 case TEST_INIT:
3114 info->name = "object_field_registered";
3115 info->category = "/main/sorcery/";
3116 info->summary = "ast_sorcery_is_object_field_registered unit test";
3117 info->description =
3118 "Test ast_sorcery_is_object_field_registered in sorcery";
3119 return AST_TEST_NOT_RUN;
3120 case TEST_EXECUTE:
3121 break;
3122 }
3123
3125 ast_test_status_update(test, "Failed to open sorcery structure\n");
3126 return AST_TEST_FAIL;
3127 }
3128
3129 object_type = ast_sorcery_get_object_type(sorcery, "test");
3130
3132
3133 ast_test_validate(test, ast_sorcery_is_object_field_registered(object_type, "joe"));
3134 ast_test_validate(test, ast_sorcery_is_object_field_registered(object_type, "bob"));
3135 ast_test_validate(test, ast_sorcery_is_object_field_registered(object_type, "@joebob"));
3136 ast_test_validate(test, ast_sorcery_is_object_field_registered(object_type, "prefix/goober"));
3137
3138 ast_test_validate(test, !ast_sorcery_is_object_field_registered(object_type, "joebob"));
3139 ast_test_validate(test, !ast_sorcery_is_object_field_registered(object_type, "prefix/"));
3140 ast_test_validate(test, !ast_sorcery_is_object_field_registered(object_type, "goober"));
3141
3143
3144 ast_test_validate(test, ast_sorcery_is_object_field_registered(object_type, "goober"));
3145
3146 return AST_TEST_PASS;
3147}
int ast_sorcery_object_fields_register(struct ast_sorcery *sorcery, const char *type, const char *regex, aco_option_handler config_handler, sorcery_fields_handler sorcery_handler)
Register a regex for multiple fields within an object.
Definition: sorcery.c:1160
struct ast_sorcery_object_type * ast_sorcery_get_object_type(const struct ast_sorcery *sorcery, const char *type)
Get the sorcery object type given a type name.
Definition: sorcery.c:2494
int ast_sorcery_is_object_field_registered(const struct ast_sorcery_object_type *object_type, const char *field_name)
Determine if a particular object field has been registered with sorcery.
Definition: sorcery.c:2514
Structure for registered object type.
Definition: sorcery.c:148
static int test_sorcery_regex_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Internal function which sets some values.
Definition: test_sorcery.c:111
static int test_sorcery_regex_fields(const void *obj, struct ast_variable **fields)
Internal function which creates some ast_variable structures.
Definition: test_sorcery.c:121

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_get_object_type(), ast_sorcery_is_object_field_registered(), ast_sorcery_object_fields_register(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, test_sorcery_regex_fields(), and test_sorcery_regex_handler().

◆ AST_TEST_DEFINE() [27/51]

AST_TEST_DEFINE ( object_fields_register  )

Definition at line 665 of file test_sorcery.c.

666{
668
669 switch (cmd) {
670 case TEST_INIT:
671 info->name = "object_fields_register";
672 info->category = "/main/sorcery/";
673 info->summary = "sorcery object regex fields registration unit test";
674 info->description =
675 "Test object regex fields registration in sorcery with a provided id";
676 return AST_TEST_NOT_RUN;
677 case TEST_EXECUTE:
678 break;
679 }
680
681 if (!(sorcery = ast_sorcery_open())) {
682 ast_test_status_update(test, "Failed to open sorcery structure\n");
683 return AST_TEST_FAIL;
684 }
685
687 ast_test_status_update(test, "Registered a regex object field successfully when no mappings or object types exist\n");
688 return AST_TEST_FAIL;
689 }
690
692 ast_test_status_update(test, "Failed to set a known wizard as a default\n");
693 return AST_TEST_FAIL;
694 }
695
697 ast_test_status_update(test, "Registered a regex object field successfully when object type does not exist\n");
698 return AST_TEST_FAIL;
699 }
700
702 ast_test_status_update(test, "Failed to register object type\n");
703 return AST_TEST_FAIL;
704 }
705
707 ast_test_status_update(test, "Registered a regex object field successfully when no mappings or object types exist\n");
708 return AST_TEST_FAIL;
709 }
710
711 return AST_TEST_PASS;
712}

References ast_sorcery_apply_default, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_internal_object_register, ast_sorcery_object_fields_register(), ast_sorcery_open, ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, test_sorcery_object_alloc(), test_sorcery_regex_fields(), and test_sorcery_regex_handler().

◆ AST_TEST_DEFINE() [28/51]

AST_TEST_DEFINE ( object_is_stale  )

Definition at line 2234 of file test_sorcery.c.

2235{
2239 RAII_VAR(struct test_sorcery_object *, obj1, NULL, ao2_cleanup);
2240 RAII_VAR(struct test_sorcery_object *, obj2, NULL, ao2_cleanup);
2241
2242 switch (cmd) {
2243 case TEST_INIT:
2244 info->name = "object_is_stale";
2245 info->category = "/main/sorcery/";
2246 info->summary = "sorcery object staleness unit test";
2247 info->description =
2248 "Test whether sorcery will query a wizard correctly if asked\n"
2249 "if an object is stale.";
2250 return AST_TEST_NOT_RUN;
2251 case TEST_EXECUTE:
2252 break;
2253 }
2254
2256 ast_test_status_update(test, "Failed to register a perfectly valid sorcery wizard\n");
2257 return AST_TEST_FAIL;
2258 }
2259
2261 ast_test_status_update(test, "Failed to register a perfectly valid sorcery wizard\n");
2262 return AST_TEST_FAIL;
2263 }
2264
2265 if (!(sorcery = ast_sorcery_open())) {
2266 ast_test_status_update(test, "Failed to open sorcery structure\n");
2267 return AST_TEST_FAIL;
2268 }
2269
2272 return AST_TEST_FAIL;
2273 }
2274
2279
2280
2281 if ((ast_sorcery_apply_default(sorcery, "test2", "test2", "test2data") != AST_SORCERY_APPLY_SUCCESS) ||
2283 return AST_TEST_FAIL;
2284 }
2285
2290
2291
2292 if (!(obj1 = ast_sorcery_alloc(sorcery, "test", "blah"))) {
2293 ast_test_status_update(test, "Failed to allocate a known object type\n");
2294 return AST_TEST_FAIL;
2295 }
2296
2297 if (!(obj2 = ast_sorcery_alloc(sorcery, "test2", "blah"))) {
2298 ast_test_status_update(test, "Failed to allocate a known object type\n");
2299 return AST_TEST_FAIL;
2300 }
2301
2302 /* The 'test' wizard has no is_stale callback */
2303 ast_test_validate(test, ast_sorcery_is_stale(sorcery, obj1) == 0);
2304
2305 /* The 'test2' wizard should return stale */
2306 ast_test_validate(test, ast_sorcery_is_stale(sorcery, obj2) == 1);
2307 ast_test_validate(test, cache.is_stale == 1);
2308
2309 return AST_TEST_PASS;
2310}
int ast_sorcery_is_stale(const struct ast_sorcery *sorcery, void *object)
Determine if a sorcery object is stale with respect to its backing datastore.
Definition: sorcery.c:2288
unsigned int is_stale
Whether the object is stale or not.
Definition: test_sorcery.c:140
static struct ast_sorcery_wizard test_wizard2
Definition: test_sorcery.c:236

References ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_apply_default, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_internal_object_register, ast_sorcery_is_stale(), ast_sorcery_object_field_register_custom_nodoc, ast_sorcery_object_field_register_nodoc, ast_sorcery_open, ast_sorcery_unref, ast_sorcery_wizard_register, ast_sorcery_wizard_unregister(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, cache, FLDSET, sip_to_pjsip::info(), sorcery_test_caching::is_stale, jack_handler(), jack_str(), jim_handler(), jim_vl(), NULL, OPT_UINT_T, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, test_sorcery_object_alloc(), test_wizard, and test_wizard2.

◆ AST_TEST_DEFINE() [29/51]

AST_TEST_DEFINE ( object_register  )

Definition at line 548 of file test_sorcery.c.

549{
551
552 switch (cmd) {
553 case TEST_INIT:
554 info->name = "object_register";
555 info->category = "/main/sorcery/";
556 info->summary = "sorcery object type registration unit test";
557 info->description =
558 "Test object type registration in sorcery";
559 return AST_TEST_NOT_RUN;
560 case TEST_EXECUTE:
561 break;
562 }
563
564 if (!(sorcery = ast_sorcery_open())) {
565 ast_test_status_update(test, "Failed to open structure\n");
566 return AST_TEST_FAIL;
567 }
568
570 ast_test_status_update(test, "Failed to set a known wizard as a default\n");
571 return AST_TEST_FAIL;
572 }
573
575 ast_test_status_update(test, "Failed to register object type\n");
576 return AST_TEST_FAIL;
577 }
578
580 ast_test_status_update(test, "Registered object type a second time, despite it being registered already\n");
581 return AST_TEST_FAIL;
582 }
583
584 return AST_TEST_PASS;
585}

References ast_sorcery_apply_default, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_internal_object_register, ast_sorcery_open, ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, and test_sorcery_object_alloc().

◆ AST_TEST_DEFINE() [30/51]

AST_TEST_DEFINE ( object_register_without_mapping  )

Definition at line 587 of file test_sorcery.c.

588{
590
591 switch (cmd) {
592 case TEST_INIT:
593 info->name = "object_register_without_mapping";
594 info->category = "/main/sorcery/";
595 info->summary = "sorcery object type registration (without mapping) unit test";
596 info->description =
597 "Test object type registration when no mapping exists in sorcery";
598 return AST_TEST_NOT_RUN;
599 case TEST_EXECUTE:
600 break;
601 }
602
603 if (!(sorcery = ast_sorcery_open())) {
604 ast_test_status_update(test, "Failed to open sorcery structure\n");
605 return AST_TEST_FAIL;
606 }
607
609 ast_test_status_update(test, "Registered object type when no object mapping exists\n");
610 return AST_TEST_FAIL;
611 }
612
613 return AST_TEST_PASS;
614}

References ast_sorcery_internal_object_register, ast_sorcery_open, ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, and test_sorcery_object_alloc().

◆ AST_TEST_DEFINE() [31/51]

AST_TEST_DEFINE ( object_retrieve_field  )

Definition at line 1808 of file test_sorcery.c.

1809{
1812 RAII_VAR(struct ast_variable *, fields, ast_variable_new("joe", "42", ""), ast_variables_destroy);
1813
1814 switch (cmd) {
1815 case TEST_INIT:
1816 info->name = "object_retrieve_field";
1817 info->category = "/main/sorcery/";
1818 info->summary = "sorcery object retrieval using a specific field unit test";
1819 info->description =
1820 "Test object retrieval using a specific field in sorcery";
1821 return AST_TEST_NOT_RUN;
1822 case TEST_EXECUTE:
1823 break;
1824 }
1825
1826 if (!fields) {
1827 ast_test_status_update(test, "Failed to create fields for object retrieval attempt\n");
1828 return AST_TEST_FAIL;
1829 }
1830
1832 ast_test_status_update(test, "Failed to open sorcery structure\n");
1833 return AST_TEST_FAIL;
1834 }
1835
1836 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
1837 ast_test_status_update(test, "Failed to allocate a known object type\n");
1838 return AST_TEST_FAIL;
1839 }
1840
1841 obj->joe = 42;
1842
1843 if (ast_sorcery_create(sorcery, obj)) {
1844 ast_test_status_update(test, "Failed to create object using in-memory wizard\n");
1845 return AST_TEST_FAIL;
1846 }
1847
1848 ao2_cleanup(obj);
1849
1850 if (!(obj = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, fields))) {
1851 ast_test_status_update(test, "Failed to retrieve properly created object using 'joe' field\n");
1852 return AST_TEST_FAIL;
1853 }
1854
1855 ao2_cleanup(obj);
1856 ast_variables_destroy(fields);
1857
1858 if (!(fields = ast_variable_new("joe", "49", ""))) {
1859 ast_test_status_update(test, "Failed to create fields for object retrieval attempt\n");
1860 return AST_TEST_FAIL;
1861 }
1862
1864 ast_test_status_update(test, "Retrieved an object using a field with an in-correct value... that should not happen\n");
1865 return AST_TEST_FAIL;
1866 }
1867
1868 return AST_TEST_PASS;
1869}

References alloc_and_initialize_sorcery(), ao2_cleanup, AST_RETRIEVE_FLAG_DEFAULT, ast_sorcery_alloc(), ast_sorcery_create(), ast_sorcery_retrieve_by_fields(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variable_new, ast_variables_destroy(), sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [32/51]

AST_TEST_DEFINE ( object_retrieve_id  )

Definition at line 1751 of file test_sorcery.c.

1752{
1755
1756 switch (cmd) {
1757 case TEST_INIT:
1758 info->name = "object_retrieve_id";
1759 info->category = "/main/sorcery/";
1760 info->summary = "sorcery object retrieval using id unit test";
1761 info->description =
1762 "Test object retrieval using id in sorcery";
1763 return AST_TEST_NOT_RUN;
1764 case TEST_EXECUTE:
1765 break;
1766 }
1767
1769 ast_test_status_update(test, "Failed to open sorcery structure\n");
1770 return AST_TEST_FAIL;
1771 }
1772
1773 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
1774 ast_test_status_update(test, "Failed to allocate a known object type\n");
1775 return AST_TEST_FAIL;
1776 }
1777
1778 if (ast_sorcery_create(sorcery, obj)) {
1779 ast_test_status_update(test, "Failed to create object using in-memory wizard\n");
1780 return AST_TEST_FAIL;
1781 }
1782
1783 ao2_cleanup(obj);
1784
1785 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah2"))) {
1786 ast_test_status_update(test, "Failed to allocate second instance of a known object type\n");
1787 return AST_TEST_FAIL;
1788 }
1789
1790 if (ast_sorcery_create(sorcery, obj)) {
1791 ast_test_status_update(test, "Failed to create second object using in-memory wizard\n");
1792 return AST_TEST_FAIL;
1793 }
1794
1795 ao2_cleanup(obj);
1796
1797 if (!(obj = ast_sorcery_retrieve_by_id(sorcery, "test", "blah"))) {
1798 ast_test_status_update(test, "Failed to retrieve properly created object using id of 'blah'\n");
1799 return AST_TEST_FAIL;
1800 } else if (strcmp(ast_sorcery_object_get_id(obj), "blah")) {
1801 ast_test_status_update(test, "Retrieved object does not have correct id\n");
1802 return AST_TEST_FAIL;
1803 }
1804
1805 return AST_TEST_PASS;
1806}

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_create(), ast_sorcery_object_get_id(), ast_sorcery_retrieve_by_id(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [33/51]

AST_TEST_DEFINE ( object_retrieve_multiple_all  )

Definition at line 1871 of file test_sorcery.c.

1872{
1875 RAII_VAR(struct ao2_container *, objects, NULL, ao2_cleanup);
1876
1877 switch (cmd) {
1878 case TEST_INIT:
1879 info->name = "object_retrieve_multiple_all";
1880 info->category = "/main/sorcery/";
1881 info->summary = "sorcery multiple object retrieval unit test";
1882 info->description =
1883 "Test multiple object retrieval in sorcery";
1884 return AST_TEST_NOT_RUN;
1885 case TEST_EXECUTE:
1886 break;
1887 }
1888
1890 ast_test_status_update(test, "Failed to open sorcery structure\n");
1891 return AST_TEST_FAIL;
1892 }
1893
1894 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
1895 ast_test_status_update(test, "Failed to allocate a known object type\n");
1896 return AST_TEST_FAIL;
1897 }
1898
1899 if (ast_sorcery_create(sorcery, obj)) {
1900 ast_test_status_update(test, "Failed to create object using in-memory wizard\n");
1901 return AST_TEST_FAIL;
1902 }
1903
1904 ao2_cleanup(obj);
1905
1906 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah2"))) {
1907 ast_test_status_update(test, "Failed to allocate second instance of a known object type\n");
1908 return AST_TEST_FAIL;
1909 }
1910
1911 if (ast_sorcery_create(sorcery, obj)) {
1912 ast_test_status_update(test, "Failed to create second object using in-memory wizard\n");
1913 return AST_TEST_FAIL;
1914 }
1915
1917 ast_test_status_update(test, "Failed to retrieve a container of all objects\n");
1918 return AST_TEST_FAIL;
1919 } else if (ao2_container_count(objects) != 2) {
1920 ast_test_status_update(test, "Received a container with no objects in it when there should be some\n");
1921 return AST_TEST_FAIL;
1922 }
1923
1924 return AST_TEST_PASS;
1925}

References alloc_and_initialize_sorcery(), ao2_cleanup, ao2_container_count(), AST_RETRIEVE_FLAG_ALL, AST_RETRIEVE_FLAG_MULTIPLE, ast_sorcery_alloc(), ast_sorcery_create(), ast_sorcery_retrieve_by_fields(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [34/51]

AST_TEST_DEFINE ( object_retrieve_multiple_field  )

Definition at line 1927 of file test_sorcery.c.

1928{
1931 RAII_VAR(struct ao2_container *, objects, NULL, ao2_cleanup);
1932 RAII_VAR(struct ast_variable *, fields, ast_variable_new("joe", "6", ""), ast_variables_destroy);
1933
1934 switch (cmd) {
1935 case TEST_INIT:
1936 info->name = "object_retrieve_multiple_field";
1937 info->category = "/main/sorcery/";
1938 info->summary = "sorcery multiple object retrieval unit test";
1939 info->description =
1940 "Test multiple object retrieval in sorcery using fields";
1941 return AST_TEST_NOT_RUN;
1942 case TEST_EXECUTE:
1943 break;
1944 }
1945
1946 if (!fields) {
1947 ast_test_status_update(test, "Failed to create fields for multiple retrieve\n");
1948 return AST_TEST_FAIL;
1949 }
1950
1952 ast_test_status_update(test, "Failed to open sorcery structure\n");
1953 return AST_TEST_FAIL;
1954 }
1955
1956 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
1957 ast_test_status_update(test, "Failed to allocate a known object type\n");
1958 return AST_TEST_FAIL;
1959 }
1960
1961 obj->joe = 6;
1962
1963 if (ast_sorcery_create(sorcery, obj)) {
1964 ast_test_status_update(test, "Failed to create object using in-memory wizard\n");
1965 return AST_TEST_FAIL;
1966 }
1967
1968 if (!(objects = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE, fields))) {
1969 ast_test_status_update(test, "Failed to retrieve a container of all objects\n");
1970 return AST_TEST_FAIL;
1971 } else if (ao2_container_count(objects) != 1) {
1972 ast_test_status_update(test, "Received a container with no objects in it when there should be some\n");
1973 return AST_TEST_FAIL;
1974 }
1975
1976 ao2_cleanup(objects);
1977 ast_variables_destroy(fields);
1978
1979 if (!(fields = ast_variable_new("joe", "7", ""))) {
1980 ast_test_status_update(test, "Failed to create fields for multiple retrieval\n");
1981 return AST_TEST_FAIL;
1982 } else if (!(objects = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE, fields))) {
1983 ast_test_status_update(test, "Failed to retrieve an empty container when retrieving multiple\n");
1984 return AST_TEST_FAIL;
1985 } else if (ao2_container_count(objects)) {
1986 ast_test_status_update(test, "Received a container with objects when there should be none in it\n");
1987 return AST_TEST_FAIL;
1988 }
1989
1990 return AST_TEST_PASS;
1991}

References alloc_and_initialize_sorcery(), ao2_cleanup, ao2_container_count(), AST_RETRIEVE_FLAG_MULTIPLE, ast_sorcery_alloc(), ast_sorcery_create(), ast_sorcery_retrieve_by_fields(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variable_new, ast_variables_destroy(), sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [35/51]

AST_TEST_DEFINE ( object_retrieve_regex  )

Definition at line 1993 of file test_sorcery.c.

1994{
1997 RAII_VAR(struct ao2_container *, objects, NULL, ao2_cleanup);
1998
1999 switch (cmd) {
2000 case TEST_INIT:
2001 info->name = "object_retrieve_regex";
2002 info->category = "/main/sorcery/";
2003 info->summary = "sorcery multiple object retrieval using regex unit test";
2004 info->description =
2005 "Test multiple object retrieval in sorcery using regular expression for matching";
2006 return AST_TEST_NOT_RUN;
2007 case TEST_EXECUTE:
2008 break;
2009 }
2010
2012 ast_test_status_update(test, "Failed to open sorcery structure\n");
2013 return AST_TEST_FAIL;
2014 }
2015
2016 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah-98joe"))) {
2017 ast_test_status_update(test, "Failed to allocate a known object type\n");
2018 return AST_TEST_FAIL;
2019 }
2020
2021 if (ast_sorcery_create(sorcery, obj)) {
2022 ast_test_status_update(test, "Failed to create object using in-memory wizard\n");
2023 return AST_TEST_FAIL;
2024 }
2025
2026 ao2_cleanup(obj);
2027
2028 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah-93joe"))) {
2029 ast_test_status_update(test, "Failed to allocate second instance of a known object type\n");
2030 return AST_TEST_FAIL;
2031 }
2032
2033 if (ast_sorcery_create(sorcery, obj)) {
2034 ast_test_status_update(test, "Failed to create second object using in-memory wizard\n");
2035 return AST_TEST_FAIL;
2036 }
2037
2038 ao2_cleanup(obj);
2039
2040 if (!(obj = ast_sorcery_alloc(sorcery, "test", "neener-93joe"))) {
2041 ast_test_status_update(test, "Failed to allocate third instance of a known object type\n");
2042 return AST_TEST_FAIL;
2043 }
2044
2045 if (ast_sorcery_create(sorcery, obj)) {
2046 ast_test_status_update(test, "Failed to create third object using in-memory wizard\n");
2047 return AST_TEST_FAIL;
2048 }
2049
2050 if (!(objects = ast_sorcery_retrieve_by_regex(sorcery, "test", "^blah-"))) {
2051 ast_test_status_update(test, "Failed to retrieve a container of objects\n");
2052 return AST_TEST_FAIL;
2053 } else if (ao2_container_count(objects) != 2) {
2054 ast_test_status_update(test, "Received a container with incorrect number of objects in it\n");
2055 return AST_TEST_FAIL;
2056 }
2057
2058 return AST_TEST_PASS;
2059}
struct ao2_container * ast_sorcery_retrieve_by_regex(const struct ast_sorcery *sorcery, const char *type, const char *regex)
Retrieve multiple objects using a regular expression on their id.
Definition: sorcery.c:1954

References alloc_and_initialize_sorcery(), ao2_cleanup, ao2_container_count(), ast_sorcery_alloc(), ast_sorcery_create(), ast_sorcery_retrieve_by_regex(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [36/51]

AST_TEST_DEFINE ( object_type_observer  )

Definition at line 2425 of file test_sorcery.c.

2426{
2429 int res = AST_TEST_FAIL;
2430
2431 switch (cmd) {
2432 case TEST_INIT:
2433 info->name = "object_type_observer";
2434 info->category = "/main/sorcery/";
2435 info->summary = "sorcery object type observer unit test";
2436 info->description =
2437 "Test that object type observers get called when they should";
2438 return AST_TEST_NOT_RUN;
2439 case TEST_EXECUTE:
2440 break;
2441 }
2442
2444 ast_test_status_update(test, "Failed to open sorcery structure\n");
2445 return AST_TEST_FAIL;
2446 }
2447
2448 if (!ast_sorcery_observer_add(sorcery, "test", NULL)) {
2449 ast_test_status_update(test, "Successfully added a NULL observer when it should not be possible\n");
2450 return AST_TEST_FAIL;
2451 }
2452
2454 ast_test_status_update(test, "Failed to add a proper observer\n");
2455 return AST_TEST_FAIL;
2456 }
2457
2458 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
2459 ast_test_status_update(test, "Failed to allocate a known object type\n");
2460 goto end;
2461 }
2462
2468
2469 if (ast_sorcery_create(sorcery, obj)) {
2470 ast_test_status_update(test, "Failed to create object using in-memory wizard\n");
2471 goto end;
2472 }
2473
2475 while (!observer.created) {
2476 struct timeval start = ast_tvnow();
2477 struct timespec end = {
2478 .tv_sec = start.tv_sec + 10,
2479 .tv_nsec = start.tv_usec * 1000,
2480 };
2481 if (ast_cond_timedwait(&observer.cond, &observer.lock, &end) == ETIMEDOUT) {
2482 break;
2483 }
2484 }
2486
2487 if (!observer.created) {
2488 ast_test_status_update(test, "Failed to receive observer notification for object creation within suitable timeframe\n");
2489 goto end;
2490 }
2491
2492 if (ast_sorcery_update(sorcery, obj)) {
2493 ast_test_status_update(test, "Failed to update object using in-memory wizard\n");
2494 goto end;
2495 }
2496
2498 while (!observer.updated) {
2499 struct timeval start = ast_tvnow();
2500 struct timespec end = {
2501 .tv_sec = start.tv_sec + 10,
2502 .tv_nsec = start.tv_usec * 1000,
2503 };
2504 if (ast_cond_timedwait(&observer.cond, &observer.lock, &end) == ETIMEDOUT) {
2505 break;
2506 }
2507 }
2509
2510 if (!observer.updated) {
2511 ast_test_status_update(test, "Failed to receive observer notification for object updating within suitable timeframe\n");
2512 goto end;
2513 }
2514
2515 if (ast_sorcery_delete(sorcery, obj)) {
2516 ast_test_status_update(test, "Failed to delete object using in-memory wizard\n");
2517 goto end;
2518 }
2519
2521 while (!observer.deleted) {
2522 struct timeval start = ast_tvnow();
2523 struct timespec end = {
2524 .tv_sec = start.tv_sec + 10,
2525 .tv_nsec = start.tv_usec * 1000,
2526 };
2527 if (ast_cond_timedwait(&observer.cond, &observer.lock, &end) == ETIMEDOUT) {
2528 break;
2529 }
2530 }
2532
2533 if (!observer.deleted) {
2534 ast_test_status_update(test, "Failed to receive observer notification for object deletion within suitable timeframe\n");
2535 goto end;
2536 }
2537
2539
2541 while (!observer.loaded) {
2542 struct timeval start = ast_tvnow();
2543 struct timespec end = {
2544 .tv_sec = start.tv_sec + 10,
2545 .tv_nsec = start.tv_usec * 1000,
2546 };
2547 if (ast_cond_timedwait(&observer.cond, &observer.lock, &end) == ETIMEDOUT) {
2548 break;
2549 }
2550 }
2552
2553 if (!observer.loaded) {
2554 ast_test_status_update(test, "Failed to receive observer notification for object type load within suitable timeframe\n");
2555 goto end;
2556 }
2557
2558 res = AST_TEST_PASS;
2559
2560end:
2566
2567 return res;
2568}
#define ast_cond_destroy(cond)
Definition: lock.h:202
#define ast_cond_init(cond, attr)
Definition: lock.h:201
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:206
#define ast_mutex_init(pmutex)
Definition: lock.h:186
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_destroy(a)
Definition: lock.h:188
#define ast_mutex_lock(a)
Definition: lock.h:189
int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Add an observer to a specific object type.
Definition: sorcery.c:2391
ast_cond_t cond
Condition for notification.
Definition: test_sorcery.c:152
const void * updated
Pointer to the update object.
Definition: test_sorcery.c:158
const void * created
Pointer to the created object.
Definition: test_sorcery.c:155
const void * deleted
Pointer to the deleted object.
Definition: test_sorcery.c:161
unsigned int loaded
Whether the type has been loaded.
Definition: test_sorcery.c:164
ast_mutex_t lock
Lock for notification.
Definition: test_sorcery.c:149
static const struct ast_sorcery_observer test_observer
Test sorcery observer implementation.
Definition: test_sorcery.c:276
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_cond_destroy, ast_cond_init, ast_cond_timedwait, ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_sorcery_alloc(), ast_sorcery_create(), ast_sorcery_delete(), ast_sorcery_observer_add(), ast_sorcery_reload(), ast_sorcery_unref, ast_sorcery_update(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_tvnow(), sorcery_test_observer::cond, sorcery_test_observer::created, sorcery_test_observer::deleted, end, sip_to_pjsip::info(), sorcery_test_observer::loaded, sorcery_test_observer::lock, NULL, observer, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, test_observer, and sorcery_test_observer::updated.

◆ AST_TEST_DEFINE() [37/51]

AST_TEST_DEFINE ( object_update  )

Definition at line 2061 of file test_sorcery.c.

2062{
2065 RAII_VAR(struct test_sorcery_object *, obj2, NULL, ao2_cleanup);
2066
2067 switch (cmd) {
2068 case TEST_INIT:
2069 info->name = "object_update";
2070 info->category = "/main/sorcery/";
2071 info->summary = "sorcery object update unit test";
2072 info->description =
2073 "Test object updating in sorcery";
2074 return AST_TEST_NOT_RUN;
2075 case TEST_EXECUTE:
2076 break;
2077 }
2078
2080 ast_test_status_update(test, "Failed to open sorcery structure\n");
2081 return AST_TEST_FAIL;
2082 }
2083
2084 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
2085 ast_test_status_update(test, "Failed to allocate a known object type\n");
2086 return AST_TEST_FAIL;
2087 }
2088
2089 if (ast_sorcery_create(sorcery, obj)) {
2090 ast_test_status_update(test, "Failed to create object using in-memory wizard\n");
2091 return AST_TEST_FAIL;
2092 }
2093
2094 if (!(obj2 = ast_sorcery_copy(sorcery, obj))) {
2095 ast_test_status_update(test, "Failed to allocate a known object type for updating\n");
2096 return AST_TEST_FAIL;
2097 }
2098
2099 ao2_cleanup(obj);
2100
2101 if (ast_sorcery_update(sorcery, obj2)) {
2102 ast_test_status_update(test, "Failed to update sorcery with new object\n");
2103 return AST_TEST_FAIL;
2104 }
2105
2106 if (!(obj = ast_sorcery_retrieve_by_id(sorcery, "test", "blah"))) {
2107 ast_test_status_update(test, "Failed to retrieve properly updated object\n");
2108 return AST_TEST_FAIL;
2109 } else if (obj != obj2) {
2110 ast_test_status_update(test, "Object retrieved is not the updated object\n");
2111 return AST_TEST_FAIL;
2112 }
2113
2114 return AST_TEST_PASS;
2115}

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_copy(), ast_sorcery_create(), ast_sorcery_retrieve_by_id(), ast_sorcery_unref, ast_sorcery_update(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [38/51]

AST_TEST_DEFINE ( object_update_uncreated  )

Definition at line 2117 of file test_sorcery.c.

2118{
2121
2122 switch (cmd) {
2123 case TEST_INIT:
2124 info->name = "object_update_uncreated";
2125 info->category = "/main/sorcery/";
2126 info->summary = "sorcery object update unit test";
2127 info->description =
2128 "Test updating of an uncreated object in sorcery";
2129 return AST_TEST_NOT_RUN;
2130 case TEST_EXECUTE:
2131 break;
2132 }
2133
2135 ast_test_status_update(test, "Failed to open sorcery structure\n");
2136 return AST_TEST_FAIL;
2137 }
2138
2139 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
2140 ast_test_status_update(test, "Failed to allocate a known object type\n");
2141 return AST_TEST_FAIL;
2142 }
2143
2144 if (!ast_sorcery_update(sorcery, obj)) {
2145 ast_test_status_update(test, "Successfully updated an object which has not been created yet\n");
2146 return AST_TEST_FAIL;
2147 }
2148
2149 return AST_TEST_PASS;
2150}

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_unref, ast_sorcery_update(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [39/51]

AST_TEST_DEFINE ( objectset_apply  )

Definition at line 1259 of file test_sorcery.c.

1260{
1261 int res = AST_TEST_PASS;
1264 RAII_VAR(struct ast_variable *, objset, NULL, ast_variables_destroy);
1265
1266 switch (cmd) {
1267 case TEST_INIT:
1268 info->name = "objectset_apply";
1269 info->category = "/main/sorcery/";
1270 info->summary = "sorcery object apply unit test";
1271 info->description =
1272 "Test object set applying in sorcery";
1273 return AST_TEST_NOT_RUN;
1274 case TEST_EXECUTE:
1275 break;
1276 }
1277
1279 ast_test_status_update(test, "Failed to open sorcery structure\n");
1280 return AST_TEST_FAIL;
1281 }
1282
1283 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
1284 ast_test_status_update(test, "Failed to allocate a known object type\n");
1285 return AST_TEST_FAIL;
1286 }
1287
1288 if (!(objset = ast_variable_new("joe", "25", ""))) {
1289 ast_test_status_update(test, "Failed to create an object set, test could not occur\n");
1290 res = AST_TEST_FAIL;
1291 } else if (ast_sorcery_objectset_apply(sorcery, obj, objset)) {
1292 ast_test_status_update(test, "Failed to apply valid object set to object\n");
1293 res = AST_TEST_FAIL;
1294 } else if (obj->joe != 25) {
1295 ast_test_status_update(test, "Object set was not actually applied to object despite it returning success\n");
1296 res = AST_TEST_FAIL;
1297 }
1298
1299 return res;
1300}

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_objectset_apply(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variable_new, ast_variables_destroy(), sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [40/51]

AST_TEST_DEFINE ( objectset_apply_fields  )

Definition at line 1463 of file test_sorcery.c.

1464{
1465 int res = AST_TEST_PASS;
1468 RAII_VAR(struct ast_variable *, objset, NULL, ast_variables_destroy);
1469
1470 switch (cmd) {
1471 case TEST_INIT:
1472 info->name = "objectset_apply_fields";
1473 info->category = "/main/sorcery/";
1474 info->summary = "sorcery object apply regex fields unit test";
1475 info->description =
1476 "Test object set apply with regex fields in sorcery";
1477 return AST_TEST_NOT_RUN;
1478 case TEST_EXECUTE:
1479 break;
1480 }
1481
1482 if (!(sorcery = ast_sorcery_open())) {
1483 ast_test_status_update(test, "Failed to open sorcery structure\n");
1484 return AST_TEST_FAIL;
1485 }
1486
1487 if ((ast_sorcery_apply_default(sorcery, "test", "memory", NULL) != AST_SORCERY_APPLY_SUCCESS) ||
1489 ast_test_status_update(test, "Failed to register 'test' object type\n");
1490 return AST_TEST_FAIL;
1491 }
1492
1494
1495 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
1496 ast_test_status_update(test, "Failed to allocate a known object type\n");
1497 return AST_TEST_FAIL;
1498 }
1499
1500 if (!(objset = ast_variable_new("toast-bob", "20", ""))) {
1501 ast_test_status_update(test, "Failed to create an object set, test could not occur\n");
1502 res = AST_TEST_FAIL;
1503 } else if (ast_sorcery_objectset_apply(sorcery, obj, objset)) {
1504 ast_test_status_update(test, "Failed to apply valid object set to object\n");
1505 res = AST_TEST_FAIL;
1506 } else if (obj->bob != 256) {
1507 ast_test_status_update(test, "Regex field handler was not called when it should have been\n");
1508 res = AST_TEST_FAIL;
1509 }
1510
1511 return res;
1512}
static int test_apply_handler(const struct ast_sorcery *sorcery, void *obj)
Simple apply handler which sets global scope integer to 1 if called.
Definition: test_sorcery.c:171

References ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_apply_default, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_internal_object_register, ast_sorcery_object_fields_register(), ast_sorcery_objectset_apply(), ast_sorcery_open, ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variable_new, ast_variables_destroy(), sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, test_apply_handler(), TEST_EXECUTE, TEST_INIT, test_sorcery_object_alloc(), test_sorcery_regex_fields(), and test_sorcery_regex_handler().

◆ AST_TEST_DEFINE() [41/51]

AST_TEST_DEFINE ( objectset_apply_handler  )

Definition at line 1302 of file test_sorcery.c.

1303{
1304 int res = AST_TEST_PASS;
1307 RAII_VAR(struct ast_variable *, objset, NULL, ast_variables_destroy);
1308
1309 switch (cmd) {
1310 case TEST_INIT:
1311 info->name = "objectset_apply_handler";
1312 info->category = "/main/sorcery/";
1313 info->summary = "sorcery object apply handler unit test";
1314 info->description =
1315 "Test object set apply handler call in sorcery";
1316 return AST_TEST_NOT_RUN;
1317 case TEST_EXECUTE:
1318 break;
1319 }
1320
1321 if (!(sorcery = ast_sorcery_open())) {
1322 ast_test_status_update(test, "Failed to open sorcery structure\n");
1323 return AST_TEST_FAIL;
1324 }
1325
1326 if ((ast_sorcery_apply_default(sorcery, "test", "memory", NULL) != AST_SORCERY_APPLY_SUCCESS) ||
1328 ast_test_status_update(test, "Failed to register 'test' object type\n");
1329 return AST_TEST_FAIL;
1330 }
1331
1334
1335 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
1336 ast_test_status_update(test, "Failed to allocate a known object type\n");
1337 return AST_TEST_FAIL;
1338 }
1339
1341
1342 if (!(objset = ast_variable_new("joe", "25", ""))) {
1343 ast_test_status_update(test, "Failed to create an object set, test could not occur\n");
1344 res = AST_TEST_FAIL;
1345 } else if (ast_sorcery_objectset_apply(sorcery, obj, objset)) {
1346 ast_test_status_update(test, "Failed to apply valid object set to object\n");
1347 res = AST_TEST_FAIL;
1348 } else if (!apply_handler_called) {
1349 ast_test_status_update(test, "Apply handler was not called when it should have been\n");
1350 res = AST_TEST_FAIL;
1351 }
1352
1353 return res;
1354}
static int apply_handler_called
Global scope apply handler integer to make sure it executed.
Definition: test_sorcery.c:168

References ao2_cleanup, apply_handler_called, ast_sorcery_alloc(), ast_sorcery_apply_default, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_internal_object_register, ast_sorcery_object_field_register_nodoc, ast_sorcery_objectset_apply(), ast_sorcery_open, ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variable_new, ast_variables_destroy(), FLDSET, sip_to_pjsip::info(), NULL, OPT_UINT_T, RAII_VAR, sorcery, test_apply_handler(), TEST_EXECUTE, TEST_INIT, and test_sorcery_object_alloc().

◆ AST_TEST_DEFINE() [42/51]

AST_TEST_DEFINE ( objectset_apply_invalid  )

Definition at line 1356 of file test_sorcery.c.

1357{
1360 RAII_VAR(struct ast_variable *, objset, NULL, ast_variables_destroy);
1361
1362 switch (cmd) {
1363 case TEST_INIT:
1364 info->name = "objectset_apply_invalid";
1365 info->category = "/main/sorcery/";
1366 info->summary = "sorcery object invalid apply unit test";
1367 info->description =
1368 "Test object set applying of an invalid set in sorcery";
1369 return AST_TEST_NOT_RUN;
1370 case TEST_EXECUTE:
1371 break;
1372 }
1373
1375 ast_test_status_update(test, "Failed to open sorcery structure\n");
1376 return AST_TEST_FAIL;
1377 }
1378
1379 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
1380 ast_test_status_update(test, "Failed to allocate a known object type\n");
1381 return AST_TEST_FAIL;
1382 }
1383
1384 if (!(objset = ast_variable_new("fred", "99", ""))) {
1385 ast_test_status_update(test, "Failed to create an object set, test could not occur\n");
1386 return AST_TEST_FAIL;
1387 } else if (!ast_sorcery_objectset_apply(sorcery, obj, objset)) {
1388 ast_test_status_update(test, "Successfully applied an invalid object set\n");
1389 return AST_TEST_FAIL;
1390 } else if ((obj->bob != 5) || (obj->joe != 10)) {
1391 ast_test_status_update(test, "Object set modified object fields when it should not have\n");
1392 return AST_TEST_FAIL;
1393 }
1394
1395 return AST_TEST_PASS;
1396}

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_objectset_apply(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variable_new, ast_variables_destroy(), sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [43/51]

AST_TEST_DEFINE ( objectset_create  )

Definition at line 1069 of file test_sorcery.c.

1070{
1071 int res = AST_TEST_PASS;
1074 RAII_VAR(struct ast_variable *, objset, NULL, ast_variables_destroy);
1075 struct ast_variable *field;
1076
1077 switch (cmd) {
1078 case TEST_INIT:
1079 info->name = "objectset_create";
1080 info->category = "/main/sorcery/";
1081 info->summary = "sorcery object set creation unit test";
1082 info->description =
1083 "Test object set creation in sorcery";
1084 return AST_TEST_NOT_RUN;
1085 case TEST_EXECUTE:
1086 break;
1087 }
1088
1090 ast_test_status_update(test, "Failed to open sorcery structure\n");
1091 return AST_TEST_FAIL;
1092 }
1093
1094 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
1095 ast_test_status_update(test, "Failed to allocate a known object type\n");
1096 return AST_TEST_FAIL;
1097 }
1098
1099 if (!(objset = ast_sorcery_objectset_create(sorcery, obj))) {
1100 ast_test_status_update(test, "Failed to create an object set for a known sane object\n");
1101 return AST_TEST_FAIL;
1102 }
1103
1104 for (field = objset; field; field = field->next) {
1105 if (!strcmp(field->name, "bob")) {
1106 if (strcmp(field->value, "5")) {
1107 ast_test_status_update(test, "Object set failed to create proper value for 'bob'\n");
1108 res = AST_TEST_FAIL;
1109 }
1110 } else if (!strcmp(field->name, "joe")) {
1111 if (strcmp(field->value, "10")) {
1112 ast_test_status_update(test, "Object set failed to create proper value for 'joe'\n");
1113 res = AST_TEST_FAIL;
1114 }
1115 } else if (!strcmp(field->name, "jim")) {
1116 if (strcmp(field->value, "444")) {
1117 ast_test_status_update(test, "Object set failed to create proper value for 'jim'\n");
1118 res = AST_TEST_FAIL;
1119 }
1120 } else if (!strcmp(field->name, "jack")) {
1121 if (strcmp(field->value, "888,999")) {
1122 ast_test_status_update(test, "Object set failed to create proper value (%s) for 'jack'\n", field->value);
1123 res = AST_TEST_FAIL;
1124 }
1125 } else {
1126 ast_test_status_update(test, "Object set created field '%s' which is unknown\n", field->name);
1127 res = AST_TEST_FAIL;
1128 }
1129 }
1130
1131 return res;
1132}
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
Definition: sorcery.h:1137

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_objectset_create, ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variables_destroy(), sip_to_pjsip::info(), ast_variable::name, ast_variable::next, NULL, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, and ast_variable::value.

◆ AST_TEST_DEFINE() [44/51]

AST_TEST_DEFINE ( objectset_create_regex  )

Definition at line 1201 of file test_sorcery.c.

1202{
1203 int res = AST_TEST_PASS;
1206 RAII_VAR(struct ast_variable *, objset, NULL, ast_variables_destroy);
1207 struct ast_variable *field;
1208
1209 switch (cmd) {
1210 case TEST_INIT:
1211 info->name = "objectset_create_regex";
1212 info->category = "/main/sorcery/";
1213 info->summary = "sorcery object set creation with regex fields unit test";
1214 info->description =
1215 "Test object set creation with regex fields in sorcery";
1216 return AST_TEST_NOT_RUN;
1217 case TEST_EXECUTE:
1218 break;
1219 }
1220
1221 if (!(sorcery = ast_sorcery_open())) {
1222 ast_test_status_update(test, "Failed to open sorcery structure\n");
1223 return AST_TEST_FAIL;
1224 }
1225
1226 if ((ast_sorcery_apply_default(sorcery, "test", "memory", NULL) != AST_SORCERY_APPLY_SUCCESS) ||
1228 ast_test_status_update(test, "Failed to register 'test' object type\n");
1229 return AST_TEST_FAIL;
1230 }
1231
1233
1234 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
1235 ast_test_status_update(test, "Failed to allocate a known object type\n");
1236 return AST_TEST_FAIL;
1237 }
1238
1239 if (!(objset = ast_sorcery_objectset_create(sorcery, obj))) {
1240 ast_test_status_update(test, "Failed to create an object set for a known sane object\n");
1241 return AST_TEST_FAIL;
1242 }
1243
1244 for (field = objset; field; field = field->next) {
1245 if (!strcmp(field->name, "toast-bob")) {
1246 if (strcmp(field->value, "10")) {
1247 ast_test_status_update(test, "Object set failed to create proper value for 'bob'\n");
1248 res = AST_TEST_FAIL;
1249 }
1250 } else {
1251 ast_test_status_update(test, "Object set created field '%s' which is unknown\n", field->name);
1252 res = AST_TEST_FAIL;
1253 }
1254 }
1255
1256 return res;
1257}

References ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_apply_default, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_internal_object_register, ast_sorcery_object_fields_register(), ast_sorcery_objectset_create, ast_sorcery_open, ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variables_destroy(), sip_to_pjsip::info(), ast_variable::name, ast_variable::next, NULL, RAII_VAR, sorcery, test_apply_handler(), TEST_EXECUTE, TEST_INIT, test_sorcery_object_alloc(), test_sorcery_regex_fields(), test_sorcery_regex_handler(), and ast_variable::value.

◆ AST_TEST_DEFINE() [45/51]

AST_TEST_DEFINE ( objectset_json_create  )

Definition at line 1134 of file test_sorcery.c.

1135{
1136 int res = AST_TEST_PASS;
1139 RAII_VAR(struct ast_json *, objset, NULL, ast_json_unref);
1140 struct ast_json_iter *field;
1141
1142 switch (cmd) {
1143 case TEST_INIT:
1144 info->name = "objectset_json_create";
1145 info->category = "/main/sorcery/";
1146 info->summary = "sorcery json object set creation unit test";
1147 info->description =
1148 "Test object set creation (for JSON format) in sorcery";
1149 return AST_TEST_NOT_RUN;
1150 case TEST_EXECUTE:
1151 break;
1152 }
1153
1155 ast_test_status_update(test, "Failed to open sorcery structure\n");
1156 return AST_TEST_FAIL;
1157 }
1158
1159 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
1160 ast_test_status_update(test, "Failed to allocate a known object type\n");
1161 return AST_TEST_FAIL;
1162 }
1163
1164 if (!(objset = ast_sorcery_objectset_json_create(sorcery, obj))) {
1165 ast_test_status_update(test, "Failed to create an object set for a known sane object\n");
1166 return AST_TEST_FAIL;
1167 }
1168
1169 for (field = ast_json_object_iter(objset); field; field = ast_json_object_iter_next(objset, field)) {
1170 struct ast_json *value = ast_json_object_iter_value(field);
1171
1172 if (!strcmp(ast_json_object_iter_key(field), "bob")) {
1173 if (strcmp(ast_json_string_get(value), "5")) {
1174 ast_test_status_update(test, "Object set failed to create proper value for 'bob'\n");
1175 res = AST_TEST_FAIL;
1176 }
1177 } else if (!strcmp(ast_json_object_iter_key(field), "joe")) {
1178 if (strcmp(ast_json_string_get(value), "10")) {
1179 ast_test_status_update(test, "Object set failed to create proper value for 'joe'\n");
1180 res = AST_TEST_FAIL;
1181 }
1182 } else if (!strcmp(ast_json_object_iter_key(field), "jim")) {
1183 if (strcmp(ast_json_string_get(value), "444")) {
1184 ast_test_status_update(test, "Object set failed to create proper value for 'jim'\n");
1185 res = AST_TEST_FAIL;
1186 }
1187 } else if (!strcmp(ast_json_object_iter_key(field), "jack")) {
1188 if (strcmp(ast_json_string_get(value), "888,999")) {
1189 ast_test_status_update(test, "Object set failed to create proper value for 'jack'\n");
1190 res = AST_TEST_FAIL;
1191 }
1192 } else {
1193 ast_test_status_update(test, "Object set created field '%s' which is unknown\n", ast_json_object_iter_key(field));
1194 res = AST_TEST_FAIL;
1195 }
1196 }
1197
1198 return res;
1199}
struct ast_json * ast_json_object_iter_value(struct ast_json_iter *iter)
Get the value from an iterator.
Definition: json.c:455
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_json_iter * ast_json_object_iter_next(struct ast_json *object, struct ast_json_iter *iter)
Get the next iterator.
Definition: json.c:447
struct ast_json_iter * ast_json_object_iter(struct ast_json *object)
Get an iterator pointing to the first field in a JSON object.
Definition: json.c:439
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:283
const char * ast_json_object_iter_key(struct ast_json_iter *iter)
Get the key from an iterator.
Definition: json.c:451
struct ast_json * ast_sorcery_objectset_json_create(const struct ast_sorcery *sorcery, const void *object)
Create an object set in JSON format for an object.
Definition: sorcery.c:1565
Iterator for JSON object key/values.
Abstract JSON element (object, array, string, int, ...).

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_json_object_iter(), ast_json_object_iter_key(), ast_json_object_iter_next(), ast_json_object_iter_value(), ast_json_string_get(), ast_json_unref(), ast_sorcery_alloc(), ast_sorcery_objectset_json_create(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, and value.

◆ AST_TEST_DEFINE() [46/51]

AST_TEST_DEFINE ( objectset_transform  )

Definition at line 1398 of file test_sorcery.c.

1399{
1402 RAII_VAR(struct ast_variable *, objset, NULL, ast_variables_destroy);
1403
1404 switch (cmd) {
1405 case TEST_INIT:
1406 info->name = "objectset_transform";
1407 info->category = "/main/sorcery/";
1408 info->summary = "sorcery object set transformation unit test";
1409 info->description =
1410 "Test object set transformation in sorcery";
1411 return AST_TEST_NOT_RUN;
1412 case TEST_EXECUTE:
1413 break;
1414 }
1415
1416 if (!(sorcery = ast_sorcery_open())) {
1417 ast_test_status_update(test, "Failed to open sorcery structure\n");
1418 return AST_TEST_FAIL;
1419 }
1420
1422 ast_test_status_update(test, "Failed to set a known wizard as a default\n");
1423 return AST_TEST_FAIL;
1424 }
1425
1427 ast_test_status_update(test, "Failed to register object type\n");
1428 return AST_TEST_FAIL;
1429 }
1430
1433
1434 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
1435 ast_test_status_update(test, "Failed to allocate a known object type\n");
1436 return AST_TEST_FAIL;
1437 }
1438
1439 if (!(objset = ast_sorcery_objectset_create(sorcery, obj))) {
1440 ast_test_status_update(test, "Failed to create an object set for a known sane object\n");
1441 return AST_TEST_FAIL;
1442 }
1443
1444 if (ast_sorcery_objectset_apply(sorcery, obj, objset)) {
1445 ast_test_status_update(test, "Failed to apply properly created object set against object\n");
1446 return AST_TEST_FAIL;
1447 }
1448
1449 if (obj->bob != 5) {
1450 ast_test_status_update(test, "Application of object set produced incorrect value on 'bob'\n");
1451 return AST_TEST_FAIL;
1452 } else if (obj->joe == 10) {
1453 ast_test_status_update(test, "Transformation callback did not change value of 'joe' from provided value\n");
1454 return AST_TEST_FAIL;
1455 } else if (obj->joe != 5000) {
1456 ast_test_status_update(test, "Value of 'joe' differs from default AND from transformation value\n");
1457 return AST_TEST_FAIL;
1458 }
1459
1460 return AST_TEST_PASS;
1461}
static struct ast_variable * test_sorcery_transform(struct ast_variable *set)
Internal function for object set transformation.
Definition: test_sorcery.c:67

References ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_apply_default, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_internal_object_register, ast_sorcery_object_field_register_nodoc, ast_sorcery_objectset_apply(), ast_sorcery_objectset_create, ast_sorcery_open, ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variables_destroy(), FLDSET, sip_to_pjsip::info(), NULL, OPT_UINT_T, RAII_VAR, sorcery, TEST_EXECUTE, TEST_INIT, test_sorcery_object_alloc(), and test_sorcery_transform().

◆ AST_TEST_DEFINE() [47/51]

AST_TEST_DEFINE ( sorcery_open  )

Definition at line 391 of file test_sorcery.c.

392{
394 RAII_VAR(struct ast_sorcery *, sorcery2, NULL, ast_sorcery_unref);
395 int refcount;
396
397 switch (cmd) {
398 case TEST_INIT:
399 info->name = "open";
400 info->category = "/main/sorcery/";
401 info->summary = "sorcery open/close unit test";
402 info->description =
403 "Test opening of sorcery and registry operations";
404 return AST_TEST_NOT_RUN;
405 case TEST_EXECUTE:
406 break;
407 }
408
410 ast_test_status_update(test, "There should NOT have been an existing sorcery instance\n");
411 return AST_TEST_FAIL;
412 }
413
414 if (!(sorcery = ast_sorcery_open())) {
415 ast_test_status_update(test, "Failed to open new sorcery structure\n");
416 return AST_TEST_FAIL;
417 }
418
420 ast_test_status_update(test, "Failed to find sorcery structure in registry\n");
421 return AST_TEST_FAIL;
422 }
423
424 if (sorcery2 != sorcery) {
425 ast_test_status_update(test, "Should have gotten same sorcery on retrieve\n");
426 return AST_TEST_FAIL;
427 }
428 ast_sorcery_unref(sorcery2);
429
430 if ((refcount = ao2_ref(sorcery, 0)) != 2) {
431 ast_test_status_update(test, "Should have been 2 references to sorcery instead of %d\n", refcount);
432 return AST_TEST_FAIL;
433 }
434
435 if (!(sorcery2 = ast_sorcery_open())) {
436 ast_test_status_update(test, "Failed to open second sorcery structure\n");
437 return AST_TEST_FAIL;
438 }
439
440 if (sorcery2 != sorcery) {
441 ast_test_status_update(test, "Should have gotten same sorcery on 2nd open\n");
442 return AST_TEST_FAIL;
443 }
444
445 if ((refcount = ao2_ref(sorcery, 0)) != 3) {
446 ast_test_status_update(test, "Should have been 3 references to sorcery instead of %d\n", refcount);
447 return AST_TEST_FAIL;
448 }
449
451 ast_sorcery_unref(sorcery2);
452
453 sorcery2 = NULL;
454
457 sorcery = NULL;
458 ast_test_status_update(test, "Should NOT have found sorcery structure in registry\n");
459 return AST_TEST_FAIL;
460 }
461
462 return AST_TEST_PASS;
463}
#define AST_MODULE
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ast_sorcery * ast_sorcery_retrieve_by_module_name(const char *module_name)
Retrieves an existing sorcery instance by module name.
Definition: sorcery.c:672

References ao2_ref, AST_MODULE, ast_sorcery_open, ast_sorcery_retrieve_by_module_name(), ast_sorcery_unref, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [48/51]

AST_TEST_DEFINE ( wizard_apply_and_insert  )

Definition at line 3452 of file test_sorcery.c.

3453{
3457 RAII_VAR(struct ast_sorcery_wizard *, wizard, NULL, ao2_cleanup);
3458 void *data;
3459
3460 switch (cmd) {
3461 case TEST_INIT:
3462 info->name = "wizard_apply_and_insert";
3463 info->category = "/main/sorcery/";
3464 info->summary = "sorcery wizard apply and insert test";
3465 info->description =
3466 "sorcery wizard apply and insert test";
3467 return AST_TEST_NOT_RUN;
3468 case TEST_EXECUTE:
3469 break;
3470 }
3471
3472 wizard1->load = sorcery_test_load;
3473 wizard1->reload = sorcery_test_load;
3474
3475 wizard2->load = sorcery_test_load;
3476 wizard2->reload = sorcery_test_load;
3477
3478 if (!(sorcery = ast_sorcery_open())) {
3479 ast_test_status_update(test, "Failed to open a sorcery instance\n");
3480 return AST_TEST_FAIL;
3481 }
3482
3485
3486 /* test_object_type isn't registered yet so count should return error */
3487 ast_test_validate(test,
3488 ast_sorcery_get_wizard_mapping_count(sorcery, "test_object_type") == -1);
3489
3490 ast_sorcery_apply_default(sorcery, "test_object_type", "test", NULL);
3491
3492 ast_test_validate(test,
3493 ast_sorcery_get_wizard_mapping_count(sorcery, "test_object_type") == 1);
3494
3495 ast_test_validate(test,
3496 ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 0, &wizard, NULL) == 0);
3497 ast_test_validate(test, strcmp("test", wizard->name) == 0);
3498 ao2_ref(wizard, -1);
3499 wizard = NULL;
3500
3501 ast_test_validate(test,
3502 ast_sorcery_insert_wizard_mapping(sorcery, "test_object_type", "test2", "test2data", 0, 0) == 0);
3503
3504 ast_test_validate(test,
3505 ast_sorcery_insert_wizard_mapping(sorcery, "test_object_type", "test2", "test2data", 0, 0) != 0);
3506
3507 ast_test_validate(test,
3508 ast_sorcery_object_type_insert_wizard(sorcery, "test_object_type", "test2", "test2data2",
3510
3511 ast_test_validate(test,
3512 ast_sorcery_object_type_remove_wizard(sorcery, "test_object_type", "test2", "test2data2") == 0);
3513
3514 ast_test_validate(test,
3515 ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 0, &wizard, &data) == 0);
3516 ast_test_validate(test, strcmp("test2", wizard->name) == 0);
3517 ast_test_validate(test, strcmp("test2data", data) == 0);
3518 ao2_ref(wizard, -1);
3519 wizard = NULL;
3520
3521 ast_test_validate(test,
3522 ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 1, &wizard, NULL) == 0);
3523 ast_test_validate(test, strcmp("test", wizard->name) == 0);
3524 ao2_ref(wizard, -1);
3525 wizard = NULL;
3526
3527 /* Test failures */
3528 ast_test_validate(test,
3529 ast_sorcery_get_wizard_mapping(sorcery, "non-existent-type", 0, &wizard, NULL) != 0);
3530
3531 ast_test_validate(test,
3532 ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", -1, &wizard, &data) != 0);
3533
3534 ast_test_validate(test,
3535 ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 2, &wizard, NULL) != 0);
3536
3537 ast_test_validate(test,
3538 ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 2, NULL, NULL) != 0);
3539
3540 /* Test remove */
3541 /* Should fail */
3542 ast_test_validate(test,
3543 ast_sorcery_remove_wizard_mapping(sorcery, "non-existent-type", "somewizard") != 0);
3544 ast_test_validate(test,
3545 ast_sorcery_remove_wizard_mapping(sorcery, "test_object_type", "somewizard") != 0);
3546
3547 /* should work */
3548 ast_test_validate(test,
3549 ast_sorcery_remove_wizard_mapping(sorcery, "test_object_type", "test") == 0);
3550
3551 ast_test_validate(test,
3552 ast_sorcery_get_wizard_mapping_count(sorcery, "test_object_type") == 1);
3553
3554 ast_test_validate(test,
3555 ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 0, &wizard, &data) == 0);
3556 ast_test_validate(test, strcmp("test2", wizard->name) == 0);
3557 ast_test_validate(test, strcmp("test2data", data) == 0);
3558 ao2_ref(wizard, -1);
3559 wizard = NULL;
3560
3561 return AST_TEST_PASS;
3562}
#define ast_sorcery_object_type_insert_wizard(sorcery, object_type_name, wizard_type_name, wizard_args, flags, position, wizard, wizard_data)
Insert an additional object wizard mapping at a specific position in the wizard list returning wizard...
Definition: sorcery.h:646
#define ast_sorcery_insert_wizard_mapping(sorcery, type, name, data, caching, position)
Insert an additional object wizard mapping at a specific position in the wizard list.
Definition: sorcery.h:562
int ast_sorcery_get_wizard_mapping_count(struct ast_sorcery *sorcery, const char *type)
Return the number of wizards mapped to an object type.
Definition: sorcery.c:778
#define ast_sorcery_remove_wizard_mapping(sorcery, type, name)
Remove an object wizard mapping.
Definition: sorcery.h:757
int ast_sorcery_get_wizard_mapping(struct ast_sorcery *sorcery, const char *type, int index, struct ast_sorcery_wizard **wizard, void **data)
By index, return a wizard mapped to an object type.
Definition: sorcery.c:790
@ AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE
Definition: sorcery.h:583
#define ast_sorcery_object_type_remove_wizard(sorcery, object_type_name, wizard_type_name, wizard_args)
Remove an object wizard mapping.
Definition: sorcery.h:724
static void sorcery_test_load(void *data, const struct ast_sorcery *sorcery, const char *type)

References ao2_cleanup, ao2_ref, ast_sorcery_apply_default, ast_sorcery_get_wizard_mapping(), ast_sorcery_get_wizard_mapping_count(), ast_sorcery_insert_wizard_mapping, ast_sorcery_object_type_insert_wizard, ast_sorcery_object_type_remove_wizard, ast_sorcery_open, ast_sorcery_remove_wizard_mapping, ast_sorcery_unref, AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE, ast_sorcery_wizard_register, ast_sorcery_wizard_unregister(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, sorcery, sorcery_test_load(), TEST_EXECUTE, TEST_INIT, test_wizard, and test_wizard2.

◆ AST_TEST_DEFINE() [49/51]

AST_TEST_DEFINE ( wizard_observation  )

Definition at line 3380 of file test_sorcery.c.

3381{
3385 .wizard_loading = wizard_loaded_observer,
3386 .wizard_loaded = wizard_loaded_observer,
3387 };
3388
3389 switch (cmd) {
3390 case TEST_INIT:
3391 info->name = "wizard_observation";
3392 info->category = "/main/sorcery/";
3393 info->summary = "sorcery wizard observation test";
3394 info->description =
3395 "Test observation of sorcery (wizard)";
3396 return AST_TEST_NOT_RUN;
3397 case TEST_EXECUTE:
3398 break;
3399 }
3400
3401 wizard->load = sorcery_test_load;
3402 wizard->reload = sorcery_test_load;
3403
3404 /* Test wizard observer remove and wizard unregister */
3408 event_observed = 0;
3410 ast_test_validate(test, (event_observed == 0), "Wizard observer removed failed");
3411
3412 /* Setup for test loaded and reloaded */
3413 if (!(sorcery = ast_sorcery_open())) {
3414 ast_test_status_update(test, "Failed to open a sorcery instance\n");
3415 return AST_TEST_FAIL;
3416 }
3417
3419 ast_sorcery_apply_default(sorcery, "test_object_type", "test", NULL);
3422
3423 /* Test wizard loading and loaded */
3425
3426 event_observed = 0;
3427 ast_sorcery_load_object(sorcery, "test_object_type");
3428 ast_test_validate(test, (event_observed == 2), "Wizard loaded failed");
3429
3430 event_observed = 0;
3431 ast_sorcery_reload_object(sorcery, "test_object_type");
3433 ast_test_validate(test, (event_observed == 0), "Wizard reloaded failed");
3434
3435 /* Test wizard reloading and reloaded */
3436 observer.wizard_loading = wizard_reloaded_observer;
3437 observer.wizard_loaded = wizard_reloaded_observer;
3439
3440 event_observed = 0;
3441 ast_sorcery_load_object(sorcery, "test_object_type");
3442 ast_test_validate(test, (event_observed == 0), "Wizard loaded failed");
3443
3444 event_observed = 0;
3445 ast_sorcery_reload_object(sorcery, "test_object_type");
3447 ast_test_validate(test, (event_observed == 2), "Wizard reloaded failed");
3448
3449 return AST_TEST_PASS;
3450}
void ast_sorcery_wizard_observer_remove(struct ast_sorcery_wizard *interface, const struct ast_sorcery_wizard_observer *callbacks)
Remove an observer from a sorcery wizard.
Definition: sorcery.c:568
int ast_sorcery_wizard_observer_add(struct ast_sorcery_wizard *wizard, const struct ast_sorcery_wizard_observer *callbacks)
Add an observer to a sorcery wizard.
Definition: sorcery.c:543
Interface for the sorcery wizard observer.
Definition: sorcery.h:265
static void wizard_reloaded_observer(const char *name, const struct ast_sorcery_wizard *wizard, const char *object_type, int reloaded)
static void wizard_loaded_observer(const char *name, const struct ast_sorcery_wizard *wizard, const char *object_type, int reloaded)

References ast_sorcery_apply_default, ast_sorcery_internal_object_register, ast_sorcery_load_object(), ast_sorcery_open, ast_sorcery_reload_object(), ast_sorcery_unref, ast_sorcery_wizard_observer_add(), ast_sorcery_wizard_observer_remove(), ast_sorcery_wizard_register, ast_sorcery_wizard_unregister(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, event_observed, sip_to_pjsip::info(), NULL, observer, RAII_VAR, sorcery, sorcery_test_load(), TEST_EXECUTE, TEST_INIT, test_sorcery_object_alloc(), test_wizard, wizard_loaded_observer(), and wizard_reloaded_observer().

◆ AST_TEST_DEFINE() [50/51]

AST_TEST_DEFINE ( wizard_read_only  )

Definition at line 3569 of file test_sorcery.c.

3570{
3575 struct ast_sorcery_wizard *wizard;
3576
3577 switch (cmd) {
3578 case TEST_INIT:
3579 info->name = "wizard_read_only";
3580 info->category = "/main/sorcery/";
3581 info->summary = "sorcery wizard read-only test";
3582 info->description =
3583 "sorcery wizard read-only test";
3584 return AST_TEST_NOT_RUN;
3585 case TEST_EXECUTE:
3586 break;
3587 }
3588
3589 wizard1->load = sorcery_test_load;
3590 wizard1->reload = sorcery_test_load;
3591
3592 if (!(sorcery = ast_sorcery_open())) {
3593 ast_test_status_update(test, "Failed to open a sorcery instance\n");
3594 return AST_TEST_FAIL;
3595 }
3596
3597 ast_sorcery_wizard_register(wizard_read_only);
3599
3600 if ((ast_sorcery_apply_default(sorcery, "test_object_type", "test-read-only", NULL) != AST_SORCERY_APPLY_SUCCESS) ||
3602 ast_test_status_update(test, "Failed to apply object defaults\n");
3603 return AST_TEST_FAIL;
3604 }
3605
3606 ast_test_validate(test,
3607 ast_sorcery_get_wizard_mapping_count(sorcery, "test_object_type") == 1);
3608
3609 ast_test_validate(test,
3611 "test", "test2data", AST_SORCERY_WIZARD_APPLY_READONLY, &wizard, NULL) == 0);
3612
3613 ast_test_validate(test, strcmp(wizard->name, wizard1->name) == 0);
3614
3615 ast_test_validate(test,
3616 ast_sorcery_get_wizard_mapping_count(sorcery, "test_object_type") == 2);
3617
3618 if (!(obj = ast_sorcery_alloc(sorcery, "test_object_type", "blah"))) {
3619 ast_test_status_update(test, "Failed to allocate a known object type\n");
3620 return AST_TEST_FAIL;
3621 }
3622
3623 if (ast_sorcery_create(sorcery, obj) == 0) {
3624 ast_test_status_update(test, "Should not have created object using read-only wizard\n");
3625 return AST_TEST_FAIL;
3626 }
3627
3628 return AST_TEST_PASS;
3629}
@ AST_SORCERY_WIZARD_APPLY_READONLY
Definition: sorcery.h:581
#define ast_sorcery_object_type_apply_wizard(sorcery, object_type_name, wizard_type_name, wizard_args, flags, wizard, wizard_data)
Apply additional object wizard mappings returning wizard information.
Definition: sorcery.h:678
const char * name
Name of the wizard.
Definition: sorcery.h:278
static struct ast_sorcery_wizard test_read_only_wizard

References ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_apply_default, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_create(), ast_sorcery_get_wizard_mapping_count(), ast_sorcery_internal_object_register, ast_sorcery_object_type_apply_wizard, ast_sorcery_open, ast_sorcery_unref, AST_SORCERY_WIZARD_APPLY_READONLY, ast_sorcery_wizard_register, ast_sorcery_wizard_unregister(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), ast_sorcery_wizard::name, NULL, RAII_VAR, sorcery, sorcery_test_load(), TEST_EXECUTE, TEST_INIT, test_read_only_wizard, test_sorcery_object_alloc(), and test_wizard.

◆ AST_TEST_DEFINE() [51/51]

AST_TEST_DEFINE ( wizard_registration  )

Definition at line 354 of file test_sorcery.c.

355{
356 switch (cmd) {
357 case TEST_INIT:
358 info->name = "wizard_registration";
359 info->category = "/main/sorcery/";
360 info->summary = "sorcery wizard registration and unregistration unit test";
361 info->description =
362 "Test registration and unregistration of a sorcery wizard";
363 return AST_TEST_NOT_RUN;
364 case TEST_EXECUTE:
365 break;
366 }
367
369 ast_test_status_update(test, "Failed to register a perfectly valid sorcery wizard\n");
370 return AST_TEST_FAIL;
371 }
372
374 ast_test_status_update(test, "Successfully registered a sorcery wizard twice, which is bad\n");
375 return AST_TEST_FAIL;
376 }
377
379 ast_test_status_update(test, "Failed to unregister a perfectly valid sorcery wizard\n");
380 return AST_TEST_FAIL;
381 }
382
384 ast_test_status_update(test, "Successfully unregistered a sorcery wizard twice, which is bad\n");
385 return AST_TEST_FAIL;
386 }
387
388 return AST_TEST_PASS;
389}

References ast_sorcery_wizard_register, ast_sorcery_wizard_unregister(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), TEST_EXECUTE, TEST_INIT, and test_wizard.

◆ instance_loaded_observer()

static void instance_loaded_observer ( const char *  name,
const struct ast_sorcery sorcery,
int  reloaded 
)
static

Definition at line 3215 of file test_sorcery.c.

3217{
3218 if (!strcmp(name, "test_sorcery") && !reloaded) {
3220 }
3221}
static const char name[]
Definition: format_mp3.c:68

References event_observed, and name.

Referenced by AST_TEST_DEFINE().

◆ instance_observer()

static void instance_observer ( const char *  name,
struct ast_sorcery sorcery 
)
static

Definition at line 3158 of file test_sorcery.c.

3159{
3160 if (!strcmp(name, "test_sorcery")) {
3161 event_observed = 1;
3162 }
3163}

References event_observed, and name.

Referenced by AST_TEST_DEFINE().

◆ instance_reloaded_observer()

static void instance_reloaded_observer ( const char *  name,
const struct ast_sorcery sorcery,
int  reloaded 
)
static

Definition at line 3223 of file test_sorcery.c.

3225{
3226 if (!strcmp(name, "test_sorcery") && reloaded) {
3228 }
3229}

References event_observed, and name.

Referenced by AST_TEST_DEFINE().

◆ jack_handler()

static int jack_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Definition at line 294 of file test_sorcery.c.

295{
296 struct test_sorcery_object *tobj = obj;
297
298 char *jacks = ast_strdupa(var->value);
299 char *val;
300
301 while ((val = strsep(&jacks, ","))) {
303 }
304 return 0;
305}
#define var
Definition: ast_expr2f.c:605
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
char * strsep(char **str, const char *delims)
#define ast_variable_list_append(head, new_var)
struct ast_variable * jack
Definition: test_sorcery.c:49
Definition: ast_expr2.c:325

References ast_strdupa, ast_variable_list_append, ast_variable_new, test_sorcery_object::jack, strsep(), and var.

Referenced by alloc_and_initialize_sorcery(), and AST_TEST_DEFINE().

◆ jack_str()

static int jack_str ( const void *  obj,
const intptr_t *  args,
char **  buf 
)
static

Definition at line 316 of file test_sorcery.c.

317{
318 const struct test_sorcery_object *tobj = obj;
319 struct ast_variable *curr = tobj->jack;
320 RAII_VAR(struct ast_str *, str, ast_str_create(128), ast_free);
321
322 while(curr) {
323 ast_str_append(&str, 0, "%s,", curr->value);
324 curr = curr->next;
325 }
328 str = NULL;
329 return 0;
330}
const char * str
Definition: app_jack.c:147
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition: strings.h:786
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139

References ast_free, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_truncate(), ast_strdup, buf, test_sorcery_object::jack, ast_variable::next, NULL, RAII_VAR, str, and ast_variable::value.

Referenced by alloc_and_initialize_sorcery(), and AST_TEST_DEFINE().

◆ jim_handler()

static int jim_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Definition at line 284 of file test_sorcery.c.

285{
286 struct test_sorcery_object *tobj = obj;
287
289
290 return 0;
291}
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
Definition: main/config.c:543
struct ast_variable * jim
Definition: test_sorcery.c:48

References ast_variable_list_append, ast_variables_dup(), test_sorcery_object::jim, and var.

Referenced by alloc_and_initialize_sorcery(), and AST_TEST_DEFINE().

◆ jim_vl()

static int jim_vl ( const void *  obj,
struct ast_variable **  fields 
)
static

Definition at line 307 of file test_sorcery.c.

308{
309 const struct test_sorcery_object *tobj = obj;
310 if (tobj->jim) {
311 *fields = ast_variables_dup(tobj->jim);
312 }
313 return 0;
314}

References ast_variables_dup(), and test_sorcery_object::jim.

Referenced by alloc_and_initialize_sorcery(), and AST_TEST_DEFINE().

◆ load_module()

static int load_module ( void  )
static

Definition at line 3688 of file test_sorcery.c.

3689{
3690 AST_TEST_REGISTER(wizard_apply_and_insert);
3691 AST_TEST_REGISTER(wizard_registration);
3692 AST_TEST_REGISTER(sorcery_open);
3693 AST_TEST_REGISTER(apply_default);
3695 AST_TEST_REGISTER(object_register);
3696 AST_TEST_REGISTER(object_register_without_mapping);
3697 AST_TEST_REGISTER(object_field_register);
3698 AST_TEST_REGISTER(object_fields_register);
3699 AST_TEST_REGISTER(object_alloc_with_id);
3700 AST_TEST_REGISTER(object_alloc_without_id);
3701 AST_TEST_REGISTER(object_copy);
3702 AST_TEST_REGISTER(object_copy_native);
3703 AST_TEST_REGISTER(object_diff);
3704 AST_TEST_REGISTER(object_diff_native);
3705 AST_TEST_REGISTER(objectset_create);
3706 AST_TEST_REGISTER(objectset_json_create);
3707 AST_TEST_REGISTER(objectset_create_regex);
3708 AST_TEST_REGISTER(objectset_apply);
3709 AST_TEST_REGISTER(objectset_apply_handler);
3710 AST_TEST_REGISTER(objectset_apply_invalid);
3711 AST_TEST_REGISTER(objectset_transform);
3712 AST_TEST_REGISTER(objectset_apply_fields);
3713 AST_TEST_REGISTER(extended_fields);
3714 AST_TEST_REGISTER(changeset_create);
3715 AST_TEST_REGISTER(changeset_create_unchanged);
3716 AST_TEST_REGISTER(object_create);
3717 AST_TEST_REGISTER(object_retrieve_id);
3718 AST_TEST_REGISTER(object_retrieve_field);
3719 AST_TEST_REGISTER(object_retrieve_multiple_all);
3720 AST_TEST_REGISTER(object_retrieve_multiple_field);
3721 AST_TEST_REGISTER(object_retrieve_regex);
3722 AST_TEST_REGISTER(object_update);
3723 AST_TEST_REGISTER(object_update_uncreated);
3724 AST_TEST_REGISTER(object_delete);
3725 AST_TEST_REGISTER(object_delete_uncreated);
3726 AST_TEST_REGISTER(object_is_stale);
3727 AST_TEST_REGISTER(caching_wizard_behavior);
3728 AST_TEST_REGISTER(object_type_observer);
3729 AST_TEST_REGISTER(configuration_file_wizard);
3730 AST_TEST_REGISTER(configuration_file_wizard_with_file_integrity);
3731 AST_TEST_REGISTER(configuration_file_wizard_with_criteria);
3732 AST_TEST_REGISTER(configuration_file_wizard_retrieve_field);
3733 AST_TEST_REGISTER(configuration_file_wizard_retrieve_multiple);
3734 AST_TEST_REGISTER(configuration_file_wizard_retrieve_multiple_all);
3735 AST_TEST_REGISTER(dialplan_function);
3736 AST_TEST_REGISTER(object_field_registered);
3737 AST_TEST_REGISTER(global_observation);
3738 AST_TEST_REGISTER(instance_observation);
3739 AST_TEST_REGISTER(wizard_observation);
3740 AST_TEST_REGISTER(wizard_read_only);
3741
3743}
static int apply_config(struct aco_info *info)
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
#define AST_TEST_REGISTER(cb)
Definition: test.h:127

References apply_config(), AST_MODULE_LOAD_SUCCESS, and AST_TEST_REGISTER.

◆ object_type_loaded_observer()

static void object_type_loaded_observer ( const char *  name,
const struct ast_sorcery sorcery,
const char *  object_type,
int  reloaded 
)
static

Definition at line 3249 of file test_sorcery.c.

3251{
3252 if (!strcmp(name, "test_sorcery") && !strcmp(object_type, "test_object_type")
3253 && !reloaded) {
3255 }
3256}

References event_observed, and name.

Referenced by AST_TEST_DEFINE().

◆ object_type_registered_observer()

static void object_type_registered_observer ( const char *  name,
struct ast_sorcery sorcery,
const char *  object_type 
)
static

Definition at line 3241 of file test_sorcery.c.

3243{
3244 if (!strcmp(name, "test_sorcery") && !strcmp(object_type, "test_object_type")) {
3246 }
3247}

References event_observed, and name.

Referenced by AST_TEST_DEFINE().

◆ object_type_reloaded_observer()

static void object_type_reloaded_observer ( const char *  name,
const struct ast_sorcery sorcery,
const char *  object_type,
int  reloaded 
)
static

Definition at line 3258 of file test_sorcery.c.

3260{
3261 if (!strcmp(name, "test_sorcery") && !strcmp(object_type, "test_object_type")
3262 && reloaded) {
3264 }
3265}

References event_observed, and name.

Referenced by AST_TEST_DEFINE().

◆ sorcery_observer_created()

static void sorcery_observer_created ( const void *  object)
static

Definition at line 247 of file test_sorcery.c.

248{
250 observer.created = object;
252}
ast_mutex_t lock
Definition: app_sla.c:331
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:589
#define ast_cond_signal(cond)
Definition: lock.h:203

References ast_cond_signal, sorcery_test_observer::cond, sorcery_test_observer::created, lock, sorcery_test_observer::lock, observer, and SCOPED_MUTEX.

◆ sorcery_observer_deleted()

static void sorcery_observer_deleted ( const void *  object)
static

◆ sorcery_observer_loaded()

static void sorcery_observer_loaded ( const char *  object_type)
static

◆ sorcery_observer_updated()

static void sorcery_observer_updated ( const void *  object)
static

◆ sorcery_test_close()

static void sorcery_test_close ( void *  data)
static

Definition at line 191 of file test_sorcery.c.

192{
193
194}

◆ sorcery_test_create()

static int sorcery_test_create ( const struct ast_sorcery sorcery,
void *  data,
void *  object 
)
static

Definition at line 196 of file test_sorcery.c.

197{
198 cache.created = 1;
199 cache.updated = 0;
200 cache.deleted = 0;
201 return 0;
202}

References cache, sorcery_test_caching::created, sorcery_test_caching::deleted, and sorcery_test_caching::updated.

◆ sorcery_test_delete()

static int sorcery_test_delete ( const struct ast_sorcery sorcery,
void *  data,
void *  object 
)
static

Definition at line 215 of file test_sorcery.c.

216{
217 cache.deleted = 1;
218 return 0;
219}

References cache, and sorcery_test_caching::deleted.

◆ sorcery_test_is_stale()

static int sorcery_test_is_stale ( const struct ast_sorcery sorcery,
void *  data,
void *  object 
)
static

Definition at line 221 of file test_sorcery.c.

222{
223 cache.is_stale = 1;
224 return 1;
225}

References cache, and sorcery_test_caching::is_stale.

◆ sorcery_test_load()

static void sorcery_test_load ( void *  data,
const struct ast_sorcery sorcery,
const char *  type 
)
static

Definition at line 3366 of file test_sorcery.c.

3367{
3368 return;
3369}

Referenced by AST_TEST_DEFINE().

◆ sorcery_test_open()

static void * sorcery_test_open ( const char *  data)
static

Definition at line 185 of file test_sorcery.c.

186{
187 wizard2_data = (void *)data;
188 return wizard2_data;
189}
static void * wizard2_data
Definition: test_sorcery.c:183

References wizard2_data.

◆ sorcery_test_retrieve_id()

static void * sorcery_test_retrieve_id ( const struct ast_sorcery sorcery,
void *  data,
const char *  type,
const char *  id 
)
static

Definition at line 204 of file test_sorcery.c.

205{
207}
static const char type[]
Definition: chan_ooh323.c:109

References ast_sorcery_alloc(), cache, sorcery_test_caching::created, sorcery_test_caching::deleted, NULL, sorcery, and type.

◆ sorcery_test_update()

static int sorcery_test_update ( const struct ast_sorcery sorcery,
void *  data,
void *  object 
)
static

Definition at line 209 of file test_sorcery.c.

210{
211 cache.updated = 1;
212 return 0;
213}

References cache, and sorcery_test_caching::updated.

◆ test_apply_handler()

static int test_apply_handler ( const struct ast_sorcery sorcery,
void *  obj 
)
static

Simple apply handler which sets global scope integer to 1 if called.

Definition at line 171 of file test_sorcery.c.

172{
174 return 0;
175}

References apply_handler_called.

Referenced by AST_TEST_DEFINE().

◆ test_sorcery_copy()

static int test_sorcery_copy ( const void *  src,
void *  dst 
)
static

Internal function which copies pre-defined data into an object, natively.

Definition at line 93 of file test_sorcery.c.

94{
95 struct test_sorcery_object *obj = dst;
96 obj->bob = 10;
97 obj->joe = 20;
98 obj->jim = ast_variable_new("jim", "444", "");
99 obj->jack = ast_variable_new("jack", "999,000", "");
100 return 0;
101}
unsigned int bob
Definition: test_sorcery.c:46
unsigned int joe
Definition: test_sorcery.c:47

References ast_variable_new, test_sorcery_object::bob, test_sorcery_object::jack, test_sorcery_object::jim, and test_sorcery_object::joe.

Referenced by AST_TEST_DEFINE().

◆ test_sorcery_diff()

static int test_sorcery_diff ( const void *  original,
const void *  modified,
struct ast_variable **  changes 
)
static

Internal function which creates a pre-defined diff natively.

Definition at line 104 of file test_sorcery.c.

105{
106 *changes = ast_variable_new("yes", "itworks", "");
107 return 0;
108}

References ast_variable_new.

Referenced by AST_TEST_DEFINE().

◆ test_sorcery_object_alloc()

static void * test_sorcery_object_alloc ( const char *  id)
static

Internal function to allocate a test object.

Definition at line 61 of file test_sorcery.c.

62{
64}
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
Definition: sorcery.c:1728
static void test_sorcery_object_destroy(void *obj)
Internal function to destroy a test object.
Definition: test_sorcery.c:53

References ast_sorcery_generic_alloc(), and test_sorcery_object_destroy().

Referenced by alloc_and_initialize_sorcery(), and AST_TEST_DEFINE().

◆ test_sorcery_object_destroy()

static void test_sorcery_object_destroy ( void *  obj)
static

Internal function to destroy a test object.

Definition at line 53 of file test_sorcery.c.

54{
55 struct test_sorcery_object *tobj = obj;
58}

References ast_variables_destroy(), test_sorcery_object::jack, and test_sorcery_object::jim.

Referenced by test_sorcery_object_alloc().

◆ test_sorcery_regex_fields()

static int test_sorcery_regex_fields ( const void *  obj,
struct ast_variable **  fields 
)
static

Internal function which creates some ast_variable structures.

Definition at line 121 of file test_sorcery.c.

122{
123 *fields = ast_variable_new("toast-bob", "10", "");
124
125 return 0;
126}

References ast_variable_new.

Referenced by AST_TEST_DEFINE().

◆ test_sorcery_regex_handler()

static int test_sorcery_regex_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Internal function which sets some values.

Definition at line 111 of file test_sorcery.c.

112{
113 struct test_sorcery_object *test = obj;
114
115 test->bob = 256;
116
117 return 0;
118}

Referenced by AST_TEST_DEFINE().

◆ test_sorcery_transform()

static struct ast_variable * test_sorcery_transform ( struct ast_variable set)
static

Internal function for object set transformation.

Definition at line 67 of file test_sorcery.c.

68{
69 struct ast_variable *field, *transformed = NULL;
70
71 for (field = set; field; field = field->next) {
72 struct ast_variable *transformed_field;
73
74 if (!strcmp(field->name, "joe")) {
75 transformed_field = ast_variable_new(field->name, "5000", "");
76 } else {
77 transformed_field = ast_variable_new(field->name, field->value, "");
78 }
79
80 if (!transformed_field) {
81 ast_variables_destroy(transformed);
82 return NULL;
83 }
84
85 transformed_field->next = transformed;
86 transformed = transformed_field;
87 }
88
89 return transformed;
90}
static int set(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_logic.c:238

References ast_variable_new, ast_variables_destroy(), ast_variable::name, ast_variable::next, NULL, set(), and ast_variable::value.

Referenced by AST_TEST_DEFINE().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 3631 of file test_sorcery.c.

3632{
3633 AST_TEST_UNREGISTER(wizard_registration);
3634 AST_TEST_UNREGISTER(sorcery_open);
3635 AST_TEST_UNREGISTER(apply_default);
3637 AST_TEST_UNREGISTER(object_register);
3638 AST_TEST_UNREGISTER(object_register_without_mapping);
3639 AST_TEST_UNREGISTER(object_field_register);
3640 AST_TEST_UNREGISTER(object_fields_register);
3641 AST_TEST_UNREGISTER(object_alloc_with_id);
3642 AST_TEST_UNREGISTER(object_alloc_without_id);
3643 AST_TEST_UNREGISTER(object_copy);
3644 AST_TEST_UNREGISTER(object_copy_native);
3645 AST_TEST_UNREGISTER(object_diff);
3646 AST_TEST_UNREGISTER(object_diff_native);
3647 AST_TEST_UNREGISTER(objectset_create);
3648 AST_TEST_UNREGISTER(objectset_json_create);
3649 AST_TEST_UNREGISTER(objectset_create_regex);
3650 AST_TEST_UNREGISTER(objectset_apply);
3651 AST_TEST_UNREGISTER(objectset_apply_handler);
3652 AST_TEST_UNREGISTER(objectset_apply_invalid);
3653 AST_TEST_UNREGISTER(objectset_transform);
3654 AST_TEST_UNREGISTER(objectset_apply_fields);
3655 AST_TEST_UNREGISTER(extended_fields);
3656 AST_TEST_UNREGISTER(changeset_create);
3657 AST_TEST_UNREGISTER(changeset_create_unchanged);
3658 AST_TEST_UNREGISTER(object_create);
3659 AST_TEST_UNREGISTER(object_retrieve_id);
3660 AST_TEST_UNREGISTER(object_retrieve_field);
3661 AST_TEST_UNREGISTER(object_retrieve_multiple_all);
3662 AST_TEST_UNREGISTER(object_retrieve_multiple_field);
3663 AST_TEST_UNREGISTER(object_retrieve_regex);
3664 AST_TEST_UNREGISTER(object_update);
3665 AST_TEST_UNREGISTER(object_update_uncreated);
3666 AST_TEST_UNREGISTER(object_delete);
3667 AST_TEST_UNREGISTER(object_delete_uncreated);
3668 AST_TEST_UNREGISTER(object_is_stale);
3669 AST_TEST_UNREGISTER(caching_wizard_behavior);
3670 AST_TEST_UNREGISTER(object_type_observer);
3671 AST_TEST_UNREGISTER(configuration_file_wizard);
3672 AST_TEST_UNREGISTER(configuration_file_wizard_with_file_integrity);
3673 AST_TEST_UNREGISTER(configuration_file_wizard_with_criteria);
3674 AST_TEST_UNREGISTER(configuration_file_wizard_retrieve_field);
3675 AST_TEST_UNREGISTER(configuration_file_wizard_retrieve_multiple);
3676 AST_TEST_UNREGISTER(configuration_file_wizard_retrieve_multiple_all);
3677 AST_TEST_UNREGISTER(dialplan_function);
3678 AST_TEST_UNREGISTER(object_field_registered);
3679 AST_TEST_UNREGISTER(global_observation);
3680 AST_TEST_UNREGISTER(instance_observation);
3681 AST_TEST_UNREGISTER(wizard_observation);
3682 AST_TEST_UNREGISTER(wizard_apply_and_insert);
3683 AST_TEST_UNREGISTER(wizard_read_only);
3684
3685 return 0;
3686}
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128

References apply_config(), and AST_TEST_UNREGISTER.

◆ wizard_loaded_observer()

static void wizard_loaded_observer ( const char *  name,
const struct ast_sorcery_wizard wizard,
const char *  object_type,
int  reloaded 
)
static

Definition at line 3357 of file test_sorcery.c.

3359{
3360 if (!strcmp(name, "test") && !strcmp(object_type, "test_object_type")
3361 && !reloaded) {
3363 }
3364}

References event_observed, and name.

Referenced by AST_TEST_DEFINE().

◆ wizard_mapped_observer()

static void wizard_mapped_observer ( const char *  name,
struct ast_sorcery sorcery,
const char *  object_type,
struct ast_sorcery_wizard wizard,
const char *  wizard_args,
void *  wizard_data 
)
static

Definition at line 3231 of file test_sorcery.c.

3234{
3235 if (!strcmp(name, "test_sorcery") && !strcmp(object_type, "test_object_type")
3236 && !strcmp(wizard->name, "memory") && !strcmp(wizard_args, "memwiz")) {
3238 }
3239}

References event_observed, name, and ast_sorcery_wizard::name.

Referenced by AST_TEST_DEFINE().

◆ wizard_observer()

static void wizard_observer ( const char *  name,
const struct ast_sorcery_wizard wizard 
)
static

Definition at line 3151 of file test_sorcery.c.

3152{
3153 if (!strcmp(wizard->name, "test")) {
3154 event_observed = 1;
3155 }
3156}

References event_observed, and ast_sorcery_wizard::name.

Referenced by AST_TEST_DEFINE().

◆ wizard_reloaded_observer()

static void wizard_reloaded_observer ( const char *  name,
const struct ast_sorcery_wizard wizard,
const char *  object_type,
int  reloaded 
)
static

Definition at line 3371 of file test_sorcery.c.

3373{
3374 if (!strcmp(name, "test") && !strcmp(object_type, "test_object_type")
3375 && reloaded) {
3377 }
3378}

References event_observed, and name.

Referenced by AST_TEST_DEFINE().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Sorcery test module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 3745 of file test_sorcery.c.

◆ apply_handler_called

int apply_handler_called
static

Global scope apply handler integer to make sure it executed.

Definition at line 168 of file test_sorcery.c.

Referenced by AST_TEST_DEFINE(), and test_apply_handler().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 3745 of file test_sorcery.c.

◆ cache

struct sorcery_test_caching cache = { 0, }
static

Global scope caching structure for testing.

Definition at line 178 of file test_sorcery.c.

Referenced by AST_TEST_DEFINE(), sorcery_test_create(), sorcery_test_delete(), sorcery_test_is_stale(), sorcery_test_retrieve_id(), and sorcery_test_update().

◆ event_observed

int event_observed
static

◆ observer

struct sorcery_test_observer observer
static

Global scope observer structure for testing.

Definition at line 181 of file test_sorcery.c.

Referenced by AST_TEST_DEFINE(), sorcery_observer_created(), sorcery_observer_deleted(), sorcery_observer_loaded(), and sorcery_observer_updated().

◆ test_observer

const struct ast_sorcery_observer test_observer
static

Test sorcery observer implementation.

Definition at line 276 of file test_sorcery.c.

Referenced by AST_TEST_DEFINE().

◆ test_read_only_wizard

struct ast_sorcery_wizard test_read_only_wizard
static
Initial value:
= {
.name = "test-read-only",
.retrieve_id = sorcery_test_retrieve_id,
}
static void * sorcery_test_retrieve_id(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
Definition: test_sorcery.c:204

Definition at line 3564 of file test_sorcery.c.

Referenced by AST_TEST_DEFINE().

◆ test_wizard

struct ast_sorcery_wizard test_wizard
static

Dummy sorcery wizards, not actually used so we only populate the name and nothing else.

Definition at line 228 of file test_sorcery.c.

Referenced by AST_TEST_DEFINE().

◆ test_wizard2

struct ast_sorcery_wizard test_wizard2
static

Definition at line 236 of file test_sorcery.c.

Referenced by AST_TEST_DEFINE().

◆ wizard2_data

void* wizard2_data
static

Definition at line 183 of file test_sorcery.c.

Referenced by sorcery_test_open().