Asterisk - The Open Source Telephony Project GIT-master-77d630f
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 3752 of file test_sorcery.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 3752 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:231
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 3752 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:3541
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1287
@ CONFIG_FLAG_NOCACHE
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:1205
def info(msg)
#define ast_sorcery_apply_config(sorcery, name)
Definition: sorcery.h:455
Structure used to handle boolean flags.
Definition: utils.h:217
unsigned int flags
Definition: utils.h:218
@ 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:978

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 2319 of file test_sorcery.c.

2320{
2321 struct ast_flags flags = { CONFIG_FLAG_NOCACHE };
2322 struct ast_config *config;
2325 RAII_VAR(struct test_sorcery_object *, obj2, NULL, ao2_cleanup);
2326 int res = AST_TEST_FAIL;
2327
2328 switch (cmd) {
2329 case TEST_INIT:
2330 info->name = "caching_wizard_behavior";
2331 info->category = "/main/sorcery/";
2332 info->summary = "sorcery caching wizard behavior unit test";
2333 info->description =
2334 "Test internal behavior of caching wizards";
2335 return AST_TEST_NOT_RUN;
2336 case TEST_EXECUTE:
2337 break;
2338 }
2339
2340 if (!(config = ast_config_load2("sorcery.conf", "test_sorcery_cache", flags))) {
2341 ast_test_status_update(test, "Sorcery configuration file not present - skipping caching_wizard_behavior test\n");
2342 return AST_TEST_NOT_RUN;
2343 }
2344
2345 if (!ast_category_get(config, "test_sorcery_cache", NULL)) {
2346 ast_test_status_update(test, "Sorcery configuration file does not contain 'test_sorcery_cache' section\n");
2348 return AST_TEST_NOT_RUN;
2349 }
2350
2352
2354 ast_test_status_update(test, "Failed to register a perfectly valid sorcery wizard\n");
2355 return AST_TEST_FAIL;
2356 }
2357
2358 if (!(sorcery = ast_sorcery_open())) {
2359 ast_test_status_update(test, "Failed to open sorcery structure\n");
2360 goto end;
2361 }
2362
2363 if (ast_sorcery_apply_config(sorcery, "test_sorcery_cache") != AST_SORCERY_APPLY_SUCCESS) {
2364 ast_test_status_update(test, "Failed to apply configured object mappings\n");
2365 goto end;
2366 }
2367
2369 ast_test_status_update(test, "Failed to register object type\n");
2370 goto end;
2371 }
2372
2373 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
2374 ast_test_status_update(test, "Failed to allocate a known object type\n");
2375 goto end;
2376 }
2377
2378 if (ast_sorcery_create(sorcery, obj)) {
2379 ast_test_status_update(test, "Failed to create object using in-memory wizard\n");
2380 goto end;
2381 }
2382
2383 ao2_cleanup(obj);
2384
2385 if (!(obj = ast_sorcery_retrieve_by_id(sorcery, "test", "blah"))) {
2386 ast_test_status_update(test, "Failed to retrieve just created object\n");
2387 goto end;
2388 } else if (!cache.created) {
2389 ast_test_status_update(test, "Caching wizard was not told to cache just created object\n");
2390 goto end;
2391 } else if (!(obj2 = ast_sorcery_retrieve_by_id(sorcery, "test", "blah"))) {
2392 ast_test_status_update(test, "Failed to retrieve just cached object\n");
2393 goto end;
2394 } else if (obj == obj2) {
2395 ast_test_status_update(test, "Returned object is *NOT* a cached object\n");
2396 goto end;
2397 } else if (ast_sorcery_update(sorcery, obj)) {
2398 ast_test_status_update(test, "Failed to update a known stored object\n");
2399 goto end;
2400 } else if (!cache.updated) {
2401 ast_test_status_update(test, "Caching wizard was not told to update object\n");
2402 goto end;
2403 } else if (ast_sorcery_delete(sorcery, obj)) {
2404 ast_test_status_update(test, "Failed to delete a known stored object\n");
2405 goto end;
2406 } else if (!cache.deleted) {
2407 ast_test_status_update(test, "Caching wizard was not told to delete object\n");
2408 goto end;
2409 }
2410
2411 ao2_cleanup(obj2);
2412
2413 if ((obj2 = ast_sorcery_retrieve_by_id(sorcery, "test", "blah"))) {
2414 ast_test_status_update(test, "Retrieved an object that should have been deleted\n");
2415 goto end;
2416 }
2417
2418 res = AST_TEST_PASS;
2419
2420end:
2422 sorcery = NULL;
2423
2425 ast_test_status_update(test, "Failed to unregister test sorcery wizard\n");
2426 return AST_TEST_FAIL;
2427 }
2428
2429 return res;
2430}
#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:537
int ast_sorcery_create(const struct ast_sorcery *sorcery, void *object)
Create and potentially persist an object using an available wizard.
Definition: sorcery.c:2125
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:1916
#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:1807
int ast_sorcery_update(const struct ast_sorcery *sorcery, void *object)
Update an object.
Definition: sorcery.c:2213
int ast_sorcery_delete(const struct ast_sorcery *sorcery, void *object)
Delete an object.
Definition: sorcery.c:2301
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}
#define ast_variable_new(name, value, filename)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1260
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:1726
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next

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(), ast_variable::name, ast_variable::next, NULL, RAII_VAR, TEST_EXECUTE, TEST_INIT, and ast_variable::value.

◆ 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(), ast_variable::next, NULL, RAII_VAR, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [6/51]

AST_TEST_DEFINE ( configuration_file_wizard  )

Definition at line 2577 of file test_sorcery.c.

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

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 2752 of file test_sorcery.c.

2753{
2754 struct ast_flags flags = { CONFIG_FLAG_NOCACHE };
2755 struct ast_config *config;
2758 RAII_VAR(struct ast_variable *, fields, ast_variable_new("joe", "41", ""), ast_variables_destroy);
2759
2760 switch (cmd) {
2761 case TEST_INIT:
2762 info->name = "configuration_file_wizard_retrieve_field";
2763 info->category = "/main/sorcery/";
2764 info->summary = "sorcery configuration file wizard field retrieval unit test";
2765 info->description =
2766 "Test the configuration file wizard retrieval using field in sorcery";
2767 return AST_TEST_NOT_RUN;
2768 case TEST_EXECUTE:
2769 break;
2770 }
2771
2772 if (!(config = ast_config_load2("test_sorcery.conf", "test_sorcery", flags))) {
2773 ast_test_status_update(test, "Test sorcery configuration file wizard file not present - skipping configuration_file_wizard_retrieve_field test\n");
2774 return AST_TEST_NOT_RUN;
2775 }
2776
2778
2779 if (!(sorcery = ast_sorcery_open())) {
2780 ast_test_status_update(test, "Failed to open sorcery structure\n");
2781 return AST_TEST_FAIL;
2782 }
2783
2784 if (ast_sorcery_apply_default(sorcery, "test", "config", "test_sorcery.conf") != AST_SORCERY_APPLY_SUCCESS) {
2785 ast_test_status_update(test, "Could not set a default wizard of the 'config' type, so skipping since it may not be loaded\n");
2786 return AST_TEST_NOT_RUN;
2787 }
2788
2790 ast_test_status_update(test, "Failed to register object type\n");
2791 return AST_TEST_FAIL;
2792 }
2793
2796
2798
2799 if (!(obj = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, fields))) {
2800 ast_test_status_update(test, "Failed to retrieve a known object that has been configured with the correct field\n");
2801 return AST_TEST_FAIL;
2802 } else if (strcmp(ast_sorcery_object_get_id(obj), "hey")) {
2803 ast_test_status_update(test, "Retrieved object has incorrect object id of '%s'\n", ast_sorcery_object_get_id(obj));
2804 return AST_TEST_FAIL;
2805 }
2806
2807 return AST_TEST_PASS;
2808}
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2380
@ 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:1960

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 2810 of file test_sorcery.c.

