From 0535a3244acc2a6c096703090b467e60e630cf60 Mon Sep 17 00:00:00 2001 From: "Alfred E. Heggestad" Date: Sun, 9 Aug 2015 15:28:08 +0200 Subject: selftest: new binary - move selftest code from module/selftest to test/. - create a new binary called 'selftest' - the selftest is testing the Baresip Core only --- .gitignore | 1 + Makefile | 30 ++++++-- mk/modules.mk | 1 - modules/selftest/cmd.c | 77 --------------------- modules/selftest/module.mk | 11 --- modules/selftest/selftest.c | 75 -------------------- modules/selftest/selftest.h | 58 ---------------- modules/selftest/sip_server.c | 97 -------------------------- modules/selftest/ua.c | 154 ----------------------------------------- src/main.c | 4 +- test/cmd.c | 77 +++++++++++++++++++++ test/main.c | 86 +++++++++++++++++++++++ test/sip_server.c | 113 ++++++++++++++++++++++++++++++ test/srcs.mk | 13 ++++ test/test.c | 30 ++++++++ test/test.h | 58 ++++++++++++++++ test/ua.c | 156 ++++++++++++++++++++++++++++++++++++++++++ 17 files changed, 562 insertions(+), 479 deletions(-) delete mode 100644 modules/selftest/cmd.c delete mode 100644 modules/selftest/module.mk delete mode 100644 modules/selftest/selftest.c delete mode 100644 modules/selftest/selftest.h delete mode 100644 modules/selftest/sip_server.c delete mode 100644 modules/selftest/ua.c create mode 100644 test/cmd.c create mode 100644 test/main.c create mode 100644 test/sip_server.c create mode 100644 test/srcs.mk create mode 100644 test/test.c create mode 100644 test/test.h create mode 100644 test/ua.c diff --git a/.gitignore b/.gitignore index 9500e37..1b037f2 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ *.out *.app baresip +selftest # Generated files src/static.c diff --git a/Makefile b/Makefile index e3401db..39ca7f6 100644 --- a/Makefile +++ b/Makefile @@ -84,12 +84,14 @@ endif BINDIR := $(PREFIX)/bin INCDIR := $(PREFIX)/include BIN := $(PROJECT)$(BIN_SUFFIX) +TEST_BIN := selftest$(BIN_SUFFIX) SHARED := lib$(PROJECT)$(LIB_SUFFIX) STATICLIB := libbaresip.a ifeq ($(STATIC),) MOD_BINS:= $(patsubst %,%$(MOD_SUFFIX),$(MODULES)) endif APP_MK := src/srcs.mk +TEST_MK := test/srcs.mk MOD_MK := $(patsubst %,modules/%/module.mk,$(MODULES)) MOD_BLD := $(patsubst %,$(BUILD)/modules/%,$(MODULES)) LIBDIR := $(PREFIX)/lib @@ -104,6 +106,7 @@ all: sanity $(MOD_BINS) $(BIN) modules: $(MOD_BINS) include $(APP_MK) +include $(TEST_MK) include $(MOD_MK) OBJS := $(patsubst %.c,$(BUILD)/src/%.o,$(filter %.c,$(SRCS))) @@ -112,6 +115,10 @@ OBJS += $(patsubst %.S,$(BUILD)/src/%.o,$(filter %.S,$(SRCS))) APP_OBJS := $(OBJS) $(patsubst %.c,$(BUILD)/src/%.o,$(APP_SRCS)) $(MOD_OBJS) +LIB_OBJS := $(OBJS) $(MOD_OBJS) + +TEST_OBJS := $(patsubst %.c,$(BUILD)/test/%.o,$(filter %.c,$(TEST_SRCS))) + ifneq ($(LIBREM_PATH),) LIBS += -L$(LIBREM_PATH) endif @@ -129,6 +136,9 @@ LIBS += -L$(SYSROOT)/lib -include $(APP_OBJS:.o=.d) +-include $(TEST_OBJS:.o=.d) + + sanity: ifeq ($(LIBRE_MK),) @echo "ERROR: Missing common makefile for libre. Check LIBRE_MK" @@ -146,11 +156,11 @@ endif Makefile: mk/*.mk $(MOD_MK) $(LIBRE_MK) -$(SHARED): $(APP_OBJS) +$(SHARED): $(LIB_OBJS) @echo " LD $@" @$(LD) $(LFLAGS) $(SH_LFLAGS) $^ -L$(LIBRE_SO) -lre $(LIBS) -o $@ -$(STATICLIB): $(APP_OBJS) +$(STATICLIB): $(LIB_OBJS) @echo " AR $@" @rm -f $@; $(AR) $(AFLAGS) $@ $^ ifneq ($(RANLIB),) @@ -167,6 +177,16 @@ else @$(LD) $(LFLAGS) $(APP_LFLAGS) $^ -L$(LIBRE_SO) -lre $(LIBS) -o $@ endif + +.PHONY: test +test: $(TEST_BIN) + +$(TEST_BIN): $(STATICLIB) $(TEST_OBJS) + @echo " LD $@" + @$(LD) $(LFLAGS) $(TEST_OBJS) \ + -L$(LIBRE_SO) -L. \ + -l$(PROJECT) -lre $(LIBS) -o $@ + $(BUILD)/%.o: %.c $(BUILD) Makefile $(APP_MK) @echo " CC $@" @$(CC) $(CFLAGS) -c $< -o $@ $(DFLAGS) @@ -180,7 +200,7 @@ $(BUILD)/%.o: %.S $(BUILD) Makefile $(APP_MK) @$(CC) $(CFLAGS) -c $< -o $@ $(DFLAGS) $(BUILD): Makefile - @mkdir -p $(BUILD)/src $(MOD_BLD) + @mkdir -p $(BUILD)/src $(MOD_BLD) $(BUILD)/test @touch $@ install: $(BIN) $(MOD_BINS) @@ -208,10 +228,12 @@ install-static: $(STATICLIB) uninstall: @rm -f $(DESTDIR)$(PREFIX)/bin/$(BIN) @rm -rf $(DESTDIR)$(MOD_PATH) + @rm -f $(DESTDIR)$(PREFIX)/lib/$(SHARED) + @rm -f $(DESTDIR)$(PREFIX)/lib/$(STATICLIB) .PHONY: clean clean: - @rm -rf $(BIN) $(MOD_BINS) $(SHARED) $(BUILD) + @rm -rf $(BIN) $(MOD_BINS) $(SHARED) $(BUILD) $(TEST_BIN) @rm -f *stamp \ `find . -name "*.[od]"` \ `find . -name "*~"` \ diff --git a/mk/modules.mk b/mk/modules.mk index dc93491..085a8c5 100644 --- a/mk/modules.mk +++ b/mk/modules.mk @@ -232,7 +232,6 @@ endif MODULES += $(EXTRA_MODULES) MODULES += stun turn ice natbd auloop presence MODULES += menu contact vumeter mwi account natpmp httpd -MODULES += selftest MODULES += srtp MODULES += uuid diff --git a/modules/selftest/cmd.c b/modules/selftest/cmd.c deleted file mode 100644 index a0e5e2c..0000000 --- a/modules/selftest/cmd.c +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file selftest/cmd.c Baresip selftest -- cmd - * - * Copyright (C) 2010 Creytiv.com - */ -#include -#include -#include "selftest.h" - - -static bool cmd_called; - - -static int cmd_test(struct re_printf *pf, void *arg) -{ - struct cmd_arg *carg = arg; - int err = 0; - (void)pf; - - ASSERT_EQ(false, cmd_called); - - ASSERT_EQ('@', carg->key); - ASSERT_TRUE(NULL == carg->prm); - ASSERT_EQ(true, carg->complete); - - cmd_called = true; - - out: - return err; -} - - -static const struct cmd cmdv[] = { - {'@', 0, "Test command", cmd_test}, -}; - - -static int vprintf_null(const char *p, size_t size, void *arg) -{ - (void)p; - (void)size; - (void)arg; - return 0; -} - - -static struct re_printf pf_null = {vprintf_null, 0}; - - -int test_cmd(void) -{ - struct cmd_ctx *ctx = 0; - int err = 0; - - cmd_called = false; - - err = cmd_register(cmdv, ARRAY_SIZE(cmdv)); - ASSERT_EQ(0, err); - - /* issue a different command */ - err = cmd_process(&ctx, 'h', &pf_null); - ASSERT_EQ(0, err); - ASSERT_EQ(false, cmd_called); - - /* issue our command, expect handler to be called */ - err = cmd_process(&ctx, '@', &pf_null); - ASSERT_EQ(0, err); - ASSERT_EQ(true, cmd_called); - - cmd_unregister(cmdv); - - /* verify that context was not created */ - ASSERT_TRUE(NULL == ctx); - - out: - return err; -} diff --git a/modules/selftest/module.mk b/modules/selftest/module.mk deleted file mode 100644 index d47f2fe..0000000 --- a/modules/selftest/module.mk +++ /dev/null @@ -1,11 +0,0 @@ -# -# module.mk -# -# Copyright (C) 2010 Creytiv.com -# - -MOD := selftest -$(MOD)_SRCS += selftest.c cmd.c ua.c -$(MOD)_SRCS += sip_server.c - -include mk/mod.mk diff --git a/modules/selftest/selftest.c b/modules/selftest/selftest.c deleted file mode 100644 index 87e89d3..0000000 --- a/modules/selftest/selftest.c +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @file selftest.c Selftest for Baresip core - * - * Copyright (C) 2010 Creytiv.com - */ -#include -#include -#include "selftest.h" - - -static void timeout_handler(void *arg) -{ - int *err = arg; - - warning("selftest: re_main() loop timed out -- test hung..\n"); - - *err = ETIMEDOUT; - - re_cancel(); -} - - -int re_main_timeout(uint32_t timeout) -{ - struct tmr tmr; - int err = 0; - - tmr_init(&tmr); - - tmr_start(&tmr, timeout * 1000, timeout_handler, &err); - re_main(NULL); - - tmr_cancel(&tmr); - return err; -} - - -static int module_init(void) -{ - int err; - - err = test_cmd(); - if (err) - return err; - - err = test_ua_alloc(); - if (err) - return err; - - err = test_uag_find_param(); - if (err) - return err; - - err = test_ua_register(); - if (err) - return err; - - re_printf("\x1b[32mselftest passed successfully\x1b[;m\n"); - - return 0; -} - - -static int module_close(void) -{ - return 0; -} - - -const struct mod_export DECL_EXPORTS(selftest) = { - "selftest", - "application", - module_init, - module_close -}; diff --git a/modules/selftest/selftest.h b/modules/selftest/selftest.h deleted file mode 100644 index f460b3f..0000000 --- a/modules/selftest/selftest.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file selftest.h Selftest for Baresip core -- internal API - * - * Copyright (C) 2010 Creytiv.com - */ - - -#define ASSERT_TRUE(cond) \ - if (!(cond)) { \ - warning("selftest: ASSERT_TRUE: %s:%u:\n", \ - __FILE__, __LINE__); \ - err = EINVAL; \ - goto out; \ - } - -#define ASSERT_EQ(expected, actual) \ - if ((expected) != (actual)) { \ - warning("selftest: ASSERT_EQ: %s:%u:" \ - " expected=%d, actual=%d\n", \ - __FILE__, __LINE__, \ - (int)(expected), (int)(actual)); \ - err = EINVAL; \ - goto out; \ - } - -#define ASSERT_STREQ(expected, actual) \ - if (0 != str_cmp((expected), (actual))) { \ - warning("selftest: ASSERT_STREQ: %s:%u:" \ - " expected = '%s', actual = '%s'\n", \ - __FILE__, __LINE__, \ - (expected), (actual)); \ - err = EBADMSG; \ - goto out; \ - } - - -/* helpers */ - -int re_main_timeout(uint32_t timeout); - -struct sip_server { - struct sa laddr; - struct udp_sock *us; - struct sip *sip; - - bool got_register_req; - bool terminate; -}; - -int sip_server_create(struct sip_server **srvp); - - -/* test cases */ - -int test_cmd(void); -int test_ua_alloc(void); -int test_uag_find_param(void); -int test_ua_register(void); diff --git a/modules/selftest/sip_server.c b/modules/selftest/sip_server.c deleted file mode 100644 index 1962c3c..0000000 --- a/modules/selftest/sip_server.c +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file sip_server.c Selftest for Baresip core -- SIP Server - * - * Copyright (C) 2010 Creytiv.com - */ -#include -#include -#include -#include "selftest.h" - - -static void udp_recv(const struct sa *src, struct mbuf *mb, void *arg) -{ - struct sip_server *srv = arg; - struct sip_msg *msg; - int err; - -#if 0 - re_printf("%b\n", mb->buf, mb->end); -#endif - - err = sip_msg_decode(&msg, mb); - if (err) { - warning("selftest: sip_msg_decode: %m\n", err); - return; - } - - if (0 == pl_strcmp(&msg->met, "REGISTER")) - srv->got_register_req = true; - - msg->sock = mem_ref(srv->us); - msg->src = *src; - msg->dst = srv->laddr; - msg->tp = SIP_TRANSP_UDP; - - if (srv->terminate) - err = sip_reply(srv->sip, msg, 503, "Server Error"); - else - err = sip_reply(srv->sip, msg, 200, "OK"); - if (err) { - warning("selftest: could not reply: %m\n", err); - } - - mem_deref(msg); - - if (srv->terminate) - re_cancel(); -} - - -static void destructor(void *arg) -{ - struct sip_server *srv = arg; - - sip_close(srv->sip, false); - mem_deref(srv->sip); - - mem_deref(srv->us); -} - - -int sip_server_create(struct sip_server **srvp) -{ - struct sip_server *srv; - int err; - - srv = mem_zalloc(sizeof *srv, destructor); - if (!srv) - return ENOMEM; - - sa_set_str(&srv->laddr, "127.0.0.1", 0); - - err = sip_alloc(&srv->sip, NULL, 16, 16, 16, - "dummy SIP registrar", NULL, NULL); - if (err) - goto out; - - err = sip_transp_add(srv->sip, SIP_TRANSP_UDP, &srv->laddr); - if (err) - goto out; - - err = udp_listen(&srv->us, &srv->laddr, udp_recv, srv); - if (err) - goto out; - - err = udp_local_get(srv->us, &srv->laddr); - if (err) - goto out; - - out: - if (err) - mem_deref(srv); - else - *srvp = srv; - - return err; -} diff --git a/modules/selftest/ua.c b/modules/selftest/ua.c deleted file mode 100644 index 0117867..0000000 --- a/modules/selftest/ua.c +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file selftest/ua.c Baresip selftest -- User-Agent (UA) - * - * Copyright (C) 2010 Creytiv.com - */ -#include -#include -#include -#include "selftest.h" - - -struct test { - struct sip_server *srv; - struct ua *ua; - int err; - bool got_register_ok; -}; - - -static void ua_event_handler(struct ua *ua, enum ua_event ev, - struct call *call, const char *prm, void *arg) -{ - struct test *t = arg; - int err = 0; - (void)call; - (void)prm; - - ASSERT_TRUE(t != NULL); - - if (ua != t->ua) - return; - - if (ev == UA_EVENT_REGISTER_OK) { - - t->got_register_ok = true; - - /* verify register success */ - ASSERT_TRUE(ua_isregistered(t->ua)); - - /* Terminate SIP Server, then De-REGISTER */ - t->srv->terminate = true; - t->ua = mem_deref(t->ua); - } - - out: - if (err) { - warning("selftest: event handler error: %m\n", err); - t->err = err; - } -} - - -int test_ua_register(void) -{ - struct test t; - char aor[256]; - int err; - - memset(&t, 0, sizeof t); - - err = sip_server_create(&t.srv); - if (err) - goto out; - - re_snprintf(aor, sizeof(aor), "sip:x:x@%J", &t.srv->laddr); - - err = ua_alloc(&t.ua, aor); - if (err) - goto out; - - err = uag_event_register(ua_event_handler, &t); - if (err) - goto out; - - /* run main-loop with timeout, wait for events */ - err = re_main_timeout(5); - if (err) - goto out; - - if (t.err) - err = t.err; - - ASSERT_TRUE(t.srv->got_register_req); - ASSERT_TRUE(t.got_register_ok); - - out: - if (err) { - warning("selftest: ua_register test failed (%m)\n", err); - } - uag_event_unregister(ua_event_handler); - mem_deref(t.srv); - mem_deref(t.ua); - - return err; -} - - -int test_ua_alloc(void) -{ - struct ua *ua; - uint32_t n_uas = list_count(uag_list()); - int err = 0; - - /* make sure we dont have that UA already */ - ASSERT_TRUE(NULL == uag_find_aor("sip:user@127.0.0.1")); - - err = ua_alloc(&ua, "Foo ;regint=0"); - if (err) - return err; - - /* verify this UA-instance */ - ASSERT_EQ(-1, ua_sipfd(ua)); - ASSERT_TRUE(!ua_isregistered(ua)); - ASSERT_STREQ("sip:user@127.0.0.1", ua_aor(ua)); - ASSERT_TRUE(NULL == ua_call(ua)); - - /* verify global UA keeper */ - ASSERT_EQ((n_uas + 1), list_count(uag_list())); - ASSERT_TRUE(ua == uag_find_aor("sip:user@127.0.0.1")); - - mem_deref(ua); - - ASSERT_EQ((n_uas), list_count(uag_list())); - - out: - return err; -} - - -int test_uag_find_param(void) -{ - struct ua *ua1 = NULL, *ua2 = NULL; - int err = 0; - - ASSERT_TRUE(NULL == uag_find_param("not", "found")); - - err = ua_alloc(&ua1, ";regint=0;abc"); - err |= ua_alloc(&ua2, ";regint=0;def=123"); - if (err) - goto out; - - ASSERT_TRUE(ua1 == uag_find_param("abc", NULL)); - ASSERT_TRUE(NULL == uag_find_param("abc", "123")); - ASSERT_TRUE(ua2 == uag_find_param("def", NULL)); - ASSERT_TRUE(ua2 == uag_find_param("def", "123")); - - ASSERT_TRUE(NULL == uag_find_param("not", "found")); - - out: - mem_deref(ua2); - mem_deref(ua1); - - return err; -} diff --git a/src/main.c b/src/main.c index 029eacc..b9a9309 100644 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,7 @@ /** - * @file main.c Main application code + * @file src/main.c Main application code * - * Copyright (C) 2010 - 2011 Creytiv.com + * Copyright (C) 2010 - 2015 Creytiv.com */ #ifdef SOLARIS #define __EXTENSIONS__ 1 diff --git a/test/cmd.c b/test/cmd.c new file mode 100644 index 0000000..dfd42fa --- /dev/null +++ b/test/cmd.c @@ -0,0 +1,77 @@ +/** + * @file test/cmd.c Baresip selftest -- cmd + * + * Copyright (C) 2010 Creytiv.com + */ +#include +#include +#include "test.h" + + +static bool cmd_called; + + +static int cmd_test(struct re_printf *pf, void *arg) +{ + struct cmd_arg *carg = arg; + int err = 0; + (void)pf; + + ASSERT_EQ(false, cmd_called); + + ASSERT_EQ('@', carg->key); + ASSERT_TRUE(NULL == carg->prm); + ASSERT_EQ(true, carg->complete); + + cmd_called = true; + + out: + return err; +} + + +static const struct cmd cmdv[] = { + {'@', 0, "Test command", cmd_test}, +}; + + +static int vprintf_null(const char *p, size_t size, void *arg) +{ + (void)p; + (void)size; + (void)arg; + return 0; +} + + +static struct re_printf pf_null = {vprintf_null, 0}; + + +int test_cmd(void) +{ + struct cmd_ctx *ctx = 0; + int err = 0; + + cmd_called = false; + + err = cmd_register(cmdv, ARRAY_SIZE(cmdv)); + ASSERT_EQ(0, err); + + /* issue a different command */ + err = cmd_process(&ctx, 'h', &pf_null); + ASSERT_EQ(0, err); + ASSERT_EQ(false, cmd_called); + + /* issue our command, expect handler to be called */ + err = cmd_process(&ctx, '@', &pf_null); + ASSERT_EQ(0, err); + ASSERT_EQ(true, cmd_called); + + cmd_unregister(cmdv); + + /* verify that context was not created */ + ASSERT_TRUE(NULL == ctx); + + out: + return err; +} diff --git a/test/main.c b/test/main.c new file mode 100644 index 0000000..c32cd4b --- /dev/null +++ b/test/main.c @@ -0,0 +1,86 @@ +/** + * @file test/main.c Selftest for Baresip core + * + * Copyright (C) 2010 Creytiv.com + */ +#include +#include +#include "test.h" + + +static int run_tests(void) +{ + int err; + + err = test_cmd(); + if (err) + return err; + + err = test_ua_alloc(); + if (err) + return err; + + err = test_uag_find_param(); + if (err) + return err; + + err = test_ua_register(); + if (err) + return err; + + return 0; +} + + +int main(void) +{ + struct config *config; + int err; + + err = libre_init(); + if (err) + return err; + + re_printf("running test..\n"); + + /* note: run SIP-traffic on localhost */ + config = conf_config(); + if (!config) { + err = ENOENT; + goto out; + } + str_ncpy(config->sip.local, "127.0.0.1:0", sizeof(config->sip.local)); + + /* XXX: needed for ua tests */ + err = ua_init("test", true, true, false, false); + if (err) + goto out; + + err = run_tests(); + if (err) + goto out; + +#if 1 + ua_stop_all(false); + err = re_main_timeout(5); + if (err) + goto out; +#endif + + re_printf("\x1b[32mOK. selftest passed successfully\x1b[;m\n"); + + out: + if (err) { + warning("test failed (%m)\n", err); + re_printf("%H\n", re_debug, 0); + } + ua_stop_all(true); + ua_close(); + + libre_close(); + + tmr_debug(); + mem_debug(); + + return err; +} diff --git a/test/sip_server.c b/test/sip_server.c new file mode 100644 index 0000000..0e637de --- /dev/null +++ b/test/sip_server.c @@ -0,0 +1,113 @@ +/** + * @file sip_server.c Selftest for Baresip core -- SIP Server + * + * Copyright (C) 2010 Creytiv.com + */ +#include +#include +#include +#include "test.h" + + +static void udp_recv(const struct sa *src, struct mbuf *mb, void *arg) +{ + struct sip_server *srv = arg; + struct sip_msg *msg; + int err; + +#if 0 + re_printf("sip: %zu bytes from %J\n", mbuf_get_left(mb), src); + re_printf("%b\n", mb->buf, mb->end); +#endif + + err = sip_msg_decode(&msg, mb); + if (err) { + warning("selftest: sip_msg_decode: %m\n", err); + return; + } + + if (0 == pl_strcmp(&msg->met, "REGISTER")) + srv->got_register_req = true; + + msg->sock = mem_ref(srv->us); + msg->src = *src; + msg->dst = srv->laddr; + msg->tp = SIP_TRANSP_UDP; + + if (srv->terminate) + err = sip_reply(srv->sip, msg, 503, "Server Error"); + else + err = sip_reply(srv->sip, msg, 200, "OK"); + if (err) { + warning("selftest: could not reply: %m\n", err); + } + + mem_deref(msg); + + if (srv->terminate) + re_cancel(); +} + + +static void destructor(void *arg) +{ + struct sip_server *srv = arg; + + sip_close(srv->sip, false); + mem_deref(srv->sip); + + mem_deref(srv->us); +} + + +int sip_server_create(struct sip_server **srvp) +{ + struct sip_server *srv; + struct sa laddr_tp; + int err; + + srv = mem_zalloc(sizeof *srv, destructor); + if (!srv) + return ENOMEM; + + err = sa_set_str(&laddr_tp, "127.0.0.1", 0); + err |= sa_set_str(&srv->laddr, "127.0.0.1", 0); + if (err) + goto out; + + err = sip_alloc(&srv->sip, NULL, 16, 16, 16, + "dummy SIP registrar", NULL, NULL); + if (err) + goto out; + + err = sip_transp_add(srv->sip, SIP_TRANSP_UDP, &laddr_tp); + if (err) { + warning("failed to add sip transport (%m)\n", err); + goto out; + } + + err = udp_listen(&srv->us, &srv->laddr, udp_recv, srv); + if (err) { + warning("sip: udp_listen on '%J' failed (%d/%m)\n", + &srv->laddr, err, err); + goto out; + } + + err = udp_local_get(srv->us, &srv->laddr); + if (err) { + warning("sip: udp_local_get\n"); + goto out; + } + +#if 0 + re_printf("sip: listen on %J\n", &srv->laddr); +#endif + + out: + if (err) + mem_deref(srv); + else + *srvp = srv; + + return err; +} diff --git a/test/srcs.mk b/test/srcs.mk new file mode 100644 index 0000000..df16f8b --- /dev/null +++ b/test/srcs.mk @@ -0,0 +1,13 @@ +# +# srcs.mk All application source files. +# +# Copyright (C) 2010 Creytiv.com +# + +TEST_SRCS += cmd.c +TEST_SRCS += ua.c + +TEST_SRCS += sip_server.c +TEST_SRCS += test.c + +TEST_SRCS += main.c diff --git a/test/test.c b/test/test.c new file mode 100644 index 0000000..ec6f6fb --- /dev/null +++ b/test/test.c @@ -0,0 +1,30 @@ +#include +#include +#include "test.h" + + +static void timeout_handler(void *arg) +{ + int *err = arg; + + warning("selftest: re_main() loop timed out -- test hung..\n"); + + *err = ETIMEDOUT; + + re_cancel(); +} + + +int re_main_timeout(uint32_t timeout) +{ + struct tmr tmr; + int err = 0; + + tmr_init(&tmr); + + tmr_start(&tmr, timeout * 1000, timeout_handler, &err); + re_main(NULL); + + tmr_cancel(&tmr); + return err; +} diff --git a/test/test.h b/test/test.h new file mode 100644 index 0000000..20807b6 --- /dev/null +++ b/test/test.h @@ -0,0 +1,58 @@ +/** + * @file test.h Selftest for Baresip core -- internal API + * + * Copyright (C) 2010 Creytiv.com + */ + + +#define ASSERT_TRUE(cond) \ + if (!(cond)) { \ + warning("selftest: ASSERT_TRUE: %s:%u:\n", \ + __FILE__, __LINE__); \ + err = EINVAL; \ + goto out; \ + } + +#define ASSERT_EQ(expected, actual) \ + if ((expected) != (actual)) { \ + warning("selftest: ASSERT_EQ: %s:%u:" \ + " expected=%d, actual=%d\n", \ + __FILE__, __LINE__, \ + (int)(expected), (int)(actual)); \ + err = EINVAL; \ + goto out; \ + } + +#define ASSERT_STREQ(expected, actual) \ + if (0 != str_cmp((expected), (actual))) { \ + warning("selftest: ASSERT_STREQ: %s:%u:" \ + " expected = '%s', actual = '%s'\n", \ + __FILE__, __LINE__, \ + (expected), (actual)); \ + err = EBADMSG; \ + goto out; \ + } + + +/* helpers */ + +int re_main_timeout(uint32_t timeout); + +struct sip_server { + struct sa laddr; + struct udp_sock *us; + struct sip *sip; + + bool got_register_req; + bool terminate; +}; + +int sip_server_create(struct sip_server **srvp); + + +/* test cases */ + +int test_cmd(void); +int test_ua_alloc(void); +int test_uag_find_param(void); +int test_ua_register(void); diff --git a/test/ua.c b/test/ua.c new file mode 100644 index 0000000..ddfa76e --- /dev/null +++ b/test/ua.c @@ -0,0 +1,156 @@ +/** + * @file test/ua.c Baresip selftest -- User-Agent (UA) + * + * Copyright (C) 2010 Creytiv.com + */ +#include +#include +#include +#include "test.h" + + +struct test { + struct sip_server *srv; + struct ua *ua; + int err; + bool got_register_ok; +}; + + +static void ua_event_handler(struct ua *ua, enum ua_event ev, + struct call *call, const char *prm, void *arg) +{ + struct test *t = arg; + int err = 0; + (void)call; + (void)prm; + + ASSERT_TRUE(t != NULL); + + if (ua != t->ua) + return; + + if (ev == UA_EVENT_REGISTER_OK) { + + t->got_register_ok = true; + + /* verify register success */ + ASSERT_TRUE(ua_isregistered(t->ua)); + + /* Terminate SIP Server, then De-REGISTER */ + t->srv->terminate = true; + t->ua = mem_deref(t->ua); + } + + out: + if (err) { + warning("selftest: event handler error: %m\n", err); + t->err = err; + } +} + + +int test_ua_register(void) +{ + struct test t; + char aor[256]; + int err; + + memset(&t, 0, sizeof t); + + err = sip_server_create(&t.srv); + if (err) { + warning("failed to create sip server (%d/%m)\n", err, err); + goto out; + } + + re_snprintf(aor, sizeof(aor), "sip:x:x@%J", &t.srv->laddr); + + err = ua_alloc(&t.ua, aor); + if (err) + goto out; + + err = uag_event_register(ua_event_handler, &t); + if (err) + goto out; + + /* run main-loop with timeout, wait for events */ + err = re_main_timeout(5); + if (err) + goto out; + + if (t.err) + err = t.err; + + ASSERT_TRUE(t.srv->got_register_req); + ASSERT_TRUE(t.got_register_ok); + + out: + if (err) { + warning("selftest: ua_register test failed (%m)\n", err); + } + uag_event_unregister(ua_event_handler); + mem_deref(t.srv); + mem_deref(t.ua); + + return err; +} + + +int test_ua_alloc(void) +{ + struct ua *ua; + uint32_t n_uas = list_count(uag_list()); + int err = 0; + + /* make sure we dont have that UA already */ + ASSERT_TRUE(NULL == uag_find_aor("sip:user@127.0.0.1")); + + err = ua_alloc(&ua, "Foo ;regint=0"); + if (err) + return err; + + /* verify this UA-instance */ + ASSERT_EQ(-1, ua_sipfd(ua)); + ASSERT_TRUE(!ua_isregistered(ua)); + ASSERT_STREQ("sip:user@127.0.0.1", ua_aor(ua)); + ASSERT_TRUE(NULL == ua_call(ua)); + + /* verify global UA keeper */ + ASSERT_EQ((n_uas + 1), list_count(uag_list())); + ASSERT_TRUE(ua == uag_find_aor("sip:user@127.0.0.1")); + + mem_deref(ua); + + ASSERT_EQ((n_uas), list_count(uag_list())); + + out: + return err; +} + + +int test_uag_find_param(void) +{ + struct ua *ua1 = NULL, *ua2 = NULL; + int err = 0; + + ASSERT_TRUE(NULL == uag_find_param("not", "found")); + + err = ua_alloc(&ua1, ";regint=0;abc"); + err |= ua_alloc(&ua2, ";regint=0;def=123"); + if (err) + goto out; + + ASSERT_TRUE(ua1 == uag_find_param("abc", NULL)); + ASSERT_TRUE(NULL == uag_find_param("abc", "123")); + ASSERT_TRUE(ua2 == uag_find_param("def", NULL)); + ASSERT_TRUE(ua2 == uag_find_param("def", "123")); + + ASSERT_TRUE(NULL == uag_find_param("not", "found")); + + out: + mem_deref(ua2); + mem_deref(ua1); + + return err; +} -- cgit v1.2.3