Skip to content

Commit

Permalink
New NUTS test framework (NNG Unit Test Support).
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
gdamore committed Nov 23, 2020
1 parent b826bfc commit 4f04e08
Show file tree
Hide file tree
Showing 44 changed files with 5,320 additions and 5,442 deletions.
4 changes: 1 addition & 3 deletions CMakeLists.txt
Expand Up @@ -87,9 +87,7 @@ endif ()
# include or not include code based on what's actually present.
add_library(nng)

add_library(nng_testing STATIC EXCLUDE_FROM_ALL
${PROJECT_SOURCE_DIR}/tests/testutil.c
${PROJECT_SOURCE_DIR}/tests/testutil.h)
add_library(nng_testing STATIC EXCLUDE_FROM_ALL)
target_compile_definitions(nng_testing PUBLIC NNG_STATIC_LIB NNG_TEST_LIB NNG_PRIVATE)

add_library(nng_private INTERFACE)
Expand Down
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Expand Up @@ -30,6 +30,8 @@ add_subdirectory(supplemental/tls)
add_subdirectory(supplemental/util)
add_subdirectory(supplemental/websocket)

add_subdirectory(testing)

# When building shared libraries we prefer to suppress default symbol
# visibility, so that only the symbols that should be exposed in the
# resulting library are. This is the default with Windows.
Expand Down
149 changes: 73 additions & 76 deletions src/compat/nanomsg/compat_tcp_test.c
Expand Up @@ -32,28 +32,28 @@

#include "compat_testutil.h"

#include <acutest.h>
#include <testutil.h>
#include <nuts.h>

void
test_bind_and_close(void)
{
int sb;
char addr[64];
testutil_scratch_addr("tcp", sizeof (addr), addr);
int sb;
char *addr;

TEST_CHECK((sb = nn_socket(AF_SP, NN_PAIR)) >= 0);
TEST_CHECK(nn_bind(sb, addr) >= 0);
TEST_CHECK(nn_close(sb) == 0);
NUTS_ADDR(addr, "tcp");

NUTS_TRUE((sb = nn_socket(AF_SP, NN_PAIR)) >= 0);
NUTS_TRUE(nn_bind(sb, addr) >= 0);
NUTS_TRUE(nn_close(sb) == 0);
}