2811{
2812 struct ast_flags flags = { CONFIG_FLAG_NOCACHE };
2813 struct ast_config *config;
2815 RAII_VAR(struct ao2_container *, objects, NULL, ao2_cleanup);
2816 RAII_VAR(struct ast_variable *, fields, ast_variable_new("joe", "99", ""), ast_variables_destroy);
2817
2818 switch (cmd) {
2819 case TEST_INIT:
2820 info->name = "configuration_file_wizard_retrieve_multiple";
2821 info->category = "/main/sorcery/";
2822 info->summary = "sorcery configuration file wizard multiple retrieval unit test";
2823 info->description =
2824 "Test the configuration file wizard multiple retrieval in sorcery";
2825 return AST_TEST_NOT_RUN;
2826 case TEST_EXECUTE:
2827 break;
2828 }
2829
2830 if (!(config = ast_config_load2("test_sorcery.conf", "test_sorcery", flags))) {
2831 ast_test_status_update(test, "Test sorcery configuration file wizard file not present - skipping configuration_file_wizard_retrieve_multiple test\n");
2832 return AST_TEST_NOT_RUN;
2833 }
2834
2836
2837 if (!fields) {
2838 ast_test_status_update(test, "Failed to create fields for multiple retrieve\n");
2839 return AST_TEST_FAIL;
2840 }
2841
2842 if (!(sorcery = ast_sorcery_open())) {
2843 ast_test_status_update(test, "Failed to open sorcery structure\n");
2844 return AST_TEST_FAIL;
2845 }
2846
2847 if (ast_sorcery_apply_default(sorcery, "test", "config", "test_sorcery.conf") != AST_SORCERY_APPLY_SUCCESS) {
2848 ast_test_status_update(test, "Could not set a default wizard of the 'config' type, so skipping since it may not be loaded\n");
2849 return AST_TEST_NOT_RUN;
2850 }
2851
2853 ast_test_status_update(test, "Failed to register object type\n");
2854 return AST_TEST_FAIL;
2855 }
2856
2859
2861
2862 if (!(objects = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE, fields))) {
2863 ast_test_status_update(test, "Failed to retrieve an empty container when retrieving multiple\n");
2864 return AST_TEST_FAIL;
2865 } else if (ao2_container_count(objects)) {
2866 ast_test_status_update(test, "Received a container with objects when there should be none in it\n");
2867 return AST_TEST_FAIL;
2868 }
2869
2870 ao2_cleanup(objects);
2871 ast_variables_destroy(fields);
2872
2873 if (!(fields = ast_variable_new("joe", "41", ""))) {
2874 ast_test_status_update(test, "Failed to create fields for multiple retrieve\n");
2875 return AST_TEST_FAIL;
2876 } else if (!(objects = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE, fields))) {
2877 ast_test_status_update(test, "Failed to retrieve a container when retrieving multiple\n");
2878 return AST_TEST_FAIL;
2879 } else if (ao2_container_count(objects) != 1) {
2880 ast_test_status_update(test, "Received a container with no objects in it when there should be\n");
2881 return AST_TEST_FAIL;
2882 }
2883
2884 return AST_TEST_PASS;
2885}
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 2887 of file test_sorcery.c.

2888{
2889 struct ast_flags flags = { CONFIG_FLAG_NOCACHE };
2890 struct ast_config *config;
2892 RAII_VAR(struct ao2_container *, objects, NULL, ao2_cleanup);
2893
2894 switch (cmd) {
2895 case TEST_INIT:
2896 info->name = "configuration_file_wizard_retrieve_multiple_all";
2897 info->category = "/main/sorcery/";
2898 info->summary = "sorcery configuration file wizard multiple retrieve all unit test";
2899 info->description =
2900 "Test the configuration file wizard multiple retrieve all in sorcery";
2901 return AST_TEST_NOT_RUN;
2902 case TEST_EXECUTE:
2903 break;
2904 }
2905
2906 if (!(config = ast_config_load2("test_sorcery.conf", "test_sorcery", flags))) {
2907 ast_test_status_update(test, "Test sorcery configuration file wizard file not present - skipping configuration_file_wizard_retrieve_multiple_all test\n");
2908 return AST_TEST_NOT_RUN;
2909 }
2910
2912
2913 if (!(sorcery = ast_sorcery_open())) {
2914 ast_test_status_update(test, "Failed to open sorcery structure\n");
2915 return AST_TEST_FAIL;
2916 }
2917
2918 if (ast_sorcery_apply_default(sorcery, "test", "config", "test_sorcery.conf") != AST_SORCERY_APPLY_SUCCESS) {
2919 ast_test_status_update(test, "Could not set a default wizard of the 'config' type, so skipping since it may not be loaded\n");
2920 return AST_TEST_NOT_RUN;
2921 }
2922
2924 ast_test_status_update(test, "Failed to register object type\n");
2925 return AST_TEST_FAIL;
2926 }
2927
2930
2932
2934 ast_test_status_update(test, "Failed to retrieve a container with all objects when there should be one\n");
2935 return AST_TEST_FAIL;
2936 } else if (ao2_container_count(objects) != 2) {
2937 ast_test_status_update(test, "Returned container does not have the correct number of objects in it\n");
2938 return AST_TEST_FAIL;
2939 }
2940
2941 return AST_TEST_PASS;
2942}
@ 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 2694 of file test_sorcery.c.

