<p>Max <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/12837">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  osmith: Looks good to me, but someone else must approve
  daniel: Looks good to me, but someone else must approve
  Max: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Add stream client/server test<br><br>Previously stream client and server code were only used in examples<br>which means regressions could be easily introduced unnoticed until they<br>trigger bugs in external code which relies on osmo_stream_*()<br><br>Fix this by adding basic client-server interaction tests with and<br>without reconnection.<br><br>Change-Id: I336f79970982ed8e1d73b73d54fa4c27ba8bce8e<br>---<br>M .gitignore<br>M tests/Makefile.am<br>A tests/stream/stream_test.c<br>A tests/stream/stream_test.err<br>A tests/stream/stream_test.ok<br>M tests/testsuite.at<br>6 files changed, 418 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/.gitignore b/.gitignore</span><br><span>index 672708d..e2f2fb9 100644</span><br><span>--- a/.gitignore</span><br><span>+++ b/.gitignore</span><br><span>@@ -56,3 +56,4 @@</span><br><span> jibuf_test</span><br><span> jibuf_tool</span><br><span> osmux_test2</span><br><span style="color: hsl(120, 100%, 40%);">+stream_test</span><br><span>diff --git a/tests/Makefile.am b/tests/Makefile.am</span><br><span>index 03a7a3c..c3628ac 100644</span><br><span>--- a/tests/Makefile.am</span><br><span>+++ b/tests/Makefile.am</span><br><span>@@ -1,7 +1,7 @@</span><br><span> AM_CFLAGS = -Wall -I$(top_srcdir)/include $(LIBOSMOCORE_CFLAGS) -g</span><br><span> AM_LDFLAGS = $(LIBOSMOCORE_LDFLAGS)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-check_PROGRAMS = osmux/osmux_test osmux/osmux_test2 jibuf/jibuf_test</span><br><span style="color: hsl(120, 100%, 40%);">+check_PROGRAMS = osmux/osmux_test osmux/osmux_test2 stream/stream_test jibuf/jibuf_test</span><br><span> check_HEADERS =</span><br><span> </span><br><span> osmux_osmux_test_SOURCES = osmux/osmux_test.c</span><br><span>@@ -10,6 +10,10 @@</span><br><span> osmux_osmux_test2_SOURCES = osmux/osmux_test2.c</span><br><span> osmux_osmux_test2_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(top_builddir)/src/libosmonetif.la</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+stream_stream_test_SOURCES = stream/stream_test.c</span><br><span style="color: hsl(120, 100%, 40%);">+stream_stream_test_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(top_builddir)/src/libosmonetif.la</span><br><span style="color: hsl(120, 100%, 40%);">+stream_stream_test_LDFLAGS = -no-install</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> jibuf_jibuf_test_SOURCES = jibuf/jibuf_test.c</span><br><span> jibuf_jibuf_test_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(top_builddir)/src/libosmonetif.la</span><br><span> </span><br><span>@@ -57,6 +61,8 @@</span><br><span> EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE)              \</span><br><span>         osmux/osmux_test.ok \</span><br><span>        osmux/osmux_test2.ok \</span><br><span style="color: hsl(120, 100%, 40%);">+        stream/stream_test.ok \</span><br><span style="color: hsl(120, 100%, 40%);">+       stream/stream_test.err \</span><br><span>             jibuf/jibuf_test.ok</span><br><span> </span><br><span> DISTCLEANFILES = atconfig</span><br><span>diff --git a/tests/stream/stream_test.c b/tests/stream/stream_test.c</span><br><span>new file mode 100644</span><br><span>index 0000000..1a0c555</span><br><span>--- /dev/null</span><br><span>+++ b/tests/stream/stream_test.c</span><br><span>@@ -0,0 +1,309 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2019 by sysmocom - s.f.m.c. GmbH.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Max Suraev</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <unistd.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/select.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/talloc.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/application.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/netif/stream.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define DSTREAMTEST 0</span><br><span style="color: hsl(120, 100%, 40%);">+struct log_info_cat osmo_stream_test_cat[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+        [DSTREAMTEST] = {</span><br><span style="color: hsl(120, 100%, 40%);">+             .name = "DSTREAMTEST",</span><br><span style="color: hsl(120, 100%, 40%);">+              .description = "STREAM test",</span><br><span style="color: hsl(120, 100%, 40%);">+               .enabled = 1, .loglevel = LOGL_INFO,</span><br><span style="color: hsl(120, 100%, 40%);">+  },</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const struct log_info osmo_stream_test_log_info = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .filter_fn = NULL,</span><br><span style="color: hsl(120, 100%, 40%);">+    .cat = osmo_stream_test_cat,</span><br><span style="color: hsl(120, 100%, 40%);">+  .num_cat = ARRAY_SIZE(osmo_stream_test_cat),</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *make_msgb(const char *m)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct msgb *msg = msgb_alloc(512, "STREAM test");</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!msg) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printf("Unable to allocate message\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (m)</span><br><span style="color: hsl(120, 100%, 40%);">+                msgb_printf(msg, "%s", m);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return msg;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define ASTR(rec) ((rec) ? "autoreconnecting" : "non-reconnecting")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* client defs */</span><br><span style="color: hsl(120, 100%, 40%);">+#define LOGCLI(cli, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("[%s] Client's %s(): " fmt, osmo_stream_cli_get_data(cli) ? "OK" : "NA", __func__, ##args)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define CLI_SND(cli, m) do {                                             \</span><br><span style="color: hsl(120, 100%, 40%);">+             struct msgb *msg = make_msgb(m);                        \</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGCLI(cli, "sent %d bytes message: %s\n",            \</span><br><span style="color: hsl(120, 100%, 40%);">+                    msg->len, msgb_hexdump(msg));                 \</span><br><span style="color: hsl(120, 100%, 40%);">+             osmo_stream_cli_send(cli, msg);                         \</span><br><span style="color: hsl(120, 100%, 40%);">+     } while(0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* client callbacks */</span><br><span style="color: hsl(120, 100%, 40%);">+static int connect_cb_cli(struct osmo_stream_cli *cli)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       void *recon = osmo_stream_cli_get_data(cli);</span><br><span style="color: hsl(120, 100%, 40%);">+  LOGCLI(cli, "callback triggered <%s>\n", recon ? "reconnected" : "initial");</span><br><span style="color: hsl(120, 100%, 40%);">+      if (recon) {</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGCLI(cli, "closing connection\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                osmo_stream_cli_close(cli);</span><br><span style="color: hsl(120, 100%, 40%);">+   } else</span><br><span style="color: hsl(120, 100%, 40%);">+                CLI_SND(cli, "Hi! from connect callback :-P");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int read_cb_cli(struct osmo_stream_cli *cli)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        int bytes;</span><br><span style="color: hsl(120, 100%, 40%);">+    void *cli_data = osmo_stream_cli_get_data(cli);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct msgb *msg = make_msgb(NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!msg)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     LOGCLI(cli, "callback triggered\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      bytes = osmo_stream_cli_recv(cli, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (bytes < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGCLI(cli, "unable to receive message\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (bytes)</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGCLI(cli, "received %d(%d) bytes: %s\n", bytes, msg->len, msgb_hexdump(msg));</span><br><span style="color: hsl(120, 100%, 40%);">+  else {</span><br><span style="color: hsl(120, 100%, 40%);">+                /* N. B: normally receiving 0 bytes means that we should close the connection and re-establish it</span><br><span style="color: hsl(120, 100%, 40%);">+                but to test autoreconnection logic we ignore it in here to let the test run till completion */</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGCLI(cli, "0-byte read, auto-reconnect will be triggered if enabled\n");</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!cli_data) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGCLI(cli, "initial read, contacting server\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         osmo_stream_cli_set_data(cli, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+           CLI_SND(cli, "Doh, responding to server :-D");</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* client helpers */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct osmo_stream_cli *init_client_reconnection(struct osmo_stream_cli *cli, bool autoreconnect)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     /* setting negative timeout ensures that we disable reconnection logic */</span><br><span style="color: hsl(120, 100%, 40%);">+     osmo_stream_cli_set_reconnect_timeout(cli, autoreconnect ? 9 : -1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (osmo_stream_cli_open(cli) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               LOGCLI(cli, "unable to open client\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return cli;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct osmo_stream_cli *make_client(void *ctx, const char *host, unsigned port, bool autoreconnect)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct osmo_stream_cli *cli = osmo_stream_cli_create(ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!cli) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printf("Unable to create client\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("Prepare %s stream client...\n", ASTR(autoreconnect));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     osmo_stream_cli_set_addr(cli, host);</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_stream_cli_set_port(cli, port);</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_stream_cli_set_connect_cb(cli, connect_cb_cli);</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_stream_cli_set_read_cb(cli, read_cb_cli);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return init_client_reconnection(cli, autoreconnect);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* server defs */</span><br><span style="color: hsl(120, 100%, 40%);">+#define LOGLNK(lnk, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("[%s] Server's %s(): " fmt, osmo_stream_srv_link_get_data(lnk) ? "OK" : "NA", __func__, ##args)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define LOGSRV(srv, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("[%s|%s] Server's %s(): " fmt, osmo_stream_srv_get_data(srv) ? "OK" : "NA", \</span><br><span style="color: hsl(120, 100%, 40%);">+               osmo_stream_srv_link_get_data(osmo_stream_srv_get_master(srv)) ? "OK" : "NA", __func__, ##args)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define SRV_SND(srv, m) do {                                              \</span><br><span style="color: hsl(120, 100%, 40%);">+             struct msgb *msg = make_msgb(m);                        \</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGSRV(srv, "sent %d bytes message: %s\n",            \</span><br><span style="color: hsl(120, 100%, 40%);">+                    msg->len, msgb_hexdump(msg));                 \</span><br><span style="color: hsl(120, 100%, 40%);">+             osmo_stream_srv_send(srv, msg);                         \</span><br><span style="color: hsl(120, 100%, 40%);">+     } while(0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* server helpers */</span><br><span style="color: hsl(120, 100%, 40%);">+static bool subsequent_read(struct osmo_stream_srv *srv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       if (osmo_stream_srv_get_data(srv))</span><br><span style="color: hsl(120, 100%, 40%);">+            return true;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        osmo_stream_srv_set_data(srv, srv);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return false;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void request_test_stop(struct osmo_stream_srv *srv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     osmo_stream_srv_link_set_data(osmo_stream_srv_get_master(srv), NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static bool test_stop_requested(struct osmo_stream_srv_link *lnk)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      if (osmo_stream_srv_link_get_data(lnk))</span><br><span style="color: hsl(120, 100%, 40%);">+               return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ return true;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* server callbacks */</span><br><span style="color: hsl(120, 100%, 40%);">+int read_cb_srv(struct osmo_stream_srv *srv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    int bytes;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct msgb *msg = make_msgb(NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!msg)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     LOGSRV(srv, "callback triggered\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      bytes = osmo_stream_srv_recv(srv, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (bytes <= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (bytes < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                     LOGSRV(srv, "unable to receive message: %s\n", strerror(-bytes));</span><br><span style="color: hsl(120, 100%, 40%);">+           else {</span><br><span style="color: hsl(120, 100%, 40%);">+                        LOGSRV(srv, "client have already closed connection\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   /* if client have already closed the connection,</span><br><span style="color: hsl(120, 100%, 40%);">+                         than it must be subsequent (after reconnect) call */</span><br><span style="color: hsl(120, 100%, 40%);">+                       request_test_stop(srv);</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+             osmo_stream_srv_destroy(srv);</span><br><span style="color: hsl(120, 100%, 40%);">+         return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGSRV(srv, "received %d(%d) bytes: %s\n", bytes, msg->len, msgb_hexdump(msg));</span><br><span style="color: hsl(120, 100%, 40%);">+          SRV_SND(srv, __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (subsequent_read(srv)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGSRV(srv, "force client disconnect on subsequent call\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                osmo_stream_srv_destroy(srv);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGSRV(srv, "keep initial client connection\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int close_cb_srv(struct osmo_stream_srv *ignored)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int accept_cb_srv(struct osmo_stream_srv_link *lnk, int fd)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_stream_srv *srv = osmo_stream_srv_create(osmo_stream_srv_link_get_data(lnk), lnk, fd,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                          read_cb_srv, close_cb_srv, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!srv) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGLNK(lnk, "error while creating connection\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_recon(void *ctx, const char *host, unsigned port, unsigned steps, struct osmo_stream_srv_link *lnk,</span><br><span style="color: hsl(120, 100%, 40%);">+                       bool autoreconnect)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_stream_cli *cli = make_client(ctx, host, port, autoreconnect);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!cli)</span><br><span style="color: hsl(120, 100%, 40%);">+             return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("=======================================\n");</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("Client/Server entering %s event loop...\n", ASTR(autoreconnect));</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("=======================================\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      osmo_stream_srv_link_set_data(lnk, ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    while(steps--) {</span><br><span style="color: hsl(120, 100%, 40%);">+              osmo_select_main(0);</span><br><span style="color: hsl(120, 100%, 40%);">+          fprintf(stderr, "\n%s test step %u [client %s, server %s], FD reg %u\n", ASTR(autoreconnect), steps,</span><br><span style="color: hsl(120, 100%, 40%);">+                        osmo_stream_cli_get_data(cli) ? "OK" : "NA",</span><br><span style="color: hsl(120, 100%, 40%);">+                      osmo_stream_srv_link_get_data(lnk) ? "OK" : "NA",</span><br><span style="color: hsl(120, 100%, 40%);">+                 osmo_fd_is_registered(osmo_stream_cli_get_ofd(cli)));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               if (test_stop_requested(lnk)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       printf("Server requested test termination\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                      steps = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   osmo_stream_cli_destroy(cli);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("%s test complete.\n\n", ASTR(autoreconnect));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int main(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_stream_srv_link *srv;</span><br><span style="color: hsl(120, 100%, 40%);">+     char *host = "127.0.0.11";</span><br><span style="color: hsl(120, 100%, 40%);">+  unsigned port = 1111;</span><br><span style="color: hsl(120, 100%, 40%);">+ void *tall_test = talloc_named_const(NULL, 1, "osmo_stream_test");</span><br><span style="color: hsl(120, 100%, 40%);">+  msgb_talloc_ctx_init(tall_test, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+   osmo_init_logging2(tall_test, &osmo_stream_test_log_info);</span><br><span style="color: hsl(120, 100%, 40%);">+        log_set_log_level(osmo_stderr_target, LOGL_INFO);</span><br><span style="color: hsl(120, 100%, 40%);">+     log_set_use_color(osmo_stderr_target, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+     log_set_print_category_hex(osmo_stderr_target, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+    log_set_print_filename(osmo_stderr_target, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      printf("Preparing stream server...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+     srv = osmo_stream_srv_link_create(tall_test);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!srv) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printf("Unable to create server\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return EXIT_FAILURE;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   osmo_stream_srv_link_set_addr(srv, host);</span><br><span style="color: hsl(120, 100%, 40%);">+     osmo_stream_srv_link_set_port(srv, port);</span><br><span style="color: hsl(120, 100%, 40%);">+     osmo_stream_srv_link_set_accept_cb(srv, accept_cb_srv);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (osmo_stream_srv_link_open(srv) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+          printf("Unable to open server\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return EXIT_FAILURE;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   test_recon(tall_test, host, port, 12, srv, true);</span><br><span style="color: hsl(120, 100%, 40%);">+     test_recon(tall_test, host, port, 8, srv, false);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   osmo_stream_srv_link_destroy(srv);</span><br><span style="color: hsl(120, 100%, 40%);">+    printf("Stream tests completed\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return EXIT_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/tests/stream/stream_test.err b/tests/stream/stream_test.err</span><br><span>new file mode 100644</span><br><span>index 0000000..07cc7b0</span><br><span>--- /dev/null</span><br><span>+++ b/tests/stream/stream_test.err</span><br><span>@@ -0,0 +1,43 @@</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+autoreconnecting test step 11 [client NA, server OK], FD reg 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+autoreconnecting test step 10 [client NA, server OK], FD reg 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+autoreconnecting test step 9 [client NA, server OK], FD reg 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+autoreconnecting test step 8 [client NA, server OK], FD reg 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+autoreconnecting test step 7 [client OK, server OK], FD reg 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+autoreconnecting test step 6 [client OK, server OK], FD reg 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+autoreconnecting test step 5 [client OK, server OK], FD reg 1</span><br><span style="color: hsl(120, 100%, 40%);">+[ CONNECTED] osmo_stream_cli_recv(): connection closed with srv</span><br><span style="color: hsl(120, 100%, 40%);">+[      NONE] osmo_stream_cli_reconnect(): retrying in 9 seconds...</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+autoreconnecting test step 4 [client OK, server OK], FD reg 0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+autoreconnecting test step 3 [client OK, server OK], FD reg 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+autoreconnecting test step 2 [client OK, server OK], FD reg 0</span><br><span style="color: hsl(120, 100%, 40%);">+connection closed with srv</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+autoreconnecting test step 1 [client OK, server NA], FD reg 0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+non-reconnecting test step 7 [client NA, server OK], FD reg 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+non-reconnecting test step 6 [client NA, server OK], FD reg 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+non-reconnecting test step 5 [client NA, server OK], FD reg 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+non-reconnecting test step 4 [client NA, server OK], FD reg 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+non-reconnecting test step 3 [client OK, server OK], FD reg 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+non-reconnecting test step 2 [client OK, server OK], FD reg 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+non-reconnecting test step 1 [client OK, server OK], FD reg 1</span><br><span style="color: hsl(120, 100%, 40%);">+[ CONNECTED] osmo_stream_cli_recv(): connection closed with srv</span><br><span style="color: hsl(120, 100%, 40%);">+[      NONE] osmo_stream_cli_reconnect(): not reconnecting, disabled.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+non-reconnecting test step 0 [client OK, server OK], FD reg 0</span><br><span>diff --git a/tests/stream/stream_test.ok b/tests/stream/stream_test.ok</span><br><span>new file mode 100644</span><br><span>index 0000000..7b6fb95</span><br><span>--- /dev/null</span><br><span>+++ b/tests/stream/stream_test.ok</span><br><span>@@ -0,0 +1,51 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Preparing stream server...</span><br><span style="color: hsl(120, 100%, 40%);">+Prepare autoreconnecting stream client...</span><br><span style="color: hsl(120, 100%, 40%);">+=======================================</span><br><span style="color: hsl(120, 100%, 40%);">+Client/Server entering autoreconnecting event loop...</span><br><span style="color: hsl(120, 100%, 40%);">+=======================================</span><br><span style="color: hsl(120, 100%, 40%);">+[NA] Client's connect_cb_cli(): callback triggered <initial></span><br><span style="color: hsl(120, 100%, 40%);">+[NA] Client's connect_cb_cli(): sent 29 bytes message: 48 69 21 20 66 72 6f 6d 20 63 6f 6e 6e 65 63 74 20 63 61 6c 6c 62 61 63 6b 20 3a 2d 50 </span><br><span style="color: hsl(120, 100%, 40%);">+[NA|OK] Server's read_cb_srv(): callback triggered</span><br><span style="color: hsl(120, 100%, 40%);">+[NA|OK] Server's read_cb_srv(): received 29(29) bytes: 48 69 21 20 66 72 6f 6d 20 63 6f 6e 6e 65 63 74 20 63 61 6c 6c 62 61 63 6b 20 3a 2d 50 </span><br><span style="color: hsl(120, 100%, 40%);">+[NA|OK] Server's read_cb_srv(): sent 11 bytes message: 72 65 61 64 5f 63 62 5f 73 72 76 </span><br><span style="color: hsl(120, 100%, 40%);">+[OK|OK] Server's read_cb_srv(): keep initial client connection</span><br><span style="color: hsl(120, 100%, 40%);">+[NA] Client's read_cb_cli(): callback triggered</span><br><span style="color: hsl(120, 100%, 40%);">+[NA] Client's read_cb_cli(): received 11(11) bytes: 72 65 61 64 5f 63 62 5f 73 72 76 </span><br><span style="color: hsl(120, 100%, 40%);">+[NA] Client's read_cb_cli(): initial read, contacting server</span><br><span style="color: hsl(120, 100%, 40%);">+[OK] Client's read_cb_cli(): 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 </span><br><span style="color: hsl(120, 100%, 40%);">+[OK|OK] Server's read_cb_srv(): callback triggered</span><br><span style="color: hsl(120, 100%, 40%);">+[OK|OK] Server's read_cb_srv(): 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 </span><br><span style="color: hsl(120, 100%, 40%);">+[OK|OK] Server's read_cb_srv(): sent 11 bytes message: 72 65 61 64 5f 63 62 5f 73 72 76 </span><br><span style="color: hsl(120, 100%, 40%);">+[OK|OK] Server's read_cb_srv(): force client disconnect on subsequent call</span><br><span style="color: hsl(120, 100%, 40%);">+[OK] Client's read_cb_cli(): callback triggered</span><br><span style="color: hsl(120, 100%, 40%);">+[OK] Client's read_cb_cli(): 0-byte read, auto-reconnect will be triggered if enabled</span><br><span style="color: hsl(120, 100%, 40%);">+[OK] Client's connect_cb_cli(): callback triggered <reconnected></span><br><span style="color: hsl(120, 100%, 40%);">+[OK] Client's connect_cb_cli(): closing connection</span><br><span style="color: hsl(120, 100%, 40%);">+[NA|OK] Server's read_cb_srv(): callback triggered</span><br><span style="color: hsl(120, 100%, 40%);">+[NA|OK] Server's read_cb_srv(): client have already closed connection</span><br><span style="color: hsl(120, 100%, 40%);">+Server requested test termination</span><br><span style="color: hsl(120, 100%, 40%);">+autoreconnecting test complete.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Prepare non-reconnecting stream client...</span><br><span style="color: hsl(120, 100%, 40%);">+=======================================</span><br><span style="color: hsl(120, 100%, 40%);">+Client/Server entering non-reconnecting event loop...</span><br><span style="color: hsl(120, 100%, 40%);">+=======================================</span><br><span style="color: hsl(120, 100%, 40%);">+[NA] Client's connect_cb_cli(): callback triggered <initial></span><br><span style="color: hsl(120, 100%, 40%);">+[NA] Client's connect_cb_cli(): sent 29 bytes message: 48 69 21 20 66 72 6f 6d 20 63 6f 6e 6e 65 63 74 20 63 61 6c 6c 62 61 63 6b 20 3a 2d 50 </span><br><span style="color: hsl(120, 100%, 40%);">+[NA|OK] Server's read_cb_srv(): callback triggered</span><br><span style="color: hsl(120, 100%, 40%);">+[NA|OK] Server's read_cb_srv(): received 29(29) bytes: 48 69 21 20 66 72 6f 6d 20 63 6f 6e 6e 65 63 74 20 63 61 6c 6c 62 61 63 6b 20 3a 2d 50 </span><br><span style="color: hsl(120, 100%, 40%);">+[NA|OK] Server's read_cb_srv(): sent 11 bytes message: 72 65 61 64 5f 63 62 5f 73 72 76 </span><br><span style="color: hsl(120, 100%, 40%);">+[OK|OK] Server's read_cb_srv(): keep initial client connection</span><br><span style="color: hsl(120, 100%, 40%);">+[NA] Client's read_cb_cli(): callback triggered</span><br><span style="color: hsl(120, 100%, 40%);">+[NA] Client's read_cb_cli(): received 11(11) bytes: 72 65 61 64 5f 63 62 5f 73 72 76 </span><br><span style="color: hsl(120, 100%, 40%);">+[NA] Client's read_cb_cli(): initial read, contacting server</span><br><span style="color: hsl(120, 100%, 40%);">+[OK] Client's read_cb_cli(): 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 </span><br><span style="color: hsl(120, 100%, 40%);">+[OK|OK] Server's read_cb_srv(): callback triggered</span><br><span style="color: hsl(120, 100%, 40%);">+[OK|OK] Server's read_cb_srv(): 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 </span><br><span style="color: hsl(120, 100%, 40%);">+[OK|OK] Server's read_cb_srv(): sent 11 bytes message: 72 65 61 64 5f 63 62 5f 73 72 76 </span><br><span style="color: hsl(120, 100%, 40%);">+[OK|OK] Server's read_cb_srv(): force client disconnect on subsequent call</span><br><span style="color: hsl(120, 100%, 40%);">+[OK] Client's read_cb_cli(): callback triggered</span><br><span style="color: hsl(120, 100%, 40%);">+[OK] Client's read_cb_cli(): 0-byte read, auto-reconnect will be triggered if enabled</span><br><span style="color: hsl(120, 100%, 40%);">+non-reconnecting test complete.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Stream tests completed</span><br><span>diff --git a/tests/testsuite.at b/tests/testsuite.at</span><br><span>index 67b91c6..8eb389d 100644</span><br><span>--- a/tests/testsuite.at</span><br><span>+++ b/tests/testsuite.at</span><br><span>@@ -1,6 +1,13 @@</span><br><span> AT_INIT</span><br><span> AT_BANNER([Regression tests.])</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+AT_SETUP([stream_test])</span><br><span style="color: hsl(120, 100%, 40%);">+AT_KEYWORDS([stream_test])</span><br><span style="color: hsl(120, 100%, 40%);">+cat $abs_srcdir/stream/stream_test.ok > expout</span><br><span style="color: hsl(120, 100%, 40%);">+cat $abs_srcdir/stream/stream_test.err > experr</span><br><span style="color: hsl(120, 100%, 40%);">+AT_CHECK([$abs_top_builddir/tests/stream/stream_test], [0], [expout], [experr])</span><br><span style="color: hsl(120, 100%, 40%);">+AT_CLEANUP</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> AT_SETUP([osmux_test])</span><br><span> AT_KEYWORDS([osmux_test])</span><br><span> cat $abs_srcdir/osmux/osmux_test.ok > expout</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/12837">change 12837</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/12837"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmo-netif </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I336f79970982ed8e1d73b73d54fa4c27ba8bce8e </div>
<div style="display:none"> Gerrit-Change-Number: 12837 </div>
<div style="display:none"> Gerrit-PatchSet: 18 </div>
<div style="display:none"> Gerrit-Owner: Max <msuraev@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: Max <msuraev@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Pau Espin Pedrol <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: daniel <dwillmann@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: osmith <osmith@sysmocom.de> </div>