lib: Remove messages_local
[Samba.git] / source3 / lib / unix_msg / tests.c
blob2a4cf862347729b269801942c215f2dca339b9e3
1 #include "replace.h"
2 #include "unix_msg.h"
3 #include "poll_funcs/poll_funcs_tevent.h"
4 #include "tevent.h"
6 struct cb_state {
7 unsigned num_received;
8 uint8_t *buf;
9 size_t buflen;
12 static void recv_cb(struct unix_msg_ctx *ctx,
13 uint8_t *msg, size_t msg_len,
14 void *private_data);
16 static void expect_messages(struct tevent_context *ev, struct cb_state *state,
17 unsigned num_msgs)
19 state->num_received = 0;
21 while (state->num_received < num_msgs) {
22 int ret;
24 ret = tevent_loop_once(ev);
25 if (ret == -1) {
26 fprintf(stderr, "tevent_loop_once failed: %s\n",
27 strerror(errno));
28 exit(1);
33 int main(void)
35 struct poll_funcs funcs;
36 const char *sock1 = "sock1";
37 const char *sock2 = "sock2";
38 struct unix_msg_ctx *ctx1, *ctx2;
39 struct tevent_context *ev;
40 struct iovec iov;
41 uint8_t msg;
42 int i, ret;
43 static uint8_t buf[1755];
45 struct cb_state state;
47 unlink(sock1);
48 unlink(sock2);
50 ev = tevent_context_init(NULL);
51 if (ev == NULL) {
52 perror("tevent_context_init failed");
53 return 1;
55 poll_funcs_init_tevent(&funcs, ev);
57 ret = unix_msg_init(sock1, &funcs, 256, 1,
58 recv_cb, &state, &ctx1);
59 if (ret != 0) {
60 fprintf(stderr, "unix_msg_init failed: %s\n",
61 strerror(ret));
62 return 1;
65 ret = unix_msg_init(sock1, &funcs, 256, 1,
66 recv_cb, &state, &ctx1);
67 if (ret == 0) {
68 fprintf(stderr, "unix_msg_init succeeded unexpectedly\n");
69 return 1;
71 if (ret != EADDRINUSE) {
72 fprintf(stderr, "unix_msg_init returned %s, expected "
73 "EADDRINUSE\n", strerror(ret));
74 return 1;
77 ret = unix_msg_init(sock2, &funcs, 256, 1,
78 recv_cb, &state, &ctx2);
79 if (ret != 0) {
80 fprintf(stderr, "unix_msg_init failed: %s\n",
81 strerror(ret));
82 return 1;
85 printf("sending a 0-length message\n");
87 state.buf = NULL;
88 state.buflen = 0;
90 ret = unix_msg_send(ctx1, sock2, NULL, 0);
91 if (ret != 0) {
92 fprintf(stderr, "unix_msg_send failed: %s\n",
93 strerror(ret));
94 return 1;
97 expect_messages(ev, &state, 1);
99 printf("sending a small message\n");
101 msg = random();
102 iov.iov_base = &msg;
103 iov.iov_len = sizeof(msg);
104 state.buf = &msg;
105 state.buflen = sizeof(msg);
107 ret = unix_msg_send(ctx1, sock2, &iov, 1);
108 if (ret != 0) {
109 fprintf(stderr, "unix_msg_send failed: %s\n",
110 strerror(ret));
111 return 1;
114 expect_messages(ev, &state, 1);
116 printf("sending six large, interleaved messages\n");
118 for (i=0; i<sizeof(buf); i++) {
119 buf[i] = random();
122 iov.iov_base = buf;
123 iov.iov_len = sizeof(buf);
124 state.buf = buf;
125 state.buflen = sizeof(buf);
127 for (i=0; i<3; i++) {
128 ret = unix_msg_send(ctx1, sock2, &iov, 1);
129 if (ret != 0) {
130 fprintf(stderr, "unix_msg_send failed: %s\n",
131 strerror(ret));
132 return 1;
134 ret = unix_msg_send(ctx2, sock2, &iov, 1);
135 if (ret != 0) {
136 fprintf(stderr, "unix_msg_send failed: %s\n",
137 strerror(ret));
138 return 1;
142 expect_messages(ev, &state, 6);
144 printf("sending a few messages in small pieces\n");
146 for (i = 0; i<5; i++) {
147 struct iovec iovs[20];
148 const size_t num_iovs = ARRAY_SIZE(iovs);
149 uint8_t *p = buf;
150 size_t j;
152 for (j=0; j<num_iovs-1; j++) {
153 size_t chunk = (random() % ((sizeof(buf) * 2) / num_iovs));
154 size_t space = (sizeof(buf) - (p - buf));
156 if (space == 0) {
157 break;
160 chunk = MIN(chunk, space);
162 iovs[j].iov_base = p;
163 iovs[j].iov_len = chunk;
164 p += chunk;
167 if (p < (buf + sizeof(buf))) {
168 iovs[j].iov_base = p;
169 iovs[j].iov_len = (sizeof(buf) - (p - buf));
170 j++;
173 ret = unix_msg_send(ctx1, sock1, iovs, j);
174 if (ret != 0) {
175 fprintf(stderr, "unix_msg_send failed: %s\n",
176 strerror(ret));
177 return 1;
181 expect_messages(ev, &state, 5);
183 printf("Filling send queues before freeing\n");
185 for (i=0; i<5; i++) {
186 ret = unix_msg_send(ctx1, sock2, &iov, 1);
187 if (ret != 0) {
188 fprintf(stderr, "unix_msg_send failed: %s\n",
189 strerror(ret));
190 return 1;
192 ret = unix_msg_send(ctx1, sock1, &iov, 1);
193 if (ret != 0) {
194 fprintf(stderr, "unix_msg_send failed: %s\n",
195 strerror(ret));
196 return 1;
200 expect_messages(ev, &state, 1); /* Read just one msg */
202 unix_msg_free(ctx1);
203 unix_msg_free(ctx2);
204 talloc_free(ev);
206 return 0;
209 static void recv_cb(struct unix_msg_ctx *ctx,
210 uint8_t *msg, size_t msg_len,
211 void *private_data)
213 struct cb_state *state = (struct cb_state *)private_data;
215 if (msg_len != state->buflen) {
216 fprintf(stderr, "expected %u bytes, got %u\n",
217 (unsigned)state->buflen, (unsigned)msg_len);
218 exit(1);
220 if ((msg_len != 0) && (memcmp(msg, state->buf, msg_len) != 0)) {
221 fprintf(stderr, "message content differs\n");
222 exit(1);
224 state->num_received += 1;