2695{
2696 struct ast_flags flags = { CONFIG_FLAG_NOCACHE };
2697 struct ast_config *config;
2700
2701 switch (cmd) {
2702 case TEST_INIT:
2703 info->name = "configuration_file_wizard_with_criteria";
2704 info->category = "/main/sorcery/";
2705 info->summary = "sorcery configuration file wizard with criteria unit test";
2706 info->description =
2707 "Test the configuration file wizard with criteria matching in sorcery";
2708 return AST_TEST_NOT_RUN;
2709 case TEST_EXECUTE:
2710 break;
2711 }
2712
2713 if (!(config = ast_config_load2("test_sorcery.conf", "test_sorcery", flags))) {
2714 ast_test_status_update(test, "Test sorcery configuration file wizard file not present - skipping configuration_file_wizard_with_criteria test\n");
2715 return AST_TEST_NOT_RUN;
2716 }
2717
2719
2720 if (!(sorcery = ast_sorcery_open())) {
2721 ast_test_status_update(test, "Failed to open sorcery structure\n");
2722 return AST_TEST_FAIL;
2723 }
2724
2725 if (ast_sorcery_apply_default(sorcery, "test", "config", "test_sorcery.conf,criteria=type=zombies") != AST_SORCERY_APPLY_SUCCESS) {
2726 ast_test_status_update(test, "Could not set a default wizard of the 'config' type, so skipping since it may not be loaded\n");
2727 return AST_TEST_NOT_RUN;
2728 }
2729
2731 ast_test_status_update(test, "Failed to register object type\n");
2732 return AST_TEST_FAIL;
2733 }
2734
2738
2740
2741 if ((obj = ast_sorcery_retrieve_by_id(sorcery, "test", "hey"))) {
2742 ast_test_status_update(test, "Retrieved object which did not match criteria\n");
2743 return AST_TEST_FAIL;
2744 } else if (!(obj = ast_sorcery_retrieve_by_id(sorcery, "test", "hey2"))) {
2745 ast_test_status_update(test, "Failed to retrieve a known object which matches criteria\n");
2746 return AST_TEST_FAIL;
2747 }
2748
2749 return AST_TEST_PASS;
2750}
@ 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 2640 of file test_sorcery.c.

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

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 2944 of file test_sorcery.c.

2945{
2948 RAII_VAR(struct ast_variable *, objset, NULL, ast_variables_destroy);
2949 struct ast_str *buf;
2950 char expression[256];
2951
2952 switch (cmd) {
2953 case TEST_INIT:
2954 info->name = "dialplan_function";
2955 info->category = "/main/sorcery/";
2956 info->summary = "AST_SORCERY dialplan function";
2957 info->description =
2958 "Test the AST_SORCERY dialplan function";
2959 return AST_TEST_NOT_RUN;
2960 case TEST_EXECUTE:
2961 break;
2962 }
2963
2965 ast_test_status_update(test, "Failed to open sorcery structure\n");
2966 return AST_TEST_FAIL;
2967 }
2968
2969 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
2970 ast_test_status_update(test, "Failed to allocate a known object type\n");
2971 return AST_TEST_FAIL;
2972 }
2973
2974 if (ast_sorcery_create(sorcery, obj)) {
2975 ast_test_status_update(test, "Failed to create a known object type\n");
2976 return AST_TEST_FAIL;
2977 }
2978
2979 if (!(buf = ast_str_create(16))) {
2980 ast_test_status_update(test, "Failed to allocate return buffer\n");
2981 return AST_TEST_FAIL;
2982 }
2983
2985 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s)", "notest_sorcery", "test", "blah", "bob");
2986 if (!ast_func_read2(NULL, expression, &buf, 16)) {
2987 ast_free(buf);
2988 ast_test_status_update(test, "Retrieved a non-existent module\n");
2989 return AST_TEST_FAIL;
2990 }
2991
2993 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s)", "test_sorcery", "notest", "blah", "bob");
2994 if (!ast_func_read2(NULL, expression, &buf, 16)) {
2995 ast_free(buf);
2996 ast_test_status_update(test, "Retrieved a non-existent type\n");
2997 return AST_TEST_FAIL;
2998 }
2999
3001 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s)", "test_sorcery", "test", "noid", "bob");
3002 if (!ast_func_read2(NULL, expression, &buf, 16)) {
3003 ast_free(buf);
3004 ast_test_status_update(test, "Retrieved a non-existent id\n");
3005 return AST_TEST_FAIL;
3006 }
3007
3009 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s)", "test_sorcery", "test", "blah", "nobob");
3010 if (!ast_func_read2(NULL, expression, &buf, 16)) {
3011 ast_free(buf);
3012 ast_test_status_update(test, "Retrieved a non-existent field\n");
3013 return AST_TEST_FAIL;
3014 }
3015
3017 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s)", "test_sorcery", "test", "blah", "bob");
3018 if (ast_func_read2(NULL, expression, &buf, 16)) {
3019 ast_free(buf);
3020 ast_test_status_update(test, "Failed retrieve field 'bob'\n");
3021 return AST_TEST_FAIL;
3022 }
3023 if (strcmp(ast_str_buffer(buf), "5")) {
3024 ast_free(buf);
3025 ast_test_status_update(test, "Failed retrieve field. Got '%u', should be '5'\n", obj->bob);
3026 return AST_TEST_FAIL;
3027 }
3028
3030 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s,single,1)", "test_sorcery", "test", "blah", "bob");
3031 if (ast_func_read2(NULL, expression, &buf, 16)) {
3032 ast_free(buf);
3033 ast_test_status_update(test, "Failed retrieve field 'bob'\n");
3034 return AST_TEST_FAIL;
3035 }
3036 if (strcmp(ast_str_buffer(buf), "5")) {
3037 ast_free(buf);
3038 ast_test_status_update(test, "Failed retrieve field. Got '%u', should be '5'\n", obj->bob);
3039 return AST_TEST_FAIL;
3040 }
3041
3043 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s,single,2)", "test_sorcery", "test", "blah", "bob");
3044 if (!ast_func_read2(NULL, expression, &buf, 16)) {
3045 ast_free(buf);
3046 ast_test_status_update(test, "Got a second 'bob' and shouldn't have\n");
3047 return AST_TEST_FAIL;
3048 }
3049
3050 /* 444 is already the first item in the list */
3051 jim_handler(NULL, ast_variable_new("jim", "555", ""), obj);
3052 jim_handler(NULL, ast_variable_new("jim", "666", ""), obj);
3053
3055 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s)", "test_sorcery", "test", "blah", "jim");
3056 if (ast_func_read2(NULL, expression, &buf, 16)) {
3057 ast_free(buf);
3058 ast_test_status_update(test, "Couldn't retrieve 'jim'\n");
3059 return AST_TEST_FAIL;
3060 }
3061 if (strcmp(ast_str_buffer(buf), "444,555,666")) {
3062 ast_free(buf);
3063 ast_test_status_update(test, "Failed retrieve jim. Got '%s', should be '444,555,666'\n", ast_str_buffer(buf));
3064 return AST_TEST_FAIL;
3065 }
3066
3068 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s,single,2)", "test_sorcery", "test", "blah", "jim");
3069 if (ast_func_read2(NULL, expression, &buf, 16)) {
3070 ast_free(buf);
3071 ast_test_status_update(test, "Couldn't retrieve 2nd jim\n");
3072 return AST_TEST_FAIL;
3073 }
3074 if (strcmp(ast_str_buffer(buf), "555")) {
3075 ast_free(buf);
3076 ast_test_status_update(test, "Failed retrieve 2nd jim. Got '%s', should be '555'\n", ast_str_buffer(buf));
3077 return AST_TEST_FAIL;
3078 }
3079
3081 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s,concat,|)", "test_sorcery", "test", "blah", "jim");
3082 if (ast_func_read2(NULL, expression, &buf, 16)) {
3083 ast_free(buf);
3084 ast_test_status_update(test, "Couldn't retrieve any 'jim'\n");
3085 return AST_TEST_FAIL;
3086 }
3087 if (strcmp(ast_str_buffer(buf), "444|555|666")) {
3088 ast_free(buf);
3089 ast_test_status_update(test, "Failed retrieve 'jim'. Got '%s', should be '444|555|666'\n", ast_str_buffer(buf));
3090 return AST_TEST_FAIL;
3091 }
3092
3094 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s,noconcat,3)", "test_sorcery", "test", "blah", "jim");
3095 if (!ast_func_read2(NULL, expression, &buf, 16)) {
3096 ast_free(buf);
3097 ast_test_status_update(test, "Should have failed with invalid retrieval_type\n");
3098 return AST_TEST_FAIL;
3099 }
3100
3102 snprintf(expression, sizeof(expression), "AST_SORCERY(%s,%s,%s,%s,single,|)", "test_sorcery", "test", "blah", "jim");
3103 if (!ast_func_read2(NULL, expression, &buf, 16)) {
3104 ast_free(buf);
3105 ast_test_status_update(test, "Should have failed with invalid occurrence_number\n");
3106 return AST_TEST_FAIL;
3107 }
3108
3109 ast_free(buf);
3110
3111 return AST_TEST_PASS;
3112}
#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:2398
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:2412
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:1695
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 3172 of file test_sorcery.c.

