]> arthur.barton.de Git - netatalk.git/blob - libevent/test/regress_buffer.c
Fix typo
[netatalk.git] / libevent / test / regress_buffer.c
1 /*
2  * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
3  * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #ifdef WIN32
29 #include <winsock2.h>
30 #include <windows.h>
31 #endif
32
33 #include "event2/event-config.h"
34
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #ifdef _EVENT_HAVE_SYS_TIME_H
38 #include <sys/time.h>
39 #endif
40 #include <sys/queue.h>
41 #ifndef WIN32
42 #include <sys/socket.h>
43 #include <sys/wait.h>
44 #include <signal.h>
45 #include <unistd.h>
46 #include <netdb.h>
47 #endif
48 #include <stdlib.h>
49 #include <stdio.h>
50 #include <string.h>
51 #include <errno.h>
52 #include <assert.h>
53
54 #include "event2/event.h"
55 #include "event2/buffer.h"
56 #include "event2/buffer_compat.h"
57 #include "event2/util.h"
58
59 #include "evbuffer-internal.h"
60 #include "log-internal.h"
61
62 #include "regress.h"
63
64 /* Validates that an evbuffer is good. Returns false if it isn't, true if it
65  * is*/
66 static int
67 _evbuffer_validate(struct evbuffer *buf)
68 {
69         struct evbuffer_chain *chain;
70         size_t sum = 0;
71         int found_last_with_datap = 0;
72
73         if (buf->first == NULL) {
74                 tt_assert(buf->last == NULL);
75                 tt_assert(buf->total_len == 0);
76         }
77
78         chain = buf->first;
79
80         tt_assert(buf->last_with_datap);
81         if (buf->last_with_datap == &buf->first)
82                 found_last_with_datap = 1;
83
84         while (chain != NULL) {
85                 if (&chain->next == buf->last_with_datap)
86                         found_last_with_datap = 1;
87                 sum += chain->off;
88                 if (chain->next == NULL) {
89                         tt_assert(buf->last == chain);
90                 }
91                 tt_assert(chain->buffer_len >= chain->misalign + chain->off);
92                 chain = chain->next;
93         }
94
95         if (buf->first)
96                 tt_assert(*buf->last_with_datap);
97
98         if (*buf->last_with_datap) {
99                 chain = *buf->last_with_datap;
100                 if (chain->off == 0 || buf->total_len == 0) {
101                         tt_assert(chain->off == 0)
102                         tt_assert(chain == buf->first);
103                         tt_assert(buf->total_len == 0);
104                 }
105                 chain = chain->next;
106                 while (chain != NULL) {
107                         tt_assert(chain->off == 0);
108                         chain = chain->next;
109                 }
110         } else {
111                 tt_assert(buf->last_with_datap == &buf->first);
112         }
113         tt_assert(found_last_with_datap);
114
115         tt_assert(sum == buf->total_len);
116         return 1;
117  end:
118         return 0;
119 }
120
121 static void
122 evbuffer_get_waste(struct evbuffer *buf, size_t *allocatedp, size_t *wastedp, size_t *usedp)
123 {
124         struct evbuffer_chain *chain;
125         size_t a, w, u;
126         int n = 0;
127         u = a = w = 0;
128
129         chain = buf->first;
130         /* skip empty at start */
131         while (chain && chain->off==0) {
132                 ++n;
133                 a += chain->buffer_len;
134                 chain = chain->next;
135         }
136         /* first nonempty chain: stuff at the end only is wasted. */
137         if (chain) {
138                 ++n;
139                 a += chain->buffer_len;
140                 u += chain->off;
141                 if (chain->next && chain->next->off)
142                         w += (size_t)(chain->buffer_len - (chain->misalign + chain->off));
143                 chain = chain->next;
144         }
145         /* subsequent nonempty chains */
146         while (chain && chain->off) {
147                 ++n;
148                 a += chain->buffer_len;
149                 w += (size_t)chain->misalign;
150                 u += chain->off;
151                 if (chain->next && chain->next->off)
152                         w += (size_t) (chain->buffer_len - (chain->misalign + chain->off));
153                 chain = chain->next;
154         }
155         /* subsequent empty chains */
156         while (chain) {
157                 ++n;
158                 a += chain->buffer_len;
159         }
160         *allocatedp = a;
161         *wastedp = w;
162         *usedp = u;
163 }
164
165 #define evbuffer_validate(buf)                  \
166         TT_STMT_BEGIN if (!_evbuffer_validate(buf)) TT_DIE(("Buffer format invalid")); TT_STMT_END
167
168 static void
169 test_evbuffer(void *ptr)
170 {
171         static char buffer[512], *tmp;
172         struct evbuffer *evb = evbuffer_new();
173         struct evbuffer *evb_two = evbuffer_new();
174         size_t sz_tmp;
175         int i;
176
177         evbuffer_validate(evb);
178         evbuffer_add_printf(evb, "%s/%d", "hello", 1);
179         evbuffer_validate(evb);
180
181         tt_assert(evbuffer_get_length(evb) == 7);
182         tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "hello/1", 1));
183
184         evbuffer_add_buffer(evb, evb_two);
185         evbuffer_validate(evb);
186
187         evbuffer_drain(evb, strlen("hello/"));
188         evbuffer_validate(evb);
189         tt_assert(evbuffer_get_length(evb) == 1);
190         tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1", 1));
191
192         evbuffer_add_printf(evb_two, "%s", "/hello");
193         evbuffer_validate(evb);
194         evbuffer_add_buffer(evb, evb_two);
195         evbuffer_validate(evb);
196
197         tt_assert(evbuffer_get_length(evb_two) == 0);
198         tt_assert(evbuffer_get_length(evb) == 7);
199         tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1/hello", 7) != 0);
200
201         memset(buffer, 0, sizeof(buffer));
202         evbuffer_add(evb, buffer, sizeof(buffer));
203         evbuffer_validate(evb);
204         tt_assert(evbuffer_get_length(evb) == 7 + 512);
205
206         tmp = (char *)evbuffer_pullup(evb, 7 + 512);
207         tt_assert(tmp);
208         tt_assert(!strncmp(tmp, "1/hello", 7));
209         tt_assert(!memcmp(tmp + 7, buffer, sizeof(buffer)));
210         evbuffer_validate(evb);
211
212         evbuffer_prepend(evb, "something", 9);
213         evbuffer_validate(evb);
214         evbuffer_prepend(evb, "else", 4);
215         evbuffer_validate(evb);
216
217         tmp = (char *)evbuffer_pullup(evb, 4 + 9 + 7);
218         tt_assert(!strncmp(tmp, "elsesomething1/hello", 4 + 9 + 7));
219         evbuffer_validate(evb);
220
221         evbuffer_drain(evb, -1);
222         evbuffer_validate(evb);
223         evbuffer_drain(evb_two, -1);
224         evbuffer_validate(evb);
225
226         for (i = 0; i < 3; ++i) {
227                 evbuffer_add(evb_two, buffer, sizeof(buffer));
228                 evbuffer_validate(evb_two);
229                 evbuffer_add_buffer(evb, evb_two);
230                 evbuffer_validate(evb);
231                 evbuffer_validate(evb_two);
232         }
233
234         tt_assert(evbuffer_get_length(evb_two) == 0);
235         tt_assert(evbuffer_get_length(evb) == i * sizeof(buffer));
236
237         /* test remove buffer */
238         sz_tmp = (size_t)(sizeof(buffer)*2.5);
239         evbuffer_remove_buffer(evb, evb_two, sz_tmp);
240         tt_assert(evbuffer_get_length(evb_two) == sz_tmp);
241         tt_assert(evbuffer_get_length(evb) == sizeof(buffer) / 2);
242         evbuffer_validate(evb);
243
244         if (memcmp(evbuffer_pullup(
245                            evb, -1), buffer, sizeof(buffer) / 2) != 0 ||
246             memcmp(evbuffer_pullup(
247                            evb_two, -1), buffer, sizeof(buffer) != 0))
248                 tt_abort_msg("Pullup did not preserve content");
249
250         evbuffer_validate(evb);
251
252
253         /* testing one-vector reserve and commit */
254         {
255                 struct evbuffer_iovec v[1];
256                 char *buf;
257                 int i, j, r;
258
259                 for (i = 0; i < 3; ++i) {
260                         r = evbuffer_reserve_space(evb, 10000, v, 1);
261                         tt_int_op(r, ==, 1);
262                         tt_assert(v[0].iov_len >= 10000);
263                         tt_assert(v[0].iov_base != NULL);
264
265                         evbuffer_validate(evb);
266                         buf = v[0].iov_base;
267                         for (j = 0; j < 10000; ++j) {
268                                 buf[j] = j;
269                         }
270                         evbuffer_validate(evb);
271
272                         tt_int_op(evbuffer_commit_space(evb, v, 1), ==, 0);
273                         evbuffer_validate(evb);
274
275                         tt_assert(evbuffer_get_length(evb) >= 10000);
276
277                         evbuffer_drain(evb, j * 5000);
278                         evbuffer_validate(evb);
279                 }
280         }
281
282  end:
283         evbuffer_free(evb);
284         evbuffer_free(evb_two);
285 }
286
287 static void
288 no_cleanup(const void *data, size_t datalen, void *extra)
289 {
290 }
291
292 static void
293 test_evbuffer_remove_buffer_with_empty(void *ptr)
294 {
295     struct evbuffer *src = evbuffer_new();
296     struct evbuffer *dst = evbuffer_new();
297     char buf[2];
298
299     evbuffer_validate(src);
300     evbuffer_validate(dst);
301
302     /* setup the buffers */
303     /* we need more data in src than we will move later */
304     evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
305     evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
306     /* we need one buffer in dst and one empty buffer at the end */
307     evbuffer_add(dst, buf, sizeof(buf));
308     evbuffer_add_reference(dst, buf, 0, no_cleanup, NULL);
309
310     evbuffer_validate(src);
311     evbuffer_validate(dst);
312
313     /* move three bytes over */
314     evbuffer_remove_buffer(src, dst, 3);
315
316     evbuffer_validate(src);
317     evbuffer_validate(dst);
318
319 end:
320     evbuffer_free(src);
321     evbuffer_free(dst);
322 }
323
324 static void
325 test_evbuffer_reserve2(void *ptr)
326 {
327         /* Test the two-vector cases of reserve/commit. */
328         struct evbuffer *buf = evbuffer_new();
329         int n, i;
330         struct evbuffer_iovec v[2];
331         size_t remaining;
332         char *cp, *cp2;
333
334         /* First chunk will necessarily be one chunk. Use 512 bytes of it.*/
335         n = evbuffer_reserve_space(buf, 1024, v, 2);
336         tt_int_op(n, ==, 1);
337         tt_int_op(evbuffer_get_length(buf), ==, 0);
338         tt_assert(v[0].iov_base != NULL);
339         tt_int_op(v[0].iov_len, >=, 1024);
340         memset(v[0].iov_base, 'X', 512);
341         cp = v[0].iov_base;
342         remaining = v[0].iov_len - 512;
343         v[0].iov_len = 512;
344         evbuffer_validate(buf);
345         tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
346         tt_int_op(evbuffer_get_length(buf), ==, 512);
347         evbuffer_validate(buf);
348
349         /* Ask for another same-chunk request, in an existing chunk. Use 8
350          * bytes of it. */
351         n = evbuffer_reserve_space(buf, 32, v, 2);
352         tt_int_op(n, ==, 1);
353         tt_assert(cp + 512 == v[0].iov_base);
354         tt_int_op(remaining, ==, v[0].iov_len);
355         memset(v[0].iov_base, 'Y', 8);
356         v[0].iov_len = 8;
357         tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
358         tt_int_op(evbuffer_get_length(buf), ==, 520);
359         remaining -= 8;
360         evbuffer_validate(buf);
361
362         /* Now ask for a request that will be split. Use only one byte of it,
363            though. */
364         n = evbuffer_reserve_space(buf, remaining+64, v, 2);
365         tt_int_op(n, ==, 2);
366         tt_assert(cp + 520 == v[0].iov_base);
367         tt_int_op(remaining, ==, v[0].iov_len);
368         tt_assert(v[1].iov_base);
369         tt_assert(v[1].iov_len >= 64);
370         cp2 = v[1].iov_base;
371         memset(v[0].iov_base, 'Z', 1);
372         v[0].iov_len = 1;
373         tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
374         tt_int_op(evbuffer_get_length(buf), ==, 521);
375         remaining -= 1;
376         evbuffer_validate(buf);
377
378         /* Now ask for a request that will be split. Use some of the first
379          * part and some of the second. */
380         n = evbuffer_reserve_space(buf, remaining+64, v, 2);
381         evbuffer_validate(buf);
382         tt_int_op(n, ==, 2);
383         tt_assert(cp + 521 == v[0].iov_base);
384         tt_int_op(remaining, ==, v[0].iov_len);
385         tt_assert(v[1].iov_base == cp2);
386         tt_assert(v[1].iov_len >= 64);
387         memset(v[0].iov_base, 'W', 400);
388         v[0].iov_len = 400;
389         memset(v[1].iov_base, 'x', 60);
390         v[1].iov_len = 60;
391         tt_int_op(0, ==, evbuffer_commit_space(buf, v, 2));
392         tt_int_op(evbuffer_get_length(buf), ==, 981);
393         evbuffer_validate(buf);
394
395         /* Now peek to make sure stuff got made how we like. */
396         memset(v,0,sizeof(v));
397         n = evbuffer_peek(buf, -1, NULL, v, 2);
398         tt_int_op(n, ==, 2);
399         tt_int_op(v[0].iov_len, ==, 921);
400         tt_int_op(v[1].iov_len, ==, 60);
401
402         cp = v[0].iov_base;
403         for (i=0; i<512; ++i)
404                 tt_int_op(cp[i], ==, 'X');
405         for (i=512; i<520; ++i)
406                 tt_int_op(cp[i], ==, 'Y');
407         for (i=520; i<521; ++i)
408                 tt_int_op(cp[i], ==, 'Z');
409         for (i=521; i<921; ++i)
410                 tt_int_op(cp[i], ==, 'W');
411
412         cp = v[1].iov_base;
413         for (i=0; i<60; ++i)
414                 tt_int_op(cp[i], ==, 'x');
415
416 end:
417         evbuffer_free(buf);
418 }
419
420 static void
421 test_evbuffer_reserve_many(void *ptr)
422 {
423         /* This is a glass-box test to handle expanding a buffer with more
424          * chunks and reallocating chunks as needed */
425         struct evbuffer *buf = evbuffer_new();
426         struct evbuffer_iovec v[8];
427         int n;
428         size_t sz;
429         int add_data = ptr && !strcmp(ptr, "add");
430         int fill_first = ptr && !strcmp(ptr, "fill");
431         char *cp1, *cp2;
432
433         /* When reserving the the first chunk, we just allocate it */
434         n = evbuffer_reserve_space(buf, 128, v, 2);
435         evbuffer_validate(buf);
436         tt_int_op(n, ==, 1);
437         tt_assert(v[0].iov_len >= 128);
438         sz = v[0].iov_len;
439         cp1 = v[0].iov_base;
440         if (add_data) {
441                 *(char*)v[0].iov_base = 'X';
442                 v[0].iov_len = 1;
443                 n = evbuffer_commit_space(buf, v, 1);
444                 tt_int_op(n, ==, 0);
445         } else if (fill_first) {
446                 memset(v[0].iov_base, 'X', v[0].iov_len);
447                 n = evbuffer_commit_space(buf, v, 1);
448                 tt_int_op(n, ==, 0);
449                 n = evbuffer_reserve_space(buf, 128, v, 2);
450                 tt_int_op(n, ==, 1);
451                 sz = v[0].iov_len;
452                 tt_assert(v[0].iov_base != cp1);
453                 cp1 = v[0].iov_base;
454         }
455
456         /* Make another chunk get added. */
457         n = evbuffer_reserve_space(buf, sz+128, v, 2);
458         evbuffer_validate(buf);
459         tt_int_op(n, ==, 2);
460         sz = v[0].iov_len + v[1].iov_len;
461         tt_int_op(sz, >=, v[0].iov_len+128);
462         if (add_data) {
463                 tt_assert(v[0].iov_base == cp1 + 1);
464         } else {
465                 tt_assert(v[0].iov_base == cp1);
466         }
467         cp1 = v[0].iov_base;
468         cp2 = v[1].iov_base;
469
470         /* And a third chunk. */
471         n = evbuffer_reserve_space(buf, sz+128, v, 3);
472         evbuffer_validate(buf);
473         tt_int_op(n, ==, 3);
474         tt_assert(cp1 == v[0].iov_base);
475         tt_assert(cp2 == v[1].iov_base);
476         sz = v[0].iov_len + v[1].iov_len + v[2].iov_len;
477
478         /* Now force a reallocation by asking for more space in only 2
479          * buffers. */
480         n = evbuffer_reserve_space(buf, sz+128, v, 2);
481         evbuffer_validate(buf);
482         if (add_data) {
483                 tt_int_op(n, ==, 2);
484                 tt_assert(cp1 == v[0].iov_base);
485         } else {
486                 tt_int_op(n, ==, 1);
487         }
488
489 end:
490         evbuffer_free(buf);
491 }
492
493 static void
494 test_evbuffer_expand(void *ptr)
495 {
496         char data[4096];
497         struct evbuffer *buf;
498         size_t a,w,u;
499         void *buffer;
500
501         memset(data, 'X', sizeof(data));
502
503         /* Make sure that expand() works on an empty buffer */
504         buf = evbuffer_new();
505         tt_int_op(evbuffer_expand(buf, 20000), ==, 0);
506         evbuffer_validate(buf);
507         a=w=u=0;
508         evbuffer_get_waste(buf, &a,&w,&u);
509         tt_assert(w == 0);
510         tt_assert(u == 0);
511         tt_assert(a >= 20000);
512         tt_assert(buf->first);
513         tt_assert(buf->first == buf->last);
514         tt_assert(buf->first->off == 0);
515         tt_assert(buf->first->buffer_len >= 20000);
516
517         /* Make sure that expand() works as a no-op when there's enough
518          * contiguous space already. */
519         buffer = buf->first->buffer;
520         evbuffer_add(buf, data, 1024);
521         tt_int_op(evbuffer_expand(buf, 1024), ==, 0);
522         tt_assert(buf->first->buffer == buffer);
523         evbuffer_validate(buf);
524         evbuffer_free(buf);
525
526         /* Make sure that expand() can work by moving misaligned data
527          * when it makes sense to do so. */
528         buf = evbuffer_new();
529         evbuffer_add(buf, data, 400);
530         {
531                 int n = (int)(buf->first->buffer_len - buf->first->off - 1);
532                 tt_assert(n < (int)sizeof(data));
533                 evbuffer_add(buf, data, n);
534         }
535         tt_assert(buf->first == buf->last);
536         tt_assert(buf->first->off == buf->first->buffer_len - 1);
537         evbuffer_drain(buf, buf->first->off - 1);
538         tt_assert(1 == evbuffer_get_length(buf));
539         tt_assert(buf->first->misalign > 0);
540         tt_assert(buf->first->off == 1);
541         buffer = buf->first->buffer;
542         tt_assert(evbuffer_expand(buf, 40) == 0);
543         tt_assert(buf->first == buf->last);
544         tt_assert(buf->first->off == 1);
545         tt_assert(buf->first->buffer == buffer);
546         tt_assert(buf->first->misalign == 0);
547         evbuffer_validate(buf);
548         evbuffer_free(buf);
549
550         /* add, expand, pull-up: This used to crash libevent. */
551         buf = evbuffer_new();
552
553         evbuffer_add(buf, data, sizeof(data));
554         evbuffer_add(buf, data, sizeof(data));
555         evbuffer_add(buf, data, sizeof(data));
556
557         evbuffer_validate(buf);
558         evbuffer_expand(buf, 1024);
559         evbuffer_validate(buf);
560         evbuffer_pullup(buf, -1);
561         evbuffer_validate(buf);
562
563 end:
564         evbuffer_free(buf);
565 }
566
567
568 static int reference_cb_called;
569 static void
570 reference_cb(const void *data, size_t len, void *extra)
571 {
572         tt_str_op(data, ==, "this is what we add as read-only memory.");
573         tt_int_op(len, ==, strlen(data));
574         tt_want(extra == (void *)0xdeadaffe);
575         ++reference_cb_called;
576 end:
577         ;
578 }
579
580 static void
581 test_evbuffer_reference(void *ptr)
582 {
583         struct evbuffer *src = evbuffer_new();
584         struct evbuffer *dst = evbuffer_new();
585         struct evbuffer_iovec v[1];
586         const char *data = "this is what we add as read-only memory.";
587         reference_cb_called = 0;
588
589         tt_assert(evbuffer_add_reference(src, data, strlen(data),
590                  reference_cb, (void *)0xdeadaffe) != -1);
591
592         evbuffer_reserve_space(dst, strlen(data), v, 1);
593         tt_assert(evbuffer_remove(src, v[0].iov_base, 10) != -1);
594
595         evbuffer_validate(src);
596         evbuffer_validate(dst);
597
598         /* make sure that we don't write data at the beginning */
599         evbuffer_prepend(src, "aaaaa", 5);
600         evbuffer_validate(src);
601         evbuffer_drain(src, 5);
602
603         tt_assert(evbuffer_remove(src, ((char*)(v[0].iov_base)) + 10,
604                 strlen(data) - 10) != -1);
605
606         v[0].iov_len = strlen(data);
607
608         evbuffer_commit_space(dst, v, 1);
609         evbuffer_validate(src);
610         evbuffer_validate(dst);
611
612         tt_int_op(reference_cb_called, ==, 1);
613
614         tt_assert(!memcmp(evbuffer_pullup(dst, strlen(data)),
615                           data, strlen(data)));
616         evbuffer_validate(dst);
617
618  end:
619         evbuffer_free(dst);
620         evbuffer_free(src);
621 }
622
623 int _evbuffer_testing_use_sendfile(void);
624 int _evbuffer_testing_use_mmap(void);
625 int _evbuffer_testing_use_linear_file_access(void);
626
627 static void
628 test_evbuffer_add_file(void *ptr)
629 {
630         const char *impl = ptr;
631         struct evbuffer *src = evbuffer_new();
632         const char *data = "this is what we add as file system data.";
633         size_t datalen;
634         const char *compare;
635         int fd = -1;
636         evutil_socket_t pair[2] = {-1, -1};
637         int r=0, n_written=0;
638
639         /* Add a test for a big file. XXXX */
640
641         tt_assert(impl);
642         if (!strcmp(impl, "sendfile")) {
643                 if (!_evbuffer_testing_use_sendfile())
644                         tt_skip();
645                 TT_BLATHER(("Using sendfile-based implementaion"));
646         } else if (!strcmp(impl, "mmap")) {
647                 if (!_evbuffer_testing_use_mmap())
648                         tt_skip();
649                 TT_BLATHER(("Using mmap-based implementaion"));
650         } else if (!strcmp(impl, "linear")) {
651                 if (!_evbuffer_testing_use_linear_file_access())
652                         tt_skip();
653                 TT_BLATHER(("Using read-based implementaion"));
654         } else {
655                 TT_DIE(("Didn't recognize the implementation"));
656         }
657
658         /* Say that it drains to a fd so that we can use sendfile. */
659         evbuffer_set_flags(src, EVBUFFER_FLAG_DRAINS_TO_FD);
660
661 #if defined(_EVENT_HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__)
662         /* We need to use a pair of AF_INET sockets, since Solaris
663            doesn't support sendfile() over AF_UNIX. */
664         if (evutil_ersatz_socketpair(AF_INET, SOCK_STREAM, 0, pair) == -1)
665                 tt_abort_msg("ersatz_socketpair failed");
666 #else
667         if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
668                 tt_abort_msg("socketpair failed");
669 #endif
670
671         datalen = strlen(data);
672         fd = regress_make_tmpfile(data, datalen);
673
674         tt_assert(fd != -1);
675
676         tt_assert(evbuffer_add_file(src, fd, 0, datalen) != -1);
677
678         evbuffer_validate(src);
679
680         while (evbuffer_get_length(src) &&
681             (r = evbuffer_write(src, pair[0])) > 0) {
682                 evbuffer_validate(src);
683                 n_written += r;
684         }
685         tt_int_op(r, !=, -1);
686         tt_int_op(n_written, ==, datalen);
687
688         evbuffer_validate(src);
689         tt_int_op(evbuffer_read(src, pair[1], (int)strlen(data)), ==, datalen);
690         evbuffer_validate(src);
691         compare = (char *)evbuffer_pullup(src, datalen);
692         tt_assert(compare != NULL);
693         if (memcmp(compare, data, datalen))
694                 tt_abort_msg("Data from add_file differs.");
695
696         evbuffer_validate(src);
697  end:
698         if (pair[0] >= 0)
699                 evutil_closesocket(pair[0]);
700         if (pair[1] >= 0)
701                 evutil_closesocket(pair[1]);
702         evbuffer_free(src);
703 }
704
705 #ifndef _EVENT_DISABLE_MM_REPLACEMENT
706 static void *
707 failing_malloc(size_t how_much)
708 {
709         errno = ENOMEM;
710         return NULL;
711 }
712 #endif
713
714 static void
715 test_evbuffer_readln(void *ptr)
716 {
717         struct evbuffer *evb = evbuffer_new();
718         struct evbuffer *evb_tmp = evbuffer_new();
719         const char *s;
720         char *cp = NULL;
721         size_t sz;
722
723 #define tt_line_eq(content)                                             \
724         TT_STMT_BEGIN                                                   \
725         if (!cp || sz != strlen(content) || strcmp(cp, content)) {      \
726                 TT_DIE(("Wanted %s; got %s [%d]", content, cp, (int)sz)); \
727         }                                                               \
728         TT_STMT_END
729
730         /* Test EOL_ANY. */
731         s = "complex silly newline\r\n\n\r\n\n\rmore\0\n";
732         evbuffer_add(evb, s, strlen(s)+2);
733         evbuffer_validate(evb);
734         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
735         tt_line_eq("complex silly newline");
736         free(cp);
737         evbuffer_validate(evb);
738         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
739         if (!cp || sz != 5 || memcmp(cp, "more\0\0", 6))
740                 tt_abort_msg("Not as expected");
741         tt_uint_op(evbuffer_get_length(evb), ==, 0);
742         evbuffer_validate(evb);
743         s = "\nno newline";
744         evbuffer_add(evb, s, strlen(s));
745         free(cp);
746         evbuffer_validate(evb);
747         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
748         tt_line_eq("");
749         free(cp);
750         evbuffer_validate(evb);
751         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
752         tt_assert(!cp);
753         evbuffer_validate(evb);
754         evbuffer_drain(evb, evbuffer_get_length(evb));
755         tt_assert(evbuffer_get_length(evb) == 0);
756         evbuffer_validate(evb);
757
758         /* Test EOL_CRLF */
759         s = "Line with\rin the middle\nLine with good crlf\r\n\nfinal\n";
760         evbuffer_add(evb, s, strlen(s));
761         evbuffer_validate(evb);
762         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
763         tt_line_eq("Line with\rin the middle");
764         free(cp);
765         evbuffer_validate(evb);
766
767         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
768         tt_line_eq("Line with good crlf");
769         free(cp);
770         evbuffer_validate(evb);
771
772         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
773         tt_line_eq("");
774         free(cp);
775         evbuffer_validate(evb);
776
777         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
778         tt_line_eq("final");
779         s = "x";
780         evbuffer_validate(evb);
781         evbuffer_add(evb, s, 1);
782         evbuffer_validate(evb);
783         free(cp);
784         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
785         tt_assert(!cp);
786         evbuffer_validate(evb);
787
788         /* Test CRLF_STRICT */
789         s = " and a bad crlf\nand a good one\r\n\r\nMore\r";
790         evbuffer_add(evb, s, strlen(s));
791         evbuffer_validate(evb);
792         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
793         tt_line_eq("x and a bad crlf\nand a good one");
794         free(cp);
795         evbuffer_validate(evb);
796
797         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
798         tt_line_eq("");
799         free(cp);
800         evbuffer_validate(evb);
801
802         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
803         tt_assert(!cp);
804         evbuffer_validate(evb);
805         evbuffer_add(evb, "\n", 1);
806         evbuffer_validate(evb);
807
808         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
809         tt_line_eq("More");
810         free(cp);
811         tt_assert(evbuffer_get_length(evb) == 0);
812         evbuffer_validate(evb);
813
814         s = "An internal CR\r is not an eol\r\nNor is a lack of one";
815         evbuffer_add(evb, s, strlen(s));
816         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
817         tt_line_eq("An internal CR\r is not an eol");
818         free(cp);
819         evbuffer_validate(evb);
820
821         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
822         tt_assert(!cp);
823         evbuffer_validate(evb);
824
825         evbuffer_add(evb, "\r\n", 2);
826         evbuffer_validate(evb);
827         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
828         tt_line_eq("Nor is a lack of one");
829         free(cp);
830         tt_assert(evbuffer_get_length(evb) == 0);
831         evbuffer_validate(evb);
832
833         /* Test LF */
834         s = "An\rand a nl\n\nText";
835         evbuffer_add(evb, s, strlen(s));
836         evbuffer_validate(evb);
837
838         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
839         tt_line_eq("An\rand a nl");
840         free(cp);
841         evbuffer_validate(evb);
842
843         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
844         tt_line_eq("");
845         free(cp);
846         evbuffer_validate(evb);
847
848         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
849         tt_assert(!cp);
850         free(cp);
851         evbuffer_add(evb, "\n", 1);
852         evbuffer_validate(evb);
853         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
854         tt_line_eq("Text");
855         free(cp);
856         evbuffer_validate(evb);
857
858         /* Test CRLF_STRICT - across boundaries*/
859         s = " and a bad crlf\nand a good one\r";
860         evbuffer_add(evb_tmp, s, strlen(s));
861         evbuffer_validate(evb);
862         evbuffer_add_buffer(evb, evb_tmp);
863         evbuffer_validate(evb);
864         s = "\n\r";
865         evbuffer_add(evb_tmp, s, strlen(s));
866         evbuffer_validate(evb);
867         evbuffer_add_buffer(evb, evb_tmp);
868         evbuffer_validate(evb);
869         s = "\nMore\r";
870         evbuffer_add(evb_tmp, s, strlen(s));
871         evbuffer_validate(evb);
872         evbuffer_add_buffer(evb, evb_tmp);
873         evbuffer_validate(evb);
874
875         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
876         tt_line_eq(" and a bad crlf\nand a good one");
877         free(cp);
878         evbuffer_validate(evb);
879
880         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
881         tt_line_eq("");
882         free(cp);
883         evbuffer_validate(evb);
884
885         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
886         tt_assert(!cp);
887         free(cp);
888         evbuffer_validate(evb);
889         evbuffer_add(evb, "\n", 1);
890         evbuffer_validate(evb);
891         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
892         tt_line_eq("More");
893         free(cp); cp = NULL;
894         evbuffer_validate(evb);
895         tt_assert(evbuffer_get_length(evb) == 0);
896
897         /* Test memory problem*/
898         s = "one line\ntwo line\nblue line";
899         evbuffer_add(evb_tmp, s, strlen(s));
900         evbuffer_validate(evb);
901         evbuffer_add_buffer(evb, evb_tmp);
902         evbuffer_validate(evb);
903
904         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
905         tt_line_eq("one line");
906         free(cp); cp = NULL;
907         evbuffer_validate(evb);
908
909         /* the next call to readline should fail */
910 #ifndef _EVENT_DISABLE_MM_REPLACEMENT
911         event_set_mem_functions(failing_malloc, realloc, free);
912         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
913         tt_assert(cp == NULL);
914         evbuffer_validate(evb);
915
916         /* now we should get the next line back */
917         event_set_mem_functions(malloc, realloc, free);
918 #endif
919         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
920         tt_line_eq("two line");
921         free(cp); cp = NULL;
922         evbuffer_validate(evb);
923
924  end:
925         evbuffer_free(evb);
926         evbuffer_free(evb_tmp);
927         if (cp) free(cp);
928 }
929
930 static void
931 test_evbuffer_search_eol(void *ptr)
932 {
933         struct evbuffer *buf = evbuffer_new();
934         struct evbuffer_ptr ptr1, ptr2;
935         const char *s;
936         size_t eol_len;
937
938         s = "string! \r\n\r\nx\n";
939         evbuffer_add(buf, s, strlen(s));
940         eol_len = -1;
941         ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_CRLF);
942         tt_int_op(ptr1.pos, ==, 8);
943         tt_int_op(eol_len, ==, 2);
944
945         eol_len = -1;
946         ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF);
947         tt_int_op(ptr2.pos, ==, 8);
948         tt_int_op(eol_len, ==, 2);
949
950         evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD);
951         eol_len = -1;
952         ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF);
953         tt_int_op(ptr2.pos, ==, 9);
954         tt_int_op(eol_len, ==, 1);
955
956         eol_len = -1;
957         ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF_STRICT);
958         tt_int_op(ptr2.pos, ==, 10);
959         tt_int_op(eol_len, ==, 2);
960
961         eol_len = -1;
962         ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_LF);
963         tt_int_op(ptr1.pos, ==, 9);
964         tt_int_op(eol_len, ==, 1);
965
966         eol_len = -1;
967         ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
968         tt_int_op(ptr2.pos, ==, 9);
969         tt_int_op(eol_len, ==, 1);
970
971         evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD);
972         eol_len = -1;
973         ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
974         tt_int_op(ptr2.pos, ==, 11);
975         tt_int_op(eol_len, ==, 1);
976
977 end:
978         evbuffer_free(buf);
979 }
980
981 static void
982 test_evbuffer_iterative(void *ptr)
983 {
984         struct evbuffer *buf = evbuffer_new();
985         const char *abc = "abcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyz";
986         unsigned i, j, sum, n;
987
988         sum = 0;
989         n = 0;
990         for (i = 0; i < 1000; ++i) {
991                 for (j = 1; j < strlen(abc); ++j) {
992                         char format[32];
993                         evutil_snprintf(format, sizeof(format), "%%%u.%us", j, j);
994                         evbuffer_add_printf(buf, format, abc);
995
996                         /* Only check for rep violations every so often.
997                            Walking over the whole list of chains can get
998                            pretty expensive as it gets long.
999                          */
1000                         if ((n % 337) == 0)
1001                                 evbuffer_validate(buf);
1002
1003                         sum += j;
1004                         n++;
1005                 }
1006         }
1007         evbuffer_validate(buf);
1008
1009         tt_uint_op(sum, ==, evbuffer_get_length(buf));
1010
1011         {
1012                 size_t a,w,u;
1013                 a=w=u=0;
1014                 evbuffer_get_waste(buf, &a, &w, &u);
1015                 if (0)
1016                         printf("Allocated: %u.\nWasted: %u.\nUsed: %u.",
1017                             (unsigned)a, (unsigned)w, (unsigned)u);
1018                 tt_assert( ((double)w)/a < .125);
1019         }
1020  end:
1021         evbuffer_free(buf);
1022
1023 }
1024
1025 static void
1026 test_evbuffer_find(void *ptr)
1027 {
1028         u_char* p;
1029         const char* test1 = "1234567890\r\n";
1030         const char* test2 = "1234567890\r";
1031 #define EVBUFFER_INITIAL_LENGTH 256
1032         char test3[EVBUFFER_INITIAL_LENGTH];
1033         unsigned int i;
1034         struct evbuffer * buf = evbuffer_new();
1035
1036         /* make sure evbuffer_find doesn't match past the end of the buffer */
1037         evbuffer_add(buf, (u_char*)test1, strlen(test1));
1038         evbuffer_validate(buf);
1039         evbuffer_drain(buf, strlen(test1));
1040         evbuffer_validate(buf);
1041         evbuffer_add(buf, (u_char*)test2, strlen(test2));
1042         evbuffer_validate(buf);
1043         p = evbuffer_find(buf, (u_char*)"\r\n", 2);
1044         tt_want(p == NULL);
1045
1046         /*
1047          * drain the buffer and do another find; in r309 this would
1048          * read past the allocated buffer causing a valgrind error.
1049          */
1050         evbuffer_drain(buf, strlen(test2));
1051         evbuffer_validate(buf);
1052         for (i = 0; i < EVBUFFER_INITIAL_LENGTH; ++i)
1053                 test3[i] = 'a';
1054         test3[EVBUFFER_INITIAL_LENGTH - 1] = 'x';
1055         evbuffer_add(buf, (u_char *)test3, EVBUFFER_INITIAL_LENGTH);
1056         evbuffer_validate(buf);
1057         p = evbuffer_find(buf, (u_char *)"xy", 2);
1058         tt_want(p == NULL);
1059
1060         /* simple test for match at end of allocated buffer */
1061         p = evbuffer_find(buf, (u_char *)"ax", 2);
1062         tt_assert(p != NULL);
1063         tt_want(strncmp((char*)p, "ax", 2) == 0);
1064
1065 end:
1066         if (buf)
1067                 evbuffer_free(buf);
1068 }
1069
1070 static void
1071 test_evbuffer_ptr_set(void *ptr)
1072 {
1073         struct evbuffer *buf = evbuffer_new();
1074         struct evbuffer_ptr pos;
1075         struct evbuffer_iovec v[1];
1076
1077         /* create some chains */
1078         evbuffer_reserve_space(buf, 5000, v, 1);
1079         v[0].iov_len = 5000;
1080         memset(v[0].iov_base, 1, v[0].iov_len);
1081         evbuffer_commit_space(buf, v, 1);
1082         evbuffer_validate(buf);
1083
1084         evbuffer_reserve_space(buf, 4000, v, 1);
1085         v[0].iov_len = 4000;
1086         memset(v[0].iov_base, 2, v[0].iov_len);
1087         evbuffer_commit_space(buf, v, 1);
1088
1089         evbuffer_reserve_space(buf, 3000, v, 1);
1090         v[0].iov_len = 3000;
1091         memset(v[0].iov_base, 3, v[0].iov_len);
1092         evbuffer_commit_space(buf, v, 1);
1093         evbuffer_validate(buf);
1094
1095         tt_int_op(evbuffer_get_length(buf), ==, 12000);
1096
1097         tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_SET) == -1);
1098         tt_assert(pos.pos == -1);
1099         tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1100         tt_assert(pos.pos == 0);
1101         tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_ADD) == -1);
1102
1103         tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1104         tt_assert(pos.pos == 0);
1105         tt_assert(evbuffer_ptr_set(buf, &pos, 10000, EVBUFFER_PTR_ADD) == 0);
1106         tt_assert(pos.pos == 10000);
1107         tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == 0);
1108         tt_assert(pos.pos == 11000);
1109         tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == -1);
1110         tt_assert(pos.pos == -1);
1111
1112 end:
1113         if (buf)
1114                 evbuffer_free(buf);
1115 }
1116
1117 static void
1118 test_evbuffer_search(void *ptr)
1119 {
1120         struct evbuffer *buf = evbuffer_new();
1121         struct evbuffer *tmp = evbuffer_new();
1122         struct evbuffer_ptr pos, end;
1123
1124         /* set up our chains */
1125         evbuffer_add_printf(tmp, "hello");  /* 5 chars */
1126         evbuffer_add_buffer(buf, tmp);
1127         evbuffer_add_printf(tmp, "foo");    /* 3 chars */
1128         evbuffer_add_buffer(buf, tmp);
1129         evbuffer_add_printf(tmp, "cat");    /* 3 chars */
1130         evbuffer_add_buffer(buf, tmp);
1131         evbuffer_add_printf(tmp, "attack");
1132         evbuffer_add_buffer(buf, tmp);
1133
1134         pos = evbuffer_search(buf, "attack", 6, NULL);
1135         tt_int_op(pos.pos, ==, 11);
1136         pos = evbuffer_search(buf, "attacker", 8, NULL);
1137         tt_int_op(pos.pos, ==, -1);
1138
1139         /* test continuing search */
1140         pos = evbuffer_search(buf, "oc", 2, NULL);
1141         tt_int_op(pos.pos, ==, 7);
1142         pos = evbuffer_search(buf, "cat", 3, &pos);
1143         tt_int_op(pos.pos, ==, 8);
1144         pos = evbuffer_search(buf, "tacking", 7, &pos);
1145         tt_int_op(pos.pos, ==, -1);
1146
1147         evbuffer_ptr_set(buf, &pos, 5, EVBUFFER_PTR_SET);
1148         pos = evbuffer_search(buf, "foo", 3, &pos);
1149         tt_int_op(pos.pos, ==, 5);
1150
1151         evbuffer_ptr_set(buf, &pos, 2, EVBUFFER_PTR_ADD);
1152         pos = evbuffer_search(buf, "tat", 3, &pos);
1153         tt_int_op(pos.pos, ==, 10);
1154
1155         /* test bounded search. */
1156         /* Set "end" to the first t in "attack". */
1157         evbuffer_ptr_set(buf, &end, 12, EVBUFFER_PTR_SET);
1158         pos = evbuffer_search_range(buf, "foo", 3, NULL, &end);
1159         tt_int_op(pos.pos, ==, 5);
1160         pos = evbuffer_search_range(buf, "foocata", 7, NULL, &end);
1161         tt_int_op(pos.pos, ==, 5);
1162         pos = evbuffer_search_range(buf, "foocatat", 8, NULL, &end);
1163         tt_int_op(pos.pos, ==, -1);
1164         pos = evbuffer_search_range(buf, "ack", 3, NULL, &end);
1165         tt_int_op(pos.pos, ==, -1);
1166
1167
1168 end:
1169         if (buf)
1170                 evbuffer_free(buf);
1171         if (tmp)
1172                 evbuffer_free(tmp);
1173 }
1174
1175 static void
1176 log_change_callback(struct evbuffer *buffer,
1177     const struct evbuffer_cb_info *cbinfo,
1178     void *arg)
1179 {
1180
1181         size_t old_len = cbinfo->orig_size;
1182         size_t new_len = old_len + cbinfo->n_added - cbinfo->n_deleted;
1183         struct evbuffer *out = arg;
1184         evbuffer_add_printf(out, "%lu->%lu; ", (unsigned long)old_len,
1185                             (unsigned long)new_len);
1186 }
1187 static void
1188 self_draining_callback(struct evbuffer *evbuffer, size_t old_len,
1189                 size_t new_len, void *arg)
1190 {
1191         if (new_len > old_len)
1192                 evbuffer_drain(evbuffer, new_len);
1193 }
1194
1195 static void
1196 test_evbuffer_callbacks(void *ptr)
1197 {
1198         struct evbuffer *buf = evbuffer_new();
1199         struct evbuffer *buf_out1 = evbuffer_new();
1200         struct evbuffer *buf_out2 = evbuffer_new();
1201         struct evbuffer_cb_entry *cb1, *cb2;
1202
1203         cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1204         cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1205
1206         /* Let's run through adding and deleting some stuff from the buffer
1207          * and turning the callbacks on and off and removing them.  The callback
1208          * adds a summary of length changes to buf_out1/buf_out2 when called. */
1209         /* size: 0-> 36. */
1210         evbuffer_add_printf(buf, "The %d magic words are spotty pudding", 2);
1211         evbuffer_validate(buf);
1212         evbuffer_cb_clear_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1213         evbuffer_drain(buf, 10); /*36->26*/
1214         evbuffer_validate(buf);
1215         evbuffer_prepend(buf, "Hello", 5);/*26->31*/
1216         evbuffer_cb_set_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1217         evbuffer_add_reference(buf, "Goodbye", 7, NULL, NULL); /*31->38*/
1218         evbuffer_remove_cb_entry(buf, cb1);
1219         evbuffer_validate(buf);
1220         evbuffer_drain(buf, evbuffer_get_length(buf)); /*38->0*/;
1221         tt_assert(-1 == evbuffer_remove_cb(buf, log_change_callback, NULL));
1222         evbuffer_add(buf, "X", 1); /* 0->1 */
1223         tt_assert(!evbuffer_remove_cb(buf, log_change_callback, buf_out2));
1224         evbuffer_validate(buf);
1225
1226         tt_str_op(evbuffer_pullup(buf_out1, -1), ==,
1227                   "0->36; 36->26; 26->31; 31->38; ");
1228         tt_str_op(evbuffer_pullup(buf_out2, -1), ==,
1229                   "0->36; 31->38; 38->0; 0->1; ");
1230         evbuffer_drain(buf_out1, evbuffer_get_length(buf_out1));
1231         evbuffer_drain(buf_out2, evbuffer_get_length(buf_out2));
1232         /* Let's test the obsolete buffer_setcb function too. */
1233         cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1234         tt_assert(cb1 != NULL);
1235         cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1236         tt_assert(cb2 != NULL);
1237         evbuffer_setcb(buf, self_draining_callback, NULL);
1238         evbuffer_add_printf(buf, "This should get drained right away.");
1239         tt_uint_op(evbuffer_get_length(buf), ==, 0);
1240         tt_uint_op(evbuffer_get_length(buf_out1), ==, 0);
1241         tt_uint_op(evbuffer_get_length(buf_out2), ==, 0);
1242         evbuffer_setcb(buf, NULL, NULL);
1243         evbuffer_add_printf(buf, "This will not.");
1244         tt_str_op(evbuffer_pullup(buf, -1), ==, "This will not.");
1245         evbuffer_validate(buf);
1246         evbuffer_drain(buf, evbuffer_get_length(buf));
1247         evbuffer_validate(buf);
1248 #if 0
1249         /* Now let's try a suspended callback. */
1250         cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1251         cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1252         evbuffer_cb_suspend(buf,cb2);
1253         evbuffer_prepend(buf,"Hello world",11); /*0->11*/
1254         evbuffer_validate(buf);
1255         evbuffer_cb_suspend(buf,cb1);
1256         evbuffer_add(buf,"more",4); /* 11->15 */
1257         evbuffer_cb_unsuspend(buf,cb2);
1258         evbuffer_drain(buf, 4); /* 15->11 */
1259         evbuffer_cb_unsuspend(buf,cb1);
1260         evbuffer_drain(buf, evbuffer_get_length(buf)); /* 11->0 */
1261
1262         tt_str_op(evbuffer_pullup(buf_out1, -1), ==,
1263                   "0->11; 11->11; 11->0; ");
1264         tt_str_op(evbuffer_pullup(buf_out2, -1), ==,
1265                   "0->15; 15->11; 11->0; ");
1266 #endif
1267
1268  end:
1269         if (buf)
1270                 evbuffer_free(buf);
1271         if (buf_out1)
1272                 evbuffer_free(buf_out1);
1273         if (buf_out2)
1274                 evbuffer_free(buf_out2);
1275 }
1276
1277 static int ref_done_cb_called_count = 0;
1278 static void *ref_done_cb_called_with = NULL;
1279 static const void *ref_done_cb_called_with_data = NULL;
1280 static size_t ref_done_cb_called_with_len = 0;
1281 static void ref_done_cb(const void *data, size_t len, void *info)
1282 {
1283         ++ref_done_cb_called_count;
1284         ref_done_cb_called_with = info;
1285         ref_done_cb_called_with_data = data;
1286         ref_done_cb_called_with_len = len;
1287 }
1288
1289 static void
1290 test_evbuffer_add_reference(void *ptr)
1291 {
1292         const char chunk1[] = "If you have found the answer to such a problem";
1293         const char chunk2[] = "you ought to write it up for publication";
1294                           /* -- Knuth's "Notes on the Exercises" from TAOCP */
1295         char tmp[16];
1296         size_t len1 = strlen(chunk1), len2=strlen(chunk2);
1297
1298         struct evbuffer *buf1 = NULL, *buf2 = NULL;
1299
1300         buf1 = evbuffer_new();
1301         tt_assert(buf1);
1302
1303         evbuffer_add_reference(buf1, chunk1, len1, ref_done_cb, (void*)111);
1304         evbuffer_add(buf1, ", ", 2);
1305         evbuffer_add_reference(buf1, chunk2, len2, ref_done_cb, (void*)222);
1306         tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
1307
1308         /* Make sure we can drain a little from a reference. */
1309         tt_int_op(evbuffer_remove(buf1, tmp, 6), ==, 6);
1310         tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
1311         tt_int_op(evbuffer_remove(buf1, tmp, 5), ==, 5);
1312         tt_int_op(memcmp(tmp, " have", 5), ==, 0);
1313
1314         /* Make sure that prepending does not meddle with immutable data */
1315         tt_int_op(evbuffer_prepend(buf1, "I have ", 7), ==, 0);
1316         tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
1317         evbuffer_validate(buf1);
1318
1319         /* Make sure that when the chunk is over, the callback is invoked. */
1320         evbuffer_drain(buf1, 7); /* Remove prepended stuff. */
1321         evbuffer_drain(buf1, len1-11-1); /* remove all but one byte of chunk1 */
1322         tt_int_op(ref_done_cb_called_count, ==, 0);
1323         evbuffer_remove(buf1, tmp, 1);
1324         tt_int_op(tmp[0], ==, 'm');
1325         tt_assert(ref_done_cb_called_with == (void*)111);
1326         tt_assert(ref_done_cb_called_with_data == chunk1);
1327         tt_assert(ref_done_cb_called_with_len == len1);
1328         tt_int_op(ref_done_cb_called_count, ==, 1);
1329         evbuffer_validate(buf1);
1330
1331         /* Drain some of the remaining chunk, then add it to another buffer */
1332         evbuffer_drain(buf1, 6); /* Remove the ", you ". */
1333         buf2 = evbuffer_new();
1334         tt_assert(buf2);
1335         tt_int_op(ref_done_cb_called_count, ==, 1);
1336         evbuffer_add(buf2, "I ", 2);
1337
1338         evbuffer_add_buffer(buf2, buf1);
1339         tt_int_op(ref_done_cb_called_count, ==, 1);
1340         evbuffer_remove(buf2, tmp, 16);
1341         tt_int_op(memcmp("I ought to write", tmp, 16), ==, 0);
1342         evbuffer_drain(buf2, evbuffer_get_length(buf2));
1343         tt_int_op(ref_done_cb_called_count, ==, 2);
1344         tt_assert(ref_done_cb_called_with == (void*)222);
1345         evbuffer_validate(buf2);
1346
1347         /* Now add more stuff to buf1 and make sure that it gets removed on
1348          * free. */
1349         evbuffer_add(buf1, "You shake and shake the ", 24);
1350         evbuffer_add_reference(buf1, "ketchup bottle", 14, ref_done_cb,
1351             (void*)3333);
1352         evbuffer_add(buf1, ". Nothing comes and then a lot'll.", 42);
1353         evbuffer_free(buf1);
1354         buf1 = NULL;
1355         tt_int_op(ref_done_cb_called_count, ==, 3);
1356         tt_assert(ref_done_cb_called_with == (void*)3333);
1357
1358 end:
1359         if (buf1)
1360                 evbuffer_free(buf1);
1361         if (buf2)
1362                 evbuffer_free(buf2);
1363 }
1364
1365 /* Some cases that we didn't get in test_evbuffer() above, for more coverage. */
1366 static void
1367 test_evbuffer_prepend(void *ptr)
1368 {
1369         struct evbuffer *buf1 = NULL, *buf2 = NULL;
1370         char tmp[128];
1371         int n;
1372
1373         buf1 = evbuffer_new();
1374         tt_assert(buf1);
1375
1376         /* Case 0: The evbuffer is entirely empty. */
1377         evbuffer_prepend(buf1, "This string has 29 characters", 29);
1378         evbuffer_validate(buf1);
1379
1380         /* Case 1: Prepend goes entirely in new chunk. */
1381         evbuffer_prepend(buf1, "Short.", 6);
1382         evbuffer_validate(buf1);
1383
1384         /* Case 2: prepend goes entirely in first chunk. */
1385         evbuffer_drain(buf1, 6+11);
1386         evbuffer_prepend(buf1, "it", 2);
1387         evbuffer_validate(buf1);
1388         tt_assert(!memcmp(buf1->first->buffer+buf1->first->misalign,
1389                 "it has", 6));
1390
1391         /* Case 3: prepend is split over multiple chunks. */
1392         evbuffer_prepend(buf1, "It is no longer true to say ", 28);
1393         evbuffer_validate(buf1);
1394         n = evbuffer_remove(buf1, tmp, sizeof(tmp)-1);
1395         tmp[n]='\0';
1396         tt_str_op(tmp,==,"It is no longer true to say it has 29 characters");
1397
1398         buf2 = evbuffer_new();
1399         tt_assert(buf2);
1400
1401         /* Case 4: prepend a buffer to an empty buffer. */
1402         n = 999;
1403         evbuffer_add_printf(buf1, "Here is string %d. ", n++);
1404         evbuffer_prepend_buffer(buf2, buf1);
1405         evbuffer_validate(buf2);
1406
1407         /* Case 5: prepend a buffer to a nonempty buffer. */
1408         evbuffer_add_printf(buf1, "Here is string %d. ", n++);
1409         evbuffer_prepend_buffer(buf2, buf1);
1410         evbuffer_validate(buf2);
1411         evbuffer_validate(buf1);
1412         n = evbuffer_remove(buf2, tmp, sizeof(tmp)-1);
1413         tmp[n]='\0';
1414         tt_str_op(tmp,==,"Here is string 1000. Here is string 999. ");
1415
1416 end:
1417         if (buf1)
1418                 evbuffer_free(buf1);
1419         if (buf2)
1420                 evbuffer_free(buf2);
1421
1422 }
1423
1424 static void
1425 test_evbuffer_peek(void *info)
1426 {
1427         struct evbuffer *buf = NULL, *tmp_buf = NULL;
1428         int i;
1429         struct evbuffer_iovec v[20];
1430         struct evbuffer_ptr ptr;
1431
1432 #define tt_iov_eq(v, s)                                         \
1433         tt_int_op((v)->iov_len, ==, strlen(s));                 \
1434         tt_assert(!memcmp((v)->iov_base, (s), strlen(s)))
1435
1436         /* Let's make a very fragmented buffer. */
1437         buf = evbuffer_new();
1438         tmp_buf = evbuffer_new();
1439         for (i = 0; i < 16; ++i) {
1440                 evbuffer_add_printf(tmp_buf, "Contents of chunk [%d]\n", i);
1441                 evbuffer_add_buffer(buf, tmp_buf);
1442         }
1443
1444         /* How many chunks do we need for everything? */
1445         i = evbuffer_peek(buf, -1, NULL, NULL, 0);
1446         tt_int_op(i, ==, 16);
1447
1448         /* Simple peek: get everything. */
1449         i = evbuffer_peek(buf, -1, NULL, v, 20);
1450         tt_int_op(i, ==, 16); /* we used only 16 chunks. */
1451         tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1452         tt_iov_eq(&v[3], "Contents of chunk [3]\n");
1453         tt_iov_eq(&v[12], "Contents of chunk [12]\n");
1454         tt_iov_eq(&v[15], "Contents of chunk [15]\n");
1455
1456         /* Just get one chunk worth. */
1457         memset(v, 0, sizeof(v));
1458         i = evbuffer_peek(buf, -1, NULL, v, 1);
1459         tt_int_op(i, ==, 1);
1460         tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1461         tt_assert(v[1].iov_base == NULL);
1462
1463         /* Suppose we want at least the first 40 bytes. */
1464         memset(v, 0, sizeof(v));
1465         i = evbuffer_peek(buf, 40, NULL, v, 16);
1466         tt_int_op(i, ==, 2);
1467         tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1468         tt_iov_eq(&v[1], "Contents of chunk [1]\n");
1469         tt_assert(v[2].iov_base == NULL);
1470
1471         /* How many chunks do we need for 100 bytes? */
1472         memset(v, 0, sizeof(v));
1473         i = evbuffer_peek(buf, 100, NULL, NULL, 0);
1474         tt_int_op(i, ==, 5);
1475         tt_assert(v[0].iov_base == NULL);
1476
1477         /* Now we ask for more bytes than we provide chunks for */
1478         memset(v, 0, sizeof(v));
1479         i = evbuffer_peek(buf, 60, NULL, v, 1);
1480         tt_int_op(i, ==, 3);
1481         tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1482         tt_assert(v[1].iov_base == NULL);
1483
1484         /* Now we ask for more bytes than the buffer has. */
1485         memset(v, 0, sizeof(v));
1486         i = evbuffer_peek(buf, 65536, NULL, v, 20);
1487         tt_int_op(i, ==, 16); /* we used only 16 chunks. */
1488         tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1489         tt_iov_eq(&v[3], "Contents of chunk [3]\n");
1490         tt_iov_eq(&v[12], "Contents of chunk [12]\n");
1491         tt_iov_eq(&v[15], "Contents of chunk [15]\n");
1492         tt_assert(v[16].iov_base == NULL);
1493
1494         /* What happens if we try an empty buffer? */
1495         memset(v, 0, sizeof(v));
1496         i = evbuffer_peek(tmp_buf, -1, NULL, v, 20);
1497         tt_int_op(i, ==, 0);
1498         tt_assert(v[0].iov_base == NULL);
1499         memset(v, 0, sizeof(v));
1500         i = evbuffer_peek(tmp_buf, 50, NULL, v, 20);
1501         tt_int_op(i, ==, 0);
1502         tt_assert(v[0].iov_base == NULL);
1503
1504         /* Okay, now time to have fun with pointers. */
1505         memset(v, 0, sizeof(v));
1506         evbuffer_ptr_set(buf, &ptr, 30, EVBUFFER_PTR_SET);
1507         i = evbuffer_peek(buf, 50, &ptr, v, 20);
1508         tt_int_op(i, ==, 3);
1509         tt_iov_eq(&v[0], " of chunk [1]\n");
1510         tt_iov_eq(&v[1], "Contents of chunk [2]\n");
1511         tt_iov_eq(&v[2], "Contents of chunk [3]\n"); /*more than we asked for*/
1512
1513         /* advance to the start of another chain. */
1514         memset(v, 0, sizeof(v));
1515         evbuffer_ptr_set(buf, &ptr, 14, EVBUFFER_PTR_ADD);
1516         i = evbuffer_peek(buf, 44, &ptr, v, 20);
1517         tt_int_op(i, ==, 2);
1518         tt_iov_eq(&v[0], "Contents of chunk [2]\n");
1519         tt_iov_eq(&v[1], "Contents of chunk [3]\n"); /*more than we asked for*/
1520
1521 end:
1522         if (buf)
1523                 evbuffer_free(buf);
1524         if (tmp_buf)
1525                 evbuffer_free(tmp_buf);
1526 }
1527
1528 /* Check whether evbuffer freezing works right.  This is called twice,
1529    once with the argument "start" and once with the argument "end".
1530    When we test "start", we freeze the start of an evbuffer and make sure
1531    that modifying the start of the buffer doesn't work.  When we test
1532    "end", we freeze the end of an evbuffer and make sure that modifying
1533    the end of the buffer doesn't work.
1534  */
1535 static void
1536 test_evbuffer_freeze(void *ptr)
1537 {
1538         struct evbuffer *buf = NULL, *tmp_buf=NULL;
1539         const char string[] = /* Year's End, Richard Wilbur */
1540             "I've known the wind by water banks to shake\n"
1541             "The late leaves down, which frozen where they fell\n"
1542             "And held in ice as dancers in a spell\n"
1543             "Fluttered all winter long into a lake...";
1544         const int start = !strcmp(ptr, "start");
1545         char *cp;
1546         char charbuf[128];
1547         int r;
1548         size_t orig_length;
1549         struct evbuffer_iovec v[1];
1550
1551         if (!start)
1552                 tt_str_op(ptr, ==, "end");
1553
1554         buf = evbuffer_new();
1555         tmp_buf = evbuffer_new();
1556         tt_assert(tmp_buf);
1557
1558         evbuffer_add(buf, string, strlen(string));
1559         evbuffer_freeze(buf, start); /* Freeze the start or the end.*/
1560
1561 #define FREEZE_EQ(a, startcase, endcase)                \
1562         do {                                            \
1563             if (start) {                                \
1564                     tt_int_op((a), ==, (startcase));    \
1565             } else {                                    \
1566                     tt_int_op((a), ==, (endcase));      \
1567             }                                           \
1568         } while (0)
1569
1570
1571         orig_length = evbuffer_get_length(buf);
1572
1573         /* These functions all manipulate the end of buf. */
1574         r = evbuffer_add(buf, "abc", 0);
1575         FREEZE_EQ(r, 0, -1);
1576         r = evbuffer_reserve_space(buf, 10, v, 1);
1577         FREEZE_EQ(r, 1, -1);
1578         if (r == 0) {
1579                 memset(v[0].iov_base, 'X', 10);
1580                 v[0].iov_len = 10;
1581         }
1582         r = evbuffer_commit_space(buf, v, 1);
1583         FREEZE_EQ(r, 0, -1);
1584         r = evbuffer_add_reference(buf, string, 5, NULL, NULL);
1585         FREEZE_EQ(r, 0, -1);
1586         r = evbuffer_add_printf(buf, "Hello %s", "world");
1587         FREEZE_EQ(r, 11, -1);
1588         /* TODO: test add_buffer, add_file, read */
1589
1590         if (!start)
1591                 tt_int_op(orig_length, ==, evbuffer_get_length(buf));
1592
1593         orig_length = evbuffer_get_length(buf);
1594
1595         /* These functions all manipulate the start of buf. */
1596         r = evbuffer_remove(buf, charbuf, 1);
1597         FREEZE_EQ(r, -1, 1);
1598         r = evbuffer_drain(buf, 3);
1599         FREEZE_EQ(r, -1, 0);
1600         r = evbuffer_prepend(buf, "dummy", 5);
1601         FREEZE_EQ(r, -1, 0);
1602         cp = evbuffer_readln(buf, NULL, EVBUFFER_EOL_LF);
1603         FREEZE_EQ(cp==NULL, 1, 0);
1604         if (cp)
1605                 free(cp);
1606         /* TODO: Test remove_buffer, add_buffer, write, prepend_buffer */
1607
1608         if (start)
1609                 tt_int_op(orig_length, ==, evbuffer_get_length(buf));
1610
1611 end:
1612         if (buf)
1613                 evbuffer_free(buf);
1614
1615         if (tmp_buf)
1616                 evbuffer_free(tmp_buf);
1617 }
1618
1619 static void *
1620 setup_passthrough(const struct testcase_t *testcase)
1621 {
1622         return testcase->setup_data;
1623 }
1624 static int
1625 cleanup_passthrough(const struct testcase_t *testcase, void *ptr)
1626 {
1627         (void) ptr;
1628         return 1;
1629 }
1630
1631 static const struct testcase_setup_t nil_setup = {
1632         setup_passthrough,
1633         cleanup_passthrough
1634 };
1635
1636 struct testcase_t evbuffer_testcases[] = {
1637         { "evbuffer", test_evbuffer, 0, NULL, NULL },
1638         { "remove_buffer_with_empty", test_evbuffer_remove_buffer_with_empty, 0, NULL, NULL },
1639         { "reserve2", test_evbuffer_reserve2, 0, NULL, NULL },
1640         { "reserve_many", test_evbuffer_reserve_many, 0, NULL, NULL },
1641         { "reserve_many2", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"add" },
1642         { "reserve_many3", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"fill" },
1643         { "expand", test_evbuffer_expand, 0, NULL, NULL },
1644         { "reference", test_evbuffer_reference, 0, NULL, NULL },
1645         { "iterative", test_evbuffer_iterative, 0, NULL, NULL },
1646         { "readln", test_evbuffer_readln, TT_NO_LOGS, &basic_setup, NULL },
1647         { "search_eol", test_evbuffer_search_eol, 0, NULL, NULL },
1648         { "find", test_evbuffer_find, 0, NULL, NULL },
1649         { "ptr_set", test_evbuffer_ptr_set, 0, NULL, NULL },
1650         { "search", test_evbuffer_search, 0, NULL, NULL },
1651         { "callbacks", test_evbuffer_callbacks, 0, NULL, NULL },
1652         { "add_reference", test_evbuffer_add_reference, 0, NULL, NULL },
1653         { "prepend", test_evbuffer_prepend, TT_FORK, NULL, NULL },
1654         { "peek", test_evbuffer_peek, 0, NULL, NULL },
1655         { "freeze_start", test_evbuffer_freeze, 0, &nil_setup, (void*)"start" },
1656         { "freeze_end", test_evbuffer_freeze, 0, &nil_setup, (void*)"end" },
1657         /* TODO: need a temp file implementation for Windows */
1658         { "add_file_sendfile", test_evbuffer_add_file, TT_FORK, &nil_setup,
1659           (void*)"sendfile" },
1660         { "add_file_mmap", test_evbuffer_add_file, TT_FORK, &nil_setup,
1661           (void*)"mmap" },
1662         { "add_file_linear", test_evbuffer_add_file, TT_FORK, &nil_setup,
1663           (void*)"linear" },
1664
1665         END_OF_TESTCASES
1666 };