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