3173{
3176 const struct ast_sorcery_global_observer observer = {
3177 .wizard_registered = wizard_observer,
3178 .instance_created = instance_observer,
3179 .wizard_unregistering = wizard_observer,
3180 .instance_destroying = instance_observer,
3181 };
3182
3183 switch (cmd) {
3184 case TEST_INIT:
3185 info->name = "global_observation";
3186 info->category = "/main/sorcery/";
3187 info->summary = "global sorcery observation test";
3188 info->description =
3189 "Test observation of sorcery (global)";
3190 return AST_TEST_NOT_RUN;
3191 case TEST_EXECUTE:
3192 break;
3193 }
3194
3196
3197 event_observed = 0;
3199 ast_test_validate(test, (event_observed == 1), "Wizard registered failed");
3200
3201 event_observed = 0;
3203 ast_test_validate(test, (event_observed == 1), "Wizard unregistered failed");
3204
3205 event_observed = 0;
3207 ast_test_validate(test, (event_observed == 1), "Instance created failed");
3208
3209 event_observed = 0;
3211 sorcery = NULL;
3212 ast_test_validate(test, (event_observed == 1), "Instance destroyed failed");
3213
3215 event_observed = 0;
3217 ast_test_validate(test, (event_observed == 0), "Observer removed failed");
3218
3219 return AST_TEST_PASS;
3220}
void ast_sorcery_global_observer_remove(const struct ast_sorcery_global_observer *callbacks)
Remove a global observer from sorcery.
Definition: sorcery.c:577
int ast_sorcery_global_observer_add(const struct ast_sorcery_global_observer *callbacks)
Add a global observer to sorcery.
Definition: sorcery.c:561
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 3274 of file test_sorcery.c.

3275{
3278 .wizard_mapped = wizard_mapped_observer,
3279 .object_type_registered = object_type_registered_observer,
3280 };
3281
3282 switch (cmd) {
3283 case TEST_INIT:
3284 info->name = "instance_observation";
3285 info->category = "/main/sorcery/";
3286 info->summary = "sorcery instance observation test";
3287 info->description =
3288 "Test observation of sorcery (instance)";
3289 return AST_TEST_NOT_RUN;
3290 case TEST_EXECUTE:
3291 break;
3292 }
3293
3294 /* Test instance load */
3295 if (!(sorcery = ast_sorcery_open())) {
3296 ast_test_status_update(test, "Failed to open a sorcery instance\n");
3297 return AST_TEST_FAIL;
3298 }
3299 observer.instance_loading = instance_loaded_observer;
3300 observer.instance_loaded = instance_loaded_observer;
3302 event_observed = 0;
3304 ast_test_validate(test, (event_observed == 2), "Instance loaded failed");
3305 event_observed = 0;
3307 ast_test_validate(test, (event_observed == 0), "Instance reloaded failed");
3308
3309 /* Test instance reload */
3311 observer.instance_loading = instance_reloaded_observer;
3312 observer.instance_loaded = instance_reloaded_observer;
3314 event_observed = 0;
3316 ast_test_validate(test, (event_observed == 0), "Instance loaded failed");
3317 event_observed = 0;
3319 ast_test_validate(test, (event_observed == 2), "Instance reloaded failed");
3320
3321 /* Test wizard mapping */
3322 event_observed = 0;
3323 ast_sorcery_apply_default(sorcery, "test_object_type", "memory", "memwiz");
3324 ast_test_validate(test, (event_observed == 1), "Wizard mapping failed");
3325
3326 /* Test object type register */
3327 event_observed = 0;
3330 ast_test_validate(test, (event_observed == 1), "Object type registered failed");
3331
3332 /* Test object type load */
3334 observer.object_type_loading = object_type_loaded_observer;
3335 observer.object_type_loaded = object_type_loaded_observer;
3337 event_observed = 0;
3338 ast_sorcery_load_object(sorcery, "test_object_type");
3339 ast_test_validate(test, (event_observed == 2), "Object type loaded failed");
3340 event_observed = 0;
3341 ast_sorcery_reload_object(sorcery, "test_object_type");
3342 ast_test_validate(test, (event_observed == 0), "Object type reloaded failed");
3343
3344 /* Test object type reload */
3346 observer.object_type_loading = object_type_reloaded_observer;
3347 observer.object_type_loaded = object_type_reloaded_observer;
3349 event_observed = 0;
3350 ast_sorcery_load_object(sorcery, "test_object_type");
3351 ast_test_validate(test, (event_observed == 0), "Object type loaded failed");
3352 event_observed = 0;
3353 ast_sorcery_reload_object(sorcery, "test_object_type");
3354 ast_test_validate(test, (event_observed == 2), "Object type reloaded failed");
3355
3357 event_observed = 0;
3358 ast_sorcery_apply_default(sorcery, "test_object_type", "memory", "memwiz");
3359 ast_test_validate(test, (event_observed == 0), "Observer remove failed");
3360
3361 return AST_TEST_PASS;
3362}
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:600
void ast_sorcery_reload(const struct ast_sorcery *sorcery)
Inform any wizards to reload persistent objects.
Definition: sorcery.c:1471
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:1456
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:1505
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:583
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:2392
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:1841

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:1191
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 2159 of file test_sorcery.c.

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

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 2206 of file test_sorcery.c.

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

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:1868

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:1202
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 3114 of file test_sorcery.c.

