summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAlfred E. Heggestad <aeh@db.org>2015-10-29 19:57:40 +0100
committerAlfred E. Heggestad <aeh@db.org>2015-10-29 19:57:40 +0100
commit664a6cd61f873db3a9e8c3a7faaaf4116fef6328 (patch)
tree1b884b8bde99f5a761939456a8e0c601113ff687 /test
parentda8cf2621a3e1a04b3bcb10f82d5a70393ecd1d6 (diff)
test: added 2 call tests
Diffstat (limited to 'test')
-rw-r--r--test/call.c236
-rw-r--r--test/main.c2
-rw-r--r--test/srcs.mk1
-rw-r--r--test/test.h3
4 files changed, 242 insertions, 0 deletions
diff --git a/test/call.c b/test/call.c
new file mode 100644
index 0000000..cad90a6
--- /dev/null
+++ b/test/call.c
@@ -0,0 +1,236 @@
+/**
+ * @file test/call.c Baresip selftest -- call
+ *
+ * Copyright (C) 2010 - 2015 Creytiv.com
+ */
+#include <string.h>
+#include <re.h>
+#include <baresip.h>
+#include "test.h"
+
+
+#define MAGIC 0x7004ca11
+
+
+enum behaviour {
+ BEHAVIOUR_ANSWER = 0,
+ BEHAVIOUR_REJECT
+};
+
+struct agent {
+ struct agent *peer;
+ struct ua *ua;
+ uint16_t close_scode;
+ bool failed;
+
+ unsigned n_incoming;
+ unsigned n_established;
+ unsigned n_closed;
+};
+
+struct fixture {
+ uint32_t magic;
+ struct agent a, b;
+ struct sa laddr_sip;
+ enum behaviour behaviour;
+ char buri[256];
+ int err;
+};
+
+
+#define fixture_init(f) \
+ memset(f, 0, sizeof(*f)); \
+ \
+ f->magic = MAGIC; \
+ aucodec_register(&dummy_pcma); \
+ \
+ err = ua_alloc(&f->a.ua, "A <sip:a:xxx@127.0.0.1>;regint=0"); \
+ TEST_ERR(err); \
+ err = ua_alloc(&f->b.ua, "B <sip:b:xxx@127.0.0.1>;regint=0"); \
+ TEST_ERR(err); \
+ \
+ f->a.peer = &f->b; \
+ f->b.peer = &f->a; \
+ \
+ err = uag_event_register(event_handler, f); \
+ TEST_ERR(err); \
+ \
+ err = sip_transp_laddr(uag_sip(), &f->laddr_sip, \
+ SIP_TRANSP_UDP, NULL); \
+ TEST_ERR(err); \
+ \
+ re_snprintf(f->buri, sizeof(f->buri), "sip:b@%J", &f->laddr_sip);
+
+
+#define fixture_close(f) \
+ mem_deref(f->b.ua); \
+ mem_deref(f->a.ua); \
+ \
+ aucodec_unregister(&dummy_pcma); \
+ \
+ uag_event_unregister(event_handler)
+
+
+static struct aucodec dummy_pcma = {
+ .pt = "8",
+ .name = "PCMA",
+ .srate = 8000,
+ .ch = 1,
+};
+
+
+static void event_handler(struct ua *ua, enum ua_event ev,
+ struct call *call, const char *prm, void *arg)
+{
+ struct fixture *f = arg;
+ struct agent *ag;
+ int err = 0;
+
+ ASSERT_TRUE(ua != NULL);
+ ASSERT_TRUE(call != NULL);
+ ASSERT_TRUE(f != NULL);
+ ASSERT_EQ(MAGIC, f->magic);
+
+ if (ua == f->a.ua)
+ ag = &f->a;
+ else if (ua == f->b.ua)
+ ag = &f->b;
+ else {
+ warning("ua not found\n");
+ return;
+ }
+
+#if 0
+ re_printf("[ %s ] event: %s (%s)\n",
+ ua_aor(ua), uag_event_str(ev), prm);
+#endif
+
+ switch (ev) {
+
+ case UA_EVENT_CALL_INCOMING:
+ ++ag->n_incoming;
+
+ switch (f->behaviour) {
+
+ case BEHAVIOUR_ANSWER:
+ err = ua_answer(ua, call);
+ if (err) {
+ warning("ua_answer failed (%m)\n", err);
+ goto out;
+ }
+ break;
+
+ case BEHAVIOUR_REJECT:
+ ua_hangup(ua, call, 0, 0);
+ call = NULL;
+ ag->failed = true;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case UA_EVENT_CALL_ESTABLISHED:
+ ++ag->n_established;
+
+ if (ag->peer->n_established) {
+ re_printf("@@@ test complete\n");
+ re_cancel();
+ }
+ break;
+
+ case UA_EVENT_CALL_CLOSED:
+ ag->failed = true;
+ ++ag->n_closed;
+
+ ag->close_scode = call_scode(call);
+
+ if (ag->peer->n_closed) {
+ re_printf("@@@ test complete\n");
+ re_cancel();
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (ag->failed && ag->peer->failed) {
+ re_cancel();
+ return;
+ }
+
+ out:
+ if (err) {
+ warning("error in event-handler (%m)\n", err);
+ f->err = err;
+ re_cancel();
+ }
+}
+
+
+int test_call_answer(void)
+{
+ struct fixture fix, *f = &fix;
+ int err = 0;
+
+ fixture_init(f);
+
+ f->behaviour = BEHAVIOUR_ANSWER;
+
+ /* Make a call from A to B */
+ err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF);
+ TEST_ERR(err);
+
+ /* run main-loop with timeout, wait for events */
+ err = re_main_timeout(5);
+ TEST_ERR(err);
+ TEST_ERR(fix.err);
+
+ ASSERT_EQ(0, fix.a.n_incoming);
+ ASSERT_EQ(1, fix.a.n_established);
+ ASSERT_EQ(0, fix.a.n_closed);
+ ASSERT_EQ(0, fix.a.close_scode);
+
+ ASSERT_EQ(1, fix.b.n_incoming);
+ ASSERT_EQ(1, fix.b.n_established);
+ ASSERT_EQ(0, fix.b.n_closed);
+
+ out:
+ fixture_close(f);
+
+ return err;
+}
+
+
+int test_call_reject(void)
+{
+ struct fixture fix, *f = &fix;
+ int err = 0;
+
+ fixture_init(f);
+
+ f->behaviour = BEHAVIOUR_REJECT;
+
+ /* Make a call from A to B */
+ err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF);
+ TEST_ERR(err);
+
+ /* run main-loop with timeout, wait for events */
+ err = re_main_timeout(5);
+ TEST_ERR(err);
+ TEST_ERR(fix.err);
+
+ ASSERT_EQ(0, fix.a.n_incoming);
+ ASSERT_EQ(0, fix.a.n_established);
+ ASSERT_EQ(1, fix.a.n_closed);
+
+ ASSERT_EQ(1, fix.b.n_incoming);
+ ASSERT_EQ(0, fix.b.n_established);
+
+ out:
+ fixture_close(f);
+
+ return err;
+}
diff --git a/test/main.c b/test/main.c
index f10293a..a959a5e 100644
--- a/test/main.c
+++ b/test/main.c
@@ -23,6 +23,8 @@ static const struct test tests[] = {
TEST(test_uag_find_param),
TEST(test_ua_register),
TEST(test_cplusplus),
+ TEST(test_call_answer),
+ TEST(test_call_reject),
};
diff --git a/test/srcs.mk b/test/srcs.mk
index 1caafbb..6195d10 100644
--- a/test/srcs.mk
+++ b/test/srcs.mk
@@ -11,6 +11,7 @@
TEST_SRCS += cmd.c
TEST_SRCS += ua.c
TEST_SRCS += cplusplus.c
+TEST_SRCS += call.c
#
diff --git a/test/test.h b/test/test.h
index 61ddd27..2600bd6 100644
--- a/test/test.h
+++ b/test/test.h
@@ -79,6 +79,9 @@ int test_ua_alloc(void);
int test_uag_find_param(void);
int test_ua_register(void);
+int test_call_answer(void);
+int test_call_reject(void);
+
#ifdef __cplusplus
extern "C" {