aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2024-11-04 21:59:53 -0800
committerGarrett D'Amore <garrett@damore.org>2024-11-04 22:40:23 -0800
commit75eb6f3cefe7979ede8c58cd6fde01ea1618cbbb (patch)
treeda2f1f4b2fab6cc36cd3951d791a0f3a9ad4ce87
parent148582c78f59e7d47a8389b40613fef293c49c5c (diff)
downloadnng-75eb6f3cefe7979ede8c58cd6fde01ea1618cbbb.tar.gz
nng-75eb6f3cefe7979ede8c58cd6fde01ea1618cbbb.tar.bz2
nng-75eb6f3cefe7979ede8c58cd6fde01ea1618cbbb.zip
Use a callback for UDP burst test.
This seems to give much higher reliability in message receives, so we've tightened it up a bit for now.
-rw-r--r--src/sp/transport/udp/udp_tran_test.c93
1 files changed, 71 insertions, 22 deletions
diff --git a/src/sp/transport/udp/udp_tran_test.c b/src/sp/transport/udp/udp_tran_test.c
index 753e49b6..38a9a15e 100644
--- a/src/sp/transport/udp/udp_tran_test.c
+++ b/src/sp/transport/udp/udp_tran_test.c
@@ -237,21 +237,72 @@ test_udp_multi_send_recv(void)
NUTS_CLOSE(s1);
}
+typedef struct {
+ nng_aio *aio;
+ int pass;
+ int fail;
+ const char *expect;
+ size_t len;
+ nng_socket sock;
+} udp_recv_count;
+
+void
+udp_recv_count_cb(void *arg)
+{
+ udp_recv_count *c = arg;
+ nng_msg *m;
+ int rv;
+
+ rv = nng_aio_result(c->aio);
+ switch (rv) {
+ case NNG_ECLOSED:
+ case NNG_ECANCELED:
+ c->fail++;
+ return;
+ case NNG_ETIMEDOUT:
+ c->fail++;
+ break;
+ case 0:
+ m = nng_aio_get_msg(c->aio);
+ nng_aio_set_msg(c->aio, NULL);
+ if (nng_msg_len(m) != c->len) {
+ c->fail++;
+ } else {
+ c->pass++;
+ }
+ nng_msg_free(m);
+ break;
+ default:
+ c->fail++;
+ nng_log_warn(
+ NULL, "Unexpected recv error %s", nng_strerror(rv));
+ break;
+ }
+
+ nng_aio_set_timeout(c->aio, 1000);
+ nng_recv_aio(c->sock, c->aio);
+}
+
+// This test uses callbacks above to ensure we
+// receive as quickly as possible, reducing the likelihood
+// of dropped messages.
void
test_udp_multi_small_burst(void)
{
- char msg[256];
- char buf[256];
- nng_socket s0;
- nng_socket s1;
- nng_listener l;
- nng_dialer d;
- size_t sz;
- char *addr;
+ char msg[256];
+ nng_socket s0;
+ nng_socket s1;
+ nng_listener l;
+ nng_dialer d;
+ size_t sz;
+ char *addr;
+ udp_recv_count rc = { 0 };
NUTS_ENABLE_LOG(NNG_LOG_NOTICE);
NUTS_ADDR(addr, "udp");
+ NUTS_PASS(nng_aio_alloc(&rc.aio, udp_recv_count_cb, &rc));
+
NUTS_OPEN(s0);
NUTS_PASS(nng_socket_set_ms(s0, NNG_OPT_RECVTIMEO, 10));
NUTS_PASS(nng_socket_set_ms(s0, NNG_OPT_SENDTIMEO, 1000));
@@ -273,7 +324,7 @@ test_udp_multi_small_burst(void)
float actual = 0;
float expect = 0;
float require = 0.50;
- int burst = 4;
+ int burst = 20;
int count = 40;
#if defined(NNG_PLATFORM_WINDOWS)
// Windows seems to drop a lot - maybe because of virtualization
@@ -299,6 +350,12 @@ test_udp_multi_small_burst(void)
require = 0.0;
#endif
+ rc.sock = s0;
+ rc.len = 95;
+ rc.expect = msg;
+
+ nng_recv_aio(rc.sock, rc.aio);
+
// Experimentally at least on Darwin, we see some packet losses
// even for loopback. Loss rates appear depressingly high.
for (int i = 0; i < count; i++) {
@@ -306,20 +363,12 @@ test_udp_multi_small_burst(void)
(void) nng_send(s1, msg, 95, 0);
expect++;
}
- for (int j = 0; j < burst; j++) {
- if (nng_recv(s0, buf, &sz, 0) == 0) {
- if (sz != 95) {
- NUTS_TRUE(sz == 95);
- }
- actual++;
- }
- }
- (void) nng_send(s0, msg, 95, 0);
- (void) nng_recv(s1, buf, &sz, 0);
- if (sz != 95) {
- NUTS_TRUE(sz == 95);
- }
+ nng_msleep(20);
}
+ nng_msleep(10);
+ nng_aio_stop(rc.aio);
+ nng_aio_free(rc.aio);
+ actual = rc.pass;
NUTS_TRUE(actual <= expect);
NUTS_TRUE(actual / expect > require);
nng_log_notice("UDP", "Packet loss: %.02f (got %.f of %.f)",