3115{
3117 RAII_VAR(struct ast_sorcery_object_type *, object_type, NULL, ao2_cleanup);
3118
3119 switch (cmd) {
3120 case TEST_INIT:
3121 info->name = "object_field_registered";
3122 info->category = "/main/sorcery/";
3123 info->summary = "ast_sorcery_is_object_field_registered unit test";
3124 info->description =
3125 "Test ast_sorcery_is_object_field_registered in sorcery";
3126 return AST_TEST_NOT_RUN;
3127 case TEST_EXECUTE:
3128 break;
3129 }
3130
3132 ast_test_status_update(test, "Failed to open sorcery structure\n");
3133 return AST_TEST_FAIL;
3134 }
3135
3136 object_type = ast_sorcery_get_object_type(sorcery, "test");
3137
3139
3140 ast_test_validate(test, ast_sorcery_is_object_field_registered(object_type, "joe"));
3141 ast_test_validate(test, ast_sorcery_is_object_field_registered(object_type, "bob"));
3142 ast_test_validate(test, ast_sorcery_is_object_field_registered(object_type, "@joebob"));
3143 ast_test_validate(test, ast_sorcery_is_object_field_registered(object_type, "prefix/goober"));
3144
3145 ast_test_validate(test, !ast_sorcery_is_object_field_registered(object_type, "joebob"));
3146 ast_test_validate(test, !ast_sorcery_is_object_field_registered(object_type, "prefix/"));
3147 ast_test_validate(test, !ast_sorcery_is_object_field_registered(object_type, "goober"));
3148
3150
3151 ast_test_validate(test, ast_sorcery_is_object_field_registered(object_type, "goober"));
3152
3153 return AST_TEST_PASS;
3154}
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:1223
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:2557
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:2577
Structure for registered object type.
Definition: sorcery.c:149
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 2241 of file test_sorcery.c.

2242{
2246 RAII_VAR(struct test_sorcery_object *, obj1, NULL, ao2_cleanup);
2247 RAII_VAR(struct test_sorcery_object *, obj2, NULL, ao2_cleanup);
2248
2249 switch (cmd) {
2250 case TEST_INIT:
2251 info->name = "object_is_stale";
2252 info->category = "/main/sorcery/";
2253 info->summary = "sorcery object staleness unit test";
2254 info->description =
2255 "Test whether sorcery will query a wizard correctly if asked\n"
2256 "if an object is stale.";
2257 return AST_TEST_NOT_RUN;
2258 case TEST_EXECUTE:
2259 break;
2260 }
2261
2263 ast_test_status_update(test, "Failed to register a perfectly valid sorcery wizard\n");
2264 return AST_TEST_FAIL;
2265 }
2266
2268 ast_test_status_update(test, "Failed to register a perfectly valid sorcery wizard\n");
2269 return AST_TEST_FAIL;
2270 }
2271
2272 if (!(sorcery = ast_sorcery_open())) {
2273 ast_test_status_update(test, "Failed to open sorcery structure\n");
2274 return AST_TEST_FAIL;
2275 }
2276
2279 return AST_TEST_FAIL;
2280 }
2281
2286
2287
2288 if ((ast_sorcery_apply_default(sorcery, "test2", "test2", "test2data") != AST_SORCERY_APPLY_SUCCESS) ||
2290 return AST_TEST_FAIL;
2291 }
2292
2297
2298
2299 if (!(obj1 = ast_sorcery_alloc(sorcery, "test", "blah"))) {
2300 ast_test_status_update(test, "Failed to allocate a known object type\n");
2301 return AST_TEST_FAIL;
2302 }
2303
2304 if (!(obj2 = ast_sorcery_alloc(sorcery, "test2", "blah"))) {
2305 ast_test_status_update(test, "Failed to allocate a known object type\n");
2306 return AST_TEST_FAIL;
2307 }
2308
2309 /* The 'test' wizard has no is_stale callback */
2310 ast_test_validate(test, ast_sorcery_is_stale(sorcery, obj1) == 0);
2311
2312 /* The 'test2' wizard should return stale */
2313 ast_test_validate(test, ast_sorcery_is_stale(sorcery, obj2) == 1);
2314 ast_test_validate(test, cache.is_stale == 1);
2315
2316 return AST_TEST_PASS;
2317}
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:2351
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:2017

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 2432 of file test_sorcery.c.

2433{
2436 int res = AST_TEST_FAIL;
2437
2438 switch (cmd) {
2439 case TEST_INIT:
2440 info->name = "object_type_observer";
2441 info->category = "/main/sorcery/";
2442 info->summary = "sorcery object type observer unit test";
2443 info->description =
2444 "Test that object type observers get called when they should";
2445 return AST_TEST_NOT_RUN;
2446 case TEST_EXECUTE:
2447 break;
2448 }
2449
2451 ast_test_status_update(test, "Failed to open sorcery structure\n");
2452 return AST_TEST_FAIL;
2453 }
2454
2455 if (!ast_sorcery_observer_add(sorcery, "test", NULL)) {
2456 ast_test_status_update(test, "Successfully added a NULL observer when it should not be possible\n");
2457 return AST_TEST_FAIL;
2458 }
2459
2461 ast_test_status_update(test, "Failed to add a proper observer\n");
2462 return AST_TEST_FAIL;
2463 }
2464
2465 if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
2466 ast_test_status_update(test, "Failed to allocate a known object type\n");
2467 goto end;
2468 }
2469
2475
2476 if (ast_sorcery_create(sorcery, obj)) {
2477 ast_test_status_update(test, "Failed to create object using in-memory wizard\n");
2478 goto end;
2479 }
2480
2482 while (!observer.created) {
2483 struct timeval start = ast_tvnow();
2484 struct timespec end = {
2485 .tv_sec = start.tv_sec + 10,
2486 .tv_nsec = start.tv_usec * 1000,
2487 };
2488 if (ast_cond_timedwait(&observer.cond, &observer.lock, &end) == ETIMEDOUT) {
2489 break;
2490 }
2491 }
2493
2494 if (!observer.created) {
2495 ast_test_status_update(test, "Failed to receive observer notification for object creation within suitable timeframe\n");
2496 goto end;
2497 }
2498
2499 if (ast_sorcery_update(sorcery, obj)) {
2500 ast_test_status_update(test, "Failed to update object using in-memory wizard\n");
2501 goto end;
2502 }
2503
2505 while (!observer.updated) {
2506 struct timeval start = ast_tvnow();
2507 struct timespec end = {
2508 .tv_sec = start.tv_sec + 10,
2509 .tv_nsec = start.tv_usec * 1000,
2510 };
2511 if (ast_cond_timedwait(&observer.cond, &observer.lock, &end) == ETIMEDOUT) {
2512 break;
2513 }
2514 }
2516
2517 if (!observer.updated) {
2518 ast_test_status_update(test, "Failed to receive observer notification for object updating within suitable timeframe\n");
2519 goto end;
2520 }
2521
2522 if (ast_sorcery_delete(sorcery, obj)) {
2523 ast_test_status_update(test, "Failed to delete object using in-memory wizard\n");
2524 goto end;
2525 }
2526
2528 while (!observer.deleted) {
2529 struct timeval start = ast_tvnow();
2530 struct timespec end = {
2531 .tv_sec = start.tv_sec + 10,
2532 .tv_nsec = start.tv_usec * 1000,
2533 };
2534 if (ast_cond_timedwait(&observer.cond, &observer.lock, &end) == ETIMEDOUT) {
2535 break;
2536 }
2537 }
2539
2540 if (!observer.deleted) {
2541 ast_test_status_update(test, "Failed to receive observer notification for object deletion within suitable timeframe\n");
2542 goto end;
2543 }
2544
2546
2548 while (!observer.loaded) {
2549 struct timeval start = ast_tvnow();
2550 struct timespec end = {
2551 .tv_sec = start.tv_sec + 10,
2552 .tv_nsec = start.tv_usec * 1000,
2553 };
2554 if (ast_cond_timedwait(&observer.cond, &observer.lock, &end) == ETIMEDOUT) {
2555 break;
2556 }
2557 }
2559
2560 if (!observer.loaded) {
2561 ast_test_status_update(test, "Failed to receive observer notification for object type load within suitable timeframe\n");
2562 goto end;
2563 }
2564
2565 res = AST_TEST_PASS;
2566
2567end:
2573
2574 return res;
2575}
#define ast_cond_destroy(cond)
Definition: lock.h:209
#define ast_cond_init(cond, attr)
Definition: lock.h:208
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:213
#define ast_mutex_init(pmutex)
Definition: lock.h:193
#define ast_mutex_unlock(a)
Definition: lock.h:197
#define ast_mutex_destroy(a)
Definition: lock.h:195
#define ast_mutex_lock(a)
Definition: lock.h:196
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:2454
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
2145 if (!ast_sorcery_update(sorcery, obj)) {
2146 ast_test_status_update(test, "Successfully updated an object which has not been created yet\n");
2147 return AST_TEST_FAIL;
2148 }
2149
2151 if (ast_sorcery_update(sorcery, obj)) {
2152 ast_test_status_update(test, "Failed to create object when update() finds no object in a backend\n");
2153 return AST_TEST_FAIL;
2154 }
2155
2156 return AST_TEST_PASS;
2157}
int ast_sorcery_update_or_create_on_update_miss
Global control for optional update->create fallback in backends.
Definition: sorcery.c:288

