diff options
| author | Garrett D'Amore <garrett@damore.org> | 2017-01-26 09:57:56 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2017-01-26 09:57:56 -0800 |
| commit | d93cbc059cd1e42773d1aec19f8b49a972f2eac3 (patch) | |
| tree | 71a6c79e8ae5c2ef9ed9beb06088ccd4d832fca9 | |
| parent | a9e81c87a7b2a203c2bd4f310f936af46ef42fc1 (diff) | |
| download | nng-d93cbc059cd1e42773d1aec19f8b49a972f2eac3.tar.gz nng-d93cbc059cd1e42773d1aec19f8b49a972f2eac3.tar.bz2 nng-d93cbc059cd1e42773d1aec19f8b49a972f2eac3.zip | |
Added more plumbing to facilitate test writing & compatibility.
Also, while here fixed a bug for the PAIR protocol in compat mode.
It should now be possible to import more of the nanomsg tests directly
with little or no modification.
| -rw-r--r-- | CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/nng.c | 42 | ||||
| -rw-r--r-- | src/nng.h | 21 | ||||
| -rw-r--r-- | src/nng_compat.c | 38 | ||||
| -rw-r--r-- | src/nng_compat.h | 18 | ||||
| -rw-r--r-- | tests/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | tests/compat_block.c | 68 | ||||
| -rw-r--r-- | tests/compat_testutil.h | 2 |
8 files changed, 188 insertions, 6 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 190e75fc..3ccf895a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,8 +91,10 @@ option (NNG_TESTS "Build and run tests" ON) option (NNG_TOOLS "Build extra tools" OFF) option (NNG_ENABLE_NNGCAT "Enable building nngcat utility." ${NNG_TOOLS}) -# Platform checks. +# Enable access to private APIs for our own use. +add_definitions (-DNNG_PRIVATE) +# Platform checks. if (CMAKE_SYSTEM_NAME MATCHES "Linux") find_package (Threads REQUIRED) @@ -625,8 +625,50 @@ nng_device(nng_socket sock1, nng_socket sock2) } +// These routines exist as utility functions, exposing some of our "guts" +// to the external world for the purposes of test code and bundled utilities. +// They should not be considered part of our public API, and applications +// should refrain from their use. + void nng_usleep(uint64_t usec) { nni_usleep(usec); } + + +uint64_t +nng_clock(void) +{ + return ((uint64_t) nni_clock()); +} + + +// nng_thread_create creates a thread structure, and starts it running. +// Unlike the internals, this allocates stuff dynamically, and does not +// wait to start. +int +nng_thread_create(void **thrp, void (*func)(void *), void *arg) +{ + nni_thr *thr; + int rv; + + if ((thr = NNI_ALLOC_STRUCT(thr)) == NULL) { + return (NNG_ENOMEM); + } + memset(thr, 0, sizeof (*thr)); + *thrp = thr; + if ((rv = nni_thr_init(thr, func, arg)) != 0) { + return (rv); + } + nni_thr_run(thr); + return (0); +} + + +void +nng_thread_destroy(void *thr) +{ + nni_thr_fini(thr); + NNI_FREE_STRUCT(thr); +} @@ -371,12 +371,25 @@ NNG_DECL int64_t nng_stat_value(nng_stat *); // which means that messages from one side are forwarded to the other. NNG_DECL int nng_device(nng_socket, nng_socket); -// Sleep for the specified usecs. This is intended for use by test -// programs (to avoid needing to expose the rest of the private details). -// Applications are discouraged from using this -- use your platform -// time services instead. +// The following functions are not intrinsic to nanomsg, and so do not +// represent our public API. Avoid their use in other applications. + +#ifdef NNG_PRIVATE + +// Sleep for specified usecs. NNG_DECL void nng_usleep(uint64_t); +// Return usecs since some arbitrary time in past. +NNG_DECL uint64_t nng_clock(void); + +// Create and start a thread. +NNG_DECL int nng_thread_create(void **, void (*)(void *), void *); + +// Destroy a thread (waiting for it to complete.) +NNG_DECL void nng_thread_destroy(void *); + +#endif // NNG_PRIVATE + // Pollset functionality. TBD. (Note that I'd rather avoid this // altogether, because I believe that the notification mechanism I've // created offers a superior way to handle this. I don't think many diff --git a/src/nng_compat.c b/src/nng_compat.c index 04759e01..3192a5f7 100644 --- a/src/nng_compat.c +++ b/src/nng_compat.c @@ -727,3 +727,41 @@ nn_cmsg_next(struct nn_msghdr *mh, struct nn_cmsghdr *first) } return (first); } + + +// Internal test support routines. + +void +nn_sleep(uint64_t msec) +{ + nng_usleep(msec / 1000); +} + + +uint64_t +nn_clock(void) +{ + return (nng_clock()); +} + + +extern void nni_panic(const char *, ...); + +int +nn_thread_init(struct nn_thread *thr, void (*func)(void *), void *arg) +{ + int rv; + + rv = nng_thread_create(&thr->thr, func, arg); + if (rv != 0) { + nni_panic("Cannot create thread: %s", nng_strerror(rv)); + } + return (rv); +} + + +void +nn_thread_term(struct nn_thread *thr) +{ + nng_thread_destroy(thr->thr); +} diff --git a/src/nng_compat.h b/src/nng_compat.h index 5866fe2c..aa0f5a2c 100644 --- a/src/nng_compat.h +++ b/src/nng_compat.h @@ -65,7 +65,7 @@ extern "C" { #define NN_PROTO_SURVEY 6 #define NN_PROTO_BUS 7 -#define NN_PAIR (NN_PROTO_PAIR * 16 + 1) +#define NN_PAIR (NN_PROTO_PAIR * 16 + 0) #define NN_PUB (NN_PROTO_PUBSUB * 16 + 0) #define NN_SUB (NN_PROTO_PUBSUB * 16 + 1) #define NN_REQ (NN_PROTO_REQREP * 16 + 0) @@ -299,6 +299,22 @@ NN_DECL int nn_freemsg(void *); NN_DECL int nn_errno(void); NN_DECL const char *nn_strerror(int); + +// This stuff is intended to be exposed only for test programs and our +// own utilities. Do not use in your own programs. + +#ifdef NNG_PRIVATE +struct nn_thread { + void *thr; +}; + +NN_DECL void nn_sleep(uint64_t); +NN_DECL uint64_t nn_clock(void); +NN_DECL int nn_thread_init(struct nn_thread *, void (*)(void *), void *); +NN_DECL void nn_thread_term(struct nn_thread *); + +#endif // NNG_PRIVATE + #ifdef __cplusplus } #endif diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 57230f33..9545f661 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -86,5 +86,6 @@ add_nng_test(survey 5) add_nng_test(tcp 5) # compatbility tests +add_nng_compat_test(compat_block 5) add_nng_compat_test(compat_cmsg 5) add_nng_compat_test(compat_reqrep 5) diff --git a/tests/compat_block.c b/tests/compat_block.c new file mode 100644 index 00000000..e873cc86 --- /dev/null +++ b/tests/compat_block.c @@ -0,0 +1,68 @@ +/* + Copyright (c) 2012 Martin Sustrik All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom + the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +#include "nng_compat.h" +#include "compat_testutil.h" + +/* This test checks whether blocking on send/recv works as expected. */ + +#define SOCKET_ADDRESS "inproc://a" + +int sc; +int sb; + +void worker (NN_UNUSED void *arg) +{ + /* Wait 0.1 sec for the main thread to block. */ + nn_sleep (100); + + test_send (sc, "ABC"); + + /* Wait 0.1 sec for the main thread to process the previous message + and block once again. */ + nn_sleep (100); + + test_send (sc, "ABC"); +} + +int main () +{ + struct nn_thread thread; + + sb = test_socket (AF_SP, NN_PAIR); + test_bind (sb, SOCKET_ADDRESS); + sc = test_socket (AF_SP, NN_PAIR); + test_connect (sc, SOCKET_ADDRESS); + + nn_thread_init (&thread, worker, NULL); + + test_recv (sb, "ABC"); + test_recv (sb, "ABC"); + + nn_thread_term (&thread); + + test_close (sc); + test_close (sb); + + return 0; +} + diff --git a/tests/compat_testutil.h b/tests/compat_testutil.h index 58020331..79adb104 100644 --- a/tests/compat_testutil.h +++ b/tests/compat_testutil.h @@ -60,6 +60,8 @@ static int test_setsockopt_impl (char *file, int line, int sock, int level, #define test_setsockopt(s, l, o, v, z) test_setsockopt_impl (__FILE__, \ __LINE__, (s), (l), (o), (v), (z)) +#define NN_UNUSED + static int test_socket_impl (char *file, int line, int family, int protocol) { |
