test_radio_dish.cpp 6.73 KB
Newer Older
somdoron's avatar
somdoron committed
1
/*
2
    Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
somdoron's avatar
somdoron committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

    This file is part of libzmq, the ZeroMQ core engine in C++.

    libzmq is free software; you can redistribute it and/or modify it under
    the terms of the GNU Lesser General Public License (LGPL) as published
    by the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    As a special exception, the Contributors give you permission to link
    this library with independent modules to produce an executable,
    regardless of the license terms of these independent modules, and to
    copy and distribute the resulting executable under terms of your choice,
    provided that you also meet, for each linked independent module, the
    terms and conditions of the license of that module. An independent
    module is a module which is not derived from or based on this library.
    If you modify this library, you must extend this exception to your
    version of the library.

    libzmq is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
    License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "testutil.hpp"
31
#include "testutil_unity.hpp"
somdoron's avatar
somdoron committed
32

33 34 35
#include <unity.h>

void setUp ()
somdoron's avatar
somdoron committed
36
{
37 38
    setup_test_context ();
}
somdoron's avatar
somdoron committed
39

40 41 42 43
void tearDown ()
{
    teardown_test_context ();
}
somdoron's avatar
somdoron committed
44

45 46 47 48 49
void msg_send_expect_success (void *s_, const char *group_, const char *body_)
{
    zmq_msg_t msg;
    const size_t len = strlen (body_);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init_size (&msg, len));
somdoron's avatar
somdoron committed
50

51
    memcpy (zmq_msg_data (&msg), body_, len);
somdoron's avatar
somdoron committed
52

53
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_set_group (&msg, group_));
somdoron's avatar
somdoron committed
54

55 56 57 58 59
    int rc = zmq_msg_send (&msg, s_, 0);
    TEST_ASSERT_EQUAL_INT ((int) len, rc);

    // TODO isn't the msg closed by zmq_msg_send?
    zmq_msg_close (&msg);
somdoron's avatar
somdoron committed
60 61
}

62
void msg_recv_cmp (void *s_, const char *group_, const char *body_)
somdoron's avatar
somdoron committed
63
{
64 65 66 67 68 69 70 71 72 73 74 75
    zmq_msg_t msg;
    const size_t len = strlen (body_);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&msg));

    int recv_rc = TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&msg, s_, 0));
    TEST_ASSERT_EQUAL_INT (len, recv_rc);

    TEST_ASSERT_EQUAL_STRING (group_, zmq_msg_group (&msg));

    TEST_ASSERT_EQUAL_STRING_LEN (body_, zmq_msg_data (&msg), len);

    zmq_msg_close (&msg);
somdoron's avatar
somdoron committed
76 77
}

78
void test_leave_unjoined_fails ()
somdoron's avatar
somdoron committed
79
{
80
    void *dish = test_context_socket (ZMQ_DISH);
somdoron's avatar
somdoron committed
81

82 83
    //  Leaving a group which we didn't join
    TEST_ASSERT_FAILURE_ERRNO (EINVAL, zmq_leave (dish, "Movies"));
somdoron's avatar
somdoron committed
84

85 86
    test_context_socket_close (dish);
}
somdoron's avatar
somdoron committed
87

88 89 90
void test_join_too_long_fails ()
{
    void *dish = test_context_socket (ZMQ_DISH);
somdoron's avatar
somdoron committed
91 92 93 94 95 96

    //  Joining too long group
    char too_long_group[ZMQ_GROUP_MAX_LENGTH + 2];
    for (int index = 0; index < ZMQ_GROUP_MAX_LENGTH + 2; index++)
        too_long_group[index] = 'A';
    too_long_group[ZMQ_GROUP_MAX_LENGTH + 1] = '\0';
97
    TEST_ASSERT_FAILURE_ERRNO (EINVAL, zmq_join (dish, too_long_group));
somdoron's avatar
somdoron committed
98

99 100 101 102 103 104 105 106
    test_context_socket_close (dish);
}

void test_join_twice_fails ()
{
    void *dish = test_context_socket (ZMQ_DISH);

    TEST_ASSERT_SUCCESS_ERRNO (zmq_join (dish, "Movies"));
somdoron's avatar
somdoron committed
107 108

    // Duplicate Joining
109 110 111 112 113
    TEST_ASSERT_FAILURE_ERRNO (EINVAL, zmq_join (dish, "Movies"));

    test_context_socket_close (dish);
}

114
void test_radio_dish_tcp_poll ()
115 116 117 118 119 120 121 122 123 124 125
{
    size_t len = MAX_SOCKET_STRING;
    char my_endpoint[MAX_SOCKET_STRING];

    void *radio = test_context_socket (ZMQ_RADIO);
    bind_loopback_ipv4 (radio, my_endpoint, len);

    void *dish = test_context_socket (ZMQ_DISH);

    // Joining
    TEST_ASSERT_SUCCESS_ERRNO (zmq_join (dish, "Movies"));
somdoron's avatar
somdoron committed
126 127

    // Connecting
128
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (dish, my_endpoint));
somdoron's avatar
somdoron committed
129

130
    msleep (SETTLE_TIME);
somdoron's avatar
somdoron committed
131

somdoron's avatar
somdoron committed
132
    //  This is not going to be sent as dish only subscribe to "Movies"
133
    msg_send_expect_success (radio, "TV", "Friends");
somdoron's avatar
somdoron committed
134

somdoron's avatar
somdoron committed
135
    //  This is going to be sent to the dish
136
    msg_send_expect_success (radio, "Movies", "Godfather");
somdoron's avatar
somdoron committed
137

somdoron's avatar
somdoron committed
138
    //  Check the correct message arrived
139
    msg_recv_cmp (dish, "Movies", "Godfather");
somdoron's avatar
somdoron committed
140 141

    //  Join group during connection optvallen
142
    TEST_ASSERT_SUCCESS_ERRNO (zmq_join (dish, "TV"));
somdoron's avatar
somdoron committed
143 144 145 146

    zmq_sleep (1);

    //  This should arrive now as we joined the group
147
    msg_send_expect_success (radio, "TV", "Friends");
somdoron's avatar
somdoron committed
148

somdoron's avatar
somdoron committed
149
    //  Check the correct message arrived
150
    msg_recv_cmp (dish, "TV", "Friends");
somdoron's avatar
somdoron committed
151

152 153
    //  Leaving group
    TEST_ASSERT_SUCCESS_ERRNO (zmq_leave (dish, "TV"));
somdoron's avatar
somdoron committed
154 155 156

    zmq_sleep (1);

somdoron's avatar
somdoron committed
157
    //  This is not going to be sent as dish only subscribe to "Movies"
158
    msg_send_expect_success (radio, "TV", "Friends");
somdoron's avatar
somdoron committed
159 160

    //  This is going to be sent to the dish
161
    msg_send_expect_success (radio, "Movies", "Godfather");
somdoron's avatar
somdoron committed
162

163
    // test zmq_poll with dish
164 165 166
    zmq_pollitem_t items[] = {
      {radio, 0, ZMQ_POLLIN, 0}, // read publications
      {dish, 0, ZMQ_POLLIN, 0},  // read subscriptions
167
    };
168 169 170
    int rc = zmq_poll (items, 2, 2000);
    TEST_ASSERT_EQUAL_INT (1, rc);
    TEST_ASSERT_EQUAL_INT (ZMQ_POLLIN, items[1].revents);
171

somdoron's avatar
somdoron committed
172
    //  Check the correct message arrived
173
    msg_recv_cmp (dish, "Movies", "Godfather");
somdoron's avatar
somdoron committed
174

175 176 177
    test_context_socket_close (dish);
    test_context_socket_close (radio);
}
somdoron's avatar
somdoron committed
178

179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
void test_dish_connect_fails ()
{
    void *dish = test_context_socket (ZMQ_DISH);

    //  Connecting dish should fail
    TEST_ASSERT_FAILURE_ERRNO (ENOCOMPATPROTO,
                               zmq_connect (dish, "udp://127.0.0.1:5556"));

    test_context_socket_close (dish);
}

void test_radio_bind_fails ()
{
    void *radio = test_context_socket (ZMQ_RADIO);

    //  Connecting dish should fail
    //  Bind radio should fail
    TEST_ASSERT_FAILURE_ERRNO (ENOCOMPATPROTO,
                               zmq_bind (radio, "udp://*:5556"));

    test_context_socket_close (radio);
}

void test_radio_dish_udp ()
{
    void *radio = test_context_socket (ZMQ_RADIO);
    void *dish = test_context_socket (ZMQ_DISH);

    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (dish, "udp://*:5556"));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (radio, "udp://127.0.0.1:5556"));

    msleep (SETTLE_TIME);

    TEST_ASSERT_SUCCESS_ERRNO (zmq_join (dish, "TV"));

    msg_send_expect_success (radio, "TV", "Friends");
    msg_recv_cmp (dish, "TV", "Friends");

    test_context_socket_close (dish);
    test_context_socket_close (radio);
}

221 222 223
int main (void)
{
    setup_test_environment ();
somdoron's avatar
somdoron committed
224

225 226 227 228
    UNITY_BEGIN ();
    RUN_TEST (test_leave_unjoined_fails);
    RUN_TEST (test_join_too_long_fails);
    RUN_TEST (test_join_twice_fails);
229 230 231 232 233
    RUN_TEST (test_radio_bind_fails);
    RUN_TEST (test_dish_connect_fails);
    RUN_TEST (test_radio_dish_tcp_poll);
    RUN_TEST (test_radio_dish_udp);

234
    return UNITY_END ();
somdoron's avatar
somdoron committed
235
}