References alloc_and_initialize_sorcery(), ao2_cleanup, ast_sorcery_alloc(), ast_sorcery_unref, ast_sorcery_update(), ast_sorcery_update_or_create_on_update_miss, 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:1628
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:735

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 3459 of file test_sorcery.c.

3460{
3464 RAII_VAR(struct ast_sorcery_wizard *, wizard, NULL, ao2_cleanup);
3465 void *data;
3466
3467 switch (cmd) {
3468 case TEST_INIT:
3469 info->name = "wizard_apply_and_insert";
3470 info->category = "/main/sorcery/";
3471 info->summary = "sorcery wizard apply and insert test";
3472 info->description =
3473 "sorcery wizard apply and insert test";
3474 return AST_TEST_NOT_RUN;
3475 case TEST_EXECUTE:
3476 break;
3477 }
3478
3479 wizard1->load = sorcery_test_load;
3480 wizard1->reload = sorcery_test_load;
3481
3482 wizard2->load = sorcery_test_load;
3483 wizard2->reload = sorcery_test_load;
3484
3485 if (!(sorcery = ast_sorcery_open())) {
3486 ast_test_status_update(test, "Failed to open a sorcery instance\n");
3487 return AST_TEST_FAIL;
3488 }
3489
3492
3493 /* test_object_type isn't registered yet so count should return error */
3494 ast_test_validate(test,
3495 ast_sorcery_get_wizard_mapping_count(sorcery, "test_object_type") == -1);
3496
3497 ast_sorcery_apply_default(sorcery, "test_object_type", "test", NULL);
3498
3499 ast_test_validate(test,
3500 ast_sorcery_get_wizard_mapping_count(sorcery, "test_object_type") == 1);
3501
3502 ast_test_validate(test,
3503 ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 0, &wizard, NULL) == 0);
3504 ast_test_validate(test, strcmp("test", wizard->name) == 0);
3505 ao2_ref(wizard, -1);
3506 wizard = NULL;
3507
3508 ast_test_validate(test,
3509 ast_sorcery_insert_wizard_mapping(sorcery, "test_object_type", "test2", "test2data", 0, 0) == 0);
3510
3511 ast_test_validate(test,
3512 ast_sorcery_insert_wizard_mapping(sorcery, "test_object_type", "test2", "test2data", 0, 0) != 0);
3513
3514 ast_test_validate(test,
3515 ast_sorcery_object_type_insert_wizard(sorcery, "test_object_type", "test2", "test2data2",
3517
3518 ast_test_validate(test,
3519 ast_sorcery_object_type_remove_wizard(sorcery, "test_object_type", "test2", "test2data2") == 0);
3520
3521 ast_test_validate(test,
3522 ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 0, &wizard, &data) == 0);
3523 ast_test_validate(test, strcmp("test2", wizard->name) == 0);
3524 ast_test_validate(test, strcmp("test2data", data) == 0);
3525 ao2_ref(wizard, -1);
3526 wizard = NULL;
3527
3528 ast_test_validate(test,
3529 ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 1, &wizard, NULL) == 0);
3530 ast_test_validate(test, strcmp("test", wizard->name) == 0);
3531 ao2_ref(wizard, -1);
3532 wizard = NULL;
3533
3534 /* Test failures */
3535 ast_test_validate(test,
3536 ast_sorcery_get_wizard_mapping(sorcery, "non-existent-type", 0, &wizard, NULL) != 0);
3537
3538 ast_test_validate(test,
3539 ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", -1, &wizard, &data) != 0);
3540
3541 ast_test_validate(test,
3542 ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 2, &wizard, NULL) != 0);
3543
3544 ast_test_validate(test,
3545 ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 2, NULL, NULL) != 0);
3546
3547 /* Test remove */
3548 /* Should fail */
3549 ast_test_validate(test,
3550 ast_sorcery_remove_wizard_mapping(sorcery, "non-existent-type", "somewizard") != 0);
3551 ast_test_validate(test,
3552 ast_sorcery_remove_wizard_mapping(sorcery, "test_object_type", "somewizard") != 0);
3553
3554 /* should work */
3555 ast_test_validate(test,
3556 ast_sorcery_remove_wizard_mapping(sorcery, "test_object_type", "test") == 0);
3557
3558 ast_test_validate(test,
3559 ast_sorcery_get_wizard_mapping_count(sorcery, "test_object_type") == 1);
3560
3561 ast_test_validate(test,
3562 ast_sorcery_get_wizard_mapping(sorcery, "test_object_type", 0, &wizard, &data) == 0);
3563 ast_test_validate(test, strcmp("test2", wizard->name) == 0);
3564 ast_test_validate(test, strcmp("test2data", data) == 0);
3565 ao2_ref(wizard, -1);
3566 wizard = NULL;
3567
3568 return AST_TEST_PASS;
3569}
#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:841
#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:853
@ 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 3387 of file test_sorcery.c.

