45 SORCERY_OBJECT(details);
71 for (field = set; field; field = field->
next) {
74 if (!strcmp(field->
name,
"joe")) {
75 transformed_field = ast_variable_new(field->
name,
"5000",
"");
77 transformed_field = ast_variable_new(field->
name, field->
value,
"");
80 if (!transformed_field) {
85 transformed_field->
next = transformed;
86 transformed = transformed_field;
98 obj->jim = ast_variable_new(
"jim",
"444",
"");
99 obj->jack = ast_variable_new(
"jack",
"999,000",
"");
106 *changes = ast_variable_new(
"yes",
"itworks",
"");
123 *fields = ast_variable_new(
"toast-bob",
"10",
"");
183 static void *wizard2_data;
185 static void *sorcery_test_open(
const char *data)
187 wizard2_data = (
void *)data;
191 static void sorcery_test_close(
void *data)
196 static int sorcery_test_create(
const struct ast_sorcery *sorcery,
void *data,
void *
object)
204 static void *sorcery_test_retrieve_id(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
const char *
id)
209 static int sorcery_test_update(
const struct ast_sorcery *sorcery,
void *data,
void *
object)
215 static int sorcery_test_delete(
const struct ast_sorcery *sorcery,
void *data,
void *
object)
221 static int sorcery_test_is_stale(
const struct ast_sorcery *sorcery,
void *data,
void *
object)
230 .create = sorcery_test_create,
231 .retrieve_id = sorcery_test_retrieve_id,
232 .update = sorcery_test_update,
233 .delete = sorcery_test_delete,
238 .open = sorcery_test_open,
239 .close = sorcery_test_close,
240 .create = sorcery_test_create,
241 .retrieve_id = sorcery_test_retrieve_id,
242 .update = sorcery_test_update,
243 .delete = sorcery_test_delete,
244 .is_stale = sorcery_test_is_stale,
247 static void sorcery_observer_created(
const void *
object)
254 static void sorcery_observer_updated(
const void *
object)
261 static void sorcery_observer_deleted(
const void *
object)
268 static void sorcery_observer_loaded(
const char *object_type)
277 .
created = sorcery_observer_created,
278 .updated = sorcery_observer_updated,
279 .deleted = sorcery_observer_deleted,
280 .loaded = sorcery_observer_loaded,
301 while ((val = strsep(&jacks,
","))) {
302 ast_variable_list_append(&tobj->jack, ast_variable_new(
"jack", val,
""));
307 static int jim_vl(
const void *obj,
struct ast_variable **fields)
316 static int jack_str(
const void *obj,
const intptr_t *args,
char **buf)
332 static struct ast_sorcery *alloc_and_initialize_sorcery(
void)
358 info->name =
"wizard_registration";
359 info->category =
"/main/sorcery/";
360 info->summary =
"sorcery wizard registration and unregistration unit test";
362 "Test registration and unregistration of a sorcery wizard";
363 return AST_TEST_NOT_RUN;
369 ast_test_status_update(
test,
"Failed to register a perfectly valid sorcery wizard\n");
370 return AST_TEST_FAIL;
374 ast_test_status_update(
test,
"Successfully registered a sorcery wizard twice, which is bad\n");
375 return AST_TEST_FAIL;
379 ast_test_status_update(
test,
"Failed to unregister a perfectly valid sorcery wizard\n");
380 return AST_TEST_FAIL;
384 ast_test_status_update(
test,
"Successfully unregistered a sorcery wizard twice, which is bad\n");
385 return AST_TEST_FAIL;
388 return AST_TEST_PASS;
400 info->category =
"/main/sorcery/";
401 info->summary =
"sorcery open/close unit test";
403 "Test opening of sorcery and registry operations";
404 return AST_TEST_NOT_RUN;
410 ast_test_status_update(
test,
"There should NOT have been an existing sorcery instance\n");
411 return AST_TEST_FAIL;
415 ast_test_status_update(
test,
"Failed to open new sorcery structure\n");
416 return AST_TEST_FAIL;
420 ast_test_status_update(
test,
"Failed to find sorcery structure in registry\n");
421 return AST_TEST_FAIL;
424 if (sorcery2 != sorcery) {
425 ast_test_status_update(
test,
"Should have gotten same sorcery on retrieve\n");
426 return AST_TEST_FAIL;
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;
436 ast_test_status_update(
test,
"Failed to open second sorcery structure\n");
437 return AST_TEST_FAIL;
440 if (sorcery2 != sorcery) {
441 ast_test_status_update(
test,
"Should have gotten same sorcery on 2nd open\n");
442 return AST_TEST_FAIL;
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;
458 ast_test_status_update(
test,
"Should NOT have found sorcery structure in registry\n");
459 return AST_TEST_FAIL;
462 return AST_TEST_PASS;
471 info->name =
"apply_default";
472 info->category =
"/main/sorcery/";
473 info->summary =
"sorcery default wizard unit test";
475 "Test setting default type wizard in sorcery";
476 return AST_TEST_NOT_RUN;
482 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
483 return AST_TEST_FAIL;
487 ast_test_status_update(
test,
"Successfully set a default wizard that doesn't exist\n");
488 return AST_TEST_FAIL;
492 ast_test_status_update(
test,
"Failed to set a known wizard as a default\n");
493 return AST_TEST_FAIL;
497 ast_test_status_update(
test,
"Successfully set a default wizard on a type twice\n");
498 return AST_TEST_FAIL;
501 return AST_TEST_PASS;
512 info->name =
"apply_config";
513 info->category =
"/main/sorcery/";
514 info->summary =
"sorcery object mapping configuration unit test";
516 "Test configured object mapping in sorcery";
517 return AST_TEST_NOT_RUN;
523 ast_test_status_update(
test,
"Sorcery configuration file not present - skipping apply_config test\n");
524 return AST_TEST_NOT_RUN;
528 ast_test_status_update(
test,
"Sorcery configuration file does not have test_sorcery section\n");
530 return AST_TEST_NOT_RUN;
536 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
537 return AST_TEST_FAIL;
541 ast_test_status_update(
test,
"Failed to apply configured object mappings\n");
542 return AST_TEST_FAIL;
545 return AST_TEST_PASS;
554 info->name =
"object_register";
555 info->category =
"/main/sorcery/";
556 info->summary =
"sorcery object type registration unit test";
558 "Test object type registration in sorcery";
559 return AST_TEST_NOT_RUN;
565 ast_test_status_update(
test,
"Failed to open structure\n");
566 return AST_TEST_FAIL;
570 ast_test_status_update(
test,
"Failed to set a known wizard as a default\n");
571 return AST_TEST_FAIL;
575 ast_test_status_update(
test,
"Failed to register object type\n");
576 return AST_TEST_FAIL;
580 ast_test_status_update(
test,
"Registered object type a second time, despite it being registered already\n");
581 return AST_TEST_FAIL;
584 return AST_TEST_PASS;
593 info->name =
"object_register_without_mapping";
594 info->category =
"/main/sorcery/";
595 info->summary =
"sorcery object type registration (without mapping) unit test";
597 "Test object type registration when no mapping exists in sorcery";
598 return AST_TEST_NOT_RUN;
604 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
605 return AST_TEST_FAIL;
609 ast_test_status_update(
test,
"Registered object type when no object mapping exists\n");
610 return AST_TEST_FAIL;
613 return AST_TEST_PASS;
622 info->name =
"object_field_register";
623 info->category =
"/main/sorcery/";
624 info->summary =
"sorcery object field registration unit test";
626 "Test object field registration in sorcery with a provided id";
627 return AST_TEST_NOT_RUN;
633 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
634 return AST_TEST_FAIL;
638 ast_test_status_update(
test,
"Registered an object field successfully when no mappings or object types exist\n");
639 return AST_TEST_FAIL;
643 ast_test_status_update(
test,
"Failed to set a known wizard as a default\n");
644 return AST_TEST_FAIL;
648 ast_test_status_update(
test,
"Registered an object field successfully when object type does not exist\n");
649 return AST_TEST_FAIL;
653 ast_test_status_update(
test,
"Failed to register object type\n");
654 return AST_TEST_FAIL;
658 ast_test_status_update(
test,
"Could not successfully register object field when mapping and object type exists\n");
659 return AST_TEST_FAIL;
662 return AST_TEST_PASS;
671 info->name =
"object_fields_register";
672 info->category =
"/main/sorcery/";
673 info->summary =
"sorcery object regex fields registration unit test";
675 "Test object regex fields registration in sorcery with a provided id";
676 return AST_TEST_NOT_RUN;
682 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
683 return AST_TEST_FAIL;
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;
692 ast_test_status_update(
test,
"Failed to set a known wizard as a default\n");
693 return AST_TEST_FAIL;
697 ast_test_status_update(
test,
"Registered a regex object field successfully when object type does not exist\n");
698 return AST_TEST_FAIL;
702 ast_test_status_update(
test,
"Failed to register object type\n");
703 return AST_TEST_FAIL;
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;
711 return AST_TEST_PASS;
716 int res = AST_TEST_PASS;
722 info->name =
"object_alloc_with_id";
723 info->category =
"/main/sorcery/";
724 info->summary =
"sorcery object allocation (with id) unit test";
726 "Test object allocation in sorcery with a provided id";
727 return AST_TEST_NOT_RUN;
732 if (!(sorcery = alloc_and_initialize_sorcery())) {
733 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
734 return AST_TEST_FAIL;
738 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
741 ast_test_status_update(
test,
"Allocated object has empty id when it should not\n");
744 ast_test_status_update(
test,
"Allocated object does not have correct id\n");
747 ast_test_status_update(
test,
"Allocated object has empty type when it should not\n");
750 ast_test_status_update(
test,
"Allocated object does not have correct type\n");
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");
762 int res = AST_TEST_PASS;
768 info->name =
"object_alloc_without_id";
769 info->category =
"/main/sorcery/";
770 info->summary =
"sorcery object allocation (without id) unit test";
772 "Test object allocation in sorcery with no provided id";
773 return AST_TEST_NOT_RUN;
778 if (!(sorcery = alloc_and_initialize_sorcery())) {
779 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
780 return AST_TEST_FAIL;
784 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
787 ast_test_status_update(
test,
"Allocated object has empty id when it should not\n");
797 int res = AST_TEST_PASS;
804 info->name =
"object_copy";
805 info->category =
"/main/sorcery/";
806 info->summary =
"sorcery object copy unit test";
808 "Test object copy in sorcery";
809 return AST_TEST_NOT_RUN;
814 if (!(sorcery = alloc_and_initialize_sorcery())) {
815 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
816 return AST_TEST_FAIL;
820 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
821 return AST_TEST_FAIL;
826 jim_handler(NULL, ast_variable_new(
"jim",
"444",
""), obj);
827 jim_handler(NULL, ast_variable_new(
"jim",
"555",
""), obj);
830 ast_test_status_update(
test,
"Failed to create a copy of a known valid object\n");
832 }
else if (
copy == obj) {
833 ast_test_status_update(
test,
"Created copy is actually the original object\n");
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");
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");
841 }
else if (!
copy->jim) {
842 ast_test_status_update(
test,
"A new ast_variable was not created for 'jim'\n");
844 }
else if (
copy->jim == obj->jim) {
845 ast_test_status_update(
test,
"Created copy of 'jim' is actually the original 'jim'\n");
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");
850 }
else if (!
copy->jim->next) {
851 ast_test_status_update(
test,
"A new ast_variable was not created for 2nd 'jim'\n");
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);
864 int res = AST_TEST_PASS;
871 info->name =
"object_copy_native";
872 info->category =
"/main/sorcery/";
873 info->summary =
"sorcery object native copy unit test";
875 "Test object native copy in sorcery";
876 return AST_TEST_NOT_RUN;
881 if (!(sorcery = alloc_and_initialize_sorcery())) {
882 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
883 return AST_TEST_FAIL;
889 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
890 return AST_TEST_FAIL;
897 ast_test_status_update(
test,
"Failed to create a copy of a known valid object\n");
899 }
else if (
copy == obj) {
900 ast_test_status_update(
test,
"Created copy is actually the original object\n");
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");
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");
908 }
else if (!
copy->jim) {
909 ast_test_status_update(
test,
"A new ast_variable was not created for 'jim'\n");
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");
926 int res = AST_TEST_PASS;
931 info->name =
"object_diff";
932 info->category =
"/main/sorcery/";
933 info->summary =
"sorcery object diff unit test";
935 "Test object diffing in sorcery";
936 return AST_TEST_NOT_RUN;
941 if (!(sorcery = alloc_and_initialize_sorcery())) {
942 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
943 return AST_TEST_FAIL;
947 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
948 return AST_TEST_FAIL;
953 jim_handler(NULL, ast_variable_new(
"jim",
"444",
""), obj1);
954 jim_handler(NULL, ast_variable_new(
"jim",
"555",
""), obj1);
957 ast_test_status_update(
test,
"Failed to allocate a second known object type\n");
958 return AST_TEST_FAIL;
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);
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;
974 for (field = changes; field; field = field->
next) {
975 if (!strcmp(field->
name,
"joe")) {
976 if (strcmp(field->
value,
"42")) {
977 ast_test_status_update(
test,
978 "Object diff produced unexpected value '%s' for joe\n", field->
value);
981 }
else if (!strcmp(field->
name,
"jim")) {
983 if (!strcmp(field->
value,
"555")) {
984 ast_test_status_update(
test,
985 "Object diff produced unexpected value '%s' for jim\n", field->
value);
989 ast_test_status_update(
test,
"Object diff produced unexpected field '%s'\n",
996 ast_test_status_update(
test,
"Object diff didn't produce 2 jims\n");
1010 int res = AST_TEST_PASS;
1014 info->name =
"object_diff_native";
1015 info->category =
"/main/sorcery/";
1016 info->summary =
"sorcery object native diff unit test";
1018 "Test native object diffing in sorcery";
1019 return AST_TEST_NOT_RUN;
1024 if (!(sorcery = alloc_and_initialize_sorcery())) {
1025 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
1026 return AST_TEST_FAIL;
1032 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
1033 return AST_TEST_FAIL;
1040 ast_test_status_update(
test,
"Failed to allocate a second known object type\n");
1041 return AST_TEST_FAIL;
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;
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;
1061 ast_test_status_update(
test,
"Object diff produced unexpected field '%s'\n", field->
name);
1062 res = AST_TEST_FAIL;
1071 int res = AST_TEST_PASS;
1079 info->name =
"objectset_create";
1080 info->category =
"/main/sorcery/";
1081 info->summary =
"sorcery object set creation unit test";
1083 "Test object set creation in sorcery";
1084 return AST_TEST_NOT_RUN;
1089 if (!(sorcery = alloc_and_initialize_sorcery())) {
1090 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
1091 return AST_TEST_FAIL;
1095 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
1096 return AST_TEST_FAIL;
1100 ast_test_status_update(
test,
"Failed to create an object set for a known sane object\n");
1101 return AST_TEST_FAIL;
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;
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;
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;
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;
1126 ast_test_status_update(
test,
"Object set created field '%s' which is unknown\n", field->
name);
1127 res = AST_TEST_FAIL;
1136 int res = AST_TEST_PASS;
1144 info->name =
"objectset_json_create";
1145 info->category =
"/main/sorcery/";
1146 info->summary =
"sorcery json object set creation unit test";
1148 "Test object set creation (for JSON format) in sorcery";
1149 return AST_TEST_NOT_RUN;
1154 if (!(sorcery = alloc_and_initialize_sorcery())) {
1155 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
1156 return AST_TEST_FAIL;
1160 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
1161 return AST_TEST_FAIL;
1165 ast_test_status_update(
test,
"Failed to create an object set for a known sane object\n");
1166 return AST_TEST_FAIL;
1174 ast_test_status_update(
test,
"Object set failed to create proper value for 'bob'\n");
1175 res = AST_TEST_FAIL;
1179 ast_test_status_update(
test,
"Object set failed to create proper value for 'joe'\n");
1180 res = AST_TEST_FAIL;
1184 ast_test_status_update(
test,
"Object set failed to create proper value for 'jim'\n");
1185 res = AST_TEST_FAIL;
1189 ast_test_status_update(
test,
"Object set failed to create proper value for 'jack'\n");
1190 res = AST_TEST_FAIL;
1194 res = AST_TEST_FAIL;
1203 int res = AST_TEST_PASS;
1211 info->name =
"objectset_create_regex";
1212 info->category =
"/main/sorcery/";
1213 info->summary =
"sorcery object set creation with regex fields unit test";
1215 "Test object set creation with regex fields in sorcery";
1216 return AST_TEST_NOT_RUN;
1222 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
1223 return AST_TEST_FAIL;
1228 ast_test_status_update(
test,
"Failed to register 'test' object type\n");
1229 return AST_TEST_FAIL;
1235 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
1236 return AST_TEST_FAIL;
1240 ast_test_status_update(
test,
"Failed to create an object set for a known sane object\n");
1241 return AST_TEST_FAIL;
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;
1251 ast_test_status_update(
test,
"Object set created field '%s' which is unknown\n", field->
name);
1252 res = AST_TEST_FAIL;
1261 int res = AST_TEST_PASS;
1268 info->name =
"objectset_apply";
1269 info->category =
"/main/sorcery/";
1270 info->summary =
"sorcery object apply unit test";
1272 "Test object set applying in sorcery";
1273 return AST_TEST_NOT_RUN;
1278 if (!(sorcery = alloc_and_initialize_sorcery())) {
1279 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
1280 return AST_TEST_FAIL;
1284 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
1285 return AST_TEST_FAIL;
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;
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;
1304 int res = AST_TEST_PASS;
1311 info->name =
"objectset_apply_handler";
1312 info->category =
"/main/sorcery/";
1313 info->summary =
"sorcery object apply handler unit test";
1315 "Test object set apply handler call in sorcery";
1316 return AST_TEST_NOT_RUN;
1322 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
1323 return AST_TEST_FAIL;
1328 ast_test_status_update(
test,
"Failed to register 'test' object type\n");
1329 return AST_TEST_FAIL;
1336 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
1337 return AST_TEST_FAIL;
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;
1346 ast_test_status_update(
test,
"Failed to apply valid object set to object\n");
1347 res = AST_TEST_FAIL;
1349 ast_test_status_update(
test,
"Apply handler was not called when it should have been\n");
1350 res = AST_TEST_FAIL;
1364 info->name =
"objectset_apply_invalid";
1365 info->category =
"/main/sorcery/";
1366 info->summary =
"sorcery object invalid apply unit test";
1368 "Test object set applying of an invalid set in sorcery";
1369 return AST_TEST_NOT_RUN;
1374 if (!(sorcery = alloc_and_initialize_sorcery())) {
1375 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
1376 return AST_TEST_FAIL;
1380 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
1381 return AST_TEST_FAIL;
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;
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;
1395 return AST_TEST_PASS;
1406 info->name =
"objectset_transform";
1407 info->category =
"/main/sorcery/";
1408 info->summary =
"sorcery object set transformation unit test";
1410 "Test object set transformation in sorcery";
1411 return AST_TEST_NOT_RUN;
1417 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
1418 return AST_TEST_FAIL;
1422 ast_test_status_update(
test,
"Failed to set a known wizard as a default\n");
1423 return AST_TEST_FAIL;
1427 ast_test_status_update(
test,
"Failed to register object type\n");
1428 return AST_TEST_FAIL;
1435 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
1436 return AST_TEST_FAIL;
1440 ast_test_status_update(
test,
"Failed to create an object set for a known sane object\n");
1441 return AST_TEST_FAIL;
1445 ast_test_status_update(
test,
"Failed to apply properly created object set against object\n");
1446 return AST_TEST_FAIL;
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;
1460 return AST_TEST_PASS;
1465 int res = AST_TEST_PASS;
1472 info->name =
"objectset_apply_fields";
1473 info->category =
"/main/sorcery/";
1474 info->summary =
"sorcery object apply regex fields unit test";
1476 "Test object set apply with regex fields in sorcery";
1477 return AST_TEST_NOT_RUN;
1483 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
1484 return AST_TEST_FAIL;
1489 ast_test_status_update(
test,
"Failed to register 'test' object type\n");
1490 return AST_TEST_FAIL;
1496 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
1497 return AST_TEST_FAIL;
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;
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;
1516 int res = AST_TEST_PASS;
1524 info->name =
"extended_fields";
1525 info->category =
"/main/sorcery/";
1526 info->summary =
"sorcery object extended fields unit test";
1528 "Test extended fields support in sorcery";
1529 return AST_TEST_NOT_RUN;
1534 if (!(sorcery = alloc_and_initialize_sorcery())) {
1535 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
1536 return AST_TEST_FAIL;
1540 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
1541 return AST_TEST_FAIL;
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;
1548 ast_test_status_update(
test,
"Failed to apply valid object set to object\n");
1549 res = AST_TEST_FAIL;
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;
1557 ast_test_status_update(
test,
"Extended field could not be set\n");
1558 res = AST_TEST_FAIL;
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;
1566 ast_test_status_update(
test,
"Extended field could not be set a second time\n");
1567 res = AST_TEST_FAIL;
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;
1581 int res = AST_TEST_PASS;
1589 info->name =
"changeset_create";
1590 info->category =
"/main/sorcery/";
1591 info->summary =
"sorcery changeset creation unit test";
1593 "Test changeset creation in sorcery";
1594 return AST_TEST_NOT_RUN;
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;
1603 tmp->
next = original;
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;
1610 tmp->
next = original;
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;
1617 tmp->
next = modified;
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;
1624 tmp->
next = modified;
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;
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;
1642 ast_test_status_update(
test,
"Changeset produced had unexpected field '%s'\n", tmp->
name);
1643 res = AST_TEST_FAIL;
1659 info->name =
"changeset_create_unchanged";
1660 info->category =
"/main/sorcery/";
1661 info->summary =
"sorcery changeset creation unit test when no changes exist";
1663 "Test changeset creation in sorcery when no changes actually exist";
1664 return AST_TEST_NOT_RUN;
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;
1673 tmp->
next = original;
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;
1680 tmp->
next = original;
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;
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;
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;
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;
1713 return AST_TEST_PASS;
1723 info->name =
"object_create";
1724 info->category =
"/main/sorcery/";
1725 info->summary =
"sorcery object creation unit test";
1727 "Test object creation in sorcery";
1728 return AST_TEST_NOT_RUN;
1733 if (!(sorcery = alloc_and_initialize_sorcery())) {
1734 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
1735 return AST_TEST_FAIL;
1739 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
1740 return AST_TEST_FAIL;
1744 ast_test_status_update(
test,
"Failed to create object using in-memory wizard\n");
1745 return AST_TEST_FAIL;
1748 return AST_TEST_PASS;
1758 info->name =
"object_retrieve_id";
1759 info->category =
"/main/sorcery/";
1760 info->summary =
"sorcery object retrieval using id unit test";
1762 "Test object retrieval using id in sorcery";
1763 return AST_TEST_NOT_RUN;
1768 if (!(sorcery = alloc_and_initialize_sorcery())) {
1769 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
1770 return AST_TEST_FAIL;
1774 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
1775 return AST_TEST_FAIL;
1779 ast_test_status_update(
test,
"Failed to create object using in-memory wizard\n");
1780 return AST_TEST_FAIL;
1786 ast_test_status_update(
test,
"Failed to allocate second instance of a known object type\n");
1787 return AST_TEST_FAIL;
1791 ast_test_status_update(
test,
"Failed to create second object using in-memory wizard\n");
1792 return AST_TEST_FAIL;
1798 ast_test_status_update(
test,
"Failed to retrieve properly created object using id of 'blah'\n");
1799 return AST_TEST_FAIL;
1801 ast_test_status_update(
test,
"Retrieved object does not have correct id\n");
1802 return AST_TEST_FAIL;
1805 return AST_TEST_PASS;
1816 info->name =
"object_retrieve_field";
1817 info->category =
"/main/sorcery/";
1818 info->summary =
"sorcery object retrieval using a specific field unit test";
1820 "Test object retrieval using a specific field in sorcery";
1821 return AST_TEST_NOT_RUN;
1827 ast_test_status_update(
test,
"Failed to create fields for object retrieval attempt\n");
1828 return AST_TEST_FAIL;
1831 if (!(sorcery = alloc_and_initialize_sorcery())) {
1832 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
1833 return AST_TEST_FAIL;
1837 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
1838 return AST_TEST_FAIL;
1844 ast_test_status_update(
test,
"Failed to create object using in-memory wizard\n");
1845 return AST_TEST_FAIL;
1851 ast_test_status_update(
test,
"Failed to retrieve properly created object using 'joe' field\n");
1852 return AST_TEST_FAIL;
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;
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;
1868 return AST_TEST_PASS;
1879 info->name =
"object_retrieve_multiple_all";
1880 info->category =
"/main/sorcery/";
1881 info->summary =
"sorcery multiple object retrieval unit test";
1883 "Test multiple object retrieval in sorcery";
1884 return AST_TEST_NOT_RUN;
1889 if (!(sorcery = alloc_and_initialize_sorcery())) {
1890 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
1891 return AST_TEST_FAIL;
1895 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
1896 return AST_TEST_FAIL;
1900 ast_test_status_update(
test,
"Failed to create object using in-memory wizard\n");
1901 return AST_TEST_FAIL;
1907 ast_test_status_update(
test,
"Failed to allocate second instance of a known object type\n");
1908 return AST_TEST_FAIL;
1912 ast_test_status_update(
test,
"Failed to create second object using in-memory wizard\n");
1913 return AST_TEST_FAIL;
1917 ast_test_status_update(
test,
"Failed to retrieve a container of all objects\n");
1918 return AST_TEST_FAIL;
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;
1924 return AST_TEST_PASS;
1936 info->name =
"object_retrieve_multiple_field";
1937 info->category =
"/main/sorcery/";
1938 info->summary =
"sorcery multiple object retrieval unit test";
1940 "Test multiple object retrieval in sorcery using fields";
1941 return AST_TEST_NOT_RUN;
1947 ast_test_status_update(
test,
"Failed to create fields for multiple retrieve\n");
1948 return AST_TEST_FAIL;
1951 if (!(sorcery = alloc_and_initialize_sorcery())) {
1952 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
1953 return AST_TEST_FAIL;
1957 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
1958 return AST_TEST_FAIL;
1964 ast_test_status_update(
test,
"Failed to create object using in-memory wizard\n");
1965 return AST_TEST_FAIL;
1969 ast_test_status_update(
test,
"Failed to retrieve a container of all objects\n");
1970 return AST_TEST_FAIL;
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;
1976 ao2_cleanup(objects);
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;
1983 ast_test_status_update(
test,
"Failed to retrieve an empty container when retrieving multiple\n");
1984 return AST_TEST_FAIL;
1986 ast_test_status_update(
test,
"Received a container with objects when there should be none in it\n");
1987 return AST_TEST_FAIL;
1990 return AST_TEST_PASS;
2001 info->name =
"object_retrieve_regex";
2002 info->category =
"/main/sorcery/";
2003 info->summary =
"sorcery multiple object retrieval using regex unit test";
2005 "Test multiple object retrieval in sorcery using regular expression for matching";
2006 return AST_TEST_NOT_RUN;
2011 if (!(sorcery = alloc_and_initialize_sorcery())) {
2012 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
2013 return AST_TEST_FAIL;
2017 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
2018 return AST_TEST_FAIL;
2022 ast_test_status_update(
test,
"Failed to create object using in-memory wizard\n");
2023 return AST_TEST_FAIL;
2029 ast_test_status_update(
test,
"Failed to allocate second instance of a known object type\n");
2030 return AST_TEST_FAIL;
2034 ast_test_status_update(
test,
"Failed to create second object using in-memory wizard\n");
2035 return AST_TEST_FAIL;
2041 ast_test_status_update(
test,
"Failed to allocate third instance of a known object type\n");
2042 return AST_TEST_FAIL;
2046 ast_test_status_update(
test,
"Failed to create third object using in-memory wizard\n");
2047 return AST_TEST_FAIL;
2051 ast_test_status_update(
test,
"Failed to retrieve a container of objects\n");
2052 return AST_TEST_FAIL;
2054 ast_test_status_update(
test,
"Received a container with incorrect number of objects in it\n");
2055 return AST_TEST_FAIL;
2058 return AST_TEST_PASS;
2069 info->name =
"object_update";
2070 info->category =
"/main/sorcery/";
2071 info->summary =
"sorcery object update unit test";
2073 "Test object updating in sorcery";
2074 return AST_TEST_NOT_RUN;
2079 if (!(sorcery = alloc_and_initialize_sorcery())) {
2080 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
2081 return AST_TEST_FAIL;
2085 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
2086 return AST_TEST_FAIL;
2090 ast_test_status_update(
test,
"Failed to create object using in-memory wizard\n");
2091 return AST_TEST_FAIL;
2095 ast_test_status_update(
test,
"Failed to allocate a known object type for updating\n");
2096 return AST_TEST_FAIL;
2102 ast_test_status_update(
test,
"Failed to update sorcery with new object\n");
2103 return AST_TEST_FAIL;
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;
2114 return AST_TEST_PASS;
2124 info->name =
"object_update_uncreated";
2125 info->category =
"/main/sorcery/";
2126 info->summary =
"sorcery object update unit test";
2128 "Test updating of an uncreated object in sorcery";
2129 return AST_TEST_NOT_RUN;
2134 if (!(sorcery = alloc_and_initialize_sorcery())) {
2135 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
2136 return AST_TEST_FAIL;
2140 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
2141 return AST_TEST_FAIL;
2145 ast_test_status_update(
test,
"Successfully updated an object which has not been created yet\n");
2146 return AST_TEST_FAIL;
2149 return AST_TEST_PASS;
2159 info->name =
"object_delete";
2160 info->category =
"/main/sorcery/";
2161 info->summary =
"sorcery object deletion unit test";
2163 "Test object deletion in sorcery";
2164 return AST_TEST_NOT_RUN;
2169 if (!(sorcery = alloc_and_initialize_sorcery())) {
2170 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
2171 return AST_TEST_FAIL;
2175 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
2176 return AST_TEST_FAIL;
2180 ast_test_status_update(
test,
"Failed to create object using in-memory wizard\n");
2181 return AST_TEST_FAIL;
2185 ast_test_status_update(
test,
"Failed to delete object using in-memory wizard\n");
2186 return AST_TEST_FAIL;
2192 ast_test_status_update(
test,
"Retrieved deleted object that should not be there\n");
2193 return AST_TEST_FAIL;
2196 return AST_TEST_PASS;
2206 info->name =
"object_delete_uncreated";
2207 info->category =
"/main/sorcery/";
2208 info->summary =
"sorcery object deletion unit test";
2210 "Test object deletion of an uncreated object in sorcery";
2211 return AST_TEST_NOT_RUN;
2216 if (!(sorcery = alloc_and_initialize_sorcery())) {
2217 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
2218 return AST_TEST_FAIL;
2222 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
2223 return AST_TEST_FAIL;
2227 ast_test_status_update(
test,
"Successfully deleted an object which was never created\n");
2228 return AST_TEST_FAIL;
2231 return AST_TEST_PASS;
2244 info->name =
"object_is_stale";
2245 info->category =
"/main/sorcery/";
2246 info->summary =
"sorcery object staleness unit test";
2248 "Test whether sorcery will query a wizard correctly if asked\n"
2249 "if an object is stale.";
2250 return AST_TEST_NOT_RUN;
2256 ast_test_status_update(
test,
"Failed to register a perfectly valid sorcery wizard\n");
2257 return AST_TEST_FAIL;
2261 ast_test_status_update(
test,
"Failed to register a perfectly valid sorcery wizard\n");
2262 return AST_TEST_FAIL;
2266 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
2267 return AST_TEST_FAIL;
2272 return AST_TEST_FAIL;
2283 return AST_TEST_FAIL;
2293 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
2294 return AST_TEST_FAIL;
2298 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
2299 return AST_TEST_FAIL;
2309 return AST_TEST_PASS;
2319 int res = AST_TEST_FAIL;
2323 info->name =
"caching_wizard_behavior";
2324 info->category =
"/main/sorcery/";
2325 info->summary =
"sorcery caching wizard behavior unit test";
2327 "Test internal behavior of caching wizards";
2328 return AST_TEST_NOT_RUN;
2333 if (!(config =
ast_config_load2(
"sorcery.conf",
"test_sorcery_cache", flags))) {
2334 ast_test_status_update(
test,
"Sorcery configuration file not present - skipping caching_wizard_behavior test\n");
2335 return AST_TEST_NOT_RUN;
2339 ast_test_status_update(
test,
"Sorcery configuration file does not contain 'test_sorcery_cache' section\n");
2341 return AST_TEST_NOT_RUN;
2347 ast_test_status_update(
test,
"Failed to register a perfectly valid sorcery wizard\n");
2348 return AST_TEST_FAIL;
2352 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
2357 ast_test_status_update(
test,
"Failed to apply configured object mappings\n");
2362 ast_test_status_update(
test,
"Failed to register object type\n");
2367 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
2372 ast_test_status_update(
test,
"Failed to create object using in-memory wizard\n");
2379 ast_test_status_update(
test,
"Failed to retrieve just created object\n");
2382 ast_test_status_update(
test,
"Caching wizard was not told to cache just created object\n");
2385 ast_test_status_update(
test,
"Failed to retrieve just cached object\n");
2387 }
else if (obj == obj2) {
2388 ast_test_status_update(
test,
"Returned object is *NOT* a cached object\n");
2391 ast_test_status_update(
test,
"Failed to update a known stored object\n");
2394 ast_test_status_update(
test,
"Caching wizard was not told to update object\n");
2397 ast_test_status_update(
test,
"Failed to delete a known stored object\n");
2400 ast_test_status_update(
test,
"Caching wizard was not told to delete object\n");
2407 ast_test_status_update(
test,
"Retrieved an object that should have been deleted\n");
2411 res = AST_TEST_PASS;
2418 ast_test_status_update(
test,
"Failed to unregister test sorcery wizard\n");
2419 return AST_TEST_FAIL;
2429 int res = AST_TEST_FAIL;
2433 info->name =
"object_type_observer";
2434 info->category =
"/main/sorcery/";
2435 info->summary =
"sorcery object type observer unit test";
2437 "Test that object type observers get called when they should";
2438 return AST_TEST_NOT_RUN;
2443 if (!(sorcery = alloc_and_initialize_sorcery())) {
2444 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
2445 return AST_TEST_FAIL;
2449 ast_test_status_update(
test,
"Successfully added a NULL observer when it should not be possible\n");
2450 return AST_TEST_FAIL;
2454 ast_test_status_update(
test,
"Failed to add a proper observer\n");
2455 return AST_TEST_FAIL;
2459 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
2470 ast_test_status_update(
test,
"Failed to create object using in-memory wizard\n");
2477 struct timespec end = {
2478 .tv_sec = start.tv_sec + 10,
2479 .tv_nsec = start.tv_usec * 1000,
2488 ast_test_status_update(
test,
"Failed to receive observer notification for object creation within suitable timeframe\n");
2493 ast_test_status_update(
test,
"Failed to update object using in-memory wizard\n");
2500 struct timespec end = {
2501 .tv_sec = start.tv_sec + 10,
2502 .tv_nsec = start.tv_usec * 1000,
2511 ast_test_status_update(
test,
"Failed to receive observer notification for object updating within suitable timeframe\n");
2516 ast_test_status_update(
test,
"Failed to delete object using in-memory wizard\n");
2523 struct timespec end = {
2524 .tv_sec = start.tv_sec + 10,
2525 .tv_nsec = start.tv_usec * 1000,
2534 ast_test_status_update(
test,
"Failed to receive observer notification for object deletion within suitable timeframe\n");
2543 struct timespec end = {
2544 .tv_sec = start.tv_sec + 10,
2545 .tv_nsec = start.tv_usec * 1000,
2554 ast_test_status_update(
test,
"Failed to receive observer notification for object type load within suitable timeframe\n");
2558 res = AST_TEST_PASS;
2579 info->name =
"configuration_file_wizard";
2580 info->category =
"/main/sorcery/";
2581 info->summary =
"sorcery configuration file wizard unit test";
2583 "Test the configuration file wizard in sorcery";
2584 return AST_TEST_NOT_RUN;
2589 if (!(config =
ast_config_load2(
"test_sorcery.conf",
"test_sorcery", flags))) {
2590 ast_test_status_update(
test,
"Test sorcery configuration file wizard file not present - skipping configuration_file_wizard test\n");
2591 return AST_TEST_NOT_RUN;
2597 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
2598 return AST_TEST_FAIL;
2602 ast_test_status_update(
test,
"Could not set a default wizard of the 'config' type, so skipping since it may not be loaded\n");
2603 return AST_TEST_NOT_RUN;
2607 ast_test_status_update(
test,
"Failed to register object type\n");
2608 return AST_TEST_FAIL;
2617 ast_test_status_update(
test,
"Retrieved object which has an unknown field\n");
2618 return AST_TEST_FAIL;
2620 ast_test_status_update(
test,
"Failed to retrieve a known object that has been configured in the configuration file\n");
2621 return AST_TEST_FAIL;
2622 }
else if (obj->bob != 98) {
2623 ast_test_status_update(
test,
"Value of 'bob' on object is not what is configured in configuration file\n");
2624 return AST_TEST_FAIL;
2625 }
else if (obj->joe != 41) {
2626 ast_test_status_update(
test,
"Value of 'joe' on object is not what is configured in configuration file\n");
2627 return AST_TEST_FAIL;
2630 return AST_TEST_PASS;
2642 info->name =
"configuration_file_wizard_with_file_integrity";
2643 info->category =
"/main/sorcery/";
2644 info->summary =
"sorcery configuration file wizard file integrity unit test";
2646 "Test the configuration file wizard with file integrity turned on in sorcery";
2647 return AST_TEST_NOT_RUN;
2652 if (!(config =
ast_config_load2(
"test_sorcery.conf",
"test_sorcery", flags))) {
2653 ast_test_status_update(
test,
"Test sorcery configuration file wizard file not present - skipping configuration_file_wizard_with_file_integrity test\n");
2654 return AST_TEST_NOT_RUN;
2660 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
2661 return AST_TEST_FAIL;
2664 if (ast_sorcery_apply_default(sorcery,
"test",
"config",
"test_sorcery.conf,integrity=file") !=
AST_SORCERY_APPLY_SUCCESS) {
2665 ast_test_status_update(
test,
"Could not set a default wizard of the 'config' type, so skipping since it may not be loaded\n");
2666 return AST_TEST_NOT_RUN;
2670 ast_test_status_update(
test,
"Failed to register object type\n");
2671 return AST_TEST_FAIL;
2680 ast_test_status_update(
test,
"Retrieved object which has an unknown field\n");
2681 return AST_TEST_FAIL;
2684 return AST_TEST_PASS;
2696 info->name =
"configuration_file_wizard_with_criteria";
2697 info->category =
"/main/sorcery/";
2698 info->summary =
"sorcery configuration file wizard with criteria unit test";
2700 "Test the configuration file wizard with criteria matching in sorcery";
2701 return AST_TEST_NOT_RUN;
2706 if (!(config =
ast_config_load2(
"test_sorcery.conf",
"test_sorcery", flags))) {
2707 ast_test_status_update(
test,
"Test sorcery configuration file wizard file not present - skipping configuration_file_wizard_with_criteria test\n");
2708 return AST_TEST_NOT_RUN;
2714 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
2715 return AST_TEST_FAIL;
2718 if (ast_sorcery_apply_default(sorcery,
"test",
"config",
"test_sorcery.conf,criteria=type=zombies") !=
AST_SORCERY_APPLY_SUCCESS) {
2719 ast_test_status_update(
test,
"Could not set a default wizard of the 'config' type, so skipping since it may not be loaded\n");
2720 return AST_TEST_NOT_RUN;
2724 ast_test_status_update(
test,
"Failed to register object type\n");
2725 return AST_TEST_FAIL;
2735 ast_test_status_update(
test,
"Retrieved object which did not match criteria\n");
2736 return AST_TEST_FAIL;
2738 ast_test_status_update(
test,
"Failed to retrieve a known object which matches criteria\n");
2739 return AST_TEST_FAIL;
2742 return AST_TEST_PASS;
2755 info->name =
"configuration_file_wizard_retrieve_field";
2756 info->category =
"/main/sorcery/";
2757 info->summary =
"sorcery configuration file wizard field retrieval unit test";
2759 "Test the configuration file wizard retrieval using field in sorcery";
2760 return AST_TEST_NOT_RUN;
2765 if (!(config =
ast_config_load2(
"test_sorcery.conf",
"test_sorcery", flags))) {
2766 ast_test_status_update(
test,
"Test sorcery configuration file wizard file not present - skipping configuration_file_wizard_retrieve_field test\n");
2767 return AST_TEST_NOT_RUN;
2773 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
2774 return AST_TEST_FAIL;
2778 ast_test_status_update(
test,
"Could not set a default wizard of the 'config' type, so skipping since it may not be loaded\n");
2779 return AST_TEST_NOT_RUN;
2783 ast_test_status_update(
test,
"Failed to register object type\n");
2784 return AST_TEST_FAIL;
2793 ast_test_status_update(
test,
"Failed to retrieve a known object that has been configured with the correct field\n");
2794 return AST_TEST_FAIL;
2797 return AST_TEST_FAIL;
2800 return AST_TEST_PASS;
2813 info->name =
"configuration_file_wizard_retrieve_multiple";
2814 info->category =
"/main/sorcery/";
2815 info->summary =
"sorcery configuration file wizard multiple retrieval unit test";
2817 "Test the configuration file wizard multiple retrieval in sorcery";
2818 return AST_TEST_NOT_RUN;
2823 if (!(config =
ast_config_load2(
"test_sorcery.conf",
"test_sorcery", flags))) {
2824 ast_test_status_update(
test,
"Test sorcery configuration file wizard file not present - skipping configuration_file_wizard_retrieve_multiple test\n");
2825 return AST_TEST_NOT_RUN;
2831 ast_test_status_update(
test,
"Failed to create fields for multiple retrieve\n");
2832 return AST_TEST_FAIL;
2836 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
2837 return AST_TEST_FAIL;
2841 ast_test_status_update(
test,
"Could not set a default wizard of the 'config' type, so skipping since it may not be loaded\n");
2842 return AST_TEST_NOT_RUN;
2846 ast_test_status_update(
test,
"Failed to register object type\n");
2847 return AST_TEST_FAIL;
2856 ast_test_status_update(
test,
"Failed to retrieve an empty container when retrieving multiple\n");
2857 return AST_TEST_FAIL;
2859 ast_test_status_update(
test,
"Received a container with objects when there should be none in it\n");
2860 return AST_TEST_FAIL;
2863 ao2_cleanup(objects);
2866 if (!(fields = ast_variable_new(
"joe",
"41",
""))) {
2867 ast_test_status_update(
test,
"Failed to create fields for multiple retrieve\n");
2868 return AST_TEST_FAIL;
2870 ast_test_status_update(
test,
"Failed to retrieve a container when retrieving multiple\n");
2871 return AST_TEST_FAIL;
2873 ast_test_status_update(
test,
"Received a container with no objects in it when there should be\n");
2874 return AST_TEST_FAIL;
2877 return AST_TEST_PASS;
2889 info->name =
"configuration_file_wizard_retrieve_multiple_all";
2890 info->category =
"/main/sorcery/";
2891 info->summary =
"sorcery configuration file wizard multiple retrieve all unit test";
2893 "Test the configuration file wizard multiple retrieve all in sorcery";
2894 return AST_TEST_NOT_RUN;
2899 if (!(config =
ast_config_load2(
"test_sorcery.conf",
"test_sorcery", flags))) {
2900 ast_test_status_update(
test,
"Test sorcery configuration file wizard file not present - skipping configuration_file_wizard_retrieve_multiple_all test\n");
2901 return AST_TEST_NOT_RUN;
2907 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
2908 return AST_TEST_FAIL;
2912 ast_test_status_update(
test,
"Could not set a default wizard of the 'config' type, so skipping since it may not be loaded\n");
2913 return AST_TEST_NOT_RUN;
2917 ast_test_status_update(
test,
"Failed to register object type\n");
2918 return AST_TEST_FAIL;
2927 ast_test_status_update(
test,
"Failed to retrieve a container with all objects when there should be one\n");
2928 return AST_TEST_FAIL;
2930 ast_test_status_update(
test,
"Returned container does not have the correct number of objects in it\n");
2931 return AST_TEST_FAIL;
2934 return AST_TEST_PASS;
2943 char expression[256];
2947 info->name =
"dialplan_function";
2948 info->category =
"/main/sorcery/";
2949 info->summary =
"AST_SORCERY dialplan function";
2951 "Test the AST_SORCERY dialplan function";
2952 return AST_TEST_NOT_RUN;
2957 if (!(sorcery = alloc_and_initialize_sorcery())) {
2958 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
2959 return AST_TEST_FAIL;
2963 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
2964 return AST_TEST_FAIL;
2968 ast_test_status_update(
test,
"Failed to create a known object type\n");
2969 return AST_TEST_FAIL;
2973 ast_test_status_update(
test,
"Failed to allocate return buffer\n");
2974 return AST_TEST_FAIL;
2978 snprintf(expression,
sizeof(expression),
"AST_SORCERY(%s,%s,%s,%s)",
"notest_sorcery",
"test",
"blah",
"bob");
2981 ast_test_status_update(
test,
"Retrieved a non-existent module\n");
2982 return AST_TEST_FAIL;
2986 snprintf(expression,
sizeof(expression),
"AST_SORCERY(%s,%s,%s,%s)",
"test_sorcery",
"notest",
"blah",
"bob");
2989 ast_test_status_update(
test,
"Retrieved a non-existent type\n");
2990 return AST_TEST_FAIL;
2994 snprintf(expression,
sizeof(expression),
"AST_SORCERY(%s,%s,%s,%s)",
"test_sorcery",
"test",
"noid",
"bob");
2997 ast_test_status_update(
test,
"Retrieved a non-existent id\n");
2998 return AST_TEST_FAIL;
3002 snprintf(expression,
sizeof(expression),
"AST_SORCERY(%s,%s,%s,%s)",
"test_sorcery",
"test",
"blah",
"nobob");
3005 ast_test_status_update(
test,
"Retrieved a non-existent field\n");
3006 return AST_TEST_FAIL;
3010 snprintf(expression,
sizeof(expression),
"AST_SORCERY(%s,%s,%s,%s)",
"test_sorcery",
"test",
"blah",
"bob");
3013 ast_test_status_update(
test,
"Failed retrieve field 'bob'\n");
3014 return AST_TEST_FAIL;
3018 ast_test_status_update(
test,
"Failed retrieve field. Got '%u', should be '5'\n", obj->bob);
3019 return AST_TEST_FAIL;
3023 snprintf(expression,
sizeof(expression),
"AST_SORCERY(%s,%s,%s,%s,single,1)",
"test_sorcery",
"test",
"blah",
"bob");
3026 ast_test_status_update(
test,
"Failed retrieve field 'bob'\n");
3027 return AST_TEST_FAIL;
3031 ast_test_status_update(
test,
"Failed retrieve field. Got '%u', should be '5'\n", obj->bob);
3032 return AST_TEST_FAIL;
3036 snprintf(expression,
sizeof(expression),
"AST_SORCERY(%s,%s,%s,%s,single,2)",
"test_sorcery",
"test",
"blah",
"bob");
3039 ast_test_status_update(
test,
"Got a second 'bob' and shouldn't have\n");
3040 return AST_TEST_FAIL;
3044 jim_handler(NULL, ast_variable_new(
"jim",
"555",
""), obj);
3045 jim_handler(NULL, ast_variable_new(
"jim",
"666",
""), obj);
3048 snprintf(expression,
sizeof(expression),
"AST_SORCERY(%s,%s,%s,%s)",
"test_sorcery",
"test",
"blah",
"jim");
3051 ast_test_status_update(
test,
"Couldn't retrieve 'jim'\n");
3052 return AST_TEST_FAIL;
3056 ast_test_status_update(
test,
"Failed retrieve jim. Got '%s', should be '444,555,666'\n",
ast_str_buffer(buf));
3057 return AST_TEST_FAIL;
3061 snprintf(expression,
sizeof(expression),
"AST_SORCERY(%s,%s,%s,%s,single,2)",
"test_sorcery",
"test",
"blah",
"jim");
3064 ast_test_status_update(
test,
"Couldn't retrieve 2nd jim\n");
3065 return AST_TEST_FAIL;
3069 ast_test_status_update(
test,
"Failed retrieve 2nd jim. Got '%s', should be '555'\n",
ast_str_buffer(buf));
3070 return AST_TEST_FAIL;
3074 snprintf(expression,
sizeof(expression),
"AST_SORCERY(%s,%s,%s,%s,concat,|)",
"test_sorcery",
"test",
"blah",
"jim");
3077 ast_test_status_update(
test,
"Couldn't retrieve any 'jim'\n");
3078 return AST_TEST_FAIL;
3082 ast_test_status_update(
test,
"Failed retrieve 'jim'. Got '%s', should be '444|555|666'\n",
ast_str_buffer(buf));
3083 return AST_TEST_FAIL;
3087 snprintf(expression,
sizeof(expression),
"AST_SORCERY(%s,%s,%s,%s,noconcat,3)",
"test_sorcery",
"test",
"blah",
"jim");
3090 ast_test_status_update(
test,
"Should have failed with invalid retrieval_type\n");
3091 return AST_TEST_FAIL;
3095 snprintf(expression,
sizeof(expression),
"AST_SORCERY(%s,%s,%s,%s,single,|)",
"test_sorcery",
"test",
"blah",
"jim");
3098 ast_test_status_update(
test,
"Should have failed with invalid occurrence_number\n");
3099 return AST_TEST_FAIL;
3104 return AST_TEST_PASS;
3114 info->name =
"object_field_registered";
3115 info->category =
"/main/sorcery/";
3116 info->summary =
"ast_sorcery_is_object_field_registered unit test";
3118 "Test ast_sorcery_is_object_field_registered in sorcery";
3119 return AST_TEST_NOT_RUN;
3124 if (!(sorcery = alloc_and_initialize_sorcery())) {
3125 ast_test_status_update(
test,
"Failed to open sorcery structure\n");
3126 return AST_TEST_FAIL;
3146 return AST_TEST_PASS;
3149 static int event_observed;
3151 static void wizard_observer(
const char *name,
const struct ast_sorcery_wizard *wizard)
3153 if (!strcmp(wizard->
name,
"test")) {
3158 static void instance_observer(
const char *name,
struct ast_sorcery *sorcery)
3160 if (!strcmp(name,
"test_sorcery")) {
3170 .wizard_registered = wizard_observer,
3171 .instance_created = instance_observer,
3172 .wizard_unregistering = wizard_observer,
3173 .instance_destroying = instance_observer,
3178 info->name =
"global_observation";
3179 info->category =
"/main/sorcery/";
3180 info->summary =
"global sorcery observation test";
3182 "Test observation of sorcery (global)";
3183 return AST_TEST_NOT_RUN;
3192 ast_test_validate(
test, (event_observed == 1),
"Wizard registered failed");
3196 ast_test_validate(
test, (event_observed == 1),
"Wizard unregistered failed");
3200 ast_test_validate(
test, (event_observed == 1),
"Instance created failed");
3205 ast_test_validate(
test, (event_observed == 1),
"Instance destroyed failed");
3210 ast_test_validate(
test, (event_observed == 0),
"Observer removed failed");
3212 return AST_TEST_PASS;
3215 static void instance_loaded_observer(
const char *name,
const struct ast_sorcery *sorcery,
3218 if (!strcmp(name,
"test_sorcery") && !reloaded) {
3223 static void instance_reloaded_observer(
const char *name,
3226 if (!strcmp(name,
"test_sorcery") && reloaded) {
3233 const char *wizard_args,
void *wizard_data)
3235 if (!strcmp(name,
"test_sorcery") && !strcmp(object_type,
"test_object_type")
3236 && !strcmp(wizard->
name,
"memory") && !strcmp(wizard_args,
"memwiz")) {
3242 struct ast_sorcery *sorcery,
const char *object_type)
3244 if (!strcmp(name,
"test_sorcery") && !strcmp(object_type,
"test_object_type")) {
3250 const struct ast_sorcery *sorcery,
const char *object_type,
int reloaded)
3252 if (!strcmp(name,
"test_sorcery") && !strcmp(object_type,
"test_object_type")
3258 static void object_type_reloaded_observer(
const char *name,
3259 const struct ast_sorcery *sorcery,
const char *object_type,
int reloaded)
3261 if (!strcmp(name,
"test_sorcery") && !strcmp(object_type,
"test_object_type")
3277 info->name =
"instance_observation";
3278 info->category =
"/main/sorcery/";
3279 info->summary =
"sorcery instance observation test";
3281 "Test observation of sorcery (instance)";
3282 return AST_TEST_NOT_RUN;
3289 ast_test_status_update(
test,
"Failed to open a sorcery instance\n");
3290 return AST_TEST_FAIL;
3297 ast_test_validate(
test, (event_observed == 2),
"Instance loaded failed");
3300 ast_test_validate(
test, (event_observed == 0),
"Instance reloaded failed");
3309 ast_test_validate(
test, (event_observed == 0),
"Instance loaded failed");
3312 ast_test_validate(
test, (event_observed == 2),
"Instance reloaded failed");
3316 ast_sorcery_apply_default(sorcery,
"test_object_type",
"memory",
"memwiz");
3317 ast_test_validate(
test, (event_observed == 1),
"Wizard mapping failed");
3323 ast_test_validate(
test, (event_observed == 1),
"Object type registered failed");
3332 ast_test_validate(
test, (event_observed == 2),
"Object type loaded failed");
3335 ast_test_validate(
test, (event_observed == 0),
"Object type reloaded failed");
3344 ast_test_validate(
test, (event_observed == 0),
"Object type loaded failed");
3347 ast_test_validate(
test, (event_observed == 2),
"Object type reloaded failed");
3351 ast_sorcery_apply_default(sorcery,
"test_object_type",
"memory",
"memwiz");
3352 ast_test_validate(
test, (event_observed == 0),
"Observer remove failed");
3354 return AST_TEST_PASS;
3357 static void wizard_loaded_observer(
const char *name,
3360 if (!strcmp(name,
"test") && !strcmp(object_type,
"test_object_type")
3366 static void sorcery_test_load(
void *data,
const struct ast_sorcery *sorcery,
const char *type)
3371 static void wizard_reloaded_observer(
const char *name,
3374 if (!strcmp(name,
"test") && !strcmp(object_type,
"test_object_type")
3385 .wizard_loading = wizard_loaded_observer,
3386 .wizard_loaded = wizard_loaded_observer,
3391 info->name =
"wizard_observation";
3392 info->category =
"/main/sorcery/";
3393 info->summary =
"sorcery wizard observation test";
3395 "Test observation of sorcery (wizard)";
3396 return AST_TEST_NOT_RUN;
3401 wizard->
load = sorcery_test_load;
3402 wizard->
reload = sorcery_test_load;
3410 ast_test_validate(
test, (event_observed == 0),
"Wizard observer removed failed");
3414 ast_test_status_update(
test,
"Failed to open a sorcery instance\n");
3415 return AST_TEST_FAIL;
3419 ast_sorcery_apply_default(sorcery,
"test_object_type",
"test", NULL);
3428 ast_test_validate(
test, (event_observed == 2),
"Wizard loaded failed");
3433 ast_test_validate(
test, (event_observed == 0),
"Wizard reloaded failed");
3442 ast_test_validate(
test, (event_observed == 0),
"Wizard loaded failed");
3447 ast_test_validate(
test, (event_observed == 2),
"Wizard reloaded failed");
3449 return AST_TEST_PASS;
3462 info->name =
"wizard_apply_and_insert";
3463 info->category =
"/main/sorcery/";
3464 info->summary =
"sorcery wizard apply and insert test";
3466 "sorcery wizard apply and insert test";
3467 return AST_TEST_NOT_RUN;
3472 wizard1->load = sorcery_test_load;
3473 wizard1->reload = sorcery_test_load;
3475 wizard2->load = sorcery_test_load;
3476 wizard2->reload = sorcery_test_load;
3479 ast_test_status_update(
test,
"Failed to open a sorcery instance\n");
3480 return AST_TEST_FAIL;
3487 ast_test_validate(
test,
3490 ast_sorcery_apply_default(sorcery,
"test_object_type",
"test", NULL);
3492 ast_test_validate(
test,
3495 ast_test_validate(
test,
3497 ast_test_validate(
test, strcmp(
"test", wizard->
name) == 0);
3501 ast_test_validate(
test,
3504 ast_test_validate(
test,
3507 ast_test_validate(
test,
3511 ast_test_validate(
test,
3514 ast_test_validate(
test,
3516 ast_test_validate(
test, strcmp(
"test2", wizard->
name) == 0);
3517 ast_test_validate(
test, strcmp(
"test2data", data) == 0);
3521 ast_test_validate(
test,
3523 ast_test_validate(
test, strcmp(
"test", wizard->
name) == 0);
3528 ast_test_validate(
test,
3531 ast_test_validate(
test,
3534 ast_test_validate(
test,
3537 ast_test_validate(
test,
3542 ast_test_validate(
test,
3544 ast_test_validate(
test,
3548 ast_test_validate(
test,
3551 ast_test_validate(
test,
3554 ast_test_validate(
test,
3556 ast_test_validate(
test, strcmp(
"test2", wizard->
name) == 0);
3557 ast_test_validate(
test, strcmp(
"test2data", data) == 0);
3561 return AST_TEST_PASS;
3565 .
name =
"test-read-only",
3566 .retrieve_id = sorcery_test_retrieve_id,
3579 info->name =
"wizard_read_only";
3580 info->category =
"/main/sorcery/";
3581 info->summary =
"sorcery wizard read-only test";
3583 "sorcery wizard read-only test";
3584 return AST_TEST_NOT_RUN;
3589 wizard1->load = sorcery_test_load;
3590 wizard1->reload = sorcery_test_load;
3593 ast_test_status_update(
test,
"Failed to open a sorcery instance\n");
3594 return AST_TEST_FAIL;
3602 ast_test_status_update(
test,
"Failed to apply object defaults\n");
3603 return AST_TEST_FAIL;
3606 ast_test_validate(
test,
3609 ast_test_validate(
test,
3613 ast_test_validate(
test, strcmp(wizard->
name, wizard1->name) == 0);
3615 ast_test_validate(
test,
3619 ast_test_status_update(
test,
"Failed to allocate a known object type\n");
3620 return AST_TEST_FAIL;
3624 ast_test_status_update(
test,
"Should not have created object using read-only wizard\n");
3625 return AST_TEST_FAIL;
3628 return AST_TEST_PASS;
3631 static int unload_module(
void)
3633 AST_TEST_UNREGISTER(wizard_registration);
3634 AST_TEST_UNREGISTER(sorcery_open);
3635 AST_TEST_UNREGISTER(apply_default);
3636 AST_TEST_UNREGISTER(apply_config);
3637 AST_TEST_UNREGISTER(object_register);
3638 AST_TEST_UNREGISTER(object_register_without_mapping);
3639 AST_TEST_UNREGISTER(object_field_register);
3640 AST_TEST_UNREGISTER(object_fields_register);
3641 AST_TEST_UNREGISTER(object_alloc_with_id);
3642 AST_TEST_UNREGISTER(object_alloc_without_id);
3643 AST_TEST_UNREGISTER(object_copy);
3644 AST_TEST_UNREGISTER(object_copy_native);
3645 AST_TEST_UNREGISTER(object_diff);
3646 AST_TEST_UNREGISTER(object_diff_native);
3647 AST_TEST_UNREGISTER(objectset_create);
3648 AST_TEST_UNREGISTER(objectset_json_create);
3649 AST_TEST_UNREGISTER(objectset_create_regex);
3650 AST_TEST_UNREGISTER(objectset_apply);
3651 AST_TEST_UNREGISTER(objectset_apply_handler);
3652 AST_TEST_UNREGISTER(objectset_apply_invalid);
3653 AST_TEST_UNREGISTER(objectset_transform);
3654 AST_TEST_UNREGISTER(objectset_apply_fields);
3655 AST_TEST_UNREGISTER(extended_fields);
3656 AST_TEST_UNREGISTER(changeset_create);
3657 AST_TEST_UNREGISTER(changeset_create_unchanged);
3658 AST_TEST_UNREGISTER(object_create);
3659 AST_TEST_UNREGISTER(object_retrieve_id);
3660 AST_TEST_UNREGISTER(object_retrieve_field);
3661 AST_TEST_UNREGISTER(object_retrieve_multiple_all);
3662 AST_TEST_UNREGISTER(object_retrieve_multiple_field);
3663 AST_TEST_UNREGISTER(object_retrieve_regex);
3664 AST_TEST_UNREGISTER(object_update);
3665 AST_TEST_UNREGISTER(object_update_uncreated);
3666 AST_TEST_UNREGISTER(object_delete);
3667 AST_TEST_UNREGISTER(object_delete_uncreated);
3668 AST_TEST_UNREGISTER(object_is_stale);
3669 AST_TEST_UNREGISTER(caching_wizard_behavior);
3670 AST_TEST_UNREGISTER(object_type_observer);
3671 AST_TEST_UNREGISTER(configuration_file_wizard);
3672 AST_TEST_UNREGISTER(configuration_file_wizard_with_file_integrity);
3673 AST_TEST_UNREGISTER(configuration_file_wizard_with_criteria);
3674 AST_TEST_UNREGISTER(configuration_file_wizard_retrieve_field);
3675 AST_TEST_UNREGISTER(configuration_file_wizard_retrieve_multiple);
3676 AST_TEST_UNREGISTER(configuration_file_wizard_retrieve_multiple_all);
3677 AST_TEST_UNREGISTER(dialplan_function);
3678 AST_TEST_UNREGISTER(object_field_registered);
3679 AST_TEST_UNREGISTER(global_observation);
3680 AST_TEST_UNREGISTER(instance_observation);
3681 AST_TEST_UNREGISTER(wizard_observation);
3682 AST_TEST_UNREGISTER(wizard_apply_and_insert);
3683 AST_TEST_UNREGISTER(wizard_read_only);
3688 static int load_module(
void)
3690 AST_TEST_REGISTER(wizard_apply_and_insert);
3691 AST_TEST_REGISTER(wizard_registration);
3692 AST_TEST_REGISTER(sorcery_open);
3693 AST_TEST_REGISTER(apply_default);
3694 AST_TEST_REGISTER(apply_config);
3695 AST_TEST_REGISTER(object_register);
3696 AST_TEST_REGISTER(object_register_without_mapping);
3697 AST_TEST_REGISTER(object_field_register);
3698 AST_TEST_REGISTER(object_fields_register);
3699 AST_TEST_REGISTER(object_alloc_with_id);
3700 AST_TEST_REGISTER(object_alloc_without_id);
3701 AST_TEST_REGISTER(object_copy);
3702 AST_TEST_REGISTER(object_copy_native);
3703 AST_TEST_REGISTER(object_diff);
3704 AST_TEST_REGISTER(object_diff_native);
3705 AST_TEST_REGISTER(objectset_create);
3706 AST_TEST_REGISTER(objectset_json_create);
3707 AST_TEST_REGISTER(objectset_create_regex);
3708 AST_TEST_REGISTER(objectset_apply);
3709 AST_TEST_REGISTER(objectset_apply_handler);
3710 AST_TEST_REGISTER(objectset_apply_invalid);
3711 AST_TEST_REGISTER(objectset_transform);
3712 AST_TEST_REGISTER(objectset_apply_fields);
3713 AST_TEST_REGISTER(extended_fields);
3714 AST_TEST_REGISTER(changeset_create);
3715 AST_TEST_REGISTER(changeset_create_unchanged);
3716 AST_TEST_REGISTER(object_create);
3717 AST_TEST_REGISTER(object_retrieve_id);
3718 AST_TEST_REGISTER(object_retrieve_field);
3719 AST_TEST_REGISTER(object_retrieve_multiple_all);
3720 AST_TEST_REGISTER(object_retrieve_multiple_field);
3721 AST_TEST_REGISTER(object_retrieve_regex);
3722 AST_TEST_REGISTER(object_update);
3723 AST_TEST_REGISTER(object_update_uncreated);
3724 AST_TEST_REGISTER(object_delete);
3725 AST_TEST_REGISTER(object_delete_uncreated);
3726 AST_TEST_REGISTER(object_is_stale);
3727 AST_TEST_REGISTER(caching_wizard_behavior);
3728 AST_TEST_REGISTER(object_type_observer);
3729 AST_TEST_REGISTER(configuration_file_wizard);
3730 AST_TEST_REGISTER(configuration_file_wizard_with_file_integrity);
3731 AST_TEST_REGISTER(configuration_file_wizard_with_criteria);
3732 AST_TEST_REGISTER(configuration_file_wizard_retrieve_field);
3733 AST_TEST_REGISTER(configuration_file_wizard_retrieve_multiple);
3734 AST_TEST_REGISTER(configuration_file_wizard_retrieve_multiple_all);
3735 AST_TEST_REGISTER(dialplan_function);
3736 AST_TEST_REGISTER(object_field_registered);
3737 AST_TEST_REGISTER(global_observation);
3738 AST_TEST_REGISTER(instance_observation);
3739 AST_TEST_REGISTER(wizard_observation);
3740 AST_TEST_REGISTER(wizard_read_only);
#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.
struct ast_variable * next
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)
When each wizard is mapped, save it off to the vector.
const void * updated
Pointer to the update object.
static struct ast_variable * test_sorcery_transform(struct ast_variable *set)
Internal function for object set transformation.
#define ast_sorcery_remove_wizard_mapping(sorcery, type, name)
Remove an object wizard mapping.
#define ast_sorcery_object_field_register_nodoc(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object without documentation.
Asterisk main include file. File version handling, generic pbx functions.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
static void test_sorcery_object_destroy(void *obj)
Internal function to destroy a test object.
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.
#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...
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
int ast_sorcery_instance_observer_add(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Add an observer to a sorcery instance.
static void object_type_loaded_observer(const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
Called after an object type is loaded/reloaded.
Interface for the global sorcery observer.
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.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
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
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.
Iterator for JSON object key/values.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
struct ast_json_iter * ast_json_object_iter(struct ast_json *object)
Get an iterator pointing to the first field in a JSON object.
ast_cond_t cond
Condition for notification.
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Structure for variables, used for configurations and for channel variables.
void(* created)(const void *object)
Callback for when an object is created.
Perform no matching, return all objects.
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.
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.
Full structure for sorcery.
Type for a default handler that should do nothing.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
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.
static int copy(char *infile, char *outfile)
Utility function to copy a file.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
#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.
Return all matching objects.
#define ast_strdup(str)
A wrapper for strdup()
int ast_sorcery_get_wizard_mapping_count(struct ast_sorcery *sorcery, const char *type)
Return the number of wizards mapped to an object type.
#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.
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.
const char * name
Name of the wizard.
int ast_sorcery_global_observer_add(const struct ast_sorcery_global_observer *callbacks)
Add a global observer to sorcery.
unsigned int updated
Whether the object has been updated in the cache or not.
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.
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.
void(* instance_loaded)(const char *name, const struct ast_sorcery *sorcery, int reloaded)
Callback after instance is loaded/reloaded.
const char * ast_sorcery_object_get_type(const void *object)
Get the type of a sorcery object.
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
#define ast_sorcery_unref(sorcery)
Decrease the reference count of a sorcery structure.
struct test_sorcery_object object
Object to return when asked.
const void * deleted
Pointer to the deleted object.
static int test_sorcery_copy(const void *src, void *dst)
Internal function which copies pre-defined data into an object, natively.
void(* wizard_loaded)(const char *name, const struct ast_sorcery_wizard *wizard, const char *object_type, int reloaded)
Callback after a wizard is loaded/reloaded for any type.
unsigned int is_stale
Whether the object is stale or not.
void ast_sorcery_global_observer_remove(const struct ast_sorcery_global_observer *callbacks)
Remove a global observer from sorcery.
const char * ast_sorcery_object_get_extended(const void *object, const char *name)
Get an extended field value from a sorcery object.
int ast_sorcery_create(const struct ast_sorcery *sorcery, void *object)
Create and potentially persist an object using an available wizard.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
Structure for registered object type.
Asterisk JSON abstraction layer.
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
struct ast_json * ast_json_object_iter_value(struct ast_json_iter *iter)
Get the value from an iterator.
Type for default option handler for unsigned integers.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Interface for the sorcery instance observer.
static int test_sorcery_regex_fields(const void *obj, struct ast_variable **fields)
Internal function which creates some ast_variable structures.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Test structure for observer.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
static int apply_handler_called
Global scope apply handler integer to make sure it executed.
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
const char * ast_json_object_iter_key(struct ast_json_iter *iter)
Get the key from an iterator.
const void * created
Pointer to the created object.
Core PBX routines and definitions.
static struct ast_sorcery_wizard test_wizard
Dummy sorcery wizards, not actually used so we only populate the name and nothing else...
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.
void ast_sorcery_instance_observer_remove(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Remove an observer from a sorcery instance.
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.
Test structure for caching.
#define ast_sorcery_wizard_register(interface)
See __ast_sorcery_wizard_register()
int ast_sorcery_delete(const struct ast_sorcery *sorcery, void *object)
Delete an object.
static void * test_sorcery_object_alloc(const char *id)
Internal function to allocate a test object.
#define ast_sorcery_internal_object_register(sorcery, type, alloc, transform, apply)
Register an internal, hidden object type.
Support for dynamic strings.
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.
int ast_sorcery_wizard_unregister(const struct ast_sorcery_wizard *interface)
Unregister a sorcery wizard.
Interface for a sorcery object type observer.
static int test_apply_handler(const struct ast_sorcery *sorcery, void *obj)
Simple apply handler which sets global scope integer to 1 if called.
struct ast_sorcery * ast_sorcery_retrieve_by_module_name(const char *module_name)
Retrieves an existing sorcery instance by module name.
static struct sorcery_test_observer observer
Global scope observer structure for testing.
void(* wizard_loading)(const char *name, const struct ast_sorcery_wizard *wizard, const char *object_type, int reloaded)
Callback before a wizard is loaded/reloaded for any type.
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
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.
Support for logging to various files, console and syslog Configuration in file logger.conf.
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.
#define ast_sorcery_object_type_remove_wizard(sorcery, object_type_name, wizard_type_name, wizard_args)
Remove an object wizard mapping.
static const struct ast_sorcery_observer test_observer
Test sorcery observer implementation.
static void object_type_registered_observer(const char *name, struct ast_sorcery *sorcery, const char *object_type)
When each object type is registered, map a memory wizard to it.
Structure used to handle boolean flags.
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.
Interface for a sorcery wizard.
void ast_sorcery_load(const struct ast_sorcery *sorcery)
Inform any wizards to load persistent objects.
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
void ast_sorcery_reload(const struct ast_sorcery *sorcery)
Inform any wizards to reload persistent objects.
void(* object_type_loaded)(const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
Callback after any object_type is loaded/reloaded.
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.
Interface for the sorcery wizard observer.
void * ast_sorcery_copy(const struct ast_sorcery *sorcery, const void *object)
Create a copy of an object.
int ast_sorcery_object_set_extended(const void *object, const char *name, const char *value)
Set an extended field value on a sorcery object.
unsigned int loaded
Whether the type has been loaded.
#define ast_sorcery_open()
Open a new sorcery structure.
#define AST_TEST_DEFINE(hdr)
void(* load)(void *data, const struct ast_sorcery *sorcery, const char *type)
Optional callback for loading persistent objects.
Abstract JSON element (object, array, string, int, ...).
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.
void(* reload)(void *data, const struct ast_sorcery *sorcery, const char *type)
Optional callback for reloading persistent objects.
unsigned int created
Whether the object has been created in the cache or not.
static struct sorcery_test_caching cache
Global scope caching structure for testing.
struct ast_category * ast_category_get(const struct ast_config *config, const char *category_name, const char *filter)
Retrieve a category if it exists.
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
#define ASTERISK_GPL_KEY
The text the key() function should return.
static int test_sorcery_diff(const void *original, const void *modified, struct ast_variable **changes)
Internal function which creates a pre-defined diff natively.
Asterisk module definitions.
void(* instance_loading)(const char *name, const struct ast_sorcery *sorcery, int reloaded)
Callback before instance is loaded/reloaded.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
static int test_sorcery_regex_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Internal function which sets some values.
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
ast_mutex_t lock
Lock for notification.
Structure for mutex and tracking information.
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.
void(* object_type_loading)(const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
Callback before any object_type is loaded/reloaded.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Sorcery Data Access Layer API.
int ast_sorcery_update(const struct ast_sorcery *sorcery, void *object)
Update an object.
struct ast_json_iter * ast_json_object_iter_next(struct ast_json *object, struct ast_json_iter *iter)
Get the next iterator.
unsigned int deleted
Whether the object has been deleted from the cache or not.