From 90f88cd23f3896c4212ddcb21a66318b1f17a7df Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Sat, 30 Nov 2024 08:11:06 -0500 Subject: [PATCH] tests: Convert device test to NUTS This also adds more tests for additional test cases (aio, and more validations of incompatible device configurations). --- src/sp/CMakeLists.txt | 1 + src/sp/device_test.c | 170 ++++++++++++++++++++++++++++++++++++++++++ tests/CMakeLists.txt | 1 - tests/device.c | 110 --------------------------- 4 files changed, 171 insertions(+), 111 deletions(-) create mode 100644 src/sp/device_test.c delete mode 100644 tests/device.c diff --git a/src/sp/CMakeLists.txt b/src/sp/CMakeLists.txt index 128aac15e..7ccaf051f 100644 --- a/src/sp/CMakeLists.txt +++ b/src/sp/CMakeLists.txt @@ -19,4 +19,5 @@ nng_sources( ) nng_test(pipe_test) +nng_test(device_test) nng_test(multistress_test) diff --git a/src/sp/device_test.c b/src/sp/device_test.c new file mode 100644 index 000000000..6d2ff1fba --- /dev/null +++ b/src/sp/device_test.c @@ -0,0 +1,170 @@ +// +// Copyright 2024 Staysail Systems, Inc. +// Copyright 2018 Capitar IT Group BV +// +// 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. +// + +#include + +#include +#include +#include + +#include + +struct dev_data { + nng_socket s1; + nng_socket s2; +}; + +void +dodev(void *arg) +{ + struct dev_data *d = arg; + + nng_device(d->s1, d->s2); +} + +#define SECOND(x) ((x) *1000) + +void +test_device_not_cooked(void) +{ + nng_socket cooked; + nng_socket raw; + NUTS_PASS(nng_pair1_open(&cooked)); + NUTS_PASS(nng_pair1_open_raw(&raw)); + NUTS_FAIL(nng_device(cooked, cooked), NNG_EINVAL); + NUTS_FAIL(nng_device(raw, cooked), NNG_EINVAL); + NUTS_FAIL(nng_device(cooked, raw), NNG_EINVAL); + NUTS_CLOSE(cooked); + NUTS_CLOSE(raw); +} + +void +test_device_incompatible(void) +{ + nng_socket s1; + nng_socket s2; + NUTS_PASS(nng_pair0_open_raw(&s1)); + NUTS_PASS(nng_pair1_open_raw(&s2)); + NUTS_FAIL(nng_device(s1, s2), NNG_EINVAL); + NUTS_CLOSE(s1); + NUTS_CLOSE(s2); +} +void +test_device_forward(void) +{ + nng_thread *thr; + struct dev_data d; + nng_duration tmo = SECOND(1); + nng_socket e1, e2; + + // will be a pair variant + NUTS_PASS(nng_pair1_open_raw(&d.s1)); + NUTS_PASS(nng_pair1_open_raw(&d.s2)); + NUTS_PASS(nng_pair1_open(&e1)); + NUTS_PASS(nng_pair1_open(&e2)); + NUTS_PASS(nng_socket_set_ms(e1, NNG_OPT_RECVTIMEO, tmo)); + NUTS_PASS(nng_socket_set_ms(e2, NNG_OPT_RECVTIMEO, tmo)); + NUTS_PASS(nng_socket_set_ms(e1, NNG_OPT_SENDTIMEO, tmo)); + NUTS_PASS(nng_socket_set_ms(e2, NNG_OPT_SENDTIMEO, tmo)); + + NUTS_MARRY(e1, d.s1); + NUTS_MARRY(e2, d.s2); + NUTS_PASS(nng_thread_create(&thr, dodev, &d)); + nng_thread_set_name(thr, "device thread"); + + NUTS_SEND(e1, "ping"); + NUTS_RECV(e2, "ping"); + NUTS_SEND(e2, "pong"); + NUTS_RECV(e1, "pong"); + + NUTS_CLOSE(e1); + NUTS_CLOSE(e2); + NUTS_CLOSE(d.s1); + NUTS_CLOSE(d.s2); + nng_thread_destroy(thr); +} + +void +test_device_reflect(void) +{ + nng_thread *thr; + struct dev_data d; + nng_duration tmo = SECOND(1); + nng_socket e1; + + // will be a pair variant + NUTS_PASS(nng_pair1_open_raw(&d.s1)); + d.s2 = d.s1; + NUTS_PASS(nng_pair1_open(&e1)); + NUTS_PASS(nng_socket_set_ms(e1, NNG_OPT_RECVTIMEO, tmo)); + NUTS_PASS(nng_socket_set_ms(e1, NNG_OPT_SENDTIMEO, tmo)); + + NUTS_MARRY(e1, d.s1); + NUTS_PASS(nng_thread_create(&thr, dodev, &d)); + nng_thread_set_name(thr, "device thread"); + + NUTS_SEND(e1, "ping"); + NUTS_RECV(e1, "ping"); + NUTS_SEND(e1, "pong"); + NUTS_RECV(e1, "pong"); + + NUTS_CLOSE(e1); + NUTS_CLOSE(d.s1); + nng_thread_destroy(thr); +} + +void +test_device_aio(void) +{ + struct dev_data d; + nng_duration tmo = SECOND(1); + nng_socket e1, e2; + nng_aio *aio; + + // will be a pair variant + NUTS_PASS(nng_pair1_open_raw(&d.s1)); + NUTS_PASS(nng_pair1_open_raw(&d.s2)); + NUTS_PASS(nng_pair1_open(&e1)); + NUTS_PASS(nng_pair1_open(&e2)); + NUTS_PASS(nng_socket_set_ms(e1, NNG_OPT_RECVTIMEO, tmo)); + NUTS_PASS(nng_socket_set_ms(e2, NNG_OPT_RECVTIMEO, tmo)); + NUTS_PASS(nng_socket_set_ms(e1, NNG_OPT_SENDTIMEO, tmo)); + NUTS_PASS(nng_socket_set_ms(e2, NNG_OPT_SENDTIMEO, tmo)); + + NUTS_MARRY(e1, d.s1); + NUTS_MARRY(e2, d.s2); + // cancellation of this aio is how we stop it + NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL)); + nng_device_aio(aio, d.s1, d.s2); + + NUTS_SEND(e1, "ping"); + NUTS_RECV(e2, "ping"); + NUTS_SEND(e2, "pong"); + NUTS_RECV(e1, "pong"); + + nng_aio_cancel(aio); + nng_aio_wait(aio); + NUTS_FAIL(nng_aio_result(aio), NNG_ECANCELED); + nng_aio_free(aio); + + NUTS_CLOSE(e1); + NUTS_CLOSE(e2); + NUTS_CLOSE(d.s1); + NUTS_CLOSE(d.s2); +} + +NUTS_TESTS = { + { "device not cooked", test_device_not_cooked }, + { "device incompatible", test_device_incompatible }, + { "device forward", test_device_forward }, + { "device reflect", test_device_reflect }, + { "device aio", test_device_aio }, + { NULL, NULL }, +}; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f41379e05..9d976dd90 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -124,7 +124,6 @@ else () endmacro(add_nng_test3) endif () -add_nng_test(device 5) add_nng_test(files 5) add_nng_test1(httpclient 60 NNG_SUPP_HTTP) add_nng_test1(httpserver 30 NNG_SUPP_HTTP) diff --git a/tests/device.c b/tests/device.c deleted file mode 100644 index f64bc6763..000000000 --- a/tests/device.c +++ /dev/null @@ -1,110 +0,0 @@ -// -// Copyright 2024 Staysail Systems, Inc. -// Copyright 2018 Capitar IT Group BV -// -// 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. -// - -#include - -#include -#include - -#include "convey.h" -#include "stubs.h" - -#define APPENDSTR(m, s) nng_msg_append(m, s, strlen(s)) -#define CHECKSTR(m, s) \ - So(nng_msg_len(m) == strlen(s)); \ - So(memcmp(nng_msg_body(m), s, strlen(s)) == 0) - -struct dev_data { - nng_socket s1; - nng_socket s2; -}; - -void -dodev(void *arg) -{ - struct dev_data *d = arg; - - nng_device(d->s1, d->s2); -} - -#define SECOND(x) ((x) *1000) - -Main({ - Test("PAIRv1 device", { - const char *addr1 = "inproc://dev1"; - const char *addr2 = "inproc://dev2"; - - Convey("We cannot create cooked mode device", { - nng_socket s1; - So(nng_pair1_open(&s1) == 0); - Reset({ nng_close(s1); }); - So(nng_device(s1, s1) == NNG_EINVAL); - }); - Convey("We can create a PAIRv1 device", { - nng_socket dev1; - nng_socket dev2; - nng_socket end1; - nng_socket end2; - nng_duration tmo; - nng_msg *msg; - nng_thread *thr; - - So(nng_pair1_open_raw(&dev1) == 0); - So(nng_pair1_open_raw(&dev2) == 0); - - struct dev_data ddata; - ddata.s1 = dev1; - ddata.s2 = dev2; - - So(nng_thread_create(&thr, dodev, &ddata) == 0); - Reset({ - nng_close(dev1); - nng_close(dev2); - nng_thread_destroy(thr); - }); - - So(nng_listen(dev1, addr1, NULL, 0) == 0); - So(nng_listen(dev2, addr2, NULL, 0) == 0); - - So(nng_pair1_open(&end1) == 0); - So(nng_pair1_open(&end2) == 0); - - So(nng_dial(end1, addr1, NULL, 0) == 0); - So(nng_dial(end2, addr2, NULL, 0) == 0); - - tmo = SECOND(1); - So(nng_socket_set_ms(end1, NNG_OPT_RECVTIMEO, tmo) == - 0); - So(nng_socket_set_ms(end2, NNG_OPT_RECVTIMEO, tmo) == - 0); - - nng_msleep(100); - Convey("Device can send and receive", { - So(nng_msg_alloc(&msg, 0) == 0); - APPENDSTR(msg, "ALPHA"); - So(nng_sendmsg(end1, msg, 0) == 0); - So(nng_recvmsg(end2, &msg, 0) == 0); - CHECKSTR(msg, "ALPHA"); - nng_msg_free(msg); - - So(nng_msg_alloc(&msg, 0) == 0); - APPENDSTR(msg, "OMEGA"); - - So(nng_sendmsg(end2, msg, 0) == 0); - So(nng_recvmsg(end1, &msg, 0) == 0); - - CHECKSTR(msg, "OMEGA"); - nng_msg_free(msg); - nng_close(end1); - nng_close(end2); - }); - }); - }); -})