]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/ntp/sntp/libevent/test/regress_buffer.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / ntp / sntp / 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 #include "util-internal.h"
28
29 #ifdef _WIN32
30 #include <winsock2.h>
31 #include <windows.h>
32 #endif
33
34 #include "event2/event-config.h"
35
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #ifdef EVENT__HAVE_SYS_TIME_H
39 #include <sys/time.h>
40 #endif
41 #include <sys/queue.h>
42 #ifndef _WIN32
43 #include <sys/socket.h>
44 #include <sys/wait.h>
45 #include <signal.h>
46 #include <unistd.h>
47 #include <netdb.h>
48 #endif
49 #include <stdlib.h>
50 #include <stdio.h>
51 #include <string.h>
52 #include <errno.h>
53 #include <assert.h>
54
55 #include "event2/event.h"
56 #include "event2/buffer.h"
57 #include "event2/buffer_compat.h"
58 #include "event2/util.h"
59
60 #include "defer-internal.h"
61 #include "evbuffer-internal.h"
62 #include "log-internal.h"
63
64 #include "regress.h"
65
66 /* Validates that an evbuffer is good. Returns false if it isn't, true if it
67  * is*/
68 static int
69 evbuffer_validate_(struct evbuffer *buf)
70 {
71         struct evbuffer_chain *chain;
72         size_t sum = 0;
73         int found_last_with_datap = 0;
74
75         if (buf->first == NULL) {
76                 tt_assert(buf->last == NULL);
77                 tt_assert(buf->total_len == 0);
78         }
79
80         chain = buf->first;
81
82         tt_assert(buf->last_with_datap);
83         if (buf->last_with_datap == &buf->first)
84                 found_last_with_datap = 1;
85
86         while (chain != NULL) {
87                 if (&chain->next == buf->last_with_datap)
88                         found_last_with_datap = 1;
89                 sum += chain->off;
90                 if (chain->next == NULL) {
91                         tt_assert(buf->last == chain);
92                 }
93                 tt_assert(chain->buffer_len >= chain->misalign + chain->off);
94                 chain = chain->next;
95         }
96
97         if (buf->first)
98                 tt_assert(*buf->last_with_datap);
99
100         if (*buf->last_with_datap) {
101                 chain = *buf->last_with_datap;
102                 if (chain->off == 0 || buf->total_len == 0) {
103                         tt_assert(chain->off == 0)
104                         tt_assert(chain == buf->first);
105                         tt_assert(buf->total_len == 0);
106                 }
107                 chain = chain->next;
108                 while (chain != NULL) {
109                         tt_assert(chain->off == 0);
110                         chain = chain->next;
111                 }
112         } else {
113                 tt_assert(buf->last_with_datap == &buf->first);
114         }
115         tt_assert(found_last_with_datap);
116
117         tt_assert(sum == buf->total_len);
118         return 1;
119  end:
120         return 0;
121 }
122
123 static void
124 evbuffer_get_waste(struct evbuffer *buf, size_t *allocatedp, size_t *wastedp, size_t *usedp)
125 {
126         struct evbuffer_chain *chain;
127         size_t a, w, u;
128         int n = 0;
129         u = a = w = 0;
130
131         chain = buf->first;
132         /* skip empty at start */
133         while (chain && chain->off==0) {
134                 ++n;
135                 a += chain->buffer_len;
136                 chain = chain->next;
137         }
138         /* first nonempty chain: stuff at the end only is wasted. */
139         if (chain) {
140                 ++n;
141                 a += chain->buffer_len;
142                 u += chain->off;
143                 if (chain->next && chain->next->off)
144                         w += (size_t)(chain->buffer_len - (chain->misalign + chain->off));
145                 chain = chain->next;
146         }
147         /* subsequent nonempty chains */
148         while (chain && chain->off) {
149                 ++n;
150                 a += chain->buffer_len;
151                 w += (size_t)chain->misalign;
152                 u += chain->off;
153                 if (chain->next && chain->next->off)
154                         w += (size_t) (chain->buffer_len - (chain->misalign + chain->off));
155                 chain = chain->next;
156         }
157         /* subsequent empty chains */
158         while (chain) {
159                 ++n;
160                 a += chain->buffer_len;
161         }
162         *allocatedp = a;
163         *wastedp = w;
164         *usedp = u;
165 }
166
167 #define evbuffer_validate(buf)                  \
168         TT_STMT_BEGIN if (!evbuffer_validate_(buf)) TT_DIE(("Buffer format invalid")); TT_STMT_END
169
170 static void
171 test_evbuffer(void *ptr)
172 {
173         static char buffer[512], *tmp;
174         struct evbuffer *evb = evbuffer_new();
175         struct evbuffer *evb_two = evbuffer_new();
176         size_t sz_tmp;
177         int i;
178
179         evbuffer_validate(evb);
180         evbuffer_add_printf(evb, "%s/%d", "hello", 1);
181         evbuffer_validate(evb);
182
183         tt_assert(evbuffer_get_length(evb) == 7);
184         tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "hello/1", 1));
185
186         evbuffer_add_buffer(evb, evb_two);
187         evbuffer_validate(evb);
188
189         evbuffer_drain(evb, strlen("hello/"));
190         evbuffer_validate(evb);
191         tt_assert(evbuffer_get_length(evb) == 1);
192         tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1", 1));
193
194         evbuffer_add_printf(evb_two, "%s", "/hello");
195         evbuffer_validate(evb);
196         evbuffer_add_buffer(evb, evb_two);
197         evbuffer_validate(evb);
198
199         tt_assert(evbuffer_get_length(evb_two) == 0);
200         tt_assert(evbuffer_get_length(evb) == 7);
201         tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1/hello", 7) != 0);
202
203         memset(buffer, 0, sizeof(buffer));
204         evbuffer_add(evb, buffer, sizeof(buffer));
205         evbuffer_validate(evb);
206         tt_assert(evbuffer_get_length(evb) == 7 + 512);
207
208         tmp = (char *)evbuffer_pullup(evb, 7 + 512);
209         tt_assert(tmp);
210         tt_assert(!strncmp(tmp, "1/hello", 7));
211         tt_assert(!memcmp(tmp + 7, buffer, sizeof(buffer)));
212         evbuffer_validate(evb);
213
214         evbuffer_prepend(evb, "something", 9);
215         evbuffer_validate(evb);
216         evbuffer_prepend(evb, "else", 4);
217         evbuffer_validate(evb);
218
219         tmp = (char *)evbuffer_pullup(evb, 4 + 9 + 7);
220         tt_assert(!strncmp(tmp, "elsesomething1/hello", 4 + 9 + 7));
221         evbuffer_validate(evb);
222
223         evbuffer_drain(evb, -1);
224         evbuffer_validate(evb);
225         evbuffer_drain(evb_two, -1);
226         evbuffer_validate(evb);
227
228         for (i = 0; i < 3; ++i) {
229                 evbuffer_add(evb_two, buffer, sizeof(buffer));
230                 evbuffer_validate(evb_two);
231                 evbuffer_add_buffer(evb, evb_two);
232                 evbuffer_validate(evb);
233                 evbuffer_validate(evb_two);
234         }
235
236         tt_assert(evbuffer_get_length(evb_two) == 0);
237         tt_assert(evbuffer_get_length(evb) == i * sizeof(buffer));
238
239         /* test remove buffer */
240         sz_tmp = (size_t)(sizeof(buffer)*2.5);
241         evbuffer_remove_buffer(evb, evb_two, sz_tmp);
242         tt_assert(evbuffer_get_length(evb_two) == sz_tmp);
243         tt_assert(evbuffer_get_length(evb) == sizeof(buffer) / 2);
244         evbuffer_validate(evb);
245
246         if (memcmp(evbuffer_pullup(
247                            evb, -1), buffer, sizeof(buffer) / 2) != 0 ||
248             memcmp(evbuffer_pullup(
249                            evb_two, -1), buffer, sizeof(buffer)) != 0)
250                 tt_abort_msg("Pullup did not preserve content");
251
252         evbuffer_validate(evb);
253
254
255         /* testing one-vector reserve and commit */
256         {
257                 struct evbuffer_iovec v[1];
258                 char *buf;
259                 int i, j, r;
260
261                 for (i = 0; i < 3; ++i) {
262                         r = evbuffer_reserve_space(evb, 10000, v, 1);
263                         tt_int_op(r, ==, 1);
264                         tt_assert(v[0].iov_len >= 10000);
265                         tt_assert(v[0].iov_base != NULL);
266
267                         evbuffer_validate(evb);
268                         buf = v[0].iov_base;
269                         for (j = 0; j < 10000; ++j) {
270                                 buf[j] = j;
271                         }
272                         evbuffer_validate(evb);
273
274                         tt_int_op(evbuffer_commit_space(evb, v, 1), ==, 0);
275                         evbuffer_validate(evb);
276
277                         tt_assert(evbuffer_get_length(evb) >= 10000);
278
279                         evbuffer_drain(evb, j * 5000);
280                         evbuffer_validate(evb);
281                 }
282         }
283
284  end:
285         evbuffer_free(evb);
286         evbuffer_free(evb_two);
287 }
288
289 static void
290 no_cleanup(const void *data, size_t datalen, void *extra)
291 {
292 }
293
294 static void
295 test_evbuffer_remove_buffer_with_empty(void *ptr)
296 {
297     struct evbuffer *src = evbuffer_new();
298     struct evbuffer *dst = evbuffer_new();
299     char buf[2];
300
301     evbuffer_validate(src);
302     evbuffer_validate(dst);
303
304     /* setup the buffers */
305     /* we need more data in src than we will move later */
306     evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
307     evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
308     /* we need one buffer in dst and one empty buffer at the end */
309     evbuffer_add(dst, buf, sizeof(buf));
310     evbuffer_add_reference(dst, buf, 0, no_cleanup, NULL);
311
312     evbuffer_validate(src);
313     evbuffer_validate(dst);
314
315     /* move three bytes over */
316     evbuffer_remove_buffer(src, dst, 3);
317
318     evbuffer_validate(src);
319     evbuffer_validate(dst);
320
321 end:
322     evbuffer_free(src);
323     evbuffer_free(dst);
324 }
325
326 static void
327 test_evbuffer_reserve2(void *ptr)
328 {
329         /* Test the two-vector cases of reserve/commit. */
330         struct evbuffer *buf = evbuffer_new();
331         int n, i;
332         struct evbuffer_iovec v[2];
333         size_t remaining;
334         char *cp, *cp2;
335
336         /* First chunk will necessarily be one chunk. Use 512 bytes of it.*/
337         n = evbuffer_reserve_space(buf, 1024, v, 2);
338         tt_int_op(n, ==, 1);
339         tt_int_op(evbuffer_get_length(buf), ==, 0);
340         tt_assert(v[0].iov_base != NULL);
341         tt_int_op(v[0].iov_len, >=, 1024);
342         memset(v[0].iov_base, 'X', 512);
343         cp = v[0].iov_base;
344         remaining = v[0].iov_len - 512;
345         v[0].iov_len = 512;
346         evbuffer_validate(buf);
347         tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
348         tt_int_op(evbuffer_get_length(buf), ==, 512);
349         evbuffer_validate(buf);
350
351         /* Ask for another same-chunk request, in an existing chunk. Use 8
352          * bytes of it. */
353         n = evbuffer_reserve_space(buf, 32, v, 2);
354         tt_int_op(n, ==, 1);
355         tt_assert(cp + 512 == v[0].iov_base);
356         tt_int_op(remaining, ==, v[0].iov_len);
357         memset(v[0].iov_base, 'Y', 8);
358         v[0].iov_len = 8;
359         tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
360         tt_int_op(evbuffer_get_length(buf), ==, 520);
361         remaining -= 8;
362         evbuffer_validate(buf);
363
364         /* Now ask for a request that will be split. Use only one byte of it,
365            though. */
366         n = evbuffer_reserve_space(buf, remaining+64, v, 2);
367         tt_int_op(n, ==, 2);
368         tt_assert(cp + 520 == v[0].iov_base);
369         tt_int_op(remaining, ==, v[0].iov_len);
370         tt_assert(v[1].iov_base);
371         tt_assert(v[1].iov_len >= 64);
372         cp2 = v[1].iov_base;
373         memset(v[0].iov_base, 'Z', 1);
374         v[0].iov_len = 1;
375         tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
376         tt_int_op(evbuffer_get_length(buf), ==, 521);
377         remaining -= 1;
378         evbuffer_validate(buf);
379
380         /* Now ask for a request that will be split. Use some of the first
381          * part and some of the second. */
382         n = evbuffer_reserve_space(buf, remaining+64, v, 2);
383         evbuffer_validate(buf);
384         tt_int_op(n, ==, 2);
385         tt_assert(cp + 521 == v[0].iov_base);
386         tt_int_op(remaining, ==, v[0].iov_len);
387         tt_assert(v[1].iov_base == cp2);
388         tt_assert(v[1].iov_len >= 64);
389         memset(v[0].iov_base, 'W', 400);
390         v[0].iov_len = 400;
391         memset(v[1].iov_base, 'x', 60);
392         v[1].iov_len = 60;
393         tt_int_op(0, ==, evbuffer_commit_space(buf, v, 2));
394         tt_int_op(evbuffer_get_length(buf), ==, 981);
395         evbuffer_validate(buf);
396
397         /* Now peek to make sure stuff got made how we like. */
398         memset(v,0,sizeof(v));
399         n = evbuffer_peek(buf, -1, NULL, v, 2);
400         tt_int_op(n, ==, 2);
401         tt_int_op(v[0].iov_len, ==, 921);
402         tt_int_op(v[1].iov_len, ==, 60);
403
404         cp = v[0].iov_base;
405         for (i=0; i<512; ++i)
406                 tt_int_op(cp[i], ==, 'X');
407         for (i=512; i<520; ++i)
408                 tt_int_op(cp[i], ==, 'Y');
409         for (i=520; i<521; ++i)
410                 tt_int_op(cp[i], ==, 'Z');
411         for (i=521; i<921; ++i)
412                 tt_int_op(cp[i], ==, 'W');
413
414         cp = v[1].iov_base;
415         for (i=0; i<60; ++i)
416                 tt_int_op(cp[i], ==, 'x');
417
418 end:
419         evbuffer_free(buf);
420 }
421
422 static void
423 test_evbuffer_reserve_many(void *ptr)
424 {
425         /* This is a glass-box test to handle expanding a buffer with more
426          * chunks and reallocating chunks as needed */
427         struct evbuffer *buf = evbuffer_new();
428         struct evbuffer_iovec v[8];
429         int n;
430         size_t sz;
431         int add_data = ptr && !strcmp(ptr, "add");
432         int fill_first = ptr && !strcmp(ptr, "fill");
433         char *cp1, *cp2;
434
435         /* When reserving the the first chunk, we just allocate it */
436         n = evbuffer_reserve_space(buf, 128, v, 2);
437         evbuffer_validate(buf);
438         tt_int_op(n, ==, 1);
439         tt_assert(v[0].iov_len >= 128);
440         sz = v[0].iov_len;
441         cp1 = v[0].iov_base;
442         if (add_data) {
443                 *(char*)v[0].iov_base = 'X';
444                 v[0].iov_len = 1;
445                 n = evbuffer_commit_space(buf, v, 1);
446                 tt_int_op(n, ==, 0);
447         } else if (fill_first) {
448                 memset(v[0].iov_base, 'X', v[0].iov_len);
449                 n = evbuffer_commit_space(buf, v, 1);
450                 tt_int_op(n, ==, 0);
451                 n = evbuffer_reserve_space(buf, 128, v, 2);
452                 tt_int_op(n, ==, 1);
453                 sz = v[0].iov_len;
454                 tt_assert(v[0].iov_base != cp1);
455                 cp1 = v[0].iov_base;
456         }
457
458         /* Make another chunk get added. */
459         n = evbuffer_reserve_space(buf, sz+128, v, 2);
460         evbuffer_validate(buf);
461         tt_int_op(n, ==, 2);
462         sz = v[0].iov_len + v[1].iov_len;
463         tt_int_op(sz, >=, v[0].iov_len+128);
464         if (add_data) {
465                 tt_assert(v[0].iov_base == cp1 + 1);
466         } else {
467                 tt_assert(v[0].iov_base == cp1);
468         }
469         cp1 = v[0].iov_base;
470         cp2 = v[1].iov_base;
471
472         /* And a third chunk. */
473         n = evbuffer_reserve_space(buf, sz+128, v, 3);
474         evbuffer_validate(buf);
475         tt_int_op(n, ==, 3);
476         tt_assert(cp1 == v[0].iov_base);
477         tt_assert(cp2 == v[1].iov_base);
478         sz = v[0].iov_len + v[1].iov_len + v[2].iov_len;
479
480         /* Now force a reallocation by asking for more space in only 2
481          * buffers. */
482         n = evbuffer_reserve_space(buf, sz+128, v, 2);
483         evbuffer_validate(buf);
484         if (add_data) {
485                 tt_int_op(n, ==, 2);
486                 tt_assert(cp1 == v[0].iov_base);
487         } else {
488                 tt_int_op(n, ==, 1);
489         }
490
491 end:
492         evbuffer_free(buf);
493 }
494
495 static void
496 test_evbuffer_expand(void *ptr)
497 {
498         char data[4096];
499         struct evbuffer *buf;
500         size_t a,w,u;
501         void *buffer;
502
503         memset(data, 'X', sizeof(data));
504
505         /* Make sure that expand() works on an empty buffer */
506         buf = evbuffer_new();
507         tt_int_op(evbuffer_expand(buf, 20000), ==, 0);
508         evbuffer_validate(buf);
509         a=w=u=0;
510         evbuffer_get_waste(buf, &a,&w,&u);
511         tt_assert(w == 0);
512         tt_assert(u == 0);
513         tt_assert(a >= 20000);
514         tt_assert(buf->first);
515         tt_assert(buf->first == buf->last);
516         tt_assert(buf->first->off == 0);
517         tt_assert(buf->first->buffer_len >= 20000);
518
519         /* Make sure that expand() works as a no-op when there's enough
520          * contiguous space already. */
521         buffer = buf->first->buffer;
522         evbuffer_add(buf, data, 1024);
523         tt_int_op(evbuffer_expand(buf, 1024), ==, 0);
524         tt_assert(buf->first->buffer == buffer);
525         evbuffer_validate(buf);
526         evbuffer_free(buf);
527
528         /* Make sure that expand() can work by moving misaligned data
529          * when it makes sense to do so. */
530         buf = evbuffer_new();
531         evbuffer_add(buf, data, 400);
532         {
533                 int n = (int)(buf->first->buffer_len - buf->first->off - 1);
534                 tt_assert(n < (int)sizeof(data));
535                 evbuffer_add(buf, data, n);
536         }
537         tt_assert(buf->first == buf->last);
538         tt_assert(buf->first->off == buf->first->buffer_len - 1);
539         evbuffer_drain(buf, buf->first->off - 1);
540         tt_assert(1 == evbuffer_get_length(buf));
541         tt_assert(buf->first->misalign > 0);
542         tt_assert(buf->first->off == 1);
543         buffer = buf->first->buffer;
544         tt_assert(evbuffer_expand(buf, 40) == 0);
545         tt_assert(buf->first == buf->last);
546         tt_assert(buf->first->off == 1);
547         tt_assert(buf->first->buffer == buffer);
548         tt_assert(buf->first->misalign == 0);
549         evbuffer_validate(buf);
550         evbuffer_free(buf);
551
552         /* add, expand, pull-up: This used to crash libevent. */
553         buf = evbuffer_new();
554
555         evbuffer_add(buf, data, sizeof(data));
556         evbuffer_add(buf, data, sizeof(data));
557         evbuffer_add(buf, data, sizeof(data));
558
559         evbuffer_validate(buf);
560         evbuffer_expand(buf, 1024);
561         evbuffer_validate(buf);
562         evbuffer_pullup(buf, -1);
563         evbuffer_validate(buf);
564
565 end:
566         evbuffer_free(buf);
567 }
568
569
570 static int reference_cb_called;
571 static void
572 reference_cb(const void *data, size_t len, void *extra)
573 {
574         tt_str_op(data, ==, "this is what we add as read-only memory.");
575         tt_int_op(len, ==, strlen(data));
576         tt_want(extra == (void *)0xdeadaffe);
577         ++reference_cb_called;
578 end:
579         ;
580 }
581
582 static void
583 test_evbuffer_reference(void *ptr)
584 {
585         struct evbuffer *src = evbuffer_new();
586         struct evbuffer *dst = evbuffer_new();
587         struct evbuffer_iovec v[1];
588         const char *data = "this is what we add as read-only memory.";
589         reference_cb_called = 0;
590
591         tt_assert(evbuffer_add_reference(src, data, strlen(data),
592                  reference_cb, (void *)0xdeadaffe) != -1);
593
594         evbuffer_reserve_space(dst, strlen(data), v, 1);
595         tt_assert(evbuffer_remove(src, v[0].iov_base, 10) != -1);
596
597         evbuffer_validate(src);
598         evbuffer_validate(dst);
599
600         /* make sure that we don't write data at the beginning */
601         evbuffer_prepend(src, "aaaaa", 5);
602         evbuffer_validate(src);
603         evbuffer_drain(src, 5);
604
605         tt_assert(evbuffer_remove(src, ((char*)(v[0].iov_base)) + 10,
606                 strlen(data) - 10) != -1);
607
608         v[0].iov_len = strlen(data);
609
610         evbuffer_commit_space(dst, v, 1);
611         evbuffer_validate(src);
612         evbuffer_validate(dst);
613
614         tt_int_op(reference_cb_called, ==, 1);
615
616         tt_assert(!memcmp(evbuffer_pullup(dst, strlen(data)),
617                           data, strlen(data)));
618         evbuffer_validate(dst);
619
620  end:
621         evbuffer_free(dst);
622         evbuffer_free(src);
623 }
624
625 static struct event_base *addfile_test_event_base = NULL;
626 static int addfile_test_done_writing = 0;
627 static int addfile_test_total_written = 0;
628 static int addfile_test_total_read = 0;
629
630 static void
631 addfile_test_writecb(evutil_socket_t fd, short what, void *arg)
632 {
633         struct evbuffer *b = arg;
634         int r;
635         evbuffer_validate(b);
636         while (evbuffer_get_length(b)) {
637                 r = evbuffer_write(b, fd);
638                 if (r > 0) {
639                         addfile_test_total_written += r;
640                         TT_BLATHER(("Wrote %d/%d bytes", r, addfile_test_total_written));
641                 } else {
642                         int e = evutil_socket_geterror(fd);
643                         if (EVUTIL_ERR_RW_RETRIABLE(e))
644                                 return;
645                         tt_fail_perror("write");
646                         event_base_loopexit(addfile_test_event_base,NULL);
647                 }
648                 evbuffer_validate(b);
649         }
650         addfile_test_done_writing = 1;
651         return;
652 end:
653         event_base_loopexit(addfile_test_event_base,NULL);
654 }
655
656 static void
657 addfile_test_readcb(evutil_socket_t fd, short what, void *arg)
658 {
659         struct evbuffer *b = arg;
660         int e, r = 0;
661         do {
662                 r = evbuffer_read(b, fd, 1024);
663                 if (r > 0) {
664                         addfile_test_total_read += r;
665                         TT_BLATHER(("Read %d/%d bytes", r, addfile_test_total_read));
666                 }
667         } while (r > 0);
668         if (r < 0) {
669                 e = evutil_socket_geterror(fd);
670                 if (! EVUTIL_ERR_RW_RETRIABLE(e)) {
671                         tt_fail_perror("read");
672                         event_base_loopexit(addfile_test_event_base,NULL);
673                 }
674         }
675         if (addfile_test_done_writing &&
676             addfile_test_total_read >= addfile_test_total_written) {
677                 event_base_loopexit(addfile_test_event_base,NULL);
678         }
679 }
680
681 static void
682 test_evbuffer_add_file(void *ptr)
683 {
684         struct basic_test_data *testdata = ptr;
685         const char *impl = testdata->setup_data;
686         struct evbuffer *src = evbuffer_new(), *dest = evbuffer_new();
687         char *tmpfilename = NULL;
688         char *data = NULL;
689         const char *expect_data;
690         size_t datalen, expect_len;
691         const char *compare;
692         int fd = -1;
693         int want_ismapping = -1, want_cansendfile = -1;
694         unsigned flags = 0;
695         int use_segment = 1, use_bigfile = 0, map_from_offset = 0,
696             view_from_offset = 0;
697         struct evbuffer_file_segment *seg = NULL;
698         ev_off_t starting_offset = 0, mapping_len = -1;
699         ev_off_t segment_offset = 0, segment_len = -1;
700         struct event *rev=NULL, *wev=NULL;
701         struct event_base *base = testdata->base;
702         evutil_socket_t pair[2] = {-1, -1};
703         struct evutil_weakrand_state seed = { 123456789U };
704
705         /* This test is highly parameterized based on substrings of its
706          * argument.  The strings are: */
707         tt_assert(impl);
708         if (strstr(impl, "nosegment")) {
709                 /* If nosegment is set, use the older evbuffer_add_file
710                  * interface */
711                 use_segment = 0;
712         }
713         if (strstr(impl, "bigfile")) {
714                 /* If bigfile is set, use a 512K file.  Else use a smaller
715                  * one. */
716                 use_bigfile = 1;
717         }
718         if (strstr(impl, "map_offset")) {
719                 /* If map_offset is set, we build the file segment starting
720                  * from a point other than byte 0 and ending somewhere other
721                  * than the last byte.  Otherwise we map the whole thing */
722                 map_from_offset = 1;
723         }
724         if (strstr(impl, "offset_in_segment")) {
725                 /* If offset_in_segment is set, we add a subsection of the
726                  * file semgment starting from a point other than byte 0 of
727                  * the segment. */
728                 view_from_offset = 1;
729         }
730         if (strstr(impl, "sendfile")) {
731                 /* If sendfile is set, we try to use a sendfile/splice style
732                  * backend. */
733                 flags = EVBUF_FS_DISABLE_MMAP;
734                 want_cansendfile = 1;
735                 want_ismapping = 0;
736         } else if (strstr(impl, "mmap")) {
737                 /* If sendfile is set, we try to use a mmap/CreateFileMapping
738                  * style backend. */
739                 flags = EVBUF_FS_DISABLE_SENDFILE;
740                 want_ismapping = 1;
741                 want_cansendfile = 0;
742         } else if (strstr(impl, "linear")) {
743                 /* If linear is set, we try to use a read-the-whole-thing
744                  * backend. */
745                 flags = EVBUF_FS_DISABLE_SENDFILE|EVBUF_FS_DISABLE_MMAP;
746                 want_ismapping = 0;
747                 want_cansendfile = 0;
748         } else if (strstr(impl, "default")) {
749                 /* The caller doesn't care which backend we use. */
750                 ;
751         } else {
752                 /* The caller must choose a backend. */
753                 TT_DIE(("Didn't recognize the implementation"));
754         }
755
756         if (use_bigfile) {
757                 unsigned int i;
758                 datalen = 1024*512;
759                 data = malloc(1024*512);
760                 tt_assert(data);
761                 for (i = 0; i < datalen; ++i)
762                         data[i] = (char)evutil_weakrand_(&seed);
763         } else {
764                 data = strdup("here is a relatively small string.");
765                 tt_assert(data);
766                 datalen = strlen(data);
767         }
768
769         fd = regress_make_tmpfile(data, datalen, &tmpfilename);
770
771         if (map_from_offset) {
772                 starting_offset = datalen/4 + 1;
773                 mapping_len = datalen / 2 - 1;
774                 expect_data = data + starting_offset;
775                 expect_len = mapping_len;
776         } else {
777                 expect_data = data;
778                 expect_len = datalen;
779         }
780         if (view_from_offset) {
781                 tt_assert(use_segment); /* Can't do this with add_file*/
782                 segment_offset = expect_len / 3;
783                 segment_len = expect_len / 2;
784                 expect_data = expect_data + segment_offset;
785                 expect_len = segment_len;
786         }
787
788         if (use_segment) {
789                 seg = evbuffer_file_segment_new(fd, starting_offset,
790                     mapping_len, flags);
791                 tt_assert(seg);
792                 if (want_ismapping >= 0) {
793                         if (seg->is_mapping != (unsigned)want_ismapping)
794                                 tt_skip();
795                 }
796                 if (want_cansendfile >= 0) {
797                         if (seg->can_sendfile != (unsigned)want_cansendfile)
798                                 tt_skip();
799                 }
800         }
801
802         /* Say that it drains to a fd so that we can use sendfile. */
803         evbuffer_set_flags(src, EVBUFFER_FLAG_DRAINS_TO_FD);
804
805 #if defined(EVENT__HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__)
806         /* We need to use a pair of AF_INET sockets, since Solaris
807            doesn't support sendfile() over AF_UNIX. */
808         if (evutil_ersatz_socketpair_(AF_INET, SOCK_STREAM, 0, pair) == -1)
809                 tt_abort_msg("ersatz_socketpair failed");
810 #else
811         if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
812                 tt_abort_msg("socketpair failed");
813 #endif
814         evutil_make_socket_nonblocking(pair[0]);
815         evutil_make_socket_nonblocking(pair[1]);
816
817         tt_assert(fd != -1);
818
819         if (use_segment) {
820                 tt_assert(evbuffer_add_file_segment(src, seg,
821                         segment_offset, segment_len)!=-1);
822         } else {
823                 tt_assert(evbuffer_add_file(src, fd, starting_offset,
824                         mapping_len) != -1);
825         }
826
827         evbuffer_validate(src);
828
829         addfile_test_event_base = base;
830         wev = event_new(base, pair[0], EV_WRITE|EV_PERSIST,
831             addfile_test_writecb, src);
832         rev = event_new(base, pair[1], EV_READ|EV_PERSIST,
833             addfile_test_readcb, dest);
834
835         event_add(wev, NULL);
836         event_add(rev, NULL);
837         event_base_dispatch(base);
838
839         evbuffer_validate(src);
840         evbuffer_validate(dest);
841
842         tt_assert(addfile_test_done_writing);
843         tt_int_op(addfile_test_total_written, ==, expect_len);
844         tt_int_op(addfile_test_total_read, ==, expect_len);
845
846         compare = (char *)evbuffer_pullup(dest, expect_len);
847         tt_assert(compare != NULL);
848         if (memcmp(compare, expect_data, expect_len)) {
849                 tt_abort_msg("Data from add_file differs.");
850         }
851
852         evbuffer_validate(dest);
853  end:
854         if (data)
855                 free(data);
856         if (seg)
857                 evbuffer_file_segment_free(seg);
858         if (src)
859                 evbuffer_free(src);
860         if (dest)
861                 evbuffer_free(dest);
862         if (pair[0] >= 0)
863                 evutil_closesocket(pair[0]);
864         if (pair[1] >= 0)
865                 evutil_closesocket(pair[1]);
866         if (wev)
867                 event_free(wev);
868         if (rev)
869                 event_free(rev);
870         if (tmpfilename) {
871                 unlink(tmpfilename);
872                 free(tmpfilename);
873         }
874 }
875
876 static int file_segment_cleanup_cb_called_count = 0;
877 static struct evbuffer_file_segment const* file_segment_cleanup_cb_called_with = NULL;
878 static int file_segment_cleanup_cb_called_with_flags = 0;
879 static void* file_segment_cleanup_cb_called_with_arg = NULL;
880 static void
881 file_segment_cleanup_cp(struct evbuffer_file_segment const* seg, int flags, void* arg)
882 {
883         ++file_segment_cleanup_cb_called_count;
884         file_segment_cleanup_cb_called_with = seg;
885         file_segment_cleanup_cb_called_with_flags = flags;
886         file_segment_cleanup_cb_called_with_arg = arg;
887 }
888
889 static void
890 test_evbuffer_file_segment_add_cleanup_cb(void* ptr)
891 {
892         char *tmpfilename = NULL;
893         int fd = -1;
894         struct evbuffer *evb = NULL;
895         struct evbuffer_file_segment *seg = NULL, *segptr;
896         char const* arg = "token";
897
898         fd = regress_make_tmpfile("file_segment_test_file", 22, &tmpfilename);
899         tt_int_op(fd, >=, 0);
900
901         evb = evbuffer_new();
902         tt_assert(evb);
903
904         segptr = seg = evbuffer_file_segment_new(fd, 0, -1, 0);
905         tt_assert(seg);
906
907         evbuffer_file_segment_add_cleanup_cb(
908           seg, &file_segment_cleanup_cp, (void*)arg);
909
910         tt_assert(fd != -1);
911
912         tt_assert(evbuffer_add_file_segment(evb, seg, 0, -1)!=-1);
913
914         evbuffer_validate(evb);
915
916         tt_int_op(file_segment_cleanup_cb_called_count, ==, 0);
917         evbuffer_file_segment_free(seg);
918         seg = NULL; /* Prevent double-free. */
919
920         tt_int_op(file_segment_cleanup_cb_called_count, ==, 0);
921         evbuffer_free(evb);
922         evb = NULL; /* pevent double-free */
923
924         tt_int_op(file_segment_cleanup_cb_called_count, ==, 1);
925         tt_assert(file_segment_cleanup_cb_called_with == segptr);
926         tt_assert(file_segment_cleanup_cb_called_with_flags == 0);
927         tt_assert(file_segment_cleanup_cb_called_with_arg == (void*)arg);
928
929 end:
930         if (evb)
931                 evbuffer_free(evb);
932         if (seg)
933                 evbuffer_file_segment_free(seg);
934         if (tmpfilename) {
935                 unlink(tmpfilename);
936                 free(tmpfilename);
937         }
938 }
939
940 #ifndef EVENT__DISABLE_MM_REPLACEMENT
941 static void *
942 failing_malloc(size_t how_much)
943 {
944         errno = ENOMEM;
945         return NULL;
946 }
947 #endif
948
949 static void
950 test_evbuffer_readln(void *ptr)
951 {
952         struct evbuffer *evb = evbuffer_new();
953         struct evbuffer *evb_tmp = evbuffer_new();
954         const char *s;
955         char *cp = NULL;
956         size_t sz;
957
958 #define tt_line_eq(content)                                             \
959         TT_STMT_BEGIN                                                   \
960         if (!cp || sz != strlen(content) || strcmp(cp, content)) {      \
961                 TT_DIE(("Wanted %s; got %s [%d]", content, cp, (int)sz)); \
962         }                                                               \
963         TT_STMT_END
964
965         /* Test EOL_ANY. */
966         s = "complex silly newline\r\n\n\r\n\n\rmore\0\n";
967         evbuffer_add(evb, s, strlen(s)+2);
968         evbuffer_validate(evb);
969         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
970         tt_line_eq("complex silly newline");
971         free(cp);
972         evbuffer_validate(evb);
973         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
974         if (!cp || sz != 5 || memcmp(cp, "more\0\0", 6))
975                 tt_abort_msg("Not as expected");
976         tt_uint_op(evbuffer_get_length(evb), ==, 0);
977         evbuffer_validate(evb);
978         s = "\nno newline";
979         evbuffer_add(evb, s, strlen(s));
980         free(cp);
981         evbuffer_validate(evb);
982         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
983         tt_line_eq("");
984         free(cp);
985         evbuffer_validate(evb);
986         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
987         tt_assert(!cp);
988         evbuffer_validate(evb);
989         evbuffer_drain(evb, evbuffer_get_length(evb));
990         tt_assert(evbuffer_get_length(evb) == 0);
991         evbuffer_validate(evb);
992
993         /* Test EOL_CRLF */
994         s = "Line with\rin the middle\nLine with good crlf\r\n\nfinal\n";
995         evbuffer_add(evb, s, strlen(s));
996         evbuffer_validate(evb);
997         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
998         tt_line_eq("Line with\rin the middle");
999         free(cp);
1000         evbuffer_validate(evb);
1001
1002         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1003         tt_line_eq("Line with good crlf");
1004         free(cp);
1005         evbuffer_validate(evb);
1006
1007         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1008         tt_line_eq("");
1009         free(cp);
1010         evbuffer_validate(evb);
1011
1012         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1013         tt_line_eq("final");
1014         s = "x";
1015         evbuffer_validate(evb);
1016         evbuffer_add(evb, s, 1);
1017         evbuffer_validate(evb);
1018         free(cp);
1019         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1020         tt_assert(!cp);
1021         evbuffer_validate(evb);
1022
1023         /* Test CRLF_STRICT */
1024         s = " and a bad crlf\nand a good one\r\n\r\nMore\r";
1025         evbuffer_add(evb, s, strlen(s));
1026         evbuffer_validate(evb);
1027         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1028         tt_line_eq("x and a bad crlf\nand a good one");
1029         free(cp);
1030         evbuffer_validate(evb);
1031
1032         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1033         tt_line_eq("");
1034         free(cp);
1035         evbuffer_validate(evb);
1036
1037         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1038         tt_assert(!cp);
1039         evbuffer_validate(evb);
1040         evbuffer_add(evb, "\n", 1);
1041         evbuffer_validate(evb);
1042
1043         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1044         tt_line_eq("More");
1045         free(cp);
1046         tt_assert(evbuffer_get_length(evb) == 0);
1047         evbuffer_validate(evb);
1048
1049         s = "An internal CR\r is not an eol\r\nNor is a lack of one";
1050         evbuffer_add(evb, s, strlen(s));
1051         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1052         tt_line_eq("An internal CR\r is not an eol");
1053         free(cp);
1054         evbuffer_validate(evb);
1055
1056         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1057         tt_assert(!cp);
1058         evbuffer_validate(evb);
1059
1060         evbuffer_add(evb, "\r\n", 2);
1061         evbuffer_validate(evb);
1062         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1063         tt_line_eq("Nor is a lack of one");
1064         free(cp);
1065         tt_assert(evbuffer_get_length(evb) == 0);
1066         evbuffer_validate(evb);
1067
1068         /* Test LF */
1069         s = "An\rand a nl\n\nText";
1070         evbuffer_add(evb, s, strlen(s));
1071         evbuffer_validate(evb);
1072
1073         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1074         tt_line_eq("An\rand a nl");
1075         free(cp);
1076         evbuffer_validate(evb);
1077
1078         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1079         tt_line_eq("");
1080         free(cp);
1081         evbuffer_validate(evb);
1082
1083         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1084         tt_assert(!cp);
1085         free(cp);
1086         evbuffer_add(evb, "\n", 1);
1087         evbuffer_validate(evb);
1088         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1089         tt_line_eq("Text");
1090         free(cp);
1091         evbuffer_validate(evb);
1092
1093         /* Test NUL */
1094         tt_int_op(evbuffer_get_length(evb), ==, 0);
1095         {
1096                 char x[] =
1097                     "NUL\n\0\0"
1098                     "The all-zeros character which may serve\0"
1099                     "to accomplish time fill\0and media fill";
1100                 /* Add all but the final NUL of x. */
1101                 evbuffer_add(evb, x, sizeof(x)-1);
1102         }
1103         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1104         tt_line_eq("NUL\n");
1105         free(cp);
1106         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1107         tt_line_eq("");
1108         free(cp);
1109         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1110         tt_line_eq("The all-zeros character which may serve");
1111         free(cp);
1112         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1113         tt_line_eq("to accomplish time fill");
1114         free(cp);
1115         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1116         tt_ptr_op(cp, ==, NULL);
1117         evbuffer_drain(evb, -1);
1118
1119         /* Test CRLF_STRICT - across boundaries*/
1120         s = " and a bad crlf\nand a good one\r";
1121         evbuffer_add(evb_tmp, s, strlen(s));
1122         evbuffer_validate(evb);
1123         evbuffer_add_buffer(evb, evb_tmp);
1124         evbuffer_validate(evb);
1125         s = "\n\r";
1126         evbuffer_add(evb_tmp, s, strlen(s));
1127         evbuffer_validate(evb);
1128         evbuffer_add_buffer(evb, evb_tmp);
1129         evbuffer_validate(evb);
1130         s = "\nMore\r";
1131         evbuffer_add(evb_tmp, s, strlen(s));
1132         evbuffer_validate(evb);
1133         evbuffer_add_buffer(evb, evb_tmp);
1134         evbuffer_validate(evb);
1135
1136         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1137         tt_line_eq(" and a bad crlf\nand a good one");
1138         free(cp);
1139         evbuffer_validate(evb);
1140
1141         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1142         tt_line_eq("");
1143         free(cp);
1144         evbuffer_validate(evb);
1145
1146         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1147         tt_assert(!cp);
1148         free(cp);
1149         evbuffer_validate(evb);
1150         evbuffer_add(evb, "\n", 1);
1151         evbuffer_validate(evb);
1152         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1153         tt_line_eq("More");
1154         free(cp); cp = NULL;
1155         evbuffer_validate(evb);
1156         tt_assert(evbuffer_get_length(evb) == 0);
1157
1158         /* Test memory problem*/
1159         s = "one line\ntwo line\nblue line";
1160         evbuffer_add(evb_tmp, s, strlen(s));
1161         evbuffer_validate(evb);
1162         evbuffer_add_buffer(evb, evb_tmp);
1163         evbuffer_validate(evb);
1164
1165         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1166         tt_line_eq("one line");
1167         free(cp); cp = NULL;
1168         evbuffer_validate(evb);
1169
1170         /* the next call to readline should fail */
1171 #ifndef EVENT__DISABLE_MM_REPLACEMENT
1172         event_set_mem_functions(failing_malloc, realloc, free);
1173         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1174         tt_assert(cp == NULL);
1175         evbuffer_validate(evb);
1176
1177         /* now we should get the next line back */
1178         event_set_mem_functions(malloc, realloc, free);
1179 #endif
1180         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1181         tt_line_eq("two line");
1182         free(cp); cp = NULL;
1183         evbuffer_validate(evb);
1184
1185  end:
1186         evbuffer_free(evb);
1187         evbuffer_free(evb_tmp);
1188         if (cp) free(cp);
1189 }
1190
1191 static void
1192 test_evbuffer_search_eol(void *ptr)
1193 {
1194         struct evbuffer *buf = evbuffer_new();
1195         struct evbuffer_ptr ptr1, ptr2;
1196         const char *s;
1197         size_t eol_len;
1198
1199         s = "string! \r\n\r\nx\n";
1200         evbuffer_add(buf, s, strlen(s));
1201         eol_len = -1;
1202         ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_CRLF);
1203         tt_int_op(ptr1.pos, ==, 8);
1204         tt_int_op(eol_len, ==, 2);
1205
1206         eol_len = -1;
1207         ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF);
1208         tt_int_op(ptr2.pos, ==, 8);
1209         tt_int_op(eol_len, ==, 2);
1210
1211         evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD);
1212         eol_len = -1;
1213         ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF);
1214         tt_int_op(ptr2.pos, ==, 9);
1215         tt_int_op(eol_len, ==, 1);
1216
1217         eol_len = -1;
1218         ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF_STRICT);
1219         tt_int_op(ptr2.pos, ==, 10);
1220         tt_int_op(eol_len, ==, 2);
1221
1222         eol_len = -1;
1223         ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_LF);
1224         tt_int_op(ptr1.pos, ==, 9);
1225         tt_int_op(eol_len, ==, 1);
1226
1227         eol_len = -1;
1228         ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
1229         tt_int_op(ptr2.pos, ==, 9);
1230         tt_int_op(eol_len, ==, 1);
1231
1232         evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD);
1233         eol_len = -1;
1234         ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
1235         tt_int_op(ptr2.pos, ==, 11);
1236         tt_int_op(eol_len, ==, 1);
1237
1238         tt_assert(evbuffer_ptr_set(buf, &ptr1, evbuffer_get_length(buf), EVBUFFER_PTR_SET) == 0);
1239         eol_len = -1;
1240         ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
1241         tt_int_op(ptr2.pos, ==, -1);
1242         tt_int_op(eol_len, ==, 0);
1243
1244 end:
1245         evbuffer_free(buf);
1246 }
1247
1248 static void
1249 test_evbuffer_iterative(void *ptr)
1250 {
1251         struct evbuffer *buf = evbuffer_new();
1252         const char *abc = "abcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyz";
1253         unsigned i, j, sum, n;
1254
1255         sum = 0;
1256         n = 0;
1257         for (i = 0; i < 1000; ++i) {
1258                 for (j = 1; j < strlen(abc); ++j) {
1259                         char format[32];
1260                         evutil_snprintf(format, sizeof(format), "%%%u.%us", j, j);
1261                         evbuffer_add_printf(buf, format, abc);
1262
1263                         /* Only check for rep violations every so often.
1264                            Walking over the whole list of chains can get
1265                            pretty expensive as it gets long.
1266                          */
1267                         if ((n % 337) == 0)
1268                                 evbuffer_validate(buf);
1269
1270                         sum += j;
1271                         n++;
1272                 }
1273         }
1274         evbuffer_validate(buf);
1275
1276         tt_uint_op(sum, ==, evbuffer_get_length(buf));
1277
1278         {
1279                 size_t a,w,u;
1280                 a=w=u=0;
1281                 evbuffer_get_waste(buf, &a, &w, &u);
1282                 if (0)
1283                         printf("Allocated: %u.\nWasted: %u.\nUsed: %u.",
1284                             (unsigned)a, (unsigned)w, (unsigned)u);
1285                 tt_assert( ((double)w)/a < .125);
1286         }
1287  end:
1288         evbuffer_free(buf);
1289
1290 }
1291
1292 static void
1293 test_evbuffer_find(void *ptr)
1294 {
1295         u_char* p;
1296         const char* test1 = "1234567890\r\n";
1297         const char* test2 = "1234567890\r";
1298 #define EVBUFFER_INITIAL_LENGTH 256
1299         char test3[EVBUFFER_INITIAL_LENGTH];
1300         unsigned int i;
1301         struct evbuffer * buf = evbuffer_new();
1302
1303         tt_assert(buf);
1304
1305         /* make sure evbuffer_find doesn't match past the end of the buffer */
1306         evbuffer_add(buf, (u_char*)test1, strlen(test1));
1307         evbuffer_validate(buf);
1308         evbuffer_drain(buf, strlen(test1));
1309         evbuffer_validate(buf);
1310         evbuffer_add(buf, (u_char*)test2, strlen(test2));
1311         evbuffer_validate(buf);
1312         p = evbuffer_find(buf, (u_char*)"\r\n", 2);
1313         tt_want(p == NULL);
1314
1315         /*
1316          * drain the buffer and do another find; in r309 this would
1317          * read past the allocated buffer causing a valgrind error.
1318          */
1319         evbuffer_drain(buf, strlen(test2));
1320         evbuffer_validate(buf);
1321         for (i = 0; i < EVBUFFER_INITIAL_LENGTH; ++i)
1322                 test3[i] = 'a';
1323         test3[EVBUFFER_INITIAL_LENGTH - 1] = 'x';
1324         evbuffer_add(buf, (u_char *)test3, EVBUFFER_INITIAL_LENGTH);
1325         evbuffer_validate(buf);
1326         p = evbuffer_find(buf, (u_char *)"xy", 2);
1327         tt_want(p == NULL);
1328
1329         /* simple test for match at end of allocated buffer */
1330         p = evbuffer_find(buf, (u_char *)"ax", 2);
1331         tt_assert(p != NULL);
1332         tt_want(strncmp((char*)p, "ax", 2) == 0);
1333
1334 end:
1335         if (buf)
1336                 evbuffer_free(buf);
1337 }
1338
1339 static void
1340 test_evbuffer_ptr_set(void *ptr)
1341 {
1342         struct evbuffer *buf = evbuffer_new();
1343         struct evbuffer_ptr pos;
1344         struct evbuffer_iovec v[1];
1345
1346         tt_assert(buf);
1347
1348         tt_int_op(evbuffer_get_length(buf), ==, 0);
1349
1350         tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1351         tt_assert(pos.pos == 0);
1352         tt_assert(evbuffer_ptr_set(buf, &pos, 1, EVBUFFER_PTR_ADD) == -1);
1353         tt_assert(pos.pos == -1);
1354         tt_assert(evbuffer_ptr_set(buf, &pos, 1, EVBUFFER_PTR_SET) == -1);
1355         tt_assert(pos.pos == -1);
1356
1357         /* create some chains */
1358         evbuffer_reserve_space(buf, 5000, v, 1);
1359         v[0].iov_len = 5000;
1360         memset(v[0].iov_base, 1, v[0].iov_len);
1361         evbuffer_commit_space(buf, v, 1);
1362         evbuffer_validate(buf);
1363
1364         evbuffer_reserve_space(buf, 4000, v, 1);
1365         v[0].iov_len = 4000;
1366         memset(v[0].iov_base, 2, v[0].iov_len);
1367         evbuffer_commit_space(buf, v, 1);
1368
1369         evbuffer_reserve_space(buf, 3000, v, 1);
1370         v[0].iov_len = 3000;
1371         memset(v[0].iov_base, 3, v[0].iov_len);
1372         evbuffer_commit_space(buf, v, 1);
1373         evbuffer_validate(buf);
1374
1375         tt_int_op(evbuffer_get_length(buf), ==, 12000);
1376
1377         tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_SET) == -1);
1378         tt_assert(pos.pos == -1);
1379         tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1380         tt_assert(pos.pos == 0);
1381         tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_ADD) == -1);
1382
1383         tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1384         tt_assert(pos.pos == 0);
1385         tt_assert(evbuffer_ptr_set(buf, &pos, 10000, EVBUFFER_PTR_ADD) == 0);
1386         tt_assert(pos.pos == 10000);
1387         tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == 0);
1388         tt_assert(pos.pos == 11000);
1389         tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == 0);
1390         tt_assert(pos.pos == 12000);
1391         tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == -1);
1392         tt_assert(pos.pos == -1);
1393
1394 end:
1395         if (buf)
1396                 evbuffer_free(buf);
1397 }
1398
1399 static void
1400 test_evbuffer_search(void *ptr)
1401 {
1402         struct evbuffer *buf = evbuffer_new();
1403         struct evbuffer *tmp = evbuffer_new();
1404         struct evbuffer_ptr pos, end;
1405
1406         tt_assert(buf);
1407         tt_assert(tmp);
1408
1409         pos = evbuffer_search(buf, "x", 1, NULL);
1410         tt_int_op(pos.pos, ==, -1);
1411         tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1412         pos = evbuffer_search(buf, "x", 1, &pos);
1413         tt_int_op(pos.pos, ==, -1);
1414         tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1415         pos = evbuffer_search_range(buf, "x", 1, &pos, &pos);
1416         tt_int_op(pos.pos, ==, -1);
1417         tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1418         pos = evbuffer_search_range(buf, "x", 1, &pos, NULL);
1419         tt_int_op(pos.pos, ==, -1);
1420
1421         /* set up our chains */
1422         evbuffer_add_printf(tmp, "hello");  /* 5 chars */
1423         evbuffer_add_buffer(buf, tmp);
1424         evbuffer_add_printf(tmp, "foo");    /* 3 chars */
1425         evbuffer_add_buffer(buf, tmp);
1426         evbuffer_add_printf(tmp, "cat");    /* 3 chars */
1427         evbuffer_add_buffer(buf, tmp);
1428         evbuffer_add_printf(tmp, "attack");
1429         evbuffer_add_buffer(buf, tmp);
1430
1431         pos = evbuffer_search(buf, "attack", 6, NULL);
1432         tt_int_op(pos.pos, ==, 11);
1433         pos = evbuffer_search(buf, "attacker", 8, NULL);
1434         tt_int_op(pos.pos, ==, -1);
1435
1436         /* test continuing search */
1437         pos = evbuffer_search(buf, "oc", 2, NULL);
1438         tt_int_op(pos.pos, ==, 7);
1439         pos = evbuffer_search(buf, "cat", 3, &pos);
1440         tt_int_op(pos.pos, ==, 8);
1441         pos = evbuffer_search(buf, "tacking", 7, &pos);
1442         tt_int_op(pos.pos, ==, -1);
1443
1444         evbuffer_ptr_set(buf, &pos, 5, EVBUFFER_PTR_SET);
1445         pos = evbuffer_search(buf, "foo", 3, &pos);
1446         tt_int_op(pos.pos, ==, 5);
1447
1448         evbuffer_ptr_set(buf, &pos, 2, EVBUFFER_PTR_ADD);
1449         pos = evbuffer_search(buf, "tat", 3, &pos);
1450         tt_int_op(pos.pos, ==, 10);
1451
1452         /* test bounded search. */
1453         /* Set "end" to the first t in "attack". */
1454         evbuffer_ptr_set(buf, &end, 12, EVBUFFER_PTR_SET);
1455         pos = evbuffer_search_range(buf, "foo", 3, NULL, &end);
1456         tt_int_op(pos.pos, ==, 5);
1457         pos = evbuffer_search_range(buf, "foocata", 7, NULL, &end);
1458         tt_int_op(pos.pos, ==, 5);
1459         pos = evbuffer_search_range(buf, "foocatat", 8, NULL, &end);
1460         tt_int_op(pos.pos, ==, -1);
1461         pos = evbuffer_search_range(buf, "ack", 3, NULL, &end);
1462         tt_int_op(pos.pos, ==, -1);
1463
1464         /* Set "end" after the last byte in the buffer. */
1465         tt_assert(evbuffer_ptr_set(buf, &end, 17, EVBUFFER_PTR_SET) == 0);
1466
1467         pos = evbuffer_search_range(buf, "attack", 6, NULL, &end);
1468         tt_int_op(pos.pos, ==, 11);
1469         tt_assert(evbuffer_ptr_set(buf, &pos, 11, EVBUFFER_PTR_SET) == 0);
1470         pos = evbuffer_search_range(buf, "attack", 6, &pos, &end);
1471         tt_int_op(pos.pos, ==, 11);
1472         tt_assert(evbuffer_ptr_set(buf, &pos, 17, EVBUFFER_PTR_SET) == 0);
1473         pos = evbuffer_search_range(buf, "attack", 6, &pos, &end);
1474         tt_int_op(pos.pos, ==, -1);
1475         tt_assert(evbuffer_ptr_set(buf, &pos, 17, EVBUFFER_PTR_SET) == 0);
1476         pos = evbuffer_search_range(buf, "attack", 6, &pos, NULL);
1477         tt_int_op(pos.pos, ==, -1);
1478
1479 end:
1480         if (buf)
1481                 evbuffer_free(buf);
1482         if (tmp)
1483                 evbuffer_free(tmp);
1484 }
1485
1486 static void
1487 log_change_callback(struct evbuffer *buffer,
1488     const struct evbuffer_cb_info *cbinfo,
1489     void *arg)
1490 {
1491
1492         size_t old_len = cbinfo->orig_size;
1493         size_t new_len = old_len + cbinfo->n_added - cbinfo->n_deleted;
1494         struct evbuffer *out = arg;
1495         evbuffer_add_printf(out, "%lu->%lu; ", (unsigned long)old_len,
1496                             (unsigned long)new_len);
1497 }
1498 static void
1499 self_draining_callback(struct evbuffer *evbuffer, size_t old_len,
1500                 size_t new_len, void *arg)
1501 {
1502         if (new_len > old_len)
1503                 evbuffer_drain(evbuffer, new_len);
1504 }
1505
1506 static void
1507 test_evbuffer_callbacks(void *ptr)
1508 {
1509         struct evbuffer *buf = evbuffer_new();
1510         struct evbuffer *buf_out1 = evbuffer_new();
1511         struct evbuffer *buf_out2 = evbuffer_new();
1512         struct evbuffer_cb_entry *cb1, *cb2;
1513
1514         tt_assert(buf);
1515         tt_assert(buf_out1);
1516         tt_assert(buf_out2);
1517
1518         cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1519         cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1520
1521         /* Let's run through adding and deleting some stuff from the buffer
1522          * and turning the callbacks on and off and removing them.  The callback
1523          * adds a summary of length changes to buf_out1/buf_out2 when called. */
1524         /* size: 0-> 36. */
1525         evbuffer_add_printf(buf, "The %d magic words are spotty pudding", 2);
1526         evbuffer_validate(buf);
1527         evbuffer_cb_clear_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1528         evbuffer_drain(buf, 10); /*36->26*/
1529         evbuffer_validate(buf);
1530         evbuffer_prepend(buf, "Hello", 5);/*26->31*/
1531         evbuffer_cb_set_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1532         evbuffer_add_reference(buf, "Goodbye", 7, NULL, NULL); /*31->38*/
1533         evbuffer_remove_cb_entry(buf, cb1);
1534         evbuffer_validate(buf);
1535         evbuffer_drain(buf, evbuffer_get_length(buf)); /*38->0*/;
1536         tt_assert(-1 == evbuffer_remove_cb(buf, log_change_callback, NULL));
1537         evbuffer_add(buf, "X", 1); /* 0->1 */
1538         tt_assert(!evbuffer_remove_cb(buf, log_change_callback, buf_out2));
1539         evbuffer_validate(buf);
1540
1541         tt_str_op((const char *) evbuffer_pullup(buf_out1, -1), ==,
1542                   "0->36; 36->26; 26->31; 31->38; ");
1543         tt_str_op((const char *) evbuffer_pullup(buf_out2, -1), ==,
1544                   "0->36; 31->38; 38->0; 0->1; ");
1545         evbuffer_drain(buf_out1, evbuffer_get_length(buf_out1));
1546         evbuffer_drain(buf_out2, evbuffer_get_length(buf_out2));
1547         /* Let's test the obsolete buffer_setcb function too. */
1548         cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1549         tt_assert(cb1 != NULL);
1550         cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1551         tt_assert(cb2 != NULL);
1552         evbuffer_setcb(buf, self_draining_callback, NULL);
1553         evbuffer_add_printf(buf, "This should get drained right away.");
1554         tt_uint_op(evbuffer_get_length(buf), ==, 0);
1555         tt_uint_op(evbuffer_get_length(buf_out1), ==, 0);
1556         tt_uint_op(evbuffer_get_length(buf_out2), ==, 0);
1557         evbuffer_setcb(buf, NULL, NULL);
1558         evbuffer_add_printf(buf, "This will not.");
1559         tt_str_op((const char *) evbuffer_pullup(buf, -1), ==, "This will not.");
1560         evbuffer_validate(buf);
1561         evbuffer_drain(buf, evbuffer_get_length(buf));
1562         evbuffer_validate(buf);
1563 #if 0
1564         /* Now let's try a suspended callback. */
1565         cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1566         cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1567         evbuffer_cb_suspend(buf,cb2);
1568         evbuffer_prepend(buf,"Hello world",11); /*0->11*/
1569         evbuffer_validate(buf);
1570         evbuffer_cb_suspend(buf,cb1);
1571         evbuffer_add(buf,"more",4); /* 11->15 */
1572         evbuffer_cb_unsuspend(buf,cb2);
1573         evbuffer_drain(buf, 4); /* 15->11 */
1574         evbuffer_cb_unsuspend(buf,cb1);
1575         evbuffer_drain(buf, evbuffer_get_length(buf)); /* 11->0 */
1576
1577         tt_str_op(evbuffer_pullup(buf_out1, -1), ==,
1578                   "0->11; 11->11; 11->0; ");
1579         tt_str_op(evbuffer_pullup(buf_out2, -1), ==,
1580                   "0->15; 15->11; 11->0; ");
1581 #endif
1582
1583  end:
1584         if (buf)
1585                 evbuffer_free(buf);
1586         if (buf_out1)
1587                 evbuffer_free(buf_out1);
1588         if (buf_out2)
1589                 evbuffer_free(buf_out2);
1590 }
1591
1592 static int ref_done_cb_called_count = 0;
1593 static void *ref_done_cb_called_with = NULL;
1594 static const void *ref_done_cb_called_with_data = NULL;
1595 static size_t ref_done_cb_called_with_len = 0;
1596 static void ref_done_cb(const void *data, size_t len, void *info)
1597 {
1598         ++ref_done_cb_called_count;
1599         ref_done_cb_called_with = info;
1600         ref_done_cb_called_with_data = data;
1601         ref_done_cb_called_with_len = len;
1602 }
1603
1604 static void
1605 test_evbuffer_add_reference(void *ptr)
1606 {
1607         const char chunk1[] = "If you have found the answer to such a problem";
1608         const char chunk2[] = "you ought to write it up for publication";
1609                           /* -- Knuth's "Notes on the Exercises" from TAOCP */
1610         char tmp[16];
1611         size_t len1 = strlen(chunk1), len2=strlen(chunk2);
1612
1613         struct evbuffer *buf1 = NULL, *buf2 = NULL;
1614
1615         buf1 = evbuffer_new();
1616         tt_assert(buf1);
1617
1618         evbuffer_add_reference(buf1, chunk1, len1, ref_done_cb, (void*)111);
1619         evbuffer_add(buf1, ", ", 2);
1620         evbuffer_add_reference(buf1, chunk2, len2, ref_done_cb, (void*)222);
1621         tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
1622
1623         /* Make sure we can drain a little from a reference. */
1624         tt_int_op(evbuffer_remove(buf1, tmp, 6), ==, 6);
1625         tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
1626         tt_int_op(evbuffer_remove(buf1, tmp, 5), ==, 5);
1627         tt_int_op(memcmp(tmp, " have", 5), ==, 0);
1628
1629         /* Make sure that prepending does not meddle with immutable data */
1630         tt_int_op(evbuffer_prepend(buf1, "I have ", 7), ==, 0);
1631         tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
1632         evbuffer_validate(buf1);
1633
1634         /* Make sure that when the chunk is over, the callback is invoked. */
1635         evbuffer_drain(buf1, 7); /* Remove prepended stuff. */
1636         evbuffer_drain(buf1, len1-11-1); /* remove all but one byte of chunk1 */
1637         tt_int_op(ref_done_cb_called_count, ==, 0);
1638         evbuffer_remove(buf1, tmp, 1);
1639         tt_int_op(tmp[0], ==, 'm');
1640         tt_assert(ref_done_cb_called_with == (void*)111);
1641         tt_assert(ref_done_cb_called_with_data == chunk1);
1642         tt_assert(ref_done_cb_called_with_len == len1);
1643         tt_int_op(ref_done_cb_called_count, ==, 1);
1644         evbuffer_validate(buf1);
1645
1646         /* Drain some of the remaining chunk, then add it to another buffer */
1647         evbuffer_drain(buf1, 6); /* Remove the ", you ". */
1648         buf2 = evbuffer_new();
1649         tt_assert(buf2);
1650         tt_int_op(ref_done_cb_called_count, ==, 1);
1651         evbuffer_add(buf2, "I ", 2);
1652
1653         evbuffer_add_buffer(buf2, buf1);
1654         tt_int_op(ref_done_cb_called_count, ==, 1);
1655         evbuffer_remove(buf2, tmp, 16);
1656         tt_int_op(memcmp("I ought to write", tmp, 16), ==, 0);
1657         evbuffer_drain(buf2, evbuffer_get_length(buf2));
1658         tt_int_op(ref_done_cb_called_count, ==, 2);
1659         tt_assert(ref_done_cb_called_with == (void*)222);
1660         evbuffer_validate(buf2);
1661
1662         /* Now add more stuff to buf1 and make sure that it gets removed on
1663          * free. */
1664         evbuffer_add(buf1, "You shake and shake the ", 24);
1665         evbuffer_add_reference(buf1, "ketchup bottle", 14, ref_done_cb,
1666             (void*)3333);
1667         evbuffer_add(buf1, ". Nothing comes and then a lot'll.", 35);
1668         evbuffer_free(buf1);
1669         buf1 = NULL;
1670         tt_int_op(ref_done_cb_called_count, ==, 3);
1671         tt_assert(ref_done_cb_called_with == (void*)3333);
1672
1673 end:
1674         if (buf1)
1675                 evbuffer_free(buf1);
1676         if (buf2)
1677                 evbuffer_free(buf2);
1678 }
1679
1680 static void
1681 test_evbuffer_multicast(void *ptr)
1682 {
1683         const char chunk1[] = "If you have found the answer to such a problem";
1684         const char chunk2[] = "you ought to write it up for publication";
1685                           /* -- Knuth's "Notes on the Exercises" from TAOCP */
1686         char tmp[16];
1687         size_t len1 = strlen(chunk1), len2=strlen(chunk2);
1688
1689         struct evbuffer *buf1 = NULL, *buf2 = NULL;
1690
1691         buf1 = evbuffer_new();
1692         tt_assert(buf1);
1693
1694         evbuffer_add(buf1, chunk1, len1);
1695         evbuffer_add(buf1, ", ", 2);
1696         evbuffer_add(buf1, chunk2, len2);
1697         tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
1698
1699         buf2 = evbuffer_new();
1700         tt_assert(buf2);
1701
1702         tt_int_op(evbuffer_add_buffer_reference(buf2, buf1), ==, 0);
1703         /* nested references are not allowed */
1704         tt_int_op(evbuffer_add_buffer_reference(buf2, buf2), ==, -1);
1705         tt_int_op(evbuffer_add_buffer_reference(buf1, buf2), ==, -1);
1706
1707         /* both buffers contain the same amount of data */
1708         tt_int_op(evbuffer_get_length(buf1), ==, evbuffer_get_length(buf1));
1709
1710         /* Make sure we can drain a little from the first buffer. */
1711         tt_int_op(evbuffer_remove(buf1, tmp, 6), ==, 6);
1712         tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
1713         tt_int_op(evbuffer_remove(buf1, tmp, 5), ==, 5);
1714         tt_int_op(memcmp(tmp, " have", 5), ==, 0);
1715
1716         /* Make sure that prepending does not meddle with immutable data */
1717         tt_int_op(evbuffer_prepend(buf1, "I have ", 7), ==, 0);
1718         tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
1719         evbuffer_validate(buf1);
1720
1721         /* Make sure we can drain a little from the second buffer. */
1722         tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6);
1723         tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
1724         tt_int_op(evbuffer_remove(buf2, tmp, 5), ==, 5);
1725         tt_int_op(memcmp(tmp, " have", 5), ==, 0);
1726
1727         /* Make sure that prepending does not meddle with immutable data */
1728         tt_int_op(evbuffer_prepend(buf2, "I have ", 7), ==, 0);
1729         tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
1730         evbuffer_validate(buf2);
1731
1732         /* Make sure the data can be read from the second buffer when the first is freed */
1733         evbuffer_free(buf1);
1734         buf1 = NULL;
1735
1736         tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6);
1737         tt_int_op(memcmp(tmp, "I have", 6), ==, 0);
1738
1739         tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6);
1740         tt_int_op(memcmp(tmp, "  foun", 6), ==, 0);
1741
1742 end:
1743         if (buf1)
1744                 evbuffer_free(buf1);
1745         if (buf2)
1746                 evbuffer_free(buf2);
1747 }
1748
1749 static void
1750 test_evbuffer_multicast_drain(void *ptr)
1751 {
1752         const char chunk1[] = "If you have found the answer to such a problem";
1753         const char chunk2[] = "you ought to write it up for publication";
1754                           /* -- Knuth's "Notes on the Exercises" from TAOCP */
1755         size_t len1 = strlen(chunk1), len2=strlen(chunk2);
1756
1757         struct evbuffer *buf1 = NULL, *buf2 = NULL;
1758
1759         buf1 = evbuffer_new();
1760         tt_assert(buf1);
1761
1762         evbuffer_add(buf1, chunk1, len1);
1763         evbuffer_add(buf1, ", ", 2);
1764         evbuffer_add(buf1, chunk2, len2);
1765         tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
1766
1767         buf2 = evbuffer_new();
1768         tt_assert(buf2);
1769
1770         tt_int_op(evbuffer_add_buffer_reference(buf2, buf1), ==, 0);
1771         tt_int_op(evbuffer_get_length(buf2), ==, len1+len2+2);
1772         tt_int_op(evbuffer_drain(buf1, evbuffer_get_length(buf1)), ==, 0);
1773         tt_int_op(evbuffer_get_length(buf2), ==, len1+len2+2);
1774         tt_int_op(evbuffer_drain(buf2, evbuffer_get_length(buf2)), ==, 0);
1775         evbuffer_validate(buf1);
1776         evbuffer_validate(buf2);
1777
1778 end:
1779         if (buf1)
1780                 evbuffer_free(buf1);
1781         if (buf2)
1782                 evbuffer_free(buf2);
1783 }
1784
1785 /* Some cases that we didn't get in test_evbuffer() above, for more coverage. */
1786 static void
1787 test_evbuffer_prepend(void *ptr)
1788 {
1789         struct evbuffer *buf1 = NULL, *buf2 = NULL;
1790         char tmp[128];
1791         int n;
1792
1793         buf1 = evbuffer_new();
1794         tt_assert(buf1);
1795
1796         /* Case 0: The evbuffer is entirely empty. */
1797         evbuffer_prepend(buf1, "This string has 29 characters", 29);
1798         evbuffer_validate(buf1);
1799
1800         /* Case 1: Prepend goes entirely in new chunk. */
1801         evbuffer_prepend(buf1, "Short.", 6);
1802         evbuffer_validate(buf1);
1803
1804         /* Case 2: prepend goes entirely in first chunk. */
1805         evbuffer_drain(buf1, 6+11);
1806         evbuffer_prepend(buf1, "it", 2);
1807         evbuffer_validate(buf1);
1808         tt_assert(!memcmp(buf1->first->buffer+buf1->first->misalign,
1809                 "it has", 6));
1810
1811         /* Case 3: prepend is split over multiple chunks. */
1812         evbuffer_prepend(buf1, "It is no longer true to say ", 28);
1813         evbuffer_validate(buf1);
1814         n = evbuffer_remove(buf1, tmp, sizeof(tmp)-1);
1815         tt_int_op(n, >=, 0);
1816         tmp[n]='\0';
1817         tt_str_op(tmp,==,"It is no longer true to say it has 29 characters");
1818
1819         buf2 = evbuffer_new();
1820         tt_assert(buf2);
1821
1822         /* Case 4: prepend a buffer to an empty buffer. */
1823         n = 999;
1824         evbuffer_add_printf(buf1, "Here is string %d. ", n++);
1825         evbuffer_prepend_buffer(buf2, buf1);
1826         evbuffer_validate(buf2);
1827
1828         /* Case 5: prepend a buffer to a nonempty buffer. */
1829         evbuffer_add_printf(buf1, "Here is string %d. ", n++);
1830         evbuffer_prepend_buffer(buf2, buf1);
1831         evbuffer_validate(buf2);
1832         evbuffer_validate(buf1);
1833         n = evbuffer_remove(buf2, tmp, sizeof(tmp)-1);
1834         tt_int_op(n, >=, 0);
1835         tmp[n]='\0';
1836         tt_str_op(tmp,==,"Here is string 1000. Here is string 999. ");
1837
1838 end:
1839         if (buf1)
1840                 evbuffer_free(buf1);
1841         if (buf2)
1842                 evbuffer_free(buf2);
1843
1844 }
1845
1846 static void
1847 test_evbuffer_peek_first_gt(void *info)
1848 {
1849         struct evbuffer *buf = NULL, *tmp_buf = NULL;
1850         struct evbuffer_ptr ptr;
1851         struct evbuffer_iovec v[2];
1852
1853         buf = evbuffer_new();
1854         tmp_buf = evbuffer_new();
1855         evbuffer_add_printf(tmp_buf, "Contents of chunk 100\n");
1856         evbuffer_add_buffer(buf, tmp_buf);
1857         evbuffer_add_printf(tmp_buf, "Contents of chunk 1\n");
1858         evbuffer_add_buffer(buf, tmp_buf);
1859
1860         evbuffer_ptr_set(buf, &ptr, 0, EVBUFFER_PTR_SET);
1861
1862         /** The only case that matters*/
1863         tt_int_op(evbuffer_peek(buf, -1, &ptr, NULL, 0), ==, 2);
1864         /** Just in case */
1865         tt_int_op(evbuffer_peek(buf, -1, &ptr, v, 2), ==, 2);
1866
1867         evbuffer_ptr_set(buf, &ptr, 20, EVBUFFER_PTR_ADD);
1868         tt_int_op(evbuffer_peek(buf, -1, &ptr, NULL, 0), ==, 2);
1869         tt_int_op(evbuffer_peek(buf, -1, &ptr, v, 2), ==, 2);
1870         tt_int_op(evbuffer_peek(buf, 2, &ptr, NULL, 0), ==, 1);
1871         tt_int_op(evbuffer_peek(buf, 2, &ptr, v, 2), ==, 1);
1872         tt_int_op(evbuffer_peek(buf, 3, &ptr, NULL, 0), ==, 2);
1873         tt_int_op(evbuffer_peek(buf, 3, &ptr, v, 2), ==, 2);
1874
1875 end:
1876         if (buf)
1877                 evbuffer_free(buf);
1878         if (tmp_buf)
1879                 evbuffer_free(tmp_buf);
1880 }
1881
1882 static void
1883 test_evbuffer_peek(void *info)
1884 {
1885         struct evbuffer *buf = NULL, *tmp_buf = NULL;
1886         int i;
1887         struct evbuffer_iovec v[20];
1888         struct evbuffer_ptr ptr;
1889
1890 #define tt_iov_eq(v, s)                                         \
1891         tt_int_op((v)->iov_len, ==, strlen(s));                 \
1892         tt_assert(!memcmp((v)->iov_base, (s), strlen(s)))
1893
1894         /* Let's make a very fragmented buffer. */
1895         buf = evbuffer_new();
1896         tmp_buf = evbuffer_new();
1897         for (i = 0; i < 16; ++i) {
1898                 evbuffer_add_printf(tmp_buf, "Contents of chunk [%d]\n", i);
1899                 evbuffer_add_buffer(buf, tmp_buf);
1900         }
1901
1902         /* How many chunks do we need for everything? */
1903         i = evbuffer_peek(buf, -1, NULL, NULL, 0);
1904         tt_int_op(i, ==, 16);
1905
1906         /* Simple peek: get everything. */
1907         i = evbuffer_peek(buf, -1, NULL, v, 20);
1908         tt_int_op(i, ==, 16); /* we used only 16 chunks. */
1909         tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1910         tt_iov_eq(&v[3], "Contents of chunk [3]\n");
1911         tt_iov_eq(&v[12], "Contents of chunk [12]\n");
1912         tt_iov_eq(&v[15], "Contents of chunk [15]\n");
1913
1914         /* Just get one chunk worth. */
1915         memset(v, 0, sizeof(v));
1916         i = evbuffer_peek(buf, -1, NULL, v, 1);
1917         tt_int_op(i, ==, 1);
1918         tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1919         tt_assert(v[1].iov_base == NULL);
1920
1921         /* Suppose we want at least the first 40 bytes. */
1922         memset(v, 0, sizeof(v));
1923         i = evbuffer_peek(buf, 40, NULL, v, 16);
1924         tt_int_op(i, ==, 2);
1925         tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1926         tt_iov_eq(&v[1], "Contents of chunk [1]\n");
1927         tt_assert(v[2].iov_base == NULL);
1928
1929         /* How many chunks do we need for 100 bytes? */
1930         memset(v, 0, sizeof(v));
1931         i = evbuffer_peek(buf, 100, NULL, NULL, 0);
1932         tt_int_op(i, ==, 5);
1933         tt_assert(v[0].iov_base == NULL);
1934
1935         /* Now we ask for more bytes than we provide chunks for */
1936         memset(v, 0, sizeof(v));
1937         i = evbuffer_peek(buf, 60, NULL, v, 1);
1938         tt_int_op(i, ==, 3);
1939         tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1940         tt_assert(v[1].iov_base == NULL);
1941
1942         /* Now we ask for more bytes than the buffer has. */
1943         memset(v, 0, sizeof(v));
1944         i = evbuffer_peek(buf, 65536, NULL, v, 20);
1945         tt_int_op(i, ==, 16); /* we used only 16 chunks. */
1946         tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1947         tt_iov_eq(&v[3], "Contents of chunk [3]\n");
1948         tt_iov_eq(&v[12], "Contents of chunk [12]\n");
1949         tt_iov_eq(&v[15], "Contents of chunk [15]\n");
1950         tt_assert(v[16].iov_base == NULL);
1951
1952         /* What happens if we try an empty buffer? */
1953         memset(v, 0, sizeof(v));
1954         i = evbuffer_peek(tmp_buf, -1, NULL, v, 20);
1955         tt_int_op(i, ==, 0);
1956         tt_assert(v[0].iov_base == NULL);
1957         memset(v, 0, sizeof(v));
1958         i = evbuffer_peek(tmp_buf, 50, NULL, v, 20);
1959         tt_int_op(i, ==, 0);
1960         tt_assert(v[0].iov_base == NULL);
1961
1962         /* Okay, now time to have fun with pointers. */
1963         memset(v, 0, sizeof(v));
1964         evbuffer_ptr_set(buf, &ptr, 30, EVBUFFER_PTR_SET);
1965         i = evbuffer_peek(buf, 50, &ptr, v, 20);
1966         tt_int_op(i, ==, 3);
1967         tt_iov_eq(&v[0], " of chunk [1]\n");
1968         tt_iov_eq(&v[1], "Contents of chunk [2]\n");
1969         tt_iov_eq(&v[2], "Contents of chunk [3]\n"); /*more than we asked for*/
1970
1971         /* advance to the start of another chain. */
1972         memset(v, 0, sizeof(v));
1973         evbuffer_ptr_set(buf, &ptr, 14, EVBUFFER_PTR_ADD);
1974         i = evbuffer_peek(buf, 44, &ptr, v, 20);
1975         tt_int_op(i, ==, 2);
1976         tt_iov_eq(&v[0], "Contents of chunk [2]\n");
1977         tt_iov_eq(&v[1], "Contents of chunk [3]\n"); /*more than we asked for*/
1978
1979         /* peek at the end of the buffer */
1980         memset(v, 0, sizeof(v));
1981         tt_assert(evbuffer_ptr_set(buf, &ptr, evbuffer_get_length(buf), EVBUFFER_PTR_SET) == 0);
1982         i = evbuffer_peek(buf, 44, &ptr, v, 20);
1983         tt_int_op(i, ==, 0);
1984         tt_assert(v[0].iov_base == NULL);
1985
1986 end:
1987         if (buf)
1988                 evbuffer_free(buf);
1989         if (tmp_buf)
1990                 evbuffer_free(tmp_buf);
1991 }
1992
1993 /* Check whether evbuffer freezing works right.  This is called twice,
1994    once with the argument "start" and once with the argument "end".
1995    When we test "start", we freeze the start of an evbuffer and make sure
1996    that modifying the start of the buffer doesn't work.  When we test
1997    "end", we freeze the end of an evbuffer and make sure that modifying
1998    the end of the buffer doesn't work.
1999  */
2000 static void
2001 test_evbuffer_freeze(void *ptr)
2002 {
2003         struct evbuffer *buf = NULL, *tmp_buf=NULL;
2004         const char string[] = /* Year's End, Richard Wilbur */
2005             "I've known the wind by water banks to shake\n"
2006             "The late leaves down, which frozen where they fell\n"
2007             "And held in ice as dancers in a spell\n"
2008             "Fluttered all winter long into a lake...";
2009         const int start = !strcmp(ptr, "start");
2010         char *cp;
2011         char charbuf[128];
2012         int r;
2013         size_t orig_length;
2014         struct evbuffer_iovec v[1];
2015
2016         if (!start)
2017                 tt_str_op(ptr, ==, "end");
2018
2019         buf = evbuffer_new();
2020         tmp_buf = evbuffer_new();
2021         tt_assert(tmp_buf);
2022
2023         evbuffer_add(buf, string, strlen(string));
2024         evbuffer_freeze(buf, start); /* Freeze the start or the end.*/
2025
2026 #define FREEZE_EQ(a, startcase, endcase)                \
2027         do {                                            \
2028             if (start) {                                \
2029                     tt_int_op((a), ==, (startcase));    \
2030             } else {                                    \
2031                     tt_int_op((a), ==, (endcase));      \
2032             }                                           \
2033         } while (0)
2034
2035
2036         orig_length = evbuffer_get_length(buf);
2037
2038         /* These functions all manipulate the end of buf. */
2039         r = evbuffer_add(buf, "abc", 0);
2040         FREEZE_EQ(r, 0, -1);
2041         r = evbuffer_reserve_space(buf, 10, v, 1);
2042         FREEZE_EQ(r, 1, -1);
2043         if (r == 1) {
2044                 memset(v[0].iov_base, 'X', 10);
2045                 v[0].iov_len = 10;
2046         }
2047         r = evbuffer_commit_space(buf, v, 1);
2048         FREEZE_EQ(r, 0, -1);
2049         r = evbuffer_add_reference(buf, string, 5, NULL, NULL);
2050         FREEZE_EQ(r, 0, -1);
2051         r = evbuffer_add_printf(buf, "Hello %s", "world");
2052         FREEZE_EQ(r, 11, -1);
2053         /* TODO: test add_buffer, add_file, read */
2054
2055         if (!start)
2056                 tt_int_op(orig_length, ==, evbuffer_get_length(buf));
2057
2058         orig_length = evbuffer_get_length(buf);
2059
2060         /* These functions all manipulate the start of buf. */
2061         r = evbuffer_remove(buf, charbuf, 1);
2062         FREEZE_EQ(r, -1, 1);
2063         r = evbuffer_drain(buf, 3);
2064         FREEZE_EQ(r, -1, 0);
2065         r = evbuffer_prepend(buf, "dummy", 5);
2066         FREEZE_EQ(r, -1, 0);
2067         cp = evbuffer_readln(buf, NULL, EVBUFFER_EOL_LF);
2068         FREEZE_EQ(cp==NULL, 1, 0);
2069         if (cp)
2070                 free(cp);
2071         /* TODO: Test remove_buffer, add_buffer, write, prepend_buffer */
2072
2073         if (start)
2074                 tt_int_op(orig_length, ==, evbuffer_get_length(buf));
2075
2076 end:
2077         if (buf)
2078                 evbuffer_free(buf);
2079
2080         if (tmp_buf)
2081                 evbuffer_free(tmp_buf);
2082 }
2083
2084 static void
2085 test_evbuffer_add_iovec(void * ptr)
2086 {
2087         struct evbuffer * buf = NULL;
2088         struct evbuffer_iovec vec[4];
2089         const char * data[] = {
2090                 "Guilt resembles a sword with two edges.",
2091                 "On the one hand, it cuts for Justice, imposing practical morality upon those who fear it.",
2092                 "Conscience does not always adhere to rational judgment.",
2093                 "Guilt is always a self-imposed burden, but it is not always rightly imposed."
2094                 /* -- R.A. Salvatore, _Sojurn_ */
2095         };
2096         size_t expected_length = 0;
2097         size_t returned_length = 0;
2098         int i;
2099
2100         buf = evbuffer_new();
2101
2102         tt_assert(buf);
2103
2104         for (i = 0; i < 4; i++) {
2105                 vec[i].iov_len  = strlen(data[i]);
2106                 vec[i].iov_base = (char*) data[i];
2107                 expected_length += vec[i].iov_len;
2108         }
2109
2110         returned_length = evbuffer_add_iovec(buf, vec, 4);
2111
2112         tt_int_op(returned_length, ==, evbuffer_get_length(buf));
2113         tt_int_op(evbuffer_get_length(buf), ==, expected_length);
2114
2115         for (i = 0; i < 4; i++) {
2116                 char charbuf[1024];
2117
2118                 memset(charbuf, 0, 1024);
2119                 evbuffer_remove(buf, charbuf, strlen(data[i]));
2120                 tt_assert(strcmp(charbuf, data[i]) == 0);
2121         }
2122
2123         tt_assert(evbuffer_get_length(buf) == 0);
2124 end:
2125         if (buf) {
2126                 evbuffer_free(buf);
2127         }
2128 }
2129
2130 static void
2131 test_evbuffer_copyout(void *dummy)
2132 {
2133         const char string[] =
2134             "Still they skirmish to and fro, men my messmates on the snow "
2135             "When we headed off the aurochs turn for turn; "
2136             "When the rich Allobrogenses never kept amanuenses, "
2137             "And our only plots were piled in lakes at Berne.";
2138         /* -- Kipling, "In The Neolithic Age" */
2139         char tmp[1024];
2140         struct evbuffer_ptr ptr;
2141         struct evbuffer *buf;
2142
2143         (void)dummy;
2144
2145         buf = evbuffer_new();
2146         tt_assert(buf);
2147
2148         tt_int_op(strlen(string), ==, 206);
2149
2150         /* Ensure separate chains */
2151         evbuffer_add_reference(buf, string, 80, no_cleanup, NULL);
2152         evbuffer_add_reference(buf, string+80, 80, no_cleanup, NULL);
2153         evbuffer_add(buf, string+160, strlen(string)-160);
2154
2155         tt_int_op(206, ==, evbuffer_get_length(buf));
2156
2157         /* First, let's test plain old copyout. */
2158
2159         /* Copy a little from the beginning. */
2160         tt_int_op(10, ==, evbuffer_copyout(buf, tmp, 10));
2161         tt_int_op(0, ==, memcmp(tmp, "Still they", 10));
2162
2163         /* Now copy more than a little from the beginning */
2164         memset(tmp, 0, sizeof(tmp));
2165         tt_int_op(100, ==, evbuffer_copyout(buf, tmp, 100));
2166         tt_int_op(0, ==, memcmp(tmp, string, 100));
2167
2168         /* Copy too much; ensure truncation. */
2169         memset(tmp, 0, sizeof(tmp));
2170         tt_int_op(206, ==, evbuffer_copyout(buf, tmp, 230));
2171         tt_int_op(0, ==, memcmp(tmp, string, 206));
2172
2173         /* That was supposed to be nondestructive, btw */
2174         tt_int_op(206, ==, evbuffer_get_length(buf));
2175
2176         /* Now it's time to test copyout_from!  First, let's start in the
2177          * first chain. */
2178         evbuffer_ptr_set(buf, &ptr, 15, EVBUFFER_PTR_SET);
2179         memset(tmp, 0, sizeof(tmp));
2180         tt_int_op(10, ==, evbuffer_copyout_from(buf, &ptr, tmp, 10));
2181         tt_int_op(0, ==, memcmp(tmp, "mish to an", 10));
2182
2183         /* Right up to the end of the first chain */
2184         memset(tmp, 0, sizeof(tmp));
2185         tt_int_op(65, ==, evbuffer_copyout_from(buf, &ptr, tmp, 65));
2186         tt_int_op(0, ==, memcmp(tmp, string+15, 65));
2187
2188         /* Span into the second chain */
2189         memset(tmp, 0, sizeof(tmp));
2190         tt_int_op(90, ==, evbuffer_copyout_from(buf, &ptr, tmp, 90));
2191         tt_int_op(0, ==, memcmp(tmp, string+15, 90));
2192
2193         /* Span into the third chain */
2194         memset(tmp, 0, sizeof(tmp));
2195         tt_int_op(160, ==, evbuffer_copyout_from(buf, &ptr, tmp, 160));
2196         tt_int_op(0, ==, memcmp(tmp, string+15, 160));
2197
2198         /* Overrun */
2199         memset(tmp, 0, sizeof(tmp));
2200         tt_int_op(206-15, ==, evbuffer_copyout_from(buf, &ptr, tmp, 999));
2201         tt_int_op(0, ==, memcmp(tmp, string+15, 206-15));
2202
2203         /* That was supposed to be nondestructive, too */
2204         tt_int_op(206, ==, evbuffer_get_length(buf));
2205
2206 end:
2207         if (buf)
2208                 evbuffer_free(buf);
2209 }
2210
2211 static void *
2212 setup_passthrough(const struct testcase_t *testcase)
2213 {
2214         return testcase->setup_data;
2215 }
2216 static int
2217 cleanup_passthrough(const struct testcase_t *testcase, void *ptr)
2218 {
2219         (void) ptr;
2220         return 1;
2221 }
2222
2223 static const struct testcase_setup_t nil_setup = {
2224         setup_passthrough,
2225         cleanup_passthrough
2226 };
2227
2228 struct testcase_t evbuffer_testcases[] = {
2229         { "evbuffer", test_evbuffer, 0, NULL, NULL },
2230         { "remove_buffer_with_empty", test_evbuffer_remove_buffer_with_empty, 0, NULL, NULL },
2231         { "reserve2", test_evbuffer_reserve2, 0, NULL, NULL },
2232         { "reserve_many", test_evbuffer_reserve_many, 0, NULL, NULL },
2233         { "reserve_many2", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"add" },
2234         { "reserve_many3", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"fill" },
2235         { "expand", test_evbuffer_expand, 0, NULL, NULL },
2236         { "reference", test_evbuffer_reference, 0, NULL, NULL },
2237         { "iterative", test_evbuffer_iterative, 0, NULL, NULL },
2238         { "readln", test_evbuffer_readln, TT_NO_LOGS, &basic_setup, NULL },
2239         { "search_eol", test_evbuffer_search_eol, 0, NULL, NULL },
2240         { "find", test_evbuffer_find, 0, NULL, NULL },
2241         { "ptr_set", test_evbuffer_ptr_set, 0, NULL, NULL },
2242         { "search", test_evbuffer_search, 0, NULL, NULL },
2243         { "callbacks", test_evbuffer_callbacks, 0, NULL, NULL },
2244         { "add_reference", test_evbuffer_add_reference, 0, NULL, NULL },
2245         { "multicast", test_evbuffer_multicast, 0, NULL, NULL },
2246         { "multicast_drain", test_evbuffer_multicast_drain, 0, NULL, NULL },
2247         { "prepend", test_evbuffer_prepend, TT_FORK, NULL, NULL },
2248         { "peek", test_evbuffer_peek, 0, NULL, NULL },
2249         { "peek_first_gt", test_evbuffer_peek_first_gt, 0, NULL, NULL },
2250         { "freeze_start", test_evbuffer_freeze, 0, &nil_setup, (void*)"start" },
2251         { "freeze_end", test_evbuffer_freeze, 0, &nil_setup, (void*)"end" },
2252         { "add_iovec", test_evbuffer_add_iovec, 0, NULL, NULL},
2253         { "copyout", test_evbuffer_copyout, 0, NULL, NULL},
2254         { "file_segment_add_cleanup_cb", test_evbuffer_file_segment_add_cleanup_cb, 0, NULL, NULL },
2255
2256 #define ADDFILE_TEST(name, parameters)                                  \
2257         { name, test_evbuffer_add_file, TT_FORK|TT_NEED_BASE,           \
2258           &basic_setup, (void*)(parameters) }
2259
2260 #define ADDFILE_TEST_GROUP(name, parameters)                    \
2261         ADDFILE_TEST(name "_sendfile", "sendfile " parameters), \
2262         ADDFILE_TEST(name "_mmap", "mmap " parameters),         \
2263         ADDFILE_TEST(name "_linear", "linear " parameters)
2264
2265         ADDFILE_TEST_GROUP("add_file", ""),
2266         ADDFILE_TEST("add_file_nosegment", "default nosegment"),
2267
2268         ADDFILE_TEST_GROUP("add_big_file", "bigfile"),
2269         ADDFILE_TEST("add_big_file_nosegment", "default nosegment bigfile"),
2270
2271         ADDFILE_TEST_GROUP("add_file_offset", "bigfile map_offset"),
2272         ADDFILE_TEST("add_file_offset_nosegment",
2273             "default nosegment bigfile map_offset"),
2274
2275         ADDFILE_TEST_GROUP("add_file_offset2", "bigfile offset_in_segment"),
2276
2277         ADDFILE_TEST_GROUP("add_file_offset3",
2278             "bigfile offset_in_segment map_offset"),
2279
2280         END_OF_TESTCASES
2281 };