Exemple #1
0
SETUP_TEARDOWN_TESTCONTEXT

void test_diffserv ()
{
    int tos = 0x28;
    int o_tos;
    size_t tos_size = sizeof (tos);
    char my_endpoint[MAX_SOCKET_STRING];

    void *sb = test_context_socket (ZMQ_PAIR);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sb, ZMQ_TOS, &tos, tos_size));
    bind_loopback_ipv4 (sb, my_endpoint, sizeof (my_endpoint));

    TEST_ASSERT_SUCCESS_ERRNO (zmq_getsockopt (sb, ZMQ_TOS, &o_tos, &tos_size));
    TEST_ASSERT_EQUAL (tos, o_tos);

    void *sc = test_context_socket (ZMQ_PAIR);
    tos = 0x58;
    TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sc, ZMQ_TOS, &tos, tos_size));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, my_endpoint));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_getsockopt (sc, ZMQ_TOS, &o_tos, &tos_size));
    TEST_ASSERT_EQUAL (tos, o_tos);

    // Wireshark can be used to verify that the server socket is
    // using DSCP 0x28 in packets to the client while the client
    // is using 0x58 in packets to the server.
    bounce (sb, sc);

    test_context_socket_close (sc);
    test_context_socket_close (sb);
}
void test_multiple_connects ()
{
    const unsigned int no_of_connects = 10;

    void *connect_socket[no_of_connects];

    // Connect first
    for (unsigned int i = 0; i < no_of_connects; ++i) {
        connect_socket[i] = test_context_socket (ZMQ_PUSH);
        TEST_ASSERT_SUCCESS_ERRNO (
          zmq_connect (connect_socket[i], "inproc://multiple"));

        // Queue up some data
        send_string_expect_success (connect_socket[i], "foobar", 0);
    }

    // Now bind
    void *bind_socket = test_context_socket (ZMQ_PULL);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket, "inproc://multiple"));

    for (unsigned int i = 0; i < no_of_connects; ++i) {
        recv_string_expect_success (bind_socket, "foobar", 0);
    }

    // Cleanup
    for (unsigned int i = 0; i < no_of_connects; ++i) {
        test_context_socket_close (connect_socket[i]);
    }

    test_context_socket_close (bind_socket);
}
void test_rebind_ipc ()
{
    char my_endpoint[32];
    make_random_ipc_endpoint (my_endpoint);

    void *sb0 = test_context_socket (ZMQ_PUSH);
    void *sb1 = test_context_socket (ZMQ_PUSH);

    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb0, my_endpoint));

    void *sc = test_context_socket (ZMQ_PULL);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, my_endpoint));

    send_string_expect_success (sb0, "42", 0);
    recv_string_expect_success (sc, "42", 0);

    test_context_socket_close (sb0);

    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb1, my_endpoint));

    send_string_expect_success (sb1, "42", 0);
    recv_string_expect_success (sc, "42", 0);

    test_context_socket_close (sc);
    test_context_socket_close (sb1);
}
Exemple #4
0
void test_pair_tcp_connect_by_name ()
{
    // all other tcp test cases bind to a loopback wildcard address, then
    // retrieve the bound endpoint, which is numerical, and use that to
    // connect. this test cases specifically uses "localhost" to connect
    // to ensure that names are correctly resolved
    void *sb = test_context_socket (ZMQ_PAIR);

    char bound_endpoint[MAX_SOCKET_STRING];
    bind_loopback_ipv4 (sb, bound_endpoint, sizeof bound_endpoint);

    // extract the bound port number
    const char *pos = strrchr (bound_endpoint, ':');
    TEST_ASSERT_NOT_NULL (pos);
    const char connect_endpoint_prefix[] = "tcp://localhost";
    char connect_endpoint[MAX_SOCKET_STRING];
    strcpy (connect_endpoint, connect_endpoint_prefix);
    strcat (connect_endpoint, pos);

    void *sc = test_context_socket (ZMQ_PAIR);

    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, connect_endpoint));

    bounce (sb, sc);

    test_context_socket_close (sc);
    test_context_socket_close (sb);
}
void test_connect_before_bind_pub_sub ()
{
    // Connect first
    void *connect_socket = test_context_socket (ZMQ_PUB);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, "inproc://cbbps"));

    // Queue up some data, this will be dropped
    send_string_expect_success (connect_socket, "before", 0);

    // Now bind
    void *bind_socket = test_context_socket (ZMQ_SUB);
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (bind_socket, ZMQ_SUBSCRIBE, "", 0));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket, "inproc://cbbps"));

    // Wait for pub-sub connection to happen
    msleep (SETTLE_TIME);

    // Queue up some data, this not will be dropped
    send_string_expect_success (connect_socket, "after", 0);

    // Read pending message
    recv_string_expect_success (bind_socket, "after", 0);

    // Cleanup
    test_context_socket_close (connect_socket);
    test_context_socket_close (bind_socket);
}
void test_unbind ()
{
    // Bind and unbind socket 1
    void *bind_socket1 = test_context_socket (ZMQ_PAIR);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket1, "inproc://unbind"));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_unbind (bind_socket1, "inproc://unbind"));

    // Bind socket 2
    void *bind_socket2 = test_context_socket (ZMQ_PAIR);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket2, "inproc://unbind"));

    // Now connect
    void *connect_socket = test_context_socket (ZMQ_PAIR);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, "inproc://unbind"));

    // Queue up some data
    send_string_expect_success (connect_socket, "foobar", 0);

    // Read pending message
    recv_string_expect_success (bind_socket2, "foobar", 0);

    // Cleanup
    test_context_socket_close (connect_socket);
    test_context_socket_close (bind_socket1);
    test_context_socket_close (bind_socket2);
}
Exemple #7
0
// This checks for normal operation - that is pings and pongs being
// exchanged normally. There should be an accepted event on the server,
// and then no event afterwards.
static void
test_heartbeat_notimeout (int is_curve_, int client_type_, int server_type_)
{
    int rc;
    char my_endpoint[MAX_SOCKET_STRING];

    void *server, *server_mon;
    prep_server_socket (1, is_curve_, &server, &server_mon, my_endpoint,
                        MAX_SOCKET_STRING, server_type_);

    void *client = test_context_socket (client_type_);
    if (is_curve_)
        setup_curve (client, 0);
    rc = zmq_connect (client, my_endpoint);

    // Give it a sec to connect and handshake
    msleep (SETTLE_TIME);

    // By now everything should report as connected
    rc = get_monitor_event (server_mon);
    TEST_ASSERT_EQUAL_INT (ZMQ_EVENT_ACCEPTED, rc);

    // We should still be connected because pings and pongs are happenin'
    TEST_ASSERT_EQUAL_INT (-1, get_monitor_event (server_mon));

    test_context_socket_close (client);
    test_context_socket_close (server);
    test_context_socket_close (server_mon);
}
void test_get_peer_state_corner_cases ()
{
#ifdef ZMQ_BUILD_DRAFT_API
    const char peer_routing_id[] = "foo";

    //  call get_peer_state with NULL socket
    int rc = zmq_socket_get_peer_state (NULL, peer_routing_id,
                                        strlen (peer_routing_id));
    TEST_ASSERT_EQUAL_INT (-1, rc);
    TEST_ASSERT_EQUAL_INT (ENOTSOCK, errno);

    void *dealer = test_context_socket (ZMQ_DEALER);
    void *router = test_context_socket (ZMQ_ROUTER);

    //  call get_peer_state with a non-ROUTER socket
    rc = zmq_socket_get_peer_state (dealer, peer_routing_id,
                                    strlen (peer_routing_id));
    TEST_ASSERT_EQUAL_INT (-1, rc);
    TEST_ASSERT_EQUAL_INT (ENOTSUP, errno);

    //  call get_peer_state for an unknown routing id
    rc = zmq_socket_get_peer_state (router, peer_routing_id,
                                    strlen (peer_routing_id));
    TEST_ASSERT_EQUAL_INT (-1, rc);
    TEST_ASSERT_EQUAL_INT (EHOSTUNREACH, errno);

    test_context_socket_close (router);
    test_context_socket_close (dealer);
#endif
}
SETUP_TEARDOWN_TESTCONTEXT

