aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/CMakeLists.txt1
-rw-r--r--tests/pair1.c3
-rw-r--r--tests/platform.c105
-rw-r--r--tests/synch.c292
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);
+ });
+})