aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2018-05-07 14:58:07 -0700
committerGarrett D'Amore <garrett@damore.org>2018-05-07 17:39:03 -0700
commite89202c83138bbc6bad1d5c5dcf55e00c0ee1800 (patch)
tree58f3e2bc5e824c34a6954dc6276bd77725794b69 /tools
parentd066d6d4307371f3bea1134a694dba18c381f564 (diff)
downloadnng-e89202c83138bbc6bad1d5c5dcf55e00c0ee1800.tar.gz
nng-e89202c83138bbc6bad1d5c5dcf55e00c0ee1800.tar.bz2
nng-e89202c83138bbc6bad1d5c5dcf55e00c0ee1800.zip
fixes #413 desire --count option for nngcat
fixes #249 nngcat needs test cases fixes #416 transports do not permit unlimited message size with 0 fixes #417 nngcat truncates input files to 4k fixes #348 nngcat should have switch to adjust maximum receive size
Diffstat (limited to 'tools')
-rw-r--r--tools/nngcat/CMakeLists.txt17
-rw-r--r--tools/nngcat/nngcat.c119
-rw-r--r--tools/nngcat/nngcat_ambiguous_test.sh29
-rw-r--r--tools/nngcat/nngcat_async_test.sh31
-rw-r--r--tools/nngcat/nngcat_dup_proto_test.sh21
-rw-r--r--tools/nngcat/nngcat_help_test.sh30
-rw-r--r--tools/nngcat/nngcat_incompat_test.sh72
-rw-r--r--tools/nngcat/nngcat_need_proto_test.sh21
-rw-r--r--tools/nngcat/nngcat_pubsub_test.sh43
-rw-r--r--tools/nngcat/nngcat_recvmaxsz_test.sh44
-rw-r--r--tools/nngcat/nngcat_unlimited_test.sh44
11 files changed, 441 insertions, 30 deletions
diff --git a/tools/nngcat/CMakeLists.txt b/tools/nngcat/CMakeLists.txt
index 3864c8e4..bcd356ee 100644
--- a/tools/nngcat/CMakeLists.txt
+++ b/tools/nngcat/CMakeLists.txt
@@ -13,4 +13,21 @@ if (NNG_ENABLE_NNGCAT)
target_include_directories (nngcat PUBLIC ${PROJECT_SOURCE_DIR}/src)
target_link_libraries (nngcat ${PROJECT_NAME})
install (TARGETS nngcat RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+ if (NNG_TESTS AND NNG_PLATFORM_POSIX)
+ macro(add_nngcat_test NAME TIMEOUT)
+ file (COPY ${NAME}_test.sh DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+ add_test (NAME ${NAME} COMMAND bash ${NAME}_test.sh)
+ set_tests_properties (${NAME} PROPERTIES TIMEOUT ${TIMEOUT})
+ endmacro()
+ add_nngcat_test (nngcat_async 10)
+ add_nngcat_test (nngcat_ambiguous 2)
+ add_nngcat_test (nngcat_need_proto 2)
+ add_nngcat_test (nngcat_dup_proto 2)
+ add_nngcat_test (nngcat_help 2)
+ add_nngcat_test (nngcat_incompat 2)
+ add_nngcat_test (nngcat_pubsub 20)
+ add_nngcat_test (nngcat_recvmaxsz 20)
+ add_nngcat_test (nngcat_unlimited 20)
+ endif()
endif()
diff --git a/tools/nngcat/nngcat.c b/tools/nngcat/nngcat.c
index c8a73859..132599e4 100644
--- a/tools/nngcat/nngcat.c
+++ b/tools/nngcat/nngcat.c
@@ -53,6 +53,8 @@ size_t keylen = 0;
void * certfile = NULL;
size_t certlen = 0;
const char * zthome = NULL;
+int count = 0;
+int recvmaxsz = -1;
// Options, must start at 1 because zero is sentinel.
enum options {
@@ -78,6 +80,7 @@ enum options {
OPT_SUBSCRIBE,
OPT_INTERVAL,
OPT_DELAY,
+ OPT_COUNT,
OPT_FORMAT,
OPT_RAW,
OPT_ASCII,
@@ -99,6 +102,7 @@ enum options {
OPT_KEYFILE,
OPT_CERTFILE,
OPT_VERSION,
+ OPT_RECVMAXSZ,
OPT_ZTHOME,
};
@@ -132,6 +136,18 @@ static nng_optspec opts[] = {
{ .o_name = "compat", .o_val = OPT_COMPAT },
{ .o_name = "async", .o_val = OPT_ASYNC },
{
+ .o_name = "recv-maxsz",
+ .o_short = 'Z',
+ .o_val = OPT_RECVMAXSZ,
+ .o_arg = true,
+ },
+ {
+ .o_name = "count",
+ .o_short = 'C',
+ .o_val = OPT_COUNT,
+ .o_arg = true,
+ },
+ {
.o_name = "delay",
.o_short = 'd',
.o_val = OPT_DELAY,
@@ -238,8 +254,18 @@ help(void)
printf(" --subscribe <topic> (only with --sub protocol)\n");
printf(" --silent (or alias -q)\n");
printf(" --verbose (or alias -v)\n");
+ printf(" --count <num> (or alias -C <num>)\n");
+ printf(" --delay <secs> (or alias -d <secs>)\n");
+ printf(" --interval <secs> (or alias -i <secs>)\n");
+ printf(" --recv-timeout <secs>\n");
+ printf(" --send-timeout <secs>\n");
+ printf(" --recv-maxsz <size> (or alias -Z <size>)\n");
printf(" --compat\n");
printf(" --async\n");
+ printf(" --insecure (or alias -k)\n");
+ printf(" --cacert <file>\n");
+ printf(" --cert <file> (or alias -E <file>)\n");
+ printf(" --key <file>\n");
printf(" --zt-home <path>\n");
printf("\n<src> may be one of:\n");
printf(" --file <file> (or alias -F <file>)\n");
@@ -279,38 +305,24 @@ static void
loadfile(const char *path, void **datap, size_t *lenp)
{
FILE * f;
- size_t cap;
char * data;
size_t len;
+
if ((f = fopen(path, "r")) == NULL) {
fatal("Cannot open file %s: %s", path, strerror(errno));
}
- cap = 4096;
- len = 0;
- if ((data = malloc(cap)) == NULL) {
+ if (fseek(f, 0, SEEK_END) != 0) {
+ fatal("Cannot seek to end of file: %s", strerror(errno));
+ }
+ len = ftell(f);
+ (void) fseek(f, 0, SEEK_SET);
+ if ((data = malloc(len + 1)) == NULL) {
fatal("Out of memory.");
}
- data[0] = '\0';
- for (;;) {
- size_t n;
- // Read until end of file, reallocating as needed.
- if (len == (cap - 1)) {
- void *old = data;
- cap *= 2;
- if ((data = realloc(old, cap)) == NULL) {
- fatal("Out of memory");
- }
- }
- n = fread(data + len, 1, cap - len, f);
- if (n == 0) {
- if (ferror(f)) {
- fatal("Read file %s failed: %s", path,
- strerror(errno));
- }
- break;
- }
- len += n;
- data[len] = '\0';
+ data[len] = '\0';
+
+ if (fread(data, 1, len, f) != len) {
+ fatal("Read file %s failed: %s", path, strerror(errno));
}
fclose(f);
*datap = data;
@@ -462,11 +474,16 @@ printmsg(char *buf, size_t len)
void
recvloop(nng_socket sock)
{
+ int iters = 0;
for (;;) {
int rv;
nng_msg *msg;
+ if ((count > 0) && (iters >= count)) {
+ break;
+ }
rv = nng_recvmsg(sock, &msg, 0);
+ iters++;
switch (rv) {
case NNG_ETIMEDOUT:
case NNG_ESTATE:
@@ -486,6 +503,7 @@ recvloop(nng_socket sock)
void
resploop(nng_socket sock)
{
+ int iters = 0;
for (;;) {
int rv;
nng_msg *msg;
@@ -502,12 +520,21 @@ resploop(nng_socket sock)
if ((rv = nng_sendmsg(sock, msg, 0)) != 0) {
fatal("Send error: %s", nng_strerror(rv));
}
+
+ iters++;
+ if ((count > 0) && (iters >= count)) {
+ break;
+ }
}
+
+ nng_msleep(200);
}
void
sendloop(nng_socket sock)
{
+ int iters = 0;
+
if (data == NULL) {
fatal("No data to send (specify with --data or --file)");
}
@@ -533,10 +560,13 @@ sendloop(nng_socket sock)
end = nng_clock();
delta = (nng_duration)(end - start);
+ iters++;
// By default, we don't loop.
- if (interval < 0) {
+ if (((interval < 0) && (count == 0)) ||
+ ((count > 0) && (iters >= count))) {
break;
}
+
// We sleep, but we account for time spent, so that our
// interval appears more or less constant. Of course
// if we took more than the interval here, then we skip
@@ -545,11 +575,15 @@ sendloop(nng_socket sock)
nng_msleep(interval - delta);
}
}
+ // Wait a bit to give queues a chance to drain.
+ nng_msleep(200);
}
void
sendrecv(nng_socket sock)
{
+ int iters = 0;
+
if (data == NULL) {
fatal("No data to send (specify with --data or --file)");
}
@@ -575,7 +609,7 @@ sendrecv(nng_socket sock)
if ((rv = nng_sendmsg(sock, msg, 0)) != 0) {
fatal("Send error: %s", nng_strerror(rv));
}
- if (interval < 0) {
+ if ((interval < 0) && (count == 0)) {
// Only one iteration through.
recvloop(sock);
break;
@@ -583,7 +617,8 @@ sendrecv(nng_socket sock)
// We would like to use recvloop, but we need to reset
// our timeout each time, as the timer counts down
- // towards zero.
+ // towards zero. Furthermore, with survey, we don't
+ // want to increment the iteration count.
for (;;) {
delta = (nng_duration)(nng_clock() - start);
@@ -620,6 +655,11 @@ sendrecv(nng_socket sock)
end = nng_clock();
delta = (nng_duration)(end - start);
+ iters++;
+ if ((count > 0) && (iters >= count)) {
+ break;
+ }
+
// We sleep, but we account for time spent, so that our
// interval appears more or less constant. Of course
// if we took more than the interval here, then we skip
@@ -687,6 +727,9 @@ main(int ac, const char **av)
snprintf(scratch, sizeof(scratch), "ipc:///%s", arg);
addrend = addaddr(addrend, val, scratch);
break;
+ case OPT_COUNT:
+ count = intarg(arg, 0x7fffffff);
+ break;
case OPT_SUBSCRIBE:
topicend = addtopic(topicend, arg);
break;
@@ -706,6 +749,12 @@ main(int ac, const char **av)
case OPT_RCV_TIMEO:
recvtimeo = intarg(arg, 86400) * 1000; // max 1 day
break;
+ case OPT_RECVMAXSZ:
+ recvmaxsz = intarg(arg, 0x7fffffff);
+ if (recvmaxsz == 0) {
+ recvmaxsz = 0x7fffffff;
+ }
+ break;
case OPT_COMPAT:
compat = 1;
break;
@@ -815,7 +864,11 @@ main(int ac, const char **av)
if (compat) {
if (async != 0) {
- fatal("Option --async and --compat are "
+ fatal("Options --async and --compat are "
+ "incompatible.");
+ }
+ if (count != 0) {
+ fatal("Options --count and --compat are "
"incompatible.");
}
if (proto == OPT_PAIR) {
@@ -990,6 +1043,12 @@ main(int ac, const char **av)
fatal("Unable to set send timeout: %s", nng_strerror(rv));
}
+ if ((recvmaxsz >= 0) &&
+ ((rv = nng_setopt_size(sock, NNG_OPT_RECVMAXSZ, recvmaxsz)) !=
+ 0)) {
+ fatal("Unable to set max receive size: %s", nng_strerror(rv));
+ }
+
for (struct addr *a = addrs; a != NULL; a = a->next) {
char * act;
nng_listener l;
@@ -1109,7 +1168,7 @@ main(int ac, const char **av)
sendrecv(sock);
break;
default:
- fatal("Protocol handling unimplmented.");
+ fatal("Protocol handling unimplemented.");
}
exit(0);
diff --git a/tools/nngcat/nngcat_ambiguous_test.sh b/tools/nngcat/nngcat_ambiguous_test.sh
new file mode 100644
index 00000000..54aec7f5
--- /dev/null
+++ b/tools/nngcat/nngcat_ambiguous_test.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+#
+# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+# Copyright 2018 Capitar IT Group BV <info@capitar.com>
+#
+# This software is supplied under the terms of the MIT License, a
+# copy of which should be located in the distribution where this
+# file was obtained (LICENSE.txt). A copy of the license may also be
+# found online at https://opensource.org/licenses/MIT.
+#
+
+NNGCAT=${NNGCAT:-./nngcat}
+CMD="${NNGCAT} --re --dial=tcp://127.0.0.1:27272"
+echo -n "Verify ambiguous options fail: "
+if ${CMD} >/dev/null 2>&1
+then
+ echo "Failed: ambigous accepted"
+ exit 1
+fi
+x=$(${CMD} 2>&1)
+if [[ ${x} =~ "ambiguous" ]]
+then
+ echo "pass"
+ exit 0
+fi
+
+echo "Failed: error did not match"
+exit 1
diff --git a/tools/nngcat/nngcat_async_test.sh b/tools/nngcat/nngcat_async_test.sh
new file mode 100644
index 00000000..527c92d1
--- /dev/null
+++ b/tools/nngcat/nngcat_async_test.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+#
+# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+# Copyright 2018 Capitar IT Group BV <info@capitar.com>
+#
+# This software is supplied under the terms of the MIT License, a
+# copy of which should be located in the distribution where this
+# file was obtained (LICENSE.txt). A copy of the license may also be
+# found online at https://opensource.org/licenses/MIT.
+#
+
+echo -n "Verify async connect: "
+
+NNGCAT=${NNGCAT:-./nngcat}
+ADDR="ipc:///tmp/nngcat_async_test"
+
+${NNGCAT} --async -d 1 --connect ${ADDR} --req0 -D "ping" &
+
+
+answer=$( ${NNGCAT} --rep0 --recv-timeout=3 --listen ${ADDR} -D "pong" --ascii 2>/dev/null )
+
+if [[ ${answer} == "ping" ]]
+then
+ echo "pass"
+ exit 0
+fi
+
+echo "Failed: req did not match"
+echo "RES: $answer"
+exit 1
diff --git a/tools/nngcat/nngcat_dup_proto_test.sh b/tools/nngcat/nngcat_dup_proto_test.sh
new file mode 100644
index 00000000..8ba9c3d6
--- /dev/null
+++ b/tools/nngcat/nngcat_dup_proto_test.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+#
+# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+# Copyright 2018 Capitar IT Group BV <info@capitar.com>
+#
+# This software is supplied under the terms of the MIT License, a
+# copy of which should be located in the distribution where this
+# file was obtained (LICENSE.txt). A copy of the license may also be
+# found online at https://opensource.org/licenses/MIT.
+#
+
+NNGCAT=${NNGCAT:-./nngcat}
+echo -n "Verify only a single protocol is allowed: "
+if ${NNGCAT} --pub0 --sub0 --dial=tcp://127.0.0.1:8989 >/dev/null 2>&1
+then
+ echo "Failed: duplicate protocols accepted"
+ exit 1
+fi
+echo "pass"
+exit 0
diff --git a/tools/nngcat/nngcat_help_test.sh b/tools/nngcat/nngcat_help_test.sh
new file mode 100644
index 00000000..2629633e
--- /dev/null
+++ b/tools/nngcat/nngcat_help_test.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+#
+# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+# Copyright 2018 Capitar IT Group BV <info@capitar.com>
+#
+# This software is supplied under the terms of the MIT License, a
+# copy of which should be located in the distribution where this
+# file was obtained (LICENSE.txt). A copy of the license may also be
+# found online at https://opensource.org/licenses/MIT.
+#
+
+NNGCAT=${NNGCAT:-./nngcat}
+echo -n "Verify nngcat help: "
+if ${NNGCAT} --help >/dev/null 2>&1
+then
+ echo "Failed: help didn't return 1"
+ exit 1
+fi
+x=$(${NNGCAT} --help 2>&1)
+if [[ ${x} =~ "Usage:" ]]
+then
+ echo "pass"
+ exit 0
+fi
+
+echo "Failed: usage did not match"
+echo "Output:"
+echo "$x"
+exit 1
diff --git a/tools/nngcat/nngcat_incompat_test.sh b/tools/nngcat/nngcat_incompat_test.sh
new file mode 100644
index 00000000..fcadef80
--- /dev/null
+++ b/tools/nngcat/nngcat_incompat_test.sh
@@ -0,0 +1,72 @@
+#!/bin/sh
+
+#
+# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+# Copyright 2018 Capitar IT Group BV <info@capitar.com>
+#
+# This software is supplied under the terms of the MIT License, a
+# copy of which should be located in the distribution where this
+# file was obtained (LICENSE.txt). A copy of the license may also be
+# found online at https://opensource.org/licenses/MIT.
+#
+
+NNGCAT=${NNGCAT:-./nngcat}
+echo "Verify incompatible options: "
+
+# Just bind something to this so other ones connect
+${NNGCAT} --pull0 --ascii -X /tmp/bogusipc &
+pid=$!
+
+trap "kill $pid && wait $pid 2>/dev/null" 0
+
+echo -n " --subscribe doesn't work with non-sub"
+if ${NNGCAT} --req0 -x /tmp/bogusipc --subscribe=oops >/dev/null 2>&1
+then
+ echo "fail"
+ exit 1
+fi
+echo "pass"
+
+echo -n " --interval doesn't work with recv only: "
+if ${NNGCAT} --interval 1 --pull -x /tmp/bogusipc >/dev/null 2>&1
+then
+ echo "fail"
+ exit 1
+fi
+echo "pass"
+
+echo -n " --pair1 doesn't work with --compat: "
+if ${NNGCAT} --compat --pair1 -x /tmp/bogusipc >/dev/null 2>&1
+then
+ echo "fail"
+ exit 1
+fi
+echo "pass"
+
+echo -n " --count doesn't work with --compat: "
+if ${NNGCAT} --compat --count=1 --pair0 -x /tmp/bogusipc >/dev/null 2>&1
+then
+ echo "fail"
+ exit 1
+fi
+echo "pass"
+
+echo -n " --count fails with non-integer: "
+if ${NNGCAT} --count=xyz --pair0 -x /tmp/bogusipc >/dev/null 2>&1
+then
+ echo "fail"
+ exit 1
+fi
+echo "pass"
+
+echo -n " --file fails with non-existing file: "
+if ${NNGCAT} --async --file=/nosuchfilehere --push0 -x /tmp/bogusipc >/dev/null 2>&1
+then
+ echo "fail"
+ exit 1
+fi
+echo "pass"
+
+echo "PASS."
+exit 0
+
diff --git a/tools/nngcat/nngcat_need_proto_test.sh b/tools/nngcat/nngcat_need_proto_test.sh
new file mode 100644
index 00000000..791b8c4b
--- /dev/null
+++ b/tools/nngcat/nngcat_need_proto_test.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+#
+# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+# Copyright 2018 Capitar IT Group BV <info@capitar.com>
+#
+# This software is supplied under the terms of the MIT License, a
+# copy of which should be located in the distribution where this
+# file was obtained (LICENSE.txt). A copy of the license may also be
+# found online at https://opensource.org/licenses/MIT.
+#
+
+NNGCAT=${NNGCAT:-./nngcat}
+echo -n "Verify a protocol is needed: "
+if ${NNGCAT} --dial=tcp://127.0.0.1:8989 >/dev/null 2>&1
+then
+ echo "Failed: protocol should be required"
+ exit 1
+fi
+echo "pass"
+exit 0
diff --git a/tools/nngcat/nngcat_pubsub_test.sh b/tools/nngcat/nngcat_pubsub_test.sh
new file mode 100644
index 00000000..a28cf865
--- /dev/null
+++ b/tools/nngcat/nngcat_pubsub_test.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+#
+# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+# Copyright 2018 Capitar IT Group BV <info@capitar.com>
+#
+# This software is supplied under the terms of the MIT License, a
+# copy of which should be located in the distribution where this
+# file was obtained (LICENSE.txt). A copy of the license may also be
+# found online at https://opensource.org/licenses/MIT.
+#
+
+echo -n "Verify pub sub: "
+
+NNGCAT=${NNGCAT:-./nngcat}
+ADDR="ipc:///tmp/nngcat_pub_sub_test"
+OUTPUT=/tmp/nngcat_pubsub_test.$$.out
+trap "rm $OUTPUT" 0
+
+${NNGCAT} --listen ${ADDR} --count=3 --recv-timeout=20 --sub0 --subscribe=one --subscribe=two --quoted > $OUTPUT 2>/dev/null &
+sleep 1
+# for speed of execution, run these in the background, they should be ignored
+${NNGCAT} -d 1 --connect ${ADDR} --pub0 --data "xyz" &
+${NNGCAT} -d 1 --connect ${ADDR} --pub0 -D "none swam" &
+# these we care about, due to ordering (checksum) so run them serially
+${NNGCAT} -d 1 --connect ${ADDR} --pub0 -D "one flew"
+${NNGCAT} -d 1 --connect ${ADDR} --pub0 --data "twofer test"
+${NNGCAT} -d 1 --connect ${ADDR} --pub0 --data "one more"
+
+wait $bgid 2>/dev/null
+
+sum=$(cksum ${OUTPUT})
+sum=${sum%% *}
+if [[ ${sum} == 3929078614 ]]
+then
+ echo "pass"
+ exit 0
+fi
+echo "FAIL: Checksum failed (Wanted 3929078614 got ${sum})"
+echo "OUTPUT:"
+cat ${OUTPUT}
+
+exit 1
diff --git a/tools/nngcat/nngcat_recvmaxsz_test.sh b/tools/nngcat/nngcat_recvmaxsz_test.sh
new file mode 100644
index 00000000..d77a5658
--- /dev/null
+++ b/tools/nngcat/nngcat_recvmaxsz_test.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+#
+# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+# Copyright 2018 Capitar IT Group BV <info@capitar.com>
+#
+# This software is supplied under the terms of the MIT License, a
+# copy of which should be located in the distribution where this
+# file was obtained (LICENSE.txt). A copy of the license may also be
+# found online at https://opensource.org/licenses/MIT.
+#
+
+echo -n "Verify maximum receive size: "
+
+NNGCAT=${NNGCAT:-./nngcat}
+ADDR="ipc:///tmp/nngcat_recvmaxsz_test"
+OUTPUT=/tmp/nngcat_recvmaxsz_test.$$.out
+trap "rm $OUTPUT" 0
+
+${NNGCAT} --listen ${ADDR} --count=3 --recv-maxsz=5 --pull0 --quoted > $OUTPUT 2>/dev/null &
+sleep 1
+# for speed of execution, run these in the background, they should be ignored
+${NNGCAT} --connect ${ADDR} --push0 --data "one"
+${NNGCAT} --connect ${ADDR} --push0 --data "55555"
+${NNGCAT} --connect ${ADDR} --push0 --data "666666"
+${NNGCAT} --connect ${ADDR} --push0 --data "7777777"
+${NNGCAT} --connect ${ADDR} --push0 --data "88888"
+
+wait $bgid 2>/dev/null
+
+sum=$(cksum ${OUTPUT})
+sum=${sum%% *}
+
+# This matches 3 lines of "one", "55555", "88888".
+if [[ ${sum} == 4122906158 ]]
+then
+ echo "pass"
+ exit 0
+fi
+echo "FAIL: Checksum failed (Wanted 3929078614 got ${sum})"
+echo "OUTPUT:"
+cat ${OUTPUT}
+
+exit 1
diff --git a/tools/nngcat/nngcat_unlimited_test.sh b/tools/nngcat/nngcat_unlimited_test.sh
new file mode 100644
index 00000000..7b5b4f2c
--- /dev/null
+++ b/tools/nngcat/nngcat_unlimited_test.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+#
+# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+# Copyright 2018 Capitar IT Group BV <info@capitar.com>
+#
+# This software is supplied under the terms of the MIT License, a
+# copy of which should be located in the distribution where this
+# file was obtained (LICENSE.txt). A copy of the license may also be
+# found online at https://opensource.org/licenses/MIT.
+#
+
+echo -n "Verify unlimited receive size: "
+
+NNGCAT=${NNGCAT:-./nngcat}
+ADDR="ipc:///tmp/nngcat_unlimited_test"
+INPUT=/tmp/nngcat_unlimited_test.$$.in
+OUTPUT=/tmp/nngcat_unlimited_test.$$.out
+trap "rm $OUTPUT $INPUT" 0
+
+# 4 MB
+dd if=/dev/urandom of=${INPUT} bs=1024 count=4096 >/dev/null 2>&1
+goodsum=$(cksum ${INPUT})
+goodsum=${goodsum%% *}
+
+${NNGCAT} --listen ${ADDR} --count=1 --recv-maxsz=0 --pull0 --raw > $OUTPUT 2>/dev/null &
+sleep 1
+# for speed of execution, run these in the background, they should be ignored
+${NNGCAT} --connect ${ADDR} --push0 --file ${INPUT}
+wait $bgid 2>/dev/null
+
+sum=$(cksum ${OUTPUT})
+sum=${sum%% *}
+
+if [[ ${sum} == ${goodsum} ]]
+then
+ echo "pass"
+ exit 0
+fi
+echo "FAIL: Checksum failed (Wanted ${goodsum} got ${sum})"
+echo "OUTPUT:"
+ls -la ${OUTPUT}
+
+exit 1