1 /*
2 Copyright (c) 2013 GoPivotal, Inc. All rights reserved.
3 Copyright (c) 2014 Achille Roussel. All rights reserved.
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"),
7 to deal in the Software without restriction, including without limitation
8 the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 and/or sell copies of the Software, and to permit persons to whom
10 the Software is furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included
13 in all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 IN THE SOFTWARE.
22 */
23
24 #include "../src/nn.h"
25 #include "../src/pubsub.h"
26 #include "../src/reqrep.h"
27
28 #include "testutil.h"
29
30 /*
31 * Nanomsg never zero copies anymore - it used to be an attribute of
32 * the inproc transport, but frankly its a mistake for anyone to depend
33 * on that. The implementation must be free to copy, move data, etc.
34 * The only thing that should be guaranteed is that the "ownership" of the
35 * message on send is passed to libnanomsg. libnanomsg may give that message
36 * to an inproc receiver, or it can do something else (like copy the data)
37 * with it.
38 */
39 #if 0
40
41 #include <string.h>
42
43 void test_allocmsg_reqrep ()
44 {
45 int rc;
46 int req;
47 void *p;
48 struct nn_iovec iov;
49 struct nn_msghdr hdr;
50
51 /* Try to create an oversized message. */
52 p = nn_allocmsg (-1, 0);
53 nn_assert (!p && nn_errno () == ENOMEM);
54 p = nn_allocmsg (-3, 0);
55 nn_assert (!p && nn_errno () == ENOMEM);
56
57 /* Try to create a message of unknown type. */
58 p = nn_allocmsg (100, 333);
59 nn_assert (!p && nn_errno () == EINVAL);
60
61 /* Create a socket. */
62 req = test_socket (AF_SP_RAW, NN_REQ);
63
64 /* Make send fail and check whether the zero-copy buffer is left alone
65 rather than deallocated. */
66 p = nn_allocmsg (100, 0);
67 nn_assert (p);
68 rc = nn_send (req, &p, NN_MSG, NN_DONTWAIT);
69 nn_assert (rc < 0);
70 errno_assert (nn_errno () == EAGAIN);
71 memset (p, 0, 100);
72 rc = nn_freemsg (p);
73 errno_assert (rc == 0);
74
75 /* Same thing with nn_sendmsg(). */
76 p = nn_allocmsg (100, 0);
77 nn_assert (p);
78 iov.iov_base = &p;
79 iov.iov_len = NN_MSG;
80 memset (&hdr, 0, sizeof (hdr));
81 hdr.msg_iov = &iov;
82 hdr.msg_iovlen = 1;
83 nn_sendmsg (req, &hdr, NN_DONTWAIT);
84 errno_assert (nn_errno () == EAGAIN);
85 memset (p, 0, 100);
86 rc = nn_freemsg (p);
87 errno_assert (rc == 0);
88
89 /* Clean up. */
90 test_close (req);
91 }
92
93 void test_reallocmsg_reqrep ()
94 {
95 int rc;
96 int req;
97 int rep;
98 void *p;
99 void *p2;
100
101 /* Create sockets. */
102 req = nn_socket (AF_SP, NN_REQ);
103 rep = nn_socket (AF_SP, NN_REP);
104 rc = nn_bind (rep, "inproc://test");
105 errno_assert (rc >= 0);
106 rc = nn_connect (req, "inproc://test");
107 errno_assert (rc >= 0);
108
109 /* Create message, make sure we handle overflow. */
110 p = nn_allocmsg (100, 0);
111 nn_assert (p);
112 p2 = nn_reallocmsg (p, (size_t)-3);
113 errno_assert (nn_errno () == ENOMEM);
114 nn_assert (p2 == NULL);
115
116 /* Realloc to fit data size. */
117 memcpy (p, "Hello World!", 12);
118 p = nn_reallocmsg (p, 12);
119 nn_assert (p);
120 rc = nn_send (req, &p, NN_MSG, 0);
121 errno_assert (rc == 12);
122
123 /* Receive request and send response. */
124 rc = nn_recv (rep, &p, NN_MSG, 0);
125 errno_assert (rc == 12);
126 rc = nn_send (rep, &p, NN_MSG, 0);
127 errno_assert (rc == 12);
128
129 /* Receive response and free message. */
130 rc = nn_recv (req, &p, NN_MSG, 0);
131 errno_assert (rc == 12);
132 rc = memcmp (p, "Hello World!", 12);
133 nn_assert (rc == 0);
134 rc = nn_freemsg (p);
135 errno_assert (rc == 0);
136
137 /* Clean up. */
138 nn_close (req);
139 nn_close (rep);
140 }
141
142 void test_reallocmsg_pubsub ()
143 {
144 int rc;
145 int pub;
146 int sub1;
147 int sub2;
148 void *p;
149 void *p1;
150 void *p2;
151
152 /* Create sockets. */
153 pub = nn_socket (AF_SP, NN_PUB);
154 sub1 = nn_socket (AF_SP, NN_SUB);
155 sub2 = nn_socket (AF_SP, NN_SUB);
156 rc = nn_bind (pub, "inproc://test");
157 errno_assert (rc >= 0);
158 rc = nn_connect (sub1, "inproc://test");
159 errno_assert (rc >= 0);
160 rc = nn_connect (sub2, "inproc://test");
161 errno_assert (rc >= 0);
162 rc = nn_setsockopt (sub1, NN_SUB, NN_SUB_SUBSCRIBE, "", 0);
163 errno_assert (rc == 0);
164 rc = nn_setsockopt (sub2, NN_SUB, NN_SUB_SUBSCRIBE, "", 0);
165 errno_assert (rc == 0);
166
167 /* Publish message. */
168 p = nn_allocmsg (12, 0);
169 nn_assert (p);
170 memcpy (p, "Hello World!", 12);
171 rc = nn_send (pub, &p, NN_MSG, 0);
172 errno_assert (rc == 12);
173
174 /* Receive messages, both messages are the same object with inproc. */
175 rc = nn_recv (sub1, &p1, NN_MSG, 0);
176 errno_assert (rc == 12);
177 rc = nn_recv (sub2, &p2, NN_MSG, 0);
178 errno_assert (rc == 12);
179 nn_assert (p1 == p2);
180 rc = memcmp (p1, "Hello World!", 12);
181 nn_assert (rc == 0);
182 rc = memcmp (p2, "Hello World!", 12);
183 nn_assert (rc == 0);
184
185 /* Reallocate one message, both messages shouldn't be the same object
186 anymore. */
187 p1 = nn_reallocmsg (p1, 15);
188 errno_assert (p1);
189 nn_assert (p1 != p2);
190 memcpy (((char*) p1) + 12, " 42", 3);
191 rc = memcmp (p1, "Hello World! 42", 15);
192 nn_assert (rc == 0);
193
194 /* Release messages. */
195 rc = nn_freemsg (p1);
196 errno_assert (rc == 0);
197 rc = nn_freemsg (p2);
198 errno_assert (rc == 0);
199
200 /* Clean up. */
201 nn_close (sub2);
202 nn_close (sub1);
203 nn_close (pub);
204 }
205 #endif
206
main()207 int main ()
208 {
209 #if 0
210 test_allocmsg_reqrep ();
211 test_reallocmsg_reqrep ();
212 test_reallocmsg_pubsub ();
213 #endif
214 return 0;
215 }
216
217