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