diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | tests/Makefile.am | 11 | ||||
-rw-r--r-- | tests/ipa_recv/ipa_recv_test.c | 226 | ||||
-rw-r--r-- | tests/ipa_recv/ipa_recv_test.ok | 12 | ||||
-rw-r--r-- | tests/testsuite.at | 7 |
5 files changed, 256 insertions, 2 deletions
@@ -27,6 +27,7 @@ tests/*_test .tarball-version .version +.dirstamp # tests tests/atconfig @@ -35,6 +36,7 @@ tests/testsuite tests/testsuite.log tests/subchan_demux/.dirstamp tests/subchan_demux/subchan_demux_test +tests/ipa_recv/ipa_recv_test 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..af87c27 --- /dev/null +++ b/tests/ipa_recv/ipa_recv_test.c @@ -0,0 +1,226 @@ +/* IPA receive test */ + +/* + * (C) 2014 by On-Waves + * (C) 2014 by sysmocom s.f.m.c. GmbH + * + * 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 <http://www.gnu.org/licenses/>. + * + */ + +#include <osmocom/abis/e1_input.h> + +#include <osmocom/abis/ipa.h> +#include <osmocom/core/utils.h> +#include <osmocom/core/msgb.h> +#include <osmocom/core/logging.h> +#include <osmocom/core/application.h> + +#include <stdio.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <err.h> + +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 + |