void
test_connect_and_close(void)
{
int sc;
char addr[64];
testutil_scratch_addr("tcp", sizeof (addr), addr);
int sc;
char *addr;

NUTS_ADDR(addr, "tcp");
TEST_NN_PASS((sc = nn_socket(AF_SP, NN_PAIR)) >= 0);
TEST_NN_PASS(nn_connect(sc, addr));
TEST_NN_PASS(nn_close(sc));
Expand All @@ -62,26 +62,25 @@ test_connect_and_close(void)
void
test_bind_and_connect(void)
{
int sb, sc, p1, p2;
char addr[64];

testutil_scratch_addr("tcp", sizeof (addr), addr);
int sb, sc, p1, p2;
char *addr;

TEST_CHECK((sb = nn_socket(AF_SP, NN_PAIR)) >= 0);
TEST_CHECK((sc = nn_socket(AF_SP, NN_PAIR)) >= 0);
TEST_CHECK(sb != sc);
NUTS_ADDR(addr, "tcp");
NUTS_TRUE((sb = nn_socket(AF_SP, NN_PAIR)) >= 0);
NUTS_TRUE((sc = nn_socket(AF_SP, NN_PAIR)) >= 0);
NUTS_TRUE(sb != sc);

TEST_NN_MARRY_EX(sb, sc, addr, p1, p2);

TEST_CHECK(nn_close(sb) == 0);
TEST_CHECK(nn_close(sc) == 0);
TEST_NN_PASS(nn_close(sb));
TEST_NN_PASS(nn_close(sc));
}

void
test_bad_addresses(void)
{
int s;
TEST_CHECK((s = nn_socket(AF_SP, NN_PAIR)) >= 0);
NUTS_TRUE((s = nn_socket(AF_SP, NN_PAIR)) >= 0);

TEST_NN_FAIL(nn_connect(s, "tcp://*:"), EINVAL);
TEST_NN_FAIL(nn_connect(s, "tcp://*:1000000"), EINVAL);
Expand All @@ -100,12 +99,12 @@ test_no_delay(void)
int s;
int opt;
size_t sz;
TEST_CHECK((s = nn_socket(AF_SP, NN_PAIR)) >= 0);
NUTS_TRUE((s = nn_socket(AF_SP, NN_PAIR)) >= 0);

sz = sizeof(opt);
TEST_NN_PASS(nn_getsockopt(s, NN_TCP, NN_TCP_NODELAY, &opt, &sz));
TEST_CHECK(sz == sizeof(opt));
TEST_CHECK(opt == 0);
NUTS_TRUE(sz == sizeof(opt));
NUTS_TRUE(opt == 0);
opt = 2;
TEST_NN_FAIL(
nn_setsockopt(s, NN_TCP, NN_TCP_NODELAY, &opt, sz), EINVAL);
Expand All @@ -115,25 +114,24 @@ test_no_delay(void)

opt = 3;
TEST_NN_PASS(nn_getsockopt(s, NN_TCP, NN_TCP_NODELAY, &opt, &sz));
TEST_CHECK(sz == sizeof(opt));
TEST_CHECK(opt == 1);
NUTS_TRUE(sz == sizeof(opt));
NUTS_TRUE(opt == 1);
TEST_NN_PASS(nn_close(s));
}

void
test_ping_pong(void)
{
int sb, sc, p1, p2;
char addr[64];

testutil_scratch_addr("tcp", sizeof(addr), addr);
int sb, sc, p1, p2;
char *addr;

NUTS_ADDR(addr, "tcp");
TEST_NN_PASS((sb = nn_socket(AF_SP, NN_PAIR)));
TEST_NN_PASS((sc = nn_socket(AF_SP, NN_PAIR)));
TEST_CHECK(sb != sc);
NUTS_TRUE(sb != sc);
TEST_NN_MARRY_EX(sc, sb, addr, p1, p2);
TEST_CHECK(p1 >= 0);
TEST_CHECK(p2 >= 0);
NUTS_TRUE(p1 >= 0);
NUTS_TRUE(p2 >= 0);

/* Ping-pong test. */
for (int i = 0; i != 100; ++i) {
Expand All @@ -142,75 +140,74 @@ test_ping_pong(void)
int n;
TEST_NN_PASS(nn_send(sc, "ABC", 3, 0));
TEST_NN_PASS(n = nn_recv(sb, buf, 4, 0));
TEST_CHECK(n == 3);
TEST_CHECK(memcmp(buf, "ABC", 3) == 0);
NUTS_TRUE(n == 3);
NUTS_TRUE(memcmp(buf, "ABC", 3) == 0);

TEST_NN_PASS(nn_send(sb, "DEF", 3, 0));
TEST_NN_PASS(n = nn_recv(sc, buf, 4, 0));
TEST_CHECK(n == 3);
TEST_CHECK(memcmp(buf, "DEF", 3) == 0);
NUTS_TRUE(n == 3);
NUTS_TRUE(memcmp(buf, "DEF", 3) == 0);
}

TEST_CHECK(nn_close(sb) == 0);
TEST_CHECK(nn_close(sc) == 0);
TEST_NN_PASS(nn_close(sb));
TEST_NN_PASS(nn_close(sc));
}

void
test_pair_reject(void)
{
int sb, sc, sd, p1, p2;
char addr[32];
int sb, sc, sd, p1, p2;
char *addr;

testutil_scratch_addr("tcp", sizeof(addr), addr);
NUTS_ADDR(addr, "tcp");

TEST_CHECK((sb = nn_socket(AF_SP, NN_PAIR)) >= 0);
TEST_CHECK((sc = nn_socket(AF_SP, NN_PAIR)) >= 0);
TEST_CHECK((sd = nn_socket(AF_SP, NN_PAIR)) >= 0);
TEST_CHECK(sb != sc);
NUTS_TRUE((sb = nn_socket(AF_SP, NN_PAIR)) >= 0);
NUTS_TRUE((sc = nn_socket(AF_SP, NN_PAIR)) >= 0);
NUTS_TRUE((sd = nn_socket(AF_SP, NN_PAIR)) >= 0);
NUTS_TRUE(sb != sc);

TEST_NN_MARRY_EX(sc, sb, addr, p1, p2);

TEST_CHECK(nn_connect(sd, addr) >= 0);
testutil_sleep(200);
NUTS_TRUE(nn_connect(sd, addr) >= 0);
NUTS_SLEEP(200);

TEST_CHECK(nn_close(sb) == 0);
TEST_CHECK(nn_close(sc) == 0);
TEST_CHECK(nn_close(sd) == 0);
TEST_NN_PASS(nn_close(sb));
TEST_NN_PASS(nn_close(sc));
TEST_NN_PASS(nn_close(sd));
}

void
test_addr_in_use(void)
{
int sb, sc;
char addr[64];

testutil_scratch_addr("tcp", sizeof(addr), addr);
int sb, sc;
char *addr;

TEST_CHECK((sb = nn_socket(AF_SP, NN_PAIR)) >= 0);
TEST_CHECK((sc = nn_socket(AF_SP, NN_PAIR)) >= 0);
TEST_CHECK(sb != sc);
NUTS_ADDR(addr, "tcp");
NUTS_TRUE((sb = nn_socket(AF_SP, NN_PAIR)) >= 0);
NUTS_TRUE((sc = nn_socket(AF_SP, NN_PAIR)) >= 0);
NUTS_TRUE(sb != sc);
TEST_NN_PASS(nn_bind(sb, addr));
TEST_NN_FAIL(nn_bind(sc, addr), EADDRINUSE);

TEST_CHECK(nn_close(sb) == 0);
TEST_CHECK(nn_close(sc) == 0);
TEST_NN_PASS(nn_close(sb));
TEST_NN_PASS(nn_close(sc));
}

void
test_max_recv_size(void)
{
int sb, sc, p1, p2;
int opt;
int n;
size_t sz;
char addr[64];
char buf[64];

testutil_scratch_addr("tcp", sizeof(addr), addr);

TEST_CHECK((sb = nn_socket(AF_SP, NN_PAIR)) >= 0);
TEST_CHECK((sc = nn_socket(AF_SP, NN_PAIR)) >= 0);
TEST_CHECK(sb != sc);
int sb, sc, p1, p2;
int opt;
int n;
size_t sz;
char buf[64];
char *addr;

NUTS_ADDR(addr, "tcp");

NUTS_TRUE((sb = nn_socket(AF_SP, NN_PAIR)) >= 0);
NUTS_TRUE((sc = nn_socket(AF_SP, NN_PAIR)) >= 0);
NUTS_TRUE(sb != sc);
opt = 100;
sz = sizeof(opt);
TEST_NN_PASS(nn_setsockopt(sb, NN_SOL_SOCKET, NN_RCVTIMEO, &opt, sz));
Expand All @@ -231,17 +228,17 @@ test_max_recv_size(void)
opt = -5;
TEST_NN_PASS(
nn_getsockopt(sb, NN_SOL_SOCKET, NN_RCVMAXSIZE, &opt, &sz));
TEST_CHECK(opt == 4);
TEST_CHECK(sz == sizeof(opt));
NUTS_TRUE(opt == 4);
NUTS_TRUE(sz == sizeof(opt));

TEST_NN_MARRY_EX(sc, sb, addr, p1, p2);

TEST_NN_PASS(nn_send(sc, "ABC", 4, 0));
TEST_NN_PASS(nn_send(sc, "012345", 6, 0));

TEST_NN_PASS(n = nn_recv(sb, buf, sizeof(buf), 0));
TEST_CHECK(n == 4);
TEST_CHECK(strcmp(buf, "ABC") == 0);
NUTS_TRUE(n == 4);
NUTS_TRUE(strcmp(buf, "ABC") == 0);

TEST_NN_FAIL(nn_recv(sb, buf, sizeof(buf), 0), ETIMEDOUT);

Expand Down
40 changes: 18 additions & 22 deletions src/compat/nanomsg/compat_testutil.h
Expand Up @@ -45,30 +45,26 @@ extern "C" {
// We do that to facilitate testing. Don't rely on this equivalence in your
// own application code.

#define TEST_NN_MARRY(s1, s2) \
do { \
int rv_; \
nng_socket s1_, s2_; \
s1_.id = s1; \
s2_.id = s2; \
\
TEST_CHECK_(testutil_marry(s1_, s2_) == 0, "marry %s", \
nng_strerror(rv_)); \
#define TEST_NN_MARRY(s1, s2) \
do { \
nng_socket s1_, s2_; \
s1_.id = s1; \
s2_.id = s2; \
\
NUTS_MARRY(s1_, s2_); \
} while (0)

#define TEST_NN_MARRY_EX(s1, s2, url, p1, p2) \
do { \
int rv_; \
nng_socket s1_, s2_; \
nng_pipe p1_, p2_; \
s1_.id = s1; \
s2_.id = s2; \
rv_ = testutil_marry_ex(s1_, s2_, url, &p1_, &p2_); \
TEST_CHECK_(rv_ == 0, "marry %s", nng_strerror(rv_)); \
p1 = p1_.id; \
p2 = p2_.id; \
TEST_CHECK(p1 >= 0); \
TEST_CHECK(p2 >= 0); \
#define TEST_NN_MARRY_EX(s1, s2, url, p1, p2) \
do { \
nng_socket s1_, s2_; \
nng_pipe p1_, p2_; \
s1_.id = s1; \
s2_.id = s2; \
NUTS_MARRY_EX(s1_, s2_, url, &p1_, &p2_); \
p1 = p1_.id; \
p2 = p2_.id; \
NUTS_TRUE(p1 >= 0); \
NUTS_TRUE(p2 >= 0); \
} while (0)

#ifdef __cplusplus
Expand Down

0 comments on commit 4f04e08

Please sign in to comment.