diff options
| author | Garrett D'Amore <garrett@damore.org> | 2024-10-13 10:07:14 -0700 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2024-10-13 10:07:14 -0700 |
| commit | 0cd24285d4f7bbb3cde20ce3ee268336b285dcf9 (patch) | |
| tree | b0d50eed624182c2f0a5023794d642214618cac6 /src/sp | |
| parent | 0bef8c0aa19042d618f9953f643b9150a5ae0ea5 (diff) | |
| download | nng-0cd24285d4f7bbb3cde20ce3ee268336b285dcf9.tar.gz nng-0cd24285d4f7bbb3cde20ce3ee268336b285dcf9.tar.bz2 nng-0cd24285d4f7bbb3cde20ce3ee268336b285dcf9.zip | |
UDP: burst testing to improve coverage
We are finding that on darwin its very easy for us to lose UDP messages
as the socket buffer appears to be depressingly small.
Diffstat (limited to 'src/sp')
| -rw-r--r-- | src/sp/transport/udp/udp.c | 34 | ||||
| -rw-r--r-- | src/sp/transport/udp/udp_tran_test.c | 112 |
2 files changed, 136 insertions, 10 deletions
diff --git a/src/sp/transport/udp/udp.c b/src/sp/transport/udp/udp.c index b55fcdb1..df5845fe 100644 --- a/src/sp/transport/udp/udp.c +++ b/src/sp/transport/udp/udp.c @@ -1289,7 +1289,8 @@ udp_timer_cb(void *arg) } static int -udp_ep_init(udp_ep **epp, nng_url *url, nni_sock *sock) +udp_ep_init(udp_ep **epp, nng_url *url, nni_sock *sock, nni_dialer *dialer, + nni_listener *listener) { udp_ep *ep; int rv; @@ -1432,7 +1433,29 @@ udp_ep_init(udp_ep **epp, nng_url *url, nni_sock *sock) nni_stat_init(&ep->st_snd_nobuf, &snd_nobuf_info); nni_stat_init(&ep->st_peer_inactive, &peer_inactive_info); - nni_stat_set_value(&ep->st_rcv_max, ep->rcvmax); + if (listener) { + nni_listener_add_stat(listener, &ep->st_rcv_max); + nni_listener_add_stat(listener, &ep->st_copy_max); + nni_listener_add_stat(listener, &ep->st_rcv_copy); + nni_listener_add_stat(listener, &ep->st_rcv_nocopy); + nni_listener_add_stat(listener, &ep->st_rcv_reorder); + nni_listener_add_stat(listener, &ep->st_rcv_toobig); + nni_listener_add_stat(listener, &ep->st_rcv_nomatch); + nni_listener_add_stat(listener, &ep->st_rcv_nobuf); + nni_listener_add_stat(listener, &ep->st_snd_toobig); + nni_listener_add_stat(listener, &ep->st_snd_nobuf); + } else { + nni_dialer_add_stat(dialer, &ep->st_rcv_max); + nni_dialer_add_stat(dialer, &ep->st_copy_max); + nni_dialer_add_stat(dialer, &ep->st_rcv_copy); + nni_dialer_add_stat(dialer, &ep->st_rcv_nocopy); + nni_dialer_add_stat(dialer, &ep->st_rcv_reorder); + nni_dialer_add_stat(dialer, &ep->st_rcv_toobig); + nni_dialer_add_stat(dialer, &ep->st_rcv_nomatch); + nni_dialer_add_stat(dialer, &ep->st_rcv_nobuf); + nni_dialer_add_stat(dialer, &ep->st_snd_toobig); + nni_dialer_add_stat(dialer, &ep->st_snd_nobuf); + } // schedule our timer callback - forever for now // adjusted automatically as we add pipes or other @@ -1474,11 +1497,10 @@ udp_dialer_init(void **dp, nng_url *url, nni_dialer *ndialer) return (rv); } - if ((rv = udp_ep_init(&ep, url, sock)) != 0) { + if ((rv = udp_ep_init(&ep, url, sock, ndialer, NULL)) != 0) { return (rv); } - nni_dialer_add_stat(ndialer, &ep->st_rcv_max); *dp = ep; return (0); } @@ -1497,13 +1519,11 @@ udp_listener_init(void **lp, nng_url *url, nni_listener *nlistener) return (rv); } - if ((rv = udp_ep_init(&ep, url, sock)) != 0) { + if ((rv = udp_ep_init(&ep, url, sock, NULL, nlistener)) != 0) { return (rv); } ep->self_sa = sa; - nni_listener_add_stat(nlistener, &ep->st_rcv_max); - *lp = ep; return (0); } diff --git a/src/sp/transport/udp/udp_tran_test.c b/src/sp/transport/udp/udp_tran_test.c index c2b515e8..304df097 100644 --- a/src/sp/transport/udp/udp_tran_test.c +++ b/src/sp/transport/udp/udp_tran_test.c @@ -1,8 +1,5 @@ // // Copyright 2024 Staysail Systems, Inc. <info@staysail.tech> -// Copyright 2018 Capitar IT Group BV <info@capitar.com> -// Copyright 2018 Devolutions <info@devolutions.net> -// Copyright 2018 Cody Piersall <cody.piersall@gmail.com> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -195,6 +192,113 @@ test_udp_recv_copy(void) NUTS_CLOSE(s1); } +void +test_udp_multi_send_recv(void) +{ + char msg[256]; + char buf[256]; + nng_socket s0; + nng_socket s1; + nng_listener l; + nng_dialer d; + size_t sz; + char *addr; + + NUTS_ADDR(addr, "udp"); + + NUTS_OPEN(s0); + NUTS_PASS(nng_socket_set_ms(s0, NNG_OPT_RECVTIMEO, 100)); + NUTS_PASS(nng_socket_set_ms(s0, NNG_OPT_SENDTIMEO, 100)); + NUTS_PASS(nng_listener_create(&l, s0, addr)); + NUTS_PASS(nng_listener_set_size(l, NNG_OPT_UDP_COPY_MAX, 100)); + NUTS_PASS(nng_listener_get_size(l, NNG_OPT_UDP_COPY_MAX, &sz)); + NUTS_TRUE(sz == 100); + NUTS_PASS(nng_listener_start(l, 0)); + + NUTS_OPEN(s1); + NUTS_PASS(nng_socket_set_ms(s1, NNG_OPT_RECVTIMEO, 100)); + NUTS_PASS(nng_socket_set_ms(s1, NNG_OPT_SENDTIMEO, 100)); + NUTS_PASS(nng_dialer_create(&d, s1, addr)); + NUTS_PASS(nng_dialer_set_size(d, NNG_OPT_UDP_COPY_MAX, 100)); + NUTS_PASS(nng_dialer_get_size(d, NNG_OPT_UDP_COPY_MAX, &sz)); + NUTS_PASS(nng_dialer_start(d, 0)); + nng_msleep(100); + + for (int i = 0; i < 1000; i++) { + NUTS_PASS(nng_send(s1, msg, 95, 0)); + NUTS_PASS(nng_recv(s0, buf, &sz, 0)); + NUTS_TRUE(sz == 95); + NUTS_PASS(nng_send(s0, msg, 95, 0)); + NUTS_PASS(nng_recv(s1, buf, &sz, 0)); + NUTS_TRUE(sz == 95); + } + NUTS_CLOSE(s0); + NUTS_CLOSE(s1); +} + +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; + + NUTS_ADDR(addr, "udp"); + + 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)); + NUTS_PASS(nng_listener_create(&l, s0, addr)); + NUTS_PASS(nng_listener_set_size(l, NNG_OPT_UDP_COPY_MAX, 100)); + NUTS_PASS(nng_listener_get_size(l, NNG_OPT_UDP_COPY_MAX, &sz)); + NUTS_TRUE(sz == 100); + NUTS_PASS(nng_listener_start(l, 0)); + + NUTS_OPEN(s1); + NUTS_PASS(nng_socket_set_ms(s1, NNG_OPT_RECVTIMEO, 10)); + NUTS_PASS(nng_socket_set_ms(s1, NNG_OPT_SENDTIMEO, 1000)); + NUTS_PASS(nng_dialer_create(&d, s1, addr)); + NUTS_PASS(nng_dialer_set_size(d, NNG_OPT_UDP_COPY_MAX, 100)); + NUTS_PASS(nng_dialer_get_size(d, NNG_OPT_UDP_COPY_MAX, &sz)); + NUTS_PASS(nng_dialer_start(d, 0)); + nng_msleep(100); + + float actual = 0; + float expect = 0; + int burst = 4; + int count = 20; + + // 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++) { + for (int j = 0; j < burst; j++) { + NUTS_PASS(nng_send(s1, msg, 95, 0)); + expect++; + } + for (int j = 0; j < burst; j++) { + if (nng_recv(s0, buf, &sz, 0) == 0) { + NUTS_TRUE(sz == 95); + actual++; + } + } + NUTS_PASS(nng_send(s0, msg, 95, 0)); + NUTS_PASS(nng_recv(s1, buf, &sz, 0)); + NUTS_TRUE(sz == 95); + } + NUTS_TRUE(actual <= expect); + NUTS_TRUE( + actual / expect > 0.80); // maximum reasonable packet loss of 20% + NUTS_MSG("Packet loss: %.02f (got %.f of %.f)", 1.0 - actual / expect, + actual, expect); + NUTS_CLOSE(s0); + NUTS_CLOSE(s1); +} + NUTS_TESTS = { { "udp wild card connect fail", test_udp_wild_card_connect_fail }, @@ -205,5 +309,7 @@ NUTS_TESTS = { { "udp malformed address", test_udp_malformed_address }, { "udp recv max", test_udp_recv_max }, { "udp recv copy", test_udp_recv_copy }, + { "udp multi send recv", test_udp_multi_send_recv }, + { "udp multi small burst", test_udp_multi_small_burst }, { NULL, NULL }, }; |