void test ()
{
    //  Create a publisher
    void *pub = test_context_socket (ZMQ_XPUB);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (pub, "inproc://soname"));

    //  set pub socket options
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (pub, ZMQ_XPUB_WELCOME_MSG, "W", 1));

    //  Create a subscriber
    void *sub = test_context_socket (ZMQ_SUB);

    // Subscribe to the welcome message
    TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, "W", 1));

    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sub, "inproc://soname"));

    const uint8_t buffer[2] = {1, 'W'};

    // Receive the welcome subscription
    recv_array_expect_success (pub, buffer, 0);

    // Receive the welcome message
    recv_string_expect_success (sub, "W", 0);

    //  Clean up.
    test_context_socket_close (pub);
    test_context_socket_close (sub);
}
void test_send_one_connected_one_unconnected ()
{
    int val;
    // TEST 1.
    // First we're going to attempt to send messages to two
    // pipes, one connected, the other not. We should see
    // the PUSH load balancing to both pipes, and hence half
    // of the messages getting queued, as connect() creates a
    // pipe immediately.

    void *to = test_context_socket (ZMQ_PULL);

    // Bind the one valid receiver
    val = 0;
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (to, ZMQ_LINGER, &val, sizeof (val)));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (to, "tipc://{6555,0,0}"));

    // Create a socket pushing to two endpoints - only 1 message should arrive.
    void *from = test_context_socket (ZMQ_PUSH);

    val = 0;
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (from, ZMQ_LINGER, &val, sizeof (val)));
    // This pipe will not connect
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (from, "tipc://{5556,0}@0.0.0"));
    // This pipe will
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (from, "tipc://{6555,0}@0.0.0"));

    // We send 10 messages, 5 should just get stuck in the queue
    // for the not-yet-connected pipe
    const int send_count = 10;
    for (int i = 0; i < send_count; ++i) {
        send_string_expect_success (from, "Hello", 0);
    }

    // We now consume from the connected pipe
    // - we should see just 5
    int timeout = SETTLE_TIME;
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (to, ZMQ_RCVTIMEO, &timeout, sizeof (int)));

    int seen = 0;
    while (true) {
        char buffer[16];
        int rc = zmq_recv (to, &buffer, sizeof (buffer), 0);
        if (rc == -1) {
            TEST_ASSERT_EQUAL_INT (EAGAIN, zmq_errno ());
            break; //  Break when we didn't get a message
        }
        seen++;
    }
    TEST_ASSERT_EQUAL_INT (send_count / 2, seen);

    test_context_socket_close (from);
    test_context_socket_close (to);
}
void test_send_disconnected_with_delay ()
{
    // TEST 3
    // This time we want to validate that the same blocking behaviour
    // occurs with an existing connection that is broken. We will send
    // messages to a connected pipe, disconnect and verify the messages
    // block. Then we reconnect and verify messages flow again.
    void *backend = test_context_socket (ZMQ_DEALER);
    void *frontend = test_context_socket (ZMQ_DEALER);
    int zero = 0;
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (backend, ZMQ_LINGER, &zero, sizeof (zero)));
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (frontend, ZMQ_LINGER, &zero, sizeof (zero)));

    //  Frontend connects to backend using DELAY_ATTACH_ON_CONNECT
    int on = 1;
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (frontend, ZMQ_DELAY_ATTACH_ON_CONNECT, &on, sizeof (on)));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (backend, "tipc://{5560,0,0}"));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (frontend, "tipc://{5560,0}@0.0.0"));

    //  Ping backend to frontend so we know when the connection is up
    send_string_expect_success (backend, "Hello", 0);
    recv_string_expect_success (frontend, "Hello", 0);

    // Send message from frontend to backend
    send_string_expect_success (frontend, "Hello", ZMQ_DONTWAIT);

    test_context_socket_close (backend);

    //  Give time to process disconnect
    msleep (SETTLE_TIME);

    // Send a message, should fail
    TEST_ASSERT_FAILURE_ERRNO (EAGAIN,
                               zmq_send (frontend, "Hello", 5, ZMQ_DONTWAIT));

    //  Recreate backend socket
    backend = test_context_socket (ZMQ_DEALER);
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (backend, ZMQ_LINGER, &zero, sizeof (zero)));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (backend, "tipc://{5560,0,0}"));

    //  Ping backend to frontend so we know when the connection is up
    send_string_expect_success (backend, "Hello", 0);
    recv_string_expect_success (frontend, "Hello", 0);

    // After the reconnect, should succeed
    send_string_expect_success (frontend, "Hello", ZMQ_DONTWAIT);

    test_context_socket_close (backend);
    test_context_socket_close (frontend);
}
void test_roundtrip ()
{
    void *sb = test_context_socket (ZMQ_REP);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb, "inproc://a"));

    void *sc = test_context_socket (ZMQ_REQ);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, "inproc://a"));

    bounce (sb, sc);

    test_context_socket_close (sc);
    test_context_socket_close (sb);
}
Exemple #13
0
SETUP_TEARDOWN_TESTCONTEXT

