diff options
| author | Garrett D'Amore <garrett@damore.org> | 2020-11-21 22:11:21 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2020-11-23 22:20:12 -0800 |
| commit | d1218d7309475193b53911667911c4f59a1a7752 (patch) | |
| tree | 6ea796998fb60d2cb8afa704faa77fe7fddd644c /src/platform | |
| parent | b826bfc171d90f8bde7bd672c0ac14201b8b2742 (diff) | |
| download | nng-d1218d7309475193b53911667911c4f59a1a7752.tar.gz nng-d1218d7309475193b53911667911c4f59a1a7752.tar.bz2 nng-d1218d7309475193b53911667911c4f59a1a7752.zip | |
New NUTS test framework (NNG Unit Test Support).
This is based on testutil/acutest, but is cleaner and fixes some
short-comings. We will be adding more support for additional
common paradigms to better facilitate transport tests.
While here we added some more test cases, and fixed a possible
symbol collision in the the stats framework (due to Linux use
of a macro definition of "si_value" in a standard OS header).
Test coverage may regress slightly as we are no longer using
some of the legacy APIs.
Diffstat (limited to 'src/platform')
| -rw-r--r-- | src/platform/platform_test.c | 170 | ||||
| -rw-r--r-- | src/platform/resolver_test.c | 105 |
2 files changed, 157 insertions, 118 deletions
diff --git a/src/platform/platform_test.c b/src/platform/platform_test.c index e7dcabaa..900efe36 100644 --- a/src/platform/platform_test.c +++ b/src/platform/platform_test.c @@ -8,17 +8,13 @@ // found online at https://opensource.org/licenses/MIT. // -#include "testutil.h" - -#include <nng/nng.h> -#include <nng/supplemental/util/platform.h> - -#include "acutest.h" +#include <nuts.h> struct add_arg { - int cnt; - nng_mtx *mx; - nng_cv * cv; + int cnt; + nng_duration delay; + nng_mtx * mx; + nng_cv * cv; }; void @@ -26,58 +22,51 @@ add(void *arg) { struct add_arg *aa = arg; + if (aa->delay > 0) { + nng_msleep(aa->delay); + } nng_mtx_lock(aa->mx); aa->cnt++; nng_cv_wake(aa->cv); nng_mtx_unlock(aa->mx); } +#ifdef __has_feature +#if __has_feature(thread_sanitizer) || __has_feature(memory_sanitizer) +#define RELAXED_CLOCKS +#endif +#endif + void test_sleep(void) { - uint64_t start, end; - start = testutil_clock(); + uint64_t start; + NUTS_CLOCK(start); nng_msleep(100); - end = testutil_clock(); - TEST_CHECK((end - start) >= 100); -#ifdef __has_feature -#if !__has_feature(thread_sanitizer) && !__has_feature(memory_sanitizer) - TEST_CHECK((end - start) <= 500); -#endif + NUTS_AFTER(start + 100); +#ifndef RELAXED_CLOCKS + NUTS_BEFORE(start + 500); #endif } void test_clock(void) { - uint64_t mstart; - uint64_t msend; - nng_time usend; - nng_time usnow; + uint64_t s0, s1; + nng_time t0, t1; - mstart = testutil_clock(); - usnow = nng_clock(); + NUTS_CLOCK(s0); + t0 = nng_clock(); nng_msleep(200); - usend = nng_clock(); - msend = testutil_clock(); + t1 = nng_clock(); + NUTS_CLOCK(s1); - TEST_CHECK(usend > usnow); - TEST_CHECK(msend > mstart); + NUTS_TRUE(t1 > t0); + NUTS_TRUE((t1 - t0) >= 200); + NUTS_TRUE((t1 - t0) < 500); -#ifdef __has_feature -#if !__has_feature(thread_sanitizer) && !__has_feature(memory_sanitizer) - uint64_t usdelta; - uint64_t msdelta; - usdelta = usend - usnow; - msdelta = msend - mstart; - TEST_CHECK(usdelta >= 200); - TEST_CHECK(usdelta < 500); // increased tolerance for CIs - if (msdelta > usdelta) { - TEST_CHECK((msdelta - usdelta) < 50); - } else { - TEST_CHECK((usdelta - msdelta) < 50); - } -#endif +#ifndef RELAXED_CLOCKS + NUTS_TRUE(abs((int) (s1 - s0) - (int) (t1 - t0)) < 50); #endif } @@ -86,7 +75,7 @@ test_mutex(void) { nng_mtx *mx, *mx2; - TEST_CHECK(nng_mtx_alloc(&mx) == 0); + NUTS_PASS(nng_mtx_alloc(&mx)); nng_mtx_lock(mx); nng_mtx_unlock(mx); @@ -95,9 +84,9 @@ test_mutex(void) nng_mtx_free(mx); // Verify that the mutexes are not always the same! - TEST_CHECK(nng_mtx_alloc(&mx) == 0); - TEST_CHECK(nng_mtx_alloc(&mx2) == 0); - TEST_CHECK(mx != mx2); + NUTS_PASS(nng_mtx_alloc(&mx)); + NUTS_PASS(nng_mtx_alloc(&mx2)); + NUTS_TRUE(mx != mx2); nng_mtx_free(mx); nng_mtx_free(mx2); } @@ -106,16 +95,16 @@ void test_thread(void) { nng_thread * thr; - int rv; struct add_arg aa; - TEST_CHECK(nng_mtx_alloc(&aa.mx) == 0); - TEST_CHECK(nng_cv_alloc(&aa.cv, aa.mx) == 0); - aa.cnt = 0; + NUTS_PASS(nng_mtx_alloc(&aa.mx)); + NUTS_PASS(nng_cv_alloc(&aa.cv, aa.mx)); + aa.cnt = 0; + aa.delay = 0; - TEST_CHECK((rv = nng_thread_create(&thr, add, &aa)) == 0); + NUTS_PASS(nng_thread_create(&thr, add, &aa)); nng_thread_destroy(thr); - TEST_CHECK(aa.cnt == 1); + NUTS_TRUE(aa.cnt == 1); nng_cv_free(aa.cv); nng_mtx_free(aa.mx); @@ -124,15 +113,15 @@ test_thread(void) void test_cond_var(void) { - nng_thread * thr; - int rv; + nng_thread * thr; struct add_arg aa; - TEST_CHECK(nng_mtx_alloc(&aa.mx) == 0); - TEST_CHECK(nng_cv_alloc(&aa.cv, aa.mx) == 0); - aa.cnt = 0; + NUTS_PASS(nng_mtx_alloc(&aa.mx)); + NUTS_PASS(nng_cv_alloc(&aa.cv, aa.mx)); + aa.cnt = 0; + aa.delay = 0; - TEST_CHECK((rv = nng_thread_create(&thr, add, &aa)) == 0); + NUTS_PASS(nng_thread_create(&thr, add, &aa)); nng_mtx_lock(aa.mx); while (aa.cnt == 0) { @@ -140,7 +129,64 @@ test_cond_var(void) } nng_mtx_unlock(aa.mx); nng_thread_destroy(thr); - TEST_CHECK(aa.cnt == 1); + NUTS_TRUE(aa.cnt == 1); + + nng_cv_free(aa.cv); + nng_mtx_free(aa.mx); +} + +void +test_cond_wake(void) +{ + nng_thread * thr; + struct add_arg aa; + nng_time now; + + NUTS_PASS(nng_mtx_alloc(&aa.mx)); + NUTS_PASS(nng_cv_alloc(&aa.cv, aa.mx)); + aa.cnt = 0; + aa.delay = 200; + + now = nng_clock(); + + NUTS_PASS(nng_thread_create(&thr, add, &aa)); + + nng_mtx_lock(aa.mx); + nng_cv_until(aa.cv, now + 500); + nng_mtx_unlock(aa.mx); + + NUTS_TRUE(nng_clock() >= now + 200); + NUTS_TRUE(nng_clock() < now + 500); + + nng_thread_destroy(thr); + nng_cv_free(aa.cv); + nng_mtx_free(aa.mx); +} + +void +test_cond_until(void) +{ + struct add_arg aa; + nng_time now; + + NUTS_PASS(nng_mtx_alloc(&aa.mx)); + NUTS_PASS(nng_cv_alloc(&aa.cv, aa.mx)); + aa.cnt = 0; + aa.delay = 0; + + now = nng_clock(); + nng_mtx_lock(aa.mx); + nng_cv_until(aa.cv, now + 100); + nng_mtx_unlock(aa.mx); + + NUTS_TRUE(nng_clock() >= now); +#ifdef NO_SPRIOUS_WAKEUPS + // Some systems (e.g. Win32) will occasionally wake a threaed + // spuriously. We therefore can't rely on condwait to be + // an absolute guarantee of minimum time passage. + NUTS_TRUE(nng_clock() >= now + 100); +#endif + NUTS_TRUE(nng_clock() < now + 1000); nng_cv_free(aa.cv); nng_mtx_free(aa.mx); @@ -166,16 +212,18 @@ test_random(void) // 1% reproduction is *highly* unlikely. // There are 4 billion possible options, we are only looking at // 1000 of them. In general, it would be an extreme outlier - // to see more than 2 repeats, unless you RNG is biased. - TEST_CHECK_(same < 5, "fewer than 5 in 1000 repeats: %d", same); + // to see more than 2 repeats, unless your RNG is biased. + NUTS_TRUE(same < 5); } -TEST_LIST = { +NUTS_TESTS = { { "sleep", test_sleep }, { "clock", test_clock }, { "mutex", test_mutex }, { "thread", test_thread }, { "cond var", test_cond_var }, + { "cond wake", test_cond_wake }, + { "cond until", test_cond_until }, { "random", test_random }, { NULL, NULL }, }; diff --git a/src/platform/resolver_test.c b/src/platform/resolver_test.c index 43168cdb..d4dd4465 100644 --- a/src/platform/resolver_test.c +++ b/src/platform/resolver_test.c @@ -8,18 +8,9 @@ // found online at https://opensource.org/licenses/MIT. // -#include "testutil.h" - -#include <string.h> - #include "core/nng_impl.h" -#include "stubs.h" - -#include "acutest.h" -#ifndef _WIN32 -#include <arpa/inet.h> // for htons, htonl -#endif +#include <nuts.h> uint8_t v6loop[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; @@ -29,14 +20,14 @@ test_google_dns(void) nng_aio * aio; nng_sockaddr sa; - TEST_NNG_PASS(nng_aio_alloc(&aio, NULL, NULL)); + NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL)); nni_resolv_ip("google-public-dns-a.google.com", "80", NNG_AF_INET, true, &sa, aio); nng_aio_wait(aio); - TEST_NNG_PASS(nng_aio_result(aio)); - TEST_CHECK(sa.s_in.sa_family == NNG_AF_INET); - TEST_CHECK(sa.s_in.sa_port == ntohs(80)); - TEST_CHECK(sa.s_in.sa_addr == 0x08080808); // aka 8.8.8.8 + NUTS_PASS(nng_aio_result(aio)); + NUTS_TRUE(sa.s_in.sa_family == NNG_AF_INET); + NUTS_TRUE(sa.s_in.sa_port == nuts_be16(80)); + NUTS_TRUE(sa.s_in.sa_addr == 0x08080808); // aka 8.8.8.8 nng_aio_free(aio); } @@ -46,13 +37,13 @@ test_numeric_addr(void) nng_aio * aio; nng_sockaddr sa; - TEST_NNG_PASS(nng_aio_alloc(&aio, NULL, NULL)); + NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL)); nni_resolv_ip("8.8.4.4", "69", NNG_AF_INET, true, &sa, aio); nng_aio_wait(aio); - TEST_NNG_PASS(nng_aio_result(aio)); - TEST_CHECK(sa.s_in.sa_family == NNG_AF_INET); - TEST_CHECK(sa.s_in.sa_port == ntohs(69)); - TEST_CHECK(sa.s_in.sa_addr == ntohl(0x08080404)); // 8.8.4.4. + NUTS_PASS(nng_aio_result(aio)); + NUTS_TRUE(sa.s_in.sa_family == NNG_AF_INET); + NUTS_TRUE(sa.s_in.sa_port == nuts_be16(69)); + NUTS_TRUE(sa.s_in.sa_addr == nuts_be32(0x08080404)); // 8.8.4.4. nng_aio_free(aio); } @@ -69,13 +60,13 @@ test_numeric_v6(void) return; // skip this one. } - TEST_NNG_PASS(nng_aio_alloc(&aio, NULL, NULL)); + NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL)); nni_resolv_ip("::1", "80", NNG_AF_INET6, true, &sa, aio); nng_aio_wait(aio); - TEST_NNG_PASS(nng_aio_result(aio)); - TEST_CHECK(sa.s_in6.sa_family == NNG_AF_INET6); - TEST_CHECK(sa.s_in6.sa_port == ntohs(80)); - TEST_CHECK(memcmp(sa.s_in6.sa_addr, v6loop, 16) == 0); + NUTS_PASS(nng_aio_result(aio)); + NUTS_TRUE(sa.s_in6.sa_family == NNG_AF_INET6); + NUTS_TRUE(sa.s_in6.sa_port == nuts_be16(80)); + NUTS_TRUE(memcmp(sa.s_in6.sa_addr, v6loop, 16) == 0); nng_aio_free(aio); } @@ -85,12 +76,12 @@ test_service_names(void) nng_aio * aio; nng_sockaddr sa; - TEST_NNG_PASS(nng_aio_alloc(&aio, NULL, NULL)); + NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL)); nni_resolv_ip("8.8.4.4", "http", NNG_AF_INET, true, &sa, aio); nng_aio_wait(aio); - TEST_NNG_PASS(nng_aio_result(aio)); - TEST_CHECK(sa.s_in.sa_port == ntohs(80)); - TEST_CHECK(sa.s_in.sa_addr = ntohl(0x08080404)); + NUTS_PASS(nng_aio_result(aio)); + NUTS_TRUE(sa.s_in.sa_port == nuts_be16(80)); + NUTS_TRUE(sa.s_in.sa_addr = nuts_be32(0x08080404)); nng_aio_free(aio); } @@ -100,36 +91,36 @@ test_localhost_v4(void) nng_aio * aio; nng_sockaddr sa; - TEST_NNG_PASS(nng_aio_alloc(&aio, NULL, NULL)); + NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL)); nni_resolv_ip("localhost", "80", NNG_AF_INET, true, &sa, aio); nng_aio_wait(aio); - TEST_NNG_PASS(nng_aio_result(aio)); - TEST_CHECK(sa.s_in.sa_family == NNG_AF_INET); - TEST_CHECK(sa.s_in.sa_port == ntohs(80)); - TEST_CHECK(sa.s_in.sa_addr == ntohl(0x7f000001)); + NUTS_PASS(nng_aio_result(aio)); + NUTS_TRUE(sa.s_in.sa_family == NNG_AF_INET); + NUTS_TRUE(sa.s_in.sa_port == nuts_be16(80)); + NUTS_TRUE(sa.s_in.sa_addr == nuts_be32(0x7f000001)); nng_aio_free(aio); } void -test_localhost_unspec(void) +test_localhost_unspecified(void) { nng_aio * aio; nng_sockaddr sa; - TEST_NNG_PASS(nng_aio_alloc(&aio, NULL, NULL)); + NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL)); nni_resolv_ip("localhost", "80", NNG_AF_UNSPEC, true, &sa, aio); nng_aio_wait(aio); - TEST_NNG_PASS(nng_aio_result(aio)); - TEST_CHECK( + NUTS_PASS(nng_aio_result(aio)); + NUTS_TRUE( (sa.s_family == NNG_AF_INET) || (sa.s_family == NNG_AF_INET6)); switch (sa.s_family) { case NNG_AF_INET: - TEST_CHECK(sa.s_in.sa_port == ntohs(80)); - TEST_CHECK(sa.s_in.sa_addr == ntohl(0x7f000001)); + NUTS_TRUE(sa.s_in.sa_port == nuts_be16(80)); + NUTS_TRUE(sa.s_in.sa_addr == nuts_be32(0x7f000001)); break; case NNG_AF_INET6: - TEST_CHECK(sa.s_in6.sa_port == ntohs(80)); - TEST_CHECK(memcmp(sa.s_in6.sa_addr, v6loop, 16) == 0); + NUTS_TRUE(sa.s_in6.sa_port == nuts_be16(80)); + NUTS_TRUE(memcmp(sa.s_in6.sa_addr, v6loop, 16) == 0); break; } nng_aio_free(aio); @@ -141,13 +132,13 @@ test_null_passive(void) nng_aio * aio; nng_sockaddr sa; - TEST_NNG_PASS(nng_aio_alloc(&aio, NULL, NULL)); + NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL)); nni_resolv_ip(NULL, "80", NNG_AF_INET, true, &sa, aio); nng_aio_wait(aio); - TEST_NNG_PASS(nng_aio_result(aio)); - TEST_CHECK(sa.s_in.sa_family == NNG_AF_INET); - TEST_CHECK(sa.s_in.sa_port == ntohs(80)); - TEST_CHECK(sa.s_in.sa_addr == 0); // INADDR_ANY + NUTS_PASS(nng_aio_result(aio)); + NUTS_TRUE(sa.s_in.sa_family == NNG_AF_INET); + NUTS_TRUE(sa.s_in.sa_port == nuts_be16(80)); + NUTS_TRUE(sa.s_in.sa_addr == 0); // any local address nng_aio_free(aio); } @@ -157,17 +148,17 @@ test_null_not_passive(void) nng_aio * aio; nng_sockaddr sa; - TEST_NNG_PASS(nng_aio_alloc(&aio, NULL, NULL)); + NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL)); nni_resolv_ip(NULL, "80", NNG_AF_INET, false, &sa, aio); nng_aio_wait(aio); - // We can either get NNG_EADDRINVAL, or a loopback address. + // We can either get invalid address, or a loopback address. // Most systems do the former, but Linux does the latter. if (nng_aio_result(aio) == 0) { - TEST_CHECK(sa.s_family == NNG_AF_INET); - TEST_CHECK(sa.s_in.sa_addr == htonl(0x7f000001)); - TEST_CHECK(sa.s_in.sa_port == htons(80)); + NUTS_TRUE(sa.s_family == NNG_AF_INET); + NUTS_TRUE(sa.s_in.sa_addr == nuts_be32(0x7f000001)); + NUTS_TRUE(sa.s_in.sa_port == nuts_be16(80)); } else { - TEST_NNG_FAIL(nng_aio_result(aio), NNG_EADDRINVAL); + NUTS_FAIL(nng_aio_result(aio), NNG_EADDRINVAL); } nng_aio_free(aio); } @@ -178,20 +169,20 @@ test_bad_port_number(void) nng_aio * aio; nng_sockaddr sa; - TEST_NNG_PASS(nng_aio_alloc(&aio, NULL, NULL)); + NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL)); nni_resolv_ip("1.1.1.1", "1000000", NNG_AF_INET, true, &sa, aio); nng_aio_wait(aio); - TEST_NNG_FAIL(nng_aio_result(aio), NNG_EADDRINVAL); + NUTS_FAIL(nng_aio_result(aio), NNG_EADDRINVAL); nng_aio_free(aio); } -TEST_LIST = { +NUTS_TESTS = { { "resolve google dns", test_google_dns }, { "resolve numeric addr", test_numeric_addr }, { "resolve numeric v6", test_numeric_v6 }, { "resolve service names", test_service_names }, { "resolve localhost v4", test_localhost_v4 }, - { "resolve localhost unspec", test_localhost_unspec }, + { "resolve localhost unspecified", test_localhost_unspecified }, { "resolve null passive", test_null_passive }, { "resolve null not passive", test_null_not_passive }, { "resolve bad port number", test_bad_port_number }, |
