Change in libosmo-netif[master]: Add stream client/server test

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Max gerrit-no-reply at lists.osmocom.org
Tue Feb 5 15:05:20 UTC 2019


Max has uploaded this change for review. ( https://gerrit.osmocom.org/12837


Change subject: Add stream client/server test
......................................................................

Add stream client/server test

Previously stream client and server code were only used in examples
which means regressions could be easily introduced unnoticed until they
trigger bugs in external code which relies on osmo_stream_*()

Fix this by adding basic client-server interaction test with single
reconnection iteration.

Change-Id: I336f79970982ed8e1d73b73d54fa4c27ba8bce8e
---
M tests/Makefile.am
A tests/stream/stream_test.c
A tests/stream/stream_test.ok
M tests/testsuite.at
4 files changed, 298 insertions(+), 1 deletion(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/37/12837/1

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 03a7a3c..c85c103 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,7 +1,7 @@
 AM_CFLAGS = -Wall -I$(top_srcdir)/include $(LIBOSMOCORE_CFLAGS) -g
 AM_LDFLAGS = $(LIBOSMOCORE_LDFLAGS)
 
-check_PROGRAMS = osmux/osmux_test osmux/osmux_test2 jibuf/jibuf_test
+check_PROGRAMS = osmux/osmux_test osmux/osmux_test2 stream/stream_test jibuf/jibuf_test
 check_HEADERS =
 
 osmux_osmux_test_SOURCES = osmux/osmux_test.c
@@ -10,6 +10,9 @@
 osmux_osmux_test2_SOURCES = osmux/osmux_test2.c
 osmux_osmux_test2_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(top_builddir)/src/libosmonetif.la
 
+stream_stream_test_SOURCES = stream/stream_test.c
+stream_stream_test_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(top_builddir)/src/libosmonetif.la
+
 jibuf_jibuf_test_SOURCES = jibuf/jibuf_test.c
 jibuf_jibuf_test_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(top_builddir)/src/libosmonetif.la
 
diff --git a/tests/stream/stream_test.c b/tests/stream/stream_test.c
new file mode 100644
index 0000000..ed3e9ea
--- /dev/null
+++ b/tests/stream/stream_test.c
@@ -0,0 +1,232 @@
+/*
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH.
+ * Author: Max Suraev
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <osmocom/core/select.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/application.h>
+
+#include <osmocom/netif/stream.h>
+
+#define DSTREAMTEST 0
+struct log_info_cat osmo_stream_test_cat[] = {
+	[DSTREAMTEST] = {
+		.name = "DSTREAMTEST",
+		.description = "STREAM test",
+		.color = "\033[1;35m",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+};
+
+const struct log_info osmo_stream_test_log_info = {
+	.filter_fn = NULL,
+	.cat = osmo_stream_test_cat,
+	.num_cat = ARRAY_SIZE(osmo_stream_test_cat),
+};
+
+void sighandler(int foo)
+{
+	LOGP(DSTREAMTEST, LOGL_NOTICE, "Signal received: closing stream.\n");
+	exit(EXIT_SUCCESS);
+}
+
+static struct msgb *make_msgb(const char *m)
+{
+	struct msgb *msg = msgb_alloc(512, "STREAM test");
+	if (!msg) {
+		printf("Unable to allocate message\n");
+		return NULL;
+	}
+
+	if (m)
+		msgb_printf(msg, "%s", m);
+
+	return msg;
+}
+
+/* client callbacks */
+static int connect_cb_cli(struct osmo_stream_cli *conn)
+{
+	void *cli_data = osmo_stream_cli_get_data(conn);
+	printf("\nClient's connect() callback triggered [%s]\n", cli_data ? "OK" : "NA");
+
+	return 0;
+}
+
+static int read_cb_cli(struct osmo_stream_cli *conn)
+{
+	int bytes;
+	void *cli_data = osmo_stream_cli_get_data(conn);
+	struct msgb *msg = make_msgb(NULL);
+	if (!msg)
+		return -ENOMEM;
+
+	printf("Client's read() callback triggered\n");
+
+	bytes = osmo_stream_cli_recv(conn, msg);
+	if (bytes < 0) {
+		printf("Unable to receive message\n");
+		return -EINVAL;
+	}
+
+	if (bytes)
+		printf("Client received %d(%d) bytes: %s\n", bytes, msg->len, msgb_hexdump(msg));
+	else
+		printf("Client received 0 bytes\n");
+
+	/* N. B: do not dereference opaque pointer itself as it might be invalid by the time callback is triggered! */
+	if (!cli_data) {
+		/* we reply to trigger server's read() callback */
+		printf("Client's initial connection, contacting server\n");
+		msgb_reset(msg);
+		osmo_stream_cli_set_data(conn, msg);
+		msgb_printf(msg, "%s", "Doh, responding to server :-D");
+		printf("Client sent %d bytes message: %s\n", msg->len, msgb_hexdump(msg));
+		osmo_stream_cli_send(conn, msg);
+	} else {
+		printf("Client's subsequent connection, closing link\n");
+		osmo_stream_cli_close(conn);
+	}
+
+	return 0;
+}
+
+/* server callbacks */
+int read_cb_srv(struct osmo_stream_srv *conn)
+{
+	int bytes;
+	struct msgb *msg = make_msgb(NULL);
+	if (!msg)
+		return -ENOMEM;
+
+	printf("Server's read() callback triggered\n");
+
+	bytes = osmo_stream_srv_recv(conn, msg);
+	if (bytes <= 0) {
+		if (bytes < 0)
+			printf("Unable to receive message: %s\n", strerror(-bytes));
+		else {
+			printf("client have already closed connection\n");
+			/* if client have already closed the connection, than it must be subsequent (after reconnect)
+			   call - we indicate this to outer loop by clearing opaque pointer */
+			osmo_stream_srv_link_set_data(osmo_stream_srv_get_master(conn), NULL);
+		}
+		osmo_stream_srv_destroy(conn);
+		return -EINVAL;
+	} else
+		printf("Server received %d(%d) bytes: %s\n", bytes, msg->len, msgb_hexdump(msg));
+
+	msgb_free(msg);
+
+	printf("Server: force client disconnect\n");
+	osmo_stream_srv_destroy(conn);
+
+	return 0;
+}
+
+static int close_cb_srv(struct osmo_stream_srv *ignored)
+{
+	printf("Server's close() callback triggered\n");
+
+	return 0;
+}
+
+static int accept_cb_srv(struct osmo_stream_srv_link *srv, int fd)
+{
+	void *ctx = osmo_stream_srv_link_get_data(srv);
+	struct msgb *msg = make_msgb("Lol, connection accepted :)");
+	struct osmo_stream_srv *conn = osmo_stream_srv_create(ctx, srv, fd, read_cb_srv, close_cb_srv, NULL);
+	if (!conn) {
+		printf("error while creating connection\n");
+		return -EINVAL;
+	}
+
+	printf("Server's accept() callback triggered\n");
+
+	/* we initiate transmission which will trigger client's read() callback */
+	if (msg) {
+		printf("Server sent %d bytes message: %s\n", msg->len, msgb_hexdump(msg));
+		osmo_stream_srv_send(conn, msg);
+	}
+
+	return 0;
+}
+
+
+int main(void)
+{
+	unsigned steps = 16, port = 1111; /* Make sure to use sufficient number of steps */
+	struct osmo_stream_srv_link *srv;
+	struct osmo_stream_cli *cli;
+	char *host = "127.0.0.11";
+	void *tall_test = talloc_named_const(NULL, 1, "osmo_stream_test");
+	msgb_talloc_ctx_init(tall_test, 0);
+	osmo_init_logging2(tall_test, &osmo_stream_test_log_info);
+	log_set_log_level(osmo_stderr_target, 1);
+
+	printf("Prepare stream client...\n");
+	cli = osmo_stream_cli_create(tall_test);
+	if (!cli) {
+		printf("Unable to create client\n");
+		return EXIT_FAILURE;
+	}
+
+	osmo_stream_cli_set_addr(cli, host);
+	osmo_stream_cli_set_port(cli, port);
+	osmo_stream_cli_set_connect_cb(cli, connect_cb_cli);
+	osmo_stream_cli_set_read_cb(cli, read_cb_cli);
+	osmo_stream_cli_set_reconnect_timeout(cli, 2);
+
+	if (osmo_stream_cli_open(cli) < 0) {
+		printf("Unable to open client\n");
+		return EXIT_FAILURE;
+	}
+
+	printf("Prepare stream server...\n");
+	srv = osmo_stream_srv_link_create(tall_test);
+	if (!srv) {
+		printf("Unable to create server\n");
+		return EXIT_FAILURE;
+	}
+
+	osmo_stream_srv_link_set_addr(srv, host);
+	osmo_stream_srv_link_set_port(srv, port);
+	osmo_stream_srv_link_set_data(srv, tall_test);
+	osmo_stream_srv_link_set_accept_cb(srv, accept_cb_srv);
+
+	if (osmo_stream_srv_link_open(srv) < 0) {
+		printf("Unable to open server\n");
+		return EXIT_FAILURE;
+	}
+
+	printf("Entering main test loop...\n");
+
+	while(steps--) {
+		osmo_select_main(0);
+		void *srv_data = osmo_stream_srv_link_get_data(srv);
+		void *cli_data = osmo_stream_cli_get_data(cli);
+		printf("\nTest step %u [client %s, server %s]\n", steps, cli_data ? "OK" : "NA", srv_data ? "OK" : "NA");
+		if (!srv_data) {
+			printf("Server requested test termination\n");
+			steps = 0;
+		}
+	}
+
+	printf("Test finished\n");
+
+	return EXIT_SUCCESS;
+}
diff --git a/tests/stream/stream_test.ok b/tests/stream/stream_test.ok
new file mode 100644
index 0000000..9c4ba1f
--- /dev/null
+++ b/tests/stream/stream_test.ok
@@ -0,0 +1,56 @@
+Prepare stream client...
+Prepare stream server...
+Entering main test loop...
+
+Test step 15 [client NA, server OK]
+
+Test step 14 [client NA, server OK]
+Server's accept() callback triggered
+Server sent 27 bytes message: 4c 6f 6c 2c 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 61 63 63 65 70 74 65 64 20 3a 29 
+
+Client's connect() callback triggered [NA]
+
+Test step 13 [client NA, server OK]
+
+Test step 12 [client NA, server OK]
+Client's read() callback triggered
+Client received 27(27) bytes: 4c 6f 6c 2c 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 61 63 63 65 70 74 65 64 20 3a 29 
+Client's initial connection, contacting server
+Client sent 29 bytes message: 44 6f 68 2c 20 72 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20 73 65 72 76 65 72 20 3a 2d 44 
+
+Test step 11 [client OK, server OK]
+
+Test step 10 [client OK, server OK]
+Server's read() callback triggered
+Server received 29(29) bytes: 44 6f 68 2c 20 72 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20 73 65 72 76 65 72 20 3a 2d 44 
+Server: force client disconnect
+Server's close() callback triggered
+
+Test step 9 [client OK, server OK]
+Client's read() callback triggered
+Client received 0 bytes
+Client's subsequent connection, closing link
+
+Test step 8 [client OK, server OK]
+
+Test step 7 [client OK, server OK]
+Server's accept() callback triggered
+Server sent 27 bytes message: 4c 6f 6c 2c 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 61 63 63 65 70 74 65 64 20 3a 29 
+
+Client's connect() callback triggered [OK]
+
+Test step 6 [client OK, server OK]
+
+Test step 5 [client OK, server OK]
+Client's read() callback triggered
+Client received 27(27) bytes: 4c 6f 6c 2c 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 61 63 63 65 70 74 65 64 20 3a 29 
+Client's subsequent connection, closing link
+
+Test step 4 [client OK, server OK]
+Server's read() callback triggered
+client have already closed connection
+Server's close() callback triggered
+
+Test step 3 [client OK, server NA]
+Server requested test termination
+Test finished
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 67b91c6..63e2f03 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -7,6 +7,12 @@
 AT_CHECK([$abs_top_builddir/tests/osmux/osmux_test], [0], [expout], [ignore])
 AT_CLEANUP
 
+AT_SETUP([stream_test])
+AT_KEYWORDS([stream_test])
+cat $abs_srcdir/stream/stream_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/stream/stream_test], [0], [expout], [ignore])
+AT_CLEANUP
+
 AT_SETUP([osmux_test2])
 AT_KEYWORDS([osmux_test2])
 cat $abs_srcdir/osmux/osmux_test2.ok > expout

-- 
To view, visit https://gerrit.osmocom.org/12837
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: libosmo-netif
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I336f79970982ed8e1d73b73d54fa4c27ba8bce8e
Gerrit-Change-Number: 12837
Gerrit-PatchSet: 1
Gerrit-Owner: Max <msuraev at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190205/bf63e4d4/attachment.htm>


More information about the gerrit-log mailing list