void test ()
{
    char endpoint1[MAX_SOCKET_STRING];
    char endpoint2[MAX_SOCKET_STRING];

    //  First, create an intermediate device
    void *xpub = test_context_socket (ZMQ_XPUB);
    bind_loopback_ipv4 (xpub, endpoint1, sizeof (endpoint1));

    void *xsub = test_context_socket (ZMQ_XSUB);
    bind_loopback_ipv4 (xsub, endpoint2, sizeof (endpoint2));

    //  Create a publisher
    void *pub = test_context_socket (ZMQ_PUB);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (pub, endpoint2));

    //  Create a subscriber
    void *sub = test_context_socket (ZMQ_SUB);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sub, endpoint1));

    //  Subscribe for all messages.
    TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, "", 0));

    //  Pass the subscription upstream through the device
    char buff[32];
    int size;
    TEST_ASSERT_SUCCESS_ERRNO (size = zmq_recv (xpub, buff, sizeof (buff), 0));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_send (xsub, buff, size, 0));

    //  Wait a bit till the subscription gets to the publisher
    msleep (SETTLE_TIME);

    //  Send an empty message
    send_string_expect_success (pub, "", 0);

    //  Pass the message downstream through the device
    TEST_ASSERT_SUCCESS_ERRNO (size = zmq_recv (xsub, buff, sizeof (buff), 0));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_send (xpub, buff, size, 0));

    //  Receive the message in the subscriber
    recv_string_expect_success (sub, "", 0);

    //  Clean up.
    test_context_socket_close (xpub);
    test_context_socket_close (xsub);
    test_context_socket_close (pub);
    test_context_socket_close (sub);
}
int test_defaults (int send_hwm_, int msg_cnt_, const char *endpoint)
{
    size_t len = SOCKET_STRING_LEN;
    char pub_endpoint[SOCKET_STRING_LEN];

    // Set up and bind XPUB socket
    void *pub_socket = test_context_socket (ZMQ_XPUB);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (pub_socket, endpoint));
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_getsockopt (pub_socket, ZMQ_LAST_ENDPOINT, pub_endpoint, &len));

    // Set up and connect SUB socket
    void *sub_socket = test_context_socket (ZMQ_SUB);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sub_socket, pub_endpoint));

    //set a hwm on publisher
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (pub_socket, ZMQ_SNDHWM, &send_hwm_, sizeof (send_hwm_)));
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (sub_socket, ZMQ_SUBSCRIBE, 0, 0));

    // Wait before starting TX operations till 1 subscriber has subscribed
    // (in this test there's 1 subscriber only)
    const char subscription_to_all_topics[] = {1, 0};
    recv_string_expect_success (pub_socket, subscription_to_all_topics, 0);

    // Send until we reach "mute" state
    int send_count = 0;
    while (send_count < msg_cnt_
           && zmq_send (pub_socket, "test message", 13, ZMQ_DONTWAIT) == 13)
        ++send_count;

    TEST_ASSERT_EQUAL_INT (send_hwm_, send_count);
    msleep (SETTLE_TIME);

    // Now receive all sent messages
    int recv_count = 0;
    char dummybuff[64];
    while (13 == zmq_recv (sub_socket, &dummybuff, 64, ZMQ_DONTWAIT)) {
        ++recv_count;
    }

    TEST_ASSERT_EQUAL_INT (send_hwm_, recv_count);

    // Clean up
    test_context_socket_close (sub_socket);
    test_context_socket_close (pub_socket);

    return recv_count;
}
SETUP_TEARDOWN_TESTCONTEXT

