summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorDavid M. Lee <dlee@digium.com>2013-04-08 13:27:45 +0000
committerDavid M. Lee <dlee@digium.com>2013-04-08 13:27:45 +0000
commita2a53cc306ea5fec65daf3630716a7c6ee13adad (patch)
tree4e59f10e2c6ab044ac307466bf921bbf1ceca7d3 /tests
parent426095bc5503391eabb3e5ce0fbbfec8b4752f2d (diff)
Stasis application WebSocket support
This is the API that binds the Stasis dialplan application to external Stasis applications. It also adds the beginnings of WebSocket application support. This module registers a dialplan function named Stasis, which is used to put a channel into the named Stasis app. As a channel enters and leaves the Stasis diaplan application, the Stasis app receives a 'stasis-start' and 'stasis-end' events. Stasis apps register themselves using the stasis_app_register and stasis_app_unregister functions. Messages are sent to an application using stasis_app_send. Finally, Stasis apps control channels through the use of the stasis_app_control object, and the family of stasis_app_control_* functions. Other changes along for the ride are: * An ast_frame_dtor function that's RAII_VAR safe * Some common JSON encoders for name/number, timeval, and context/extension/priority Review: https://reviewboard.asterisk.org/r/2361/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@384879 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'tests')
-rw-r--r--tests/test_abstract_jb.c25
-rw-r--r--tests/test_app_stasis.c194
-rw-r--r--tests/test_json.c102
3 files changed, 303 insertions, 18 deletions
diff --git a/tests/test_abstract_jb.c b/tests/test_abstract_jb.c
index f39b0b03b..17861e6bc 100644
--- a/tests/test_abstract_jb.c
+++ b/tests/test_abstract_jb.c
@@ -67,17 +67,6 @@ static void dispose_jitterbuffer(struct ast_jb *jb)
jb->jbobj = NULL;
}
-/*! \internal \brief Destructor for frames
- * \param f The frame to destroy
- */
-static void dispose_frame(struct ast_frame *f)
-{
- if (!f) {
- return;
- }
- ast_frfree(f);
-}
-
/*! \internal \brief Create a test frame
* \param timestamp the time in ms of the frame
* \param seqno the frame's sequence number
@@ -217,8 +206,8 @@ static struct ast_jb default_jb = {
RAII_VAR(struct ast_jb *, jb, &default_jb, dispose_jitterbuffer); \
const struct ast_jb_impl *impl; \
struct ast_jb_conf conf; \
- RAII_VAR(struct ast_frame *, expected_frame, NULL, dispose_frame); \
- RAII_VAR(struct ast_frame *, actual_frame, NULL, dispose_frame); \
+ RAII_VAR(struct ast_frame *, expected_frame, NULL, ast_frame_dtor); \
+ RAII_VAR(struct ast_frame *, actual_frame, NULL, ast_frame_dtor); \
int res; \
\
switch (cmd) { \
@@ -273,8 +262,8 @@ static struct ast_jb default_jb = {
RAII_VAR(struct ast_jb *, jb, &default_jb, dispose_jitterbuffer); \
const struct ast_jb_impl *impl; \
struct ast_jb_conf conf; \
- RAII_VAR(struct ast_frame *, expected_frame, NULL, dispose_frame); \
- RAII_VAR(struct ast_frame *, actual_frame, NULL, dispose_frame); \
+ RAII_VAR(struct ast_frame *, expected_frame, NULL, ast_frame_dtor); \
+ RAII_VAR(struct ast_frame *, actual_frame, NULL, ast_frame_dtor); \
int res; \
long next; \
int i; \
@@ -336,7 +325,7 @@ static struct ast_jb default_jb = {
RAII_VAR(struct ast_jb *, jb, &default_jb, dispose_jitterbuffer); \
const struct ast_jb_impl *impl; \
struct ast_jb_conf conf; \
- RAII_VAR(struct ast_frame *, expected_frame, NULL, dispose_frame); \
+ RAII_VAR(struct ast_frame *, expected_frame, NULL, ast_frame_dtor); \
int res; \
int i; \
\
@@ -401,8 +390,8 @@ static struct ast_jb default_jb = {
RAII_VAR(struct ast_jb *, jb, &default_jb, dispose_jitterbuffer); \
const struct ast_jb_impl *impl; \
struct ast_jb_conf conf; \
- RAII_VAR(struct ast_frame *, actual_frame, NULL, dispose_frame); \
- RAII_VAR(struct ast_frame *, expected_frame, NULL, dispose_frame); \
+ RAII_VAR(struct ast_frame *, actual_frame, NULL, ast_frame_dtor); \
+ RAII_VAR(struct ast_frame *, expected_frame, NULL, ast_frame_dtor); \
int res; \
long next; \
int i; \
diff --git a/tests/test_app_stasis.c b/tests/test_app_stasis.c
new file mode 100644
index 000000000..02eb85af0
--- /dev/null
+++ b/tests/test_app_stasis.c
@@ -0,0 +1,194 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * David M. Lee, II <dlee@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file \brief Test Stasis Application API.
+ * \author\verbatim David M. Lee, II <dlee@digium.com> \endverbatim
+ *
+ * \ingroup tests
+ */
+
+/*** MODULEINFO
+ <depend>TEST_FRAMEWORK</depend>
+ <depend>app_stasis</depend>
+ <support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/module.h"
+#include "asterisk/test.h"
+#include "asterisk/app_stasis.h"
+
+static const char *test_category = "/stasis/app/";
+
+AST_TEST_DEFINE(app_invoke_dne)
+{
+ int res;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = __func__;
+ info->category = test_category;
+ info->summary = "Test stasis app invocation.";
+ info->description = "Test stasis app invocation.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ res = stasis_app_send("i-am-not-an-app", ast_json_null());
+ ast_test_validate(test, -1 == res);
+
+ return AST_TEST_PASS;
+}
+
+struct app_data {
+ int invocations;
+ struct ast_json *messages;
+};
+
+static void app_data_dtor(void *obj)
+{
+ struct app_data *actual = obj;
+
+ ast_json_unref(actual->messages);
+ actual->messages = NULL;
+}
+
+static struct app_data *app_data_create(void)
+{
+ struct app_data *res = ao2_alloc(sizeof(struct app_data), app_data_dtor);
+
+ if (!res) {
+ return NULL;
+ }
+
+ res->messages = ast_json_array_create();
+ return res;
+}
+
+static void test_handler(void *data, const char *app_name, struct ast_json *message)
+{
+ struct app_data *actual = data;
+ int res;
+ ++(actual->invocations);
+ res = ast_json_array_append(actual->messages, ast_json_copy(message));
+ ast_assert(res == 0);
+}
+
+AST_TEST_DEFINE(app_invoke_one)
+{
+ RAII_VAR(struct app_data *, app_data, NULL, ao2_cleanup);
+ RAII_VAR(char *, app_name, NULL, stasis_app_unregister);
+ RAII_VAR(struct ast_json *, expected_message, NULL, ast_json_unref);
+ RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+ int res;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = __func__;
+ info->category = test_category;
+ info->summary = "Test stasis app invocation.";
+ info->description = "Test stasis app invocation.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ app_name = "test-handler";
+
+ app_data = app_data_create();
+
+ stasis_app_register(app_name, test_handler, app_data);
+ message = ast_json_pack("{ s: o }", "test-message", ast_json_null());
+ expected_message = ast_json_pack("[o]", ast_json_ref(message));
+
+ res = stasis_app_send(app_name, message);
+ ast_test_validate(test, 0 == res);
+ ast_test_validate(test, 1 == app_data->invocations);
+ ast_test_validate(test, ast_json_equal(expected_message, app_data->messages));
+
+ return AST_TEST_PASS;
+}
+
+AST_TEST_DEFINE(app_replaced)
+{
+ RAII_VAR(struct app_data *, app_data1, NULL, ao2_cleanup);
+ RAII_VAR(struct app_data *, app_data2, NULL, ao2_cleanup);
+ RAII_VAR(char *, app_name, NULL, stasis_app_unregister);
+ RAII_VAR(struct ast_json *, expected_message1, NULL, ast_json_unref);
+ RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+ RAII_VAR(struct ast_json *, expected_message2, NULL, ast_json_unref);
+ int res;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = __func__;
+ info->category = test_category;
+ info->summary = "Test stasis app invocation.";
+ info->description = "Test stasis app invocation.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ app_name = "test-handler";
+
+ app_data1 = app_data_create();
+ app_data2 = app_data_create();
+
+ stasis_app_register(app_name, test_handler, app_data1);
+ stasis_app_register(app_name, test_handler, app_data2);
+ expected_message1 = ast_json_pack("[{s: {}}]", "application-replaced");
+ message = ast_json_pack("{ s: o }", "test-message", ast_json_null());
+ expected_message2 = ast_json_pack("[o]", ast_json_ref(message));
+
+ res = stasis_app_send(app_name, message);
+ ast_test_validate(test, 0 == res);
+ ast_test_validate(test, 1 == app_data1->invocations);
+ ast_test_validate(test, ast_json_equal(expected_message1, app_data1->messages));
+ ast_test_validate(test, 1 == app_data2->invocations);
+ ast_test_validate(test, ast_json_equal(expected_message2, app_data2->messages));
+
+ return AST_TEST_PASS;
+}
+
+static int unload_module(void)
+{
+ AST_TEST_UNREGISTER(app_invoke_dne);
+ AST_TEST_UNREGISTER(app_invoke_one);
+ AST_TEST_UNREGISTER(app_replaced);
+ return 0;
+}
+
+static int load_module(void)
+{
+ AST_TEST_REGISTER(app_replaced);
+ AST_TEST_REGISTER(app_invoke_one);
+ AST_TEST_REGISTER(app_invoke_dne);
+ return AST_MODULE_LOAD_SUCCESS;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, 0, "Stasis Core testing",
+ .load = load_module,
+ .unload = unload_module,
+ .nonoptreq = "app_stasis"
+ );
diff --git a/tests/test_json.c b/tests/test_json.c
index 603867279..9b4be5beb 100644
--- a/tests/test_json.c
+++ b/tests/test_json.c
@@ -1611,6 +1611,102 @@ AST_TEST_DEFINE(json_test_clever_circle)
return AST_TEST_PASS;
}
+AST_TEST_DEFINE(json_test_name_number)
+{
+ RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
+ RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
+ RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "name_number";
+ info->category = "/main/json/";
+ info->summary = "JSON encoding of name/number pair.";
+ info->description = "Test JSON abstraction library.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ ast_test_validate(test, NULL == ast_json_name_number("name", NULL));
+ ast_test_validate(test, NULL == ast_json_name_number(NULL, "1234"));
+ ast_test_validate(test, NULL == ast_json_name_number(NULL, NULL));
+
+ expected = ast_json_pack("{s: s, s: s}",
+ "name", "Jenny",
+ "number", "867-5309");
+ uut = ast_json_name_number("Jenny", "867-5309");
+ ast_test_validate(test, ast_json_equal(expected, uut));
+
+ return AST_TEST_PASS;
+}
+
+AST_TEST_DEFINE(json_test_timeval)
+{
+ RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
+ RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
+ RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
+ struct timeval tv = {};
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "timeval";
+ info->category = "/main/json/";
+ info->summary = "JSON encoding of timevals.";
+ info->description = "Test JSON abstraction library.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ ast_test_validate(test, NULL == ast_json_timeval(NULL, NULL));
+ expected = ast_json_string_create("2013-02-07T09:32:34.314-0600");
+
+ tv.tv_sec = 1360251154;
+ tv.tv_usec = 314159;
+ uut = ast_json_timeval(&tv, "America/Chicago");
+
+ ast_test_validate(test, ast_json_equal(expected, uut));
+
+ return AST_TEST_PASS;
+}
+
+AST_TEST_DEFINE(json_test_cep)
+{
+ RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
+ RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
+ RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "cep";
+ info->category = "/main/json/";
+ info->summary = "JSON with circular references cannot be encoded.";
+ info->description = "Test JSON abstraction library.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ expected = ast_json_pack("{s: o, s: o, s: o}",
+ "context", ast_json_null(),
+ "exten", ast_json_null(),
+ "priority", ast_json_null());
+ uut = ast_json_dialplan_cep(NULL, NULL, -1);
+ ast_test_validate(test, ast_json_equal(expected, uut));
+
+ ast_json_unref(expected);
+ ast_json_unref(uut);
+ expected = ast_json_pack("{s: s, s: s, s: i}",
+ "context", "main",
+ "exten", "4321",
+ "priority", 7);
+ uut = ast_json_dialplan_cep("main", "4321", 7);
+ ast_test_validate(test, ast_json_equal(expected, uut));
+
+ return AST_TEST_PASS;
+}
+
static int unload_module(void)
{
AST_TEST_UNREGISTER(json_test_false);
@@ -1661,6 +1757,9 @@ static int unload_module(void)
AST_TEST_UNREGISTER(json_test_circular_object);
AST_TEST_UNREGISTER(json_test_circular_array);
AST_TEST_UNREGISTER(json_test_clever_circle);
+ AST_TEST_UNREGISTER(json_test_name_number);
+ AST_TEST_UNREGISTER(json_test_timeval);
+ AST_TEST_UNREGISTER(json_test_cep);
return 0;
}
@@ -1714,6 +1813,9 @@ static int load_module(void)
AST_TEST_REGISTER(json_test_circular_object);
AST_TEST_REGISTER(json_test_circular_array);
AST_TEST_REGISTER(json_test_clever_circle);
+ AST_TEST_REGISTER(json_test_name_number);
+ AST_TEST_REGISTER(json_test_timeval);
+ AST_TEST_REGISTER(json_test_cep);
return AST_MODULE_LOAD_SUCCESS;
}