3388{
3392 .wizard_loading = wizard_loaded_observer,
3393 .wizard_loaded = wizard_loaded_observer,
3394 };
3395
3396 switch (cmd) {
3397 case TEST_INIT:
3398 info->name = "wizard_observation";
3399 info->category = "/main/sorcery/";
3400 info->summary = "sorcery wizard observation test";
3401 info->description =
3402 "Test observation of sorcery (wizard)";
3403 return AST_TEST_NOT_RUN;
3404 case TEST_EXECUTE:
3405 break;
3406 }
3407
3408 wizard->load = sorcery_test_load;
3409 wizard->reload = sorcery_test_load;
3410
3411 /* Test wizard observer remove and wizard unregister */
3415 event_observed = 0;
3417 ast_test_validate(test, (event_observed == 0), "Wizard observer removed failed");
3418
3419 /* Setup for test loaded and reloaded */
3420 if (!(sorcery = ast_sorcery_open())) {
3421 ast_test_status_update(test, "Failed to open a sorcery instance\n");
3422 return AST_TEST_FAIL;
3423 }
3424
3426 ast_sorcery_apply_default(sorcery, "test_object_type", "test", NULL);
3429
3430 /* Test wizard loading and loaded */
3432
3433 event_observed = 0;
3434 ast_sorcery_load_object(sorcery, "test_object_type");
3435 ast_test_validate(test, (event_observed == 2), "Wizard loaded failed");
3436
3437 event_observed = 0;
3438 ast_sorcery_reload_object(sorcery, "test_object_type");
3440 ast_test_validate(test, (event_observed == 0), "Wizard reloaded failed");
3441
3442 /* Test wizard reloading and reloaded */
3443 observer.wizard_loading = wizard_reloaded_observer;
3444 observer.wizard_loaded = wizard_reloaded_observer;
3446
3447 event_observed = 0;
3448 ast_sorcery_load_object(sorcery, "test_object_type");
3449 ast_test_validate(test, (event_observed == 0), "Wizard loaded failed");
3450
3451 event_observed = 0;
3452 ast_sorcery_reload_object(sorcery, "test_object_type");
3454 ast_test_validate(test, (event_observed == 2), "Wizard reloaded failed");
3455
3456 return AST_TEST_PASS;
3457}
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:631
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:606
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 3576 of file test_sorcery.c.

3577{
3582 struct ast_sorcery_wizard *wizard;
3583
3584 switch (cmd) {
3585 case TEST_INIT:
3586 info->name = "wizard_read_only";
3587 info->category = "/main/sorcery/";
3588 info->summary = "sorcery wizard read-only test";
3589 info->description =
3590 "sorcery wizard read-only test";
3591 return AST_TEST_NOT_RUN;
3592 case TEST_EXECUTE:
3593 break;
3594 }
3595
3596 wizard1->load = sorcery_test_load;
3597 wizard1->reload = sorcery_test_load;
3598
3599 if (!(sorcery = ast_sorcery_open())) {
3600 ast_test_status_update(test, "Failed to open a sorcery instance\n");
3601 return AST_TEST_FAIL;
3602 }
3603
3604 ast_sorcery_wizard_register(wizard_read_only);
3606
3607 if ((ast_sorcery_apply_default(sorcery, "test_object_type", "test-read-only", NULL) != AST_SORCERY_APPLY_SUCCESS) ||
3609 ast_test_status_update(test, "Failed to apply object defaults\n");
3610 return AST_TEST_FAIL;
3611 }
3612
3613 ast_test_validate(test,
3614 ast_sorcery_get_wizard_mapping_count(sorcery, "test_object_type") == 1);
3615
3616 ast_test_validate(test,
3618 "test", "test2data", AST_SORCERY_WIZARD_APPLY_READONLY, &wizard, NULL) == 0);
3619
3620 ast_test_validate(test, strcmp(wizard->name, wizard1->name) == 0);
3621
3622 ast_test_validate(test,
3623 ast_sorcery_get_wizard_mapping_count(sorcery, "test_object_type") == 2);
3624
3625 if (!(obj = ast_sorcery_alloc(sorcery, "test_object_type", "blah"))) {
3626 ast_test_status_update(test, "Failed to allocate a known object type\n");
3627 return AST_TEST_FAIL;
3628 }
3629
3630 if (ast_sorcery_create(sorcery, obj) == 0) {
3631 ast_test_status_update(test, "Should not have created object using read-only wizard\n");
3632 return AST_TEST_FAIL;
3633 }
3634
3635 return AST_TEST_PASS;
3636}
@ 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 3222 of file test_sorcery.c.

3224{
3225 if (!strcmp(name, "test_sorcery") && !reloaded) {
3227 }
3228}
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 3165 of file test_sorcery.c.

3166{
3167 if (!strcmp(name, "test_sorcery")) {
3168 event_observed = 1;
3169 }
3170}

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 3230 of file test_sorcery.c.

3232{
3233 if (!strcmp(name, "test_sorcery") && reloaded) {
3235 }
3236}

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
char * strsep(char **str, const char *delims)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#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:150
#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:629
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 3695 of file test_sorcery.c.