void test ()
{
    //  First, create an intermediate device.
    void *xpub = test_context_socket (ZMQ_XPUB);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (xpub, "tipc://{5560,0,0}"));
    void *xsub = test_context_socket (ZMQ_XSUB);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (xsub, "tipc://{5561,0,0}"));

    //  Create a publisher.
    void *pub = test_context_socket (ZMQ_PUB);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (pub, "tipc://{5561,0}@0.0.0"));

    //  Create a subscriber.
    void *sub = test_context_socket (ZMQ_SUB);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sub, "tipc://{5560,0}@0.0.0"));

    // TODO the remainder of this method is duplicated with test_sub_forward

    //  Subscribe for all messages.
    TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, "", 0));

    //  Pass the subscription upstream through the device
    char buff[32];
    int size;
    TEST_ASSERT_SUCCESS_ERRNO (size = zmq_recv (xpub, buff, sizeof (buff), 0));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_send (xsub, buff, size, 0));

    //  Wait a bit till the subscription gets to the publisher
    msleep (SETTLE_TIME);

    //  Send an empty message
    send_string_expect_success (pub, "", 0);

    //  Pass the message downstream through the device
    TEST_ASSERT_SUCCESS_ERRNO (size = zmq_recv (xsub, buff, sizeof (buff), 0));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_send (xpub, buff, size, 0));

    //  Receive the message in the subscriber
    recv_string_expect_success (sub, "", 0);

    //  Clean up.
    test_context_socket_close (xpub);
    test_context_socket_close (xsub);
    test_context_socket_close (pub);
    test_context_socket_close (sub);
}
Exemple #16
0
void test_stream_2_stream ()
{
    char buff[256];
    const char msg[] = "hi 1";
    const int disabled = 0;
    const int zero = 0;
    char my_endpoint[MAX_SOCKET_STRING];

    //  Set up listener STREAM.
    void *rbind = test_context_socket (ZMQ_STREAM);
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (rbind, ZMQ_STREAM_NOTIFY, &disabled, sizeof (disabled)));

    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (rbind, ZMQ_LINGER, &zero, sizeof zero));
    bind_loopback_ipv4 (rbind, my_endpoint, sizeof my_endpoint);

    //  Set up connection stream.
    void *rconn1 = test_context_socket (ZMQ_STREAM);
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (rconn1, ZMQ_LINGER, &zero, sizeof zero));

    //  Do the connection.
    TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (rconn1, ZMQ_CONNECT_ROUTING_ID,
                                               rconn1routing_id,
                                               strlen (rconn1routing_id)));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (rconn1, my_endpoint));

    /*  Uncomment to test assert on duplicate routing id.
    //  Test duplicate connect attempt.
    TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (rconn1, ZMQ_CONNECT_ROUTING_ID, rconn1routing_id, strlen(rconn1routing_id)));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (rconn1, bindip));
*/
    //  Send data to the bound stream.
    send_string_expect_success (rconn1, rconn1routing_id, ZMQ_SNDMORE);
    send_string_expect_success (rconn1, msg, 0);

    //  Accept data on the bound stream.
    TEST_ASSERT_GREATER_THAN (
      0, TEST_ASSERT_SUCCESS_ERRNO (zmq_recv (rbind, buff, 256, 0)));
    TEST_ASSERT_EQUAL (0, buff[0]); // an auto-generated routing id
    recv_string_expect_success (rbind, msg, 0);

    // Handle close of the socket.
    TEST_ASSERT_SUCCESS_ERRNO (zmq_unbind (rbind, my_endpoint));
    test_context_socket_close (rbind);
    test_context_socket_close (rconn1);
}
Exemple #17
0
void test_io_completion_port ()
{
    void *const s = test_context_socket (ZMQ_PAIR);
    SOCKET fd;
    size_t fd_size = sizeof fd;
    TEST_ASSERT_SUCCESS_ERRNO (zmq_getsockopt (s, ZMQ_FD, &fd, &fd_size));

    ::WSAPROTOCOL_INFO pi;
    TEST_ASSERT_SUCCESS_RAW_ERRNO (
      ::WSADuplicateSocket (fd, ::GetCurrentProcessId (), &pi));
    const SOCKET socket = ::WSASocket (pi.iAddressFamily /*AF_INET*/,
                                       pi.iSocketType /*SOCK_STREAM*/,
                                       pi.iProtocol /*IPPROTO_TCP*/, &pi, 0, 0);

    const HANDLE iocp =
      ::CreateIoCompletionPort (INVALID_HANDLE_VALUE, NULL, 0, 0);
    TEST_ASSERT_NOT_EQUAL (NULL, iocp);
    const HANDLE res =
      ::CreateIoCompletionPort (reinterpret_cast<HANDLE> (socket), iocp, 0, 0);
    TEST_ASSERT_NOT_EQUAL (NULL, res);

    TEST_ASSERT_SUCCESS_RAW_ERRNO (closesocket (socket));
    TEST_ASSERT_TRUE (CloseHandle (iocp));

    test_context_socket_close (s);
}
void test_shutdown_stress_tipc ()
{
    void *s1;
    void *s2;
    int i;
    int j;
    pthread_t threads[THREAD_COUNT];

    for (j = 0; j != 10; j++) {
        //  Check the shutdown with many parallel I/O threads.
        setup_test_context ();
        zmq_ctx_set (get_test_context (), ZMQ_IO_THREADS, 7);

        s1 = test_context_socket (ZMQ_PUB);

        TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (s1, "tipc://{5560,0,0}"));

        for (i = 0; i != THREAD_COUNT; i++) {
            s2 = zmq_socket (get_test_context (), ZMQ_SUB);
            TEST_ASSERT_SUCCESS_RAW_ERRNO (
              pthread_create (&threads[i], NULL, worker, s2));
        }

        for (i = 0; i != THREAD_COUNT; i++) {
            TEST_ASSERT_SUCCESS_RAW_ERRNO (pthread_join (threads[i], NULL));
        }

        test_context_socket_close (s1);

        teardown_test_context ();
    }
}
SETUP_TEARDOWN_TESTCONTEXT

