[asterisk-commits] rmudgett: branch rmudgett/parking r330704 - /team/rmudgett/parking/main/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Aug 2 18:27:38 CDT 2011
Author: rmudgett
Date: Tue Aug 2 18:27:34 2011
New Revision: 330704
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=330704
Log:
* Write unit test for dialplan parking space usage map.
* Move features unit test code to better place to eliminate forward
references.
* Fix dialplan usage extension removal. Must be sure that the extension
is present before removing it or get a warning.
Modified:
team/rmudgett/parking/main/features.c
Modified: team/rmudgett/parking/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/parking/main/features.c?view=diff&rev=330704&r1=330703&r2=330704
==============================================================================
--- team/rmudgett/parking/main/features.c (original)
+++ team/rmudgett/parking/main/features.c Tue Aug 2 18:27:34 2011
@@ -1463,211 +1463,6 @@
return masq_park_call(rchan, peer, 0, NULL, 1, args);
}
-#ifdef TEST_FRAMEWORK
-static int fake_fixup(struct ast_channel *clonechan, struct ast_channel *original)
-{
- return 0;
-}
-
-static struct ast_channel *create_test_channel(const struct ast_channel_tech *fake_tech)
-{
- struct ast_channel *test_channel1;
-
- if (!(test_channel1 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
- NULL, NULL, 0, 0, "TestChannel1"))) {
- ast_log(LOG_WARNING, "Whoa, test channel creation failed.\n");
- return NULL;
- }
-
- /* normally this is done in the channel driver */
- test_channel1->nativeformats = AST_FORMAT_GSM;
- test_channel1->writeformat = AST_FORMAT_GSM;
- test_channel1->rawwriteformat = AST_FORMAT_GSM;
- test_channel1->readformat = AST_FORMAT_GSM;
- test_channel1->rawreadformat = AST_FORMAT_GSM;
- test_channel1->tech = fake_tech;
-
- return test_channel1;
-}
-
-static int unpark_test_channel(struct ast_channel *toremove, struct ast_park_call_args *args)
-{
- struct ast_context *con;
- struct parkeduser *pu_toremove;
- int res = 0;
-
- args->pu->notquiteyet = 1; /* go ahead and stop processing the test parking */
-
- AST_LIST_LOCK(&args->pu->parkinglot->parkings);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&args->pu->parkinglot->parkings, pu_toremove, list) {
- if (pu_toremove == args->pu) {
- AST_LIST_REMOVE_CURRENT(list);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&args->pu->parkinglot->parkings);
-
- if (!pu_toremove) {
- ast_log(LOG_WARNING, "Whoa, could not find parking test call!\n");
- return -1;
- }
-
- con = ast_context_find(args->pu->parkinglot->cfg.parking_con);
- if (con) {
- if (ast_context_remove_extension2(con, args->pu->parkingexten, 1, NULL, 0)) {
- ast_log(LOG_WARNING, "Whoa, failed to remove the parking extension!\n");
- res = -1;
- } else {
- notify_metermaids(args->pu->parkingexten,
- pu_toremove->parkinglot->cfg.parking_con, AST_DEVICE_NOT_INUSE);
- }
- } else {
- ast_log(LOG_WARNING, "Whoa, no parking context?\n");
- res = -1;
- }
-
- parkinglot_unref(pu_toremove->parkinglot);
- ast_free(pu_toremove);
- args->pu = NULL;
-
- if (!res && toremove) {
- ast_hangup(toremove);
- }
- return res;
-}
-
-/* BUGBUG need to reexamine tests for reference leaks and locking issues. */
-/* BUGBUG this internal test is rubbish. */
-AST_TEST_DEFINE(features_test)
-{
- struct ast_channel *test_channel1 = NULL;
- struct ast_channel *parked_chan = NULL;
- struct ast_parkinglot *dynlot;
- struct ast_park_call_args args = {
- .timeout = DEFAULT_PARK_TIME,
- };
-
- int res = 0;
-
- static const struct ast_channel_tech fake_tech = {
- .fixup = fake_fixup, /* silence warning from masquerade */
- };
-
- static const char unique_parkinglot[] = "myuniquetestparkinglot3141592654";
- static const char parkinglot_range[] = "750-760";
-
- switch (cmd) {
- case TEST_INIT:
- info->name = "features_test";
- info->category = "/main/features/";
- info->summary = "Features unit test";
- info->description =
- "Tests whether parking respects PARKINGLOT settings";
- return AST_TEST_NOT_RUN;
- case TEST_EXECUTE:
- break;
- }
-
- /* changing a config option is a bad practice, but must be done in this case */
- parkeddynamic = 1;
-
-
- ast_test_status_update(test, "Test parking functionality with defaults\n");
- if (!(test_channel1 = create_test_channel(&fake_tech))) {
- res = -1;
- goto exit_features_test;
- }
- if (park_call_full(test_channel1, NULL, &args)) {
- res = -1;
- goto exit_features_test;
- }
- if (unpark_test_channel(test_channel1, &args)) {
- res = -1;
- goto exit_features_test;
- }
-
-
- ast_test_status_update(test, "Check that certain parking options are respected\n");
- if (!(test_channel1 = create_test_channel(&fake_tech))) {
- res = -1;
- goto exit_features_test;
- }
- pbx_builtin_setvar_helper(test_channel1, "PARKINGLOT", unique_parkinglot);
- pbx_builtin_setvar_helper(test_channel1, "PARKINGDYNPOS", parkinglot_range);
- if (park_call_full(test_channel1, NULL, &args)) {
- res = -1;
- goto exit_features_test;
- }
- /* grab newly created parking lot for destruction in the end */
- dynlot = args.pu->parkinglot;
- if (args.pu->parkingnum != 750
- || strcasecmp(dynlot->name, unique_parkinglot)
- || dynlot->cfg.parking_start != 750
- || dynlot->cfg.parking_stop != 760) {
- ast_test_status_update(test, "Parking settings were not respected\n");
- if (!unpark_test_channel(test_channel1, &args)) {
- test_channel1 = NULL;
- }
- res = -1;
- goto exit_features_test;
- } else {
- ast_test_status_update(test, "Parking settings for non-masquerading park verified\n");
- }
- if (unpark_test_channel(test_channel1, &args)) {
- res = -1;
- goto exit_features_test;
- }
-
-
- ast_test_status_update(test, "Check #2 that certain parking options are respected\n");
- if (!(test_channel1 = create_test_channel(&fake_tech))) {
- res = -1;
- goto exit_features_test;
- }
- pbx_builtin_setvar_helper(test_channel1, "PARKINGLOT", unique_parkinglot);
- pbx_builtin_setvar_helper(test_channel1, "PARKINGDYNPOS", parkinglot_range);
- if (masq_park_call(test_channel1, NULL, 0, NULL, 0, &args)) {
- res = -1;
- goto exit_features_test;
- }
- /* hangup zombie channel */
- ast_hangup(test_channel1);
- test_channel1 = NULL;
-
- dynlot = args.pu->parkinglot;
- if (args.pu->parkingnum != 750
- || strcasecmp(dynlot->name, unique_parkinglot)
- || dynlot->cfg.parking_start != 750
- || dynlot->cfg.parking_stop != 760) {
- ast_test_status_update(test, "Parking settings were not respected\n");
- res = -1;
- } else {
- ast_test_status_update(test, "Parking settings for masquerading park verified\n");
- }
-
- /* find the real channel */
- parked_chan = ast_channel_get_by_name("TestChannel1");
- if (unpark_test_channel(parked_chan, &args)) {
- if (parked_chan) {
- ast_hangup(parked_chan);
- }
- res = -1;
- }
-
-
-exit_features_test:
-
- if (test_channel1) {
- ast_hangup(test_channel1);
- }
-
- ast_features_reload();
- return res ? AST_TEST_FAIL : AST_TEST_PASS;
-}
-#endif
-
-
/*!
* \brief set caller and callee according to the direction
* \param caller, callee, peer, chan, sense
@@ -4332,7 +4127,6 @@
{
struct parkeduser *pu;
int res = 0;
- char parkingslot[AST_MAX_EXTENSION];
/* Lock parking list */
AST_LIST_LOCK(&curlot->parkings);
@@ -4408,6 +4202,8 @@
if (comebacktoorigin) {
set_c_e_p(chan, parking_con_dial, peername_flat, 1);
} else {
+ char parkingslot[AST_MAX_EXTENSION];
+
snprintf(parkingslot, sizeof(parkingslot), "%d", pu->parkingnum);
pbx_builtin_setvar_helper(chan, "PARKINGSLOT", parkingslot);
set_c_e_p(chan, "parkedcallstimeout", peername_flat, 1);
@@ -5814,9 +5610,29 @@
/*!
* \internal
+ * \brief Remove the given extension if it exists.
+ *
+ * \param context Dialplan database context name.
+ * \param exten Extension to remove.
+ * \param priority Extension priority to remove.
+ *
+ * \return Nothing
+ */
+static void remove_exten_if_exist(const char *context, const char *exten, int priority)
+{
+ struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
+
+ if (pbx_find_extension(NULL, NULL, &q, context, exten, priority, NULL, NULL,
+ E_MATCH)) {
+ ast_context_remove_extension(context, exten, priority, registrar);
+ }
+}
+
+/*!
+ * \internal
* \brief Remove unused parking lot access ramp items.
*
- * \param con Dialplan database context.
+ * \param context Dialplan database context name.
* \param old_ramps Before configuration reload access ramp usage map.
* \param new_ramps After configuration reload access ramp usage map.
*
@@ -5826,7 +5642,7 @@
*
* \return Nothing
*/
-static void remove_dead_ramp_usage(struct ast_context *con, struct parking_dp_ramp_map *old_ramps, struct parking_dp_ramp_map *new_ramps)
+static void remove_dead_ramp_usage(const char *context, struct parking_dp_ramp_map *old_ramps, struct parking_dp_ramp_map *new_ramps)
{
struct parking_dp_ramp *old_ramp;
struct parking_dp_ramp *new_ramp;
@@ -5843,7 +5659,7 @@
cmp = strcmp(old_ramp->exten, new_ramp->exten);
if (cmp < 0) {
/* New map does not have old ramp. */
- ast_context_remove_extension2(con, old_ramp->exten, 0, registrar, 0);
+ remove_exten_if_exist(context, old_ramp->exten, 1);
old_ramp = AST_LIST_NEXT(old_ramp, node);
continue;
}
@@ -5858,7 +5674,7 @@
/* Any old ramps left must be dead. */
for (; old_ramp; old_ramp = AST_LIST_NEXT(old_ramp, node)) {
- ast_context_remove_extension2(con, old_ramp->exten, 0, registrar, 0);
+ remove_exten_if_exist(context, old_ramp->exten, 1);
}
}
@@ -5866,25 +5682,26 @@
* \internal
* \brief Destroy the given parking space.
*
- * \param con Dialplan database context.
+ * \param context Dialplan database context name.
* \param space Parking space.
*
* \return Nothing
*/
-static void destroy_space(struct ast_context *con, int space)
+static void destroy_space(const char *context, int space)
{
char exten[AST_MAX_EXTENSION];
- /* Destroy all priorities of the parking space that we registered. */
+ /* Destroy priorities of the parking space that we registered. */
snprintf(exten, sizeof(exten), "%d", space);
- ast_context_remove_extension2(con, exten, 0, registrar, 0);
+ remove_exten_if_exist(context, exten, PRIORITY_HINT);
+ remove_exten_if_exist(context, exten, 1);
}
/*!
* \internal
* \brief Remove unused parking lot space items.
*
- * \param con Dialplan database context.
+ * \param context Dialplan database context name.
* \param old_spaces Before configuration reload parking space usage map.
* \param new_spaces After configuration reload parking space usage map.
* \param destroy_space Function to destroy parking space item.
@@ -5895,9 +5712,9 @@
*
* \return Nothing
*/
-static void remove_dead_spaces_usage(struct ast_context *con,
+static void remove_dead_spaces_usage(const char *context,
struct parking_dp_space_map *old_spaces, struct parking_dp_space_map *new_spaces,
- void (*destroy_space)(struct ast_context *con, int space))
+ void (*destroy_space)(const char *context, int space))
{
struct parking_dp_spaces *old_range;
struct parking_dp_spaces *new_range;
@@ -5947,7 +5764,7 @@
/* Destroy dead parking spaces. */
for (; space <= stop; ++space) {
- destroy_space(con, space);
+ destroy_space(context, space);
}
}
}
@@ -5956,7 +5773,7 @@
* \internal
* \brief Remove unused parking lot context items.
*
- * \param con Dialplan database context.
+ * \param context Dialplan database context name.
* \param old_ctx Before configuration reload context usage map.
* \param new_ctx After configuration reload context usage map.
*
@@ -5966,13 +5783,13 @@
*
* \return Nothing
*/
-static void remove_dead_context_usage(struct ast_context *con, struct parking_dp_context *old_ctx, struct parking_dp_context *new_ctx)
-{
- remove_dead_ramp_usage(con, &old_ctx->access_extens, &new_ctx->access_extens);
- remove_dead_spaces_usage(con, &old_ctx->spaces, &new_ctx->spaces, destroy_space);
+static void remove_dead_context_usage(const char *context, struct parking_dp_context *old_ctx, struct parking_dp_context *new_ctx)
+{
+ remove_dead_ramp_usage(context, &old_ctx->access_extens, &new_ctx->access_extens);
+ remove_dead_spaces_usage(context, &old_ctx->spaces, &new_ctx->spaces, destroy_space);
#if 0
/* I don't think we should destroy hints if the parking space still exists. */
- remove_dead_spaces_usage(con, &old_ctx->hints, &new_ctx->hints, destroy_space_hint);
+ remove_dead_spaces_usage(context, &old_ctx->hints, &new_ctx->hints, destroy_space_hint);
#endif
}
@@ -6007,23 +5824,16 @@
cmp = strcmp(old_ctx->context, new_ctx->context);
if (cmp < 0) {
/* New map does not have old map context. */
- ast_wrlock_contexts();
con = ast_context_find(old_ctx->context);
if (con) {
ast_context_destroy(con, registrar);
}
- ast_unlock_contexts();
old_ctx = AST_LIST_NEXT(old_ctx, node);
continue;
}
if (cmp == 0) {
/* Old and new map have this context. */
- ast_wrlock_contexts();
- con = ast_context_find(old_ctx->context);
- if (con) {
- remove_dead_context_usage(con, old_ctx, new_ctx);
- }
- ast_unlock_contexts();
+ remove_dead_context_usage(old_ctx->context, old_ctx, new_ctx);
old_ctx = AST_LIST_NEXT(old_ctx, node);
} else {
/* Old map does not have new map context. */
@@ -6033,12 +5843,10 @@
/* Any old contexts left must be dead. */
for (; old_ctx; old_ctx = AST_LIST_NEXT(old_ctx, node)) {
- ast_wrlock_contexts();
con = ast_context_find(old_ctx->context);
if (con) {
ast_context_destroy(con, registrar);
}
- ast_unlock_contexts();
}
}
@@ -7112,6 +6920,445 @@
return 0;
}
+#if defined(TEST_FRAMEWORK)
+/*!
+ * \internal
+ * \brief Convert parking spaces map list to a comma separated string.
+ *
+ * \param str String buffer to fill.
+ * \param spaces Parking spaces map list to convert.
+ *
+ * \return Nothing
+ */
+static void create_spaces_str(struct ast_str **str, struct parking_dp_space_map *spaces)
+{
+ const char *comma;
+ struct parking_dp_spaces *cur;
+
+ ast_str_reset(*str);
+ comma = "";
+ AST_LIST_TRAVERSE(spaces, cur, node) {
+ if (cur->start == cur->stop) {
+ ast_str_append(str, 0, "%s%d", comma, cur->start);
+ } else {
+ ast_str_append(str, 0, "%s%d-%d", comma, cur->start, cur->stop);
+ }
+ comma = ",";
+ }
+}
+#endif /* defined(TEST_FRAMEWORK) */
+
+#if defined(TEST_FRAMEWORK)
+/*!
+ * \internal
+ * \brief Compare parking spaces map to what is expected.
+ *
+ * \param test Unit test context.
+ * \param spaces Parking spaces map list to check.
+ * \param expected String to compare with.
+ * \param what What is being compared.
+ *
+ * \retval 0 successful compare.
+ * \retval nonzero if failed to compare.
+ */
+static int check_spaces(struct ast_test *test, struct parking_dp_space_map *spaces, const char *expected, const char *what)
+{
+ int cmp;
+ struct ast_str *str = ast_str_alloca(1024);
+
+ create_spaces_str(&str, spaces);
+ cmp = strcmp(expected, ast_str_buffer(str));
+ if (cmp) {
+ ast_test_status_update(test,
+ "Unexpected parking space map for %s. Expect:'%s' Got:'%s'\n",
+ what, expected, ast_str_buffer(str));
+ }
+ return cmp;
+}
+#endif /* defined(TEST_FRAMEWORK) */
+
+#if defined(TEST_FRAMEWORK)
+/*!
+ * \internal
+ * \brief Add a dead space to the dead spaces list.
+ *
+ * \param context Dead spaces list ptr pretending to be a context name ptr.
+ * \param space Dead space to add to the list.
+ *
+ * \return Nothing
+ */
+static void test_add_dead_space(const char *context, int space)
+{
+ struct parking_dp_space_map *dead_spaces = (struct parking_dp_space_map *) context;
+
+ usage_context_add_spaces(dead_spaces, space, space, NULL);
+}
+#endif /* defined(TEST_FRAMEWORK) */
+
+#if defined(TEST_FRAMEWORK)
+struct test_map {
+ const char *ramp;
+ int start;
+ int stop;
+ const char *expect;
+};
+
+/*!
+ * \internal
+ * \brief Build a parking lot dialplan usage test map from a table.
+ *
+ * \param test Unit test context.
+ * \param lot Parking lot to use to build test usage map.
+ * \param table_name Name of passed in table.
+ * \param table Usage information to put in the usage map.
+ * \param num_entries Number of entries in the table.
+ *
+ * \retval Created context node on success.
+ * \retval NULL on error.
+ */
+static struct parking_dp_context *test_build_maps(struct ast_test *test,
+ struct ast_parkinglot *lot, const char *table_name, const struct test_map *table,
+ size_t num_entries)
+{
+ struct parking_dp_context *ctx_node;
+ int cur_index = 0;
+ char what[40];
+
+ snprintf(what, sizeof(what), "%s[%d]", table_name, cur_index);
+ ast_copy_string(lot->cfg.parkext, table->ramp, sizeof(lot->cfg.parkext));
+ lot->cfg.parking_start = table->start;
+ lot->cfg.parking_stop = table->stop;
+ ctx_node = build_dialplan_useage_context(lot);
+ if (!ctx_node) {
+ ast_test_status_update(test, "Failed to create parking lot context map for %s\n",
+ what);
+ return NULL;
+ }
+ if (check_spaces(test, &ctx_node->spaces, table->expect, what)) {
+ destroy_dialplan_usage_context(ctx_node);
+ return NULL;
+ }
+ while (--num_entries) {
+ ++cur_index;
+ ++table;
+ snprintf(what, sizeof(what), "%s[%d]", table_name, cur_index);
+ ast_copy_string(lot->cfg.parkext, table->ramp, sizeof(lot->cfg.parkext));
+ lot->cfg.parking_start = table->start;
+ lot->cfg.parking_stop = table->stop;
+ if (dialplan_usage_add_parkinglot_data(ctx_node, lot)) {
+ ast_test_status_update(test, "Failed to add parking lot data for %s\n", what);
+ destroy_dialplan_usage_context(ctx_node);
+ return NULL;
+ }
+ if (check_spaces(test, &ctx_node->spaces, table->expect, what)) {
+ destroy_dialplan_usage_context(ctx_node);
+ return NULL;
+ }
+ }
+ return ctx_node;
+}
+
+static const struct test_map test_old_ctx[] = {
+ /* The following order of building ctx is important to test adding items to the lists. */
+ { "702", 14, 15, "14-15" },
+ { "700", 10, 11, "10-11,14-15" },
+ { "701", 18, 19, "10-11,14-15,18-19" },
+ { "703", 12, 13, "10-15,18-19" },
+ { "704", 16, 17, "10-19" },
+ { "704", 10, 19, "10-19" },
+
+ /* Add more spaces to ctx to test removing dead parking spaces. */
+ { "705", 21, 23, "10-19,21-23" },
+ { "706", 26, 29, "10-19,21-23,26-29" },
+ { "707", 31, 32, "10-19,21-23,26-29,31-32" },
+ { "708", 36, 38, "10-19,21-23,26-29,31-32,36-38" },
+ { "708", 40, 41, "10-19,21-23,26-29,31-32,36-38,40-41" },
+};
+
+static const struct test_map test_new_ctx[] = {
+ { "702", 4, 5, "4-5" },
+ { "704", 22, 24, "4-5,22-24" },
+ { "709", 27, 28, "4-5,22-24,27-28" },
+ { "710", 30, 33, "4-5,22-24,27-28,30-33" },
+ { "711", 35, 37, "4-5,22-24,27-28,30-33,35-37" },
+};
+#endif /* defined(TEST_FRAMEWORK) */
+
+#if defined(TEST_FRAMEWORK)
+/*!
+ * \internal
+ * \brief Test parking dialplan usage map code.
+ *
+ * \param test Unit test context.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int test_dialplan_usage_map(struct ast_test *test)
+{
+ struct parking_dp_context *old_ctx;
+ struct parking_dp_context *new_ctx;
+ struct ast_parkinglot *lot;
+ struct parking_dp_space_map dead_spaces = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
+ int res;
+
+ ast_test_status_update(test, "Test parking dialplan usage map code\n");
+
+ lot = create_parkinglot("test_lot");
+ if (!lot) {
+ return -1;
+ }
+ ast_copy_string(lot->cfg.parking_con, "test-ctx", sizeof(lot->cfg.parking_con));
+
+ ast_test_status_update(test, "Build old_ctx map\n");
+ old_ctx = test_build_maps(test, lot, "test_old_ctx", test_old_ctx,
+ ARRAY_LEN(test_old_ctx));
+ if (!old_ctx) {
+ ao2_ref(lot, -1);
+ return -1;
+ }
+
+ ast_test_status_update(test, "Build new_ctx map\n");
+ new_ctx = test_build_maps(test, lot, "test_new_ctx", test_new_ctx,
+ ARRAY_LEN(test_new_ctx));
+ if (!new_ctx) {
+ res = -1;
+ goto fail_old_ctx;
+ }
+
+ ast_test_status_update(test, "Test removing dead parking spaces\n");
+ remove_dead_spaces_usage((void *) &dead_spaces, &old_ctx->spaces,
+ &new_ctx->spaces, test_add_dead_space);
+ if (check_spaces(test, &dead_spaces, "10-19,21,26,29,38,40-41", "dead_spaces")) {
+ res = -1;
+ goto fail_new_ctx;
+ }
+
+ res = 0;
+
+fail_new_ctx:
+ destroy_dialplan_usage_context(new_ctx);
+
+fail_old_ctx:
+ destroy_dialplan_usage_context(old_ctx);
+ ao2_ref(lot, -1);
+ return res;
+}
+#endif /* defined(TEST_FRAMEWORK) */
+
+#if defined(TEST_FRAMEWORK)
+static int fake_fixup(struct ast_channel *clonechan, struct ast_channel *original)
+{
+ return 0;
+}
+#endif /* defined(TEST_FRAMEWORK) */
+
+#if defined(TEST_FRAMEWORK)
+static struct ast_channel *create_test_channel(const struct ast_channel_tech *fake_tech)
+{
+ struct ast_channel *test_channel1;
+
+ if (!(test_channel1 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
+ NULL, NULL, 0, 0, "TestChannel1"))) {
+ ast_log(LOG_WARNING, "Whoa, test channel creation failed.\n");
+ return NULL;
+ }
+
+ /* normally this is done in the channel driver */
+ test_channel1->nativeformats = AST_FORMAT_GSM;
+ test_channel1->writeformat = AST_FORMAT_GSM;
+ test_channel1->rawwriteformat = AST_FORMAT_GSM;
+ test_channel1->readformat = AST_FORMAT_GSM;
+ test_channel1->rawreadformat = AST_FORMAT_GSM;
+ test_channel1->tech = fake_tech;
+
+ return test_channel1;
+}
+#endif /* defined(TEST_FRAMEWORK) */
+
+#if defined(TEST_FRAMEWORK)
+static int unpark_test_channel(struct ast_channel *toremove, struct ast_park_call_args *args)
+{
+ struct ast_context *con;
+ struct parkeduser *pu_toremove;
+ int res = 0;
+
+ args->pu->notquiteyet = 1; /* go ahead and stop processing the test parking */
+
+ AST_LIST_LOCK(&args->pu->parkinglot->parkings);
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&args->pu->parkinglot->parkings, pu_toremove, list) {
+ if (pu_toremove == args->pu) {
+ AST_LIST_REMOVE_CURRENT(list);
+ break;
+ }
+ }
+ AST_LIST_TRAVERSE_SAFE_END;
+ AST_LIST_UNLOCK(&args->pu->parkinglot->parkings);
+
+ if (!pu_toremove) {
+ ast_log(LOG_WARNING, "Whoa, could not find parking test call!\n");
+ return -1;
+ }
+
+ con = ast_context_find(args->pu->parkinglot->cfg.parking_con);
+ if (con) {
+ if (ast_context_remove_extension2(con, args->pu->parkingexten, 1, NULL, 0)) {
+ ast_log(LOG_WARNING, "Whoa, failed to remove the parking extension!\n");
+ res = -1;
+ } else {
+ notify_metermaids(args->pu->parkingexten,
+ pu_toremove->parkinglot->cfg.parking_con, AST_DEVICE_NOT_INUSE);
+ }
+ } else {
+ ast_log(LOG_WARNING, "Whoa, no parking context?\n");
+ res = -1;
+ }
+
+ parkinglot_unref(pu_toremove->parkinglot);
+ ast_free(pu_toremove);
+ args->pu = NULL;
+
+ if (!res && toremove) {
+ ast_hangup(toremove);
+ }
+ return res;
+}
+#endif /* defined(TEST_FRAMEWORK) */
+
+#if defined(TEST_FRAMEWORK)
+AST_TEST_DEFINE(features_test)
+{
+ struct ast_channel *test_channel1 = NULL;
+ struct ast_channel *parked_chan = NULL;
+ struct ast_parkinglot *dynlot;
+ struct ast_park_call_args args = {
+ .timeout = DEFAULT_PARK_TIME,
+ };
+
+ int res = 0;
+
+ static const struct ast_channel_tech fake_tech = {
+ .fixup = fake_fixup, /* silence warning from masquerade */
+ };
+
+ static const char unique_parkinglot[] = "myuniquetestparkinglot3141592654";
+ static const char parkinglot_range[] = "750-760";
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "features_test";
+ info->category = "/main/features/";
+ info->summary = "Features unit test";
+ info->description =
+ "Tests whether parking respects PARKINGLOT settings";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ if (test_dialplan_usage_map(test)) {
+ res = -1;
+ goto exit_features_test;
+ }
+
+ /* changing a config option is a bad practice, but must be done in this case */
+ parkeddynamic = 1;
+
+ ast_test_status_update(test, "Test parking functionality with defaults\n");
+ if (!(test_channel1 = create_test_channel(&fake_tech))) {
+ res = -1;
+ goto exit_features_test;
+ }
+ if (park_call_full(test_channel1, NULL, &args)) {
+ res = -1;
+ goto exit_features_test;
+ }
+ if (unpark_test_channel(test_channel1, &args)) {
+ res = -1;
+ goto exit_features_test;
+ }
+
+
+ ast_test_status_update(test, "Check that certain parking options are respected\n");
+ if (!(test_channel1 = create_test_channel(&fake_tech))) {
+ res = -1;
+ goto exit_features_test;
+ }
+ pbx_builtin_setvar_helper(test_channel1, "PARKINGLOT", unique_parkinglot);
+ pbx_builtin_setvar_helper(test_channel1, "PARKINGDYNPOS", parkinglot_range);
+ if (park_call_full(test_channel1, NULL, &args)) {
+ res = -1;
+ goto exit_features_test;
+ }
+ /* grab newly created parking lot for destruction in the end */
+ dynlot = args.pu->parkinglot;
+ if (args.pu->parkingnum != 750
+ || strcasecmp(dynlot->name, unique_parkinglot)
+ || dynlot->cfg.parking_start != 750
+ || dynlot->cfg.parking_stop != 760) {
+ ast_test_status_update(test, "Parking settings were not respected\n");
+ if (!unpark_test_channel(test_channel1, &args)) {
+ test_channel1 = NULL;
+ }
+ res = -1;
+ goto exit_features_test;
+ } else {
+ ast_test_status_update(test, "Parking settings for non-masquerading park verified\n");
+ }
+ if (unpark_test_channel(test_channel1, &args)) {
+ res = -1;
+ goto exit_features_test;
+ }
+
+
+ ast_test_status_update(test, "Check #2 that certain parking options are respected\n");
+ if (!(test_channel1 = create_test_channel(&fake_tech))) {
+ res = -1;
+ goto exit_features_test;
+ }
+ pbx_builtin_setvar_helper(test_channel1, "PARKINGLOT", unique_parkinglot);
+ pbx_builtin_setvar_helper(test_channel1, "PARKINGDYNPOS", parkinglot_range);
+ if (masq_park_call(test_channel1, NULL, 0, NULL, 0, &args)) {
+ res = -1;
+ goto exit_features_test;
+ }
+ /* hangup zombie channel */
+ ast_hangup(test_channel1);
+ test_channel1 = NULL;
+
+ dynlot = args.pu->parkinglot;
+ if (args.pu->parkingnum != 750
+ || strcasecmp(dynlot->name, unique_parkinglot)
+ || dynlot->cfg.parking_start != 750
+ || dynlot->cfg.parking_stop != 760) {
+ ast_test_status_update(test, "Parking settings were not respected\n");
+ res = -1;
+ } else {
+ ast_test_status_update(test, "Parking settings for masquerading park verified\n");
+ }
+
+ /* find the real channel */
+ parked_chan = ast_channel_get_by_name("TestChannel1");
+ if (unpark_test_channel(parked_chan, &args)) {
+ if (parked_chan) {
+ ast_hangup(parked_chan);
+ }
+ res = -1;
+ }
+
+
+exit_features_test:
+
+ if (test_channel1) {
+ ast_hangup(test_channel1);
+ }
+
+ force_reload_load = 1;
+ ast_features_reload();
+ return res ? AST_TEST_FAIL : AST_TEST_PASS;
+}
+#endif /* defined(TEST_FRAMEWORK) */
+
int ast_features_init(void)
{
int res;
@@ -7138,9 +7385,9 @@
}
res |= ast_devstate_prov_add("Park", metermaidstate);
-#ifdef TEST_FRAMEWORK
+#if defined(TEST_FRAMEWORK)
res |= AST_TEST_REGISTER(features_test);
-#endif
+#endif /* defined(TEST_FRAMEWORK) */
return res;
}
More information about the asterisk-commits
mailing list