3696{
3697 AST_TEST_REGISTER(wizard_apply_and_insert);
3698 AST_TEST_REGISTER(wizard_registration);
3699 AST_TEST_REGISTER(sorcery_open);
3700 AST_TEST_REGISTER(apply_default);
3702 AST_TEST_REGISTER(object_register);
3703 AST_TEST_REGISTER(object_register_without_mapping);
3704 AST_TEST_REGISTER(object_field_register);
3705 AST_TEST_REGISTER(object_fields_register);
3706 AST_TEST_REGISTER(object_alloc_with_id);
3707 AST_TEST_REGISTER(object_alloc_without_id);
3708 AST_TEST_REGISTER(object_copy);
3709 AST_TEST_REGISTER(object_copy_native);
3710 AST_TEST_REGISTER(object_diff);
3711 AST_TEST_REGISTER(object_diff_native);
3712 AST_TEST_REGISTER(objectset_create);
3713 AST_TEST_REGISTER(objectset_json_create);
3714 AST_TEST_REGISTER(objectset_create_regex);
3715 AST_TEST_REGISTER(objectset_apply);
3716 AST_TEST_REGISTER(objectset_apply_handler);
3717 AST_TEST_REGISTER(objectset_apply_invalid);
3718 AST_TEST_REGISTER(objectset_transform);
3719 AST_TEST_REGISTER(objectset_apply_fields);
3720 AST_TEST_REGISTER(extended_fields);
3721 AST_TEST_REGISTER(changeset_create);
3722 AST_TEST_REGISTER(changeset_create_unchanged);
3723 AST_TEST_REGISTER(object_create);
3724 AST_TEST_REGISTER(object_retrieve_id);
3725 AST_TEST_REGISTER(object_retrieve_field);
3726 AST_TEST_REGISTER(object_retrieve_multiple_all);
3727 AST_TEST_REGISTER(object_retrieve_multiple_field);
3728 AST_TEST_REGISTER(object_retrieve_regex);
3729 AST_TEST_REGISTER(object_update);
3730 AST_TEST_REGISTER(object_update_uncreated);
3731 AST_TEST_REGISTER(object_delete);
3732 AST_TEST_REGISTER(object_delete_uncreated);
3733 AST_TEST_REGISTER(object_is_stale);
3734 AST_TEST_REGISTER(caching_wizard_behavior);
3735 AST_TEST_REGISTER(object_type_observer);
3736 AST_TEST_REGISTER(configuration_file_wizard);
3737 AST_TEST_REGISTER(configuration_file_wizard_with_file_integrity);
3738 AST_TEST_REGISTER(configuration_file_wizard_with_criteria);
3739 AST_TEST_REGISTER(configuration_file_wizard_retrieve_field);
3740 AST_TEST_REGISTER(configuration_file_wizard_retrieve_multiple);
3741 AST_TEST_REGISTER(configuration_file_wizard_retrieve_multiple_all);
3742 AST_TEST_REGISTER(dialplan_function);
3743 AST_TEST_REGISTER(object_field_registered);
3744 AST_TEST_REGISTER(global_observation);
3745 AST_TEST_REGISTER(instance_observation);
3746 AST_TEST_REGISTER(wizard_observation);
3747 AST_TEST_REGISTER(wizard_read_only);
3748
3750}
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 3256 of file test_sorcery.c.

3258{
3259 if (!strcmp(name, "test_sorcery") && !strcmp(object_type, "test_object_type")
3260 && !reloaded) {
3262 }
3263}

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 3248 of file test_sorcery.c.

3250{
3251 if (!strcmp(name, "test_sorcery") && !strcmp(object_type, "test_object_type")) {
3253 }
3254}

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 3265 of file test_sorcery.c.

3267{
3268 if (!strcmp(name, "test_sorcery") && !strcmp(object_type, "test_object_type")
3269 && reloaded) {
3271 }
3272}

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:337
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:596
#define ast_cond_signal(cond)
Definition: lock.h:210

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 3373 of file test_sorcery.c.

3374{
3375 return;
3376}

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:1791
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:266

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 3638 of file test_sorcery.c.

3639{
3640 AST_TEST_UNREGISTER(wizard_registration);
3641 AST_TEST_UNREGISTER(sorcery_open);
3642 AST_TEST_UNREGISTER(apply_default);
3644 AST_TEST_UNREGISTER(object_register);
3645 AST_TEST_UNREGISTER(object_register_without_mapping);
3646 AST_TEST_UNREGISTER(object_field_register);
3647 AST_TEST_UNREGISTER(object_fields_register);
3648 AST_TEST_UNREGISTER(object_alloc_with_id);
3649 AST_TEST_UNREGISTER(object_alloc_without_id);
3650 AST_TEST_UNREGISTER(object_copy);
3651 AST_TEST_UNREGISTER(object_copy_native);
3652 AST_TEST_UNREGISTER(object_diff);
3653 AST_TEST_UNREGISTER(object_diff_native);
3654 AST_TEST_UNREGISTER(objectset_create);
3655 AST_TEST_UNREGISTER(objectset_json_create);
3656 AST_TEST_UNREGISTER(objectset_create_regex);
3657 AST_TEST_UNREGISTER(objectset_apply);
3658 AST_TEST_UNREGISTER(objectset_apply_handler);
3659 AST_TEST_UNREGISTER(objectset_apply_invalid);
3660 AST_TEST_UNREGISTER(objectset_transform);
3661 AST_TEST_UNREGISTER(objectset_apply_fields);
3662 AST_TEST_UNREGISTER(extended_fields);
3663 AST_TEST_UNREGISTER(changeset_create);
3664 AST_TEST_UNREGISTER(changeset_create_unchanged);
3665 AST_TEST_UNREGISTER(object_create);
3666 AST_TEST_UNREGISTER(object_retrieve_id);
3667 AST_TEST_UNREGISTER(object_retrieve_field);
3668 AST_TEST_UNREGISTER(object_retrieve_multiple_all);
3669 AST_TEST_UNREGISTER(object_retrieve_multiple_field);
3670 AST_TEST_UNREGISTER(object_retrieve_regex);
3671 AST_TEST_UNREGISTER(object_update);
3672 AST_TEST_UNREGISTER(object_update_uncreated);
3673 AST_TEST_UNREGISTER(object_delete);
3674 AST_TEST_UNREGISTER(object_delete_uncreated);
3675 AST_TEST_UNREGISTER(object_is_stale);
3676 AST_TEST_UNREGISTER(caching_wizard_behavior);
3677 AST_TEST_UNREGISTER(object_type_observer);
3678 AST_TEST_UNREGISTER(configuration_file_wizard);
3679 AST_TEST_UNREGISTER(configuration_file_wizard_with_file_integrity);
3680 AST_TEST_UNREGISTER(configuration_file_wizard_with_criteria);
3681 AST_TEST_UNREGISTER(configuration_file_wizard_retrieve_field);
3682 AST_TEST_UNREGISTER(configuration_file_wizard_retrieve_multiple);
3683 AST_TEST_UNREGISTER(configuration_file_wizard_retrieve_multiple_all);
3684 AST_TEST_UNREGISTER(dialplan_function);
3685 AST_TEST_UNREGISTER(object_field_registered);
3686 AST_TEST_UNREGISTER(global_observation);
3687 AST_TEST_UNREGISTER(instance_observation);
3688 AST_TEST_UNREGISTER(wizard_observation);
3689 AST_TEST_UNREGISTER(wizard_apply_and_insert);
3690 AST_TEST_UNREGISTER(wizard_read_only);
3691
3692 return 0;
3693}
#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 3364 of file test_sorcery.c.

3366{
3367 if (!strcmp(name, "test") && !strcmp(object_type, "test_object_type")
3368 && !reloaded) {
3370 }
3371}

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 3238 of file test_sorcery.c.

3241{
3242 if (!strcmp(name, "test_sorcery") && !strcmp(object_type, "test_object_type")
3243 && !strcmp(wizard->name, "memory") && !strcmp(wizard_args, "memwiz")) {
3245 }
3246}

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 3158 of file test_sorcery.c.

3159{
3160 if (!strcmp(wizard->name, "test")) {
3161 event_observed = 1;
3162 }
3163}

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 3378 of file test_sorcery.c.

3380{
3381 if (!strcmp(name, "test") && !strcmp(object_type, "test_object_type")
3382 && reloaded) {
3384 }
3385}

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 3752 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 3752 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 3571 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().