void test_reconnect_ivl_against_pair_socket (const char *my_endpoint_,
                                             void *sb_)
{
    void *sc = test_context_socket (ZMQ_PAIR);
    int interval = -1;
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (sc, ZMQ_RECONNECT_IVL, &interval, sizeof (int)));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, my_endpoint_));

    bounce (sb_, sc);

    TEST_ASSERT_SUCCESS_ERRNO (zmq_unbind (sb_, my_endpoint_));

    expect_bounce_fail (sb_, sc);

    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb_, my_endpoint_));

    expect_bounce_fail (sb_, sc);

    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, my_endpoint_));

    bounce (sb_, sc);

    test_context_socket_close (sc);
}
void test_connect_only ()
{
    void *connect_socket = test_context_socket (ZMQ_PUSH);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, "inproc://a"));

    test_context_socket_close (connect_socket);
}
void test_multiple_threads ()
{
    const unsigned int no_of_threads = 30;

    void *threads[no_of_threads];

    // Connect first
    for (unsigned int i = 0; i < no_of_threads; ++i) {
        threads[i] = zmq_threadstart (&pusher, NULL);
    }

    // Now bind
    void *bind_socket = test_context_socket (ZMQ_PULL);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket, "inproc://sink"));

    for (unsigned int i = 0; i < no_of_threads; ++i) {
        // Read pending message
        recv_string_expect_success (bind_socket, "foobar", 0);
    }

    // Cleanup
    for (unsigned int i = 0; i < no_of_threads; ++i) {
        zmq_threadclose (threads[i]);
    }

    test_context_socket_close (bind_socket);
}
Exemple #22
0
void test_xpub_verbose_one_sub ()
{
    void *pub = test_context_socket (ZMQ_XPUB);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (pub, test_endpoint));

    void *sub = test_context_socket (ZMQ_SUB);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sub, test_endpoint));

    //  Subscribe for A
    TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, topic_a, 1));

    // Receive subscriptions from subscriber
    recv_array_expect_success (pub, subscribe_a_msg, 0);

    // Subscribe socket for B instead
    TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, topic_b, 1));

    // Receive subscriptions from subscriber
    recv_array_expect_success (pub, subscribe_b_msg, 0);

    //  Subscribe again for A again
    TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, topic_a, 1));

    //  This time it is duplicated, so it will be filtered out
    TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_recv (pub, NULL, 0, ZMQ_DONTWAIT));

    int verbose = 1;
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (pub, ZMQ_XPUB_VERBOSE, &verbose, sizeof (int)));

    // Subscribe socket for A again
    TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, topic_a, 1));

    // This time with VERBOSE the duplicated sub will be received
    recv_array_expect_success (pub, subscribe_a_msg, 0);

    // Sending A message and B Message
    send_string_expect_success (pub, topic_a, 0);
    send_string_expect_success (pub, topic_b, 0);

    recv_string_expect_success (sub, topic_a, 0);
    recv_string_expect_success (sub, topic_b, 0);

    //  Clean up.
    test_context_socket_close (pub);
    test_context_socket_close (sub);
}
void test_reconnect_ivl_ipc (void)
{
    const char *ipc_endpoint = "ipc:///tmp/test_reconnect_ivl";
    void *sb = test_context_socket (ZMQ_PAIR);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb, ipc_endpoint));

    test_reconnect_ivl_against_pair_socket (ipc_endpoint, sb);
    test_context_socket_close (sb);
}
Exemple #24
0
void test_setsockopt_heartbeat_ttl_more_than_max_fails ()
{
    void *const socket = test_context_socket (ZMQ_PAIR);
    const int value = heartbeat_ttl_max + 1;
    TEST_ASSERT_FAILURE_ERRNO (
      EINVAL,
      zmq_setsockopt (socket, ZMQ_HEARTBEAT_TTL, &value, sizeof (value)));

    test_context_socket_close (socket);
}
void test_reconnect_ivl_tcp (bind_function_t bind_function_)
{
    char my_endpoint[MAX_SOCKET_STRING];

    void *sb = test_context_socket (ZMQ_PAIR);
    bind_function_ (sb, my_endpoint, sizeof my_endpoint);

    test_reconnect_ivl_against_pair_socket (my_endpoint, sb);
    test_context_socket_close (sb);
}
Exemple #26
0
// This checks for a broken TCP connection (or, in this case a stuck one
// where the peer never responds to PINGS). There should be an accepted event
// then a disconnect event.
static void test_heartbeat_timeout (int server_type_, int mock_ping_)
{
    int rc;
    char my_endpoint[MAX_SOCKET_STRING];

    void *server, *server_mon;
    prep_server_socket (!mock_ping_, 0, &server, &server_mon, my_endpoint,
                        MAX_SOCKET_STRING, server_type_);

    struct sockaddr_in ip4addr;
    raw_socket s;

    ip4addr.sin_family = AF_INET;
    ip4addr.sin_port = htons (atoi (strrchr (my_endpoint, ':') + 1));
#if defined(ZMQ_HAVE_WINDOWS) && (_WIN32_WINNT < 0x0600)
    ip4addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
#else
    inet_pton (AF_INET, "127.0.0.1", &ip4addr.sin_addr);
#endif

    s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
    rc = TEST_ASSERT_SUCCESS_RAW_ERRNO (
      connect (s, (struct sockaddr *) &ip4addr, sizeof ip4addr));
    TEST_ASSERT_GREATER_THAN_INT (-1, rc);

    // Mock a ZMTP 3 client so we can forcibly time out a connection
    mock_handshake (s, mock_ping_);

    // By now everything should report as connected
    rc = get_monitor_event (server_mon);
    TEST_ASSERT_EQUAL_INT (ZMQ_EVENT_ACCEPTED, rc);

    if (!mock_ping_) {
        // We should have been disconnected
        rc = get_monitor_event (server_mon);
        TEST_ASSERT_EQUAL_INT (ZMQ_EVENT_DISCONNECTED, rc);
    }

    close (s);

    test_context_socket_close (server);
    test_context_socket_close (server_mon);
}
void test_bind_before_connect ()
{
    // Bind first
    void *bind_socket = test_context_socket (ZMQ_PAIR);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket, "inproc://bbc"));

    // Now connect
    void *connect_socket = test_context_socket (ZMQ_PAIR);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, "inproc://bbc"));

    // Queue up some data
    send_string_expect_success (connect_socket, "foobar", 0);

    // Read pending message
    recv_string_expect_success (bind_socket, "foobar", 0);

    // Cleanup
    test_context_socket_close (connect_socket);
    test_context_socket_close (bind_socket);
}
void test_shutdown_during_pend ()
{
    // Connect first
    void *connect_socket = test_context_socket (ZMQ_PAIR);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, "inproc://cbb"));

    zmq_ctx_shutdown (get_test_context ());

    // Cleanup
    test_context_socket_close (connect_socket);
}
void test_reconnect_ivl_ipc (void)
{
    char my_endpoint[256];
    make_random_ipc_endpoint (my_endpoint);

    void *sb = test_context_socket (ZMQ_PAIR);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb, my_endpoint));

    test_reconnect_ivl_against_pair_socket (my_endpoint, sb);
    test_context_socket_close (sb);
}
void test_basic ()
{
    size_t len = MAX_SOCKET_STRING;
    char my_endpoint[MAX_SOCKET_STRING];
    void *router = test_context_socket (ZMQ_ROUTER);

    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (router, "tcp://127.0.0.1:*"));
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_getsockopt (router, ZMQ_LAST_ENDPOINT, my_endpoint, &len));

    //  Send a message to an unknown peer with the default setting
    //  This will not report any error
    send_string_expect_success (router, "UNKNOWN", ZMQ_SNDMORE);
    send_string_expect_success (router, "DATA", 0);

    //  Send a message to an unknown peer with mandatory routing
    //  This will fail
    int mandatory = 1;
    TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (router, ZMQ_ROUTER_MANDATORY,
                                               &mandatory, sizeof (mandatory)));
    int rc = zmq_send (router, "UNKNOWN", 7, ZMQ_SNDMORE);
    TEST_ASSERT_EQUAL_INT (-1, rc);
    TEST_ASSERT_EQUAL_INT (EHOSTUNREACH, errno);

    //  Create dealer called "X" and connect it to our router
    void *dealer = test_context_socket (ZMQ_DEALER);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (dealer, ZMQ_ROUTING_ID, "X", 1));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (dealer, my_endpoint));

    //  Get message from dealer to know when connection is ready
    send_string_expect_success (dealer, "Hello", 0);
    recv_string_expect_success (router, "X", 0);

    //  Send a message to connected dealer now
    //  It should work
    send_string_expect_success (router, "X", ZMQ_SNDMORE);
    send_string_expect_success (router, "Hello", 0);

    test_context_socket_close (router);
    test_context_socket_close (dealer);
}