diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | tests/pair1.c | 3 | ||||
| -rw-r--r-- | tests/platform.c | 105 | ||||
| -rw-r--r-- | tests/synch.c | 292 |
4 files changed, 338 insertions, 63 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 73484a4a..754d3ab2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -85,6 +85,7 @@ add_nng_test(pubsub 5) add_nng_test(resolv 10) add_nng_test(sock 5) add_nng_test(survey 5) +add_nng_test(synch 5) add_nng_test(tcp 5) add_nng_test(scalability 20) add_nng_test(message 5) diff --git a/tests/pair1.c b/tests/pair1.c index 08691fd4..d160acdd 100644 --- a/tests/pair1.c +++ b/tests/pair1.c @@ -94,7 +94,6 @@ TestMain("PAIRv1 protocol", { }); Convey("Cannot set raw mode after connect", { - int r = 1; So(nng_listen(s1, addr, NULL, 0) == 0); So(nng_dial(c1, addr, NULL, 0) == 0); nng_usleep(100000); @@ -313,7 +312,6 @@ TestMain("PAIRv1 protocol", { int ttl; ttl = 0; - sz = sizeof(ttl); So(nng_setopt_int(s1, NNG_OPT_MAXTTL, 0) == NNG_EINVAL); @@ -423,7 +421,6 @@ TestMain("PAIRv1 protocol", { uint32_t hops; nng_pipe p1; nng_pipe p2; - size_t sz; So(nng_getopt_int(s1, NNG_OPT_POLYAMOROUS, &v) == 0); So(v == 0); diff --git a/tests/platform.c b/tests/platform.c index 5bfdc367..a28bc4e4 100644 --- a/tests/platform.c +++ b/tests/platform.c @@ -1,5 +1,6 @@ // -// Copyright 2016 Garrett D'Amore <garrett@damore.org> +// Copyright 2017 Garrett D'Amore <garrett@damore.org> +// Copyright 2017 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 @@ -8,20 +9,20 @@ // #include "convey.h" -#include "nng.h" #include "core/nng_impl.h" +#include "nng.h" -#ifndef _WIN32 +#ifndef _WIN32 #include <sys/time.h> #endif uint64_t getms(void) { -#ifdef _WIN32 - return (GetTickCount64()) ; +#ifdef _WIN32 + return (GetTickCount64()); #else - static time_t epoch; + static time_t epoch; struct timeval tv; if (epoch == 0) { @@ -35,7 +36,7 @@ getms(void) return (0); } tv.tv_sec -= epoch; - return (((uint64_t)(tv.tv_sec ) * 1000) + (tv.tv_usec / 1000)); + return (((uint64_t)(tv.tv_sec) * 1000) + (tv.tv_usec / 1000)); #endif } @@ -43,15 +44,15 @@ getms(void) void add(void *arg) { - *(int *)arg += 1; + *(int *) arg += 1; } // Notify tests for verifying condvars. struct notifyarg { - int did; - int when; + int did; + int when; nni_mtx mx; - nni_cv cv; + nni_cv cv; }; void @@ -66,17 +67,10 @@ notifyafter(void *arg) nni_mtx_unlock(&na->mx); } -int -nop(void) -{ - return (0); -} +TestMain("Platform Operations", { -Main({ nni_init(); - Test("Platform Operations", { - // This is required for anything else to work Convey("The clock works", { uint64_t now = getms(); @@ -84,13 +78,13 @@ Main({ Convey("usleep works", { nni_usleep(100000); - So((getms() - now) >= 100); // cannot be *shorter*!! - So((getms() - now) < 150); // crummy clock resolution? - }) + So((getms() - now) >= 100); // cannot be *shorter*!! + So((getms() - now) < 150); // crummy clock resolution? + }); Convey("times work", { uint64_t msend; - int usdelta; - int msdelta; + int usdelta; + int msdelta; nni_time usend; nni_time usnow = nni_clock(); nni_usleep(200000); @@ -99,19 +93,17 @@ Main({ So(usend > usnow); So(msend > now); - usdelta = (int)((usend - usnow) / 1000); - msdelta = (int)((msend - now)); + usdelta = (int) ((usend - usnow) / 1000); + msdelta = (int) ((msend - now)); So(usdelta >= 200); So(usdelta < 220); So(abs(msdelta - usdelta) < 20); - }) - }) + }); + }); Convey("Mutexes work", { static nni_mtx mx; - int rv; - rv = nni_mtx_init(&mx); - So(rv == 0); + nni_mtx_init(&mx); Convey("We can lock a mutex", { nni_mtx_lock(&mx); @@ -124,40 +116,36 @@ Main({ So(1); nni_mtx_unlock(&mx); So(1); - }) - }) - }) - Convey("We can finalize it", { - nni_mtx_fini(&mx); - }) - }) + }); + }); + }); + Convey("We can finalize it", { nni_mtx_fini(&mx); }); + }); Convey("Threads work", { static nni_thr thr; - int val = 0; - int rv; + int val = 0; + int rv; Convey("We can create threads", { rv = nni_thr_init(&thr, add, &val); So(rv == 0); nni_thr_run(&thr); - Reset({ - nni_thr_fini(&thr); - }) + Reset({ nni_thr_fini(&thr); }); Convey("It ran", { - nni_usleep(50000); // for context switch + nni_usleep(50000); // for context switch So(val == 1); - }) - }) - }) + }); + }); + }); Convey("Condition variables work", { static struct notifyarg arg; - static nni_thr thr; + static nni_thr thr; - So(nni_mtx_init(&arg.mx) == 0); - So(nni_cv_init(&arg.cv, &arg.mx) == 0); + nni_mtx_init(&arg.mx); + nni_cv_init(&arg.cv, &arg.mx); So(nni_thr_init(&thr, notifyafter, &arg) == 0); Reset({ @@ -167,7 +155,7 @@ Main({ }); Convey("Notification works", { - arg.did = 0; + arg.did = 0; arg.when = 10000; nni_thr_run(&thr); @@ -178,10 +166,10 @@ Main({ nni_mtx_unlock(&arg.mx); nni_thr_wait(&thr); So(arg.did == 1); - }) + }); Convey("Timeout works", { - arg.did = 0; + arg.did = 0; arg.when = 200000; nni_thr_run(&thr); nni_mtx_lock(&arg.mx); @@ -191,10 +179,9 @@ Main({ So(arg.did == 0); nni_mtx_unlock(&arg.mx); nni_thr_wait(&thr); - }) - + }); Convey("Not running works", { - arg.did = 0; + arg.did = 0; arg.when = 1; nni_mtx_lock(&arg.mx); if (!arg.did) { @@ -202,8 +189,6 @@ Main({ } So(arg.did == 0); nni_mtx_unlock(&arg.mx); - }) - }) - }) - nni_fini(); + }); + }); }) diff --git a/tests/synch.c b/tests/synch.c new file mode 100644 index 00000000..a49e27e1 --- /dev/null +++ b/tests/synch.c @@ -0,0 +1,292 @@ +// +// Copyright 2017 Garrett D'Amore <garrett@damore.org> +// Copyright 2017 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. +// + +#include "convey.h" +#include "core/nng_impl.h" +#include "nng.h" + +// Notify tests for verifying condvars. +struct notifyarg { + int did; + int when; + nni_mtx mx; + nni_cv cv; +}; + +#ifdef PLATFORM_POSIX +#ifndef NDEBUG +#define SYNC_FALLBACK 1 +#endif +#endif + +void +notifyafter(void *arg) +{ + struct notifyarg *na = arg; + + nni_usleep(na->when); + nni_mtx_lock(&na->mx); + na->did = 1; + nni_cv_wake(&na->cv); + nni_mtx_unlock(&na->mx); +} + +struct notifyarg arg; +nni_thr thr; + +static void +test_sync(void) +{ + Convey("Mutexes work", { + nni_mtx mx; + + nni_mtx_init(&mx); + + Convey("We can lock a mutex", { + nni_mtx_lock(&mx); + So(1); + Convey("And we can unlock it", { + nni_mtx_unlock(&mx); + So(1); + Convey("And then lock it again", { + nni_mtx_lock(&mx); + So(1); + nni_mtx_unlock(&mx); + So(1); + }); + }); + Convey("Things block properly", { + + nni_mtx_init(&arg.mx); + nni_cv_init(&arg.cv, &arg.mx); + So(nni_thr_init(&thr, notifyafter, &arg) == 0); + arg.did = 0; + arg.when = 0; + nni_mtx_lock(&arg.mx); + nni_thr_run(&thr); + nng_usleep(10000); + So(arg.did == 0); + nni_mtx_unlock(&arg.mx); + nng_usleep(10000); + nni_mtx_lock(&arg.mx); + while (!arg.did) { + nni_cv_wait(&arg.cv); + } + So(arg.did != 0); + nni_mtx_unlock(&arg.mx); + nni_thr_fini(&thr); + nni_cv_fini(&arg.cv); + nni_mtx_fini(&arg.mx); + }) + }); + Convey("We can finalize it", { nni_mtx_fini(&mx); }); + }); + + Convey("Condition variables work", { + + nni_mtx_init(&arg.mx); + nni_cv_init(&arg.cv, &arg.mx); + So(nni_thr_init(&thr, notifyafter, &arg) == 0); + + Reset({ + nni_cv_fini(&arg.cv); + nni_mtx_fini(&arg.mx); + nni_thr_fini(&thr); + }); + + Convey("Notification works", { + arg.did = 0; + arg.when = 10000; + nni_thr_run(&thr); + + nni_mtx_lock(&arg.mx); + if (!arg.did) { + nni_cv_wait(&arg.cv); + } + nni_mtx_unlock(&arg.mx); + nni_thr_wait(&thr); + So(arg.did == 1); + }); + + Convey("Timeout works", { + arg.did = 0; + arg.when = 200000; + nni_thr_run(&thr); + nni_mtx_lock(&arg.mx); + if (!arg.did) { + nni_cv_until(&arg.cv, nni_clock() + 10000); + } + So(arg.did == 0); + nni_mtx_unlock(&arg.mx); + nni_thr_wait(&thr); + }); + + Convey("Empty timeout is EAGAIN", { + nni_mtx_lock(&arg.mx); + So(nni_cv_until(&arg.cv, 0) == NNG_EAGAIN); + nni_mtx_unlock(&arg.mx); + }); + + Convey("Not running works", { + arg.did = 0; + arg.when = 1; + nni_mtx_lock(&arg.mx); + if (!arg.did) { + nni_cv_until(&arg.cv, nni_clock() + 10000); + } + So(arg.did == 0); + nni_mtx_unlock(&arg.mx); + }); + }); +} + +#if SYNC_FALLBACK +extern int nni_plat_sync_fallback; + +#define ConveyFB(x, y) Convey(x, y) + +static void +test_sync_fallback(void) +{ + nni_plat_sync_fallback = 1; + Convey("Mutexes work", { + nni_mtx mx; + int rv; + + nni_mtx_init(&mx); + + Convey("We can lock a mutex", { + nni_mtx_lock(&mx); + So(1); + Convey("And we can unlock it", { + nni_mtx_unlock(&mx); + So(1); + Convey("And then lock it again", { + nni_mtx_lock(&mx); + So(1); + nni_mtx_unlock(&mx); + So(1); + }); + }); + Convey("Things block properly", { + + nni_mtx_init(&arg.mx); + nni_cv_init(&arg.cv, &arg.mx); + So(nni_thr_init(&thr, notifyafter, &arg) == 0); + arg.did = 0; + arg.when = 0; + nni_mtx_lock(&arg.mx); + nni_thr_run(&thr); + nng_usleep(10000); + So(arg.did == 0); + nni_mtx_unlock(&arg.mx); + nng_usleep(10000); + nni_mtx_lock(&arg.mx); + while (!arg.did) { + nni_cv_wait(&arg.cv); + } + So(arg.did != 0); + nni_mtx_unlock(&arg.mx); + nni_thr_fini(&thr); + nni_cv_fini(&arg.cv); + nni_mtx_fini(&arg.mx); + }) + }); + Convey("We can finalize it", { nni_mtx_fini(&mx); }); + }); + + Convey("Condition variables work", { + + nni_mtx_init(&arg.mx); + nni_cv_init(&arg.cv, &arg.mx); + So(nni_thr_init(&thr, notifyafter, &arg) == 0); + + Reset({ + nni_cv_fini(&arg.cv); + nni_mtx_fini(&arg.mx); + nni_thr_fini(&thr); + }); + + Convey("Notification works", { + arg.did = 0; + arg.when = 10000; + nni_thr_run(&thr); + + nni_mtx_lock(&arg.mx); + if (!arg.did) { + nni_cv_wait(&arg.cv); + } + nni_mtx_unlock(&arg.mx); + nni_thr_wait(&thr); + So(arg.did == 1); + }); + + Convey("Timeout works", { + arg.did = 0; + arg.when = 200000; + nni_thr_run(&thr); + nni_mtx_lock(&arg.mx); + if (!arg.did) { + nni_cv_until(&arg.cv, nni_clock() + 10000); + } + So(arg.did == 0); + nni_mtx_unlock(&arg.mx); + nni_thr_wait(&thr); + }); + + Convey("Empty timeout is EAGAIN", { + nni_mtx_lock(&arg.mx); + So(nni_cv_until(&arg.cv, 0) == NNG_EAGAIN); + nni_mtx_unlock(&arg.mx); + }); + + Convey("Not running works", { + arg.did = 0; + arg.when = 1; + nni_mtx_lock(&arg.mx); + if (!arg.did) { + nni_cv_until(&arg.cv, nni_clock() + 10000); + } + So(arg.did == 0); + nni_mtx_unlock(&arg.mx); + }); + }); +} +#else +#define ConveyFB(x, y) +#endif + +TestMain("Synchronization", { + nni_init(); + + Convey("Synchronization works", { test_sync(); }); + + ConveyFB("Fallback synchronization works", { test_sync_fallback(); }); + + ConveyFB("Transform works", { + nni_plat_sync_fallback = 0; + nni_mtx_init(&arg.mx); + nni_plat_sync_fallback = 1; + nni_cv_init(&arg.cv, &arg.mx); + So(nni_thr_init(&thr, notifyafter, &arg) == 0); + + arg.did = 0; + arg.when = 10000; + nni_thr_run(&thr); + + nni_mtx_lock(&arg.mx); + if (!arg.did) { + nni_cv_wait(&arg.cv); + } + nni_mtx_unlock(&arg.mx); + nni_thr_wait(&thr); + So(arg.did == 1); + }); +}) |
