1  /*
2     Copyright (c) 2012 Martin Sustrik  All rights reserved.
3 
4     Permission is hereby granted, free of charge, to any person obtaining a copy
5     of this software and associated documentation files (the "Software"),
6     to deal in the Software without restriction, including without limitation
7     the rights to use, copy, modify, merge, publish, distribute, sublicense,
8     and/or sell copies of the Software, and to permit persons to whom
9 
10     The above copyright notice and this permission notice shall be included
11     in all copies or substantial portions of the Software.
12 
13     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16     THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19     IN THE SOFTWARE.
20 */
21 
22 #include "../src/nn.h"
23 #include "../src/bus.h"
24 #include "../src/pair.h"
25 #include "../src/pubsub.h"
26 #include "../src/reqrep.h"
27 #include "../src/inproc.h"
28 
29 #include "testutil.h"
30 
31 /*  Tests inproc transport. */
32 
33 #define SOCKET_ADDRESS "inproc://test"
34 
main()35 int main ()
36 {
37     int rc;
38     int sb;
39     int sc;
40     int s1, s2;
41     int i;
42     char buf [256];
43     int val;
44     struct nn_msghdr hdr;
45     struct nn_iovec iovec;
46     unsigned char body [3];
47     void *control;
48     struct nn_cmsghdr *cmsg;
49     unsigned char *data;
50 
51     /*  Create a simple topology. */
52     sc = test_socket (AF_SP, NN_PAIR);
53     test_connect (sc, SOCKET_ADDRESS);
54     sb = test_socket (AF_SP, NN_PAIR);
55     test_bind (sb, SOCKET_ADDRESS);
56 
57     /*  Try a duplicate bind. It should fail. */
58     rc = nn_bind (sc, SOCKET_ADDRESS);
59     nn_assert (rc < 0 && errno == EADDRINUSE);
60 
61     /*  Ping-pong test. */
62     for (i = 0; i != 100; ++i) {
63 
64         test_send (sc, "ABC");
65         test_recv (sb, "ABC");
66         test_send (sb, "DEFG");
67         test_recv (sc, "DEFG");
68     }
69 
70     /*  Batch transfer test. */
71     for (i = 0; i != 100; ++i) {
72         test_send (sc, "XYZ");
73     }
74     for (i = 0; i != 100; ++i) {
75         test_recv (sb, "XYZ");
76     }
77 
78     test_close (sc);
79     test_close (sb);
80 
81     /*  Test whether queue limits are observed. */
82     sb = test_socket (AF_SP, NN_PAIR);
83     val = 200;
84     test_setsockopt (sb, NN_SOL_SOCKET, NN_RCVBUF, &val, sizeof (val));
85     test_bind (sb, SOCKET_ADDRESS);
86     sc = test_socket (AF_SP, NN_PAIR);
87     test_connect (sc, SOCKET_ADDRESS);
88 
89     val = 200;
90     test_setsockopt (sc, NN_SOL_SOCKET, NN_SNDTIMEO, &val, sizeof (val));
91     i = 0;
92     while (1) {
93         rc = nn_send (sc, "0123456789", 10, 0);
94         if (rc < 0 && nn_errno () == ETIMEDOUT)
95             break;
96         errno_assert (rc >= 0);
97         nn_assert (rc == 10);
98         ++i;
99     }
100     nn_assert (i == 20);
101     test_recv (sb, "0123456789");
102     test_send (sc, "0123456789");
103     rc = nn_send (sc, "0123456789", 10, 0);
104     nn_assert (rc < 0 && nn_errno () == ETIMEDOUT);
105     for (i = 0; i != 20; ++i) {
106         test_recv (sb, "0123456789");
107     }
108 
109     /*  Make sure that even a message that doesn't fit into the buffers
110         gets across. */
111     for (i = 0; i != sizeof (buf); ++i)
112         buf [i] = 'A';
113     rc = nn_send (sc, buf, 256, 0);
114     errno_assert (rc >= 0);
115     nn_assert (rc == 256);
116     rc = nn_recv (sb, buf, sizeof (buf), 0);
117     errno_assert (rc >= 0);
118     nn_assert (rc == 256);
119 
120     test_close (sc);
121     test_close (sb);
122 
123 #if 0
124     /*  Test whether connection rejection is handled decently. */
125     sb = test_socket (AF_SP, NN_PAIR);
126     test_bind (sb, SOCKET_ADDRESS);
127     s1 = test_socket (AF_SP, NN_PAIR);
128     test_connect (s1, SOCKET_ADDRESS);
129     s2 = test_socket (AF_SP, NN_PAIR);
130     test_connect (s2, SOCKET_ADDRESS);
131     nn_sleep (100);
132     test_close (s2);
133     test_close (s1);
134     test_close (sb);
135 #endif
136 
137     /* Check whether SP message header is transferred correctly. */
138     sb = test_socket (AF_SP_RAW, NN_REP);
139     test_bind (sb, SOCKET_ADDRESS);
140     sc = test_socket (AF_SP, NN_REQ);
141     test_connect (sc, SOCKET_ADDRESS);
142 
143     test_send (sc, "ABC");
144 
145     iovec.iov_base = body;
146     iovec.iov_len = sizeof (body);
147     hdr.msg_iov = &iovec;
148     hdr.msg_iovlen = 1;
149     hdr.msg_control = &control;
150     hdr.msg_controllen = NN_MSG;
151     rc = nn_recvmsg (sb, &hdr, 0);
152     errno_assert (rc == 3);
153 
154     cmsg = NN_CMSG_FIRSTHDR (&hdr);
155     while (1) {
156         nn_assert (cmsg);
157         if (cmsg->cmsg_level == PROTO_SP && cmsg->cmsg_type == SP_HDR)
158             break;
159         cmsg = NN_CMSG_NXTHDR (&hdr, cmsg);
160     }
161     nn_assert (cmsg->cmsg_len == NN_CMSG_SPACE (8+sizeof (size_t)));
162     data = NN_CMSG_DATA (cmsg);
163     nn_assert (!(data[0+sizeof (size_t)] & 0x80));
164     nn_assert (data[4+sizeof (size_t)] & 0x80);
165 
166     nn_freemsg (control);
167 
168     test_close (sc);
169     test_close (sb);
170 
171     /* Test binding a new socket after originally bound socket shuts down. */
172     sb = test_socket (AF_SP, NN_BUS);
173     test_bind (sb, SOCKET_ADDRESS);
174 
175     sc = test_socket (AF_SP, NN_BUS);
176     test_connect (sc, SOCKET_ADDRESS);
177 
178     s1 = test_socket (AF_SP, NN_BUS);
179     test_connect (s1, SOCKET_ADDRESS);
180 
181     /* Close bound socket, leaving connected sockets connect. */
182     test_close (sb);
183 
184     nn_sleep (100);
185 
186     /* Rebind a new socket to the address to which our connected sockets are listening. */
187     s2 = test_socket (AF_SP, NN_BUS);
188     test_bind (s2, SOCKET_ADDRESS);
189 
190     /*  Ping-pong test. */
191     for (i = 0; i != 100; ++i) {
192 
193         test_send (sc, "ABC");
194         test_send (s1, "QRS");
195         test_recv (s2, "ABC");
196         test_recv (s2, "QRS");
197         test_send (s2, "DEFG");
198         test_recv (sc, "DEFG");
199         test_recv (s1, "DEFG");
200     }
201 
202     /*  Batch transfer test. */
203     for (i = 0; i != 100; ++i) {
204         test_send (sc, "XYZ");
205     }
206     for (i = 0; i != 100; ++i) {
207         test_recv (s2, "XYZ");
208     }
209     for (i = 0; i != 100; ++i) {
210         test_send (s1, "MNO");
211     }
212     for (i = 0; i != 100; ++i) {
213         test_recv (s2, "MNO");
214     }
215 
216     test_close (s1);
217     test_close (sc);
218     test_close (s2);
219 
220     return 0;
221 }
222 
223