From patchwork Thu Mar 20 18:14:33 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Erlbeck X-Patchwork-Id: 332345 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ganesha.gnumonks.org (ganesha.gnumonks.org [IPv6:2001:780:45:1d:225:90ff:fe52:c662]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id DAC762C008F for ; Fri, 21 Mar 2014 05:15:43 +1100 (EST) Received: from localhost ([127.0.0.1] helo=ganesha.gnumonks.org) by ganesha.gnumonks.org with esmtp (Exim 4.72) (envelope-from ) id 1WQhV1-0000iT-H9; Thu, 20 Mar 2014 19:15:27 +0100 Received: from mail.sysmocom.de ([2a01:4f8:191:444c::2:4]) by ganesha.gnumonks.org with esmtp (Exim 4.72) (envelope-from ) id 1WQhUU-0000i4-EE for openbsc@lists.osmocom.org; Thu, 20 Mar 2014 19:14:56 +0100 Received: from sysmocom-tmp.lan (p5099b351.dip0.t-ipconnect.de [80.153.179.81]) by mail.sysmocom.de (Postfix) with ESMTPSA id 7C8A916F83; Thu, 20 Mar 2014 18:14:53 +0000 (UTC) From: Jacob Erlbeck To: openbsc@lists.osmocom.org Subject: [PATCH 1/2] ipa/test: Add test program for IPA message reception Date: Thu, 20 Mar 2014 19:14:33 +0100 Message-Id: <1395339274-24803-1-git-send-email-jerlbeck@sysmocom.de> X-Mailer: git-send-email 1.7.9.5 X-Spam-Score: 0.0 (/) Cc: pablo@gnumonks.org, Jacob Erlbeck X-BeenThere: openbsc@lists.osmocom.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Development of the OpenBSC GSM base station controller List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: openbsc-bounces@lists.osmocom.org Errors-To: openbsc-bounces@lists.osmocom.org This patch adds tests for ipa_msg_recv(), where messages are sent either complete or partitioned. Sponsored-by: On-Waves ehf --- tests/Makefile.am | 11 +- tests/ipa_recv/ipa_recv_test.c | 247 +++++++++++++++++++++++++++++++++++++++ tests/ipa_recv/ipa_recv_test.ok | 12 ++ tests/testsuite.at | 7 ++ 4 files changed, 275 insertions(+), 2 deletions(-) create mode 100644 tests/ipa_recv/ipa_recv_test.c create mode 100644 tests/ipa_recv/ipa_recv_test.ok diff --git a/tests/Makefile.am b/tests/Makefile.am index af8a9cf..c8b8996 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -5,7 +5,8 @@ AM_LDFLAGS = $(COVERAGE_LDFLAGS) check_PROGRAMS = e1inp_ipa_bsc_test \ e1inp_ipa_bts_test \ ipa_proxy_test \ - subchan_demux/subchan_demux_test + subchan_demux/subchan_demux_test \ + ipa_recv/ipa_recv_test e1inp_ipa_bsc_test_SOURCES = e1inp_ipa_bsc_test.c e1inp_ipa_bsc_test_LDADD = $(top_builddir)/src/libosmoabis.la \ @@ -25,6 +26,11 @@ subchan_demux_subchan_demux_test_LDADD = $(top_builddir)/src/libosmoabis.la \ $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ $(LIBOSMOVTY_LIBS) +ipa_recv_ipa_recv_test_SOURCES = ipa_recv/ipa_recv_test.c +ipa_recv_ipa_recv_test_LDADD = $(top_builddir)/src/libosmoabis.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) + # boilerplate for the tests # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac @@ -45,7 +51,8 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac } >'$(srcdir)/package.m4' EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \ - subchan_demux/subchan_demux_test.ok + subchan_demux/subchan_demux_test.ok \ + ipa_recv/ipa_recv_test.ok TESTSUITE = $(srcdir)/testsuite diff --git a/tests/ipa_recv/ipa_recv_test.c b/tests/ipa_recv/ipa_recv_test.c new file mode 100644 index 0000000..7b26259 --- /dev/null +++ b/tests/ipa_recv/ipa_recv_test.c @@ -0,0 +1,247 @@ +/* IPA receive test */ + +/* (C) 2014 by On-Waves + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#if 0 +/* IPA protocol ip.access, type: RSL */ +static const unsigned char gsm_ipa_chanrqd[13] = { + 0x00, 0x0a, 0x00, 0x0c, 0x13, 0x01, 0x88, 0x13, + 0x4e, 0x42, 0x93, 0x11, 0x00 +}; + +/* IPA protocol ip.access, type: RSL */ +static const unsigned char gsm_ipa_chanactivack[10] = { + 0x00, 0x07, 0x00, 0x08, 0x22, 0x01, 0x12, 0x08, + 0x43, 0x81 +}; + +/* IPA protocol ip.access, type: RSL */ +static const unsigned char gsm_ipa_data[40] = { + 0x00, 0x25, 0x00, 0x08, 0x28, 0x01, 0x12, 0x1b, + 0x00, 0x19, 0x03, 0x3b, 0x3b, 0x00, 0x04, 0x00, + 0x0a, 0x38, 0x00, 0x0b, 0x00, 0x12, 0x06, 0x15, + 0x35, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +#endif + +static const char *ipa_test_messages[] = { + "Hello IPA", + "A longer test message. ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz", + "Hello again IPA", + "", + "Next is empty", + NULL, + "Bye", + "Bye", +}; + +static void append_ipa_message(struct msgb *msg, int proto, const char *text) +{ + int len = 0; + unsigned char *l2; + + if (text) + len = strlen(text) + 1; + + msgb_put_u16(msg, len); + msgb_put_u8(msg, proto); + + l2 = msgb_put(msg, len); + if (text) + strcpy((char *)l2, text); +} + +static int receive_messages(int fd) +{ + struct msgb *msg; + char dummy; + int rc; + while (1) { + if (recv(fd, &dummy, 1, MSG_PEEK) < 1) { + rc = -EAGAIN; + break; + } + msg = NULL; + rc = ipa_msg_recv(fd, &msg); + if (rc == -1) + rc = -errno; + fprintf(stderr, + "ipa_msg_recv: %d, msg %s NULL\n", + rc, msg ? "!=" : "=="); + if (rc == -EAGAIN) + printf( "got msg %s NULL, " + "returned: %s\n", + msg ? "!=" : "==", + rc == 0 ? "EOF" : + rc > 0 ? "OK" : + strerror(-rc)); + if (rc == 0) + return 0; + if (rc == -EAGAIN) + break; + if (rc < 0) { + printf("ipa_msg_recv failed with: %s\n", strerror(-rc)); + return rc; + } + printf("got IPA message, size=%d, proto=%d, text=\"%s\"\n", + rc, msg->data[2], msg->l2h); + msgb_free(msg); + }; + + return rc; +} + +static int slurp_data(int fd) { + int rc; + char buf[256]; + int count = 0; + + do { + rc = recv(fd, buf, sizeof(buf), 0); + if (rc <= 0) + break; + + count += rc; + } while (1); + + return count; +}; + +static void test_complete_recv(void) +{ + int sv[2]; + struct msgb *msg_out = msgb_alloc(4096, "msg_out"); + int rc, i; + + printf("Testing IPA recv with complete messages.\n"); + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) + err(1, "socketpair"); + + fcntl(sv[0], F_SETFL, O_NONBLOCK); + + for (i=0; i < ARRAY_SIZE(ipa_test_messages); i++) + append_ipa_message(msg_out, 200, ipa_test_messages[i]); + + while (msg_out->len > 0) { + rc = write(sv[1], msg_out->data, msg_out->len); + if (rc == -1) + err(1, "write"); + msgb_pull(msg_out, rc); + } + + for (i=0; i < ARRAY_SIZE(ipa_test_messages); i++) { + rc = receive_messages(sv[0]); + if (rc == 0) + break; + + if (rc < 0 && rc != -EAGAIN) + break; + } + + rc = slurp_data(sv[0]); + printf("done: unread %d, unsent %d\n", rc, msg_out->len); + + close(sv[1]); + close(sv[0]); + + msgb_free(msg_out); +} + + +static void test_partial_recv(void) +{ + int sv[2]; + struct msgb *msg_out = msgb_alloc(4096, "msg_out"); + int rc, i; + + printf("Testing IPA recv with partitioned messages.\n"); + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) + err(1, "socketpair"); + + fcntl(sv[0], F_SETFL, O_NONBLOCK); + + for (i=0; i < ARRAY_SIZE(ipa_test_messages); i++) + append_ipa_message(msg_out, 200, ipa_test_messages[i]); + + while (msg_out->len > 0) { + int len = 5; + if (len > msg_out->len) + len = msg_out->len; + if (write(sv[1], msg_out->data, len) == -1) + err(1, "write"); + msgb_pull(msg_out, len); + + if (msg_out->len == 0) + shutdown(sv[1], SHUT_WR); + + rc = receive_messages(sv[0]); + + if (rc == 0) + break; + + if (rc < 0 && rc != -EAGAIN) + break; + } + rc = slurp_data(sv[0]); + printf("done: unread %d, unsent %d\n", rc, msg_out->len); + + close(sv[1]); + close(sv[0]); + + msgb_free(msg_out); +} + +static struct log_info info = {}; + +int main(int argc, char **argv) +{ + osmo_init_logging(&info); + log_set_all_filter(osmo_stderr_target, 1); + log_set_log_level(osmo_stderr_target, LOGL_INFO); + + printf("Testing the IPA layer.\n"); + + /* run the tests */ + test_complete_recv(); + test_partial_recv(); + + printf("No crashes.\n"); + return 0; +} diff --git a/tests/ipa_recv/ipa_recv_test.ok b/tests/ipa_recv/ipa_recv_test.ok new file mode 100644 index 0000000..4144d47 --- /dev/null +++ b/tests/ipa_recv/ipa_recv_test.ok @@ -0,0 +1,12 @@ +Testing the IPA layer. +Testing IPA recv with complete messages. +got IPA message, size=10, proto=200, text="Hello IPA" +got IPA message, size=86, proto=200, text="A longer test message. ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz" +got IPA message, size=16, proto=200, text="Hello again IPA" +got IPA message, size=1, proto=200, text="" +got IPA message, size=14, proto=200, text="Next is empty" +done: unread 14, unsent 0 +Testing IPA recv with partitioned messages. +ipa_msg_recv failed with: Input/output error +done: unread 0, unsent 154 +No crashes. diff --git a/tests/testsuite.at b/tests/testsuite.at index 04193c5..ff550b0 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -11,8 +11,15 @@ AT_BANNER([Regression tests.]) # AT_CHECK([$abs_top_builddir/tests/NAME/NAME_test], [], [expout]) # AT_CLEANUP +AT_SETUP([ipa_recv]) +AT_KEYWORDS([ipa_recv]) +cat $abs_srcdir/ipa_recv/ipa_recv_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/ipa_recv/ipa_recv_test], [], [expout],[ignore]) +AT_CLEANUP + AT_SETUP([subchan_demux]) AT_KEYWORDS([subchan_demux]) cat $abs_srcdir/subchan_demux/subchan_demux_test.ok > expout AT_CHECK([$abs_top_builddir/tests/subchan_demux/subchan_demux_test], [], [expout]) AT_CLEANUP +