39#if defined(TEST_FRAMEWORK)
41#define TEST_CATEGORY "/res/parking/"
43#define CHANNEL_TECH_NAME "ParkingTestChannel"
48 .id.number.str =
"100",
64 .description =
"Parking unit test technology",
65 .write = parking_test_write,
66 .read = parking_test_read,
70static int set_test_formats(
struct ast_channel *chan)
91static struct ast_channel *create_alice_channel(
void)
94 "100",
"Alice",
"100",
"100",
"default",
NULL,
NULL, 0,
101 if (set_test_formats(alice)) {
138#define TEST_LOT_NAME "unit_tests_res_parking_test_lot"
140static struct parking_lot *generate_test_parking_lot(
const char *
name,
int low_space,
int high_space,
const char *park_exten,
const char *park_context,
struct ast_test *
test)
145 test_cfg = parking_lot_cfg_create(
name);
150 test_cfg->parking_start = low_space;
151 test_cfg->parking_stop = high_space;
152 test_cfg->parkingtime = 10;
153 test_cfg->comebackdialtime = 10;
154 test_cfg->parkfindnext = 1;
155 test_cfg->parkext_exclusive = 1;
173static int dispose_test_lot(
struct parking_lot *test_lot,
int expect_destruction)
182 if ((expect_destruction && !found_lot) || (!expect_destruction && found_lot)) {
196 info->name =
"create_lot";
198 info->summary =
"Parking lot creation";
200 "Creates a parking lot and then disposes of it.";
208 test_lot = generate_test_parking_lot(TEST_LOT_NAME, 701, 703,
NULL,
"unit_test_res_parking_create_lot_con",
test);
219 dispose_test_lot(test_lot, 1);
225 if (dispose_test_lot(found_copy, 1)) {
244 info->name =
"park_channel";
246 info->summary =
"Park a Channel";
248 "Creates a parking lot, parks a channel in it, then removes it from the parking lot bridge.";
256 test_lot = generate_test_parking_lot(TEST_LOT_NAME, 701, 703,
NULL,
"unit_test_res_parking_create_lot_con",
test);
262 chan_alice = create_alice_channel();
265 dispose_test_lot(test_lot, 1);
273 if (!parking_bridge) {
275 dispose_test_lot(test_lot, 1);
282 dispose_test_lot(test_lot, 1);
292 if (dispose_test_lot(test_lot, 1)) {
388 .parker_dial_string =
"ParkingTestChannel/Alice",
395 info->name =
"park_retrieve";
397 info->summary =
"Retrieve a parked channel";
399 "Creates a parking lot, parks a channel in it, then removes it from the parking lot bridge.";
407 test_lot = generate_test_parking_lot(TEST_LOT_NAME, 701, 703,
NULL,
"unit_test_res_parking_create_lot_con",
test);
413 chan_alice = create_alice_channel();
416 dispose_test_lot(test_lot, 1);
424 if (!parking_bridge) {
426 dispose_test_lot(test_lot, 1);
433 dispose_test_lot(test_lot, 1);
440 if (!retrieved_user) {
448 if (!parked_users_match(retrieved_user, &expected_user,
test)) {
454 if (retrieved_user->chan != chan_alice) {
463 if (dispose_test_lot(test_lot, 1)) {
471static int check_retrieve_call_extensions(
struct ast_test *
test,
int expected)
476 char search_buffer[4];
481 if (check ? !expected : expected) {
484 expected ?
"not present" :
"present",
485 expected ?
"should" :
"should not");
487 }
else if (check && expected) {
498 sprintf(search_buffer,
"%d",
extens);
503 if (check ? !expected : expected) {
507 expected ?
"not present" :
"present",
508 expected ?
"should" :
"should not");
510 }
else if (check && expected) {
512 ast_test_status_update(
test,
"An extension '%s' has the wrong application associated with it. Got '%s', expected 'ParkedCall'.\n",
530 info->name =
"park_extensions";
532 info->summary =
"Parking lot extension creation tests";
534 "Creates parking lots and checks that they registered the expected extensions, then removes them.";
540 test_lot = generate_test_parking_lot(TEST_LOT_NAME, 701, 703,
"700",
"unit_test_res_parking_create_lot_con",
test);
546 if (check_retrieve_call_extensions(
test, 1)) {
547 dispose_test_lot(test_lot, 1);
551 ast_test_status_update(
test,
"Extensions for the test parking lot were verified. Cleaning up and verifying their removal.\n");
553 if (dispose_test_lot(test_lot, 1)) {
560 if (check_retrieve_call_extensions(
test, 0)) {
561 ast_log(
LOG_ERROR,
"Test 'park_extensions' failed to clean up after itself properly.\n");
587 info->name =
"extension_conflicts";
589 info->summary =
"Tests the addition of parking lot extensions to make sure conflicts are detected";
591 "Creates parking lots with overlapping extensions to test for conflicts";
598 base_lot = generate_test_parking_lot(TEST_LOT_NAME, 701, 703,
"700",
"unit_test_res_parking_create_lot_con",
test);
606 cur_lot_name =
"unit_tests_res_parking_test_lot_fail1";
608 expect_fail1 = generate_test_parking_lot(cur_lot_name,
609 801, 803,
"700",
"unit_test_res_parking_create_lot_con",
618 cur_lot_name =
"unit_tests_res_parking_test_lot_fail2";
619 expect_fail2 = generate_test_parking_lot(cur_lot_name,
620 702, 705,
"800",
"unit_test_res_parking_create_lot_con",
628 cur_lot_name =
"unit_tests_res_parking_test_lot_fail3";
629 expect_fail3 = generate_test_parking_lot(cur_lot_name,
630 698, 700,
"testfail3",
"unit_test_res_parking_create_lot_con",
638 cur_lot_name =
"unit_tests_res_parking_test_lot_fail4";
639 expect_fail4 = generate_test_parking_lot(cur_lot_name,
640 704, 706,
"703",
"unit_test_res_parking_create_lot_con",
648 cur_lot_name =
"unit_tests_res_parking_test_lot_success1";
649 expect_success1 = generate_test_parking_lot(cur_lot_name,
650 701, 703,
"700",
"unit_test_res_parking_create_lot_con_2",
652 if (!expect_success1) {
658 cur_lot_name =
"unit_tests_res_parking_test_lot_success2";
659 expect_success2 = generate_test_parking_lot(cur_lot_name,
660 601, 605,
"600",
"unit_test_res_parking_create_lot_con",
662 if (!expect_success2) {
668 cur_lot_name =
"unit_tests_res_parking_test_lot_success3";
669 expect_success3 = generate_test_parking_lot(cur_lot_name,
670 704, 706,
"testsuccess3",
"unit_test_res_parking_create_lot_con",
672 if (!expect_success3) {
678 cur_lot_name =
"unit_tests_res_parking_test_lot_success4";
679 expect_success4 = generate_test_parking_lot(cur_lot_name,
680 697, 699,
"testsuccess4",
"unit_test_res_parking_create_lot_con",
682 if (!expect_success4) {
688 if (base_lot && dispose_test_lot(base_lot, 1)) {
694 dispose_test_lot(expect_fail1, 1);
699 dispose_test_lot(expect_fail2, 1);
704 dispose_test_lot(expect_fail3, 1);
709 dispose_test_lot(expect_fail4, 1);
713 if (expect_success1 && dispose_test_lot(expect_success1, 1)) {
718 if (expect_success2 && dispose_test_lot(expect_success2, 1)) {
723 if (expect_success3 && dispose_test_lot(expect_success3, 1)) {
728 if (expect_success4 && dispose_test_lot(expect_success4, 1)) {
746 info->name =
"dynamic_parking_variables";
748 info->summary =
"Tests whether dynamic parking lot creation respects channel variables";
750 "Creates a template parking lot, creates a channel, sets dynamic parking variables, and then creates a parking lot for that channel";
758 expected_cfg = parking_lot_cfg_create(
"unit_tests_res_parking_test_lot_dynamic");
765 expected_cfg->parking_start = 751;
766 expected_cfg->parking_stop = 760;
767 expected_cfg->parkingtime = 10;
768 expected_cfg->comebackdialtime = 10;
769 expected_cfg->parkfindnext = 1;
770 expected_cfg->parkext_exclusive = 1;
773 ast_string_field_set(expected_cfg, comebackcontext,
"unit_test_res_parking_create_lot_comeback");
777 template_lot = generate_test_parking_lot(TEST_LOT_NAME, 701, 703,
"700",
"unit_test_res_parking_create_lot_con",
test);
786 chan_alice = create_alice_channel();
804 dynamic_lot = parking_create_dynamic_lot_forced(
"unit_tests_res_parking_test_lot_dynamic", chan_alice);
813 if (!parking_lot_cfgs_match(dynamic_lot->cfg, expected_cfg,
test)) {
822 if (template_lot && dispose_test_lot(template_lot, 1)) {
827 if (dynamic_lot && dispose_test_lot(dynamic_lot, 1)) {
841#if defined(TEST_FRAMEWORK)
856#if defined(TEST_FRAMEWORK)
Asterisk main include file. File version handling, generic pbx functions.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
int ast_bridge_depart(struct ast_channel *chan)
Depart a channel from a bridge.
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
@ AST_BRIDGE_IMPART_CHAN_DEPARTABLE
Internal Asterisk hangup causes.
const char * ast_channel_name(const struct ast_channel *chan)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
void ast_channel_set_caller(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
Set the caller id information in the Asterisk channel.
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_state_set(struct ast_channel *chan, enum ast_channel_state)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
#define ast_channel_unlock(chan)
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
static int hangup_channel(struct stasis_app_control *control, struct ast_channel *chan, void *data)
struct ast_frame ast_null_frame
Asterisk module definitions.
struct ast_bridge * park_application_setup(struct ast_channel *parkee, struct ast_channel *parker, const char *app_data, int *silence_announcements)
Function to prepare a channel for parking by determining which parking bridge should be used,...
struct parked_user * parking_lot_retrieve_parked_user(struct parking_lot *lot, int target)
Determine if there is a parked user in a parking space and pull it from the parking lot if there is.
void unload_parking_tests(void)
Unregister parking unit tests.
int load_parking_tests(void)
Register parking unit tests.
Core PBX routines and definitions.
const char * ast_get_extension_app(struct ast_exten *e)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
struct ast_exten * pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
static void * cleanup(void *unused)
Call Parking Resource Internal API.
struct parking_lot * parking_lot_build_or_update(struct parking_lot_cfg *cfg, int dynamic)
If a parking lot exists in the parking lot list already, update its status to match the provided conf...
struct parking_lot * parking_lot_find_by_name(const char *lot_name)
Find a parking lot based on its name.
int parking_lot_remove_if_unused(struct parking_lot *lot)
Remove a parking lot from the usable lists if it is no longer involved in any calls and no configurat...
int parking_lot_cfg_create_extensions(struct parking_lot_cfg *lot_cfg)
Add extensions for a parking lot configuration.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Structure that contains information about a bridge.
Structure to describe a channel "technology", ie a channel driver See for examples:
Main Channel structure associated with a channel.
ast_exten: An extension The dialplan is saved as a linked list with each context having it's own link...
Data structure associated with a single frame of data.
Caller Party information.
struct ast_party_id id
Caller party ID.
struct ast_party_name name
Subscriber name.
char * str
Subscriber name (Malloced)
char * parker_dial_string
enum park_call_resolution resolution
const ast_string_field comebackcontext
unsigned int parkfindnext
unsigned int parkext_exclusive
const ast_string_field parkext
unsigned int comebackdialtime
const ast_string_field parking_con
enum parking_lot_modes mode
struct ast_bridge * parking_bridge
const ast_string_field name
#define AST_TEST_REGISTER(cb)
#define ast_test_status_update(a, b, c...)
#define AST_TEST_UNREGISTER(cb)
#define AST_TEST_DEFINE(hdr)
#define CHANNEL_TECH_NAME
static void safe_channel_release(struct ast_channel *chan)
static void do_sleep(struct timespec *to_sleep)
static struct timespec to_sleep
A 1 second sleep.
Time-related functions and macros.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.