upload http
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / srclib / apr / test / testpoll.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "test_apr.h"
18 #include "apr_strings.h"
19 #include "apr_errno.h"
20 #include "apr_general.h"
21 #include "apr_lib.h"
22 #include "apr_network_io.h"
23 #include "apr_poll.h"
24
25 #define SMALL_NUM_SOCKETS 3
26 /* We can't use 64 here, because some platforms *ahem* Solaris *ahem* have
27  * a default limit of 64 open file descriptors per process.  If we use
28  * 64, the test will fail even though the code is correct.
29  */
30 #define LARGE_NUM_SOCKETS 50
31
32 static apr_socket_t *s[LARGE_NUM_SOCKETS];
33 static apr_sockaddr_t *sa[LARGE_NUM_SOCKETS];
34 static apr_pollfd_t *pollarray;
35 static apr_pollfd_t *pollarray_large;
36 static apr_pollset_t *pollset;
37
38 static void make_socket(apr_socket_t **sock, apr_sockaddr_t **sa, 
39                         apr_port_t port, apr_pool_t *p, CuTest *tc)
40 {
41     apr_status_t rv;
42
43     rv = apr_sockaddr_info_get(sa, "127.0.0.1", APR_UNSPEC, port, 0, p);
44     CuAssertIntEquals(tc, APR_SUCCESS, rv);
45
46     rv = apr_socket_create(sock, (*sa)->family, SOCK_DGRAM, p);
47     CuAssertIntEquals(tc, APR_SUCCESS, rv);
48
49     rv =apr_socket_bind((*sock), (*sa));
50     CuAssertIntEquals(tc, APR_SUCCESS, rv);
51 }
52
53 static void check_sockets(const apr_pollfd_t *pollarray, 
54                           apr_socket_t **sockarray, int which, int pollin, 
55                           CuTest *tc)
56 {
57     apr_status_t rv;
58     apr_int16_t event;
59     char *str;
60
61     rv = apr_poll_revents_get(&event, sockarray[which], 
62                               (apr_pollfd_t *)pollarray);
63     CuAssertIntEquals(tc, APR_SUCCESS, rv);
64     if (pollin) {
65         str = apr_psprintf(p, "Socket %d not signalled when it should be",
66                            which);
67         CuAssert(tc, str, event & APR_POLLIN);
68     } else {
69         str = apr_psprintf(p, "Socket %d signalled when it should not be",
70                            which);
71         CuAssert(tc, str, !(event & APR_POLLIN));
72     }
73 }
74
75 static void send_msg(apr_socket_t **sockarray, apr_sockaddr_t **sas, int which,
76                      CuTest *tc)
77 {
78     apr_size_t len = 5;
79     apr_status_t rv;
80
81     CuAssertPtrNotNull(tc, sockarray[which]);
82
83     rv = apr_socket_sendto(sockarray[which], sas[which], 0, "hello", &len);
84     CuAssertIntEquals(tc, APR_SUCCESS, rv);
85     CuAssertIntEquals(tc, strlen("hello"), len);
86 }
87
88 static void recv_msg(apr_socket_t **sockarray, int which, apr_pool_t *p, 
89                      CuTest *tc)
90 {
91     apr_size_t buflen = 5;
92     char *buffer = apr_pcalloc(p, sizeof(char) * (buflen + 1));
93     apr_sockaddr_t *recsa;
94     apr_status_t rv;
95
96     CuAssertPtrNotNull(tc, sockarray[which]);
97
98     apr_sockaddr_info_get(&recsa, "127.0.0.1", APR_UNSPEC, 7770, 0, p);
99
100     rv = apr_socket_recvfrom(recsa, sockarray[which], 0, buffer, &buflen);
101     CuAssertIntEquals(tc, APR_SUCCESS, rv);
102     CuAssertIntEquals(tc, strlen("hello"), buflen);
103     CuAssertStrEquals(tc, "hello", buffer);
104 }
105
106     
107 static void create_all_sockets(CuTest *tc)
108 {
109     int i;
110
111     for (i = 0; i < LARGE_NUM_SOCKETS; i++){
112         make_socket(&s[i], &sa[i], 7777 + i, p, tc);
113     }
114 }
115        
116 static void setup_small_poll(CuTest *tc)
117 {
118     apr_status_t rv;
119     int i;
120
121     rv = apr_poll_setup(&pollarray, SMALL_NUM_SOCKETS, p);
122     CuAssertIntEquals(tc, APR_SUCCESS, rv);
123     
124     for (i = 0; i < SMALL_NUM_SOCKETS;i++){
125         CuAssertIntEquals(tc, 0, pollarray[i].reqevents);
126         CuAssertIntEquals(tc, 0, pollarray[i].rtnevents);
127
128         rv = apr_poll_socket_add(pollarray, s[i], APR_POLLIN);
129         CuAssertIntEquals(tc, APR_SUCCESS, rv);
130         CuAssertPtrEquals(tc, s[i], pollarray[i].desc.s);
131     }
132 }
133
134 static void setup_large_poll(CuTest *tc)
135 {
136     apr_status_t rv;
137     int i;
138
139     rv = apr_poll_setup(&pollarray_large, LARGE_NUM_SOCKETS, p);
140     CuAssertIntEquals(tc, APR_SUCCESS, rv);
141     
142     for (i = 0; i < LARGE_NUM_SOCKETS;i++){
143         CuAssertIntEquals(tc, 0, pollarray_large[i].reqevents);
144         CuAssertIntEquals(tc, 0, pollarray_large[i].rtnevents);
145
146         rv = apr_poll_socket_add(pollarray_large, s[i], APR_POLLIN);
147         CuAssertIntEquals(tc, APR_SUCCESS, rv);
148         CuAssertPtrEquals(tc, s[i], pollarray_large[i].desc.s);
149     }
150 }
151
152 static void nomessage(CuTest *tc)
153 {
154     apr_status_t rv;
155     int srv = SMALL_NUM_SOCKETS;
156
157     rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
158     CuAssertIntEquals(tc, 1, APR_STATUS_IS_TIMEUP(rv));
159     check_sockets(pollarray, s, 0, 0, tc);
160     check_sockets(pollarray, s, 1, 0, tc);
161     check_sockets(pollarray, s, 2, 0, tc);
162 }
163
164 static void send_2(CuTest *tc)
165 {
166     apr_status_t rv;
167     int srv = SMALL_NUM_SOCKETS;
168
169     send_msg(s, sa, 2, tc);
170
171     rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
172     CuAssertIntEquals(tc, APR_SUCCESS, rv);
173     check_sockets(pollarray, s, 0, 0, tc);
174     check_sockets(pollarray, s, 1, 0, tc);
175     check_sockets(pollarray, s, 2, 1, tc);
176 }
177
178 static void recv_2_send_1(CuTest *tc)
179 {
180     apr_status_t rv;
181     int srv = SMALL_NUM_SOCKETS;
182
183     recv_msg(s, 2, p, tc);
184     send_msg(s, sa, 1, tc);
185
186     rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
187     CuAssertIntEquals(tc, APR_SUCCESS, rv);
188     check_sockets(pollarray, s, 0, 0, tc);
189     check_sockets(pollarray, s, 1, 1, tc);
190     check_sockets(pollarray, s, 2, 0, tc);
191 }
192
193 static void send_2_signaled_1(CuTest *tc)
194 {
195     apr_status_t rv;
196     int srv = SMALL_NUM_SOCKETS;
197
198     send_msg(s, sa, 2, tc);
199
200     rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
201     CuAssertIntEquals(tc, APR_SUCCESS, rv);
202     check_sockets(pollarray, s, 0, 0, tc);
203     check_sockets(pollarray, s, 1, 1, tc);
204     check_sockets(pollarray, s, 2, 1, tc);
205 }
206
207 static void recv_1_send_0(CuTest *tc)
208 {
209     apr_status_t rv;
210     int srv = SMALL_NUM_SOCKETS;
211
212     recv_msg(s, 1, p, tc);
213     send_msg(s, sa, 0, tc);
214
215     rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
216     CuAssertIntEquals(tc, APR_SUCCESS, rv);
217     check_sockets(pollarray, s, 0, 1, tc);
218     check_sockets(pollarray, s, 1, 0, tc);
219     check_sockets(pollarray, s, 2, 1, tc);
220 }
221
222 static void clear_all_signalled(CuTest *tc)
223 {
224     apr_status_t rv;
225     int srv = SMALL_NUM_SOCKETS;
226
227     recv_msg(s, 0, p, tc);
228     recv_msg(s, 2, p, tc);
229
230     rv = apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
231     CuAssertIntEquals(tc, 1, APR_STATUS_IS_TIMEUP(rv));
232     check_sockets(pollarray, s, 0, 0, tc);
233     check_sockets(pollarray, s, 1, 0, tc);
234     check_sockets(pollarray, s, 2, 0, tc);
235 }
236
237 static void send_large_pollarray(CuTest *tc)
238 {
239     apr_status_t rv;
240     int lrv = LARGE_NUM_SOCKETS;
241     int i;
242
243     send_msg(s, sa, LARGE_NUM_SOCKETS - 1, tc);
244
245     rv = apr_poll(pollarray_large, LARGE_NUM_SOCKETS, &lrv, 
246                   2 * APR_USEC_PER_SEC);
247     CuAssertIntEquals(tc, APR_SUCCESS, rv);
248
249     for (i = 0; i < LARGE_NUM_SOCKETS; i++) {
250         if (i == (LARGE_NUM_SOCKETS - 1)) {
251             check_sockets(pollarray_large, s, i, 1, tc);
252         }
253         else {
254             check_sockets(pollarray_large, s, i, 0, tc);
255         }
256     }
257 }
258
259 static void recv_large_pollarray(CuTest *tc)
260 {
261     apr_status_t rv;
262     int lrv = LARGE_NUM_SOCKETS;
263     int i;
264
265     recv_msg(s, LARGE_NUM_SOCKETS - 1, p, tc);
266
267     rv = apr_poll(pollarray_large, LARGE_NUM_SOCKETS, &lrv, 
268                   2 * APR_USEC_PER_SEC);
269     CuAssertIntEquals(tc, 1, APR_STATUS_IS_TIMEUP(rv));
270
271     for (i = 0; i < LARGE_NUM_SOCKETS; i++) {
272         check_sockets(pollarray_large, s, i, 0, tc);
273     }
274 }
275
276 static void setup_pollset(CuTest *tc)
277 {
278     apr_status_t rv;
279     rv = apr_pollset_create(&pollset, LARGE_NUM_SOCKETS, p, 0);
280     CuAssertIntEquals(tc, APR_SUCCESS, rv);
281 }
282
283 static void add_sockets_pollset(CuTest *tc)
284 {
285     apr_status_t rv;
286     int i;
287
288     for (i = 0; i < LARGE_NUM_SOCKETS;i++){
289         apr_pollfd_t socket_pollfd;
290
291         CuAssertPtrNotNull(tc, s[i]);
292
293         socket_pollfd.desc_type = APR_POLL_SOCKET;
294         socket_pollfd.reqevents = APR_POLLIN;
295         socket_pollfd.desc.s = s[i];
296         socket_pollfd.client_data = s[i];
297         rv = apr_pollset_add(pollset, &socket_pollfd);
298         CuAssertIntEquals(tc, APR_SUCCESS, rv);
299     }
300 }
301
302 static void nomessage_pollset(CuTest *tc)
303 {
304     apr_status_t rv;
305     int lrv;
306     const apr_pollfd_t *descs = NULL;
307
308     rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
309     CuAssertIntEquals(tc, 1, APR_STATUS_IS_TIMEUP(rv));
310     CuAssertIntEquals(tc, 0, lrv);
311     CuAssertPtrEquals(tc, NULL, descs);
312 }
313
314 static void send0_pollset(CuTest *tc)
315 {
316     apr_status_t rv;
317     const apr_pollfd_t *descs = NULL;
318     int num;
319     
320     send_msg(s, sa, 0, tc);
321     rv = apr_pollset_poll(pollset, 0, &num, &descs);
322     CuAssertIntEquals(tc, APR_SUCCESS, rv);
323     CuAssertIntEquals(tc, 1, num);
324     CuAssertPtrNotNull(tc, descs);
325
326     CuAssertPtrEquals(tc, s[0], descs[0].desc.s);
327     CuAssertPtrEquals(tc, s[0],  descs[0].client_data);
328 }
329
330 static void recv0_pollset(CuTest *tc)
331 {
332     apr_status_t rv;
333     int lrv;
334     const apr_pollfd_t *descs = NULL;
335
336     recv_msg(s, 0, p, tc);
337     rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
338     CuAssertIntEquals(tc, 1, APR_STATUS_IS_TIMEUP(rv));
339     CuAssertIntEquals(tc, 0, lrv);
340     CuAssertPtrEquals(tc, NULL, descs);
341 }
342
343 static void send_middle_pollset(CuTest *tc)
344 {
345     apr_status_t rv;
346     const apr_pollfd_t *descs = NULL;
347     int num;
348     
349     send_msg(s, sa, 2, tc);
350     send_msg(s, sa, 5, tc);
351     rv = apr_pollset_poll(pollset, 0, &num, &descs);
352     CuAssertIntEquals(tc, APR_SUCCESS, rv);
353     CuAssertIntEquals(tc, 2, num);
354     CuAssertPtrNotNull(tc, descs);
355
356     CuAssert(tc, "Incorrect socket in result set",
357             ((descs[0].desc.s == s[2]) && (descs[1].desc.s == s[5])) ||
358             ((descs[0].desc.s == s[5]) && (descs[1].desc.s == s[2])));
359 }
360
361 static void clear_middle_pollset(CuTest *tc)
362 {
363     apr_status_t rv;
364     int lrv;
365     const apr_pollfd_t *descs = NULL;
366
367     recv_msg(s, 2, p, tc);
368     recv_msg(s, 5, p, tc);
369
370     rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
371     CuAssertIntEquals(tc, 1, APR_STATUS_IS_TIMEUP(rv));
372     CuAssertIntEquals(tc, 0, lrv);
373     CuAssertPtrEquals(tc, NULL, descs);
374 }
375
376 static void send_last_pollset(CuTest *tc)
377 {
378     apr_status_t rv;
379     const apr_pollfd_t *descs = NULL;
380     int num;
381     
382     send_msg(s, sa, LARGE_NUM_SOCKETS - 1, tc);
383     rv = apr_pollset_poll(pollset, 0, &num, &descs);
384     CuAssertIntEquals(tc, APR_SUCCESS, rv);
385     CuAssertIntEquals(tc, 1, num);
386     CuAssertPtrNotNull(tc, descs);
387
388     CuAssertPtrEquals(tc, s[LARGE_NUM_SOCKETS - 1], descs[0].desc.s);
389     CuAssertPtrEquals(tc, s[LARGE_NUM_SOCKETS - 1],  descs[0].client_data);
390 }
391
392 static void clear_last_pollset(CuTest *tc)
393 {
394     apr_status_t rv;
395     int lrv;
396     const apr_pollfd_t *descs = NULL;
397
398     recv_msg(s, LARGE_NUM_SOCKETS - 1, p, tc);
399
400     rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
401     CuAssertIntEquals(tc, 1, APR_STATUS_IS_TIMEUP(rv));
402     CuAssertIntEquals(tc, 0, lrv);
403     CuAssertPtrEquals(tc, NULL, descs);
404 }
405
406 static void close_all_sockets(CuTest *tc)
407 {
408     apr_status_t rv;
409     int i;
410
411     for (i = 0; i < LARGE_NUM_SOCKETS; i++){
412         rv = apr_socket_close(s[i]);
413         CuAssertIntEquals(tc, APR_SUCCESS, rv);
414     }
415 }
416
417 static void pollset_remove(CuTest *tc)
418 {
419     apr_status_t rv;
420     apr_pollset_t *pollset;
421     const apr_pollfd_t *hot_files;
422     apr_pollfd_t pfd;
423     apr_int32_t num;
424
425     rv = apr_pollset_create(&pollset, 5, p, 0);
426     CuAssertIntEquals(tc, APR_SUCCESS, rv);
427
428     pfd.p = p;
429     pfd.desc_type = APR_POLL_SOCKET;
430     pfd.reqevents = APR_POLLOUT;
431
432     pfd.desc.s = s[0];
433     pfd.client_data = (void *)1;
434     rv = apr_pollset_add(pollset, &pfd);
435     CuAssertIntEquals(tc, APR_SUCCESS, rv);
436
437     pfd.desc.s = s[1];
438     pfd.client_data = (void *)2;
439     rv = apr_pollset_add(pollset, &pfd);
440     CuAssertIntEquals(tc, APR_SUCCESS, rv);
441
442     pfd.desc.s = s[2];
443     pfd.client_data = (void *)3;
444     rv = apr_pollset_add(pollset, &pfd);
445     CuAssertIntEquals(tc, APR_SUCCESS, rv);
446
447     pfd.desc.s = s[1];
448     pfd.client_data = (void *)4;
449     rv = apr_pollset_add(pollset, &pfd);
450     CuAssertIntEquals(tc, APR_SUCCESS, rv);
451
452     pfd.desc.s = s[3];
453     pfd.client_data = (void *)5;
454     rv = apr_pollset_add(pollset, &pfd);
455     CuAssertIntEquals(tc, APR_SUCCESS, rv);
456
457     rv = apr_pollset_poll(pollset, 1000, &num, &hot_files);
458     CuAssertIntEquals(tc, APR_SUCCESS, rv);
459     CuAssertIntEquals(tc, 5, num);
460
461     /* now remove the pollset elements referring to desc s[1] */
462     pfd.desc.s = s[1];
463     pfd.client_data = (void *)999; /* not used on this call */
464     rv = apr_pollset_remove(pollset, &pfd);
465     CuAssertIntEquals(tc, APR_SUCCESS, rv);
466
467     /* this time only three should match */
468     rv = apr_pollset_poll(pollset, 1000, &num, &hot_files);
469     CuAssertIntEquals(tc, APR_SUCCESS, rv);
470     CuAssertIntEquals(tc, 3, num);
471     CuAssertPtrEquals(tc, (void *)1, hot_files[0].client_data);
472     CuAssertPtrEquals(tc, s[0], hot_files[0].desc.s);
473     CuAssertPtrEquals(tc, (void *)3, hot_files[1].client_data);
474     CuAssertPtrEquals(tc, s[2], hot_files[1].desc.s);
475     CuAssertPtrEquals(tc, (void *)5, hot_files[2].client_data);
476     CuAssertPtrEquals(tc, s[3], hot_files[2].desc.s);
477     
478     /* now remove the pollset elements referring to desc s[2] */
479     pfd.desc.s = s[2];
480     pfd.client_data = (void *)999; /* not used on this call */
481     rv = apr_pollset_remove(pollset, &pfd);
482     CuAssertIntEquals(tc, APR_SUCCESS, rv);
483
484     /* this time only two should match */
485     rv = apr_pollset_poll(pollset, 1000, &num, &hot_files);
486     CuAssertIntEquals(tc, APR_SUCCESS, rv);
487     CuAssertIntEquals(tc, 2, num);
488     CuAssertPtrEquals(tc, (void *)1, hot_files[0].client_data);
489     CuAssertPtrEquals(tc, s[0], hot_files[0].desc.s);
490     CuAssertPtrEquals(tc, (void *)5, hot_files[1].client_data);
491     CuAssertPtrEquals(tc, s[3], hot_files[1].desc.s);
492 }
493
494 CuSuite *testpoll(void)
495 {
496     CuSuite *suite = CuSuiteNew("Poll");
497
498     SUITE_ADD_TEST(suite, create_all_sockets);
499     SUITE_ADD_TEST(suite, setup_small_poll);
500     SUITE_ADD_TEST(suite, setup_large_poll);
501     SUITE_ADD_TEST(suite, nomessage);
502     SUITE_ADD_TEST(suite, send_2);
503     SUITE_ADD_TEST(suite, recv_2_send_1);
504     SUITE_ADD_TEST(suite, send_2_signaled_1);
505     SUITE_ADD_TEST(suite, recv_1_send_0);
506     SUITE_ADD_TEST(suite, clear_all_signalled);
507     SUITE_ADD_TEST(suite, send_large_pollarray);
508     SUITE_ADD_TEST(suite, recv_large_pollarray);
509
510     SUITE_ADD_TEST(suite, setup_pollset);
511     SUITE_ADD_TEST(suite, add_sockets_pollset);
512     SUITE_ADD_TEST(suite, nomessage_pollset);
513     SUITE_ADD_TEST(suite, send0_pollset);
514     SUITE_ADD_TEST(suite, recv0_pollset);
515     SUITE_ADD_TEST(suite, send_middle_pollset);
516     SUITE_ADD_TEST(suite, clear_middle_pollset);
517     SUITE_ADD_TEST(suite, send_last_pollset);
518     SUITE_ADD_TEST(suite, clear_last_pollset);
519
520     SUITE_ADD_TEST(suite, pollset_remove);
521     
522     SUITE_ADD_TEST(suite, close_all_sockets);
523
524     return suite;
525 }
526